diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-17 08:11:25 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-17 08:11:25 +0000 |
commit | 917078386b9b5113f33c093e296e10927b00b37e (patch) | |
tree | 9271cfa2434d5b69916bdd121b47c11b8bdbb7b2 /lib/Serialization/ASTReader.cpp | |
parent | 2a76410c0a23a6feb98d0f13e9c8bfa0638d3adf (diff) |
[PCH] Don't deserialize bodies of interesting decls while iterating
over them because more interesting decls can be added during body
deserialization.
Should fix msvc build tests.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146824 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 90 |
1 files changed, 49 insertions, 41 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 00f7b7ad0e..3af04c2bc8 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -6024,56 +6024,64 @@ void ASTReader::ClearSwitchCaseIDs() { SwitchCaseStmts.clear(); } +void ASTReader::finishPendingActions() { + while (!PendingIdentifierInfos.empty() || + !PendingPreviousDecls.empty() || + !PendingChainedObjCCategories.empty()) { + + // 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(); + } +} + void ASTReader::FinishedDeserializing() { assert(NumCurrentElementsDeserializing && "FinishedDeserializing not paired with StartedDeserializing"); if (NumCurrentElementsDeserializing == 1) { - // Fully load the interesting decls, including deserializing their bodies, - // so that any other declarations that get referenced in the body will be - // fully deserialized by the time we pass them to the consumer. - for (std::deque<Decl *>::iterator - I = InterestingDecls.begin(), - E = InterestingDecls.end(); I != E; ++I) - (*I)->getBody(); - - 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(); - + while (Consumer && !InterestingDecls.empty()) { + finishPendingActions(); + // 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(); - - PassInterestingDeclToConsumer(D); + Decl *D = InterestingDecls.front(); + InterestingDecls.pop_front(); + + // Fully load the interesting decls, including deserializing their + // bodies, so that any other declarations that get referenced in the + // body will be fully deserialized by the time we pass them to the + // consumer. + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + if (FD->doesThisDeclarationHaveABody()) { + FD->getBody(); + finishPendingActions(); + } } - } while ((Consumer && !InterestingDecls.empty()) || - !PendingIdentifierInfos.empty() || - !PendingPreviousDecls.empty() || - !PendingChainedObjCCategories.empty()); + PassInterestingDeclToConsumer(D); + } + + finishPendingActions(); assert(PendingForwardRefs.size() == 0 && "Some forward refs did not get linked to the definition!"); |