Point diagnostics that complain about a use of a selector in an objc message, to the selector location.

Previously it would point to the left bracket or the receiver, which can be particularly
problematic if the receiver is a block literal and we end up point the diagnostic far away
for the selector that is complaining about.

rdar://13620447

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180833 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index e7b5ec9..fed86ee 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -1191,6 +1191,12 @@
                                      bool isClassMessage, bool isSuperMessage,
                                      SourceLocation lbrac, SourceLocation rbrac,
                                      QualType &ReturnType, ExprValueKind &VK) {
+  SourceLocation SelLoc;
+  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+    SelLoc = SelectorLocs.front();
+  else
+    SelLoc = lbrac;
+
   if (!Method) {
     // Apply default argument promotion as for (C99 6.5.2.2p6).
     for (unsigned i = 0; i != NumArgs; i++) {
@@ -1200,7 +1206,7 @@
       ExprResult result;
       if (getLangOpts().DebuggerSupport) {
         QualType paramTy; // ignored
-        result = checkUnknownAnyArg(lbrac, Args[i], paramTy);
+        result = checkUnknownAnyArg(SelLoc, Args[i], paramTy);
       } else {
         result = DefaultArgumentPromotion(Args[i]);
       }
@@ -1216,7 +1222,7 @@
       DiagID = isClassMessage ? diag::warn_class_method_not_found
                               : diag::warn_inst_method_not_found;
     if (!getLangOpts().DebuggerSupport)
-      Diag(lbrac, DiagID)
+      Diag(SelLoc, DiagID)
         << Sel << isClassMessage << SourceRange(SelectorLocs.front(), 
                                                 SelectorLocs.back());
 
@@ -1242,7 +1248,7 @@
     NumNamedArgs = Method->param_size();
   // FIXME. This need be cleaned up.
   if (NumArgs < NumNamedArgs) {
-    Diag(lbrac, diag::err_typecheck_call_too_few_args)
+    Diag(SelLoc, diag::err_typecheck_call_too_few_args)
       << 2 << NumNamedArgs << NumArgs;
     return false;
   }
@@ -1268,7 +1274,7 @@
     // from the argument.
     if (param->getType() == Context.UnknownAnyTy) {
       QualType paramType;
-      ExprResult argE = checkUnknownAnyArg(lbrac, argExpr, paramType);
+      ExprResult argE = checkUnknownAnyArg(SelLoc, argExpr, paramType);
       if (argE.isInvalid()) {
         IsError = true;
       } else {
@@ -1287,7 +1293,7 @@
 
     InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                       param);
-    ExprResult ArgE = PerformCopyInitialization(Entity, lbrac, Owned(argExpr));
+    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, Owned(argExpr));
     if (ArgE.isInvalid())
       IsError = true;
     else
@@ -1317,10 +1323,10 @@
     }
   }
 
-  DiagnoseSentinelCalls(Method, lbrac, Args, NumArgs);
+  DiagnoseSentinelCalls(Method, SelLoc, Args, NumArgs);
 
   // Do additional checkings on method.
-  IsError |= CheckObjCMethodCall(Method, lbrac, Args, NumArgs);
+  IsError |= CheckObjCMethodCall(Method, SelLoc, Args, NumArgs);
 
   return IsError;
 }
@@ -1993,7 +1999,12 @@
       << FixItHint::CreateInsertion(Loc, "[");
     LBracLoc = Loc;
   }
