LCOV - code coverage report
Current view: top level - gcc/rust/expand - rust-expand-visitor.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 80.7 % 591 477
Test Date: 2026-02-28 14:20:25 Functions: 80.2 % 111 89
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        12736 : is_builtin (AST::Attribute &attr)
      33              : {
      34        12736 :   auto &segments = attr.get_path ().get_segments ();
      35        12736 :   return !segments.empty ()
      36        12736 :          && !Analysis::BuiltinAttributeMappings::get ()
      37        12736 :                ->lookup_builtin (segments[0].get_segment_name ())
      38        12736 :                .is_error ();
      39              : }
      40              : 
      41              : /* Expand all of the macro invocations currently contained in a crate */
      42              : void
      43        10347 : ExpandVisitor::go (AST::Crate &crate)
      44              : {
      45        10347 :   visit (crate);
      46        10347 : }
      47              : 
      48              : static std::vector<std::unique_ptr<AST::Item>>
      49          291 : builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
      50              :                      BuiltinMacro to_derive)
      51              : {
      52          291 :   auto items = AST::DeriveVisitor::derive (item, derive, to_derive);
      53          722 :   for (auto &item : items)
      54          431 :     Analysis::Mappings::get ().add_derived_node (item->get_node_id ());
      55          291 :   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        52814 : expand_tail_expr (AST::BlockExpr &block_expr, MacroExpander &expander)
     137              : {
     138        52814 :   if (block_expr.has_tail_expr ())
     139              :     {
     140        39875 :       auto tail = block_expr.take_tail_expr ();
     141        39875 :       auto attrs = tail->get_outer_attrs ();
     142        39875 :       bool changed = false;
     143        40753 :       for (auto it = attrs.begin (); it != attrs.end ();)
     144              :         {
     145          878 :           auto current = *it;
     146          878 :           if (is_builtin (current))
     147              :             {
     148          878 :               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          878 :         }
     162        39875 :       if (changed)
     163            0 :         block_expr.normalize_tail_expr ();
     164              :       else
     165        39875 :         block_expr.set_tail_expr (std::move (tail));
     166        39875 :     }
     167        52814 : }
     168              : 
     169              : void
     170        13535 : ExpandVisitor::expand_inner_items (
     171              :   std::vector<std::unique_ptr<AST::Item>> &items)
     172              : {
     173        13535 :   expander.push_context (MacroExpander::ContextType::ITEM);
     174              : 
     175        70469 :   for (auto it = items.begin (); it != items.end (); it++)
     176              :     {
     177        56934 :       Rust::AST::Item &item = **it;
     178        56934 :       if (item.has_outer_attrs ())
     179              :         {
     180         8881 :           auto &attrs = item.get_outer_attrs ();
     181              : 
     182        20889 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     183              :                /* erase => No increment*/)
     184              :             {
     185        12008 :               auto current = *attr_it;
     186              : 
     187        12008 :               if (current.is_derive ())
     188              :                 {
     189          160 :                   current.parse_attr_to_meta_item ();
     190          160 :                   attr_it = attrs.erase (attr_it);
     191              :                   // Get traits to derive in the current attribute
     192          160 :                   auto traits_to_derive = current.get_traits_to_derive ();
     193          451 :                   for (auto &to_derive : traits_to_derive)
     194              :                     {
     195          291 :                       auto maybe_builtin = MacroBuiltin::builtins.lookup (
     196          291 :                         to_derive.get ().as_string ());
     197          291 :                       if (maybe_builtin.has_value ())
     198              :                         {
     199          291 :                           auto new_items
     200              :                             = builtin_derive_item (item, current,
     201          291 :                                                    maybe_builtin.value ());
     202              : 
     203          722 :                           for (auto &&new_item : new_items)
     204          431 :                             it = items.insert (it, std::move (new_item));
     205          291 :                         }
     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          160 :                 }
     217              :               else /* Attribute */
     218              :                 {
     219        11848 :                   if (is_builtin (current))
     220              :                     {
     221        11848 :                       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        12008 :             }
     240              :         }
     241              :     }
     242              : 
     243        13535 :   expand_macro_children (items, &AST::SingleASTNode::take_item);
     244              : 
     245        13535 :   expander.pop_context ();
     246        13535 : }
     247              : 
     248              : void
     249        52814 : ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
     250              : {
     251        52814 :   auto &stmts = expr.get_statements ();
     252        52814 :   expander.push_context (MacroExpander::ContextType::STMT);
     253              : 
     254       101305 :   for (auto it = stmts.begin (); it != stmts.end (); it++)
     255              :     {
     256        48491 :       auto &stmt = *it;
     257              : 
     258              :       // skip all non-item statements
     259        48491 :       if (stmt->get_stmt_kind () != AST::Stmt::Kind::Item)
     260        46890 :         continue;
     261              : 
     262         1601 :       auto &item = static_cast<AST::Item &> (*stmt.get ());
     263              : 
     264         1601 :       if (item.has_outer_attrs ())
     265              :         {
     266           10 :           auto &attrs = item.get_outer_attrs ();
     267              : 
     268           19 :           for (auto attr_it = attrs.begin (); attr_it != attrs.end ();
     269              :                /* erase => No increment*/)
     270              :             {
     271           10 :               auto current = *attr_it;
     272              : 
     273           10 :               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           10 :                   if (is_builtin (current))
     305              :                     {
     306            9 :                       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           10 :             }
     325              :         }
     326              :     }
     327              : 
     328        52814 :   if (!expr.has_tail_expr ())
     329        12998 :     expr.normalize_tail_expr ();
     330              : 
     331        52814 :   expand_macro_children (stmts, &AST::SingleASTNode::take_stmt);
     332              : 
     333        52814 :   expander.pop_context ();
     334        52814 : }
     335              : 
     336              : void
     337      1285533 : ExpandVisitor::maybe_expand_expr (std::unique_ptr<AST::Expr> &expr)
     338              : {
     339      1285533 :   NodeId old_expect = expr->get_node_id ();
     340      1285533 :   std::swap (macro_invoc_expect_id, old_expect);
     341              : 
     342      1285533 :   expander.push_context (MacroExpander::ContextType::EXPR);
     343      1285533 :   expr->accept_vis (*this);
     344      1285533 :   expander.pop_context ();
     345              : 
     346      1285533 :   std::swap (macro_invoc_expect_id, old_expect);
     347              : 
     348      1285533 :   auto final_fragment = expander.take_expanded_fragment ();
     349      1285533 :   if (final_fragment.should_expand ()
     350      1285533 :       && final_fragment.is_expression_fragment ())
     351         1892 :     expr = final_fragment.take_expression_fragment ();
     352      1285533 : }
     353              : 
     354              : void
     355       104231 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::Type> &type)
     356              : {
     357       104231 :   NodeId old_expect = type->get_node_id ();
     358       104231 :   std::swap (macro_invoc_expect_id, old_expect);
     359              : 
     360       104231 :   expander.push_context (MacroExpander::ContextType::TYPE);
     361       104231 :   type->accept_vis (*this);
     362       104231 :   expander.pop_context ();
     363              : 
     364       104231 :   std::swap (macro_invoc_expect_id, old_expect);
     365              : 
     366       104231 :   auto final_fragment = expander.take_expanded_fragment ();
     367       104231 :   if (final_fragment.should_expand () && final_fragment.is_type_fragment ())
     368           28 :     type = final_fragment.take_type_fragment ();
     369       104231 : }
     370              : 
     371              : // HACK: maybe we shouldn't have TypeNoBounds as a base class
     372              : void
     373        37310 : ExpandVisitor::maybe_expand_type (std::unique_ptr<AST::TypeNoBounds> &type)
     374              : {
     375        37310 :   NodeId old_expect = type->get_node_id ();
     376        37310 :   std::swap (macro_invoc_expect_id, old_expect);
     377              : 
     378        37310 :   expander.push_context (MacroExpander::ContextType::TYPE);
     379        37310 :   type->accept_vis (*this);
     380        37310 :   expander.pop_context ();
     381              : 
     382        37310 :   std::swap (macro_invoc_expect_id, old_expect);
     383              : 
     384        37310 :   auto final_fragment = expander.take_expanded_fragment ();
     385        37310 :   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        37310 : }
     389              : 
     390              : void
     391        68786 : ExpandVisitor::maybe_expand_pattern (std::unique_ptr<AST::Pattern> &pattern)
     392              : {
     393        68786 :   NodeId old_expect = pattern->get_node_id ();
     394        68786 :   std::swap (macro_invoc_expect_id, old_expect);
     395              : 
     396        68786 :   expander.push_context (MacroExpander::ContextType::PATTERN);
     397        68786 :   pattern->accept_vis (*this);
     398        68786 :   expander.pop_context ();
     399              : 
     400        68786 :   std::swap (macro_invoc_expect_id, old_expect);
     401              : 
     402        68786 :   auto final_fragment = expander.take_expanded_fragment ();
     403        68786 :   if (final_fragment.should_expand () && final_fragment.is_pattern_fragment ())
     404            1 :     pattern = final_fragment.take_pattern_fragment ();
     405        68786 : }
     406              : 
     407              : void
     408         3920 : ExpandVisitor::expand_struct_fields (std::vector<AST::StructField> &fields)
     409              : {
     410         3920 :   expand_fields (fields);
     411         3920 : }
     412              : 
     413              : void
     414         3188 : ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
     415              : {
     416         3188 :   expand_fields (fields);
     417         3188 : }
     418              : 
     419              : // FIXME: This can definitely be refactored with the method above
     420              : void
     421        44012 : ExpandVisitor::expand_function_params (
     422              :   std::vector<std::unique_ptr<AST::Param>> &params)
     423              : {
     424        93200 :   for (auto &p : params)
     425        49188 :     visit (p);
     426        44012 : }
     427              : 
     428              : void
     429         9101 : ExpandVisitor::expand_generic_args (AST::GenericArgs &args)
     430              : {
     431        18610 :   for (auto &arg : args.get_generic_args ())
     432              :     {
     433         9509 :       switch (arg.get_kind ())
     434              :         {
     435         3842 :         case AST::GenericArg::Kind::Type:
     436         3842 :           maybe_expand_type (arg.get_type_ptr ());
     437         3842 :           break;
     438          138 :         case AST::GenericArg::Kind::Const:
     439          138 :           maybe_expand_expr (arg.get_expression_ptr ());
     440          138 :           break;
     441              :         default:
     442              :           break;
     443              :           // FIXME: Figure out what to do here if there is ambiguity. Since the
     444              :           // resolver comes after the expansion, we need to figure out a way to
     445              :           // strip ambiguous values here
     446              :           // TODO: ARTHUR: Probably add a `mark_as_strip` method to `GenericArg`
     447              :           // or something. This would clean up this whole thing
     448              :         }
     449              :     }
     450              : 
     451              :   // FIXME: Can we have macro invocations in generic type bindings?
     452              :   // expand binding args - strip sub-types only
     453              :   // FIXME: ARTHUR: This needs a test! Foo<Item = macro!()>
     454         9295 :   for (auto &binding : args.get_binding_args ())
     455          194 :     maybe_expand_type (binding.get_type_ptr ());
     456         9101 : }
     457              : 
     458              : void
     459          978 : ExpandVisitor::expand_qualified_path_type (AST::QualifiedPathType &path_type)
     460              : {
     461          978 :   maybe_expand_type (path_type.get_type_ptr ());
     462              : 
     463              :   // FIXME: ARTHUR: Can we do macro expansion in there? Needs a test!
     464          978 :   if (path_type.has_as_clause ())
     465          884 :     path_type.get_as_type_path ().accept_vis (*this);
     466          978 : }
     467              : 
     468              : void
     469          134 : ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
     470              : {
     471          260 :   for (auto &param : params)
     472              :     {
     473          126 :       maybe_expand_pattern (param.get_pattern_ptr ());
     474              : 
     475          126 :       if (param.has_type_given ())
     476          116 :         maybe_expand_type (param.get_type_ptr ());
     477              :     }
     478          134 : }
     479              : 
     480              : void
     481          761 : ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
     482              : {
     483         1542 :   for (auto &item : where_clause.get_items ())
     484          781 :     visit (item);
     485          761 : }
     486              : 
     487              : void
     488        10347 : ExpandVisitor::visit (AST::Crate &crate)
     489              : {
     490        10347 :   expand_inner_items (crate.items);
     491        10347 : }
     492              : 
     493              : void
     494            0 : ExpandVisitor::visit (AST::DelimTokenTree &)
     495            0 : {}
     496              : 
     497              : void
     498            0 : ExpandVisitor::visit (AST::AttrInputMetaItemContainer &)
     499            0 : {}
     500              : 
     501              : void
     502        54996 : ExpandVisitor::visit (AST::IdentifierExpr &ident_expr)
     503        54996 : {}
     504              : 
     505              : void
     506          540 : ExpandVisitor::visit (AST::LifetimeParam &)
     507          540 : {}
     508              : 
     509              : void
     510          194 : ExpandVisitor::visit (AST::ConstGenericParam &)
     511          194 : {}
     512              : 
     513              : void
     514         2793 : ExpandVisitor::visit (AST::MacroInvocation &macro_invoc)
     515              : {
     516         2793 :   if (macro_invoc_expect_id != macro_invoc.get_node_id ())
     517              :     {
     518            0 :       rust_internal_error_at (
     519              :         macro_invoc.get_locus (),
     520              :         "attempting to expand node with id %d into position with node id %d",
     521            0 :         (int) macro_invoc.get_node_id (), (int) macro_invoc_expect_id);
     522              :     }
     523              : 
     524              :   // TODO: Can we do the AST fragment replacing here? Probably not, right?
     525         4742 :   expander.expand_invoc (macro_invoc, macro_invoc.has_semicolon ()
     526              :                                         ? AST::InvocKind::Semicoloned
     527              :                                         : AST::InvocKind::Expr);
     528         2793 : }
     529              : 
     530              : void
     531        58952 : ExpandVisitor::visit (AST::PathInExpression &path)
     532              : {
     533        58952 :   if (!path.is_lang_item ())
     534       142507 :     for (auto &segment : path.get_segments ())
     535       167504 :       if (segment.has_generic_args ())
     536         2102 :         expand_generic_args (segment.get_generic_args ());
     537        58952 : }
     538              : 
     539              : void
     540         7001 : ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
     541              : {
     542         7001 :   if (segment.has_generic_args ())
     543         6999 :     expand_generic_args (segment.get_generic_args ());
     544         7001 : }
     545              : 
     546              : void
     547           60 : ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
     548              : {
     549           60 :   auto &type_path_function = segment.get_type_path_function ();
     550              : 
     551          124 :   for (auto &type : type_path_function.get_params ())
     552           64 :     visit (type);
     553              : 
     554           60 :   if (type_path_function.has_return_type ())
     555           56 :     maybe_expand_type (type_path_function.get_return_type_ptr ());
     556           60 : }
     557              : 
     558              : void
     559          269 : ExpandVisitor::visit (AST::QualifiedPathInExpression &path)
     560              : {
     561          269 :   expand_qualified_path_type (path.get_qualified_path_type ());
     562              : 
     563          538 :   for (auto &segment : path.get_segments ())
     564          538 :     if (segment.has_generic_args ())
     565            0 :       expand_generic_args (segment.get_generic_args ());
     566          269 : }
     567              : 
     568              : void
     569          709 : ExpandVisitor::visit (AST::QualifiedPathInType &path)
     570              : {
     571          709 :   expand_qualified_path_type (path.get_qualified_path_type ());
     572              : 
     573              :   // this shouldn't strip any segments, but can strip inside them
     574          709 :   for (auto &segment : path.get_segments ())
     575            0 :     visit (segment);
     576          709 : }
     577              : 
     578              : void
     579       562466 : ExpandVisitor::visit (AST::LiteralExpr &expr)
     580       562466 : {}
     581              : 
     582              : void
     583            0 : ExpandVisitor::visit (AST::AttrInputLiteral &)
     584            0 : {}
     585              : 
     586              : void
     587            0 : ExpandVisitor::visit (AST::AttrInputMacro &macro)
     588              : {
     589            0 :   rust_sorry_at (UNDEF_LOCATION, "macros in attributes not supported");
     590            0 : }
     591              : 
     592              : void
     593            0 : ExpandVisitor::visit (AST::MetaItemLitExpr &)
     594            0 : {}
     595              : 
     596              : void
     597            0 : ExpandVisitor::visit (AST::MetaItemPathExpr &)
     598            0 : {}
     599              : 
     600              : void
     601       531673 : ExpandVisitor::visit (AST::ArithmeticOrLogicalExpr &expr)
     602              : {
     603       531673 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     604       531673 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     605       531673 : }
     606              : 
     607              : void
     608         6898 : ExpandVisitor::visit (AST::ComparisonExpr &expr)
     609              : {
     610         6898 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     611         6898 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     612         6898 : }
     613              : 
     614              : void
     615          846 : ExpandVisitor::visit (AST::LazyBooleanExpr &expr)
     616              : {
     617          846 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     618          846 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     619          846 : }
     620              : 
     621              : void
     622        11769 : ExpandVisitor::visit (AST::TypeCastExpr &expr)
     623              : {
     624        11769 :   maybe_expand_expr (expr.get_casted_expr_ptr ());
     625        11769 :   maybe_expand_type (expr.get_type_to_cast_to_ptr ());
     626        11769 : }
     627              : 
     628              : void
     629         4531 : ExpandVisitor::visit (AST::AssignmentExpr &expr)
     630              : {
     631         4531 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     632         4531 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     633         4531 : }
     634              : 
     635              : void
     636         1275 : ExpandVisitor::visit (AST::CompoundAssignmentExpr &expr)
     637              : {
     638         1275 :   maybe_expand_expr (expr.get_left_expr_ptr ());
     639         1275 :   maybe_expand_expr (expr.get_right_expr_ptr ());
     640         1275 : }
     641              : 
     642              : void
     643          753 : ExpandVisitor::visit (AST::GroupedExpr &expr)
     644              : {
     645          753 :   maybe_expand_expr (expr.get_expr_in_parens_ptr ());
     646          753 : }
     647              : 
     648              : void
     649          165 : ExpandVisitor::visit (AST::StructExprStruct &expr)
     650          165 : {}
     651              : 
     652              : void
     653        26324 : ExpandVisitor::visit (AST::CallExpr &expr)
     654              : {
     655        26324 :   visit (expr.get_function_expr ());
     656              : 
     657        58647 :   for (auto &param : expr.get_params ())
     658        32323 :     maybe_expand_expr (param);
     659        26324 : }
     660              : 
     661              : void
     662           74 : ExpandVisitor::visit (AST::ClosureExprInner &expr)
     663              : {
     664           74 :   expand_closure_params (expr.get_params ());
     665              : 
     666           74 :   maybe_expand_expr (expr.get_definition_expr_ptr ());
     667           74 : }
     668              : 
     669              : void
     670        52814 : ExpandVisitor::visit (AST::BlockExpr &expr)
     671              : {
     672        52814 :   expand_inner_stmts (expr);
     673              : 
     674        52814 :   expand_tail_expr (expr, expander);
     675        52814 :   if (expr.has_tail_expr ())
     676        39875 :     maybe_expand_expr (expr.get_tail_expr_ptr ());
     677        52814 : }
     678              : 
     679              : void
     680           60 : ExpandVisitor::visit (AST::ClosureExprInnerTyped &expr)
     681              : {
     682           60 :   expand_closure_params (expr.get_params ());
     683              : 
     684           60 :   maybe_expand_type (expr.get_return_type_ptr ());
     685              : 
     686           60 :   visit (expr.get_definition_expr ());
     687           60 : }
     688              : 
     689              : void
     690           34 : ExpandVisitor::visit (AST::ContinueExpr &expr)
     691           34 : {}
     692              : 
     693              : void
     694         1057 : ExpandVisitor::visit (AST::IfExpr &expr)
     695              : {
     696         1057 :   maybe_expand_expr (expr.get_condition_expr_ptr ());
     697              : 
     698         1057 :   visit (expr.get_if_block ());
     699         1057 : }
     700              : 
     701              : void
     702         3162 : ExpandVisitor::visit (AST::IfExprConseqElse &expr)
     703              : {
     704         3162 :   maybe_expand_expr (expr.get_condition_expr_ptr ());
     705              : 
     706         3162 :   visit (expr.get_if_block ());
     707         3162 :   visit (expr.get_else_block ());
     708         3162 : }
     709              : 
     710              : void
     711           36 : ExpandVisitor::visit (AST::IfLetExpr &expr)
     712              : {
     713           36 :   maybe_expand_expr (expr.get_value_expr_ptr ());
     714              : 
     715           36 :   visit (expr.get_if_block ());
     716           36 : }
     717              : 
     718              : void
     719           24 : ExpandVisitor::visit (AST::IfLetExprConseqElse &expr)
     720              : {
     721           24 :   maybe_expand_expr (expr.get_value_expr_ptr ());
     722              : 
     723           24 :   visit (expr.get_if_block ());
     724           24 :   visit (expr.get_else_block ());
     725           24 : }
     726              : 
     727              : void
     728         1282 : ExpandVisitor::visit (AST::TupleExpr &expr)
     729              : {
     730         3542 :   for (auto &sub : expr.get_tuple_elems ())
     731         2260 :     maybe_expand_expr (sub);
     732         1282 : }
     733              : 
     734              : void
     735        10821 : ExpandVisitor::visit (AST::TypeParam &param)
     736              : {
     737        12797 :   for (auto &bound : param.get_type_param_bounds ())
     738         1976 :     visit (bound);
     739              : 
     740        10821 :   if (param.has_type ())
     741          923 :     maybe_expand_type (param.get_type_ptr ());
     742        10821 : }
     743              : 
     744              : void
     745            4 : ExpandVisitor::visit (AST::LifetimeWhereClauseItem &)
     746            4 : {}
     747              : 
     748              : void
     749          777 : ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
     750              : {
     751          777 :   maybe_expand_type (item.get_type_ptr ());
     752              : 
     753         1554 :   for (auto &bound : item.get_type_param_bounds ())
     754          777 :     visit (bound);
     755          777 : }
     756              : 
     757              : void
     758         3188 : ExpandVisitor::visit (AST::Module &module)
     759              : {
     760         3188 :   expand_inner_items (module.get_items ());
     761         3188 : }
     762              : 
     763              : void
     764           48 : ExpandVisitor::visit (AST::ExternCrate &crate)
     765           48 : {}
     766              : 
     767              : void
     768            0 : ExpandVisitor::visit (AST::UseTreeGlob &)
     769            0 : {}
     770              : 
     771              : void
     772            0 : ExpandVisitor::visit (AST::UseTreeList &)
     773            0 : {}
     774              : 
     775              : void
     776            0 : ExpandVisitor::visit (AST::UseTreeRebind &)
     777            0 : {}
     778              : 
     779              : void
     780         1837 : ExpandVisitor::visit (AST::UseDeclaration &use_decl)
     781         1837 : {}
     782              : 
     783              : void
     784        44012 : ExpandVisitor::visit (AST::Function &function)
     785              : {
     786        44012 :   if (function.has_body ())
     787        34337 :     visit_inner_using_attrs (
     788        34337 :       function, function.get_definition ().value ()->get_inner_attrs ());
     789        48362 :   for (auto &param : function.get_generic_params ())
     790         4350 :     visit (param);
     791              : 
     792        44012 :   expand_function_params (function.get_function_params ());
     793              : 
     794        44012 :   if (function.has_return_type ())
     795        32204 :     maybe_expand_type (function.get_return_type_ptr ());
     796              : 
     797        44012 :   if (function.has_where_clause ())
     798          520 :     expand_where_clause (function.get_where_clause ());
     799              : 
     800        44012 :   if (function.has_body ())
     801        34337 :     visit (*function.get_definition ());
     802        44012 : }
     803              : 
     804              : void
     805         3495 : ExpandVisitor::visit (AST::StructStruct &struct_item)
     806              : {
     807         4682 :   for (auto &generic : struct_item.get_generic_params ())
     808         1187 :     visit (generic);
     809              : 
     810         3495 :   if (struct_item.has_where_clause ())
     811            4 :     expand_where_clause (struct_item.get_where_clause ());
     812              : 
     813         3495 :   expand_struct_fields (struct_item.get_fields ());
     814         3495 : }
     815              : 
     816              : void
     817         2076 : ExpandVisitor::visit (AST::TupleStruct &tuple_struct)
     818              : {
     819         2815 :   for (auto &generic : tuple_struct.get_generic_params ())
     820          739 :     visit (generic);
     821              : 
     822         2076 :   if (tuple_struct.has_where_clause ())
     823            0 :     expand_where_clause (tuple_struct.get_where_clause ());
     824              : 
     825         2076 :   expand_tuple_fields (tuple_struct.get_fields ());
     826         2076 : }
     827              : 
     828              : void
     829         1028 : ExpandVisitor::visit (AST::EnumItem &item)
     830         1028 : {}
     831              : 
     832              : void
     833         1112 : ExpandVisitor::visit (AST::EnumItemTuple &item)
     834              : {
     835         1112 :   expand_tuple_fields (item.get_tuple_fields ());
     836         1112 : }
     837              : 
     838              : void
     839          208 : ExpandVisitor::visit (AST::EnumItemStruct &item)
     840              : {
     841          208 :   expand_struct_fields (item.get_struct_fields ());
     842          208 : }
     843              : 
     844              : void
     845          675 : ExpandVisitor::visit (AST::EnumItemDiscriminant &item)
     846              : {
     847          675 :   maybe_expand_expr (item.get_expr_ptr ());
     848          675 : }
     849              : 
     850              : void
     851          217 : ExpandVisitor::visit (AST::Union &union_item)
     852              : {
     853          374 :   for (auto &generic : union_item.get_generic_params ())
     854          157 :     visit (generic);
     855              : 
     856          217 :   expand_struct_fields (union_item.get_variants ());
     857          217 : }
     858              : 
     859              : void
     860         1151 : ExpandVisitor::visit (AST::ConstantItem &const_item)
     861              : {
     862         1151 :   maybe_expand_type (const_item.get_type_ptr ());
     863              : 
     864         1151 :   if (const_item.has_expr ())
     865         1082 :     maybe_expand_expr (const_item.get_expr_ptr ());
     866         1151 : }
     867              : 
     868              : void
     869          111 : ExpandVisitor::visit (AST::StaticItem &static_item)
     870              : {
     871          111 :   maybe_expand_type (static_item.get_type_ptr ());
     872              : 
     873          111 :   maybe_expand_expr (static_item.get_expr_ptr ());
     874          111 : }
     875              : 
     876              : void
     877         8654 : ExpandVisitor::visit (AST::Trait &trait)
     878              : {
     879        10295 :   for (auto &generic : trait.get_generic_params ())
     880         1641 :     visit (generic);
     881              : 
     882        10328 :   for (auto &bound : trait.get_type_param_bounds ())
     883         1674 :     visit (bound);
     884              : 
     885         8654 :   if (trait.has_where_clause ())
     886           21 :     expand_where_clause (trait.get_where_clause ());
     887              : 
     888         8654 :   expander.push_context (MacroExpander::ContextType::TRAIT);
     889              : 
     890         8654 :   expand_macro_children (MacroExpander::ContextType::TRAIT,
     891              :                          trait.get_trait_items (),
     892              :                          &AST::SingleASTNode::take_assoc_item);
     893              : 
     894         8654 :   expander.pop_context ();
     895         8654 : }
     896              : 
     897              : void
     898         2189 : ExpandVisitor::visit (AST::InherentImpl &impl)
     899              : {
     900         4378 :   visit_inner_attrs (impl);
     901              :   // just expand sub-stuff - can't actually strip generic params themselves
     902         2959 :   for (auto &generic : impl.get_generic_params ())
     903          770 :     visit (generic);
     904              : 
     905              :   // FIXME: Is that correct? How do we test that?
     906         2189 :   expander.push_context (MacroExpander::ContextType::ITEM);
     907              : 
     908         2189 :   maybe_expand_type (impl.get_type_ptr ());
     909              : 
     910         2189 :   expander.pop_context ();
     911              : 
     912         2189 :   if (impl.has_where_clause ())
     913            2 :     expand_where_clause (impl.get_where_clause ());
     914              : 
     915         2189 :   expand_macro_children (MacroExpander::ContextType::IMPL,
     916              :                          impl.get_impl_items (),
     917              :                          &AST::SingleASTNode::take_assoc_item);
     918         2189 : }
     919              : 
     920              : void
     921        11576 : ExpandVisitor::visit (AST::TraitImpl &impl)
     922              : {
     923        23152 :   visit_inner_attrs (impl);
     924              :   // just expand sub-stuff - can't actually strip generic params themselves
     925        13474 :   for (auto &param : impl.get_generic_params ())
     926         1898 :     visit (param);
     927              : 
     928              :   // FIXME: Is that correct? How do we test that?
     929        11576 :   expander.push_context (MacroExpander::ContextType::ITEM);
     930              : 
     931        11576 :   maybe_expand_type (impl.get_type_ptr ());
     932              : 
     933        11576 :   expander.pop_context ();
     934              : 
     935        11576 :   visit (impl.get_trait_path ());
     936              : 
     937        11576 :   if (impl.has_where_clause ())
     938          214 :     expand_where_clause (impl.get_where_clause ());
     939              : 
     940        11576 :   expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
     941              :                          impl.get_impl_items (),
     942              :                          &AST::SingleASTNode::take_assoc_item);
     943        11576 : }
     944              : 
     945              : void
     946            2 : ExpandVisitor::visit (AST::ExternalTypeItem &item)
     947            2 : {}
     948              : 
     949              : void
     950            2 : ExpandVisitor::visit (AST::ExternalStaticItem &static_item)
     951              : {
     952            2 :   maybe_expand_type (static_item.get_type_ptr ());
     953            2 : }
     954              : 
     955              : void
     956         3288 : ExpandVisitor::visit (AST::ExternBlock &block)
     957              : {
     958         6576 :   visit_inner_attrs (block);
     959              : 
     960         3288 :   expand_macro_children (MacroExpander::ContextType::EXTERN,
     961              :                          block.get_extern_items (),
     962              :                          &AST::SingleASTNode::take_external_item);
     963         3288 : }
     964              : 
     965              : void
     966            0 : ExpandVisitor::visit (AST::MacroMatchRepetition &)
     967            0 : {}
     968              : 
     969              : void
     970            0 : ExpandVisitor::visit (AST::MacroMatcher &)
     971            0 : {}
     972              : 
     973              : void
     974         3774 : ExpandVisitor::visit (AST::MacroRulesDefinition &rules_def)
     975         3774 : {}
     976              : 
     977              : void
     978            0 : ExpandVisitor::visit (AST::MetaItemPath &)
     979            0 : {}
     980              : 
     981              : void
     982            0 : ExpandVisitor::visit (AST::MetaItemSeq &)
     983            0 : {}
     984              : 
     985              : void
     986            0 : ExpandVisitor::visit (AST::MetaListPaths &)
     987            0 : {}
     988              : 
     989              : void
     990            0 : ExpandVisitor::visit (AST::MetaListNameValueStr &)
     991            0 : {}
     992              : 
     993              : void
     994          219 : ExpandVisitor::visit (AST::StructPatternFieldIdent &field)
     995          219 : {}
     996              : 
     997              : void
     998           88 : ExpandVisitor::visit (AST::GroupedPattern &pattern)
     999              : {
    1000           88 :   maybe_expand_pattern (pattern.get_pattern_in_parens_ptr ());
    1001           88 : }
    1002              : 
    1003              : void
    1004           64 : ExpandVisitor::visit (AST::SlicePatternItemsNoRest &items)
    1005              : {
    1006          192 :   for (auto &sub : items.get_patterns ())
    1007          128 :     maybe_expand_pattern (sub);
    1008           64 : }
    1009              : 
    1010              : void
    1011           88 : ExpandVisitor::visit (AST::SlicePatternItemsHasRest &items)
    1012              : {
    1013          174 :   for (auto &sub : items.get_lower_patterns ())
    1014           86 :     maybe_expand_pattern (sub);
    1015          174 :   for (auto &sub : items.get_upper_patterns ())
    1016           86 :     maybe_expand_pattern (sub);
    1017           88 : }
    1018              : 
    1019              : void
    1020          470 : ExpandVisitor::visit (AST::AltPattern &pattern)
    1021              : {
    1022         1449 :   for (auto &alt : pattern.get_alts ())
    1023          979 :     maybe_expand_pattern (alt);
    1024          470 : }
    1025              : 
    1026              : void
    1027         2556 : ExpandVisitor::visit (AST::TupleStructItemsNoRest &tuple_items)
    1028              : {
    1029         5432 :   for (auto &sub : tuple_items.get_patterns ())
    1030         2876 :     maybe_expand_pattern (sub);
    1031         2556 : }
    1032              : 
    1033              : void
    1034           78 : ExpandVisitor::visit (AST::TupleStructItemsHasRest &tuple_items)
    1035              : {
    1036          140 :   for (auto &sub : tuple_items.get_lower_patterns ())
    1037           62 :     maybe_expand_pattern (sub);
    1038              : 
    1039          116 :   for (auto &sub : tuple_items.get_upper_patterns ())
    1040           38 :     maybe_expand_pattern (sub);
    1041           78 : }
    1042              : 
    1043              : void
    1044         1172 : ExpandVisitor::visit (AST::TuplePatternItemsNoRest &tuple_items)
    1045              : {
    1046         3550 :   for (auto &sub : tuple_items.get_patterns ())
    1047         2378 :     maybe_expand_pattern (sub);
    1048         1172 : }
    1049              : 
    1050              : void
    1051           54 : ExpandVisitor::visit (AST::TuplePatternItemsHasRest &tuple_items)
    1052              : {
    1053          110 :   for (auto &sub : tuple_items.get_lower_patterns ())
    1054           56 :     maybe_expand_pattern (sub);
    1055              : 
    1056          118 :   for (auto &sub : tuple_items.get_upper_patterns ())
    1057           64 :     maybe_expand_pattern (sub);
    1058           54 : }
    1059              : 
    1060              : void
    1061        27445 : ExpandVisitor::visit (AST::LetStmt &stmt)
    1062              : {
    1063        27445 :   maybe_expand_pattern (stmt.get_pattern_ptr ());
    1064              : 
    1065        27445 :   if (stmt.has_type ())
    1066         4503 :     maybe_expand_type (stmt.get_type_ptr ());
    1067              : 
    1068        27445 :   if (stmt.has_init_expr ())
    1069        25022 :     maybe_expand_expr (stmt.get_init_expr_ptr ());
    1070        27445 : }
    1071              : 
    1072              : void
    1073        19224 : ExpandVisitor::visit (AST::ExprStmt &stmt)
    1074              : {
    1075        19224 :   maybe_expand_expr (stmt.get_expr_ptr ());
    1076        19224 : }
    1077              : 
    1078              : void
    1079          131 : ExpandVisitor::visit (AST::BareFunctionType &type)
    1080              : {
    1081          229 :   for (auto &param : type.get_function_params ())
    1082              :     {
    1083           98 :       maybe_expand_type (param.get_type_ptr ());
    1084              :     }
    1085              : 
    1086          131 :   if (type.has_return_type ())
    1087           97 :     visit (type.get_return_type ());
    1088          131 : }
    1089              : 
    1090              : void
    1091        27367 : ExpandVisitor::visit (AST::FunctionParam &param)
    1092              : {
    1093        27367 :   maybe_expand_pattern (param.get_pattern_ptr ());
    1094        27367 :   maybe_expand_type (param.get_type_ptr ());
    1095        27367 : }
    1096              : 
    1097              : void
    1098         1751 : ExpandVisitor::visit (AST::VariadicParam &param)
    1099              : {
    1100         1751 :   if (param.has_pattern ())
    1101           22 :     maybe_expand_pattern (param.get_pattern_ptr ());
    1102         1751 : }
    1103              : 
    1104              : void
    1105        20070 : ExpandVisitor::visit (AST::SelfParam &param)
    1106              : {
    1107              :   /* TODO: maybe check for invariants being violated - e.g. both type and
    1108              :    * lifetime? */
    1109        20070 :   if (param.has_type ())
    1110            2 :     maybe_expand_type (param.get_type_ptr ());
    1111        20070 : }
    1112              : 
    1113              : template <typename T>
    1114              : void
    1115            0 : ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
    1116              : {
    1117              :   // FIXME: Retrieve path from segments + local use statements instead of string
    1118            0 :   expander.expand_attribute_proc_macro (item, path);
    1119            0 : }
    1120              : 
    1121              : template <typename T>
    1122              : void
    1123        51390 : ExpandVisitor::visit_inner_using_attrs (T &item,
    1124              :                                         std::vector<AST::Attribute> &attrs)
    1125              : {
    1126        51390 :   for (auto it = attrs.begin (); it != attrs.end (); /* erase => No increment*/)
    1127              :     {
    1128            0 :       auto current = *it;
    1129              : 
    1130            0 :       if (!is_builtin (current) && !current.is_derive ())
    1131              :         {
    1132            0 :           it = attrs.erase (it);
    1133            0 :           expand_inner_attribute (item, current.get_path ());
    1134              :         }
    1135              :       else
    1136              :         {
    1137            0 :           it++;
    1138              :         }
    1139              :     }
    1140        51390 : }
    1141              : 
    1142              : template <typename T>
    1143              : void
    1144         3288 : ExpandVisitor::visit_inner_attrs (T &item)
    1145              : {
    1146        17053 :   visit_inner_using_attrs (item, item.get_inner_attrs ());
    1147              : }
    1148              : 
    1149              : } // 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.