reikdas updated this revision to Diff 306097.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77598/new/

https://reviews.llvm.org/D77598

Files:
  clang/include/clang/AST/StmtDataCollectors.td
  clang/include/clang/AST/TemplateBase.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTTypeTraits.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclPrinter.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/NestedNameSpecifier.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TemplateBase.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Analysis/PathDiagnostic.cpp
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/Analysis/eval-predefined-exprs.cpp
  clang/test/CXX/lex/lex.literal/lex.ext/p12.cpp
  clang/test/CXX/temp/temp.param/p10-2a.cpp
  clang/test/SemaCXX/builtin-align-cxx.cpp
  clang/test/SemaCXX/cxx11-ast-print.cpp
  clang/test/SemaCXX/matrix-type-builtins.cpp
  clang/test/SemaCXX/matrix-type-operators.cpp
  clang/test/SemaTemplate/address_space-dependent.cpp
  clang/test/SemaTemplate/delegating-constructors.cpp
  clang/test/SemaTemplate/matrix-type.cpp
  clang/test/SemaTemplate/temp_arg_nontype.cpp
  clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
  clang/tools/libclang/CIndex.cpp
  
clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp

Index: clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
===================================================================
--- clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
+++ clang/unittests/Tooling/RecursiveASTVisitorTests/TemplateArgumentLocTraverser.cpp
@@ -20,7 +20,7 @@
     llvm::raw_string_ostream Stream(ArgStr);
     const TemplateArgument &Arg = ArgLoc.getArgument();
 
-    Arg.print(Context->getPrintingPolicy(), Stream);
+    Arg.print(Context->getPrintingPolicy(), Stream, /*IncludeType*/ true);
     Match(Stream.str(), ArgLoc.getLocation());
     return ExpectedLocationVisitor<TemplateArgumentLocTraverser>::
       TraverseTemplateArgumentLoc(ArgLoc);
Index: clang/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -5144,8 +5144,9 @@
     SmallString<128> Str;
     llvm::raw_svector_ostream OS(Str);
     OS << *ClassSpec;
-    printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
-                              Policy);
+    printTemplateArgumentList(
+        OS, ClassSpec->getTemplateArgs().asArray(), Policy,
+        ClassSpec->getSpecializedTemplate()->getTemplateParameters());
     return cxstring::createDup(OS.str());
   }
 
Index: clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
===================================================================
--- clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -457,3 +457,13 @@
   X<f> y;
   int n = y.call(); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}}
 }
+
+namespace PR9227 {
+template <auto N> struct S {};
+template <> struct S<1> { using type = int; }; // expected-note {{'S<1>::type' declared here}}
+S<1L>::type t;                                 // expected-error {{no type named 'type' in 'PR9227::S<1L>'; did you mean 'S<1>::type'?}}
+
+template <auto N> struct A {};
+template <> struct A<1> { using type = int; }; // expected-note {{'A<1>::type' declared here}}
+A<2>::type x;                                  // expected-error {{no type named 'type' in 'PR9227::A<2>'; did you mean 'A<1>::type'?}}
+} // namespace PR9227
Index: clang/test/SemaTemplate/temp_arg_nontype.cpp
===================================================================
--- clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -270,6 +270,23 @@
   void test_char_possibly_negative() { enable_if_char<'\x02'>::type i; } // expected-error{{enable_if_char<'\x02'>'; did you mean 'enable_if_char<'a'>::type'?}}
   void test_char_single_quote() { enable_if_char<'\''>::type i; } // expected-error{{enable_if_char<'\''>'; did you mean 'enable_if_char<'a'>::type'?}}
   void test_char_backslash() { enable_if_char<'\\'>::type i; } // expected-error{{enable_if_char<'\\'>'; did you mean 'enable_if_char<'a'>::type'?}}
+
+  template <int N> struct enable_if_int {};
+  template <> struct enable_if_int<1> { typedef int type; }; // expected-note{{'enable_if_int<1>::type' declared here}}
+  void test_int() { enable_if_int<2>::type i; } // expected-error{{enable_if_int<2>'; did you mean 'enable_if_int<1>::type'?}}
+
+  template <unsigned int N> struct enable_if_unsigned_int {};
+  template <> struct enable_if_unsigned_int<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_int<1>::type' declared here}}
+  void test_unsigned_int() { enable_if_unsigned_int<2>::type i; } // expected-error{{enable_if_unsigned_int<2>'; did you mean 'enable_if_unsigned_int<1>::type'?}}
+
+  template <unsigned long long N> struct enable_if_unsigned_long_long {};
+  template <> struct enable_if_unsigned_long_long<1> { typedef int type; }; // expected-note{{'enable_if_unsigned_long_long<1>::type' declared here}}
+  void test_unsigned_long_long() { enable_if_unsigned_long_long<2>::type i; } // expected-error{{enable_if_unsigned_long_long<2>'; did you mean 'enable_if_unsigned_long_long<1>::type'?}}
+
+  template <long long N> struct enable_if_long_long {};
+  template <> struct enable_if_long_long<1> { typedef int type; }; // expected-note{{'enable_if_long_long<1>::type' declared here}}
+  void test_long_long() { enable_if_long_long<2>::type i; } // expected-error{{enable_if_long_long<2>'; did you mean 'enable_if_long_long<1>::type'?}}
+
 }
 
 namespace PR10579 {
Index: clang/test/SemaTemplate/matrix-type.cpp
===================================================================
--- clang/test/SemaTemplate/matrix-type.cpp
+++ clang/test/SemaTemplate/matrix-type.cpp
@@ -17,7 +17,7 @@
 
 void instantiate_template_3() {
   matrix_template_3<1, 10>();
-  matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0, 10>' requested here}}
+  matrix_template_3<0, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_3<0U, 10U>' requested here}}
 }
 
 template <int Rows, unsigned Cols>
@@ -27,7 +27,7 @@
 
 void instantiate_template_4() {
   matrix_template_4<2, 10>();
-  matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10>' requested here}}
+  matrix_template_4<-3, 10>(); // expected-note{{in instantiation of function template specialization 'matrix_template_4<-3, 10U>' requested here}}
 }
 
 template <class T, unsigned long R, unsigned long C>
Index: clang/test/SemaTemplate/delegating-constructors.cpp
===================================================================
--- clang/test/SemaTemplate/delegating-constructors.cpp
+++ clang/test/SemaTemplate/delegating-constructors.cpp
@@ -9,7 +9,7 @@
   public:
     template <unsigned N>
     string(const char (&str)[N])
-      : string(str) {} // expected-error{{constructor for 'string<6>' creates a delegation cycle}}
+      : string(str) {} // expected-error{{constructor for 'string<6U>' creates a delegation cycle}}
   };
 
   void f() {
Index: clang/test/SemaTemplate/address_space-dependent.cpp
===================================================================
--- clang/test/SemaTemplate/address_space-dependent.cpp
+++ clang/test/SemaTemplate/address_space-dependent.cpp
@@ -102,7 +102,7 @@
   HasASTemplateFields<1> HASTF;
   neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}}
   correct<0x7FFFF1>();
