diff options
author | Michael Forney <mforney@mforney.org> | 2022-11-26 23:14:24 -0800 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2022-11-26 23:14:49 -0800 |
commit | 3809a018648d2e5597af5eb941e1d003e7ed01cd (patch) | |
tree | 722dbd8fe38a1527e23c6e45ac8c7a82b550d9bb | |
parent | 527fdf60a483475ccd6131c7e736d788cd2704cf (diff) |
Move kind-specific decl fields to union
-rw-r--r-- | cc.h | 22 | ||||
-rw-r--r-- | decl.c | 18 | ||||
-rw-r--r-- | expr.c | 2 | ||||
-rw-r--r-- | qbe.c | 32 | ||||
-rw-r--r-- | scope.c | 24 |
5 files changed, 53 insertions, 45 deletions
@@ -271,15 +271,19 @@ struct decl { char *asmname; _Bool defined; - /* link in list of tentative object definitions */ - struct list tentative; - /* alignment of object storage (may be stricter than type requires) */ - int align; - - /* the function might have an "inline definition" (C11 6.7.4p7) */ - _Bool inlinedefn; - - enum builtinkind builtin; + union { + struct { + /* link in list of tentative object definitions */ + struct list tentative; + /* alignment of object storage (may be stricter than type requires) */ + int align; + } obj; + struct { + /* the function might have an "inline definition" (C11 6.7.4p7) */ + _Bool inlinedefn; + } func; + enum builtinkind builtin; + } u; }; struct scope { @@ -947,8 +947,8 @@ decl(struct scope *s, struct func *f) d = declcommon(s, kind, name, asmname, t, tq, sc, prior); if (align && align < t->align) error(&tok.loc, "specified alignment of object '%s' is less strict than is required by type", name); - if (d->align < align) - d->align = align; + if (d->u.obj.align < align) + d->u.obj.align = align; init = NULL; if (consume(TASSIGN)) { if (f && d->linkage != LINKNONE) @@ -957,8 +957,8 @@ decl(struct scope *s, struct func *f) error(&tok.loc, "object '%s' redefined", name); init = parseinit(s, d->type); } else if (d->linkage != LINKNONE) { - if (!(sc & SCEXTERN) && !d->defined && !d->tentative.next) - listinsert(tentativedefns.prev, &d->tentative); + if (!(sc & SCEXTERN) && !d->defined && !d->u.obj.tentative.next) + listinsert(tentativedefns.prev, &d->u.obj.tentative); break; } if (d->linkage != LINKNONE || sc & SCSTATIC) @@ -966,8 +966,8 @@ decl(struct scope *s, struct func *f) else funcinit(f, d, init); d->defined = true; - if (d->tentative.next) - listremove(&d->tentative); + if (d->u.obj.tentative.next) + listremove(&d->u.obj.tentative); break; case DECLFUNC: if (align) @@ -989,7 +989,7 @@ decl(struct scope *s, struct func *f) } } d = declcommon(s, kind, name, asmname, t, tq, sc, prior); - d->inlinedefn = d->linkage == LINKEXTERN && fs & FUNCINLINE && !(sc & SCEXTERN) && (!prior || prior->inlinedefn); + d->u.func.inlinedefn = d->linkage == LINKEXTERN && fs & FUNCINLINE && !(sc & SCEXTERN) && (!prior || prior->u.func.inlinedefn); if (tok.kind == TLBRACE) { if (!allowfunc) error(&tok.loc, "function definition not allowed"); @@ -999,7 +999,7 @@ decl(struct scope *s, struct func *f) f = mkfunc(d, name, t, s); stmt(f, s); /* XXX: need to keep track of function in case a later declaration specifies extern */ - if (!d->inlinedefn) + if (!d->u.func.inlinedefn) emitfunc(f, d->linkage == LINKEXTERN); s = delscope(s); delfunc(f); @@ -1044,5 +1044,5 @@ emittentativedefns(void) struct list *l; for (l = tentativedefns.next; l != &tentativedefns; l = l->next) - emitdata(listelement(l, struct decl, tentative), NULL); + emitdata(listelement(l, struct decl, u.obj.tentative), NULL); } @@ -906,7 +906,7 @@ postfixexpr(struct scope *s, struct expr *r) case TLPAREN: /* function call */ next(); if (r->kind == EXPRIDENT && r->u.ident.decl->kind == DECLBUILTIN) { - e = builtinfunc(s, r->u.ident.decl->builtin); + e = builtinfunc(s, r->u.ident.decl->u.builtin); expect(TRPAREN, "after builtin parameters"); break; } @@ -256,29 +256,31 @@ funcalloc(struct func *f, struct decl *d) enum instkind op; struct inst *inst; unsigned long long size; + int align; assert(!d->type->incomplete); assert(d->type->size > 0); - if (!d->align) - d->align = d->type->align; - else if (d->align < d->type->align) - error(&tok.loc, "object requires alignment %d, which is stricter than %d", d->type->align, d->align); + align = d->u.obj.align; + if (!align) + align = d->type->align; + else if (align < d->type->align) + error(&tok.loc, "object requires alignment %d, which is stricter than %d", d->type->align, align); size = d->type->size; - switch (d->align) { + switch (align) { case 1: case 2: case 4: op = IALLOC4; break; case 8: op = IALLOC8; break; - default: size += d->align - 16; /* fallthrough */ + default: size += align - 16; /* fallthrough */ case 16: op = IALLOC16; break; } inst = mkinst(f, op, ptrclass, mkintconst(size), NULL); arrayaddptr(&f->start->insts, inst); - if (d->align > 16) { + if (align > 16) { /* TODO: implement alloc32 in QBE and use that instead */ - inst = mkinst(f, IADD, ptrclass, &inst->res, mkintconst(d->align - 16)); + inst = mkinst(f, IADD, ptrclass, &inst->res, mkintconst(align - 16)); arrayaddptr(&f->start->insts, inst); - inst = mkinst(f, IAND, ptrclass, &inst->res, mkintconst(-d->align)); + inst = mkinst(f, IAND, ptrclass, &inst->res, mkintconst(-align)); arrayaddptr(&f->start->insts, inst); } d->value = &inst->res; @@ -1321,18 +1323,20 @@ emitdata(struct decl *d, struct init *init) struct type *t; unsigned long long offset = 0, start, end, bits = 0; size_t i; + int align; - if (!d->align) - d->align = d->type->align; - else if (d->align < d->type->align) - error(&tok.loc, "object requires alignment %d, which is stricter than %d", d->type->align, d->align); + align = d->u.obj.align; + if (!align) + align = d->type->align; + else if (align < d->type->align) + error(&tok.loc, "object requires alignment %d, which is stricter than %d", d->type->align, align); for (cur = init; cur; cur = cur->next) cur->expr = eval(cur->expr, EVALINIT); if (d->linkage == LINKEXTERN) fputs("export ", stdout); fputs("data ", stdout); emitvalue(d->value); - printf(" = align %d { ", d->align); + printf(" = align %d { ", align); while (init) { cur = init; @@ -14,19 +14,19 @@ scopeinit(void) char *name; struct decl decl; } builtins[] = { - {"__builtin_alloca", {.kind = DECLBUILTIN, .builtin = BUILTINALLOCA}}, - {"__builtin_constant_p", {.kind = DECLBUILTIN, .builtin = BUILTINCONSTANTP}}, - {"__builtin_expect", {.kind = DECLBUILTIN, .builtin = BUILTINEXPECT}}, - {"__builtin_inff", {.kind = DECLBUILTIN, .builtin = BUILTININFF}}, - {"__builtin_nanf", {.kind = DECLBUILTIN, .builtin = BUILTINNANF}}, - {"__builtin_offsetof", {.kind = DECLBUILTIN, .builtin = BUILTINOFFSETOF}}, + {"__builtin_alloca", {.kind = DECLBUILTIN, .u.builtin = BUILTINALLOCA}}, + {"__builtin_constant_p", {.kind = DECLBUILTIN, .u.builtin = BUILTINCONSTANTP}}, + {"__builtin_expect", {.kind = DECLBUILTIN, .u.builtin = BUILTINEXPECT}}, + {"__builtin_inff", {.kind = DECLBUILTIN, .u.builtin = BUILTININFF}}, + {"__builtin_nanf", {.kind = DECLBUILTIN, .u.builtin = BUILTINNANF}}, + {"__builtin_offsetof", {.kind = DECLBUILTIN, .u.builtin = BUILTINOFFSETOF}}, {"__builtin_types_compatible_p", - {.kind = DECLBUILTIN, .builtin = BUILTINTYPESCOMPATIBLEP}}, - {"__builtin_unreachable", {.kind = DECLBUILTIN, .builtin = BUILTINUNREACHABLE}}, - {"__builtin_va_arg", {.kind = DECLBUILTIN, .builtin = BUILTINVAARG}}, - {"__builtin_va_copy", {.kind = DECLBUILTIN, .builtin = BUILTINVACOPY}}, - {"__builtin_va_end", {.kind = DECLBUILTIN, .builtin = BUILTINVAEND}}, - {"__builtin_va_start", {.kind = DECLBUILTIN, .builtin = BUILTINVASTART}}, + {.kind = DECLBUILTIN, .u.builtin = BUILTINTYPESCOMPATIBLEP}}, + {"__builtin_unreachable", {.kind = DECLBUILTIN, .u.builtin = BUILTINUNREACHABLE}}, + {"__builtin_va_arg", {.kind = DECLBUILTIN, .u.builtin = BUILTINVAARG}}, + {"__builtin_va_copy", {.kind = DECLBUILTIN, .u.builtin = BUILTINVACOPY}}, + {"__builtin_va_end", {.kind = DECLBUILTIN, .u.builtin = BUILTINVAEND}}, + {"__builtin_va_start", {.kind = DECLBUILTIN, .u.builtin = BUILTINVASTART}}, }; static struct decl valist; struct builtin *b; |