// Copyright (C) 2020-2024 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 // . #include "rust-ast-resolve.h" #include "rust-ast-full.h" #include "rust-tyty.h" #include "rust-ast-resolve-toplevel.h" #include "rust-ast-resolve-item.h" #include "rust-ast-resolve-expr.h" #include "rust-ast-resolve-struct-expr-field.h" extern bool saw_errors (void); namespace Rust { namespace Resolver { // 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) { // lookup current crate name CrateNum cnum = mappings->get_current_crate (); std::string crate_name; bool ok = mappings->get_crate_name (cnum, crate_name); rust_assert (ok); // setup the ribs NodeId scope_node_id = crate.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); resolver->get_label_scope ().push (scope_node_id); resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); // get the root segment CanonicalPath crate_prefix = CanonicalPath::new_seg (scope_node_id, crate_name); crate_prefix.set_crate_num (cnum); // setup a dummy crate node resolver->get_name_scope ().insert ( CanonicalPath::new_seg (crate.get_node_id (), "__$$crate__"), crate.get_node_id (), UNDEF_LOCATION); // setup the root scope resolver->push_new_module_scope (scope_node_id); // first gather the top-level namespace names then we drill down so this // allows for resolving forward declarations since an impl block might have // a Self type Foo which is defined after the impl block for example. for (auto it = crate.items.begin (); it != crate.items.end (); it++) ResolveTopLevel::go (it->get (), CanonicalPath::create_empty (), crate_prefix); // FIXME remove this if (saw_errors ()) { resolver->pop_module_scope (); return; } // 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 (), CanonicalPath::create_empty (), crate_prefix); // done resolver->pop_module_scope (); } } // namespace Resolver } // namespace Rust