Move property API's up to ObjCContainerDecl (removing a lot of duplicate code).
Add isa/cast/dyncast support for ObjCContainerDecl.
Renamed classprop_iterator/begin/end to prop_iterator/begin/end (the class prefix was confusing).
More simplifications to Sema::ActOnAtEnd()...
Added/changed some FIXME's as a result of the above work.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61988 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 83f8fa4..f1ce3f3 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -224,6 +224,7 @@
   case Field:               nFieldDecls++; break;
   case Record:              nSUC++; break;
   case Enum:                nEnumDecls++; break;
+  case ObjCContainer:       break; // is abstract...no need to account for.
   case ObjCInterface:       nInterfaceDecls++; break;
   case ObjCClass:           nClassDecls++; break;
   case ObjCMethod:          nMethodDecls++; break;
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index cf3bd0a..7e62fa1 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -62,11 +62,11 @@
 }
 
 ObjCContainerDecl::~ObjCContainerDecl() {
+  delete [] PropertyDecl;
 }
 
 ObjCInterfaceDecl::~ObjCInterfaceDecl() {
   delete [] Ivars;
-  delete [] PropertyDecl;
   // FIXME: CategoryList?
 }
 
@@ -274,37 +274,6 @@
   return true;
 }
 
-/// FindPropertyDeclaration - Finds declaration of the property given its name
-/// in 'PropertyId' and returns it. It returns 0, if not found.
-///
-ObjCPropertyDecl *
-  ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
-  for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(),
-       E = classprop_end(); I != E; ++I) {
-    ObjCPropertyDecl *property = *I;
-    if (property->getIdentifier() == PropertyId)
-      return property;
-  }
-  // Look through categories.
-  for (ObjCCategoryDecl *Category = getCategoryList();
-       Category; Category = Category->getNextClassCategory()) {
-    ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
-    if (property)
-      return property;
-  }
-  // Look through protocols.
-  for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(),
-       E = protocol_end(); I != E; ++I) {
-    ObjCProtocolDecl *Protocol = *I;
-    ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
-    if (property)
-      return property;
-  }
-  if (getSuperClass())
-    return getSuperClass()->FindPropertyDeclaration(PropertyId);
-  return 0;
-}
-
 /// FindCategoryDeclaration - Finds category declaration in the list of
 /// categories for this class and returns it. Name of the category is passed
 /// in 'CategoryId'. If category not found, return 0;
@@ -377,43 +346,6 @@
   }
 }
 
-/// addProperties - Insert property declaration AST nodes into
-/// ObjCInterfaceDecl's PropertyDecl field.
-///
-void ObjCInterfaceDecl::addProperties(ObjCPropertyDecl **Properties, 
-                                      unsigned NumProperties) {
-  if (NumProperties == 0) return;
-  
-  NumPropertyDecl = NumProperties;
-  PropertyDecl = new ObjCPropertyDecl*[NumProperties];
-  memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
-}                                   
-
-/// mergeProperties - Adds properties to the end of list of current properties
-/// for this class.
-
-void ObjCInterfaceDecl::mergeProperties(ObjCPropertyDecl **Properties, 
-                                        unsigned NumNewProperties) {
-  if (NumNewProperties == 0) return;
-  
-  if (PropertyDecl) {
-    ObjCPropertyDecl **newPropertyDecl =  
-      new ObjCPropertyDecl*[NumNewProperties + NumPropertyDecl];
-    ObjCPropertyDecl **buf = newPropertyDecl;
-    // put back original properties in buffer.
-    memcpy(buf, PropertyDecl, NumPropertyDecl*sizeof(ObjCPropertyDecl*));
-    // Add new properties to this buffer.
-    memcpy(buf+NumPropertyDecl, Properties, 
-           NumNewProperties*sizeof(ObjCPropertyDecl*));
-    delete[] PropertyDecl;
-    PropertyDecl = newPropertyDecl;
-    NumPropertyDecl += NumNewProperties;
-  }
-  else {
-    addProperties(Properties, NumNewProperties);
-  }
-}
-
 // Get the local instance method declared in this interface.
 // FIXME: handle overloading, instance & class methods can have the same name.
 ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
@@ -447,9 +379,9 @@
 }
 
 /// mergeProperties - Adds properties to the end of list of current properties
-/// for this category.
+/// for this class.
 
-void ObjCCategoryDecl::mergeProperties(ObjCPropertyDecl **Properties, 
+void ObjCContainerDecl::mergeProperties(ObjCPropertyDecl **Properties, 
                                         unsigned NumNewProperties) {
   if (NumNewProperties == 0) return;
   
@@ -472,22 +404,10 @@
 }
 
 /// addProperties - Insert property declaration AST nodes into
-/// ObjCProtocolDecl's PropertyDecl field.
+/// ObjCContainerDecl's PropertyDecl field.
 ///
-void ObjCProtocolDecl::addProperties(ObjCPropertyDecl **Properties, 
-                                     unsigned NumProperties) {
-  if (NumProperties == 0) return;
-  
-  NumPropertyDecl = NumProperties;
-  PropertyDecl = new ObjCPropertyDecl*[NumProperties];
-  memcpy(PropertyDecl, Properties, NumProperties*sizeof(ObjCPropertyDecl*));
-}
-
-/// addProperties - Insert property declaration AST nodes into
-/// ObjCCategoryDecl's PropertyDecl field.
-///
-void ObjCCategoryDecl::addProperties(ObjCPropertyDecl **Properties, 
-                                     unsigned NumProperties) {
+void ObjCContainerDecl::addProperties(ObjCPropertyDecl **Properties, 
+                                      unsigned NumProperties) {
   if (NumProperties == 0) return;
   
   NumPropertyDecl = NumProperties;
@@ -499,26 +419,31 @@
 /// in 'PropertyId' and returns it. It returns 0, if not found.
 ///
 ObjCPropertyDecl *
-ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
-  for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(),
-       E = classprop_end(); I != E; ++I) {
+ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
+  for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) {
     ObjCPropertyDecl *property = *I;
     if (property->getIdentifier() == PropertyId)
       return property;
   }
-  return 0;
-}
-
-/// FindPropertyDeclaration - Finds declaration of the property given its name
-/// in 'PropertyId' and returns it. It returns 0, if not found.
-///
-ObjCPropertyDecl *
-ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
-  for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(),
-       E = classprop_end(); I != E; ++I) {
-    ObjCPropertyDecl *property = *I;
-    if (property->getIdentifier() == PropertyId)
-      return property;
+  const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this);
+  if (OID) {
+    // Look through categories.
+    for (ObjCCategoryDecl *Category = OID->getCategoryList();
+         Category; Category = Category->getNextClassCategory()) {
+      ObjCPropertyDecl *property = Category->FindPropertyDeclaration(PropertyId);
+      if (property)
+        return property;
+    }
+    // Look through protocols.
+    for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
+         E = OID->protocol_end(); I != E; ++I) {
+      ObjCProtocolDecl *Protocol = *I;
+      ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId);
+      if (property)
+        return property;
+    }
+    if (OID->getSuperClass())
+      return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
   }
   return 0;
 }
diff --git a/lib/AST/TranslationUnit.cpp b/lib/AST/TranslationUnit.cpp
index adf6876..c02db82 100644
--- a/lib/AST/TranslationUnit.cpp
+++ b/lib/AST/TranslationUnit.cpp
@@ -46,8 +46,8 @@
       //  eventually be fixed when the ownership of ObjCPropertyDecls gets
       //  cleaned up.
       if (ObjCInterfaceDecl* IDecl = dyn_cast<ObjCInterfaceDecl>(*I))
