Whenever we complain about a failed initialization of a function or
method parameter, provide a note pointing at the parameter itself so
the user does not have to manually look for the function/method being
called and match up parameters to arguments. For example, we now get:

t.c:4:5: warning: incompatible pointer types passing 'long *' to
parameter of
      type 'int *' [-pedantic]
  f(long_ptr);
    ^~~~~~~~
t.c:1:13: note: passing argument to parameter 'x' here
void f(int *x);
            ^



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102038 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a284803..5333684 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -4076,7 +4076,8 @@
   bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
                                 SourceLocation Loc,
                                 QualType DstType, QualType SrcType,
-                                Expr *SrcExpr, AssignmentAction Action);
+                                Expr *SrcExpr, AssignmentAction Action,
+                                bool *Complained = 0);
 
   /// CheckAssignmentConstraints - Perform type checking for assignment,
   /// argument passing, variable initialization, and function return values.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 265f44c..3621f70 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -7036,7 +7036,11 @@
 bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
                                     SourceLocation Loc,
                                     QualType DstType, QualType SrcType,
-                                    Expr *SrcExpr, AssignmentAction Action) {
+                                    Expr *SrcExpr, AssignmentAction Action,
+                                    bool *Complained) {
+  if (Complained)
+    *Complained = false;
+
   // Decode the result (notice that AST's are still created for extensions).
   bool isInvalid = false;
   unsigned DiagKind;
@@ -7121,6 +7125,8 @@
   
   Diag(Loc, DiagKind) << FirstType << SecondType << Action
     << SrcExpr->getSourceRange() << Hint;
+  if (Complained)
+    *Complained = true;
   return isInvalid;
 }
 
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 6a9efbd..eae5f63 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -3308,6 +3308,20 @@
                                  move_arg(ConstructorArgs));
 }
 
+void InitializationSequence::PrintInitLocationNote(Sema &S,
+                                              const InitializedEntity &Entity) {
+  if (Entity.getKind() == InitializedEntity::EK_Parameter && Entity.getDecl()) {
+    if (Entity.getDecl()->getLocation().isInvalid())
+      return;
+
+    if (Entity.getDecl()->getDeclName())
+      S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_named_here)
+        << Entity.getDecl()->getDeclName();
+    else
+      S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here);
+  }
+}
+
 Action::OwningExprResult 
 InitializationSequence::Perform(Sema &S,
                                 const InitializedEntity &Entity,
@@ -3474,6 +3488,7 @@
         S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
           << Entity.getType().isVolatileQualified()
           << CurInitExpr->getSourceRange();
+        PrintInitLocationNote(S, Entity);
         return S.ExprError();
       }
         
@@ -3695,10 +3710,16 @@
             == Sema::Compatible)
         ConvTy = Sema::Compatible;
 
+      bool Complained;
       if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
                                      Step->Type, SourceType,
-                                     CurInitExpr, getAssignmentAction(Entity)))
+                                     CurInitExpr, 
+                                     getAssignmentAction(Entity),
+                                     &Complained)) {
+        PrintInitLocationNote(S, Entity);
         return S.ExprError();
+      } else if (Complained)
+        PrintInitLocationNote(S, Entity);
 
       CurInit.release();
       CurInit = S.Owned(CurInitExpr);
@@ -3972,6 +3993,7 @@
     break;
   }
   
+  PrintInitLocationNote(S, Entity);
   return true;
 }
 
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
index ba11470..5f2592f 100644
--- a/lib/Sema/SemaInit.h
+++ b/lib/Sema/SemaInit.h
@@ -542,7 +542,11 @@
   
   /// \brief The candidate set created when initialization failed.
   OverloadCandidateSet FailedCandidateSet;
-  
+
+  /// \brief Prints a follow-up note that highlights the location of
+  /// the initialized entity, if it's remote.
+  void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
+
 public:
   /// \brief Try to perform initialization of the given entity, creating a 
   /// record of the steps required to perform the initialization.