diff options
author | Yitzhak Mandelbaum <yitzhakm@google.com> | 2019-10-03 13:01:00 +0000 |
---|---|---|
committer | Yitzhak Mandelbaum <yitzhakm@google.com> | 2019-10-03 13:01:00 +0000 |
commit | e80e8896957402c66aad3514ca9c865268d726b3 (patch) | |
tree | d75c0b31bbab28517c51e285b0ea7d41389a0c2b /clang/lib/Tooling/Refactoring | |
parent | c79099e0f44d0f85515fd30c83923d9d9dc1679b (diff) | |
download | bcm5719-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.cpp | 63 |
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))); |