aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in2
-rw-r--r--gcc/rust/backend/rust-compile-base.cc280
-rw-r--r--gcc/rust/backend/rust-compile-base.h27
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc9
-rw-r--r--gcc/rust/backend/rust-compile-extern.h6
-rw-r--r--gcc/rust/backend/rust-compile-implitem.cc102
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h504
-rw-r--r--gcc/rust/backend/rust-compile-item.cc202
-rw-r--r--gcc/rust/backend/rust-compile-item.h367
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc10
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h28
-rw-r--r--gcc/rust/backend/rust-compile.cc100
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h16
-rw-r--r--gcc/rust/rust-backend.h4
-rw-r--r--gcc/rust/rust-gcc.cc14
15 files changed, 648 insertions, 1023 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 660ed23..4f76216 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -96,6 +96,8 @@ GRS_OBJS = \
rust/rust-compile-intrinsic.o \
rust/rust-compile-pattern.o \
rust/rust-base62.o \
+ rust/rust-compile-item.o \
+ rust/rust-compile-implitem.o \
rust/rust-compile-expr.o \
rust/rust-compile-type.o \
rust/rust-constexpr.o \
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 81598c4..85d85b9 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -17,6 +17,11 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-base.h"
+#include "rust-compile-item.h"
+#include "rust-compile-stmt.h"
+#include "rust-compile-fnparam.h"
+#include "rust-compile-var-decl.h"
+
#include "fold-const.h"
#include "stringpool.h"
@@ -169,5 +174,280 @@ HIRCompileBase::address_expression (tree expr, Location location)
return build_fold_addr_expr_loc (location.gcc_location (), expr);
}
+std::vector<Bvariable *>
+HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib,
+ tree fndecl)
+{
+ std::vector<Bvariable *> locals;
+ rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool {
+ Resolver::Definition d;
+ bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
+ rust_assert (ok);
+
+ HIR::Stmt *decl = nullptr;
+ ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
+ rust_assert (ok);
+
+ // if its a function we extract this out side of this fn context
+ // and it is not a local to this function
+ bool is_item = ctx->get_mappings ()->lookup_hir_item (
+ decl->get_mappings ().get_crate_num (),
+ decl->get_mappings ().get_hirid ())
+ != nullptr;
+ if (is_item)
+ {
+ HIR::Item *item = static_cast<HIR::Item *> (decl);
+ CompileItem::compile (item, ctx);
+ return true;
+ }
+
+ Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
+ locals.push_back (compiled);
+
+ return true;
+ });
+
+ return locals;
+}
+
+void
+HIRCompileBase::compile_function_body (Context *ctx, tree fndecl,
+ HIR::BlockExpr &function_body,
+ bool has_return_type)
+{
+ for (auto &s : function_body.get_statements ())
+ {
+ auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
+ if (compiled_expr != nullptr)
+ {
+ tree compiled_stmt
+ = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
+ ctx->add_statement (compiled_stmt);
+ }
+ }
+
+ if (function_body.has_expr ())
+ {
+ // the previous passes will ensure this is a valid return
+ // or a valid trailing expression
+ tree compiled_expr
+ = CompileExpr::Compile (function_body.expr.get (), ctx);
+
+ if (compiled_expr != nullptr)
+ {
+ if (has_return_type)
+ {
+ std::vector<tree> retstmts;
+ retstmts.push_back (compiled_expr);
+
+ auto ret = ctx->get_backend ()->return_statement (
+ fndecl, retstmts,
+ function_body.get_final_expr ()->get_locus ());
+ ctx->add_statement (ret);
+ }
+ else
+ {
+ tree final_stmt
+ = ctx->get_backend ()->expression_statement (fndecl,
+ compiled_expr);
+ ctx->add_statement (final_stmt);
+ }
+ }
+ }
+}
+
+tree
+HIRCompileBase::compile_function (
+ Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
+ std::vector<HIR::FunctionParam> &function_params,
+ const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
+ AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body,
+ const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype,
+ bool function_has_return)
+{
+ tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+ std::string ir_symbol_name
+ = canonical_path->get () + fntype->subst_as_string ();
+
+ // we don't mangle the main fn since we haven't implemented the main shim
+ bool is_main_fn = fn_name.compare ("main") == 0;
+ std::string asm_name = fn_name;
+ 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, locus);
+ setup_attributes_on_fndecl (fndecl, is_main_fn, !visibility.is_error (),
+ qualifiers, outer_attrs);
+ setup_abi_options (fndecl, fntype->get_abi ());
+
+ // 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;
+ if (!self_param.is_error ())
+ {
+ rust_assert (fntype->is_method ());
+ TyTy::BaseType *self_tyty_lookup = fntype->get_self_type ();
+
+ tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
+ Bvariable *compiled_self_param
+ = CompileSelfParam::compile (ctx, fndecl, self_param, self_type,
+ self_param.get_locus ());
+
+ param_vars.push_back (compiled_self_param);
+ ctx->insert_var_decl (self_param.get_mappings ().get_hirid (),
+ compiled_self_param);
+ }
+
+ // offset from + 1 for the TyTy::FnType being used when this is a method to
+ // skip over Self on the FnType
+ bool is_method = !self_param.is_error ();
+ size_t i = is_method ? 1 : 0;
+ for (auto &referenced_param : function_params)
+ {
+ auto tyty_param = fntype->param_at (i++);
+ auto param_tyty = tyty_param.second;
+ auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
+
+ Location param_locus = referenced_param.get_locus ();
+ Bvariable *compiled_param_var
+ = CompileFnParam::compile (ctx, fndecl, &referenced_param,
+ compiled_param_type, param_locus);
+
+ param_vars.push_back (compiled_param_var);
+ ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
+ compiled_param_var);
+ }
+
+ if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+ return error_mark_node;
+
+ // lookup locals
+ auto body_mappings = function_body->get_mappings ();
+ Resolver::Rib *rib = nullptr;
+ bool ok
+ = ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (), &rib);
+ rust_assert (ok);
+
+ std::vector<Bvariable *> locals
+ = compile_locals_for_block (ctx, *rib, fndecl);
+
+ tree enclosing_scope = NULL_TREE;
+ 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_return)
+ {
+ 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, locus,
+ &ret_var_stmt);
+
+ ctx->add_statement (ret_var_stmt);
+ }
+
+ ctx->push_fn (fndecl, return_address);
+ compile_function_body (ctx, fndecl, *function_body, function_has_return);
+ tree bind_tree = ctx->pop_block ();
+
+ gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
+ DECL_SAVED_TREE (fndecl) = bind_tree;
+
+ ctx->pop_fn ();
+ ctx->push_function (fndecl);
+
+ return fndecl;
+}
+
+tree
+HIRCompileBase::compile_constant_item (
+ Context *ctx, TyTy::BaseType *resolved_type,
+ const Resolver::CanonicalPath *canonical_path, HIR::Expr *const_value_expr,
+ Location locus)
+{
+ const std::string &ident = canonical_path->get ();
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
+ 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 (const_value_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, locus)},
+ NULL, locus);
+
+ tree fndecl
+ = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
+ TREE_READONLY (fndecl) = 1;
+
+ tree enclosing_scope = NULL_TREE;
+ HIR::BlockExpr *function_body
+ = static_cast<HIR::BlockExpr *> (const_value_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, locus,
+ &ret_var_stmt);
+
+ ctx->add_statement (ret_var_stmt);
+ ctx->push_fn (fndecl, return_address);
+
+ compile_function_body (ctx, fndecl, *function_body, true);
+ tree bind_tree = ctx->pop_block ();
+
+ gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
+ DECL_SAVED_TREE (fndecl) = bind_tree;
+
+ ctx->pop_fn ();
+
+ // lets fold it into a call expr
+ tree call = build_call_array_loc (locus.gcc_location (), const_type,
+ fndecl, 0, NULL);
+ folded_expr = ConstCtx::fold (call);
+ }
+
+ return ctx->get_backend ()->named_constant_expression (const_type, ident,
+ folded_expr, locus);
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index ec75356..17e889c 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -35,14 +35,9 @@ protected:
Context *ctx;
+protected:
Context *get_context () { return ctx; }
- void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
- bool has_return_type);
-
- bool compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
- std::vector<Bvariable *> &locals);
-
tree coercion_site (tree rvalue, TyTy::BaseType *actual,
TyTy::BaseType *expected, Location lvalue_locus,
Location rvalue_locus);
@@ -81,6 +76,26 @@ protected:
static tree address_expression (tree, Location);
static bool mark_addressable (tree, Location);
+
+ static std::vector<Bvariable *>
+ compile_locals_for_block (Context *ctx, Resolver::Rib &rib, tree fndecl);
+
+ static void compile_function_body (Context *ctx, tree fndecl,
+ HIR::BlockExpr &function_body,
+ bool has_return_type);
+
+ static tree compile_function (
+ Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
+ std::vector<HIR::FunctionParam> &function_params,
+ const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility,
+ AST::AttrVec &outer_attrs, Location locus, HIR::BlockExpr *function_body,
+ const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype,
+ bool function_has_return);
+
+ static tree
+ compile_constant_item (Context *ctx, TyTy::BaseType *resolved_type,
+ const Resolver::CanonicalPath *canonical_path,
+ HIR::Expr *const_value_expr, Location locus);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index f65e1fd..ab560e8 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -18,6 +18,7 @@
#include "rust-compile.h"
#include "rust-compile-item.h"
+#include "rust-compile-implitem.h"
#include "rust-compile-expr.h"
#include "rust-compile-struct-field-expr.h"
#include "rust-hir-trait-resolve.h"
@@ -713,7 +714,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
tree fn = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
{
- return ctx->get_backend ()->function_code_expression (fn, expr_locus);
+ return address_expression (fn, expr_locus);
}
// Now we can try and resolve the address since this might be a forward
@@ -765,8 +766,7 @@ CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
// contain an implementation we should actually return
// error_mark_node
- return CompileTraitItem::Compile (receiver,
- trait_item_ref->get_hir_trait_item (),
+ return CompileTraitItem::Compile (trait_item_ref->get_hir_trait_item (),
ctx, fntype, true, expr_locus);
}
else
@@ -1343,8 +1343,7 @@ CompileExpr::visit (HIR::IdentifierExpr &expr)
}
else if (ctx->lookup_function_decl (ref, &fn))
{
- translated
- = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ());
+ translated = address_expression (fn, expr.get_locus ());
}
else if (ctx->lookup_var_decl (ref, &var))
{
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index 143b240..1412e7a 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -21,12 +21,6 @@
#include "rust-compile-base.h"
#include "rust-compile-intrinsic.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"
namespace Rust {
namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc
new file mode 100644
index 0000000..8dc18d3
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -0,0 +1,102 @@
+// Copyright (C) 2020-2022 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-compile-implitem.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-fnparam.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+CompileTraitItem::visit (HIR::TraitItemConst &constant)
+{
+ rust_assert (concrete != nullptr);
+ TyTy::BaseType *resolved_type = concrete;
+
+ const Resolver::CanonicalPath *canonical_path = nullptr;
+ bool ok = ctx->get_mappings ()->lookup_canonical_path (
+ constant.get_mappings ().get_crate_num (),
+ constant.get_mappings ().get_nodeid (), &canonical_path);
+ rust_assert (ok);
+
+ HIR::Expr *const_value_expr = constant.get_expr ().get ();
+ tree const_expr
+ = compile_constant_item (ctx, resolved_type, canonical_path,
+ const_value_expr, constant.get_locus ());
+ ctx->push_const (const_expr);
+ ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
+
+ reference = const_expr;
+}
+
+void
+CompileTraitItem::visit (HIR::TraitItemFunc &func)
+{
+ rust_assert (func.has_block_defined ());
+
+ rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::FnType *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);
+ }
+ reference = address_expression (lookup, ref_locus);
+ return;
+ }
+ }
+
+ if (fntype->has_subsititions_defined ())
+ {
+ // override the Hir Lookups for the substituions in this context
+ fntype->override_context ();
+ }
+
+ const Resolver::CanonicalPath *canonical_path = nullptr;
+ bool ok = ctx->get_mappings ()->lookup_canonical_path (
+ func.get_mappings ().get_crate_num (), func.get_mappings ().get_nodeid (),
+ &canonical_path);
+ rust_assert (ok);
+
+ // FIXME
+ HIR::Visibility vis (HIR::Visibility::PublicVisType::NONE,
+ AST::SimplePath::create_empty ());
+ HIR::TraitFunctionDecl &function = func.get_decl ();
+ tree fndecl
+ = compile_function (ctx, function.get_function_name (),
+ function.get_self (), function.get_function_params (),
+ function.get_qualifiers (), vis,
+ func.get_outer_attrs (), func.get_locus (),
+ func.get_block_expr ().get (), canonical_path, fntype,
+ function.has_return_type ());
+ reference = address_expression (fndecl, ref_locus);
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index 9320276..60b7246 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -19,19 +19,17 @@
#ifndef RUST_COMPILE_IMPLITEM_H
#define RUST_COMPILE_IMPLITEM_H
-#include "rust-compile-base.h"
-#include "rust-compile-tyty.h"
-#include "rust-compile-var-decl.h"
-#include "rust-compile-stmt.h"
+#include "rust-compile-item.h"
#include "rust-compile-expr.h"
#include "rust-compile-fnparam.h"
namespace Rust {
namespace Compile {
-class CompileInherentImplItem : public HIRCompileBase
+// this is a proxy for HIR::ImplItem's back to use the normel HIR::Item path
+class CompileInherentImplItem : public CompileItem
{
- using Rust::Compile::HIRCompileBase::visit;
+ using Rust::Compile::CompileItem::visit;
public:
static tree Compile (HIR::ImplItem *item, Context *ctx,
@@ -50,265 +48,11 @@ public:
return compiler.reference;
}
- void visit (HIR::ConstantItem &constant) override
- {
- TyTy::BaseType *resolved_type = nullptr;
- bool ok
- = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
- &resolved_type);
- rust_assert (ok);
-
- tree type = TyTyResolveCompile::compile (ctx, resolved_type);
- tree value = CompileExpr::Compile (constant.get_expr (), ctx);
-
- 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 ();
- tree const_expr = ctx->get_backend ()->named_constant_expression (
- type, constant.get_identifier (), value, 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);
- }
- reference
- = ctx->get_backend ()->function_code_expression (lookup,
- ref_locus);
- return;
- }
- }
-
- if (fntype->has_subsititions_defined ())
- {
- // override the Hir Lookups for the substituions in this context
- fntype->override_context ();
- }
-
- // convert to the actual function type
- tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-
- 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);
-
- std::string ir_symbol_name
- = canonical_path->get () + fntype->subst_as_string ();
- std::string 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, false, function.has_visibility (),
- function.get_qualifiers (),
- function.get_outer_attrs ());
- ctx->insert_function_decl (fntype, fndecl);
-
- // setup the params
- TyTy::BaseType *tyret = fntype->get_return_type ();
- std::vector<Bvariable *> param_vars;
-
- if (function.is_method ())
- {
- // insert self
- TyTy::BaseType *self_tyty_lookup = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- function.get_self_param ().get_mappings ().get_hirid (),
- &self_tyty_lookup))
- {
- rust_error_at (function.get_self_param ().get_locus (),
- "failed to lookup self param type");
- return;
- }
-
- tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
- if (self_type == nullptr)
- {
- rust_error_at (function.get_self_param ().get_locus (),
- "failed to compile self param type");
- return;
- }
-
- Bvariable *compiled_self_param
- = CompileSelfParam::compile (ctx, fndecl, function.get_self_param (),
- self_type,
- function.get_self_param ().get_locus ());
- if (compiled_self_param == nullptr)
- {
- rust_error_at (function.get_self_param ().get_locus (),
- "failed to compile self param variable");
- return;
- }
-
- param_vars.push_back (compiled_self_param);
- ctx->insert_var_decl (
- function.get_self_param ().get_mappings ().get_hirid (),
- compiled_self_param);
- }
-
- // offset from + 1 for the TyTy::FnType being used when this is a method to
- // skip over Self on the FnType
- size_t i = function.is_method () ? 1 : 0;
- for (auto referenced_param : function.get_function_params ())
- {
- auto tyty_param = fntype->param_at (i);
- auto param_tyty = tyty_param.second;
-
- auto compiled_param_type
- = TyTyResolveCompile::compile (ctx, param_tyty);
- if (compiled_param_type == nullptr)
- {
- rust_error_at (referenced_param.get_locus (),
- "failed to compile parameter type");
- return;
- }
-
- 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);
- }
-
private:
CompileInherentImplItem (Context *ctx, TyTy::BaseType *concrete,
Location ref_locus)
- : HIRCompileBase (ctx), concrete (concrete),
- reference (ctx->get_backend ()->error_expression ()),
- ref_locus (ref_locus)
+ : CompileItem (ctx, concrete, ref_locus)
{}
-
- TyTy::BaseType *concrete;
- tree reference;
- Location ref_locus;
};
class CompileTraitItem : public HIRCompileBase
@@ -316,12 +60,11 @@ class CompileTraitItem : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static tree Compile (const TyTy::BaseType *self, HIR::TraitItem *item,
- Context *ctx, TyTy::BaseType *concrete,
- bool is_query_mode = false,
+ static tree Compile (HIR::TraitItem *item, Context *ctx,
+ TyTy::BaseType *concrete, bool is_query_mode = false,
Location ref_locus = Location ())
{
- CompileTraitItem compiler (self, ctx, concrete, ref_locus);
+ CompileTraitItem compiler (ctx, concrete, ref_locus);
item->accept_vis (compiler);
if (is_query_mode
@@ -332,240 +75,17 @@ public:
return compiler.reference;
}
- void visit (HIR::TraitItemConst &constant) override
- {
- rust_assert (concrete != nullptr);
- TyTy::BaseType *resolved_type = concrete;
-
- tree type = TyTyResolveCompile::compile (ctx, resolved_type);
- tree value = CompileExpr::Compile (constant.get_expr ().get (), ctx);
-
- const Resolver::CanonicalPath *canonical_path = nullptr;
- bool 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 ();
- tree const_expr = ctx->get_backend ()->named_constant_expression (
- type, constant.get_name (), value, 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::TraitItemFunc &func) override
- {
- rust_assert (func.has_block_defined ());
-
- rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
- TyTy::FnType *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);
- }
- reference
- = ctx->get_backend ()->function_code_expression (lookup,
- ref_locus);
- return;
- }
- }
-
- if (fntype->has_subsititions_defined ())
- {
- // override the Hir Lookups for the substituions in this context
- fntype->override_context ();
- }
-
- // convert to the actual function type
- tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- HIR::TraitFunctionDecl &function = func.get_decl ();
-
- const Resolver::CanonicalPath *canonical_path = nullptr;
- bool ok = ctx->get_mappings ()->lookup_canonical_path (
- func.get_mappings ().get_crate_num (), func.get_mappings ().get_nodeid (),
- &canonical_path);
- rust_assert (ok);
-
- std::string fn_identifier = canonical_path->get ();
- std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
-
- unsigned int flags = 0;
- tree fndecl
- = ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
- asm_name, flags, func.get_locus ());
- setup_attributes_on_fndecl (fndecl, false, false,
- func.get_decl ().get_qualifiers (),
- func.get_outer_attrs ());
- ctx->insert_function_decl (fntype, fndecl);
-
- // setup the params
- TyTy::BaseType *tyret = fntype->get_return_type ();
- std::vector<Bvariable *> param_vars;
-
- if (function.is_method ())
- {
- // insert self
- TyTy::BaseType *self_tyty_lookup = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- function.get_self ().get_mappings ().get_hirid (),
- &self_tyty_lookup))
- {
- rust_error_at (function.get_self ().get_locus (),
- "failed to lookup self param type");
- return;
- }
-
- tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
- if (self_type == nullptr)
- {
- rust_error_at (function.get_self ().get_locus (),
- "failed to compile self param type");
- return;
- }
+ void visit (HIR::TraitItemConst &constant) override;
- Bvariable *compiled_self_param
- = CompileSelfParam::compile (ctx, fndecl, function.get_self (),
- self_type,
- function.get_self ().get_locus ());
- if (compiled_self_param == nullptr)
- {
- rust_error_at (function.get_self ().get_locus (),
- "failed to compile self param variable");
- return;
- }
-
- param_vars.push_back (compiled_self_param);
- ctx->insert_var_decl (function.get_self ().get_mappings ().get_hirid (),
- compiled_self_param);
- }
-
- // offset from + 1 for the TyTy::FnType being used when this is a method to
- // skip over Self on the FnType
- size_t i = function.is_method () ? 1 : 0;
- for (auto referenced_param : function.get_function_params ())
- {
- auto tyty_param = fntype->param_at (i);
- auto param_tyty = tyty_param.second;
-
- auto compiled_param_type
- = TyTyResolveCompile::compile (ctx, param_tyty);
- if (compiled_param_type == nullptr)
- {
- rust_error_at (referenced_param.get_locus (),
- "failed to compile parameter type");
- return;
- }
-
- 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 (func.get_locus (),
- "failed to setup parameter variables");
- return;
- }
-
- // lookup locals
- auto block_expr = func.get_block_expr ().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 (func.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 = func.get_block_expr ().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_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,
- func.get_locus (), &ret_var_stmt);
-
- ctx->add_statement (ret_var_stmt);
- }
-
- ctx->push_fn (fndecl, return_address);
-
- compile_function_body (fndecl, *func.get_block_expr ().get (),
- function.has_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 (func.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::TraitItemFunc &func) override;
private:
- CompileTraitItem (const TyTy::BaseType *self, Context *ctx,
- TyTy::BaseType *concrete, Location ref_locus)
- : HIRCompileBase (ctx), self (self), concrete (concrete),
+ CompileTraitItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus)
+ : HIRCompileBase (ctx), concrete (concrete),
reference (ctx->get_backend ()->error_expression ()),
ref_locus (ref_locus)
{}
- const TyTy::BaseType *self;
TyTy::BaseType *concrete;
tree reference;
Location ref_locus;
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
new file mode 100644
index 0000000..d42cc1e
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -0,0 +1,202 @@
+// Copyright (C) 2020-2022 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-compile-item.h"
+#include "rust-compile-implitem.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-extern.h"
+#include "rust-constexpr.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+CompileItem::visit (HIR::StaticItem &var)
+{
+ // 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
+CompileItem::visit (HIR::ConstantItem &constant)
+{
+ // 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);
+
+ HIR::Expr *const_value_expr = constant.get_expr ();
+ tree const_expr
+ = compile_constant_item (ctx, resolved_type, canonical_path,
+ const_value_expr, constant.get_locus ());
+
+ ctx->push_const (const_expr);
+ ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
+ reference = const_expr;
+}
+
+void
+CompileItem::visit (HIR::Function &function)
+{
+ 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);
+ }
+
+ reference = address_expression (lookup, ref_locus);
+ return;
+ }
+ }
+
+ if (fntype->has_subsititions_defined ())
+ {
+ // override the Hir Lookups for the substituions in this context
+ fntype->override_context ();
+ }
+
+ 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);
+
+ tree fndecl
+ = compile_function (ctx, function.get_function_name (),
+ function.get_self_param (),
+ function.get_function_params (),
+ function.get_qualifiers (), function.get_visibility (),
+ function.get_outer_attrs (), function.get_locus (),
+ function.get_definition ().get (), canonical_path,
+ fntype, function.has_function_return_type ());
+ reference = address_expression (fndecl, ref_locus);
+}
+
+void
+CompileItem::visit (HIR::ImplBlock &impl_block)
+{
+ 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
+CompileItem::visit (HIR::ExternBlock &extern_block)
+{
+ for (auto &item : extern_block.get_extern_items ())
+ {
+ CompileExternItem::compile (item.get (), ctx, concrete);
+ }
+}
+
+void
+CompileItem::visit (HIR::Module &module)
+{
+ for (auto &item : module.get_items ())
+ CompileItem::compile (item.get (), ctx);
+}
+
+} // namespace Compile
+} // namespace Rust
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)
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index c624046..2ef1232 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -16,10 +16,10 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include "rust-linemap.h"
-#include "rust-backend.h"
#include "rust-compile-resolve-path.h"
#include "rust-compile-item.h"
+#include "rust-compile-implitem.h"
+#include "rust-compile-expr.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
@@ -131,7 +131,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
tree fn = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
{
- return ctx->get_backend ()->function_code_expression (fn, expr_locus);
+ return address_expression (fn, expr_locus);
}
}
@@ -245,8 +245,8 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup,
associated->setup_associated_types ();
return CompileTraitItem::Compile (
- receiver, trait_item_ref->get_hir_trait_item (), ctx, lookup,
- true, expr_locus);
+ trait_item_ref->get_hir_trait_item (), ctx, lookup, true,
+ expr_locus);
}
else
{
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 10f9a52..24a2084 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -48,34 +48,6 @@ public:
translated = CompileExpr::Compile (stmt.get_expr (), ctx);
}
- void visit (HIR::ConstantItem &constant) override
- {
- TyTy::BaseType *resolved_type = nullptr;
- bool ok
- = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
- &resolved_type);
- rust_assert (ok);
-
- tree type = TyTyResolveCompile::compile (ctx, resolved_type);
- tree value = CompileExpr::Compile (constant.get_expr (), ctx);
-
- 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 ();
- tree const_expr
- = ctx->get_backend ()->named_constant_expression (type, ident, value,
- constant.get_locus ());
-
- ctx->push_const (const_expr);
- ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
-
- translated = const_expr;
- }
-
void visit (HIR::LetStmt &stmt) override
{
// nothing to do
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 2299ddb..fcbfc05 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -16,14 +16,16 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include "rust-compile.h"
-#include "rust-compile-item.h"
-#include "rust-compile-expr.h"
-#include "rust-compile-struct-field-expr.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
#include "rust-hir-type-bounds.h"
#include "rust-hir-dot-operator.h"
+#include "rust-compile.h"
+#include "rust-compile-item.h"
+#include "rust-compile-implitem.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-struct-field-expr.h"
+#include "rust-compile-stmt.h"
namespace Rust {
namespace Compile {
@@ -67,9 +69,8 @@ CompileBlock::visit (HIR::BlockExpr &expr)
return;
}
- std::vector<Bvariable *> locals;
- bool ok = compile_locals_for_block (*rib, fndecl, locals);
- rust_assert (ok);
+ std::vector<Bvariable *> locals
+ = compile_locals_for_block (ctx, *rib, fndecl);
tree enclosing_scope = ctx->peek_enclosing_scope ();
tree new_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
@@ -203,87 +204,6 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
// Shared methods in compilation
-void
-HIRCompileBase::compile_function_body (tree fndecl,
- HIR::BlockExpr &function_body,
- bool has_return_type)
-{
- for (auto &s : function_body.get_statements ())
- {
- auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
- if (compiled_expr != nullptr)
- {
- tree compiled_stmt
- = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
- ctx->add_statement (compiled_stmt);
- }
- }
-
- if (function_body.has_expr ())
- {
- // the previous passes will ensure this is a valid return
- // or a valid trailing expression
- tree compiled_expr
- = CompileExpr::Compile (function_body.expr.get (), ctx);
-
- if (compiled_expr != nullptr)
- {
- if (has_return_type)
- {
- std::vector<tree> retstmts;
- retstmts.push_back (compiled_expr);
-
- auto ret = ctx->get_backend ()->return_statement (
- fndecl, retstmts,
- function_body.get_final_expr ()->get_locus ());
- ctx->add_statement (ret);
- }
- else
- {
- tree final_stmt
- = ctx->get_backend ()->expression_statement (fndecl,
- compiled_expr);
- ctx->add_statement (final_stmt);
- }
- }
- }
-}
-
-bool
-HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
- std::vector<Bvariable *> &locals)
-{
- rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool {
- Resolver::Definition d;
- bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
- rust_assert (ok);
-
- HIR::Stmt *decl = nullptr;
- ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
- rust_assert (ok);
-
- // if its a function we extract this out side of this fn context
- // and it is not a local to this function
- bool is_item = ctx->get_mappings ()->lookup_hir_item (
- decl->get_mappings ().get_crate_num (),
- decl->get_mappings ().get_hirid ())
- != nullptr;
- if (is_item)
- {
- HIR::Item *item = static_cast<HIR::Item *> (decl);
- CompileItem::compile (item, ctx);
- return true;
- }
-
- Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
- locals.push_back (compiled);
-
- return true;
- });
-
- return true;
-}
-
tree
HIRCompileBase::coercion_site (tree rvalue, TyTy::BaseType *actual,
TyTy::BaseType *expected, Location lvalue_locus,
@@ -533,8 +453,8 @@ HIRCompileBase::compute_address_for_trait_item (
rust_assert (trait_item_has_definition);
HIR::TraitItem *trait_item = ref->get_hir_trait_item ();
- return CompileTraitItem::Compile (root, trait_item, ctx, trait_item_fntype,
- true, locus);
+ return CompileTraitItem::Compile (trait_item, ctx, trait_item_fntype, true,
+ locus);
}
bool
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 5fdf806..d1cb762 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -510,7 +510,6 @@ struct FunctionParam
{
std::unique_ptr<Pattern> param_name;
std::unique_ptr<Type> type;
-
Location locus;
Analysis::NodeMapping mappings;
@@ -1226,11 +1225,7 @@ public:
bool is_method () const { return !self.is_error (); }
- SelfParam &get_self_param ()
- {
- rust_assert (is_method ());
- return self;
- }
+ SelfParam &get_self_param () { return self; }
protected:
/* Use covariance to implement clone function as returning this object
@@ -2242,11 +2237,7 @@ public:
bool is_method () const { return !self.is_error (); }
- SelfParam &get_self ()
- {
- rust_assert (is_method ());
- return self;
- }
+ SelfParam &get_self () { return self; }
Identifier get_function_name () const { return function_name; }
@@ -2341,7 +2332,8 @@ public:
return TraitItemKind::FUNC;
}
- AST::AttrVec get_outer_attrs () const { return outer_attrs; }
+ AST::AttrVec &get_outer_attrs () { return outer_attrs; }
+ const AST::AttrVec &get_outer_attrs () const { return outer_attrs; }
protected:
// Clone function implementation as (not pure) virtual method
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index f7a1ac6..ac856af 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -251,10 +251,6 @@ public:
// Return an expression that converts EXPR to TYPE.
virtual tree convert_expression (tree type, tree expr, Location) = 0;
- // Create an expression for the address of a function. This is used to
- // get the address of the code for a function.
- virtual tree function_code_expression (tree, Location) = 0;
-
// Return an expression for the field at INDEX in BSTRUCT.
virtual tree struct_field_expression (tree bstruct, size_t index, Location)
= 0;
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 86a4106..b648365 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -229,8 +229,6 @@ public:
tree convert_expression (tree type, tree expr, Location);
- tree function_code_expression (tree, Location);
-
tree struct_field_expression (tree, size_t, Location);
tree compound_expression (tree, tree, Location);
@@ -1305,18 +1303,6 @@ Gcc_backend::convert_expression (tree type_tree, tree expr_tree,
return ret;
}
-// Get the address of a function.
-
-tree
-Gcc_backend::function_code_expression (tree func, Location location)
-{
- if (func == error_mark_node)
- return this->error_expression ();
-
- tree ret = build_fold_addr_expr_loc (location.gcc_location (), func);
- return ret;
-}
-
// Return an expression for the field at INDEX in BSTRUCT.
tree