Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-expand-visitor.h"
20 : : #include "rust-ast-fragment.h"
21 : : #include "rust-hir-map.h"
22 : : #include "rust-item.h"
23 : : #include "rust-proc-macro.h"
24 : : #include "rust-attributes.h"
25 : : #include "rust-ast.h"
26 : : #include "rust-type.h"
27 : : #include "rust-derive.h"
28 : :
29 : : namespace Rust {
30 : :
31 : : bool
32 : 1253076 : is_builtin (AST::Attribute &attr)
33 : : {
34 : 1253076 : auto &segments = attr.get_path ().get_segments ();
35 : 1253076 : return !segments.empty ()
36 : 1253076 : && !Analysis::BuiltinAttributeMappings::get ()
37 : 1253076 : ->lookup_builtin (segments[0].get_segment_name ())
38 : 1253076 : .is_error ();
39 : : }
40 : :
41 : : /* Expand all of the macro invocations currently contained in a crate */
42 : : void
43 : 10315 : ExpandVisitor::go (AST::Crate &crate)
44 : : {
45 : 10315 : visit (crate);
46 : 10315 : }
47 : :
48 : : static std::vector<std::unique_ptr<AST::Item>>
49 : 1047 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
50 : : BuiltinMacro to_derive)
51 : : {
52 : 1047 : auto items = AST::DeriveVisitor::derive (item, derive, to_derive);
53 : 2402 : for (auto &item : items)
54 : 1355 : Analysis::Mappings::get ().add_derived_node (item->get_node_id ());
55 : 1047 : return items;
56 : : }
57 : :
58 : : static std::vector<std::unique_ptr<AST::Item>>
59 : 0 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
60 : : MacroExpander &expander)
61 : : {
62 : 0 : std::vector<std::unique_ptr<AST::Item>> result;
63 : 0 : auto frag = expander.expand_derive_proc_macro (item, to_derive);
64 : 0 : if (!frag.is_error ())
65 : : {
66 : 0 : for (auto &node : frag.get_nodes ())
67 : : {
68 : 0 : switch (node.get_kind ())
69 : : {
70 : 0 : case AST::SingleASTNode::Kind::Item:
71 : 0 : Analysis::Mappings::get ().add_derived_node (
72 : 0 : node.get_item ()->get_node_id ());
73 : 0 : result.push_back (node.take_item ());
74 : 0 : break;
75 : 0 : default:
76 : 0 : rust_unreachable ();
77 : : }
78 : : }
79 : : }
80 : 0 : return result;
81 : 0 : }
82 : :
83 : : static std::vector<std::unique_ptr<AST::Item>>
84 : 0 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
85 : : MacroExpander &expander)
86 : : {
87 : 0 : std::vector<std::unique_ptr<AST::Item>> result;
88 : 0 : auto frag = expander.expand_attribute_proc_macro (item, name);
89 : 0 : if (!frag.is_error ())
90 : : {
91 : 0 : for (auto &node : frag.get_nodes ())
92 : : {
93 : 0 : switch (node.get_kind ())
94 : : {
95 : 0 : case AST::SingleASTNode::Kind::Item:
96 : 0 : result.push_back (node.take_item ());
97 : 0 : break;
98 : 0 : default:
99 : 0 : rust_unreachable ();
100 : : }
101 : : }
102 : : }
103 : 0 : return result;
104 : 0 : }
105 : :
106 : : /* Helper function to expand a given attribute on a statement and collect back
107 : : * statements.
108 : : * T should be anything that can be used as a statement accepting outer
109 : : * attributes.
110 : : */
111 : : template <typename T>
112 : : static std::vector<std::unique_ptr<AST::Stmt>>
113 : 1 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
114 : : MacroExpander &expander)
115 : : {
116 : 1 : std::vector<std::unique_ptr<AST::Stmt>> result;
117 : 1 : auto frag = expander.expand_attribute_proc_macro (statement, attribute);
118 : 1 : if (!frag.is_error ())
119 : : {
120 : 0 : for (auto &node : frag.get_nodes ())
121 : : {
122 : 0 : switch (node.get_kind ())
123 : : {
124 : 0 : case AST::SingleASTNode::Kind::Stmt:
125 : 0 : result.push_back (node.take_stmt ());
126 : : break;
127 : 0 : default:
128 : 0 : rust_unreachable ();
129 : : }
130 : : }
131 : : }
132 : 1 : return result;
133 : 1 : }
134 : :
135 : : void
136 : 608972 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
137 : : {
138 : 608972 : if (block_expr.has_tail_expr ())
139 : : {
140 : 532188 : auto tail = block_expr.take_tail_expr ();
141 : 532188 : auto attrs = tail->get_outer_attrs ();
142 : 532188 : bool changed = false;
143 : 534755 : for (auto it = attrs.begin (); it != attrs.end ();)
144 : : {
145 : 2567 : auto current = *it;
146 : 2567 : if (is_builtin (current))
147 : : {
148 : 2567 : it++;
149 : : }
150 : : else
151 : : {
152 : 0 : it = attrs.erase (it);
153 : 0 : changed = true;
154 : 0 : auto new_stmts
155 : : = expand_stmt_attribute (block_expr, current.get_path (),
156 : 0 : expander);
157 : 0 : auto &stmts = block_expr.get_statements ();
158 : 0 : std::move (new_stmts.begin (), new_stmts.end (),
159 : : std::inserter (stmts, stmts.end ()));
160 : 0 : }
161 : 2567 : }
162 : 532188 : if (changed)
163 : 0 : block_expr.normalize_tail_expr ();
164 : : else
165 : 532188 : block_expr.set_tail_expr (std::move (tail));
166 : 532188 : }
167 : 608972 : }
168 : :
169 : : void
170 : 21753 : ExpandVisitor::expand_inner_items (
171 : : std::vector<std::unique_ptr<AST::Item>> &items)
172 : : {
173 : 21753 : expander.push_context (MacroExpander::ContextType::ITEM);
174 : :
175 : 458466 : for (auto it = items.begin (); it != items.end (); it++)
176 : : {
177 : 436713 : Rust::AST::Item &item = **it;
178 : 436713 : if (item.has_outer_attrs ())
179 : : {
180 : 296777 : auto &attrs = item.get_outer_attrs ();
181 : :
182 : 1533313 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
183 : : /* erase => No increment*/)
184 : : {
185 : 1236536 : auto current = *attr_it;
186 : :
187 : 1236536 : if (current.is_derive ())
188 : : {
189 : 393 : current.parse_attr_to_meta_item ();
190 : 393 : attr_it = attrs.erase (attr_it);
191 : : // Get traits to derive in the current attribute
192 : 393 : auto traits_to_derive = current.get_traits_to_derive ();
193 : 1440 : for (auto &to_derive : traits_to_derive)
194 : : {
195 : 1047 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
196 : 1047 : to_derive.get ().as_string ());
197 : 1047 : if (maybe_builtin.has_value ())
198 : : {
199 : 1047 : auto new_items
200 : : = builtin_derive_item (item, current,
201 : 1047 : maybe_builtin.value ());
202 : :
203 : 2402 : for (auto &&new_item : new_items)
204 : 1355 : it = items.insert (it, std::move (new_item));
205 : 1047 : }
206 : : else
207 : : {
208 : : // Macro is not a builtin, so it must be a
209 : : // user-defined derive macro.
210 : 0 : auto new_items
211 : 0 : = derive_item (item, to_derive, expander);
212 : 0 : std::move (new_items.begin (), new_items.end (),
213 : : std::inserter (items, it));
214 : 0 : }
215 : : }
216 : 393 : }
217 : : else /* Attribute */
218 : : {
219 : 1236143 : if (is_builtin (current))
220 : : {
221 : 1236143 : attr_it++;
222 : : }
223 : : else
224 : : {
225 : 0 : attr_it = attrs.erase (attr_it);
226 : 0 : auto new_items
227 : : = expand_item_attribute (item, current.get_path (),
228 : 0 : expander);
229 : 0 : it = items.erase (it);
230 : 0 : std::move (new_items.begin (), new_items.end (),
231 : : std::inserter (items, it));
232 : : // TODO: Improve this ?
233 : : // item is invalid since it refers to now deleted,
234 : : // cancel the loop increment and break.
235 : 0 : it--;
236 : 0 : break;
237 : 0 : }
238 : : }
239 : 1236536 : }
240 : : }
241 : : }
242 : :
243 : 21753 : expand_macro_children (items, &AST::SingleASTNode::take_item);
244 : :
245 : 21753 : expander.pop_context ();
246 : 21753 : }
247 : :
248 : : void
249 : 608972 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
250 : : {
251 : 608972 : auto &stmts = expr.get_statements ();
252 : 608972 : expander.push_context (MacroExpander::ContextType::STMT);
253 : :
254 : 954866 : for (auto it = stmts.begin (); it != stmts.end (); it++)
255 : : {
256 : 345894 : auto &stmt = *it;
257 : :
258 : : // skip all non-item statements
259 : 345894 : if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
260 : 301515 : continue;
261 : :
262 : 44379 : auto &item = static_cast<AST::Item &> (*stmt.get ());
263 : :
264 : 44379 : if (item.has_outer_attrs ())
265 : : {
266 : 13561 : auto &attrs = item.get_outer_attrs ();
267 : :
268 : 27891 : for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
269 : : /* erase => No increment*/)
270 : : {
271 : 14331 : auto current = *attr_it;
272 : :
273 : 14331 : if (current.is_derive ())
274 : : {
275 : 0 : attr_it = attrs.erase (attr_it);
276 : : // Get traits to derive in the current attribute
277 : 0 : auto traits_to_derive = current.get_traits_to_derive ();
278 : 0 : for (auto &to_derive : traits_to_derive)
279 : : {
280 : 0 : auto maybe_builtin = MacroBuiltin::builtins.lookup (
281 : 0 : to_derive.get ().as_string ());
282 : 0 : if (maybe_builtin.has_value ())
283 : : {
284 : 0 : auto new_items
285 : : = builtin_derive_item (item, current,
286 : 0 : maybe_builtin.value ());
287 : :
288 : : // this inserts the derive *before* the item - is it a
289 : : // problem?
290 : 0 : for (auto &&new_item : new_items)
291 : 0 : it = stmts.insert (it, std::move (new_item));
292 : 0 : }
293 : : else
294 : : {
295 : 0 : auto new_items
296 : 0 : = derive_item (item, to_derive, expander);
297 : 0 : std::move (new_items.begin (), new_items.end (),
298 : : std::inserter (stmts, it));
299 : 0 : }
300 : : }
301 : 0 : }
302 : : else /* Attribute */
303 : : {
304 : 14331 : if (is_builtin (current))
305 : : {
306 : 14330 : attr_it++;
307 : : }
308 : : else
309 : : {
310 : 1 : attr_it = attrs.erase (attr_it);
311 : 1 : auto new_items
312 : : = expand_stmt_attribute (item, current.get_path (),
313 : 1 : expander);
314 : 1 : it = stmts.erase (it);
315 : 1 : std::move (new_items.begin (), new_items.end (),
316 : : std::inserter (stmts, it));
317 : : // TODO: Improve this ?
318 : : // item is invalid since it refers to now deleted,
319 : : // cancel the loop increment and break.
320 : 1 : it--;
321 : 1 : break;
322 : 1 : }
323 : : }
324 : 14331 : }
325 : : }
326 : : }
327 : :
328 : 608972 : if (!expr.has_tail_expr ())
329 : 76869 : expr.normalize_tail_expr ();
330 : :
331 : 608972 : expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
332 : :
333 : 608972 : expander.pop_context ();
334 : 608972 : }
335 : :
336 : : void
337 : 16893027 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
338 : : {
339 : 16893027 : NodeId old_expect = expr->get_node_id ();
340 : 16893027 : std::swap (macro_invoc_expect_id, old_expect);
341 : :
342 : 16893027 : expander.push_context (MacroExpander::ContextType::EXPR);
343 : 16893027 : expr->accept_vis (*this);
344 : 16893027 : expander.pop_context ();
345 : :
346 : 16893027 : std::swap (macro_invoc_expect_id, old_expect);
347 : :
348 : 16893027 : auto final_fragment = expander.take_expanded_fragment ();
349 : 16893027 : if (final_fragment.should_expand ()
350 : 16893027 : && final_fragment.is_expression_fragment ())
351 : 49659 : expr = final_fragment.take_expression_fragment ();
352 : 16893027 : }
353 : :
354 : : void
355 : 1886185 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
356 : : {
357 : 1886185 : NodeId old_expect = type->get_node_id ();
358 : 1886185 : std::swap (macro_invoc_expect_id, old_expect);
359 : :
360 : 1886185 : expander.push_context (MacroExpander::ContextType::TYPE);
361 : 1886185 : type->accept_vis (*this);
362 : 1886185 : expander.pop_context ();
363 : :
364 : 1886185 : std::swap (macro_invoc_expect_id, old_expect);
365 : :
366 : 1886185 : auto final_fragment = expander.take_expanded_fragment ();
367 : 1886185 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
368 : 496 : type = final_fragment.take_type_fragment ();
369 : 1886185 : }
370 : :
371 : : // HACK: maybe we shouldn't have TypeNoBounds as a base class
372 : : void
373 : 445583 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
374 : : {
375 : 445583 : NodeId old_expect = type->get_node_id ();
376 : 445583 : std::swap (macro_invoc_expect_id, old_expect);
377 : :
378 : 445583 : expander.push_context (MacroExpander::ContextType::TYPE);
379 : 445583 : type->accept_vis (*this);
380 : 445583 : expander.pop_context ();
381 : :
382 : 445583 : std::swap (macro_invoc_expect_id, old_expect);
383 : :
384 : 445583 : auto final_fragment = expander.take_expanded_fragment ();
385 : 445583 : if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
386 : 2 : type = std::make_unique<AST::ParenthesisedType> (
387 : 3 : final_fragment.take_type_fragment (), BUILTINS_LOCATION);
388 : 445583 : }
389 : :
390 : : void
391 : 2542768 : ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
392 : : {
393 : 2542768 : NodeId old_expect = pattern->get_node_id ();
394 : 2542768 : std::swap (macro_invoc_expect_id, old_expect);
395 : :
396 : 2542768 : expander.push_context (MacroExpander::ContextType::PATTERN);
397 : 2542768 : pattern->accept_vis (*this);
398 : 2542768 : expander.pop_context ();
399 : :
400 : 2542768 : std::swap (macro_invoc_expect_id, old_expect);
401 : :
402 : 2542768 : auto final_fragment = expander.take_expanded_fragment ();
403 : 2542768 : if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
404 : 1 : pattern = final_fragment.take_pattern_fragment ();
405 : 2542768 : }
406 : :
407 : : // FIXME: Can this be refactored into a `scoped` method? Which takes a
408 : : // ContextType as parameter and a lambda? And maybe just an std::vector<T>&?
409 : : void
410 : 23969 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
411 : : {
412 : 42492 : for (auto &field : fields)
413 : : {
414 : 18523 : maybe_expand_type (field.get_field_type_ptr ());
415 : : }
416 : 23969 : }
417 : :
418 : : void
419 : 7594 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
420 : : {
421 : 29063 : for (auto &field : fields)
422 : 21469 : maybe_expand_type (field.get_field_type_ptr ());
423 : 7594 : }
424 : :
425 : : // FIXME: This can definitely be refactored with the method above
426 : : void
427 : 457539 : ExpandVisitor::expand_function_params (
428 : : std::vector<std::unique_ptr<AST::Param>> ¶ms)
429 : : {
430 : 1279462 : for (auto &p : params)
431 : 821923 : visit (p);
432 : 457539 : }
433 : :
434 : : void
435 : 495055 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
436 : : {
437 : 981166 : for (auto &arg : args.get_generic_args ())
438 : : {
439 : 486111 : switch (arg.get_kind ())
440 : : {
441 : 153841 : case AST::GenericArg::Kind::Type:
442 : 153841 : maybe_expand_type (arg.get_type_ptr ());
443 : 153841 : break;
444 : 138 : case AST::GenericArg::Kind::Const:
445 : 138 : maybe_expand_expr (arg.get_expression_ptr ());
446 : 138 : break;
447 : : default:
448 : : break;
449 : : // FIXME: Figure out what to do here if there is ambiguity. Since the
450 : : // resolver comes after the expansion, we need to figure out a way to
451 : : // strip ambiguous values here
452 : : // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
453 : : // or something. This would clean up this whole thing
454 : : }
455 : : }
456 : :
457 : : // FIXME: Can we have macro invocations in generic type bindings?
458 : : // expand binding args - strip sub-types only
459 : : // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
460 : 504076 : for (auto &binding : args.get_binding_args ())
461 : 9021 : maybe_expand_type (binding.get_type_ptr ());
462 : 495055 : }
463 : :
464 : : void
465 : 106684 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
466 : : {
467 : 106684 : maybe_expand_type (path_type.get_type_ptr ());
468 : :
469 : : // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
470 : 106684 : if (path_type.has_as_clause ())
471 : 104053 : path_type.get_as_type_path ().accept_vis (*this);
472 : 106684 : }
473 : :
474 : : void
475 : 10459 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> ¶ms)
476 : : {
477 : 22975 : for (auto ¶m : params)
478 : : {
479 : 12516 : maybe_expand_pattern (param.get_pattern_ptr ());
480 : :
481 : 12516 : if (param.has_type_given ())
482 : 711 : maybe_expand_type (param.get_type_ptr ());
483 : : }
484 : 10459 : }
485 : :
486 : : void
487 : 28084 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
488 : : {
489 : 66002 : for (auto &item : where_clause.get_items ())
490 : 37918 : visit (item);
491 : 28084 : }
492 : :
493 : : void
494 : 10315 : ExpandVisitor::visit (AST::Crate &crate)
495 : : {
496 : 10315 : expand_inner_items (crate.items);
497 : 10315 : }
498 : :
499 : : void
500 : 0 : ExpandVisitor::visit (AST::DelimTokenTree &)
501 : 0 : {}
502 : :
503 : : void
504 : 0 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
505 : 0 : {}
506 : :
507 : : void
508 : 4023854 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
509 : 4023854 : {}
510 : :
511 : : void
512 : 40403 : ExpandVisitor::visit (AST::LifetimeParam &)
513 : 40403 : {}
514 : :
515 : : void
516 : 2819 : ExpandVisitor::visit (AST::ConstGenericParam &)
517 : 2819 : {}
518 : :
519 : : void
520 : 61669 : ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc)
521 : : {
522 : 61669 : if (macro_invoc_expect_id != macro_invoc.get_node_id ())
523 : : {
524 : 0 : rust_internal_error_at (
525 : : macro_invoc.get_locus (),
526 : : "attempting to expand node with id %d into position with node id %d",
527 : 0 : (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
528 : : }
529 : :
530 : : // TODO: Can we do the AST fragment replacing here? Probably not, right?
531 : 111849 : expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
532 : : ? AST::InvocKind::Semicoloned
533 : : : AST::InvocKind::Expr);
534 : 61669 : }
535 : :
536 : : void
537 : 2479386 : ExpandVisitor::visit (AST::PathInExpression &path)
538 : : {
539 : 2479386 : if (!path.is_lang_item ())
540 : 5283424 : for (auto &segment : path.get_segments ())
541 : 5621034 : if (segment.has_generic_args ())
542 : 16491 : expand_generic_args (segment.get_generic_args ());
543 : 2479386 : }
544 : :
545 : : void
546 : 478566 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
547 : : {
548 : 478566 : if (segment.has_generic_args ())
549 : 478564 : expand_generic_args (segment.get_generic_args ());
550 : 478566 : }
551 : :
552 : : void
553 : 17671 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
554 : : {
555 : 17671 : auto &type_path_function = segment.get_type_path_function ();
556 : :
557 : 42234 : for (auto &type : type_path_function.get_params ())
558 : 24563 : visit (type);
559 : :
560 : 17671 : if (type_path_function.has_return_type ())
561 : 17074 : maybe_expand_type (type_path_function.get_return_type_ptr ());
562 : 17671 : }
563 : :
564 : : void
565 : 3640 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
566 : : {
567 : 3640 : expand_qualified_path_type (path.get_qualified_path_type ());
568 : :
569 : 7280 : for (auto &segment : path.get_segments ())
570 : 7280 : if (segment.has_generic_args ())
571 : 0 : expand_generic_args (segment.get_generic_args ());
572 : 3640 : }
573 : :
574 : : void
575 : 103044 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
576 : : {
577 : 103044 : expand_qualified_path_type (path.get_qualified_path_type ());
578 : :
579 : : // this shouldn't strip any segments, but can strip inside them
580 : 103044 : for (auto &segment : path.get_segments ())
581 : 0 : visit (segment);
582 : 103044 : }
583 : :
584 : : void
585 : 6309199 : ExpandVisitor::visit (AST::LiteralExpr &expr)
586 : 6309199 : {}
587 : :
588 : : void
589 : 0 : ExpandVisitor::visit (AST::AttrInputLiteral &)
590 : 0 : {}
591 : :
592 : : void
593 : 0 : ExpandVisitor::visit (AST::AttrInputMacro ¯o)
594 : : {
595 : 0 : rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
596 : 0 : }
597 : :
598 : : void
599 : 0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
600 : 0 : {}
601 : :
602 : : void
603 : 0 : ExpandVisitor::visit (AST::MetaItemPathExpr &)
604 : 0 : {}
605 : :
606 : : void
607 : 1192678 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
608 : : {
609 : 1192678 : maybe_expand_expr (expr.get_left_expr_ptr ());
610 : 1192678 : maybe_expand_expr (expr.get_right_expr_ptr ());
611 : 1192678 : }
612 : :
613 : : void
614 : 91730 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
615 : : {
616 : 91730 : maybe_expand_expr (expr.get_left_expr_ptr ());
617 : 91730 : maybe_expand_expr (expr.get_right_expr_ptr ());
618 : 91730 : }
619 : :
620 : : void
621 : 25243 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
622 : : {
623 : 25243 : maybe_expand_expr (expr.get_left_expr_ptr ());
624 : 25243 : maybe_expand_expr (expr.get_right_expr_ptr ());
625 : 25243 : }
626 : :
627 : : void
628 : 127855 : ExpandVisitor::visit (AST::TypeCastExpr &expr)
629 : : {
630 : 127855 : maybe_expand_expr (expr.get_casted_expr_ptr ());
631 : 127855 : maybe_expand_type (expr.get_type_to_cast_to_ptr ());
632 : 127855 : }
633 : :
634 : : void
635 : 39383 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
636 : : {
637 : 39383 : maybe_expand_expr (expr.get_left_expr_ptr ());
638 : 39383 : maybe_expand_expr (expr.get_right_expr_ptr ());
639 : 39383 : }
640 : :
641 : : void
642 : 28987 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
643 : : {
644 : 28987 : maybe_expand_expr (expr.get_left_expr_ptr ());
645 : 28987 : maybe_expand_expr (expr.get_right_expr_ptr ());
646 : 28987 : }
647 : :
648 : : void
649 : 211515 : ExpandVisitor::visit (AST::GroupedExpr &expr)
650 : : {
651 : 211515 : maybe_expand_expr (expr.get_expr_in_parens_ptr ());
652 : 211515 : }
653 : :
654 : : void
655 : 990 : ExpandVisitor::visit (AST::StructExprStruct &expr)
656 : 990 : {}
657 : :
658 : : void
659 : 2020278 : ExpandVisitor::visit (AST::CallExpr &expr)
660 : : {
661 : 2020278 : visit (expr.get_function_expr ());
662 : :
663 : 7332134 : for (auto ¶m : expr.get_params ())
664 : 5311856 : maybe_expand_expr (param);
665 : 2020278 : }
666 : :
667 : : void
668 : 10364 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
669 : : {
670 : 10364 : expand_closure_params (expr.get_params ());
671 : :
672 : 10364 : maybe_expand_expr (expr.get_definition_expr_ptr ());
673 : 10364 : }
674 : :
675 : : void
676 : 608972 : ExpandVisitor::visit (AST::BlockExpr &expr)
677 : : {
678 : 608972 : expand_inner_stmts (expr);
679 : :
680 : 608972 : expand_tail_expr (expr, expander);
681 : 608972 : if (expr.has_tail_expr ())
682 : 532188 : maybe_expand_expr (expr.get_tail_expr_ptr ());
683 : 608972 : }
684 : :
685 : : void
686 : 95 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
687 : : {
688 : 95 : expand_closure_params (expr.get_params ());
689 : :
690 : 95 : maybe_expand_type (expr.get_return_type_ptr ());
691 : :
692 : 95 : visit (expr.get_definition_expr ());
693 : 95 : }
694 : :
695 : : void
696 : 512 : ExpandVisitor::visit (AST::ContinueExpr &expr)
697 : 512 : {}
698 : :
699 : : void
700 : 22734 : ExpandVisitor::visit (AST::IfExpr &expr)
701 : : {
702 : 22734 : maybe_expand_expr (expr.get_condition_expr_ptr ());
703 : :
704 : 22734 : visit (expr.get_if_block ());
705 : 22734 : }
706 : :
707 : : void
708 : 39583 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
709 : : {
710 : 39583 : maybe_expand_expr (expr.get_condition_expr_ptr ());
711 : :
712 : 39583 : visit (expr.get_if_block ());
713 : 39583 : visit (expr.get_else_block ());
714 : 39583 : }
715 : :
716 : : void
717 : 2169 : ExpandVisitor::visit (AST::IfLetExpr &expr)
718 : : {
719 : 2169 : maybe_expand_expr (expr.get_value_expr_ptr ());
720 : :
721 : 2169 : visit (expr.get_if_block ());
722 : 2169 : }
723 : :
724 : : void
725 : 1074 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
726 : : {
727 : 1074 : maybe_expand_expr (expr.get_value_expr_ptr ());
728 : :
729 : 1074 : visit (expr.get_if_block ());
730 : 1074 : visit (expr.get_else_block ());
731 : 1074 : }
732 : :
733 : : void
734 : 139152 : ExpandVisitor::visit (AST::TupleExpr &expr)
735 : : {
736 : 398206 : for (auto &sub : expr.get_tuple_elems ())
737 : 259054 : maybe_expand_expr (sub);
738 : 139152 : }
739 : :
740 : : void
741 : 263003 : ExpandVisitor::visit (AST::TypeParam ¶m)
742 : : {
743 : 340149 : for (auto &bound : param.get_type_param_bounds ())
744 : 77146 : visit (bound);
745 : :
746 : 263003 : if (param.has_type ())
747 : 2043 : maybe_expand_type (param.get_type_ptr ());
748 : 263003 : }
749 : :
750 : : void
751 : 39 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
752 : 39 : {}
753 : :
754 : : void
755 : 37879 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
756 : : {
757 : 37879 : maybe_expand_type (item.get_type_ptr ());
758 : :
759 : 77504 : for (auto &bound : item.get_type_param_bounds ())
760 : 39625 : visit (bound);
761 : 37879 : }
762 : :
763 : : void
764 : 11438 : ExpandVisitor::visit (AST::Module &module)
765 : : {
766 : 11438 : expand_inner_items (module.get_items ());
767 : 11438 : }
768 : :
769 : : void
770 : 48 : ExpandVisitor::visit (AST::ExternCrate &crate)
771 : 48 : {}
772 : :
773 : : void
774 : 0 : ExpandVisitor::visit (AST::UseTreeGlob &)
775 : 0 : {}
776 : :
777 : : void
778 : 0 : ExpandVisitor::visit (AST::UseTreeList &)
779 : 0 : {}
780 : :
781 : : void
782 : 0 : ExpandVisitor::visit (AST::UseTreeRebind &)
783 : 0 : {}
784 : :
785 : : void
786 : 25431 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
787 : 25431 : {}
788 : :
789 : : void
790 : 457539 : ExpandVisitor::visit (AST::Function &function)
791 : : {
792 : 457539 : if (function.has_body ())
793 : 413570 : visit_inner_using_attrs (
794 : 413570 : function, function.get_definition ().value ()->get_inner_attrs ());
795 : 513266 : for (auto ¶m : function.get_generic_params ())
796 : 55727 : visit (param);
797 : :
798 : 457539 : expand_function_params (function.get_function_params ());
799 : :
800 : 457539 : if (function.has_return_type ())
801 : 392683 : maybe_expand_type (function.get_return_type_ptr ());
802 : :
803 : 457539 : if (function.has_where_clause ())
804 : 15123 : expand_where_clause (function.get_where_clause ());
805 : :
806 : 457539 : if (function.has_body ())
807 : 413570 : visit (*function.get_definition ());
808 : 457539 : }
809 : :
810 : : void
811 : 23480 : ExpandVisitor::visit (AST::StructStruct &struct_item)
812 : : {
813 : 33603 : for (auto &generic : struct_item.get_generic_params ())
814 : 10123 : visit (generic);
815 : :
816 : 23480 : if (struct_item.has_where_clause ())
817 : 389 : expand_where_clause (struct_item.get_where_clause ());
818 : :
819 : 23480 : expand_struct_fields (struct_item.get_fields ());
820 : 23480 : }
821 : :
822 : : void
823 : 5541 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
824 : : {
825 : 7730 : for (auto &generic : tuple_struct.get_generic_params ())
826 : 2189 : visit (generic);
827 : :
828 : 5541 : if (tuple_struct.has_where_clause ())
829 : 35 : expand_where_clause (tuple_struct.get_where_clause ());
830 : :
831 : 5541 : expand_tuple_fields (tuple_struct.get_fields ());
832 : 5541 : }
833 : :
834 : : void
835 : 3087 : ExpandVisitor::visit (AST::EnumItem &item)
836 : 3087 : {}
837 : :
838 : : void
839 : 2053 : ExpandVisitor::visit (AST::EnumItemTuple &item)
840 : : {
841 : 2053 : expand_tuple_fields (item.get_tuple_fields ());
842 : 2053 : }
843 : :
844 : : void
845 : 202 : ExpandVisitor::visit (AST::EnumItemStruct &item)
846 : : {
847 : 202 : expand_struct_fields (item.get_struct_fields ());
848 : 202 : }
849 : :
850 : : void
851 : 780 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
852 : : {
853 : 780 : maybe_expand_expr (item.get_expr_ptr ());
854 : 780 : }
855 : :
856 : : void
857 : 287 : ExpandVisitor::visit (AST::Union &union_item)
858 : : {
859 : 514 : for (auto &generic : union_item.get_generic_params ())
860 : 227 : visit (generic);
861 : :
862 : 287 : expand_struct_fields (union_item.get_variants ());
863 : 287 : }
864 : :
865 : : void
866 : 25571 : ExpandVisitor::visit (AST::ConstantItem &const_item)
867 : : {
868 : 25571 : maybe_expand_type (const_item.get_type_ptr ());
869 : :
870 : 25571 : if (const_item.has_expr ())
871 : 24837 : maybe_expand_expr (const_item.get_expr_ptr ());
872 : 25571 : }
873 : :
874 : : void
875 : 1332 : ExpandVisitor::visit (AST::StaticItem &static_item)
876 : : {
877 : 1332 : maybe_expand_type (static_item.get_type_ptr ());
878 : :
879 : 1332 : maybe_expand_expr (static_item.get_expr_ptr ());
880 : 1332 : }
881 : :
882 : : void
883 : 13264 : ExpandVisitor::visit (AST::Trait &trait)
884 : : {
885 : 16970 : for (auto &generic : trait.get_generic_params ())
886 : 3706 : visit (generic);
887 : :
888 : 17421 : for (auto &bound : trait.get_type_param_bounds ())
889 : 4157 : visit (bound);
890 : :
891 : 13264 : if (trait.has_where_clause ())
892 : 21 : expand_where_clause (trait.get_where_clause ());
893 : :
894 : 13264 : expander.push_context (MacroExpander::ContextType::TRAIT);
895 : :
896 : 13264 : expand_macro_children (MacroExpander::ContextType::TRAIT,
897 : : trait.get_trait_items (),
898 : : &AST::SingleASTNode::take_assoc_item);
899 : :
900 : 13264 : expander.pop_context ();
901 : 13264 : }
902 : :
903 : : void
904 : 12255 : ExpandVisitor::visit (AST::InherentImpl &impl)
905 : : {
906 : 24510 : visit_inner_attrs (impl);
907 : : // just expand sub-stuff - can't actually strip generic params themselves
908 : 22191 : for (auto &generic : impl.get_generic_params ())
909 : 9936 : visit (generic);
910 : :
911 : : // FIXME: Is that correct? How do we test that?
912 : 12255 : expander.push_context (MacroExpander::ContextType::ITEM);
913 : :
914 : 12255 : maybe_expand_type (impl.get_type_ptr ());
915 : :
916 : 12255 : expander.pop_context ();
917 : :
918 : 12255 : if (impl.has_where_clause ())
919 : 107 : expand_where_clause (impl.get_where_clause ());
920 : :
921 : 12255 : expand_macro_children (MacroExpander::ContextType::IMPL,
922 : : impl.get_impl_items (),
923 : : &AST::SingleASTNode::take_assoc_item);
924 : 12255 : }
925 : :
926 : : void
927 : 234784 : ExpandVisitor::visit (AST::TraitImpl &impl)
928 : : {
929 : 469568 : visit_inner_attrs (impl);
930 : : // just expand sub-stuff - can't actually strip generic params themselves
931 : 457868 : for (auto ¶m : impl.get_generic_params ())
932 : 223084 : visit (param);
933 : :
934 : : // FIXME: Is that correct? How do we test that?
935 : 234784 : expander.push_context (MacroExpander::ContextType::ITEM);
936 : :
937 : 234784 : maybe_expand_type (impl.get_type_ptr ());
938 : :
939 : 234784 : expander.pop_context ();
940 : :
941 : 234784 : visit (impl.get_trait_path ());
942 : :
943 : 234784 : if (impl.has_where_clause ())
944 : 12409 : expand_where_clause (impl.get_where_clause ());
945 : :
946 : 234784 : expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
947 : : impl.get_impl_items (),
948 : : &AST::SingleASTNode::take_assoc_item);
949 : 234784 : }
950 : :
951 : : void
952 : 37 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
953 : 37 : {}
954 : :
955 : : void
956 : 2 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
957 : : {
958 : 2 : maybe_expand_type (static_item.get_type_ptr ());
959 : 2 : }
960 : :
961 : : void
962 : 4789 : ExpandVisitor::visit (AST::ExternBlock &block)
963 : : {
964 : 9578 : visit_inner_attrs (block);
965 : :
966 : 4789 : expand_macro_children (MacroExpander::ContextType::EXTERN,
967 : : block.get_extern_items (),
968 : : &AST::SingleASTNode::take_external_item);
969 : 4789 : }
970 : :
971 : : void
972 : 0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
973 : 0 : {}
974 : :
975 : : void
976 : 0 : ExpandVisitor::visit (AST::MacroMatcher &)
977 : 0 : {}
978 : :
979 : : void
980 : 28857 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
981 : 28857 : {}
982 : :
983 : : void
984 : 0 : ExpandVisitor::visit (AST::MetaItemPath &)
985 : 0 : {}
986 : :
987 : : void
988 : 0 : ExpandVisitor::visit (AST::MetaItemSeq &)
989 : 0 : {}
990 : :
991 : : void
992 : 0 : ExpandVisitor::visit (AST::MetaListPaths &)
993 : 0 : {}
994 : :
995 : : void
996 : 0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
997 : 0 : {}
998 : :
999 : : void
1000 : 635 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
1001 : 635 : {}
1002 : :
1003 : : void
1004 : 88 : ExpandVisitor::visit (AST::GroupedPattern &pattern)
1005 : : {
1006 : 88 : maybe_expand_pattern (pattern.get_pattern_in_parens_ptr ());
1007 : 88 : }
1008 : :
1009 : : void
1010 : 204 : ExpandVisitor::visit (AST::SlicePatternItemsNoRest &items)
1011 : : {
1012 : 367 : for (auto &sub : items.get_patterns ())
1013 : 163 : maybe_expand_pattern (sub);
1014 : 204 : }
1015 : :
1016 : : void
1017 : 228 : ExpandVisitor::visit (AST::SlicePatternItemsHasRest &items)
1018 : : {
1019 : 664 : for (auto &sub : items.get_lower_patterns ())
1020 : 436 : maybe_expand_pattern (sub);
1021 : 314 : for (auto &sub : items.get_upper_patterns ())
1022 : 86 : maybe_expand_pattern (sub);
1023 : 228 : }
1024 : :
1025 : : void
1026 : 1644 : ExpandVisitor::visit (AST::AltPattern &pattern)
1027 : : {
1028 : 5762 : for (auto &alt : pattern.get_alts ())
1029 : 4118 : maybe_expand_pattern (alt);
1030 : 1644 : }
1031 : :
1032 : : void
1033 : 26655 : ExpandVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
1034 : : {
1035 : 54503 : for (auto &sub : tuple_items.get_patterns ())
1036 : 27848 : maybe_expand_pattern (sub);
1037 : 26655 : }
1038 : :
1039 : : void
1040 : 323 : ExpandVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
1041 : : {
1042 : 385 : for (auto &sub : tuple_items.get_lower_patterns ())
1043 : 62 : maybe_expand_pattern (sub);
1044 : :
1045 : 361 : for (auto &sub : tuple_items.get_upper_patterns ())
1046 : 38 : maybe_expand_pattern (sub);
1047 : 323 : }
1048 : :
1049 : : void
1050 : 85899 : ExpandVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
1051 : : {
1052 : 285443 : for (auto &sub : tuple_items.get_patterns ())
1053 : 199544 : maybe_expand_pattern (sub);
1054 : 85899 : }
1055 : :
1056 : : void
1057 : 54 : ExpandVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
1058 : : {
1059 : 110 : for (auto &sub : tuple_items.get_lower_patterns ())
1060 : 56 : maybe_expand_pattern (sub);
1061 : :
1062 : 118 : for (auto &sub : tuple_items.get_upper_patterns ())
1063 : 64 : maybe_expand_pattern (sub);
1064 : 54 : }
1065 : :
1066 : : void
1067 : 151444 : ExpandVisitor::visit (AST::LetStmt &stmt)
1068 : : {
1069 : 151444 : maybe_expand_pattern (stmt.get_pattern_ptr ());
1070 : :
1071 : 151444 : if (stmt.has_type ())
1072 : 18321 : maybe_expand_type (stmt.get_type_ptr ());
1073 : :
1074 : 151444 : if (stmt.has_init_expr ())
1075 : 145429 : maybe_expand_expr (stmt.get_init_expr_ptr ());
1076 : 151444 : }
1077 : :
1078 : : void
1079 : 149826 : ExpandVisitor::visit (AST::ExprStmt &stmt)
1080 : : {
1081 : 149826 : maybe_expand_expr (stmt.get_expr_ptr ());
1082 : 149826 : }
1083 : :
1084 : : void
1085 : 18212 : ExpandVisitor::visit (AST::BareFunctionType &type)
1086 : : {
1087 : 127048 : for (auto ¶m : type.get_function_params ())
1088 : : {
1089 : 108836 : maybe_expand_type (param.get_type_ptr ());
1090 : : }
1091 : :
1092 : 18212 : if (type.has_return_type ())
1093 : 17898 : visit (type.get_return_type ());
1094 : 18212 : }
1095 : :
1096 : : void
1097 : 526993 : ExpandVisitor::visit (AST::FunctionParam ¶m)
1098 : : {
1099 : 526993 : maybe_expand_pattern (param.get_pattern_ptr ());
1100 : 526993 : maybe_expand_type (param.get_type_ptr ());
1101 : 526993 : }
1102 : :
1103 : : void
1104 : 1749 : ExpandVisitor::visit (AST::VariadicParam ¶m)
1105 : : {
1106 : 1749 : if (param.has_pattern ())
1107 : 22 : maybe_expand_pattern (param.get_pattern_ptr ());
1108 : 1749 : }
1109 : :
1110 : : void
1111 : 293181 : ExpandVisitor::visit (AST::SelfParam ¶m)
1112 : : {
1113 : : /* TODO: maybe check for invariants being violated - e.g. both type and
1114 : : * lifetime? */
1115 : 293181 : if (param.has_type ())
1116 : 457 : maybe_expand_type (param.get_type_ptr ());
1117 : 293181 : }
1118 : :
1119 : : template <typename T>
1120 : : void
1121 : 0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
1122 : : {
1123 : : // FIXME: Retrieve path from segments + local use statements instead of string
1124 : 0 : expander.expand_attribute_proc_macro (item, path);
1125 : 0 : }
1126 : :
1127 : : template <typename T>
1128 : : void
1129 : 665398 : ExpandVisitor::visit_inner_using_attrs (T &item,
1130 : : std::vector<AST::Attribute> &attrs)
1131 : : {
1132 : 665433 : for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
1133 : : {
1134 : 35 : auto current = *it;
1135 : :
1136 : 35 : if (!is_builtin (current) && !current.is_derive ())
1137 : : {
1138 : 0 : it = attrs.erase (it);
1139 : 0 : expand_inner_attribute (item, current.get_path ());
1140 : : }
1141 : : else
1142 : : {
1143 : 35 : it++;
1144 : : }
1145 : : }
1146 : 665398 : }
1147 : :
1148 : : template <typename T>
1149 : : void
1150 : 4789 : ExpandVisitor::visit_inner_attrs (T &item)
1151 : : {
1152 : 251828 : visit_inner_using_attrs (item, item.get_inner_attrs ());
1153 : : }
1154 : :
1155 : : } // namespace Rust
|