This is a large/messy diff that unifies the ObjC AST's with DeclContext.

- ObjCContainerDecl's (ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl), ObjCCategoryImpl, & ObjCImplementation are all DeclContexts.
- ObjCMethodDecl is now a ScopedDecl (so it can play nicely with DeclContext).
- ObjCContainerDecl now does iteration/lookup using DeclContext infrastructure (no more linear search:-)
- Removed ASTContext argument to DeclContext::lookup(). It wasn't being used and complicated it's use from an ObjC AST perspective.
- Added Sema::ProcessPropertyDecl() and removed Sema::diagnosePropertySetterGetterMismatch().
- Simplified Sema::ActOnAtEnd() considerably. Still more work to do.
- Fixed an incorrect casting assumption in Sema::getCurFunctionOrMethodDecl(), now that ObjCMethodDecl is a ScopedDecl.
- Removed addPropertyMethods from ObjCInterfaceDecl/ObjCCategoryDecl/ObjCProtocolDecl.

This passes all the tests on my machine. Since many of the changes are central to the way ObjC finds it's methods, I expect some fallout (and there are still a handful of FIXME's). Nevertheless, this should be a step in the right direction.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61929 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f14dc3c..4989014 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -419,7 +419,7 @@
   return false;
 }
 
-DeclContext *DeclContext::getPrimaryContext(ASTContext &Context) {
+DeclContext *DeclContext::getPrimaryContext() {
   switch (DeclKind) {
   case Decl::TranslationUnit:
   case Decl::LinkageSpec:
@@ -468,9 +468,15 @@
     return this;
 
   case Decl::ObjCInterface:
+  case Decl::ObjCProtocol:
+  case Decl::ObjCCategory:
     // FIXME: Can Objective-C interfaces be forward-declared?
     return this;
 
+  case Decl::ObjCImplementation:
+  case Decl::ObjCCategoryImpl:
+    return this;
+
   default:
     assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
           "Unknown DeclContext kind");
@@ -486,6 +492,10 @@
   case Decl::CXXRecord:
   case Decl::ObjCMethod:
   case Decl::ObjCInterface:
+  case Decl::ObjCCategory:
+  case Decl::ObjCProtocol:
+  case Decl::ObjCImplementation:
+  case Decl::ObjCCategoryImpl:
   case Decl::LinkageSpec:
   case Decl::Block:
     // There is only one DeclContext for these entities.
@@ -511,7 +521,7 @@
 /// buildLookup - Build the lookup data structure with all of the
 /// declarations in DCtx (and any other contexts linked to it or
 /// transparent contexts nested within it).
-void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
+void DeclContext::buildLookup(DeclContext *DCtx) {
   for (; DCtx; DCtx = DCtx->getNextContext()) {
     for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end(); 
          D != DEnd; ++D) {
@@ -522,22 +532,22 @@
       // add its members (recursively).
       if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
         if (InnerCtx->isTransparentContext())
-          buildLookup(Context, InnerCtx->getPrimaryContext(Context));
+          buildLookup(InnerCtx->getPrimaryContext());
     }
   }
 }
 
 DeclContext::lookup_result 
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
-  DeclContext *PrimaryContext = getPrimaryContext(Context);
+DeclContext::lookup(DeclarationName Name) {
+  DeclContext *PrimaryContext = getPrimaryContext();
   if (PrimaryContext != this)
-    return PrimaryContext->lookup(Context, Name);
+    return PrimaryContext->lookup(Name);
 
   /// If there is no lookup data structure, build one now by walking
   /// all of the linked DeclContexts (in declaration order!) and
   /// inserting their values.
   if (LookupPtr.getPointer() == 0)
-    buildLookup(Context, this);
+    buildLookup(this);
 
   if (isLookupMap()) {
     StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
@@ -563,8 +573,8 @@
 }
 
 DeclContext::lookup_const_result 
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
-  return const_cast<DeclContext*>(this)->lookup(Context, Name);
+DeclContext::lookup(DeclarationName Name) const {
+  return const_cast<DeclContext*>(this)->lookup(Name);
 }
 
 const DeclContext *DeclContext::getLookupContext() const {
@@ -575,7 +585,7 @@
 }
 
 void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
-  DeclContext *PrimaryContext = getPrimaryContext(Context);
+  DeclContext *PrimaryContext = getPrimaryContext();
   if (PrimaryContext != this) {
     PrimaryContext->insert(Context, D);
     return;
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 7f787de..e3d7534 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -98,7 +98,7 @@
                                            Context.getCanonicalType(ClassType));
   unsigned TypeQuals;
   DeclContext::lookup_const_iterator Con, ConEnd;
-  for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
+  for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
        Con != ConEnd; ++Con) {
     if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context, TypeQuals) &&
         (TypeQuals & QualType::Const) != 0)
