diff options
Diffstat (limited to 'gcc/rust/resolve/rust-ast-resolve.cc')
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc new file mode 100644 index 0000000..664af12 --- /dev/null +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -0,0 +1,245 @@ +// 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/>. + +#include "rust-ast-resolve.h" +#include "rust-ast-resolve-toplevel.h" +#include "rust-ast-resolve-item.h" +#include "rust-ast-full.h" + +#define MKBUILTIN_TYPE(_X, _R) \ + do \ + { \ + AST::PathIdentSegment seg (_X); \ + auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( \ + new AST::TypePathSegment (::std::move (seg), false, \ + Linemap::predeclared_location ())); \ + ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs; \ + segs.push_back (::std::move (typePath)); \ + auto builtin_type \ + = new AST::TypePath (::std::move (segs), \ + Linemap::predeclared_location (), false); \ + _R.push_back (builtin_type); \ + } \ + while (0) + +namespace Rust { +namespace Resolver { + +// Resolver + +Resolver::Resolver () + : mappings (Analysis::Mappings::get ()), + name_scope (Scope (mappings->get_current_crate ())), + type_scope (Scope (mappings->get_current_crate ())) +{ + generate_builtins (); +} + +Resolver * +Resolver::get () +{ + static Resolver *instance; + if (instance == nullptr) + instance = new Resolver (); + + return instance; +} + +void +Resolver::push_new_name_rib (Rib *r) +{ + rust_assert (name_ribs.find (r->get_node_id ()) == name_ribs.end ()); + name_ribs[r->get_node_id ()] = r; +} + +void +Resolver::push_new_type_rib (Rib *r) +{ + if (type_ribs.size () == 0) + global_type_node_id = r->get_node_id (); + + rust_assert (type_ribs.find (r->get_node_id ()) == type_ribs.end ()); + type_ribs[r->get_node_id ()] = r; +} + +bool +Resolver::find_name_rib (NodeId id, Rib **rib) +{ + auto it = name_ribs.find (id); + if (it == name_ribs.end ()) + return false; + + *rib = it->second; + return true; +} + +bool +Resolver::find_type_rib (NodeId id, Rib **rib) +{ + auto it = type_ribs.find (id); + if (it == type_ribs.end ()) + return false; + + *rib = it->second; + return true; +} + +void +Resolver::insert_builtin_types (Rib *r) +{ + auto builtins = get_builtin_types (); + for (auto it = builtins.begin (); it != builtins.end (); it++) + r->insert_name ((*it)->as_string (), (*it)->get_node_id ()); +} + +std::vector<AST::TypePath *> & +Resolver::get_builtin_types () +{ + return builtins; +} + +void +Resolver::generate_builtins () +{ + MKBUILTIN_TYPE ("u8", builtins); + MKBUILTIN_TYPE ("u16", builtins); + MKBUILTIN_TYPE ("u32", builtins); + MKBUILTIN_TYPE ("u64", builtins); + + MKBUILTIN_TYPE ("i8", builtins); + MKBUILTIN_TYPE ("i16", builtins); + MKBUILTIN_TYPE ("i32", builtins); + MKBUILTIN_TYPE ("i64", builtins); + + MKBUILTIN_TYPE ("f32", builtins); + MKBUILTIN_TYPE ("f64", builtins); + + MKBUILTIN_TYPE ("char", builtins); + MKBUILTIN_TYPE ("str", builtins); + MKBUILTIN_TYPE ("bool", builtins); +} + +void +Resolver::insert_new_definition (NodeId id, Definition def) +{ + auto it = name_definitions.find (id); + rust_assert (it == name_definitions.end ()); + + name_definitions[id] = def; +} + +bool +Resolver::lookup_definition (NodeId id, Definition *def) +{ + auto it = name_definitions.find (id); + if (it == name_definitions.end ()) + return false; + + *def = it->second; + return true; +} + +void +Resolver::insert_resolved_name (NodeId refId, NodeId defId) +{ + auto it = resolved_names.find (refId); + rust_assert (it == resolved_names.end ()); + + resolved_names[refId] = defId; +} + +bool +Resolver::lookup_resolved_name (NodeId refId, NodeId *defId) +{ + auto it = resolved_names.find (refId); + if (it == resolved_names.end ()) + return false; + + *defId = it->second; + return true; +} + +void +Resolver::insert_resolved_type (NodeId refId, NodeId defId) +{ + auto it = resolved_types.find (refId); + rust_assert (it == resolved_types.end ()); + + resolved_types[refId] = defId; +} + +bool +Resolver::lookup_resolved_type (NodeId refId, NodeId *defId) +{ + auto it = resolved_types.find (refId); + if (it == resolved_types.end ()) + return false; + + *defId = it->second; + return true; +} + +// NameResolution + +NameResolution * +NameResolution::get () +{ + static NameResolution *instance; + if (instance == nullptr) + instance = new NameResolution (); + + return instance; +} + +NameResolution::NameResolution () + : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()) +{ + // these are global + resolver->get_type_scope ().push (mappings->get_next_node_id ()); + resolver->insert_builtin_types (resolver->get_type_scope ().peek ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); +} + +void +NameResolution::Resolve (AST::Crate &crate) +{ + auto resolver = get (); + resolver->go (crate); +} + +void +NameResolution::go (AST::Crate &crate) +{ + // setup parent scoping for names + resolver->get_name_scope ().push (crate.get_node_id ()); + resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); + // setup parent scoping for new types + resolver->get_type_scope ().push (mappings->get_next_node_id ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + + // first gather the top-level namespace names then we drill down + for (auto it = crate.items.begin (); it != crate.items.end (); it++) + ResolveTopLevel::go (it->get ()); + + // next we can drill down into the items and their scopes + for (auto it = crate.items.begin (); it != crate.items.end (); it++) + ResolveItem::go (it->get ()); +} + +} // namespace Resolver +} // namespace Rust |