aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/backend/rust-compile-base.cc')
-rw-r--r--gcc/rust/backend/rust-compile-base.cc103
1 files changed, 57 insertions, 46 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 60ae25c..70147a3 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -35,6 +35,7 @@
#include "stringpool.h"
#include "attribs.h"
#include "tree.h"
+#include "print-tree.h"
namespace Rust {
namespace Compile {
@@ -466,9 +467,9 @@ HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib,
}
void
-HIRCompileBase::compile_function_body (Context *ctx, tree fndecl,
+HIRCompileBase::compile_function_body (tree fndecl,
HIR::BlockExpr &function_body,
- bool has_return_type)
+ TyTy::BaseType *fn_return_ty)
{
for (auto &s : function_body.get_statements ())
{
@@ -482,40 +483,48 @@ HIRCompileBase::compile_function_body (Context *ctx, tree fndecl,
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);
+ Location locus = function_body.get_final_expr ()->get_locus ();
+ tree return_value = CompileExpr::Compile (function_body.expr.get (), ctx);
- if (compiled_expr != nullptr)
+ // we can only return this if non unit value return type
+ if (!fn_return_ty->is_unit ())
{
- 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
- {
- // FIXME can this actually happen?
- ctx->add_statement (compiled_expr);
- }
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fndecl, return_value,
+ locus);
+ ctx->add_statement (return_stmt);
}
+ else
+ {
+ // just add the stmt expression
+ ctx->add_statement (return_value);
+
+ // now just return unit expression
+ tree unit_expr = unit_expression (ctx, locus);
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fndecl, unit_expr, locus);
+ ctx->add_statement (return_stmt);
+ }
+ }
+ else if (fn_return_ty->is_unit ())
+ {
+ // we can only do this if the function is of unit type otherwise other
+ // errors should have occurred
+ Location locus = function_body.get_locus ();
+ tree return_value = unit_expression (ctx, locus);
+ tree return_stmt
+ = ctx->get_backend ()->return_statement (fndecl, return_value, locus);
+ ctx->add_statement (return_stmt);
}
}
tree
HIRCompileBase::compile_function (
- Context *ctx, const std::string &fn_name, HIR::SelfParam &self_param,
+ 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)
+ const Resolver::CanonicalPath *canonical_path, TyTy::FnType *fntype)
{
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
std::string ir_symbol_name
@@ -606,24 +615,19 @@ HIRCompileBase::compile_function (
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;
+ tree return_type = TyTyResolveCompile::compile (ctx, tyret);
- return_address
- = ctx->get_backend ()->temporary_variable (fndecl, code_block,
- return_type, NULL,
- address_is_taken, locus,
- &ret_var_stmt);
+ 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->add_statement (ret_var_stmt);
ctx->push_fn (fndecl, return_address);
- compile_function_body (ctx, fndecl, *function_body, function_has_return);
+ compile_function_body (fndecl, *function_body, tyret);
tree bind_tree = ctx->pop_block ();
gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
@@ -642,14 +646,13 @@ HIRCompileBase::compile_function (
tree
HIRCompileBase::compile_constant_item (
- Context *ctx, TyTy::BaseType *resolved_type,
- const Resolver::CanonicalPath *canonical_path, HIR::Expr *const_value_expr,
- Location locus)
+ 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;
@@ -661,7 +664,6 @@ HIRCompileBase::compile_constant_item (
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;
@@ -703,13 +705,14 @@ HIRCompileBase::compile_constant_item (
{
HIR::BlockExpr *function_body
= static_cast<HIR::BlockExpr *> (const_value_expr);
- compile_function_body (ctx, fndecl, *function_body, true);
+ compile_function_body (fndecl, *function_body, resolved_type);
}
else
{
tree value = CompileExpr::Compile (const_value_expr, ctx);
+
tree return_expr = ctx->get_backend ()->return_statement (
- fndecl, {value}, const_value_expr->get_locus ());
+ fndecl, value, const_value_expr->get_locus ());
ctx->add_statement (return_expr);
}
@@ -831,5 +834,13 @@ HIRCompileBase::resolve_method_address (
return CompileInherentImplItem::Compile (impl_item, ctx, monomorphized);
}
+tree
+HIRCompileBase::unit_expression (Context *ctx, Location locus)
+{
+ tree unit_type = TyTyResolveCompile::get_unit_type (ctx);
+ return ctx->get_backend ()->constructor_expression (unit_type, false, {}, -1,
+ locus);
+}
+
} // namespace Compile
} // namespace Rust