DoDoENT created this revision. Herald added a project: All. DoDoENT requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
If enabled, it will ensure that full type name is always printed. This should fix issue reported here: https://github.com/llvm/llvm-project/issues/57562 Currently, I've disabled the policy by default, as enabling it makes some tests fail, notably: - CodeGenCXX/debug-info-template.cpp - SemaCXX/constexpr-printing.cpp - SemaCXX/cxx2a-nttp-printing.cpp - SemaTemplate/temp_arg_string_printing.cpp However, my opinion is that those tests should be updated and new policy always enabled, to mimic GCC's behavior. I've added 2 new tests in AST/TypePrinterTest.cpp, one of which actually demonstrates the issue I've had in the first place (which was also reported on GitHub). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D134453 Files: clang/include/clang/AST/PrettyPrinter.h clang/lib/AST/APValue.cpp clang/lib/AST/TemplateBase.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); } @@ -127,3 +127,86 @@ Policy.EntireContentsOfLargeArray = true; })); } + +TEST(TypePrinter, TemplateIdWithFullTypeNTTP) { + constexpr char Code[] = R"cpp( + enum struct Encoding { UTF8, ASCII }; + template <int N, Encoding E = Encoding::ASCII> + struct Str { + constexpr Str(char const (&s)[N]) { __builtin_memcpy(value, s, N); } + char value[N]; + }; + template <Str> class ASCII {}; + + ASCII<"some string"> x; + )cpp"; + auto Matcher = classTemplateSpecializationDecl( + hasName("ASCII"), has(cxxConstructorDecl( + isMoveConstructor(), + has(parmVarDecl(hasType(qualType().bind("id"))))))); + + ASSERT_TRUE(PrintedTypeMatches( + Code, {"-std=c++20"}, Matcher, + R"(ASCII<Str<12, Encoding::ASCII>{"some string"}> &&)", + [](PrintingPolicy &Policy) { + Policy.AlwaysIncludeTypeForNonTypeTemplateArgument = true; + })); + + ASSERT_TRUE(PrintedTypeMatches( + Code, {"-std=c++20"}, Matcher, R"(ASCII<{"some string"}> &&)", + [](PrintingPolicy &Policy) { + Policy.AlwaysIncludeTypeForNonTypeTemplateArgument = false; + })); +} + +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, {{{0}}}, {{{0}}}, {{{0}}}>)", + [](PrintingPolicy &Policy) { + Policy.PrintCanonicalTypes = true; + 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.PrintCanonicalTypes = true; + Policy.AlwaysIncludeTypeForNonTypeTemplateArgument = true; + })); +} Index: clang/lib/AST/TemplateBase.cpp =================================================================== --- clang/lib/AST/TemplateBase.cpp +++ clang/lib/AST/TemplateBase.cpp @@ -432,10 +432,11 @@ } 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)) { + if (Policy.AlwaysIncludeTypeForNonTypeTemplateArgument) + 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,18 @@ /// enumerator name or via cast of an integer. unsigned UseEnumerators : 1; + /// Whether to 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, + /// regardless if PrintCanonicalTypes is enabled. + 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