From: Douglas Gregor Date: Wed, 6 Jul 2011 03:00:34 +0000 (+0000) Subject: Improve the Python bindings for libclang in a few ways, from Eli X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8be80e1e6effd5a333bc70e7f030dc9397d0554e;p=clang Improve the Python bindings for libclang in a few ways, from Eli Bendersky. Specifically: * Implemented a new function in libclang: clang_isAttribute * Fixing TranslationUnit.get_includes to only go through the argument * buffer when it contains something. This fixed a crash on Windows * clang_getFileName returns CXString, not char*. Made appropriate * fixes in cindex.py - now the relevant tests pass and we can see the * full locations correctly again (previously there was garbage in * place of the file name) * Exposed clang_getCursorDisplayName to the python bindings git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134460 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index 08ad80234e..8cadcaa7ad 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -321,6 +321,10 @@ class CursorKind(object): """Test if this is a statement kind.""" return CursorKind_is_stmt(self) + def is_attribute(self): + """Test if this is an attribute kind.""" + return CursorKind_is_attribute(self) + def is_invalid(self): """Test if this is an invalid kind.""" return CursorKind_is_inv(self) @@ -978,8 +982,9 @@ class TranslationUnit(ClangObject): headers. """ def visitor(fobj, lptr, depth, includes): - loc = lptr.contents - includes.append(FileInclusion(loc.file, File(fobj), loc, depth)) + if depth > 0: + loc = lptr.contents + includes.append(FileInclusion(loc.file, File(fobj), loc, depth)) # Automatically adapt CIndex/ctype pointers to python objects includes = [] @@ -1074,7 +1079,7 @@ class File(ClangObject): @property def name(self): """Return the complete file and path name of the file.""" - return File_name(self) + return _CXString_getCString(File_name(self)) @property def time(self): @@ -1147,6 +1152,10 @@ CursorKind_is_stmt = lib.clang_isStatement CursorKind_is_stmt.argtypes = [CursorKind] CursorKind_is_stmt.restype = bool +CursorKind_is_attribute = lib.clang_isAttribute +CursorKind_is_attribute.argtypes = [CursorKind] +CursorKind_is_attribute.restype = bool + CursorKind_is_inv = lib.clang_isInvalid CursorKind_is_inv.argtypes = [CursorKind] CursorKind_is_inv.restype = bool @@ -1183,6 +1192,11 @@ Cursor_spelling.argtypes = [Cursor] Cursor_spelling.restype = _CXString Cursor_spelling.errcheck = _CXString.from_result +Cursor_displayname = lib.clang_getCursorDisplayName +Cursor_displayname.argtypes = [Cursor] +Cursor_displayname.restype = _CXString +Cursor_displayname.errcheck = _CXString.from_result + Cursor_loc = lib.clang_getCursorLocation Cursor_loc.argtypes = [Cursor] Cursor_loc.restype = SourceLocation @@ -1253,7 +1267,7 @@ TranslationUnit_includes.argtypes = [TranslationUnit, # File Functions File_name = lib.clang_getFileName File_name.argtypes = [File] -File_name.restype = c_char_p +File_name.restype = _CXString File_time = lib.clang_getFileTime File_time.argtypes = [File] diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py index bdfa318558..d7a1cfad8f 100644 --- a/bindings/python/tests/cindex/test_cursor_kind.py +++ b/bindings/python/tests/cindex/test_cursor_kind.py @@ -18,10 +18,14 @@ def test_kind_groups(): for k in CursorKind.get_all_kinds(): group = [n for n in ('is_declaration', 'is_reference', 'is_expression', - 'is_statement', 'is_invalid') + 'is_statement', 'is_invalid', 'is_attribute') if getattr(k, n)()] - if k == CursorKind.TRANSLATION_UNIT: + if k in ( CursorKind.TRANSLATION_UNIT, + CursorKind.MACRO_DEFINITION, + CursorKind.MACRO_INSTANTIATION, + CursorKind.INCLUSION_DIRECTIVE, + CursorKind.PREPROCESSING_DIRECTIVE): assert len(group) == 0 else: assert len(group) == 1 diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py index f130db6aeb..2e65d9518d 100644 --- a/bindings/python/tests/cindex/test_translation_unit.py +++ b/bindings/python/tests/cindex/test_translation_unit.py @@ -58,24 +58,27 @@ def test_unsaved_files_2(): spellings = [c.spelling for c in tu.cursor.get_children()] assert spellings[-1] == 'x' +def normpaths_equal(path1, path2): + """ Compares two paths for equality after normalizing them with + os.path.normpath + """ + return os.path.normpath(path1) == os.path.normpath(path2) def test_includes(): def eq(expected, actual): if not actual.is_input_file: - return expected[0] == actual.source.name and \ - expected[1] == actual.include.name + return normpaths_equal(expected[0], actual.source.name) and \ + normpaths_equal(expected[1], actual.include.name) else: - return expected[1] == actual.include.name + return normpaths_equal(expected[1], actual.include.name) src = os.path.join(kInputsDir, 'include.cpp') h1 = os.path.join(kInputsDir, "header1.h") h2 = os.path.join(kInputsDir, "header2.h") h3 = os.path.join(kInputsDir, "header3.h") - inc = [(None, src), (src, h1), (h1, h3), (src, h2), (h2, h3)] + inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)] index = Index.create() tu = index.parse(src) for i in zip(inc, tu.get_includes()): assert eq(i[0], i[1]) - - diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index cb0b3c1bab..01e7bce6bd 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1473,6 +1473,11 @@ CINDEX_LINKAGE unsigned clang_isExpression(enum CXCursorKind); */ CINDEX_LINKAGE unsigned clang_isStatement(enum CXCursorKind); +/** + * \brief Determine whether the given cursor kind represents an attribute. + */ +CINDEX_LINKAGE unsigned clang_isAttribute(enum CXCursorKind); + /** * \brief Determine whether the given cursor kind represents an invalid * cursor. diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index e4902e9035..fc331d077a 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -3562,6 +3562,10 @@ unsigned clang_isStatement(enum CXCursorKind K) { return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; } +unsigned clang_isAttribute(enum CXCursorKind K) { + return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr; +} + unsigned clang_isTranslationUnit(enum CXCursorKind K) { return K == CXCursor_TranslationUnit; } diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 85dfcb6868..daada6d3f0 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -112,6 +112,7 @@ _clang_getTranslationUnitSpelling _clang_getTypeDeclaration _clang_getTypeKindSpelling _clang_hashCursor +_clang_isAttribute _clang_isConstQualifiedType _clang_isCursorDefinition _clang_isDeclaration diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 403cd67538..0d27f6babb 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -112,6 +112,7 @@ clang_getTranslationUnitSpelling clang_getTypeDeclaration clang_getTypeKindSpelling clang_hashCursor +clang_isAttribute clang_isConstQualifiedType clang_isCursorDefinition clang_isDeclaration