diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-04-06 00:00:49 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-19 15:32:12 +0100 |
commit | 4aab2ae2afedc01434638e22f13867ed4100310b (patch) | |
tree | a0e8cff86071ade0562f7bce16da5de745029847 | |
parent | 333a4cbff7ef62208647c234af12caa35271b59c (diff) | |
download | gcc-4aab2ae2afedc01434638e22f13867ed4100310b.zip gcc-4aab2ae2afedc01434638e22f13867ed4100310b.tar.gz gcc-4aab2ae2afedc01434638e22f13867ed4100310b.tar.bz2 |
gccrs: imports: Create ImportData class and use it in import_mappings
gcc/rust/ChangeLog:
* resolve/rust-early-name-resolver-2.0.cc (Early::resolve_glob_import):
Use ImportData class.
(Early::resolve_simple_import): Likewise.
(Early::resolve_rebind_import): Likewise.
(Early::build_import_mapping): Likewise.
* resolve/rust-early-name-resolver-2.0.h: Likewise.
* resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Likewise.
(finalize_glob_import): Likewise.
(finalize_rebind_import): Likewise.
(FinalizeImports::go): Likewise.
* resolve/rust-finalize-imports-2.0.h: Likewise.
* resolve/rust-name-resolution-context.h: Likewise.
* resolve/rust-rib.h: Define ImportData class.
-rw-r--r-- | gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 91 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-early-name-resolver-2.0.h | 37 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-finalize-imports-2.0.cc | 35 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-finalize-imports-2.0.h | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolution-context.h | 27 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-rib.h | 2 |
6 files changed, 102 insertions, 96 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 41d0a07..ba73a54 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc @@ -83,7 +83,8 @@ Early::resolve_glob_import (TopLevel::ImportKind &&glob) // here, we insert the module's NodeId into the import_mappings and will look // up the module proper in `FinalizeImports` - import_mappings.insert ({std::move (glob), resolved->get_node_id ()}); + // The namespace does not matter here since we are dealing with a glob + import_mappings.insert ({std::move (glob), ImportData::Glob (*resolved)}); return true; } @@ -91,89 +92,21 @@ Early::resolve_glob_import (TopLevel::ImportKind &&glob) bool Early::resolve_simple_import (TopLevel::ImportKind &&import) { - // TODO: Fix documentation - the function has changed slightly - - const auto &path = import.to_resolve; - // auto locus = path.get_final_segment ().get_locus (); - // auto declared_name = path.get_final_segment ().as_string (); - - // In that function, we only need to declare a new definition - the use path. - // the resolution needs to happpen in the EarlyNameResolver. So the - // definitions we'll add will be the path's NodeId - that makes sense, as we - // need one definition per path declared in a Use tree. so all good. - // alright, now in what namespace do we declare them? all of them? do we only - // declare them in the EarlyNameResolver? this is dodgy - - // in what namespace do we perform path resolution? All of them? see which one - // matches? Error out on ambiguities? - // so, apparently, for each one that matches, add it to the proper namespace - // :( - - return ctx.values.resolve_path (path.get_segments ()) - .or_else ([&] () { return ctx.types.resolve_path (path.get_segments ()); }) - .or_else ([&] () { return ctx.macros.resolve_path (path.get_segments ()); }) - .map ([&] (Rib::Definition def) { - import_mappings.insert ({std::move (import), def.get_node_id ()}); + return ctx.resolve_path (import.to_resolve) + .map ([&] (std::pair<Rib::Definition, Namespace> def_ns) { + import_mappings.insert ( + {std::move (import), ImportData::Simple (def_ns)}); }) .has_value (); - - // switch (ns) - // { - // case Namespace::Values: - // resolved = ctx.values.resolve_path (path.get_segments ()); - // break; - // case Namespace::Types: - // resolved = ctx.types.resolve_path (path.get_segments ()); - // break; - // case Namespace::Macros: - // resolved = ctx.macros.resolve_path (path.get_segments ()); - // break; - // case Namespace::Labels: - // // TODO: Is that okay? - // rust_unreachable (); - // } - - // FIXME: Ugly - // (void) resolved.map ([this, &found, path, import] (Rib::Definition - // def) { - // found = true; - - // import_mappings.insert ({std::move (import), def.get_node_id - // ()}); - - // // what do we do with the id? - // // insert_or_error_out (declared_name, locus, def.get_node_id (), - // // ns); auto result = node_forwarding.find (def.get_node_id ()); - // if - // // (result != node_forwarding.cend () - // // && result->second != path.get_node_id ()) - // // rust_error_at (path.get_locus (), "%qs defined multiple - // times", - // // declared_name.c_str ()); - // // else // No previous thing has inserted this into our scope - // // node_forwarding.insert ({def.get_node_id (), - // path.get_node_id - // // ()}); - - // return def.get_node_id (); - // }); - // }; - - // resolve_and_insert (path); - - // return found; } bool Early::resolve_rebind_import (TopLevel::ImportKind &&rebind_import) { - auto &path = rebind_import.to_resolve; - - return ctx.values.resolve_path (path.get_segments ()) - .or_else ([&] () { return ctx.types.resolve_path (path.get_segments ()); }) - .or_else ([&] () { return ctx.macros.resolve_path (path.get_segments ()); }) - .map ([&] (Rib::Definition def) { - import_mappings.insert ({std::move (rebind_import), def.get_node_id ()}); + return ctx.resolve_path (rebind_import.to_resolve) + .map ([&] (std::pair<Rib::Definition, Namespace> def_ns) { + import_mappings.insert ( + {std::move (rebind_import), ImportData::Rebind (def_ns)}); }) .has_value (); } @@ -183,8 +116,8 @@ Early::build_import_mapping (TopLevel::ImportKind &&import) { auto found = false; - // We create a copy of the path in case of errors, since the `import` will be - // moved into the newly created import mappings + // We create a copy of the path in case of errors, since the `import` will + // be moved into the newly created import mappings auto path = import.to_resolve; switch (import.kind) 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 6651bd2..2ae3162 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h @@ -24,6 +24,7 @@ #include "rust-ast-visitor.h" #include "rust-name-resolution-context.h" #include "rust-default-resolver.h" +#include "rust-rib.h" #include "rust-toplevel-name-resolver-2.0.h" namespace Rust { @@ -55,6 +56,40 @@ public: void visit (AST::Function &) override; void visit (AST::StructStruct &) override; + struct ImportData + { + enum class Kind + { + Simple, + Glob, + Rebind + } kind; + + Rib::Definition definition; + tl::optional<Namespace> ns; + + static ImportData Simple (std::pair<Rib::Definition, Namespace> def_ns) + { + return ImportData (Kind::Simple, def_ns.first, def_ns.second); + } + + static ImportData Rebind (std::pair<Rib::Definition, Namespace> def_ns) + { + return ImportData (Kind::Rebind, def_ns.first, def_ns.second); + } + + static ImportData Glob (Rib::Definition module) + { + return ImportData (Kind::Glob, module); + } + + private: + ImportData (Kind kind, Rib::Definition definition, + tl::optional<Namespace> ns = tl::nullopt) + : kind (kind), definition (definition), ns (ns) + {} + }; + private: void visit_attributes (std::vector<AST::Attribute> &attrs); @@ -93,7 +128,7 @@ private: }; // Mappings between an import and the definition it imports - std::map<TopLevel::ImportKind, NodeId> import_mappings; + std::map<TopLevel::ImportKind, ImportData> import_mappings; // FIXME: Documentation // Call this on all the paths of a UseDec - so each flattened path in a diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc b/gcc/rust/resolve/rust-finalize-imports-2.0.cc index 1725e71..f5c8157 100644 --- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc +++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc @@ -125,25 +125,30 @@ GlobbingVisitor::visit (AST::UseDeclaration &use) } void -finalize_simple_import (TopLevel &toplevel, - const std::pair<TopLevel::ImportKind, NodeId> &mapping) +finalize_simple_import ( + TopLevel &toplevel, + const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping) { // FIXME: We probably need to store namespace information auto locus = mapping.first.to_resolve.get_locus (); - auto def = mapping.second; + auto data = mapping.second; auto identifier = mapping.first.to_resolve.get_final_segment ().get_segment_name (); // FIXME: Fix the namespace in which we insert the new definition - toplevel.insert_or_error_out (identifier, locus, def, Namespace::Values); + toplevel.insert_or_error_out (identifier, locus, + data.definition.get_node_id (), + data.ns.value ()); } void -finalize_glob_import (NameResolutionContext &ctx, - const std::pair<TopLevel::ImportKind, NodeId> &mapping) +finalize_glob_import ( + NameResolutionContext &ctx, + const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping) { - auto module = Analysis::Mappings::get ().lookup_ast_module (mapping.second); + auto module = Analysis::Mappings::get ().lookup_ast_module ( + mapping.second.definition.get_node_id ()); rust_assert (module); GlobbingVisitor glob_visitor (ctx); @@ -151,14 +156,15 @@ finalize_glob_import (NameResolutionContext &ctx, } void -finalize_rebind_import (TopLevel &toplevel, - const std::pair<TopLevel::ImportKind, NodeId> &mapping) +finalize_rebind_import ( + TopLevel &toplevel, + const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping) { // We can fetch the value here as `resolve_rebind` will only be called on // imports of the right kind auto &path = mapping.first.to_resolve; auto &rebind = mapping.first.rebind.value (); - auto def = mapping.second; + auto data = mapping.second; location_t locus = UNKNOWN_LOCATION; std::string declared_name; @@ -180,12 +186,15 @@ finalize_rebind_import (TopLevel &toplevel, } // FIXME: Fix the namespace in which we insert the new definition - toplevel.insert_or_error_out (declared_name, locus, def, Namespace::Values); + toplevel.insert_or_error_out (declared_name, locus, + data.definition.get_node_id (), + data.ns.value ()); } void -FinalizeImports::go (std::map<TopLevel::ImportKind, NodeId> import_mappings, - TopLevel &toplevel, NameResolutionContext &ctx) +FinalizeImports::go ( + std::map<TopLevel::ImportKind, Early::ImportData> import_mappings, + TopLevel &toplevel, NameResolutionContext &ctx) { for (const auto &mapping : import_mappings) switch (mapping.first.kind) diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h b/gcc/rust/resolve/rust-finalize-imports-2.0.h index e566a48..ed4dc7d 100644 --- a/gcc/rust/resolve/rust-finalize-imports-2.0.h +++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h @@ -18,6 +18,7 @@ #include "rust-name-resolution-context.h" #include "rust-toplevel-name-resolver-2.0.h" +#include "rust-early-name-resolver-2.0.h" namespace Rust { namespace Resolver2_0 { @@ -88,8 +89,9 @@ private: class FinalizeImports { public: - static void go (std::map<TopLevel::ImportKind, NodeId> import_mappings, - TopLevel &toplevel, NameResolutionContext &ctx); + static void + go (std::map<TopLevel::ImportKind, Early::ImportData> import_mappings, + TopLevel &toplevel, NameResolutionContext &ctx); }; } // namespace Resolver2_0 diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index 3605392..2fc8528 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -22,6 +22,7 @@ #include "optional.h" #include "rust-forever-stack.h" #include "rust-hir-map.h" +#include "rust-rib.h" namespace Rust { namespace Resolver2_0 { @@ -198,6 +199,32 @@ public: std::function<void (void)> lambda, tl::optional<Identifier> path = {}); + template <typename P> + tl::optional<std::pair<Rib::Definition, Namespace>> + resolve_path (const P &path) + { + const auto &segments = path.get_segments (); + + // Pair a definition with the namespace it was found in + auto pair_with_ns = [] (Namespace ns) { + return [ns] (Rib::Definition def) { return std::make_pair (def, ns); }; + }; + + // We first check in values, if not found then types, if not found then + // macros. There should not be any ambiguity at this point - this function + // will short circuit and return the first definition it has found. + return values.resolve_path (segments) + .map (pair_with_ns (Namespace::Values)) + .or_else ([&] () { + return types.resolve_path (segments).map ( + pair_with_ns (Namespace::Types)); + }) + .or_else ([&] () { + return macros.resolve_path (segments).map ( + pair_with_ns (Namespace::Macros)); + }); + } + ForeverStack<Namespace::Values> values; ForeverStack<Namespace::Types> types; ForeverStack<Namespace::Macros> macros; diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h index 3228a3c..11a6b56 100644 --- a/gcc/rust/resolve/rust-rib.h +++ b/gcc/rust/resolve/rust-rib.h @@ -124,7 +124,7 @@ public: bool is_ambiguous () const; - NodeId get_node_id () + NodeId get_node_id () const { rust_assert (!is_ambiguous ()); return ids[0]; |