improve the 'conflicting types' diagnostics to include correct location info, now
that it is plumbed through Sema.  On a file from growl, we used to emit:

t.mi:107059:1: warning: conflicting types for 'removePluginHandler:forPluginTypes:'
- (void) removePluginHandler:(id <GrowlPluginHandler>)handler forPluginTypes:(NSSet *)extensions {
^
t.mi:105280:1: note: previous definition is here
- (void) removePluginHandler:(id <NSObject>)handler forPluginTypes:(NSSet *)types;
^

now we produce:

t.mi:107059:55: warning: conflicting parameter types in implementation of 'removePluginHandler:forPluginTypes:': 'id<NSObject>' vs 'id<GrowlPluginHandler>'
- (void) removePluginHandler:(id <GrowlPluginHandler>)handler forPluginTypes:(NSSet *)extensions {
                                                      ^
t.mi:105280:45: note: previous definition is here
- (void) removePluginHandler:(id <NSObject>)handler forPluginTypes:(NSSet *)types;
                                            ^

We still don't have proper loc info for properties, hence the FIXME.

rdar://6782494



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68879 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 52b6db5..6048901 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -763,25 +763,28 @@
 
 void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
                                        ObjCMethodDecl *IntfMethodDecl) {
-  bool err = false;
   if (!Context.typesAreCompatible(IntfMethodDecl->getResultType(),
-                                  ImpMethodDecl->getResultType()))
-    err = true;
-  else
-    for (ObjCMethodDecl::param_iterator IM=ImpMethodDecl->param_begin(),
-         IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
-         IM != EM; ++IM, ++IF) {
-      if (!Context.typesAreCompatible((*IF)->getType(), (*IM)->getType())) {
-        err = true;
-        break;
-      }
-    }
-  
-  if (err) {
-    Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_types) 
-      << ImpMethodDecl->getDeclName();
+                                  ImpMethodDecl->getResultType())) {
+    Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_ret_types) 
+      << ImpMethodDecl->getDeclName() << IntfMethodDecl->getResultType()
+      << ImpMethodDecl->getResultType();
     Diag(IntfMethodDecl->getLocation(), diag::note_previous_definition);
   }
+  
+  for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
+       IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
+       IM != EM; ++IM, ++IF) {
+    if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType()))
+      continue;
+    
+    Diag((*IM)->getLocation(), diag::warn_conflicting_param_types) 
+      << ImpMethodDecl->getDeclName() << (*IF)->getType()
+      << (*IM)->getType();
+    SourceLocation Loc = (*IF)->getLocation();
+    // FIXME
+    if (Loc == SourceLocation()) Loc = IntfMethodDecl->getLocation();
+    Diag(Loc, diag::note_previous_definition);
+  }
 }
 
 /// isPropertyReadonly - Return true if property is readonly, by searching