]> granicus.if.org Git - clang/commitdiff
When libclang visits a translation unit via clang_visitChildren(),
authorDouglas Gregor <dgregor@apple.com>
Wed, 16 Mar 2011 23:23:30 +0000 (23:23 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 16 Mar 2011 23:23:30 +0000 (23:23 +0000)
walk the preprocessing record *before* walking the declarations, so
they we pretend that we actually respect the phases of translation.

We still walk the preprocessing record after the declarations when
performing token annotation or finding the cursor at a location, since
those routines depend on those semantics.

Fixes <rdar://problem/9137195>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127776 91177308-0d34-0410-b5e6-96231b3b80d8

test/Index/load-exprs.c
tools/libclang/CIndex.cpp

index 62df2a7c5d070e9db11de1525ca15b600869e081..a4723d88ef85d815420f81bfcdcf4c4a6c01f2e0 100644 (file)
@@ -32,7 +32,7 @@ void test_members(int aval, int bval) {
 }
 
 // RUN: c-index-test -test-load-source all %s -fblocks | FileCheck %s
-
+// CHECK: macro definition=__clang__
 // CHECK: load-exprs.c:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:1 - 1:14]
 // CHECK: load-exprs.c:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23]
 // CHECK: load-exprs.c:2:16: FieldDecl=a:2:16 (Definition) Extent=[2:12 - 2:17]
index 538efd7ae380b0731b2adfbcdb9437e14715bcb9..8d5c701d4772487050165058c7f81edc3c358aa0 100644 (file)
@@ -188,6 +188,10 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
   // be suppressed.
   unsigned MaxPCHLevel;
 
+  /// \brief Whether we should visit the preprocessing record entries last, 
+  /// after visiting other declarations.
+  bool VisitPreprocessorLast;
+  
   /// \brief When valid, a source range to which the cursor should restrict
   /// its search.
   SourceRange RegionOfInterest;
@@ -235,11 +239,12 @@ public:
   CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
                 CXClientData ClientData,
                 unsigned MaxPCHLevel,
+                bool VisitPreprocessorLast,
                 SourceRange RegionOfInterest = SourceRange())
     : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
       Visitor(Visitor), ClientData(ClientData),
-      MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest), 
-      DI_current(0)
+      MaxPCHLevel(MaxPCHLevel), VisitPreprocessorLast(VisitPreprocessorLast),
+      RegionOfInterest(RegionOfInterest), DI_current(0)
   {
     Parent.kind = CXCursor_NoDeclFound;
     Parent.data[0] = 0;
@@ -501,46 +506,54 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
   if (clang_isTranslationUnit(Cursor.kind)) {
     CXTranslationUnit tu = getCursorTU(Cursor);
     ASTUnit *CXXUnit = static_cast<ASTUnit*>(tu->TUData);
-    if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
-        RegionOfInterest.isInvalid()) {
-      for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
-                                    TLEnd = CXXUnit->top_level_end();
-           TL != TLEnd; ++TL) {
-        if (Visit(MakeCXCursor(*TL, tu), true))
+    
+    int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
+    for (unsigned I = 0; I != 2; ++I) {
+      if (VisitOrder[I]) {
+        if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
+            RegionOfInterest.isInvalid()) {
+          for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
+                                        TLEnd = CXXUnit->top_level_end();
+               TL != TLEnd; ++TL) {
+            if (Visit(MakeCXCursor(*TL, tu), true))
+              return true;
+          }
+        } else if (VisitDeclContext(
+                                CXXUnit->getASTContext().getTranslationUnitDecl()))
           return true;
+        continue;
       }
-    } else if (VisitDeclContext(
-                            CXXUnit->getASTContext().getTranslationUnitDecl()))
-      return true;
 
-    // Walk the preprocessing record.
-    if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
-      // FIXME: Once we have the ability to deserialize a preprocessing record,
-      // do so.
-      PreprocessingRecord::iterator E, EEnd;
-      for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
-        if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
-          if (Visit(MakeMacroInstantiationCursor(MI, tu)))
-            return true;
-          
-          continue;
-        }
-        
-        if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
-          if (Visit(MakeMacroDefinitionCursor(MD, tu)))
-            return true;
+      // Walk the preprocessing record.
+      if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
+        // FIXME: Once we have the ability to deserialize a preprocessing record,
+        // do so.
+        PreprocessingRecord::iterator E, EEnd;
+        for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) {
+          if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) {
+            if (Visit(MakeMacroInstantiationCursor(MI, tu)))
+              return true;
+            
+            continue;
+          }
           
-          continue;
-        }
-        
-        if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
-          if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
-            return true;
+          if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) {
+            if (Visit(MakeMacroDefinitionCursor(MD, tu)))
+              return true;
+            
+            continue;
+          }
           
-          continue;
+          if (InclusionDirective *ID = dyn_cast<InclusionDirective>(*E)) {
+            if (Visit(MakeInclusionDirectiveCursor(ID, tu)))
+              return true;
+            
+            continue;
+          }
         }
       }
     }
+    
     return false;
   }
 
@@ -2860,7 +2873,8 @@ unsigned clang_visitChildren(CXCursor parent,
                              CXCursorVisitor visitor,
                              CXClientData client_data) {
   CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data, 
-                          getCursorASTUnit(parent)->getMaxPCHLevel());
+                          getCursorASTUnit(parent)->getMaxPCHLevel(),
+                          false);
   return CursorVis.VisitChildren(parent);
 }
 
@@ -3316,7 +3330,7 @@ CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
     // the region of interest, rather than starting from the translation unit.
     CXCursor Parent = clang_getTranslationUnitCursor(TU);
     CursorVisitor CursorVis(TU, GetCursorVisitor, &Result,
-                            Decl::MaxPCHLevel, SourceLocation(SLoc));
+                            Decl::MaxPCHLevel, true, SourceLocation(SLoc));
     CursorVis.VisitChildren(Parent);
   }
   
@@ -4283,7 +4297,7 @@ public:
       NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
       AnnotateVis(tu,
                   AnnotateTokensVisitor, this,
-                  Decl::MaxPCHLevel, RegionOfInterest),
+                  Decl::MaxPCHLevel, true, RegionOfInterest),
       SrcMgr(static_cast<ASTUnit*>(tu->TUData)->getSourceManager()),
       HasContextSensitiveKeywords(false) { }