[cfe-commits] r148323 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/Type.h lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 17 11:21:53 PST 2012


Author: dgregor
Date: Tue Jan 17 13:21:53 2012
New Revision: 148323

URL: http://llvm.org/viewvc/llvm-project?rev=148323&view=rev
Log:
Rework the way in which we (de-)serialize the declarations
corresponding to TagType and ObjCInterfaceType. Previously, we would
serialize the definition (if available) or the canonical declaration
(if no definition was available). However, this can end up forcing the
deserialization of the definition even through we might not want to
yet. 

Instead, always serialize the canonical declaration reference in the
TagType/ObjCInterfaceType entry, and as part of loading a pending
definition, update the "decl" pointer within the type node to point at
the definition. This is more robust in hard-to-isolate cases
where the *Type gets built and filled in before we see the definition.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=148323&r1=148322&r2=148323&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Jan 17 13:21:53 2012
@@ -2225,6 +2225,7 @@
   friend class TagDecl;
   friend class TemplateTypeParmDecl;
   friend class TagType;
+  friend class ASTReader;
 
 protected:
   TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=148323&r1=148322&r2=148323&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Jan 17 13:21:53 2012
@@ -3070,6 +3070,8 @@
   /// TagDecl that declares the entity.
   TagDecl * decl;
 
+  friend class ASTReader;
+  
 protected:
   TagType(TypeClass TC, const TagDecl *D, QualType can);
 
@@ -4160,6 +4162,7 @@
     : ObjCObjectType(Nonce_ObjCInterface),
       Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
   friend class ASTContext;  // ASTContext creates these.
+  friend class ASTReader;
   friend class ObjCInterfaceDecl;
 
 public:

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=148323&r1=148322&r2=148323&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Jan 17 13:21:53 2012
@@ -3901,8 +3901,9 @@
     }
     unsigned Idx = 0;
     bool IsDependent = Record[Idx++];
-    QualType T
-      = Context.getRecordType(ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx));
+    RecordDecl *RD = ReadDeclAs<RecordDecl>(*Loc.F, Record, Idx);
+    RD = cast_or_null<RecordDecl>(RD->getCanonicalDecl());
+    QualType T = Context.getRecordType(RD);
     const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
     return T;
   }
@@ -3966,7 +3967,7 @@
     unsigned Idx = 0;
     ObjCInterfaceDecl *ItfD
       = ReadDeclAs<ObjCInterfaceDecl>(*Loc.F, Record, Idx);
-    return Context.getObjCInterfaceType(ItfD);
+    return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
   }
 
   case TYPE_OBJC_OBJECT: {
@@ -6124,6 +6125,7 @@
     // Load pending declaration chains.
     for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
       loadPendingDeclChain(PendingDeclChains[I]);
+      PendingDeclChainsKnown.erase(PendingDeclChains[I]);
     }
     PendingDeclChains.clear();
     
@@ -6143,16 +6145,28 @@
   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;
+    if (TagDecl *TD = dyn_cast<TagDecl>(*D)) {
+      if (const TagType *TagT = dyn_cast<TagType>(TD->TypeForDecl)) {
+        // Make sure that the TagType points at the definition.
+        const_cast<TagType*>(TagT)->decl = TD;
+      }
       
+      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;
     }
     
     if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
+      // Make sure that the ObjCInterfaceType points at the definition.
+      const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))
+        ->Decl = ID;
+      
       for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
                                            REnd = ID->redecls_end();
            R != REnd; ++R)

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=148323&r1=148322&r2=148323&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Jan 17 13:21:53 2012
@@ -239,7 +239,7 @@
 
 void ASTTypeWriter::VisitTagType(const TagType *T) {
   Record.push_back(T->isDependentType());
-  Writer.AddDeclRef(T->getDecl(), Record);
+  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
   assert(!T->isBeingDefined() &&
          "Cannot serialize in the middle of a type definition");
 }
@@ -369,7 +369,7 @@
 }
 
 void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
-  Writer.AddDeclRef(T->getDecl(), Record);
+  Writer.AddDeclRef(T->getDecl()->getCanonicalDecl(), Record);
   Code = TYPE_OBJC_INTERFACE;
 }
 





More information about the cfe-commits mailing list