[cfe-commits] r148223 - in /cfe/trunk: include/clang/AST/ASTMutationListener.h include/clang/Serialization/ASTWriter.h lib/AST/DeclObjC.cpp lib/Serialization/ASTCommon.h lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp test/Modules/Inputs/redecl-merge-left-left.h test/Modules/Inputs/redecl-merge-right.h test/Modules/redecl-merge.m

Douglas Gregor dgregor at apple.com
Sun Jan 15 10:08:05 PST 2012


Author: dgregor
Date: Sun Jan 15 12:08:05 2012
New Revision: 148223

URL: http://llvm.org/viewvc/llvm-project?rev=148223&view=rev
Log:
When deserializing the definition of a C++ class/ObjC class/ObjC
protocol, record the definition pointer in the canonical declaration
for that entity, and then propagate that definition pointer from the
canonical declaration to all other deserialized declarations. This
approach works well even when deserializing declarations that didn't
know about the original definition, which can occur with modules.

A nice bonus from this definition-deserialization approach is that we
no longer need update records when a definition is added, because the
redeclaration chains ensure that the if any declaration is loaded, the
definition will also get loaded.



Modified:
    cfe/trunk/include/clang/AST/ASTMutationListener.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Serialization/ASTCommon.h
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/redecl-merge-left-left.h
    cfe/trunk/test/Modules/Inputs/redecl-merge-right.h
    cfe/trunk/test/Modules/redecl-merge.m

Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)
+++ cfe/trunk/include/clang/AST/ASTMutationListener.h Sun Jan 15 12:08:05 2012
@@ -63,9 +63,6 @@
   virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
                                             const ObjCInterfaceDecl *IFD) {}
 
-  /// \brief A objc interface or protocol forward reference was completed.
-  virtual void CompletedObjCForwardRef(const ObjCContainerDecl *D) {}
-
   /// \brief A objc class extension redeclared or introduced a property.
   ///
   /// \param Prop the property in the class extension

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Sun Jan 15 12:08:05 2012
@@ -689,7 +689,6 @@
   virtual void StaticDataMemberInstantiated(const VarDecl *D);
   virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
                                             const ObjCInterfaceDecl *IFD);
-  virtual void CompletedObjCForwardRef(const ObjCContainerDecl *D);
   virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
                                             const ObjCPropertyDecl *OrigProp,
                                             const ObjCCategoryDecl *ClassExt);

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Sun Jan 15 12:08:05 2012
@@ -245,9 +245,6 @@
     if (*RD != this)
       RD->Data = Data;
   }
-
-  if (ASTMutationListener *L = getASTContext().getASTMutationListener())
-    L->CompletedObjCForwardRef(this);
 }
 
 /// getFirstClassExtension - Find first class extension of the given class.
@@ -1058,9 +1055,6 @@
   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
        RD != RDEnd; ++RD)
     RD->Data = this->Data;
-  
-  if (ASTMutationListener *L = getASTContext().getASTMutationListener())
-    L->CompletedObjCForwardRef(this);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Serialization/ASTCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.h (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.h Sun Jan 15 12:08:05 2012
@@ -22,13 +22,10 @@
 namespace serialization {
 
 enum DeclUpdateKind {
-  UPD_CXX_SET_DEFINITIONDATA,
   UPD_CXX_ADDED_IMPLICIT_MEMBER,
   UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
   UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
-  UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
-  UPD_OBJC_SET_CLASS_DEFINITIONDATA,
-  UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA
+  UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Jan 15 12:08:05 2012
@@ -677,6 +677,10 @@
     // Read the definition.
     ID->allocateDefinitionData();
     
+    // Set the definition data of the canonical declaration, so other
+    // redeclarations will see it.
+    ID->getCanonicalDecl()->Data = ID->Data;
+    
     ObjCInterfaceDecl::DefinitionData &Data = ID->data();
     
     // Read the superclass.
@@ -722,8 +726,8 @@
     
     // Note that we have deserialized a definition.
     Reader.PendingDefinitions.insert(ID);
-  } else if (Def && Def->Data) {
-    ID->Data = Def->Data;
+  } else {
+    ID->Data = ID->getCanonicalDecl()->Data;
   }
 }
 
@@ -746,6 +750,10 @@
     // Read the definition.
     PD->allocateDefinitionData();
     
+    // Set the definition data of the canonical declaration, so other
+    // redeclarations will see it.
+    PD->getCanonicalDecl()->Data = PD->Data;
+
     unsigned NumProtoRefs = Record[Idx++];
     SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
     ProtoRefs.reserve(NumProtoRefs);
@@ -760,8 +768,8 @@
     
     // Note that we have deserialized a definition.
     Reader.PendingDefinitions.insert(PD);
-  } else if (Def && Def->Data) {
-    PD->Data = Def->Data;
+  } else {
+    PD->Data = PD->getCanonicalDecl()->Data;
   }
 }
 