-  tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650>' requested here}}
+  tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}}
 
   __attribute__((address_space(1))) char *x;
   __attribute__((address_space(2))) char *y;
Index: clang/test/SemaCXX/matrix-type-operators.cpp
===================================================================
--- clang/test/SemaCXX/matrix-type-operators.cpp
+++ clang/test/SemaCXX/matrix-type-operators.cpp
@@ -28,13 +28,13 @@
   Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
   unsigned v1 = add<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
   // expected-error@-1 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
-  // expected-note@-2 {{in instantiation of function template specialization 'add<unsigned int, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+  // expected-note@-2 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
 
   Mat1.value = add<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2);
-  // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 2, 2, unsigned int, 3, 3, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
 
   Mat1.value = add<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3);
-  // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 3, 3, float, 2, 2, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'add<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
 }
 
 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
@@ -56,13 +56,13 @@
   Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
   unsigned v1 = subtract<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
   // expected-error@-1 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
-  // expected-note@-2 {{in instantiation of function template specialization 'subtract<unsigned int, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+  // expected-note@-2 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
 
   Mat1.value = subtract<unsigned, 2, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat1, Mat2);
-  // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 2, 2, unsigned int, 3, 3, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 2U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
 
   Mat1.value = subtract<unsigned, 3, 3, float, 2, 2, unsigned, 2, 2>(Mat2, Mat3);
-  // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 3, 3, float, 2, 2, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'subtract<unsigned int, 3U, 3U, float, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
 }
 
 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
@@ -89,15 +89,15 @@
   MyMatrix<float, 2, 2> Mat3;
   Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
   unsigned v1 = multiply<unsigned, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat1, Mat1);
-  // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
   // expected-error@-2 {{cannot initialize a variable of type 'unsigned int' with an rvalue of type 'typename MyMatrix<unsigned int, 2U, 2U>::matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
 
   MyMatrix<unsigned, 3, 2> Mat4;
   Mat1.value = multiply<unsigned, 3, 2, unsigned, 3, 3, unsigned, 2, 2>(Mat4, Mat2);
-  // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 3, 2, unsigned int, 3, 3, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply<unsigned int, 3U, 2U, unsigned int, 3U, 3U, unsigned int, 2U, 2U>' requested here}}
 
   Mat1.value = multiply<float, 2, 2, unsigned, 2, 2, unsigned, 2, 2>(Mat3, Mat1);
-  // expected-note@-1 {{in instantiation of function template specialization 'multiply<float, 2, 2, unsigned int, 2, 2, unsigned int, 2, 2>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'multiply<float, 2U, 2U, unsigned int, 2U, 2U, unsigned int, 2U, 2U>' requested here}}
 
   Mat4.value = Mat4.value * Mat1;
   // expected-error@-1 {{no viable conversion from 'MyMatrix<unsigned int, 2, 2>' to 'unsigned int'}}
Index: clang/test/SemaCXX/matrix-type-builtins.cpp
===================================================================
--- clang/test/SemaCXX/matrix-type-builtins.cpp
+++ clang/test/SemaCXX/matrix-type-builtins.cpp
@@ -30,14 +30,14 @@
   MyMatrix<unsigned, 3, 3> Mat2;
   Mat1.value = *((decltype(Mat1)::matrix_t *)Ptr1);
   Mat1.value = transpose<unsigned, 2, 3, unsigned, 2, 3>(Mat1);
-  // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 2, 3, unsigned int, 2, 3>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 2U, 3U, unsigned int, 2U, 3U>' requested here}}
 
   Mat1.value = transpose<unsigned, 3, 3, unsigned, 2, 3>(Mat2);
-  // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3, 3, unsigned int, 2, 3>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3U, 3U, unsigned int, 2U, 3U>' requested here}}
 
   MyMatrix<float, 3, 3> Mat3;
   Mat3.value = transpose<unsigned, 3, 3, float, 3, 3>(Mat2);
-  // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3, 3, float, 3, 3>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'transpose<unsigned int, 3U, 3U, float, 3U, 3U>' requested here}}
 }
 
 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1>
@@ -55,13 +55,13 @@
 void test_column_major_loads_template(unsigned *Ptr1, float *Ptr2) {
   MyMatrix<unsigned, 2, 3> Mat1;
   Mat1.value = column_major_load<unsigned, 2, 3, unsigned, 2, 3>(Mat1, Ptr1);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2, 3, unsigned int, 2, 3>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2U, 3U, unsigned int, 2U, 3U>' requested here}}
   column_major_load<unsigned, 2, 3, unsigned, 5, 5>(Mat1, Ptr1);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2, 3, unsigned int, 5, 5>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<unsigned int, 2U, 3U, unsigned int, 5U, 5U>' requested here}}
 
   MyMatrix<float, 2, 3> Mat2;
   Mat1.value = column_major_load<float, 2, 3, unsigned, 2, 3>(Mat2, Ptr2);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<float, 2, 3, unsigned int, 2, 3>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_load<float, 2U, 3U, unsigned int, 2U, 3U>' requested here}}
 }
 
 constexpr int constexpr1() { return 1; }
@@ -116,10 +116,10 @@
 
 void test_column_major_stores_template(MyMatrix<unsigned, 2, 3> &M1, unsigned *Ptr1, MyMatrix<float, 3, 4> &M2, float *Ptr2) {
   column_major_store(M1, Ptr2, 10);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2, 3, float *>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2U, 3U, float *>' requested here}}
 
   column_major_store<decltype(M2), float *, 1>(M2, Ptr2);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<MyMatrix<float, 3, 4> &, float *, 1>' requested here}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<MyMatrix<float, 3, 4> &, float *, 1U>' requested here}}
 }
 
 template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1>
@@ -139,13 +139,13 @@
 void test_column_major_store_template(unsigned *Ptr1, float *Ptr2) {
   MyMatrix<unsigned, 2, 3> Mat1;
   column_major_store<unsigned, 2, 3, unsigned>(Mat1, Ptr1);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2, 3, unsigned int>'}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2U, 3U, unsigned int>'}}
   column_major_store<unsigned, 2, 3, float>(Mat1, Ptr2);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2, 3, float>'}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<unsigned int, 2U, 3U, float>'}}
 
   MyMatrix<float, 2, 3> Mat2;
   column_major_store<float, 2, 3, unsigned>(Mat2, Ptr1);
-  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<float, 2, 3, unsigned int>'}}
+  // expected-note@-1 {{in instantiation of function template specialization 'column_major_store<float, 2U, 3U, unsigned int>'}}
 }
 
 void test_column_major_store_constexpr(unsigned *Ptr, MyMatrix<unsigned, 3, 3> &M) {
Index: clang/test/SemaCXX/cxx11-ast-print.cpp
===================================================================
--- clang/test/SemaCXX/cxx11-ast-print.cpp
+++ clang/test/SemaCXX/cxx11-ast-print.cpp
@@ -40,7 +40,7 @@
 const char *p10 = 3.300e+15_fritz;
 
 template <class C, C...> const char *operator"" _suffix();
-// CHECK: const char *PR23120 = operator""_suffix<char32_t, 66615>();
+// CHECK: const char *PR23120 = operator""_suffix<char32_t, (char32_t)66615>();
 const char *PR23120 = U"𐐷"_suffix;
 
 // PR28885
Index: clang/test/SemaCXX/builtin-align-cxx.cpp
===================================================================
--- clang/test/SemaCXX/builtin-align-cxx.cpp
+++ clang/test/SemaCXX/builtin-align-cxx.cpp
@@ -31,10 +31,10 @@
 void test() {
   test_templated_arguments<int, 32>(); // fine
   test_templated_arguments<struct fwddecl, 16>();
-  // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<fwddecl, 16, 16>'}}
+  // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<fwddecl, 16L, 16L>'}}
   // expected-note@-2{{forward declaration of 'fwddecl'}}
   test_templated_arguments<int, 7>(); // invalid alignment value
-  // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<int, 7, 16>'}}
+  // expected-note@-1{{in instantiation of function template specialization 'test_templated_arguments<int, 7L, 16L>'}}
 }
 
 template <typename T, long ArraySize>
Index: clang/test/CXX/temp/temp.param/p10-2a.cpp
===================================================================
--- clang/test/CXX/temp/temp.param/p10-2a.cpp
+++ clang/test/CXX/temp/temp.param/p10-2a.cpp
@@ -133,7 +133,7 @@
 
 using j1 = J<1, 'b'>;
 using j2 = J<'a', nullptr>;
-// expected-error@-1 {{constraints not satisfied for alias template 'J' [with x = <'a', nullptr>]}}
+// expected-error@-1 {{constraints not satisfied for alias template 'J' [with x = <(signed char)'a', nullptr>]}}
 
 template<OneOf<char, int> auto &x>
 // expected-error@-1 {{constrained placeholder types other than simple 'auto' on non-type template parameters not supported yet}}
Index: clang/test/CXX/lex/lex.literal/lex.ext/p12.cpp
===================================================================
--- clang/test/CXX/lex/lex.literal/lex.ext/p12.cpp
+++ clang/test/CXX/lex/lex.literal/lex.ext/p12.cpp
@@ -15,7 +15,7 @@
 void *a = 123_x; // ok, calls #2
 int b = u8"\"тест 𐀀"_x; // ok, calls #1
 int c = u8R"("тест 𐀀)"_x; // ok, calls #1
-int d = "test"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char, 't', 'e', 's', 't'>' requested here}}
+int d = "test"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char, (signed char)'t', (signed char)'e', (signed char)'s', (signed char)'t'>' requested here}}
 int e = uR"("тест 𐀀)"_x;
 int f = UR"("тест 𐀀)"_x;
-int g = UR"("тест_𐀀)"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char32_t, 34, 1090, 1077, 1089, 1090, 95, 65536>' requested here}}
+int g = UR"("тест_𐀀)"_x; // expected-note {{in instantiation of function template specialization 'operator""_x<char32_t, (char32_t)34, (char32_t)1090, (char32_t)1077, (char32_t)1089, (char32_t)1090, (char32_t)95, (char32_t)65536>' requested here}}
Index: clang/test/Analysis/eval-predefined-exprs.cpp
===================================================================
--- clang/test/Analysis/eval-predefined-exprs.cpp
+++ clang/test/Analysis/eval-predefined-exprs.cpp
@@ -14,7 +14,7 @@
   clang_analyzer_dump(__PRETTY_FUNCTION__);
   // expected-warning@-3 {{&Element{"func",0 S64b,char}}}
   // expected-warning@-3 {{&Element{"func",0 S64b,char}}}
-  // expected-warning@-3 {{&Element{"void func(U) [T = Class, Value = 42, U = char]",0 S64b,char}}}
+  // expected-warning@-3 {{&Element{"void func(U) [T = Class, Value = 42ULL, U = char]",0 S64b,char}}}
 
 #ifdef ANALYZER_MS
   clang_analyzer_dump(__FUNCDNAME__);
@@ -23,8 +23,8 @@
   clang_analyzer_dump(L__FUNCSIG__);
   // expected-warning@-4 {{&Element{"??$func@UClass@?1??foo@@YAXXZ@$0CK@D@@YAXD@Z",0 S64b,char}}}
   // expected-warning@-4 {{&Element{L"func",0 S64b,wchar_t}}}
-  // expected-warning@-4 {{&Element{"void __cdecl func(U) [T = Class, Value = 42, U = char]",0 S64b,char}}}
-  // expected-warning@-4 {{&Element{L"void __cdecl func(U) [T = Class, Value = 42, U = char]",0 S64b,wchar_t}}}
+  // expected-warning@-4 {{&Element{"void __cdecl func(U) [T = Class, Value = 42ULL, U = char]",0 S64b,char}}}
+  // expected-warning@-4 {{&Element{L"void __cdecl func(U) [T = Class, Value = 42ULL, U = char]",0 S64b,wchar_t}}}
 #endif
 }
 
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -587,8 +587,10 @@
       SmallString<128> TemplateArgsStr;
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       Template->printName(OS);
+      const TemplateParameterList *TPL = Template->getTemplateParameters();
+      // FIXME: Only pass parameter list if template is not overloaded
       printTemplateArgumentList(OS, Active->template_arguments(),
-                                getPrintingPolicy());
+                                getPrintingPolicy(), TPL);
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_arg_instantiation_here)
         << OS.str()
@@ -653,8 +655,12 @@
       SmallString<128> TemplateArgsStr;
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       FD->printName(OS);
+      const TemplateParameterList *TPL = nullptr;
+      // FIXME: Only pass parameter list if template is not overloaded
+      if (auto *TD = dyn_cast<TemplateDecl>(Active->Entity))
+        TPL = TD->getTemplateParameters();
       printTemplateArgumentList(OS, Active->template_arguments(),
-                                getPrintingPolicy());
+                                getPrintingPolicy(), TPL);
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_function_arg_instantiation_here)
         << OS.str()
@@ -805,9 +811,14 @@
       SmallString<128> TemplateArgsStr;
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       cast<NamedDecl>(Active->Entity)->printName(OS);
-      if (!isa<FunctionDecl>(Active->Entity))
+      if (!isa<FunctionDecl>(Active->Entity)) {
+        const TemplateParameterList *TPL = nullptr;
+        if (auto *TD = dyn_cast<TemplateDecl>(Active->Entity))
+          TPL = TD->getTemplateParameters();
+        // FIXME: Only pass parameter list if template is not overloaded
         printTemplateArgumentList(OS, Active->template_arguments(),
-                                  getPrintingPolicy());
+                                  getPrintingPolicy(), TPL);
+      }
       Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
         << Active->InstantiationRange;
       break;
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4715,8 +4715,41 @@
     OS << "'" << Concept->getName();
     if (TypeLoc.hasExplicitTemplateArgs()) {
       OS << "<";
-      for (const auto &Arg : Type.getTypeConstraintArguments())
-        Arg.print(S.getPrintingPolicy(), OS);
+      const TemplateParameterList *TPL =
+          Type.getTypeConstraintConcept()->getTemplateParameters();
+      unsigned i = 0;
+      for (const auto &Arg : Type.getTypeConstraintArguments()) {
+        // FIXME: Only pass parameter if template is not overloaded
+        if (!TPL)
+          Arg.print(S.getPrintingPolicy(), OS, /*IncludeType*/ true);
+        else if (i >= TPL->size())
+          Arg.print(S.getPrintingPolicy(), OS, /*IncludeType*/ false);
+        else {
+          bool IncludeType = false;
+          const NamedDecl *TemplParam = TPL->getParam(i);
+          if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+            const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+            if (auto *autoT = T->getAs<AutoType>()) {
+              if (autoT->getAs<DeducedType>()) {
+                IncludeType = true;
+              }
+            } else if (T->getAs<DeducedType>()) {
+              IncludeType = true;
+            }
+          } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+            const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+            if (auto *autoT = T->getAs<AutoType>()) {
+              if (autoT->getAs<DeducedType>()) {
+                IncludeType = true;
+              }
+            } else if (T->getAs<DeducedType>()) {
+              IncludeType = true;
+            }
+          }
+          Arg.print(S.getPrintingPolicy(), OS, IncludeType);
+        }
+        i++;
+      }
       OS << ">";
     }
     OS << "'";
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3561,7 +3561,10 @@
       OS << VD->getName();
       if (const auto *IV = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
         // This is a template variable, print the expanded template arguments.
-        printTemplateArgumentList(OS, IV->getTemplateArgs().asArray(), Policy);
+        // FIXME: Only pass parameter list if template is not overloaded
+        printTemplateArgumentList(
+            OS, IV->getTemplateArgs().asArray(), Policy,
+            IV->getSpecializedTemplate()->getTemplateParameters());
       }
       return true;
     }
@@ -10934,7 +10937,28 @@
     }
 
     Out << " = ";
-    Args[I].print(getPrintingPolicy(), Out);
+    bool IncludeType = false;
+    const NamedDecl *TemplParam = Params->getParam(I);
+    if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+      const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+      if (auto *autoT = T->getAs<AutoType>()) {
+        if (autoT->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      } else if (T->getAs<DeducedType>()) {
+        IncludeType = true;
+      }
+    } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+      const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+      if (auto *autoT = T->getAs<AutoType>()) {
+        if (autoT->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      } else if (T->getAs<DeducedType>()) {
+        IncludeType = true;
+      }
+    }
+    Args[I].print(getPrintingPolicy(), Out, IncludeType);
   }
 
   Out << ']';
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -968,15 +968,45 @@
 }
 
 static std::string printTemplateArgs(const PrintingPolicy &PrintingPolicy,
-                                     TemplateArgumentListInfo &Args) {
+                                     TemplateArgumentListInfo &Args,
+                                     const TemplateParameterList *Params) {
   SmallString<128> SS;
   llvm::raw_svector_ostream OS(SS);
   bool First = true;
+  unsigned i = 0;
   for (auto &Arg : Args.arguments()) {
     if (!First)
       OS << ", ";
-    Arg.getArgument().print(PrintingPolicy, OS);
+    if (!Params)
+      Arg.getArgument().print(PrintingPolicy, OS, /*IncludeType*/ true);
+    else if (i >= Params->size())
+      Arg.getArgument().print(PrintingPolicy, OS, /*IncludeType*/ false);
+    else {
+      bool IncludeType = false;
+      const NamedDecl *TemplParam = Params->getParam(i);
+      if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+        const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+        if (auto *autoT = T->getAs<AutoType>()) {
+          if (autoT->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (T->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+        const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+        if (auto *autoT = T->getAs<AutoType>()) {
+          if (autoT->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (T->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      }
+      Arg.getArgument().print(PrintingPolicy, OS, IncludeType);
+    }
     First = false;
+    i++;
   }
   return std::string(OS.str());
 }
@@ -984,11 +1014,12 @@
 static bool lookupStdTypeTraitMember(Sema &S, LookupResult &TraitMemberLookup,
                                      SourceLocation Loc, StringRef Trait,
                                      TemplateArgumentListInfo &Args,
+                                     const TemplateParameterList *Params,
                                      unsigned DiagID) {
   auto DiagnoseMissing = [&] {
     if (DiagID)
       S.Diag(Loc, DiagID) << printTemplateArgs(S.Context.getPrintingPolicy(),
-                                               Args);
+                                               Args, Params);
     return true;
   };
 
@@ -1026,7 +1057,7 @@
     if (DiagID)
       S.RequireCompleteType(
           Loc, TraitTy, DiagID,
-          printTemplateArgs(S.Context.getPrintingPolicy(), Args));
+          printTemplateArgs(S.Context.getPrintingPolicy(), Args, Params));
     return true;
   }
 
@@ -1066,7 +1097,8 @@
 
   // If there's no tuple_size specialization or the lookup of 'value' is empty,
   // it's not tuple-like.
-  if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, /*DiagID*/ 0) ||
+  if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, nullptr,
+                               /*DiagID*/ 0) ||
       R.empty())
     return IsTupleLike::NotTupleLike;
 
