[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'? llvm-svn: 145536
This commit is contained in:
parent
8eeb353071
commit
b9e53ed4e2
@ -738,6 +738,7 @@ private:
|
||||
getModulePreprocessedEntity(unsigned GlobalIndex);
|
||||
|
||||
void PassInterestingDeclsToConsumer();
|
||||
void PassInterestingDeclToConsumer(Decl *D);
|
||||
|
||||
/// \brief Produce an error diagnostic and return true.
|
||||
///
|
||||
|
||||
@ -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();
|
||||
}
|
||||
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();
|
||||
|
||||
// Ready to load previous declarations of Decls that were delayed.
|
||||
while (!PendingPreviousDecls.empty()) {
|
||||
loadAndAttachPreviousDecl(PendingPreviousDecls.front().first,
|
||||
PendingPreviousDecls.front().second);
|
||||
PendingPreviousDecls.pop_front();
|
||||
}
|
||||
PassInterestingDeclToConsumer(D);
|
||||
}
|
||||
|
||||
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)
|
||||
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!");
|
||||
|
||||
33
clang/test/PCH/pending-ids.m
Normal file
33
clang/test/PCH/pending-ids.m
Normal file
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user