]> granicus.if.org Git - clang/commitdiff
Delay passing InterestingDecls to the Consumer until when we know we are not in recur...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 7 Jul 2010 15:46:26 +0000 (15:46 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 7 Jul 2010 15:46:26 +0000 (15:46 +0000)
declarations are fully initialized.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107783 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/PCHReader.h
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHReaderDecl.cpp

index 651c3c80c2d853e4619e5011e9c275503c6ee196..9f917391068378560ce777ceddef00a18f0aabae 100644 (file)
@@ -453,7 +453,7 @@ private:
   /// "Interesting" declarations are those that have data that may
   /// need to be emitted, such as inline function definitions or
   /// Objective-C protocols.
-  llvm::SmallVector<Decl *, 16> InterestingDecls;
+  std::deque<Decl *> InterestingDecls;
 
   /// \brief When reading a Stmt tree, Stmt operands are placed in this stack.
   llvm::SmallVector<Stmt *, 16> StmtStack;
@@ -519,6 +519,8 @@ private:
   void LoadedDecl(unsigned Index, Decl *D);
   Decl *ReadDeclRecord(uint64_t Offset, unsigned Index);
 
+  void PassInterestingDeclsToConsumer();
+
   /// \brief Produce an error diagnostic and return true.
   ///
   /// This routine should only be used for fatal errors that have to
index 03a55367b460326c50db6035089db2b6a9fd9dc3..2b7dcacd03a20af5750fc2f04b3eddcf5bb50330 100644 (file)
@@ -2692,6 +2692,15 @@ PCHReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
   return const_cast<DeclContext*>(DC)->lookup(Name);
 }
 
+void PCHReader::PassInterestingDeclsToConsumer() {
+  assert(Consumer);
+  while (!InterestingDecls.empty()) {
+    DeclGroupRef DG(InterestingDecls.front());
+    InterestingDecls.pop_front();
+    Consumer->HandleTopLevelDecl(DG);
+  }
+}
+
 void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
   this->Consumer = Consumer;
 
@@ -2699,15 +2708,12 @@ void PCHReader::StartTranslationUnit(ASTConsumer *Consumer) {
     return;
 
   for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
-    // Force deserialization of this decl, which will cause it to be passed to
-    // the consumer (or queued).
+    // Force deserialization of this decl, which will cause it to be queued for
+    // passing to the consumer.
     GetDecl(ExternalDefinitions[I]);
   }
 
-  for (unsigned I = 0, N = InterestingDecls.size(); I != N; ++I) {
-    DeclGroupRef DG(InterestingDecls[I]);
-    Consumer->HandleTopLevelDecl(DG);
-  }
+  PassInterestingDeclsToConsumer();
 }
 
 void PCHReader::PrintStats() {
@@ -3340,6 +3346,11 @@ PCHReader::LoadingTypeOrDecl::~LoadingTypeOrDecl() {
                                      true);
       Reader.PendingIdentifierInfos.pop_front();
     }
+
+    // We are not in recursive loading, so it's safe to pass the "interesting"
+    // decls to the consumer.
+    if (Reader.Consumer)
+      Reader.PassInterestingDeclsToConsumer();
   }
 
   Reader.CurrentlyLoadingTypeOrDecl = Parent;
index 6b441e1c0d7cc198e7c922ed6b7b3deba1306009..0233886abe798a832bd4decc005693604a917f6c 100644 (file)
@@ -1474,16 +1474,11 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
   assert(Idx == Record.size());
 
   // If we have deserialized a declaration that has a definition the
-  // AST consumer might need to know about, notify the consumer
-  // about that definition now or queue it for later.
-  if (isConsumerInterestedIn(D)) {
-    if (Consumer) {
-      DeclGroupRef DG(D);
-      Consumer->HandleTopLevelDecl(DG);
-    } else {
-      InterestingDecls.push_back(D);
-    }
-  }
+  // 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(D))
+    InterestingDecls.push_back(D);
 
   return D;
 }