[clang] 1c57172 - [libTooling] Add smart pointer support to the `access` Stencil

Shu-Chun Weng via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 14 10:46:24 PDT 2021


Author: Shu-Chun Weng
Date: 2021-04-14T10:45:59-07:00
New Revision: 1c5717225e89d4b266784f1a1fe482530bc4b6f2

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

LOG: [libTooling] Add smart pointer support to the `access` Stencil

This extends smart pointer support beyond the existing `maybeDeref` and
`maybeAddressOf`.

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

Added: 
    

Modified: 
    clang/lib/Tooling/Transformer/Stencil.cpp
    clang/unittests/Tooling/StencilTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Tooling/Transformer/Stencil.cpp b/clang/lib/Tooling/Transformer/Stencil.cpp
index d46087e4b04bc..235473b691878 100644
--- a/clang/lib/Tooling/Transformer/Stencil.cpp
+++ b/clang/lib/Tooling/Transformer/Stencil.cpp
@@ -323,10 +323,23 @@ Error evalData(const AccessData &Data, const MatchFinder::MatchResult &Match,
     return llvm::make_error<StringError>(errc::invalid_argument,
                                          "Id not bound: " + Data.BaseId);
   if (!E->isImplicitCXXThis()) {
-    if (llvm::Optional<std::string> S =
-            E->getType()->isAnyPointerType()
-                ? tooling::buildArrow(*E, *Match.Context)
-                : tooling::buildDot(*E, *Match.Context))
+    llvm::Optional<std::string> S;
+    if (E->getType()->isAnyPointerType() ||
+        isSmartPointerType(E->getType(), *Match.Context)) {
+      // Strip off any operator->. This can only occur inside an actual arrow
+      // member access, so we treat it as equivalent to an actual object
+      // expression.
+      if (const auto *OpCall = dyn_cast<clang::CXXOperatorCallExpr>(E)) {
+        if (OpCall->getOperator() == clang::OO_Arrow &&
+            OpCall->getNumArgs() == 1) {
+          E = OpCall->getArg(0);
+        }
+      }
+      S = tooling::buildArrow(*E, *Match.Context);
+    } else {
+      S = tooling::buildDot(*E, *Match.Context);
+    }
+    if (S.hasValue())
       *Result += *S;
     else
       return llvm::make_error<StringError>(

diff  --git a/clang/unittests/Tooling/StencilTest.cpp b/clang/unittests/Tooling/StencilTest.cpp
index 2333319339014..df05e6deeb577 100644
--- a/clang/unittests/Tooling/StencilTest.cpp
+++ b/clang/unittests/Tooling/StencilTest.cpp
@@ -392,6 +392,37 @@ TEST_F(StencilTest, AccessOpPointerDereference) {
   testExpr(Id, Snippet, access(Id, "field"), "x->field");
 }
 
+TEST_F(StencilTest, AccessOpSmartPointer) {
+  StringRef Snippet = R"cc(
+    Smart x;
+    x;
+  )cc";
+  StringRef Id = "id";
+  testExpr(Id, Snippet, access(Id, "field"), "x->field");
+}
+
+TEST_F(StencilTest, AccessOpSmartPointerDereference) {
+  StringRef Snippet = R"cc(
+    Smart x;
+    *x;
+  )cc";
+  StringRef Id = "id";
+  testExpr(Id, Snippet, access(Id, "field"), "(*x).field");
+}
+
+TEST_F(StencilTest, AccessOpSmartPointerMemberCall) {
+  StringRef Snippet = R"cc(
+    Smart x;
+    x->Field;
+  )cc";
+  StringRef Id = "id";
+  auto StmtMatch =
+      matchStmt(Snippet, memberExpr(hasObjectExpression(expr().bind(Id))));
+  ASSERT_TRUE(StmtMatch);
+  EXPECT_THAT_EXPECTED(access(Id, "field")->eval(StmtMatch->Result),
+                       HasValue("x->field"));
+}
+
 TEST_F(StencilTest, AccessOpExplicitThis) {
   using clang::ast_matchers::hasObjectExpression;
   using clang::ast_matchers::memberExpr;


        


More information about the cfe-commits mailing list