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,54 +949,107 @@ )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 -| |-{ +|-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, QualifiedId) { + 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(); + }; +}; +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 @@ -1294,7 +1429,49 @@ )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 +1479,10 @@ 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,56 +1506,67 @@ | |-SimpleDeclarator | | |-operator | | |-"" -| | |-_i -| | `-ParametersAndQualifiers -| | |-( -| | |-SimpleDeclaration -| | | |-unsigned -| | | |-long -| | | `-long -| | `-) -| `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" -| | |-_f +| | |-_s | | `-ParametersAndQualifiers | | |-( | | |-SimpleDeclaration -| | | |-long -| | | `-double -| | `-) -| `-; -|-SimpleDeclaration -| |-unsigned -| |-SimpleDeclarator -| | |-operator -| | |-"" -| | |-_c -| | `-ParametersAndQualifiers -| | |-( +| | | |-const +| | | |-char +| | | `-SimpleDeclarator +| | | `-* +| | |-, | | |-SimpleDeclaration -| | | `-char +| | | `-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 | | |-"" -| | |-_s +| | |-_i | | `-ParametersAndQualifiers | | |-( | | |-SimpleDeclaration -| | | |-const -| | | |-char -| | | `-SimpleDeclarator -| | | `-* -| | |-, -| | |-SimpleDeclaration -| | | `-size_t +| | | |-unsigned +| | | |-long +| | | `-long | | `-) | `-; |-SimpleDeclaration @@ -1441,56 +1615,126 @@ | | `-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, 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() { - 12ll; - 12ull; + 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", + )cpp", R"txt( *: TranslationUnit -`-SimpleDeclaration - |-void - |-SimpleDeclarator - | |-test - | `-ParametersAndQualifiers - | |-( +|-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 + | `-; + `-} +)txt")); +} + +TEST_P(SyntaxTreeTest, IntegerLiteralLongLong) { + if (!GetParam().isCXX11OrLater()) { + return; + } + EXPECT_TRUE(treeDumpEqual( + R"cpp( +void test() { + 12ll; + 12ull; +} +)cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-test + | `-ParametersAndQualifiers + | |-( | `-) `-CompoundStatement |-{ @@ -2299,15 +2543,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 +2558,6 @@ | |-test | `-ParametersAndQualifiers | |-( - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-a - | |-, - | |-SimpleDeclaration - | | |-int - | | `-SimpleDeclarator - | | `-b | `-) `-CompoundStatement |-{ @@ -2352,6 +2583,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 +2643,66 @@ | | `-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 +2710,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 +2736,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,31 +2808,138 @@ | | | | `-& | | | `-) | | `-; -| |-UnknownDeclaration -| | `-SimpleDeclaration -| | |-friend -| | |-bool -| | |-SimpleDeclarator -| | | |-operator -| | | |-< -| | | `-ParametersAndQualifiers -| | | |-( -| | | |-SimpleDeclaration -| | | | |-const -| | | | |-X -| | | | `-SimpleDeclarator -| | | | `-& -| | | |-, -| | | |-SimpleDeclaration -| | | | |-const -| | | | |-X -| | | | `-SimpleDeclarator -| | | | `-& -| | | `-) -| | `-; -| |-UnknownDeclaration -| | `-SimpleDeclaration -| | |-friend +| |-} +| `-; +`-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 +| | |-bool +| | |-SimpleDeclarator +| | | |-operator +| | | |-< +| | | `-ParametersAndQualifiers +| | | |-( +| | | |-SimpleDeclaration +| | | | |-const +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | |-, +| | | |-SimpleDeclaration +| | | | |-const +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | `-) +| | `-; +| |-} +| `-; +`-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 | | |-X | | |-SimpleDeclarator | | | |-operator @@ -2528,6 +2958,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 +3024,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 +3099,6 @@ | |-SimpleDeclaration | | |-X | | `-SimpleDeclarator - | | `-x - | |-, - | |-SimpleDeclaration - | | |-X - | | `-SimpleDeclarator - | | `-y - | |-, - | |-SimpleDeclaration - | | |-X - | | `-SimpleDeclarator | | |-* | | `-xp | |-, @@ -2591,57 +3117,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 +3127,7 @@ )txt")); } -TEST_P(SyntaxTreeTest, UserDefinedUnaryPrefixOperator) { +TEST_P(SyntaxTreeTest, UserDefinedPrefixIncrOperator) { if (!GetParam().isCXX()) { return; } @@ -2660,13 +3135,9 @@ R"cpp( struct X { X operator++(); - bool operator!(); - X* operator&(); }; void test(X x) { ++x; - !x; - &x; } )cpp", R"txt( @@ -2684,6 +3155,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 +3209,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 +3281,6 @@ |-{ |-ExpressionStatement | |-PrefixUnaryOperatorExpression - | | |-++ - | | `-IdExpression - | | `-UnqualifiedId - | | `-x - | `-; - |-ExpressionStatement - | |-PrefixUnaryOperatorExpression - | | |-! - | | `-IdExpression - | | `-UnqualifiedId - | | `-x - | `-; - |-ExpressionStatement - | |-PrefixUnaryOperatorExpression | | |-& | | `-IdExpression | | `-UnqualifiedId