summaryrefslogtreecommitdiffstats
path: root/bindings/python
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-08-17 00:43:03 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-08-17 00:43:03 +0000
commitd7933e6f29b4c93df8263df21ff5e2e1dd0cecb8 (patch)
treec6c7a44f6adfe38bbde375475cd207b1a454e187 /bindings/python
parent4b43b305342ae2e49d473d0fa6152e5d0c343765 (diff)
[python] Add support for CXType to python bindings.
Patch by Anders Waldenborg! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137797 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings/python')
-rw-r--r--bindings/python/clang/cindex.py208
-rw-r--r--bindings/python/tests/cindex/test_cursor.py4
2 files changed, 210 insertions, 2 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 8cadcaa7ad..2110170162 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -634,6 +634,14 @@ class Cursor(Structure):
"""
return Cursor_extent(self)
+ @property
+ def type(self):
+ """
+ Retrieve the type (if any) of of the entity pointed at by the
+ cursor.
+ """
+ return Cursor_type(self)
+
def get_children(self):
"""Return an iterator for accessing the children of this cursor."""
@@ -656,6 +664,165 @@ class Cursor(Structure):
return None
return res
+
+### Type Kinds ###
+
+class TypeKind(object):
+ """
+ Describes the kind of type.
+ """
+
+ # The unique kind objects, indexed by id.
+ _kinds = []
+ _name_map = None
+
+ def __init__(self, value):
+ if value >= len(TypeKind._kinds):
+ TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
+ if TypeKind._kinds[value] is not None:
+ raise ValueError,'TypeKind already loaded'
+ self.value = value
+ TypeKind._kinds[value] = self
+ TypeKind._name_map = None
+
+ def from_param(self):
+ return self.value
+
+ @property
+ def name(self):
+ """Get the enumeration name of this cursor kind."""
+ if self._name_map is None:
+ self._name_map = {}
+ for key,value in TypeKind.__dict__.items():
+ if isinstance(value,TypeKind):
+ self._name_map[value] = key
+ return self._name_map[self]
+
+ @staticmethod
+ def from_id(id):
+ if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
+ raise ValueError,'Unknown cursor kind'
+ return TypeKind._kinds[id]
+
+ def __repr__(self):
+ return 'TypeKind.%s' % (self.name,)
+
+
+
+TypeKind.INVALID = TypeKind(0)
+TypeKind.UNEXPOSED = TypeKind(1)
+TypeKind.VOID = TypeKind(2)
+TypeKind.BOOL = TypeKind(3)
+TypeKind.CHAR_U = TypeKind(4)
+TypeKind.UCHAR = TypeKind(5)
+TypeKind.CHAR16 = TypeKind(6)
+TypeKind.CHAR32 = TypeKind(7)
+TypeKind.USHORT = TypeKind(8)
+TypeKind.UINT = TypeKind(9)
+TypeKind.ULONG = TypeKind(10)
+TypeKind.ULONGLONG = TypeKind(11)
+TypeKind.UINT128 = TypeKind(12)
+TypeKind.CHAR_S = TypeKind(13)
+TypeKind.SCHAR = TypeKind(14)
+TypeKind.WCHAR = TypeKind(15)
+TypeKind.SHORT = TypeKind(16)
+TypeKind.INT = TypeKind(17)
+TypeKind.LONG = TypeKind(18)
+TypeKind.LONGLONG = TypeKind(19)
+TypeKind.INT128 = TypeKind(20)
+TypeKind.FLOAT = TypeKind(21)
+TypeKind.DOUBLE = TypeKind(22)
+TypeKind.LONGDOUBLE = TypeKind(23)
+TypeKind.NULLPTR = TypeKind(24)
+TypeKind.OVERLOAD = TypeKind(25)
+TypeKind.DEPENDENT = TypeKind(26)
+TypeKind.OBJCID = TypeKind(27)
+TypeKind.OBJCCLASS = TypeKind(28)
+TypeKind.OBJCSEL = TypeKind(29)
+TypeKind.COMPLEX = TypeKind(100)
+TypeKind.POINTER = TypeKind(101)
+TypeKind.BLOCKPOINTER = TypeKind(102)
+TypeKind.LVALUEREFERENCE = TypeKind(103)
+TypeKind.RVALUEREFERENCE = TypeKind(104)
+TypeKind.RECORD = TypeKind(105)
+TypeKind.ENUM = TypeKind(106)
+TypeKind.TYPEDEF = TypeKind(107)
+TypeKind.OBJCINTERFACE = TypeKind(108)
+TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
+TypeKind.FUNCTIONNOPROTO = TypeKind(110)
+TypeKind.FUNCTIONPROTO = TypeKind(111)
+
+
+class Type(Structure):
+ """
+ The type of an element in the abstract syntax tree.
+ """
+ _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
+
+ @property
+ def kind(self):
+ """Return the kind of this type."""
+ return TypeKind.from_id(self._kind_id)
+
+ @staticmethod
+ def from_result(res, fn, args):
+ assert isinstance(res, Type)
+ return res
+
+ def get_canonical(self):
+ """
+ Return the canonical type for a Type.
+
+ Clang's type system explicitly models typedefs and all the
+ ways a specific type can be represented. The canonical type
+ is the underlying type with all the "sugar" removed. For
+ example, if 'T' is a typedef for 'int', the canonical type for
+ 'T' would be 'int'.
+ """
+ return Type_get_canonical(self)
+
+ def is_const_qualified(self):
+ """
+ Determine whether a Type has the "const" qualifier set,
+ without looking through typedefs that may have added "const"
+ at a different level.
+ """
+ return Type_is_const_qualified(self)
+
+ def is_volatile_qualified(self):
+ """
+ Determine whether a Type has the "volatile" qualifier set,
+ without looking through typedefs that may have added
+ "volatile" at a different level.
+ """
+ return Type_is_volatile_qualified(self)
+
+ def is_restrict_qualified(self):
+ """
+ Determine whether a Type has the "restrict" qualifier set,
+ without looking through typedefs that may have added
+ "restrict" at a different level.
+ """
+ return Type_is_restrict_qualified(self)
+
+ def get_pointee(self):
+ """
+ For pointer types, returns the type of the pointee.
+ """
+ return Type_get_pointee(self)
+
+ def get_declaration(self):
+ """
+ Return the cursor for the declaration of the given type.
+ """
+ return Type_get_declaration(self)
+
+ def get_result(self):
+ """
+ Retrieve the result type associated with a function type.
+ """
+ return Type_get_result(self)
+
## CIndex Objects ##
# CIndex objects (derived from ClangObject) are essentially lightweight
@@ -1210,11 +1377,50 @@ 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_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_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
+
+
# Index Functions
Index_create = lib.clang_createIndex
Index_create.argtypes = [c_int, c_int]
@@ -1313,6 +1519,6 @@ _clang_getCompletionPriority.restype = c_int
###
-__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind',
+__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 'Type', 'TypeKind',
'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
'SourceLocation', 'File']
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
index a653ba7bf2..04e4838945 100644
--- a/bindings/python/tests/cindex/test_cursor.py
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -1,4 +1,4 @@
-from clang.cindex import Index, CursorKind
+from clang.cindex import Index, CursorKind, TypeKind
kInput = """\
// FIXME: Find nicer way to drop builtins and other cruft.
@@ -47,8 +47,10 @@ def test_get_children():
assert len(s0_nodes) == 2
assert s0_nodes[0].kind == CursorKind.FIELD_DECL
assert s0_nodes[0].spelling == 'a'
+ assert s0_nodes[0].type.kind == TypeKind.INT
assert s0_nodes[1].kind == CursorKind.FIELD_DECL
assert s0_nodes[1].spelling == 'b'
+ assert s0_nodes[1].type.kind == TypeKind.INT
assert tu_nodes[1].kind == CursorKind.STRUCT_DECL
assert tu_nodes[1].spelling == 's1'