+ /// Don't print contents of DeclContexts. Used to provide a 'terse' output. + unsigned DontRecurseInDeclContext : 1;
Please give a concrete example here of the difference between 'terse' and non-'terse' output. --Sean Silva On Mon, Aug 20, 2012 at 7:39 PM, Dmitri Gribenko <[email protected]> wrote: > Author: gribozavr > Date: Mon Aug 20 18:39:06 2012 > New Revision: 162245 > > URL: http://llvm.org/viewvc/llvm-project?rev=162245&view=rev > Log: > DeclPrinter: add terse output mode and lots of tests > > Add a flag PrintingPolicy::DontRecurseInDeclContext to provide "terse" output > from DeclPrinter. The motivation is to use DeclPrinter to print declarations > in user-friendly format, without overwhelming user with inner detail of the > declaration being printed. > > Also add many tests for DeclPrinter. There are quite a few things that we > print incorrectly: search for WRONG in DeclPrinterTest.cpp -- and these tests > check our output against incorrect output, so that we can fix/refactor/rewrite > the DeclPrinter later. > > Added: > cfe/trunk/unittests/AST/DeclPrinterTest.cpp > Modified: > cfe/trunk/include/clang/AST/PrettyPrinter.h > cfe/trunk/lib/AST/DeclPrinter.cpp > cfe/trunk/unittests/AST/CMakeLists.txt > cfe/trunk/unittests/AST/Makefile > > Modified: cfe/trunk/include/clang/AST/PrettyPrinter.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=162245&r1=162244&r2=162245&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/PrettyPrinter.h (original) > +++ cfe/trunk/include/clang/AST/PrettyPrinter.h Mon Aug 20 18:39:06 2012 > @@ -39,7 +39,7 @@ > SuppressUnwrittenScope(false), SuppressInitializers(false), > ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), > SuppressStrongLifetime(false), Bool(LO.Bool), > - DumpSourceManager(0) { } > + DontRecurseInDeclContext(false), DumpSourceManager(0) { } > > /// \brief What language we're printing. > LangOptions LangOpts; > @@ -134,6 +134,9 @@ > /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). > unsigned Bool : 1; > > + /// Don't print contents of DeclContexts. Used to provide a 'terse' > output. > + unsigned DontRecurseInDeclContext : 1; > + > /// \brief If we are "dumping" rather than "pretty-printing", this points > to > /// a SourceManager which will be used to dump SourceLocations. Dumping > /// involves printing the internal details of the AST and pretty-printing > > Modified: cfe/trunk/lib/AST/DeclPrinter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=162245&r1=162244&r2=162245&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclPrinter.cpp (original) > +++ cfe/trunk/lib/AST/DeclPrinter.cpp Mon Aug 20 18:39:06 2012 > @@ -220,6 +220,9 @@ > > //---------------------------------------------------------------------------- > > void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { > + if (Policy.DontRecurseInDeclContext) > + return; > + > if (Indent) > Indentation += Policy.Indentation; > > > Modified: cfe/trunk/unittests/AST/CMakeLists.txt > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CMakeLists.txt?rev=162245&r1=162244&r2=162245&view=diff > ============================================================================== > --- cfe/trunk/unittests/AST/CMakeLists.txt (original) > +++ cfe/trunk/unittests/AST/CMakeLists.txt Mon Aug 20 18:39:06 2012 > @@ -1,8 +1,9 @@ > add_clang_unittest(ASTTests > CommentLexer.cpp > CommentParser.cpp > + DeclPrinterTest.cpp > ) > > target_link_libraries(ASTTests > - clangAST > + clangAST clangASTMatchers clangTooling > ) > > Added: cfe/trunk/unittests/AST/DeclPrinterTest.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/DeclPrinterTest.cpp?rev=162245&view=auto > ============================================================================== > --- cfe/trunk/unittests/AST/DeclPrinterTest.cpp (added) > +++ cfe/trunk/unittests/AST/DeclPrinterTest.cpp Mon Aug 20 18:39:06 2012 > @@ -0,0 +1,1200 @@ > +//===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests > ----===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file contains tests for Decl::print() and related methods. > +// > +// Search this file for WRONG to see test cases that are producing something > +// completely wrong, invalid C++ or just misleading. > +// > +// These tests have a coding convention: > +// * declaration to be printed is named 'A' unless it should have some > special > +// name (e.g., 'operator+'); > +// * additional helper declarations are 'Z', 'Y', 'X' and so on. > +// > +//===----------------------------------------------------------------------===// > + > +#include "clang/AST/ASTContext.h" > +#include "clang/ASTMatchers/ASTMatchFinder.h" > +#include "clang/Tooling/Tooling.h" > +#include "gtest/gtest.h" > + > +using namespace clang; > +using namespace ast_matchers; > +using namespace tooling; > + > +namespace { > + > +void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D) { > + PrintingPolicy Policy = Context->getPrintingPolicy(); > + Policy.DontRecurseInDeclContext = true; > + D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false); > +} > + > +class PrintMatch : public MatchFinder::MatchCallback { > + SmallString<1024> Printed; > + unsigned NumFoundDecls; > + > +public: > + PrintMatch() : NumFoundDecls(0) {} > + > + virtual void run(const MatchFinder::MatchResult &Result) { > + const Decl *D = Result.Nodes.getDeclAs<Decl>("id"); > + if (!D || D->isImplicit()) > + return; > + NumFoundDecls++; > + if (NumFoundDecls > 1) > + return; > + > + llvm::raw_svector_ostream Out(Printed); > + PrintDecl(Out, Result.Context, D); > + } > + > + StringRef getPrinted() const { > + return Printed; > + } > + > + unsigned getNumFoundDecls() const { > + return NumFoundDecls; > + } > +}; > + > +bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code, > + ArrayRef<const char *> ClangArgs) { > + SmallString<16> FileNameStorage; > + StringRef FileNameRef = "input.cc"; > + > + std::vector<std::string> ArgVector; > + ArgVector.push_back("clang-tool"); > + ArgVector.push_back("-fsyntax-only"); > + ArgVector.push_back(FileNameRef.data()); > + for (unsigned i = 0, e = ClangArgs.size(); i != e; ++i) > + ArgVector.push_back(ClangArgs[i]); > + > + FileManager Files((FileSystemOptions())); > + ToolInvocation Invocation(ArgVector, ToolAction, &Files); > + > + SmallString<1024> CodeStorage; > + Invocation.mapVirtualFile(FileNameRef, > + Code.toNullTerminatedStringRef(CodeStorage)); > + return Invocation.run(); > +} > + > +::testing::AssertionResult PrintedDeclMatches( > + StringRef Code, > + ArrayRef<const char *> ClangArgs, > + const DeclarationMatcher &NodeMatch, > + StringRef ExpectedPrinted) { > + PrintMatch Printer; > + MatchFinder Finder; > + Finder.addMatcher(NodeMatch, &Printer); > + OwningPtr<FrontendActionFactory> > Factory(newFrontendActionFactory(&Finder)); > + > + if (!runToolOnCode(Factory->create(), Code, ClangArgs)) > + return testing::AssertionFailure() << "Parsing error in \"" << Code << > "\""; > + > + if (Printer.getNumFoundDecls() == 0) > + return testing::AssertionFailure() > + << "Matcher didn't find any declarations"; > + > + if (Printer.getNumFoundDecls() > 1) > + return testing::AssertionFailure() > + << "Matcher should match only one declaration " > + "(found " << Printer.getNumFoundDecls() << ")"; > + > + if (Printer.getPrinted() != ExpectedPrinted) > + return ::testing::AssertionFailure() > + << "Expected \"" << ExpectedPrinted << "\", " > + "got \"" << Printer.getPrinted() << "\""; > + > + return ::testing::AssertionSuccess(); > +} > + > +::testing::AssertionResult PrintedDeclMatches(StringRef Code, > + StringRef DeclName, > + StringRef ExpectedPrinted) { > + return PrintedDeclMatches(Code, > + ArrayRef<const char *>(), > + > nameableDeclaration(hasName(DeclName)).bind("id"), > + ExpectedPrinted); > +} > + > +::testing::AssertionResult PrintedDeclMatches( > + StringRef Code, > + const DeclarationMatcher &NodeMatch, > + StringRef ExpectedPrinted) { > + return PrintedDeclMatches(Code, > + ArrayRef<const char *>(), > + NodeMatch, > + ExpectedPrinted); > +} > + > +::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code, > + StringRef DeclName, > + StringRef > ExpectedPrinted) { > + return PrintedDeclMatches(Code, > + ArrayRef<const char *>("-std=c++11"), > + > nameableDeclaration(hasName(DeclName)).bind("id"), > + ExpectedPrinted); > +} > + > +::testing::AssertionResult PrintedDeclCXX11Matches( > + StringRef Code, > + const DeclarationMatcher &NodeMatch, > + StringRef ExpectedPrinted) { > + return PrintedDeclMatches(Code, > + ArrayRef<const char *>("-std=c++11"), > + NodeMatch, > + ExpectedPrinted); > +} > + > +} // unnamed namespace > + > +TEST(DeclPrinter, TestNamespace1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "namespace A { int B; }", > + "A", > + "namespace A {\n}")); > + // Should be: with { ... } > +} > + > +TEST(DeclPrinter, TestNamespace2) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "inline namespace A { int B; }", > + "A", > + "inline namespace A {\n}")); > + // Should be: with { ... } > +} > + > +TEST(DeclPrinter, TestNamespaceAlias1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "namespace Z { }" > + "namespace A = Z;", > + "A", > + "namespace A = Z")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestNamespaceAlias2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "namespace X { namespace Y {} }" > + "namespace A = X::Y;", > + "A", > + "namespace A = X::Y")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class A { int a; };", > + "A", > + "class A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A { int a; };", > + "A", > + "struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "union A { int a; };", > + "A", > + "union A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class A : Z { int b; };", > + "A", > + "class A : Z {\n}")); > + // Should be: with semicolon, with { ... }, without two spaces > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl5) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z { int a; };" > + "struct A : Z { int b; };", > + "A", > + "struct A : Z {\n}")); > + // Should be: with semicolon, with { ... }, without two spaces > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl6) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class A : public Z { int b; };", > + "A", > + "class A : public Z {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl7) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class A : protected Z { int b; };", > + "A", > + "class A : protected Z {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl8) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class A : private Z { int b; };", > + "A", > + "class A : private Z {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl9) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class A : virtual Z { int b; };", > + "A", > + "class A : virtual Z {\n}")); > + // Should be: with semicolon, with { ... }, without two spaces > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl10) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class A : virtual public Z { int b; };", > + "A", > + "class A : virtual public Z {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestCXXRecordDecl11) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class Z { int a; };" > + "class Y : virtual public Z { int b; };" > + "class A : virtual public Z, private Y { int c; };", > + "A", > + "class A : virtual public Z, private Y {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestFunctionDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void A();", > + "A", > + "void A()")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "extern void A();", > + "A", > + "extern void A()")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "static void A();", > + "A", > + "static void A()")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "inline void A();", > + "A", > + "inline void A()")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl5) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "constexpr int A(int a);", > + "A", > + "int A(int a)")); > + // WRONG; Should be: "constexpr int A(int a);" > +} > + > +TEST(DeclPrinter, TestFunctionDecl6) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void A(int a);", > + "A", > + "void A(int a)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl7) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void A(...);", > + "A", > + "void A(...)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl8) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void A(int a, ...);", > + "A", > + "void A(int a, ...)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl9) { > + ASSERT_TRUE(PrintedDeclMatches( > + "typedef long size_t;" > + "typedef int *pInt;" > + "void A(int a, pInt b, size_t c);", > + "A", > + "void A(int a, pInt b, size_t c)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl10) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void A(int a, int b = 0);", > + "A", > + "void A(int a, int b = 0)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl11) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void (*A(int a))(int b);", > + "A", > + "void (*A(int a))(int)")); > + // Should be: with semicolon, with parameter name (?) > +} > + > +TEST(DeclPrinter, TestFunctionDecl12) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "void A(T t) { }" > + "template<>" > + "void A(int N) { }", > + function(hasName("A"), isExplicitTemplateSpecialization()).bind("id"), > + "void A(int N) {\n}\n\n")); > + // WRONG; Should be: "template <> void A(int N);")); > +} > + > + > +TEST(DeclPrinter, TestCXXConstructorDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " A();" > + "};", > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "A();" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " A(int a);" > + "};", > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "A(int a);" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " A(const A &a);" > + "};", > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "A(const A &a);" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " A(const A &a, int = 0);" > + "};", > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "A(const A &a, int = 0);" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl5) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "struct A {" > + " A(const A &&a);" > + "};", > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "A(const A &&a);" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl6) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " explicit A(int a);" > + "};", > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "explicit A(int a);" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl7) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " constexpr A();" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "constexpr A();" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl8) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " A() = default;" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + constructor(ofClass(hasName("A"))).bind("id"), > + "")); > + // WRONG; Should be: "A() = default;" > +} > + > +TEST(DeclPrinter, TestCXXConstructorDecl9) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " A() = delete;" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + constructor(ofClass(hasName("A"))).bind("id"), > + " = delete")); > + // WRONG; Should be: "A() = delete;" > +} > + > +TEST(DeclPrinter, TestCXXDestructorDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " ~A();" > + "};", > + destructor(ofClass(hasName("A"))).bind("id"), > + "void ~A()")); > + // WRONG; Should be: "~A();" > +} > + > +TEST(DeclPrinter, TestCXXDestructorDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " virtual ~A();" > + "};", > + destructor(ofClass(hasName("A"))).bind("id"), > + "virtual void ~A()")); > + // WRONG; Should be: "virtual ~A();" > +} > + > +TEST(DeclPrinter, TestCXXConversionDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " operator int();" > + "};", > + method(ofClass(hasName("A"))).bind("id"), > + "int operator int()")); > + // WRONG; Should be: "operator int();" > +} > + > +TEST(DeclPrinter, TestCXXConversionDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct A {" > + " operator bool();" > + "};", > + method(ofClass(hasName("A"))).bind("id"), > + "bool operator _Bool()")); > + // WRONG; Should be: "operator bool();" > +} > + > +TEST(DeclPrinter, TestCXXConversionDecl3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {};" > + "struct A {" > + " operator Z();" > + "};", > + method(ofClass(hasName("A"))).bind("id"), > + "Z operator struct Z()")); > + // WRONG; Should be: "operator Z();" > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "namespace std { typedef decltype(sizeof(int)) size_t; }" > + "struct Z {" > + " void *operator new(std::size_t);" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + method(ofClass(hasName("Z"))).bind("id"), > + "void *operator new(std::size_t)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "namespace std { typedef decltype(sizeof(int)) size_t; }" > + "struct Z {" > + " void *operator new[](std::size_t);" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + method(ofClass(hasName("Z"))).bind("id"), > + "void *operator new[](std::size_t)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void operator delete(void *);" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + method(ofClass(hasName("Z"))).bind("id"), > + "void operator delete(void *) noexcept")); > + // Should be: with semicolon, without noexcept? > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void operator delete(void *);" > + "};", > + method(ofClass(hasName("Z"))).bind("id"), > + "void operator delete(void *)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void operator delete[](void *);" > + "};", > + ArrayRef<const char *>("-std=c++11"), > + method(ofClass(hasName("Z"))).bind("id"), > + "void operator delete[](void *) noexcept")); > + // Should be: with semicolon, without noexcept? > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_Operator1) { > + const char *OperatorNames[] = { > + "+", "-", "*", "/", "%", "^", "&", "|", > + "=", "<", ">", "+=", "-=", "*=", "/=", "%=", > + "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==", "!=", > + "<=", ">=", "&&", "||", ",", "->*", > + "()", "[]" > + }; > + > + for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) > { > + SmallString<128> Code; > + Code.append("struct Z { void operator"); > + Code.append(OperatorNames[i]); > + Code.append("(Z z); };"); > + > + SmallString<128> Expected; > + Expected.append("void operator"); > + Expected.append(OperatorNames[i]); > + Expected.append("(Z z)"); > + // Should be: with semicolon > + > + ASSERT_TRUE(PrintedDeclMatches( > + Code, > + method(ofClass(hasName("Z"))).bind("id"), > + Expected)); > + } > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_Operator2) { > + const char *OperatorNames[] = { > + "~", "!", "++", "--", "->" > + }; > + > + for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) > { > + SmallString<128> Code; > + Code.append("struct Z { void operator"); > + Code.append(OperatorNames[i]); > + Code.append("(); };"); > + > + SmallString<128> Expected; > + Expected.append("void operator"); > + Expected.append(OperatorNames[i]); > + Expected.append("()"); > + // Should be: with semicolon > + > + ASSERT_TRUE(PrintedDeclMatches( > + Code, > + method(ofClass(hasName("Z"))).bind("id"), > + Expected)); > + } > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void A(int a);" > + "};", > + "A", > + "void A(int a)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " virtual void A(int a);" > + "};", > + "A", > + "virtual void A(int a)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " virtual void A(int a);" > + "};" > + "struct ZZ : Z {" > + " void A(int a);" > + "};", > + "ZZ::A", > + "void A(int a)")); > + // Should be: with semicolon > + // TODO: should we print "virtual"? > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " inline void A(int a);" > + "};", > + "A", > + "inline void A(int a)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl5) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " virtual void A(int a) = 0;" > + "};", > + "A", > + "virtual void A(int a) = 0")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void A(int a) const;" > + "};", > + "A", > + "void A(int a) const")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void A(int a) volatile;" > + "};", > + "A", > + "void A(int a) volatile")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void A(int a) const volatile;" > + "};", > + "A", > + "void A(int a) const volatile")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "struct Z {" > + " void A(int a) &;" > + "};", > + "A", > + "void A(int a)")); > + // WRONG; Should be: "void A(int a) &;" > +} > + > +TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "struct Z {" > + " void A(int a) &&;" > + "};", > + "A", > + "void A(int a)")); > + // WRONG; Should be: "void A(int a) &&;" > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void A(int a) throw();" > + "};", > + "A", > + "void A(int a) throw()")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z {" > + " void A(int a) throw(int);" > + "};", > + "A", > + "void A(int a) throw(int)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "class ZZ {};" > + "struct Z {" > + " void A(int a) throw(ZZ, int);" > + "};", > + "A", > + "void A(int a) throw(ZZ, int)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "struct Z {" > + " void A(int a) noexcept;" > + "};", > + "A", > + "void A(int a) noexcept")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "struct Z {" > + " void A(int a) noexcept(true);" > + "};", > + "A", > + "void A(int a) noexcept(trueA(int a) noexcept(true)")); > + // WRONG; Should be: "void A(int a) noexcept(true);" > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "struct Z {" > + " void A(int a) noexcept(1 < 2);" > + "};", > + "A", > + "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)")); > + // WRONG; Should be: "void A(int a) noexcept(1 < 2);" > +} > + > +TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<int N>" > + "struct Z {" > + " void A(int a) noexcept(N < 2);" > + "};", > + "A", > + "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)")); > + // WRONG; Should be: "void A(int a) noexcept(N < 2);" > +} > + > +TEST(DeclPrinter, TestVarDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "char *const (*(*A)[5])(int);", > + "A", > + "char *const (*(*A)[5])(int)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestVarDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "void (*A)() throw(int);", > + "A", > + "void (*A)() throw(int)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestVarDecl3) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "void (*A)() noexcept;", > + "A", > + "void (*A)() noexcept")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFieldDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "struct Z { T A; };", > + "A", > + "T A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFieldDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<int N>" > + "struct Z { int A[N]; };", > + "A", > + "int A[N]")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "struct A { T a; };", > + classTemplate(hasName("A")).bind("id"), > + "template <typename T> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T = int>" > + "struct A { T a; };", > + classTemplate(hasName("A")).bind("id"), > + "template <typename T = int> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<class T>" > + "struct A { T a; };", > + classTemplate(hasName("A")).bind("id"), > + "template <class T> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T, typename U>" > + "struct A { T a; U b; };", > + classTemplate(hasName("A")).bind("id"), > + "template <typename T, typename U> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl5) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<int N>" > + "struct A { int a[N]; };", > + classTemplate(hasName("A")).bind("id"), > + "template <int N> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl6) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<int N = 42>" > + "struct A { int a[N]; };", > + classTemplate(hasName("A")).bind("id"), > + "template <int N = 42> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl7) { > + ASSERT_TRUE(PrintedDeclMatches( > + "typedef int MyInt;" > + "template<MyInt N>" > + "struct A { int a[N]; };", > + classTemplate(hasName("A")).bind("id"), > + "template <MyInt N> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl8) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<template<typename U> class T> struct A { };", > + classTemplate(hasName("A")).bind("id"), > + "template <template <typename U> class T> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl9) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T> struct Z { };" > + "template<template<typename U> class T = Z> struct A { };", > + classTemplate(hasName("A")).bind("id"), > + "template <template <typename U> class T> struct A {\n}")); > + // Should be: with semicolon, with { ... } > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl10) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename... T>" > + "struct A { int a; };", > + classTemplate(hasName("A")).bind("id"), > + "template <typename ... T> struct A {\n}")); > + // Should be: with semicolon, with { ... }, without spaces before '...' > +} > + > +TEST(DeclPrinter, TestClassTemplateDecl11) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename... T>" > + "struct A : public T... { int a; };", > + classTemplate(hasName("A")).bind("id"), > + "template <typename ... T> struct A : public T... {\n}")); > + // Should be: with semicolon, with { ... }, without spaces before '...' > +} > + > +TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T, typename U>" > + "struct A { T a; U b; };" > + "template<typename T>" > + "struct A<T, int> { T a; };", > + classTemplateSpecialization().bind("id"), > + "struct A {\n}")); > + // WRONG; Should be: "template<typename T> struct A<T, int> { ... }" > +} > + > +TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "struct A { T a; };" > + "template<typename T>" > + "struct A<T *> { T a; };", > + classTemplateSpecialization().bind("id"), > + "struct A {\n}")); > + // WRONG; Should be: "template<typename T> struct A<T *> { ... }" > +} > + > +TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "struct A { T a; };" > + "template<>" > + "struct A<int> { int a; };", > + classTemplateSpecialization().bind("id"), > + "struct A {\n}")); > + // WRONG; Should be: "template<> struct A<int> { ... }" > +} > + > +TEST(DeclPrinter, TestFunctionTemplateDecl1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "void A(T &t);", > + functionTemplate(hasName("A")).bind("id"), > + "template <typename T> void A(T &t)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionTemplateDecl2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T>" > + "void A(T &t) { }", > + functionTemplate(hasName("A")).bind("id"), > + "template <typename T> void A(T &t) {\n}\n\n")); > + // Should be: without body, with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionTemplateDecl3) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename... T>" > + "void A(T... a);", > + functionTemplate(hasName("A")).bind("id"), > + "template <typename ... T> void A(T a...)")); > + // WRONG; Should be: "template <typename ... T> void A(T... a)" > + // (not "T a...") > + // Should be: with semicolon. > +} > + > +TEST(DeclPrinter, TestFunctionTemplateDecl4) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z { template<typename T> void A(T t); };", > + functionTemplate(hasName("A")).bind("id"), > + "template <typename T> void A(T t)")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionTemplateDecl5) { > + ASSERT_TRUE(PrintedDeclMatches( > + "struct Z { template<typename T> void A(T t) {} };", > + functionTemplate(hasName("A")).bind("id"), > + "template <typename T> void A(T t) {\n}\n\n")); > + // Should be: without body, with semicolon > +} > + > +TEST(DeclPrinter, TestFunctionTemplateDecl6) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T >struct Z {" > + " template<typename U> void A(U t) {}" > + "};", > + functionTemplate(hasName("A")).bind("id"), > + "template <typename U> void A(U t) {\n}\n\n")); > + // Should be: without body, with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList1) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T> struct Z {};" > + "struct X {};" > + "Z<X> A;", > + "A", > + "Z<X> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList2) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T, typename U> struct Z {};" > + "struct X {};" > + "typedef int Y;" > + "Z<X, Y> A;", > + "A", > + "Z<X, Y> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList3) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<typename T> struct Z {};" > + "template<typename T> struct X {};" > + "Z<X<int> > A;", > + "A", > + "Z<X<int> > A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList4) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename T> struct Z {};" > + "template<typename T> struct X {};" > + "Z<X<int>> A;", > + "A", > + "Z<X<int> > A")); > + // Should be: with semicolon, without extra space in "> >" > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList5) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename T> struct Z {};" > + "template<typename T> struct X { Z<T> A; };", > + "A", > + "Z<T> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList6) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<template<typename T> class U> struct Z {};" > + "template<typename T> struct X {};" > + "Z<X> A;", > + "A", > + "Z<X> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList7) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<template<typename T> class U> struct Z {};" > + "template<template<typename T> class U> struct Y {" > + " Z<U> A;" > + "};", > + "A", > + "Z<U> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList8) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename T> struct Z {};" > + "template<template<typename T> class U> struct Y {" > + " Z<U<int> > A;" > + "};", > + "A", > + "Z<U<int> > A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList9) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<unsigned I> struct Z {};" > + "Z<0> A;", > + "A", > + "Z<0> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList10) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<unsigned I> struct Z {};" > + "template<unsigned I> struct X { Z<I> A; };", > + "A", > + "Z<I> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList11) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<int I> struct Z {};" > + "Z<42 * 10 - 420 / 1> A;", > + "A", > + "Z<42 * 10 - 420 / 1> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList12) { > + ASSERT_TRUE(PrintedDeclMatches( > + "template<const char *p> struct Z {};" > + "extern const char X[] = \"aaa\";" > + "Z<X> A;", > + "A", > + "Z<X> A")); > + // Should be: with semicolon > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList13) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename... T> struct Z {};" > + "template<typename... T> struct X {" > + " Z<T...> A;" > + "};", > + "A", > + "Z<T...> A")); > + // Should be: with semicolon, without extra space in "> >" > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList14) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<typename... T> struct Z {};" > + "template<typename T> struct Y {};" > + "template<typename... T> struct X {" > + " Z<Y<T>...> A;" > + "};", > + "A", > + "Z<Y<T>...> A")); > + // Should be: with semicolon, without extra space in "> >" > +} > + > +TEST(DeclPrinter, TestTemplateArgumentList15) { > + ASSERT_TRUE(PrintedDeclCXX11Matches( > + "template<unsigned I> struct Z {};" > + "template<typename... T> struct X {" > + " Z<sizeof...(T)> A;" > + "};", > + "A", > + "Z<sizeof...(T)> A")); > + // Should be: with semicolon, without extra space in "> >" > +} > + > > Modified: cfe/trunk/unittests/AST/Makefile > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/Makefile?rev=162245&r1=162244&r2=162245&view=diff > ============================================================================== > --- cfe/trunk/unittests/AST/Makefile (original) > +++ cfe/trunk/unittests/AST/Makefile Mon Aug 20 18:39:06 2012 > @@ -9,7 +9,10 @@ > > CLANG_LEVEL = ../.. > TESTNAME = AST > -LINK_COMPONENTS := support mc > -USEDLIBS = clangAST.a clangLex.a clangBasic.a > +include $(CLANG_LEVEL)/../../Makefile.config > +LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc > +USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a > \ > + clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \ > + clangAST.a clangASTMatchers.a clangLex.a clangBasic.a clangEdit.a > > include $(CLANG_LEVEL)/unittests/Makefile > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
