Patch to provide separate ASTs for multiple ObjC class extension 
declarations (implements radar 7928731).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106597 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index bb62e9e..80bda84 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -868,7 +868,8 @@
 void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
   // Find ivars declared in class extension.
-  if (const ObjCCategoryDecl *CDecl = OI->getClassExtension()) {
+  for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
+       CDecl = CDecl->getNextClassExtension()) {
     for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
          E = CDecl->ivar_end(); I != E; ++I) {
       Ivars.push_back(*I);
@@ -933,7 +934,8 @@
 unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) {
   unsigned count = 0;  
   // Count ivars declared in class extension.
-  if (const ObjCCategoryDecl *CDecl = OI->getClassExtension())
+  for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
+       CDecl = CDecl->getNextClassExtension())
     count += CDecl->ivar_size();
 
   // Count ivar defined in this class's implementation.  This
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 370dbc5..e1c2abd 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -2636,6 +2636,8 @@
   LexicalDC->addDecl(ToProperty);
 
   ToProperty->setPropertyAttributes(D->getPropertyAttributes());
+  ToProperty->setPropertyAttributesAsWritten(
+                                      D->getPropertyAttributesAsWritten());
   ToProperty->setGetterName(Importer.Import(D->getGetterName()));
   ToProperty->setSetterName(Importer.Import(D->getSetterName()));
   ToProperty->setGetterMethodDecl(
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 335e89b..adb0e7d 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -223,17 +223,24 @@
   setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
 }
 
-/// getClassExtension - Find class extension of the given class.
-// FIXME. can speed it up, if need be.
-ObjCCategoryDecl* ObjCInterfaceDecl::getClassExtension() const {
-  const ObjCInterfaceDecl* ClassDecl = this;
-  for (ObjCCategoryDecl *CDecl = ClassDecl->getCategoryList(); CDecl;
+/// getFirstClassExtension - Find first class extension of the given class.
+ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
+  for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
        CDecl = CDecl->getNextClassCategory())
     if (CDecl->IsClassExtension())
       return CDecl;
   return 0;
 }
 
+/// getNextClassCategory - Find next class extension in list of categories.
+const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
+  for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl; 
+        CDecl = CDecl->getNextClassCategory())
+    if (CDecl->IsClassExtension())
+      return CDecl;
+  return 0;
+}
+
 ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
                                               ObjCInterfaceDecl *&clsDeclared) {
   ObjCInterfaceDecl* ClassDecl = this;
@@ -242,11 +249,13 @@
       clsDeclared = ClassDecl;
       return I;
     }
-    if (const ObjCCategoryDecl *CDecl = ClassDecl->getClassExtension())
+    for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
+         CDecl; CDecl = CDecl->getNextClassExtension()) {
       if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
         clsDeclared = ClassDecl;
         return I;
       }
+    }
       
     ClassDecl = ClassDecl->getSuperClass();
   }