Contains the following (related to problems found while investigting <rdar://problem/6497631> Message lookup is sometimes different than gcc's).

- Implement instance/class overloading in ObjCContainerDecl (removing a FIXME). This involved hacking NamedDecl::declarationReplaces(), which took awhile to figure out (didn't realize replace was the default).
- Changed Sema::ActOnInstanceMessage() to remove redundant warnings when dealing with protocols. For now, I've omitted the "protocol" term in the diagnostic. It simplifies the code flow and wan't always 100% accurate (e.g. "Foo<Prot>" looks in the class interface, not just the protocol).
- Changed several test cases to jive with the above changes.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65292 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 387f79a..f760852 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Expr.h"
@@ -194,6 +195,10 @@
     // For function declarations, we keep track of redeclarations.
     return FD->getPreviousDeclaration() == OldD;
 
+  // For method declarations, we keep track of redeclarations.
+  if (isa<ObjCMethodDecl>(this))
+    return false;
+    
   // For non-function declarations, if the declarations are of the
   // same kind then this must be a redeclaration, or semantic analysis
   // would not have given us the new declaration.
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 461bb96..a9f7922 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Stmt.h"
+#include "llvm/ADT/STLExtras.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -42,21 +43,42 @@
 //===----------------------------------------------------------------------===//
 
 // 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));
+  // 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(Sel);
+       Meth != MethEnd; ++Meth) {
+    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+    if (MD && MD->isInstanceMethod())
+      return MD;
+  }
   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));
+  // 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(Sel);
+       Meth != MethEnd; ++Meth) {
+    ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
+    if (MD && MD->isClassMethod())
+      return MD;
+  }
   return 0;
 }