summaryrefslogtreecommitdiff
path: root/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'bindings')
-rw-r--r--bindings/python/clang/cindex.py103
-rw-r--r--bindings/python/tests/cindex/test_cdb.py17
-rw-r--r--bindings/python/tests/cindex/test_cursor.py82
-rw-r--r--bindings/python/tests/cindex/test_diagnostics.py12
4 files changed, 208 insertions, 6 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index e4b38769b77d4..aeb34f8cb2320 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -360,6 +360,23 @@ class Diagnostic(object):
return FixItIterator(self)
@property
+ def children(self):
+ class ChildDiagnosticsIterator:
+ def __init__(self, diag):
+ self.diag_set = conf.lib.clang_getChildDiagnostics(diag)
+
+ def __len__(self):
+ return int(conf.lib.clang_getNumDiagnosticsInSet(self.diag_set))
+
+ def __getitem__(self, key):
+ diag = conf.lib.clang_getDiagnosticInSet(self.diag_set, key)
+ if not diag:
+ raise IndexError
+ return Diagnostic(diag)
+
+ return ChildDiagnosticsIterator(self)
+
+ @property
def category_number(self):
"""The category number for this diagnostic or 0 if unavailable."""
return conf.lib.clang_getDiagnosticCategory(self)
@@ -1120,6 +1137,9 @@ CursorKind.MODULE_IMPORT_DECL = CursorKind(600)
# A type alias template declaration
CursorKind.TYPE_ALIAS_TEMPLATE_DECL = CursorKind(601)
+# A code completion overload candidate.
+CursorKind.OVERLOAD_CANDIDATE = CursorKind(700)
+
### Template Argument Kinds ###
class TemplateArgumentKind(BaseEnumeration):
"""
@@ -1174,6 +1194,32 @@ class Cursor(Structure):
"""
return conf.lib.clang_CXXMethod_isConst(self)
+ def is_converting_constructor(self):
+ """Returns True if the cursor refers to a C++ converting constructor.
+ """
+ return conf.lib.clang_CXXConstructor_isConvertingConstructor(self)
+
+ def is_copy_constructor(self):
+ """Returns True if the cursor refers to a C++ copy constructor.
+ """
+ return conf.lib.clang_CXXConstructor_isCopyConstructor(self)
+
+ def is_default_constructor(self):
+ """Returns True if the cursor refers to a C++ default constructor.
+ """
+ return conf.lib.clang_CXXConstructor_isDefaultConstructor(self)
+
+ def is_move_constructor(self):
+ """Returns True if the cursor refers to a C++ move constructor.
+ """
+ return conf.lib.clang_CXXConstructor_isMoveConstructor(self)
+
+ def is_default_method(self):
+ """Returns True if the cursor refers to a C++ member function or member
+ function template that is declared '= default'.
+ """
+ return conf.lib.clang_CXXMethod_isDefaulted(self)
+
def is_mutable_field(self):
"""Returns True if the cursor refers to a C++ field that is declared
'mutable'.
@@ -1685,6 +1731,7 @@ TypeKind.DEPENDENT = TypeKind(26)
TypeKind.OBJCID = TypeKind(27)
TypeKind.OBJCCLASS = TypeKind(28)
TypeKind.OBJCSEL = TypeKind(29)
+TypeKind.FLOAT128 = TypeKind(30)
TypeKind.COMPLEX = TypeKind(100)
TypeKind.POINTER = TypeKind(101)
TypeKind.BLOCKPOINTER = TypeKind(102)
@@ -1704,6 +1751,7 @@ TypeKind.VARIABLEARRAY = TypeKind(115)
TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
TypeKind.MEMBERPOINTER = TypeKind(117)
TypeKind.AUTO = TypeKind(118)
+TypeKind.ELABORATED = TypeKind(119)
class RefQualifierKind(BaseEnumeration):
"""Describes a specific ref-qualifier of a type."""
@@ -1902,6 +1950,12 @@ class Type(Structure):
"""
return conf.lib.clang_Type_getClassType(self)
+ def get_named_type(self):
+ """
+ Retrieve the type named by the qualified-id.
+ """
+ return conf.lib.clang_Type_getNamedType(self)
+
def get_align(self):
"""
Retrieve the alignment of the record.
@@ -2383,7 +2437,7 @@ class TranslationUnit(ClangObject):
functions above. __init__ is only called internally.
"""
assert isinstance(index, Index)
-
+ self.index = index
ClangObject.__init__(self, ptr)
def __del__(self):
@@ -2703,6 +2757,11 @@ class CompileCommand(object):
return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
@property
+ def filename(self):
+ """Get the working filename for this CompileCommand"""
+ return conf.lib.clang_CompileCommand_getFilename(self.cmd)
+
+ @property
def arguments(self):
"""
Get an iterable object providing each argument in the
@@ -2884,6 +2943,11 @@ functionList = [
_CXString,
_CXString.from_result),
+ ("clang_CompileCommand_getFilename",
+ [c_object_p],
+ _CXString,
+ _CXString.from_result),
+
("clang_CompileCommand_getNumArgs",
[c_object_p],
c_uint),
@@ -2908,6 +2972,22 @@ functionList = [
[Index, c_char_p],
c_object_p),
+ ("clang_CXXConstructor_isConvertingConstructor",
+ [Cursor],
+ bool),
+
+ ("clang_CXXConstructor_isCopyConstructor",
+ [Cursor],
+ bool),
+
+ ("clang_CXXConstructor_isDefaultConstructor",
+ [Cursor],
+ bool),
+
+ ("clang_CXXConstructor_isMoveConstructor",
+ [Cursor],
+ bool),
+
("clang_CXXField_isMutable",
[Cursor],
bool),
@@ -2916,6 +2996,10 @@ functionList = [
[Cursor],
bool),
+ ("clang_CXXMethod_isDefaulted",
+ [Cursor],
+ bool),
+
("clang_CXXMethod_isPureVirtual",
[Cursor],
bool),
@@ -2997,6 +3081,10 @@ functionList = [
Type,
Type.from_result),
+ ("clang_getChildDiagnostics",
+ [Diagnostic],
+ c_object_p),
+
("clang_getCompletionAvailability",
[c_void_p],
c_int),
@@ -3117,6 +3205,10 @@ functionList = [
_CXString,
_CXString.from_result),
+ ("clang_getDiagnosticInSet",
+ [c_object_p, c_uint],
+ c_object_p),
+
("clang_getDiagnosticLocation",
[Diagnostic],
SourceLocation),
@@ -3218,6 +3310,10 @@ functionList = [
[c_object_p],
c_uint),
+ ("clang_getNumDiagnosticsInSet",
+ [c_object_p],
+ c_uint),
+
("clang_getNumElements",
[Type],
c_longlong),
@@ -3477,6 +3573,11 @@ functionList = [
[Type],
c_uint),
+ ("clang_Type_getNamedType",
+ [Type],
+ Type,
+ Type.from_result),
+
("clang_Type_visitFields",
[Type, callbacks['fields_visit'], py_object],
c_uint),
diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py
index e1f824f797f22..35fe3e108a12e 100644
--- a/bindings/python/tests/cindex/test_cdb.py
+++ b/bindings/python/tests/cindex/test_cdb.py
@@ -38,27 +38,34 @@ def test_all_compilecommand():
cmds = cdb.getAllCompileCommands()
assert len(cmds) == 3
expected = [
+ { 'wd': '/home/john.doe/MyProject',
+ 'file': '/home/john.doe/MyProject/project.cpp',
+ 'line': ['clang++', '-o', 'project.o', '-c',
+ '/home/john.doe/MyProject/project.cpp']},
{ 'wd': '/home/john.doe/MyProjectA',
+ 'file': '/home/john.doe/MyProject/project2.cpp',
'line': ['clang++', '-o', 'project2.o', '-c',
'/home/john.doe/MyProject/project2.cpp']},
{ 'wd': '/home/john.doe/MyProjectB',
+ 'file': '/home/john.doe/MyProject/project2.cpp',
'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c',
'/home/john.doe/MyProject/project2.cpp']},
- { 'wd': '/home/john.doe/MyProject',
- 'line': ['clang++', '-o', 'project.o', '-c',
- '/home/john.doe/MyProject/project.cpp']}
+
]
for i in range(len(cmds)):
assert cmds[i].directory == expected[i]['wd']
+ assert cmds[i].filename == expected[i]['file']
for arg, exp in zip(cmds[i].arguments, expected[i]['line']):
assert arg == exp
def test_1_compilecommand():
"""Check file with single compile command"""
cdb = CompilationDatabase.fromDirectory(kInputsDir)
- cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
+ file = '/home/john.doe/MyProject/project.cpp'
+ cmds = cdb.getCompileCommands(file)
assert len(cmds) == 1
- assert cmds[0].directory == '/home/john.doe/MyProject'
+ assert cmds[0].directory == os.path.dirname(file)
+ assert cmds[0].filename == file
expected = [ 'clang++', '-o', 'project.o', '-c',
'/home/john.doe/MyProject/project.cpp']
for arg, exp in zip(cmds[0].arguments, expected):
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
index c5ea50516ad21..6c8230d4283c4 100644
--- a/bindings/python/tests/cindex/test_cursor.py
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -112,6 +112,88 @@ def test_is_const_method():
assert foo.is_const_method()
assert not bar.is_const_method()
+def test_is_converting_constructor():
+ """Ensure Cursor.is_converting_constructor works."""
+ source = 'class X { explicit X(int); X(double); X(); };'
+ tu = get_tu(source, lang='cpp')
+
+ xs = get_cursors(tu, 'X')
+
+ assert len(xs) == 4
+ assert xs[0].kind == CursorKind.CLASS_DECL
+ cs = xs[1:]
+ assert cs[0].kind == CursorKind.CONSTRUCTOR
+ assert cs[1].kind == CursorKind.CONSTRUCTOR
+ assert cs[2].kind == CursorKind.CONSTRUCTOR
+
+ assert not cs[0].is_converting_constructor()
+ assert cs[1].is_converting_constructor()
+ assert not cs[2].is_converting_constructor()
+
+
+def test_is_copy_constructor():
+ """Ensure Cursor.is_copy_constructor works."""
+ source = 'class X { X(); X(const X&); X(X&&); };'
+ tu = get_tu(source, lang='cpp')
+
+ xs = get_cursors(tu, 'X')
+ assert xs[0].kind == CursorKind.CLASS_DECL
+ cs = xs[1:]
+ assert cs[0].kind == CursorKind.CONSTRUCTOR
+ assert cs[1].kind == CursorKind.CONSTRUCTOR
+ assert cs[2].kind == CursorKind.CONSTRUCTOR
+
+ assert not cs[0].is_copy_constructor()
+ assert cs[1].is_copy_constructor()
+ assert not cs[2].is_copy_constructor()
+
+def test_is_default_constructor():
+ """Ensure Cursor.is_default_constructor works."""
+ source = 'class X { X(); X(int); };'
+ tu = get_tu(source, lang='cpp')
+
+ xs = get_cursors(tu, 'X')
+ assert xs[0].kind == CursorKind.CLASS_DECL
+ cs = xs[1:]
+ assert cs[0].kind == CursorKind.CONSTRUCTOR
+ assert cs[1].kind == CursorKind.CONSTRUCTOR
+
+ assert cs[0].is_default_constructor()
+ assert not cs[1].is_default_constructor()
+
+def test_is_move_constructor():
+ """Ensure Cursor.is_move_constructor works."""
+ source = 'class X { X(); X(const X&); X(X&&); };'
+ tu = get_tu(source, lang='cpp')
+
+ xs = get_cursors(tu, 'X')
+ assert xs[0].kind == CursorKind.CLASS_DECL
+ cs = xs[1:]
+ assert cs[0].kind == CursorKind.CONSTRUCTOR
+ assert cs[1].kind == CursorKind.CONSTRUCTOR
+ assert cs[2].kind == CursorKind.CONSTRUCTOR
+
+ assert not cs[0].is_move_constructor()
+ assert not cs[1].is_move_constructor()
+ assert cs[2].is_move_constructor()
+
+def test_is_default_method():
+ """Ensure Cursor.is_default_method works."""
+ source = 'class X { X() = default; }; class Y { Y(); };'
+ tu = get_tu(source, lang='cpp')
+
+ xs = get_cursors(tu, 'X')
+ ys = get_cursors(tu, 'Y')
+
+ assert len(xs) == 2
+ assert len(ys) == 2
+
+ xc = xs[1]
+ yc = ys[1]
+
+ assert xc.is_default_method()
+ assert not yc.is_default_method()
+
def test_is_mutable_field():
"""Ensure Cursor.is_mutable_field works."""
source = 'class X { int x_; mutable int y_; };'
diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py
index 48ab6176fd1df..ba6e545e8b1ab 100644
--- a/bindings/python/tests/cindex/test_diagnostics.py
+++ b/bindings/python/tests/cindex/test_diagnostics.py
@@ -80,3 +80,15 @@ def test_diagnostic_option():
assert d.option == '-Wunused-parameter'
assert d.disable_option == '-Wno-unused-parameter'
+
+def test_diagnostic_children():
+ tu = get_tu('void f(int x) {} void g() { f(); }')
+ assert len(tu.diagnostics) == 1
+ d = tu.diagnostics[0]
+
+ children = d.children
+ assert len(children) == 1
+ assert children[0].severity == Diagnostic.Note
+ assert children[0].spelling.endswith('declared here')
+ assert children[0].location.line == 1
+ assert children[0].location.column == 1