From 99d7f9f979b18ece720802b1551ddb894bc4ff4a Mon Sep 17 00:00:00 2001
From: Nick Lewycky <nicholas@mxc.ca>
Date: Sat, 11 Jan 2014 02:37:12 +0000
Subject: [PATCH] Use the appropriate SourceLocation for the template backtrace
 when doing template argument deduction.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198995 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Sema/SemaLookup.cpp                       |  2 +-
 lib/Sema/SemaTemplateDeduction.cpp            | 28 ++++++++-----------
 test/SemaCXX/cxx98-compat.cpp                 |  4 +--
 test/SemaCXX/implicit-member-functions.cpp    |  2 +-
 test/SemaCXX/typo-correction.cpp              |  4 +--
 .../instantiate-exception-spec.cpp            |  6 ++--
 .../instantiate-function-params.cpp           |  6 ++--
 test/SemaTemplate/instantiation-backtrace.cpp |  4 +--
 .../instantiation-depth-subst-2.cpp           |  4 +--
 .../instantiation-depth-subst.cpp             |  4 +--
 test/SemaTemplate/instantiation-order.cpp     |  4 +--
 test/SemaTemplate/operator-template.cpp       |  5 ++--
 12 files changed, 33 insertions(+), 40 deletions(-)

diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index ed2f5e93d35..2aa1ee56402 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -2546,7 +2546,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
   // Now we perform lookup on the name we computed earlier and do overload
   // resolution. Lookup is only performed directly into the class since there
   // will always be a (possibly implicit) declaration to shadow any others.
-  OverloadCandidateSet OCS((SourceLocation()));
+  OverloadCandidateSet OCS(RD->getLocation());
   DeclContext::lookup_result R = RD->lookup(Name);
   assert(!R.empty() &&
          "lookup for a constructor or assignment operator was empty");
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 71826d6799b..8e1122aa43a 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -2285,8 +2285,8 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
     return Result;
 
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
-                             DeducedArgs, Info);
+  InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
+                             Info);
   if (Inst.isInvalid())
     return TDK_InstantiationDepth;
 
@@ -2449,8 +2449,8 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
     return Result;
 
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
-                             DeducedArgs, Info);
+  InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
+                             Info);
   if (Inst.isInvalid())
     return TDK_InstantiationDepth;
 
@@ -2535,8 +2535,8 @@ Sema::SubstituteExplicitTemplateArguments(
   // explicitly-specified template arguments against this function template,
   // and then substitute them into the function parameter types.
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
-                             FunctionTemplate, DeducedArgs,
+  InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
+                             DeducedArgs,
            ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution,
                              Info);
   if (Inst.isInvalid())
@@ -2789,8 +2789,8 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
   // Enter a new template instantiation context while we instantiate the
   // actual function declaration.
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
-                             FunctionTemplate, DeducedArgs,
+  InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
+                             DeducedArgs,
               ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
                              Info);
   if (Inst.isInvalid())
@@ -4624,8 +4624,7 @@ Sema::getMoreSpecializedPartialSpecialization(
                                             /*RefParamComparisons=*/0);
   if (Better1) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end());
-    InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2, DeducedArgs,
-                               Info);
+    InstantiatingTemplate Inst(*this, Loc, PS2, DeducedArgs, Info);
     Better1 = !::FinishTemplateArgumentDeduction(
         *this, PS2, PS1->getTemplateArgs(), Deduced, Info);
   }
@@ -4640,8 +4639,7 @@ Sema::getMoreSpecializedPartialSpecialization(
   if (Better2) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
                                                  Deduced.end());
-    InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1, DeducedArgs,
-                               Info);
+    InstantiatingTemplate Inst(*this, Loc, PS1, DeducedArgs, Info);
     Better2 = !::FinishTemplateArgumentDeduction(
         *this, PS1, PS2->getTemplateArgs(), Deduced, Info);
   }
@@ -4685,8 +4683,7 @@ Sema::getMoreSpecializedPartialSpecialization(
   if (Better1) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
                                                  Deduced.end());
-    InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2,
-                               DeducedArgs, Info);
+    InstantiatingTemplate Inst(*this, Loc, PS2, DeducedArgs, Info);
     Better1 = !::FinishTemplateArgumentDeduction(*this, PS2,
                                                  PS1->getTemplateArgs(),
                                                  Deduced, Info);
