[cfe-commits] r112296 - in /cfe/trunk: include/clang-c/Index.h test/Index/load-stmts.cpp tools/c-index-test/c-index-test.c tools/libclang/CIndex.cpp tools/libclang/CMakeLists.txt tools/libclang/CXCursor.cpp tools/libclang/CXCursor.h tools/libclang/libclang.darwin.exports tools/libclang/libclang.exports
Ted Kremenek
kremenek at apple.com
Fri Aug 27 14:34:58 PDT 2010
Author: kremenek
Date: Fri Aug 27 16:34:58 2010
New Revision: 112296
URL: http://llvm.org/viewvc/llvm-project?rev=112296&view=rev
Log:
Implement CXCursor support for walking C++ base specifiers. This includes adding the API hooks clang_isVirtualBase() and clang_getCXXAccessSpecifier() to query properties of the base specifier.
Implements <rdar://problem/8274883>.
Modified:
cfe/trunk/include/clang-c/Index.h
cfe/trunk/test/Index/load-stmts.cpp
cfe/trunk/tools/c-index-test/c-index-test.c
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/tools/libclang/CMakeLists.txt
cfe/trunk/tools/libclang/CXCursor.cpp
cfe/trunk/tools/libclang/CXCursor.h
cfe/trunk/tools/libclang/libclang.darwin.exports
cfe/trunk/tools/libclang/libclang.exports
Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Fri Aug 27 16:34:58 2010
@@ -1001,7 +1001,8 @@
* referenced by the type of size is the typedef for size_type.
*/
CXCursor_TypeRef = 43,
- CXCursor_LastRef = 43,
+ CXCursor_CXXBaseSpecifier = 44,
+ CXCursor_LastRef = CXCursor_CXXBaseSpecifier,
/* Error conditions */
CXCursor_FirstInvalid = 70,
@@ -1439,6 +1440,29 @@
CINDEX_LINKAGE unsigned clang_isPODType(CXType T);
/**
+ * \brief Returns 1 if the base class specified by the cursor with kind
+ * CX_CXXBaseSpecifier is virtual.
+ */
+CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor);
+
+/**
+ * \brief Represents the C++ access control level to a base class for a
+ * cursor with kind CX_CXXBaseSpecifier.
+ */
+enum CX_CXXAccessSpecifier {
+ CX_CXXInvalidAccessSpecifier,
+ CX_CXXPublic,
+ CX_CXXProtected,
+ CX_CXXPrivate
+};
+
+/**
+ * \brief Returns the access control level for the C++ base specifier
+ * represented by a cursor with kind CX_CXXBaseSpecifier.
+ */
+CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);
+
+/**
* @}
*/
Modified: cfe/trunk/test/Index/load-stmts.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/load-stmts.cpp?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/test/Index/load-stmts.cpp (original)
+++ cfe/trunk/test/Index/load-stmts.cpp Fri Aug 27 16:34:58 2010
@@ -10,6 +10,21 @@
}
}
+// Test handling of C++ base specifiers.
+class A {
+ void doA();
+};
+
+class B {
+ void doB();
+};
+
+class C : public A, private B {
+ void doC();
+};
+
+class D : virtual public C, virtual private A {};
+
// RUN: c-index-test -test-load-source all %s | FileCheck %s
// CHECK: load-stmts.cpp:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14]
// CHECK: load-stmts.cpp:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23]
@@ -56,4 +71,15 @@
// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:3 - 9:17]
// CHECK: load-stmts.cpp:9:8: UnexposedExpr= Extent=[9:8 - 9:10]
// CHECK: <invalid loc>:0:0: UnexposedStmt= Extent=[9:12 - 9:17]
+// CHECK: load-stmts.cpp:14:7: ClassDecl=A:14:7 (Definition) Extent=[14:1 - 16:2]
+// CHECK: load-stmts.cpp:15:8: CXXMethod=doA:15:8 Extent=[15:8 - 15:13]
+// CHECK: load-stmts.cpp:18:7: ClassDecl=B:18:7 (Definition) Extent=[18:1 - 20:2]
+// CHECK: load-stmts.cpp:19:8: CXXMethod=doB:19:8 Extent=[19:8 - 19:13]
+// CHECK: load-stmts.cpp:22:7: ClassDecl=C:22:7 (Definition) Extent=[22:1 - 24:2]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class A:14:7 [access=public isVirtual=false]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class B:18:7 [access=private isVirtual=false]
+// CHECK: load-stmts.cpp:23:8: CXXMethod=doC:23:8 Extent=[23:8 - 23:13]
+// CHECK: load-stmts.cpp:26:7: ClassDecl=D:26:7 (Definition) Extent=[26:1 - 26:49]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class C:22:7 [access=public isVirtual=true]
+// CHECK: <invalid loc>:0:0: C++ base class specifier=class A:14:7 [access=private isVirtual=true]
Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Fri Aug 27 16:34:58 2010
@@ -204,6 +204,26 @@
printf(" [IBOutletCollection=%s]", clang_getCString(S));
clang_disposeString(S);
}
+
+ if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
+ enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
+ unsigned isVirtual = clang_isVirtualBase(Cursor);
+ const char *accessStr = 0;
+
+ switch (access) {
+ case CX_CXXInvalidAccessSpecifier:
+ accessStr = "invalid"; break;
+ case CX_CXXPublic:
+ accessStr = "public"; break;
+ case CX_CXXProtected:
+ accessStr = "protected"; break;
+ case CX_CXXPrivate:
+ accessStr = "private"; break;
+ }
+
+ printf(" [access=%s isVirtual=%s]", accessStr,
+ isVirtual ? "true" : "false");
+ }
}
}
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Aug 27 16:34:58 2010
@@ -285,6 +285,7 @@
// Declaration visitors
bool VisitAttributes(Decl *D);
bool VisitBlockDecl(BlockDecl *B);
+ bool VisitCXXRecordDecl(CXXRecordDecl *D);
bool VisitDeclContext(DeclContext *DC);
bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
bool VisitTypedefDecl(TypedefDecl *D);
@@ -1080,6 +1081,19 @@
return false;
}
+bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
+ if (D->isDefinition()) {
+ for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
+ E = D->bases_end(); I != E; ++I) {
+ if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
+ return true;
+ }
+ }
+
+ return VisitTagDecl(D);
+}
+
+
bool CursorVisitor::VisitBlockExpr(BlockExpr *B) {
return Visit(B->getBlockDecl());
}
@@ -1825,6 +1839,10 @@
assert(OID && "getCursorSpelling(): Missing protocol decl");
return createCXString(OID->getIdentifier()->getNameStart());
}
+ case CXCursor_CXXBaseSpecifier: {
+ CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
+ return createCXString(B->getType().getAsString());
+ }
case CXCursor_TypeRef: {
TypeDecl *Type = getCursorTypeRef(C).first;
assert(Type && "Missing type decl");
@@ -1953,6 +1971,8 @@
return createCXString("Namespace");
case CXCursor_LinkageSpec:
return createCXString("LinkageSpec");
+ case CXCursor_CXXBaseSpecifier:
+ return createCXString("C++ base class specifier");
}
llvm_unreachable("Unhandled CXCursorKind");
@@ -2076,6 +2096,11 @@
std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
}
+
+ case CXCursor_CXXBaseSpecifier: {
+ // FIXME: Figure out what location to return for a CXXBaseSpecifier.
+ return clang_getNullLocation();
+ }
default:
// FIXME: Need a way to enumerate all non-reference cases.
@@ -2129,6 +2154,10 @@
case CXCursor_TypeRef:
return getCursorTypeRef(C).second;
+
+ case CXCursor_CXXBaseSpecifier:
+ // FIXME: Figure out what source range to use for a CXBaseSpecifier.
+ return SourceRange();
default:
// FIXME: Need a way to enumerate all non-reference cases.
@@ -2202,6 +2231,12 @@
case CXCursor_TypeRef:
return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit);
+
+ case CXCursor_CXXBaseSpecifier: {
+ CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+ return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
+ CXXUnit));
+ }
default:
// We would prefer to enumerate all non-reference cursor kinds here.
Modified: cfe/trunk/tools/libclang/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CMakeLists.txt?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CMakeLists.txt (original)
+++ cfe/trunk/tools/libclang/CMakeLists.txt Fri Aug 27 16:34:58 2010
@@ -21,6 +21,7 @@
add_clang_library(libclang
CIndex.cpp
+ CIndexCXX.cpp
CIndexCodeCompletion.cpp
CIndexDiagnostic.cpp
CIndexInclusionStack.cpp
Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Fri Aug 27 16:34:58 2010
@@ -302,6 +302,16 @@
reinterpret_cast<uintptr_t>(C.data[1])));
}
+CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){
+ CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
+ return C;
+}
+
+CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
+ assert(C.kind == CXCursor_CXXBaseSpecifier);
+ return static_cast<CXXBaseSpecifier*>(C.data[0]);
+}
+
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
ASTUnit *TU) {
CXCursor C = { CXCursor_PreprocessingDirective,
Modified: cfe/trunk/tools/libclang/CXCursor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.h?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.h (original)
+++ cfe/trunk/tools/libclang/CXCursor.h Fri Aug 27 16:34:58 2010
@@ -23,6 +23,7 @@
class ASTContext;
class ASTUnit;
class Attr;
+class CXXBaseSpecifier;
class Decl;
class Expr;
class MacroDefinition;
@@ -75,6 +76,12 @@
/// and optionally the location where the reference occurred.
std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
+/// \brief Create a CXX base specifier cursor.
+CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU);
+
+/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
+CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
+
/// \brief Create a preprocessing directive cursor.
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, ASTUnit *TU);
Modified: cfe/trunk/tools/libclang/libclang.darwin.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.darwin.exports?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.darwin.exports (original)
+++ cfe/trunk/tools/libclang/libclang.darwin.exports Fri Aug 27 16:34:58 2010
@@ -14,8 +14,8 @@
_clang_createTranslationUnit
_clang_createTranslationUnitFromSourceFile
_clang_defaultCodeCompleteOptions
-_clang_defaultEditingTranslationUnitOptions
_clang_defaultDiagnosticDisplayOptions
+_clang_defaultEditingTranslationUnitOptions
_clang_defaultReparseOptions
_clang_defaultSaveOptions
_clang_disposeCodeCompleteResults
@@ -30,7 +30,7 @@
_clang_equalTypes
_clang_formatDiagnostic
_clang_getCString
-_clang_getIBOutletCollectionType
+_clang_getCXXAccessSpecifier
_clang_getCanonicalType
_clang_getClangVersion
_clang_getCompletionAvailability
@@ -48,8 +48,8 @@
_clang_getCursorLinkage
_clang_getCursorLocation
_clang_getCursorReferenced
-_clang_getCursorSpelling
_clang_getCursorResultType
+_clang_getCursorSpelling
_clang_getCursorType
_clang_getCursorUSR
_clang_getDefinitionSpellingAndExtent
@@ -64,6 +64,7 @@
_clang_getFile
_clang_getFileName
_clang_getFileTime
+_clang_getIBOutletCollectionType
_clang_getInclusions
_clang_getInstantiationLocation
_clang_getLocation
@@ -89,12 +90,13 @@
_clang_isDeclaration
_clang_isExpression
_clang_isInvalid
-_clang_isPreprocessing
_clang_isPODType
+_clang_isPreprocessing
_clang_isReference
_clang_isStatement
_clang_isTranslationUnit
_clang_isUnexposed
+_clang_isVirtualBase
_clang_parseTranslationUnit
_clang_reparseTranslationUnit
_clang_saveTranslationUnit
Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=112296&r1=112295&r2=112296&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Fri Aug 27 16:34:58 2010
@@ -30,6 +30,7 @@
clang_equalTypes
clang_formatDiagnostic
clang_getCString
+clang_getCXXAccessSpecifier
clang_getCanonicalType
clang_getClangVersion
clang_getCompletionAvailability
@@ -95,6 +96,7 @@
clang_isStatement
clang_isTranslationUnit
clang_isUnexposed
+clang_isVirtualBase
clang_parseTranslationUnit
clang_reparseTranslationUnit
clang_saveTranslationUnit
More information about the cfe-commits
mailing list