llvm-project/clang/unittests/AST/DeclPrinterTest.cpp
Daniel Jasper bd3d76d90c Rename the ASTMatchers to better match AST nodes. Now, all
ASTMatchers have the same name as the corresponding AST nodes
but are lower case. The only exceptions are the "CXX" prefixes
which are not copied over to the matcher names as the goal is to
actually remove these prefixes from the AST node names.

llvm-svn: 162536
2012-08-24 05:12:34 +00:00

1241 lines
33 KiB
C++

//===- 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.TerseOutput = 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 *>(),
namedDecl(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"),
namedDecl(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(
"void A() {}",
"A",
"void A()"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl3) {
ASSERT_TRUE(PrintedDeclMatches(
"void Z();"
"void A() { Z(); }",
"A",
"void A()"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl4) {
ASSERT_TRUE(PrintedDeclMatches(
"extern void A();",
"A",
"extern void A()"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl5) {
ASSERT_TRUE(PrintedDeclMatches(
"static void A();",
"A",
"static void A()"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl6) {
ASSERT_TRUE(PrintedDeclMatches(
"inline void A();",
"A",
"inline void A()"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl7) {
ASSERT_TRUE(PrintedDeclCXX11Matches(
"constexpr int A(int a);",
"A",
"int A(int a)"));
// WRONG; Should be: "constexpr int A(int a);"
}
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(
"void A(...);",
"A",
"void A(...)"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl10) {
ASSERT_TRUE(PrintedDeclMatches(
"void A(int a, ...);",
"A",
"void A(int a, ...)"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl11) {
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, TestFunctionDecl12) {
ASSERT_TRUE(PrintedDeclMatches(
"void A(int a, int b = 0);",
"A",
"void A(int a, int b = 0)"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionDecl13) {
ASSERT_TRUE(PrintedDeclMatches(
"void (*A(int a))(int b);",
"A",
"void (*A(int a))(int)"));
// Should be: with semicolon, with parameter name (?)
}
TEST(DeclPrinter, TestFunctionDecl14) {
ASSERT_TRUE(PrintedDeclMatches(
"template<typename T>"
"void A(T t) { }"
"template<>"
"void A(int N) { }",
functionDecl(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
"void A(int N)"));
// WRONG; Should be: "template <> void A(int N);"));
}
TEST(DeclPrinter, TestCXXConstructorDecl1) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" A();"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
""));
// WRONG; Should be: "A();"
}
TEST(DeclPrinter, TestCXXConstructorDecl2) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" A(int a);"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
""));
// WRONG; Should be: "A(int a);"
}
TEST(DeclPrinter, TestCXXConstructorDecl3) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" A(const A &a);"
"};",
constructorDecl(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);"
"};",
constructorDecl(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);"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
""));
// WRONG; Should be: "A(const A &&a);"
}
TEST(DeclPrinter, TestCXXConstructorDecl6) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" explicit A(int a);"
"};",
constructorDecl(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"),
constructorDecl(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"),
constructorDecl(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"),
constructorDecl(ofClass(hasName("A"))).bind("id"),
" = delete"));
// WRONG; Should be: "A() = delete;"
}
TEST(DeclPrinter, TestCXXConstructorDecl10) {
ASSERT_TRUE(PrintedDeclCXX11Matches(
"template<typename... T>"
"struct A {"
" A(const A &a);"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
""));
// WRONG; Should be: "A(const A &a);"
}
TEST(DeclPrinter, TestCXXConstructorDecl11) {
ASSERT_TRUE(PrintedDeclCXX11Matches(
"template<typename... T>"
"struct A : public T... {"
" A(T&&... ts) : T(ts)... {}"
"};",
constructorDecl(ofClass(hasName("A"))).bind("id"),
"A<T...>(T &&ts...) : T(ts)"));
// WRONG; Should be: "A(T&&... ts) : T(ts)..."
}
TEST(DeclPrinter, TestCXXDestructorDecl1) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" ~A();"
"};",
destructorDecl(ofClass(hasName("A"))).bind("id"),
"void ~A()"));
// WRONG; Should be: "~A();"
}
TEST(DeclPrinter, TestCXXDestructorDecl2) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" virtual ~A();"
"};",
destructorDecl(ofClass(hasName("A"))).bind("id"),
"virtual void ~A()"));
// WRONG; Should be: "virtual ~A();"
}
TEST(DeclPrinter, TestCXXConversionDecl1) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" operator int();"
"};",
methodDecl(ofClass(hasName("A"))).bind("id"),
"int operator int()"));
// WRONG; Should be: "operator int();"
}
TEST(DeclPrinter, TestCXXConversionDecl2) {
ASSERT_TRUE(PrintedDeclMatches(
"struct A {"
" operator bool();"
"};",
methodDecl(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();"
"};",
methodDecl(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"),
methodDecl(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"),
methodDecl(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"),
methodDecl(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 *);"
"};",
methodDecl(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"),
methodDecl(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,
methodDecl(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,
methodDecl(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; };",
classTemplateDecl(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; };",
classTemplateDecl(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; };",
classTemplateDecl(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; };",
classTemplateDecl(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]; };",
classTemplateDecl(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]; };",
classTemplateDecl(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]; };",
classTemplateDecl(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 { };",
classTemplateDecl(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 { };",
classTemplateDecl(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; };",
classTemplateDecl(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; };",
classTemplateDecl(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; };",
classTemplateSpecializationDecl().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; };",
classTemplateSpecializationDecl().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; };",
classTemplateSpecializationDecl().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);",
functionTemplateDecl(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) { }",
functionTemplateDecl(hasName("A")).bind("id"),
"template <typename T> void A(T &t)"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionTemplateDecl3) {
ASSERT_TRUE(PrintedDeclCXX11Matches(
"template<typename... T>"
"void A(T... a);",
functionTemplateDecl(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); };",
functionTemplateDecl(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) {} };",
functionTemplateDecl(hasName("A")).bind("id"),
"template <typename T> void A(T t)"));
// Should be: with semicolon
}
TEST(DeclPrinter, TestFunctionTemplateDecl6) {
ASSERT_TRUE(PrintedDeclMatches(
"template<typename T >struct Z {"
" template<typename U> void A(U t) {}"
"};",
functionTemplateDecl(hasName("A")).bind("id"),
"template <typename U> void A(U t)"));
// Should be: 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 "> >"
}