@@ -4702,8 +4699,7 @@ Sema::getMoreSpecializedPartialSpecialization(
                                             /*RefParamComparisons=*/0);
   if (Better2) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end());
-    InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1,
-                               DeducedArgs, Info);
+    InstantiatingTemplate Inst(*this, Loc, PS1, DeducedArgs, Info);
     Better2 = !::FinishTemplateArgumentDeduction(*this, PS1,
                                                  PS2->getTemplateArgs(),
                                                  Deduced, Info);
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 9690638ce02..2329295a5fa 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -219,11 +219,11 @@ int n = {}; // expected-warning {{scalar initialized from empty initializer list
 class PrivateMember {
   struct ImPrivate {};
 };
-template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}} expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
+template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}}
   return typename T::ImPrivate();
 }
 int SFINAEAccessControl(...) { return 0; }
-int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember());
+int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember()); // expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
 
 template<typename T>
 struct FriendRedefinition {
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index b5f7fe1016b..de679fe14a0 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -58,13 +58,13 @@ namespace Recursion {
   };
   struct B;
   struct A {
+    // expected-note@-1 {{while substituting deduced template arguments}}
     typedef B type;
     template<typename T,
              typename = typename InvokeCopyConstructor<typename T::type>::type>
     // expected-note@-1 {{in instantiation of template class}}
     A(const T &);
     // expected-note@-1 {{in instantiation of default argument}}
-    // expected-note@-2 {{while substituting deduced template arguments}}
   };
   struct B { // expected-note {{candidate constructor (the implicit move }}
     B(); // expected-note {{candidate constructor not viable}}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 8dbedd2dc47..85413566722 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -282,13 +282,13 @@ namespace b6956809_test1 {
 namespace b6956809_test2 {
   template<typename T> struct Err { typename T::error n; };  // expected-error{{type 'void *' cannot be used prior to '::' because it has no members}}
   struct S {
-    template<typename T> typename Err<T>::type method(T);  // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}  expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
+    template<typename T> typename Err<T>::type method(T);  // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}
     template<typename T> int method(T *);
   };
 
   void test() {
     S s;
-    int k = s.methodd((void*)0);  // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}}
+    int k = s.methodd((void*)0);  // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
   }
 }
 
diff --git a/test/SemaTemplate/instantiate-exception-spec.cpp b/test/SemaTemplate/instantiate-exception-spec.cpp
index d4f12df22ec..993ee8dfae1 100644
--- a/test/SemaTemplate/instantiate-exception-spec.cpp
+++ b/test/SemaTemplate/instantiate-exception-spec.cpp
@@ -1,11 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-// FIXME: the "note" should be down at the call site!
-template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}} \
-                         // expected-note{{instantiation of}}
+template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
 struct Incomplete; // expected-note{{forward}}
 
 void test_f1(Incomplete *incomplete_p, int *int_p) {
   f1(int_p);
-  f1(incomplete_p); 
+  f1(incomplete_p); // expected-note{{instantiation of}}
 }
diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp
index 5bfae537c04..556a8181f04 100644
--- a/test/SemaTemplate/instantiate-function-params.cpp
+++ b/test/SemaTemplate/instantiate-function-params.cpp
@@ -7,12 +7,12 @@ template<typename T1> struct if_ {
 };
 template <class Model, void (Model::*)()> struct wrap_constraints { };
 template <class Model> 
