зеркало из https://github.com/microsoft/clang-1.git
[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
This commit is contained in:
Родитель
4b43b30534
Коммит
d7933e6f29
|
@ -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']
|
||||
|
|
|
@ -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'
|
||||
|
|
Загрузка…
Ссылка в новой задаче