@@ -1081,7 +1113,8 @@
     Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
                                                SourceLocation Loc) override {
       return S.Diag(Loc, diag::err_decomp_decl_std_tuple_size_not_constant)
-          << printTemplateArgs(S.Context.getPrintingPolicy(), Args);
+             << printTemplateArgs(S.Context.getPrintingPolicy(), Args,
+                                  /*Params*/ nullptr);
     }
   } Diagnoser(R, Args);
 
@@ -1109,7 +1142,7 @@
   DeclarationName TypeDN = S.PP.getIdentifierInfo("type");
   LookupResult R(S, TypeDN, Loc, Sema::LookupOrdinaryName);
   if (lookupStdTypeTraitMember(
-          S, R, Loc, "tuple_element", Args,
+          S, R, Loc, "tuple_element", Args, /*Params*/ nullptr,
           diag::err_decomp_decl_std_tuple_element_not_specialized))
     return QualType();
 
@@ -1117,7 +1150,8 @@
   if (!TD) {
     R.suppressDiagnostics();
     S.Diag(Loc, diag::err_decomp_decl_std_tuple_element_not_specialized)
-      << printTemplateArgs(S.Context.getPrintingPolicy(), Args);
+        << printTemplateArgs(S.Context.getPrintingPolicy(), Args,
+                             /*Params*/ nullptr);
     if (!R.empty())
       S.Diag(R.getRepresentativeDecl()->getLocation(), diag::note_declared_at);
     return QualType();
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -275,7 +275,11 @@
   // Add any template specialization args.
   if (Info) {
     const TemplateArgumentList *TArgs = Info->TemplateArguments;
-    printTemplateArgumentList(OS, TArgs->asArray(), getPrintingPolicy());
+    const TemplateParameterList *TPL = nullptr;
+    if (auto *TD = dyn_cast<TemplateDecl>(FD))
+      TPL = TD->getTemplateParameters();
+    // FIXME: Only pass template parameter list if template is overloaded
+    printTemplateArgumentList(OS, TArgs->asArray(), getPrintingPolicy(), TPL);
   }
 
   // Copy this name on the side and use its reference.
@@ -1191,7 +1195,11 @@
   SmallString<128> NS;
   llvm::raw_svector_ostream OS(NS);
   Ty->getTemplateName().print(OS, getPrintingPolicy(), /*qualified*/ false);
-  printTemplateArgumentList(OS, Ty->template_arguments(), getPrintingPolicy());
+  const TemplateParameterList *TPL =
+      Ty->getTemplateName().getAsTemplateDecl()->getTemplateParameters();
+  // FIXME: Only pass parameter list if template is not overloaded
+  printTemplateArgumentList(OS, Ty->template_arguments(), getPrintingPolicy(),
+                            TPL);
 
   SourceLocation Loc = AliasDecl->getLocation();
   return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
@@ -2093,8 +2101,12 @@
 
   // Add any template specialization args.
   if (const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
+    const TemplateParameterList *TPL = nullptr;
+    if (auto *TD = dyn_cast<TemplateDecl>(VD))
+      TPL = TD->getTemplateParameters();
+    // FIXME: Only pass template parameter list if template is not overloaded
     printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
-                              getPrintingPolicy());
+                              getPrintingPolicy(), TPL);
   }
 
   OS << '\'';
Index: clang/lib/Analysis/PathDiagnostic.cpp
===================================================================
--- clang/lib/Analysis/PathDiagnostic.cpp
+++ clang/lib/Analysis/PathDiagnostic.cpp
@@ -898,7 +898,7 @@
   if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
     describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
   } else {
-    TArg.print(PrintingPolicy(LO), Out);
+    TArg.print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
   }
 }
 
Index: clang/lib/AST/TypePrinter.cpp
===================================================================
--- clang/lib/AST/TypePrinter.cpp
+++ clang/lib/AST/TypePrinter.cpp
@@ -1805,16 +1805,17 @@
 }
 
 static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,
-                          llvm::raw_ostream &OS) {
-  A.print(PP, OS);
+                          llvm::raw_ostream &OS, bool IncludeType) {
+  A.print(PP, OS, IncludeType);
 }
 
 static void printArgument(const TemplateArgumentLoc &A,
-                          const PrintingPolicy &PP, llvm::raw_ostream &OS) {
+                          const PrintingPolicy &PP, llvm::raw_ostream &OS,
+                          bool IncludeType) {
   const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();
   if (Kind == TemplateArgument::ArgKind::Type)
     return A.getTypeSourceInfo()->getType().print(OS, PP);
-  return A.getArgument().print(PP, OS);
+  return A.getArgument().print(PP, OS, IncludeType);
 }
 
 static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
@@ -1976,6 +1977,7 @@
 
   bool NeedSpace = false;
   bool FirstArg = true;
+  unsigned i = 0;
   for (const auto &Arg : Args) {
     // Print the argument into a string.
     SmallString<128> Buf;
@@ -1984,12 +1986,39 @@
     if (Argument.getKind() == TemplateArgument::Pack) {
       if (Argument.pack_size() && !FirstArg)
         OS << Comma;
-      printTo(ArgOS, Argument.getPackAsArray(), Policy, true, nullptr);
+      printTo(ArgOS, Argument.getPackAsArray(), Policy, true, TPL);
     } else {
       if (!FirstArg)
         OS << Comma;
       // Tries to print the argument with location info if exists.
-      printArgument(Arg, Policy, ArgOS);
+      if (!TPL)
+        printArgument(Arg, Policy, ArgOS, /*IncludeType*/ true);
+      else if (i >= TPL->size())
+        printArgument(Arg, Policy, ArgOS, /*IncludeType*/ false);
+      else {
+        bool IncludeType = false;
+        const NamedDecl *TemplParam = TPL->getParam(i);
+        if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+          const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+          if (auto *autoT = T->getAs<AutoType>()) {
+            if (autoT->getAs<DeducedType>()) {
+              IncludeType = true;
+            }
+          } else if (T->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+          const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+          if (auto *autoT = T->getAs<AutoType>()) {
+            if (autoT->getAs<DeducedType>()) {
+              IncludeType = true;
+            }
+          } else if (T->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        }
+        printArgument(Arg, Policy, ArgOS, IncludeType);
+      }
     }
     StringRef ArgString = ArgOS.str();
 
@@ -2006,6 +2035,7 @@
     NeedSpace = Policy.SplitTemplateClosers && !ArgString.empty() &&
                 ArgString.back() == '>';
     FirstArg = false;
+    i++;
   }
 
   if (NeedSpace)
Index: clang/lib/AST/TemplateBase.cpp
===================================================================
--- clang/lib/AST/TemplateBase.cpp
+++ clang/lib/AST/TemplateBase.cpp
@@ -50,8 +50,10 @@
 /// \param Out the raw_ostream instance to use for printing.
 ///
 /// \param Policy the printing policy for EnumConstantDecl printing.
-static void printIntegral(const TemplateArgument &TemplArg,
-                          raw_ostream &Out, const PrintingPolicy& Policy) {
+///
+/// \param IncludeType the flag to determine printing type information.
+static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
+                          const PrintingPolicy &Policy, bool IncludeType) {
   const Type *T = TemplArg.getIntegralType().getTypePtr();
   const llvm::APSInt &Val = TemplArg.getAsIntegral();
 
@@ -70,14 +72,48 @@
 
   if (T->isBooleanType() && !Policy.MSVCFormatting) {
     Out << (Val.getBoolValue() ? "true" : "false");
+  } else if (T->isBooleanType()) {
+    Out << Val;
   } else if (T->isCharType()) {
     const char Ch = Val.getZExtValue();
+    if (IncludeType) {
+      if (T->isSignedIntegerType())
+        Out << "(signed char)";
+      else
+        Out << "(unsigned char)";
+    }
     Out << ((Ch == '\'') ? "'\\" : "'");
     Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
     Out << "'";
-  } else {
+  } else if (IncludeType) {
+    if (auto *BT = T->getAs<BuiltinType>()) {
+      switch (BT->getKind()) {
+      case BuiltinType::ULongLong:
+        Out << Val << "ULL";
+        break;
+      case BuiltinType::LongLong:
+        Out << Val << "LL";
+        break;
+      case BuiltinType::ULong:
+        Out << Val << "UL";
+        break;
+      case BuiltinType::Long:
+        Out << Val << "L";
+        break;
+      case BuiltinType::UInt:
+        Out << Val << "U";
+        break;
+      case BuiltinType::Int:
+        Out << Val;
+        break;
+      default:
+        Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
+            << Val;
+        break;
+      }
+    }
+  } else
     Out << Val;
-  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -339,8 +375,9 @@
   llvm_unreachable("Invalid TemplateArgument Kind!");
 }
 
-void TemplateArgument::print(const PrintingPolicy &Policy,
-                             raw_ostream &Out) const {
+void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
+                             bool IncludeType) const {
+
   switch (getKind()) {
   case Null:
     Out << "(no value)";
@@ -369,6 +406,7 @@
   }
 
   case NullPtr:
+    // FIXME: Include the type if it's not obvious from the context.
     Out << "nullptr";
     break;
 
@@ -382,7 +420,7 @@
     break;
 
   case Integral:
-    printIntegral(*this, Out, Policy);
+    printIntegral(*this, Out, Policy, IncludeType);
     break;
 
   case Expression:
@@ -398,7 +436,8 @@
       else
         Out << ", ";
 
-      P.print(Policy, Out);
+      // FIXME: What is the corresponding parameter for an unpacked argument?
+      P.print(Policy, Out, IncludeType);
     }
     Out << ">";
     break;
@@ -409,7 +448,7 @@
   LangOptions LO; // FIXME! see also TemplateName::dump().
   LO.CPlusPlus = true;
   LO.Bool = true;
-  print(PrintingPolicy(LO), Out);
+  print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
 }
 
 LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
@@ -504,7 +543,7 @@
     LangOptions LangOpts;
     LangOpts.CPlusPlus = true;
     PrintingPolicy Policy(LangOpts);
-    Arg.print(Policy, OS);
+    Arg.print(Policy, OS, /*IncludeType*/ true);
     return DB << OS.str();
   }
   }
Index: clang/lib/AST/StmtPrinter.cpp
===================================================================
--- clang/lib/AST/StmtPrinter.cpp
+++ clang/lib/AST/StmtPrinter.cpp
@@ -979,8 +979,13 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getNameInfo();
-  if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+  if (Node->hasExplicitTemplateArgs()) {
+    const TemplateParameterList *TPL = nullptr;
+    if (!Node->hadMultipleCandidates())
+      if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
+        TPL = TD->getTemplateParameters();
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
+  }
 }
 
 void StmtPrinter::VisitDependentScopeDeclRefExpr(
@@ -990,8 +995,10 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getNameInfo();
+  const TemplateParameterList *TPL = nullptr;
+  // FIXME: Get list of corresponding template parameters
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
 }
 
 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
@@ -1000,8 +1007,10 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getNameInfo();
+  // FIXME: Get list of corresponding template parameters
+  const TemplateParameterList *TPL = nullptr;
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
 }
 
 static bool isImplicitSelf(const Expr *E) {
@@ -1438,8 +1447,10 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getMemberNameInfo();
+  const TemplateParameterList *TPL = nullptr;
+  // FIXME: Get list of corresponding template parameters
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
 }
 
 void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
@@ -1853,8 +1864,12 @@
     assert(Args);
 
     if (Args->size() != 1) {
+      const TemplateParameterList *TPL = nullptr;
+      if (!DRE->hadMultipleCandidates())
+        if (auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
+          TPL = TD->getTemplateParameters();
       OS << "operator\"\"" << Node->getUDSuffix()->getName();
-      printTemplateArgumentList(OS, Args->asArray(), Policy);
+      printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
       OS << "()";
       return;
     }
@@ -2209,8 +2224,10 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getMemberNameInfo();
+  const TemplateParameterList *TPL = nullptr;
+  // FIXME: Get list of corresponding template parameters
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
 }
 
 void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
@@ -2223,8 +2240,10 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getMemberNameInfo();
+  const TemplateParameterList *TPL = nullptr;
+  // FIXME: Get list of corresponding template parameters
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
 }
 
 void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
@@ -2303,8 +2322,13 @@
   if (E->getTemplateKWLoc().isValid())
     OS << "template ";
   OS << E->getFoundDecl()->getName();
+  const TemplateParameterList *TPL = nullptr;
+  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
+    if (!DRE->hadMultipleCandidates())
+      if (auto *TD = dyn_cast<TemplateDecl>(E->getFoundDecl()))
+        TPL = TD->getTemplateParameters();
   printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
-                            Policy);
+                            Policy, TPL);
 }
 
 void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
Index: clang/lib/AST/NestedNameSpecifier.cpp
===================================================================
--- clang/lib/AST/NestedNameSpecifier.cpp
+++ clang/lib/AST/NestedNameSpecifier.cpp
@@ -288,8 +288,10 @@
     if (ResolveTemplateArguments && Record) {
         // Print the type trait with resolved template parameters.
         Record->printName(OS);
-        printTemplateArgumentList(OS, Record->getTemplateArgs().asArray(),
-                                  Policy);
+        // FIXME: Only pass parameter list if function template is overloaded
+        printTemplateArgumentList(
+            OS, Record->getTemplateArgs().asArray(), Policy,
+            Record->getSpecializedTemplate()->getTemplateParameters());
         break;
     }
     const Type *T = getAsType();
@@ -313,16 +315,24 @@
       SpecType->getTemplateName().print(OS, InnerPolicy, true);
 
       // Print the template argument list.
-      printTemplateArgumentList(OS, SpecType->template_arguments(),
-                                InnerPolicy);
+      const TemplateParameterList *TPL = nullptr;
+      if (TemplateDecl *TD = SpecType->getTemplateName().getAsTemplateDecl())
+        TPL = TD->getTemplateParameters();
+      // FIXME: Only pass parameter list if template is overloaded
+      printTemplateArgumentList(OS, SpecType->template_arguments(), InnerPolicy,
+                                TPL);
     } else if (const auto *DepSpecType =
                    dyn_cast<DependentTemplateSpecializationType>(T)) {
       // Print the template name without its corresponding
       // nested-name-specifier.
       OS << DepSpecType->getIdentifier()->getName();
       // Print the template argument list.
+      const TemplateParameterList *TPL = nullptr;
+      if (auto *TD = dyn_cast<TemplateDecl>(Record))
+        TPL = TD->getTemplateParameters();
+      // FIXME: Only pass template parameter list if template is overloaded
       printTemplateArgumentList(OS, DepSpecType->template_arguments(),
-                                InnerPolicy);
+                                InnerPolicy, TPL);
     } else {
       // Print the type normally
       QualType(T, 0).print(OS, InnerPolicy);
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -699,7 +699,29 @@
         StringRef Param = Params->getParam(i)->getName();
         if (Param.empty()) continue;
         TOut << Param << " = ";
-        Args.get(i).print(Policy, TOut);
+        // FIXME: Only pass parameter if template is overloaded
+        bool IncludeType = false;
+        const NamedDecl *TemplParam = Params->getParam(i);
+        if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+          const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+          if (auto *autoT = T->getAs<AutoType>()) {
+            if (autoT->getAs<DeducedType>()) {
+              IncludeType = true;
+            }
+          } else if (T->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+          const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+          if (auto *autoT = T->getAs<AutoType>()) {
+            if (autoT->getAs<DeducedType>()) {
+              IncludeType = true;
+            }
+          } else if (T->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        }
+        Args.get(i).print(Policy, TOut, IncludeType);
         TOut << ", ";
       }
     }
@@ -715,7 +737,7 @@
         StringRef Param = Params->getParam(i)->getName();
         if (Param.empty()) continue;
         TOut << Param << " = ";
-        Args->get(i).print(Policy, TOut);
+        Args->get(i).print(Policy, TOut, /*IncludeType*/ true);
         TOut << ", ";
       }
     }
Index: clang/lib/AST/DeclTemplate.cpp
===================================================================
--- clang/lib/AST/DeclTemplate.cpp
+++ clang/lib/AST/DeclTemplate.cpp
@@ -1434,8 +1434,10 @@
   ConceptName.printName(OS, Policy);
   if (hasExplicitTemplateArgs()) {
     OS << "<";
+    // FIXME: Only pass parameter if template is not overloaded
+    // FIXME: Find corresponding parameter for argument
     for (auto &ArgLoc : ArgsAsWritten->arguments())
-      ArgLoc.getArgument().print(Policy, OS);
+      ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
     OS << ">";
   }
 }
Index: clang/lib/AST/DeclPrinter.cpp
===================================================================
--- clang/lib/AST/DeclPrinter.cpp
+++ clang/lib/AST/DeclPrinter.cpp
@@ -110,8 +110,12 @@
 
     void printTemplateParameters(const TemplateParameterList *Params,
                                  bool OmitTemplateKW = false);
-    void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args);
-    void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args);
+    void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args,
+                                const TemplateParameterList *Params,
+                                bool TemplOverloaded);
+    void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args,
+                                const TemplateParameterList *Params,
+                                bool TemplOverloaded);
     void prettyPrintAttributes(Decl *D);
     void prettyPrintPragmas(Decl *D);
     void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
@@ -641,11 +645,18 @@
     llvm::raw_string_ostream POut(Proto);
     DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
     const auto *TArgAsWritten = D->getTemplateSpecializationArgsAsWritten();
+    const TemplateParameterList *TPL = D->getTemplateSpecializationInfo()
+                                           ->getTemplate()
+                                           ->getTemplateParameters();
+    // FIXME: Check if function template is overloaded
+    bool TemplOverloaded = false;
     if (TArgAsWritten && !Policy.PrintCanonicalTypes)
-      TArgPrinter.printTemplateArguments(TArgAsWritten->arguments());
+      TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(), TPL,
+                                         TemplOverloaded);
     else if (const TemplateArgumentList *TArgs =
                  D->getTemplateSpecializationArgs())
-      TArgPrinter.printTemplateArguments(TArgs->asArray());
+      TArgPrinter.printTemplateArguments(TArgs->asArray(), TPL,
+                                         TemplOverloaded);
   }
 
   QualType Ty = D->getType();
@@ -980,7 +991,11 @@
           if (const auto *TST =
                   dyn_cast<TemplateSpecializationType>(TSI->getType()))
             Args = TST->template_arguments();
-      printTemplateArguments(Args);
+      // FIXME: Check if function template is overloaded
+      bool TemplOverloaded = false;
+      printTemplateArguments(
+          Args, S->getSpecializedTemplate()->getTemplateParameters(),
+          TemplOverloaded);
     }
   }
 
@@ -1072,22 +1087,80 @@
     Out << ' ';
 }
 