-        for (ObjCInterfaceDecl::classprop_iterator ID=IDecl->classprop_begin(),
-             ED=IDecl->classprop_end(); ID!=ED; ++ID) {
+        for (ObjCInterfaceDecl::prop_iterator ID=IDecl->prop_begin(),
+             ED=IDecl->prop_end(); ID!=ED; ++ID) {
           if (!*ID || Killed.count(*ID)) continue;
           Killed.insert(*ID);
           (*ID)->Destroy(*Context);
@@ -59,8 +59,8 @@
       //  eventually be fixed when the ownership of ObjCPropertyDecls gets
       //  cleaned up.
       if (ObjCProtocolDecl* PDecl = dyn_cast<ObjCProtocolDecl>(*I))
-        for (ObjCProtocolDecl::classprop_iterator ID=PDecl->classprop_begin(),
-             ED=PDecl->classprop_end(); ID!=ED; ++ID) {
+        for (ObjCProtocolDecl::prop_iterator ID=PDecl->prop_begin(),
+             ED=PDecl->prop_end(); ID!=ED; ++ID) {
           if (!*ID || Killed.count(*ID)) continue;
           Killed.insert(*ID);
           (*ID)->Destroy(*Context);
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 03f7b78..873f21e 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -782,8 +782,8 @@
   Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + 
                                    PD->getNameAsString(),
                                0,
-                               PD->classprop_begin(),
-                               PD->classprop_end());
+                               PD->prop_begin(),
+                               PD->prop_end());
 
   // Return null if no extension bits are used.
   if (Values[1]->isNullValue() && Values[2]->isNullValue() && 
@@ -1002,8 +1002,8 @@
   if (Category) {
     Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
                                  OCD,
-                                 Category->classprop_begin(),
-                                 Category->classprop_end());
+                                 Category->prop_begin(),
+                                 Category->prop_end());
   } else {
     Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
   }
@@ -1279,8 +1279,8 @@
   Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
   Values[2] = EmitPropertyList("\01L_OBJC_$_PROP_LIST_" + ID->getNameAsString(),
                                ID,
-                               ID->getClassInterface()->classprop_begin(),
-                               ID->getClassInterface()->classprop_end());
+                               ID->getClassInterface()->prop_begin(),
+                               ID->getClassInterface()->prop_end());
 
   // Return null if no extension bits are used.
   if (Values[1]->isNullValue() && Values[2]->isNullValue())
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 5f191a2..2599561 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -320,12 +320,12 @@
   if (!SDecl)
     return;
   // FIXME: O(N^2)
-  for (ObjCInterfaceDecl::classprop_iterator S = SDecl->classprop_begin(),
-       E = SDecl->classprop_end(); S != E; ++S) {
+  for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
+       E = SDecl->prop_end(); S != E; ++S) {
     ObjCPropertyDecl *SuperPDecl = (*S);
     // Does property in super class has declaration in current class?
-    for (ObjCInterfaceDecl::classprop_iterator I = IDecl->classprop_begin(),
-         E = IDecl->classprop_end(); I != E; ++I) {
+    for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(),
+         E = IDecl->prop_end(); I != E; ++I) {
       ObjCPropertyDecl *PDecl = (*I);
       if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
           DiagnosePropertyMismatch(PDecl, SuperPDecl, 
@@ -346,12 +346,12 @@
     // Category
     ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
     assert (CatDecl && "MergeOneProtocolPropertiesIntoClass");
-    for (ObjCProtocolDecl::classprop_iterator P = PDecl->classprop_begin(),
-         E = PDecl->classprop_end(); P != E; ++P) {
+    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+         E = PDecl->prop_end(); P != E; ++P) {
       ObjCPropertyDecl *Pr = (*P);
-      ObjCCategoryDecl::classprop_iterator CP, CE;
+      ObjCCategoryDecl::prop_iterator CP, CE;
       // Is this property already in  category's list of properties?
-      for (CP = CatDecl->classprop_begin(), CE = CatDecl->classprop_end(); 
+      for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); 
            CP != CE; ++CP)
         if ((*CP)->getIdentifier() == Pr->getIdentifier())
           break;
@@ -365,12 +365,12 @@
     CatDecl->mergeProperties(&mergeProperties[0], mergeProperties.size());
     return;
   }
-  for (ObjCProtocolDecl::classprop_iterator P = PDecl->classprop_begin(),
-       E = PDecl->classprop_end(); P != E; ++P) {
+  for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+       E = PDecl->prop_end(); P != E; ++P) {
     ObjCPropertyDecl *Pr = (*P);
-    ObjCInterfaceDecl::classprop_iterator CP, CE;
+    ObjCInterfaceDecl::prop_iterator CP, CE;
     // Is this property already in  class's list of properties?
-    for (CP = IDecl->classprop_begin(), CE = IDecl->classprop_end(); 
+    for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); 
          CP != CE; ++CP)
       if ((*CP)->getIdentifier() == Pr->getIdentifier())
         break;
@@ -1153,19 +1153,13 @@
         isa<ObjCInterfaceDecl>(ClassDecl) || isa<ObjCCategoryDecl>(ClassDecl)
          || isa<ObjCProtocolDecl>(ClassDecl);
   bool checkIdenticalMethods = isa<ObjCImplementationDecl>(ClassDecl);
-  
-  
+
   if (pNum != 0) {
-    if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl))
-      IDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
-    else if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
+    if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl))
       CDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
