harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Msrc/gen.c | 15+++++++++++----
Mtests/903-call.ha | 9++++++---
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; };