]> granicus.if.org Git - clang/commitdiff
[PCH] In ASTReader::FinishedDeserializing, after we do PassInterestingDeclsToConsumer
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 30 Nov 2011 23:18:26 +0000 (23:18 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 30 Nov 2011 23:18:26 +0000 (23:18 +0000)
we may end up having added more pending stuff to do, so go in a loop until everything
is cleared out.

This fixes the error in rdar://10278815 which has a certain David Lynch-esque quality..

  error: unknown type name 'BOOL'; did you mean 'BOOL'?

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

include/clang/Serialization/ASTReader.h
lib/Serialization/ASTReader.cpp
test/PCH/pending-ids.m [new file with mode: 0644]

index a641942fc5a07df82dc74e6e13c42460751ec684..8f7148d296583ccca08841f534bd70fe9beed7d7 100644 (file)
@@ -738,6 +738,7 @@ private:
     getModulePreprocessedEntity(unsigned GlobalIndex);
 
   void PassInterestingDeclsToConsumer();
+  void PassInterestingDeclToConsumer(Decl *D);
 
   /// \brief Produce an error diagnostic and return true.
   ///
index af12bf39fab1fe3e1fd60b1370a2816caa25bcd2..95a73c31819d815a7f0db07a5192480f4adcce22 100644 (file)
@@ -4531,13 +4531,17 @@ void ASTReader::PassInterestingDeclsToConsumer() {
     Decl *D = InterestingDecls.front();
     InterestingDecls.pop_front();
 
-    if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
-      PassObjCImplDeclToConsumer(ImplD, Consumer);
-    else
-      Consumer->HandleInterestingDecl(DeclGroupRef(D));
+    PassInterestingDeclToConsumer(D);
   }
 }
 
+void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
+  if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+    PassObjCImplDeclToConsumer(ImplD, Consumer);
+  else
+    Consumer->HandleInterestingDecl(DeclGroupRef(D));
+}
+
 void ASTReader::StartTranslationUnit(ASTConsumer *Consumer) {
   this->Consumer = Consumer;
 
@@ -5693,33 +5697,43 @@ void ASTReader::FinishedDeserializing() {
   assert(NumCurrentElementsDeserializing &&
          "FinishedDeserializing not paired with StartedDeserializing");
   if (NumCurrentElementsDeserializing == 1) {
-    // If any identifiers with corresponding top-level declarations have
-    // been loaded, load those declarations now.
-    while (!PendingIdentifierInfos.empty()) {
-      SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
-                              PendingIdentifierInfos.front().DeclIDs, true);
-      PendingIdentifierInfos.pop_front();
-    }
-
-    // Ready to load previous declarations of Decls that were delayed.
-    while (!PendingPreviousDecls.empty()) {
-      loadAndAttachPreviousDecl(PendingPreviousDecls.front().first,
-                                PendingPreviousDecls.front().second);
-      PendingPreviousDecls.pop_front();
-    }
+    do {
+      // If any identifiers with corresponding top-level declarations have
+      // been loaded, load those declarations now.
+      while (!PendingIdentifierInfos.empty()) {
+        SetGloballyVisibleDecls(PendingIdentifierInfos.front().II,
+                                PendingIdentifierInfos.front().DeclIDs, true);
+        PendingIdentifierInfos.pop_front();
+      }
+  
+      // Ready to load previous declarations of Decls that were delayed.
+      while (!PendingPreviousDecls.empty()) {
+        loadAndAttachPreviousDecl(PendingPreviousDecls.front().first,
+                                  PendingPreviousDecls.front().second);
+        PendingPreviousDecls.pop_front();
+      }
+  
+      for (std::vector<std::pair<ObjCInterfaceDecl *,
+                                 serialization::DeclID> >::iterator
+             I = PendingChainedObjCCategories.begin(),
+             E = PendingChainedObjCCategories.end(); I != E; ++I) {
+        loadObjCChainedCategories(I->second, I->first);
+      }
+      PendingChainedObjCCategories.clear();
+  
+      // We are not in recursive loading, so it's safe to pass the "interesting"
+      // decls to the consumer.
+      if (Consumer && !InterestingDecls.empty()) {
+        Decl *D = InterestingDecls.front();
+        InterestingDecls.pop_front();
 
-    for (std::vector<std::pair<ObjCInterfaceDecl *,
-                               serialization::DeclID> >::iterator
-           I = PendingChainedObjCCategories.begin(),
-           E = PendingChainedObjCCategories.end(); I != E; ++I) {
-      loadObjCChainedCategories(I->second, I->first);
-    }
-    PendingChainedObjCCategories.clear();
+        PassInterestingDeclToConsumer(D);
+      }
 
-    // We are not in recursive loading, so it's safe to pass the "interesting"
-    // decls to the consumer.
-    if (Consumer)
-      PassInterestingDeclsToConsumer();
+    } while ((Consumer && !InterestingDecls.empty()) ||
+             !PendingIdentifierInfos.empty() ||
+             !PendingPreviousDecls.empty() ||
+             !PendingChainedObjCCategories.empty());
 
     assert(PendingForwardRefs.size() == 0 &&
            "Some forward refs did not get linked to the definition!");
diff --git a/test/PCH/pending-ids.m b/test/PCH/pending-ids.m
new file mode 100644 (file)
index 0000000..b612d89
--- /dev/null
@@ -0,0 +1,33 @@
+// Test for rdar://10278815
+
+// Without PCH
+// RUN: %clang_cc1 -fsyntax-only -verify -include %s %s
+
+// With PCH
+// RUN: %clang_cc1 %s -emit-pch -o %t
+// RUN: %clang_cc1 -emit-llvm-only -verify %s -include-pch %t -g
+
+#ifndef HEADER
+#define HEADER
+//===----------------------------------------------------------------------===//
+// Header
+
+typedef char BOOL;
+
+@interface NSString
++ (BOOL)meth;
+@end
+
+static NSString * const cake = @"cake";
+
+//===----------------------------------------------------------------------===//
+#else
+//===----------------------------------------------------------------------===//
+
+@interface Foo {
+  BOOL ivar;
+}
+@end
+
+//===----------------------------------------------------------------------===//
+#endif