Replace "failed template argument deduction" diagnostic with something useful
in the one case where we've already factored out a reason code.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174036 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index aa6bcd6..f20bd06 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2331,6 +2331,9 @@
     "candidate template ignored: substitution failure%0%1">;
 def note_ovl_candidate_disabled_by_enable_if : Note<
     "candidate template ignored: disabled by %0%1">;
+def note_ovl_candidate_failed_overload_resolution : Note<
+    "candidate template ignored: couldn't resolve reference to overloaded "
+    "function %0">;
     
 // Note that we don't treat templates differently for this diagnostic.
 def note_ovl_candidate_arity : Note<"candidate "
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 305b067..8a2cef7 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -694,6 +694,10 @@
       /// \brief Return the second template argument this deduction failure
       /// refers to, if any.
       const TemplateArgument *getSecondArg();
+
+      /// \brief Return the expression this deduction failure refers to,
+      /// if any.
+      Expr *getExpr();
       
       /// \brief Free any memory associated with this deduction failure.
       void Destroy();
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 5c69a92..e9a1449 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -47,7 +47,7 @@
 
 public:
   TemplateDeductionInfo(SourceLocation Loc)
-    : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { }
+    : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { }
 
   /// \brief Returns the location at which template argument is
   /// occurring.
@@ -150,6 +150,13 @@
   ///
   /// FIXME: Finish documenting this.
   TemplateArgument SecondArg;
+
+  /// \brief The expression which caused a deduction failure.
+  ///
+  ///   TDK_FailedOverloadResolution: this argument is the reference to
+  //    an overloaded function which could not be resolved to a specific
+  //    function.
+  Expr *Expression;
 };
 
 }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 22cb61e..dbab739 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -588,8 +588,11 @@
     }
     break;
 
-  case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_FailedOverloadResolution:
+    Result.Data = Info.Expression;
+    break;
+
+  case Sema::TDK_NonDeducedMismatch:
     break;
   }
 
@@ -741,6 +744,15 @@
   return 0;
 }
 
+Expr *
+OverloadCandidate::DeductionFailureInfo::getExpr() {
+  if (static_cast<Sema::TemplateDeductionResult>(Result) ==
+        Sema::TDK_FailedOverloadResolution)
+    return static_cast<Expr*>(Data);
+
+  return 0;
+}
+
 void OverloadCandidateSet::destroyCandidates() {
   for (iterator i = begin(), e = end(); i != e; ++i) {
     for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii)
@@ -8442,10 +8454,18 @@
     return;
   }
 
+  case Sema::TDK_FailedOverloadResolution: {
+    OverloadExpr::FindResult R =
+        OverloadExpr::find(Cand->DeductionFailure.getExpr());
+    S.Diag(Fn->getLocation(),
+           diag::note_ovl_candidate_failed_overload_resolution)
+      << R.Expression->getName();
+    return;
+  }
+
   // TODO: diagnose these individually, then kill off
   // note_ovl_candidate_bad_deduction, which is uselessly vague.
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_FailedOverloadResolution:
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
     MaybeEmitInheritedConstructorNote(S, Fn);
     return;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index a8de3a8..003d016 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -2879,7 +2879,8 @@
 /// described in C++ [temp.deduct.call].
 ///
 /// \returns true if the caller should not attempt to perform any template
-/// argument deduction based on this P/A pair.
+/// argument deduction based on this P/A pair because the argument is an
+/// overloaded function set that could not be resolved.
 static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
                                           TemplateParameterList *TemplateParams,
                                                       QualType &ParamType,
@@ -2895,7 +2896,7 @@
   if (ParamRefType) {
     QualType PointeeType = ParamRefType->getPointeeType();
 
-    // If the argument has incomplete array type, try to complete it's type.
+    // If the argument has incomplete array type, try to complete its type.
     if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0))
       ArgType = Arg->getType();
 
@@ -2993,8 +2994,8 @@
 
 /// \brief Perform template argument deduction by matching a parameter type
 ///        against a single expression, where the expression is an element of
-///        an initializer list that was originally matched against the argument
-///        type.
+///        an initializer list that was originally matched against a parameter
+///        of type \c initializer_list\<ParamType\>.
 static Sema::TemplateDeductionResult
 DeduceTemplateArgumentByListElement(Sema &S,
                                     TemplateParameterList *TemplateParams,
@@ -3023,8 +3024,10 @@
   // For all other cases, just match by type.
   QualType ArgType = Arg->getType();
   if (AdjustFunctionParmAndArgTypesForDeduction(S, TemplateParams, ParamType, 
-                                                ArgType, Arg, TDF))
+                                                ArgType, Arg, TDF)) {
+    Info.Expression = Arg;
     return Sema::TDK_FailedOverloadResolution;
+  }
   return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, ParamType,
                                             ArgType, Info, Deduced, TDF);
 }
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 4fd419d..88571d6 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -199,3 +199,12 @@
     f({{1,2},{3,4}});
   }
 }
+
+namespace init_list_deduction_failure {
+  void f();
+  void f(int);
+  template<typename T> void g(std::initializer_list<T>);
+  // expected-note@-1 {{candidate template ignored: couldn't resolve reference to overloaded function 'f'}}
+  void h() { g({f}); }
+  // expected-error@-1 {{no matching function for call to 'g'}}
+}