-inline char has_constraints_(Model* ,  // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \
-                             // expected-note 3{{candidate template ignored}}
+inline char has_constraints_(Model* , // expected-note 3{{candidate template ignored}}
                                wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 2{{in instantiation}}
 
 template <class Model> struct not_satisfied {
-  static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}}
+  static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}} \
+  // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }}
 };
 template <class ModelFn> struct requirement_;
 template <void(*)()> struct instantiate {
diff --git a/test/SemaTemplate/instantiation-backtrace.cpp b/test/SemaTemplate/instantiation-backtrace.cpp
index f640836b768..39dfb0b32a2 100644
--- a/test/SemaTemplate/instantiation-backtrace.cpp
+++ b/test/SemaTemplate/instantiation-backtrace.cpp
@@ -39,13 +39,13 @@ namespace PR13365 {
   template <class T1, class T2>
     typename ResultTy<T2>::error Deduce( void (T1::*member)(T2) ) {} // \
     // expected-note {{instantiation of template class 'PR13365::ResultTy<int &>'}} \
-    // expected-note {{substituting deduced template arguments into function template 'Deduce' [with T1 = PR13365::Cls, T2 = int &]}} \
     // expected-note {{substitution failure [with T1 = PR13365::Cls, T2 = int &]}}
 
   struct Cls {
     void method(int&);
   };
   void test() {
-    Deduce(&Cls::method); // expected-error {{no matching function}}
+    Deduce(&Cls::method); // expected-error {{no matching function}} \
+                          // expected-note {{substituting deduced template arguments into function template 'Deduce' [with T1 = PR13365::Cls, T2 = int &]}}
   }
 }
diff --git a/test/SemaTemplate/instantiation-depth-subst-2.cpp b/test/SemaTemplate/instantiation-depth-subst-2.cpp
index ef2a5c765d9..c9df093b1f7 100644
--- a/test/SemaTemplate/instantiation-depth-subst-2.cpp
+++ b/test/SemaTemplate/instantiation-depth-subst-2.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -verify %s -ftemplate-depth 2
 
 template<int N> struct S { };
-template<typename T> S<T() + T()> operator+(T, T); // expected-error {{instantiation exceeded maximum depth}} expected-note 3{{while substituting}}
+template<typename T> S<T() + T()> operator+(T, T); // expected-error {{instantiation exceeded maximum depth}} expected-note 2{{while substituting}}
 S<0> s;
-int k = s + s;
+int k = s + s; // expected-note {{while substituting}}
diff --git a/test/SemaTemplate/instantiation-depth-subst.cpp b/test/SemaTemplate/instantiation-depth-subst.cpp
index 06795f9514d..2a3e422ac7a 100644
--- a/test/SemaTemplate/instantiation-depth-subst.cpp
+++ b/test/SemaTemplate/instantiation-depth-subst.cpp
@@ -3,7 +3,7 @@
 // PR9793
 template<typename T> auto f(T t) -> decltype(f(t)); // \
 // expected-error {{recursive template instantiation exceeded maximum depth of 2}} \
-// expected-note 3 {{while substituting}}
+// expected-note 2 {{while substituting}}
 
 struct S {};
-int k = f(S{});
+int k = f(S{}); // expected-note {{while substituting}}
diff --git a/test/SemaTemplate/instantiation-order.cpp b/test/SemaTemplate/instantiation-order.cpp
index e058a5bc187..9cac256ad45 100644
--- a/test/SemaTemplate/instantiation-order.cpp
+++ b/test/SemaTemplate/instantiation-order.cpp
@@ -5,11 +5,11 @@
 template <class T> struct A { using X = typename T::X; }; // expected-error {{no members}}
 template <class T> typename T::X f(typename A<T>::X);
 template <class T> void f(...) {}
-template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}} expected-note {{substituting}}
+template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}}
 template <class T> void g(...) {}
 
 void h()
 {
   f<int>(0); // ok, SFINAE in return type
-  g<int>(0); // not ok, substitution inside A<int> is a hard error
+  g<int>(0); // not ok, substitution inside A<int> is a hard error // expected-note {{substituting}}
 }
diff --git a/test/SemaTemplate/operator-template.cpp b/test/SemaTemplate/operator-template.cpp
index 30d6ccfb959..41662509706 100644
--- a/test/SemaTemplate/operator-template.cpp
+++ b/test/SemaTemplate/operator-template.cpp
@@ -12,7 +12,6 @@ int a0(A<int> x) { return x == 1; }
 template<class X>struct B{typedef X Y;};
 template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
 // expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
-// expected-note{{in instantiation of function template specialization}} \
 // expected-note{{candidate template ignored: substitution failure [with X = int]}}
-int a(B<int> x) { return operator==(&x,1); } // expected-error{{no matching function for call to 'operator=='}}
-
+int a(B<int> x) { return operator==(&x,1); } // expected-error{{no matching function for call to 'operator=='}} \
+// expected-note{{in instantiation of function template specialization}}
-- 
GitLab