1,669 changes: 1,158 additions & 511 deletions clang/unittests/Tooling/Syntax/TreeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,26 +632,48 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, UnqualifiedId) {
TEST_P(SyntaxTreeTest, UnqualifiedId_Identifier) {
EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a) {
a;
}
)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-int
| | `-SimpleDeclarator
| | `-a
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-IdExpression
| | `-UnqualifiedId
| | `-a
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UnqualifiedId_OperatorFunctionId) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
// TODO: Expose `id-expression` from `Declarator`
friend X operator+(const X&, const X&);
operator int();
};
template<typename T>
void f(T&);
void test(X x) {
x; // identifier
operator+(x, x); // operator-function-id
f<X>(x); // template-id
// TODO: Expose `id-expression` from `MemberExpr`
x.operator int(); // conversion-funtion-id
x.~X(); // ~type-name
operator+(x, x);
}
)cpp",
R"txt(
Expand Down Expand Up @@ -682,35 +704,8 @@ void test(X x) {
| | | | `-&
| | | `-)
| | `-;
| |-SimpleDeclaration
| | |-SimpleDeclarator
| | | |-operator
| | | |-int
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-;
| |-}
| `-;
|-TemplateDeclaration
| |-template
| |-<
| |-UnknownDeclaration
| | |-typename
| | `-T
| |->
| `-SimpleDeclaration
| |-void
| |-SimpleDeclarator
| | |-f
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | |-T
| | | `-SimpleDeclarator
| | | `-&
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
Expand All @@ -725,11 +720,6 @@ void test(X x) {
`-CompoundStatement
|-{
|-ExpressionStatement
| |-IdExpression
| | `-UnqualifiedId
| | `-x
| `-;
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | `-UnqualifiedId
Expand All @@ -745,20 +735,53 @@ void test(X x) {
| | | `-x
| | `-)
| `-;
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | |-f
| | | |-<
| | | |-X
| | | `->
| | |-(
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UnqualifiedId_ConversionFunctionId) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
operator int();
};
void test(X x) {
// TODO: Expose `id-expression` from `MemberExpr`
x.operator int();
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-SimpleDeclaration
| | |-SimpleDeclarator
| | | |-operator
| | | |-int
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-UnknownExpression
Expand All @@ -771,6 +794,93 @@ void test(X x) {
| | |-(
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UnqualifiedId_LiteralOperatorId) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
unsigned operator "" _w(char);
void test() {
operator "" _w('1');
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_w
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | `-char
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | |-operator
| | | |-""
| | | `-_w
| | |-(
| | |-CharacterLiteralExpression
| | | `-'1'
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UnqualifiedId_Destructor) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X { };
void test(X x) {
// TODO: Expose `id-expression` from `MemberExpr`
x.~X();
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-UnknownExpression
Expand All @@ -787,18 +897,16 @@ void test(X x) {
)txt"));
}

