diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -632,26 +632,48 @@ )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 @@ | | | | `-& | | | `-) | | `-; -| |-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 @@ `-CompoundStatement |-{ |-ExpressionStatement - | |-IdExpression - | | `-UnqualifiedId - | | `-x - | `-; - |-ExpressionStatement | |-UnknownExpression | | |-IdExpression | | | `-UnqualifiedId @@ -745,20 +735,53 @@ | | | `-x | | `-) | `-; - |-ExpressionStatement - | |-UnknownExpression - | | |-IdExpression - | | | `-UnqualifiedId - | | | |-f - | | | |-< - | | | |-X - | | | `-> - | | |-( - | | |-IdExpression - | | | `-UnqualifiedId - | | | `-x - | | `-) - | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, UnqualifiedIdConversionFunctionId) { + 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 @@ -771,6 +794,93 @@ | | |-( | | `-) | `-; + `-} +)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 + | |-UnknownExpression + | | |-IdExpression + | | | `-UnqualifiedId + | | | |-operator + | | | |-"" + | | | `-_w + | | |-( + | | |-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 @@ -787,18 +897,16 @@ )txt")); } -TEST_P(SyntaxTreeTest, UnqualifiedIdCxx11OrLater) { +TEST_P(SyntaxTreeTest, UnqualifiedIdDecltypeDestructor) { 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( @@ -809,20 +917,6 @@ | |-{ | |-} | `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" -| | |-_w -| | `-ParametersAndQualifiers -| | |-( -| | |-SimpleDeclaration -| | | |-long -| | | |-long -| | | `-unsigned -| | `-) -| `-; `-SimpleDeclaration |-void |-SimpleDeclarator @@ -838,18 +932,6 @@ |-{ |-ExpressionStatement | |-UnknownExpression - | | |-IdExpression - | | | `-UnqualifiedId - | | | |-operator - | | | |-"" - | | | `-_w - | | |-( - | | |-IntegerLiteralExpression - | | | `-1llu - | | `-) - | `-; - |-ExpressionStatement - | |-UnknownExpression | | |-UnknownExpression | | | |-IdExpression | | | | `-UnqualifiedId @@ -867,83 +949,20 @@ )txt")); } -TEST_P(SyntaxTreeTest, QualifiedId) { +TEST_P(SyntaxTreeTest, UnqualifiedIdTemplateId) { if (!GetParam().isCXX()) { return; } EXPECT_TRUE(treeDumpEqual( R"cpp( -namespace n { - struct S { - template - struct ST { - static void f(); - }; - }; -} template -struct ST { - struct S { - template - static U f(); - }; -}; +T 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(); } )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 | |-< @@ -952,36 +971,16 @@ | | `-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 | |-( @@ -991,44 +990,221 @@ |-ExpressionStatement | |-UnknownExpression | | |-IdExpression - | | | |-NestedNameSpecifier - | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-n - | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-S - | | | | |-:: - | | | | |-SimpleTemplateNameSpecifier - | | | | | |-template - | | | | | |-ST - | | | | | |-< - | | | | | |-int - | | | | | `-> - | | | | `-:: | | | `-UnqualifiedId - | | | `-f + | | | |-f + | | | |-< + | | | |-int + | | | `-> | | |-( | | `-) | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, QualifiedIdWithNamespace) { + 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, 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 +| |-< +| |-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, 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 - | | | | | `-n - | | | | |-:: - | | | | |-IdentifierNameSpecifier | | | | | `-S - | | | | |-:: - | | | | |-SimpleTemplateNameSpecifier - | | | | | |-ST - | | | | | |-< - | | | | | |-int - | | | | | `-> | | | | `-:: | | | `-UnqualifiedId - | | | `-f + | | | |-f + | | | |-< + | | | |-int + | | | `-> | | |-( | | `-) | `-; @@ -1036,15 +1212,10 @@ | |-UnknownExpression | | |-IdExpression | | | |-NestedNameSpecifier - | | | | |-SimpleTemplateNameSpecifier - | | | | | |-ST - | | | | | |-< - | | | | | |-int - | | | | | `-> - | | | | |-:: | | | | |-IdentifierNameSpecifier | | | | | `-S | | | | `-:: + | | | |-template | | | `-UnqualifiedId | | | |-f | | | |-< @@ -1053,18 +1224,86 @@ | | |-( | | `-) | `-; + `-} +)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 + | |-test + | `-ParametersAndQualifiers + | |-( + | `-) + `-CompoundStatement + |-{ |-ExpressionStatement | |-UnknownExpression | | |-IdExpression | | | |-NestedNameSpecifier + | | | | |-:: + | | | | |-IdentifierNameSpecifier + | | | | | `-n + | | | | |-:: | | | | |-SimpleTemplateNameSpecifier + | | | | | |-template | | | | | |-ST | | | | | |-< | | | | | |-int | | | | | `-> - | | | | |-:: - | | | | |-IdentifierNameSpecifier - | | | | | `-S | | | | `-:: | | | |-template | | | `-UnqualifiedId @@ -1093,9 +1332,7 @@ template void test() { T::template U::f(); - T::U::f(); - T::template f<0>(); } )cpp", @@ -1182,8 +1419,7 @@ static void f(){} }; void test(S s) { - decltype(s):: // decltype-specifier - f(); + decltype(s)::f(); } )cpp", R"txt( @@ -1294,47 +1530,75 @@ )txt")); } -TEST_P(SyntaxTreeTest, UserDefinedLiteral) { +TEST_P(SyntaxTreeTest, CharUserDefinedLiteral) { 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 -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 + '2'_c; } )cpp", R"txt( *: TranslationUnit |-SimpleDeclaration -| |-typedef -| |-decltype -| |-( -| |-UnknownExpression -| | |-sizeof -| | |-( -| | |-void -| | |-* -| | `-) -| |-) +| |-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; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +typedef decltype(sizeof(void *)) size_t; + +unsigned operator "" _s(const char*, size_t); + +void test() { + "12"_s; +} + )cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-typedef +| |-decltype +| |-( +| |-UnknownExpression +| | |-sizeof +| | |-( +| | |-void +| | |-* +| | `-) +| |-) | |-SimpleDeclarator | | `-size_t | `-; @@ -1343,26 +1607,67 @@ | |-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, 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 | | |-"" -| | |-_f +| | |-_i | | `-ParametersAndQualifiers | | |-( | | |-SimpleDeclaration +| | | |-unsigned | | | |-long -| | | `-double +| | | `-long | | `-) | `-; |-SimpleDeclaration @@ -1370,29 +1675,88 @@ | |-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, 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 | | |-"" -| | |-_s +| | |-_f | | `-ParametersAndQualifiers | | |-( | | |-SimpleDeclaration -| | | |-const -| | | |-char -| | | `-SimpleDeclarator -| | | `-* -| | |-, -| | |-SimpleDeclaration -| | | `-size_t +| | | |-long +| | | `-double | | `-) | `-; |-SimpleDeclaration @@ -1437,34 +1801,14 @@ `-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 | `-; @@ -2299,15 +2643,11 @@ )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 @@ | |-test | `-ParametersAndQualifiers | |-( - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-a - | |-, - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-b | `-) `-CompoundStatement |-{ @@ -2352,6 +2683,38 @@ | | | `-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 @@ | | `-IntegerLiteralExpression | | `-42 | `-; - |-ExpressionStatement - | |-BinaryOperatorExpression - | | |-BinaryOperatorExpression - | | | |-IdExpression - | | | | `-UnqualifiedId - | | | | `-a - | | | |-+ - | | | `-BinaryOperatorExpression - | | | |-IdExpression - | | | | `-UnqualifiedId - | | | | `-b - | | | |-* - | | | `-IntegerLiteralExpression - | | | `-4 - | | |-+ - | | `-IntegerLiteralExpression - | | `-2 + `-} +)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 + | | | |-IntegerLiteralExpression + | | | | `-1 + | | | |-+ + | | | `-BinaryOperatorExpression + | | | |-IntegerLiteralExpression + | | | | `-2 + | | | |-* + | | | `-IntegerLiteralExpression + | | | `-3 + | | |-+ + | | `-IntegerLiteralExpression + | | `-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 @@ 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 @@ | | | | `-& | | | `-) | | `-; +| |-} +| `-; +`-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 @@ | | | | `-& | | | `-) | | `-; +| |-} +| `-; +`-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 @@ | | | | `-& | | | `-) | | `-; +| |-} +| `-; +`-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 @@ | | | | `-& | | | `-) | | `-; +| |-} +| `-; +`-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 @@ | | | | `-& | | | `-) | | `-; +| |-} +| `-; +`-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 @@ | |-SimpleDeclaration | | |-X | | `-SimpleDeclarator - | | `-x - | |-, - | |-SimpleDeclaration - | | |-X - | | `-SimpleDeclarator - | | `-y - | |-, - | |-SimpleDeclaration - | | |-X - | | `-SimpleDeclarator | | |-* | | `-xp | |-, @@ -2591,57 +3217,6 @@ | |-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 @@ )txt")); } -TEST_P(SyntaxTreeTest, UserDefinedUnaryPrefixOperator) { +TEST_P(SyntaxTreeTest, UserDefinedPrefixIncrOperator) { if (!GetParam().isCXX()) { return; } @@ -2660,13 +3235,9 @@ R"cpp( struct X { X operator++(); - bool operator!(); - X* operator&(); }; void test(X x) { ++x; - !x; - &x; } )cpp", R"txt( @@ -2684,6 +3255,51 @@ | | | |-( | | | `-) | | `-; +| |-} +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-X + | | `-SimpleDeclarator + | | `-x + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-PrefixUnaryOperatorExpression + | | |-++ + | | `-IdExpression + | | `-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 @@ -2693,6 +3309,51 @@ | | | |-( | | | `-) | | `-; +| |-} +| `-; +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-X + | | `-SimpleDeclarator + | | `-x + | `-) + `-CompoundStatement + |-{ + |-ExpressionStatement + | |-PrefixUnaryOperatorExpression + | | |-! + | | `-IdExpression + | | `-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 @@ -2720,20 +3381,6 @@ |-{ |-ExpressionStatement | |-PrefixUnaryOperatorExpression - | | |-++ - | | `-IdExpression - | | `-UnqualifiedId - | | `-x - | `-; - |-ExpressionStatement - | |-PrefixUnaryOperatorExpression - | | |-! - | | `-IdExpression - | | `-UnqualifiedId - | | `-x - | `-; - |-ExpressionStatement - | |-PrefixUnaryOperatorExpression | | |-& | | `-IdExpression | | `-UnqualifiedId