diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -640,6 +640,24 @@ return true; } + bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) { + if (S->isInfixBinaryOp()) { + Builder.markExprChild( + S->getArg(0), + syntax::NodeRole::BinaryOperatorExpression_leftHandSide); + Builder.markChildToken( + S->getOperatorLoc(), + syntax::NodeRole::BinaryOperatorExpression_operatorToken); + Builder.markExprChild( + S->getArg(1), + syntax::NodeRole::BinaryOperatorExpression_rightHandSide); + Builder.foldNode(Builder.getExprRange(S), + new (allocator()) syntax::BinaryOperatorExpression, S); + return true; + } + return RecursiveASTVisitor::WalkUpFromCXXOperatorCallExpr(S); + } + bool WalkUpFromNamespaceDecl(NamespaceDecl *S) { auto Tokens = Builder.getDeclarationRange(S); if (Tokens.front().kind() == tok::coloncolon) { 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 @@ -993,6 +993,134 @@ )txt"); } +TEST_F(SyntaxTreeTest, UserDefinedBinaryOperator) { + expectTreeDumpEqual( + R"cpp( +struct X { + X& operator=(const X&); + friend X operator+(X, const X&); + friend bool operator<(const X&, const X&); +}; +void test(X x, X y) { + x = y; + x + y; + x < y; +} + )cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-struct +| |-X +| |-{ +| |-SimpleDeclaration +| | |-X +| | |-SimpleDeclarator +| | | |-& +| | | |-operator +| | | |-= +| | | `-ParametersAndQualifiers +| | | |-( +| | | |-SimpleDeclaration +| | | | |-const +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | `-) +| | `-; +| |-UnknownDeclaration +| | `-SimpleDeclaration +| | |-friend +| | |-X +| | |-SimpleDeclarator +| | | |-operator +| | | |-+ +| | | `-ParametersAndQualifiers +| | | |-( +| | | |-SimpleDeclaration +| | | | `-X +| | | |-, +| | | |-SimpleDeclaration +| | | | |-const +| | | | |-X +| | | | `-SimpleDeclarator +| | | | `-& +| | | `-) +| | `-; +| |-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 + | | |-UnknownExpression + | | | `-x + | | |-UnknownExpression + | | | `-= + | | `-UnknownExpression + | | `-y + | `-; + |-ExpressionStatement + | |-BinaryOperatorExpression + | | |-UnknownExpression + | | | `-UnknownExpression + | | | `-x + | | |-UnknownExpression + | | | `-+ + | | `-UnknownExpression + | | `-y + | `-; + |-ExpressionStatement + | |-BinaryOperatorExpression + | | |-UnknownExpression + | | | `-x + | | |-UnknownExpression + | | | `-< + | | `-UnknownExpression + | | `-y + | `-; + `-} +)txt"); +} + TEST_F(SyntaxTreeTest, MultipleDeclaratorsGrouping) { expectTreeDumpEqual( R"cpp(