Eliminate the three SmallVectors in ObjCImplDecl (for instance
methods, class methods, and property implementations) and instead
place all of these entities into the DeclContext.

This eliminates more linear walks when looking for class or instance
methods and should make PCH (de-)serialization of ObjCDecls trivial
(and lazy).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69849 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index a855ecf..3895b13 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2142,7 +2142,8 @@
     if (const ObjCCategoryImplDecl *CID = 
         dyn_cast<ObjCCategoryImplDecl>(Container)) {
       for (ObjCCategoryImplDecl::propimpl_iterator
-             i = CID->propimpl_begin(), e = CID->propimpl_end(); i != e; ++i) {
+             i = CID->propimpl_begin(*this), e = CID->propimpl_end(*this);
+           i != e; ++i) {
         ObjCPropertyImplDecl *PID = *i;
         if (PID->getPropertyDecl() == PD) {
           if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
@@ -2155,7 +2156,8 @@
     } else {
       const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
       for (ObjCCategoryImplDecl::propimpl_iterator
-             i = OID->propimpl_begin(), e = OID->propimpl_end(); i != e; ++i) {
+             i = OID->propimpl_begin(*this), e = OID->propimpl_end(*this);
+           i != e; ++i) {
         ObjCPropertyImplDecl *PID = *i;
         if (PID->getPropertyDecl() == PD) {
           if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 1e05eb6..3bffbf5 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -541,13 +541,20 @@
 }
 
 
+void ObjCImplDecl::addPropertyImplementation(ASTContext &Context, 
+                                             ObjCPropertyImplDecl *property) {
+  property->setLexicalDeclContext(this);
+  addDecl(Context, property);
+}
+
 /// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
 /// properties implemented in this category @implementation block and returns
 /// the implemented property that uses it.
 ///
 ObjCPropertyImplDecl *ObjCImplDecl::
-FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
-  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
+FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
+  for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
+       i != e; ++i){
     ObjCPropertyImplDecl *PID = *i;
     if (PID->getPropertyIvarDecl() &&
         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
@@ -561,8 +568,9 @@
 /// category @implementation block.
 ///
 ObjCPropertyImplDecl *ObjCImplDecl::
-FindPropertyImplDecl(IdentifierInfo *Id) const {
-  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
+FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
+  for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
+       i != e; ++i){
     ObjCPropertyImplDecl *PID = *i;
     if (PID->getPropertyDecl()->getIdentifier() == Id)
       return PID;
@@ -573,22 +581,47 @@
 // getInstanceMethod - This method returns an instance method by looking in
 // the class implementation. Unlike interfaces, we don't look outside the
 // implementation.
-ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
-  for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); I != E; ++I)
-    if ((*I)->getSelector() == Sel)
-      return *I;
-  return NULL;
+ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
+                                                Selector Sel) const {
+  // Since instance & class methods can have the same name, the loop below
+  // ensures we get the correct method.
+  //
+  // @interface Whatever
+  // - (int) class_method;
+  // + (float) class_method;
+  // @end
+  //
+  lookup_const_iterator Meth, MethEnd;
+  for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
+       Meth != MethEnd; ++Meth) {
+    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+    if (MD && MD->isInstanceMethod())
+      return MD;
+  }
+  return 0;
 }
 
 // getClassMethod - This method returns an instance method by looking in
 // the class implementation. Unlike interfaces, we don't look outside the
 // implementation.
-ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
-  for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
-       I != E; ++I)
-    if ((*I)->getSelector() == Sel)
-      return *I;
-  return NULL;
+ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context, 
+                                             Selector Sel) const {
+  // Since instance & class methods can have the same name, the loop below
+  // ensures we get the correct method.
+  //
+  // @interface Whatever
+  // - (int) class_method;
+  // + (float) class_method;
+  // @end
+  //
+  lookup_const_iterator Meth, MethEnd;
+  for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
+       Meth != MethEnd; ++Meth) {
+    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+    if (MD && MD->isClassMethod())
+      return MD;
+  }
+  return 0;
 }
 
 //===----------------------------------------------------------------------===//