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