From d1211fd1ec037f88c2cc855bc850200948c76940 Mon Sep 17 00:00:00 2001 From: Eduardo Caldas Date: Tue, 11 Aug 2020 16:28:00 +0000 Subject: [PATCH] [SyntaxTree] Split tests for expressions We do that because: * Big tests generated big tree dumps that could hardly serve as documentation. * In most cases the tests didn't share setup, thus there was not much addition in lines of code. We split tests for: * `UserDefinedLiteral` * `NestedBinaryOperator` * `UserDefinedBinaryOperator` * `UserDefinedPrefixOperator` * `QualifiedId` Differential Revision: https://reviews.llvm.org/D85819 --- clang/unittests/Tooling/Syntax/TreeTest.cpp | 1527 +++++++++++++------ 1 file changed, 1087 insertions(+), 440 deletions(-) diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp index a5d1a4bfcacf..834496ce0082 100644 --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -632,26 +632,48 @@ void test() { )txt")); } -TEST_P(SyntaxTreeTest, UnqualifiedId) { +TEST_P(SyntaxTreeTest, UnqualifiedIdIdentifier) { + 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, UnqualifiedIdOperatorFunctionId) { 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 -void f(T&); void test(X x) { - x; // identifier - operator+(x, x); // operator-function-id - f(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( @@ -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 @@ -725,11 +720,6 @@ void test(X x) { `-CompoundStatement |-{ |-ExpressionStatement - | |-IdExpression - | | `-UnqualifiedId - | | `-x - | `-; - |-ExpressionStatement | |-UnknownExpression | | |-IdExpression | | | `-UnqualifiedId @@ -745,60 +735,22 @@ void test(X x) { | | | `-x | | `-) | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-IdExpression - | | | `-UnqualifiedId - | | | |-f - | | | |-< - | | | |-X - | | | `-> - | | |-( - | | |-IdExpression - | | | `-UnqualifiedId - | | | `-x - | | `-) - | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-UnknownExpression - | | | |-IdExpression - | | | | `-UnqualifiedId - | | | | `-x - | | | |-. - | | | |-operator - | | | `-int - | | |-( - | | `-) - | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-UnknownExpression - | | | |-IdExpression - | | | | `-UnqualifiedId - | | | | `-x - | | | |-. - | | | |-~ - | | | `-X - | | |-( - | | `-) - | `-; `-} )txt")); } -TEST_P(SyntaxTreeTest, UnqualifiedIdCxx11OrLater) { - if (!GetParam().isCXX11OrLater()) { +TEST_P(SyntaxTreeTest, UnqualifiedIdConversionFunctionId) { + if (!GetParam().isCXX()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( -struct X { }; -unsigned operator "" _w(long long unsigned); +struct X { + operator int(); +}; void test(X x) { - operator "" _w(1llu); // literal-operator-id // TODO: Expose `id-expression` from `MemberExpr` - x.~decltype(x)(); // ~decltype-specifier + x.operator int(); } )cpp", R"txt( @@ -807,22 +759,16 @@ void test(X x) { | |-struct | |-X | |-{ +| |-SimpleDeclaration +| | |-SimpleDeclarator +| | | |-operator +| | | |-int +| | | `-ParametersAndQualifiers +| | | |-( +| | | `-) +| | `-; | |-} | `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" -| | |-_w -| | `-ParametersAndQualifiers -| | |-( -| | |-SimpleDeclaration -| | | |-long -| | | |-long -| | | `-unsigned -| | `-) -| `-; `-SimpleDeclaration |-void |-SimpleDeclarator @@ -834,6 +780,56 @@ void test(X x) { | | `-SimpleDeclarator | | `-x | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-UnknownExpression + | | |-UnknownExpression + | | | |-IdExpression + | | | | `-UnqualifiedId + | | | | `-x + | | | |-. + | | | |-operator + | | | `-int + | | |-( + | | `-) + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UnqualifiedIdLiteralOperatorId) { + 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 @@ -844,10 +840,96 @@ void test(X x) { | | | |-"" | | | `-_w | | |-( - | | |-IntegerLiteralExpression - | | | `-1llu + | | |-CharacterLiteralExpression + | | | `-'1' | | `-) | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UnqualifiedIdDestructor) { + 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 + | | | |-IdExpression + | | | | `-UnqualifiedId + | | | | `-x + | | | |-. + | | | |-~ + | | | `-X + | | |-( + | | `-) + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UnqualifiedIdDecltypeDestructor) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +struct X { }; +void test(X x) { + // TODO: Expose `id-expression` from `MemberExpr` + x.~decltype(x)(); +} +)cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-struct +| |-X +| |-{ +| |-} +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-X + | | `-SimpleDeclarator + | | `-x + | `-) + `-CompoundStatement + |-{ |-ExpressionStatement | |-UnknownExpression | | |-UnknownExpression @@ -867,46 +949,71 @@ void test(X x) { )txt")); } -TEST_P(SyntaxTreeTest, QualifiedId) { +TEST_P(SyntaxTreeTest, UnqualifiedIdTemplateId) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +template +T f(); +void test() { + f(); +} +)cpp", + R"txt( +*: TranslationUnit +|-TemplateDeclaration +| |-template +| |-< +| |-UnknownDeclaration +| | |-typename +| | `-T +| |-> +| `-SimpleDeclaration +| |-T +| |-SimpleDeclarator +| | |-f +| | `-ParametersAndQualifiers +| | |-( +| | `-) +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-UnknownExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | |-f + | | | |-< + | | | |-int + | | | `-> + | | |-( + | | `-) + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, QualifiedIdWithNamespace) { if (!GetParam().isCXX()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( namespace n { - struct S { - template - struct ST { - static void f(); - }; - }; + struct S { }; } -template -struct ST { - struct S { - template - static U f(); - }; -}; void test() { - :: // global-namespace-specifier - n:: // namespace-specifier - S:: // type-name-specifier - template ST:: // type-template-instantiation-specifier - f(); - - n:: // namespace-specifier - S:: // type-name-specifier - ST:: // type-template-instantiation-specifier - f(); - - ST:: // type-name-specifier - S:: // type-name-specifier - f(); - - ST:: // type-name-specifier - S:: // type-name-specifier - template f(); + ::n::S s1; + n::S s2; } )cpp", R"txt( @@ -919,31 +1026,62 @@ void test() { | | |-struct | | |-S | | |-{ -| | |-TemplateDeclaration -| | | |-template -| | | |-< -| | | |-UnknownDeclaration -| | | | |-typename -| | | | `-T -| | | |-> -| | | `-SimpleDeclaration -| | | |-struct -| | | |-ST -| | | |-{ -| | | |-SimpleDeclaration -| | | | |-static -| | | | |-void -| | | | |-SimpleDeclarator -| | | | | |-f -| | | | | `-ParametersAndQualifiers -| | | | | |-( -| | | | | `-) -| | | | `-; -| | | |-} -| | | `-; | | |-} | | `-; | `-} +`-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, QualifiedIdWithTemplateSpecifier) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +template +struct ST { + struct S { }; +}; +void test() { + ::template ST::S s1; + ::ST::S s2; +} +)cpp", + R"txt( +*: TranslationUnit |-TemplateDeclaration | |-template | |-< @@ -959,26 +1097,190 @@ void test() { | | |-struct | | |-S | | |-{ -| | |-TemplateDeclaration -| | | |-template -| | | |-< -| | | |-UnknownDeclaration -| | | | |-typename -| | | | `-U -| | | |-> -| | | `-SimpleDeclaration -| | | |-static -| | | |-U -| | | |-SimpleDeclarator -| | | | |-f -| | | | `-ParametersAndQualifiers -| | | | |-( -| | | | `-) -| | | `-; | | |-} | | `-; | |-} | `-; +`-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, QualifiedIdWithOptionalTemplateKw) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +struct S { + template + static U f(); +}; +void test() { + S::f(); + S::template f(); +} +)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 + | | | | | `-S + | | | | `-:: + | | | `-UnqualifiedId + | | | |-f + | | | |-< + | | | |-int + | | | `-> + | | |-( + | | `-) + | `-; + |-ExpressionStatement + | |-UnknownExpression + | | |-IdExpression + | | | |-NestedNameSpecifier + | | | | |-IdentifierNameSpecifier + | | | | | `-S + | | | | `-:: + | | | |-template + | | | `-UnqualifiedId + | | | |-f + | | | |-< + | | | |-int + | | | `-> + | | |-( + | | `-) + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, QualifiedIdComplex) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +namespace n { + template + struct ST { + template + static U f(); + }; +} +void test() { + ::n::template ST::template f(); +} +)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 @@ -996,9 +1298,6 @@ void test() { | | | | |-IdentifierNameSpecifier | | | | | `-n | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-S - | | | | |-:: | | | | |-SimpleTemplateNameSpecifier | | | | | |-template | | | | | |-ST @@ -1006,66 +1305,6 @@ void test() { | | | | | |-int | | | | | `-> | | | | `-:: - | | | `-UnqualifiedId - | | | `-f - | | |-( - | | `-) - | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-IdExpression - | | | |-NestedNameSpecifier - | | | | |-IdentifierNameSpecifier - | | | | | `-n - | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-S - | | | | |-:: - | | | | |-SimpleTemplateNameSpecifier - | | | | | |-ST - | | | | | |-< - | | | | | |-int - | | | | | `-> - | | | | `-:: - | | | `-UnqualifiedId - | | | `-f - | | |-( - | | `-) - | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-IdExpression - | | | |-NestedNameSpecifier - | | | | |-SimpleTemplateNameSpecifier - | | | | | |-ST - | | | | | |-< - | | | | | |-int - | | | | | `-> - | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-S - | | | | `-:: - | | | `-UnqualifiedId - | | | |-f - | | | |-< - | | | |-int - | | | `-> - | | |-( - | | `-) - | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-IdExpression - | | | |-NestedNameSpecifier - | | | | |-SimpleTemplateNameSpecifier - | | | | | |-ST - | | | | | |-< - | | | | | |-int - | | | | | `-> - | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-S - | | | | `-:: | | | |-template | | | `-UnqualifiedId | | | |-f @@ -1093,9 +1332,7 @@ TEST_P(SyntaxTreeTest, QualifiedIdWithDependentType) { template void test() { T::template U::f(); - T::U::f(); - T::template f<0>(); } )cpp", @@ -1182,8 +1419,7 @@ struct S { static void f(){} }; void test(S s) { - decltype(s):: // decltype-specifier - f(); + decltype(s)::f(); } )cpp", R"txt( @@ -1294,7 +1530,49 @@ void test() { )txt")); } -TEST_P(SyntaxTreeTest, UserDefinedLiteral) { +TEST_P(SyntaxTreeTest, CharUserDefinedLiteral) { + 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, StringUserDefinedLiteral) { if (!GetParam().isCXX11OrLater()) { return; } @@ -1302,24 +1580,10 @@ TEST_P(SyntaxTreeTest, UserDefinedLiteral) { 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 -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( @@ -1343,45 +1607,6 @@ void test() { | |-SimpleDeclarator | | |-operator | | |-"" -| | |-_i -| | `-ParametersAndQualifiers -| | |-( -| | |-SimpleDeclaration -| | | |-unsigned -| | | |-long -| | | `-long -| | `-) -| `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" -| | |-_f -| | `-ParametersAndQualifiers -| | |-( -| | |-SimpleDeclaration -| | | |-long -| | | `-double -| | `-) -| `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" -| | |-_c -| | `-ParametersAndQualifiers -| | |-( -| | |-SimpleDeclaration -| | | `-char -| | `-) -| `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" | | |-_s | | `-ParametersAndQualifiers | | |-( @@ -1395,6 +1620,56 @@ void test() { | | | `-size_t | | `-) | `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-StringUserDefinedLiteralExpression + | | `-"12"_s + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, IntegerUserDefinedLiteral) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +unsigned operator "" _i(unsigned long long); +unsigned operator "" _r(const char*); +template +unsigned operator "" _t(); + +void test() { + 12_i; + 12_r; + 12_t; +} + )cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_i +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-unsigned +| | | |-long +| | | `-long +| | `-) +| `-; |-SimpleDeclaration | |-unsigned | |-SimpleDeclarator @@ -1441,29 +1716,98 @@ void test() { | | `-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 | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, FloatUserDefinedLiteral) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +unsigned operator "" _f(long double); +unsigned operator "" _r(const char*); +template +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 +| | |-"" +| | |-_f +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-long +| | | `-double +| | `-) +| `-; +|-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_r +| | `-ParametersAndQualifiers +| | |-( +| | |-SimpleDeclaration +| | | |-const +| | | |-char +| | | `-SimpleDeclarator +| | | `-* +| | `-) +| `-; +|-TemplateDeclaration +| |-template +| |-< +| |-SimpleDeclaration +| | `-char +| |-... +| |-> +| `-SimpleDeclaration +| |-unsigned +| |-SimpleDeclarator +| | |-operator +| | |-"" +| | |-_t +| | `-ParametersAndQualifiers +| | |-( +| | `-) +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-FloatUserDefinedLiteralExpression + | | `-1.2_f + | `-; + |-ExpressionStatement + | |-FloatUserDefinedLiteralExpression + | | `-1.2_r + | `-; |-ExpressionStatement | |-FloatUserDefinedLiteralExpression | | `-1.2_t @@ -2299,15 +2643,11 @@ void test(int a) { )txt")); } -TEST_P(SyntaxTreeTest, NestedBinaryOperator) { +TEST_P(SyntaxTreeTest, NestedBinaryOperatorWithParenthesis) { EXPECT_TRUE(treeDumpEqual( R"cpp( -void test(int a, int b) { +void test() { (1 + 2) * (4 / 2); - a + b + 42; - a = b = 42; - a + b * 4 + 2; - a % 2 + b * 42; } )cpp", R"txt( @@ -2318,15 +2658,6 @@ void test(int a, int b) { | |-test | `-ParametersAndQualifiers | |-( - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-a - | |-, - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-b | `-) `-CompoundStatement |-{ @@ -2352,6 +2683,38 @@ void test(int a, int b) { | | | `-2 | | `-) | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, NestedBinaryOperatorWithAssociativity) { + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test(int a, int b) { + a + b + 42; + a = b = 42; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-int + | | `-SimpleDeclarator + | | `-a + | |-, + | |-SimpleDeclaration + | | |-int + | | `-SimpleDeclarator + | | `-b + | `-) + `-CompoundStatement + |-{ |-ExpressionStatement | |-BinaryOperatorExpression | | |-BinaryOperatorExpression @@ -2380,47 +2743,66 @@ void test(int a, int b) { | | `-IntegerLiteralExpression | | `-42 | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, NestedBinaryOperatorWithPrecedence) { + 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, UserDefinedAssignmentOperator) { if (!GetParam().isCXX()) { return; } @@ -2428,21 +2810,9 @@ TEST_P(SyntaxTreeTest, UserDefinedBinaryOperator) { 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( @@ -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, UserDefinedPlusOperator) { + 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 @@ -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, UserDefinedLessOperator) { + 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 @@ -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, UserDefinedShiftOperator) { + 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 @@ -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, UserDefinedCommaOperator) { + 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 @@ -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, UserDefinedArrowPointerOperator) { + 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 @@ -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 | |-, @@ -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 @@ -2652,7 +3227,7 @@ void test(X x, X y, X* xp, int X::* pmi) { )txt")); } -TEST_P(SyntaxTreeTest, UserDefinedUnaryPrefixOperator) { +TEST_P(SyntaxTreeTest, UserDefinedPrefixIncrOperator) { if (!GetParam().isCXX()) { return; } @@ -2660,13 +3235,9 @@ TEST_P(SyntaxTreeTest, UserDefinedUnaryPrefixOperator) { R"cpp( struct X { X operator++(); - bool operator!(); - X* operator&(); }; void test(X x) { ++x; - !x; - &x; } )cpp", R"txt( @@ -2684,25 +3255,6 @@ void test(X x) { | | | |-( | | | `-) | | `-; -| |-SimpleDeclaration -| | |-bool -| | |-SimpleDeclarator -| | | |-operator -| | | |-! -| | | `-ParametersAndQualifiers -| | | |-( -| | | `-) -| | `-; -| |-SimpleDeclaration -| | |-X -| | |-SimpleDeclarator -| | | |-* -| | | |-operator -| | | |-& -| | | `-ParametersAndQualifiers -| | | |-( -| | | `-) -| | `-; | |-} | `-; `-SimpleDeclaration @@ -2725,6 +3277,53 @@ void test(X x) { | | `-UnqualifiedId | | `-x | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UserDefinedExclamOperator) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +struct X { + bool operator!(); +}; +void test(X x) { + !x; +} +)cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-struct +| |-X +| |-{ +| |-SimpleDeclaration +| | |-bool +| | |-SimpleDeclarator +| | | |-operator +| | | |-! +| | | `-ParametersAndQualifiers +| | | |-( +| | | `-) +| | `-; +| |-} +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-X + | | `-SimpleDeclarator + | | `-x + | `-) + `-CompoundStatement + |-{ |-ExpressionStatement | |-PrefixUnaryOperatorExpression | | |-! @@ -2732,6 +3331,54 @@ void test(X x) { | | `-UnqualifiedId | | `-x | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UserDefinedReferenceOperator) { + 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 | | |-&