[PATCH] D104390: [libTooling] Change `access` stencil to recognize use of `operator*`.

Yitzhak Mandelbaum via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 16 08:30:20 PDT 2021


ymandel created this revision.
ymandel added a reviewer: gribozavr2.
ymandel requested review of this revision.
Herald added a project: clang.

Currently, `access` doesn't recognize a dereferenced smart pointer. So,
`access(e, "field")` where `e = *x`, yields:

- `x->field`, for normal-pointer x,
- `(*x).field`, for smart-pointer x.

This patch normalizes handling of smart pointer to match normal pointer, when
the smart pointer type supports `->`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104390

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


Index: clang/unittests/Tooling/StencilTest.cpp
===================================================================
--- clang/unittests/Tooling/StencilTest.cpp
+++ clang/unittests/Tooling/StencilTest.cpp
@@ -407,7 +407,7 @@
     *x;
   )cc";
   StringRef Id = "id";
-  testExpr(Id, Snippet, access(Id, "field"), "(*x).field");
+  testExpr(Id, Snippet, access(Id, "field"), "x->field");
 }
 
 TEST_F(StencilTest, AccessOpSmartPointerMemberCall) {
Index: clang/lib/Tooling/Transformer/Stencil.cpp
===================================================================
--- clang/lib/Tooling/Transformer/Stencil.cpp
+++ clang/lib/Tooling/Transformer/Stencil.cpp
@@ -73,6 +73,25 @@
   return match(SmartPointer, Ty, Context).size() > 0;
 }
 
+static const Expr *isDereference(const Expr &E, ASTContext &Context) {
+  using namespace ::clang::ast_matchers;
+
+  const auto HasOverloadedArrow = cxxRecordDecl(hasMethod(cxxMethodDecl(
+      hasOverloadedOperatorName("->"), returns(qualType(pointsTo(type()))))));
+  auto Deref = expr(anyOf(
+      cxxOperatorCallExpr(hasOverloadedOperatorName("*"),
+                          // FIXME: Use `hasUnaryOperand` once bug in
+                          // `equivalentUnaryOperand` is fixed.
+                          // hasArgument(0, expr().bind("arg"))
+                          hasUnaryOperand(expr().bind("arg")),
+                          callee(cxxMethodDecl(ofClass(HasOverloadedArrow)))),
+      unaryOperator(hasOperatorName("*"),
+                    hasUnaryOperand(expr().bind("arg")))));
+  auto matches = match(Deref, E, Context);
+  llvm::errs() << "num matches = " << matches.size() << "\n";
+  return selectFirst<Expr>("arg", matches);
+}
+
 namespace {
 // An arbitrary fragment of code within a stencil.
 class RawTextStencil : public StencilInterface {
@@ -309,6 +328,8 @@
           }
         }
         S = tooling::buildArrow(*E, *Match.Context);
+      } else if (const auto *Operand = isDereference(*E, *Match.Context)) {
+        S = tooling::buildArrow(*Operand, *Match.Context);
       } else {
         S = tooling::buildDot(*E, *Match.Context);
       }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D104390.352449.patch
Type: text/x-patch
Size: 2123 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210616/49719a2d/attachment-0001.bin>


More information about the cfe-commits mailing list