Move the functionality that looks for ObjC overridden methods from
ASTContext to the ObjCMethodDecl, and have the more generic
ASTContext::getOverriddenMethods() use the ObjCMethodDecl::getOverriddenMethods()
function.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165518 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 67e89f3..0d28846 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1026,161 +1026,6 @@
   OverriddenMethods[Method].push_back(Overridden);
 }
 
-static void CollectOverriddenMethodsRecurse(const ObjCContainerDecl *Container,
-                                            const ObjCMethodDecl *Method,
-                                    SmallVectorImpl<const NamedDecl *> &Methods,
-                                            bool MovedToSuper) {
-  if (!Container)
-    return;
-
-  // In categories look for overriden methods from protocols. A method from
-  // category is not "overriden" since it is considered as the "same" method
-  // (same USR) as the one from the interface.
-  if (const ObjCCategoryDecl *
-        Category = dyn_cast<ObjCCategoryDecl>(Container)) {
-    // Check whether we have a matching method at this category but only if we
-    // are at the super class level.
-    if (MovedToSuper)
-      if (ObjCMethodDecl *
-            Overridden = Container->getMethod(Method->getSelector(),
-                                              Method->isInstanceMethod()))
-        if (Method != Overridden) {
-          // We found an override at this category; there is no need to look
-          // into its protocols.
-          Methods.push_back(Overridden);
-          return;
-        }
-
-    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
-                                          PEnd = Category->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
-    return;
-  }
-
-  // Check whether we have a matching method at this level.
-  if (const ObjCMethodDecl *
-        Overridden = Container->getMethod(Method->getSelector(),
-                                                    Method->isInstanceMethod()))
-    if (Method != Overridden) {
-      // We found an override at this level; there is no need to look
-      // into other protocols or categories.
-      Methods.push_back(Overridden);
-      return;
-    }
-
-  if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
-    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
-                                          PEnd = Protocol->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
-  }
-
-  if (const ObjCInterfaceDecl *
-        Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
-                                           PEnd = Interface->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
-
-    for (const ObjCCategoryDecl *Category = Interface->getCategoryList();
-         Category; Category = Category->getNextClassCategory())
-      CollectOverriddenMethodsRecurse(Category, Method, Methods,
-                                      MovedToSuper);
-
-    if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
-      return CollectOverriddenMethodsRecurse(Super, Method, Methods,
-                                             /*MovedToSuper=*/true);
-  }
-}
-
-static inline void CollectOverriddenMethods(const ObjCContainerDecl *Container,
-                                            const ObjCMethodDecl *Method,
-                                  SmallVectorImpl<const NamedDecl *> &Methods) {
-  CollectOverriddenMethodsRecurse(Container, Method, Methods,
-                                  /*MovedToSuper=*/false);
-}
-
-static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
-                               SmallVectorImpl<const NamedDecl *> &overridden) {
-  assert(Method->isOverriding());
-
-  if (const ObjCProtocolDecl *
-        ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
-    CollectOverriddenMethods(ProtD, Method, overridden);
-
-  } else if (const ObjCImplDecl *
-               IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
-    const ObjCInterfaceDecl *ID = IMD->getClassInterface();
-    if (!ID)
-      return;
-    // Start searching for overridden methods using the method from the
-    // interface as starting point.
-    if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
-                                                  Method->isInstanceMethod()))
-      Method = IFaceMeth;
-    CollectOverriddenMethods(ID, Method, overridden);
-
-  } else if (const ObjCCategoryDecl *
-               CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
-    const ObjCInterfaceDecl *ID = CatD->getClassInterface();
-    if (!ID)
-      return;
-    // Start searching for overridden methods using the method from the
-    // interface as starting point.
-    if (const ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
-                                                  Method->isInstanceMethod()))
-      Method = IFaceMeth;
-    CollectOverriddenMethods(ID, Method, overridden);
-
-  } else {
-    CollectOverriddenMethods(
-                  dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
-                  Method, overridden);
-  }
-}
-
-static void collectOnCategoriesAfterLocation(SourceLocation Loc,
-                                             const ObjCInterfaceDecl *Class,
-                                             SourceManager &SM,
-                                             const ObjCMethodDecl *Method,
-                                  SmallVectorImpl<const NamedDecl *> &Methods) {
-  if (!Class)
-    return;
-
-  for (const ObjCCategoryDecl *Category = Class->getCategoryList();
-       Category; Category = Category->getNextClassCategory())
-    if (SM.isBeforeInTranslationUnit(Loc, Category->getLocation()))
-      CollectOverriddenMethodsRecurse(Category, Method, Methods, true);
-
-  collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
-                                   Method, Methods);
-}
-
-/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
-/// returns false.
-/// You'd think that in that case there are no overrides but categories can
-/// "introduce" new overridden methods that are missed by Sema because the
-/// overrides lookup that it does for methods, inside implementations, will
-/// stop at the interface level (if there is a method there) and not look
-/// further in super classes.
-static void collectOverriddenMethodsFast(SourceManager &SM,
-                                         const ObjCMethodDecl *Method,
-                                  SmallVectorImpl<const NamedDecl *> &Methods) {
-  assert(!Method->isOverriding());
-
-  const ObjCContainerDecl *
-    ContD = cast<ObjCContainerDecl>(Method->getDeclContext());
-  if (isa<ObjCInterfaceDecl>(ContD) || isa<ObjCProtocolDecl>(ContD))
-    return;
-  const ObjCInterfaceDecl *Class = Method->getClassInterface();
-  if (!Class)
-    return;
-
-  collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
-                                   SM, Method, Methods);
-}
-
 void ASTContext::getOverriddenMethods(const NamedDecl *D,
                                SmallVectorImpl<const NamedDecl *> &Overridden) {
   assert(D);
@@ -1198,18 +1043,13 @@
   if (!Method)
     return;
 
-  if (Method->isRedeclaration()) {
-    Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
-                   getMethod(Method->getSelector(), Method->isInstanceMethod());
-  }
-
-  if (!Method->isOverriding()) {
-    collectOverriddenMethodsFast(SourceMgr, Method, Overridden);
-  } else {
-    collectOverriddenMethodsSlow(Method, Overridden);
-    assert(!Overridden.empty() &&
-           "ObjCMethodDecl's overriding bit is not as expected");
-  }
+  SmallVector<const ObjCMethodDecl *, 8> OverDecls;
+  Method->getOverriddenMethods(OverDecls);
+  for (SmallVector<const ObjCMethodDecl *, 8>::iterator
+            M = OverDecls.begin(),
+         MEnd = OverDecls.end();
+       M != MEnd; ++M)
+    Overridden.push_back(*M);
 }
 
 void ASTContext::addedLocalImportDecl(ImportDecl *Import) {