DoDoENT updated this revision to Diff 468883. DoDoENT added a comment. Update comment/documentation of the new policy to correctly reflect the change in previous diff.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D134453/new/ https://reviews.llvm.org/D134453 Files: clang/include/clang/AST/PrettyPrinter.h clang/lib/AST/APValue.cpp clang/lib/AST/TemplateBase.cpp clang/test/CodeGenCXX/debug-info-template.cpp clang/test/SemaCXX/cxx2a-nttp-printing.cpp clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp clang/test/SemaTemplate/temp_arg_string_printing.cpp clang/unittests/AST/TypePrinterTest.cpp
Index: clang/unittests/AST/TypePrinterTest.cpp =================================================================== --- clang/unittests/AST/TypePrinterTest.cpp +++ clang/unittests/AST/TypePrinterTest.cpp @@ -48,7 +48,7 @@ std::string Code = R"cpp( namespace N { template <typename> struct Type {}; - + template <typename T> void Foo(const Type<T> &Param); } @@ -115,15 +115,65 @@ ASSERT_TRUE(PrintedTypeMatches( Code, {"-std=c++20"}, Matcher, - R"(ASCII<{"this nontype template argument is [...]"}> &&)", + R"(ASCII<Str<52>{"this nontype template argument is [...]"}> &&)", [](PrintingPolicy &Policy) { Policy.EntireContentsOfLargeArray = false; })); ASSERT_TRUE(PrintedTypeMatches( Code, {"-std=c++20"}, Matcher, - R"(ASCII<{"this nontype template argument is too long to print"}> &&)", + R"(ASCII<Str<52>{"this nontype template argument is too long to print"}> &&)", [](PrintingPolicy &Policy) { Policy.EntireContentsOfLargeArray = true; })); } + +TEST(TypePrinter, TemplateIdWithComplexFullTypeNTTP) { + constexpr char Code[] = R"cpp( + template< typename T, auto ... dims > + struct NDArray {}; + + struct Dimension + { + using value_type = unsigned short; + + value_type size{ value_type( 0 ) }; + }; + + template < typename ConcreteDim > + struct DimensionImpl : Dimension {}; + + struct Width : DimensionImpl< Width > {}; + struct Height : DimensionImpl< Height > {}; + struct Channels : DimensionImpl< Channels > {}; + + inline constexpr Width W; + inline constexpr Height H; + inline constexpr Channels C; + + template< auto ... Dims > + consteval auto makeArray() noexcept + { + return NDArray< float, Dims ... >{}; + } + + [[ maybe_unused ]] auto x { makeArray< H, W, C >() }; + + )cpp"; + auto Matcher = varDecl( + allOf(hasAttr(attr::Kind::Unused), hasType(qualType().bind("id")))); + + ASSERT_TRUE(PrintedTypeMatches( + Code, {"-std=c++20"}, Matcher, + R"(NDArray<float, Height{{{0}}}, Width{{{0}}}, Channels{{{0}}}>)", + [](PrintingPolicy &Policy) { + Policy.AlwaysIncludeTypeForNonTypeTemplateArgument = false; + })); + + ASSERT_TRUE(PrintedTypeMatches( + Code, {"-std=c++20"}, Matcher, + R"(NDArray<float, Height{DimensionImpl<Height>{Dimension{0}}}, Width{DimensionImpl<Width>{Dimension{0}}}, Channels{DimensionImpl<Channels>{Dimension{0}}}>)", + [](PrintingPolicy &Policy) { + Policy.AlwaysIncludeTypeForNonTypeTemplateArgument = true; + })); +} Index: clang/test/SemaTemplate/temp_arg_string_printing.cpp =================================================================== --- clang/test/SemaTemplate/temp_arg_string_printing.cpp +++ clang/test/SemaTemplate/temp_arg_string_printing.cpp @@ -19,111 +19,111 @@ template <Str> class ASCII {}; void not_string() { - // CHECK{LITERAL}: ASCII<{{9, -1, 42}}> + // CHECK{LITERAL}: ASCII<Str<int, 3>{{9, -1, 42}}> new ASCII<(int[]){9, -1, 42}>; - // CHECK{LITERAL}: ASCII<{{3.140000e+00, 0.000000e+00, 4.200000e+01}}> + // CHECK{LITERAL}: ASCII<Str<double, 3>{{3.140000e+00, 0.000000e+00, 4.200000e+01}}> new ASCII<(double[]){3.14, 0., 42.}>; } void narrow() { - // CHECK{LITERAL}: ASCII<{""}> + // CHECK{LITERAL}: ASCII<Str<char, 1>{""}> new ASCII<"">; - // CHECK{LITERAL}: ASCII<{"the quick brown fox jumps"}> + // CHECK{LITERAL}: ASCII<Str<char, 26>{"the quick brown fox jumps"}> new ASCII<"the quick brown fox jumps">; - // CHECK{LITERAL}: ASCII<{"OVER THE LAZY DOG 0123456789"}> + // CHECK{LITERAL}: ASCII<Str<char, 29>{"OVER THE LAZY DOG 0123456789"}> new ASCII<"OVER THE LAZY DOG 0123456789">; - // CHECK{LITERAL}: ASCII<{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> + // CHECK{LITERAL}: ASCII<Str<char, 33>{"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> new ASCII<R"(\`~!@#$%^&*()_+-={}[]|'";:,.<>?/)">; - // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}> + // CHECK{LITERAL}: ASCII<Str<char, 8>{{101, 115, 99, 97, 112, 101, 0, 0}}> new ASCII<"escape\0">; - // CHECK{LITERAL}: ASCII<{"escape\r\n"}> + // CHECK{LITERAL}: ASCII<Str<char, 9>{"escape\r\n"}> new ASCII<"escape\r\n">; - // CHECK{LITERAL}: ASCII<{"escape\\\t\f\v"}> + // CHECK{LITERAL}: ASCII<Str<char, 11>{"escape\\\t\f\v"}> new ASCII<"escape\\\t\f\v">; - // CHECK{LITERAL}: ASCII<{"escape\a\bc"}> + // CHECK{LITERAL}: ASCII<Str<char, 10>{"escape\a\bc"}> new ASCII<"escape\a\b\c">; - // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}> + // CHECK{LITERAL}: ASCII<Str<char, 5>{{110, 111, 116, 17, 0}}> new ASCII<"not\x11">; - // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}> + // CHECK{LITERAL}: ASCII<Str<char, 10>{{18, 20, 127, 16, 1, 32, 97, 98, 99, 0}}> new ASCII<"\x12\x14\x7f\x10\x01 abc">; - // CHECK{LITERAL}: ASCII<{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}> + // CHECK{LITERAL}: ASCII<Str<char, 11>{{18, 20, 127, 16, 1, 32, 97, 98, 99, 100, 0}}> new ASCII<"\x12\x14\x7f\x10\x01 abcd">; - // CHECK{LITERAL}: ASCII<{"print more characters as string"}> + // CHECK{LITERAL}: ASCII<Str<char, 32>{"print more characters as string"}> new ASCII<"print more characters as string">; - // CHECK{LITERAL}: ASCII<{"print more characters as string, no uplimit"}> + // CHECK{LITERAL}: ASCII<Str<char, 44>{"print more characters as string, no uplimit"}> new ASCII<"print more characters as string, no uplimit">; } void wide() { - // CHECK{LITERAL}: ASCII<{L""}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 1>{L""}> new ASCII<L"">; - // CHECK{LITERAL}: ASCII<{L"the quick brown fox jumps"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 26>{L"the quick brown fox jumps"}> new ASCII<L"the quick brown fox jumps">; - // CHECK{LITERAL}: ASCII<{L"OVER THE LAZY DOG 0123456789"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 29>{L"OVER THE LAZY DOG 0123456789"}> new ASCII<L"OVER THE LAZY DOG 0123456789">; - // CHECK{LITERAL}: ASCII<{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 33>{L"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> new ASCII<LR"(\`~!@#$%^&*()_+-={}[]|'";:,.<>?/)">; - // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 8>{{101, 115, 99, 97, 112, 101, 0, 0}}> new ASCII<L"escape\0">; - // CHECK{LITERAL}: ASCII<{L"escape\r\n"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 9>{L"escape\r\n"}> new ASCII<L"escape\r\n">; - // CHECK{LITERAL}: ASCII<{L"escape\\\t\f\v"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 11>{L"escape\\\t\f\v"}> new ASCII<L"escape\\\t\f\v">; - // CHECK{LITERAL}: ASCII<{L"escape\a\bc"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 10>{L"escape\a\bc"}> new ASCII<L"escape\a\b\c">; - // CHECK{LITERAL}: ASCII<{{110, 111, 116, 17, 0}}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 5>{{110, 111, 116, 17, 0}}> new ASCII<L"not\x11">; - // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 10>{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 0}}> new ASCII<L"\x12\x14\xff\x597d\x88 abc">; - // CHECK{LITERAL}: ASCII<{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 100, 0}}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 11>{{18, 20, 255, 22909, 136, 32, 97, 98, 99, 100, 0}}> new ASCII<L"\x12\x14\xff\x597d\x88 abcd">; - // CHECK{LITERAL}: ASCII<{L"print more characters as string"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 32>{L"print more characters as string"}> new ASCII<L"print more characters as string">; - // CHECK{LITERAL}: ASCII<{L"print more characters as string, no uplimit"}> + // CHECK{LITERAL}: ASCII<Str<wchar_t, 44>{L"print more characters as string, no uplimit"}> new ASCII<L"print more characters as string, no uplimit">; } void utf8() { - // CHECK{LITERAL}: ASCII<{u8""}> + // CHECK{LITERAL}: ASCII<Str<char8_t, 1>{u8""}> new ASCII<u8"">; - // CHECK{LITERAL}: ASCII<{u8"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> + // CHECK{LITERAL}: ASCII<Str<char8_t, 33>{u8"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> new ASCII<u8R"(\`~!@#$%^&*()_+-={}[]|'";:,.<>?/)">; - // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}> + // CHECK{LITERAL}: ASCII<Str<char8_t, 8>{{101, 115, 99, 97, 112, 101, 0, 0}}> new ASCII<u8"escape\0">; - // CHECK{LITERAL}: ASCII<{u8"escape\r\n"}> + // CHECK{LITERAL}: ASCII<Str<char8_t, 9>{u8"escape\r\n"}> new ASCII<u8"escape\r\n">; - // CHECK{LITERAL}: ASCII<{{229, 165, 189, 239, 191, 189, 0}}> + // CHECK{LITERAL}: ASCII<Str<char8_t, 7>{{229, 165, 189, 239, 191, 189, 0}}> new ASCII<u8"\u597d\ufffd">; - // CHECK{LITERAL}: ASCII<{u8"print more characters as string, no uplimit"}> + // CHECK{LITERAL}: ASCII<Str<char8_t, 44>{u8"print more characters as string, no uplimit"}> new ASCII<u8"print more characters as string, no uplimit">; } void utf16() { - // CHECK{LITERAL}: ASCII<{u""}> + // CHECK{LITERAL}: ASCII<Str<char16_t, 1>{u""}> new ASCII<u"">; - // CHECK{LITERAL}: ASCII<{u"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> + // CHECK{LITERAL}: ASCII<Str<char16_t, 33>{u"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> new ASCII<uR"(\`~!@#$%^&*()_+-={}[]|'";:,.<>?/)">; - // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}> + // CHECK{LITERAL}: ASCII<Str<char16_t, 8>{{101, 115, 99, 97, 112, 101, 0, 0}}> new ASCII<u"escape\0">; - // CHECK{LITERAL}: ASCII<{u"escape\r\n"}> + // CHECK{LITERAL}: ASCII<Str<char16_t, 9>{u"escape\r\n"}> new ASCII<u"escape\r\n">; - // CHECK{LITERAL}: ASCII<{{22909, 65533, 0}}> + // CHECK{LITERAL}: ASCII<Str<char16_t, 3>{{22909, 65533, 0}}> new ASCII<u"\u597d\ufffd">; - // CHECK{LITERAL}: ASCII<{u"print more characters as string, no uplimit"}> + // CHECK{LITERAL}: ASCII<Str<char16_t, 44>{u"print more characters as string, no uplimit"}> new ASCII<u"print more characters as string, no uplimit">; } void utf32() { - // CHECK{LITERAL}: ASCII<{U""}> + // CHECK{LITERAL}: ASCII<Str<char32_t, 1>{U""}> new ASCII<U"">; - // CHECK{LITERAL}: ASCII<{U"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> + // CHECK{LITERAL}: ASCII<Str<char32_t, 33>{U"\\`~!@#$%^&*()_+-={}[]|\'\";:,.<>?/"}> new ASCII<UR"(\`~!@#$%^&*()_+-={}[]|'";:,.<>?/)">; - // CHECK{LITERAL}: ASCII<{{101, 115, 99, 97, 112, 101, 0, 0}}> + // CHECK{LITERAL}: ASCII<Str<char32_t, 8>{{101, 115, 99, 97, 112, 101, 0, 0}}> new ASCII<U"escape\0">; - // CHECK{LITERAL}: ASCII<{U"escape\r\n"}> + // CHECK{LITERAL}: ASCII<Str<char32_t, 9>{U"escape\r\n"}> new ASCII<U"escape\r\n">; - // CHECK{LITERAL}: ASCII<{{22909, 131358, 0}}> + // CHECK{LITERAL}: ASCII<Str<char32_t, 3>{{22909, 131358, 0}}> new ASCII<U"\u597d\U0002011E">; - // CHECK{LITERAL}: ASCII<{U"print more characters as string, no uplimit"}> + // CHECK{LITERAL}: ASCII<Str<char32_t, 44>{U"print more characters as string, no uplimit"}> new ASCII<U"print more characters as string, no uplimit">; } Index: clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp =================================================================== --- clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp +++ clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp @@ -185,7 +185,7 @@ namespace Diags { struct A { int n, m; }; template<A a> struct X { static_assert(a.n == a.m); }; // expected-error {{static assertion failed due to requirement 'Diags::A{1, 2}.n == Diags::A{1, 2}.m'}} - template struct X<A{1, 2}>; // expected-note {{in instantiation of template class 'Diags::X<{1, 2}>' requested here}} + template struct X<A{1, 2}>; // expected-note {{in instantiation of template class 'Diags::X<Diags::A{1, 2}>' requested here}} } namespace CTADPartialOrder { Index: clang/test/SemaCXX/cxx2a-nttp-printing.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-nttp-printing.cpp +++ clang/test/SemaCXX/cxx2a-nttp-printing.cpp @@ -16,13 +16,13 @@ " is too long"> a; Foo(a); // expected-error {{no matching function}} - decltype(a)::display(); // expected-error {{no member named 'display' in 'ASCII<{"this nontype template argument is [...]"}>'}} + decltype(a)::display(); // expected-error {{no member named 'display' in 'ASCII<Str<43>{"this nontype template argument is [...]"}>'}} } void test_non_ascii() { ASCII<"wait a s\033cond"> a; Bar(a); // expected-error {{no matching function}} - decltype(a)::display(); // expected-error {{no member named 'display' in 'ASCII<{{119, 97, 105, 116, 32, 97, 32, 115, 27, 99, ...}}>'}} + decltype(a)::display(); // expected-error {{no member named 'display' in 'ASCII<Str<14>{{119, 97, 105, 116, 32, 97, 32, 115, 27, 99, ...}}>'}} } // The dialects (C++20 and above) that accept string literals as non-type @@ -30,5 +30,5 @@ void test_trigraph() { ASCII<"what??!"> a; // expected-warning {{trigraph ignored}} Meow(a); // expected-error {{no matching function}} - decltype(a)::display(); // expected-error {{no member named 'display' in 'ASCII<{"what??!"}>'}} + decltype(a)::display(); // expected-error {{no member named 'display' in 'ASCII<Str<8>{"what??!"}>'}} } Index: clang/test/CodeGenCXX/debug-info-template.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-template.cpp +++ clang/test/CodeGenCXX/debug-info-template.cpp @@ -165,7 +165,7 @@ static constexpr const ClassTemplateArg &Arg = A; }; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArgTemplate<{1, 2.000000e+00}>", {{.*}}, templateParams: ![[CLASS_TEMP_ARGS:[0-9]*]], +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArgTemplate<ClassTemplateArg{1, 2.000000e+00}>", {{.*}}, templateParams: ![[CLASS_TEMP_ARGS:[0-9]*]], // CHECK: ![[CLASS_TEMP_ARG_CONST_REF_TYPE:[0-9]*]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: ![[CLASS_TEMP_ARG_CONST_TYPE:[0-9]*]], // CHECK: ![[CLASS_TEMP_ARG_CONST_TYPE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[CLASS_TEMP_ARG_TYPE:[0-9]*]]) // CHECK: ![[CLASS_TEMP_ARG_TYPE]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "ClassTemplateArg", @@ -221,20 +221,20 @@ template<typename T1, typename T2, typename T3, typename T4> void f1() { } template void f1<t1 () volatile, t1 () const volatile, t1 () &, t1 () &&>(); -// CHECK: !DISubprogram(name: "f1<RawFuncQual::t1 () volatile, RawFuncQual::t1 () const volatile, RawFuncQual::t1 () &, RawFuncQual::t1 () &&>", +// CHECK: !DISubprogram(name: "f1<RawFuncQual::t1 () volatile, RawFuncQual::t1 () const volatile, RawFuncQual::t1 () &, RawFuncQual::t1 () &&>", // CHECK-SAME: templateParams: ![[RAW_FUNC_QUAL_ARGS:[0-9]*]], // CHECK: ![[RAW_FUNC_QUAL_ARGS]] = !{![[RAW_FUNC_QUAL_T1:[0-9]*]], ![[RAW_FUNC_QUAL_T2:[0-9]*]], ![[RAW_FUNC_QUAL_T3:[0-9]*]], ![[RAW_FUNC_QUAL_T4:[0-9]*]]} -// CHECK: ![[RAW_FUNC_QUAL_T1]] = !DITemplateTypeParameter(name: "T1", type: ![[RAW_FUNC_QUAL_VOL:[0-9]*]]) +// CHECK: ![[RAW_FUNC_QUAL_T1]] = !DITemplateTypeParameter(name: "T1", type: ![[RAW_FUNC_QUAL_VOL:[0-9]*]]) // CHECK: ![[RAW_FUNC_QUAL_VOL]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[RAW_FUNC_QUAL_TYPE:[0-9]*]]) // CHECK: ![[RAW_FUNC_QUAL_TYPE]] = !DISubroutineType(types: ![[RAW_FUNC_QUAL_LIST:[0-9]*]] // CHECK: ![[RAW_FUNC_QUAL_LIST]] = !{![[RAW_FUNC_QUAL_STRUCT:[0-9]*]]} // CHECK: ![[RAW_FUNC_QUAL_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "t1" -// CHECK: ![[RAW_FUNC_QUAL_T2]] = !DITemplateTypeParameter(name: "T2", type: ![[RAW_FUNC_QUAL_CNST:[0-9]*]]) +// CHECK: ![[RAW_FUNC_QUAL_T2]] = !DITemplateTypeParameter(name: "T2", type: ![[RAW_FUNC_QUAL_CNST:[0-9]*]]) // CHECK: ![[RAW_FUNC_QUAL_CNST]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[RAW_FUNC_QUAL_TYPE:[0-9]*]]) -// CHECK: ![[RAW_FUNC_QUAL_T3]] = !DITemplateTypeParameter(name: "T3", type: ![[RAW_FUNC_QUAL_REF:[0-9]*]]) +// CHECK: ![[RAW_FUNC_QUAL_T3]] = !DITemplateTypeParameter(name: "T3", type: ![[RAW_FUNC_QUAL_REF:[0-9]*]]) // CHECK: ![[RAW_FUNC_QUAL_REF]] = !DISubroutineType(flags: DIFlagLValueReference, types: ![[RAW_FUNC_QUAL_LIST]]) -// CHECK: ![[RAW_FUNC_QUAL_T4]] = !DITemplateTypeParameter(name: "T4", type: ![[RAW_FUNC_QUAL_REF_REF:[0-9]*]]) +// CHECK: ![[RAW_FUNC_QUAL_T4]] = !DITemplateTypeParameter(name: "T4", type: ![[RAW_FUNC_QUAL_REF_REF:[0-9]*]]) // CHECK: ![[RAW_FUNC_QUAL_REF_REF]] = !DISubroutineType(flags: DIFlagRValueReference, types: ![[RAW_FUNC_QUAL_LIST]]) } // namespace RawFuncQual Index: clang/lib/AST/TemplateBase.cpp =================================================================== --- clang/lib/AST/TemplateBase.cpp +++ clang/lib/AST/TemplateBase.cpp @@ -432,10 +432,10 @@ } case Declaration: { - // FIXME: Include the type if it's not obvious from the context. NamedDecl *ND = getAsDecl(); if (getParamTypeForDecl()->isRecordType()) { if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) { + TPO->getType().getUnqualifiedType().print(Out, Policy); TPO->printAsInit(Out, Policy); break; } Index: clang/lib/AST/APValue.cpp =================================================================== --- clang/lib/AST/APValue.cpp +++ clang/lib/AST/APValue.cpp @@ -892,6 +892,8 @@ assert(BI != CD->bases_end()); if (!First) Out << ", "; + if (Policy.AlwaysIncludeTypeForNonTypeTemplateArgument) + BI->getType().getUnqualifiedType().print(Out, Policy); getStructBase(I).printPretty(Out, Policy, BI->getType(), Ctx); First = false; } Index: clang/include/clang/AST/PrettyPrinter.h =================================================================== --- clang/include/clang/AST/PrettyPrinter.h +++ clang/include/clang/AST/PrettyPrinter.h @@ -75,7 +75,7 @@ PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true), UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false), CleanUglifiedParameters(false), EntireContentsOfLargeArray(true), - UseEnumerators(true) {} + UseEnumerators(true), AlwaysIncludeTypeForNonTypeTemplateArgument(false) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -295,6 +295,42 @@ /// enumerator name or via cast of an integer. unsigned UseEnumerators : 1; + /// Whether to always print full type names of non-type template arguments. + /// + /// \code + /// template< typename T, auto ... dims > + /// struct NDArray {}; + + /// struct Dimension + /// { + /// using value_type = unsigned short; + + /// value_type size{ value_type( 0 ) }; + /// }; + + /// template < typename ConcreteDim > + /// struct DimensionImpl : Dimension {}; + + /// struct Width : DimensionImpl< Width > {}; + /// struct Height : DimensionImpl< Height > {}; + /// struct Channels : DimensionImpl< Channels > {}; + + /// inline constexpr Width W; + /// inline constexpr Height H; + /// inline constexpr Channels C; + + /// template< auto ... Dims > + /// consteval auto makeArray() noexcept + /// { + /// return NDArray< float, Dims ... >{}; + /// } + + /// [[ maybe_unused ]] auto x { makeArray< H, W, C >() }; + /// \endcode + /// + /// decltype(x) will be printed as "NDArray<float, Height{DimensionImpl<Height>{Dimension{0}}}, Width{DimensionImpl<Width>{Dimension{0}}}, Channels{DimensionImpl<Channels>{Dimension{0}}}>" if enabled and as "NDArray<float, Height{{{0}}}, Width{{{0}}}, Channels{{{0}}}>" if disabled + unsigned AlwaysIncludeTypeForNonTypeTemplateArgument : 1; + /// Callbacks to use to allow the behavior of printing to be customized. const PrintingCallbacks *Callbacks = nullptr; };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits