From 35019dbe6ba58e572818c12279029db6f75cca61 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Thu, 16 Nov 2017 01:28:25 +0000 Subject: [PATCH] [DeclPrinter] Honor TerseOutput for constructors Patch by Nikolai Kosjar! Differential Revision: https://reviews.llvm.org/D39957 llvm-svn: 318365 --- clang/lib/AST/DeclPrinter.cpp | 115 ++++++++++++----------- clang/test/Index/comment-cplus-decls.cpp | 2 +- clang/unittests/AST/DeclPrinterTest.cpp | 60 ++++++++---- 3 files changed, 104 insertions(+), 73 deletions(-) diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 68adfc7c5630..d40599ed2fe1 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -608,66 +608,69 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } if (CDecl) { - bool HasInitializerList = false; - for (const auto *BMInitializer : CDecl->inits()) { - if (BMInitializer->isInClassMemberInitializer()) - continue; + if (!Policy.TerseOutput) { + bool HasInitializerList = false; + for (const auto *BMInitializer : CDecl->inits()) { + if (BMInitializer->isInClassMemberInitializer()) + continue; - if (!HasInitializerList) { - Proto += " : "; - Out << Proto; - Proto.clear(); - HasInitializerList = true; - } else - Out << ", "; - - if (BMInitializer->isAnyMemberInitializer()) { - FieldDecl *FD = BMInitializer->getAnyMember(); - Out << *FD; - } else { - Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy); - } - - Out << "("; - if (!BMInitializer->getInit()) { - // Nothing to print - } else { - Expr *Init = BMInitializer->getInit(); - if (ExprWithCleanups *Tmp = dyn_cast(Init)) - Init = Tmp->getSubExpr(); - - Init = Init->IgnoreParens(); - - Expr *SimpleInit = nullptr; - Expr **Args = nullptr; - unsigned NumArgs = 0; - if (ParenListExpr *ParenList = dyn_cast(Init)) { - Args = ParenList->getExprs(); - NumArgs = ParenList->getNumExprs(); - } else if (CXXConstructExpr *Construct - = dyn_cast(Init)) { - Args = Construct->getArgs(); - NumArgs = Construct->getNumArgs(); + if (!HasInitializerList) { + Proto += " : "; + Out << Proto; + Proto.clear(); + HasInitializerList = true; } else - SimpleInit = Init; - - if (SimpleInit) - SimpleInit->printPretty(Out, nullptr, Policy, Indentation); - else { - for (unsigned I = 0; I != NumArgs; ++I) { - assert(Args[I] != nullptr && "Expected non-null Expr"); - if (isa(Args[I])) - break; - - if (I) - Out << ", "; - Args[I]->printPretty(Out, nullptr, Policy, Indentation); + Out << ", "; + + if (BMInitializer->isAnyMemberInitializer()) { + FieldDecl *FD = BMInitializer->getAnyMember(); + Out << *FD; + } else { + Out << QualType(BMInitializer->getBaseClass(), 0) + .getAsString(Policy); + } + + Out << "("; + if (!BMInitializer->getInit()) { + // Nothing to print + } else { + Expr *Init = BMInitializer->getInit(); + if (ExprWithCleanups *Tmp = dyn_cast(Init)) + Init = Tmp->getSubExpr(); + + Init = Init->IgnoreParens(); + + Expr *SimpleInit = nullptr; + Expr **Args = nullptr; + unsigned NumArgs = 0; + if (ParenListExpr *ParenList = dyn_cast(Init)) { + Args = ParenList->getExprs(); + NumArgs = ParenList->getNumExprs(); + } else if (CXXConstructExpr *Construct = + dyn_cast(Init)) { + Args = Construct->getArgs(); + NumArgs = Construct->getNumArgs(); + } else + SimpleInit = Init; + + if (SimpleInit) + SimpleInit->printPretty(Out, nullptr, Policy, Indentation); + else { + for (unsigned I = 0; I != NumArgs; ++I) { + assert(Args[I] != nullptr && "Expected non-null Expr"); + if (isa(Args[I])) + break; + + if (I) + Out << ", "; + Args[I]->printPretty(Out, nullptr, Policy, Indentation); + } } } + Out << ")"; + if (BMInitializer->isPackExpansion()) + Out << "..."; } - Out << ")"; - if (BMInitializer->isPackExpansion()) - Out << "..."; } } else if (!ConversionDecl && !isa(D)) { if (FT && FT->hasTrailingReturn()) { @@ -712,7 +715,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (D->getBody()) D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation); } else { - if (isa(*D)) + if (!Policy.TerseOutput && isa(*D)) Out << " {}"; } } diff --git a/clang/test/Index/comment-cplus-decls.cpp b/clang/test/Index/comment-cplus-decls.cpp index 6e32c60a2228..c4b08eb779a1 100644 --- a/clang/test/Index/comment-cplus-decls.cpp +++ b/clang/test/Index/comment-cplus-decls.cpp @@ -46,7 +46,7 @@ protected: data* reserved; }; // CHECK: class Test {} -// CHECK: Test() : reserved(new Test::data()) {} +// CHECK: Test() // CHECK: unsigned int getID() const // CHECK: ~Test(){{( noexcept)?}} // CHECK: Test::data *reserved diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp index ae6d0f0dd2e2..dc1977d87689 100644 --- a/clang/unittests/AST/DeclPrinterTest.cpp +++ b/clang/unittests/AST/DeclPrinterTest.cpp @@ -31,18 +31,25 @@ using namespace tooling; namespace { -void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D) { +using PrintingPolicyModifier = void (*)(PrintingPolicy &policy); + +void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D, + PrintingPolicyModifier PolicyModifier) { PrintingPolicy Policy = Context->getPrintingPolicy(); Policy.TerseOutput = true; + if (PolicyModifier) + PolicyModifier(Policy); D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false); } class PrintMatch : public MatchFinder::MatchCallback { SmallString<1024> Printed; unsigned NumFoundDecls; + PrintingPolicyModifier PolicyModifier; public: - PrintMatch() : NumFoundDecls(0) {} + PrintMatch(PrintingPolicyModifier PolicyModifier) + : NumFoundDecls(0), PolicyModifier(PolicyModifier) {} void run(const MatchFinder::MatchResult &Result) override { const Decl *D = Result.Nodes.getNodeAs("id"); @@ -53,7 +60,7 @@ public: return; llvm::raw_svector_ostream Out(Printed); - PrintDecl(Out, Result.Context, D); + PrintDecl(Out, Result.Context, D, PolicyModifier); } StringRef getPrinted() const { @@ -65,13 +72,12 @@ public: } }; -::testing::AssertionResult PrintedDeclMatches( - StringRef Code, - const std::vector &Args, - const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted, - StringRef FileName) { - PrintMatch Printer; +::testing::AssertionResult +PrintedDeclMatches(StringRef Code, const std::vector &Args, + const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, StringRef FileName, + PrintingPolicyModifier PolicyModifier = nullptr) { + PrintMatch Printer(PolicyModifier); MatchFinder Finder; Finder.addMatcher(NodeMatch, &Printer); std::unique_ptr Factory( @@ -109,16 +115,17 @@ public: "input.cc"); } -::testing::AssertionResult PrintedDeclCXX98Matches( - StringRef Code, - const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted) { +::testing::AssertionResult +PrintedDeclCXX98Matches(StringRef Code, const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, + PrintingPolicyModifier PolicyModifier = nullptr) { std::vector Args(1, "-std=c++98"); return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, - "input.cc"); + "input.cc", + PolicyModifier); } ::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code, @@ -478,6 +485,27 @@ TEST(DeclPrinter, TestCXXConstructorDecl4) { "A(const A &a, int = 0)")); } +TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer) { + ASSERT_TRUE(PrintedDeclCXX98Matches( + "struct A {" + " int m;" + " A() : m(2) {}" + "};", + cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), + "A()")); +} + +TEST(DeclPrinter, TestCXXConstructorDeclWithMemberInitializer_NoTerseOutput) { + ASSERT_TRUE(PrintedDeclCXX98Matches( + "struct A {" + " int m;" + " A() : m(2) {}" + "};", + cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), + "A() : m(2) {\n}\n", + [](PrintingPolicy &Policy){ Policy.TerseOutput = false; })); +} + TEST(DeclPrinter, TestCXXConstructorDecl5) { ASSERT_TRUE(PrintedDeclCXX11Matches( "struct A {" @@ -540,7 +568,7 @@ TEST(DeclPrinter, TestCXXConstructorDecl11) { " A(T&&... ts) : T(ts)... {}" "};", cxxConstructorDecl(ofClass(hasName("A"))).bind("id"), - "A(T &&...ts) : T(ts)... {}")); + "A(T &&...ts)")); } TEST(DeclPrinter, TestCXXDestructorDecl1) {