[PATCH] D70554: [libTooling] Add stencil combinators for nodes that may be pointers or values.

2019-11-22 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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.

2019-11-22 Thread Dmitri Gribenko via Phabricator via cfe-commits
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.

2019-11-22 Thread Dmitri Gribenko via Phabricator via cfe-commits
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.

2019-11-22 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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.

2019-11-22 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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.

2019-11-22 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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.

2019-11-22 Thread Dmitri Gribenko via Phabricator via cfe-commits
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.

2019-11-21 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
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