diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 2e48b2b46c4dae..ca64f8f6cfbed1 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -528,7 +528,8 @@ void DeclPrinter::VisitEnumDecl(EnumDecl *D) { prettyPrintAttributes(D); - Out << ' ' << *D; + if (D->getDeclName()) + Out << ' ' << D->getDeclName(); if (D->isFixed()) Out << " : " << D->getIntegerType().stream(Policy); @@ -933,7 +934,12 @@ void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) { void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) { if (D->isInline()) Out << "inline "; - Out << "namespace " << *D << " {\n"; + + Out << "namespace "; + if (D->getDeclName()) + Out << D->getDeclName() << ' '; + Out << "{\n"; + VisitDeclContext(D); Indent() << "}"; } @@ -1091,10 +1097,15 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) { if (const TemplateTemplateParmDecl *TTP = dyn_cast(D)) { - Out << "class "; + Out << "class"; + if (TTP->isParameterPack()) - Out << "..."; - Out << D->getName(); + Out << " ..."; + else if (TTP->getDeclName()) + Out << ' '; + + if (TTP->getDeclName()) + Out << TTP->getDeclName(); } else if (auto *TD = D->getTemplatedDecl()) Visit(TD); else if (const auto *Concept = dyn_cast(D)) { @@ -1216,7 +1227,7 @@ void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) { break; } - Out << Param->getDeclName().getAsString(); + Out << Param->getDeclName(); if (Param->hasExplicitBound()) { Out << " : " << Param->getUnderlyingType().getAsString(Policy); @@ -1695,10 +1706,11 @@ void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) { if (TTP->isParameterPack()) Out << " ..."; - else if (!TTP->getName().empty()) + else if (TTP->getDeclName()) Out << ' '; - Out << *TTP; + if (TTP->getDeclName()) + Out << TTP->getDeclName(); if (TTP->hasDefaultArgument()) { Out << " = "; diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp index 939c8b52c12c1e..38e46a378b4741 100644 --- a/clang/unittests/AST/DeclPrinterTest.cpp +++ b/clang/unittests/AST/DeclPrinterTest.cpp @@ -37,6 +37,7 @@ void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D, PrintingPolicyModifier PolicyModifier) { PrintingPolicy Policy = Context->getPrintingPolicy(); Policy.TerseOutput = true; + Policy.Indentation = 0; if (PolicyModifier) PolicyModifier(Policy); D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false); @@ -162,14 +163,21 @@ ::testing::AssertionResult PrintedDeclCXX11nonMSCMatches( } ::testing::AssertionResult -PrintedDeclCXX1ZMatches(StringRef Code, const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted) { - std::vector Args(1, "-std=c++1z"); - return PrintedDeclMatches(Code, - Args, - NodeMatch, - ExpectedPrinted, - "input.cc"); +PrintedDeclCXX17Matches(StringRef Code, const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, + PrintingPolicyModifier PolicyModifier = nullptr) { + std::vector Args(1, "-std=c++17"); + return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.cc", + PolicyModifier); +} + +::testing::AssertionResult +PrintedDeclC11Matches(StringRef Code, const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, + PrintingPolicyModifier PolicyModifier = nullptr) { + std::vector Args(1, "-std=c11"); + return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.c", + PolicyModifier); } ::testing::AssertionResult @@ -250,6 +258,72 @@ TEST(DeclPrinter, TestNamespaceAlias2) { // Should be: with semicolon } +TEST(DeclPrinter, TestNamespaceUnnamed) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "namespace { int X; }", + namespaceDecl(has(varDecl(hasName("X")))).bind("id"), + "namespace {\nint X;\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestNamespaceUsingDirective) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "namespace X { namespace A {} }" + "using namespace X::A;", + usingDirectiveDecl().bind("id"), "using namespace X::A", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestEnumDecl1) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "enum A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"), + "enum A {\na0,\na1,\na2\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestEnumDecl2) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "enum A { a0 = -1, a1, a2 = 1 };", enumDecl(hasName("A")).bind("id"), + "enum A {\na0 = -1,\na1,\na2 = 1\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestEnumDecl3) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "enum { a0, a1, a2 };", + enumDecl(has(enumConstantDecl(hasName("a0")))).bind("id"), + "enum {\na0,\na1,\na2\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestEnumDecl4) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "enum class A { a0, a1, a2 };", enumDecl(hasName("A")).bind("id"), + "enum class A : int {\na0,\na1,\na2\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestRecordDecl1) { + ASSERT_TRUE(PrintedDeclC11Matches( + "struct A { int a; };", recordDecl(hasName("A")).bind("id"), + "struct A {\nint a;\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestRecordDecl2) { + ASSERT_TRUE(PrintedDeclC11Matches( + "struct A { struct { int i; }; };", recordDecl(hasName("A")).bind("id"), + "struct A {\nstruct {\nint i;\n};\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + +TEST(DeclPrinter, TestRecordDecl3) { + ASSERT_TRUE(PrintedDeclC11Matches( + "union { int A; } u;", + recordDecl(has(fieldDecl(hasName("A")))).bind("id"), "union {\nint A;\n}", + [](PrintingPolicy &Policy) { Policy.TerseOutput = false; })); +} + TEST(DeclPrinter, TestCXXRecordDecl1) { ASSERT_TRUE(PrintedDeclCXX98Matches( "class A { int a; };", @@ -1119,6 +1193,39 @@ TEST(DeclPrinter, TestFunctionTemplateDecl6) { "template void A(U t)")); } +TEST(DeclPrinter, TestUnnamedTemplateParameters) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "template class> void A();", + functionTemplateDecl(hasName("A")).bind("id"), + "template class> void A()")); +} + +TEST(DeclPrinter, TestUnnamedTemplateParametersPacks) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "template class ...> void A();", + functionTemplateDecl(hasName("A")).bind("id"), + "template class ...> void A()")); +} + +TEST(DeclPrinter, TestNamedTemplateParametersPacks) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "template class ...Z> void A();", + functionTemplateDecl(hasName("A")).bind("id"), + "template class ...Z> void A()")); +} + +TEST(DeclPrinter, TestTemplateTemplateParameterWrittenWithTypename) { + ASSERT_TRUE(PrintedDeclCXX17Matches( + "template