Improve diagnostics when printing a template instantiation backtrace
involving substitution of deduced template arguments into a class
template partial specialization or function template, or when
substituting explicitly-specific template arguments into a function
template. We now print the actual deduced argument bindings so the
user can see what got deduced.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99923 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 58c40cf..61f1048 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1385,13 +1385,13 @@
   "for '%0' required here">;
 def note_explicit_template_arg_substitution_here : Note<
   "while substituting explicitly-specified template arguments into function "
-  "template %0, here">;
+  "template %0 %1">;
 def note_function_template_deduction_instantiation_here : Note<
-  "while substituting deduced template arguments into function template %0, "
-  "here">;
+  "while substituting deduced template arguments into function template %0 "
+  "%1">;
 def note_partial_spec_deduct_instantiation_here : Note<
   "during template argument deduction for class template partial "
-  "specialization %0, here">;
+  "specialization %0 %1">;
 def note_prior_template_arg_substitution : Note<
   "while substituting prior template arguments into %select{non-type|template}0"
   " template parameter%1 %2">;
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 4da1fcb..d08f483 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -394,7 +394,11 @@
         = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
       Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
                    diag::note_explicit_template_arg_substitution_here)
-        << FnTmpl << Active->InstantiationRange;
+        << FnTmpl 
+        << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), 
+                                           Active->TemplateArgs, 
+                                           Active->NumTemplateArgs)
+        << Active->InstantiationRange;
       break;
     }
 
@@ -405,13 +409,21 @@
         Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
                      diag::note_partial_spec_deduct_instantiation_here)
           << Context.getTypeDeclType(PartialSpec)
+          << getTemplateArgumentBindingsText(
+                                         PartialSpec->getTemplateParameters(), 
+                                             Active->TemplateArgs, 
+                                             Active->NumTemplateArgs)
           << Active->InstantiationRange;
       } else {
         FunctionTemplateDecl *FnTmpl
           = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
         Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
                      diag::note_function_template_deduction_instantiation_here)
-          << FnTmpl << Active->InstantiationRange;
+          << FnTmpl
+          << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), 
+                                             Active->TemplateArgs, 
+                                             Active->NumTemplateArgs)
+          << Active->InstantiationRange;
       }
       break;
 
diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp
index 14c4d9f..ea8dd70 100644
--- a/test/SemaTemplate/instantiate-function-params.cpp
+++ b/test/SemaTemplate/instantiate-function-params.cpp
@@ -7,7 +7,7 @@
 };
 template <class Model, void (Model::*)()> struct wrap_constraints { };
 template <class Model> 
-inline char has_constraints_(Model* ,  // expected-note 4{{while substituting}} \
+inline char has_constraints_(Model* ,  // expected-note 4{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \
                              // expected-note 3{{candidate template ignored}}
                                wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 4{{in instantiation}}