Index: bindings/python/clang/cindex.py =================================================================== --- bindings/python/clang/cindex.py +++ bindings/python/clang/cindex.py @@ -1434,6 +1434,13 @@ return self._referenced @property + def is_local_var(self): + if not hasattr(self, '_is_local_var'): + self._is_local_var = conf.lib.clang_Cursor_isLocalVarDecl(self) + + return self._is_local_var + + @property def brief_comment(self): """Returns the brief comment text associated with that Cursor""" return conf.lib.clang_Cursor_getBriefCommentText(self) Index: bindings/python/tests/cindex/test_cursor.py =================================================================== --- bindings/python/tests/cindex/test_cursor.py +++ bindings/python/tests/cindex/test_cursor.py @@ -279,6 +279,48 @@ else: assert False, "Couldn't find annotation" +local_var = """ +extern "C" { + int var0; + static int var1; + + void func(void){ + static int var2; + int var3; + } +}; + +int var4; + +class Classy { + static int var5; + + void member(){ + int var6; + static int var7; + } +}; +""" + +def test_is_local_var(): + tu = get_tu(local_var, lang="cpp") + var0 = get_cursor(tu, "var0") + var1 = get_cursor(tu, "var1") + var2 = get_cursor(tu, "var2") + var3 = get_cursor(tu, "var3") + var4 = get_cursor(tu, "var4") + var5 = get_cursor(tu, "var5") + var6 = get_cursor(tu, "var6") + var7 = get_cursor(tu, "var7") + assert not var0.is_local_var + assert not var1.is_local_var + assert var2.is_local_var + assert var3.is_local_var + assert not var4.is_local_var + assert not var5.is_local_var + assert var6.is_local_var + assert var7.is_local_var + def test_result_type(): tu = get_tu('int foo();') foo = get_cursor(tu, 'foo') @@ -370,3 +412,4 @@ # [c-index-test handles this by running the source through clang, emitting # an AST file and running libclang on that AST file] assert foo.mangled_name in ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH') + Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -3882,6 +3882,11 @@ CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C); /** + * \brief Returns non-zero if the Cursor refers to a local VarDecl. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isLocalVarDecl(CXCursor C); + +/** * \brief Given a cursor that represents a declaration, return the associated * comment's source range. The range may include multiple consecutive comments * with whitespace in between. Index: test/Index/islocalvardecl.cpp =================================================================== --- /dev/null +++ test/Index/islocalvardecl.cpp @@ -0,0 +1,32 @@ +// RUN: c-index-test -test-print-local-var-kind %s | FileCheck %s + +extern "C" { + int var0; + static int var1; + + void func(void){ + static int var2; + int var3; + } +}; + +int var4; + +class Classy { + static int var5; + + void member(){ + int var6; + static int var7; + } +}; + +// CHECK: VarDecl=var0:3:5 (Definition) IsLocalVarDecl=0 +// CHECK: VarDecl=var1:4:12 (Definition) IsLocalVarDecl=0 +// CHECK: VarDecl=var2:7:14 (Definition) IsLocalVarDecl=1 +// CHECK: VarDecl=var3:8:7 (Definition) IsLocalVarDecl=1 +// CHECK: VarDecl=var4:13:5 (Definition) IsLocalVarDecl=0 +// CHECK: VarDecl=var5:17:12 IsLocalVarDecl=0 +// CHECK: VarDecl=var6:20:9 (Definition) IsLocalVarDecl=1 +// CHECK: VarDecl=var7:21:16 (Definition) IsLocalVarDecl=1 + Index: tools/c-index-test/c-index-test.c =================================================================== --- tools/c-index-test/c-index-test.c +++ tools/c-index-test/c-index-test.c @@ -1276,6 +1276,22 @@ } /******************************************************************************/ +/* Local VarKind testing. */ +/******************************************************************************/ + +static enum CXChildVisitResult PrintIsLocalVarDecl(CXCursor C, CXCursor p, + CXClientData d){ + + if (clang_getCursorKind(C) != CXCursor_VarDecl) + return CXChildVisit_Recurse; + + PrintCursor(C, NULL); + printf(" IsLocalVarDecl=%d\n", clang_Cursor_isLocalVarDecl(C)); + + return CXChildVisit_Recurse; +} + +/******************************************************************************/ /* Typekind testing. */ /******************************************************************************/ @@ -4150,10 +4166,12 @@ fprintf(stderr, " c-index-test -test-print-linkage-source {}*\n" " c-index-test -test-print-visibility {}*\n" + " c-index-test -test-print-is-local-var {}*\n" " c-index-test -test-print-type {}*\n" " c-index-test -test-print-type-size {}*\n" " c-index-test -test-print-bitwidth {}*\n" - " c-index-test -test-print-type-declaration {}*\n" + " c-index-test -test-print-type-declaration {}*\n"); + fprintf(stderr, " c-index-test -print-usr [ {}]*\n" " c-index-test -print-usr-file \n" " c-index-test -write-pch \n"); @@ -4241,6 +4259,9 @@ else if (argc > 2 && strcmp(argv[1], "-test-print-visibility") == 0) return perform_test_load_source(argc - 2, argv + 2, "all", PrintVisibility, NULL); + else if (argc > 2 && strcmp(argv[1], "-test-print-is-local-var") == 0) + return perform_test_load_source(argc - 2, argv + 2, "all", PrintIsLocalVarDecl, + NULL); else if (argc > 2 && strcmp(argv[1], "-test-print-type") == 0) return perform_test_load_source(argc - 2, argv + 2, "all", PrintType, 0); Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -6921,6 +6921,19 @@ return 0; } +unsigned clang_Cursor_isLocalVarDecl(CXCursor C){ + if (C.kind != CXCursor_VarDecl) { + return 0; + } + + const Decl *D = getCursorDecl(C); + if (const VarDecl *VD = dyn_cast(D)) { + return VD->isLocalVarDecl(); + } + + return 0; +} + CXSourceRange clang_Cursor_getCommentRange(CXCursor C) { if (!clang_isDeclaration(C.kind)) return clang_getNullRange(); Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -33,6 +33,7 @@ clang_Cursor_isNull clang_Cursor_isObjCOptional clang_Cursor_isVariadic +clang_Cursor_isLocalVarDecl clang_Cursor_getModule clang_Cursor_getStorageClass clang_File_isEqual