diff options
Diffstat (limited to 'bindings/python/clang/cindex.py')
-rw-r--r-- | bindings/python/clang/cindex.py | 308 |
1 files changed, 254 insertions, 54 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index aeb34f8cb232..c22d2510c62c 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -64,6 +64,7 @@ call is efficient. from ctypes import * import collections +import sys import clang.enumerations @@ -73,6 +74,33 @@ import clang.enumerations # this by marshalling object arguments as void**. c_object_p = POINTER(c_void_p) +if sys.version_info[0] > 2: +# Python 3 strings are unicode, translate them to/from utf8 for C-interop +# Python 3 replaces xrange with range, we want xrange behaviour + xrange = range + + class c_string_p(c_char_p): + def __init__(self, p=None): + if type(p) == str: + p = p.encode("utf8") + super(c_char_p, self).__init__(p) + + def __str__(self): + return str(self.value) + + @property + def value(self): + if super(c_char_p, self).value is None: + return None + return super(c_char_p, self).value.decode("utf8") + + @classmethod + def from_param(cls, param): + return cls(param) +else: + c_string_p = c_char_p + + callbacks = {} ### Exception Classes ### @@ -147,7 +175,7 @@ class CachedProperty(object): class _CXString(Structure): """Helper for transforming CXString results.""" - _fields_ = [("spelling", c_char_p), ("free", c_int)] + _fields_ = [("spelling", c_string_p), ("free", c_int)] def __del__(self): conf.lib.clang_disposeString(self) @@ -305,6 +333,14 @@ class Diagnostic(object): Error = 3 Fatal = 4 + DisplaySourceLocation = 0x01 + DisplayColumn = 0x02 + DisplaySourceRanges = 0x04 + DisplayOption = 0x08 + DisplayCategoryId = 0x10 + DisplayCategoryName = 0x20 + _FormatOptionsMask = 0x3f + def __init__(self, ptr): self.ptr = ptr @@ -321,7 +357,7 @@ class Diagnostic(object): @property def spelling(self): - return conf.lib.clang_getDiagnosticSpelling(self) + return str(conf.lib.clang_getDiagnosticSpelling(self)) @property def ranges(self): @@ -350,8 +386,8 @@ class Diagnostic(object): def __getitem__(self, key): range = SourceRange() - value = conf.lib.clang_getDiagnosticFixIt(self.diag, key, - byref(range)) + value = str(conf.lib.clang_getDiagnosticFixIt(self.diag, key, + byref(range))) if len(value) == 0: raise IndexError @@ -384,12 +420,12 @@ class Diagnostic(object): @property def category_name(self): """The string name of the category for this diagnostic.""" - return conf.lib.clang_getDiagnosticCategoryText(self) + return str(conf.lib.clang_getDiagnosticCategoryText(self)) @property def option(self): """The command-line option that enables this diagnostic.""" - return conf.lib.clang_getDiagnosticOption(self, None) + return str(conf.lib.clang_getDiagnosticOption(self, None)) @property def disable_option(self): @@ -397,12 +433,29 @@ class Diagnostic(object): disable = _CXString() conf.lib.clang_getDiagnosticOption(self, byref(disable)) - return conf.lib.clang_getCString(disable) + return str(conf.lib.clang_getCString(disable)) + + def format(self, options=None): + """ + Format this diagnostic for display. The options argument takes + Diagnostic.Display* flags, which can be combined using bitwise OR. If + the options argument is not provided, the default display options will + be used. + """ + if options is None: + options = conf.lib.clang_defaultDiagnosticDisplayOptions() + if options & ~Diagnostic._FormatOptionsMask: + raise ValueError('Invalid format options') + formatted = conf.lib.clang_formatDiagnostic(self, options) + return conf.lib.clang_getCString(formatted) def __repr__(self): return "<Diagnostic severity %r, location %r, spelling %r>" % ( self.severity, self.location, self.spelling) + def __str__(self): + return self.format() + def from_param(self): return self.ptr @@ -529,8 +582,8 @@ class BaseEnumeration(object): if value >= len(self.__class__._kinds): self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1) if self.__class__._kinds[value] is not None: - raise ValueError,'{0} value {1} already loaded'.format( - str(self.__class__), value) + raise ValueError('{0} value {1} already loaded'.format( + str(self.__class__), value)) self.value = value self.__class__._kinds[value] = self self.__class__._name_map = None @@ -547,12 +600,12 @@ class BaseEnumeration(object): for key, value in self.__class__.__dict__.items(): if isinstance(value, self.__class__): self._name_map[value] = key - return self._name_map[self] + return str(self._name_map[self]) @classmethod def from_id(cls, id): if id >= len(cls._kinds) or cls._kinds[id] is None: - raise ValueError,'Unknown template argument kind %d' % id + raise ValueError('Unknown template argument kind %d' % id) return cls._kinds[id] def __repr__(self): @@ -571,7 +624,7 @@ class CursorKind(BaseEnumeration): @staticmethod def get_all_kinds(): """Return all CursorKind enumeration instances.""" - return filter(None, CursorKind._kinds) + return [x for x in CursorKind._kinds if x] def is_declaration(self): """Test if this is a declaration kind.""" @@ -983,6 +1036,12 @@ CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145) # Represents the "self" expression in a ObjC method. CursorKind.OBJ_SELF_EXPR = CursorKind(146) +# OpenMP 4.0 [2.4, Array Section]. +CursorKind.OMP_ARRAY_SECTION_EXPR = CursorKind(147) + +# Represents an @available(...) check. +CursorKind.OBJC_AVAILABILITY_CHECK_EXPR = CursorKind(148) + # A statement whose specific kind is not exposed via this interface. # @@ -1084,6 +1143,126 @@ CursorKind.NULL_STMT = CursorKind(230) # Adaptor class for mixing declarations with statements and expressions. CursorKind.DECL_STMT = CursorKind(231) +# OpenMP parallel directive. +CursorKind.OMP_PARALLEL_DIRECTIVE = CursorKind(232) + +# OpenMP SIMD directive. +CursorKind.OMP_SIMD_DIRECTIVE = CursorKind(233) + +# OpenMP for directive. +CursorKind.OMP_FOR_DIRECTIVE = CursorKind(234) + +# OpenMP sections directive. +CursorKind.OMP_SECTIONS_DIRECTIVE = CursorKind(235) + +# OpenMP section directive. +CursorKind.OMP_SECTION_DIRECTIVE = CursorKind(236) + +# OpenMP single directive. +CursorKind.OMP_SINGLE_DIRECTIVE = CursorKind(237) + +# OpenMP parallel for directive. +CursorKind.OMP_PARALLEL_FOR_DIRECTIVE = CursorKind(238) + +# OpenMP parallel sections directive. +CursorKind.OMP_PARALLEL_SECTIONS_DIRECTIVE = CursorKind(239) + +# OpenMP task directive. +CursorKind.OMP_TASK_DIRECTIVE = CursorKind(240) + +# OpenMP master directive. +CursorKind.OMP_MASTER_DIRECTIVE = CursorKind(241) + +# OpenMP critical directive. +CursorKind.OMP_CRITICAL_DIRECTIVE = CursorKind(242) + +# OpenMP taskyield directive. +CursorKind.OMP_TASKYIELD_DIRECTIVE = CursorKind(243) + +# OpenMP barrier directive. +CursorKind.OMP_BARRIER_DIRECTIVE = CursorKind(244) + +# OpenMP taskwait directive. +CursorKind.OMP_TASKWAIT_DIRECTIVE = CursorKind(245) + +# OpenMP flush directive. +CursorKind.OMP_FLUSH_DIRECTIVE = CursorKind(246) + +# Windows Structured Exception Handling's leave statement. +CursorKind.SEH_LEAVE_STMT = CursorKind(247) + +# OpenMP ordered directive. +CursorKind.OMP_ORDERED_DIRECTIVE = CursorKind(248) + +# OpenMP atomic directive. +CursorKind.OMP_ATOMIC_DIRECTIVE = CursorKind(249) + +# OpenMP for SIMD directive. +CursorKind.OMP_FOR_SIMD_DIRECTIVE = CursorKind(250) + +# OpenMP parallel for SIMD directive. +CursorKind.OMP_PARALLELFORSIMD_DIRECTIVE = CursorKind(251) + +# OpenMP target directive. +CursorKind.OMP_TARGET_DIRECTIVE = CursorKind(252) + +# OpenMP teams directive. +CursorKind.OMP_TEAMS_DIRECTIVE = CursorKind(253) + +# OpenMP taskgroup directive. +CursorKind.OMP_TASKGROUP_DIRECTIVE = CursorKind(254) + +# OpenMP cancellation point directive. +CursorKind.OMP_CANCELLATION_POINT_DIRECTIVE = CursorKind(255) + +# OpenMP cancel directive. +CursorKind.OMP_CANCEL_DIRECTIVE = CursorKind(256) + +# OpenMP target data directive. +CursorKind.OMP_TARGET_DATA_DIRECTIVE = CursorKind(257) + +# OpenMP taskloop directive. +CursorKind.OMP_TASK_LOOP_DIRECTIVE = CursorKind(258) + +# OpenMP taskloop simd directive. +CursorKind.OMP_TASK_LOOP_SIMD_DIRECTIVE = CursorKind(259) + +# OpenMP distribute directive. +CursorKind.OMP_DISTRIBUTE_DIRECTIVE = CursorKind(260) + +# OpenMP target enter data directive. +CursorKind.OMP_TARGET_ENTER_DATA_DIRECTIVE = CursorKind(261) + +# OpenMP target exit data directive. +CursorKind.OMP_TARGET_EXIT_DATA_DIRECTIVE = CursorKind(262) + +# OpenMP target parallel directive. +CursorKind.OMP_TARGET_PARALLEL_DIRECTIVE = CursorKind(263) + +# OpenMP target parallel for directive. +CursorKind.OMP_TARGET_PARALLELFOR_DIRECTIVE = CursorKind(264) + +# OpenMP target update directive. +CursorKind.OMP_TARGET_UPDATE_DIRECTIVE = CursorKind(265) + +# OpenMP distribute parallel for directive. +CursorKind.OMP_DISTRIBUTE_PARALLELFOR_DIRECTIVE = CursorKind(266) + +# OpenMP distribute parallel for simd directive. +CursorKind.OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(267) + +# OpenMP distribute simd directive. +CursorKind.OMP_DISTRIBUTE_SIMD_DIRECTIVE = CursorKind(268) + +# OpenMP target parallel for simd directive. +CursorKind.OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE = CursorKind(269) + +# OpenMP target simd directive. +CursorKind.OMP_TARGET_SIMD_DIRECTIVE = CursorKind(270) + +# OpenMP teams distribute directive. +CursorKind.OMP_TEAMS_DISTRIBUTE_DIRECTIVE = CursorKind(271) + ### # Other Kinds @@ -1136,6 +1315,10 @@ CursorKind.INCLUSION_DIRECTIVE = CursorKind(503) CursorKind.MODULE_IMPORT_DECL = CursorKind(600) # A type alias template declaration CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601) +# A static_assert or _Static_assert node +CursorKind.STATIC_ASSERT = CursorKind(602) +# A friend declaration +CursorKind.FRIEND_DECL = CursorKind(603) # A code completion overload candidate. CursorKind.OVERLOAD_CANDIDATE = CursorKind(700) @@ -1274,9 +1457,9 @@ class Cursor(Structure): def spelling(self): """Return the spelling of the entity pointed at by the cursor.""" if not hasattr(self, '_spelling'): - self._spelling = conf.lib.clang_getCursorSpelling(self) + self._spelling = str(conf.lib.clang_getCursorSpelling(self)) - return self._spelling + return str(self._spelling) @property def displayname(self): @@ -1288,7 +1471,7 @@ class Cursor(Structure): arguments of a class template specialization. """ if not hasattr(self, '_displayname'): - self._displayname = conf.lib.clang_getCursorDisplayName(self) + self._displayname = str(conf.lib.clang_getCursorDisplayName(self)) return self._displayname @@ -1296,7 +1479,7 @@ class Cursor(Structure): def mangled_name(self): """Return the mangled name for the entity referenced by this cursor.""" if not hasattr(self, '_mangled_name'): - self._mangled_name = conf.lib.clang_Cursor_getMangling(self) + self._mangled_name = str(conf.lib.clang_Cursor_getMangling(self)) return self._mangled_name @@ -1435,7 +1618,7 @@ class Cursor(Structure): self._objc_type_encoding = \ conf.lib.clang_getDeclObjCTypeEncoding(self) - return self._objc_type_encoding + return str(self._objc_type_encoding) @property def hash(self): @@ -1482,17 +1665,23 @@ class Cursor(Structure): @property def brief_comment(self): """Returns the brief comment text associated with that Cursor""" - return conf.lib.clang_Cursor_getBriefCommentText(self) + r = conf.lib.clang_Cursor_getBriefCommentText(self) + if not r: + return None + return str(r) @property def raw_comment(self): """Returns the raw comment text associated with that Cursor""" - return conf.lib.clang_Cursor_getRawCommentText(self) + r = conf.lib.clang_Cursor_getRawCommentText(self) + if not r: + return None + return str(r) def get_arguments(self): """Return an iterator for accessing the arguments of this cursor.""" num_args = conf.lib.clang_Cursor_getNumArguments(self) - for i in range(0, num_args): + for i in xrange(0, num_args): yield conf.lib.clang_Cursor_getArgument(self, i) def get_num_template_arguments(self): @@ -1622,7 +1811,7 @@ class StorageClass(object): if value >= len(StorageClass._kinds): StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1) if StorageClass._kinds[value] is not None: - raise ValueError,'StorageClass already loaded' + raise ValueError('StorageClass already loaded') self.value = value StorageClass._kinds[value] = self StorageClass._name_map = None @@ -1643,7 +1832,7 @@ class StorageClass(object): @staticmethod def from_id(id): if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]: - raise ValueError,'Unknown storage class %d' % id + raise ValueError('Unknown storage class %d' % id) return StorageClass._kinds[id] def __repr__(self): @@ -1696,7 +1885,7 @@ class TypeKind(BaseEnumeration): @property def spelling(self): """Retrieve the spelling of this TypeKind.""" - return conf.lib.clang_getTypeKindSpelling(self.value) + return str(conf.lib.clang_getTypeKindSpelling(self.value)) def __repr__(self): return 'TypeKind.%s' % (self.name,) @@ -1972,7 +2161,7 @@ class Type(Structure): """ Retrieve the offset of a field in the record. """ - return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname)) + return conf.lib.clang_Type_getOffsetOf(self, fieldname) def get_ref_qualifier(self): """ @@ -1999,7 +2188,7 @@ class Type(Structure): @property def spelling(self): """Retrieve the spelling of this Type.""" - return conf.lib.clang_getTypeSpelling(self) + return str(conf.lib.clang_getTypeSpelling(self)) def __eq__(self, other): if type(other) != type(self): @@ -2031,7 +2220,7 @@ class ClangObject(object): class _CXUnsavedFile(Structure): """Helper for passing unsaved file arguments.""" - _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)] + _fields_ = [("name", c_string_p), ("contents", c_string_p), ('length', c_ulong)] # Functions calls through the python interface are rather slow. Fortunately, # for most symboles, we do not need to perform a function call. Their spelling @@ -2077,7 +2266,7 @@ class CompletionChunk: self.__kindNumberCache = -1 def __repr__(self): - return "{'" + self.spelling + "', " + str(self.kind) + "}" + return "{'" + str(self.spelling) + "', " + str(self.kind) + "}" @CachedProperty def spelling(self): @@ -2386,7 +2575,9 @@ class TranslationUnit(ClangObject): args_array = None if len(args) > 0: - args_array = (c_char_p * len(args))(* args) + args_array = (c_string_p * len(args))() + for i,a in enumerate(args): + args_array[i] = c_string_p(a) unsaved_array = None if len(unsaved_files) > 0: @@ -2395,8 +2586,8 @@ class TranslationUnit(ClangObject): if hasattr(contents, "read"): contents = contents.read() - unsaved_array[i].name = name - unsaved_array[i].contents = contents + unsaved_array[i].name = c_string_p(name) + unsaved_array[i].contents = c_string_p(contents) unsaved_array[i].length = len(contents) ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array, @@ -2451,7 +2642,7 @@ class TranslationUnit(ClangObject): @property def spelling(self): """Get the original translation unit source file name.""" - return conf.lib.clang_getTranslationUnitSpelling(self) + return str(conf.lib.clang_getTranslationUnitSpelling(self)) def get_includes(self): """ @@ -2574,9 +2765,9 @@ class TranslationUnit(ClangObject): # FIXME: It would be great to support an efficient version # of this, one day. value = value.read() - print value + print(value) if not isinstance(value, str): - raise TypeError,'Unexpected unsaved file contents.' + raise TypeError('Unexpected unsaved file contents.') unsaved_files_array[i].name = name unsaved_files_array[i].contents = value unsaved_files_array[i].length = len(value) @@ -2638,11 +2829,11 @@ class TranslationUnit(ClangObject): # FIXME: It would be great to support an efficient version # of this, one day. value = value.read() - print value + print(value) if not isinstance(value, str): - raise TypeError,'Unexpected unsaved file contents.' - unsaved_files_array[i].name = name - unsaved_files_array[i].contents = value + raise TypeError('Unexpected unsaved file contents.') + unsaved_files_array[i].name = c_string_p(name) + unsaved_files_array[i].contents = c_string_p(value) unsaved_files_array[i].length = len(value) ptr = conf.lib.clang_codeCompleteAt(self, path, line, column, unsaved_files_array, len(unsaved_files), options) @@ -2677,7 +2868,7 @@ class File(ClangObject): @property def name(self): """Return the complete file and path name of the file.""" - return conf.lib.clang_getCString(conf.lib.clang_getFileName(self)) + return str(conf.lib.clang_getCString(conf.lib.clang_getFileName(self))) @property def time(self): @@ -2685,7 +2876,7 @@ class File(ClangObject): return conf.lib.clang_getFileTime(self) def __str__(self): - return self.name + return str(self.name) def __repr__(self): return "<File: %s>" % (self.name) @@ -2754,12 +2945,12 @@ class CompileCommand(object): @property def directory(self): """Get the working directory for this CompileCommand""" - return conf.lib.clang_CompileCommand_getDirectory(self.cmd) + return str(conf.lib.clang_CompileCommand_getDirectory(self.cmd)) @property def filename(self): """Get the working filename for this CompileCommand""" - return conf.lib.clang_CompileCommand_getFilename(self.cmd) + return str(conf.lib.clang_CompileCommand_getFilename(self.cmd)) @property def arguments(self): @@ -2771,7 +2962,7 @@ class CompileCommand(object): """ length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd) for i in xrange(length): - yield conf.lib.clang_CompileCommand_getArg(self.cmd, i) + yield str(conf.lib.clang_CompileCommand_getArg(self.cmd, i)) class CompileCommands(object): """ @@ -2865,7 +3056,7 @@ class Token(Structure): This is the textual representation of the token in source. """ - return conf.lib.clang_getTokenSpelling(self._tu, self) + return str(conf.lib.clang_getTokenSpelling(self._tu, self)) @property def kind(self): @@ -2908,7 +3099,7 @@ functionList = [ [c_object_p]), ("clang_CompilationDatabase_fromDirectory", - [c_char_p, POINTER(c_uint)], + [c_string_p, POINTER(c_uint)], c_object_p, CompilationDatabase.from_result), @@ -2918,7 +3109,7 @@ functionList = [ CompileCommands.from_result), ("clang_CompilationDatabase_getCompileCommands", - [c_object_p, c_char_p], + [c_object_p, c_string_p], c_object_p, CompileCommands.from_result), @@ -2953,7 +3144,7 @@ functionList = [ c_uint), ("clang_codeCompleteAt", - [TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int], + [TranslationUnit, c_string_p, c_int, c_int, c_void_p, c_int, c_int], POINTER(CCRStructure)), ("clang_codeCompleteGetDiagnostic", @@ -2969,7 +3160,7 @@ functionList = [ c_object_p), ("clang_createTranslationUnit", - [Index, c_char_p], + [Index, c_string_p], c_object_p), ("clang_CXXConstructor_isConvertingConstructor", @@ -3012,6 +3203,10 @@ functionList = [ [Cursor], bool), + ("clang_defaultDiagnosticDisplayOptions", + [], + c_uint), + ("clang_defaultSaveOptions", [TranslationUnit], c_uint), @@ -3053,6 +3248,10 @@ functionList = [ [Type, Type], bool), + ("clang_formatDiagnostic", + [Diagnostic, c_uint], + _CXString), + ("clang_getArgType", [Type, c_uint], Type, @@ -3111,7 +3310,7 @@ functionList = [ ("clang_getCString", [_CXString], - c_char_p), + c_string_p), ("clang_getCursor", [TranslationUnit, SourceLocation], @@ -3258,7 +3457,7 @@ functionList = [ Type.from_result), ("clang_getFile", - [TranslationUnit, c_char_p], + [TranslationUnit, c_string_p], c_object_p), ("clang_getFileName", @@ -3387,7 +3586,7 @@ functionList = [ ("clang_getTUResourceUsageName", [c_uint], - c_char_p), + c_string_p), ("clang_getTypeDeclaration", [Type], @@ -3482,7 +3681,7 @@ functionList = [ bool), ("clang_parseTranslationUnit", - [Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int], + [Index, c_string_p, c_void_p, c_int, c_void_p, c_int, c_int], c_object_p), ("clang_reparseTranslationUnit", @@ -3490,7 +3689,7 @@ functionList = [ c_int), ("clang_saveTranslationUnit", - [TranslationUnit, c_char_p, c_uint], + [TranslationUnit, c_string_p, c_uint], c_int), ("clang_tokenize", @@ -3562,7 +3761,7 @@ functionList = [ Type.from_result), ("clang_Type_getOffsetOf", - [Type, c_char_p], + [Type, c_string_p], c_longlong), ("clang_Type_getSizeOf", @@ -3621,7 +3820,8 @@ def register_functions(lib, ignore_errors): def register(item): return register_function(lib, item, ignore_errors) - map(register, functionList) + for f in functionList: + register(f) class Config: library_path = None |