annotate clang/lib/Tooling/Transformer/Stencil.cpp @ 180:680fa57a2f20

fix compile errors.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 30 May 2020 17:44:06 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===--- Stencil.cpp - Stencil implementation -------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "clang/Tooling/Transformer/Stencil.h"
anatofuz
parents:
diff changeset
10 #include "clang/AST/ASTContext.h"
anatofuz
parents:
diff changeset
11 #include "clang/AST/ASTTypeTraits.h"
anatofuz
parents:
diff changeset
12 #include "clang/AST/Expr.h"
anatofuz
parents:
diff changeset
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
anatofuz
parents:
diff changeset
14 #include "clang/ASTMatchers/ASTMatchers.h"
anatofuz
parents:
diff changeset
15 #include "clang/Lex/Lexer.h"
anatofuz
parents:
diff changeset
16 #include "clang/Tooling/Transformer/SourceCode.h"
anatofuz
parents:
diff changeset
17 #include "clang/Tooling/Transformer/SourceCodeBuilders.h"
anatofuz
parents:
diff changeset
18 #include "llvm/ADT/SmallVector.h"
anatofuz
parents:
diff changeset
19 #include "llvm/ADT/Twine.h"
anatofuz
parents:
diff changeset
20 #include "llvm/Support/Errc.h"
anatofuz
parents:
diff changeset
21 #include <atomic>
anatofuz
parents:
diff changeset
22 #include <memory>
anatofuz
parents:
diff changeset
23 #include <string>
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 using namespace clang;
anatofuz
parents:
diff changeset
26 using namespace transformer;
anatofuz
parents:
diff changeset
27
anatofuz
parents:
diff changeset
28 using ast_matchers::MatchFinder;
anatofuz
parents:
diff changeset
29 using llvm::errc;
anatofuz
parents:
diff changeset
30 using llvm::Error;
anatofuz
parents:
diff changeset
31 using llvm::Expected;
anatofuz
parents:
diff changeset
32 using llvm::StringError;
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 static llvm::Expected<DynTypedNode>
anatofuz
parents:
diff changeset
35 getNode(const ast_matchers::BoundNodes &Nodes, StringRef Id) {
anatofuz
parents:
diff changeset
36 auto &NodesMap = Nodes.getMap();
anatofuz
parents:
diff changeset
37 auto It = NodesMap.find(Id);
anatofuz
parents:
diff changeset
38 if (It == NodesMap.end())
anatofuz
parents:
diff changeset
39 return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
anatofuz
parents:
diff changeset
40 "Id not bound: " + Id);
anatofuz
parents:
diff changeset
41 return It->second;
anatofuz
parents:
diff changeset
42 }
anatofuz
parents:
diff changeset
43
anatofuz
parents:
diff changeset
44 namespace {
anatofuz
parents:
diff changeset
45 // An arbitrary fragment of code within a stencil.
anatofuz
parents:
diff changeset
46 struct RawTextData {
anatofuz
parents:
diff changeset
47 explicit RawTextData(std::string T) : Text(std::move(T)) {}
anatofuz
parents:
diff changeset
48 std::string Text;
anatofuz
parents:
diff changeset
49 };
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 // A debugging operation to dump the AST for a particular (bound) AST node.
anatofuz
parents:
diff changeset
52 struct DebugPrintNodeData {
anatofuz
parents:
diff changeset
53 explicit DebugPrintNodeData(std::string S) : Id(std::move(S)) {}
anatofuz
parents:
diff changeset
54 std::string Id;
anatofuz
parents:
diff changeset
55 };
anatofuz
parents:
diff changeset
56
anatofuz
parents:
diff changeset
57 // Operators that take a single node Id as an argument.
anatofuz
parents:
diff changeset
58 enum class UnaryNodeOperator {
anatofuz
parents:
diff changeset
59 Parens,
anatofuz
parents:
diff changeset
60 Deref,
anatofuz
parents:
diff changeset
61 MaybeDeref,
anatofuz
parents:
diff changeset
62 AddressOf,
anatofuz
parents:
diff changeset
63 MaybeAddressOf,
anatofuz
parents:
diff changeset
64 };
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 // Generic container for stencil operations with a (single) node-id argument.
anatofuz
parents:
diff changeset
67 struct UnaryOperationData {
anatofuz
parents:
diff changeset
68 UnaryOperationData(UnaryNodeOperator Op, std::string Id)
anatofuz
parents:
diff changeset
69 : Op(Op), Id(std::move(Id)) {}
anatofuz
parents:
diff changeset
70 UnaryNodeOperator Op;
anatofuz
parents:
diff changeset
71 std::string Id;
anatofuz
parents:
diff changeset
72 };
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 // The fragment of code corresponding to the selected range.
anatofuz
parents:
diff changeset
75 struct SelectorData {
anatofuz
parents:
diff changeset
76 explicit SelectorData(RangeSelector S) : Selector(std::move(S)) {}
anatofuz
parents:
diff changeset
77 RangeSelector Selector;
anatofuz
parents:
diff changeset
78 };
anatofuz
parents:
diff changeset
79
anatofuz
parents:
diff changeset
80 // A stencil operation to build a member access `e.m` or `e->m`, as appropriate.
anatofuz
parents:
diff changeset
81 struct AccessData {
anatofuz
parents:
diff changeset
82 AccessData(StringRef BaseId, Stencil Member)
anatofuz
parents:
diff changeset
83 : BaseId(std::string(BaseId)), Member(std::move(Member)) {}
anatofuz
parents:
diff changeset
84 std::string BaseId;
anatofuz
parents:
diff changeset
85 Stencil Member;
anatofuz
parents:
diff changeset
86 };
anatofuz
parents:
diff changeset
87
anatofuz
parents:
diff changeset
88 struct IfBoundData {
anatofuz
parents:
diff changeset
89 IfBoundData(StringRef Id, Stencil TrueStencil, Stencil FalseStencil)
anatofuz
parents:
diff changeset
90 : Id(std::string(Id)), TrueStencil(std::move(TrueStencil)),
anatofuz
parents:
diff changeset
91 FalseStencil(std::move(FalseStencil)) {}
anatofuz
parents:
diff changeset
92 std::string Id;
anatofuz
parents:
diff changeset
93 Stencil TrueStencil;
anatofuz
parents:
diff changeset
94 Stencil FalseStencil;
anatofuz
parents:
diff changeset
95 };
anatofuz
parents:
diff changeset
96
anatofuz
parents:
diff changeset
97 struct SequenceData {
anatofuz
parents:
diff changeset
98 SequenceData(std::vector<Stencil> Stencils) : Stencils(std::move(Stencils)) {}
anatofuz
parents:
diff changeset
99 std::vector<Stencil> Stencils;
anatofuz
parents:
diff changeset
100 };
anatofuz
parents:
diff changeset
101
anatofuz
parents:
diff changeset
102 std::string toStringData(const RawTextData &Data) {
anatofuz
parents:
diff changeset
103 std::string Result;
anatofuz
parents:
diff changeset
104 llvm::raw_string_ostream OS(Result);
anatofuz
parents:
diff changeset
105 OS << "\"";
anatofuz
parents:
diff changeset
106 OS.write_escaped(Data.Text);
anatofuz
parents:
diff changeset
107 OS << "\"";
anatofuz
parents:
diff changeset
108 OS.flush();
anatofuz
parents:
diff changeset
109 return Result;
anatofuz
parents:
diff changeset
110 }
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 std::string toStringData(const DebugPrintNodeData &Data) {
anatofuz
parents:
diff changeset
113 return (llvm::Twine("dPrint(\"") + Data.Id + "\")").str();
anatofuz
parents:
diff changeset
114 }
anatofuz
parents:
diff changeset
115
anatofuz
parents:
diff changeset
116 std::string toStringData(const UnaryOperationData &Data) {
anatofuz
parents:
diff changeset
117 StringRef OpName;
anatofuz
parents:
diff changeset
118 switch (Data.Op) {
anatofuz
parents:
diff changeset
119 case UnaryNodeOperator::Parens:
anatofuz
parents:
diff changeset
120 OpName = "expression";
anatofuz
parents:
diff changeset
121 break;
anatofuz
parents:
diff changeset
122 case UnaryNodeOperator::Deref:
anatofuz
parents:
diff changeset
123 OpName = "deref";
anatofuz
parents:
diff changeset
124 break;
anatofuz
parents:
diff changeset
125 case UnaryNodeOperator::MaybeDeref:
anatofuz
parents:
diff changeset
126 OpName = "maybeDeref";
anatofuz
parents:
diff changeset
127 break;
anatofuz
parents:
diff changeset
128 case UnaryNodeOperator::AddressOf:
anatofuz
parents:
diff changeset
129 OpName = "addressOf";
anatofuz
parents:
diff changeset
130 break;
anatofuz
parents:
diff changeset
131 case UnaryNodeOperator::MaybeAddressOf:
anatofuz
parents:
diff changeset
132 OpName = "maybeAddressOf";
anatofuz
parents:
diff changeset
133 break;
anatofuz
parents:
diff changeset
134 }
anatofuz
parents:
diff changeset
135 return (OpName + "(\"" + Data.Id + "\")").str();
anatofuz
parents:
diff changeset
136 }
anatofuz
parents:
diff changeset
137
anatofuz
parents:
diff changeset
138 std::string toStringData(const SelectorData &) { return "selection(...)"; }
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 std::string toStringData(const AccessData &Data) {
anatofuz
parents:
diff changeset
141 return (llvm::Twine("access(\"") + Data.BaseId + "\", " +
anatofuz
parents:
diff changeset
142 Data.Member->toString() + ")")
anatofuz
parents:
diff changeset
143 .str();
anatofuz
parents:
diff changeset
144 }
anatofuz
parents:
diff changeset
145
anatofuz
parents:
diff changeset
146 std::string toStringData(const IfBoundData &Data) {
anatofuz
parents:
diff changeset
147 return (llvm::Twine("ifBound(\"") + Data.Id + "\", " +
anatofuz
parents:
diff changeset
148 Data.TrueStencil->toString() + ", " + Data.FalseStencil->toString() +
anatofuz
parents:
diff changeset
149 ")")
anatofuz
parents:
diff changeset
150 .str();
anatofuz
parents:
diff changeset
151 }
anatofuz
parents:
diff changeset
152
anatofuz
parents:
diff changeset
153 std::string toStringData(const MatchConsumer<std::string> &) {
anatofuz
parents:
diff changeset
154 return "run(...)";
anatofuz
parents:
diff changeset
155 }
anatofuz
parents:
diff changeset
156
anatofuz
parents:
diff changeset
157 std::string toStringData(const SequenceData &Data) {
anatofuz
parents:
diff changeset
158 llvm::SmallVector<std::string, 2> Parts;
anatofuz
parents:
diff changeset
159 Parts.reserve(Data.Stencils.size());
anatofuz
parents:
diff changeset
160 for (const auto &S : Data.Stencils)
anatofuz
parents:
diff changeset
161 Parts.push_back(S->toString());
anatofuz
parents:
diff changeset
162 return (llvm::Twine("seq(") + llvm::join(Parts, ", ") + ")").str();
anatofuz
parents:
diff changeset
163 }
anatofuz
parents:
diff changeset
164
anatofuz
parents:
diff changeset
165 // The `evalData()` overloads evaluate the given stencil data to a string, given
anatofuz
parents:
diff changeset
166 // the match result, and append it to `Result`. We define an overload for each
anatofuz
parents:
diff changeset
167 // type of stencil data.
anatofuz
parents:
diff changeset
168
anatofuz
parents:
diff changeset
169 Error evalData(const RawTextData &Data, const MatchFinder::MatchResult &,
anatofuz
parents:
diff changeset
170 std::string *Result) {
anatofuz
parents:
diff changeset
171 Result->append(Data.Text);
anatofuz
parents:
diff changeset
172 return Error::success();
anatofuz
parents:
diff changeset
173 }
anatofuz
parents:
diff changeset
174
anatofuz
parents:
diff changeset
175 Error evalData(const DebugPrintNodeData &Data,
anatofuz
parents:
diff changeset
176 const MatchFinder::MatchResult &Match, std::string *Result) {
anatofuz
parents:
diff changeset
177 std::string Output;
anatofuz
parents:
diff changeset
178 llvm::raw_string_ostream Os(Output);
anatofuz
parents:
diff changeset
179 auto NodeOrErr = getNode(Match.Nodes, Data.Id);
anatofuz
parents:
diff changeset
180 if (auto Err = NodeOrErr.takeError())
anatofuz
parents:
diff changeset
181 return Err;
anatofuz
parents:
diff changeset
182 NodeOrErr->print(Os, PrintingPolicy(Match.Context->getLangOpts()));
anatofuz
parents:
diff changeset
183 *Result += Os.str();
anatofuz
parents:
diff changeset
184 return Error::success();
anatofuz
parents:
diff changeset
185 }
anatofuz
parents:
diff changeset
186
anatofuz
parents:
diff changeset
187 Error evalData(const UnaryOperationData &Data,
anatofuz
parents:
diff changeset
188 const MatchFinder::MatchResult &Match, std::string *Result) {
anatofuz
parents:
diff changeset
189 const auto *E = Match.Nodes.getNodeAs<Expr>(Data.Id);
anatofuz
parents:
diff changeset
190 if (E == nullptr)
anatofuz
parents:
diff changeset
191 return llvm::make_error<StringError>(
anatofuz
parents:
diff changeset
192 errc::invalid_argument, "Id not bound or not Expr: " + Data.Id);
anatofuz
parents:
diff changeset
193 llvm::Optional<std::string> Source;
anatofuz
parents:
diff changeset
194 switch (Data.Op) {
anatofuz
parents:
diff changeset
195 case UnaryNodeOperator::Parens:
anatofuz
parents:
diff changeset
196 Source = tooling::buildParens(*E, *Match.Context);
anatofuz
parents:
diff changeset
197 break;
anatofuz
parents:
diff changeset
198 case UnaryNodeOperator::Deref:
anatofuz
parents:
diff changeset
199 Source = tooling::buildDereference(*E, *Match.Context);
anatofuz
parents:
diff changeset
200 break;
anatofuz
parents:
diff changeset
201 case UnaryNodeOperator::MaybeDeref:
anatofuz
parents:
diff changeset
202 if (!E->getType()->isAnyPointerType()) {
anatofuz
parents:
diff changeset
203 *Result += tooling::getText(*E, *Match.Context);
anatofuz
parents:
diff changeset
204 return Error::success();
anatofuz
parents:
diff changeset
205 }
anatofuz
parents:
diff changeset
206 Source = tooling::buildDereference(*E, *Match.Context);
anatofuz
parents:
diff changeset
207 break;
anatofuz
parents:
diff changeset
208 case UnaryNodeOperator::AddressOf:
anatofuz
parents:
diff changeset
209 Source = tooling::buildAddressOf(*E, *Match.Context);
anatofuz
parents:
diff changeset
210 break;
anatofuz
parents:
diff changeset
211 case UnaryNodeOperator::MaybeAddressOf:
anatofuz
parents:
diff changeset
212 if (E->getType()->isAnyPointerType()) {
anatofuz
parents:
diff changeset
213 *Result += tooling::getText(*E, *Match.Context);
anatofuz
parents:
diff changeset
214 return Error::success();
anatofuz
parents:
diff changeset
215 }
anatofuz
parents:
diff changeset
216 Source = tooling::buildAddressOf(*E, *Match.Context);
anatofuz
parents:
diff changeset
217 break;
anatofuz
parents:
diff changeset
218 }
anatofuz
parents:
diff changeset
219 if (!Source)
anatofuz
parents:
diff changeset
220 return llvm::make_error<StringError>(
anatofuz
parents:
diff changeset
221 errc::invalid_argument,
anatofuz
parents:
diff changeset
222 "Could not construct expression source from ID: " + Data.Id);
anatofuz
parents:
diff changeset
223 *Result += *Source;
anatofuz
parents:
diff changeset
224 return Error::success();
anatofuz
parents:
diff changeset
225 }
anatofuz
parents:
diff changeset
226
anatofuz
parents:
diff changeset
227 Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match,
anatofuz
parents:
diff changeset
228 std::string *Result) {
anatofuz
parents:
diff changeset
229 auto Range = Data.Selector(Match);
anatofuz
parents:
diff changeset
230 if (!Range)
anatofuz
parents:
diff changeset
231 return Range.takeError();
anatofuz
parents:
diff changeset
232 if (auto Err = tooling::validateEditRange(*Range, *Match.SourceManager))
anatofuz
parents:
diff changeset
233 return Err;
anatofuz
parents:
diff changeset
234 *Result += tooling::getText(*Range, *Match.Context);
anatofuz
parents:
diff changeset
235 return Error::success();
anatofuz
parents:
diff changeset
236 }
anatofuz
parents:
diff changeset
237
anatofuz
parents:
diff changeset
238 Error evalData(const AccessData &Data, const MatchFinder::MatchResult &Match,
anatofuz
parents:
diff changeset
239 std::string *Result) {
anatofuz
parents:
diff changeset
240 const auto *E = Match.Nodes.getNodeAs<Expr>(Data.BaseId);
anatofuz
parents:
diff changeset
241 if (E == nullptr)
anatofuz
parents:
diff changeset
242 return llvm::make_error<StringError>(errc::invalid_argument,
anatofuz
parents:
diff changeset
243 "Id not bound: " + Data.BaseId);
anatofuz
parents:
diff changeset
244 if (!E->isImplicitCXXThis()) {
anatofuz
parents:
diff changeset
245 if (llvm::Optional<std::string> S =
anatofuz
parents:
diff changeset
246 E->getType()->isAnyPointerType()
anatofuz
parents:
diff changeset
247 ? tooling::buildArrow(*E, *Match.Context)
anatofuz
parents:
diff changeset
248 : tooling::buildDot(*E, *Match.Context))
anatofuz
parents:
diff changeset
249 *Result += *S;
anatofuz
parents:
diff changeset
250 else
anatofuz
parents:
diff changeset
251 return llvm::make_error<StringError>(
anatofuz
parents:
diff changeset
252 errc::invalid_argument,
anatofuz
parents:
diff changeset
253 "Could not construct object text from ID: " + Data.BaseId);
anatofuz
parents:
diff changeset
254 }
anatofuz
parents:
diff changeset
255 return Data.Member->eval(Match, Result);
anatofuz
parents:
diff changeset
256 }
anatofuz
parents:
diff changeset
257
anatofuz
parents:
diff changeset
258 Error evalData(const IfBoundData &Data, const MatchFinder::MatchResult &Match,
anatofuz
parents:
diff changeset
259 std::string *Result) {
anatofuz
parents:
diff changeset
260 auto &M = Match.Nodes.getMap();
anatofuz
parents:
diff changeset
261 return (M.find(Data.Id) != M.end() ? Data.TrueStencil : Data.FalseStencil)
anatofuz
parents:
diff changeset
262 ->eval(Match, Result);
anatofuz
parents:
diff changeset
263 }
anatofuz
parents:
diff changeset
264
anatofuz
parents:
diff changeset
265 Error evalData(const MatchConsumer<std::string> &Fn,
anatofuz
parents:
diff changeset
266 const MatchFinder::MatchResult &Match, std::string *Result) {
anatofuz
parents:
diff changeset
267 Expected<std::string> Value = Fn(Match);
anatofuz
parents:
diff changeset
268 if (!Value)
anatofuz
parents:
diff changeset
269 return Value.takeError();
anatofuz
parents:
diff changeset
270 *Result += *Value;
anatofuz
parents:
diff changeset
271 return Error::success();
anatofuz
parents:
diff changeset
272 }
anatofuz
parents:
diff changeset
273
anatofuz
parents:
diff changeset
274 Error evalData(const SequenceData &Data, const MatchFinder::MatchResult &Match,
anatofuz
parents:
diff changeset
275 std::string *Result) {
anatofuz
parents:
diff changeset
276 for (const auto &S : Data.Stencils)
anatofuz
parents:
diff changeset
277 if (auto Err = S->eval(Match, Result))
anatofuz
parents:
diff changeset
278 return Err;
anatofuz
parents:
diff changeset
279 return Error::success();
anatofuz
parents:
diff changeset
280 }
anatofuz
parents:
diff changeset
281
anatofuz
parents:
diff changeset
282 template <typename T> class StencilImpl : public StencilInterface {
anatofuz
parents:
diff changeset
283 T Data;
anatofuz
parents:
diff changeset
284
anatofuz
parents:
diff changeset
285 public:
anatofuz
parents:
diff changeset
286 template <typename... Ps>
anatofuz
parents:
diff changeset
287 explicit StencilImpl(Ps &&... Args) : Data(std::forward<Ps>(Args)...) {}
anatofuz
parents:
diff changeset
288
anatofuz
parents:
diff changeset
289 Error eval(const MatchFinder::MatchResult &Match,
anatofuz
parents:
diff changeset
290 std::string *Result) const override {
anatofuz
parents:
diff changeset
291 return evalData(Data, Match, Result);
anatofuz
parents:
diff changeset
292 }
anatofuz
parents:
diff changeset
293
anatofuz
parents:
diff changeset
294 std::string toString() const override { return toStringData(Data); }
anatofuz
parents:
diff changeset
295 };
anatofuz
parents:
diff changeset
296 } // namespace
anatofuz
parents:
diff changeset
297
anatofuz
parents:
diff changeset
298 Stencil transformer::detail::makeStencil(StringRef Text) { return text(Text); }
anatofuz
parents:
diff changeset
299
anatofuz
parents:
diff changeset
300 Stencil transformer::detail::makeStencil(RangeSelector Selector) {
anatofuz
parents:
diff changeset
301 return selection(std::move(Selector));
anatofuz
parents:
diff changeset
302 }
anatofuz
parents:
diff changeset
303
anatofuz
parents:
diff changeset
304 Stencil transformer::text(StringRef Text) {
anatofuz
parents:
diff changeset
305 return std::make_shared<StencilImpl<RawTextData>>(std::string(Text));
anatofuz
parents:
diff changeset
306 }
anatofuz
parents:
diff changeset
307
anatofuz
parents:
diff changeset
308 Stencil transformer::selection(RangeSelector Selector) {
anatofuz
parents:
diff changeset
309 return std::make_shared<StencilImpl<SelectorData>>(std::move(Selector));
anatofuz
parents:
diff changeset
310 }
anatofuz
parents:
diff changeset
311
anatofuz
parents:
diff changeset
312 Stencil transformer::dPrint(StringRef Id) {
anatofuz
parents:
diff changeset
313 return std::make_shared<StencilImpl<DebugPrintNodeData>>(std::string(Id));
anatofuz
parents:
diff changeset
314 }
anatofuz
parents:
diff changeset
315
anatofuz
parents:
diff changeset
316 Stencil transformer::expression(llvm::StringRef Id) {
anatofuz
parents:
diff changeset
317 return std::make_shared<StencilImpl<UnaryOperationData>>(
anatofuz
parents:
diff changeset
318 UnaryNodeOperator::Parens, std::string(Id));
anatofuz
parents:
diff changeset
319 }
anatofuz
parents:
diff changeset
320
anatofuz
parents:
diff changeset
321 Stencil transformer::deref(llvm::StringRef ExprId) {
anatofuz
parents:
diff changeset
322 return std::make_shared<StencilImpl<UnaryOperationData>>(
anatofuz
parents:
diff changeset
323 UnaryNodeOperator::Deref, std::string(ExprId));
anatofuz
parents:
diff changeset
324 }
anatofuz
parents:
diff changeset
325
anatofuz
parents:
diff changeset
326 Stencil transformer::maybeDeref(llvm::StringRef ExprId) {
anatofuz
parents:
diff changeset
327 return std::make_shared<StencilImpl<UnaryOperationData>>(
anatofuz
parents:
diff changeset
328 UnaryNodeOperator::MaybeDeref, std::string(ExprId));
anatofuz
parents:
diff changeset
329 }
anatofuz
parents:
diff changeset
330
anatofuz
parents:
diff changeset
331 Stencil transformer::addressOf(llvm::StringRef ExprId) {
anatofuz
parents:
diff changeset
332 return std::make_shared<StencilImpl<UnaryOperationData>>(
anatofuz
parents:
diff changeset
333 UnaryNodeOperator::AddressOf, std::string(ExprId));
anatofuz
parents:
diff changeset
334 }
anatofuz
parents:
diff changeset
335
anatofuz
parents:
diff changeset
336 Stencil transformer::maybeAddressOf(llvm::StringRef ExprId) {
anatofuz
parents:
diff changeset
337 return std::make_shared<StencilImpl<UnaryOperationData>>(
anatofuz
parents:
diff changeset
338 UnaryNodeOperator::MaybeAddressOf, std::string(ExprId));
anatofuz
parents:
diff changeset
339 }
anatofuz
parents:
diff changeset
340
anatofuz
parents:
diff changeset
341 Stencil transformer::access(StringRef BaseId, Stencil Member) {
anatofuz
parents:
diff changeset
342 return std::make_shared<StencilImpl<AccessData>>(BaseId, std::move(Member));
anatofuz
parents:
diff changeset
343 }
anatofuz
parents:
diff changeset
344
anatofuz
parents:
diff changeset
345 Stencil transformer::ifBound(StringRef Id, Stencil TrueStencil,
anatofuz
parents:
diff changeset
346 Stencil FalseStencil) {
anatofuz
parents:
diff changeset
347 return std::make_shared<StencilImpl<IfBoundData>>(Id, std::move(TrueStencil),
anatofuz
parents:
diff changeset
348 std::move(FalseStencil));
anatofuz
parents:
diff changeset
349 }
anatofuz
parents:
diff changeset
350
anatofuz
parents:
diff changeset
351 Stencil transformer::run(MatchConsumer<std::string> Fn) {
anatofuz
parents:
diff changeset
352 return std::make_shared<StencilImpl<MatchConsumer<std::string>>>(
anatofuz
parents:
diff changeset
353 std::move(Fn));
anatofuz
parents:
diff changeset
354 }
anatofuz
parents:
diff changeset
355
anatofuz
parents:
diff changeset
356 Stencil transformer::catVector(std::vector<Stencil> Parts) {
anatofuz
parents:
diff changeset
357 // Only one argument, so don't wrap in sequence.
anatofuz
parents:
diff changeset
358 if (Parts.size() == 1)
anatofuz
parents:
diff changeset
359 return std::move(Parts[0]);
anatofuz
parents:
diff changeset
360 return std::make_shared<StencilImpl<SequenceData>>(std::move(Parts));
anatofuz
parents:
diff changeset
361 }