LCOV - code coverage report
Current view: top level - gcc/rust/expand - rust-expand-visitor.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.0 % 512 420
Test Date: 2026-08-22 16:33:35 Functions: 81.1 % 90 73
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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      1197800 : is_builtin (AST::Attribute &attr)
      33              : {
      34      1197800 :   auto &segments = attr.get_path ().get_segments ();
      35      1197800 :   return !segments.empty ()
      36      1197800 :          && !Analysis::BuiltinAttributeMappings::get ()
      37      1197800 :                ->lookup_builtin (segments[0].get_segment_name ())
      38      1197800 :                .is_error ();
      39              : }
      40              : 
      41              : /* Expand all of the macro invocations currently contained in a crate */
      42              : void
      43        11133 : ExpandVisitor::go (AST::Crate &crate)
      44              : {
      45        11133 :   visit (crate);
      46        11133 : }
      47              : 
      48              : static std::vector<std::unique_ptr<AST::Item>>
      49         1055 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
      50              :                      BuiltinMacro to_derive, MacroExpander &expander)
      51              : {
      52         1055 :   auto item_source = AST::Builder::get_item_source (expander.crate);
      53              : 
      54         1055 :   auto items
      55         1055 :     = AST::DeriveVisitor::derive (item, derive, to_derive, item_source);
      56              : 
      57         2414 :   for (auto &item : items)
      58         1359 :     Analysis::Mappings::get ().add_derived_node (item->get_node_id ());
      59              : 
      60         1055 :   return items;
      61              : }
      62              : 
      63              : static std::vector<std::unique_ptr<AST::Item>>
      64            5 : derive_item (AST::Item &item, AST::SimplePath &to_derive,
      65              :              MacroExpander &expander)
      66              : {
      67            5 :   std::vector<std::unique_ptr<AST::Item>> result;
      68            5 :   auto frag = expander.expand_derive_proc_macro (item, to_derive);
      69            5 :   if (!frag.is_error ())
      70              :     {
      71            0 :       for (auto &node : frag.get_nodes ())
      72              :         {
      73            0 :           switch (node.get_kind ())
      74              :             {
      75            0 :             case AST::SingleASTNode::Kind::Item:
      76            0 :               Analysis::Mappings::get ().add_derived_node (
      77            0 :                 node.get_item ()->get_node_id ());
      78            0 :               result.push_back (node.take_item ());
      79            0 :               break;
      80            0 :             default:
      81            0 :               rust_unreachable ();
      82              :             }
      83              :         }
      84              :     }
      85            5 :   return result;
      86            5 : }
      87              : 
      88              : static std::vector<std::unique_ptr<AST::Item>>
      89            0 : expand_item_attribute (AST::Item &item, AST::SimplePath &name,
      90              :                        MacroExpander &expander)
      91              : {
      92            0 :   std::vector<std::unique_ptr<AST::Item>> result;
      93            0 :   auto frag = expander.expand_attribute_proc_macro (item, name);
      94            0 :   if (!frag.is_error ())
      95              :     {
      96            0 :       for (auto &node : frag.get_nodes ())
      97              :         {
      98            0 :           switch (node.get_kind ())
      99              :             {
     100            0 :             case AST::SingleASTNode::Kind::Item:
     101            0 :               result.push_back (node.take_item ());
     102            0 :               break;
     103            0 :             default:
     104            0 :               rust_unreachable ();
     105              :             }
     106              :         }
     107              :     }
     108            0 :   return result;
     109            0 : }
     110              : 
     111              : /* Helper function to expand a given attribute on a statement and collect back
     112              :  * statements.
     113              :  * T should be anything that can be used as a statement accepting outer
     114              :  * attributes.
     115              :  */
     116              : template <typename T>
     117              : static std::vector<std::unique_ptr<AST::Stmt>>
     118            1 : expand_stmt_attribute (T &statement, AST::SimplePath &attribute,
     119              :                        MacroExpander &expander)
     120              : {
     121            1 :   std::vector<std::unique_ptr<AST::Stmt>> result;
     122            1 :   auto frag = expander.expand_attribute_proc_macro (statement, attribute);
     123            1 :   if (!frag.is_error ())
     124              :     {
     125            0 :       for (auto &node : frag.get_nodes ())
     126              :         {
     127            0 :           switch (node.get_kind ())
     128              :             {
     129            0 :             case AST::SingleASTNode::Kind::Stmt:
     130            0 :               result.push_back (node.take_stmt ());
     131              :               break;
     132            0 :             default:
     133            0 :               rust_unreachable ();
     134              :             }
     135              :         }
     136              :     }
     137            1 :   return result;
     138            1 : }
     139              : 
     140              : void
     141       612554 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
     142              : {
     143       612554 :   if (block_expr.has_tail_expr ())
     144              :     {
     145       533588 :       auto tail = block_expr.take_tail_expr ();
     146       533588 :       auto attrs = tail->get_outer_attrs ();
     147       533588 :       bool changed = false;
     148       536155 :       for (auto it = attrs.begin (); it != attrs.end ();)
     149              :         {
     150         2567 :           auto current = *it;
     151         2567 :           if (is_builtin (current))
     152              :             {
     153         2567 :               it++;
     154              :             }
     155              :           else
     156              :             {
     157            0 :               it = attrs.erase (it);
     158            0 :               changed = true;
     159            0 :               auto new_stmts
     160              :                 = expand_stmt_attribute (block_expr, current.get_path (),
     161            0 :                                          expander);
     162            0 :               auto &stmts = block_expr.get_statements ();
     163            0 :               std::move (new_stmts.begin (), new_stmts.end (),
     164              :                          std::inserter (stmts, stmts.end ()));
     165            0 :             }
     166         2567 :         }
     167       533588 :       if (changed)
     168            0 :         block_expr.normalize_tail_expr ();
     169              :       else
     170       533588 :         block_expr.set_tail_expr (std::move (tail));
     171       533588 :     }
     172       612554 : }
     173              : 
     174              : void
     175        22544 : ExpandVisitor::expand_inner_items (
     176              :   std::vector<std::unique_ptr<AST::Item>> &items)
     177              : {
     178        22544 :   expander.push_context (MacroExpander::ContextType::ITEM);
     179              : 
     180       462168 :   for (auto it = items.begin (); it != items.end (); it++)
     181              :     {
     182       439624 :       Rust::AST::Item &item = **it;
     183       439624 :       if (item.has_outer_attrs ())
     184              :         {
     185       297549 :           auto &attrs = item.get_outer_attrs ();
     186              : 
     187      1478818 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     188              :                /* erase => No increment*/)
     189              :             {
     190      1181269 :               auto current = *attr_it;
     191              : 
     192      1181269 :               if (current.is_derive ())
     193              :                 {
     194          402 :                   current.parse_attr_to_meta_item ();
     195          402 :                   attr_it = attrs.erase (attr_it);
     196              :                   // Get traits to derive in the current attribute
     197          402 :                   auto traits_to_derive = current.get_traits_to_derive ();
     198         1462 :                   for (auto &to_derive : traits_to_derive)
     199              :                     {
     200         1060 :                       auto maybe_builtin = MacroBuiltin::builtins.lookup (
     201         1060 :                         to_derive.get ().as_string ());
     202         1060 :                       if (maybe_builtin.has_value ())
     203              :                         {
     204         1055 :                           auto new_items
     205              :                             = builtin_derive_item (item, current,
     206         1055 :                                                    maybe_builtin.value (),
     207         1055 :                                                    expander);
     208              : 
     209         2414 :                           for (auto &&new_item : new_items)
     210         1359 :                             it = items.insert (it, std::move (new_item));
     211         1055 :                         }
     212              :                       else
     213              :                         {
     214              :                           // Macro is not a builtin, so it must be a
     215              :                           // user-defined derive macro.
     216            5 :                           auto new_items
     217            5 :                             = derive_item (item, to_derive, expander);
     218            5 :                           std::move (new_items.begin (), new_items.end (),
     219              :                                      std::inserter (items, it));
     220            5 :                         }
     221              :                     }
     222          402 :                 }
     223              :               else /* Attribute */
     224              :                 {
     225      1180867 :                   if (is_builtin (current))
     226              :                     {
     227      1180867 :                       visit (*attr_it);
     228      1180867 :                       attr_it++;
     229              :                     }
     230              :                   else
     231              :                     {
     232            0 :                       attr_it = attrs.erase (attr_it);
     233            0 :                       auto new_items
     234              :                         = expand_item_attribute (item, current.get_path (),
     235            0 :                                                  expander);
     236            0 :                       it = items.erase (it);
     237            0 :                       std::move (new_items.begin (), new_items.end (),
     238              :                                  std::inserter (items, it));
     239              :                       // TODO: Improve this ?
     240              :                       // item is invalid since it refers to now deleted,
     241              :                       // cancel the loop increment and break.
     242            0 :                       it--;
     243            0 :                       break;
     244            0 :                     }
     245              :                 }
     246      1181269 :             }
     247              :         }
     248              :     }
     249              : 
     250        22544 :   expand_macro_children (items, &AST::SingleASTNode::take_item);
     251              : 
     252        22544 :   expander.pop_context ();
     253        22544 : }
     254              : 
     255              : void
     256       612554 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
     257              : {
     258       612554 :   auto &stmts = expr.get_statements ();
     259       612554 :   expander.push_context (MacroExpander::ContextType::STMT);
     260              : 
     261       957253 :   for (auto it = stmts.begin (); it != stmts.end (); it++)
     262              :     {
     263       344699 :       auto &stmt = *it;
     264              : 
     265              :       // skip all non-item statements
     266       344699 :       if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
     267       305990 :         continue;
     268              : 
     269        38709 :       auto &item = static_cast<AST::Item &> (*stmt.get ());
     270              : 
     271        38709 :       if (item.has_outer_attrs ())
     272              :         {
     273        13561 :           auto &attrs = item.get_outer_attrs ();
     274              : 
     275        27891 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     276              :                /* erase => No increment*/)
     277              :             {
     278        14331 :               auto current = *attr_it;
     279              : 
     280        14331 :               if (current.is_derive ())
     281              :                 {
     282            0 :                   attr_it = attrs.erase (attr_it);
     283              :                   // Get traits to derive in the current attribute
     284            0 :                   auto traits_to_derive = current.get_traits_to_derive ();
     285            0 :                   for (auto &to_derive : traits_to_derive)
     286              :                     {
     287            0 :                       auto maybe_builtin = MacroBuiltin::builtins.lookup (
     288            0 :                         to_derive.get ().as_string ());
     289            0 :                       if (maybe_builtin.has_value ())
     290              :                         {
     291            0 :                           auto new_items
     292              :                             = builtin_derive_item (item, current,
     293            0 :                                                    maybe_builtin.value (),
     294            0 :                                                    expander);
     295              : 
     296              :                           // this inserts the derive *before* the item - is it a
     297              :                           // problem?
     298            0 :                           for (auto &&new_item : new_items)
     299            0 :                             it = stmts.insert (it, std::move (new_item));
     300            0 :                         }
     301              :                       else
     302              :                         {
     303            0 :                           auto new_items
     304            0 :                             = derive_item (item, to_derive, expander);
     305            0 :                           std::move (new_items.begin (), new_items.end (),
     306              :                                      std::inserter (stmts, it));
     307            0 :                         }
     308              :                     }
     309            0 :                 }
     310              :               else /* Attribute */
     311              :                 {
     312        14331 :                   if (is_builtin (current))
     313              :                     {
     314        14330 :                       visit (*attr_it);
     315        14330 :                       attr_it++;
     316              :                     }
     317              :                   else
     318              :                     {
     319            1 :                       attr_it = attrs.erase (attr_it);
     320            1 :                       auto new_items
     321              :                         = expand_stmt_attribute (item, current.get_path (),
     322            1 :                                                  expander);
     323            1 :                       it = stmts.erase (it);
     324            1 :                       std::move (new_items.begin (), new_items.end (),
     325              :                                  std::inserter (stmts, it));
     326              :                       // TODO: Improve this ?
     327              :                       // item is invalid since it refers to now deleted,
     328              :                       // cancel the loop increment and break.
     329            1 :                       it--;
     330            1 :                       break;
     331            1 :                     }
     332              :                 }
     333        14331 :             }
     334              :         }
     335              :     }
     336              : 
     337       612554 :   if (!expr.has_tail_expr ())
     338        79051 :     expr.normalize_tail_expr ();
     339              : 
     340       612554 :   expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
     341              : 
     342       612554 :   expander.pop_context ();
     343       612554 : }
     344              : 
     345              : void
     346      1245970 : ExpandVisitor::visit (AST::Attribute &attr)
     347              : {
     348              :   // An attribute input containing a macro may have been expanded to a literal
     349      1245970 :   if (attr.has_attr_input ()
     350      1245970 :       && attr.get_attr_input ().get_attr_input_type ()
     351              :            == AST::AttrInput::AttrInputType::EXPR)
     352              :     {
     353          936 :       auto &expr = static_cast<AST::AttrInputExpr &> (attr.get_attr_input ());
     354          936 :       if (expr.get_expr ().is_literal ())
     355              :         {
     356          300 :           auto &lit = static_cast<AST::LiteralExpr &> (expr.get_expr ());
     357          300 :           attr.set_attr_input (std::make_unique<AST::AttrInputLiteral> (lit));
     358              :         }
     359              :     }
     360      1245970 :   AST::DefaultASTVisitor::visit (attr);
     361      1245970 : }
     362              : 
     363              : void
     364     18933249 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
     365              : {
     366     18933249 :   NodeId old_expect = expr->get_node_id ();
     367     18933249 :   std::swap (macro_invoc_expect_id, old_expect);
     368              : 
     369     18933249 :   expander.push_context (MacroExpander::ContextType::EXPR);
     370     18933249 :   expr->accept_vis (*this);
     371     18933249 :   expander.pop_context ();
     372              : 
     373     18933249 :   std::swap (macro_invoc_expect_id, old_expect);
     374              : 
     375     18933249 :   auto final_fragment = expander.take_expanded_fragment ();
     376     18933249 :   if (final_fragment.should_expand ()
     377     18933249 :       && final_fragment.is_expression_fragment ())
     378        50267 :     expr = final_fragment.take_expression_fragment ();
     379     18933249 : }
     380              : 
     381              : void
     382      1889483 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
     383              : {
     384      1889483 :   NodeId old_expect = type->get_node_id ();
     385      1889483 :   std::swap (macro_invoc_expect_id, old_expect);
     386              : 
     387      1889483 :   expander.push_context (MacroExpander::ContextType::TYPE);
     388      1889483 :   type->accept_vis (*this);
     389      1889483 :   expander.pop_context ();
     390              : 
     391      1889483 :   std::swap (macro_invoc_expect_id, old_expect);
     392              : 
     393      1889483 :   auto final_fragment = expander.take_expanded_fragment ();
     394      1889483 :   if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
     395          496 :     type = final_fragment.take_type_fragment ();
     396      1889483 : }
     397              : 
     398              : // HACK: maybe we shouldn't have TypeNoBounds as a base class
     399              : void
     400       446762 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
     401              : {
     402       446762 :   NodeId old_expect = type->get_node_id ();
     403       446762 :   std::swap (macro_invoc_expect_id, old_expect);
     404              : 
     405       446762 :   expander.push_context (MacroExpander::ContextType::TYPE);
     406       446762 :   type->accept_vis (*this);
     407       446762 :   expander.pop_context ();
     408              : 
     409       446762 :   std::swap (macro_invoc_expect_id, old_expect);
     410              : 
     411       446762 :   auto final_fragment = expander.take_expanded_fragment ();
     412       446762 :   if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
     413            2 :     type = std::make_unique<AST::ParenthesisedType> (
     414            3 :       final_fragment.take_type_fragment (), BUILTINS_LOCATION);
     415       446762 : }
     416              : 
     417              : void
     418      2545135 : ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
     419              : {
     420      2545135 :   NodeId old_expect = pattern->get_node_id ();
     421      2545135 :   std::swap (macro_invoc_expect_id, old_expect);
     422              : 
     423      2545135 :   expander.push_context (MacroExpander::ContextType::PATTERN);
     424      2545135 :   pattern->accept_vis (*this);
     425      2545135 :   expander.pop_context ();
     426              : 
     427      2545135 :   std::swap (macro_invoc_expect_id, old_expect);
     428              : 
     429      2545135 :   auto final_fragment = expander.take_expanded_fragment ();
     430      2545135 :   if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
     431            1 :     pattern = final_fragment.take_pattern_fragment ();
     432      2545135 : }
     433              : 
     434              : void
     435        24280 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
     436              : {
     437        24280 :   expand_fields (fields);
     438        24280 : }
     439              : 
     440              : void
     441         7654 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
     442              : {
     443         7654 :   expand_fields (fields);
     444         7654 : }
     445              : 
     446              : // FIXME: This can definitely be refactored with the method above
     447              : void
     448       459657 : ExpandVisitor::expand_function_params (
     449              :   std::vector<std::unique_ptr<AST::Param>> &params)
     450              : {
     451      1282833 :   for (auto &p : params)
     452       823176 :     visit (p);
     453       459657 : }
     454              : 
     455              : void
     456       495322 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
     457              : {
     458       981685 :   for (auto &arg : args.get_generic_args ())
     459              :     {
     460       486363 :       switch (arg.get_kind ())
     461              :         {
     462       153683 :         case AST::GenericArg::Kind::Type:
     463       153683 :           maybe_expand_type (arg.get_type_ptr ());
     464       153683 :           break;
     465          323 :         case AST::GenericArg::Kind::Const:
     466          323 :           maybe_expand_expr (arg.get_expression_ptr ());
     467          323 :           break;
     468              :         default:
     469              :           break;
     470              :           // FIXME: Figure out what to do here if there is ambiguity. Since the
     471              :           // resolver comes after the expansion, we need to figure out a way to
     472              :           // strip ambiguous values here
     473              :           // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
     474              :           // or something. This would clean up this whole thing
     475              :         }
     476              :     }
     477              : 
     478              :   // FIXME: Can we have macro invocations in generic type bindings?
     479              :   // expand binding args - strip sub-types only
     480              :   // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
     481       504343 :   for (auto &binding : args.get_binding_args ())
     482         9021 :     maybe_expand_type (binding.get_type_ptr ());
     483       495322 : }
     484              : 
     485              : void
     486       106688 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
     487              : {
     488       106688 :   maybe_expand_type (path_type.get_type_ptr ());
     489              : 
     490              :   // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
     491       106688 :   if (path_type.has_as_clause ())
     492       104057 :     path_type.get_as_type_path ().accept_vis (*this);
     493       106688 : }
     494              : 
     495              : void
     496        10459 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
     497              : {
     498        22975 :   for (auto &param : params)
     499              :     {
     500        12516 :       maybe_expand_pattern (param.get_pattern_ptr ());
     501              : 
     502        12516 :       if (param.has_type_given ())
     503          711 :         maybe_expand_type (param.get_type_ptr ());
     504              :     }
     505        10459 : }
     506              : 
     507              : void
     508        28088 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
     509              : {
     510        66010 :   for (auto &item : where_clause.get_items ())
     511        37922 :     visit (item);
     512        28088 : }
     513              : 
     514              : void
     515        11133 : ExpandVisitor::visit (AST::Crate &crate)
     516              : {
     517        11133 :   expand_inner_items (crate.items);
     518        11133 : }
     519              : 
     520              : void
     521       367766 : ExpandVisitor::visit (AST::DelimTokenTree &)
     522       367766 : {}
     523              : 
     524              : void
     525         1850 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
     526         1850 : {}
     527              : 
     528              : void
     529      4025150 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
     530      4025150 : {}
     531              : 
     532              : void
     533        40385 : ExpandVisitor::visit (AST::LifetimeParam &)
     534        40385 : {}
     535              : 
     536              : void
     537         2840 : ExpandVisitor::visit (AST::ConstGenericParam &)
     538         2840 : {}
     539              : 
     540              : void
     541        56637 : ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
     542              : {
     543        56637 :   if (macro_invoc_expect_id != macro_invoc.get_node_id ())
     544              :     {
     545            0 :       rust_internal_error_at (
     546              :         macro_invoc.get_locus (),
     547              :         "attempting to expand node with id %d into position with node id %d",
     548            0 :         (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
     549              :     }
     550              : 
     551              :   // TODO: Can we do the AST fragment replacing here? Probably not, right?
     552       107481 :   expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
     553              :                                         ? AST::InvocKind::Semicoloned
     554              :                                         : AST::InvocKind::Expr);
     555        56637 : }
     556              : 
     557              : void
     558      2499356 : ExpandVisitor::visit (AST::PathInExpression &path)
     559              : {
     560      2499356 :   if (!path.is_lang_item ())
     561      5366539 :     for (auto &segment : path.get_segments ())
     562      5747324 :       if (segment.has_generic_args ())
     563        16503 :         expand_generic_args (segment.get_generic_args ());
     564      2499356 : }
     565              : 
     566              : void
     567       478821 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
     568              : {
     569       478821 :   if (segment.has_generic_args ())
     570       478819 :     expand_generic_args (segment.get_generic_args ());
     571       478821 : }
     572              : 
     573              : void
     574        17671 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
     575              : {
     576        17671 :   auto &type_path_function = segment.get_type_path_function ();
     577              : 
     578        42234 :   for (auto &type : type_path_function.get_params ())
     579        24563 :     visit (type);
     580              : 
     581        17671 :   if (type_path_function.has_return_type ())
     582        17074 :     maybe_expand_type (type_path_function.get_return_type_ptr ());
     583        17671 : }
     584              : 
     585              : void
     586         3644 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
     587              : {
     588         3644 :   expand_qualified_path_type (path.get_qualified_path_type ());
     589              : 
     590         7288 :   for (auto &segment : path.get_segments ())
     591         7288 :     if (segment.has_generic_args ())
     592            0 :       expand_generic_args (segment.get_generic_args ());
     593         3644 : }
     594              : 
     595              : void
     596       103044 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
     597              : {
     598       103044 :   expand_qualified_path_type (path.get_qualified_path_type ());
     599              : 
     600              :   // this shouldn't strip any segments, but can strip inside them
     601       103044 :   for (auto &segment : path.get_segments ())
     602            0 :     visit (segment);
     603       103044 : }
     604              : 
     605              : void
     606      6314066 : ExpandVisitor::visit (AST::LiteralExpr &expr)
     607      6314066 : {}
     608              : 
     609              : void
     610       803752 : ExpandVisitor::visit (AST::AttrInputLiteral &)
     611       803752 : {}
     612              : 
     613              : void
     614          636 : ExpandVisitor::visit (AST::AttrInputExpr &attr_input)
     615              : {
     616          636 :   maybe_expand_expr (attr_input.get_expr_ptr ());
     617          636 : }
     618              : 
     619              : void
     620            0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
     621            0 : {}
     622              : 
     623              : void
     624            0 : ExpandVisitor::visit (AST::MetaItemPathExpr &)
     625            0 : {}
     626              : 
     627              : void
     628          997 : ExpandVisitor::visit (AST::StructExprStruct &expr)
     629          997 : {}
     630              : 
     631              : void
     632        10364 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
     633              : {
     634        10364 :   expand_closure_params (expr.get_params ());
     635              : 
     636        10364 :   maybe_expand_expr (expr.get_definition_expr_ptr ());
     637        10364 : }
     638              : 
     639              : void
     640       612554 : ExpandVisitor::visit (AST::BlockExpr &expr)
     641              : {
     642       612554 :   expand_inner_stmts (expr);
     643              : 
     644       612554 :   expand_tail_expr (expr, expander);
     645       612554 :   if (expr.has_tail_expr ())
     646       533588 :     maybe_expand_expr (expr.get_tail_expr_ptr ());
     647       612554 : }
     648              : 
     649              : void
     650           95 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
     651              : {
     652           95 :   expand_closure_params (expr.get_params ());
     653              : 
     654           95 :   maybe_expand_type (expr.get_return_type_ptr ());
     655              : 
     656           95 :   visit (expr.get_definition_expr ());
     657           95 : }
     658              : 
     659              : void
     660        24302 : ExpandVisitor::visit (AST::IfExpr &expr)
     661              : {
     662        24302 :   maybe_expand_expr (expr.get_condition_expr_ptr ());
     663              : 
     664        24302 :   visit (expr.get_if_block ());
     665        24302 : }
     666              : 
     667              : void
     668        39699 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
     669              : {
     670        39699 :   maybe_expand_expr (expr.get_condition_expr_ptr ());
     671              : 
     672        39699 :   visit (expr.get_if_block ());
     673        39699 :   visit (expr.get_else_block ());
     674        39699 : }
     675              : 
     676              : void
     677         2169 : ExpandVisitor::visit (AST::IfLetExpr &expr)
     678              : {
     679         2169 :   maybe_expand_expr (expr.get_value_expr_ptr ());
     680              : 
     681         2169 :   visit (expr.get_if_block ());
     682         2169 : }
     683              : 
     684              : void
     685         1074 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
     686              : {
     687         1074 :   maybe_expand_expr (expr.get_value_expr_ptr ());
     688              : 
     689         1074 :   visit (expr.get_if_block ());
     690         1074 :   visit (expr.get_else_block ());
     691         1074 : }
     692              : 
     693              : void
     694       263552 : ExpandVisitor::visit (AST::TypeParam &param)
     695              : {
     696       340734 :   for (auto &bound : param.get_type_param_bounds ())
     697        77182 :     visit (bound);
     698              : 
     699       263552 :   if (param.has_type ())
     700         2045 :     maybe_expand_type (param.get_type_ptr ());
     701       263552 : }
     702              : 
     703              : void
     704           39 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
     705           39 : {}
     706              : 
     707              : void
     708        37883 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
     709              : {
     710        37883 :   maybe_expand_type (item.get_type_ptr ());
     711              : 
     712        77512 :   for (auto &bound : item.get_type_param_bounds ())
     713        39629 :     visit (bound);
     714        37883 : }
     715              : 
     716              : void
     717        11411 : ExpandVisitor::visit (AST::Module &module)
     718              : {
     719        11411 :   expand_inner_items (module.get_items ());
     720        11411 : }
     721              : 
     722              : void
     723           74 : ExpandVisitor::visit (AST::ExternCrate &crate)
     724           74 : {}
     725              : 
     726              : void
     727            0 : ExpandVisitor::visit (AST::UseTreeGlob &)
     728            0 : {}
     729              : 
     730              : void
     731            0 : ExpandVisitor::visit (AST::UseTreeList &)
     732            0 : {}
     733              : 
     734              : void
     735            0 : ExpandVisitor::visit (AST::UseTreeRebind &)
     736            0 : {}
     737              : 
     738              : void
     739        25548 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
     740        25548 : {}
     741              : 
     742              : void
     743       459657 : ExpandVisitor::visit (AST::Function &function)
     744              : {
     745       459657 :   if (function.has_body ())
     746       414841 :     visit_inner_using_attrs (
     747       414841 :       function, function.get_definition ().value ()->get_inner_attrs ());
     748       515787 :   for (auto &param : function.get_generic_params ())
     749        56130 :     visit (param);
     750              : 
     751       459657 :   expand_function_params (function.get_function_params ());
     752              : 
     753       459657 :   if (function.has_return_type ())
     754       394171 :     maybe_expand_type (function.get_return_type_ptr ());
     755              : 
     756       459657 :   if (function.has_where_clause ())
     757        15125 :     expand_where_clause (function.get_where_clause ());
     758              : 
     759       459657 :   if (function.has_body ())
     760       414841 :     visit (*function.get_definition ());
     761       459657 : }
     762              : 
     763              : void
     764        23775 : ExpandVisitor::visit (AST::StructStruct &struct_item)
     765              : {
     766        33928 :   for (auto &generic : struct_item.get_generic_params ())
     767        10153 :     visit (generic);
     768              : 
     769        23775 :   if (struct_item.has_where_clause ())
     770          389 :     expand_where_clause (struct_item.get_where_clause ());
     771              : 
     772        23775 :   expand_struct_fields (struct_item.get_fields ());
     773        23775 : }
     774              : 
     775              : void
     776         5583 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
     777              : {
     778         7782 :   for (auto &generic : tuple_struct.get_generic_params ())
     779         2199 :     visit (generic);
     780              : 
     781         5583 :   if (tuple_struct.has_where_clause ())
     782           35 :     expand_where_clause (tuple_struct.get_where_clause ());
     783              : 
     784         5583 :   expand_tuple_fields (tuple_struct.get_fields ());
     785         5583 : }
     786              : 
     787              : void
     788         3145 : ExpandVisitor::visit (AST::EnumItem &item)
     789         3145 : {}
     790              : 
     791              : void
     792         2071 : ExpandVisitor::visit (AST::EnumItemTuple &item)
     793              : {
     794         2071 :   expand_tuple_fields (item.get_tuple_fields ());
     795         2071 : }
     796              : 
     797              : void
     798          208 : ExpandVisitor::visit (AST::EnumItemStruct &item)
     799              : {
     800          208 :   expand_struct_fields (item.get_struct_fields ());
     801          208 : }
     802              : 
     803              : void
     804          792 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
     805              : {
     806          792 :   maybe_expand_expr (item.get_expr_ptr ());
     807          792 : }
     808              : 
     809              : void
     810          297 : ExpandVisitor::visit (AST::Union &union_item)
     811              : {
     812          526 :   for (auto &generic : union_item.get_generic_params ())
     813          229 :     visit (generic);
     814              : 
     815          297 :   expand_struct_fields (union_item.get_variants ());
     816          297 : }
     817              : 
     818              : void
     819        13826 : ExpandVisitor::visit (AST::Trait &trait)
     820              : {
     821        17526 :   for (auto &generic : trait.get_generic_params ())
     822         3700 :     visit (generic);
     823              : 
     824        17997 :   for (auto &bound : trait.get_type_param_bounds ())
     825         4171 :     visit (bound);
     826              : 
     827        13826 :   if (trait.has_where_clause ())
     828           21 :     expand_where_clause (trait.get_where_clause ());
     829              : 
     830        13826 :   expander.push_context (MacroExpander::ContextType::TRAIT);
     831              : 
     832        13826 :   expand_macro_children (MacroExpander::ContextType::TRAIT,
     833              :                          trait.get_trait_items (),
     834              :                          &AST::SingleASTNode::take_assoc_item);
     835              : 
     836        13826 :   expander.pop_context ();
     837        13826 : }
     838              : 
     839              : void
     840        12351 : ExpandVisitor::visit (AST::InherentImpl &impl)
     841              : {
     842        24702 :   visit_inner_attrs (impl);
     843              :   // just expand sub-stuff - can't actually strip generic params themselves
     844        22332 :   for (auto &generic : impl.get_generic_params ())
     845         9981 :     visit (generic);
     846              : 
     847              :   // FIXME: Is that correct? How do we test that?
     848        12351 :   expander.push_context (MacroExpander::ContextType::ITEM);
     849              : 
     850        12351 :   maybe_expand_type (impl.get_type_ptr ());
     851              : 
     852        12351 :   expander.pop_context ();
     853              : 
     854        12351 :   if (impl.has_where_clause ())
     855          107 :     expand_where_clause (impl.get_where_clause ());
     856              : 
     857        12351 :   expand_macro_children (MacroExpander::ContextType::IMPL,
     858              :                          impl.get_impl_items (),
     859              :                          &AST::SingleASTNode::take_assoc_item);
     860        12351 : }
     861              : 
     862              : void
     863       234968 : ExpandVisitor::visit (AST::TraitImpl &impl)
     864              : {
     865       469936 :   visit_inner_attrs (impl);
     866              :   // just expand sub-stuff - can't actually strip generic params themselves
     867       458074 :   for (auto &param : impl.get_generic_params ())
     868       223106 :     visit (param);
     869              : 
     870              :   // FIXME: Is that correct? How do we test that?
     871       234968 :   expander.push_context (MacroExpander::ContextType::ITEM);
     872              : 
     873       234968 :   maybe_expand_type (impl.get_type_ptr ());
     874              : 
     875       234968 :   expander.pop_context ();
     876              : 
     877       234968 :   visit (impl.get_trait_path ());
     878              : 
     879       234968 :   if (impl.has_where_clause ())
     880        12411 :     expand_where_clause (impl.get_where_clause ());
     881              : 
     882       234968 :   expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
     883              :                          impl.get_impl_items (),
     884              :                          &AST::SingleASTNode::take_assoc_item);
     885       234968 : }
     886              : 
     887              : void
     888           39 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
     889           39 : {}
     890              : 
     891              : void
     892            2 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
     893              : {
     894            2 :   maybe_expand_type (static_item.get_type_ptr ());
     895            2 : }
     896              : 
     897              : void
     898         5244 : ExpandVisitor::visit (AST::ExternBlock &block)
     899              : {
     900        10488 :   visit_inner_attrs (block);
     901              : 
     902         5244 :   expand_macro_children (MacroExpander::ContextType::EXTERN,
     903              :                          block.get_extern_items (),
     904              :                          &AST::SingleASTNode::take_external_item);
     905         5244 : }
     906              : 
     907              : void
     908            0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
     909            0 : {}
     910              : 
     911              : void
     912            0 : ExpandVisitor::visit (AST::MacroMatcher &)
     913            0 : {}
     914              : 
     915              : void
     916        28895 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
     917        28895 : {}
     918              : 
     919              : void
     920            0 : ExpandVisitor::visit (AST::MetaItemPath &)
     921            0 : {}
     922              : 
     923              : void
     924            0 : ExpandVisitor::visit (AST::MetaItemSeq &)
     925            0 : {}
     926              : 
     927              : void
     928            0 : ExpandVisitor::visit (AST::MetaListPaths &)
     929            0 : {}
     930              : 
     931              : void
     932            0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
     933            0 : {}
     934              : 
     935              : void
     936          651 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
     937          651 : {}
     938              : 
     939              : void
     940        18218 : ExpandVisitor::visit (AST::BareFunctionType &type)
     941              : {
     942       127062 :   for (auto &param : type.get_function_params ())
     943              :     {
     944       108844 :       maybe_expand_type (param.get_type_ptr ());
     945              :     }
     946              : 
     947        18218 :   if (type.has_return_type ())
     948        17898 :     visit (type.get_return_type ());
     949        18218 : }
     950              : 
     951              : void
     952       527785 : ExpandVisitor::visit (AST::FunctionParam &param)
     953              : {
     954       527785 :   maybe_expand_pattern (param.get_pattern_ptr ());
     955       527785 :   maybe_expand_type (param.get_type_ptr ());
     956       527785 : }
     957              : 
     958              : void
     959         1859 : ExpandVisitor::visit (AST::VariadicParam &param)
     960              : {
     961         1859 :   if (param.has_pattern ())
     962           22 :     maybe_expand_pattern (param.get_pattern_ptr ());
     963         1859 : }
     964              : 
     965              : void
     966       293532 : ExpandVisitor::visit (AST::SelfParam &param)
     967              : {
     968              :   /* TODO: maybe check for invariants being violated - e.g. both type and
     969              :    * lifetime? */
     970       293532 :   if (param.has_type ())
     971          457 :     maybe_expand_type (param.get_type_ptr ());
     972       293532 : }
     973              : 
     974              : template <typename T>
     975              : void
     976            0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
     977              : {
     978              :   // FIXME: Retrieve path from segments + local use statements instead of string
     979            0 :   expander.expand_attribute_proc_macro (item, path);
     980            0 : }
     981              : 
     982              : template <typename T>
     983              : void
     984       667404 : ExpandVisitor::visit_inner_using_attrs (T &item,
     985              :                                         std::vector<AST::Attribute> &attrs)
     986              : {
     987       667474 :   for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
     988              :     {
     989           35 :       auto current = *it;
     990              : 
     991           35 :       if (!is_builtin (current) && !current.is_derive ())
     992              :         {
     993            0 :           it = attrs.erase (it);
     994            0 :           expand_inner_attribute (item, current.get_path ());
     995              :         }
     996              :       else
     997              :         {
     998           35 :           it++;
     999              :         }
    1000              :     }
    1001       667404 : }
    1002              : 
    1003              : template <typename T>
    1004              : void
    1005         5244 : ExpandVisitor::visit_inner_attrs (T &item)
    1006              : {
    1007       252563 :   visit_inner_using_attrs (item, item.get_inner_attrs ());
    1008              : }
    1009              : 
    1010              : } // namespace Rust
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.