/// \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
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);
// 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
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;
// 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;
}
}