]> granicus.if.org Git - clang/commitdiff
When deserializing the definition of a C++ class/ObjC class/ObjC
authorDouglas Gregor <dgregor@apple.com>
Sun, 15 Jan 2012 18:08:05 +0000 (18:08 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 15 Jan 2012 18:08:05 +0000 (18:08 +0000)
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.

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

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

index 551dffa747ee8c4d03c1a78c026d3bb2e160361a..a5d3d9c93647116802632f5d8e266eff643b129d 100644 (file)
@@ -63,9 +63,6 @@ public:
   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
index c97c9f42c832b4590d34cce0d40b1096073f020f..8852d5dc67ccedb7c19d37d8ea0d23b82206e558 100644 (file)
@@ -689,7 +689,6 @@ public:
   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);
index b0aeabf68f8afc0b01799548a4ddd28cfd0bef80..6a3bdfd4bb4ff37832183a0e6340aee362a62cea 100644 (file)
@@ -245,9 +245,6 @@ void ObjCInterfaceDecl::startDefinition() {
     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 @@ void ObjCProtocolDecl::startDefinition() {
   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
        RD != RDEnd; ++RD)
     RD->Data = this->Data;
-  
-  if (ASTMutationListener *L = getASTContext().getASTMutationListener())
-    L->CompletedObjCForwardRef(this);
 }
 
 //===----------------------------------------------------------------------===//
index 2190844a8370240aa32e6565649dcaf269518525..16db8e36952fb2d1bfeaefb1ce963d097090a38e 100644 (file)
@@ -22,13 +22,10 @@ namespace clang {
 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);
index 6788d9ee5c642406a5ca12811e7e2497d1456b49..863aabb1734cc9d47525a5cbb58526c690ae7ff8 100644 (file)
@@ -677,6 +677,10 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
     // 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 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
     
     // 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 @@ void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
     // 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 @@ void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
     
     // 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 @@ void ASTDeclReader::InitializeCXXDefinitionData(CXXRecordDecl *D,
 
   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 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D,
             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 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
   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 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
       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;
-    }
     }
   }
 }
index d49e7110c3934bbd668ca6bdb12b24b2cd7bba63..20420d6ddcc1ea1d608ba6366c9ff776bbe9988a 100644 (file)
@@ -3519,12 +3519,9 @@ void ASTWriter::ResolveDeclUpdatesBlocks() {
     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 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
       // 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 @@ void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
   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,
index 612608159b2bf6e40c2d0f6e56ce31a11db6f249..79c4d620bee9f7f720b0a2c0896347dc45d9f9ba 100644 (file)
@@ -3,3 +3,5 @@
 @class C4;
 void accept_a_C4(C4*);
 
+@class ClassWithDef;
+
index 86a3993bc47ce36c1351c55823b45bf27a662735..113ff2217410b71b582bc15b6a9298e9d8df64f9 100644 (file)
@@ -88,3 +88,7 @@ public:
 int ONE;
 @import redecl_merge_top.Explicit;
 const int one = ONE;
+
+@interface ClassWithDef 
+- (void)method;
+@end
index cb44a13d184afbbe86e0e56b6124e55cbc0d467b..591c4a29a9e64f6f79f8977215cd6623c7a12b4d 100644 (file)
@@ -110,6 +110,9 @@ void test_C3(C3 *c3) {
 }
 
 C4 *global_C4;
+
+ClassWithDef *cwd1;
+
 @import redecl_merge_left_left;
 
 void test_C4a(C4 *c4) {
@@ -117,6 +120,10 @@ void test_C4a(C4 *c4) {
   accept_a_C4(c4);
 }
 
+void test_ClassWithDef(ClassWithDef *cwd) {
+  [cwd method];
+}
+
 @import redecl_merge_bottom;
 
 void test_C4b() {