TEST_P(SyntaxTreeTest, UnqualifiedIdCxx11OrLater) {
TEST_P(SyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X { };
unsigned operator "" _w(long long unsigned);
void test(X x) {
operator "" _w(1llu); // literal-operator-id
// TODO: Expose `id-expression` from `MemberExpr`
x.~decltype(x)(); // ~decltype-specifier
x.~decltype(x)();
}
)cpp",
R"txt(
Expand All @@ -809,20 +917,6 @@ void test(X x) {
| |-{
| |-}
| `-;
|-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_w
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | |-long
| | | |-long
| | | `-unsigned
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
Expand All @@ -838,18 +932,6 @@ void test(X x) {
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | |-operator
| | | |-""
| | | `-_w
| | |-(
| | |-IntegerLiteralExpression
| | | `-1llu
| | `-)
| `-;
|-ExpressionStatement
| |-UnknownExpression
| | |-UnknownExpression
| | | |-IdExpression
| | | | `-UnqualifiedId
Expand All @@ -867,83 +949,20 @@ void test(X x) {
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedId) {
TEST_P(SyntaxTreeTest, UnqualifiedId_TemplateId) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
namespace n {
struct S {
template<typename T>
struct ST {
static void f();
};
};
}
template<typename T>
struct ST {
struct S {
template<typename U>
static U f();
};
};
T f();
void test() {
:: // global-namespace-specifier
n:: // namespace-specifier
S:: // type-name-specifier
template ST<int>:: // type-template-instantiation-specifier
f();
n:: // namespace-specifier
S:: // type-name-specifier
ST<int>:: // type-template-instantiation-specifier
f();
ST<int>:: // type-name-specifier
S:: // type-name-specifier
f<int>();
ST<int>:: // type-name-specifier
S:: // type-name-specifier
template f<int>();
}
)cpp",
R"txt(
*: TranslationUnit
|-NamespaceDefinition
| |-namespace
| |-n
| |-{
| |-SimpleDeclaration
| | |-struct
| | |-S
| | |-{
| | |-TemplateDeclaration
| | | |-template
| | | |-<
| | | |-UnknownDeclaration
| | | | |-typename
| | | | `-T
| | | |->
| | | `-SimpleDeclaration
| | | |-struct
| | | |-ST
| | | |-{
| | | |-SimpleDeclaration
| | | | |-static
| | | | |-void
| | | | |-SimpleDeclarator
| | | | | |-f
| | | | | `-ParametersAndQualifiers
| | | | | |-(
| | | | | `-)
| | | | `-;
| | | |-}
| | | `-;
| | |-}
| | `-;
| `-}
|-TemplateDeclaration
| |-template
| |-<
Expand All @@ -952,99 +971,317 @@ void test() {
| | `-T
| |->
| `-SimpleDeclaration
| |-struct
| |-ST
| |-{
| |-SimpleDeclaration
| | |-struct
| | |-S
| | |-{
| | |-TemplateDeclaration
| | | |-template
| | | |-<
| | | |-UnknownDeclaration
| | | | |-typename
| | | | `-U
| | | |->
| | | `-SimpleDeclaration
| | | |-static
| | | |-U
| | | |-SimpleDeclarator
| | | | |-f
| | | | `-ParametersAndQualifiers
| | | | |-(
| | | | `-)
| | | `-;
| | |-}
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-T
| |-SimpleDeclarator
| | |-f
| | `-ParametersAndQualifiers
| | |-(
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | |-f
| | | |-<
| | | |-int
| | | `->
| | |-(
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedId_NamespaceSpecifier) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
namespace n {
struct S { };
}
void test() {
::n::S s1;
n::S s2;
}
)cpp",
R"txt(
*: TranslationUnit
|-NamespaceDefinition
| |-namespace
| |-n
| |-{
| |-SimpleDeclaration
| | |-struct
| | |-S
| | |-{
| | |-}
| | `-;
| `-}
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-DeclarationStatement
| |-SimpleDeclaration
| | |-NestedNameSpecifier
| | | |-::
| | | |-IdentifierNameSpecifier
| | | | `-n
| | | `-::
| | |-S
| | `-SimpleDeclarator
| | `-UnknownExpression
| | `-s1
| `-;
|-DeclarationStatement
| |-SimpleDeclaration
| | |-NestedNameSpecifier
| | | |-IdentifierNameSpecifier
| | | | `-n
| | | `-::
| | |-S
| | `-SimpleDeclarator
| | `-UnknownExpression
| | `-s2
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedId_TemplateSpecifier) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
template<typename T>
struct ST {
struct S { };
};
void test() {
::template ST<int>::S s1;
::ST<int>::S s2;
}
)cpp",
R"txt(
*: TranslationUnit
|-TemplateDeclaration
| |-template
| |-<
| |-UnknownDeclaration
| | |-typename
| | `-T
| |->
| `-SimpleDeclaration
| |-struct
| |-ST
| |-{
| |-SimpleDeclaration
| | |-struct
| | |-S
| | |-{
| | |-}
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-DeclarationStatement
| |-SimpleDeclaration
| | |-NestedNameSpecifier
| | | |-::
| | | |-SimpleTemplateNameSpecifier
| | | | |-template
| | | | |-ST
| | | | |-<
| | | | |-int
| | | | `->
| | | `-::
| | |-S
| | `-SimpleDeclarator
| | `-UnknownExpression
| | `-s1
| `-;
|-DeclarationStatement
| |-SimpleDeclaration
| | |-NestedNameSpecifier
| | | |-::
| | | |-SimpleTemplateNameSpecifier
| | | | |-ST
| | | | |-<
| | | | |-int
| | | | `->
| | | `-::
| | |-S
| | `-SimpleDeclarator
| | `-UnknownExpression
| | `-s2
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedId_DecltypeSpecifier) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct S {
static void f(){}
};
void test(S s) {
decltype(s)::f();
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-S
| |-{
| |-SimpleDeclaration
| | |-static
| | |-void
| | |-SimpleDeclarator
| | | |-f
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-CompoundStatement
| | |-{
| | `-}
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-S
| | `-SimpleDeclarator
| | `-s
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-n
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-S
| | | | |-::
| | | | |-SimpleTemplateNameSpecifier
| | | | | |-template
| | | | | |-ST
| | | | | |-<
| | | | | |-int
| | | | | `->
| | | | |-DecltypeNameSpecifier
| | | | | |-decltype
| | | | | |-(
| | | | | |-IdExpression
| | | | | | `-UnqualifiedId
| | | | | | `-s
| | | | | `-)
| | | | `-::
| | | `-UnqualifiedId
| | | `-f
| | |-(
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedId_OptionalTemplateKw) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct S {
template<typename U>
static U f();
};
void test() {
S::f<int>();
S::template f<int>();
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-S
| |-{
| |-TemplateDeclaration
| | |-template
| | |-<
| | |-UnknownDeclaration
| | | |-typename
| | | `-U
| | |->
| | `-SimpleDeclaration
| | |-static
| | |-U
| | |-SimpleDeclarator
| | | |-f
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-IdentifierNameSpecifier
| | | | | `-n
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-S
| | | | |-::
| | | | |-SimpleTemplateNameSpecifier
| | | | | |-ST
| | | | | |-<
| | | | | |-int
| | | | | `->
| | | | `-::
| | | `-UnqualifiedId
| | | `-f
| | | |-f
| | | |-<
| | | |-int
| | | `->
| | |-(
| | `-)
| `-;
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-SimpleTemplateNameSpecifier
| | | | | |-ST
| | | | | |-<
| | | | | |-int
| | | | | `->
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-S
| | | | `-::
| | | |-template
| | | `-UnqualifiedId
| | | |-f
| | | |-<
Expand All @@ -1053,18 +1290,86 @@ void test() {
| | |-(
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedId_Complex) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
namespace n {
template<typename T>
struct ST {
template<typename U>
static U f();
};
}
void test() {
::n::template ST<int>::template f<int>();
}
)cpp",
R"txt(
*: TranslationUnit
|-NamespaceDefinition
| |-namespace
| |-n
| |-{
| |-TemplateDeclaration
| | |-template
| | |-<
| | |-UnknownDeclaration
| | | |-typename
| | | `-T
| | |->
| | `-SimpleDeclaration
| | |-struct
| | |-ST
| | |-{
| | |-TemplateDeclaration
| | | |-template
| | | |-<
| | | |-UnknownDeclaration
| | | | |-typename
| | | | `-U
| | | |->
| | | `-SimpleDeclaration
| | | |-static
| | | |-U
| | | |-SimpleDeclarator
| | | | |-f
| | | | `-ParametersAndQualifiers
| | | | |-(
| | | | `-)
| | | `-;
| | |-}
| | `-;
| `-}
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-n
| | | | |-::
| | | | |-SimpleTemplateNameSpecifier
| | | | | |-template
| | | | | |-ST
| | | | | |-<
| | | | | |-int
| | | | | `->
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-S
| | | | `-::
| | | |-template
| | | `-UnqualifiedId
Expand All @@ -1079,7 +1384,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedIdWithDependentType) {
TEST_P(SyntaxTreeTest, QualifiedId_DependentType) {
if (!GetParam().isCXX()) {
return;
}
Expand All @@ -1093,9 +1398,7 @@ TEST_P(SyntaxTreeTest, QualifiedIdWithDependentType) {
template <typename T>
void test() {
T::template U<int>::f();
T::U::f();
T::template f<0>();
}
)cpp",
Expand Down Expand Up @@ -1142,100 +1445,33 @@ void test() {
| | | |-NestedNameSpecifier
| | | | |-IdentifierNameSpecifier
| | | | | `-T
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-U
| | | | `-::
| | | `-UnqualifiedId
| | | `-f
| | |-(
| | `-)
| `-;
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-IdentifierNameSpecifier
| | | | | `-T
| | | | `-::
| | | |-template
| | | `-UnqualifiedId
| | | |-f
| | | |-<
| | | |-IntegerLiteralExpression
| | | | `-0
| | | `->
| | |-(
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, QualifiedIdDecltype) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct S {
static void f(){}
};
void test(S s) {
decltype(s):: // decltype-specifier
f();
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-S
| |-{
| |-SimpleDeclaration
| | |-static
| | |-void
| | |-SimpleDeclarator
| | | |-f
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-CompoundStatement
| | |-{
| | `-}
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-S
| | `-SimpleDeclarator
| | `-s
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-DecltypeNameSpecifier
| | | | | |-decltype
| | | | | |-(
| | | | | |-IdExpression
| | | | | | `-UnqualifiedId
| | | | | | `-s
| | | | | `-)
| | | | `-::
| | | `-UnqualifiedId
| | | `-f
| | |-(
| | `-)
| `-;
`-}
| | | | |-::
| | | | |-IdentifierNameSpecifier
| | | | | `-U
| | | | `-::
| | | `-UnqualifiedId
| | | `-f
| | |-(
| | `-)
| `-;
|-ExpressionStatement
| |-UnknownExpression
| | |-IdExpression
| | | |-NestedNameSpecifier
| | | | |-IdentifierNameSpecifier
| | | | | `-T
| | | | `-::
| | | |-template
| | | `-UnqualifiedId
| | | |-f
| | | |-<
| | | |-IntegerLiteralExpression
| | | | `-0
| | | `->
| | |-(
| | `-)
| `-;
`-}
)txt"));
}

Expand Down Expand Up @@ -1294,32 +1530,60 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedLiteral) {
TEST_P(SyntaxTreeTest, UserDefinedLiteral_Char) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
unsigned operator "" _c(char);
void test() {
'2'_c;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_c
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | `-char
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-CharUserDefinedLiteralExpression
| | `-'2'_c
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedLiteral_String) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
typedef decltype(sizeof(void *)) size_t;
unsigned operator "" _i(unsigned long long);
unsigned operator "" _f(long double);
unsigned operator "" _c(char);
unsigned operator "" _s(const char*, size_t);
unsigned operator "" _r(const char*);
template <char...>
unsigned operator "" _t();
void test() {
12_i; // call: operator "" _i(12uLL) | kind: integer
1.2_f; // call: operator "" _f(1.2L) | kind: float
'2'_c; // call: operator "" _c('2') | kind: char
"12"_s; // call: operator "" _s("12") | kind: string
12_r; // call: operator "" _r("12") | kind: integer
1.2_r; // call: operator "" _i("1.2") | kind: float
12_t; // call: operator<'1', '2'> "" _x() | kind: integer
1.2_t; // call: operator<'1', '2'> "" _x() | kind: float
"12"_s;
}
)cpp",
R"txt(
Expand All @@ -1343,56 +1607,156 @@ void test() {
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_i
| | |-_s
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | |-unsigned
| | | |-long
| | | `-long
| | | |-const
| | | |-char
| | | `-SimpleDeclarator
| | | `-*
| | |-,
| | |-SimpleDeclaration
| | | `-size_t
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-StringUserDefinedLiteralExpression
| | `-"12"_s
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedLiteral_Integer) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
unsigned operator "" _i(unsigned long long);
unsigned operator "" _r(const char*);
template <char...>
unsigned operator "" _t();
void test() {
12_i;
12_r;
12_t;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_f
| | |-_i
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | |-unsigned
| | | |-long
| | | `-double
| | | `-long
| | `-)
| `-;
|-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_c
| | |-_r
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | `-char
| | | |-const
| | | |-char
| | | `-SimpleDeclarator
| | | `-*
| | `-)
| `-;
|-TemplateDeclaration
| |-template
| |-<
| |-SimpleDeclaration
| | `-char
| |-...
| |->
| `-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_t
| | `-ParametersAndQualifiers
| | |-(
| | `-)
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-IntegerUserDefinedLiteralExpression
| | `-12_i
| `-;
|-ExpressionStatement
| |-IntegerUserDefinedLiteralExpression
| | `-12_r
| `-;
|-ExpressionStatement
| |-IntegerUserDefinedLiteralExpression
| | `-12_t
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedLiteral_Float) {
if (!GetParam().isCXX11OrLater()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
unsigned operator "" _f(long double);
unsigned operator "" _r(const char*);
template <char...>
unsigned operator "" _t();
void test() {
1.2_f; // call: operator "" _f(1.2L) | kind: float
1.2_r; // call: operator "" _i("1.2") | kind: float
1.2_t; // call: operator<'1', '2'> "" _x() | kind: float
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-unsigned
| |-SimpleDeclarator
| | |-operator
| | |-""
| | |-_s
| | |-_f
| | `-ParametersAndQualifiers
| | |-(
| | |-SimpleDeclaration
| | | |-const
| | | |-char
| | | `-SimpleDeclarator
| | | `-*
| | |-,
| | |-SimpleDeclaration
| | | `-size_t
| | | |-long
| | | `-double
| | `-)
| `-;
|-SimpleDeclaration
Expand Down Expand Up @@ -1437,42 +1801,22 @@ void test() {
`-CompoundStatement
|-{
|-ExpressionStatement
| |-IntegerUserDefinedLiteralExpression
| | `-12_i
| `-;
|-ExpressionStatement
| |-FloatUserDefinedLiteralExpression
| | `-1.2_f
| `-;
|-ExpressionStatement
| |-CharUserDefinedLiteralExpression
| | `-'2'_c
| `-;
|-ExpressionStatement
| |-StringUserDefinedLiteralExpression
| | `-"12"_s
| `-;
|-ExpressionStatement
| |-IntegerUserDefinedLiteralExpression
| | `-12_r
| `-;
|-ExpressionStatement
| |-FloatUserDefinedLiteralExpression
| | `-1.2_r
| `-;
|-ExpressionStatement
| |-IntegerUserDefinedLiteralExpression
| | `-12_t
| `-;
|-ExpressionStatement
| |-FloatUserDefinedLiteralExpression
| | `-1.2_t
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, IntegerLiteralLongLong) {
TEST_P(SyntaxTreeTest, IntegerLiteral_LongLong) {
if (!GetParam().isCXX11OrLater()) {
return;
}
Expand Down Expand Up @@ -1506,7 +1850,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, IntegerLiteralBinary) {
TEST_P(SyntaxTreeTest, IntegerLiteral_Binary) {
if (!GetParam().isCXX14OrLater()) {
return;
}
Expand Down Expand Up @@ -1535,7 +1879,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, IntegerLiteralWithDigitSeparators) {
TEST_P(SyntaxTreeTest, IntegerLiteral_WithDigitSeparators) {
if (!GetParam().isCXX14OrLater()) {
return;
}
Expand Down Expand Up @@ -1615,7 +1959,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, CharacterLiteralUtf) {
TEST_P(SyntaxTreeTest, CharacterLiteral_Utf) {
if (!GetParam().isCXX11OrLater()) {
return;
}
Expand Down Expand Up @@ -1659,7 +2003,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, CharacterLiteralUtf8) {
TEST_P(SyntaxTreeTest, CharacterLiteral_Utf8) {
if (!GetParam().isCXX17OrLater()) {
return;
}
Expand Down Expand Up @@ -1734,7 +2078,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, FloatingLiteralHexadecimal) {
TEST_P(SyntaxTreeTest, FloatingLiteral_Hexadecimal) {
if (!GetParam().isCXX17OrLater()) {
return;
}
Expand Down Expand Up @@ -1809,7 +2153,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, StringLiteralUtf) {
TEST_P(SyntaxTreeTest, StringLiteral_Utf) {
if (!GetParam().isCXX11OrLater()) {
return;
}
Expand Down Expand Up @@ -1848,7 +2192,7 @@ void test() {
)txt"));
}

TEST_P(SyntaxTreeTest, StringLiteralRaw) {
TEST_P(SyntaxTreeTest, StringLiteral_Raw) {
if (!GetParam().isCXX11OrLater()) {
return;
}
Expand Down Expand Up @@ -2299,15 +2643,56 @@ void test(int a) {
)txt"));
}

TEST_P(SyntaxTreeTest, NestedBinaryOperator) {
TEST_P(SyntaxTreeTest, BinaryOperator_NestedWithParenthesis) {
EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
(1 + 2) * (4 / 2);
}
)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-ParenExpression
| | | |-(
| | | |-BinaryOperatorExpression
| | | | |-IntegerLiteralExpression
| | | | | `-1
| | | | |-+
| | | | `-IntegerLiteralExpression
| | | | `-2
| | | `-)
| | |-*
| | `-ParenExpression
| | |-(
| | |-BinaryOperatorExpression
| | | |-IntegerLiteralExpression
| | | | `-4
| | | |-/
| | | `-IntegerLiteralExpression
| | | `-2
| | `-)
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, BinaryOperator_Associativity) {
EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test(int a, int b) {
(1 + 2) * (4 / 2);
a + b + 42;
a = b = 42;
a + b * 4 + 2;
a % 2 + b * 42;
}
)cpp",
R"txt(
Expand All @@ -2332,28 +2717,6 @@ void test(int a, int b) {
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-ParenExpression
| | | |-(
| | | |-BinaryOperatorExpression
| | | | |-IntegerLiteralExpression
| | | | | `-1
| | | | |-+
| | | | `-IntegerLiteralExpression
| | | | `-2
| | | `-)
| | |-*
| | `-ParenExpression
| | |-(
| | |-BinaryOperatorExpression
| | | |-IntegerLiteralExpression
| | | | `-4
| | | |-/
| | | `-IntegerLiteralExpression
| | | `-2
| | `-)
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-BinaryOperatorExpression
| | | |-IdExpression
| | | | `-UnqualifiedId
Expand All @@ -2380,69 +2743,76 @@ void test(int a, int b) {
| | `-IntegerLiteralExpression
| | `-42
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, BinaryOperator_Precedence) {
EXPECT_TRUE(treeDumpEqual(
R"cpp(
void test() {
1 + 2 * 3 + 4;
1 % 2 + 3 * 4;
}
)cpp",
R"txt(
*: TranslationUnit
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-BinaryOperatorExpression
| | | |-IdExpression
| | | | `-UnqualifiedId
| | | | `-a
| | | |-IntegerLiteralExpression
| | | | `-1
| | | |-+
| | | `-BinaryOperatorExpression
| | | |-IdExpression
| | | | `-UnqualifiedId
| | | | `-b
| | | |-IntegerLiteralExpression
| | | | `-2
| | | |-*
| | | `-IntegerLiteralExpression
| | | `-4
| | | `-3
| | |-+
| | `-IntegerLiteralExpression
| | `-2
| | `-4
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-BinaryOperatorExpression
| | | |-IdExpression
| | | | `-UnqualifiedId
| | | | `-a
| | | |-IntegerLiteralExpression
| | | | `-1
| | | |-%
| | | `-IntegerLiteralExpression
| | | `-2
| | |-+
| | `-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-b
| | |-IntegerLiteralExpression
| | | `-3
| | |-*
| | `-IntegerLiteralExpression
| | `-42
| | `-4
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedBinaryOperator) {
TEST_P(SyntaxTreeTest, OverloadedOperator_Assignment) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X& operator=(const X&);
friend X operator+(X, const X&);
friend bool operator<(const X&, const X&);
friend X operator<<(X&, const X&);
X operator,(X&);
X operator->*(int);
// TODO: Unbox operators in syntax tree.
// Represent operators by `+` instead of `IdExpression-UnqualifiedId-+`
};
void test(X x, X y, X* xp, int X::* pmi) {
void test(X x, X y) {
x = y;
x + y;
x < y;
x << y;
x, y;
xp->*pmi;
}
)cpp",
R"txt(
Expand All @@ -2466,6 +2836,59 @@ void test(X x, X y, X* xp, int X::* pmi) {
| | | | `-&
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-y
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-=
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_Plus) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
friend X operator+(X, const X&);
};
void test(X x, X y) {
x + y;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-UnknownDeclaration
| | `-SimpleDeclaration
| | |-friend
Expand All @@ -2485,6 +2908,60 @@ void test(X x, X y, X* xp, int X::* pmi) {
| | | | `-&
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-y
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-UnknownExpression
| | | `-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-+
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_Less) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
friend bool operator<(const X&, const X&);
};
void test(X x, X y) {
x < y;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-UnknownDeclaration
| | `-SimpleDeclaration
| | |-friend
Expand All @@ -2507,6 +2984,59 @@ void test(X x, X y, X* xp, int X::* pmi) {
| | | | `-&
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-y
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-<
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_LeftShift) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
friend X operator<<(X&, const X&);
};
void test(X x, X y) {
x << y;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-UnknownDeclaration
| | `-SimpleDeclaration
| | |-friend
Expand All @@ -2528,6 +3058,59 @@ void test(X x, X y, X* xp, int X::* pmi) {
| | | | `-&
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-y
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-<<
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_Comma) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X operator,(X&);
};
void test(X x, X y) {
x, y;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-SimpleDeclaration
| | |-X
| | |-SimpleDeclarator
Expand All @@ -2541,6 +3124,59 @@ void test(X x, X y, X* xp, int X::* pmi) {
| | | | `-&
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-y
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-,
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_PointerToMember) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X operator->*(int);
};
void test(X* xp, int X::* pmi) {
xp->*pmi;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-SimpleDeclaration
| | |-X
| | |-SimpleDeclarator
Expand All @@ -2563,16 +3199,6 @@ void test(X x, X y, X* xp, int X::* pmi) {
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-y
| |-,
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | |-*
| | `-xp
| |-,
Expand All @@ -2591,57 +3217,6 @@ void test(X x, X y, X* xp, int X::* pmi) {
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-=
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-UnknownExpression
| | | `-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-+
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-<
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-<<
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-x
| | |-,
| | `-IdExpression
| | `-UnqualifiedId
| | `-y
| `-;
|-ExpressionStatement
| |-BinaryOperatorExpression
| | |-IdExpression
| | | `-UnqualifiedId
| | | `-xp
| | |-->*
| | `-IdExpression
Expand All @@ -2652,21 +3227,17 @@ void test(X x, X y, X* xp, int X::* pmi) {
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedUnaryPrefixOperator) {
TEST_P(SyntaxTreeTest, OverloadedOperator_Negation) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X operator++();
bool operator!();
X* operator&();
};
void test(X x) {
++x;
!x;
&x;
}
)cpp",
R"txt(
Expand All @@ -2676,15 +3247,6 @@ void test(X x) {
| |-X
| |-{
| |-SimpleDeclaration
| | |-X
| | |-SimpleDeclarator
| | | |-operator
| | | |-++
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-;
| |-SimpleDeclaration
| | |-bool
| | |-SimpleDeclarator
| | | |-operator
Expand All @@ -2693,6 +3255,51 @@ void test(X x) {
| | | |-(
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-PrefixUnaryOperatorExpression
| | |-!
| | `-IdExpression
| | `-UnqualifiedId
| | `-x
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_AddressOf) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X* operator&();
};
void test(X x) {
&x;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-SimpleDeclaration
| | |-X
| | |-SimpleDeclarator
Expand Down Expand Up @@ -2720,21 +3327,61 @@ void test(X x) {
|-{
|-ExpressionStatement
| |-PrefixUnaryOperatorExpression
| | |-++
| | `-IdExpression
| | `-UnqualifiedId
| | `-x
| `-;
|-ExpressionStatement
| |-PrefixUnaryOperatorExpression
| | |-!
| | |-&
| | `-IdExpression
| | `-UnqualifiedId
| | `-x
| `-;
`-}
)txt"));
}

TEST_P(SyntaxTreeTest, OverloadedOperator_PrefixIncrement) {
if (!GetParam().isCXX()) {
return;
}
EXPECT_TRUE(treeDumpEqual(
R"cpp(
struct X {
X operator++();
};
void test(X x) {
++x;
}
)cpp",
R"txt(
*: TranslationUnit
|-SimpleDeclaration
| |-struct
| |-X
| |-{
| |-SimpleDeclaration
| | |-X
| | |-SimpleDeclarator
| | | |-operator
| | | |-++
| | | `-ParametersAndQualifiers
| | | |-(
| | | `-)
| | `-;
| |-}
| `-;
`-SimpleDeclaration
|-void
|-SimpleDeclarator
| |-test
| `-ParametersAndQualifiers
| |-(
| |-SimpleDeclaration
| | |-X
| | `-SimpleDeclarator
| | `-x
| `-)
`-CompoundStatement
|-{
|-ExpressionStatement
| |-PrefixUnaryOperatorExpression
| | |-&
| | |-++
| | `-IdExpression
| | `-UnqualifiedId
| | `-x
Expand All @@ -2743,7 +3390,7 @@ void test(X x) {
)txt"));
}

TEST_P(SyntaxTreeTest, UserDefinedUnaryPostfixOperator) {
TEST_P(SyntaxTreeTest, OverloadedOperator_PostfixIncrement) {
if (!GetParam().isCXX()) {
return;
}
Expand Down