Add pch reader/writer support for most of DeclObjC.h. Very close to reading/writing all ObjC AST nodes that we will encounter in header files (still a few FIXME's).

Once selector support is in place, we should be able to take this for a spin (and add test cases).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69674 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index e694a14..abdb24f 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -71,6 +71,17 @@
     void VisitObjCContainerDecl(ObjCContainerDecl *D);
     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
     void VisitObjCIvarDecl(ObjCIvarDecl *D);
+    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
+    void VisitObjCClassDecl(ObjCClassDecl *D);
+    void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    void VisitObjCImplDecl(ObjCImplDecl *D);
+    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
+    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
   };
 }
 
@@ -207,7 +218,6 @@
   ID->setImplicitInterfaceDecl(Record[Idx++]);
   ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
   // FIXME: add protocols, categories.
 }
 
@@ -216,6 +226,86 @@
   IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
 }
 
+void PCHDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
+  VisitObjCContainerDecl(PD);
+  PD->setForwardDecl(Record[Idx++]);
+  PD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  unsigned NumProtoRefs = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  ProtoRefs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  PD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
+}
+
+void PCHDeclReader::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *FD) {
+  VisitFieldDecl(FD);
+}
+
+void PCHDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
+  VisitDecl(CD);
+  unsigned NumClassRefs = Record[Idx++];
+  llvm::SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
+  ClassRefs.reserve(NumClassRefs);
+  for (unsigned I = 0; I != NumClassRefs; ++I)
+    ClassRefs.push_back(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  CD->setClassList(Reader.getContext(), &ClassRefs[0], NumClassRefs);
+}
+
+void PCHDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
+  VisitDecl(FPD);
+  unsigned NumProtoRefs = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  ProtoRefs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  FPD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
+}
+
+void PCHDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) {
+  VisitObjCContainerDecl(CD);
+  CD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  unsigned NumProtoRefs = Record[Idx++];
+  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  ProtoRefs.reserve(NumProtoRefs);
+  for (unsigned I = 0; I != NumProtoRefs; ++I)
+    ProtoRefs.push_back(cast<ObjCProtocolDecl>(Reader.GetDecl(Record[Idx++])));
+  CD->setProtocolList(&ProtoRefs[0], NumProtoRefs, Reader.getContext());
+  CD->setNextClassCategory(cast<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
+  CD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+
+void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
+  VisitNamedDecl(CAD);
+  CAD->setClassInterface(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
+void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  VisitNamedDecl(D);
+  // FIXME: Implement.
+}
+
+void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
+  VisitDecl(D);
+  // FIXME: Implement.
+}
+
+void PCHDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  VisitObjCImplDecl(D);
+  // FIXME: Implement.
+}
+
+void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  VisitObjCImplDecl(D);
+  // FIXME: Implement.
+}
+
+
+void PCHDeclReader::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  VisitDecl(D);
+  // FIXME: Implement.
+}
+
 void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
   VisitValueDecl(FD);
   FD->setMutable(Record[Idx++]);
@@ -1833,17 +1923,68 @@
     break;
   }
 
-  case pch::DECL_OBJC_INTERFACE_DECL: {
+  case pch::DECL_OBJC_INTERFACE: {
     D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
     break;
   }
 
-  case pch::DECL_OBJC_IVAR_DECL: {
+  case pch::DECL_OBJC_IVAR: {
     D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), 0, QualType(),
                              ObjCIvarDecl::None);
     break;
   }
 
+  case pch::DECL_OBJC_PROTOCOL: {
+    D = ObjCProtocolDecl::Create(Context, 0, SourceLocation(), 0);
+    break;
+  }
+
+  case pch::DECL_OBJC_AT_DEFS_FIELD: {
+    D = ObjCAtDefsFieldDecl::Create(Context, 0, SourceLocation(), 0, 
+                                    QualType(), 0);
+    break;
+  }
+
+  case pch::DECL_OBJC_CLASS: {
+    D = ObjCClassDecl::Create(Context, 0, SourceLocation());
+    break;
+  }
+
+  case pch::DECL_OBJC_FORWARD_PROTOCOL: {
+    D = ObjCForwardProtocolDecl::Create(Context, 0, SourceLocation());
+    break;
+  }
+
+  case pch::DECL_OBJC_CATEGORY: {
+    D = ObjCCategoryDecl::Create(Context, 0, SourceLocation(), 0);
+    break;
+  }
+
+  case pch::DECL_OBJC_CATEGORY_IMPL: {
+    // FIXME: Implement.
+    break;
+  }
+  
+  case pch::DECL_OBJC_IMPLEMENTATION: {
+    // FIXME: Implement.
+    break;
+  }
+  
+  case pch::DECL_OBJC_COMPATIBLE_ALIAS: {
+    // FIXME: Implement.
+    break;
+  }
+  
+  case pch::DECL_OBJC_PROPERTY: {
+    // FIXME: Implement.
+    break;
+  }
+  
+  case pch::DECL_OBJC_PROPERTY_IMPL: {
+    // FIXME: Implement.
+    break;
+  }
+
   case pch::DECL_FIELD: {
     D = FieldDecl::Create(Context, 0, SourceLocation(), 0, QualType(), 0, 
                           false);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 643b8db..16eaf98 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -277,6 +277,17 @@
     void VisitObjCContainerDecl(ObjCContainerDecl *D);
     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
     void VisitObjCIvarDecl(ObjCIvarDecl *D);
+    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    void VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D);
+    void VisitObjCClassDecl(ObjCClassDecl *D);
+    void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
+    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    void VisitObjCImplDecl(ObjCImplDecl *D);
+    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
+    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
   };
 }
 
@@ -412,14 +423,95 @@
   Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
   Writer.AddSourceLocation(D->getLocEnd(), Record);
   // FIXME: add protocols, categories.
-  Code = pch::DECL_OBJC_INTERFACE_DECL;
+  Code = pch::DECL_OBJC_INTERFACE;
 }
 
 void PCHDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
   VisitFieldDecl(D);
   // FIXME: stable encoding for @public/@private/@protected/@package
   Record.push_back(D->getAccessControl()); 
-  Code = pch::DECL_OBJC_IVAR_DECL;
+  Code = pch::DECL_OBJC_IVAR;
+}
+
+void PCHDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+  VisitObjCContainerDecl(D);
+  Record.push_back(D->isForwardDecl());
+  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);
+  Code = pch::DECL_OBJC_PROTOCOL;
+}
+
+void PCHDeclWriter::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
+  VisitFieldDecl(D);
+  Code = pch::DECL_OBJC_AT_DEFS_FIELD;
+}
+
+void PCHDeclWriter::VisitObjCClassDecl(ObjCClassDecl *D) {
+  VisitDecl(D);
+  Record.push_back(D->size());
+  for (ObjCClassDecl::iterator I = D->begin(), IEnd = D->end(); I != IEnd; ++I)
+    Writer.AddDeclRef(*I, Record);
+  Code = pch::DECL_OBJC_CLASS;
+}
+
+void PCHDeclWriter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
+  VisitDecl(D);
+  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);
+  Code = pch::DECL_OBJC_FORWARD_PROTOCOL;
+}
+
+void PCHDeclWriter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+  VisitObjCContainerDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), 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);
+  Writer.AddDeclRef(D->getNextClassCategory(), Record);
+  Writer.AddSourceLocation(D->getLocEnd(), Record);
+  Code = pch::DECL_OBJC_CATEGORY;
+}
+
+void PCHDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
+  VisitNamedDecl(D);
+  Writer.AddDeclRef(D->getClassInterface(), Record);
+  Code = pch::DECL_OBJC_COMPATIBLE_ALIAS;
+}
+
+void PCHDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+  VisitNamedDecl(D);
+  // FIXME: Implement.
+  Code = pch::DECL_OBJC_PROPERTY;
+}
+
+void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
+  VisitDecl(D);
+  // FIXME: Implement.
+  // Abstract class (no need to define a stable pch::DECL code).
+}
+
+void PCHDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  VisitObjCImplDecl(D);
+  // FIXME: Implement.
+  Code = pch::DECL_OBJC_CATEGORY_IMPL;
+}
+
+void PCHDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  VisitObjCImplDecl(D);
+  // FIXME: Implement.
+  Code = pch::DECL_OBJC_IMPLEMENTATION;
+}
+
+void PCHDeclWriter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  VisitDecl(D);
+  // FIXME: Implement.
+  Code = pch::DECL_OBJC_PROPERTY_IMPL;
 }
 
 void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {