reikdas updated this revision to Diff 307587.
reikdas added a comment.

Address @rsmith 's comments.


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

https://reviews.llvm.org/D77598

Files:
  clang/include/clang/AST/DeclTemplate.h
  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,17 @@
   X<f> y;
   int n = y.call(); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}}
 }
+
+namespace TypeSuffix {
+  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 'TypeSuffix::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 'TypeSuffix::A<2>'; did you mean 'A<1>::type'?}}
+
+  template <auto... N> struct X {};
+  X<1, 1u>::type y; // expected-error {{no type named 'type' in 'TypeSuffix::X<1, 1u>'}}
+  X<1, 1>::type z; // expected-error {{no type named 'type' in 'TypeSuffix::X<1, 1>'}}
+}
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, u32'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, u32'34', u32'1090', u32'1077', u32'1089', u32'1090', u32'95', u32'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
@@ -588,7 +588,7 @@
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       Template->printName(OS);
       printTemplateArgumentList(OS, Active->template_arguments(),
-                                getPrintingPolicy());
+                                getPrintingPolicy(), /*TPL*/ nullptr);
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_arg_instantiation_here)
         << OS.str()
@@ -654,7 +654,7 @@
       llvm::raw_svector_ostream OS(TemplateArgsStr);
       FD->printName(OS);
       printTemplateArgumentList(OS, Active->template_arguments(),
-                                getPrintingPolicy());
+                                getPrintingPolicy(), /*TPL*/ nullptr);
       Diags.Report(Active->PointOfInstantiation,
                    diag::note_default_function_arg_instantiation_here)
         << OS.str()
@@ -805,9 +805,13 @@
       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();
         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,15 @@
     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
+        Arg.print(S.getPrintingPolicy(), OS,
+                  TemplateParameterList::shouldIncludeTypeForArgument(TPL, i));
+        i++;
+      }
       OS << ">";
     }
     OS << "'";
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -3561,7 +3561,9 @@
       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);
+        printTemplateArgumentList(
+            OS, IV->getTemplateArgs().asArray(), Policy,
+            IV->getSpecializedTemplate()->getTemplateParameters());
       }
       return true;
     }
@@ -10934,7 +10936,9 @@
     }
 
     Out << " = ";
-    Args[I].print(getPrintingPolicy(), Out);
+    Args[I].print(
+        getPrintingPolicy(), Out,
+        TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
   }
 
   Out << ']';
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -968,15 +968,20 @@
 }
 
 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);
+    Arg.getArgument().print(
+        PrintingPolicy, OS,
+        TemplateParameterList::shouldIncludeTypeForArgument(Params, i));
     First = false;
+    i++;
   }
   return std::string(OS.str());
 }
@@ -984,11 +989,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 +1032,7 @@
     if (DiagID)
       S.RequireCompleteType(
           Loc, TraitTy, DiagID,
-          printTemplateArgs(S.Context.getPrintingPolicy(), Args));
+          printTemplateArgs(S.Context.getPrintingPolicy(), Args, Params));
     return true;
   }
 
@@ -1066,7 +1072,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 +1088,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 +1117,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 +1125,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,8 @@
   // Add any template specialization args.
   if (Info) {
     const TemplateArgumentList *TArgs = Info->TemplateArguments;
-    printTemplateArgumentList(OS, TArgs->asArray(), getPrintingPolicy());
+    printTemplateArgumentList(OS, TArgs->asArray(), getPrintingPolicy(),
+                              /*TPL*/ nullptr);
   }
 
   // Copy this name on the side and use its reference.
@@ -1191,7 +1192,8 @@
   SmallString<128> NS;
   llvm::raw_svector_ostream OS(NS);
   Ty->getTemplateName().print(OS, getPrintingPolicy(), /*qualified*/ false);
-  printTemplateArgumentList(OS, Ty->template_arguments(), getPrintingPolicy());
+  printTemplateArgumentList(OS, Ty->template_arguments(), getPrintingPolicy(),
+                            /*TPL*/ nullptr);
 
   SourceLocation Loc = AliasDecl->getLocation();
   return DBuilder.createTypedef(Src, OS.str(), getOrCreateFile(Loc),
@@ -2094,7 +2096,7 @@
   // Add any template specialization args.
   if (const auto *VTpl = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
     printTemplateArgumentList(OS, VTpl->getTemplateArgs().asArray(),
-                              getPrintingPolicy());
+                              getPrintingPolicy(), /*TPL*/ nullptr);
   }
 
   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,14 @@
     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);
+      printArgument(
+          Arg, Policy, ArgOS,
+          TemplateParameterList::shouldIncludeTypeForArgument(TPL, i));
     }
     StringRef ArgString = ArgOS.str();
 
@@ -2006,6 +2010,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,55 @@
 
   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 if (T->isUnsignedIntegerType())
+        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:
+        if (T->isUnsignedIntegerType() && T->isChar8Type())
+          Out << "u8'" << Val << "'";
+        else if (T->isUnsignedIntegerType() && T->isChar16Type())
+          Out << "u16'" << Val << "'";
+        else if (T->isUnsignedIntegerType() && T->isChar32Type())
+          Out << "u32'" << Val << "'";
+        else
+          Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
+              << Val;
+        break;
+      }
+    }
+  } else
     Out << Val;
-  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -339,8 +382,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 +413,7 @@
   }
 
   case NullPtr:
+    // FIXME: Include the type if it's not obvious from the context.
     Out << "nullptr";
     break;
 
@@ -382,7 +427,7 @@
     break;
 
   case Integral:
-    printIntegral(*this, Out, Policy);
+    printIntegral(*this, Out, Policy, IncludeType);
     break;
 
   case Expression:
@@ -398,7 +443,7 @@
       else
         Out << ", ";
 
-      P.print(Policy, Out);
+      P.print(Policy, Out, IncludeType);
     }
     Out << ">";
     break;
@@ -409,7 +454,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 +549,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(
@@ -991,7 +996,8 @@
     OS << "template ";
   OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy,
+                              /*TPL*/ nullptr);
 }
 
 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
@@ -1001,7 +1007,8 @@
     OS << "template ";
   OS << Node->getNameInfo();
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy,
+                              /*TPL*/ nullptr);
 }
 
 static bool isImplicitSelf(const Expr *E) {
@@ -1438,8 +1445,14 @@
   if (Node->hasTemplateKeyword())
     OS << "template ";
   OS << Node->getMemberNameInfo();
+  const TemplateParameterList *TPL = nullptr;
+  if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl()))
+    TPL = FD->getDescribedTemplateParams();
+  else if (auto *TD =
+               dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
+    TPL = TD->getDescribedTemplateParams();
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
 }
 
 void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
@@ -1853,8 +1866,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;
     }
@@ -2210,7 +2227,8 @@
     OS << "template ";
   OS << Node->getMemberNameInfo();
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy,
+                              /*TPL*/ nullptr);
 }
 
 void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
@@ -2224,7 +2242,8 @@
     OS << "template ";
   OS << Node->getMemberNameInfo();
   if (Node->hasExplicitTemplateArgs())
-    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+    printTemplateArgumentList(OS, Node->template_arguments(), Policy,
+                              /*TPL*/ nullptr);
 }
 
 void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
@@ -2304,7 +2323,8 @@
     OS << "template ";
   OS << E->getFoundDecl()->getName();
   printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
-                            Policy);
+                            Policy,
+                            E->getNamedConcept()->getTemplateParameters());
 }
 
 void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
Index: clang/lib/AST/NestedNameSpecifier.cpp
===================================================================
--- clang/lib/AST/NestedNameSpecifier.cpp
+++ clang/lib/AST/NestedNameSpecifier.cpp
@@ -288,8 +288,9 @@
     if (ResolveTemplateArguments && Record) {
         // Print the type trait with resolved template parameters.
         Record->printName(OS);
-        printTemplateArgumentList(OS, Record->getTemplateArgs().asArray(),
-                                  Policy);
+        printTemplateArgumentList(
+            OS, Record->getTemplateArgs().asArray(), Policy,
+            Record->getSpecializedTemplate()->getTemplateParameters());
         break;
     }
     const Type *T = getAsType();
@@ -313,8 +314,11 @@
       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();
+      printTemplateArgumentList(OS, SpecType->template_arguments(), InnerPolicy,
+                                TPL);
     } else if (const auto *DepSpecType =
                    dyn_cast<DependentTemplateSpecializationType>(T)) {
       // Print the template name without its corresponding
@@ -322,7 +326,7 @@
       OS << DepSpecType->getIdentifier()->getName();
       // Print the template argument list.
       printTemplateArgumentList(OS, DepSpecType->template_arguments(),
-                                InnerPolicy);
+                                InnerPolicy, /*TPL*/ nullptr);
     } 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,10 @@
         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
+        Args.get(i).print(
+            Policy, TOut,
+            TemplateParameterList::shouldIncludeTypeForArgument(Params, i));
         TOut << ", ";
       }
     }
@@ -715,7 +718,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,36 @@
     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
+      Args[I].print(
+          Policy, Out,
+          TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
   }
   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)
+      Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
+    else
+      Args[I].getArgument().print(
+          Policy, Out,
+          TemplateParameterList::shouldIncludeTypeForArgument(Params, I));
   }
   Out << ">";
 }
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -2852,7 +2852,8 @@
   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
   const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
   if (TemplateArgs)
-    printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy);
+    printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy,
+                              /*TPL*/ nullptr);
 }
 
 bool FunctionDecl::isVariadic() const {
Index: clang/lib/AST/ASTTypeTraits.cpp
===================================================================
--- clang/lib/AST/ASTTypeTraits.cpp
+++ clang/lib/AST/ASTTypeTraits.cpp
@@ -129,9 +129,9 @@
 void DynTypedNode::print(llvm::raw_ostream &OS,
                          const PrintingPolicy &PP) const {
   if (const TemplateArgument *TA = get<TemplateArgument>())
-    TA->print(PP, OS);
+    TA->print(PP, OS, /*IncludeType*/ true);
   else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>())
-    TAL->getArgument().print(PP, OS);
+    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>())
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,29 @@
     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 *ParamValueDecl = dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
+              if (auto *ParamType = ParamValueDecl->getType()->getContainedDeducedType())
+                Args->get(i).print(Context.getLangOpts(), OS, IncludeType);
+          }
           // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
           OS << '\n';
         }
Index: clang/include/clang/AST/DeclTemplate.h
===================================================================
--- clang/include/clang/AST/DeclTemplate.h
+++ clang/include/clang/AST/DeclTemplate.h
@@ -204,6 +204,21 @@
              bool OmitTemplateKW = false) const;
   void print(raw_ostream &Out, const ASTContext &Context,
              const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
+
+  static bool shouldIncludeTypeForArgument(const TemplateParameterList *TPL,
+                                           unsigned Idx) {
+    if (!TPL)
+      return true;
+    else if (Idx >= TPL->size())
+      return false;
+    else {
+      const NamedDecl *TemplParam = TPL->getParam(Idx);
+      if (auto *ParamValueDecl = dyn_cast<ValueDecl>(TemplParam))
+        if (ParamValueDecl->getType()->getContainedDeducedType())
+          return true;
+      return false;
+    }
+  }
 };
 
 /// Stores a list of template parameters and the associated
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D77598: I... Pratyush Das via Phabricator via cfe-commits

Reply via email to