[cfe-commits] r146886 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Serialization/ASTReader.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp test/Modules/redecl-merge.m

Douglas Gregor dgregor at apple.com
Mon Dec 19 11:00:48 PST 2011


Author: dgregor
Date: Mon Dec 19 13:00:47 2011
New Revision: 146886

URL: http://llvm.org/viewvc/llvm-project?rev=146886&view=rev
Log:
Once we have fully deserialized a redeclaration chain for something
with a definition pointer (e.g., C++ and Objective-C classes), zip
through the redeclaration chain to make sure that all of the
declarations point to the definition data. 

As part of this, realized again why the first redeclaration of an
entity in a file is important, and brought back that idea.


Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/Modules/redecl-merge.m

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=146886&r1=146885&r2=146886&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Dec 19 13:00:47 2011
@@ -928,6 +928,7 @@
   static bool classof(const ObjCInterfaceDecl *D) { return true; }
   static bool classofKind(Kind K) { return K == ObjCInterface; }
 
+  friend class ASTReader;
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
 };

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=146886&r1=146885&r2=146886&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Dec 19 13:00:47 2011
@@ -338,7 +338,10 @@
   /// the DefinitionData pointer of all pending references.
   PendingForwardRefsMap PendingForwardRefs;
 
-
+  /// \brief The set of C++ or Objective-C classes that have forward 
+  /// declarations that have not yet been linked to their definitions.
+  llvm::SmallPtrSet<Decl *, 4> PendingDefinitions;
+  
   typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID>
       FirstLatestDeclIDMap;
   /// \brief Map of first declarations from a chained PCH that point to the

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=146886&r1=146885&r2=146886&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Dec 19 13:00:47 2011
@@ -6095,6 +6095,29 @@
     }
     PendingChainedObjCCategories.clear();
   }
+  
+  // If we deserialized any C++ or Objective-C class definitions, make sure
+  // that all redeclarations point to the definitions. Note that this can only 
+  // happen now, after the redeclaration chains have been fully wired.
+  for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
+                                           DEnd = PendingDefinitions.end();
+       D != DEnd; ++D) {
+    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {
+      for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),
+                                       REnd = RD->redecls_end();
+           R != REnd; ++R)
+        cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;
+      
+      continue;
+    }
+    
+    ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(*D);
+    for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
+                                         REnd = ID->redecls_end();
+         R != REnd; ++R)
+      R->Data = ID->Data;
+  }
+  PendingDefinitions.clear();
 }
 
 void ASTReader::FinishedDeserializing() {

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=146886&r1=146885&r2=146886&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Dec 19 13:00:47 2011
@@ -630,6 +630,9 @@
       // pending references were linked.
       Reader.PendingForwardRefs.erase(ID);
 #endif
+      
+      // Note that we have deserialized a definition.
+      Reader.PendingDefinitions.insert(ID);
     }
   } else if (Def) {
     if (Def->Data) {
@@ -1030,6 +1033,9 @@
       Reader.PendingForwardRefs.erase(D);
 #endif
     }
+    
+    // Note that we have deserialized a definition.
+    Reader.PendingDefinitions.insert(D);
   } else if (DefinitionDecl) {
     if (DefinitionDecl->DefinitionData) {
       D->DefinitionData = DefinitionDecl->DefinitionData;
@@ -1162,7 +1168,7 @@
 void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
   // can be used while this is still initializing.
-  enum RedeclKind { FirstDeclaration, PointsToPrevious };
+  enum RedeclKind { FirstDeclaration, FirstInFile, PointsToPrevious };
   RedeclKind Kind = (RedeclKind)Record[Idx++];
   
   // Determine the first declaration ID.
@@ -1190,7 +1196,8 @@
     }
     break;
   }
