diff options
Diffstat (limited to 'gcc/rust/rust-session-manager.cc')
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 6966ccc..d4e3715 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -827,9 +827,6 @@ Session::injection (AST::Crate &crate) void Session::expansion (AST::Crate &crate) { - /* We need to name resolve macros and imports here */ - Resolver::EarlyNameResolver ().go (crate); - rust_debug ("started expansion"); /* rustc has a modification to windows PATH temporarily here, which may end @@ -839,11 +836,41 @@ Session::expansion (AST::Crate &crate) // if not, would at least have to configure recursion_limit ExpansionCfg cfg; + auto fixed_point_reached = false; + unsigned iterations = 0; + // create extctxt? from parse session, cfg, and resolver? /* expand by calling cxtctxt object's monotonic_expander's expand_crate * method. */ MacroExpander expander (crate, cfg, *this); - expander.expand_crate (); + + while (!fixed_point_reached && iterations < cfg.recursion_limit) + { + /* We need to name resolve macros and imports here */ + Resolver::EarlyNameResolver ().go (crate); + + expander.expand_crate (); + + fixed_point_reached = !expander.has_changed (); + expander.reset_changed_state (); + iterations++; + + if (saw_errors ()) + break; + } + + if (iterations == cfg.recursion_limit) + { + auto last_invoc = expander.get_last_invocation (); + auto last_def = expander.get_last_definition (); + + rust_assert (last_def && last_invoc); + + RichLocation range (last_invoc->get_locus ()); + range.add_range (last_def->get_locus ()); + + rust_error_at (range, "reached recursion limit"); + } // error reporting - check unused macros, get missing fragment specifiers |