commit 682e8d0662e4b1a155c8fbd1efe225f94d1e31d9
parent 89cb94fd268a2a9d2c736a10057744c1269c4d85
Author: Eyal Sawady <ecs@d2evs.net>
Date: Sat, 24 Jul 2021 16:13:18 +0000
gen: implement aggregate return types
Diffstat:
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -454,12 +454,10 @@ gen_expr_call(struct gen_context *ctx,
.type = Q_INSTR,
.instr = Q_CALL,
};
- struct gen_temp returns = {0};
if (out) {
- // XXX: This is definitely broken on aggregate returns
- gen_direct(ctx, &returns, expr->result, "call.returns.%d");
call.out = xcalloc(1, sizeof(struct qbe_value));
- qval_temp(ctx, call.out, &returns);
+ gen_qtemp(ctx, call.out, qtype_lookup(ctx, expr->result, true),
+ "call.returns.%d");
}
struct qbe_arguments *args, **next = &call.args;
@@ -485,6 +483,15 @@ gen_expr_call(struct gen_context *ctx,
push(&ctx->current->body, &call);
if (out) {
+ struct gen_temp returns = {
+ .name = call.out->name,
+ .type = expr->result,
+ .is_global = false,
+ .indirect = false,
+ };
+ if (type_is_aggregate(expr->result)) {
+ returns.indirect = true;
+ }
gen_copy(ctx, out, &returns);
}
}
diff --git a/tests/903-call.ha b/tests/903-call.ha
@@ -2,7 +2,7 @@ type coords = struct { x: int, y: int };
fn foo() size = 2;
fn equal(x: int, y: int) bool = x == y;
-fn aggregate(c: coords) int = c.x;
+fn aggregate(c: coords) coords = c;
export fn main() int = {
// Indirect
@@ -17,8 +17,11 @@ export fn main() int = {
let x = 1234;
assert(equal(x, 1234));
- // Aggregate params
+ // Aggregate params and return
let x = coords { x = 1234, y = 4321 };
- assert(aggregate(x) == 1234);
+ let x = aggregate(x);
+ // TODO: Use &&
+ assert(x.x == 1234);
+ assert(x.y == 4321);
return 0;
};