mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 12:00:11 -05:00
447 lines
12 KiB
C++
447 lines
12 KiB
C++
// Copyright (C) 2020-2026 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-default-resolver.h"
|
|
#include "rust-ast-full.h"
|
|
#include "rust-ast-visitor.h"
|
|
#include "rust-item.h"
|
|
|
|
namespace Rust {
|
|
namespace Resolver2_0 {
|
|
|
|
void
|
|
DefaultResolver::visit (AST::Crate &crate)
|
|
{
|
|
auto inner_fn = [this, &crate] () { AST::DefaultASTVisitor::visit (crate); };
|
|
|
|
auto &mappings = Analysis::Mappings::get ();
|
|
|
|
auto crate_num = mappings.lookup_crate_num (crate.get_node_id ());
|
|
rust_assert (crate_num.has_value ());
|
|
auto crate_name = mappings.get_crate_name (*crate_num);
|
|
rust_assert (crate_name.has_value ());
|
|
|
|
ctx.canonical_ctx.scope_crate (crate.get_node_id (), *crate_name, inner_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::BlockExpr &expr)
|
|
{
|
|
// extracting the lambda from the `scoped` call otherwise the code looks like
|
|
// a hot turd thanks to our .clang-format
|
|
|
|
auto inner_fn = [this, &expr] () { AST::DefaultASTVisitor::visit (expr); };
|
|
|
|
ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::Module &module)
|
|
{
|
|
auto item_fn_1
|
|
= [this, &module] () { AST::DefaultASTVisitor::visit (module); };
|
|
|
|
auto item_fn_2 = [this, &module, &item_fn_1] () {
|
|
ctx.canonical_ctx.scope (module.get_node_id (), module.get_name (),
|
|
std::move (item_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn_2,
|
|
module.get_name ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::Function &function)
|
|
{
|
|
auto def_fn_1
|
|
= [this, &function] () { AST::DefaultASTVisitor::visit (function); };
|
|
|
|
auto def_fn_2 = [this, &function, &def_fn_1] () {
|
|
ctx.canonical_ctx.scope (function.get_node_id (),
|
|
function.get_function_name (),
|
|
std::move (def_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn_2,
|
|
function.get_function_name ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::ForLoopExpr &expr)
|
|
{
|
|
ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
|
|
[this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit_if_let_patterns (AST::IfLetExpr &expr)
|
|
{
|
|
for (auto &pattern : expr.get_patterns ())
|
|
visit (pattern);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::IfLetExpr &expr)
|
|
{
|
|
auto inner_vis = [this, &expr] () {
|
|
visit_if_let_patterns (expr);
|
|
visit (expr.get_if_block ());
|
|
};
|
|
|
|
visit_outer_attrs (expr);
|
|
|
|
visit (expr.get_value_expr ());
|
|
|
|
ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_vis);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::IfLetExprConseqElse &expr)
|
|
{
|
|
DefaultResolver::visit (static_cast<AST::IfLetExpr &> (expr));
|
|
visit (expr.get_else_block ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::Trait &trait)
|
|
{
|
|
visit_outer_attrs (trait);
|
|
visit (trait.get_visibility ());
|
|
visit_inner_attrs (trait);
|
|
|
|
auto inner_fn_1 = [this, &trait] () {
|
|
for (auto &item : trait.get_trait_items ())
|
|
visit (item);
|
|
};
|
|
|
|
auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
|
|
visit (trait.get_implicit_self ());
|
|
for (auto &generic : trait.get_generic_params ())
|
|
visit (generic);
|
|
if (trait.has_where_clause ())
|
|
visit (trait.get_where_clause ());
|
|
for (auto &bound : trait.get_type_param_bounds ())
|
|
visit (bound);
|
|
|
|
ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_1);
|
|
};
|
|
|
|
auto inner_fn_3 = [this, &trait, &inner_fn_2] () {
|
|
ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_identifier (),
|
|
std::move (inner_fn_2));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Generics, trait.get_node_id (), inner_fn_3,
|
|
trait.get_identifier () /* FIXME: Is that valid?*/);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::InherentImpl &impl)
|
|
{
|
|
visit_outer_attrs (impl);
|
|
visit (impl.get_visibility ());
|
|
visit_inner_attrs (impl);
|
|
|
|
auto inner_fn_1 = [this, &impl] () {
|
|
for (auto &item : impl.get_impl_items ())
|
|
visit (item);
|
|
};
|
|
|
|
auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
|
|
maybe_insert_big_self (impl);
|
|
for (auto &generic : impl.get_generic_params ())
|
|
visit (generic);
|
|
if (impl.has_where_clause ())
|
|
visit (impl.get_where_clause ());
|
|
visit_impl_type (impl.get_type ());
|
|
|
|
ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
|
|
};
|
|
|
|
auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
|
|
ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::TraitImpl &impl)
|
|
{
|
|
visit_outer_attrs (impl);
|
|
visit (impl.get_visibility ());
|
|
visit_inner_attrs (impl);
|
|
|
|
auto inner_fn_1 = [this, &impl] () {
|
|
for (auto &item : impl.get_impl_items ())
|
|
visit (item);
|
|
};
|
|
|
|
auto inner_fn_2 = [this, &impl, &inner_fn_1] () {
|
|
maybe_insert_big_self (impl);
|
|
for (auto &generic : impl.get_generic_params ())
|
|
visit (generic);
|
|
if (impl.has_where_clause ())
|
|
visit (impl.get_where_clause ());
|
|
visit_impl_type (impl.get_type ());
|
|
visit (impl.get_trait_path ());
|
|
|
|
ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn_1);
|
|
};
|
|
|
|
auto inner_fn_3 = [this, &impl, &inner_fn_2] () {
|
|
ctx.canonical_ctx.scope_impl (impl, std::move (inner_fn_2));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Generics, impl.get_node_id (), inner_fn_3);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::StructStruct &type)
|
|
{
|
|
auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
|
|
|
|
auto inner_fn_2 = [this, &type, &inner_fn_1] () {
|
|
ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
|
|
std::move (inner_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
|
|
inner_fn_2, type.get_struct_name ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::TupleStruct &type)
|
|
{
|
|
auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
|
|
|
|
auto inner_fn_2 = [this, &type, &inner_fn_1] () {
|
|
ctx.canonical_ctx.scope (type.get_node_id (), type.get_struct_name (),
|
|
std::move (inner_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
|
|
inner_fn_2, type.get_struct_name ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::EnumItem &item)
|
|
{
|
|
auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
|
|
|
|
ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
|
|
inner_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::EnumItemTuple &item)
|
|
{
|
|
auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
|
|
|
|
ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
|
|
inner_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::EnumItemStruct &item)
|
|
{
|
|
auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
|
|
|
|
ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
|
|
inner_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::EnumItemDiscriminant &item)
|
|
{
|
|
auto inner_fn = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
|
|
|
|
ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
|
|
inner_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::Enum &type)
|
|
{
|
|
auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
|
|
|
|
auto inner_fn_2 = [this, &type, &inner_fn_1] () {
|
|
ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
|
|
std::move (inner_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
|
|
inner_fn_2, type.get_identifier ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::Union &type)
|
|
{
|
|
auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
|
|
|
|
auto inner_fn_2 = [this, &type, &inner_fn_1] () {
|
|
ctx.canonical_ctx.scope (type.get_node_id (), type.get_identifier (),
|
|
std::move (inner_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
|
|
inner_fn_2, type.get_identifier ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::TypeAlias &type)
|
|
{
|
|
auto inner_fn_1 = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
|
|
|
|
auto inner_fn_2 = [this, &type, &inner_fn_1] () {
|
|
ctx.canonical_ctx.scope (type.get_node_id (), type.get_new_type_name (),
|
|
std::move (inner_fn_1));
|
|
};
|
|
|
|
ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
|
|
inner_fn_2, type.get_new_type_name ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit_closure_params (AST::ClosureExpr &expr)
|
|
{
|
|
for (auto ¶m : expr.get_params ())
|
|
visit (param);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::ClosureExpr &expr)
|
|
{
|
|
auto expr_fn = [this, &expr] () {
|
|
visit_closure_params (expr);
|
|
visit (expr.get_definition_expr ());
|
|
};
|
|
|
|
visit_outer_attrs (expr);
|
|
|
|
ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), expr_fn);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::ClosureExprInner &expr)
|
|
{
|
|
if (expr.is_marked_for_strip ())
|
|
return;
|
|
|
|
visit (static_cast<AST::ClosureExpr &> (expr));
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
|
|
{
|
|
if (expr.is_marked_for_strip ())
|
|
return;
|
|
|
|
visit (static_cast<AST::ClosureExpr &> (expr));
|
|
visit (expr.get_return_type ());
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::MatchExpr &expr)
|
|
{
|
|
if (expr.is_marked_for_strip ())
|
|
return;
|
|
|
|
AST::DefaultASTVisitor::visit (expr);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::ConstantItem &item)
|
|
{
|
|
auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
|
|
|
|
auto expr_vis_2 = [this, &item, &expr_vis_1] () {
|
|
ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
|
|
std::move (expr_vis_1));
|
|
};
|
|
|
|
// FIXME: Why do we need a Rib here?
|
|
ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::StaticItem &item)
|
|
{
|
|
auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
|
|
|
|
auto expr_vis_2 = [this, &item, &expr_vis_1] () {
|
|
ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
|
|
std::move (expr_vis_1));
|
|
};
|
|
|
|
// FIXME: Why do we need a Rib here?
|
|
ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::TypeParam ¶m)
|
|
{
|
|
auto expr_vis = [this, ¶m] () { AST::DefaultASTVisitor::visit (param); };
|
|
|
|
ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (), expr_vis);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit_extern_crate (AST::ExternCrate &extern_crate,
|
|
AST::Crate &crate, CrateNum num)
|
|
{
|
|
visit (crate);
|
|
}
|
|
|
|
void
|
|
DefaultResolver::visit (AST::ExternCrate &crate)
|
|
{
|
|
auto &mappings = Analysis::Mappings::get ();
|
|
auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
|
|
|
|
if (!num_opt)
|
|
{
|
|
rust_error_at (crate.get_locus (), "unknown crate %qs",
|
|
crate.get_referenced_crate ().c_str ());
|
|
return;
|
|
}
|
|
|
|
CrateNum num = *num_opt;
|
|
|
|
AST::Crate &referenced_crate = mappings.get_ast_crate (num);
|
|
|
|
auto sub_visitor_1
|
|
= [&, this] () { visit_extern_crate (crate, referenced_crate, num); };
|
|
|
|
auto sub_visitor_2 = [&] () {
|
|
ctx.canonical_ctx.scope_crate (referenced_crate.get_node_id (),
|
|
crate.get_referenced_crate (),
|
|
std::move (sub_visitor_1));
|
|
};
|
|
|
|
if (crate.has_as_clause ())
|
|
ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
|
|
sub_visitor_2, crate.get_as_clause ());
|
|
else
|
|
ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
|
|
sub_visitor_2, crate.get_referenced_crate ());
|
|
}
|
|
|
|
} // namespace Resolver2_0
|
|
} // namespace Rust
|