aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-11-30 23:18:26 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-11-30 23:18:26 +0000
commit8d39c3ddfc17d9e768a17eb0ce9f11c33bf9d50a (patch)
tree6931105d484e9a86f4e4470c38479ec818c6a9c4
parent436bd50a3821c0f7a859af0e423d5c0a55159bf1 (diff)
[PCH] In ASTReader::FinishedDeserializing, after we do PassInterestingDeclsToConsumer
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
-rw-r--r--include/clang/Serialization/ASTReader.h1
-rw-r--r--lib/Serialization/ASTReader.cpp72
-rw-r--r--test/PCH/pending-ids.m33
3 files changed, 77 insertions, 29 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index a641942fc5..8f7148d296 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -738,6 +738,7 @@ private:
getModulePreprocessedEntity(unsigned GlobalIndex);
void PassInterestingDeclsToConsumer();
+ void PassInterestingDeclToConsumer(Decl *D);
/// \brief Produce an error diagnostic and return true.
///
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index af12bf39fa..95a73c3181 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -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
index 0000000000..b612d89e94
--- /dev/null
+++ b/test/PCH/pending-ids.m
@@ -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