aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/Syntax/BuildTree.cpp
diff options
context:
space:
mode:
authorEduardo Caldas <ecaldas@google.com>2020-08-11 16:28:00 +0000
committerEduardo Caldas <ecaldas@google.com>2020-08-12 08:01:18 +0000
commitac37afa650271d8366b706d79ff8e217fc624cbb (patch)
tree6848e400e41e103513e6d9ad3dccaa80cfe4fd86 /clang/lib/Tooling/Syntax/BuildTree.cpp
parent88bbd30736561190a6733d0ad60aec21446b914c (diff)
downloadllvm-ac37afa650271d8366b706d79ff8e217fc624cbb.zip
llvm-ac37afa650271d8366b706d79ff8e217fc624cbb.tar.gz
llvm-ac37afa650271d8366b706d79ff8e217fc624cbb.tar.bz2
[SyntaxTree] Unbox operators into tokens for nodes generated from `CXXOperatorCallExpr`
For an user define `<`, `x < y` would yield the syntax tree: ``` BinaryOperatorExpression |-IdExpression | `-UnqualifiedId | `-x |-IdExpression | `-UnqualifiedId | `-< `-IdExpression `-UnqualifiedId `-y ``` But there is no syntatic difference at call site between call site or built-in `<`. As such they should generate the same syntax tree, namely: ``` BinaryOperatorExpression |-IdExpression | `-UnqualifiedId | `-x |-< `-IdExpression `-UnqualifiedId `-y ``` Differential Revision: https://reviews.llvm.org/D85750
Diffstat (limited to 'clang/lib/Tooling/Syntax/BuildTree.cpp')
-rw-r--r--clang/lib/Tooling/Syntax/BuildTree.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 9045153..11d3997 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -1007,23 +1007,26 @@ public:
}
bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *S) {
- if (getOperatorNodeKind(*S) ==
- syntax::NodeKind::PostfixUnaryOperatorExpression) {
+ // To construct a syntax tree of the same shape for calls to built-in and
+ // user-defined operators, ignore the `DeclRefExpr` that refers to the
+ // operator and treat it as a simple token. Do that by traversing
+ // arguments instead of children.
+ for (auto *child : S->arguments()) {
// A postfix unary operator is declared as taking two operands. The
// second operand is used to distinguish from its prefix counterpart. In
// the semantic AST this "phantom" operand is represented as a
// `IntegerLiteral` with invalid `SourceLocation`. We skip visiting this
// operand because it does not correspond to anything written in source
- // code
- for (auto *child : S->children()) {
- if (child->getSourceRange().isInvalid())
- continue;
- if (!TraverseStmt(child))
- return false;
+ // code.
+ if (child->getSourceRange().isInvalid()) {
+ assert(getOperatorNodeKind(*S) ==
+ syntax::NodeKind::PostfixUnaryOperatorExpression);
+ continue;
}
- return WalkUpFromCXXOperatorCallExpr(S);
- } else
- return RecursiveASTVisitor::TraverseCXXOperatorCallExpr(S);
+ if (!TraverseStmt(child))
+ return false;
+ }
+ return WalkUpFromCXXOperatorCallExpr(S);
}
bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr *S) {