@@ -1104,12 +1112,21 @@
 
   if (D == DefinitionDecl) {
     D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
+    
+    // Propagate the DefinitionData pointer to the canonical declaration, so
+    // that all other deserialized declarations will see it.
+    // FIXME: Complain if there already is a DefinitionData!
+    D->getCanonicalDecl()->DefinitionData = D->DefinitionData;
+    
     ReadCXXDefinitionData(*D->DefinitionData, Record, Idx);
 
-    // Note that we have deserialized a definition.
+    // Note that we have deserialized a definition. Any declarations 
+    // deserialized before this one will be be given the DefinitionData pointer
+    // at the end.
     Reader.PendingDefinitions.insert(D);
-  } else if (DefinitionDecl && DefinitionDecl->DefinitionData) {
-    D->DefinitionData = DefinitionDecl->DefinitionData;
+  } else {
+    // Propagate DefinitionData pointer from the canonical declaration.
+    D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
   }
 }
 
@@ -1514,8 +1531,6 @@
             static_cast<NamespaceDecl *>(static_cast<void*>(ExistingCanon)));
         }
         
-        // FIXME: Update common pointer for RedeclarableTemplateDecls?
-        
         // Don't introduce DCanon into the set of pending declaration chains.
         Redecl.suppress();
         
@@ -2372,15 +2387,6 @@
   unsigned Idx = 0;
   while (Idx < Record.size()) {
     switch ((DeclUpdateKind)Record[Idx++]) {
-    case UPD_CXX_SET_DEFINITIONDATA: {
-      CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
-      CXXRecordDecl *DefinitionDecl
-        = Reader.ReadDeclAs<CXXRecordDecl>(ModuleFile, Record, Idx);
-      assert(!RD->DefinitionData && "DefinitionData is already set!");
-      InitializeCXXDefinitionData(RD, DefinitionDecl, Record, Idx);
-      break;
-    }
-
     case UPD_CXX_ADDED_IMPLICIT_MEMBER:
       cast<CXXRecordDecl>(D)->addedMember(Reader.ReadDecl(ModuleFile, Record, Idx));
       break;
@@ -2410,24 +2416,6 @@
       cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation(
           Reader.ReadSourceLocation(ModuleFile, Record, Idx));
       break;
-    
-    case UPD_OBJC_SET_CLASS_DEFINITIONDATA: {
-      ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
-      ObjCInterfaceDecl *Def
-        = Reader.ReadDeclAs<ObjCInterfaceDecl>(ModuleFile, Record, Idx);
-      if (Def->Data)
-        ID->Data = Def->Data;
-      break;
-    }
-
-    case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA: {
-      ObjCProtocolDecl *ID = cast<ObjCProtocolDecl>(D);
-      ObjCProtocolDecl *Def
-        = Reader.ReadDeclAs<ObjCProtocolDecl>(ModuleFile, Record, Idx);
-      if (Def->Data)
-        ID->Data = Def->Data;
-      break;
-    }
     }
   }
 }

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sun Jan 15 12:08:05 2012
@@ -3519,12 +3519,9 @@
     unsigned Idx = 0, N = URec.size();
     while (Idx < N) {
       switch ((DeclUpdateKind)URec[Idx++]) {
-      case UPD_CXX_SET_DEFINITIONDATA:
       case UPD_CXX_ADDED_IMPLICIT_MEMBER:
       case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
       case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
-      case UPD_OBJC_SET_CLASS_DEFINITIONDATA:
-      case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA:
         URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
         ++Idx;
         break;
@@ -4365,22 +4362,6 @@
       // have created a new definition decl instead ?
       RewriteDecl(RD);
     }
-
-    for (CXXRecordDecl::redecl_iterator
-           I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) {
-      CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I);
-      if (Redecl == RD)
-        continue;
-
-      // We are interested when a PCH decl is modified.
-      if (Redecl->isFromASTFile()) {
-        UpdateRecord &Record = DeclUpdates[Redecl];
-        Record.push_back(UPD_CXX_SET_DEFINITIONDATA);
-        assert(Redecl->DefinitionData);
-        assert(Redecl->DefinitionData->Definition == D);
-        Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
-      }
-    }
   }
 }
 void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
