harec

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

commit 5ac2538aba824a53cb73c301f545d1a2b585c827
parent cc42fcfe62355e614d451e9ae8e207b2658cb4ad
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Mon, 11 Jan 2021 09:12:11 -0500

gen: implement type aliases

Diffstat:
Msrc/gen.c | 53+++++++++++++++++++++++++++--------------------------
Msrc/qtype.c | 4++--
2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -281,24 +281,19 @@ address_index(struct gen_context *ctx, const struct expression *expr, struct qbe_value *out) { - const struct type *atype = expr->access.array->result; - while (atype->storage == TYPE_STORAGE_POINTER) { - atype = atype->pointer.referent; - } - assert(atype->storage == TYPE_STORAGE_ARRAY); // TODO: Slices - gen_temp(ctx, out, &qbe_long, "object.%d"); // XXX: ARCH gen_expression(ctx, expr->access.array, out); - atype = expr->access.array->result; + const struct type *atype = type_dealias(expr->access.array->result); if (atype->storage == TYPE_STORAGE_POINTER) { // We get one dereference for free for aggregate types - atype = atype->pointer.referent; + atype = type_dealias(atype->pointer.referent); } while (atype->storage == TYPE_STORAGE_POINTER) { pushi(ctx->current, out, Q_LOADL, out, NULL); - atype = atype->pointer.referent; + atype = type_dealias(atype->pointer.referent); } + assert(atype->storage == TYPE_STORAGE_ARRAY); // TODO: Slices struct qbe_value index = {0}; gen_temp(ctx, &index, &qbe_long, "index.%d"); @@ -320,22 +315,17 @@ address_field(struct gen_context *ctx, const struct expression *expr, struct qbe_value *out) { - const struct type *stype = expr->access._struct->result; - while (stype->storage == TYPE_STORAGE_POINTER) { - stype = stype->pointer.referent; - } - gen_temp(ctx, out, &qbe_long, "object.%d"); // XXX: ARCH gen_expression(ctx, expr->access._struct, out); - stype = expr->access._struct->result; + const struct type *stype = type_dealias(expr->access._struct->result); if (stype->storage == TYPE_STORAGE_POINTER) { // We get one dereference for free for aggregate types - stype = stype->pointer.referent; + stype = type_dealias(stype->pointer.referent); } while (stype->storage == TYPE_STORAGE_POINTER) { pushi(ctx->current, out, Q_LOADL, out, NULL); - stype = stype->pointer.referent; + stype = type_dealias(stype->pointer.referent); } const struct struct_field *field = expr->access.field; @@ -576,12 +566,6 @@ gen_expr_call(struct gen_context *ctx, .instr = Q_CALL, }; - if (expr->call.lvalue->result->func.result != &builtin_type_void) { - gen_temp(ctx, &result, qtype_for_type(ctx, - expr->call.lvalue->result->func.result, true), "returns.%d"); - call.out = qval_dup(&result); - } - struct qbe_arguments *arg, **next = &call.args; struct call_argument *carg = expr->call.args; arg = *next = xcalloc(1, sizeof(struct qbe_arguments)); @@ -589,6 +573,22 @@ gen_expr_call(struct gen_context *ctx, gen_expression(ctx, expr->call.lvalue, &arg->value); next = &arg->next; + const struct type *ftype = type_dealias(expr->call.lvalue->result); + if (ftype->storage == TYPE_STORAGE_POINTER) { + // We get one dereference for free for aggregate types + ftype = type_dealias(ftype->pointer.referent); + } + while (ftype->storage == TYPE_STORAGE_POINTER) { + pushi(ctx->current, &arg->value, Q_LOADL, &arg->value, NULL); + ftype = type_dealias(ftype->pointer.referent); + } + assert(ftype->storage == TYPE_STORAGE_FUNCTION); + if (ftype->func.result != &builtin_type_void) { + gen_temp(ctx, &result, qtype_for_type(ctx, + ftype->func.result, true), "returns.%d"); + call.out = qval_dup(&result); + } + while (carg) { assert(!carg->variadic); // TODO arg = *next = xcalloc(1, sizeof(struct qbe_arguments)); @@ -618,8 +618,8 @@ gen_expr_cast(struct gen_context *ctx, const struct expression *expr, const struct qbe_value *out) { - const struct type *to = expr->result, - *from = expr->cast.value->result; + const struct type *to = type_dealias(expr->result), + *from = type_dealias(expr->cast.value->result); if (to->storage == from->storage) { gen_expression(ctx, expr->cast.value, out); return; @@ -691,7 +691,6 @@ gen_expr_cast(struct gen_context *ctx, break; case TYPE_STORAGE_F32: case TYPE_STORAGE_F64: - case TYPE_STORAGE_ALIAS: case TYPE_STORAGE_TAGGED_UNION: case TYPE_STORAGE_ENUM: assert(0); // TODO @@ -702,6 +701,8 @@ gen_expr_cast(struct gen_context *ctx, case TYPE_STORAGE_SLICE: pushi(ctx->current, &result, Q_COPY, &in, NULL); break; + case TYPE_STORAGE_ALIAS: + assert(0); // Handled above case TYPE_STORAGE_BOOL: case TYPE_STORAGE_FUNCTION: case TYPE_STORAGE_STRING: diff --git a/src/qtype.c b/src/qtype.c @@ -218,7 +218,7 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended) case TYPE_STORAGE_FUNCTION: return qtype_for_xtype(Q__AGGREGATE); case TYPE_STORAGE_ALIAS: - assert(0); // TODO + return qtype_for_type(ctx, type->alias.type, extended); } assert(0); // Unreachable } @@ -250,7 +250,7 @@ type_is_aggregate(const struct type *type) case TYPE_STORAGE_VOID: return false; case TYPE_STORAGE_ALIAS: - assert(0); // TODO + return type_is_aggregate(type->alias.type); case TYPE_STORAGE_ARRAY: case TYPE_STORAGE_SLICE: case TYPE_STORAGE_STRING: