summaryrefslogtreecommitdiff
path: root/bindings/python/clang/cindex.py
diff options
context:
space:
mode:
authorEli Bendersky <eliben@google.com>2014-10-10 20:01:05 +0000
committerEli Bendersky <eliben@google.com>2014-10-10 20:01:05 +0000
commita0b1e640c5872ea7bd3f297b772f6842aabe5d4d (patch)
tree0ddf747eb590189d2d8bfe929d8d089c5c590410 /bindings/python/clang/cindex.py
parent2fdc497405b20e3d4a02e8b8a121f63e4baa3587 (diff)
downloadclang-a0b1e640c5872ea7bd3f297b772f6842aabe5d4d.tar.gz
Add libclang capabilities to retriete template arguments from specializations.
Includes Python bindings. Reviewed in http://reviews.llvm.org/D5621 Patch by Rob Springer git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219529 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings/python/clang/cindex.py')
-rw-r--r--bindings/python/clang/cindex.py204
1 files changed, 98 insertions, 106 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 68f7e48fc6..8bcf9c3bda 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -496,24 +496,28 @@ class TokenKind(object):
setattr(TokenKind, name, kind)
### Cursor Kinds ###
-
-class CursorKind(object):
- """
- A CursorKind describes the kind of entity that a cursor points to.
+class BaseEnumeration(object):
"""
+ Common base class for named enumerations held in sync with Index.h values.
- # The unique kind objects, indexed by id.
+ Subclasses must define their own _kinds and _name_map members, as:
_kinds = []
_name_map = None
+ These values hold the per-subclass instances and value-to-name mappings,
+ respectively.
+
+ """
def __init__(self, value):
- if value >= len(CursorKind._kinds):
- CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
- if CursorKind._kinds[value] is not None:
- raise ValueError,'CursorKind already loaded'
+ if value >= len(self.__class__._kinds):
+ self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1)
+ if self.__class__._kinds[value] is not None:
+ raise ValueError,'{0} value {1} already loaded'.format(
+ str(self.__class__), value)
self.value = value
- CursorKind._kinds[value] = self
- CursorKind._name_map = None
+ self.__class__._kinds[value] = self
+ self.__class__._name_map = None
+
def from_param(self):
return self.value
@@ -523,16 +527,29 @@ class CursorKind(object):
"""Get the enumeration name of this cursor kind."""
if self._name_map is None:
self._name_map = {}
- for key,value in CursorKind.__dict__.items():
- if isinstance(value,CursorKind):
+ for key, value in self.__class__.__dict__.items():
+ if isinstance(value, self.__class__):
self._name_map[value] = key
return self._name_map[self]
- @staticmethod
- def from_id(id):
- if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
- raise ValueError,'Unknown cursor kind %d' % id
- return CursorKind._kinds[id]
+ @classmethod
+ def from_id(cls, id):
+ if id >= len(cls._kinds) or cls._kinds[id] is None:
+ raise ValueError,'Unknown template argument kind %d' % id
+ return cls._kinds[id]
+
+ def __repr__(self):
+ return '%s.%s' % (self.__class__, self.name,)
+
+
+class CursorKind(BaseEnumeration):
+ """
+ A CursorKind describes the kind of entity that a cursor points to.
+ """
+
+ # The required BaseEnumeration declarations.
+ _kinds = []
+ _name_map = None
@staticmethod
def get_all_kinds():
@@ -578,11 +595,6 @@ class CursorKind(object):
def __repr__(self):
return 'CursorKind.%s' % (self.name,)
-# FIXME: Is there a nicer way to expose this enumeration? We could potentially
-# represent the nested structure, or even build a class hierarchy. The main
-# things we want for sure are (a) simple external access to kinds, (b) a place
-# to hang a description and name, (c) easy to keep in sync with Index.h.
-
###
# Declaration Kinds
@@ -1101,6 +1113,24 @@ CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
# A module import declaration.
CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
+
+### Template Argument Kinds ###
+class TemplateArgumentKind(BaseEnumeration):
+ """
+ A TemplateArgumentKind describes the kind of entity that a template argument
+ represents.
+ """
+
+ # The required BaseEnumeration declarations.
+ _kinds = []
+ _name_map = None
+
+TemplateArgumentKind.NULL = TemplateArgumentKind(0)
+TemplateArgumentKind.TYPE = TemplateArgumentKind(1)
+TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2)
+TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3)
+TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4)
+
### Cursors ###
class Cursor(Structure):
@@ -1378,6 +1408,27 @@ class Cursor(Structure):
for i in range(0, num_args):
yield conf.lib.clang_Cursor_getArgument(self, i)
+ def get_num_template_arguments(self):
+ """Returns the number of template args associated with this cursor."""
+ return conf.lib.clang_Cursor_getNumTemplateArguments(self)
+
+ def get_template_argument_kind(self, num):
+ """Returns the TemplateArgumentKind for the indicated template
+ argument."""
+ return conf.lib.clang_Cursor_getTemplateArgumentKind(self, num)
+
+ def get_template_argument_type(self, num):
+ """Returns the CXType for the indicated template argument."""
+ return conf.lib.clang_Cursor_getTemplateArgumentType(self, num)
+
+ def get_template_argument_value(self, num):
+ """Returns the value of the indicated arg as a signed 64b integer."""
+ return conf.lib.clang_Cursor_getTemplateArgumentValue(self, num)
+
+ def get_template_argument_unsigned_value(self, num):
+ """Returns the value of the indicated arg as an unsigned 64b integer."""
+ return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num)
+
def get_children(self):
"""Return an iterator for accessing the children of this cursor."""
@@ -1461,7 +1512,7 @@ class Cursor(Structure):
### C++ access specifiers ###
-class AccessSpecifier(object):
+class AccessSpecifier(BaseEnumeration):
"""
Describes the access of a C++ class member
"""
@@ -1470,34 +1521,9 @@ class AccessSpecifier(object):
_kinds = []
_name_map = None
- def __init__(self, value):
- if value >= len(AccessSpecifier._kinds):
- AccessSpecifier._kinds += [None] * (value - len(AccessSpecifier._kinds) + 1)
- if AccessSpecifier._kinds[value] is not None:
- raise ValueError,'AccessSpecifier already loaded'
- self.value = value
- AccessSpecifier._kinds[value] = self
- AccessSpecifier._name_map = None
-
def from_param(self):
return self.value
- @property
- def name(self):
- """Get the enumeration name of this access specifier."""
- if self._name_map is None:
- self._name_map = {}
- for key,value in AccessSpecifier.__dict__.items():
- if isinstance(value,AccessSpecifier):
- self._name_map[value] = key
- return self._name_map[self]
-
- @staticmethod
- def from_id(id):
- if id >= len(AccessSpecifier._kinds) or not AccessSpecifier._kinds[id]:
- raise ValueError,'Unknown access specifier %d' % id
- return AccessSpecifier._kinds[id]
-
def __repr__(self):
return 'AccessSpecifier.%s' % (self.name,)
@@ -1509,7 +1535,7 @@ AccessSpecifier.NONE = AccessSpecifier(4)
### Type Kinds ###
-class TypeKind(object):
+class TypeKind(BaseEnumeration):
"""
Describes the kind of type.
"""
@@ -1518,39 +1544,11 @@ class TypeKind(object):
_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]
-
@property
def spelling(self):
"""Retrieve the spelling of this TypeKind."""
return conf.lib.clang_getTypeKindSpelling(self.value)
- @staticmethod
- def from_id(id):
- if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
- raise ValueError,'Unknown type kind %d' % id
- return TypeKind._kinds[id]
-
def __repr__(self):
return 'TypeKind.%s' % (self.name,)
@@ -1603,43 +1601,16 @@ TypeKind.VARIABLEARRAY = TypeKind(115)
TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
TypeKind.MEMBERPOINTER = TypeKind(117)
-class RefQualifierKind(object):
+class RefQualifierKind(BaseEnumeration):
"""Describes a specific ref-qualifier of a type."""
# The unique kind objects, indexed by id.
_kinds = []
_name_map = None
- def __init__(self, value):
- if value >= len(RefQualifierKind._kinds):
- num_kinds = value - len(RefQualifierKind._kinds) + 1
- RefQualifierKind._kinds += [None] * num_kinds
- if RefQualifierKind._kinds[value] is not None:
- raise ValueError, 'RefQualifierKind already loaded'
- self.value = value
- RefQualifierKind._kinds[value] = self
- RefQualifierKind._name_map = None
-
def from_param(self):
return self.value
- @property
- def name(self):
- """Get the enumeration name of this kind."""
- if self._name_map is None:
- self._name_map = {}
- for key, value in RefQualifierKind.__dict__.items():
- if isinstance(value, RefQualifierKind):
- self._name_map[value] = key
- return self._name_map[self]
-
- @staticmethod
- def from_id(id):
- if (id >= len(RefQualifierKind._kinds) or
- RefQualifierKind._kinds[id] is None):
- raise ValueError, 'Unknown type kind %d' % id
- return RefQualifierKind._kinds[id]
-
def __repr__(self):
return 'RefQualifierKind.%s' % (self.name,)
@@ -3314,6 +3285,27 @@ functionList = [
Cursor,
Cursor.from_result),
+ ("clang_Cursor_getNumTemplateArguments",
+ [Cursor],
+ c_int),
+
+ ("clang_Cursor_getTemplateArgumentKind",
+ [Cursor, c_uint],
+ TemplateArgumentKind.from_id),
+
+ ("clang_Cursor_getTemplateArgumentType",
+ [Cursor, c_uint],
+ Type,
+ Type.from_result),
+
+ ("clang_Cursor_getTemplateArgumentValue",
+ [Cursor, c_uint],
+ c_longlong),
+
+ ("clang_Cursor_getTemplateArgumentUnsignedValue",
+ [Cursor, c_uint],
+ c_ulonglong),
+
("clang_Cursor_isBitField",
[Cursor],
bool),