aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/rust-session-manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/rust-session-manager.cc')
-rw-r--r--gcc/rust/rust-session-manager.cc35
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