[clang] 85c15f1 - [SyntaxTree] Add support for `this`

Eduardo Caldas via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 21 01:01:41 PDT 2020


Author: Eduardo Caldas
Date: 2020-08-21T08:01:29Z
New Revision: 85c15f17cc684b35cdb4a5f3a76d45160de7b597

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

LOG: [SyntaxTree] Add support for `this`

Differential Revision: https://reviews.llvm.org/D86298

Added: 
    

Modified: 
    clang/include/clang/Tooling/Syntax/Nodes.h
    clang/lib/Tooling/Syntax/BuildTree.cpp
    clang/lib/Tooling/Syntax/Nodes.cpp
    clang/unittests/Tooling/Syntax/BuildTreeTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h
index 8b499bc5ceb9..0b3991768008 100644
--- a/clang/include/clang/Tooling/Syntax/Nodes.h
+++ b/clang/include/clang/Tooling/Syntax/Nodes.h
@@ -56,6 +56,7 @@ enum class NodeKind : uint16_t {
   StringUserDefinedLiteralExpression,
   IdExpression,
   MemberExpression,
+  ThisExpression,
 
   // Statements.
   UnknownStatement,
@@ -313,6 +314,16 @@ class UnknownExpression final : public Expression {
   }
 };
 
+/// Models a this expression `this`. C++ [expr.prim.this]
+class ThisExpression final : public Expression {
+public:
+  ThisExpression() : Expression(NodeKind::ThisExpression) {}
+  static bool classof(const Node *N) {
+    return N->kind() == NodeKind::ThisExpression;
+  }
+  Leaf *thisKeyword();
+};
+
 /// Models a parenthesized expression `(E)`. C++ [expr.prim.paren]
 /// e.g. `(3 + 2)` in `a = 1 + (3 + 2);`
 class ParenExpression final : public Expression {

diff  --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 37d29a270463..3ab52ce5b7b4 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -950,6 +950,16 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
     return true;
   }
 
+  bool WalkUpFromCXXThisExpr(CXXThisExpr *S) {
+    if (!S->isImplicit()) {
+      Builder.markChildToken(S->getLocation(),
+                             syntax::NodeRole::IntroducerKeyword);
+      Builder.foldNode(Builder.getExprRange(S),
+                       new (allocator()) syntax::ThisExpression, S);
+    }
+    return true;
+  }
+
   bool WalkUpFromParenExpr(ParenExpr *S) {
     Builder.markChildToken(S->getLParen(), syntax::NodeRole::OpenParen);
     Builder.markExprChild(S->getSubExpr(),

diff  --git a/clang/lib/Tooling/Syntax/Nodes.cpp b/clang/lib/Tooling/Syntax/Nodes.cpp
index e09c8f20f210..ecd4c4dac728 100644
--- a/clang/lib/Tooling/Syntax/Nodes.cpp
+++ b/clang/lib/Tooling/Syntax/Nodes.cpp
@@ -20,6 +20,8 @@ raw_ostream &syntax::operator<<(raw_ostream &OS, NodeKind K) {
     return OS << "UnknownExpression";
   case NodeKind::ParenExpression:
     return OS << "ParenExpression";
+  case NodeKind::ThisExpression:
+    return OS << "ThisExpression";
   case NodeKind::IntegerLiteralExpression:
     return OS << "IntegerLiteralExpression";
   case NodeKind::CharacterLiteralExpression:
@@ -286,6 +288,11 @@ syntax::Leaf *syntax::ParenExpression::closeParen() {
   return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::CloseParen));
 }
 
+syntax::Leaf *syntax::ThisExpression::thisKeyword() {
+  return cast_or_null<syntax::Leaf>(
+      findChild(syntax::NodeRole::IntroducerKeyword));
+}
+
 syntax::Leaf *syntax::LiteralExpression::literalToken() {
   return cast_or_null<syntax::Leaf>(findChild(syntax::NodeRole::LiteralToken));
 }

diff  --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
index a3e86dac50c5..d4e2684934f3 100644
--- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
+++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp
@@ -905,6 +905,68 @@ UnknownExpression
 )txt"}));
 }
 
+TEST_P(SyntaxTreeTest, This_Simple) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+      R"cpp(
+struct S {
+  S* test(){
+    return [[this]];
+  }
+};
+)cpp",
+      {R"txt(
+ThisExpression
+`-this
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, This_ExplicitMemberAccess) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+      R"cpp(
+struct S {
+  int a;
+  void test(){
+    [[this->a]];
+  }
+};
+)cpp",
+      {R"txt(
+MemberExpression
+|-ThisExpression
+| `-this
+|-->
+`-IdExpression
+  `-UnqualifiedId
+    `-a
+)txt"}));
+}
+
+TEST_P(SyntaxTreeTest, This_ImplicitMemberAccess) {
+  if (!GetParam().isCXX()) {
+    return;
+  }
+  EXPECT_TRUE(treeDumpEqualOnAnnotations(
+      R"cpp(
+struct S {
+  int a;
+  void test(){
+    [[a]];
+  }
+};
+)cpp",
+      {R"txt(
+IdExpression
+`-UnqualifiedId
+  `-a
+)txt"}));
+}
+
 TEST_P(SyntaxTreeTest, ParenExpr) {
   EXPECT_TRUE(treeDumpEqualOnAnnotations(
       R"cpp(
@@ -2099,29 +2161,6 @@ UnknownExpression
 )txt"}));
 }
 
-TEST_P(SyntaxTreeTest, MemberExpression_Implicit) {
-  if (!GetParam().isCXX()) {
-    return;
-  }
-  EXPECT_TRUE(treeDumpEqualOnAnnotations(
-      R"cpp(
-struct S {
-  int a;
-  int test(){
-    // FIXME: Remove the `UnknownExpression` wrapping `a`. This
-    // `UnknownExpression` comes from an implicit leaf `CXXThisExpr`.
-    [[a]];
-  }
-};
-)cpp",
-      {R"txt(
-IdExpression
-`-UnqualifiedId
-  `-UnknownExpression
-    `-a
-)txt"}));
-}
-
 TEST_P(SyntaxTreeTest, MemberExpression_VariableTemplate) {
   if (!GetParam().isCXX14OrLater()) {
     return;


        


More information about the cfe-commits mailing list