return Root;
}
- void expectTreeDumpEqual(StringRef Code, StringRef Tree) {
+ ::testing::AssertionResult treeDumpEqual(StringRef Code, StringRef Tree) {
SCOPED_TRACE(llvm::join(GetParam().getCommandLineArgs(), " "));
- SCOPED_TRACE(Code);
auto *Root = buildTree(Code, GetParam());
- EXPECT_EQ(Diags->getClient()->getNumErrors(), 0u)
- << "Source file has syntax errors, they were printed to the test log";
+ if (Diags->getClient()->getNumErrors() != 0) {
+ return ::testing::AssertionFailure()
+ << "Source file has syntax errors, they were printed to the test "
+ "log";
+ }
std::string Actual = std::string(StringRef(Root->dump(*Arena)).trim());
+ // EXPECT_EQ shows the diff between the two strings if they are different.
EXPECT_EQ(Tree.trim().str(), Actual);
+ if (Actual != Tree.trim().str()) {
+ return ::testing::AssertionFailure();
+ }
+ return ::testing::AssertionSuccess();
}
// Adds a file to the test VFS.
};
TEST_P(SyntaxTreeTest, Simple) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int main() {}
void foo() {}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
`-CompoundStatement
|-{
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, SimpleVariable) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int a;
int b = 42;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| `-UnknownExpression
| `-42
`-;
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, SimpleFunction) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void foo(int a, int b) {}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
`-CompoundStatement
|-{
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, If) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int main() {
if (1) {}
if (1) {} else if (0) {}
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| |-{
| `-}
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, For) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
for (;;) {}
| |-{
| `-}
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, RangeBasedFor) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
int a[3];
for (int x : a)
;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| `-EmptyStatement
| `-;
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, DeclarationStatement) {
- expectTreeDumpEqual("void test() { int a = 10; }",
- R"txt(
+ EXPECT_TRUE(treeDumpEqual(
+ R"cpp(
+void test() {
+ int a = 10;
+}
+)cpp",
+ R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-void
| | `-10
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, Switch) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
switch (1) {
| | `-;
| `-}
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, While) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
while (1) { continue; break; }
| | `-;
| `-}
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, UnhandledStatement) {
// Unhandled statements should end up as 'unknown statement'.
// This example uses a 'label statement', which does not yet have a syntax
// counterpart.
- expectTreeDumpEqual("int main() { foo: return 100; }",
- R"txt(
+ EXPECT_TRUE(treeDumpEqual(
+ R"cpp(
+int main() {
+ foo: return 100;
+}
+)cpp",
+ R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-int
| | `-100
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, Expressions) {
// expressions should be wrapped in 'ExpressionStatement' when they appear
// in a statement position.
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
test();
if (1) test(); else test();
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-)
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, CxxNullPtrLiteral) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
nullptr;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-nullptr
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, PostfixUnaryOperator) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a) {
a++;
a--;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `---
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, PrefixUnaryOperator) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a, int *ap) {
--a; ++a;
!a;
__real a; __imag a;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-a
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, PrefixUnaryOperatorCxx) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a, bool b) {
compl a;
not b;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-b
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, BinaryOperator) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a) {
1 - 2;
1 & 2;
a ^= 3;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-3
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, BinaryOperatorCxx) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a) {
true || false;
1 bitand 2;
a xor_eq 3;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-3
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, NestedBinaryOperator) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a, int b) {
(1 + 2) * (4 / 2);
a + b * 4 + 2;
a % 2 + b * 42;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-42
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, UserDefinedBinaryOperator) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X& operator=(const X&);
x + y;
x < y;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| | `-y
| `-;
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, MultipleDeclaratorsGrouping) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
- int *a, b; int *c, d;
- )cpp",
+int *a, b;
+int *c, d;
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
|-SimpleDeclarator
| `-d
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
- typedef int *a, b;
- )cpp",
+typedef int *a, b;
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-SimpleDeclarator
| `-b
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, MultipleDeclaratorsInsideStatement) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void foo() {
- int *a, b;
- typedef int *ta, tb;
+ int *a, b;
+ typedef int *ta, tb;
}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-tb
| `-;
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, Namespaces) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
namespace a { namespace b {} }
namespace a::b {}
namespace {}
namespace foo = a;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-NamespaceDefinition
|-=
|-a
`-;
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, UsingDirective) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
namespace ns {}
using namespace ::ns;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-NamespaceDefinition
|-::
|-ns
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, UsingDeclaration) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
namespace ns { int a; }
using ns::a;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-NamespaceDefinition
|-::
|-a
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, FreeStandingClasses) {
// Free-standing classes, must live inside a SimpleDeclaration.
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X;
struct X {};
struct Y {} *y2;
struct {} *a1;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-*
| `-a1
`-;
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, Templates) {
// tree when `-fdelayed-template-parsing` is active.
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
template <class T> struct cls {};
template <class T> int var = 10;
template <class T> int fun() {}
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-TemplateDeclaration
`-CompoundStatement
|-{
`-}
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, NestedTemplates) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
template <class T>
struct X {
template <class U>
U foo();
};
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-TemplateDeclaration
| `-;
|-}
`-;
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, Templates2) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
template <class T> struct X { struct Y; };
template <class T> struct X<T>::Y {};
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-TemplateDeclaration
|-{
|-}
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, TemplatesUsingUsing) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
template <class T> struct X {
using T::foo;
using typename T::bar;
};
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-TemplateDeclaration
| `-;
|-}
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ExplicitTemplateInstantations) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
template <class T> struct X {};
template <class T> struct X<T*> {};
|-float
|->
`-;
-)txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, UsingType) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
using type = int;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-TypeAliasDeclaration
|-=
|-int
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, EmptyDeclaration) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-EmptyDeclaration
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, StaticAssert) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
static_assert(true, "message");
static_assert(true);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-StaticAssertDeclaration
| `-true
|-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ExternC) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
extern "C" int a;
extern "C" { int b; int c; }
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-LinkageSpecificationDeclaration
| | `-c
| `-;
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, NonModifiableNodes) {
// Some nodes are non-modifiable, they are marked with 'I:'.
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
#define HALF_IF if (1+
#define HALF_IF_2 1) {}
| |-{
| `-}
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ModifiableNodes) {
// All nodes can be mutated.
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
#define OPEN {
#define CLOSE }
| | `-;
| `-}
`-}
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ArraySubscriptsInDeclarators) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int a[10];
int b[1][2][3];
int c[] = {1,2,3};
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-UnknownExpression
| | `-3
| `-}
- `-; )txt");
+ `-;
+)txt"));
}
TEST_P(SyntaxTreeTest, StaticArraySubscriptsInDeclarators) {
if (!GetParam().isC99OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void f(int xs[static 10]);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | | `-10
| | `-]
| `-)
- `-; )txt");
+ `-;
+)txt"));
}
TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctions) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int func1();
int func2a(int a);
int func3b(int *);
int func4a(int a, float b);
int func4b(int, float);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| | `-float
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctionsCxx) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int func1(const int a, volatile int b, const volatile int c);
int func2(int& a);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| | `-a
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ParametersAndQualifiersInFreeFunctionsCxx11) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int func1(int&& a);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-a
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ParametersAndQualifiersInMemberFunctions) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct Test {
int a();
int e() &;
int f() &&;
};
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| `-;
|-}
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, TrailingReturn) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
auto foo() -> int;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| |-->
| `-int
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, DynamicExceptionSpecification) {
if (!GetParam().supportsCXXDynamicExceptionSpecification()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct MyException1 {};
struct MyException2 {};
int b() throw(...);
int c() throw(MyException1);
int d() throw(MyException1, MyException2);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-MyException2
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, NoexceptExceptionSpecification) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int a() noexcept;
int b() noexcept(true);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| | `-true
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, DeclaratorsInParentheses) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
int (a);
int *(b);
int (*c)(int);
int *(d)(int);
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| | `-int
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ConstVolatileQualifiers) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
const int west = -1;
int const east = 1;
const int const universal = 0;
const int const *const *volatile b;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-volatile
| `-b
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, RangesOfDeclaratorsWithTrailingReturnTypes) {
if (!GetParam().isCXX11OrLater()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
auto foo() -> auto(*)(int) -> double*;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| `-SimpleDeclarator
| `-*
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, MemberPointers) {
if (!GetParam().isCXX()) {
return;
}
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {};
int X::* a;
const int X::* b;
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| | `-*
| `-b
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ComplexDeclarator) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void x(char a, short (*b)(int));
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-)
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, ComplexDeclarator2) {
- expectTreeDumpEqual(
+ EXPECT_TRUE(treeDumpEqual(
R"cpp(
void x(char a, short (*b)(int), long (**c)(long long));
- )cpp",
+)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
| | `-)
| `-)
`-;
- )txt");
+)txt"));
}
TEST_P(SyntaxTreeTest, Mutations) {