summaryrefslogtreecommitdiffstats
path: root/clang/lib/Tooling/Refactoring
diff options
context:
space:
mode:
authorYitzhak Mandelbaum <yitzhakm@google.com>2019-10-03 13:01:00 +0000
committerYitzhak Mandelbaum <yitzhakm@google.com>2019-10-03 13:01:00 +0000
commite80e8896957402c66aad3514ca9c865268d726b3 (patch)
treed75c0b31bbab28517c51e285b0ea7d41389a0c2b /clang/lib/Tooling/Refactoring
parentc79099e0f44d0f85515fd30c83923d9d9dc1679b (diff)
downloadbcm5719-llvm-e80e8896957402c66aad3514ca9c865268d726b3.tar.gz
bcm5719-llvm-e80e8896957402c66aad3514ca9c865268d726b3.zip
[libTooling] Add various Stencil combinators for expressions.
Summary: This revision adds three new Stencil combinators: * `expression`, which idiomatically constructs the source for an expression, including wrapping the expression's source in parentheses if needed. * `deref`, which constructs an idiomatic dereferencing expression. * `addressOf`, which constructs an idiomatic address-taking expression. Reviewers: gribozavr Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68315 llvm-svn: 373593
Diffstat (limited to 'clang/lib/Tooling/Refactoring')
-rw-r--r--clang/lib/Tooling/Refactoring/Stencil.cpp63
1 files changed, 62 insertions, 1 deletions
diff --git a/clang/lib/Tooling/Refactoring/Stencil.cpp b/clang/lib/Tooling/Refactoring/Stencil.cpp
index a01b8102338..f7687f91e49 100644
--- a/clang/lib/Tooling/Refactoring/Stencil.cpp
+++ b/clang/lib/Tooling/Refactoring/Stencil.cpp
@@ -24,6 +24,7 @@ using namespace clang;
using namespace tooling;
using ast_matchers::MatchFinder;
+using ast_type_traits::DynTypedNode;
using llvm::errc;
using llvm::Error;
using llvm::Expected;
@@ -37,7 +38,7 @@ template <typename D> const D *down_cast(const StencilPartInterface *P) {
return static_cast<const D *>(P);
}
-static llvm::Expected<ast_type_traits::DynTypedNode>
+static llvm::Expected<DynTypedNode>
getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
auto &NodesMap = Nodes.getMap();
auto It = NodesMap.find(Id);
@@ -60,6 +61,21 @@ struct DebugPrintNodeData {
std::string Id;
};
+// Operators that take a single node Id as an argument.
+enum class UnaryNodeOperator {
+ Parens,
+ Deref,
+ Address,
+};
+
+// Generic container for stencil operations with a (single) node-id argument.
+struct UnaryOperationData {
+ UnaryOperationData(UnaryNodeOperator Op, std::string Id)
+ : Op(Op), Id(std::move(Id)) {}
+ UnaryNodeOperator Op;
+ std::string Id;
+};
+
// The fragment of code corresponding to the selected range.
struct SelectorData {
explicit SelectorData(RangeSelector S) : Selector(std::move(S)) {}
@@ -91,6 +107,10 @@ bool isEqualData(const DebugPrintNodeData &A, const DebugPrintNodeData &B) {
return A.Id == B.Id;
}
+bool isEqualData(const UnaryOperationData &A, const UnaryOperationData &B) {
+ return A.Op == B.Op && A.Id == B.Id;
+}
+
// Equality is not (yet) defined for \c RangeSelector.
bool isEqualData(const SelectorData &, const SelectorData &) { return false; }
@@ -130,6 +150,32 @@ Error evalData(const DebugPrintNodeData &Data,
return Error::success();
}
+Error evalData(const UnaryOperationData &Data,
+ const MatchFinder::MatchResult &Match, std::string *Result) {
+ const auto *E = Match.Nodes.getNodeAs<Expr>(Data.Id);
+ if (E == nullptr)
+ return llvm::make_error<StringError>(
+ errc::invalid_argument, "Id not bound or not Expr: " + Data.Id);
+ llvm::Optional<std::string> Source;
+ switch (Data.Op) {
+ case UnaryNodeOperator::Parens:
+ Source = buildParens(*E, *Match.Context);
+ break;
+ case UnaryNodeOperator::Deref:
+ Source = buildDereference(*E, *Match.Context);
+ break;
+ case UnaryNodeOperator::Address:
+ Source = buildAddressOf(*E, *Match.Context);
+ break;
+ }
+ if (!Source)
+ return llvm::make_error<StringError>(
+ errc::invalid_argument,
+ "Could not construct expression source from ID: " + Data.Id);
+ *Result += *Source;
+ return Error::success();
+}
+
Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match,
std::string *Result) {
auto Range = Data.Selector(Match);
@@ -239,6 +285,21 @@ StencilPart stencil::dPrint(StringRef Id) {
return StencilPart(std::make_shared<StencilPartImpl<DebugPrintNodeData>>(Id));
}
+StencilPart stencil::expression(llvm::StringRef Id) {
+ return StencilPart(std::make_shared<StencilPartImpl<UnaryOperationData>>(
+ UnaryNodeOperator::Parens, Id));
+}
+
+StencilPart stencil::deref(llvm::StringRef ExprId) {
+ return StencilPart(std::make_shared<StencilPartImpl<UnaryOperationData>>(
+ UnaryNodeOperator::Deref, ExprId));
+}
+
+StencilPart stencil::addressOf(llvm::StringRef ExprId) {
+ return StencilPart(std::make_shared<StencilPartImpl<UnaryOperationData>>(
+ UnaryNodeOperator::Address, ExprId));
+}
+
StencilPart stencil::access(StringRef BaseId, StencilPart Member) {
return StencilPart(
std::make_shared<StencilPartImpl<AccessData>>(BaseId, std::move(Member)));
OpenPOWER on IntegriCloud