Move the data that corresponds to the definition of a protocol into a
separately-allocated DefinitionData structure. Introduce various
functions that will help with the separation of declarations from
definitions (isThisDeclarationADefinition(), hasDefinition(),
getDefinition()).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147408 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 476f8b5..f88a394 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -764,17 +764,29 @@
   PD->InitiallyForwardDecl = Record[Idx++];
   PD->isForwardProtoDecl = Record[Idx++];
   PD->setLocEnd(ReadSourceLocation(Record, Idx));
-  unsigned NumProtoRefs = Record[Idx++];
-  SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
-  ProtoRefs.reserve(NumProtoRefs);
-  for (unsigned I = 0; I != NumProtoRefs; ++I)
-    ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  SmallVector<SourceLocation, 16> ProtoLocs;
-  ProtoLocs.reserve(NumProtoRefs);
-  for (unsigned I = 0; I != NumProtoRefs; ++I)
-    ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
-  PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
-                      Reader.getContext());
+  
+  ObjCProtocolDecl *Def = ReadDeclAs<ObjCProtocolDecl>(Record, Idx);
+  if (PD == Def) {
+    // Read the definition.
+    PD->allocateDefinitionData();
+    
+    unsigned NumProtoRefs = Record[Idx++];
+    SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+    ProtoRefs.reserve(NumProtoRefs);
+    for (unsigned I = 0; I != NumProtoRefs; ++I)
+      ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
+    SmallVector<SourceLocation, 16> ProtoLocs;
+    ProtoLocs.reserve(NumProtoRefs);
+    for (unsigned I = 0; I != NumProtoRefs; ++I)
+      ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
+    PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
+                        Reader.getContext());
+    
+    // FIXME: Note that we have deserialized a definition.
+    // Reader.PendingDefinitions.insert(PD);
+  } else if (Def && Def->Data) {
+    PD->Data = Def->Data;
+  }
 }
 
 void ASTDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 0692c02..f139485 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -519,16 +519,23 @@
 void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
   VisitObjCContainerDecl(D);
   Record.push_back(D->isInitiallyForwardDecl());
-  Record.push_back(D->isForwardDecl());
+  Record.push_back(D->isForwardProtoDecl);
   Writer.AddSourceLocation(D->getLocEnd(), Record);
-  Record.push_back(D->protocol_size());
-  for (ObjCProtocolDecl::protocol_iterator
-       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
-    Writer.AddDeclRef(*I, Record);
-  for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
-         PLEnd = D->protocol_loc_end();
-       PL != PLEnd; ++PL)
-    Writer.AddSourceLocation(*PL, Record);
+  
+  ObjCProtocolDecl *Def = D->getDefinition();
+  Writer.AddDeclRef(Def, Record);
+
+  if (D == Def) {
+    Record.push_back(D->protocol_size());
+    for (ObjCProtocolDecl::protocol_iterator
+         I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
+      Writer.AddDeclRef(*I, Record);
+    for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
+           PLEnd = D->protocol_loc_end();
+         PL != PLEnd; ++PL)
+      Writer.AddSourceLocation(*PL, Record);
+  }
+  
   Code = serialization::DECL_OBJC_PROTOCOL;
 }