Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -2449,6 +2449,24 @@ CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor); /** + * \brief Describe the visibility of the entity referred to by a cursor. + */ +enum CXVisibilityKind { + /** \brief This value indicates that no visibility information is available + * for a provided CXCursor. */ + CXVisibility_Invalid, + + /** \brief Symbol not seen by the linker. */ + CXVisibility_Hidden, + /** \brief Symbol seen by the linker but resolves to a symbol inside this object. */ + CXVisibility_Protected, + /** \brief Symbol seen by the linker and acts like a normal symbol. */ + CXVisibility_Default, +}; + +CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor); + +/** * \brief Determine the availability of the entity that this cursor refers to, * taking the current target platform into account. * Index: test/Index/symbol-visibility.c =================================================================== --- /dev/null +++ test/Index/symbol-visibility.c @@ -0,0 +1,9 @@ +// RUN: c-index-test -test-print-visibility %s | FileCheck %s + +__attribute__ ((visibility ("default"))) void foo1(); +__attribute__ ((visibility ("protected"))) void foo2(); +__attribute__ ((visibility ("hidden"))) void foo3(); + +// CHECK: FunctionDecl=foo1:3:47visibility=Default +// CHECK: FunctionDecl=foo2:4:49visibility=Protected +// CHECK: FunctionDecl=foo3:5:46visibility=Hidden 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 @@ -1246,6 +1246,32 @@ } /******************************************************************************/ +/* Visibility testing. */ +/******************************************************************************/ + +static enum CXChildVisitResult PrintVisibility(CXCursor cursor, CXCursor p, + CXClientData d) { + const char *visibility = 0; + + if (clang_isInvalid(clang_getCursorKind(cursor))) + return CXChildVisit_Recurse; + + switch (clang_getCursorVisibility(cursor)) { + case CXVisibility_Invalid: break; + case CXVisibility_Hidden: visibility = "Hidden"; break; + case CXVisibility_Protected: visibility = "Protected"; break; + case CXVisibility_Default: visibility = "Default"; break; + } + + if (visibility) { + PrintCursor(cursor, NULL); + printf("visibility=%s\n", visibility); + } + + return CXChildVisit_Recurse; +} + +/******************************************************************************/ /* Typekind testing. */ /******************************************************************************/ @@ -4061,6 +4087,7 @@ " c-index-test -test-inclusion-stack-tu \n"); fprintf(stderr, " c-index-test -test-print-linkage-source {}*\n" + " c-index-test -test-print-visibility {}*\n" " c-index-test -test-print-type {}*\n" " c-index-test -test-print-type-size {}*\n" " c-index-test -test-print-bitwidth {}*\n" @@ -4148,6 +4175,9 @@ else if (argc > 2 && strcmp(argv[1], "-test-print-linkage-source") == 0) return perform_test_load_source(argc - 2, argv + 2, "all", PrintLinkage, NULL); + 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-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 @@ -6351,6 +6351,27 @@ } // end: extern "C" //===----------------------------------------------------------------------===// +// Operations for querying visibility of a cursor. +//===----------------------------------------------------------------------===// + +extern "C" { +CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) { + if (!clang_isDeclaration(cursor.kind)) + return CXVisibility_Invalid; + + const Decl *D = cxcursor::getCursorDecl(cursor); + if (const NamedDecl *ND = dyn_cast_or_null(D)) + switch (ND->getVisibility()) { + case HiddenVisibility: return CXVisibility_Hidden; + case ProtectedVisibility: return CXVisibility_Protected; + case DefaultVisibility: return CXVisibility_Default; + }; + + return CXVisibility_Invalid; +} +} // end: extern "C" + +//===----------------------------------------------------------------------===// // Operations for querying language of a cursor. //===----------------------------------------------------------------------===// Index: tools/libclang/libclang.exports =================================================================== --- tools/libclang/libclang.exports +++ tools/libclang/libclang.exports @@ -173,6 +173,7 @@ clang_getCursorSpelling clang_getCursorType clang_getCursorUSR +clang_getCursorVisibility clang_getDeclObjCTypeEncoding clang_getDefinitionSpellingAndExtent clang_getDiagnostic