diff options
Diffstat (limited to 'gcc/rust/backend/rust-compile-item.h')
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 367 |
1 files changed, 6 insertions, 361 deletions
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index 70b5415..71f259f 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -20,14 +20,6 @@ #define RUST_COMPILE_ITEM #include "rust-compile-base.h" -#include "rust-compile-tyty.h" -#include "rust-compile-implitem.h" -#include "rust-compile-var-decl.h" -#include "rust-compile-stmt.h" -#include "rust-compile-expr.h" -#include "rust-compile-fnparam.h" -#include "rust-compile-extern.h" -#include "rust-constexpr.h" namespace Rust { namespace Compile { @@ -54,364 +46,17 @@ public: return compiler.reference; } - void visit (HIR::StaticItem &var) override - { - // have we already compiled this? - Bvariable *static_decl_ref = nullptr; - if (ctx->lookup_var_decl (var.get_mappings ().get_hirid (), - &static_decl_ref)) - { - reference - = ctx->get_backend ()->var_expression (static_decl_ref, ref_locus); - return; - } - - TyTy::BaseType *resolved_type = nullptr; - bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (), - &resolved_type); - rust_assert (ok); - - tree type = TyTyResolveCompile::compile (ctx, resolved_type); - tree value = CompileExpr::Compile (var.get_expr (), ctx); - - const Resolver::CanonicalPath *canonical_path = nullptr; - ok = ctx->get_mappings ()->lookup_canonical_path ( - var.get_mappings ().get_crate_num (), var.get_mappings ().get_nodeid (), - &canonical_path); - rust_assert (ok); - - std::string name = canonical_path->get (); - std::string asm_name = ctx->mangle_item (resolved_type, *canonical_path); - - bool is_external = false; - bool is_hidden = false; - bool in_unique_section = true; - - Bvariable *static_global - = ctx->get_backend ()->global_variable (name, asm_name, type, is_external, - is_hidden, in_unique_section, - var.get_locus ()); - ctx->get_backend ()->global_variable_set_init (static_global, value); - - ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global); - ctx->push_var (static_global); - - reference = ctx->get_backend ()->var_expression (static_global, ref_locus); - } - - void visit (HIR::ConstantItem &constant) override - { - // resolve the type - TyTy::BaseType *resolved_type = nullptr; - bool ok - = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (), - &resolved_type); - rust_assert (ok); - - // canonical path - const Resolver::CanonicalPath *canonical_path = nullptr; - ok = ctx->get_mappings ()->lookup_canonical_path ( - constant.get_mappings ().get_crate_num (), - constant.get_mappings ().get_nodeid (), &canonical_path); - rust_assert (ok); - std::string ident = canonical_path->get (); - - // types - tree type = TyTyResolveCompile::compile (ctx, resolved_type); - tree const_type = build_qualified_type (type, TYPE_QUAL_CONST); - - HIR::Expr *const_value_expr = constant.get_expr (); - bool is_block_expr - = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block; - - // compile the expression - tree folded_expr = error_mark_node; - if (!is_block_expr) - { - tree value = CompileExpr::Compile (constant.get_expr (), ctx); - folded_expr = ConstCtx::fold (value); - } - else - { - // in order to compile a block expr we want to reuse as much existing - // machineary that we already have. This means the best approach is to - // make a _fake_ function with a block so it can hold onto temps then - // use our constexpr code to fold it completely or error_mark_node - Backend::typed_identifier receiver; - tree compiled_fn_type = ctx->get_backend ()->function_type ( - receiver, {}, - {Backend::typed_identifier ("_", const_type, constant.get_locus ())}, - NULL, constant.get_locus ()); - - tree fndecl - = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, - constant.get_locus ()); - TREE_READONLY (fndecl) = 1; - - tree enclosing_scope = NULL_TREE; - HIR::BlockExpr *function_body - = static_cast<HIR::BlockExpr *> (constant.get_expr ()); - Location start_location = function_body->get_locus (); - Location end_location = function_body->get_end_locus (); - - tree code_block - = ctx->get_backend ()->block (fndecl, enclosing_scope, {}, - start_location, end_location); - ctx->push_block (code_block); - - bool address_is_taken = false; - tree ret_var_stmt = NULL_TREE; - Bvariable *return_address = ctx->get_backend ()->temporary_variable ( - fndecl, code_block, const_type, NULL, address_is_taken, - constant.get_locus (), &ret_var_stmt); - - ctx->add_statement (ret_var_stmt); - ctx->push_fn (fndecl, return_address); - - compile_function_body (fndecl, *function_body, true); - - ctx->pop_block (); - - auto body = ctx->get_backend ()->block_statement (code_block); - if (!ctx->get_backend ()->function_set_body (fndecl, body)) - { - rust_error_at (constant.get_locus (), - "failed to set body to constant function"); - return; - } - - ctx->pop_fn (); - - // lets fold it into a call expr - tree call = build_call_array_loc (constant.get_locus ().gcc_location (), - const_type, fndecl, 0, NULL); - folded_expr = ConstCtx::fold (call); - } - - tree const_expr - = ctx->get_backend ()->named_constant_expression (const_type, ident, - folded_expr, - constant.get_locus ()); - - ctx->push_const (const_expr); - ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); - - reference = const_expr; - } - - void visit (HIR::Function &function) override - { - TyTy::BaseType *fntype_tyty; - if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (), - &fntype_tyty)) - { - rust_fatal_error (function.get_locus (), - "failed to lookup function type"); - return; - } - - rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF); - TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty); - if (fntype->has_subsititions_defined ()) - { - // we cant do anything for this only when it is used and a concrete type - // is given - if (concrete == nullptr) - return; - else - { - rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF); - fntype = static_cast<TyTy::FnType *> (concrete); - } - } - - // items can be forward compiled which means we may not need to invoke this - // code. We might also have already compiled this generic function as well. - tree lookup = NULL_TREE; - if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup, - fntype->get_id (), fntype)) - { - // has this been added to the list then it must be finished - if (ctx->function_completed (lookup)) - { - tree dummy = NULL_TREE; - if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy)) - { - ctx->insert_function_decl (fntype, lookup); - } + void visit (HIR::StaticItem &var) override; - reference - = ctx->get_backend ()->function_code_expression (lookup, - ref_locus); - return; - } - } + void visit (HIR::ConstantItem &constant) override; - if (fntype->has_subsititions_defined ()) - { - // override the Hir Lookups for the substituions in this context - fntype->override_context (); - } + void visit (HIR::Function &function) override; - tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype); + void visit (HIR::ImplBlock &impl_block) override; - const Resolver::CanonicalPath *canonical_path = nullptr; - bool ok = ctx->get_mappings ()->lookup_canonical_path ( - function.get_mappings ().get_crate_num (), - function.get_mappings ().get_nodeid (), &canonical_path); - rust_assert (ok); + void visit (HIR::ExternBlock &extern_block) override; - std::string ir_symbol_name - = canonical_path->get () + fntype->subst_as_string (); - std::string asm_name = function.get_function_name (); - - // we don't mangle the main fn since we haven't implemented the main shim - // yet - bool is_main_fn = function.get_function_name ().compare ("main") == 0; - if (!is_main_fn) - { - asm_name = ctx->mangle_item (fntype, *canonical_path); - } - - unsigned int flags = 0; - tree fndecl - = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, - asm_name, flags, function.get_locus ()); - setup_attributes_on_fndecl (fndecl, is_main_fn, function.has_visibility (), - function.get_qualifiers (), - function.get_outer_attrs ()); - - // insert into the context - ctx->insert_function_decl (fntype, fndecl); - - // setup the params - TyTy::BaseType *tyret = fntype->get_return_type (); - std::vector<Bvariable *> param_vars; - - size_t i = 0; - for (auto &it : fntype->get_params ()) - { - HIR::FunctionParam &referenced_param - = function.get_function_params ().at (i); - auto param_tyty = it.second; - auto compiled_param_type - = TyTyResolveCompile::compile (ctx, param_tyty); - - Location param_locus - = ctx->get_mappings ()->lookup_location (param_tyty->get_ref ()); - Bvariable *compiled_param_var - = CompileFnParam::compile (ctx, fndecl, &referenced_param, - compiled_param_type, param_locus); - if (compiled_param_var == nullptr) - { - rust_error_at (param_locus, "failed to compile parameter variable"); - return; - } - - param_vars.push_back (compiled_param_var); - - ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (), - compiled_param_var); - i++; - } - - if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars)) - { - rust_fatal_error (function.get_locus (), - "failed to setup parameter variables"); - return; - } - - // lookup locals - auto block_expr = function.get_definition ().get (); - auto body_mappings = block_expr->get_mappings (); - - Resolver::Rib *rib = nullptr; - if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), - &rib)) - { - rust_fatal_error (function.get_locus (), - "failed to setup locals per block"); - return; - } - - std::vector<Bvariable *> locals; - ok = compile_locals_for_block (*rib, fndecl, locals); - rust_assert (ok); - - tree enclosing_scope = NULL_TREE; - HIR::BlockExpr *function_body = function.get_definition ().get (); - Location start_location = function_body->get_locus (); - Location end_location = function_body->get_end_locus (); - - tree code_block - = ctx->get_backend ()->block (fndecl, enclosing_scope, locals, - start_location, end_location); - ctx->push_block (code_block); - - Bvariable *return_address = nullptr; - if (function.has_function_return_type ()) - { - tree return_type = TyTyResolveCompile::compile (ctx, tyret); - - bool address_is_taken = false; - tree ret_var_stmt = NULL_TREE; - - return_address = ctx->get_backend ()->temporary_variable ( - fndecl, code_block, return_type, NULL, address_is_taken, - function.get_locus (), &ret_var_stmt); - - ctx->add_statement (ret_var_stmt); - } - - ctx->push_fn (fndecl, return_address); - - compile_function_body (fndecl, *function.get_definition ().get (), - function.has_function_return_type ()); - - ctx->pop_block (); - auto body = ctx->get_backend ()->block_statement (code_block); - if (!ctx->get_backend ()->function_set_body (fndecl, body)) - { - rust_error_at (function.get_locus (), "failed to set body to function"); - return; - } - - ctx->pop_fn (); - ctx->push_function (fndecl); - - reference - = ctx->get_backend ()->function_code_expression (fndecl, ref_locus); - } - - void visit (HIR::ImplBlock &impl_block) override - { - TyTy::BaseType *self_lookup = nullptr; - if (!ctx->get_tyctx ()->lookup_type ( - impl_block.get_type ()->get_mappings ().get_hirid (), &self_lookup)) - { - rust_error_at (impl_block.get_locus (), - "failed to resolve type of impl"); - return; - } - - for (auto &impl_item : impl_block.get_impl_items ()) - CompileInherentImplItem::Compile (impl_item.get (), ctx); - } - - void visit (HIR::ExternBlock &extern_block) override - { - for (auto &item : extern_block.get_extern_items ()) - { - CompileExternItem::compile (item.get (), ctx, concrete); - } - } - - void visit (HIR::Module &module) override - { - for (auto &item : module.get_items ()) - CompileItem::compile (item.get (), ctx); - } + void visit (HIR::Module &module) override; protected: CompileItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus) |