Author: Eric Li Date: 2023-06-06T15:11:09-04:00 New Revision: 3cb6ead77c6668fcd1362763b2603752c6c595fa
URL: https://github.com/llvm/llvm-project/commit/3cb6ead77c6668fcd1362763b2603752c6c595fa DIFF: https://github.com/llvm/llvm-project/commit/3cb6ead77c6668fcd1362763b2603752c6c595fa.diff LOG: [clang][TypePrinter] Add option to skip over elaborated types Elaborated types are sugar that represent how the type was spelled in the original source. When printing a type outside of that original context, the qualifiers as saved in the elaborated type will be incorrect. Additionally, their existence also inhibits the use of `PrintingCallbacks::isScopeVisible` as a customization point. Differential Revision: https://reviews.llvm.org/D149677 Added: Modified: clang/include/clang/AST/PrettyPrinter.h clang/lib/AST/TypePrinter.cpp clang/unittests/AST/TypePrinterTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index 5aeaca7beda2f..8a0bc6dfb57b8 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -60,14 +60,15 @@ struct PrintingPolicy { : Indentation(2), SuppressSpecifiers(false), SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false), SuppressScope(false), SuppressUnwrittenScope(false), - SuppressInlineNamespace(true), SuppressInitializers(false), - ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), - SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), + SuppressInlineNamespace(true), SuppressElaboration(false), + SuppressInitializers(false), ConstantArraySizeAsWritten(false), + AnonymousTagLocations(true), SuppressStrongLifetime(false), + SuppressLifetimeQualifiers(false), SuppressTemplateArgsInCXXConstructors(false), SuppressDefaultTemplateArgs(true), Bool(LO.Bool), Nullptr(LO.CPlusPlus11 || LO.C2x), NullptrTypeInNamespace(LO.CPlusPlus), - Restrict(LO.C99), Alignof(LO.CPlusPlus11), - UnderscoreAlignof(LO.C11), UseVoidForZeroParams(!LO.CPlusPlus), + Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11), + UseVoidForZeroParams(!LO.CPlusPlus), SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), @@ -139,6 +140,10 @@ struct PrintingPolicy { /// removed. unsigned SuppressInlineNamespace : 1; + /// Ignore qualifiers and tag keywords as specified by elaborated type sugar, + /// instead letting the underlying type print as normal. + unsigned SuppressElaboration : 1; + /// Suppress printing of variable initializers. /// /// This flag is used when printing the loop variable in a for-range diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 00f5fe0da8cdf..1b62f6630928c 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1576,6 +1576,11 @@ void TypePrinter::printElaboratedBefore(const ElaboratedType *T, return; } + if (Policy.SuppressElaboration) { + printBefore(T->getNamedType(), OS); + return; + } + // The tag definition will take care of these. if (!Policy.IncludeTagDefinition) { @@ -1595,6 +1600,12 @@ void TypePrinter::printElaboratedAfter(const ElaboratedType *T, raw_ostream &OS) { if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) return; + + if (Policy.SuppressElaboration) { + printAfter(T->getNamedType(), OS); + return; + } + ElaboratedTypePolicyRAII PolicyRAII(Policy); printAfter(T->getNamedType(), OS); } diff --git a/clang/unittests/AST/TypePrinterTest.cpp b/clang/unittests/AST/TypePrinterTest.cpp index 77ff442236686..f0a6eb7e9fd8c 100644 --- a/clang/unittests/AST/TypePrinterTest.cpp +++ b/clang/unittests/AST/TypePrinterTest.cpp @@ -97,6 +97,33 @@ TEST(TypePrinter, ParamsUglified) { "const f<Tp &> *", Clean)); } +TEST(TypePrinter, SuppressElaboration) { + llvm::StringLiteral Code = R"cpp( + namespace shared { + namespace a { + template <typename T> + struct S {}; + } // namespace a + namespace b { + struct Foo {}; + } // namespace b + using Alias = a::S<b::Foo>; + } // namespace shared + )cpp"; + + auto Matcher = typedefNameDecl(hasName("::shared::Alias"), + hasType(qualType().bind("id"))); + ASSERT_TRUE(PrintedTypeMatches( + Code, {}, Matcher, "a::S<b::Foo>", + [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; })); + ASSERT_TRUE(PrintedTypeMatches(Code, {}, Matcher, + "shared::a::S<shared::b::Foo>", + [](PrintingPolicy &Policy) { + Policy.SuppressElaboration = true; + Policy.FullyQualifiedName = true; + })); +} + TEST(TypePrinter, TemplateIdWithNTTP) { constexpr char Code[] = R"cpp( template <int N> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits