[clang] ac37afa - [SyntaxTree] Unbox operators into tokens for nodes generated from `CXXOperatorCallExpr`

Eduardo Caldas via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 12 01:14:21 PDT 2020


Author: Eduardo Caldas
Date: 2020-08-12T08:01:18Z
New Revision: ac37afa650271d8366b706d79ff8e217fc624cbb

URL: https://github.com/llvm/llvm-project/commit/ac37afa650271d8366b706d79ff8e217fc624cbb
DIFF: https://github.com/llvm/llvm-project/commit/ac37afa650271d8366b706d79ff8e217fc624cbb.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/Tooling/Syntax/BuildTree.cpp
    clang/unittests/Tooling/Syntax/TreeTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 90451539b3b4..11d399730040 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -1007,23 +1007,26 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
   }
 
   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) {

diff  --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp
index 46101660df8e..a5d1a4bfcacf 100644
--- a/clang/unittests/Tooling/Syntax/TreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp
@@ -2592,9 +2592,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
     | | |-IdExpression
     | | | `-UnqualifiedId
     | | |   `-x
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-=
+    | | |-=
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-y
@@ -2605,9 +2603,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
     | | | `-IdExpression
     | | |   `-UnqualifiedId
     | | |     `-x
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-+
+    | | |-+
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-y
@@ -2617,9 +2613,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
     | | |-IdExpression
     | | | `-UnqualifiedId
     | | |   `-x
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-<
+    | | |-<
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-y
@@ -2629,9 +2623,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
     | | |-IdExpression
     | | | `-UnqualifiedId
     | | |   `-x
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-<<
+    | | |-<<
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-y
@@ -2641,9 +2633,7 @@ void test(X x, X y, X* xp, int X::* pmi) {
     | | |-IdExpression
     | | | `-UnqualifiedId
     | | |   `-x
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-,
+    | | |-,
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-y
@@ -2730,27 +2720,21 @@ void test(X x) {
     |-{
     |-ExpressionStatement
     | |-PrefixUnaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-++
+    | | |-++
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-x
     | `-;
     |-ExpressionStatement
     | |-PrefixUnaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-!
+    | | |-!
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-x
     | `-;
     |-ExpressionStatement
     | |-PrefixUnaryOperatorExpression
-    | | |-IdExpression
-    | | | `-UnqualifiedId
-    | | |   `-&
+    | | |-&
     | | `-IdExpression
     | |   `-UnqualifiedId
     | |     `-x
@@ -2809,9 +2793,7 @@ void test(X x) {
     | | |-IdExpression
     | | | `-UnqualifiedId
     | | |   `-x
-    | | `-IdExpression
-    | |   `-UnqualifiedId
-    | |     `-++
+    | | `-++
     | `-;
     `-}
 )txt"));


        


More information about the cfe-commits mailing list