File: | build/source/clang/include/clang/Tooling/Transformer/RewriteRule.h |
Warning: | line 174, column 1 Potential memory leak |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- Transformer.cpp - Transformer library implementation ---*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #include "clang/Tooling/Transformer/RewriteRule.h" | |||
10 | #include "clang/AST/ASTTypeTraits.h" | |||
11 | #include "clang/AST/Stmt.h" | |||
12 | #include "clang/ASTMatchers/ASTMatchFinder.h" | |||
13 | #include "clang/ASTMatchers/ASTMatchers.h" | |||
14 | #include "clang/Basic/SourceLocation.h" | |||
15 | #include "clang/Tooling/Transformer/SourceCode.h" | |||
16 | #include "llvm/ADT/StringRef.h" | |||
17 | #include "llvm/Support/Errc.h" | |||
18 | #include "llvm/Support/Error.h" | |||
19 | #include <map> | |||
20 | #include <string> | |||
21 | #include <utility> | |||
22 | #include <vector> | |||
23 | ||||
24 | using namespace clang; | |||
25 | using namespace transformer; | |||
26 | ||||
27 | using ast_matchers::MatchFinder; | |||
28 | using ast_matchers::internal::DynTypedMatcher; | |||
29 | ||||
30 | using MatchResult = MatchFinder::MatchResult; | |||
31 | ||||
32 | const char transformer::RootID[] = "___root___"; | |||
33 | ||||
34 | static Expected<SmallVector<transformer::Edit, 1>> | |||
35 | translateEdits(const MatchResult &Result, ArrayRef<ASTEdit> ASTEdits) { | |||
36 | SmallVector<transformer::Edit, 1> Edits; | |||
37 | for (const auto &E : ASTEdits) { | |||
38 | Expected<CharSourceRange> Range = E.TargetRange(Result); | |||
39 | if (!Range) | |||
40 | return Range.takeError(); | |||
41 | std::optional<CharSourceRange> EditRange = | |||
42 | tooling::getFileRangeForEdit(*Range, *Result.Context); | |||
43 | // FIXME: let user specify whether to treat this case as an error or ignore | |||
44 | // it as is currently done. This behavior is problematic in that it hides | |||
45 | // failures from bad ranges. Also, the behavior here differs from | |||
46 | // `flatten`. Here, we abort (without error), whereas flatten, if it hits an | |||
47 | // empty list, does not abort. As a result, `editList({A,B})` is not | |||
48 | // equivalent to `flatten(edit(A), edit(B))`. The former will abort if `A` | |||
49 | // produces a bad range, whereas the latter will simply ignore A. | |||
50 | if (!EditRange) | |||
51 | return SmallVector<Edit, 0>(); | |||
52 | transformer::Edit T; | |||
53 | T.Kind = E.Kind; | |||
54 | T.Range = *EditRange; | |||
55 | if (E.Replacement) { | |||
56 | auto Replacement = E.Replacement->eval(Result); | |||
57 | if (!Replacement) | |||
58 | return Replacement.takeError(); | |||
59 | T.Replacement = std::move(*Replacement); | |||
60 | } | |||
61 | if (E.Note) { | |||
62 | auto Note = E.Note->eval(Result); | |||
63 | if (!Note) | |||
64 | return Note.takeError(); | |||
65 | T.Note = std::move(*Note); | |||
66 | } | |||
67 | if (E.Metadata) { | |||
68 | auto Metadata = E.Metadata(Result); | |||
69 | if (!Metadata) | |||
70 | return Metadata.takeError(); | |||
71 | T.Metadata = std::move(*Metadata); | |||
72 | } | |||
73 | Edits.push_back(std::move(T)); | |||
74 | } | |||
75 | return Edits; | |||
76 | } | |||
77 | ||||
78 | EditGenerator transformer::editList(SmallVector<ASTEdit, 1> Edits) { | |||
79 | return [Edits = std::move(Edits)](const MatchResult &Result) { | |||
80 | return translateEdits(Result, Edits); | |||
81 | }; | |||
82 | } | |||
83 | ||||
84 | EditGenerator transformer::edit(ASTEdit Edit) { | |||
85 | return [Edit = std::move(Edit)](const MatchResult &Result) { | |||
86 | return translateEdits(Result, {Edit}); | |||
87 | }; | |||
88 | } | |||
89 | ||||
90 | EditGenerator transformer::noopEdit(RangeSelector Anchor) { | |||
91 | return [Anchor = std::move(Anchor)](const MatchResult &Result) | |||
92 | -> Expected<SmallVector<transformer::Edit, 1>> { | |||
93 | Expected<CharSourceRange> Range = Anchor(Result); | |||
94 | if (!Range) | |||
95 | return Range.takeError(); | |||
96 | // In case the range is inside a macro expansion, map the location back to a | |||
97 | // "real" source location. | |||
98 | SourceLocation Begin = | |||
99 | Result.SourceManager->getSpellingLoc(Range->getBegin()); | |||
100 | Edit E; | |||
101 | // Implicitly, leave `E.Replacement` as the empty string. | |||
102 | E.Kind = EditKind::Range; | |||
103 | E.Range = CharSourceRange::getCharRange(Begin, Begin); | |||
104 | return SmallVector<Edit, 1>{E}; | |||
105 | }; | |||
106 | } | |||
107 | ||||
108 | EditGenerator | |||
109 | transformer::flattenVector(SmallVector<EditGenerator, 2> Generators) { | |||
110 | if (Generators.size() == 1) | |||
111 | return std::move(Generators[0]); | |||
112 | return | |||
113 | [Gs = std::move(Generators)]( | |||
114 | const MatchResult &Result) -> llvm::Expected<SmallVector<Edit, 1>> { | |||
115 | SmallVector<Edit, 1> AllEdits; | |||
116 | for (const auto &G : Gs) { | |||
117 | llvm::Expected<SmallVector<Edit, 1>> Edits = G(Result); | |||
118 | if (!Edits) | |||
119 | return Edits.takeError(); | |||
120 | AllEdits.append(Edits->begin(), Edits->end()); | |||
121 | } | |||
122 | return AllEdits; | |||
123 | }; | |||
124 | } | |||
125 | ||||
126 | ASTEdit transformer::changeTo(RangeSelector Target, TextGenerator Replacement) { | |||
127 | ASTEdit E; | |||
128 | E.TargetRange = std::move(Target); | |||
129 | E.Replacement = std::move(Replacement); | |||
130 | return E; | |||
131 | } | |||
132 | ||||
133 | ASTEdit transformer::note(RangeSelector Anchor, TextGenerator Note) { | |||
134 | ASTEdit E; | |||
135 | E.TargetRange = transformer::before(Anchor); | |||
136 | E.Note = std::move(Note); | |||
137 | return E; | |||
138 | } | |||
139 | ||||
140 | namespace { | |||
141 | /// A \c TextGenerator that always returns a fixed string. | |||
142 | class SimpleTextGenerator : public MatchComputation<std::string> { | |||
143 | std::string S; | |||
144 | ||||
145 | public: | |||
146 | SimpleTextGenerator(std::string S) : S(std::move(S)) {} | |||
147 | llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &, | |||
148 | std::string *Result) const override { | |||
149 | Result->append(S); | |||
150 | return llvm::Error::success(); | |||
151 | } | |||
152 | std::string toString() const override { | |||
153 | return (llvm::Twine("text(\"") + S + "\")").str(); | |||
154 | } | |||
155 | }; | |||
156 | } // namespace | |||
157 | ||||
158 | static TextGenerator makeText(std::string S) { | |||
159 | return std::make_shared<SimpleTextGenerator>(std::move(S)); | |||
160 | } | |||
161 | ||||
162 | ASTEdit transformer::remove(RangeSelector S) { | |||
163 | return change(std::move(S), makeText("")); | |||
164 | } | |||
165 | ||||
166 | static std::string formatHeaderPath(StringRef Header, IncludeFormat Format) { | |||
167 | switch (Format) { | |||
168 | case transformer::IncludeFormat::Quoted: | |||
169 | return Header.str(); | |||
170 | case transformer::IncludeFormat::Angled: | |||
171 | return ("<" + Header + ">").str(); | |||
172 | } | |||
173 | llvm_unreachable("Unknown transformer::IncludeFormat enum")::llvm::llvm_unreachable_internal("Unknown transformer::IncludeFormat enum" , "clang/lib/Tooling/Transformer/RewriteRule.cpp", 173); | |||
174 | } | |||
175 | ||||
176 | ASTEdit transformer::addInclude(RangeSelector Target, StringRef Header, | |||
177 | IncludeFormat Format) { | |||
178 | ASTEdit E; | |||
179 | E.Kind = EditKind::AddInclude; | |||
180 | E.TargetRange = Target; | |||
181 | E.Replacement = makeText(formatHeaderPath(Header, Format)); | |||
182 | return E; | |||
183 | } | |||
184 | ||||
185 | EditGenerator | |||
186 | transformer::detail::makeEditGenerator(llvm::SmallVector<ASTEdit, 1> Edits) { | |||
187 | return editList(std::move(Edits)); | |||
188 | } | |||
189 | ||||
190 | EditGenerator transformer::detail::makeEditGenerator(ASTEdit Edit) { | |||
191 | return edit(std::move(Edit)); | |||
192 | } | |||
193 | ||||
194 | RewriteRule transformer::detail::makeRule(DynTypedMatcher M, | |||
195 | EditGenerator Edits) { | |||
196 | RewriteRule R; | |||
197 | R.Cases = {{std::move(M), std::move(Edits)}}; | |||
198 | return R; | |||
199 | } | |||
200 | ||||
201 | RewriteRule transformer::makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
202 | std::initializer_list<ASTEdit> Edits) { | |||
203 | return detail::makeRule(std::move(M), | |||
204 | detail::makeEditGenerator(std::move(Edits))); | |||
205 | } | |||
206 | ||||
207 | namespace { | |||
208 | ||||
209 | /// Unconditionally binds the given node set before trying `InnerMatcher` and | |||
210 | /// keeps the bound nodes on a successful match. | |||
211 | template <typename T> | |||
212 | class BindingsMatcher : public ast_matchers::internal::MatcherInterface<T> { | |||
213 | ast_matchers::BoundNodes Nodes; | |||
214 | const ast_matchers::internal::Matcher<T> InnerMatcher; | |||
215 | ||||
216 | public: | |||
217 | explicit BindingsMatcher(ast_matchers::BoundNodes Nodes, | |||
218 | ast_matchers::internal::Matcher<T> InnerMatcher) | |||
219 | : Nodes(std::move(Nodes)), InnerMatcher(std::move(InnerMatcher)) {} | |||
220 | ||||
221 | bool matches( | |||
222 | const T &Node, ast_matchers::internal::ASTMatchFinder *Finder, | |||
223 | ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override { | |||
224 | ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); | |||
225 | for (const auto &N : Nodes.getMap()) | |||
226 | Result.setBinding(N.first, N.second); | |||
227 | if (InnerMatcher.matches(Node, Finder, &Result)) { | |||
228 | *Builder = std::move(Result); | |||
229 | return true; | |||
230 | } | |||
231 | return false; | |||
232 | } | |||
233 | }; | |||
234 | ||||
235 | /// Matches nodes of type T that have at least one descendant node for which the | |||
236 | /// given inner matcher matches. Will match for each descendant node that | |||
237 | /// matches. Based on ForEachDescendantMatcher, but takes a dynamic matcher, | |||
238 | /// instead of a static one, because it is used by RewriteRule, which carries | |||
239 | /// (only top-level) dynamic matchers. | |||
240 | template <typename T> | |||
241 | class DynamicForEachDescendantMatcher | |||
242 | : public ast_matchers::internal::MatcherInterface<T> { | |||
243 | const DynTypedMatcher DescendantMatcher; | |||
244 | ||||
245 | public: | |||
246 | explicit DynamicForEachDescendantMatcher(DynTypedMatcher DescendantMatcher) | |||
247 | : DescendantMatcher(std::move(DescendantMatcher)) {} | |||
248 | ||||
249 | bool matches( | |||
250 | const T &Node, ast_matchers::internal::ASTMatchFinder *Finder, | |||
251 | ast_matchers::internal::BoundNodesTreeBuilder *Builder) const override { | |||
252 | return Finder->matchesDescendantOf( | |||
253 | Node, this->DescendantMatcher, Builder, | |||
254 | ast_matchers::internal::ASTMatchFinder::BK_All); | |||
255 | } | |||
256 | }; | |||
257 | ||||
258 | template <typename T> | |||
259 | ast_matchers::internal::Matcher<T> | |||
260 | forEachDescendantDynamically(ast_matchers::BoundNodes Nodes, | |||
261 | DynTypedMatcher M) { | |||
262 | return ast_matchers::internal::makeMatcher(new BindingsMatcher<T>( | |||
263 | std::move(Nodes), | |||
264 | ast_matchers::internal::makeMatcher( | |||
265 | new DynamicForEachDescendantMatcher<T>(std::move(M))))); | |||
266 | } | |||
267 | ||||
268 | class ApplyRuleCallback : public MatchFinder::MatchCallback { | |||
269 | public: | |||
270 | ApplyRuleCallback(RewriteRule Rule) : Rule(std::move(Rule)) {} | |||
271 | ||||
272 | template <typename T> | |||
273 | void registerMatchers(const ast_matchers::BoundNodes &Nodes, | |||
274 | MatchFinder *MF) { | |||
275 | for (auto &Matcher : transformer::detail::buildMatchers(Rule)) | |||
276 | MF->addMatcher(forEachDescendantDynamically<T>(Nodes, Matcher), this); | |||
277 | } | |||
278 | ||||
279 | void run(const MatchFinder::MatchResult &Result) override { | |||
280 | if (!Edits) | |||
281 | return; | |||
282 | size_t I = transformer::detail::findSelectedCase(Result, Rule); | |||
283 | auto Transformations = Rule.Cases[I].Edits(Result); | |||
284 | if (!Transformations) { | |||
285 | Edits = Transformations.takeError(); | |||
286 | return; | |||
287 | } | |||
288 | Edits->append(Transformations->begin(), Transformations->end()); | |||
289 | } | |||
290 | ||||
291 | RewriteRule Rule; | |||
292 | ||||
293 | // Initialize to a non-error state. | |||
294 | Expected<SmallVector<Edit, 1>> Edits = SmallVector<Edit, 1>(); | |||
295 | }; | |||
296 | } // namespace | |||
297 | ||||
298 | template <typename T> | |||
299 | llvm::Expected<SmallVector<clang::transformer::Edit, 1>> | |||
300 | rewriteDescendantsImpl(const T &Node, RewriteRule Rule, | |||
301 | const MatchResult &Result) { | |||
302 | ApplyRuleCallback Callback(std::move(Rule)); | |||
303 | MatchFinder Finder; | |||
304 | Callback.registerMatchers<T>(Result.Nodes, &Finder); | |||
305 | Finder.match(Node, *Result.Context); | |||
306 | return std::move(Callback.Edits); | |||
307 | } | |||
308 | ||||
309 | llvm::Expected<SmallVector<clang::transformer::Edit, 1>> | |||
310 | transformer::detail::rewriteDescendants(const Decl &Node, RewriteRule Rule, | |||
311 | const MatchResult &Result) { | |||
312 | return rewriteDescendantsImpl(Node, std::move(Rule), Result); | |||
313 | } | |||
314 | ||||
315 | llvm::Expected<SmallVector<clang::transformer::Edit, 1>> | |||
316 | transformer::detail::rewriteDescendants(const Stmt &Node, RewriteRule Rule, | |||
317 | const MatchResult &Result) { | |||
318 | return rewriteDescendantsImpl(Node, std::move(Rule), Result); | |||
319 | } | |||
320 | ||||
321 | llvm::Expected<SmallVector<clang::transformer::Edit, 1>> | |||
322 | transformer::detail::rewriteDescendants(const TypeLoc &Node, RewriteRule Rule, | |||
323 | const MatchResult &Result) { | |||
324 | return rewriteDescendantsImpl(Node, std::move(Rule), Result); | |||
325 | } | |||
326 | ||||
327 | llvm::Expected<SmallVector<clang::transformer::Edit, 1>> | |||
328 | transformer::detail::rewriteDescendants(const DynTypedNode &DNode, | |||
329 | RewriteRule Rule, | |||
330 | const MatchResult &Result) { | |||
331 | if (const auto *Node = DNode.get<Decl>()) | |||
332 | return rewriteDescendantsImpl(*Node, std::move(Rule), Result); | |||
333 | if (const auto *Node = DNode.get<Stmt>()) | |||
334 | return rewriteDescendantsImpl(*Node, std::move(Rule), Result); | |||
335 | if (const auto *Node = DNode.get<TypeLoc>()) | |||
336 | return rewriteDescendantsImpl(*Node, std::move(Rule), Result); | |||
337 | ||||
338 | return llvm::make_error<llvm::StringError>( | |||
339 | llvm::errc::invalid_argument, | |||
340 | "type unsupported for recursive rewriting, Kind=" + | |||
341 | DNode.getNodeKind().asStringRef()); | |||
342 | } | |||
343 | ||||
344 | EditGenerator transformer::rewriteDescendants(std::string NodeId, | |||
345 | RewriteRule Rule) { | |||
346 | return [NodeId = std::move(NodeId), | |||
347 | Rule = std::move(Rule)](const MatchResult &Result) | |||
348 | -> llvm::Expected<SmallVector<clang::transformer::Edit, 1>> { | |||
349 | const ast_matchers::BoundNodes::IDToNodeMap &NodesMap = | |||
350 | Result.Nodes.getMap(); | |||
351 | auto It = NodesMap.find(NodeId); | |||
352 | if (It == NodesMap.end()) | |||
353 | return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument, | |||
354 | "ID not bound: " + NodeId); | |||
355 | return detail::rewriteDescendants(It->second, std::move(Rule), Result); | |||
356 | }; | |||
357 | } | |||
358 | ||||
359 | void transformer::addInclude(RewriteRuleBase &Rule, StringRef Header, | |||
360 | IncludeFormat Format) { | |||
361 | for (auto &Case : Rule.Cases) | |||
| ||||
362 | Case.Edits = flatten(std::move(Case.Edits), addInclude(Header, Format)); | |||
363 | } | |||
364 | ||||
365 | #ifndef NDEBUG | |||
366 | // Filters for supported matcher kinds. FIXME: Explicitly list the allowed kinds | |||
367 | // (all node matcher types except for `QualType` and `Type`), rather than just | |||
368 | // banning `QualType` and `Type`. | |||
369 | static bool hasValidKind(const DynTypedMatcher &M) { | |||
370 | return !M.canConvertTo<QualType>(); | |||
371 | } | |||
372 | #endif | |||
373 | ||||
374 | // Binds each rule's matcher to a unique (and deterministic) tag based on | |||
375 | // `TagBase` and the id paired with the case. All of the returned matchers have | |||
376 | // their traversal kind explicitly set, either based on a pre-set kind or to the | |||
377 | // provided `DefaultTraversalKind`. | |||
378 | static std::vector<DynTypedMatcher> taggedMatchers( | |||
379 | StringRef TagBase, | |||
380 | const SmallVectorImpl<std::pair<size_t, RewriteRule::Case>> &Cases, | |||
381 | TraversalKind DefaultTraversalKind) { | |||
382 | std::vector<DynTypedMatcher> Matchers; | |||
383 | Matchers.reserve(Cases.size()); | |||
384 | for (const auto &Case : Cases) { | |||
385 | std::string Tag = (TagBase + Twine(Case.first)).str(); | |||
386 | // HACK: Many matchers are not bindable, so ensure that tryBind will work. | |||
387 | DynTypedMatcher BoundMatcher(Case.second.Matcher); | |||
388 | BoundMatcher.setAllowBind(true); | |||
389 | auto M = *BoundMatcher.tryBind(Tag); | |||
390 | Matchers.push_back(!M.getTraversalKind() | |||
391 | ? M.withTraversalKind(DefaultTraversalKind) | |||
392 | : std::move(M)); | |||
393 | } | |||
394 | return Matchers; | |||
395 | } | |||
396 | ||||
397 | // Simply gathers the contents of the various rules into a single rule. The | |||
398 | // actual work to combine these into an ordered choice is deferred to matcher | |||
399 | // registration. | |||
400 | template <> | |||
401 | RewriteRuleWith<void> | |||
402 | transformer::applyFirst(ArrayRef<RewriteRuleWith<void>> Rules) { | |||
403 | RewriteRule R; | |||
404 | for (auto &Rule : Rules) | |||
405 | R.Cases.append(Rule.Cases.begin(), Rule.Cases.end()); | |||
406 | return R; | |||
407 | } | |||
408 | ||||
409 | std::vector<DynTypedMatcher> | |||
410 | transformer::detail::buildMatchers(const RewriteRuleBase &Rule) { | |||
411 | // Map the cases into buckets of matchers -- one for each "root" AST kind, | |||
412 | // which guarantees that they can be combined in a single anyOf matcher. Each | |||
413 | // case is paired with an identifying number that is converted to a string id | |||
414 | // in `taggedMatchers`. | |||
415 | std::map<ASTNodeKind, | |||
416 | SmallVector<std::pair<size_t, RewriteRuleBase::Case>, 1>> | |||
417 | Buckets; | |||
418 | const SmallVectorImpl<RewriteRule::Case> &Cases = Rule.Cases; | |||
419 | for (int I = 0, N = Cases.size(); I < N; ++I) { | |||
420 | assert(hasValidKind(Cases[I].Matcher) &&(static_cast <bool> (hasValidKind(Cases[I].Matcher) && "Matcher must be non-(Qual)Type node matcher") ? void (0) : __assert_fail ("hasValidKind(Cases[I].Matcher) && \"Matcher must be non-(Qual)Type node matcher\"" , "clang/lib/Tooling/Transformer/RewriteRule.cpp", 421, __extension__ __PRETTY_FUNCTION__)) | |||
421 | "Matcher must be non-(Qual)Type node matcher")(static_cast <bool> (hasValidKind(Cases[I].Matcher) && "Matcher must be non-(Qual)Type node matcher") ? void (0) : __assert_fail ("hasValidKind(Cases[I].Matcher) && \"Matcher must be non-(Qual)Type node matcher\"" , "clang/lib/Tooling/Transformer/RewriteRule.cpp", 421, __extension__ __PRETTY_FUNCTION__)); | |||
422 | Buckets[Cases[I].Matcher.getSupportedKind()].emplace_back(I, Cases[I]); | |||
423 | } | |||
424 | ||||
425 | // Each anyOf explicitly controls the traversal kind. The anyOf itself is set | |||
426 | // to `TK_AsIs` to ensure no nodes are skipped, thereby deferring to the kind | |||
427 | // of the branches. Then, each branch is either left as is, if the kind is | |||
428 | // already set, or explicitly set to `TK_AsIs`. We choose this setting because | |||
429 | // it is the default interpretation of matchers. | |||
430 | std::vector<DynTypedMatcher> Matchers; | |||
431 | for (const auto &Bucket : Buckets) { | |||
432 | DynTypedMatcher M = DynTypedMatcher::constructVariadic( | |||
433 | DynTypedMatcher::VO_AnyOf, Bucket.first, | |||
434 | taggedMatchers("Tag", Bucket.second, TK_AsIs)); | |||
435 | M.setAllowBind(true); | |||
436 | // `tryBind` is guaranteed to succeed, because `AllowBind` was set to true. | |||
437 | Matchers.push_back(M.tryBind(RootID)->withTraversalKind(TK_AsIs)); | |||
438 | } | |||
439 | return Matchers; | |||
440 | } | |||
441 | ||||
442 | DynTypedMatcher transformer::detail::buildMatcher(const RewriteRuleBase &Rule) { | |||
443 | std::vector<DynTypedMatcher> Ms = buildMatchers(Rule); | |||
444 | assert(Ms.size() == 1 && "Cases must have compatible matchers.")(static_cast <bool> (Ms.size() == 1 && "Cases must have compatible matchers." ) ? void (0) : __assert_fail ("Ms.size() == 1 && \"Cases must have compatible matchers.\"" , "clang/lib/Tooling/Transformer/RewriteRule.cpp", 444, __extension__ __PRETTY_FUNCTION__)); | |||
445 | return Ms[0]; | |||
446 | } | |||
447 | ||||
448 | SourceLocation transformer::detail::getRuleMatchLoc(const MatchResult &Result) { | |||
449 | auto &NodesMap = Result.Nodes.getMap(); | |||
450 | auto Root = NodesMap.find(RootID); | |||
451 | assert(Root != NodesMap.end() && "Transformation failed: missing root node.")(static_cast <bool> (Root != NodesMap.end() && "Transformation failed: missing root node." ) ? void (0) : __assert_fail ("Root != NodesMap.end() && \"Transformation failed: missing root node.\"" , "clang/lib/Tooling/Transformer/RewriteRule.cpp", 451, __extension__ __PRETTY_FUNCTION__)); | |||
452 | std::optional<CharSourceRange> RootRange = tooling::getFileRangeForEdit( | |||
453 | CharSourceRange::getTokenRange(Root->second.getSourceRange()), | |||
454 | *Result.Context); | |||
455 | if (RootRange) | |||
456 | return RootRange->getBegin(); | |||
457 | // The match doesn't have a coherent range, so fall back to the expansion | |||
458 | // location as the "beginning" of the match. | |||
459 | return Result.SourceManager->getExpansionLoc( | |||
460 | Root->second.getSourceRange().getBegin()); | |||
461 | } | |||
462 | ||||
463 | // Finds the case that was "selected" -- that is, whose matcher triggered the | |||
464 | // `MatchResult`. | |||
465 | size_t transformer::detail::findSelectedCase(const MatchResult &Result, | |||
466 | const RewriteRuleBase &Rule) { | |||
467 | if (Rule.Cases.size() == 1) | |||
468 | return 0; | |||
469 | ||||
470 | auto &NodesMap = Result.Nodes.getMap(); | |||
471 | for (size_t i = 0, N = Rule.Cases.size(); i < N; ++i) { | |||
472 | std::string Tag = ("Tag" + Twine(i)).str(); | |||
473 | if (NodesMap.find(Tag) != NodesMap.end()) | |||
474 | return i; | |||
475 | } | |||
476 | llvm_unreachable("No tag found for this rule.")::llvm::llvm_unreachable_internal("No tag found for this rule." , "clang/lib/Tooling/Transformer/RewriteRule.cpp", 476); | |||
477 | } |
1 | //===--- RewriteRule.h - RewriteRule class ----------------------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | /// | |||
9 | /// \file | |||
10 | /// Defines the RewriteRule class and related functions for creating, | |||
11 | /// modifying and interpreting RewriteRules. | |||
12 | /// | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #ifndef LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H | |||
16 | #define LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H | |||
17 | ||||
18 | #include "clang/ASTMatchers/ASTMatchFinder.h" | |||
19 | #include "clang/ASTMatchers/ASTMatchers.h" | |||
20 | #include "clang/ASTMatchers/ASTMatchersInternal.h" | |||
21 | #include "clang/Tooling/Refactoring/AtomicChange.h" | |||
22 | #include "clang/Tooling/Transformer/MatchConsumer.h" | |||
23 | #include "clang/Tooling/Transformer/RangeSelector.h" | |||
24 | #include "llvm/ADT/Any.h" | |||
25 | #include "llvm/ADT/STLExtras.h" | |||
26 | #include "llvm/ADT/SmallVector.h" | |||
27 | #include "llvm/Support/Error.h" | |||
28 | #include <functional> | |||
29 | #include <string> | |||
30 | #include <utility> | |||
31 | ||||
32 | namespace clang { | |||
33 | namespace transformer { | |||
34 | // Specifies how to interpret an edit. | |||
35 | enum class EditKind { | |||
36 | // Edits a source range in the file. | |||
37 | Range, | |||
38 | // Inserts an include in the file. The `Replacement` field is the name of the | |||
39 | // newly included file. | |||
40 | AddInclude, | |||
41 | }; | |||
42 | ||||
43 | /// A concrete description of a source edit, represented by a character range in | |||
44 | /// the source to be replaced and a corresponding replacement string. | |||
45 | struct Edit { | |||
46 | EditKind Kind = EditKind::Range; | |||
47 | CharSourceRange Range; | |||
48 | std::string Replacement; | |||
49 | std::string Note; | |||
50 | llvm::Any Metadata; | |||
51 | }; | |||
52 | ||||
53 | /// Format of the path in an include directive -- angle brackets or quotes. | |||
54 | enum class IncludeFormat { | |||
55 | Quoted, | |||
56 | Angled, | |||
57 | }; | |||
58 | ||||
59 | /// Maps a match result to a list of concrete edits (with possible | |||
60 | /// failure). This type is a building block of rewrite rules, but users will | |||
61 | /// generally work in terms of `ASTEdit`s (below) rather than directly in terms | |||
62 | /// of `EditGenerator`. | |||
63 | using EditGenerator = MatchConsumer<llvm::SmallVector<Edit, 1>>; | |||
64 | ||||
65 | template <typename T> using Generator = std::shared_ptr<MatchComputation<T>>; | |||
66 | ||||
67 | using TextGenerator = Generator<std::string>; | |||
68 | ||||
69 | using AnyGenerator = MatchConsumer<llvm::Any>; | |||
70 | ||||
71 | // Description of a source-code edit, expressed in terms of an AST node. | |||
72 | // Includes: an ID for the (bound) node, a selector for source related to the | |||
73 | // node, a replacement and, optionally, an explanation for the edit. | |||
74 | // | |||
75 | // * Target: the source code impacted by the rule. This identifies an AST node, | |||
76 | // or part thereof (\c Part), whose source range indicates the extent of the | |||
77 | // replacement applied by the replacement term. By default, the extent is the | |||
78 | // node matched by the pattern term (\c NodePart::Node). Target's are typed | |||
79 | // (\c Kind), which guides the determination of the node extent. | |||
80 | // | |||
81 | // * Replacement: a function that produces a replacement string for the target, | |||
82 | // based on the match result. | |||
83 | // | |||
84 | // * Note: (optional) a note specifically for this edit, potentially referencing | |||
85 | // elements of the match. This will be displayed to the user, where possible; | |||
86 | // for example, in clang-tidy diagnostics. Use of notes should be rare -- | |||
87 | // explanations of the entire rewrite should be set in the rule | |||
88 | // (`RewriteRule::Explanation`) instead. Notes serve the rare cases wherein | |||
89 | // edit-specific diagnostics are required. | |||
90 | // | |||
91 | // `ASTEdit` should be built using the `change` convenience functions. For | |||
92 | // example, | |||
93 | // \code | |||
94 | // changeTo(name(fun), cat("Frodo")) | |||
95 | // \endcode | |||
96 | // Or, if we use Stencil for the TextGenerator: | |||
97 | // \code | |||
98 | // using stencil::cat; | |||
99 | // changeTo(statement(thenNode), cat("{", thenNode, "}")) | |||
100 | // changeTo(callArgs(call), cat(x, ",", y)) | |||
101 | // \endcode | |||
102 | // Or, if you are changing the node corresponding to the rule's matcher, you can | |||
103 | // use the single-argument override of \c change: | |||
104 | // \code | |||
105 | // changeTo(cat("different_expr")) | |||
106 | // \endcode | |||
107 | struct ASTEdit { | |||
108 | EditKind Kind = EditKind::Range; | |||
109 | RangeSelector TargetRange; | |||
110 | TextGenerator Replacement; | |||
111 | TextGenerator Note; | |||
112 | // Not all transformations will want or need to attach metadata and therefore | |||
113 | // should not be required to do so. | |||
114 | AnyGenerator Metadata = [](const ast_matchers::MatchFinder::MatchResult &) | |||
115 | -> llvm::Expected<llvm::Any> { | |||
116 | return llvm::Expected<llvm::Any>(llvm::Any()); | |||
117 | }; | |||
118 | }; | |||
119 | ||||
120 | /// Generates a single (specified) edit. | |||
121 | EditGenerator edit(ASTEdit E); | |||
122 | ||||
123 | /// Lifts a list of `ASTEdit`s into an `EditGenerator`. | |||
124 | /// | |||
125 | /// The `EditGenerator` will return an empty vector if any of the edits apply to | |||
126 | /// portions of the source that are ineligible for rewriting (certain | |||
127 | /// interactions with macros, for example) and it will fail if any invariants | |||
128 | /// are violated relating to bound nodes in the match. However, it does not | |||
129 | /// fail in the case of conflicting edits -- conflict handling is left to | |||
130 | /// clients. We recommend use of the \c AtomicChange or \c Replacements classes | |||
131 | /// for assistance in detecting such conflicts. | |||
132 | EditGenerator editList(llvm::SmallVector<ASTEdit, 1> Edits); | |||
133 | ||||
134 | /// Generates no edits. | |||
135 | inline EditGenerator noEdits() { return editList({}); } | |||
136 | ||||
137 | /// Generates a single, no-op edit anchored at the start location of the | |||
138 | /// specified range. A `noopEdit` may be preferred over `noEdits` to associate a | |||
139 | /// diagnostic `Explanation` with the rule. | |||
140 | EditGenerator noopEdit(RangeSelector Anchor); | |||
141 | ||||
142 | /// Generates a single, no-op edit with the associated note anchored at the | |||
143 | /// start location of the specified range. | |||
144 | ASTEdit note(RangeSelector Anchor, TextGenerator Note); | |||
145 | ||||
146 | /// Version of `ifBound` specialized to `ASTEdit`. | |||
147 | inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit, | |||
148 | ASTEdit FalseEdit) { | |||
149 | return ifBound(std::move(ID), edit(std::move(TrueEdit)), | |||
150 | edit(std::move(FalseEdit))); | |||
151 | } | |||
152 | ||||
153 | /// Version of `ifBound` that has no "False" branch. If the node is not bound, | |||
154 | /// then no edits are produced. | |||
155 | inline EditGenerator ifBound(std::string ID, ASTEdit TrueEdit) { | |||
156 | return ifBound(std::move(ID), edit(std::move(TrueEdit)), noEdits()); | |||
157 | } | |||
158 | ||||
159 | /// Flattens a list of generators into a single generator whose elements are the | |||
160 | /// concatenation of the results of the argument generators. | |||
161 | EditGenerator flattenVector(SmallVector<EditGenerator, 2> Generators); | |||
162 | ||||
163 | namespace detail { | |||
164 | /// Helper function to construct an \c EditGenerator. Overloaded for common | |||
165 | /// cases so that user doesn't need to specify which factory function to | |||
166 | /// use. This pattern gives benefits similar to implicit constructors, while | |||
167 | /// maintaing a higher degree of explicitness. | |||
168 | inline EditGenerator injectEdits(ASTEdit E) { return edit(std::move(E)); } | |||
169 | inline EditGenerator injectEdits(EditGenerator G) { return G; } | |||
170 | } // namespace detail | |||
171 | ||||
172 | template <typename... Ts> EditGenerator flatten(Ts &&...Edits) { | |||
173 | return flattenVector({detail::injectEdits(std::forward<Ts>(Edits))...}); | |||
174 | } | |||
| ||||
175 | ||||
176 | // Every rewrite rule is triggered by a match against some AST node. | |||
177 | // Transformer guarantees that this ID is bound to the triggering node whenever | |||
178 | // a rewrite rule is applied. | |||
179 | extern const char RootID[]; | |||
180 | ||||
181 | /// Replaces a portion of the source text with \p Replacement. | |||
182 | ASTEdit changeTo(RangeSelector Target, TextGenerator Replacement); | |||
183 | /// DEPRECATED: use \c changeTo. | |||
184 | inline ASTEdit change(RangeSelector Target, TextGenerator Replacement) { | |||
185 | return changeTo(std::move(Target), std::move(Replacement)); | |||
186 | } | |||
187 | ||||
188 | /// Replaces the entirety of a RewriteRule's match with \p Replacement. For | |||
189 | /// example, to replace a function call, one could write: | |||
190 | /// \code | |||
191 | /// makeRule(callExpr(callee(functionDecl(hasName("foo")))), | |||
192 | /// changeTo(cat("bar()"))) | |||
193 | /// \endcode | |||
194 | inline ASTEdit changeTo(TextGenerator Replacement) { | |||
195 | return changeTo(node(RootID), std::move(Replacement)); | |||
196 | } | |||
197 | /// DEPRECATED: use \c changeTo. | |||
198 | inline ASTEdit change(TextGenerator Replacement) { | |||
199 | return changeTo(std::move(Replacement)); | |||
200 | } | |||
201 | ||||
202 | /// Inserts \p Replacement before \p S, leaving the source selected by \S | |||
203 | /// unchanged. | |||
204 | inline ASTEdit insertBefore(RangeSelector S, TextGenerator Replacement) { | |||
205 | return changeTo(before(std::move(S)), std::move(Replacement)); | |||
206 | } | |||
207 | ||||
208 | /// Inserts \p Replacement after \p S, leaving the source selected by \S | |||
209 | /// unchanged. | |||
210 | inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) { | |||
211 | return changeTo(after(std::move(S)), std::move(Replacement)); | |||
212 | } | |||
213 | ||||
214 | /// Removes the source selected by \p S. | |||
215 | ASTEdit remove(RangeSelector S); | |||
216 | ||||
217 | /// Adds an include directive for the given header to the file of `Target`. The | |||
218 | /// particular location specified by `Target` is ignored. | |||
219 | ASTEdit addInclude(RangeSelector Target, StringRef Header, | |||
220 | IncludeFormat Format = IncludeFormat::Quoted); | |||
221 | ||||
222 | /// Adds an include directive for the given header to the file associated with | |||
223 | /// `RootID`. If `RootID` matches inside a macro expansion, will add the | |||
224 | /// directive to the file in which the macro was expanded (as opposed to the | |||
225 | /// file in which the macro is defined). | |||
226 | inline ASTEdit addInclude(StringRef Header, | |||
227 | IncludeFormat Format = IncludeFormat::Quoted) { | |||
228 | return addInclude(expansion(node(RootID)), Header, Format); | |||
229 | } | |||
230 | ||||
231 | // FIXME: If `Metadata` returns an `llvm::Expected<T>` the `AnyGenerator` will | |||
232 | // construct an `llvm::Expected<llvm::Any>` where no error is present but the | |||
233 | // `llvm::Any` holds the error. This is unlikely but potentially surprising. | |||
234 | // Perhaps the `llvm::Expected` should be unwrapped, or perhaps this should be a | |||
235 | // compile-time error. No solution here is perfect. | |||
236 | // | |||
237 | // Note: This function template accepts any type callable with a MatchResult | |||
238 | // rather than a `std::function` because the return-type needs to be deduced. If | |||
239 | // it accepted a `std::function<R(MatchResult)>`, lambdas or other callable | |||
240 | // types would not be able to deduce `R`, and users would be forced to specify | |||
241 | // explicitly the type they intended to return by wrapping the lambda at the | |||
242 | // call-site. | |||
243 | template <typename Callable> | |||
244 | inline ASTEdit withMetadata(ASTEdit Edit, Callable Metadata) { | |||
245 | Edit.Metadata = | |||
246 | [Gen = std::move(Metadata)]( | |||
247 | const ast_matchers::MatchFinder::MatchResult &R) -> llvm::Any { | |||
248 | return Gen(R); | |||
249 | }; | |||
250 | ||||
251 | return Edit; | |||
252 | } | |||
253 | ||||
254 | /// Assuming that the inner range is enclosed by the outer range, creates | |||
255 | /// precision edits to remove the parts of the outer range that are not included | |||
256 | /// in the inner range. | |||
257 | inline EditGenerator shrinkTo(RangeSelector outer, RangeSelector inner) { | |||
258 | return editList({remove(enclose(before(outer), before(inner))), | |||
259 | remove(enclose(after(inner), after(outer)))}); | |||
260 | } | |||
261 | ||||
262 | /// Description of a source-code transformation. | |||
263 | // | |||
264 | // A *rewrite rule* describes a transformation of source code. A simple rule | |||
265 | // contains each of the following components: | |||
266 | // | |||
267 | // * Matcher: the pattern term, expressed as clang matchers (with Transformer | |||
268 | // extensions). | |||
269 | // | |||
270 | // * Edits: a set of Edits to the source code, described with ASTEdits. | |||
271 | // | |||
272 | // However, rules can also consist of (sub)rules, where the first that matches | |||
273 | // is applied and the rest are ignored. So, the above components together form | |||
274 | // a logical "case" and a rule is a sequence of cases. | |||
275 | // | |||
276 | // Rule cases have an additional, implicit, component: the parameters. These are | |||
277 | // portions of the pattern which are left unspecified, yet bound in the pattern | |||
278 | // so that we can reference them in the edits. | |||
279 | // | |||
280 | // The \c Transformer class can be used to apply the rewrite rule and obtain the | |||
281 | // corresponding replacements. | |||
282 | struct RewriteRuleBase { | |||
283 | struct Case { | |||
284 | ast_matchers::internal::DynTypedMatcher Matcher; | |||
285 | EditGenerator Edits; | |||
286 | }; | |||
287 | // We expect RewriteRules will most commonly include only one case. | |||
288 | SmallVector<Case, 1> Cases; | |||
289 | }; | |||
290 | ||||
291 | /// A source-code transformation with accompanying metadata. | |||
292 | /// | |||
293 | /// When a case of the rule matches, the \c Transformer invokes the | |||
294 | /// corresponding metadata generator and provides it alongside the edits. | |||
295 | template <typename MetadataT> struct RewriteRuleWith : RewriteRuleBase { | |||
296 | SmallVector<Generator<MetadataT>, 1> Metadata; | |||
297 | }; | |||
298 | ||||
299 | template <> struct RewriteRuleWith<void> : RewriteRuleBase {}; | |||
300 | ||||
301 | using RewriteRule = RewriteRuleWith<void>; | |||
302 | ||||
303 | namespace detail { | |||
304 | ||||
305 | RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
306 | EditGenerator Edits); | |||
307 | ||||
308 | template <typename MetadataT> | |||
309 | RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
310 | EditGenerator Edits, | |||
311 | Generator<MetadataT> Metadata) { | |||
312 | RewriteRuleWith<MetadataT> R; | |||
313 | R.Cases = {{std::move(M), std::move(Edits)}}; | |||
314 | R.Metadata = {std::move(Metadata)}; | |||
315 | return R; | |||
316 | } | |||
317 | ||||
318 | inline EditGenerator makeEditGenerator(EditGenerator Edits) { return Edits; } | |||
319 | EditGenerator makeEditGenerator(llvm::SmallVector<ASTEdit, 1> Edits); | |||
320 | EditGenerator makeEditGenerator(ASTEdit Edit); | |||
321 | ||||
322 | } // namespace detail | |||
323 | ||||
324 | /// Constructs a simple \c RewriteRule. \c Edits can be an \c EditGenerator, | |||
325 | /// multiple \c ASTEdits, or a single \c ASTEdit. | |||
326 | /// @{ | |||
327 | template <int &..., typename EditsT> | |||
328 | RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
329 | EditsT &&Edits) { | |||
330 | return detail::makeRule( | |||
331 | std::move(M), detail::makeEditGenerator(std::forward<EditsT>(Edits))); | |||
332 | } | |||
333 | ||||
334 | RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
335 | std::initializer_list<ASTEdit> Edits); | |||
336 | /// @} | |||
337 | ||||
338 | /// Overloads of \c makeRule that also generate metadata when matching. | |||
339 | /// @{ | |||
340 | template <typename MetadataT, int &..., typename EditsT> | |||
341 | RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
342 | EditsT &&Edits, | |||
343 | Generator<MetadataT> Metadata) { | |||
344 | return detail::makeRule( | |||
345 | std::move(M), detail::makeEditGenerator(std::forward<EditsT>(Edits)), | |||
346 | std::move(Metadata)); | |||
347 | } | |||
348 | ||||
349 | template <typename MetadataT> | |||
350 | RewriteRuleWith<MetadataT> makeRule(ast_matchers::internal::DynTypedMatcher M, | |||
351 | std::initializer_list<ASTEdit> Edits, | |||
352 | Generator<MetadataT> Metadata) { | |||
353 | return detail::makeRule(std::move(M), | |||
354 | detail::makeEditGenerator(std::move(Edits)), | |||
355 | std::move(Metadata)); | |||
356 | } | |||
357 | /// @} | |||
358 | ||||
359 | /// For every case in Rule, adds an include directive for the given header. The | |||
360 | /// common use is assumed to be a rule with only one case. For example, to | |||
361 | /// replace a function call and add headers corresponding to the new code, one | |||
362 | /// could write: | |||
363 | /// \code | |||
364 | /// auto R = makeRule(callExpr(callee(functionDecl(hasName("foo")))), | |||
365 | /// changeTo(cat("bar()"))); | |||
366 | /// addInclude(R, "path/to/bar_header.h"); | |||
367 | /// addInclude(R, "vector", IncludeFormat::Angled); | |||
368 | /// \endcode | |||
369 | void addInclude(RewriteRuleBase &Rule, llvm::StringRef Header, | |||
370 | IncludeFormat Format = IncludeFormat::Quoted); | |||
371 | ||||
372 | /// Applies the first rule whose pattern matches; other rules are ignored. If | |||
373 | /// the matchers are independent then order doesn't matter. In that case, | |||
374 | /// `applyFirst` is simply joining the set of rules into one. | |||
375 | // | |||
376 | // `applyFirst` is like an `anyOf` matcher with an edit action attached to each | |||
377 | // of its cases. Anywhere you'd use `anyOf(m1.bind("id1"), m2.bind("id2"))` and | |||
378 | // then dispatch on those ids in your code for control flow, `applyFirst` lifts | |||
379 | // that behavior to the rule level. So, you can write `applyFirst({makeRule(m1, | |||
380 | // action1), makeRule(m2, action2), ...});` | |||
381 | // | |||
382 | // For example, consider a type `T` with a deterministic serialization function, | |||
383 | // `serialize()`. For performance reasons, we would like to make it | |||
384 | // non-deterministic. Therefore, we want to drop the expectation that | |||
385 | // `a.serialize() = b.serialize() iff a = b` (although we'll maintain | |||
386 | // `deserialize(a.serialize()) = a`). | |||
387 | // | |||
388 | // We have three cases to consider (for some equality function, `eq`): | |||
389 | // ``` | |||
390 | // eq(a.serialize(), b.serialize()) --> eq(a,b) | |||
391 | // eq(a, b.serialize()) --> eq(deserialize(a), b) | |||
392 | // eq(a.serialize(), b) --> eq(a, deserialize(b)) | |||
393 | // ``` | |||
394 | // | |||
395 | // `applyFirst` allows us to specify each independently: | |||
396 | // ``` | |||
397 | // auto eq_fun = functionDecl(...); | |||
398 | // auto method_call = cxxMemberCallExpr(...); | |||
399 | // | |||
400 | // auto two_calls = callExpr(callee(eq_fun), hasArgument(0, method_call), | |||
401 | // hasArgument(1, method_call)); | |||
402 | // auto left_call = | |||
403 | // callExpr(callee(eq_fun), callExpr(hasArgument(0, method_call))); | |||
404 | // auto right_call = | |||
405 | // callExpr(callee(eq_fun), callExpr(hasArgument(1, method_call))); | |||
406 | // | |||
407 | // RewriteRule R = applyFirst({makeRule(two_calls, two_calls_action), | |||
408 | // makeRule(left_call, left_call_action), | |||
409 | // makeRule(right_call, right_call_action)}); | |||
410 | // ``` | |||
411 | /// @{ | |||
412 | template <typename MetadataT> | |||
413 | RewriteRuleWith<MetadataT> | |||
414 | applyFirst(ArrayRef<RewriteRuleWith<MetadataT>> Rules) { | |||
415 | RewriteRuleWith<MetadataT> R; | |||
416 | for (auto &Rule : Rules) { | |||
417 | assert(Rule.Cases.size() == Rule.Metadata.size() &&(static_cast <bool> (Rule.Cases.size() == Rule.Metadata .size() && "mis-match in case and metadata array size" ) ? void (0) : __assert_fail ("Rule.Cases.size() == Rule.Metadata.size() && \"mis-match in case and metadata array size\"" , "clang/include/clang/Tooling/Transformer/RewriteRule.h", 418 , __extension__ __PRETTY_FUNCTION__)) | |||
418 | "mis-match in case and metadata array size")(static_cast <bool> (Rule.Cases.size() == Rule.Metadata .size() && "mis-match in case and metadata array size" ) ? void (0) : __assert_fail ("Rule.Cases.size() == Rule.Metadata.size() && \"mis-match in case and metadata array size\"" , "clang/include/clang/Tooling/Transformer/RewriteRule.h", 418 , __extension__ __PRETTY_FUNCTION__)); | |||
419 | R.Cases.append(Rule.Cases.begin(), Rule.Cases.end()); | |||
420 | R.Metadata.append(Rule.Metadata.begin(), Rule.Metadata.end()); | |||
421 | } | |||
422 | return R; | |||
423 | } | |||
424 | ||||
425 | template <> | |||
426 | RewriteRuleWith<void> applyFirst(ArrayRef<RewriteRuleWith<void>> Rules); | |||
427 | ||||
428 | template <typename MetadataT> | |||
429 | RewriteRuleWith<MetadataT> | |||
430 | applyFirst(const std::vector<RewriteRuleWith<MetadataT>> &Rules) { | |||
431 | return applyFirst(llvm::ArrayRef(Rules)); | |||
432 | } | |||
433 | ||||
434 | template <typename MetadataT> | |||
435 | RewriteRuleWith<MetadataT> | |||
436 | applyFirst(std::initializer_list<RewriteRuleWith<MetadataT>> Rules) { | |||
437 | return applyFirst(llvm::ArrayRef(Rules.begin(), Rules.end())); | |||
438 | } | |||
439 | /// @} | |||
440 | ||||
441 | /// Converts a \c RewriteRuleWith<T> to a \c RewriteRule by stripping off the | |||
442 | /// metadata generators. | |||
443 | template <int &..., typename MetadataT> | |||
444 | std::enable_if_t<!std::is_same<MetadataT, void>::value, RewriteRule> | |||
445 | stripMetadata(RewriteRuleWith<MetadataT> Rule) { | |||
446 | RewriteRule R; | |||
447 | R.Cases = std::move(Rule.Cases); | |||
448 | return R; | |||
449 | } | |||
450 | ||||
451 | /// Applies `Rule` to all descendants of the node bound to `NodeId`. `Rule` can | |||
452 | /// refer to nodes bound by the calling rule. `Rule` is not applied to the node | |||
453 | /// itself. | |||
454 | /// | |||
455 | /// For example, | |||
456 | /// ``` | |||
457 | /// auto InlineX = | |||
458 | /// makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3"))); | |||
459 | /// makeRule(functionDecl(hasName("f"), hasBody(stmt().bind("body"))).bind("f"), | |||
460 | /// flatten( | |||
461 | /// changeTo(name("f"), cat("newName")), | |||
462 | /// rewriteDescendants("body", InlineX))); | |||
463 | /// ``` | |||
464 | /// Here, we find the function `f`, change its name to `newName` and change all | |||
465 | /// appearances of `x` in its body to `3`. | |||
466 | EditGenerator rewriteDescendants(std::string NodeId, RewriteRule Rule); | |||
467 | ||||
468 | /// The following three functions are a low-level part of the RewriteRule | |||
469 | /// API. We expose them for use in implementing the fixtures that interpret | |||
470 | /// RewriteRule, like Transformer and TransfomerTidy, or for more advanced | |||
471 | /// users. | |||
472 | // | |||
473 | // FIXME: These functions are really public, if advanced, elements of the | |||
474 | // RewriteRule API. Recast them as such. Or, just declare these functions | |||
475 | // public and well-supported and move them out of `detail`. | |||
476 | namespace detail { | |||
477 | /// The following overload set is a version of `rewriteDescendants` that | |||
478 | /// operates directly on the AST, rather than generating a Transformer | |||
479 | /// combinator. It applies `Rule` to all descendants of `Node`, although not | |||
480 | /// `Node` itself. `Rule` can refer to nodes bound in `Result`. | |||
481 | /// | |||
482 | /// For example, assuming that "body" is bound to a function body in MatchResult | |||
483 | /// `Results`, this will produce edits to change all appearances of `x` in that | |||
484 | /// body to `3`. | |||
485 | /// ``` | |||
486 | /// auto InlineX = | |||
487 | /// makeRule(declRefExpr(to(varDecl(hasName("x")))), changeTo(cat("3"))); | |||
488 | /// const auto *Node = Results.Nodes.getNodeAs<Stmt>("body"); | |||
489 | /// auto Edits = rewriteDescendants(*Node, InlineX, Results); | |||
490 | /// ``` | |||
491 | /// @{ | |||
492 | llvm::Expected<SmallVector<Edit, 1>> | |||
493 | rewriteDescendants(const Decl &Node, RewriteRule Rule, | |||
494 | const ast_matchers::MatchFinder::MatchResult &Result); | |||
495 | ||||
496 | llvm::Expected<SmallVector<Edit, 1>> | |||
497 | rewriteDescendants(const Stmt &Node, RewriteRule Rule, | |||
498 | const ast_matchers::MatchFinder::MatchResult &Result); | |||
499 | ||||
500 | llvm::Expected<SmallVector<Edit, 1>> | |||
501 | rewriteDescendants(const TypeLoc &Node, RewriteRule Rule, | |||
502 | const ast_matchers::MatchFinder::MatchResult &Result); | |||
503 | ||||
504 | llvm::Expected<SmallVector<Edit, 1>> | |||
505 | rewriteDescendants(const DynTypedNode &Node, RewriteRule Rule, | |||
506 | const ast_matchers::MatchFinder::MatchResult &Result); | |||
507 | /// @} | |||
508 | ||||
509 | /// Builds a single matcher for the rule, covering all of the rule's cases. | |||
510 | /// Only supports Rules whose cases' matchers share the same base "kind" | |||
511 | /// (`Stmt`, `Decl`, etc.) Deprecated: use `buildMatchers` instead, which | |||
512 | /// supports mixing matchers of different kinds. | |||
513 | ast_matchers::internal::DynTypedMatcher | |||
514 | buildMatcher(const RewriteRuleBase &Rule); | |||
515 | ||||
516 | /// Builds a set of matchers that cover the rule. | |||
517 | /// | |||
518 | /// One matcher is built for each distinct node matcher base kind: Stmt, Decl, | |||
519 | /// etc. Node-matchers for `QualType` and `Type` are not permitted, since such | |||
520 | /// nodes carry no source location information and are therefore not relevant | |||
521 | /// for rewriting. If any such matchers are included, will return an empty | |||
522 | /// vector. | |||
523 | std::vector<ast_matchers::internal::DynTypedMatcher> | |||
524 | buildMatchers(const RewriteRuleBase &Rule); | |||
525 | ||||
526 | /// Gets the beginning location of the source matched by a rewrite rule. If the | |||
527 | /// match occurs within a macro expansion, returns the beginning of the | |||
528 | /// expansion point. `Result` must come from the matching of a rewrite rule. | |||
529 | SourceLocation | |||
530 | getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result); | |||
531 | ||||
532 | /// Returns the index of the \c Case of \c Rule that was selected in the match | |||
533 | /// result. Assumes a matcher built with \c buildMatcher. | |||
534 | size_t findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result, | |||
535 | const RewriteRuleBase &Rule); | |||
536 | } // namespace detail | |||
537 | } // namespace transformer | |||
538 | } // namespace clang | |||
539 | ||||
540 | #endif // LLVM_CLANG_TOOLING_TRANSFORMER_REWRITERULE_H |
1 | // Implementation of std::function -*- C++ -*- |
2 | |
3 | // Copyright (C) 2004-2020 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file include/bits/std_function.h |
26 | * This is an internal header file, included by other library headers. |
27 | * Do not attempt to use it directly. @headername{functional} |
28 | */ |
29 | |
30 | #ifndef _GLIBCXX_STD_FUNCTION_H1 |
31 | #define _GLIBCXX_STD_FUNCTION_H1 1 |
32 | |
33 | #pragma GCC system_header |
34 | |
35 | #if __cplusplus201703L < 201103L |
36 | # include <bits/c++0x_warning.h> |
37 | #else |
38 | |
39 | #if __cpp_rtti199711L |
40 | # include <typeinfo> |
41 | #endif |
42 | #include <bits/stl_function.h> |
43 | #include <bits/invoke.h> |
44 | #include <bits/refwrap.h> |
45 | #include <bits/functexcept.h> |
46 | |
47 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
48 | { |
49 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
50 | |
51 | /** |
52 | * @brief Exception class thrown when class template function's |
53 | * operator() is called with an empty target. |
54 | * @ingroup exceptions |
55 | */ |
56 | class bad_function_call : public std::exception |
57 | { |
58 | public: |
59 | virtual ~bad_function_call() noexcept; |
60 | |
61 | const char* what() const noexcept; |
62 | }; |
63 | |
64 | /** |
65 | * Trait identifying "location-invariant" types, meaning that the |
66 | * address of the object (or any of its members) will not escape. |
67 | * Trivially copyable types are location-invariant and users can |
68 | * specialize this trait for other types. |
69 | */ |
70 | template<typename _Tp> |
71 | struct __is_location_invariant |
72 | : is_trivially_copyable<_Tp>::type |
73 | { }; |
74 | |
75 | class _Undefined_class; |
76 | |
77 | union _Nocopy_types |
78 | { |
79 | void* _M_object; |
80 | const void* _M_const_object; |
81 | void (*_M_function_pointer)(); |
82 | void (_Undefined_class::*_M_member_pointer)(); |
83 | }; |
84 | |
85 | union [[gnu::may_alias]] _Any_data |
86 | { |
87 | void* _M_access() { return &_M_pod_data[0]; } |
88 | const void* _M_access() const { return &_M_pod_data[0]; } |
89 | |
90 | template<typename _Tp> |
91 | _Tp& |
92 | _M_access() |
93 | { return *static_cast<_Tp*>(_M_access()); } |
94 | |
95 | template<typename _Tp> |
96 | const _Tp& |
97 | _M_access() const |
98 | { return *static_cast<const _Tp*>(_M_access()); } |
99 | |
100 | _Nocopy_types _M_unused; |
101 | char _M_pod_data[sizeof(_Nocopy_types)]; |
102 | }; |
103 | |
104 | enum _Manager_operation |
105 | { |
106 | __get_type_info, |
107 | __get_functor_ptr, |
108 | __clone_functor, |
109 | __destroy_functor |
110 | }; |
111 | |
112 | template<typename _Signature> |
113 | class function; |
114 | |
115 | /// Base class of all polymorphic function object wrappers. |
116 | class _Function_base |
117 | { |
118 | public: |
119 | static const size_t _M_max_size = sizeof(_Nocopy_types); |
120 | static const size_t _M_max_align = __alignof__(_Nocopy_types); |
121 | |
122 | template<typename _Functor> |
123 | class _Base_manager |
124 | { |
125 | protected: |
126 | static const bool __stored_locally = |
127 | (__is_location_invariant<_Functor>::value |
128 | && sizeof(_Functor) <= _M_max_size |
129 | && __alignof__(_Functor) <= _M_max_align |
130 | && (_M_max_align % __alignof__(_Functor) == 0)); |
131 | |
132 | typedef integral_constant<bool, __stored_locally> _Local_storage; |
133 | |
134 | // Retrieve a pointer to the function object |
135 | static _Functor* |
136 | _M_get_pointer(const _Any_data& __source) |
137 | { |
138 | if _GLIBCXX17_CONSTEXPRconstexpr (__stored_locally) |
139 | { |
140 | const _Functor& __f = __source._M_access<_Functor>(); |
141 | return const_cast<_Functor*>(std::__addressof(__f)); |
142 | } |
143 | else // have stored a pointer |
144 | return __source._M_access<_Functor*>(); |
145 | } |
146 | |
147 | // Clone a location-invariant function object that fits within |
148 | // an _Any_data structure. |
149 | static void |
150 | _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) |
151 | { |
152 | ::new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); |
153 | } |
154 | |
155 | // Clone a function object that is not location-invariant or |
156 | // that cannot fit into an _Any_data structure. |
157 | static void |
158 | _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) |
159 | { |
160 | __dest._M_access<_Functor*>() = |
161 | new _Functor(*__source._M_access<const _Functor*>()); |
162 | } |
163 | |
164 | // Destroying a location-invariant object may still require |
165 | // destruction. |
166 | static void |
167 | _M_destroy(_Any_data& __victim, true_type) |
168 | { |
169 | __victim._M_access<_Functor>().~_Functor(); |
170 | } |
171 | |
172 | // Destroying an object located on the heap. |
173 | static void |
174 | _M_destroy(_Any_data& __victim, false_type) |
175 | { |
176 | delete __victim._M_access<_Functor*>(); |
177 | } |
178 | |
179 | public: |
180 | static bool |
181 | _M_manager(_Any_data& __dest, const _Any_data& __source, |
182 | _Manager_operation __op) |
183 | { |
184 | switch (__op) |
185 | { |
186 | #if __cpp_rtti199711L |
187 | case __get_type_info: |
188 | __dest._M_access<const type_info*>() = &typeid(_Functor); |
189 | break; |
190 | #endif |
191 | case __get_functor_ptr: |
192 | __dest._M_access<_Functor*>() = _M_get_pointer(__source); |
193 | break; |
194 | |
195 | case __clone_functor: |
196 | _M_clone(__dest, __source, _Local_storage()); |
197 | break; |
198 | |
199 | case __destroy_functor: |
200 | _M_destroy(__dest, _Local_storage()); |
201 | break; |
202 | } |
203 | return false; |
204 | } |
205 | |
206 | static void |
207 | _M_init_functor(_Any_data& __functor, _Functor&& __f) |
208 | { _M_init_functor(__functor, std::move(__f), _Local_storage()); } |
209 | |
210 | template<typename _Signature> |
211 | static bool |
212 | _M_not_empty_function(const function<_Signature>& __f) |
213 | { return static_cast<bool>(__f); } |
214 | |
215 | template<typename _Tp> |
216 | static bool |
217 | _M_not_empty_function(_Tp* __fp) |
218 | { return __fp != nullptr; } |
219 | |
220 | template<typename _Class, typename _Tp> |
221 | static bool |
222 | _M_not_empty_function(_Tp _Class::* __mp) |
223 | { return __mp != nullptr; } |
224 | |
225 | template<typename _Tp> |
226 | static bool |
227 | _M_not_empty_function(const _Tp&) |
228 | { return true; } |
229 | |
230 | private: |
231 | static void |
232 | _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type) |
233 | { ::new (__functor._M_access()) _Functor(std::move(__f)); } |
234 | |
235 | static void |
236 | _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type) |
237 | { __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); } |
238 | }; |
239 | |
240 | _Function_base() : _M_manager(nullptr) { } |
241 | |
242 | ~_Function_base() |
243 | { |
244 | if (_M_manager) |
245 | _M_manager(_M_functor, _M_functor, __destroy_functor); |
246 | } |
247 | |
248 | bool _M_empty() const { return !_M_manager; } |
249 | |
250 | typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, |
251 | _Manager_operation); |
252 | |
253 | _Any_data _M_functor; |
254 | _Manager_type _M_manager; |
255 | }; |
256 | |
257 | template<typename _Signature, typename _Functor> |
258 | class _Function_handler; |
259 | |
260 | template<typename _Res, typename _Functor, typename... _ArgTypes> |
261 | class _Function_handler<_Res(_ArgTypes...), _Functor> |
262 | : public _Function_base::_Base_manager<_Functor> |
263 | { |
264 | typedef _Function_base::_Base_manager<_Functor> _Base; |
265 | |
266 | public: |
267 | static bool |
268 | _M_manager(_Any_data& __dest, const _Any_data& __source, |
269 | _Manager_operation __op) |
270 | { |
271 | switch (__op) |
272 | { |
273 | #if __cpp_rtti199711L |
274 | case __get_type_info: |
275 | __dest._M_access<const type_info*>() = &typeid(_Functor); |
276 | break; |
277 | #endif |
278 | case __get_functor_ptr: |
279 | __dest._M_access<_Functor*>() = _Base::_M_get_pointer(__source); |
280 | break; |
281 | |
282 | default: |
283 | _Base::_M_manager(__dest, __source, __op); |
284 | } |
285 | return false; |
286 | } |
287 | |
288 | static _Res |
289 | _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args) |
290 | { |
291 | return std::__invoke_r<_Res>(*_Base::_M_get_pointer(__functor), |
292 | std::forward<_ArgTypes>(__args)...); |
293 | } |
294 | }; |
295 | |
296 | /** |
297 | * @brief Primary class template for std::function. |
298 | * @ingroup functors |
299 | * |
300 | * Polymorphic function wrapper. |
301 | */ |
302 | template<typename _Res, typename... _ArgTypes> |
303 | class function<_Res(_ArgTypes...)> |
304 | : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>, |
305 | private _Function_base |
306 | { |
307 | template<typename _Func, |
308 | typename _Res2 = __invoke_result<_Func&, _ArgTypes...>> |
309 | struct _Callable |
310 | : __is_invocable_impl<_Res2, _Res>::type |
311 | { }; |
312 | |
313 | // Used so the return type convertibility checks aren't done when |
314 | // performing overload resolution for copy construction/assignment. |
315 | template<typename _Tp> |
316 | struct _Callable<function, _Tp> : false_type { }; |
317 | |
318 | template<typename _Cond, typename _Tp> |
319 | using _Requires = typename enable_if<_Cond::value, _Tp>::type; |
320 | |
321 | public: |
322 | typedef _Res result_type; |
323 | |
324 | // [3.7.2.1] construct/copy/destroy |
325 | |
326 | /** |
327 | * @brief Default construct creates an empty function call wrapper. |
328 | * @post @c !(bool)*this |
329 | */ |
330 | function() noexcept |
331 | : _Function_base() { } |
332 | |
333 | /** |
334 | * @brief Creates an empty function call wrapper. |
335 | * @post @c !(bool)*this |
336 | */ |
337 | function(nullptr_t) noexcept |
338 | : _Function_base() { } |
339 | |
340 | /** |
341 | * @brief %Function copy constructor. |
342 | * @param __x A %function object with identical call signature. |
343 | * @post @c bool(*this) == bool(__x) |
344 | * |
345 | * The newly-created %function contains a copy of the target of @a |
346 | * __x (if it has one). |
347 | */ |
348 | function(const function& __x); |
349 | |
350 | /** |
351 | * @brief %Function move constructor. |
352 | * @param __x A %function object rvalue with identical call signature. |
353 | * |
354 | * The newly-created %function contains the target of @a __x |
355 | * (if it has one). |
356 | */ |
357 | function(function&& __x) noexcept : _Function_base() |
358 | { |
359 | __x.swap(*this); |
360 | } |
361 | |
362 | /** |
363 | * @brief Builds a %function that targets a copy of the incoming |
364 | * function object. |
365 | * @param __f A %function object that is callable with parameters of |
366 | * type @c T1, @c T2, ..., @c TN and returns a value convertible |
367 | * to @c Res. |
368 | * |
369 | * The newly-created %function object will target a copy of |
370 | * @a __f. If @a __f is @c reference_wrapper<F>, then this function |
371 | * object will contain a reference to the function object @c |
372 | * __f.get(). If @a __f is a NULL function pointer or NULL |
373 | * pointer-to-member, the newly-created object will be empty. |
374 | * |
375 | * If @a __f is a non-NULL function pointer or an object of type @c |
376 | * reference_wrapper<F>, this function will not throw. |
377 | */ |
378 | template<typename _Functor, |
379 | typename = _Requires<__not_<is_same<_Functor, function>>, void>, |
380 | typename = _Requires<_Callable<_Functor>, void>> |
381 | function(_Functor); |
382 | |
383 | /** |
384 | * @brief %Function assignment operator. |
385 | * @param __x A %function with identical call signature. |
386 | * @post @c (bool)*this == (bool)x |
387 | * @returns @c *this |
388 | * |
389 | * The target of @a __x is copied to @c *this. If @a __x has no |
390 | * target, then @c *this will be empty. |
391 | * |
392 | * If @a __x targets a function pointer or a reference to a function |
393 | * object, then this operation will not throw an %exception. |
394 | */ |
395 | function& |
396 | operator=(const function& __x) |
397 | { |
398 | function(__x).swap(*this); |
399 | return *this; |
400 | } |
401 | |
402 | /** |
403 | * @brief %Function move-assignment operator. |
404 | * @param __x A %function rvalue with identical call signature. |
405 | * @returns @c *this |
406 | * |
407 | * The target of @a __x is moved to @c *this. If @a __x has no |
408 | * target, then @c *this will be empty. |
409 | * |
410 | * If @a __x targets a function pointer or a reference to a function |
411 | * object, then this operation will not throw an %exception. |
412 | */ |
413 | function& |
414 | operator=(function&& __x) noexcept |
415 | { |
416 | function(std::move(__x)).swap(*this); |
417 | return *this; |
418 | } |
419 | |
420 | /** |
421 | * @brief %Function assignment to zero. |
422 | * @post @c !(bool)*this |
423 | * @returns @c *this |
424 | * |
425 | * The target of @c *this is deallocated, leaving it empty. |
426 | */ |
427 | function& |
428 | operator=(nullptr_t) noexcept |
429 | { |
430 | if (_M_manager) |
431 | { |
432 | _M_manager(_M_functor, _M_functor, __destroy_functor); |
433 | _M_manager = nullptr; |
434 | _M_invoker = nullptr; |
435 | } |
436 | return *this; |
437 | } |
438 | |
439 | /** |
440 | * @brief %Function assignment to a new target. |
441 | * @param __f A %function object that is callable with parameters of |
442 | * type @c T1, @c T2, ..., @c TN and returns a value convertible |
443 | * to @c Res. |
444 | * @return @c *this |
445 | * |
446 | * This %function object wrapper will target a copy of @a |
447 | * __f. If @a __f is @c reference_wrapper<F>, then this function |
448 | * object will contain a reference to the function object @c |
449 | * __f.get(). If @a __f is a NULL function pointer or NULL |
450 | * pointer-to-member, @c this object will be empty. |
451 | * |
452 | * If @a __f is a non-NULL function pointer or an object of type @c |
453 | * reference_wrapper<F>, this function will not throw. |
454 | */ |
455 | template<typename _Functor> |
456 | _Requires<_Callable<typename decay<_Functor>::type>, function&> |
457 | operator=(_Functor&& __f) |
458 | { |
459 | function(std::forward<_Functor>(__f)).swap(*this); |
460 | return *this; |
461 | } |
462 | |
463 | /// @overload |
464 | template<typename _Functor> |
465 | function& |
466 | operator=(reference_wrapper<_Functor> __f) noexcept |
467 | { |
468 | function(__f).swap(*this); |
469 | return *this; |
470 | } |
471 | |
472 | // [3.7.2.2] function modifiers |
473 | |
474 | /** |
475 | * @brief Swap the targets of two %function objects. |
476 | * @param __x A %function with identical call signature. |
477 | * |
478 | * Swap the targets of @c this function object and @a __f. This |
479 | * function will not throw an %exception. |
480 | */ |
481 | void swap(function& __x) noexcept |
482 | { |
483 | std::swap(_M_functor, __x._M_functor); |
484 | std::swap(_M_manager, __x._M_manager); |
485 | std::swap(_M_invoker, __x._M_invoker); |
486 | } |
487 | |
488 | // [3.7.2.3] function capacity |
489 | |
490 | /** |
491 | * @brief Determine if the %function wrapper has a target. |
492 | * |
493 | * @return @c true when this %function object contains a target, |
494 | * or @c false when it is empty. |
495 | * |
496 | * This function will not throw an %exception. |
497 | */ |
498 | explicit operator bool() const noexcept |
499 | { return !_M_empty(); } |
500 | |
501 | // [3.7.2.4] function invocation |
502 | |
503 | /** |
504 | * @brief Invokes the function targeted by @c *this. |
505 | * @returns the result of the target. |
506 | * @throws bad_function_call when @c !(bool)*this |
507 | * |
508 | * The function call operator invokes the target function object |
509 | * stored by @c this. |
510 | */ |
511 | _Res operator()(_ArgTypes... __args) const; |
512 | |
513 | #if __cpp_rtti199711L |
514 | // [3.7.2.5] function target access |
515 | /** |
516 | * @brief Determine the type of the target of this function object |
517 | * wrapper. |
518 | * |
519 | * @returns the type identifier of the target function object, or |
520 | * @c typeid(void) if @c !(bool)*this. |
521 | * |
522 | * This function will not throw an %exception. |
523 | */ |
524 | const type_info& target_type() const noexcept; |
525 | |
526 | /** |
527 | * @brief Access the stored target function object. |
528 | * |
529 | * @return Returns a pointer to the stored target function object, |
530 | * if @c typeid(_Functor).equals(target_type()); otherwise, a NULL |
531 | * pointer. |
532 | * |
533 | * This function does not throw exceptions. |
534 | * |
535 | * @{ |
536 | */ |
537 | template<typename _Functor> _Functor* target() noexcept; |
538 | |
539 | template<typename _Functor> const _Functor* target() const noexcept; |
540 | // @} |
541 | #endif |
542 | |
543 | private: |
544 | using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...); |
545 | _Invoker_type _M_invoker; |
546 | }; |
547 | |
548 | #if __cpp_deduction_guides201703L >= 201606 |
549 | template<typename> |
550 | struct __function_guide_helper |
551 | { }; |
552 | |
553 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
554 | struct __function_guide_helper< |
555 | _Res (_Tp::*) (_Args...) noexcept(_Nx) |
556 | > |
557 | { using type = _Res(_Args...); }; |
558 | |
559 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
560 | struct __function_guide_helper< |
561 | _Res (_Tp::*) (_Args...) & noexcept(_Nx) |
562 | > |
563 | { using type = _Res(_Args...); }; |
564 | |
565 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
566 | struct __function_guide_helper< |
567 | _Res (_Tp::*) (_Args...) const noexcept(_Nx) |
568 | > |
569 | { using type = _Res(_Args...); }; |
570 | |
571 | template<typename _Res, typename _Tp, bool _Nx, typename... _Args> |
572 | struct __function_guide_helper< |
573 | _Res (_Tp::*) (_Args...) const & noexcept(_Nx) |
574 | > |
575 | { using type = _Res(_Args...); }; |
576 | |
577 | template<typename _Res, typename... _ArgTypes> |
578 | function(_Res(*)(_ArgTypes...)) -> function<_Res(_ArgTypes...)>; |
579 | |
580 | template<typename _Functor, typename _Signature = typename |
581 | __function_guide_helper<decltype(&_Functor::operator())>::type> |
582 | function(_Functor) -> function<_Signature>; |
583 | #endif |
584 | |
585 | // Out-of-line member definitions. |
586 | template<typename _Res, typename... _ArgTypes> |
587 | function<_Res(_ArgTypes...)>:: |
588 | function(const function& __x) |
589 | : _Function_base() |
590 | { |
591 | if (static_cast<bool>(__x)) |
592 | { |
593 | __x._M_manager(_M_functor, __x._M_functor, __clone_functor); |
594 | _M_invoker = __x._M_invoker; |
595 | _M_manager = __x._M_manager; |
596 | } |
597 | } |
598 | |
599 | template<typename _Res, typename... _ArgTypes> |
600 | template<typename _Functor, typename, typename> |
601 | function<_Res(_ArgTypes...)>:: |
602 | function(_Functor __f) |
603 | : _Function_base() |
604 | { |
605 | typedef _Function_handler<_Res(_ArgTypes...), _Functor> _My_handler; |
606 | |
607 | if (_My_handler::_M_not_empty_function(__f)) |
608 | { |
609 | _My_handler::_M_init_functor(_M_functor, std::move(__f)); |
610 | _M_invoker = &_My_handler::_M_invoke; |
611 | _M_manager = &_My_handler::_M_manager; |
612 | } |
613 | } |
614 | |
615 | template<typename _Res, typename... _ArgTypes> |
616 | _Res |
617 | function<_Res(_ArgTypes...)>:: |
618 | operator()(_ArgTypes... __args) const |
619 | { |
620 | if (_M_empty()) |
621 | __throw_bad_function_call(); |
622 | return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...); |
623 | } |
624 | |
625 | #if __cpp_rtti199711L |
626 | template<typename _Res, typename... _ArgTypes> |
627 | const type_info& |
628 | function<_Res(_ArgTypes...)>:: |
629 | target_type() const noexcept |
630 | { |
631 | if (_M_manager) |
632 | { |
633 | _Any_data __typeinfo_result; |
634 | _M_manager(__typeinfo_result, _M_functor, __get_type_info); |
635 | return *__typeinfo_result._M_access<const type_info*>(); |
636 | } |
637 | else |
638 | return typeid(void); |
639 | } |
640 | |
641 | template<typename _Res, typename... _ArgTypes> |
642 | template<typename _Functor> |
643 | _Functor* |
644 | function<_Res(_ArgTypes...)>:: |
645 | target() noexcept |
646 | { |
647 | const function* __const_this = this; |
648 | const _Functor* __func = __const_this->template target<_Functor>(); |
649 | return const_cast<_Functor*>(__func); |
650 | } |
651 | |
652 | template<typename _Res, typename... _ArgTypes> |
653 | template<typename _Functor> |
654 | const _Functor* |
655 | function<_Res(_ArgTypes...)>:: |
656 | target() const noexcept |
657 | { |
658 | if (typeid(_Functor) == target_type() && _M_manager) |
659 | { |
660 | _Any_data __ptr; |
661 | _M_manager(__ptr, _M_functor, __get_functor_ptr); |
662 | return __ptr._M_access<const _Functor*>(); |
663 | } |
664 | else |
665 | return nullptr; |
666 | } |
667 | #endif |
668 | |
669 | // [20.7.15.2.6] null pointer comparisons |
670 | |
671 | /** |
672 | * @brief Compares a polymorphic function object wrapper against 0 |
673 | * (the NULL pointer). |
674 | * @returns @c true if the wrapper has no target, @c false otherwise |
675 | * |
676 | * This function will not throw an %exception. |
677 | */ |
678 | template<typename _Res, typename... _Args> |
679 | inline bool |
680 | operator==(const function<_Res(_Args...)>& __f, nullptr_t) noexcept |
681 | { return !static_cast<bool>(__f); } |
682 | |
683 | #if __cpp_impl_three_way_comparison < 201907L |
684 | /// @overload |
685 | template<typename _Res, typename... _Args> |
686 | inline bool |
687 | operator==(nullptr_t, const function<_Res(_Args...)>& __f) noexcept |
688 | { return !static_cast<bool>(__f); } |
689 | |
690 | /** |
691 | * @brief Compares a polymorphic function object wrapper against 0 |
692 | * (the NULL pointer). |
693 | * @returns @c false if the wrapper has no target, @c true otherwise |
694 | * |
695 | * This function will not throw an %exception. |
696 | */ |
697 | template<typename _Res, typename... _Args> |
698 | inline bool |
699 | operator!=(const function<_Res(_Args...)>& __f, nullptr_t) noexcept |
700 | { return static_cast<bool>(__f); } |
701 | |
702 | /// @overload |
703 | template<typename _Res, typename... _Args> |
704 | inline bool |
705 | operator!=(nullptr_t, const function<_Res(_Args...)>& __f) noexcept |
706 | { return static_cast<bool>(__f); } |
707 | #endif |
708 | |
709 | // [20.7.15.2.7] specialized algorithms |
710 | |
711 | /** |
712 | * @brief Swap the targets of two polymorphic function object wrappers. |
713 | * |
714 | * This function will not throw an %exception. |
715 | */ |
716 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
717 | // 2062. Effect contradictions w/o no-throw guarantee of std::function swaps |
718 | template<typename _Res, typename... _Args> |
719 | inline void |
720 | swap(function<_Res(_Args...)>& __x, function<_Res(_Args...)>& __y) noexcept |
721 | { __x.swap(__y); } |
722 | |
723 | #if __cplusplus201703L >= 201703L |
724 | namespace __detail::__variant |
725 | { |
726 | template<typename> struct _Never_valueless_alt; // see <variant> |
727 | |
728 | // Provide the strong exception-safety guarantee when emplacing a |
729 | // function into a variant. |
730 | template<typename _Signature> |
731 | struct _Never_valueless_alt<std::function<_Signature>> |
732 | : std::true_type |
733 | { }; |
734 | } // namespace __detail::__variant |
735 | #endif // C++17 |
736 | |
737 | _GLIBCXX_END_NAMESPACE_VERSION |
738 | } // namespace std |
739 | |
740 | #endif // C++11 |
741 | #endif // _GLIBCXX_STD_FUNCTION_H |