DoDoENT updated this revision to Diff 468881.
DoDoENT retitled this revision from "Introduce the
`AlwaysIncludeTypeForNonTypeTemplateArgument` into printing policy" to
"Disambiguate type names when printing NTTP types".
DoDoENT edited the summary of this revision.
DoDoENT added a comment.
Implemented changes requested in the review:
- type name of NTTP is now always printed, as C++ requires
- keep full NTTP type printing behind a policy, for those that want/need that
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,17 @@
/// enumerator name or via cast of an integer.
unsigned UseEnumerators : 1;
+ /// Whether to always print full type names of non-type template arguments.
+ ///
+ /// \code
+ /// struct Point { int x, y; };
+ /// template< Point p > struct S {};
+ /// S< Point{ 1, 2 } > s;
+ /// \endcode
+ ///
+ /// decltype(s) will be printed as "S<Point{1,2}>" if enabled and as "S<{1,2}>" 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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits