aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve/rust-name-resolver.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve/rust-name-resolver.h')
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h212
1 files changed, 212 insertions, 0 deletions
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
new file mode 100644
index 0000000..014628a
--- /dev/null
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -0,0 +1,212 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_NAME_RESOLVER_H
+#define RUST_NAME_RESOLVER_H
+
+#include "rust-system.h"
+#include "rust-canonical-path.h"
+#include "rust-hir-map.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver {
+
+class Rib
+{
+public:
+ // Rust uses local_def_ids assigned by def_collector on the AST
+ // lets use NodeId instead
+ Rib (CrateNum crateNum, NodeId node_id);
+
+ // this takes the relative paths of items within a compilation unit for lookup
+ void insert_name (
+ const CanonicalPath &path, NodeId id, Location locus, bool shadow,
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
+
+ bool lookup_canonical_path (const NodeId &id, CanonicalPath *ident);
+ bool lookup_name (const CanonicalPath &ident, NodeId *id);
+ void clear_name (const CanonicalPath &ident, NodeId id);
+ void append_reference_for_def (NodeId def, NodeId ref);
+ bool have_references_for_node (NodeId def) const;
+ bool decl_was_declared_here (NodeId def) const;
+ void debug () const;
+ std::string debug_str () const;
+
+ CrateNum get_crate_num () const { return crate_num; }
+ NodeId get_node_id () const { return node_id; }
+ std::map<NodeId, Location> &get_declarations () { return decls_within_rib; }
+
+private:
+ CrateNum crate_num;
+ NodeId node_id;
+ std::map<CanonicalPath, NodeId> path_mappings;
+ std::map<NodeId, CanonicalPath> reverse_path_mappings;
+ std::map<NodeId, Location> decls_within_rib;
+ std::map<NodeId, std::set<NodeId>> references;
+ Analysis::Mappings *mappings;
+};
+
+class Scope
+{
+public:
+ Scope (CrateNum crate_num);
+
+ void
+ insert (const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
+
+ void insert (const CanonicalPath &ident, NodeId id, Location locus);
+ bool lookup (const CanonicalPath &ident, NodeId *id);
+
+ void iterate (std::function<bool (Rib *)> cb);
+ void iterate (std::function<bool (const Rib *)> cb) const;
+
+ Rib *peek ();
+ void push (NodeId id);
+ Rib *pop ();
+
+ bool decl_was_declared_here (NodeId def) const;
+ void append_reference_for_def (NodeId refId, NodeId defId);
+
+ CrateNum get_crate_num () const { return crate_num; }
+
+private:
+ CrateNum crate_num;
+ std::vector<Rib *> stack;
+};
+
+class Resolver
+{
+public:
+ static Resolver *get ();
+ ~Resolver () {}
+
+ // these builtin types
+ void insert_builtin_types (Rib *r);
+
+ // these will be required for type resolution passes to
+ // map back to tyty nodes
+ std::vector<AST::Type *> &get_builtin_types ();
+
+ void push_new_name_rib (Rib *r);
+ void push_new_type_rib (Rib *r);
+ void push_new_label_rib (Rib *r);
+ void push_new_macro_rib (Rib *r);
+
+ bool find_name_rib (NodeId id, Rib **rib);
+ bool find_type_rib (NodeId id, Rib **rib);
+ bool find_label_rib (NodeId id, Rib **rib);
+ bool find_macro_rib (NodeId id, Rib **rib);
+
+ void insert_resolved_name (NodeId refId, NodeId defId);
+ bool lookup_resolved_name (NodeId refId, NodeId *defId);
+
+ void insert_resolved_type (NodeId refId, NodeId defId);
+ bool lookup_resolved_type (NodeId refId, NodeId *defId);
+
+ void insert_resolved_label (NodeId refId, NodeId defId);
+ bool lookup_resolved_label (NodeId refId, NodeId *defId);
+
+ void insert_resolved_macro (NodeId refId, NodeId defId);
+ bool lookup_resolved_macro (NodeId refId, NodeId *defId);
+
+ // proxy for scoping
+ Scope &get_name_scope () { return name_scope; }
+ Scope &get_type_scope () { return type_scope; }
+ Scope &get_label_scope () { return label_scope; }
+ Scope &get_macro_scope () { return macro_scope; }
+
+ NodeId get_global_type_node_id () { return global_type_node_id; }
+ void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; }
+ NodeId get_unit_type_node_id () { return unit_ty_node_id; }
+
+ void push_new_module_scope (NodeId module_id)
+ {
+ current_module_stack.push_back (module_id);
+ }
+
+ void pop_module_scope ()
+ {
+ rust_assert (!current_module_stack.empty ());
+ current_module_stack.pop_back ();
+ }
+
+ NodeId peek_current_module_scope () const
+ {
+ rust_assert (!current_module_stack.empty ());
+ return current_module_stack.back ();
+ }
+
+ NodeId peek_crate_module_scope () const
+ {
+ rust_assert (!current_module_stack.empty ());
+ return current_module_stack.front ();
+ }
+
+ NodeId peek_parent_module_scope () const
+ {
+ rust_assert (current_module_stack.size () > 1);
+ return current_module_stack.at (current_module_stack.size () - 2);
+ }
+
+private:
+ Resolver ();
+
+ void generate_builtins ();
+
+ Analysis::Mappings *mappings;
+ TypeCheckContext *tyctx;
+
+ std::vector<AST::Type *> builtins;
+
+ Scope name_scope;
+ Scope type_scope;
+ Scope label_scope;
+ Scope macro_scope;
+
+ NodeId global_type_node_id;
+ NodeId unit_ty_node_id;
+
+ // map a AST Node to a Rib
+ std::map<NodeId, Rib *> name_ribs;
+ std::map<NodeId, Rib *> type_ribs;
+ std::map<NodeId, Rib *> label_ribs;
+ std::map<NodeId, Rib *> macro_ribs;
+
+ // Rust uses DefIds to namespace these under a crate_num
+ // but then it uses the def_collector to assign local_defids
+ // to each ast node as well. not sure if this is going to fit
+ // with gcc very well to compile a full crate in one go but we will
+ // see.
+
+ // these are of the form ref->Def-NodeId
+ // we need two namespaces one for names and ones for types
+ std::map<NodeId, NodeId> resolved_names;
+ std::map<NodeId, NodeId> resolved_types;
+ std::map<NodeId, NodeId> resolved_labels;
+ std::map<NodeId, NodeId> resolved_macros;
+
+ // keep track of the current module scope ids
+ std::vector<NodeId> current_module_stack;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_NAME_RESOLVER_H