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.h222
1 files changed, 222 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..2aa592c
--- /dev/null
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -0,0 +1,222 @@
+// Copyright (C) 2020 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-hir-map.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver {
+
+class Rib
+{
+public:
+ // Rusts uses local_def_ids assigned by def_collector on the AST
+ // lets use NodeId instead
+ Rib (CrateNum crateNum, NodeId node_id)
+ : crate_num (crateNum), node_id (node_id)
+ {}
+
+ ~Rib () {}
+
+ void insert_name (std::string ident, NodeId id)
+ {
+ mappings[ident] = id;
+ decls_within_rib.insert (id);
+ }
+
+ bool lookup_name (std::string ident, NodeId *id)
+ {
+ auto it = mappings.find (ident);
+ if (it == mappings.end ())
+ return false;
+
+ *id = it->second;
+ return true;
+ }
+
+ CrateNum get_crate_num () const { return crate_num; }
+ NodeId get_node_id () const { return node_id; }
+
+ void iterate_decls (std::function<bool (NodeId)> cb)
+ {
+ for (auto it : decls_within_rib)
+ {
+ if (!cb (it))
+ return;
+ }
+ }
+
+private:
+ CrateNum crate_num;
+ NodeId node_id;
+ std::map<std::string, NodeId> mappings;
+ std::set<NodeId> decls_within_rib;
+};
+
+class Scope
+{
+public:
+ Scope (CrateNum crate_num) : crate_num (crate_num) {}
+ ~Scope () {}
+
+ void insert (std::string ident, NodeId id)
+ {
+ peek ()->insert_name (ident, id);
+ }
+
+ bool lookup (std::string ident, NodeId *id)
+ {
+ NodeId lookup = UNKNOWN_NODEID;
+ iterate ([&] (Rib *r) mutable -> bool {
+ if (r->lookup_name (ident, &lookup))
+ return false;
+ return true;
+ });
+
+ *id = lookup;
+ return lookup != UNKNOWN_NODEID;
+ }
+
+ void iterate (std::function<bool (Rib *)> cb)
+ {
+ for (auto it = stack.rbegin (); it != stack.rend (); ++it)
+ {
+ if (!cb (*it))
+ return;
+ }
+ }
+
+ Rib *peek () { return stack.back (); }
+
+ void push (NodeId id) { stack.push_back (new Rib (get_crate_num (), id)); }
+
+ Rib *pop ()
+ {
+ Rib *r = peek ();
+ stack.pop_back ();
+ return r;
+ }
+
+ CrateNum get_crate_num () const { return crate_num; }
+
+private:
+ CrateNum crate_num;
+ std::vector<Rib *> stack;
+};
+
+// This can map simple NodeIds for names to their parent node
+// for example:
+//
+// var x = y + 1;
+//
+// say y has node id=1 and the plus_expression has id=2
+// then the Definition will have
+// Definition { node=1, parent=2 }
+// this will be used later to gather the ribs for the type inferences context
+//
+// if parent is UNKNOWN_NODEID then this is a root declaration
+// say the var_decl hasa node_id=4;
+// the parent could be a BLOCK_Expr node_id but lets make it UNKNOWN_NODE_ID so
+// we know when it terminates
+struct Definition
+{
+ NodeId node;
+ NodeId parent;
+ // add kind ?
+};
+
+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::TypePath *> &get_builtin_types ();
+
+ void push_new_name_rib (Rib *r);
+ void push_new_type_rib (Rib *r);
+
+ bool find_name_rib (NodeId id, Rib **rib);
+ bool find_type_rib (NodeId id, Rib **rib);
+
+ void insert_new_definition (NodeId id, Definition def);
+ bool lookup_definition (NodeId id, Definition *def);
+
+ 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);
+
+ // proxy for scoping
+ Scope &get_name_scope () { return name_scope; }
+ Scope &get_type_scope () { return type_scope; }
+
+ NodeId get_global_type_node_id () { return global_type_node_id; }
+
+private:
+ Resolver ();
+
+ void generate_builtins ();
+
+ Analysis::Mappings *mappings;
+ TypeCheckContext *tyctx;
+
+ std::vector<AST::TypePath *> builtins;
+
+ Scope name_scope;
+ Scope type_scope;
+
+ NodeId global_type_node_id;
+
+ // map a AST Node to a Rib
+ std::map<NodeId, Rib *> name_ribs;
+ std::map<NodeId, Rib *> type_ribs;
+
+ // map any Node to its Definition
+ // ie any name or type usage
+ std::map<NodeId, Definition> name_definitions;
+
+ // 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, std::set<NodeId> > nameDefNodeIdToRibs;
+ std::map<NodeId, std::set<NodeId> > typeDefNodeIdToRibs;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_NAME_RESOLVER_H