aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-early-name-resolver-2.0.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-early-name-resolver-2.0.h')
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h168
1 files changed, 168 insertions, 0 deletions
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 fc5d8af..0eb6d29 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,8 @@
#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 {
namespace Resolver2_0 {
@@ -32,9 +34,14 @@ class Early : public DefaultResolver
{
using DefaultResolver::visit;
+ TopLevel toplevel;
+ bool dirty;
+
public:
Early (NameResolutionContext &ctx);
+ bool is_dirty () { return dirty; }
+
void go (AST::Crate &crate);
const std::vector<Error> &get_macro_resolve_errors () const
@@ -53,6 +60,111 @@ public:
void visit (AST::Function &) override;
void visit (AST::StructStruct &) override;
+ void visit (AST::UseDeclaration &) override;
+
+ struct ImportData
+ {
+ enum class Kind
+ {
+ Simple,
+ Glob,
+ Rebind
+ } kind;
+
+ static ImportData
+ Simple (std::vector<std::pair<Rib::Definition, Namespace>> &&definitions)
+ {
+ return ImportData (Kind::Simple, std::move (definitions));
+ }
+
+ static ImportData
+ Rebind (std::vector<std::pair<Rib::Definition, Namespace>> &&definitions)
+ {
+ return ImportData (Kind::Rebind, std::move (definitions));
+ }
+
+ static ImportData Glob (Rib::Definition module)
+ {
+ 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,
+ 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;
+ };
+
+ struct ImportPair
+ {
+ TopLevel::ImportKind import_kind;
+ ImportData data;
+
+ explicit ImportPair (TopLevel::ImportKind &&kind, ImportData &&data)
+ : import_kind (std::move (kind)), data (std::move (data))
+ {}
+ };
+
+ class ImportMappings
+ {
+ public:
+ std::vector<ImportPair> &new_or_access (NodeId path_id)
+ {
+ // 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 iter = mappings.insert ({{path_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.
+ return iter.first->second;
+ }
+
+ void insert (NodeId path_id, std::vector<ImportPair> &&pairs)
+ {
+ mappings.insert ({{path_id}, std::move (pairs)});
+ }
+
+ // Same as `insert`, but with just one node
+ void insert (NodeId path_id, ImportPair &&pair)
+ {
+ mappings.insert ({{path_id}, {pair}});
+ }
+
+ std::vector<ImportPair> &get (NodeId use_id) { return mappings[use_id]; }
+
+ private:
+ // Each path can import in multiple namespaces, hence the mapping from one
+ // path to a vector of import pairs
+ std::unordered_map<NodeId, std::vector<ImportPair>> mappings;
+ };
private:
void visit_attributes (std::vector<AST::Attribute> &attrs);
@@ -91,10 +203,66 @@ private:
std::vector<std::unordered_map<std::string, NodeId>> scopes;
};
+ // Mappings between an import and the definition it imports
+ ImportMappings import_mappings;
+
+ // FIXME: Documentation
+ // Call this on all the paths of a UseDec - so each flattened path in a
+ // UseTreeList for example
+ // FIXME: Should that return `found`?
+ bool resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import);
+ 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)
+ {
+ 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));
+ };
+ };
+
+ std::vector<Error> value_errors;
+ std::vector<Error> type_errors;
+ std::vector<Error> macro_errors;
+
+ ctx.resolve_path (path, value_errors, Namespace::Values)
+ .map (pair_with_ns (Namespace::Values));
+ ctx.resolve_path (path, type_errors, Namespace::Types)
+ .map (pair_with_ns (Namespace::Types));
+ ctx.resolve_path (path, macro_errors, Namespace::Macros)
+ .map (pair_with_ns (Namespace::Macros));
+
+ if (!value_errors.empty () && !type_errors.empty ()
+ && !macro_errors.empty ())
+ for (auto &ent : value_errors)
+ collect_error (std::move (ent));
+
+ return resolved;
+ }
+
+ // Handle an import, resolving it to its definition and adding it to the list
+ // of import mappings
+ void build_import_mapping (
+ std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import);
+
TextualScope textual_scope;
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