-    else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(ClassDecl))
-      PDecl->addProperties((ObjCPropertyDecl**)allProperties, pNum);
     else
       assert(false && "ActOnAtEnd - property declaration misplaced");
   }
-
   DeclContext *DC = dyn_cast<DeclContext>(ClassDecl);
   assert(DC && "Missing DeclContext");
 
@@ -1218,38 +1212,29 @@
     // super class.
     ComparePropertiesInBaseAndSuper(I);
     MergeProtocolPropertiesIntoClass(I, I);
-    for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
-         e = I->classprop_end(); i != e; ++i) {
-      ProcessPropertyDecl((*i), I);
-    }
-    I->setAtEndLoc(AtEndLoc);
-  } else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
-    for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
-         e = P->classprop_end(); i != e; ++i) {
-      ProcessPropertyDecl((*i), P);
-    }
-    P->setAtEndLoc(AtEndLoc);
-  }
-  else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
+  } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
     // Categories are used to extend the class by declaring new methods.
     // By the same token, they are also used to add new properties. No 
     // need to compare the added property to those in the class.
 
     // Merge protocol properties into category
     MergeProtocolPropertiesIntoClass(C, C);
-    for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
-         e = C->classprop_end(); i != e; ++i) {
-      ProcessPropertyDecl((*i), C);
-    }
-    C->setAtEndLoc(AtEndLoc);
   }
-  else if (ObjCImplementationDecl *IC = 
-                dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
+  if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(ClassDecl)) {
+    // ProcessPropertyDecl is responsible for diagnosing conflicts with any
+    // user-defined setter/getter. It also synthesizes setter/getter methods
+    // and adds them to the DeclContext and global method pools.
+    for (ObjCContainerDecl::prop_iterator i = CDecl->prop_begin(),
+                                          e = CDecl->prop_end(); i != e; ++i)
+      ProcessPropertyDecl((*i), CDecl);
+    CDecl->setAtEndLoc(AtEndLoc);
+  }
+  if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
     IC->setLocEnd(AtEndLoc);
     if (ObjCInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier()))
       ImplMethodsVsClassMethods(IC, IDecl);
-  } else {
-    ObjCCategoryImplDecl* CatImplClass = cast<ObjCCategoryImplDecl>(ClassDecl);
+  } else if (ObjCCategoryImplDecl* CatImplClass = 
+                                   dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
     CatImplClass->setLocEnd(AtEndLoc);
     ObjCInterfaceDecl* IDecl = CatImplClass->getClassInterface();
     // Find category interface decl and then check that all methods declared