aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2022-11-26 23:14:24 -0800
committerMichael Forney <mforney@mforney.org>2022-11-26 23:14:49 -0800
commit3809a018648d2e5597af5eb941e1d003e7ed01cd (patch)
tree722dbd8fe38a1527e23c6e45ac8c7a82b550d9bb
parent527fdf60a483475ccd6131c7e736d788cd2704cf (diff)
Move kind-specific decl fields to union
-rw-r--r--cc.h22
-rw-r--r--decl.c18
-rw-r--r--expr.c2
-rw-r--r--qbe.c32
-rw-r--r--scope.c24
5 files changed, 53 insertions, 45 deletions
diff --git a/cc.h b/cc.h
index 263b209..6f2a193 100644
--- a/cc.h
+++ b/cc.h
@@ -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 {
diff --git a/decl.c b/decl.c
index 809cf25..4a0d319 100644
--- a/decl.c
+++ b/decl.c
@@ -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);
}
diff --git a/expr.c b/expr.c
index 955b73f..1fe280c 100644
--- a/expr.c
+++ b/expr.c
@@ -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;
}
diff --git a/qbe.c b/qbe.c
index 3bcd0ae..04cce00 100644
--- a/qbe.c
+++ b/qbe.c
@@ -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;
diff --git a/scope.c b/scope.c
index 299d379..ab6e293 100644
--- a/scope.c
+++ b/scope.c
@@ -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;