From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Import mapping was relying on resolve_path which in turn relies on the cursor function. This means the mapping resolver should be called from the correct scope instead of being called from the crate scope.
gcc/rust/ChangeLog: * resolve/rust-early-name-resolver-2.0.cc (Early::Early): Move the top level visitor from the function scope to attributes. (Early::go): Remove top level visitor creation and adapt calling code. Remove call to mapping resolution and import finalization. (Early::finalize_simple_import): Move the finalization from it's visitor. (Early::finalize_glob_import): Likewise. (Early::finalize_rebind_import): Likewise. (Early::visit): Add mapping resolution and finalization in UseDeclaration visitor function. * resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Move function. (finalize_glob_import): Likewise. (finalize_rebind_import): Likewise. (FinalizeImports::visit): Remove call to finalizers. * resolve/rust-early-name-resolver-2.0.h (class Early): Add top level attribute. * resolve/rust-finalize-imports-2.0.h: Add function prototypes. * resolve/rust-toplevel-name-resolver-2.0.h: Change getter return type to reference. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> --- .../resolve/rust-early-name-resolver-2.0.cc | 98 +++++++++++++++++-- .../resolve/rust-early-name-resolver-2.0.h | 9 ++ gcc/rust/resolve/rust-finalize-imports-2.0.cc | 79 +-------------- gcc/rust/resolve/rust-finalize-imports-2.0.h | 4 +- .../resolve/rust-toplevel-name-resolver-2.0.h | 5 +- 5 files changed, 105 insertions(+), 90 deletions(-) diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc index b894d130ccf..492a665f43e 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc @@ -27,7 +27,8 @@ namespace Rust { namespace Resolver2_0 { -Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty (false) +Early::Early (NameResolutionContext &ctx) + : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false) {} void @@ -52,16 +53,10 @@ void Early::go (AST::Crate &crate) { // First we go through TopLevel resolution to get all our declared items - auto toplevel = TopLevel (ctx); toplevel.go (crate); // We start with resolving the list of imports that `TopLevel` has built for // us - for (auto &&import : toplevel.get_imports_to_resolve ()) - build_import_mapping (std::move (import)); - - // Once this is done, we finalize their resolution - FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate); dirty = toplevel.is_dirty (); // We now proceed with resolving macros, which can be nested in almost any @@ -375,5 +370,94 @@ Early::visit (AST::StructStruct &s) DefaultResolver::visit (s); } +void +Early::finalize_simple_import (const Early::ImportPair &mapping) +{ + // FIXME: We probably need to store namespace information + + auto locus = mapping.import_kind.to_resolve.get_locus (); + auto data = mapping.data; + auto identifier + = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name (); + + for (auto &&definition : data.definitions ()) + toplevel + .insert_or_error_out ( + identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */); +} + +void +Early::finalize_glob_import (NameResolutionContext &ctx, + const Early::ImportPair &mapping) +{ + auto module = Analysis::Mappings::get ().lookup_ast_module ( + mapping.data.module ().get_node_id ()); + rust_assert (module); + + GlobbingVisitor glob_visitor (ctx); + glob_visitor.go (module.value ()); +} + +void +Early::finalize_rebind_import (const Early::ImportPair &mapping) +{ + // We can fetch the value here as `resolve_rebind` will only be called on + // imports of the right kind + auto &path = mapping.import_kind.to_resolve; + auto &rebind = mapping.import_kind.rebind.value (); + auto data = mapping.data; + + location_t locus = UNKNOWN_LOCATION; + std::string declared_name; + + // FIXME: This needs to be done in `FinalizeImports` + switch (rebind.get_new_bind_type ()) + { + case AST::UseTreeRebind::NewBindType::IDENTIFIER: + declared_name = rebind.get_identifier ().as_string (); + locus = rebind.get_identifier ().get_locus (); + break; + case AST::UseTreeRebind::NewBindType::NONE: + declared_name = path.get_final_segment ().as_string (); + locus = path.get_final_segment ().get_locus (); + break; + case AST::UseTreeRebind::NewBindType::WILDCARD: + rust_unreachable (); + break; + } + + for (auto &&definition : data.definitions ()) + toplevel.insert_or_error_out ( + declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */); +} + +void +Early::visit (AST::UseDeclaration &decl) +{ + auto &imports = toplevel.get_imports_to_resolve (); + auto current_import = imports.find (decl.get_node_id ()); + if (current_import != imports.end ()) + { + build_import_mapping (*current_import); + } + + // Once this is done, we finalize their resolution + for (const auto &mapping : import_mappings.get (decl.get_node_id ())) + switch (mapping.import_kind.kind) + { + case TopLevel::ImportKind::Kind::Glob: + finalize_glob_import (ctx, mapping); + break; + case TopLevel::ImportKind::Kind::Simple: + finalize_simple_import (mapping); + break; + case TopLevel::ImportKind::Kind::Rebind: + finalize_rebind_import (mapping); + break; + } + + DefaultResolver::visit (decl); +} + } // namespace Resolver2_0 } // namespace Rust diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h b/gcc/rust/resolve/rust-early-name-resolver-2.0.h index e309b50174c..c4226fe9ea8 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h @@ -34,6 +34,7 @@ class Early : public DefaultResolver { using DefaultResolver::visit; + TopLevel toplevel; bool dirty; public: @@ -59,6 +60,7 @@ public: void visit (AST::Function &) override; void visit (AST::StructStruct &) override; + void visit (AST::UseDeclaration &) override; struct ImportData { @@ -246,6 +248,13 @@ private: std::vector<Error> macro_resolve_errors; void collect_error (Error e) { macro_resolve_errors.push_back (e); } + + void finalize_simple_import (const Early::ImportPair &mapping); + + void finalize_glob_import (NameResolutionContext &ctx, + const Early::ImportPair &mapping); + + void finalize_rebind_import (const Early::ImportPair &mapping); }; } // namespace Resolver2_0 diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc b/gcc/rust/resolve/rust-finalize-imports-2.0.cc index 71916ae432b..bd6002a09f4 100644 --- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc +++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc @@ -125,67 +125,6 @@ GlobbingVisitor::visit (AST::UseDeclaration &use) // Handle cycles ? } -void -finalize_simple_import (TopLevel &toplevel, const Early::ImportPair &mapping) -{ - // FIXME: We probably need to store namespace information - - auto locus = mapping.import_kind.to_resolve.get_locus (); - auto data = mapping.data; - auto identifier - = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name (); - - for (auto &&definition : data.definitions ()) - toplevel - .insert_or_error_out ( - identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */); -} - -void -finalize_glob_import (NameResolutionContext &ctx, - const Early::ImportPair &mapping) -{ - auto module = Analysis::Mappings::get ().lookup_ast_module ( - mapping.data.module ().get_node_id ()); - rust_assert (module); - - GlobbingVisitor glob_visitor (ctx); - glob_visitor.go (module.value ()); -} - -void -finalize_rebind_import (TopLevel &toplevel, const Early::ImportPair &mapping) -{ - // We can fetch the value here as `resolve_rebind` will only be called on - // imports of the right kind - auto &path = mapping.import_kind.to_resolve; - auto &rebind = mapping.import_kind.rebind.value (); - auto data = mapping.data; - - location_t locus = UNKNOWN_LOCATION; - std::string declared_name; - - // FIXME: This needs to be done in `FinalizeImports` - switch (rebind.get_new_bind_type ()) - { - case AST::UseTreeRebind::NewBindType::IDENTIFIER: - declared_name = rebind.get_identifier ().as_string (); - locus = rebind.get_identifier ().get_locus (); - break; - case AST::UseTreeRebind::NewBindType::NONE: - declared_name = path.get_final_segment ().as_string (); - locus = path.get_final_segment ().get_locus (); - break; - case AST::UseTreeRebind::NewBindType::WILDCARD: - rust_unreachable (); - break; - } - - for (auto &&definition : data.definitions ()) - toplevel.insert_or_error_out ( - declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */); -} - FinalizeImports::FinalizeImports (Early::ImportMappings &&data, TopLevel &toplevel, NameResolutionContext &ctx) @@ -202,23 +141,7 @@ FinalizeImports::go (AST::Crate &crate) void FinalizeImports::visit (AST::UseDeclaration &use) -{ - auto import_mappings = data.get (use.get_node_id ()); - - for (const auto &mapping : import_mappings) - switch (mapping.import_kind.kind) - { - case TopLevel::ImportKind::Kind::Glob: - finalize_glob_import (ctx, mapping); - break; - case TopLevel::ImportKind::Kind::Simple: - finalize_simple_import (toplevel, mapping); - break; - case TopLevel::ImportKind::Kind::Rebind: - finalize_rebind_import (toplevel, mapping); - break; - } -} +{} } // namespace Resolver2_0 } // namespace Rust diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h b/gcc/rust/resolve/rust-finalize-imports-2.0.h index 0fba5a517a1..a06fe538846 100644 --- a/gcc/rust/resolve/rust-finalize-imports-2.0.h +++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h @@ -96,11 +96,11 @@ public: void go (AST::Crate &crate); + void visit (AST::UseDeclaration &) override; + private: using AST::DefaultASTVisitor::visit; - void visit (AST::UseDeclaration &) override; - Early::ImportMappings data; TopLevel &toplevel; NameResolutionContext &ctx; diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h index 559c0d8757f..3ff37eda16d 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h @@ -108,10 +108,9 @@ public: {} }; - std::unordered_map<NodeId, std::vector<ImportKind>> && - get_imports_to_resolve () + std::unordered_map<NodeId, std::vector<ImportKind>> &get_imports_to_resolve () { - return std::move (imports_to_resolve); + return imports_to_resolve; } void check_multiple_insertion_error ( -- 2.45.2