-void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args) {
+void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
+                                         const TemplateParameterList *Params,
+                                         bool TemplOverloaded) {
   Out << "<";
   for (size_t I = 0, E = Args.size(); I < E; ++I) {
     if (I)
       Out << ", ";
-    Args[I].print(Policy, Out);
+    if (TemplOverloaded || !Params)
+      Args[I].print(Policy, Out, /*IncludeType*/ true);
+    else if (I >= Params->size())
+      Args[I].print(Policy, Out, /*IncludeType*/ false);
+    else {
+      bool IncludeType = false;
+      const NamedDecl *TemplParam = Params->getParam(I);
+      if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+        const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+        if (auto *autoT = T->getAs<AutoType>()) {
+          if (autoT->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (T->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+        const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+        if (auto *autoT = T->getAs<AutoType>()) {
+          if (autoT->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (T->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      }
+      Args[I].print(Policy, Out, IncludeType);
+    }
   }
   Out << ">";
 }
 
-void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args) {
+void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
+                                         const TemplateParameterList *Params,
+                                         bool TemplOverloaded) {
   Out << "<";
   for (size_t I = 0, E = Args.size(); I < E; ++I) {
     if (I)
       Out << ", ";
-    Args[I].getArgument().print(Policy, Out);
+    if (TemplOverloaded || !Params)
+      Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
+    else if (I >= Params->size())
+      Args[I].getArgument().print(Policy, Out, /*IncludeType*/ false);
+    else {
+      bool IncludeType = false;
+      const NamedDecl *TemplParam = Params->getParam(I);
+      if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+        const clang::Type *T = ParamTypeDecl->getTypeForDecl();
+        if (auto *autoT = T->getAs<AutoType>()) {
+          if (autoT->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (T->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+        const clang::Type *T = ParamValueDecl->getType().getTypePtr();
+        if (auto *autoT = T->getAs<AutoType>()) {
+          if (autoT->getAs<DeducedType>()) {
+            IncludeType = true;
+          }
+        } else if (T->getAs<DeducedType>()) {
+          IncludeType = true;
+        }
+      }
+      Args[I].getArgument().print(Policy, Out, IncludeType);
+    }
   }
   Out << ">";
 }
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1627,6 +1627,7 @@
     if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
       OS << Spec->getName();
       const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+      // FIXME: Only pass template parameter list if template isn't overloaded
       printTemplateArgumentList(
           OS, TemplateArgs.asArray(), P,
           Spec->getSpecializedTemplate()->getTemplateParameters());
@@ -2851,8 +2852,13 @@
     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
   const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
-  if (TemplateArgs)
-    printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy);
+  if (TemplateArgs) {
+    const TemplateParameterList *TPL = nullptr;
+    if (auto *TD = dyn_cast<TemplateDecl>(this))
+      TPL = TD->getTemplateParameters();
+    // FIXME: Only pass template parameter list if template isn't overloaded
+    printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy, TPL);
+  }
 }
 
 bool FunctionDecl::isVariadic() const {
Index: clang/lib/AST/ASTTypeTraits.cpp
===================================================================
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -128,11 +128,11 @@
 
 void DynTypedNode::print(llvm::raw_ostream &OS,
                          const PrintingPolicy &PP) const {
-  if (const TemplateArgument *TA = get<TemplateArgument>())
-    TA->print(PP, OS);
-  else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>())
-    TAL->getArgument().print(PP, OS);
-  else if (const TemplateName *TN = get<TemplateName>())
+  if (const TemplateArgument *TA = get<TemplateArgument>()) {
+    TA->print(PP, OS, /*IncludeType*/ true);
+  } else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>()) {
+    TAL->getArgument().print(PP, OS, /*IncludeType*/ true);
+  } else if (const TemplateName *TN = get<TemplateName>())
     TN->print(OS, PP);
   else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
     NNS->print(OS, PP);
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -7457,8 +7457,9 @@
       if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
         const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
         llvm::raw_string_ostream OS(S);
-        printTemplateArgumentList(OS, TemplateArgs.asArray(),
-                                  getPrintingPolicy());
+        printTemplateArgumentList(
+            OS, TemplateArgs.asArray(), getPrintingPolicy(),
+            Spec->getSpecializedTemplate()->getTemplateParameters());
       }
     } else {
       S += '?';
Index: clang/include/clang/AST/TemplateBase.h
===================================================================
--- clang/include/clang/AST/TemplateBase.h
+++ clang/include/clang/AST/TemplateBase.h
@@ -389,7 +389,8 @@
   TemplateArgument getPackExpansionPattern() const;
 
   /// Print this template argument to the given output stream.
-  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
+  void print(const PrintingPolicy &Policy, raw_ostream &Out,
+             bool IncludeType) const;
 
   /// Debugging aid that dumps the template argument.
   void dump(raw_ostream &Out) const;
Index: clang/include/clang/AST/StmtDataCollectors.td
===================================================================
--- clang/include/clang/AST/StmtDataCollectors.td
+++ clang/include/clang/AST/StmtDataCollectors.td
@@ -45,13 +45,46 @@
     if (const FunctionDecl *D = S->getDirectCallee()) {
       // If the function is a template specialization, we also need to handle
       // the template arguments as they are not included in the qualified name.
+      const TemplateParameterList *TPL = nullptr;
+      if (auto SD = dyn_cast<DeclRefExpr>(S))
+        if (!SD->hadMultipleCandidates())
+          if (auto *TD = dyn_cast<TemplateDecl>(D))
+            TPL = TD->getTemplateParameters();
       if (auto Args = D->getTemplateSpecializationArgs()) {
         std::string ArgString;
 
         // Print all template arguments into ArgString
         llvm::raw_string_ostream OS(ArgString);
         for (unsigned i = 0; i < Args->size(); ++i) {
-          Args->get(i).print(Context.getLangOpts(), OS);
+          if (!TPL) {
+            Args->get(i).print(Context.getLangOpts(), OS, /*IncludeType*/ true);
+          }  else if (i >= TPL->size()) {
+            Args->get(i).print(Context.getLangOpts(), OS, /*IncludeType*/ false);
+          }
+          else {
+            bool IncludeType = false;
+            const NamedDecl *TemplParam = TPL->getParam(i);
+            if (auto *ParamTypeDecl = dyn_cast<TypeDecl>(TemplParam)) {
+              const clang::Type *ParamType = ParamTypeDecl->getTypeForDecl();
+              if (auto *autoT = ParamType->getAs<AutoType>()) {
+                if (autoT->getAs<DeducedType>()) {
+                  IncludeType = true;
+                }
+              } else if (ParamType->getAs<DeducedType>()) {
+                IncludeType = true;
+              }
+            } else if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam)) {
+              const clang::Type *ParamType = ParamValueDecl->getType().getTypePtr();
+              if (auto *autoT = ParamType->getAs<AutoType>()) {
+                if (autoT->getAs<DeducedType>()) {
+                  IncludeType = true;
+                }
+              } else if (ParamType->getAs<DeducedType>()) {
+                IncludeType = true;
+              }
+            }
+            Args->get(i).print(Context.getLangOpts(), OS, IncludeType);
+          }
           // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
           OS << '\n';
         }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to