-  
+  SourceLocation SelLoc;
+  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+    SelLoc = SelectorLocs.front();
+  else
+    SelLoc = Loc;
+
   if (ReceiverType->isDependentType()) {
     // If the receiver type is dependent, we can't type-check anything
     // at this point. Build a dependent expression.
@@ -2018,7 +2029,7 @@
   assert(Class && "We don't know which class we're messaging?");
   // objc++ diagnoses during typename annotation.
   if (!getLangOpts().CPlusPlus)
-    (void)DiagnoseUseOfDecl(Class, Loc);
+    (void)DiagnoseUseOfDecl(Class, SelLoc);
   // Find the method we are messaging.
   if (!Method) {
     SourceRange TypeRange 
@@ -2043,7 +2054,7 @@
     if (!Method)
       Method = Class->lookupPrivateClassMethod(Sel);
 
-    if (Method && DiagnoseUseOfDecl(Method, Loc))
+    if (Method && DiagnoseUseOfDecl(Method, SelLoc))
       return ExprError();
   }
 
@@ -2159,7 +2170,14 @@
                                       bool isImplicit) {
   // The location of the receiver.
   SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart();
-  
+  SourceRange RecRange =
+      SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
+  SourceLocation SelLoc;
+  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+    SelLoc = SelectorLocs.front();
+  else
+    SelLoc = Loc;
+
   if (LBracLoc.isInvalid()) {
     Diag(Loc, diag::err_missing_open_square_message_send)
       << FixItHint::CreateInsertion(Loc, "[");
@@ -2264,7 +2282,7 @@
           Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
           // warn if instance method found for a Class message.
           if (Method) {
-            Diag(Loc, diag::warn_instance_method_on_class_found)
+            Diag(SelLoc, diag::warn_instance_method_on_class_found)
               << Method->getSelector() << Sel;
             Diag(Method->getLocation(), diag::note_method_declared_at)
               << Method->getDeclName();
@@ -2279,7 +2297,7 @@
             if (!Method)
               Method = ClassDecl->lookupPrivateClassMethod(Sel);
           }
-          if (Method && DiagnoseUseOfDecl(Method, Loc))
+          if (Method && DiagnoseUseOfDecl(Method, SelLoc))
             return ExprError();
         }
         if (!Method) {
@@ -2298,7 +2316,7 @@
                   if (const ObjCInterfaceDecl *ID =
                       dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
                     if (ID->getSuperClass())
-                      Diag(Loc, diag::warn_root_inst_method_not_found)
+                      Diag(SelLoc, diag::warn_root_inst_method_not_found)
                       << Sel << SourceRange(LBracLoc, RBracLoc);
                   }
             }
@@ -2317,7 +2335,7 @@
         Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
         if (!Method)
           Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
-        if (Method && DiagnoseUseOfDecl(Method, Loc))
+        if (Method && DiagnoseUseOfDecl(Method, SelLoc))
           return ExprError();
       } else if (const ObjCObjectPointerType *OCIType
                    = ReceiverType->getAsObjCInterfacePointerType()) {
@@ -2353,8 +2371,8 @@
           Method = ClassDecl->lookupPrivateMethod(Sel);
 
           if (!Method && getLangOpts().ObjCAutoRefCount) {
-            Diag(Loc, diag::err_arc_may_not_respond)
-              << OCIType->getPointeeType() << Sel 
+            Diag(SelLoc, diag::err_arc_may_not_respond)
+              << OCIType->getPointeeType() << Sel << RecRange
               << SourceRange(SelectorLocs.front(), SelectorLocs.back());
             return ExprError();
           }
@@ -2367,12 +2385,13 @@
               Method = LookupInstanceMethodInGlobalPool(Sel,
                                               SourceRange(LBracLoc, RBracLoc));
               if (Method && !forwardClass)
-                Diag(Loc, diag::warn_maynot_respond)
-                  << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
+                Diag(SelLoc, diag::warn_maynot_respond)
+                  << OCIType->getInterfaceDecl()->getIdentifier()
+                  << Sel << RecRange;
             }
           }
         }
-        if (Method && DiagnoseUseOfDecl(Method, Loc, forwardClass))
+        if (Method && DiagnoseUseOfDecl(Method, SelLoc, forwardClass))
           return ExprError();
       } else {
         // Reject other random receiver types (e.g. structs).
@@ -2401,8 +2420,6 @@
                           diag::err_illegal_message_expr_incomplete_type))
     return ExprError();
 
-  SourceLocation SelLoc = SelectorLocs.front();
-
   // In ARC, forbid the user from sending messages to 
   // retain/release/autorelease/dealloc/retainCount explicitly.
   if (getLangOpts().ObjCAutoRefCount) {
@@ -2427,8 +2444,8 @@
     case OMF_release:
     case OMF_autorelease:
     case OMF_retainCount:
-      Diag(Loc, diag::err_arc_illegal_explicit_message)
-        << Sel << SelLoc;
+      Diag(SelLoc, diag::err_arc_illegal_explicit_message)
+        << Sel << RecRange;
       break;
     
     case OMF_performSelector: