aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2024-04-06 00:00:49 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-19 15:32:12 +0100
commit4aab2ae2afedc01434638e22f13867ed4100310b (patch)
treea0e8cff86071ade0562f7bce16da5de745029847
parent333a4cbff7ef62208647c234af12caa35271b59c (diff)
downloadgcc-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.cc91
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h37
-rw-r--r--gcc/rust/resolve/rust-finalize-imports-2.0.cc35
-rw-r--r--gcc/rust/resolve/rust-finalize-imports-2.0.h6
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h27
-rw-r--r--gcc/rust/resolve/rust-rib.h2
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];