summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-01-03 17:13:21 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-01-03 17:13:21 -0500
commit5665bde91427725cf0231cab7e54a6b37b6fba7f (patch)
treef9042cb12a9e07d5b9d8c48caf46d4abe231e5bd /types.c
parent72b20e0c81144adb60f5f342af4ec1cec8a86e9c (diff)
improved the way #sizeof and #alignof work
Diffstat (limited to 'types.c')
-rw-r--r--types.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/types.c b/types.c
index 529eaaf..486dac5 100644
--- a/types.c
+++ b/types.c
@@ -1492,15 +1492,20 @@ static bool types_expr(Typer *tr, Expression *e) {
code->kind = EXPR_VAL;
t->kind = TYPE_UNKNOWN;
} break;
- case EXPR_DSIZEOF: {
- if (!types_expr(tr, e->dsizeof.of))
- return false;
- t->kind = TYPE_BUILTIN;
- t->builtin = BUILTIN_I64;
- } break;
- case EXPR_DALIGNOF: {
- if (!types_expr(tr, e->dalignof.of))
+ case EXPR_DSIZEOF:
+ case EXPR_DALIGNOF: {
+ 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) {
+ Value val;
+ if (!eval_expr(tr->evalr, of, &val))
+ return false;
+ e->val.i64 = (I64)compiler_sizeof(val.type);
+ } else {
+ e->val.i64 = (I64)compiler_sizeof(&of->type);
+ }
+ e->kind = EXPR_VAL;
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_I64;
} break;