commit 508b0410ae64c0269182db470f4b962654d16cc2
parent 7d173b3f6d558ad24bce75f4bd6336ebfe4f14bf
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 4 Jan 2021 19:01:01 -0500
Fix issues with aggregate types in emit
Diffstat:
3 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -98,6 +98,8 @@ check_expr_access(struct context *ctx,
"Cannot index non-array, non-slice object");
expect(&aexpr->access.index->loc, type_is_integer(itype),
"Cannot use non-integer type as slice/array index");
+ expr->access.index = lower_implicit_cast(
+ &builtin_type_size, expr->access.index);
expr->result = atype->array.members;
break;
case ACCESS_FIELD:
diff --git a/src/emit.c b/src/emit.c
@@ -5,7 +5,7 @@
#include "qbe.h"
static void
-emit_qtype(const struct qbe_type *type, FILE *out)
+emit_qtype(const struct qbe_type *type, bool aggr, FILE *out)
{
switch (type->stype) {
case Q_BYTE:
@@ -17,7 +17,11 @@ emit_qtype(const struct qbe_type *type, FILE *out)
fprintf(out, "%c", (char)type->stype);
break;
case Q__AGGREGATE:
- fprintf(out, ":%s", type->name);
+ if (aggr) {
+ fprintf(out, ":%s", type->name);
+ } else {
+ fprintf(out, "l");
+ }
break;
case Q__VOID:
break; // no-op
@@ -38,7 +42,7 @@ emit_type(const struct qbe_def *def, FILE *out)
while (field) {
if (field->type) {
fprintf(out, " ");
- emit_qtype(field->type, out);
+ emit_qtype(field->type, true, out);
}
if (field->count) {
fprintf(out, " %zu", field->count);
@@ -109,7 +113,7 @@ emit_call(struct qbe_statement *stmt, FILE *out)
bool comma = false;
while (arg) {
fprintf(out, "%s", comma ? ", " : "");
- emit_qtype(arg->value.type, out);
+ emit_qtype(arg->value.type, true, out);
fprintf(out, " ");
emit_value(&arg->value, out);
arg = arg->next;
@@ -131,11 +135,7 @@ emit_stmt(struct qbe_statement *stmt, FILE *out)
if (stmt->out != NULL) {
emit_value(stmt->out, out);
fprintf(out, " =");
- if (stmt->out->indirect) {
- emit_qtype(&qbe_long, out); // XXX: ARCH
- } else {
- emit_qtype(stmt->out->type, out);
- }
+ emit_qtype(stmt->out->type, false, out);
fprintf(out, " ");
}
if (stmt->instr == Q_CALL) {
@@ -165,12 +165,12 @@ emit_func(struct qbe_def *def, FILE *out)
fprintf(out, "%sfunction", def->exported ? "export " : "");
if (def->func.returns->stype != Q__VOID) {
fprintf(out, " ");
- emit_qtype(def->func.returns, out);
+ emit_qtype(def->func.returns, true, out);
}
fprintf(out, " $%s(", def->name);
struct qbe_func_param *param = def->func.params;
while (param) {
- emit_qtype(param->type, out);
+ emit_qtype(param->type, true, out);
fprintf(out, " %%%s", param->name);
if (param->next) {
fprintf(out, ", ");
diff --git a/src/gen.c b/src/gen.c
@@ -54,7 +54,10 @@ alloc_temp(struct gen_context *ctx, struct qbe_value *val,
gen_temp(ctx, val, qtype_for_type(ctx, type, true), fmt);
val->indirect = true;
constl(&size, type->size);
+ const struct qbe_type *qtype = val->type;
+ val->type = &qbe_long;
pushprei(ctx->current, val, alloc_for_align(type->align), &size, NULL);
+ val->type = qtype;
}
static struct gen_binding *