aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-expr.h42
-rw-r--r--gcc/rust/backend/rust-compile.cc142
2 files changed, 140 insertions, 44 deletions
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index eb245dc..170580b 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -363,12 +363,28 @@ public:
void visit (HIR::AssignmentExpr &expr) override
{
fncontext fn = ctx->peek_fn ();
- auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+ auto lvalue = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rvalue = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ // assignments are coercion sites so lets convert the rvalue if necessary
+ TyTy::BaseType *expected = nullptr;
+ TyTy::BaseType *actual = nullptr;
+
+ bool ok;
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_lhs ()->get_mappings ().get_hirid (), &expected);
+ rust_assert (ok);
+
+ ok = ctx->get_tyctx ()->lookup_type (
+ expr.get_rhs ()->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
Bstatement *assignment
- = ctx->get_backend ()->assignment_statement (fn.fndecl, lhs, rhs,
+ = ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue, rvalue,
expr.get_locus ());
+
ctx->add_statement (assignment);
}
@@ -412,11 +428,11 @@ public:
void visit (HIR::ArrayElemsValues &elems) override
{
- elems.iterate ([&] (HIR::Expr *e) mutable -> bool {
- Bexpression *translated_expr = CompileExpr::Compile (e, ctx);
- constructor.push_back (translated_expr);
- return true;
- });
+ for (auto &elem : elems.get_values ())
+ {
+ Bexpression *translated_expr = CompileExpr::Compile (elem.get (), ctx);
+ constructor.push_back (translated_expr);
+ }
}
void visit (HIR::ArrayElemsCopied &elems) override
@@ -646,11 +662,11 @@ public:
// this assumes all fields are in order from type resolution and if a base
// struct was specified those fields are filed via accesors
std::vector<Bexpression *> vals;
- struct_expr.iterate ([&] (HIR::StructExprField *field) mutable -> bool {
- Bexpression *expr = CompileStructExprField::Compile (field, ctx);
- vals.push_back (expr);
- return true;
- });
+ for (auto &field : struct_expr.get_fields ())
+ {
+ Bexpression *expr = CompileStructExprField::Compile (field.get (), ctx);
+ vals.push_back (expr);
+ }
translated
= ctx->get_backend ()->constructor_expression (type, vals,
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 58c679f..23a035f 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -69,39 +69,120 @@ CompileExpr::visit (HIR::CallExpr &expr)
|| tyty->get_kind () == TyTy::TypeKind::FNPTR;
if (!is_fn)
{
- Btype *type = TyTyResolveCompile::compile (ctx, tyty);
+ rust_assert (tyty->get_kind () == TyTy::TypeKind::ADT);
+ TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyty);
+ Btype *compiled_adt_type = TyTyResolveCompile::compile (ctx, tyty);
// this assumes all fields are in order from type resolution and if a
// base struct was specified those fields are filed via accesors
std::vector<Bexpression *> vals;
- expr.iterate_params ([&] (HIR::Expr *argument) mutable -> bool {
- Bexpression *e = CompileExpr::Compile (argument, ctx);
- vals.push_back (e);
- return true;
- });
+ for (size_t i = 0; i < expr.get_arguments ().size (); i++)
+ {
+ auto &argument = expr.get_arguments ().at (i);
+ auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+
+ // assignments are coercion sites so lets convert the rvalue if
+ // necessary
+ auto respective_field = adt->get_field (i);
+ auto expected = respective_field->get_field_type ();
+
+ TyTy::BaseType *actual = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+ argument->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ // coerce it if required
+ rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+
+ // add it to the list
+ vals.push_back (rvalue);
+ }
translated
- = ctx->get_backend ()->constructor_expression (type, vals, -1,
- expr.get_locus ());
+ = ctx->get_backend ()->constructor_expression (compiled_adt_type, vals,
+ -1, expr.get_locus ());
}
else
{
- // must be a call to a function
- Bexpression *fn = CompileExpr::Compile (expr.get_fnexpr (), ctx);
- rust_assert (fn != nullptr);
+ auto get_parameter_tyty_at_index
+ = [] (const TyTy::BaseType *base, size_t index,
+ TyTy::BaseType **result) -> bool {
+ bool is_fn = base->get_kind () == TyTy::TypeKind::FNDEF
+ || base->get_kind () == TyTy::TypeKind::FNPTR;
+ rust_assert (is_fn);
+
+ if (base->get_kind () == TyTy::TypeKind::FNPTR)
+ {
+ const TyTy::FnPtr *fn = static_cast<const TyTy::FnPtr *> (base);
+ *result = fn->param_at (index);
+
+ return true;
+ }
+
+ const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (base);
+ auto param = fn->param_at (index);
+ *result = param.second;
- std::vector<Bexpression *> args;
- expr.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
- Bexpression *compiled_expr = CompileExpr::Compile (p, ctx);
- rust_assert (compiled_expr != nullptr);
- args.push_back (compiled_expr);
return true;
- });
+ };
+
+ bool is_varadic = false;
+ if (tyty->get_kind () == TyTy::TypeKind::FNDEF)
+ {
+ const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (tyty);
+ is_varadic = fn->is_varadic ();
+ }
+
+ size_t required_num_args;
+ if (tyty->get_kind () == TyTy::TypeKind::FNDEF)
+ {
+ const TyTy::FnType *fn = static_cast<const TyTy::FnType *> (tyty);
+ required_num_args = fn->num_params ();
+ }
+ else
+ {
+ const TyTy::FnPtr *fn = static_cast<const TyTy::FnPtr *> (tyty);
+ required_num_args = fn->num_params ();
+ }
+ std::vector<Bexpression *> args;
+ for (size_t i = 0; i < expr.get_arguments ().size (); i++)
+ {
+ auto &argument = expr.get_arguments ().at (i);
+ auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+
+ if (is_varadic && i >= required_num_args)
+ {
+ args.push_back (rvalue);
+ continue;
+ }
+
+ // assignments are coercion sites so lets convert the rvalue if
+ // necessary
+ bool ok;
+ TyTy::BaseType *expected = nullptr;
+ ok = get_parameter_tyty_at_index (tyty, i, &expected);
+ rust_assert (ok);
+
+ TyTy::BaseType *actual = nullptr;
+ ok = ctx->get_tyctx ()->lookup_type (
+ argument->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ // coerce it if required
+ rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+
+ // add it to the list
+ args.push_back (rvalue);
+ }
+
+ // must be a call to a function
+ auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx);
auto fncontext = ctx->peek_fn ();
translated
- = ctx->get_backend ()->call_expression (fncontext.fndecl, fn, args,
- nullptr, expr.get_locus ());
+ = ctx->get_backend ()->call_expression (fncontext.fndecl, fn_address,
+ args, nullptr,
+ expr.get_locus ());
}
}
@@ -224,12 +305,12 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
std::vector<Bexpression *> args;
args.push_back (self_argument);
- expr.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
- Bexpression *compiled_expr = CompileExpr::Compile (p, ctx);
- rust_assert (compiled_expr != nullptr);
- args.push_back (compiled_expr);
- return true;
- });
+ for (auto &argument : expr.get_arguments ())
+ {
+ Bexpression *compiled_expr
+ = CompileExpr::Compile (argument.get (), ctx);
+ args.push_back (compiled_expr);
+ }
Bexpression *fn_expr
= ctx->get_backend ()->var_expression (fn_convert_expr_tmp,
@@ -414,12 +495,11 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
args.push_back (self);
// normal args
- expr.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
- Bexpression *compiled_expr = CompileExpr::Compile (p, ctx);
- rust_assert (compiled_expr != nullptr);
- args.push_back (compiled_expr);
- return true;
- });
+ for (auto &argument : expr.get_arguments ())
+ {
+ Bexpression *compiled_expr = CompileExpr::Compile (argument.get (), ctx);
+ args.push_back (compiled_expr);
+ }
auto fncontext = ctx->peek_fn ();
translated