diff options
-rw-r--r-- | eval.c | 55 | ||||
-rw-r--r-- | test.toc | 1 | ||||
-rw-r--r-- | types.c | 6 | ||||
-rw-r--r-- | types.h | 1 |
4 files changed, 32 insertions, 31 deletions
@@ -55,6 +55,31 @@ static size_t compiler_sizeof_builtin(BuiltinType b) { return 0; } +static size_t compiler_alignof(Type *t); +/* finds offsets and size */ +static void eval_struct_find_offsets(Type *t) { + assert(t->kind == TYPE_STRUCT); + if (!(t->struc->flags & STRUCT_DEF_FOUND_OFFSETS)) { + size_t bytes = 0; + size_t total_align = 0; + arr_foreach(t->struc->fields, Field, f) { + size_t falign = compiler_alignof(f->type); + if (falign > total_align) + total_align = falign; + /* align */ + bytes += ((falign - bytes) % falign + falign) % falign; /* = -bytes mod falign */ + assert(bytes % falign == 0); + f->offset = bytes; + /* add size */ + bytes += compiler_sizeof(f->type); + } + bytes += ((total_align - bytes) % total_align + total_align) % total_align; /* = -bytes mod align */ + t->struc->size = bytes; + t->struc->align = total_align; + t->struc->flags |= STRUCT_DEF_FOUND_OFFSETS; + } +} + static size_t compiler_alignof(Type *t) { Value v; assert(t->flags & TYPE_IS_RESOLVED); @@ -82,12 +107,8 @@ static size_t compiler_alignof(Type *t) { return sizeof v.pkg; case TYPE_STRUCT: { /* assume the align of a struct is (at most) the greatest align out of its children's */ - size_t align = 1; - arr_foreach(t->struc->fields, Field, f) { - size_t falign = compiler_alignof(f->type); - if (falign > align) align = falign; - } - return align; + eval_struct_find_offsets(t); + return t->struc->align; } case TYPE_UNKNOWN: case TYPE_EXPR: @@ -97,28 +118,6 @@ static size_t compiler_alignof(Type *t) { return 0; } -/* finds offsets and size */ -static void eval_struct_find_offsets(Type *t) { - assert(t->kind == TYPE_STRUCT); - if (!(t->struc->flags & STRUCT_DEF_FOUND_OFFSETS)) { - size_t bytes = 0; - arr_foreach(t->struc->fields, Field, f) { - size_t falign = compiler_alignof(f->type); - /* align */ - bytes += ((falign - bytes) % falign + falign) % falign; /* = -bytes mod falign */ - assert(bytes % falign == 0); - f->offset = bytes; - /* add size */ - bytes += compiler_sizeof(f->type); - } - /* final align */ - size_t align = compiler_alignof(t); - bytes += ((align - bytes) % align + align) % align; /* = -bytes mod align */ - t->struc->size = bytes; - t->struc->flags |= STRUCT_DEF_FOUND_OFFSETS; - } -} - /* size of a type at compile time */ static size_t compiler_sizeof(Type *t) { Value v; @@ -18,5 +18,6 @@ main ::= fn() { c:x = 7; d:x = 18; k : [5]struct {x: int; y: int;}; + puti(#alignof(k)); puti(k[0].x); };
\ No newline at end of file @@ -1502,13 +1502,13 @@ static bool types_expr(Typer *tr, Expression *e) { Expression *of = e->kind == EXPR_DSIZEOF ? e->dsizeof.of : e->dalignof.of; if (!types_expr(tr, of)) return false; - if (e->dsizeof.of->type.kind == TYPE_TYPE) { + if (of->type.kind == TYPE_TYPE) { Value val; if (!eval_expr(tr->evalr, of, &val)) return false; - e->val.i64 = (I64)compiler_sizeof(val.type); + e->val.i64 = (I64)(e->kind == EXPR_DSIZEOF ? compiler_sizeof : compiler_alignof)(val.type); } else { - e->val.i64 = (I64)compiler_sizeof(&of->type); + e->val.i64 = (I64)(e->kind == EXPR_DSIZEOF ? compiler_sizeof : compiler_alignof)(&of->type); } e->kind = EXPR_VAL; t->kind = TYPE_BUILTIN; @@ -387,6 +387,7 @@ typedef struct { Location where; U16 flags; size_t size; /* size of this struct during compile time */ + size_t align; struct { Identifier name; IdentID id; |