[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
This revision was automatically updated to reflect the committed changes. ymandel marked an inline comment as done. Closed by commit rG01e8dd2e7a85: [libTooling] Add stencil combinators for nodes that may be pointers or values. (authored by ymandel). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 Files: clang/include/clang/Tooling/Transformer/Stencil.h 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 @@ -233,6 +233,46 @@ testExpr(Id, "int *x; *x;", addressOf(Id), "x"); } +TEST_F(StencilTest, MaybeDerefValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", maybeDeref(Id), "x"); +} + +TEST_F(StencilTest, MaybeDerefPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", maybeDeref(Id), "*x"); +} + +TEST_F(StencilTest, MaybeDerefBinOp) { + StringRef Id = "id"; + testExpr(Id, "int *x; x + 1;", maybeDeref(Id), "*(x + 1)"); +} + +TEST_F(StencilTest, MaybeDerefAddressExpr) { + StringRef Id = "id"; + testExpr(Id, "int x; &x;", maybeDeref(Id), "x"); +} + +TEST_F(StencilTest, MaybeAddressOfPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", maybeAddressOf(Id), "x"); +} + +TEST_F(StencilTest, MaybeAddressOfValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", addressOf(Id), "&x"); +} + +TEST_F(StencilTest, MaybeAddressOfBinOp) { + StringRef Id = "id"; + testExpr(Id, "int x; x + 1;", maybeAddressOf(Id), "&(x + 1)"); +} + +TEST_F(StencilTest, MaybeAddressOfDerefExpr) { + StringRef Id = "id"; + testExpr(Id, "int *x; *x;", addressOf(Id), "x"); +} + TEST_F(StencilTest, AccessOpValue) { StringRef Snippet = R"cc( S x; Index: clang/lib/Tooling/Transformer/Stencil.cpp === --- clang/lib/Tooling/Transformer/Stencil.cpp +++ clang/lib/Tooling/Transformer/Stencil.cpp @@ -59,7 +59,9 @@ enum class UnaryNodeOperator { Parens, Deref, - Address, + MaybeDeref, + AddressOf, + MaybeAddressOf, }; // Generic container for stencil operations with a (single) node-id argument. @@ -121,9 +123,15 @@ case UnaryNodeOperator::Deref: OpName = "deref"; break; - case UnaryNodeOperator::Address: + case UnaryNodeOperator::MaybeDeref: +OpName = "maybeDeref"; +break; + case UnaryNodeOperator::AddressOf: OpName = "addressOf"; break; + case UnaryNodeOperator::MaybeAddressOf: +OpName = "maybeAddressOf"; +break; } return (OpName + "(\"" + Data.Id + "\")").str(); } @@ -191,7 +199,21 @@ case UnaryNodeOperator::Deref: Source = tooling::buildDereference(*E, *Match.Context); break; - case UnaryNodeOperator::Address: + case UnaryNodeOperator::MaybeDeref: +if (!E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} +Source = tooling::buildDereference(*E, *Match.Context); +break; + case UnaryNodeOperator::AddressOf: +Source = tooling::buildAddressOf(*E, *Match.Context); +break; + case UnaryNodeOperator::MaybeAddressOf: +if (E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} Source = tooling::buildAddressOf(*E, *Match.Context); break; } @@ -300,9 +322,19 @@ UnaryNodeOperator::Deref, ExprId); } +Stencil transformer::maybeDeref(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::MaybeDeref, ExprId); +} + Stencil transformer::addressOf(llvm::StringRef ExprId) { return std::make_shared>( - UnaryNodeOperator::Address, ExprId); + UnaryNodeOperator::AddressOf, ExprId); +} + +Stencil transformer::maybeAddressOf(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::MaybeAddressOf, ExprId); } Stencil transformer::access(StringRef BaseId, Stencil Member) { Index: clang/include/clang/Tooling/Transformer/Stencil.h === --- clang/include/clang/Tooling/Transformer/Stencil.h +++ clang/include/clang/Tooling/Transformer/Stencil.h @@ -87,11 +87,24 @@ /// \p ExprId is wrapped in parentheses, if needed. Stencil deref(llvm::StringRef ExprId); +/// If \p ExprId is of pointer type, constructs an idiomatic dereferencing of +/// the expression bound to \p ExprId, including wrapping it in parentheses, if +/// needed. Otherwise, generates the original expression source. +/// FIXME: Identify smart-pointers as pointer types. +Stencil maybeDeref(llvm::StringRef ExprId); + /// Constructs an expression that idiomatically takes the address of the /// expression bound to \p ExprId. \p ExprId is wrapped in parentheses, if /// needed
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
gribozavr2 marked an inline comment as done. gribozavr2 added inline comments. Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:96 +// Constructs an expression that idiomatically represents a value, taking into +// account whether `ExprId` is a pointer or already a value. +Stencil asValue(llvm::StringRef ExprId); ymandel wrote: > gribozavr2 wrote: > > Need more explanation to cover the cases when the expression is a pointer > > to a pointer (do we deref once or twice?), or a smart pointer (do we take > > care of that at all?) > > > > WDYT about calling it `maybeDeref()` or `derefIfPointer()`? > I went with maybe... Given that, I didn't elaborate on pointer-to-pointer > case because it never claims to result in a value. WDYT? > > also, I kind of like derefIfPointer better, but addressOfIfValue just seemed > to clunky. So, went w/ maybe... > Given that, I didn't elaborate on pointer-to-pointer case because it never > claims to result in a value. WDYT? I think it is clear what happens with pointers to pointers given the current doc comment. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
gribozavr2 accepted this revision. gribozavr2 added inline comments. Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:90 +/// If \p ExprId is of pointer type, constructs an idiomatic dereferencing of +/// the expression bound to \p ExprId, including wrapping it in parentheses, if "If the expression \p ExprId has pointer type ..." Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:101 +/// If \p ExprId is not a pointer type, constructs an expression that +/// idiomatically takes the address of the expression bound to \p ExprId, "If the expression \p ExprId is not a pointer, ..." Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
ymandel updated this revision to Diff 230646. ymandel added a comment. renamed combinators; reordered cases to pair x and maybeX. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 Files: clang/include/clang/Tooling/Transformer/Stencil.h 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 @@ -233,6 +233,46 @@ testExpr(Id, "int *x; *x;", addressOf(Id), "x"); } +TEST_F(StencilTest, MaybeDerefValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", maybeDeref(Id), "x"); +} + +TEST_F(StencilTest, MaybeDerefPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", maybeDeref(Id), "*x"); +} + +TEST_F(StencilTest, MaybeDerefBinOp) { + StringRef Id = "id"; + testExpr(Id, "int *x; x + 1;", maybeDeref(Id), "*(x + 1)"); +} + +TEST_F(StencilTest, MaybeDerefAddressExpr) { + StringRef Id = "id"; + testExpr(Id, "int x; &x;", maybeDeref(Id), "x"); +} + +TEST_F(StencilTest, MaybeAddressOfPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", maybeAddressOf(Id), "x"); +} + +TEST_F(StencilTest, MaybeAddressOfValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", addressOf(Id), "&x"); +} + +TEST_F(StencilTest, MaybeAddressOfBinOp) { + StringRef Id = "id"; + testExpr(Id, "int x; x + 1;", maybeAddressOf(Id), "&(x + 1)"); +} + +TEST_F(StencilTest, MaybeAddressOfDerefExpr) { + StringRef Id = "id"; + testExpr(Id, "int *x; *x;", addressOf(Id), "x"); +} + TEST_F(StencilTest, AccessOpValue) { StringRef Snippet = R"cc( S x; Index: clang/lib/Tooling/Transformer/Stencil.cpp === --- clang/lib/Tooling/Transformer/Stencil.cpp +++ clang/lib/Tooling/Transformer/Stencil.cpp @@ -59,7 +59,9 @@ enum class UnaryNodeOperator { Parens, Deref, - Address, + MaybeDeref, + AddressOf, + MaybeAddressOf, }; // Generic container for stencil operations with a (single) node-id argument. @@ -121,9 +123,15 @@ case UnaryNodeOperator::Deref: OpName = "deref"; break; - case UnaryNodeOperator::Address: + case UnaryNodeOperator::MaybeDeref: +OpName = "maybeDeref"; +break; + case UnaryNodeOperator::AddressOf: OpName = "addressOf"; break; + case UnaryNodeOperator::MaybeAddressOf: +OpName = "maybeAddressOf"; +break; } return (OpName + "(\"" + Data.Id + "\")").str(); } @@ -191,7 +199,21 @@ case UnaryNodeOperator::Deref: Source = tooling::buildDereference(*E, *Match.Context); break; - case UnaryNodeOperator::Address: + case UnaryNodeOperator::MaybeDeref: +if (!E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} +Source = tooling::buildDereference(*E, *Match.Context); +break; + case UnaryNodeOperator::AddressOf: +Source = tooling::buildAddressOf(*E, *Match.Context); +break; + case UnaryNodeOperator::MaybeAddressOf: +if (E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} Source = tooling::buildAddressOf(*E, *Match.Context); break; } @@ -300,9 +322,19 @@ UnaryNodeOperator::Deref, ExprId); } +Stencil transformer::maybeDeref(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::MaybeDeref, ExprId); +} + Stencil transformer::addressOf(llvm::StringRef ExprId) { return std::make_shared>( - UnaryNodeOperator::Address, ExprId); + UnaryNodeOperator::AddressOf, ExprId); +} + +Stencil transformer::maybeAddressOf(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::MaybeAddressOf, ExprId); } Stencil transformer::access(StringRef BaseId, Stencil Member) { Index: clang/include/clang/Tooling/Transformer/Stencil.h === --- clang/include/clang/Tooling/Transformer/Stencil.h +++ clang/include/clang/Tooling/Transformer/Stencil.h @@ -87,11 +87,24 @@ /// \p ExprId is wrapped in parentheses, if needed. Stencil deref(llvm::StringRef ExprId); +/// If \p ExprId is of pointer type, constructs an idiomatic dereferencing of +/// the expression bound to \p ExprId, including wrapping it in parentheses, if +/// needed. Otherwise, generates the original expression source. +/// FIXME: Identify smart points as pointer types. +Stencil maybeDeref(llvm::StringRef ExprId); + /// Constructs an expression that idiomatically takes the address of the /// expression bound to \p ExprId. \p ExprId is wrapped in parentheses, if /// needed. Stencil addressOf(llvm::StringRef ExprId); +/// If \p ExprId is not a pointer type, constructs an expression that +//
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
ymandel marked 5 inline comments as done. ymandel added a comment. Thanks for the review! Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:96 +// Constructs an expression that idiomatically represents a value, taking into +// account whether `ExprId` is a pointer or already a value. +Stencil asValue(llvm::StringRef ExprId); gribozavr2 wrote: > Need more explanation to cover the cases when the expression is a pointer to > a pointer (do we deref once or twice?), or a smart pointer (do we take care > of that at all?) > > WDYT about calling it `maybeDeref()` or `derefIfPointer()`? I went with maybe... Given that, I didn't elaborate on pointer-to-pointer case because it never claims to result in a value. WDYT? also, I kind of like derefIfPointer better, but addressOfIfValue just seemed to clunky. So, went w/ maybe... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
ymandel updated this revision to Diff 230647. ymandel added a comment. fix typo Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 Files: clang/include/clang/Tooling/Transformer/Stencil.h 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 @@ -233,6 +233,46 @@ testExpr(Id, "int *x; *x;", addressOf(Id), "x"); } +TEST_F(StencilTest, MaybeDerefValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", maybeDeref(Id), "x"); +} + +TEST_F(StencilTest, MaybeDerefPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", maybeDeref(Id), "*x"); +} + +TEST_F(StencilTest, MaybeDerefBinOp) { + StringRef Id = "id"; + testExpr(Id, "int *x; x + 1;", maybeDeref(Id), "*(x + 1)"); +} + +TEST_F(StencilTest, MaybeDerefAddressExpr) { + StringRef Id = "id"; + testExpr(Id, "int x; &x;", maybeDeref(Id), "x"); +} + +TEST_F(StencilTest, MaybeAddressOfPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", maybeAddressOf(Id), "x"); +} + +TEST_F(StencilTest, MaybeAddressOfValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", addressOf(Id), "&x"); +} + +TEST_F(StencilTest, MaybeAddressOfBinOp) { + StringRef Id = "id"; + testExpr(Id, "int x; x + 1;", maybeAddressOf(Id), "&(x + 1)"); +} + +TEST_F(StencilTest, MaybeAddressOfDerefExpr) { + StringRef Id = "id"; + testExpr(Id, "int *x; *x;", addressOf(Id), "x"); +} + TEST_F(StencilTest, AccessOpValue) { StringRef Snippet = R"cc( S x; Index: clang/lib/Tooling/Transformer/Stencil.cpp === --- clang/lib/Tooling/Transformer/Stencil.cpp +++ clang/lib/Tooling/Transformer/Stencil.cpp @@ -59,7 +59,9 @@ enum class UnaryNodeOperator { Parens, Deref, - Address, + MaybeDeref, + AddressOf, + MaybeAddressOf, }; // Generic container for stencil operations with a (single) node-id argument. @@ -121,9 +123,15 @@ case UnaryNodeOperator::Deref: OpName = "deref"; break; - case UnaryNodeOperator::Address: + case UnaryNodeOperator::MaybeDeref: +OpName = "maybeDeref"; +break; + case UnaryNodeOperator::AddressOf: OpName = "addressOf"; break; + case UnaryNodeOperator::MaybeAddressOf: +OpName = "maybeAddressOf"; +break; } return (OpName + "(\"" + Data.Id + "\")").str(); } @@ -191,7 +199,21 @@ case UnaryNodeOperator::Deref: Source = tooling::buildDereference(*E, *Match.Context); break; - case UnaryNodeOperator::Address: + case UnaryNodeOperator::MaybeDeref: +if (!E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} +Source = tooling::buildDereference(*E, *Match.Context); +break; + case UnaryNodeOperator::AddressOf: +Source = tooling::buildAddressOf(*E, *Match.Context); +break; + case UnaryNodeOperator::MaybeAddressOf: +if (E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} Source = tooling::buildAddressOf(*E, *Match.Context); break; } @@ -300,9 +322,19 @@ UnaryNodeOperator::Deref, ExprId); } +Stencil transformer::maybeDeref(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::MaybeDeref, ExprId); +} + Stencil transformer::addressOf(llvm::StringRef ExprId) { return std::make_shared>( - UnaryNodeOperator::Address, ExprId); + UnaryNodeOperator::AddressOf, ExprId); +} + +Stencil transformer::maybeAddressOf(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::MaybeAddressOf, ExprId); } Stencil transformer::access(StringRef BaseId, Stencil Member) { Index: clang/include/clang/Tooling/Transformer/Stencil.h === --- clang/include/clang/Tooling/Transformer/Stencil.h +++ clang/include/clang/Tooling/Transformer/Stencil.h @@ -87,11 +87,24 @@ /// \p ExprId is wrapped in parentheses, if needed. Stencil deref(llvm::StringRef ExprId); +/// If \p ExprId is of pointer type, constructs an idiomatic dereferencing of +/// the expression bound to \p ExprId, including wrapping it in parentheses, if +/// needed. Otherwise, generates the original expression source. +/// FIXME: Identify smart-pointers as pointer types. +Stencil maybeDeref(llvm::StringRef ExprId); + /// Constructs an expression that idiomatically takes the address of the /// expression bound to \p ExprId. \p ExprId is wrapped in parentheses, if /// needed. Stencil addressOf(llvm::StringRef ExprId); +/// If \p ExprId is not a pointer type, constructs an expression that +/// idiomatically takes the address of the express
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
gribozavr2 accepted this revision. gribozavr2 added inline comments. This revision is now accepted and ready to land. Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:95 +// Constructs an expression that idiomatically represents a value, taking into +// account whether `ExprId` is a pointer or already a value. Three slashes, please. Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:96 +// Constructs an expression that idiomatically represents a value, taking into +// account whether `ExprId` is a pointer or already a value. +Stencil asValue(llvm::StringRef ExprId); Need more explanation to cover the cases when the expression is a pointer to a pointer (do we deref once or twice?), or a smart pointer (do we take care of that at all?) WDYT about calling it `maybeDeref()` or `derefIfPointer()`? Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:99 + +// Constructs an expression that idiomatically represents a pointer, taking into +// account whether `ExprId` is a value or already a pointer. Three slashes, please. Comment at: clang/include/clang/Tooling/Transformer/Stencil.h:101 +// account whether `ExprId` is a value or already a pointer. +Stencil asPointer(llvm::StringRef ExprId); + Similarly, `maybeAddressOf()`? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70554/new/ https://reviews.llvm.org/D70554 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.
ymandel created this revision. ymandel added a reviewer: gribozavr. Herald added a project: clang. Adds combinators `asValue` and `asPointer` to provide a uniform way to handle nodes which may be bound to either a pointer or a value (most often in the context of member expressions). Such polymorphism is already supported by `access`; these combinators extend it to more general uses. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D70554 Files: clang/include/clang/Tooling/Transformer/Stencil.h 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 @@ -233,6 +233,46 @@ testExpr(Id, "int *x; *x;", addressOf(Id), "x"); } +TEST_F(StencilTest, AsValueValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", asValue(Id), "x"); +} + +TEST_F(StencilTest, AsValuePointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", asValue(Id), "*x"); +} + +TEST_F(StencilTest, AsValueBinOp) { + StringRef Id = "id"; + testExpr(Id, "int *x; x + 1;", asValue(Id), "*(x + 1)"); +} + +TEST_F(StencilTest, AsValueAddressExpr) { + StringRef Id = "id"; + testExpr(Id, "int x; &x;", asValue(Id), "x"); +} + +TEST_F(StencilTest, AsPointerPointer) { + StringRef Id = "id"; + testExpr(Id, "int *x; x;", asPointer(Id), "x"); +} + +TEST_F(StencilTest, AsPointerValue) { + StringRef Id = "id"; + testExpr(Id, "int x; x;", addressOf(Id), "&x"); +} + +TEST_F(StencilTest, AsPointerBinOp) { + StringRef Id = "id"; + testExpr(Id, "int x; x + 1;", asPointer(Id), "&(x + 1)"); +} + +TEST_F(StencilTest, AsPointerDerefExpr) { + StringRef Id = "id"; + testExpr(Id, "int *x; *x;", addressOf(Id), "x"); +} + TEST_F(StencilTest, AccessOpValue) { StringRef Snippet = R"cc( S x; Index: clang/lib/Tooling/Transformer/Stencil.cpp === --- clang/lib/Tooling/Transformer/Stencil.cpp +++ clang/lib/Tooling/Transformer/Stencil.cpp @@ -60,6 +60,8 @@ Parens, Deref, Address, + AsValue, + AsPointer, }; // Generic container for stencil operations with a (single) node-id argument. @@ -124,6 +126,12 @@ case UnaryNodeOperator::Address: OpName = "addressOf"; break; + case UnaryNodeOperator::AsValue: +OpName = "asValue"; +break; + case UnaryNodeOperator::AsPointer: +OpName = "asPointer"; +break; } return (OpName + "(\"" + Data.Id + "\")").str(); } @@ -194,6 +202,21 @@ case UnaryNodeOperator::Address: Source = tooling::buildAddressOf(*E, *Match.Context); break; + case UnaryNodeOperator::AsValue: +if (!E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} +Source = tooling::buildDereference(*E, *Match.Context); +break; + + case UnaryNodeOperator::AsPointer: +if (E->getType()->isAnyPointerType()) { + *Result += tooling::getText(*E, *Match.Context); + return Error::success(); +} +Source = tooling::buildAddressOf(*E, *Match.Context); +break; } if (!Source) return llvm::make_error( @@ -305,6 +328,16 @@ UnaryNodeOperator::Address, ExprId); } +Stencil transformer::asValue(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::AsValue, ExprId); +} + +Stencil transformer::asPointer(llvm::StringRef ExprId) { + return std::make_shared>( + UnaryNodeOperator::AsPointer, ExprId); +} + Stencil transformer::access(StringRef BaseId, Stencil Member) { return std::make_shared>(BaseId, std::move(Member)); } Index: clang/include/clang/Tooling/Transformer/Stencil.h === --- clang/include/clang/Tooling/Transformer/Stencil.h +++ clang/include/clang/Tooling/Transformer/Stencil.h @@ -92,6 +92,14 @@ /// needed. Stencil addressOf(llvm::StringRef ExprId); +// Constructs an expression that idiomatically represents a value, taking into +// account whether `ExprId` is a pointer or already a value. +Stencil asValue(llvm::StringRef ExprId); + +// Constructs an expression that idiomatically represents a pointer, taking into +// account whether `ExprId` is a value or already a pointer. +Stencil asPointer(llvm::StringRef ExprId); + /// Constructs a `MemberExpr` that accesses the named member (\p Member) of the /// object bound to \p BaseId. The access is constructed idiomatically: if \p /// BaseId is bound to `e` and \p Member identifies member `m`, then returns ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits