diff options
| -rw-r--r-- | clang/include/clang/Serialization/ASTReader.h | 18 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 25 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 35 |
3 files changed, 47 insertions, 31 deletions
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index de122e63ba8..63ccb246161 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -984,14 +984,26 @@ private: /// \brief The generation number of each identifier, which keeps track of /// the last time we loaded information about this identifier. llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration; - - /// \brief Contains declarations and definitions that will be + + class InterestingDecl { + Decl *D; + bool DeclHasPendingBody; + + public: + InterestingDecl(Decl *D, bool HasBody) + : D(D), DeclHasPendingBody(HasBody) {} + Decl *getDecl() { return D; } + /// Whether the declaration has a pending body. + bool hasPendingBody() { return DeclHasPendingBody; } + }; + + /// \brief Contains declarations and definitions that could be /// "interesting" to the ASTConsumer, when we get that AST consumer. /// /// "Interesting" declarations are those that have data that may /// need to be emitted, such as inline function definitions or /// Objective-C protocols. - std::deque<Decl *> InterestingDecls; + std::deque<InterestingDecl> PotentiallyInterestingDecls; /// \brief The list of redeclaration chains that still need to be /// reconstructed, and the local offset to the corresponding list diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 78f71b3efeb..406c4b50d92 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7234,31 +7234,6 @@ static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD, Consumer->HandleInterestingDecl(DeclGroupRef(ImplD)); } -void ASTReader::PassInterestingDeclsToConsumer() { - assert(Consumer); - - if (PassingDeclsToConsumer) - return; - - // Guard variable to avoid recursively redoing the process of passing - // decls to consumer. - SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer, - true); - - // Ensure that we've loaded all potentially-interesting declarations - // that need to be eagerly loaded. - for (auto ID : EagerlyDeserializedDecls) - GetDecl(ID); - EagerlyDeserializedDecls.clear(); - - while (!InterestingDecls.empty()) { - Decl *D = InterestingDecls.front(); - InterestingDecls.pop_front(); - - PassInterestingDeclToConsumer(D); - } -} - void ASTReader::PassInterestingDeclToConsumer(Decl *D) { if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D)) PassObjCImplDeclToConsumer(ImplD, Consumer); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 2fb882c1bec..e0304d22fe5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3626,12 +3626,37 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // AST consumer might need to know about, queue it. // We don't pass it to the consumer immediately because we may be in recursive // loading, and some declarations may still be initializing. - if (isConsumerInterestedIn(Context, D, Reader.hasPendingBody())) - InterestingDecls.push_back(D); + PotentiallyInterestingDecls.push_back( + InterestingDecl(D, Reader.hasPendingBody())); return D; } +void ASTReader::PassInterestingDeclsToConsumer() { + assert(Consumer); + + if (PassingDeclsToConsumer) + return; + + // Guard variable to avoid recursively redoing the process of passing + // decls to consumer. + SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer, + true); + + // Ensure that we've loaded all potentially-interesting declarations + // that need to be eagerly loaded. + for (auto ID : EagerlyDeserializedDecls) + GetDecl(ID); + EagerlyDeserializedDecls.clear(); + + while (!PotentiallyInterestingDecls.empty()) { + InterestingDecl D = PotentiallyInterestingDecls.front(); + PotentiallyInterestingDecls.pop_front(); + if (isConsumerInterestedIn(Context, D.getDecl(), D.hasPendingBody())) + PassInterestingDeclToConsumer(D.getDecl()); + } +} + void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { // The declaration may have been modified by files later in the chain. // If this is the case, read the record containing the updates from each file @@ -3642,6 +3667,9 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { auto UpdateOffsets = std::move(UpdI->second); DeclUpdateOffsets.erase(UpdI); + // FIXME: This call to isConsumerInterestedIn is not safe because + // we could be deserializing declarations at the moment. We should + // delay calling this in the same way as done in D30793. bool WasInteresting = isConsumerInterestedIn(Context, D, false); for (auto &FileAndOffset : UpdateOffsets) { ModuleFile *F = FileAndOffset.first; @@ -3663,7 +3691,8 @@ void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) { // we need to hand it off to the consumer. if (!WasInteresting && isConsumerInterestedIn(Context, D, Reader.hasPendingBody())) { - InterestingDecls.push_back(D); + PotentiallyInterestingDecls.push_back( + InterestingDecl(D, Reader.hasPendingBody())); WasInteresting = true; } } |

