summaryrefslogtreecommitdiffstats
path: root/bindings/python/clang/cindex.py
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/python/clang/cindex.py')
-rw-r--r--bindings/python/clang/cindex.py1759
1 files changed, 1238 insertions, 521 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 6f0d25f..fc0a2a1 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -65,6 +65,8 @@ call is efficient.
from ctypes import *
import collections
+import clang.enumerations
+
def get_cindex_library():
# FIXME: It's probably not the case that the library is actually found in
# this location. We need a better system of identifying and loading the
@@ -85,6 +87,49 @@ def get_cindex_library():
c_object_p = POINTER(c_void_p)
lib = get_cindex_library()
+callbacks = {}
+
+### Exception Classes ###
+
+class TranslationUnitLoadError(Exception):
+ """Represents an error that occurred when loading a TranslationUnit.
+
+ This is raised in the case where a TranslationUnit could not be
+ instantiated due to failure in the libclang library.
+
+ FIXME: Make libclang expose additional error information in this scenario.
+ """
+ pass
+
+class TranslationUnitSaveError(Exception):
+ """Represents an error that occurred when saving a TranslationUnit.
+
+ Each error has associated with it an enumerated value, accessible under
+ e.save_error. Consumers can compare the value with one of the ERROR_
+ constants in this class.
+ """
+
+ # Indicates that an unknown error occurred. This typically indicates that
+ # I/O failed during save.
+ ERROR_UNKNOWN = 1
+
+ # Indicates that errors during translation prevented saving. The errors
+ # should be available via the TranslationUnit's diagnostics.
+ ERROR_TRANSLATION_ERRORS = 2
+
+ # Indicates that the translation unit was somehow invalid.
+ ERROR_INVALID_TU = 3
+
+ def __init__(self, enumeration, message):
+ assert isinstance(enumeration, int)
+
+ if enumeration < 1 or enumeration > 3:
+ raise Exception("Encountered undefined TranslationUnit save error "
+ "constant: %d. Please file a bug to have this "
+ "value supported." % enumeration)
+
+ self.save_error = enumeration
+ Exception.__init__(self, 'Error %d: %s' % (enumeration, message))
### Structures and Utility Classes ###
@@ -94,12 +139,12 @@ class _CXString(Structure):
_fields_ = [("spelling", c_char_p), ("free", c_int)]
def __del__(self):
- _CXString_dispose(self)
+ lib.clang_disposeString(self)
@staticmethod
def from_result(res, fn, args):
assert isinstance(res, _CXString)
- return _CXString_getCString(res)
+ return lib.clang_getCString(res)
class SourceLocation(Structure):
"""
@@ -111,7 +156,8 @@ class SourceLocation(Structure):
def _get_instantiation(self):
if self._data is None:
f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
- SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
+ lib.clang_getInstantiationLocation(self, byref(f), byref(l),
+ byref(c), byref(o))
if f:
f = File(f)
else:
@@ -125,7 +171,17 @@ class SourceLocation(Structure):
Retrieve the source location associated with a given file/line/column in
a particular translation unit.
"""
- return SourceLocation_getLocation(tu, file, line, column)
+ return lib.clang_getLocation(tu, file, line, column)
+
+ @staticmethod
+ def from_offset(tu, file, offset):
+ """Retrieve a SourceLocation from a given character offset.
+
+ tu -- TranslationUnit file belongs to
+ file -- File instance to obtain offset from
+ offset -- Integer character offset within file
+ """
+ return lib.clang_getLocationForOffset(tu, file, offset)
@property
def file(self):
@@ -148,7 +204,7 @@ class SourceLocation(Structure):
return self._get_instantiation()[3]
def __eq__(self, other):
- return SourceLocation_equalLocations(self, other)
+ return lib.clang_equalLocations(self, other)
def __ne__(self, other):
return not self.__eq__(other)
@@ -175,7 +231,7 @@ class SourceRange(Structure):
# object.
@staticmethod
def from_locations(start, end):
- return SourceRange_getRange(start, end)
+ return lib.clang_getRange(start, end)
@property
def start(self):
@@ -183,7 +239,7 @@ class SourceRange(Structure):
Return a SourceLocation representing the first character within a
source range.
"""
- return SourceRange_start(self)
+ return lib.clang_getRangeStart(self)
@property
def end(self):
@@ -191,10 +247,10 @@ class SourceRange(Structure):
Return a SourceLocation representing the last character within a
source range.
"""
- return SourceRange_end(self)
+ return lib.clang_getRangeEnd(self)
def __eq__(self, other):
- return SourceRange_equalRanges(self, other)
+ return lib.clang_equalRanges(self, other)
def __ne__(self, other):
return not self.__eq__(other)
@@ -219,19 +275,19 @@ class Diagnostic(object):
self.ptr = ptr
def __del__(self):
- _clang_disposeDiagnostic(self)
+ lib.clang_disposeDiagnostic(self)
@property
def severity(self):
- return _clang_getDiagnosticSeverity(self)
+ return lib.clang_getDiagnosticSeverity(self)
@property
def location(self):
- return _clang_getDiagnosticLocation(self)
+ return lib.clang_getDiagnosticLocation(self)
@property
def spelling(self):
- return _clang_getDiagnosticSpelling(self)
+ return lib.clang_getDiagnosticSpelling(self)
@property
def ranges(self):
@@ -240,12 +296,12 @@ class Diagnostic(object):
self.diag = diag
def __len__(self):
- return int(_clang_getDiagnosticNumRanges(self.diag))
+ return int(lib.clang_getDiagnosticNumRanges(self.diag))
def __getitem__(self, key):
if (key >= len(self)):
raise IndexError
- return _clang_getDiagnosticRange(self.diag, key)
+ return lib.clang_getDiagnosticRange(self.diag, key)
return RangeIterator(self)
@@ -256,11 +312,12 @@ class Diagnostic(object):
self.diag = diag
def __len__(self):
- return int(_clang_getDiagnosticNumFixIts(self.diag))
+ return int(lib.clang_getDiagnosticNumFixIts(self.diag))
def __getitem__(self, key):
range = SourceRange()
- value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
+ value = lib.clang_getDiagnosticFixIt(self.diag, key,
+ byref(range))
if len(value) == 0:
raise IndexError
@@ -271,25 +328,25 @@ class Diagnostic(object):
@property
def category_number(self):
"""The category number for this diagnostic."""
- return _clang_getDiagnosticCategory(self)
+ return lib.clang_getDiagnosticCategory(self)
@property
def category_name(self):
"""The string name of the category for this diagnostic."""
- return _clang_getDiagnosticCategoryName(self.category_number)
+ return lib.clang_getDiagnosticCategoryName(self.category_number)
@property
def option(self):
"""The command-line option that enables this diagnostic."""
- return _clang_getDiagnosticOption(self, None)
+ return lib.clang_getDiagnosticOption(self, None)
@property
def disable_option(self):
"""The command-line option that disables this diagnostic."""
disable = _CXString()
- _clang_getDiagnosticOption(self, byref(disable))
+ lib.clang_getDiagnosticOption(self, byref(disable))
- return _CXString_getCString(disable)
+ return lib.clang_getCString(disable)
def __repr__(self):
return "<Diagnostic severity %r, location %r, spelling %r>" % (
@@ -312,6 +369,98 @@ class FixIt(object):
def __repr__(self):
return "<FixIt range %r, value %r>" % (self.range, self.value)
+class TokenGroup(object):
+ """Helper class to facilitate token management.
+
+ Tokens are allocated from libclang in chunks. They must be disposed of as a
+ collective group.
+
+ One purpose of this class is for instances to represent groups of allocated
+ tokens. Each token in a group contains a reference back to an instance of
+ this class. When all tokens from a group are garbage collected, it allows
+ this class to be garbage collected. When this class is garbage collected,
+ it calls the libclang destructor which invalidates all tokens in the group.
+
+ You should not instantiate this class outside of this module.
+ """
+ def __init__(self, tu, memory, count):
+ self._tu = tu
+ self._memory = memory
+ self._count = count
+
+ def __del__(self):
+ lib.clang_disposeTokens(self._tu, self._memory, self._count)
+
+ @staticmethod
+ def get_tokens(tu, extent):
+ """Helper method to return all tokens in an extent.
+
+ This functionality is needed multiple places in this module. We define
+ it here because it seems like a logical place.
+ """
+ tokens_memory = POINTER(Token)()
+ tokens_count = c_uint()
+
+ lib.clang_tokenize(tu, extent, byref(tokens_memory),
+ byref(tokens_count))
+
+ count = int(tokens_count.value)
+
+ # If we get no tokens, no memory was allocated. Be sure not to return
+ # anything and potentially call a destructor on nothing.
+ if count < 1:
+ return
+
+ tokens_array = cast(tokens_memory, POINTER(Token * count)).contents
+
+ token_group = TokenGroup(tu, tokens_memory, tokens_count)
+
+ for i in xrange(0, count):
+ token = Token()
+ token.int_data = tokens_array[i].int_data
+ token.ptr_data = tokens_array[i].ptr_data
+ token._tu = tu
+ token._group = token_group
+
+ yield token
+
+class TokenKind(object):
+ """Describes a specific type of a Token."""
+
+ _value_map = {} # int -> TokenKind
+
+ def __init__(self, value, name):
+ """Create a new TokenKind instance from a numeric value and a name."""
+ self.value = value
+ self.name = name
+
+ def __repr__(self):
+ return 'TokenKind.%s' % (self.name,)
+
+ @staticmethod
+ def from_value(value):
+ """Obtain a registered TokenKind instance from its value."""
+ result = TokenKind._value_map.get(value, None)
+
+ if result is None:
+ raise ValueError('Unknown TokenKind: %d' % value)
+
+ return result
+
+ @staticmethod
+ def register(value, name):
+ """Register a new TokenKind enumeration.
+
+ This should only be called at module load time by code within this
+ package.
+ """
+ if value in TokenKind._value_map:
+ raise ValueError('TokenKind already registered: %d' % value)
+
+ kind = TokenKind(value, name)
+ TokenKind._value_map[value] = kind
+ setattr(TokenKind, name, kind)
+
### Cursor Kinds ###
class CursorKind(object):
@@ -358,39 +507,39 @@ class CursorKind(object):
def is_declaration(self):
"""Test if this is a declaration kind."""
- return CursorKind_is_decl(self)
+ return lib.clang_isDeclaration(self)
def is_reference(self):
"""Test if this is a reference kind."""
- return CursorKind_is_ref(self)
+ return lib.clang_isReference(self)
def is_expression(self):
"""Test if this is an expression kind."""
- return CursorKind_is_expr(self)
+ return lib.clang_isExpression(self)
def is_statement(self):
"""Test if this is a statement kind."""
- return CursorKind_is_stmt(self)
+ return lib.clang_isStatement(self)
def is_attribute(self):
"""Test if this is an attribute kind."""
- return CursorKind_is_attribute(self)
+ return lib.clang_isAttribute(self)
def is_invalid(self):
"""Test if this is an invalid kind."""
- return CursorKind_is_inv(self)
+ return lib.clang_isInvalid(self)
def is_translation_unit(self):
"""Test if this is a translation unit kind."""
- return CursorKind_is_translation_unit(self)
+ return lib.clang_isTranslationUnit(self)
def is_preprocessing(self):
"""Test if this is a preprocessing kind."""
- return CursorKind_is_preprocessing(self)
+ return lib.clang_isPreprocessing(self)
def is_unexposed(self):
"""Test if this is an unexposed kind."""
- return CursorKind_is_unexposed(self)
+ return lib.clang_isUnexposed(self)
def __repr__(self):
return 'CursorKind.%s' % (self.name,)
@@ -635,7 +784,7 @@ CursorKind.BINARY_OPERATOR = CursorKind(114)
CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
# The ?: ternary operator.
-CursorKind.CONDITONAL_OPERATOR = CursorKind(116)
+CursorKind.CONDITIONAL_OPERATOR = CursorKind(116)
# An explicit cast in C (C99 6.5.4) or a C-style cast in C++
# (C++ [expr.cast]), which uses the syntax (Type)expr.
@@ -887,10 +1036,15 @@ class Cursor(Structure):
@staticmethod
def from_location(tu, location):
- return Cursor_get(tu, location)
+ # We store a reference to the TU in the instance so the TU won't get
+ # collected before the cursor.
+ cursor = lib.clang_getCursor(tu, location)
+ cursor._tu = tu
+
+ return cursor
def __eq__(self, other):
- return Cursor_eq(self, other)
+ return lib.clang_equalCursors(self, other)
def __ne__(self, other):
return not self.__eq__(other)
@@ -900,7 +1054,13 @@ class Cursor(Structure):
Returns true if the declaration pointed at by the cursor is also a
definition of that entity.
"""
- return Cursor_is_def(self)
+ return lib.clang_isCursorDefinition(self)
+
+ def is_static_method(self):
+ """Returns True if the cursor refers to a C++ member function or member
+ function template that is declared 'static'.
+ """
+ return lib.clang_CXXMethod_isStatic(self)
def get_definition(self):
"""
@@ -910,7 +1070,7 @@ class Cursor(Structure):
"""
# TODO: Should probably check that this is either a reference or
# declaration prior to issuing the lookup.
- return Cursor_def(self)
+ return lib.clang_getCursorDefinition(self)
def get_usr(self):
"""Return the Unified Symbol Resultion (USR) for the entity referenced
@@ -921,7 +1081,7 @@ class Cursor(Structure):
program. USRs can be compared across translation units to determine,
e.g., when references in one translation refer to an entity defined in
another translation unit."""
- return Cursor_usr(self)
+ return lib.clang_getCursorUSR(self)
@property
def kind(self):
@@ -936,7 +1096,8 @@ class Cursor(Structure):
# this, for consistency with clang_getCursorUSR.
return None
if not hasattr(self, '_spelling'):
- self._spelling = Cursor_spelling(self)
+ self._spelling = lib.clang_getCursorSpelling(self)
+
return self._spelling
@property
@@ -949,7 +1110,8 @@ class Cursor(Structure):
class template specialization.
"""
if not hasattr(self, '_displayname'):
- self._displayname = Cursor_displayname(self)
+ self._displayname = lib.clang_getCursorDisplayName(self)
+
return self._displayname
@property
@@ -959,7 +1121,8 @@ class Cursor(Structure):
pointed at by the cursor.
"""
if not hasattr(self, '_loc'):
- self._loc = Cursor_loc(self)
+ self._loc = lib.clang_getCursorLocation(self)
+
return self._loc
@property
@@ -969,7 +1132,8 @@ class Cursor(Structure):
pointed at by the cursor.
"""
if not hasattr(self, '_extent'):
- self._extent = Cursor_extent(self)
+ self._extent = lib.clang_getCursorExtent(self)
+
return self._extent
@property
@@ -978,10 +1142,33 @@ class Cursor(Structure):
Retrieve the Type (if any) of the entity pointed at by the cursor.
"""
if not hasattr(self, '_type'):
- self._type = Cursor_type(self)
+ self._type = lib.clang_getCursorType(self)
+
return self._type
@property
+ def canonical(self):
+ """Return the canonical Cursor corresponding to this Cursor.
+
+ The canonical cursor is the cursor which is representative for the
+ underlying entity. For example, if you have multiple forward
+ declarations for the same class, the canonical cursor for the forward
+ declarations will be identical.
+ """
+ if not hasattr(self, '_canonical'):
+ self._canonical = lib.clang_getCanonicalCursor(self)
+
+ return self._canonical
+
+ @property
+ def result_type(self):
+ """Retrieve the Type of the result for this Cursor."""
+ if not hasattr(self, '_result_type'):
+ self._result_type = lib.clang_getResultType(self.type)
+
+ return self._result_type
+
+ @property
def underlying_typedef_type(self):
"""Return the underlying type of a typedef declaration.
@@ -990,7 +1177,7 @@ class Cursor(Structure):
"""
if not hasattr(self, '_underlying_type'):
assert self.kind.is_declaration()
- self._underlying_type = Cursor_underlying_type(self)
+ self._underlying_type = lib.clang_getTypedefDeclUnderlyingType(self)
return self._underlying_type
@@ -1003,15 +1190,39 @@ class Cursor(Structure):
"""
if not hasattr(self, '_enum_type'):
assert self.kind == CursorKind.ENUM_DECL
- self._enum_type = Cursor_enum_type(self)
+ self._enum_type = lib.clang_getEnumDeclIntegerType(self)
return self._enum_type
@property
+ def enum_value(self):
+ """Return the value of an enum constant."""
+ if not hasattr(self, '_enum_value'):
+ assert self.kind == CursorKind.ENUM_CONSTANT_DECL
+ # Figure out the underlying type of the enum to know if it
+ # is a signed or unsigned quantity.
+ underlying_type = self.type
+ if underlying_type.kind == TypeKind.ENUM:
+ underlying_type = underlying_type.get_declaration().enum_type
+ if underlying_type.kind in (TypeKind.CHAR_U,
+ TypeKind.UCHAR,
+ TypeKind.CHAR16,
+ TypeKind.CHAR32,
+ TypeKind.USHORT,
+ TypeKind.UINT,
+ TypeKind.ULONG,
+ TypeKind.ULONGLONG,
+ TypeKind.UINT128):
+ self._enum_value = lib.clang_getEnumConstantDeclUnsignedValue(self)
+ else:
+ self._enum_value = lib.clang_getEnumConstantDeclValue(self)
+ return self._enum_value
+
+ @property
def objc_type_encoding(self):
"""Return the Objective-C type encoding as a str."""
if not hasattr(self, '_objc_type_encoding'):
- self._objc_type_encoding = Cursor_objc_type_encoding(self)
+ self._objc_type_encoding = lib.clang_getDeclObjCTypeEncoding(self)
return self._objc_type_encoding
@@ -1019,10 +1230,33 @@ class Cursor(Structure):
def hash(self):
"""Returns a hash of the cursor as an int."""
if not hasattr(self, '_hash'):
- self._hash = Cursor_hash(self)
+ self._hash = lib.clang_hashCursor(self)
return self._hash
+ @property
+ def semantic_parent(self):
+ """Return the semantic parent for this cursor."""
+ if not hasattr(self, '_semantic_parent'):
+ self._semantic_parent = lib.clang_getCursorSemanticParent(self)
+
+ return self._semantic_parent
+
+ @property
+ def lexical_parent(self):
+ """Return the lexical parent for this cursor."""
+ if not hasattr(self, '_lexical_parent'):
+ self._lexical_parent = lib.clang_getCursorLexicalParent(self)
+
+ return self._lexical_parent
+
+ @property
+ def translation_unit(self):
+ """Returns the TranslationUnit to which this Cursor belongs."""
+ # If this triggers an AttributeError, the instance was not properly
+ # created.
+ return self._tu
+
def get_children(self):
"""Return an iterator for accessing the children of this cursor."""
@@ -1030,21 +1264,57 @@ class Cursor(Structure):
def visitor(child, parent, children):
# FIXME: Document this assertion in API.
# FIXME: There should just be an isNull method.
- assert child != Cursor_null()
+ assert child != lib.clang_getNullCursor()
+
+ # Create reference to TU so it isn't GC'd before Cursor.
+ child._tu = self._tu
children.append(child)
return 1 # continue
children = []
- Cursor_visit(self, Cursor_visit_callback(visitor), children)
+ lib.clang_visitChildren(self, callbacks['cursor_visit'](visitor),
+ children)
return iter(children)
+ def get_tokens(self):
+ """Obtain Token instances formulating that compose this Cursor.
+
+ This is a generator for Token instances. It returns all tokens which
+ occupy the extent this cursor occupies.
+ """
+ return TokenGroup.get_tokens(self._tu, self.extent)
+
@staticmethod
def from_result(res, fn, args):
assert isinstance(res, Cursor)
# FIXME: There should just be an isNull method.
- if res == Cursor_null():
+ if res == lib.clang_getNullCursor():
return None
+
+ # Store a reference to the TU in the Python object so it won't get GC'd
+ # before the Cursor.
+ tu = None
+ for arg in args:
+ if isinstance(arg, TranslationUnit):
+ tu = arg
+ break
+
+ if hasattr(arg, 'translation_unit'):
+ tu = arg.translation_unit
+ break
+
+ assert tu is not None
+
+ res._tu = tu
return res
+ @staticmethod
+ def from_cursor_result(res, fn, args):
+ assert isinstance(res, Cursor)
+ if res == lib.clang_getNullCursor():
+ return None
+
+ res._tu = args[0]._tu
+ return res
### Type Kinds ###
@@ -1082,7 +1352,7 @@ class TypeKind(object):
@property
def spelling(self):
"""Retrieve the spelling of this TypeKind."""
- return TypeKind_spelling(self.value)
+ return lib.clang_getTypeKindSpelling(self.value)
@staticmethod
def from_id(id):
@@ -1093,12 +1363,6 @@ class TypeKind(object):
def __repr__(self):
return 'TypeKind.%s' % (self.name,)
-TypeKind_spelling = lib.clang_getTypeKindSpelling
-TypeKind_spelling.argtypes = [c_uint]
-TypeKind_spelling.restype = _CXString
-TypeKind_spelling.errcheck = _CXString.from_result
-
-
TypeKind.INVALID = TypeKind(0)
TypeKind.UNEXPOSED = TypeKind(1)
TypeKind.VOID = TypeKind(2)
@@ -1168,7 +1432,7 @@ class Type(Structure):
def __len__(self):
if self.length is None:
- self.length = Type_get_num_arg_types(self.parent)
+ self.length = lib.clang_getNumArgTypes(self.parent)
return self.length
@@ -1184,7 +1448,7 @@ class Type(Structure):
raise IndexError("Index greater than container length: "
"%d > %d" % ( key, len(self) ))
- result = Type_get_arg_type(self.parent, key)
+ result = lib.clang_getArgType(self.parent, key)
if result.kind == TypeKind.INVALID:
raise IndexError("Argument could not be retrieved.")
@@ -1200,7 +1464,7 @@ class Type(Structure):
If accessed on a type that is not an array, complex, or vector type, an
exception will be raised.
"""
- result = Type_get_element_type(self)
+ result = lib.clang_getElementType(self)
if result.kind == TypeKind.INVALID:
raise Exception('Element type not available on this type.')
@@ -1214,15 +1478,32 @@ class Type(Structure):
If the Type is not an array or vector, this raises.
"""
- result = Type_get_num_elements(self)
+ result = lib.clang_getNumElements(self)
if result < 0:
raise Exception('Type does not have elements.')
return result
+ @property
+ def translation_unit(self):
+ """The TranslationUnit to which this Type is associated."""
+ # If this triggers an AttributeError, the instance was not properly
+ # instantiated.
+ return self._tu
+
@staticmethod
def from_result(res, fn, args):
assert isinstance(res, Type)
+
+ tu = None
+ for arg in args:
+ if hasattr(arg, 'translation_unit'):
+ tu = arg.translation_unit
+ break
+
+ assert tu is not None
+ res._tu = tu
+
return res
def get_canonical(self):
@@ -1235,7 +1516,7 @@ class Type(Structure):
example, if 'T' is a typedef for 'int', the canonical type for
'T' would be 'int'.
"""
- return Type_get_canonical(self)
+ return lib.clang_getCanonicalType(self)
def is_const_qualified(self):
"""Determine whether a Type has the "const" qualifier set.
@@ -1243,7 +1524,7 @@ class Type(Structure):
This does not look through typedefs that may have added "const"
at a different level.
"""
- return Type_is_const_qualified(self)
+ return lib.clang_isConstQualifiedType(self)
def is_volatile_qualified(self):
"""Determine whether a Type has the "volatile" qualifier set.
@@ -1251,7 +1532,7 @@ class Type(Structure):
This does not look through typedefs that may have added "volatile"
at a different level.
"""
- return Type_is_volatile_qualified(self)
+ return lib.clang_isVolatileQualifiedType(self)
def is_restrict_qualified(self):
"""Determine whether a Type has the "restrict" qualifier set.
@@ -1259,53 +1540,53 @@ class Type(Structure):
This does not look through typedefs that may have added "restrict" at
a different level.
"""
- return Type_is_restrict_qualified(self)
+ return lib.clang_isRestrictQualifiedType(self)
def is_function_variadic(self):
"""Determine whether this function Type is a variadic function type."""
assert self.kind == TypeKind.FUNCTIONPROTO
- return Type_is_variadic(self)
+ return lib.clang_isFunctionTypeVariadic(self)
def is_pod(self):
"""Determine whether this Type represents plain old data (POD)."""
- return Type_is_pod(self)
+ return lib.clang_isPODType(self)
def get_pointee(self):
"""
For pointer types, returns the type of the pointee.
"""
- return Type_get_pointee(self)
+ return lib.clang_getPointeeType(self)
def get_declaration(self):
"""
Return the cursor for the declaration of the given type.
"""
- return Type_get_declaration(self)
+ return lib.clang_getTypeDeclaration(self)
def get_result(self):
"""
Retrieve the result type associated with a function type.
"""
- return Type_get_result(self)
+ return lib.clang_getResultType(self)
def get_array_element_type(self):
"""
Retrieve the type of the elements of the array type.
"""
- return Type_get_array_element(self)
+ return lib.clang_getArrayElementType(self)
def get_array_size(self):
"""
Retrieve the size of the constant array.
"""
- return Type_get_array_size(self)
+ return lib.clang_getArraySize(self)
def __eq__(self, other):
if type(other) != type(self):
return False
- return Type_equal(self, other)
+ return lib.clang_equalTypes(self, other)
def __ne__(self, other):
return not self.__eq__(other)
@@ -1333,65 +1614,6 @@ class _CXUnsavedFile(Structure):
"""Helper for passing unsaved file arguments."""
_fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
-## Diagnostic Conversion ##
-
-_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
-_clang_getNumDiagnostics.argtypes = [c_object_p]
-_clang_getNumDiagnostics.restype = c_uint
-
-_clang_getDiagnostic = lib.clang_getDiagnostic
-_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
-_clang_getDiagnostic.restype = c_object_p
-
-_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
-_clang_disposeDiagnostic.argtypes = [Diagnostic]
-
-_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
-_clang_getDiagnosticSeverity.argtypes = [Diagnostic]
-_clang_getDiagnosticSeverity.restype = c_int
-
-_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
-_clang_getDiagnosticLocation.argtypes = [Diagnostic]
-_clang_getDiagnosticLocation.restype = SourceLocation
-
-_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
-_clang_getDiagnosticSpelling.argtypes = [Diagnostic]
-_clang_getDiagnosticSpelling.restype = _CXString
-_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
-
-_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
-_clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
-_clang_getDiagnosticNumRanges.restype = c_uint
-
-_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
-_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
-_clang_getDiagnosticRange.restype = SourceRange
-
-_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
-_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
-_clang_getDiagnosticNumFixIts.restype = c_uint
-
-_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
-_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
-_clang_getDiagnosticFixIt.restype = _CXString
-_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
-
-_clang_getDiagnosticCategory = lib.clang_getDiagnosticCategory
-_clang_getDiagnosticCategory.argtypes = [Diagnostic]
-_clang_getDiagnosticCategory.restype = c_uint
-
-_clang_getDiagnosticCategoryName = lib.clang_getDiagnosticCategoryName
-_clang_getDiagnosticCategoryName.argtypes = [c_uint]
-_clang_getDiagnosticCategoryName.restype = _CXString
-_clang_getDiagnosticCategoryName.errcheck = _CXString.from_result
-
-_clang_getDiagnosticOption = lib.clang_getDiagnosticOption
-_clang_getDiagnosticOption.argtypes = [Diagnostic, POINTER(_CXString)]
-_clang_getDiagnosticOption.restype = _CXString
-_clang_getDiagnosticOption.errcheck = _CXString.from_result
-
-###
-
class CompletionChunk:
class Kind:
def __init__(self, name):
@@ -1412,16 +1634,16 @@ class CompletionChunk:
@property
def spelling(self):
- return _clang_getCompletionChunkText(self.cs, self.key).spelling
+ return lib.clang_getCompletionChunkText(self.cs, self.key).spelling
@property
def kind(self):
- res = _clang_getCompletionChunkKind(self.cs, self.key)
+ res = lib.clang_getCompletionChunkKind(self.cs, self.key)
return completionChunkKindMap[res]
@property
def string(self):
- res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
+ res = lib.clang_getCompletionChunkCompletionString(self.cs, self.key)
if (res):
return CompletionString(res)
@@ -1478,7 +1700,7 @@ class CompletionString(ClangObject):
return "<Availability: %s>" % self
def __len__(self):
- return _clang_getNumCompletionChunks(self.obj)
+ return lib.clang_getNumCompletionChunks(self.obj)
def __getitem__(self, key):
if len(self) <= key:
@@ -1487,11 +1709,11 @@ class CompletionString(ClangObject):
@property
def priority(self):
- return _clang_getCompletionPriority(self.obj)
+ return lib.clang_getCompletionPriority(self.obj)
@property
def availability(self):
- res = _clang_getCompletionAvailability(self.obj)
+ res = lib.clang_getCompletionAvailability(self.obj)
return availabilityKinds[res]
def __repr__(self):
@@ -1553,10 +1775,10 @@ class CodeCompletionResults(ClangObject):
self.ccr= ccr
def __len__(self):
- return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
+ return int(lib.clang_codeCompleteGetNumDiagnostics(self.ccr))
def __getitem__(self, key):
- return _clang_codeCompleteGetDiagnostic(self.ccr, key)
+ return lib.clang_codeCompleteGetDiagnostic(self.ccr, key)
return DiagnosticsItr(self)
@@ -1575,21 +1797,17 @@ class Index(ClangObject):
Parameters:
excludeDecls -- Exclude local declarations from translation units.
"""
- return Index(Index_create(excludeDecls, 0))
+ return Index(lib.clang_createIndex(excludeDecls, 0))
def __del__(self):
- Index_dispose(self)
+ lib.clang_disposeIndex(self)
def read(self, path):
- """Load the translation unit from the given AST file."""
- ptr = TranslationUnit_read(self, path)
- if ptr:
- return TranslationUnit(ptr)
- return None
+ """Load a TranslationUnit from the given AST file."""
+ return TranslationUnit.from_ast(path, self)
- def parse(self, path, args = [], unsaved_files = [], options = 0):
- """
- Load the translation unit from the given source code file by running
+ def parse(self, path, args=None, unsaved_files=None, options = 0):
+ """Load the translation unit from the given source code file by running
clang and generating the AST before loading. Additional command line
parameters can be passed to clang via the args parameter.
@@ -1597,53 +1815,167 @@ class Index(ClangObject):
to as unsaved_files, the first item should be the filenames to be mapped
and the second should be the contents to be substituted for the
file. The contents may be passed as strings or file objects.
- """
- arg_array = 0
- if len(args):
- arg_array = (c_char_p * len(args))(* args)
- unsaved_files_array = 0
- if len(unsaved_files):
- unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
- for i,(name,value) in enumerate(unsaved_files):
- if not isinstance(value, str):
- # FIXME: It would be great to support an efficient version
- # of this, one day.
- value = value.read()
- 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
- unsaved_files_array[i].length = len(value)
- ptr = TranslationUnit_parse(self, path, arg_array, len(args),
- unsaved_files_array, len(unsaved_files),
- options)
- if ptr:
- return TranslationUnit(ptr)
- return None
+ If an error was encountered during parsing, a TranslationUnitLoadError
+ will be raised.
+ """
+ return TranslationUnit.from_source(path, args, unsaved_files, options,
+ self)
class TranslationUnit(ClangObject):
- """
- The TranslationUnit class represents a source code translation unit and
- provides read-only access to its top-level declarations.
+ """Represents a source code translation unit.
+
+ This is one of the main types in the API. Any time you wish to interact
+ with Clang's representation of a source file, you typically start with a
+ translation unit.
"""
- def __init__(self, ptr):
+ # Default parsing mode.
+ PARSE_NONE = 0
+
+ # Instruct the parser to create a detailed processing record containing
+ # metadata not normally retained.
+ PARSE_DETAILED_PROCESSING_RECORD = 1
+
+ # Indicates that the translation unit is incomplete. This is typically used
+ # when parsing headers.
+ PARSE_INCOMPLETE = 2
+
+ # Instruct the parser to create a pre-compiled preamble for the translation
+ # unit. This caches the preamble (included files at top of source file).
+ # This is useful if the translation unit will be reparsed and you don't
+ # want to incur the overhead of reparsing the preamble.
+ PARSE_PRECOMPILED_PREAMBLE = 4
+
+ # Cache code completion information on parse. This adds time to parsing but
+ # speeds up code completion.
+ PARSE_CACHE_COMPLETION_RESULTS = 8
+
+ # Flags with values 16 and 32 are deprecated and intentionally omitted.
+
+ # Do not parse function bodies. This is useful if you only care about
+ # searching for declarations/definitions.
+ PARSE_SKIP_FUNCTION_BODIES = 64
+
+ @classmethod
+ def from_source(cls, filename, args=None, unsaved_files=None, options=0,
+ index=None):
+ """Create a TranslationUnit by parsing source.
+
+ This is capable of processing source code both from files on the
+ filesystem as well as in-memory contents.
+
+ Command-line arguments that would be passed to clang are specified as
+ a list via args. These can be used to specify include paths, warnings,
+ etc. e.g. ["-Wall", "-I/path/to/include"].
+
+ In-memory file content can be provided via unsaved_files. This is an
+ iterable of 2-tuples. The first element is the str filename. The
+ second element defines the content. Content can be provided as str
+ source code or as file objects (anything with a read() method). If
+ a file object is being used, content will be read until EOF and the
+ read cursor will not be reset to its original position.
+
+ options is a bitwise or of TranslationUnit.PARSE_XXX flags which will
+ control parsing behavior.
+
+ index is an Index instance to utilize. If not provided, a new Index
+ will be created for this TranslationUnit.
+
+ To parse source from the filesystem, the filename of the file to parse
+ is specified by the filename argument. Or, filename could be None and
+ the args list would contain the filename(s) to parse.
+
+ To parse source from an in-memory buffer, set filename to the virtual
+ filename you wish to associate with this source (e.g. "test.c"). The
+ contents of that file are then provided in unsaved_files.
+
+ If an error occurs, a TranslationUnitLoadError is raised.
+
+ Please note that a TranslationUnit with parser errors may be returned.
+ It is the caller's responsibility to check tu.diagnostics for errors.
+
+ Also note that Clang infers the source language from the extension of
+ the input filename. If you pass in source code containing a C++ class
+ declaration with the filename "test.c" parsing will fail.
+ """
+ if args is None:
+ args = []
+
+ if unsaved_files is None:
+ unsaved_files = []
+
+ if index is None:
+ index = Index.create()
+
+ args_array = None
+ if len(args) > 0:
+ args_array = (c_char_p * len(args))(* args)
+
+ unsaved_array = None
+ if len(unsaved_files) > 0:
+ unsaved_array = (_CXUnsavedFile * len(unsaved_files))()
+ for i, (name, contents) in enumerate(unsaved_files):
+ if hasattr(contents, "read"):
+ contents = contents.read()
+
+ unsaved_array[i].name = name
+ unsaved_array[i].contents = contents
+ unsaved_array[i].length = len(contents)
+
+ ptr = lib.clang_parseTranslationUnit(index, filename, args_array,
+ len(args), unsaved_array,
+ len(unsaved_files), options)
+
+ if ptr is None:
+ raise TranslationUnitLoadError("Error parsing translation unit.")
+
+ return cls(ptr, index=index)
+
+ @classmethod
+ def from_ast_file(cls, filename, index=None):
+ """Create a TranslationUnit instance from a saved AST file.
+
+ A previously-saved AST file (provided with -emit-ast or
+ TranslationUnit.save()) is loaded from the filename specified.
+
+ If the file cannot be loaded, a TranslationUnitLoadError will be
+ raised.
+
+ index is optional and is the Index instance to use. If not provided,
+ a default Index will be created.
+ """
+ if index is None:
+ index = Index.create()
+
+ ptr = lib.clang_createTranslationUnit(index, filename)
+ if ptr is None:
+ raise TranslationUnitLoadError(filename)
+
+ return cls(ptr=ptr, index=index)
+
+ def __init__(self, ptr, index):
+ """Create a TranslationUnit instance.
+
+ TranslationUnits should be created using one of the from_* @classmethod
+ functions above. __init__ is only called internally.
+ """
+ assert isinstance(index, Index)
+
ClangObject.__init__(self, ptr)
def __del__(self):
- TranslationUnit_dispose(self)
+ lib.clang_disposeTranslationUnit(self)
@property
def cursor(self):
"""Retrieve the cursor that represents the given translation unit."""
- return TranslationUnit_cursor(self)
+ return lib.clang_getTranslationUnitCursor(self)
@property
def spelling(self):
"""Get the original translation unit source file name."""
- return TranslationUnit_spelling(self)
+ return lib.clang_getTranslationUnitSpelling(self)
def get_includes(self):
"""
@@ -1660,11 +1992,72 @@ class TranslationUnit(ClangObject):
# Automatically adapt CIndex/ctype pointers to python objects
includes = []
- TranslationUnit_includes(self,
- TranslationUnit_includes_callback(visitor),
- includes)
+ lib.clang_getInclusions(self,
+ callbacks['translation_unit_includes'](visitor), includes)
+
return iter(includes)
+ def get_file(self, filename):
+ """Obtain a File from this translation unit."""
+
+ return File.from_name(self, filename)
+
+ def get_location(self, filename, position):
+ """Obtain a SourceLocation for a file in this translation unit.
+
+ The position can be specified by passing:
+
+ - Integer file offset. Initial file offset is 0.
+ - 2-tuple of (line number, column number). Initial file position is
+ (0, 0)
+ """
+ f = self.get_file(filename)
+
+ if isinstance(position, int):
+ return SourceLocation.from_offset(self, f, position)
+
+ return SourceLocation.from_position(self, f, position[0], position[1])
+
+ def get_extent(self, filename, locations):
+ """Obtain a SourceRange from this translation unit.
+
+ The bounds of the SourceRange must ultimately be defined by a start and
+ end SourceLocation. For the locations argument, you can pass:
+
+ - 2 SourceLocation instances in a 2-tuple or list.
+ - 2 int file offsets via a 2-tuple or list.
+ - 2 2-tuple or lists of (line, column) pairs in a 2-tuple or list.
+
+ e.g.
+
+ get_extent('foo.c', (5, 10))
+ get_extent('foo.c', ((1, 1), (1, 15)))
+ """
+ f = self.get_file(filename)
+
+ if len(locations) < 2:
+ raise Exception('Must pass object with at least 2 elements')
+
+ start_location, end_location = locations
+
+ if hasattr(start_location, '__len__'):
+ start_location = SourceLocation.from_position(self, f,
+ start_location[0], start_location[1])
+ elif isinstance(start_location, int):
+ start_location = SourceLocation.from_offset(self, f,
+ start_location)
+
+ if hasattr(end_location, '__len__'):
+ end_location = SourceLocation.from_position(self, f,
+ end_location[0], end_location[1])
+ elif isinstance(end_location, int):
+ end_location = SourceLocation.from_offset(self, f, end_location)
+
+ assert isinstance(start_location, SourceLocation)
+ assert isinstance(end_location, SourceLocation)
+
+ return SourceRange.from_locations(start_location, end_location)
+
@property
def diagnostics(self):
"""
@@ -1675,17 +2068,17 @@ class TranslationUnit(ClangObject):
self.tu = tu
def __len__(self):
- return int(_clang_getNumDiagnostics(self.tu))
+ return int(lib.clang_getNumDiagnostics(self.tu))
def __getitem__(self, key):
- diag = _clang_getDiagnostic(self.tu, key)
+ diag = lib.clang_getDiagnostic(self.tu, key)
if not diag:
raise IndexError
return Diagnostic(diag)
return DiagIterator(self)
- def reparse(self, unsaved_files = [], options = 0):
+ def reparse(self, unsaved_files=None, options=0):
"""
Reparse an already parsed translation unit.
@@ -1694,6 +2087,9 @@ class TranslationUnit(ClangObject):
and the second should be the contents to be substituted for the
file. The contents may be passed as strings or file objects.
"""
+ if unsaved_files is None:
+ unsaved_files = []
+
unsaved_files_array = 0
if len(unsaved_files):
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
@@ -1708,10 +2104,31 @@ class TranslationUnit(ClangObject):
unsaved_files_array[i].name = name
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
- ptr = TranslationUnit_reparse(self, len(unsaved_files),
- unsaved_files_array,
- options)
- def codeComplete(self, path, line, column, unsaved_files = [], options = 0):
+ ptr = lib.clang_reparseTranslationUnit(self, len(unsaved_files),
+ unsaved_files_array, options)
+
+ def save(self, filename):
+ """Saves the TranslationUnit to a file.
+
+ This is equivalent to passing -emit-ast to the clang frontend. The
+ saved file can be loaded back into a TranslationUnit. Or, if it
+ corresponds to a header, it can be used as a pre-compiled header file.
+
+ If an error occurs while saving, a TranslationUnitSaveError is raised.
+ If the error was TranslationUnitSaveError.ERROR_INVALID_TU, this means
+ the constructed TranslationUnit was not valid at time of save. In this
+ case, the reason(s) why should be available via
+ TranslationUnit.diagnostics().
+
+ filename -- The path to save the translation unit to.
+ """
+ options = lib.clang_defaultSaveOptions(self)
+ result = int(lib.clang_saveTranslationUnit(self, filename, options))
+ if result != 0:
+ raise TranslationUnitSaveError(result,
+ 'Error saving TranslationUnit.')
+
+ def codeComplete(self, path, line, column, unsaved_files=None, options=0):
"""
Code complete in this translation unit.
@@ -1720,6 +2137,9 @@ class TranslationUnit(ClangObject):
and the second should be the contents to be substituted for the
file. The contents may be passed as strings or file objects.
"""
+ if unsaved_files is None:
+ unsaved_files = []
+
unsaved_files_array = 0
if len(unsaved_files):
unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
@@ -1734,15 +2154,25 @@ class TranslationUnit(ClangObject):
unsaved_files_array[i].name = name
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
- ptr = TranslationUnit_codeComplete(self, path,
- line, column,
- unsaved_files_array,
- len(unsaved_files),
- options)
+ ptr = lib.clang_codeCompleteAt(self, path, line, column,
+ unsaved_files_array, len(unsaved_files), options)
if ptr:
return CodeCompletionResults(ptr)
return None
+ def get_tokens(self, locations=None, extent=None):
+ """Obtain tokens in this translation unit.
+
+ This is a generator for Token instances. The caller specifies a range
+ of source code to obtain tokens for. The range can be specified as a
+ 2-tuple of SourceLocation or as a SourceRange. If both are defined,
+ behavior is undefined.
+ """
+ if locations is not None:
+ extent = SourceRange(start=locations[0], end=locations[1])
+
+ return TokenGroup.get_tokens(self, extent)
+
class File(ClangObject):
"""
The File class represents a particular source file that is part of a
@@ -1752,17 +2182,17 @@ class File(ClangObject):
@staticmethod
def from_name(translation_unit, file_name):
"""Retrieve a file handle within the given translation unit."""
- return File(File_getFile(translation_unit, file_name))
+ return File(lib.clang_getFile(translation_unit, file_name))
@property
def name(self):
"""Return the complete file and path name of the file."""
- return _CXString_getCString(File_name(self))
+ return lib.clang_getCString(lib.clang_getFileName(self))
@property
def time(self):
"""Return the last modification time of the file."""
- return File_time(self)
+ return lib.clang_getFileTime(self)
def __str__(self):
return self.name
@@ -1770,6 +2200,14 @@ class File(ClangObject):
def __repr__(self):
return "<File: %s>" % (self.name)
+ @staticmethod
+ def from_cursor_result(res, fn, args):
+ assert isinstance(res, File)
+
+ # Copy a reference to the TranslationUnit to prevent premature GC.
+ res._tu = args[0]._tu
+ return res
+
class FileInclusion(object):
"""
The FileInclusion class represents the inclusion of one source file by
@@ -1790,337 +2228,616 @@ class FileInclusion(object):
"""True if the included file is the input file."""
return self.depth == 0
-# Additional Functions and Types
+class CompilationDatabaseError(Exception):
+ """Represents an error that occurred when working with a CompilationDatabase
-# String Functions
-_CXString_dispose = lib.clang_disposeString
-_CXString_dispose.argtypes = [_CXString]
+ Each error is associated to an enumerated value, accessible under
+ e.cdb_error. Consumers can compare the value with one of the ERROR_
+ constants in this class.
+ """
-_CXString_getCString = lib.clang_getCString
-_CXString_getCString.argtypes = [_CXString]
-_CXString_getCString.restype = c_char_p
+ # An unknown error occured
+ ERROR_UNKNOWN = 0
-# Source Location Functions
-SourceLocation_loc = lib.clang_getInstantiationLocation
-SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
- POINTER(c_uint), POINTER(c_uint),
- POINTER(c_uint)]
-
-SourceLocation_getLocation = lib.clang_getLocation
-SourceLocation_getLocation.argtypes = [TranslationUnit, File, c_uint, c_uint]
-SourceLocation_getLocation.restype = SourceLocation
-
-SourceLocation_equalLocations = lib.clang_equalLocations
-SourceLocation_equalLocations.argtypes = [SourceLocation, SourceLocation]
-SourceLocation_equalLocations.restype = bool
-
-# Source Range Functions
-SourceRange_getRange = lib.clang_getRange
-SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
-SourceRange_getRange.restype = SourceRange
-
-SourceRange_start = lib.clang_getRangeStart
-SourceRange_start.argtypes = [SourceRange]
-SourceRange_start.restype = SourceLocation
-
-SourceRange_end = lib.clang_getRangeEnd
-SourceRange_end.argtypes = [SourceRange]
-SourceRange_end.restype = SourceLocation
-
-SourceRange_equalRanges = lib.clang_equalRanges
-SourceRange_equalRanges.argtypes = [SourceRange, SourceRange]
-SourceRange_equalRanges.restype = bool
-
-# CursorKind Functions
-CursorKind_is_decl = lib.clang_isDeclaration
-CursorKind_is_decl.argtypes = [CursorKind]
-CursorKind_is_decl.restype = bool
-
-CursorKind_is_ref = lib.clang_isReference
-CursorKind_is_ref.argtypes = [CursorKind]
-CursorKind_is_ref.restype = bool
-
-CursorKind_is_expr = lib.clang_isExpression
-CursorKind_is_expr.argtypes = [CursorKind]
-CursorKind_is_expr.restype = bool
-
-CursorKind_is_stmt = lib.clang_isStatement
-CursorKind_is_stmt.argtypes = [CursorKind]
-CursorKind_is_stmt.restype = bool
-
-CursorKind_is_attribute = lib.clang_isAttribute
-CursorKind_is_attribute.argtypes = [CursorKind]
-CursorKind_is_attribute.restype = bool
-
-CursorKind_is_inv = lib.clang_isInvalid
-CursorKind_is_inv.argtypes = [CursorKind]
-CursorKind_is_inv.restype = bool
-
-CursorKind_is_translation_unit = lib.clang_isTranslationUnit
-CursorKind_is_translation_unit.argtypes = [CursorKind]
-CursorKind_is_translation_unit.restype = bool
-
-CursorKind_is_preprocessing = lib.clang_isPreprocessing
-CursorKind_is_preprocessing.argtypes = [CursorKind]
-CursorKind_is_preprocessing.restype = bool
-
-CursorKind_is_unexposed = lib.clang_isUnexposed
-CursorKind_is_unexposed.argtypes = [CursorKind]
-CursorKind_is_unexposed.restype = bool
-
-# Cursor Functions
-# TODO: Implement this function
-Cursor_get = lib.clang_getCursor
-Cursor_get.argtypes = [TranslationUnit, SourceLocation]
-Cursor_get.restype = Cursor
-
-Cursor_null = lib.clang_getNullCursor
-Cursor_null.restype = Cursor
-
-Cursor_usr = lib.clang_getCursorUSR
-Cursor_usr.argtypes = [Cursor]
-Cursor_usr.restype = _CXString
-Cursor_usr.errcheck = _CXString.from_result
-
-Cursor_is_def = lib.clang_isCursorDefinition
-Cursor_is_def.argtypes = [Cursor]
-Cursor_is_def.restype = bool
-
-Cursor_def = lib.clang_getCursorDefinition
-Cursor_def.argtypes = [Cursor]
-Cursor_def.restype = Cursor
-Cursor_def.errcheck = Cursor.from_result
-
-Cursor_eq = lib.clang_equalCursors
-Cursor_eq.argtypes = [Cursor, Cursor]
-Cursor_eq.restype = bool
-
-Cursor_hash = lib.clang_hashCursor
-Cursor_hash.argtypes = [Cursor]
-Cursor_hash.restype = c_uint
-
-Cursor_spelling = lib.clang_getCursorSpelling
-Cursor_spelling.argtypes = [Cursor]
-Cursor_spelling.restype = _CXString
-Cursor_spelling.errcheck = _CXString.from_result
-
-Cursor_displayname = lib.clang_getCursorDisplayName
-Cursor_displayname.argtypes = [Cursor]
-Cursor_displayname.restype = _CXString
-Cursor_displayname.errcheck = _CXString.from_result
-
-Cursor_loc = lib.clang_getCursorLocation
-Cursor_loc.argtypes = [Cursor]
-Cursor_loc.restype = SourceLocation
-
-Cursor_extent = lib.clang_getCursorExtent
-Cursor_extent.argtypes = [Cursor]
-Cursor_extent.restype = SourceRange
-
-Cursor_ref = lib.clang_getCursorReferenced
-Cursor_ref.argtypes = [Cursor]
-Cursor_ref.restype = Cursor
-Cursor_ref.errcheck = Cursor.from_result
-
-Cursor_type = lib.clang_getCursorType
-Cursor_type.argtypes = [Cursor]
-Cursor_type.restype = Type
-Cursor_type.errcheck = Type.from_result
-
-Cursor_underlying_type = lib.clang_getTypedefDeclUnderlyingType
-Cursor_underlying_type.argtypes = [Cursor]
-Cursor_underlying_type.restype = Type
-Cursor_underlying_type.errcheck = Type.from_result
-
-Cursor_enum_type = lib.clang_getEnumDeclIntegerType
-Cursor_enum_type.argtypes = [Cursor]
-Cursor_enum_type.restype = Type
-Cursor_enum_type.errcheck = Type.from_result
-
-Cursor_objc_type_encoding = lib.clang_getDeclObjCTypeEncoding
-Cursor_objc_type_encoding.argtypes = [Cursor]
-Cursor_objc_type_encoding.restype = _CXString
-Cursor_objc_type_encoding.errcheck = _CXString.from_result
-
-Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
-Cursor_visit = lib.clang_visitChildren
-Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
-Cursor_visit.restype = c_uint
-
-# Type Functions
-Type_get_canonical = lib.clang_getCanonicalType
-Type_get_canonical.argtypes = [Type]
-Type_get_canonical.restype = Type
-Type_get_canonical.errcheck = Type.from_result
-
-Type_is_const_qualified = lib.clang_isConstQualifiedType
-Type_is_const_qualified.argtypes = [Type]
-Type_is_const_qualified.restype = bool
-
-Type_is_volatile_qualified = lib.clang_isVolatileQualifiedType
-Type_is_volatile_qualified.argtypes = [Type]
-Type_is_volatile_qualified.restype = bool
-
-Type_is_restrict_qualified = lib.clang_isRestrictQualifiedType
-Type_is_restrict_qualified.argtypes = [Type]
-Type_is_restrict_qualified.restype = bool
-
-Type_is_pod = lib.clang_isPODType
-Type_is_pod.argtypes = [Type]
-Type_is_pod.restype = bool
-
-Type_is_variadic = lib.clang_isFunctionTypeVariadic
-Type_is_variadic.argtypes = [Type]
-Type_is_variadic.restype = bool
-
-Type_get_pointee = lib.clang_getPointeeType
-Type_get_pointee.argtypes = [Type]
-Type_get_pointee.restype = Type
-Type_get_pointee.errcheck = Type.from_result
-
-Type_get_declaration = lib.clang_getTypeDeclaration
-Type_get_declaration.argtypes = [Type]
-Type_get_declaration.restype = Cursor
-Type_get_declaration.errcheck = Cursor.from_result
-
-Type_get_result = lib.clang_getResultType
-Type_get_result.argtypes = [Type]
-Type_get_result.restype = Type
-Type_get_result.errcheck = Type.from_result
-
-Type_get_num_arg_types = lib.clang_getNumArgTypes
-Type_get_num_arg_types.argtypes = [Type]
-Type_get_num_arg_types.restype = c_uint
-
-Type_get_arg_type = lib.clang_getArgType
-Type_get_arg_type.argtypes = [Type, c_uint]
-Type_get_arg_type.restype = Type
-Type_get_arg_type.errcheck = Type.from_result
-Type_get_element_type = lib.clang_getElementType
-
-Type_get_element_type.argtypes = [Type]
-Type_get_element_type.restype = Type
-Type_get_element_type.errcheck = Type.from_result
-
-Type_get_num_elements = lib.clang_getNumElements
-Type_get_num_elements.argtypes = [Type]
-Type_get_num_elements.restype = c_longlong
-
-Type_get_array_element = lib.clang_getArrayElementType
-Type_get_array_element.argtypes = [Type]
-Type_get_array_element.restype = Type
-Type_get_array_element.errcheck = Type.from_result
-
-Type_get_array_size = lib.clang_getArraySize
-Type_get_array_size.argtype = [Type]
-Type_get_array_size.restype = c_longlong
-
-Type_equal = lib.clang_equalTypes
-Type_equal.argtypes = [Type, Type]
-Type_equal.restype = bool
-
-# Index Functions
-Index_create = lib.clang_createIndex
-Index_create.argtypes = [c_int, c_int]
-Index_create.restype = c_object_p
-
-Index_dispose = lib.clang_disposeIndex
-Index_dispose.argtypes = [Index]
-
-# Translation Unit Functions
-TranslationUnit_read = lib.clang_createTranslationUnit
-TranslationUnit_read.argtypes = [Index, c_char_p]
-TranslationUnit_read.restype = c_object_p
-
-TranslationUnit_parse = lib.clang_parseTranslationUnit
-TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
- c_int, c_void_p, c_int, c_int]
-TranslationUnit_parse.restype = c_object_p
-
-TranslationUnit_reparse = lib.clang_reparseTranslationUnit
-TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
-TranslationUnit_reparse.restype = c_int
-
-TranslationUnit_codeComplete = lib.clang_codeCompleteAt
-TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
- c_int, c_void_p, c_int, c_int]
-TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
-
-TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
-TranslationUnit_cursor.argtypes = [TranslationUnit]
-TranslationUnit_cursor.restype = Cursor
-TranslationUnit_cursor.errcheck = Cursor.from_result
-
-TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
-TranslationUnit_spelling.argtypes = [TranslationUnit]
-TranslationUnit_spelling.restype = _CXString
-TranslationUnit_spelling.errcheck = _CXString.from_result
-
-TranslationUnit_dispose = lib.clang_disposeTranslationUnit
-TranslationUnit_dispose.argtypes = [TranslationUnit]
-
-TranslationUnit_includes_callback = CFUNCTYPE(None,
- c_object_p,
- POINTER(SourceLocation),
- c_uint, py_object)
-TranslationUnit_includes = lib.clang_getInclusions
-TranslationUnit_includes.argtypes = [TranslationUnit,
- TranslationUnit_includes_callback,
- py_object]
-
-# File Functions
-File_getFile = lib.clang_getFile
-File_getFile.argtypes = [TranslationUnit, c_char_p]
-File_getFile.restype = c_object_p
-
-File_name = lib.clang_getFileName
-File_name.argtypes = [File]
-File_name.restype = _CXString
-
-File_time = lib.clang_getFileTime
-File_time.argtypes = [File]
-File_time.restype = c_uint
-
-# Code completion
-
-CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
-CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
-
-_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
-_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
-_clang_codeCompleteGetNumDiagnostics.restype = c_int
-
-_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
-_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
-_clang_codeCompleteGetDiagnostic.restype = Diagnostic
-
-_clang_getCompletionChunkText = lib.clang_getCompletionChunkText
-_clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
-_clang_getCompletionChunkText.restype = _CXString
+ # The database could not be loaded
+ ERROR_CANNOTLOADDATABASE = 1
-_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
-_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
-_clang_getCompletionChunkKind.restype = c_int
+ def __init__(self, enumeration, message):
+ assert isinstance(enumeration, int)
-_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
-_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
-_clang_getCompletionChunkCompletionString.restype = c_object_p
+ if enumeration > 1:
+ raise Exception("Encountered undefined CompilationDatabase error "
+ "constant: %d. Please file a bug to have this "
+ "value supported." % enumeration)
-_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
-_clang_getNumCompletionChunks.argtypes = [c_void_p]
-_clang_getNumCompletionChunks.restype = c_int
+ self.cdb_error = enumeration
+ Exception.__init__(self, 'Error %d: %s' % (enumeration, message))
-_clang_getCompletionAvailability = lib.clang_getCompletionAvailability
-_clang_getCompletionAvailability.argtypes = [c_void_p]
-_clang_getCompletionAvailability.restype = c_int
+class CompileCommand(object):
+ """Represents the compile command used to build a file"""
+ def __init__(self, cmd, ccmds):
+ self.cmd = cmd
+ # Keep a reference to the originating CompileCommands
+ # to prevent garbage collection
+ self.ccmds = ccmds
-_clang_getCompletionPriority = lib.clang_getCompletionPriority
-_clang_getCompletionPriority.argtypes = [c_void_p]
-_clang_getCompletionPriority.restype = c_int
+ @property
+ def directory(self):
+ """Get the working directory for this CompileCommand"""
+ return lib.clang_CompileCommand_getDirectory(self.cmd)
+ @property
+ def arguments(self):
+ """
+ Get an iterable object providing each argument in the
+ command line for the compiler invocation as a _CXString.
-###
+ Invariant : the first argument is the compiler executable
+ """
+ length = lib.clang_CompileCommand_getNumArgs(self.cmd)
+ for i in xrange(length):
+ yield lib.clang_CompileCommand_getArg(self.cmd, i)
+
+class CompileCommands(object):
+ """
+ CompileCommands is an iterable object containing all CompileCommand
+ that can be used for building a specific file.
+ """
+ def __init__(self, ccmds):
+ self.ccmds = ccmds
+
+ def __del__(self):
+ lib.clang_CompileCommands_dispose(self.ccmds)
+
+ def __len__(self):
+ return int(lib.clang_CompileCommands_getSize(self.ccmds))
+
+ def __getitem__(self, i):
+ cc = lib.clang_CompileCommands_getCommand(self.ccmds, i)
+ if not cc:
+ raise IndexError
+ return CompileCommand(cc, self)
+
+ @staticmethod
+ def from_result(res, fn, args):
+ if not res:
+ return None
+ return CompileCommands(res)
+
+class CompilationDatabase(ClangObject):
+ """
+ The CompilationDatabase is a wrapper class around
+ clang::tooling::CompilationDatabase
+
+ It enables querying how a specific source file can be built.
+ """
+
+ def __del__(self):
+ lib.clang_CompilationDatabase_dispose(self)
+
+ @staticmethod
+ def from_result(res, fn, args):
+ if not res:
+ raise CompilationDatabaseError(0,
+ "CompilationDatabase loading failed")
+ return CompilationDatabase(res)
+
+ @staticmethod
+ def fromDirectory(buildDir):
+ """Builds a CompilationDatabase from the database found in buildDir"""
+ errorCode = c_uint()
+ try:
+ cdb = lib.clang_CompilationDatabase_fromDirectory(buildDir,
+ byref(errorCode))
+ except CompilationDatabaseError as e:
+ raise CompilationDatabaseError(int(errorCode.value),
+ "CompilationDatabase loading failed")
+ return cdb
+
+ def getCompileCommands(self, filename):
+ """
+ Get an iterable object providing all the CompileCommands available to
+ build filename. Returns None if filename is not found in the database.
+ """
+ return lib.clang_CompilationDatabase_getCompileCommands(self, filename)
+
+class Token(Structure):
+ """Represents a single token from the preprocessor.
+
+ Tokens are effectively segments of source code. Source code is first parsed
+ into tokens before being converted into the AST and Cursors.
+
+ Tokens are obtained from parsed TranslationUnit instances. You currently
+ can't create tokens manually.
+ """
+ _fields_ = [
+ ('int_data', c_uint * 4),
+ ('ptr_data', c_void_p)
+ ]
+
+ @property
+ def spelling(self):
+ """The spelling of this token.
+
+ This is the textual representation of the token in source.
+ """
+ return lib.clang_getTokenSpelling(self._tu, self)
+
+ @property
+ def kind(self):
+ """Obtain the TokenKind of the current token."""
+ return TokenKind.from_value(lib.clang_getTokenKind(self))
+
+ @property
+ def location(self):
+ """The SourceLocation this Token occurs at."""
+ return lib.clang_getTokenLocation(self._tu, self)
+
+ @property
+ def extent(self):
+ """The SourceRange this Token occupies."""
+ return lib.clang_getTokenExtent(self._tu, self)
+
+ @property
+ def cursor(self):
+ """The Cursor this Token corresponds to."""
+ cursor = Cursor()
+
+ lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor))
+
+ return cursor
+
+# Now comes the plumbing to hook up the C library.
+
+# Register callback types in common container.
+callbacks['translation_unit_includes'] = CFUNCTYPE(None, c_object_p,
+ POINTER(SourceLocation), c_uint, py_object)
+callbacks['cursor_visit'] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
+
+def register_functions(lib):
+ """Register function prototypes with a libclang library instance.
+
+ This must be called as part of library instantiation so Python knows how
+ to call out to the shared library.
+ """
+ # Functions are registered in strictly alphabetical order.
+ lib.clang_annotateTokens.argtype = [TranslationUnit, POINTER(Token),
+ c_uint, POINTER(Cursor)]
+
+ lib.clang_CompilationDatabase_dispose.argtypes = [c_object_p]
+
+ lib.clang_CompilationDatabase_fromDirectory.argtypes = [c_char_p,
+ POINTER(c_uint)]
+ lib.clang_CompilationDatabase_fromDirectory.restype = c_object_p
+ lib.clang_CompilationDatabase_fromDirectory.errcheck = CompilationDatabase.from_result
+
+ lib.clang_CompilationDatabase_getCompileCommands.argtypes = [c_object_p, c_char_p]
+ lib.clang_CompilationDatabase_getCompileCommands.restype = c_object_p
+ lib.clang_CompilationDatabase_getCompileCommands.errcheck = CompileCommands.from_result
+
+ lib.clang_CompileCommands_dispose.argtypes = [c_object_p]
+
+ lib.clang_CompileCommands_getCommand.argtypes = [c_object_p, c_uint]
+ lib.clang_CompileCommands_getCommand.restype = c_object_p
+
+ lib.clang_CompileCommands_getSize.argtypes = [c_object_p]
+ lib.clang_CompileCommands_getSize.restype = c_uint
+
+ lib.clang_CompileCommand_getArg.argtypes = [c_object_p, c_uint]
+ lib.clang_CompileCommand_getArg.restype = _CXString
+ lib.clang_CompileCommand_getArg.errcheck = _CXString.from_result
+
+ lib.clang_CompileCommand_getDirectory.argtypes = [c_object_p]
+ lib.clang_CompileCommand_getDirectory.restype = _CXString
+ lib.clang_CompileCommand_getDirectory.errcheck = _CXString.from_result
+
+ lib.clang_CompileCommand_getNumArgs.argtypes = [c_object_p]
+ lib.clang_CompileCommand_getNumArgs.restype = c_uint
+
+ lib.clang_codeCompleteAt.argtypes = [TranslationUnit, c_char_p, c_int,
+ c_int, c_void_p, c_int, c_int]
+ lib.clang_codeCompleteAt.restype = POINTER(CCRStructure)
+
+ lib.clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults,
+ c_int]
+ lib.clang_codeCompleteGetDiagnostic.restype = Diagnostic
+
+ lib.clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
+ lib.clang_codeCompleteGetNumDiagnostics.restype = c_int
+
+ lib.clang_createIndex.argtypes = [c_int, c_int]
+ lib.clang_createIndex.restype = c_object_p
+
+ lib.clang_createTranslationUnit.argtypes = [Index, c_char_p]
+ lib.clang_createTranslationUnit.restype = c_object_p
+
+ lib.clang_CXXMethod_isStatic.argtypes = [Cursor]
+ lib.clang_CXXMethod_isStatic.restype = bool
+
+ lib.clang_CXXMethod_isVirtual.argtypes = [Cursor]
+ lib.clang_CXXMethod_isVirtual.restype = bool
+
+ lib.clang_defaultSaveOptions.argtypes = [TranslationUnit]
+ lib.clang_defaultSaveOptions.restype = c_uint
+
+ lib.clang_disposeCodeCompleteResults.argtypes = [CodeCompletionResults]
+
+ #lib.clang_disposeCXTUResourceUsage.argtypes = [CXTUResourceUsage]
+
+ lib.clang_disposeDiagnostic.argtypes = [Diagnostic]
+
+ lib.clang_disposeIndex.argtypes = [Index]
+
+ lib.clang_disposeString.argtypes = [_CXString]
+
+ lib.clang_disposeTokens.argtype = [TranslationUnit, POINTER(Token), c_uint]
+
+ lib.clang_disposeTranslationUnit.argtypes = [TranslationUnit]
+
+ lib.clang_equalCursors.argtypes = [Cursor, Cursor]
+ lib.clang_equalCursors.restype = bool
+
+ lib.clang_equalLocations.argtypes = [SourceLocation, SourceLocation]
+ lib.clang_equalLocations.restype = bool
+
+ lib.clang_equalRanges.argtypes = [SourceRange, SourceRange]
+ lib.clang_equalRanges.restype = bool
+
+ lib.clang_equalTypes.argtypes = [Type, Type]
+ lib.clang_equalTypes.restype = bool
+
+ lib.clang_getArgType.argtypes = [Type, c_uint]
+ lib.clang_getArgType.restype = Type
+ lib.clang_getArgType.errcheck = Type.from_result
+
+ lib.clang_getArrayElementType.argtypes = [Type]
+ lib.clang_getArrayElementType.restype = Type
+ lib.clang_getArrayElementType.errcheck = Type.from_result
+
+ lib.clang_getArraySize.argtypes = [Type]
+ lib.clang_getArraySize.restype = c_longlong
+
+ lib.clang_getCanonicalCursor.argtypes = [Cursor]
+ lib.clang_getCanonicalCursor.restype = Cursor
+ lib.clang_getCanonicalCursor.errcheck = Cursor.from_cursor_result
+
+ lib.clang_getCanonicalType.argtypes = [Type]
+ lib.clang_getCanonicalType.restype = Type
+ lib.clang_getCanonicalType.errcheck = Type.from_result
+
+ lib.clang_getCompletionAvailability.argtypes = [c_void_p]
+ lib.clang_getCompletionAvailability.restype = c_int
+
+ lib.clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
+ lib.clang_getCompletionChunkCompletionString.restype = c_object_p
+
+ lib.clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
+ lib.clang_getCompletionChunkKind.restype = c_int
+
+ lib.clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
+ lib.clang_getCompletionChunkText.restype = _CXString
+
+ lib.clang_getCompletionPriority.argtypes = [c_void_p]
+ lib.clang_getCompletionPriority.restype = c_int
+
+ lib.clang_getCString.argtypes = [_CXString]
+ lib.clang_getCString.restype = c_char_p
+
+ lib.clang_getCursor.argtypes = [TranslationUnit, SourceLocation]
+ lib.clang_getCursor.restype = Cursor
+
+ lib.clang_getCursorDefinition.argtypes = [Cursor]
+ lib.clang_getCursorDefinition.restype = Cursor
+ lib.clang_getCursorDefinition.errcheck = Cursor.from_result
+
+ lib.clang_getCursorDisplayName.argtypes = [Cursor]
+ lib.clang_getCursorDisplayName.restype = _CXString
+ lib.clang_getCursorDisplayName.errcheck = _CXString.from_result
+
+ lib.clang_getCursorExtent.argtypes = [Cursor]
+ lib.clang_getCursorExtent.restype = SourceRange
+
+ lib.clang_getCursorLexicalParent.argtypes = [Cursor]
+ lib.clang_getCursorLexicalParent.restype = Cursor
+ lib.clang_getCursorLexicalParent.errcheck = Cursor.from_cursor_result
+
+ lib.clang_getCursorLocation.argtypes = [Cursor]
+ lib.clang_getCursorLocation.restype = SourceLocation
+
+ lib.clang_getCursorReferenced.argtypes = [Cursor]
+ lib.clang_getCursorReferenced.restype = Cursor
+ lib.clang_getCursorReferenced.errcheck = Cursor.from_result
+
+ lib.clang_getCursorReferenceNameRange.argtypes = [Cursor, c_uint, c_uint]
+ lib.clang_getCursorReferenceNameRange.restype = SourceRange
+
+ lib.clang_getCursorSemanticParent.argtypes = [Cursor]
+ lib.clang_getCursorSemanticParent.restype = Cursor
+ lib.clang_getCursorSemanticParent.errcheck = Cursor.from_cursor_result
+
+ lib.clang_getCursorSpelling.argtypes = [Cursor]
+ lib.clang_getCursorSpelling.restype = _CXString
+ lib.clang_getCursorSpelling.errcheck = _CXString.from_result
+
+ lib.clang_getCursorType.argtypes = [Cursor]
+ lib.clang_getCursorType.restype = Type
+ lib.clang_getCursorType.errcheck = Type.from_result
+
+ lib.clang_getCursorUSR.argtypes = [Cursor]
+ lib.clang_getCursorUSR.restype = _CXString
+ lib.clang_getCursorUSR.errcheck = _CXString.from_result
+
+ #lib.clang_getCXTUResourceUsage.argtypes = [TranslationUnit]
+ #lib.clang_getCXTUResourceUsage.restype = CXTUResourceUsage
+
+ lib.clang_getCXXAccessSpecifier.argtypes = [Cursor]
+ lib.clang_getCXXAccessSpecifier.restype = c_uint
+
+ lib.clang_getDeclObjCTypeEncoding.argtypes = [Cursor]
+ lib.clang_getDeclObjCTypeEncoding.restype = _CXString
+ lib.clang_getDeclObjCTypeEncoding.errcheck = _CXString.from_result
+
+ lib.clang_getDiagnostic.argtypes = [c_object_p, c_uint]
+ lib.clang_getDiagnostic.restype = c_object_p
+
+ lib.clang_getDiagnosticCategory.argtypes = [Diagnostic]
+ lib.clang_getDiagnosticCategory.restype = c_uint
+
+ lib.clang_getDiagnosticCategoryName.argtypes = [c_uint]
+ lib.clang_getDiagnosticCategoryName.restype = _CXString
+ lib.clang_getDiagnosticCategoryName.errcheck = _CXString.from_result
+
+ lib.clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint,
+ POINTER(SourceRange)]
+ lib.clang_getDiagnosticFixIt.restype = _CXString
+ lib.clang_getDiagnosticFixIt.errcheck = _CXString.from_result
+
+ lib.clang_getDiagnosticLocation.argtypes = [Diagnostic]
+ lib.clang_getDiagnosticLocation.restype = SourceLocation
+
+ lib.clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
+ lib.clang_getDiagnosticNumFixIts.restype = c_uint
+
+ lib.clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
+ lib.clang_getDiagnosticNumRanges.restype = c_uint
+
+ lib.clang_getDiagnosticOption.argtypes = [Diagnostic, POINTER(_CXString)]
+ lib.clang_getDiagnosticOption.restype = _CXString
+ lib.clang_getDiagnosticOption.errcheck = _CXString.from_result
+
+ lib.clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
+ lib.clang_getDiagnosticRange.restype = SourceRange
+
+ lib.clang_getDiagnosticSeverity.argtypes = [Diagnostic]
+ lib.clang_getDiagnosticSeverity.restype = c_int
+
+ lib.clang_getDiagnosticSpelling.argtypes = [Diagnostic]
+ lib.clang_getDiagnosticSpelling.restype = _CXString
+ lib.clang_getDiagnosticSpelling.errcheck = _CXString.from_result
+
+ lib.clang_getElementType.argtypes = [Type]
+ lib.clang_getElementType.restype = Type
+ lib.clang_getElementType.errcheck = Type.from_result
+
+ lib.clang_getEnumConstantDeclUnsignedValue.argtypes = [Cursor]
+ lib.clang_getEnumConstantDeclUnsignedValue.restype = c_ulonglong
+
+ lib.clang_getEnumConstantDeclValue.argtypes = [Cursor]
+ lib.clang_getEnumConstantDeclValue.restype = c_longlong
+
+ lib.clang_getEnumDeclIntegerType.argtypes = [Cursor]
+ lib.clang_getEnumDeclIntegerType.restype = Type
+ lib.clang_getEnumDeclIntegerType.errcheck = Type.from_result
+
+ lib.clang_getFile.argtypes = [TranslationUnit, c_char_p]
+ lib.clang_getFile.restype = c_object_p
+
+ lib.clang_getFileName.argtypes = [File]
+ lib.clang_getFileName.restype = _CXString
+ # TODO go through _CXString.from_result?
+
+ lib.clang_getFileTime.argtypes = [File]
+ lib.clang_getFileTime.restype = c_uint
+
+ lib.clang_getIBOutletCollectionType.argtypes = [Cursor]
+ lib.clang_getIBOutletCollectionType.restype = Type
+ lib.clang_getIBOutletCollectionType.errcheck = Type.from_result
+
+ lib.clang_getIncludedFile.argtypes = [Cursor]
+ lib.clang_getIncludedFile.restype = File
+ lib.clang_getIncludedFile.errcheck = File.from_cursor_result
+
+ lib.clang_getInclusions.argtypes = [TranslationUnit,
+ callbacks['translation_unit_includes'], py_object]
+
+ lib.clang_getInstantiationLocation.argtypes = [SourceLocation,
+ POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint), POINTER(c_uint)]
+
+ lib.clang_getLocation.argtypes = [TranslationUnit, File, c_uint, c_uint]
+ lib.clang_getLocation.restype = SourceLocation
+
+ lib.clang_getLocationForOffset.argtypes = [TranslationUnit, File, c_uint]
+ lib.clang_getLocationForOffset.restype = SourceLocation
+
+ lib.clang_getNullCursor.restype = Cursor
+
+ lib.clang_getNumArgTypes.argtypes = [Type]
+ lib.clang_getNumArgTypes.restype = c_uint
+
+ lib.clang_getNumCompletionChunks.argtypes = [c_void_p]
+ lib.clang_getNumCompletionChunks.restype = c_int
+
+ lib.clang_getNumDiagnostics.argtypes = [c_object_p]
+ lib.clang_getNumDiagnostics.restype = c_uint
+
+ lib.clang_getNumElements.argtypes = [Type]
+ lib.clang_getNumElements.restype = c_longlong
+
+ lib.clang_getNumOverloadedDecls.argtypes = [Cursor]
+ lib.clang_getNumOverloadedDecls.restyp = c_uint
+
+ lib.clang_getOverloadedDecl.argtypes = [Cursor, c_uint]
+ lib.clang_getOverloadedDecl.restype = Cursor
+ lib.clang_getOverloadedDecl.errcheck = Cursor.from_cursor_result
+
+ lib.clang_getPointeeType.argtypes = [Type]
+ lib.clang_getPointeeType.restype = Type
+ lib.clang_getPointeeType.errcheck = Type.from_result
+
+ lib.clang_getRange.argtypes = [SourceLocation, SourceLocation]
+ lib.clang_getRange.restype = SourceRange
+
+ lib.clang_getRangeEnd.argtypes = [SourceRange]
+ lib.clang_getRangeEnd.restype = SourceLocation
+
+ lib.clang_getRangeStart.argtypes = [SourceRange]
+ lib.clang_getRangeStart.restype = SourceLocation
+
+ lib.clang_getResultType.argtypes = [Type]
+ lib.clang_getResultType.restype = Type
+ lib.clang_getResultType.errcheck = Type.from_result
+
+ lib.clang_getSpecializedCursorTemplate.argtypes = [Cursor]
+ lib.clang_getSpecializedCursorTemplate.restype = Cursor
+ lib.clang_getSpecializedCursorTemplate.errcheck = Cursor.from_cursor_result
+
+ lib.clang_getTemplateCursorKind.argtypes = [Cursor]
+ lib.clang_getTemplateCursorKind.restype = c_uint
+
+ lib.clang_getTokenExtent.argtypes = [TranslationUnit, Token]
+ lib.clang_getTokenExtent.restype = SourceRange
+
+ lib.clang_getTokenKind.argtypes = [Token]
+ lib.clang_getTokenKind.restype = c_uint
+
+ lib.clang_getTokenLocation.argtype = [TranslationUnit, Token]
+ lib.clang_getTokenLocation.restype = SourceLocation
+
+ lib.clang_getTokenSpelling.argtype = [TranslationUnit, Token]
+ lib.clang_getTokenSpelling.restype = _CXString
+ lib.clang_getTokenSpelling.errcheck = _CXString.from_result
+
+ lib.clang_getTranslationUnitCursor.argtypes = [TranslationUnit]
+ lib.clang_getTranslationUnitCursor.restype = Cursor
+ lib.clang_getTranslationUnitCursor.errcheck = Cursor.from_result
+
+ lib.clang_getTranslationUnitSpelling.argtypes = [TranslationUnit]
+ lib.clang_getTranslationUnitSpelling.restype = _CXString
+ lib.clang_getTranslationUnitSpelling.errcheck = _CXString.from_result
+
+ lib.clang_getTUResourceUsageName.argtypes = [c_uint]
+ lib.clang_getTUResourceUsageName.restype = c_char_p
+
+ lib.clang_getTypeDeclaration.argtypes = [Type]
+ lib.clang_getTypeDeclaration.restype = Cursor
+ lib.clang_getTypeDeclaration.errcheck = Cursor.from_result
+
+ lib.clang_getTypedefDeclUnderlyingType.argtypes = [Cursor]
+ lib.clang_getTypedefDeclUnderlyingType.restype = Type
+ lib.clang_getTypedefDeclUnderlyingType.errcheck = Type.from_result
+
+ lib.clang_getTypeKindSpelling.argtypes = [c_uint]
+ lib.clang_getTypeKindSpelling.restype = _CXString
+ lib.clang_getTypeKindSpelling.errcheck = _CXString.from_result
+
+ lib.clang_hashCursor.argtypes = [Cursor]
+ lib.clang_hashCursor.restype = c_uint
+
+ lib.clang_isAttribute.argtypes = [CursorKind]
+ lib.clang_isAttribute.restype = bool
+
+ lib.clang_isConstQualifiedType.argtypes = [Type]
+ lib.clang_isConstQualifiedType.restype = bool
+
+ lib.clang_isCursorDefinition.argtypes = [Cursor]
+ lib.clang_isCursorDefinition.restype = bool
+
+ lib.clang_isDeclaration.argtypes = [CursorKind]
+ lib.clang_isDeclaration.restype = bool
+
+ lib.clang_isExpression.argtypes = [CursorKind]
+ lib.clang_isExpression.restype = bool
+
+ lib.clang_isFileMultipleIncludeGuarded.argtypes = [TranslationUnit, File]
+ lib.clang_isFileMultipleIncludeGuarded.restype = bool
+
+ lib.clang_isFunctionTypeVariadic.argtypes = [Type]
+ lib.clang_isFunctionTypeVariadic.restype = bool
+
+ lib.clang_isInvalid.argtypes = [CursorKind]
+ lib.clang_isInvalid.restype = bool
+
+ lib.clang_isPODType.argtypes = [Type]
+ lib.clang_isPODType.restype = bool
+
+ lib.clang_isPreprocessing.argtypes = [CursorKind]
+ lib.clang_isPreprocessing.restype = bool
+
+ lib.clang_isReference.argtypes = [CursorKind]
+ lib.clang_isReference.restype = bool
+
+ lib.clang_isRestrictQualifiedType.argtypes = [Type]
+ lib.clang_isRestrictQualifiedType.restype = bool
+
+ lib.clang_isStatement.argtypes = [CursorKind]
+ lib.clang_isStatement.restype = bool
+
+ lib.clang_isTranslationUnit.argtypes = [CursorKind]
+ lib.clang_isTranslationUnit.restype = bool
+
+ lib.clang_isUnexposed.argtypes = [CursorKind]
+ lib.clang_isUnexposed.restype = bool
+
+ lib.clang_isVirtualBase.argtypes = [Cursor]
+ lib.clang_isVirtualBase.restype = bool
+
+ lib.clang_isVolatileQualifiedType.argtypes = [Type]
+ lib.clang_isVolatileQualifiedType.restype = bool
+
+ lib.clang_parseTranslationUnit.argypes = [Index, c_char_p, c_void_p, c_int,
+ c_void_p, c_int, c_int]
+ lib.clang_parseTranslationUnit.restype = c_object_p
+
+ lib.clang_reparseTranslationUnit.argtypes = [TranslationUnit, c_int,
+ c_void_p, c_int]
+ lib.clang_reparseTranslationUnit.restype = c_int
+
+ lib.clang_saveTranslationUnit.argtypes = [TranslationUnit, c_char_p,
+ c_uint]
+ lib.clang_saveTranslationUnit.restype = c_int
+
+ lib.clang_tokenize.argtypes = [TranslationUnit, SourceRange,
+ POINTER(POINTER(Token)), POINTER(c_uint)]
+
+ lib.clang_visitChildren.argtypes = [Cursor, callbacks['cursor_visit'],
+ py_object]
+ lib.clang_visitChildren.restype = c_uint
+
+register_functions(lib)
+
+def register_enumerations():
+ for name, value in clang.enumerations.TokenKinds:
+ TokenKind.register(value, name)
+
+register_enumerations()
-__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 'Type', 'TypeKind',
- 'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
- 'SourceLocation', 'File']
+__all__ = [
+ 'CodeCompletionResults',
+ 'CompilationDatabase',
+ 'CompileCommands',
+ 'CompileCommand',
+ 'CursorKind',
+ 'Cursor',
+ 'Diagnostic',
+ 'File',
+ 'FixIt',
+ 'Index',
+ 'SourceLocation',
+ 'SourceRange',
+ 'TokenKind',
+ 'Token',
+ 'TranslationUnitLoadError',
+ 'TranslationUnit',
+ 'TypeKind',
+ 'Type',
+]
OpenPOWER on IntegriCloud