-      
+   
+  case FirstInFile:
   case PointsToPrevious: {
     FirstDeclID = ReadDeclID(Record, Idx);
     DeclID PrevDeclID = ReadDeclID(Record, Idx);
@@ -1204,9 +1211,13 @@
     // loaded and attached later on.
     D->CommonOrPrev = FirstDecl;
     
-    // Make a note that we need to wire up this declaration to its
-    // previous declaration, later.
-    Reader.PendingPreviousDecls.push_back(std::make_pair(D, PrevDeclID));
+    if (Kind == PointsToPrevious) {
+      // Make a note that we need to wire up this declaration to its
+      // previous declaration, later. We don't need to do this for the first
+      // declaration in any given module file, because those will be wired 
+      // together later.
+      Reader.PendingPreviousDecls.push_back(std::make_pair(D, PrevDeclID));
+    }
     break;
   }
   }
@@ -1412,7 +1423,7 @@
 
 template <typename T>
 void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
-  enum RedeclKind { FirstDeclaration = 0, PointsToPrevious };
+  enum RedeclKind { FirstDeclaration = 0, FirstInFile, PointsToPrevious };
   RedeclKind Kind = (RedeclKind)Record[Idx++];
   
   DeclID FirstDeclID;
@@ -1420,7 +1431,8 @@
   case FirstDeclaration:
     FirstDeclID = ThisDeclID;
     break;
-      
+    
+  case FirstInFile:
   case PointsToPrevious: {
     FirstDeclID = ReadDeclID(Record, Idx);
     DeclID PrevDeclID = ReadDeclID(Record, Idx);
@@ -1433,10 +1445,14 @@
     // loaded & attached later on.
     D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl);
     
-    // Make a note that we need to wire up this declaration to its
-    // previous declaration, later.
-    Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
-                                                         PrevDeclID));
+    if (Kind == PointsToPrevious) {
+      // Make a note that we need to wire up this declaration to its
+      // previous declaration, later. We don't need to do this for the first
+      // declaration in any given module file, because those will be wired 
+      // together later.
+      Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
+                                                           PrevDeclID));
+    }
     break;
   }
   }

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=146886&r1=146885&r2=146886&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Dec 19 13:00:47 2011
@@ -1051,7 +1051,7 @@
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
   // getCommonPtr() can be used while this is still initializing.
-  enum { FirstDeclaration, PointsToPrevious };
+  enum { FirstDeclaration, FirstInFile, PointsToPrevious };
   RedeclarableTemplateDecl *Prev = D->getPreviousDeclaration();
   RedeclarableTemplateDecl *First = 0;
   if (!Prev) {
@@ -1063,7 +1063,7 @@
       Record.push_back(D->isMemberSpecialization());
   } else {
     First = D->getFirstDeclaration();
-    Record.push_back(PointsToPrevious);
+    Record.push_back(Prev->isFromASTFile()? FirstInFile : PointsToPrevious);
     Writer.AddDeclRef(First, Record);
     Writer.AddDeclRef(Prev, Record);    
   }
@@ -1276,14 +1276,14 @@
 
 template <typename T>
 void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
-  enum { FirstDeclaration = 0, PointsToPrevious };
+  enum { FirstDeclaration = 0, FirstInFile, PointsToPrevious };
   T *Prev = D->getPreviousDeclaration();
   T *First = D->getFirstDeclaration();
   
   if (!Prev) {
     Record.push_back(FirstDeclaration);
   } else {  
-    Record.push_back(PointsToPrevious);
+    Record.push_back(Prev->isFromASTFile()? FirstInFile : PointsToPrevious);
     Writer.AddDeclRef(First, Record);
     Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
   }

Modified: cfe/trunk/test/Modules/redecl-merge.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecl-merge.m?rev=146886&r1=146885&r2=146886&view=diff
==============================================================================
--- cfe/trunk/test/Modules/redecl-merge.m (original)
+++ cfe/trunk/test/Modules/redecl-merge.m Mon Dec 19 13:00:47 2011
@@ -32,7 +32,7 @@
 
 #ifdef __cplusplus
 void testVector() {
-  Vector<int> *vec_int;
-  // FIXME:  vec_int.push_back(0);
+  Vector<int> vec_int;
+  vec_int.push_back(0);
 }
 #endif





More information about the cfe-commits mailing list