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); }
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); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits