aboutsummaryrefslogtreecommitdiff
path: root/bindings/python
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commitbfef399519ca9b8a4b4c6b563253bad7e0eeffe0 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /bindings/python
parent6a0372513edbc473b538d2f724efac50405d6fef (diff)
downloadsrc-bfef399519ca9b8a4b4c6b563253bad7e0eeffe0.tar.gz
src-bfef399519ca9b8a4b4c6b563253bad7e0eeffe0.zip
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):vendor/clang/clang-release_34-r197841
Notes
Notes: svn path=/vendor/clang/dist/; revision=259701 svn path=/vendor/clang/clang-release_34-r197841/; revision=259703; tag=vendor/clang/clang-release_34-r197841
Diffstat (limited to 'bindings/python')
-rw-r--r--bindings/python/clang/cindex.py169
-rw-r--r--bindings/python/tests/cindex/test_comment.py40
-rw-r--r--bindings/python/tests/cindex/test_cursor_kind.py11
-rw-r--r--bindings/python/tests/cindex/test_type.py38
4 files changed, 250 insertions, 8 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 880a1502a4ba..c103c7078003 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -266,6 +266,29 @@ class SourceRange(Structure):
def __ne__(self, other):
return not self.__eq__(other)
+ def __contains__(self, other):
+ """Useful to detect the Token/Lexer bug"""
+ if not isinstance(other, SourceLocation):
+ return False
+ if other.file is None and self.start.file is None:
+ pass
+ elif ( self.start.file.name != other.file.name or
+ other.file.name != self.end.file.name):
+ # same file name
+ return False
+ # same file, in between lines
+ if self.start.line < other.line < self.end.line:
+ return True
+ elif self.start.line == other.line:
+ # same file first line
+ if self.start.column <= other.column:
+ return True
+ elif other.line == self.end.line:
+ # same file last line
+ if other.column <= self.end.column:
+ return True
+ return False
+
def __repr__(self):
return "<SourceRange start %r, end %r>" % (self.start, self.end)
@@ -508,7 +531,7 @@ class CursorKind(object):
@staticmethod
def from_id(id):
if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
- raise ValueError,'Unknown cursor kind'
+ raise ValueError,'Unknown cursor kind %d' % id
return CursorKind._kinds[id]
@staticmethod
@@ -721,10 +744,14 @@ CursorKind.MEMBER_REF = CursorKind(47)
# A reference to a labeled statement.
CursorKind.LABEL_REF = CursorKind(48)
-# A reference toa a set of overloaded functions or function templates
+# A reference to a set of overloaded functions or function templates
# that has not yet been resolved to a specific function or function template.
CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
+# A reference to a variable that occurs in some non-expression
+# context, e.g., a C++ lambda capture list.
+CursorKind.VARIABLE_REF = CursorKind(50)
+
###
# Invalid/Error Kinds
@@ -908,6 +935,26 @@ CursorKind.PACK_EXPANSION_EXPR = CursorKind(142)
# pack.
CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
+# Represents a C++ lambda expression that produces a local function
+# object.
+#
+# \code
+# void abssort(float *x, unsigned N) {
+# std::sort(x, x + N,
+# [](float a, float b) {
+# return std::abs(a) < std::abs(b);
+# });
+# }
+# \endcode
+CursorKind.LAMBDA_EXPR = CursorKind(144)
+
+# Objective-c Boolean Literal.
+CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145)
+
+# Represents the "self" expression in a ObjC method.
+CursorKind.OBJ_SELF_EXPR = CursorKind(146)
+
+
# A statement whose specific kind is not exposed via this interface.
#
# Unexposed statements have the same operations as any other kind of statement;
@@ -999,6 +1046,9 @@ CursorKind.SEH_EXCEPT_STMT = CursorKind(227)
# Windows Structured Exception Handling's finally statement.
CursorKind.SEH_FINALLY_STMT = CursorKind(228)
+# A MS inline assembly statement extension.
+CursorKind.MS_ASM_STMT = CursorKind(229)
+
# The null statement.
CursorKind.NULL_STMT = CursorKind(230)
@@ -1028,6 +1078,7 @@ CursorKind.CXX_FINAL_ATTR = CursorKind(404)
CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405)
CursorKind.ANNOTATE_ATTR = CursorKind(406)
CursorKind.ASM_LABEL_ATTR = CursorKind(407)
+CursorKind.PACKED_ATTR = CursorKind(408)
###
# Preprocessing
@@ -1036,6 +1087,12 @@ CursorKind.MACRO_DEFINITION = CursorKind(501)
CursorKind.MACRO_INSTANTIATION = CursorKind(502)
CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
+###
+# Extra declaration
+
+# A module import declaration.
+CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
+
### Cursors ###
class Cursor(Structure):
@@ -1282,6 +1339,16 @@ class Cursor(Structure):
return self._referenced
+ @property
+ def brief_comment(self):
+ """Returns the brief comment text associated with that Cursor"""
+ return conf.lib.clang_Cursor_getBriefCommentText(self)
+
+ @property
+ def raw_comment(self):
+ """Returns the raw comment text associated with that Cursor"""
+ return conf.lib.clang_Cursor_getRawCommentText(self)
+
def get_arguments(self):
"""Return an iterator for accessing the arguments of this cursor."""
num_args = conf.lib.clang_Cursor_getNumArguments(self)
@@ -1450,6 +1517,54 @@ TypeKind.FUNCTIONNOPROTO = TypeKind(110)
TypeKind.FUNCTIONPROTO = TypeKind(111)
TypeKind.CONSTANTARRAY = TypeKind(112)
TypeKind.VECTOR = TypeKind(113)
+TypeKind.INCOMPLETEARRAY = TypeKind(114)
+TypeKind.VARIABLEARRAY = TypeKind(115)
+TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
+TypeKind.MEMBERPOINTER = TypeKind(117)
+
+class RefQualifierKind(object):
+ """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,)
+
+RefQualifierKind.NONE = RefQualifierKind(0)
+RefQualifierKind.LVALUE = RefQualifierKind(1)
+RefQualifierKind.RVALUE = RefQualifierKind(2)
class Type(Structure):
"""
@@ -1625,6 +1740,12 @@ class Type(Structure):
"""
return conf.lib.clang_getArraySize(self)
+ def get_class_type(self):
+ """
+ Retrieve the class type of the member pointer type.
+ """
+ return conf.lib.clang_Type_getClassType(self)
+
def get_align(self):
"""
Retrieve the alignment of the record.
@@ -1643,6 +1764,18 @@ class Type(Structure):
"""
return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
+ def get_ref_qualifier(self):
+ """
+ Retrieve the ref-qualifier of the type.
+ """
+ return RefQualifierKind.from_id(
+ conf.lib.clang_Type_getCXXRefQualifier(self))
+
+ @property
+ def spelling(self):
+ """Retrieve the spelling of this Type."""
+ return conf.lib.clang_getTypeSpelling(self)
+
def __eq__(self, other):
if type(other) != type(self):
return False
@@ -1918,7 +2051,7 @@ class Index(ClangObject):
def read(self, path):
"""Load a TranslationUnit from the given AST file."""
- return TranslationUnit.from_ast(path, self)
+ return TranslationUnit.from_ast_file(path, self)
def parse(self, path, args=None, unsaved_files=None, options = 0):
"""Load the translation unit from the given source code file by running
@@ -2590,6 +2723,10 @@ functionList = [
[Index, c_char_p],
c_object_p),
+ ("clang_CXXMethod_isPureVirtual",
+ [Cursor],
+ bool),
+
("clang_CXXMethod_isStatic",
[Cursor],
bool),
@@ -2973,6 +3110,11 @@ functionList = [
_CXString,
_CXString.from_result),
+ ("clang_getTypeSpelling",
+ [Type],
+ _CXString,
+ _CXString.from_result),
+
("clang_hashCursor",
[Cursor],
c_uint),
@@ -3077,17 +3219,36 @@ functionList = [
[Cursor],
bool),
+ ("clang_Cursor_getBriefCommentText",
+ [Cursor],
+ _CXString,
+ _CXString.from_result),
+
+ ("clang_Cursor_getRawCommentText",
+ [Cursor],
+ _CXString,
+ _CXString.from_result),
+
("clang_Type_getAlignOf",
[Type],
c_longlong),
+ ("clang_Type_getClassType",
+ [Type],
+ Type,
+ Type.from_result),
+
("clang_Type_getOffsetOf",
[Type, c_char_p],
c_longlong),
("clang_Type_getSizeOf",
[Type],
- c_ulonglong),
+ c_longlong),
+
+ ("clang_Type_getCXXRefQualifier",
+ [Type],
+ c_uint),
]
class LibclangError(Exception):
diff --git a/bindings/python/tests/cindex/test_comment.py b/bindings/python/tests/cindex/test_comment.py
new file mode 100644
index 000000000000..d8f3129ac51e
--- /dev/null
+++ b/bindings/python/tests/cindex/test_comment.py
@@ -0,0 +1,40 @@
+from clang.cindex import TranslationUnit
+from tests.cindex.util import get_cursor
+
+def test_comment():
+ files = [('fake.c', """
+/// Aaa.
+int test1;
+
+/// Bbb.
+/// x
+void test2(void);
+
+void f() {
+
+}
+""")]
+ # make a comment-aware TU
+ tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files,
+ options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION)
+ test1 = get_cursor(tu, 'test1')
+ assert test1 is not None, "Could not find test1."
+ assert test1.type.is_pod()
+ raw = test1.raw_comment
+ brief = test1.brief_comment
+ assert raw == """/// Aaa."""
+ assert brief == """Aaa."""
+
+ test2 = get_cursor(tu, 'test2')
+ raw = test2.raw_comment
+ brief = test2.brief_comment
+ assert raw == """/// Bbb.\n/// x"""
+ assert brief == """Bbb. x"""
+
+ f = get_cursor(tu, 'f')
+ raw = f.raw_comment
+ brief = f.brief_comment
+ assert raw is None
+ assert brief is None
+
+
diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py
index f8466e5e0d1d..8cabc512d4c5 100644
--- a/bindings/python/tests/cindex/test_cursor_kind.py
+++ b/bindings/python/tests/cindex/test_cursor_kind.py
@@ -4,8 +4,15 @@ def test_name():
assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL'
def test_get_all_kinds():
- assert CursorKind.UNEXPOSED_DECL in CursorKind.get_all_kinds()
- assert CursorKind.TRANSLATION_UNIT in CursorKind.get_all_kinds()
+ kinds = CursorKind.get_all_kinds()
+ assert CursorKind.UNEXPOSED_DECL in kinds
+ assert CursorKind.TRANSLATION_UNIT in kinds
+ assert CursorKind.VARIABLE_REF in kinds
+ assert CursorKind.LAMBDA_EXPR in kinds
+ assert CursorKind.OBJ_BOOL_LITERAL_EXPR in kinds
+ assert CursorKind.OBJ_SELF_EXPR in kinds
+ assert CursorKind.MS_ASM_STMT in kinds
+ assert CursorKind.MODULE_IMPORT_DECL in kinds
def test_kind_groups():
"""Check that every kind classifies to exactly one group."""
diff --git a/bindings/python/tests/cindex/test_type.py b/bindings/python/tests/cindex/test_type.py
index 9bbed5aa940e..a02c06fe5a13 100644
--- a/bindings/python/tests/cindex/test_type.py
+++ b/bindings/python/tests/cindex/test_type.py
@@ -132,6 +132,22 @@ def test_equal():
assert a.type != None
assert a.type != 'foo'
+def test_type_spelling():
+ """Ensure Type.spelling works."""
+ tu = get_tu('int c[5]; int i[]; int x; int v[x];')
+ c = get_cursor(tu, 'c')
+ i = get_cursor(tu, 'i')
+ x = get_cursor(tu, 'x')
+ v = get_cursor(tu, 'v')
+ assert c is not None
+ assert i is not None
+ assert x is not None
+ assert v is not None
+ assert c.type.spelling == "int [5]"
+ assert i.type.spelling == "int []"
+ assert x.type.spelling == "int"
+ assert v.type.spelling == "int [x]"
+
def test_typekind_spelling():
"""Ensure TypeKind.spelling works."""
tu = get_tu('int a;')
@@ -237,12 +253,20 @@ void bar(int a, int b);
def test_element_type():
"""Ensure Type.element_type works."""
- tu = get_tu('int i[5];')
+ tu = get_tu('int c[5]; int i[]; int x; int v[x];')
+ c = get_cursor(tu, 'c')
i = get_cursor(tu, 'i')
+ v = get_cursor(tu, 'v')
+ assert c is not None
assert i is not None
+ assert v is not None
- assert i.type.kind == TypeKind.CONSTANTARRAY
+ assert c.type.kind == TypeKind.CONSTANTARRAY
+ assert c.type.element_type.kind == TypeKind.INT
+ assert i.type.kind == TypeKind.INCOMPLETEARRAY
assert i.type.element_type.kind == TypeKind.INT
+ assert v.type.kind == TypeKind.VARIABLEARRAY
+ assert v.type.element_type.kind == TypeKind.INT
@raises(Exception)
def test_invalid_element_type():
@@ -361,3 +385,13 @@ struct Test {
assert teststruct.type.get_offset("bar") == bar
+def test_decay():
+ """Ensure decayed types are handled as the original type"""
+
+ tu = get_tu("void foo(int a[]);")
+ foo = get_cursor(tu, 'foo')
+ a = foo.type.argument_types()[0]
+
+ assert a.kind == TypeKind.INCOMPLETEARRAY
+ assert a.element_type.kind == TypeKind.INT
+ assert a.get_canonical().kind == TypeKind.INCOMPLETEARRAY