[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