diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-04-08 18:44:15 +0200 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2024-09-26 22:48:32 +0000 |
commit | 9f6c1790991b9dd9b6b1af2f2f9e22b9534b29e3 (patch) | |
tree | 876b094216c5165164501296004194eee82d7ec5 /gcc | |
parent | c67b14ccc5b4ab16c237b448633a8e8718644153 (diff) | |
download | gcc-9f6c1790991b9dd9b6b1af2f2f9e22b9534b29e3.zip gcc-9f6c1790991b9dd9b6b1af2f2f9e22b9534b29e3.tar.gz gcc-9f6c1790991b9dd9b6b1af2f2f9e22b9534b29e3.tar.bz2 |
Insert imports in all namespaces they were resolved in
gcc/rust/ChangeLog:
* resolve/rust-early-name-resolver-2.0.cc (Early::resolve_simple_import):
Insert import in all namespaces where they were resolved.
(Early::resolve_rebind_import): Likewise.
* resolve/rust-early-name-resolver-2.0.h: Improve APIs, make them
accept multiple resolutions.
* resolve/rust-finalize-imports-2.0.cc: Handle multiple resolutions.
* resolve/rust-name-resolution-context.h (resolve_path): Remove function.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 74 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-early-name-resolver-2.0.h | 66 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-finalize-imports-2.0.cc | 17 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolution-context.h | 26 |
4 files changed, 106 insertions, 77 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 6c5446a..52c6674 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc @@ -94,44 +94,54 @@ Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob) bool Early::resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import) { - return ctx.resolve_path (import.to_resolve) - .map ([&] (std::pair<Rib::Definition, Namespace> def_ns) { - // We insert an empty vector, unless an element was already present for - // `use_dec_id` - which is returned in the tuple's first member - auto tuple = import_mappings.insert ({use_dec_id, {}}); - // We then get that tuple's first member, which will be an iterator to the - // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly - // created empty vector (plus its key since this is a hashmap iterator). - // we then access the second member of the pair to get access to the - // vector directly. - auto &imports = tuple.first->second; - - imports.emplace_back ( - std::make_pair (std::move (import), ImportData::Simple (def_ns))); - }) - .has_value (); + auto definitions = resolve_path_in_all_ns (import.to_resolve); + + // if we've found at least one definition, then we're good + if (definitions.empty ()) + return false; + + // We insert an empty vector, unless an element was already present for + // `use_dec_id` - which is returned in the tuple's first member + auto tuple = import_mappings.insert ({use_dec_id, {}}); + // We then get that tuple's first member, which will be an iterator to the + // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly + // created empty vector (plus its key since this is a hashmap iterator). + // we then access the second member of the pair to get access to the + // vector directly. + auto &imports = tuple.first->second; + + imports.emplace_back ( + std::make_pair (std::move (import), + ImportData::Simple (std::move (definitions)))); + + return true; } bool Early::resolve_rebind_import (NodeId use_dec_id, TopLevel::ImportKind &&rebind_import) { - return ctx.resolve_path (rebind_import.to_resolve) - .map ([&] (std::pair<Rib::Definition, Namespace> def_ns) { - // We insert an empty vector, unless an element was already present for - // `use_dec_id` - which is returned in the tuple's first member - auto tuple = import_mappings.insert ({use_dec_id, {}}); - // We then get that tuple's first member, which will be an iterator to the - // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly - // created empty vector (plus its key since this is a hashmap iterator). - // we then access the second member of the pair to get access to the - // vector directly. - auto &imports = tuple.first->second; - - imports.emplace_back (std::make_pair (std::move (rebind_import), - ImportData::Rebind (def_ns))); - }) - .has_value (); + auto definitions = resolve_path_in_all_ns (rebind_import.to_resolve); + + // if we've found at least one definition, then we're good + if (definitions.empty ()) + return false; + + // We insert an empty vector, unless an element was already present for + // `use_dec_id` - which is returned in the tuple's first member + auto tuple = import_mappings.insert ({use_dec_id, {}}); + // We then get that tuple's first member, which will be an iterator to the + // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly + // created empty vector (plus its key since this is a hashmap iterator). + // we then access the second member of the pair to get access to the + // vector directly. + auto &imports = tuple.first->second; + + imports.emplace_back ( + std::make_pair (std::move (rebind_import), + ImportData::Rebind (std::move (definitions)))); + + return true; } void 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 1f2ce15..a267d7a 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h @@ -65,17 +65,16 @@ public: Rebind } kind; - Rib::Definition definition; - tl::optional<Namespace> ns; - - static ImportData Simple (std::pair<Rib::Definition, Namespace> def_ns) + static ImportData + Simple (std::vector<std::pair<Rib::Definition, Namespace>> &&definitions) { - return ImportData (Kind::Simple, def_ns.first, def_ns.second); + return ImportData (Kind::Simple, std::move (definitions)); } - static ImportData Rebind (std::pair<Rib::Definition, Namespace> def_ns) + static ImportData + Rebind (std::vector<std::pair<Rib::Definition, Namespace>> &&definitions) { - return ImportData (Kind::Rebind, def_ns.first, def_ns.second); + return ImportData (Kind::Rebind, std::move (definitions)); } static ImportData Glob (Rib::Definition module) @@ -83,11 +82,36 @@ public: return ImportData (Kind::Glob, module); } + Rib::Definition module () const + { + rust_assert (kind == Kind::Glob); + return glob_module; + } + + std::vector<std::pair<Rib::Definition, Namespace>> definitions () const + { + rust_assert (kind != Kind::Glob); + return std::move (resolved_definitions); + } + private: - ImportData (Kind kind, Rib::Definition definition, - tl::optional<Namespace> ns = tl::nullopt) - : kind (kind), definition (definition), ns (ns) + ImportData ( + Kind kind, + std::vector<std::pair<Rib::Definition, Namespace>> &&definitions) + : kind (kind), resolved_definitions (std::move (definitions)) {} + + ImportData (Kind kind, Rib::Definition module) + : kind (kind), glob_module (module) + {} + + // TODO: Should this be a union? + + // For Simple and Rebind + std::vector<std::pair<Rib::Definition, Namespace>> resolved_definitions; + + // For Glob + Rib::Definition glob_module; }; private: @@ -141,6 +165,28 @@ private: bool resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&import); bool resolve_rebind_import (NodeId use_dec_id, TopLevel::ImportKind &&import); + template <typename P> + std::vector<std::pair<Rib::Definition, Namespace>> + resolve_path_in_all_ns (const P &path) + { + const auto &segments = path.get_segments (); + std::vector<std::pair<Rib::Definition, Namespace>> resolved; + + // Pair a definition with the namespace it was found in + auto pair_with_ns = [&] (Namespace ns) { + return [&, ns] (Rib::Definition def) { + auto pair = std::make_pair (def, ns); + return resolved.emplace_back (std::move (pair)); + }; + }; + + ctx.values.resolve_path (segments).map (pair_with_ns (Namespace::Values)); + ctx.types.resolve_path (segments).map (pair_with_ns (Namespace::Types)); + ctx.macros.resolve_path (segments).map (pair_with_ns (Namespace::Macros)); + + return resolved; + } + // Handle an import, resolving it to its definition and adding it to the list // of import mappings void build_import_mapping ( diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc b/gcc/rust/resolve/rust-finalize-imports-2.0.cc index ac288e3..52bbcaa 100644 --- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc +++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc @@ -137,10 +137,10 @@ finalize_simple_import ( 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, - data.definition.get_node_id (), - data.ns.value ()); + 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 @@ -149,7 +149,7 @@ finalize_glob_import ( const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping) { auto module = Analysis::Mappings::get ().lookup_ast_module ( - mapping.second.definition.get_node_id ()); + mapping.second.module ().get_node_id ()); rust_assert (module); GlobbingVisitor glob_visitor (ctx); @@ -186,10 +186,9 @@ finalize_rebind_import ( break; } - // FIXME: Fix the namespace in which we insert the new definition - toplevel.insert_or_error_out (declared_name, locus, - data.definition.get_node_id (), - data.ns.value ()); + 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 ( diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index 331854d..f17cd0a 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -199,32 +199,6 @@ 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; |