diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-01 10:41:45 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-01 11:19:11 +0100 |
commit | 58d1721529e99c7c633615e7491b777a6198ed00 (patch) | |
tree | 494dea8c86717a2efeacd4dc757de0bc5d48ff0a /gcc/rust/expand/rust-macro-expand.cc | |
parent | 12d156566af84ec834abb7e18feac6e8f5884451 (diff) | |
download | gcc-58d1721529e99c7c633615e7491b777a6198ed00.zip gcc-58d1721529e99c7c633615e7491b777a6198ed00.tar.gz gcc-58d1721529e99c7c633615e7491b777a6198ed00.tar.bz2 |
macroinvocation: Only allow *stmt* visitors when semicoloned
Diffstat (limited to 'gcc/rust/expand/rust-macro-expand.cc')
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 146 |
1 files changed, 62 insertions, 84 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index f52b24a..be3859f 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -310,31 +310,33 @@ public: // supposedly does not require - cfg does nothing } - // FIXME: ARTHUR: Check to see if necessary for MacroInvocation - // void visit (AST::MacroInvocationSemi ¯o_invoc) override - // { - // // initial strip test based on outer attrs - // expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); - // if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ())) - // { - // macro_invoc.mark_for_strip (); - // return; - // } + void visit (AST::MacroInvocation ¯o_invoc) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); + if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ())) + { + macro_invoc.mark_for_strip (); + return; + } - // // can't strip simple path + // can't strip simple path - // // I don't think any macro token trees can be stripped in any way + // I don't think any macro token trees can be stripped in any way - // // TODO: maybe have cfg! macro stripping behaviour here? + // TODO: maybe have cfg! macro stripping behaviour here? - // expander.expand_invoc_semi (macro_invoc); + if (macro_invoc.has_semicolon ()) + expander.expand_invoc_semi (macro_invoc); + else + expander.expand_invoc (macro_invoc); - // // we need to visit the expanded fragments since it may need cfg - // expansion - // // and it may be recursive - // for (auto &node : macro_invoc.get_fragment ().get_nodes ()) - // node.accept_vis (*this); - // } + // we need to visit the expanded fragments since it may need cfg + // expansion + // and it may be recursive + for (auto &node : macro_invoc.get_fragment ().get_nodes ()) + node.accept_vis (*this); + } void visit (AST::PathInExpression &path) override { @@ -2536,28 +2538,6 @@ public: expander.mappings->insert_macro_def (&rules_def); } - void visit (AST::MacroInvocation ¯o_invoc) override - { - // FIXME - // we probably need another recurision check here - - // initial strip test based on outer attrs - expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); - if (expander.fails_cfg_with_expand (macro_invoc.get_outer_attrs ())) - { - macro_invoc.mark_for_strip (); - return; - } - - // I don't think any macro token trees can be stripped in any way - expander.expand_invoc (macro_invoc); - - // we need to visit the expanded fragments since it may need cfg expansion - // and it may be recursive - for (auto &node : macro_invoc.get_fragment ().get_nodes ()) - node.accept_vis (*this); - } - void visit (AST::MetaItemPath &) override {} void visit (AST::MetaItemSeq &) override {} void visit (AST::MetaWord &) override {} @@ -3210,48 +3190,46 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc) invoc.set_fragment (std::move (fragment)); } -// FIXME: ARTHUR: Check to see if necessary for MacroInvocation -// void -// MacroExpander::expand_invoc_semi (AST::MacroInvocationSemi &invoc) -// { -// if (depth_exceeds_recursion_limit ()) -// { -// rust_error_at (invoc.get_locus (), "reached recursion limit"); -// return; -// } -// -// AST::MacroInvocData &invoc_data = invoc.get_invoc_data (); -// -// // lookup the rules for this macro -// NodeId resolved_node = UNKNOWN_NODEID; -// bool found = resolver->get_macro_scope ().lookup ( -// Resolver::CanonicalPath::new_seg (invoc.get_macro_node_id (), -// invoc_data.get_path ().as_string ()), -// &resolved_node); -// if (!found) -// { -// rust_error_at (invoc.get_locus (), "unknown macro"); -// return; -// } -// -// // lookup the rules -// AST::MacroRulesDefinition *rules_def = nullptr; -// bool ok = mappings->lookup_macro_def (resolved_node, &rules_def); -// rust_assert (ok); -// -// auto fragment = AST::ASTFragment::create_empty (); -// -// if (rules_def->is_builtin ()) -// fragment -// = rules_def->get_builtin_transcriber () (invoc.get_locus (), -// invoc_data); -// else -// fragment -// = expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, true); -// -// // lets attach this fragment to the invocation -// invoc.set_fragment (std::move (fragment)); -// } +void +MacroExpander::expand_invoc_semi (AST::MacroInvocation &invoc) +{ + if (depth_exceeds_recursion_limit ()) + { + rust_error_at (invoc.get_locus (), "reached recursion limit"); + return; + } + + AST::MacroInvocData &invoc_data = invoc.get_invoc_data (); + + // lookup the rules for this macro + NodeId resolved_node = UNKNOWN_NODEID; + bool found = resolver->get_macro_scope ().lookup ( + Resolver::CanonicalPath::new_seg (invoc.get_macro_node_id (), + invoc_data.get_path ().as_string ()), + &resolved_node); + if (!found) + { + rust_error_at (invoc.get_locus (), "unknown macro"); + return; + } + + // lookup the rules + AST::MacroRulesDefinition *rules_def = nullptr; + bool ok = mappings->lookup_macro_def (resolved_node, &rules_def); + rust_assert (ok); + + auto fragment = AST::ASTFragment::create_empty (); + + if (rules_def->is_builtin ()) + fragment + = rules_def->get_builtin_transcriber () (invoc.get_locus (), invoc_data); + else + fragment + = expand_decl_macro (invoc.get_locus (), invoc_data, *rules_def, true); + + // lets attach this fragment to the invocation + invoc.set_fragment (std::move (fragment)); +} /* Determines whether any cfg predicate is false and hence item with attributes * should be stripped. Note that attributes must be expanded before calling. */ |