@@ -114,7 +114,7 @@
   DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
 
   DeclContext::lookup_const_iterator Op, OpEnd;
-  for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
+  for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
        Op != OpEnd; ++Op) {
     // C++ [class.copy]p9:
     //   A user-declared copy assignment operator is a non-static non-template
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 2bfad5a..0b6eff1 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -24,7 +24,7 @@
                                        SourceLocation beginLoc, 
                                        SourceLocation endLoc,
                                        Selector SelInfo, QualType T,
-                                       Decl *contextDecl,
+                                       DeclContext *contextDecl,
                                        bool isInstance,
                                        bool isVariadic,
                                        bool isSynthesized,
@@ -61,8 +61,6 @@
 }
 
 ObjCContainerDecl::~ObjCContainerDecl() {
-  delete [] InstanceMethods;
-  delete [] ClassMethods;
 }
 
 ObjCInterfaceDecl::~ObjCInterfaceDecl() {
@@ -362,7 +360,7 @@
   assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
   DeclarationName Member = ivar->getDeclName();
   DeclContext::lookup_result Lookup = (const_cast< RecordDecl *>(RecordForDecl))
-                                        ->lookup(Context, Member);
+                                        ->lookup(Member);
   assert((Lookup.first != Lookup.second) && "field decl not found");
   FieldDecl *MemberDecl = dyn_cast<FieldDecl>(*Lookup.first);
   assert(MemberDecl && "field decl not found");
@@ -382,27 +380,6 @@
   }
 }
 
-/// addMethods - Insert instance and methods declarations into
-/// ObjCInterfaceDecl's InsMethods and ClsMethods fields.
-///
-void ObjCContainerDecl::addMethods(ObjCMethodDecl **insMethods, 
-                                   unsigned numInsMembers,
-                                   ObjCMethodDecl **clsMethods,
-                                   unsigned numClsMembers,
-                                   SourceLocation endLoc) {
-  NumInstanceMethods = numInsMembers;
-  if (numInsMembers) {
-    InstanceMethods = new ObjCMethodDecl*[numInsMembers];
-    memcpy(InstanceMethods, insMethods, numInsMembers*sizeof(ObjCMethodDecl*));
-  }
-  NumClassMethods = numClsMembers;
-  if (numClsMembers) {
-    ClassMethods = new ObjCMethodDecl*[numClsMembers];
-    memcpy(ClassMethods, clsMethods, numClsMembers*sizeof(ObjCMethodDecl*));
-  }
-  AtEndLoc = endLoc;
-}
-
 /// addProperties - Insert property declaration AST nodes into
 /// ObjCInterfaceDecl's PropertyDecl field.
 ///
@@ -440,18 +417,45 @@
   }
 }
 