@@ -4474,45 +4455,6 @@
   LocalChainedObjCCategories.push_back(Data);
 }
 
-void ASTWriter::CompletedObjCForwardRef(const ObjCContainerDecl *D) {
-  assert(!WritingAST && "Already writing the AST!");
-
-  if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    for (ObjCInterfaceDecl::redecl_iterator I = ID->redecls_begin(), 
-                                            E = ID->redecls_end(); 
-         I != E; ++I) {
-      if (*I == ID)
-        continue;
-      
-      // We are interested when a PCH decl is modified.
-      if (I->isFromASTFile()) {
-        UpdateRecord &Record = DeclUpdates[*I];
-        Record.push_back(UPD_OBJC_SET_CLASS_DEFINITIONDATA);
-        assert((*I)->hasDefinition());
-        assert((*I)->getDefinition() == D);
-        Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
-      }
-    }
-  }
-
-  if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
-    for (ObjCProtocolDecl::redecl_iterator I = PD->redecls_begin(), 
-                                           E = PD->redecls_end(); 
-         I != E; ++I) {
-      if (*I == PD)
-        continue;
-      
-      // We are interested when a PCH decl is modified.
-      if (I->isFromASTFile()) {
-        UpdateRecord &Record = DeclUpdates[*I];
-        Record.push_back(UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA);
-        assert((*I)->hasDefinition());
-        assert((*I)->getDefinition() == D);
-        Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
-      }
-    }
-  }
-}
 
 void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
                                           const ObjCPropertyDecl *OrigProp,

Modified: cfe/trunk/test/Modules/Inputs/redecl-merge-left-left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-merge-left-left.h?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-merge-left-left.h (original)
+++ cfe/trunk/test/Modules/Inputs/redecl-merge-left-left.h Sun Jan 15 12:08:05 2012
@@ -3,3 +3,5 @@
 @class C4;
 void accept_a_C4(C4*);
 
+ at class ClassWithDef;
+

Modified: cfe/trunk/test/Modules/Inputs/redecl-merge-right.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/redecl-merge-right.h?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/redecl-merge-right.h (original)
+++ cfe/trunk/test/Modules/Inputs/redecl-merge-right.h Sun Jan 15 12:08:05 2012
@@ -88,3 +88,7 @@
 int ONE;
 @import redecl_merge_top.Explicit;
 const int one = ONE;
+
+ at interface ClassWithDef 
+- (void)method;
+ at end

Modified: cfe/trunk/test/Modules/redecl-merge.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecl-merge.m?rev=148223&r1=148222&r2=148223&view=diff
==============================================================================
--- cfe/trunk/test/Modules/redecl-merge.m (original)
+++ cfe/trunk/test/Modules/redecl-merge.m Sun Jan 15 12:08:05 2012
@@ -110,6 +110,9 @@
 }
 
 C4 *global_C4;
+
+ClassWithDef *cwd1;
+
 @import redecl_merge_left_left;
 
 void test_C4a(C4 *c4) {
@@ -117,6 +120,10 @@
   accept_a_C4(c4);
 }
 
+void test_ClassWithDef(ClassWithDef *cwd) {
+  [cwd method];
+}
+
 @import redecl_merge_bottom;
 
 void test_C4b() {





More information about the cfe-commits mailing list