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

Addresses @rsmith 's comments.

> On that basis, I think it would be preferable to change 
> TemplateArgument::print to accept not a bool indicating whether the type was 
> known, but instead a const NamedDecl * for the corresponding template 
> parameter. Then the logic is: include the type if we don't know the 
> corresponding parameter or if its type is deduced.

I decided to continue passing a bool and move the logic for checking if the 
corresponding parameter's type is deduced to the caller. This is to handle the 
case where we need to let the template argument printing routine know not to 
print the cast when we get a parameter list whose size is lesser than the 
length of the list of arguments.

Unfortunately, there are still some cases where there are explicit casts when 
we don't want them to be.


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*/ true);
     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,55 @@
 
 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>()) {
+    // FIXME: Only check parameter if template isn't overloaded
+    bool IncludeType = false;
+    const NamedDecl *TemplParam = get<NamedDecl>();
+    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;
+      }
+    }
+    TA->print(PP, OS, IncludeType);
+  } else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>()) {
+    // FIXME: Only check parameter if template isn't overloaded
+    bool IncludeType = false;
+    const NamedDecl *TemplParam = get<NamedDecl>();
+    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;
+      }
+    }
+    TAL->getArgument().print(PP, OS, IncludeType);
+  } 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
  • [PATCH] D77598: I... Pratyush Das via Phabricator via cfe-commits

Reply via email to