-static void 
-addPropertyMethods(Decl *D,
-                   ASTContext &Context,
-                   ObjCPropertyDecl *property,
-                   llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-                   llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ObjCMethodDecl *GetterDecl, *SetterDecl = 0;
-  
-  GetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getGetterName()]);
-  if (!property->isReadOnly())
-    SetterDecl = const_cast<ObjCMethodDecl*>(InsMap[property->getSetterName()]);
-  
+// 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 {
+  lookup_const_result MethodResult = lookup(Sel);
+  if (MethodResult.first)
+    return const_cast<ObjCMethodDecl*>(
+             dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+  return 0;
+}
+
+// Get the local class method declared in this interface.
+ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const {
+  lookup_const_result MethodResult = lookup(Sel);
+  if (MethodResult.first)
+    return const_cast<ObjCMethodDecl*>(
+             dyn_cast<ObjCMethodDecl>(*MethodResult.first));
+  return 0;
+}
+
+unsigned ObjCContainerDecl::getNumInstanceMethods() const {
+  unsigned sum = 0;
+  for (instmeth_iterator I=instmeth_begin(), E=instmeth_end(); I != E; ++I)
+    sum++;
+  return sum;
+}
+unsigned ObjCContainerDecl::getNumClassMethods() const { 
+  unsigned sum = 0;
+  for (classmeth_iterator I=classmeth_begin(), E=classmeth_end(); I != E; ++I)
+    sum++;
+  return sum;
+}
+
+/// addPropertyMethods - Goes through list of properties declared in this class
+/// and builds setter/getter method declartions depending on the setter/getter
+/// attributes of the property.
+///
+void ObjCContainerDecl::getPropertyMethods(
+       ASTContext &Context, ObjCPropertyDecl *property,
+       ObjCMethodDecl *& GetterDecl, ObjCMethodDecl *&SetterDecl) {
   // FIXME: The synthesized property we set here is misleading. We
   // almost always synthesize these methods unless the user explicitly
   // provided prototypes (which is odd, but allowed). Sema should be
@@ -467,15 +471,12 @@
       ObjCMethodDecl::Create(Context, property->getLocation(), 
                              property->getLocation(), 
                              property->getGetterName(), 
-                             property->getType(),
-                             D,
+                             property->getType(), this,
                              true, false, true, 
                              (property->getPropertyImplementation() == 
                               ObjCPropertyDecl::Optional) ? 
                              ObjCMethodDecl::Optional : 
                              ObjCMethodDecl::Required);
-    insMethods.push_back(GetterDecl);
-    InsMap[property->getGetterName()] = GetterDecl;
   }
   else
     // A user declared getter will be synthesize when @synthesize of
@@ -496,15 +497,12 @@
       ObjCMethodDecl::Create(Context, property->getLocation(), 
                              property->getLocation(), 
                              property->getSetterName(), 
-                             Context.VoidTy,
-                             D,
+                             Context.VoidTy, this,
                              true, false, true,
                              (property->getPropertyImplementation() == 
                               ObjCPropertyDecl::Optional) ? 
                              ObjCMethodDecl::Optional : 
                              ObjCMethodDecl::Required);
-    insMethods.push_back(SetterDecl);
-    InsMap[property->getSetterName()] = SetterDecl;
     // Invent the arguments for the setter. We don't bother making a
     // nice name for the argument.
     ParmVarDecl *Argument = ParmVarDecl::Create(Context, 
@@ -523,30 +521,6 @@
   property->setSetterMethodDecl(SetterDecl);
 }
 
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCInterfaceDecl::addPropertyMethods(
-       ASTContext &Context,
-       ObjCPropertyDecl *property,
-       llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-       llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCCategoryDecl::addPropertyMethods(
-       ASTContext &Context,
-       ObjCPropertyDecl *property,
-       llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, 
-       llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
 /// mergeProperties - Adds properties to the end of list of current properties
 /// for this category.
 
@@ -572,18 +546,6 @@
   }
 }
 
-/// addPropertyMethods - Goes through list of properties declared in this class
-/// and builds setter/getter method declartions depending on the setter/getter
-/// attributes of the property.
-///
-void ObjCProtocolDecl::addPropertyMethods(
-       ASTContext &Context,
-       ObjCPropertyDecl *property,
-       llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
-       llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap) {
-  ::addPropertyMethods(this, Context, property, insMethods, InsMap);
-}
-
 /// addProperties - Insert property declaration AST nodes into
 /// ObjCProtocolDecl's PropertyDecl field.
 ///
@@ -850,9 +812,8 @@
   // Get length of this name.
   unsigned length = 3;  // _I_ or _C_
   length += getClassInterface()->getNameAsString().size()+1; // extra for _
-  NamedDecl *MethodContext = getMethodContext();
   if (ObjCCategoryImplDecl *CID = 
-      dyn_cast<ObjCCategoryImplDecl>(MethodContext))
+      dyn_cast<ObjCCategoryImplDecl>(getMethodContext()))
     length += CID->getNameAsString().size()+1;
   length += getSelector().getAsString().size(); // selector name
   return length;