]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Resolve nested macro definition
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Tue, 8 Aug 2023 10:16:44 +0000 (12:16 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:00:34 +0000 (19:00 +0100)
We need to collect the early resolver's macros error to emit them at a
later stage after further expansion in order to retrieve macros defined
by other macro invocations.
Register some mappings for macro invocations and macro definitions.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::visit):
Collect error instead of emitting it. Also add invocation
registration.
* resolve/rust-early-name-resolver-2.0.h (std::function<void):
Add type definition for collection.
* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit):
Register macro rule definition in mappings.
* rust-session-manager.cc (Session::expansion): Add macro
resolve error collection.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/resolve/rust-early-name-resolver-2.0.cc
gcc/rust/resolve/rust-early-name-resolver-2.0.h
gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
gcc/rust/rust-session-manager.cc

index df72d6e27c3ccba31cb240ae29101a9501309ece..a201bc4a78bad40c0bd80109818db50cee6f9bd7 100644 (file)
@@ -135,13 +135,28 @@ Early::visit (AST::MacroInvocation &invoc)
   // if the definition still does not have a value, then it's an error
   if (!definition.has_value ())
     {
-      rust_error_at (invoc.get_locus (), ErrorCode::E0433,
-                    "could not resolve macro invocation");
+      collect_error ([&] () {
+       rust_error_at (invoc.get_locus (), ErrorCode::E0433,
+                      "could not resolve macro invocation");
+      });
       return;
     }
 
   // now do we need to keep mappings or something? or insert "uses" into our
   // ForeverStack? can we do that? are mappings simpler?
+  auto mappings = Analysis::Mappings::get ();
+  AST::MacroRulesDefinition *rules_def = nullptr;
+  if (!mappings->lookup_macro_def (definition.value (), &rules_def))
+    {
+      // Macro definition not found, maybe it is not expanded yet.
+      return;
+    }
+
+  AST::MacroRulesDefinition *tmp_def = nullptr;
+  if (mappings->lookup_macro_invocation (invoc, &tmp_def))
+    return;
+
+  mappings->insert_macro_invocation (invoc, rules_def);
 }
 
 void
index fe83cf4493b3a887ff065263ed72679a646422f7..67785d0b60449a53adb01437f6742e85f6851f99 100644 (file)
@@ -28,6 +28,8 @@
 namespace Rust {
 namespace Resolver2_0 {
 
+using ResolveError = std::function<void ()>;
+
 class Early : public DefaultResolver
 {
   using DefaultResolver::visit;
@@ -37,6 +39,11 @@ public:
 
   void go (AST::Crate &crate);
 
+  const std::vector<ResolveError> &get_macro_resolve_errors () const
+  {
+    return macro_resolve_errors;
+  }
+
   // we need to handle definitions for textual scoping
   void visit (AST::MacroRulesDefinition &) override;
 
@@ -76,6 +83,9 @@ private:
   };
 
   TextualScope textual_scope;
+  std::vector<ResolveError> macro_resolve_errors;
+
+  void collect_error (ResolveError e) { macro_resolve_errors.push_back (e); }
 };
 
 } // namespace Resolver2_0
index c28d92270037db0eec0a151cb86eca5342ae8f68..e6c48d5d0edf71d8b61987e44b4ce42d0de0f920 100644 (file)
@@ -107,6 +107,13 @@ TopLevel::visit (AST::MacroRulesDefinition &macro)
 
   if (macro.get_kind () == AST::MacroRulesDefinition::MacroKind::DeclMacro)
     insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
+
+  auto mappings = Analysis::Mappings::get ();
+  AST::MacroRulesDefinition *tmp = nullptr;
+  if (mappings->lookup_macro_def (macro.get_node_id (), &tmp))
+    return;
+
+  mappings->insert_macro_def (&macro);
 }
 
 void
index 1c5d72906d84cfdcb72be300926bac412470bc52..8911e7d89aeed058eb91c44dade7b089553004ec 100644 (file)
@@ -874,6 +874,7 @@ Session::expansion (AST::Crate &crate)
   /* expand by calling cxtctxt object's monotonic_expander's expand_crate
    * method. */
   MacroExpander expander (crate, cfg, *this);
+  std::vector<Resolver2_0::ResolveError> macro_errors;
 
   while (!fixed_point_reached && iterations < cfg.recursion_limit)
     {
@@ -882,7 +883,11 @@ Session::expansion (AST::Crate &crate)
       auto ctx = Resolver2_0::NameResolutionContext ();
 
       if (flag_name_resolution_2_0)
-       Resolver2_0::Early (ctx).go (crate);
+       {
+         Resolver2_0::Early early (ctx);
+         early.go (crate);
+         macro_errors = early.get_macro_resolve_errors ();
+       }
       else
        Resolver::EarlyNameResolver ().go (crate);
 
@@ -896,6 +901,10 @@ Session::expansion (AST::Crate &crate)
        break;
     }
 
+  // Fixed point reached: Emit unresolved macros error
+  for (auto &error : macro_errors)
+    error ();
+
   if (iterations == cfg.recursion_limit)
     {
       auto &last_invoc = expander.get_last_invocation ();