]> granicus.if.org Git - clang/commitdiff
[PCH] Load the chained objc categories only after recursive loading is finished
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 14 Nov 2011 07:07:59 +0000 (07:07 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 14 Nov 2011 07:07:59 +0000 (07:07 +0000)
otherwise we may crash.

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

include/clang/Serialization/ASTReader.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTReaderDecl.cpp

index bef02f0d9586dae8b82bc7a4a6f0e73ac12767cd..7a9a15caf4f203f723d8267d985308a239e8bfdf 100644 (file)
@@ -624,6 +624,11 @@ private:
   /// deeply nested calls when there are many redeclarations.
   std::deque<std::pair<Decl *, serialization::DeclID> > PendingPreviousDecls;
 
+  /// \brief We delay loading the chain of objc categories after recursive
+  /// loading of declarations is finished.
+  std::vector<std::pair<ObjCInterfaceDecl *, serialization::DeclID> >
+    PendingChainedObjCCategories;
+
   /// \brief Ready to load the previous declaration of the given Decl.
   void loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID);
 
index 80b582e246dd7039eb8bffe4f945e03039f02df4..6192fb77517c6e9a1225bc37ff96b1faf8147501 100644 (file)
@@ -5543,6 +5543,14 @@ void ASTReader::FinishedDeserializing() {
       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)
index 729cde0abfba8d613f84df2f076526b60093622a..719f5bc06e11ca403b5642f68e972a2b3201d8f8 100644 (file)
@@ -1772,9 +1772,11 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
 
   // Load any relevant update records.
   loadDeclUpdateRecords(ID, D);
-  
+
+  // Load the category chain after recursive loading is finished.
   if (ObjCChainedCategoriesInterfaces.count(ID))
-    loadObjCChainedCategories(ID, cast<ObjCInterfaceDecl>(D));
+    PendingChainedObjCCategories.push_back(
+                                std::make_pair(cast<ObjCInterfaceDecl>(D), ID));
   
   // If we have deserialized a declaration that has a definition the
   // AST consumer might need to know about, queue it.