diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-11-30 23:18:26 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-11-30 23:18:26 +0000 |
commit | 8d39c3ddfc17d9e768a17eb0ce9f11c33bf9d50a (patch) | |
tree | 6931105d484e9a86f4e4470c38479ec818c6a9c4 | |
parent | 436bd50a3821c0f7a859af0e423d5c0a55159bf1 (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.h | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 72 | ||||
-rw-r--r-- | test/PCH/pending-ids.m | 33 |
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 |