aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-04-12 20:34:50 -0700
committerMichael Forney <mforney@mforney.org>2022-01-22 11:36:12 -0800
commit65d860fade5a39fb62b0b39081edbce199e40d58 (patch)
tree8b9f39a6aa9224efc4aae093061ddfe577a3c196
parent0bc29c89c13a61806a28f054f04a01afd8242669 (diff)
Port to C99
-rw-r--r--README.md4
-rw-r--r--cc.h24
-rwxr-xr-xconfigure2
-rw-r--r--decl.c62
-rw-r--r--driver.c1
-rw-r--r--eval.c134
-rw-r--r--expr.c121
-rw-r--r--init.c46
-rw-r--r--map.c2
-rw-r--r--qbe.c188
-rw-r--r--targ.c6
-rw-r--r--type.c43
-rw-r--r--util.h2
13 files changed, 315 insertions, 320 deletions
diff --git a/README.md b/README.md
index cb6c069..c646470 100644
--- a/README.md
+++ b/README.md
@@ -16,8 +16,8 @@ It was inspired by several other small C compilers including [8cc],
## Requirements
-The compiler itself is written in standard C11 and can be built with
-any conforming C11 compiler.
+The compiler itself is written in standard C99 and can be built with
+any conforming C99 compiler.
The POSIX driver depends on POSIX.1-2008 interfaces, and the `Makefile`
requires a POSIX-compatible make(1).
diff --git a/cc.h b/cc.h
index 35a8fb8..6f23b86 100644
--- a/cc.h
+++ b/cc.h
@@ -112,7 +112,7 @@ enum tokenkind {
TBORASSIGN,
TCOMMA,
THASH,
- THASHHASH,
+ THASHHASH
};
struct location {
@@ -136,7 +136,7 @@ enum typequal {
QUALCONST = 1<<1,
QUALRESTRICT = 1<<2,
QUALVOLATILE = 1<<3,
- QUALATOMIC = 1<<4,
+ QUALATOMIC = 1<<4
};
enum typekind {
@@ -157,7 +157,7 @@ enum typekind {
TYPEARRAY,
TYPEFUNC,
TYPESTRUCT,
- TYPEUNION,
+ TYPEUNION
};
enum typeprop {
@@ -171,7 +171,7 @@ enum typeprop {
PROPSCALAR = 1<<5,
PROPAGGR = 1<<6,
PROPDERIVED = 1<<7,
- PROPFLOAT = 1<<8,
+ PROPFLOAT = 1<<8
};
struct param {
@@ -202,10 +202,8 @@ struct type {
int align;
unsigned long long size;
struct value *value; /* used by the backend */
- union {
- struct type *base;
- struct list link; /* used only during construction of type */
- };
+ struct type *base;
+ struct list link; /* used only during construction of type */
/* qualifiers of the base type */
enum typequal qual;
_Bool incomplete, flexible;
@@ -225,7 +223,7 @@ struct type {
char *tag;
struct member *members;
} structunion;
- };
+ } u;
};
enum declkind {
@@ -313,11 +311,7 @@ enum exprkind {
struct stringlit {
size_t size;
- union {
- unsigned char *data;
- uint_least16_t *data16;
- uint_least32_t *data32;
- };
+ void *data;
};
struct expr {
@@ -369,7 +363,7 @@ struct expr {
enum builtinkind kind;
} builtin;
struct value *temp;
- };
+ } u;
};
struct init {
diff --git a/configure b/configure
index be7a95b..fe5688a 100755
--- a/configure
+++ b/configure
@@ -169,7 +169,7 @@ cat >config.mk <<EOF
PREFIX=$prefix
BINDIR=$bindir
CC=${CC:-cc}
-CFLAGS=${CFLAGS:--std=c11 -Wall -Wpedantic -Wno-parentheses -Wno-switch -g -pipe}
+CFLAGS=${CFLAGS:--std=c99 -Wall -Wpedantic -Wno-parentheses -Wno-switch -g -pipe}
LDFLAGS=$LDFLAGS
EOF
echo done
diff --git a/decl.c b/decl.c
index d81f54b..fd1745c 100644
--- a/decl.c
+++ b/decl.c
@@ -184,8 +184,8 @@ tagspec(struct scope *s)
t->prop |= PROPAGGR;
t->size = 0;
t->align = 0;
- t->structunion.tag = tag;
- t->structunion.members = NULL;
+ t->u.structunion.tag = tag;
+ t->u.structunion.members = NULL;
}
t->incomplete = true;
if (tag)
@@ -200,11 +200,11 @@ tagspec(struct scope *s)
case TYPESTRUCT:
case TYPEUNION:
b.type = t;
- b.last = &t->structunion.members;
+ b.last = &t->u.structunion.members;
b.bits = 0;
do structdecl(s, &b);
while (tok.kind != TRBRACE);
- if (!t->structunion.members)
+ if (!t->u.structunion.members)
error(&tok.loc, "struct/union has no members");
next();
t->size = ALIGNUP(t->size, t->align);
@@ -219,11 +219,11 @@ tagspec(struct scope *s)
e = constexpr(s);
if (e->kind != EXPRCONST || !(e->type->prop & PROPINT))
error(&tok.loc, "expected integer constant expression");
- i = e->constant.u;
- if (e->type->basic.issigned && i >= 1ull << 63) {
+ i = e->u.constant.u;
+ if (e->type->u.basic.issigned && i >= 1ull << 63) {
if (i < -1ull << 31)
goto invalid;
- t->basic.issigned = true;
+ t->u.basic.issigned = true;
} else if (i >= 1ull << 32) {
goto invalid;
}
@@ -237,7 +237,7 @@ tagspec(struct scope *s)
large = true;
d->type = &typeuint;
}
- if (large && t->basic.issigned)
+ if (large && t->u.basic.issigned)
error(&tok.loc, "neither 'int' nor 'unsigned' can represent all enumerator values");
scopeputdecl(s, name, d);
if (!consume(TCOMMA))
@@ -428,7 +428,7 @@ done:
if (!t && (tq || sc && *sc || fs && *fs))
error(&tok.loc, "declaration has no type specifier");
if (t && tq && t->kind == TYPEARRAY) {
- t = mkarraytype(t->base, t->qual | tq, t->array.length);
+ t = mkarraytype(t->base, t->qual | tq, t->u.array.length);
tq = QUALNONE;
}
@@ -509,12 +509,12 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
func:
t = mktype(TYPEFUNC, PROPDERIVED);
t->qual = QUALNONE;
- t->func.isprototype = false;
- t->func.isvararg = false;
- t->func.isnoreturn = false;
- t->func.params = NULL;
- t->func.nparam = 0;
- p = &t->func.params;
+ t->u.func.isprototype = false;
+ t->u.func.isvararg = false;
+ t->u.func.isnoreturn = false;
+ t->u.func.params = NULL;
+ t->u.func.nparam = 0;
+ p = &t->u.func.params;
switch (tok.kind) {
case TIDENT:
if (!istypename(s, tok.lit)) {
@@ -528,26 +528,26 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
}
/* fallthrough */
default:
- t->func.isprototype = true;
+ t->u.func.isprototype = true;
for (;;) {
*p = parameter(s);
p = &(*p)->next;
- ++t->func.nparam;
+ ++t->u.func.nparam;
if (!consume(TCOMMA))
break;
if (consume(TELLIPSIS)) {
- t->func.isvararg = true;
+ t->u.func.isvararg = true;
break;
}
}
- if (t->func.params->type->kind == TYPEVOID && !t->func.params->next)
- t->func.params = NULL;
+ if (t->u.func.params->type->kind == TYPEVOID && !t->u.func.params->next)
+ t->u.func.params = NULL;
break;
case TRPAREN:
break;
}
expect(TRPAREN, "to close function declarator");
- t->func.paraminfo = t->func.isprototype || t->func.params || tok.kind == TLBRACE;
+ t->u.func.paraminfo = t->u.func.isprototype || t->u.func.params || tok.kind == TLBRACE;
listinsert(ptr->prev, &t->link);
break;
case TLBRACK: /* array declarator */
@@ -562,11 +562,11 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs
e = eval(assignexpr(s), EVALARITH);
if (e->kind != EXPRCONST || !(e->type->prop & PROPINT))
error(&tok.loc, "VLAs are not yet supported");
- i = e->constant.u;
- if (e->type->basic.issigned && i > INT64_MAX)
+ i = e->u.constant.u;
+ if (e->type->u.basic.issigned && i > INT64_MAX)
error(&tok.loc, "array length must be non-negative");
delexpr(e);
- t->array.length = i;
+ t->u.array.length = i;
t->incomplete = false;
}
expect(TRBRACK, "after array length");
@@ -605,7 +605,7 @@ declarator(struct scope *s, struct qualtype base, char **name, bool allowabstrac
if (base.type->kind == TYPEFUNC)
error(&tok.loc, "array element has function type");
t->align = base.type->align;
- t->size = base.type->size * t->array.length; // XXX: overflow?
+ t->size = base.type->size * t->u.array.length; /* XXX: overflow? */
break;
}
base.type = t;
@@ -782,7 +782,7 @@ structdecl(struct scope *s, struct structbuilder *b)
if (!base.type)
error(&tok.loc, "no type in struct member declaration");
if (tok.kind == TSEMICOLON) {
- if ((base.type->kind != TYPESTRUCT && base.type->kind != TYPEUNION) || base.type->structunion.tag)
+ if ((base.type->kind != TYPESTRUCT && base.type->kind != TYPEUNION) || base.type->u.structunion.tag)
error(&tok.loc, "struct declaration must declare at least one member");
next();
addmember(b, base, NULL, align, -1);
@@ -973,18 +973,18 @@ decl(struct scope *s, struct func *f)
case DECLFUNC:
if (align)
error(&tok.loc, "function '%s' declared with alignment specifier", name);
- t->func.isnoreturn |= fs & FUNCNORETURN;
+ t->u.func.isnoreturn |= fs & FUNCNORETURN;
if (f && sc && sc != SCEXTERN) /* 6.7.1p7 */
error(&tok.loc, "function '%s' with block scope may only have storage class 'extern'", name);
- if (!t->func.isprototype && t->func.params) {
+ if (!t->u.func.isprototype && t->u.func.params) {
if (!allowfunc)
error(&tok.loc, "function definition not allowed");
/* collect type information for parameters before we check compatibility */
- while (paramdecl(s, t->func.params))
+ while (paramdecl(s, t->u.func.params))
;
if (tok.kind != TLBRACE)
error(&tok.loc, "function declaration with identifier list is not part of definition");
- for (p = t->func.params; p; p = p->next) {
+ for (p = t->u.func.params; p; p = p->next) {
if (!p->type)
error(&tok.loc, "old-style function definition does not declare '%s'", p->name);
}
@@ -1026,7 +1026,7 @@ struct decl *stringdecl(struct expr *expr)
if (!strings)
strings = mkmap(64);
assert(expr->kind == EXPRSTRING);
- mapkey(&key, expr->string.data, expr->string.size);
+ mapkey(&key, expr->u.string.data, expr->u.string.size);
entry = mapput(strings, &key);
d = *entry;
if (!d) {
diff --git a/driver.c b/driver.c
index 441078e..09afe0f 100644
--- a/driver.c
+++ b/driver.c
@@ -585,4 +585,5 @@ main(int argc, char *argv[])
output = "a.out";
buildexe(inputs.val, inputs.len / sizeof(*input), output);
}
+ return 0;
}
diff --git a/eval.c b/eval.c
index 871f917..de08a1f 100644
--- a/eval.c
+++ b/eval.c
@@ -14,16 +14,16 @@ cast(struct expr *expr)
size = expr->type->size;
if (expr->type->prop & PROPFLOAT)
size |= F;
- else if (expr->type->prop & PROPINT && expr->type->basic.issigned)
+ else if (expr->type->prop & PROPINT && expr->type->u.basic.issigned)
size |= S;
switch (size) {
- case 1: expr->constant.u = (uint8_t)expr->constant.u; break;
- case 1|S: expr->constant.u = (expr->constant.u & UINT8_MAX ^ INT8_MIN) - INT8_MIN; break;
- case 2: expr->constant.u = (uint16_t)expr->constant.u; break;
- case 2|S: expr->constant.u = (expr->constant.u & UINT16_MAX ^ INT16_MIN) - INT16_MIN; break;
- case 4: expr->constant.u = (uint32_t)expr->constant.u; break;
- case 4|S: expr->constant.u = (expr->constant.u & UINT32_MAX ^ INT32_MIN) - INT32_MIN; break;
- case 4|F: expr->constant.f = (float)expr->constant.f; break;
+ case 1: expr->u.constant.u = (uint8_t)expr->u.constant.u; break;
+ case 1|S: expr->u.constant.u = (expr->u.constant.u & UINT8_MAX ^ INT8_MIN) - INT8_MIN; break;
+ case 2: expr->u.constant.u = (uint16_t)expr->u.constant.u; break;
+ case 2|S: expr->u.constant.u = (expr->u.constant.u & UINT16_MAX ^ INT16_MIN) - INT16_MIN; break;
+ case 4: expr->u.constant.u = (uint32_t)expr->u.constant.u; break;
+ case 4|S: expr->u.constant.u = (expr->u.constant.u & UINT32_MAX ^ INT32_MIN) - INT32_MIN; break;
+ case 4|F: expr->u.constant.f = (float)expr->u.constant.f; break;
}
}
@@ -33,51 +33,51 @@ binary(struct expr *expr, enum tokenkind op, struct expr *l, struct expr *r)
expr->kind = EXPRCONST;
if (l->type->prop & PROPFLOAT)
op |= F;
- else if (l->type->prop & PROPINT && l->type->basic.issigned)
+ else if (l->type->prop & PROPINT && l->type->u.basic.issigned)
op |= S;
switch (op) {
case TMUL:
- case TMUL|S: expr->constant.u = l->constant.u * r->constant.u; break;
- case TMUL|F: expr->constant.f = l->constant.f * r->constant.f; break;
- case TDIV: expr->constant.u = l->constant.u / r->constant.u; break;
- case TDIV|S: expr->constant.i = l->constant.i / r->constant.i; break;
- case TDIV|F: expr->constant.f = l->constant.f / r->constant.f; break;
- case TMOD: expr->constant.u = l->constant.u % r->constant.u; break;
- case TMOD|S: expr->constant.i = l->constant.i % r->constant.i; break;
+ case TMUL|S: expr->u.constant.u = l->u.constant.u * r->u.constant.u; break;
+ case TMUL|F: expr->u.constant.f = l->u.constant.f * r->u.constant.f; break;
+ case TDIV: expr->u.constant.u = l->u.constant.u / r->u.constant.u; break;
+ case TDIV|S: expr->u.constant.i = l->u.constant.i / r->u.constant.i; break;
+ case TDIV|F: expr->u.constant.f = l->u.constant.f / r->u.constant.f; break;
+ case TMOD: expr->u.constant.u = l->u.constant.u % r->u.constant.u; break;
+ case TMOD|S: expr->u.constant.i = l->u.constant.i % r->u.constant.i; break;
case TADD:
- case TADD|S: expr->constant.u = l->constant.u + r->constant.u; break;
- case TADD|F: expr->constant.f = l->constant.f + r->constant.f; break;
+ case TADD|S: expr->u.constant.u = l->u.constant.u + r->u.constant.u; break;
+ case TADD|F: expr->u.constant.f = l->u.constant.f + r->u.constant.f; break;
case TSUB:
- case TSUB|S: expr->constant.u = l->constant.u - r->constant.u; break;
- case TSUB|F: expr->constant.f = l->constant.f - r->constant.f; break;
+ case TSUB|S: expr->u.constant.u = l->u.constant.u - r->u.constant.u; break;
+ case TSUB|F: expr->u.constant.f = l->u.constant.f - r->u.constant.f; break;
case TSHL:
- case TSHL|S: expr->constant.u = l->constant.u << (r->constant.u & 63); break;
- case TSHR: expr->constant.u = l->constant.u >> (r->constant.u & 63); break;
- case TSHR|S: expr->constant.i = l->constant.i >> (r->constant.u & 63); break;
+ case TSHL|S: expr->u.constant.u = l->u.constant.u << (r->u.constant.u & 63); break;
+ case TSHR: expr->u.constant.u = l->u.constant.u >> (r->u.constant.u & 63); break;
+ case TSHR|S: expr->u.constant.i = l->u.constant.i >> (r->u.constant.u & 63); break;
case TBAND:
- case TBAND|S: expr->constant.u = l->constant.u & r->constant.u; break;
+ case TBAND|S: expr->u.constant.u = l->u.constant.u & r->u.constant.u; break;
case TBOR:
- case TBOR|S: expr->constant.u = l->constant.u | r->constant.u; break;
+ case TBOR|S: expr->u.constant.u = l->u.constant.u | r->u.constant.u; break;
case TXOR:
- case TXOR|S: expr->constant.u = l->constant.u ^ r->constant.u; break;
- case TLESS: expr->constant.u = l->constant.u < r->constant.u; break;
- case TLESS|S: expr->constant.u = l->constant.i < r->constant.i; break;
- case TLESS|F: expr->constant.u = l->constant.f < r->constant.f; break;
- case TGREATER: expr->constant.u = l->constant.u > r->constant.u; break;
- case TGREATER|S: expr->constant.u = l->constant.i > r->constant.i; break;
- case TGREATER|F: expr->constant.u = l->constant.f > r->constant.f; break;
- case TLEQ: expr->constant.u = l->constant.u <= r->constant.u; break;
- case TLEQ|S: expr->constant.u = l->constant.i <= r->constant.i; break;
- case TLEQ|F: expr->constant.u = l->constant.f <= r->constant.f; break;
- case TGEQ: expr->constant.u = l->constant.u >= r->constant.u; break;
- case TGEQ|S: expr->constant.u = l->constant.i >= r->constant.i; break;
- case TGEQ|F: expr->constant.u = l->constant.f >= r->constant.f; break;
+ case TXOR|S: expr->u.constant.u = l->u.constant.u ^ r->u.constant.u; break;
+ case TLESS: expr->u.constant.u = l->u.constant.u < r->u.constant.u; break;
+ case TLESS|S: expr->u.constant.u = l->u.constant.i < r->u.constant.i; break;
+ case TLESS|F: expr->u.constant.u = l->u.constant.f < r->u.constant.f; break;
+ case TGREATER: expr->u.constant.u = l->u.constant.u > r->u.constant.u; break;
+ case TGREATER|S: expr->u.constant.u = l->u.constant.i > r->u.constant.i; break;
+ case TGREATER|F: expr->u.constant.u = l->u.constant.f > r->u.constant.f; break;
+ case TLEQ: expr->u.constant.u = l->u.constant.u <= r->u.constant.u; break;
+ case TLEQ|S: expr->u.constant.u = l->u.constant.i <= r->u.constant.i; break;
+ case TLEQ|F: expr->u.constant.u = l->u.constant.f <= r->u.constant.f; break;
+ case TGEQ: expr->u.constant.u = l->u.constant.u >= r->u.constant.u; break;
+ case TGEQ|S: expr->u.constant.u = l->u.constant.i >= r->u.constant.i; break;
+ case TGEQ|F: expr->u.constant.u = l->u.constant.f >= r->u.constant.f; break;
case TEQL:
- case TEQL|S: expr->constant.u = l->constant.u == r->constant.u; break;
- case TEQL|F: expr->constant.u = l->constant.f == r->constant.f; break;
+ case TEQL|S: expr->u.constant.u = l->u.constant.u == r->u.constant.u; break;
+ case TEQL|F: expr->u.constant.u = l->u.constant.f == r->u.constant.f; break;
case TNEQ:
- case TNEQ|S: expr->constant.u = l->constant.u != r->constant.u; break;
- case TNEQ|F: expr->constant.u = l->constant.f != r->constant.f; break;
+ case TNEQ|S: expr->u.constant.u = l->u.constant.u != r->u.constant.u; break;
+ case TNEQ|F: expr->u.constant.u = l->u.constant.f != r->u.constant.f; break;
default:
fatal("internal error; unknown binary expression");
}
@@ -96,19 +96,19 @@ eval(struct expr *expr, enum evalkind kind)
t = expr->type;
switch (expr->kind) {
case EXPRIDENT:
- if (expr->ident.decl->kind != DECLCONST)
+ if (expr->u.ident.decl->kind != DECLCONST)
break;
expr->kind = EXPRCONST;
- expr->constant.u = intconstvalue(expr->ident.decl->value);
+ expr->u.constant.u = intconstvalue(expr->u.ident.decl->value);
break;
case EXPRCOMPOUND:
if (kind != EVALINIT)
break;
d = mkdecl(DECLOBJECT, t, expr->qual, LINKNONE);
d->value = mkglobal(NULL, true);
- emitdata(d, expr->compound.init);
+ emitdata(d, expr->u.compound.init);
expr->kind = EXPRIDENT;
- expr->ident.decl = d;
+ expr->u.ident.decl = d;
break;
case EXPRUNARY:
l = eval(expr->base, kind);
@@ -122,7 +122,7 @@ eval(struct expr *expr, enum evalkind kind)
case EXPRSTRING:
if (kind != EVALINIT)
break;
- l->ident.decl = stringdecl(l);
+ l->u.ident.decl = stringdecl(l);
l->kind = EXPRIDENT;
expr->base = l;
break;
@@ -133,22 +133,22 @@ eval(struct expr *expr, enum evalkind kind)
if (l->kind == EXPRCONST) {
expr->kind = EXPRCONST;
if (l->type->prop & PROPINT && t->prop & PROPFLOAT) {
- if (l->type->basic.issigned)
- expr->constant.f = l->constant.i;
+ if (l->type->u.basic.issigned)
+ expr->u.constant.f = l->u.constant.i;
else
- expr->constant.f = l->constant.u;
+ expr->u.constant.f = l->u.constant.u;
} else if (l->type->prop & PROPFLOAT && t->prop & PROPINT) {
- if (t->basic.issigned) {
- if (l->constant.f < INT64_MIN || l->constant.f > INT64_MAX)
- error(&tok.loc, "integer part of floating-point constant %g cannot be represented as signed integer", l->constant.f);
- expr->constant.i = l->constant.f;
+ if (t->u.basic.issigned) {
+ if (l->u.constant.f < INT64_MIN || l->u.constant.f > INT64_MAX)
+ error(&tok.loc, "integer part of floating-point constant %g cannot be represented as signed integer", l->u.constant.f);
+ expr->u.constant.i = l->u.constant.f;
} else {
- if (l->constant.f < 0 || l->constant.f > UINT64_MAX)
- error(&tok.loc, "integer part of floating-point constant %g cannot be represented as unsigned integer", l->constant.f);
- expr->constant.u = l->constant.f;
+ if (l->u.constant.f < 0 || l->u.constant.f > UINT64_MAX)
+ error(&tok.loc, "integer part of floating-point constant %g cannot be represented as unsigned integer", l->u.constant.f);
+ expr->u.constant.u = l->u.constant.f;
}
} else {
- expr->constant = l->constant;
+ expr->u.constant = l->u.constant;
}
cast(expr);
} else if (l->type->kind == TYPEPOINTER) {
@@ -163,10 +163,10 @@ eval(struct expr *expr, enum evalkind kind)
}
break;
case EXPRBINARY:
- l = eval(expr->binary.l, kind);
- r = eval(expr->binary.r, kind);
- expr->binary.l = l;
- expr->binary.r = r;
+ l = eval(expr->u.binary.l, kind);
+ r = eval(expr->u.binary.r, kind);
+ expr->u.binary.l = l;
+ expr->u.binary.r = r;
switch (expr->op) {
case TADD:
if (r->kind == EXPRBINARY)
@@ -177,21 +177,21 @@ eval(struct expr *expr, enum evalkind kind)
break;
if (l->kind == EXPRCONST) {
binary(expr, expr->op, l, r);
- } else if (l->kind == EXPRBINARY && l->type->kind == TYPEPOINTER && l->op == TADD && l->binary.r->kind == EXPRCONST) {
+ } else if (l->kind == EXPRBINARY && l->type->kind == TYPEPOINTER && l->op == TADD && l->u.binary.r->kind == EXPRCONST) {
/* (P + C1) ± C2 -> P + (C1 ± C2) */
- binary(expr->binary.r, expr->op, l->binary.r, r);
+ binary(expr->u.binary.r, expr->op, l->u.binary.r, r);
expr->op = TADD;
- expr->binary.l = l->binary.l;
+ expr->u.binary.l = l->u.binary.l;
}
break;
case TLOR:
if (l->kind != EXPRCONST)
break;
- return l->constant.u ? l : r;
+ return l->u.constant.u ? l : r;
case TLAND:
if (l->kind != EXPRCONST)
break;
- return l->constant.u ? r : l;
+ return l->u.constant.u ? r : l;
default:
if (l->kind != EXPRCONST || r->kind != EXPRCONST)
break;
diff --git a/expr.c b/expr.c
index e969241..9437b33 100644
--- a/expr.c
+++ b/expr.c
@@ -34,8 +34,8 @@ delexpr(struct expr *e)
switch (e->kind) {
case EXPRCALL:
delexpr(e->base);
- while (sub = e->call.args) {
- e->call.args = sub->next;
+ while (sub = e->u.call.args) {
+ e->u.call.args = sub->next;
delexpr(sub);
}
break;
@@ -46,13 +46,13 @@ delexpr(struct expr *e)
delexpr(e->base);
break;
case EXPRBINARY:
- delexpr(e->binary.l);
- delexpr(e->binary.r);
+ delexpr(e->u.binary.l);
+ delexpr(e->u.binary.r);
break;
case EXPRCOND:
delexpr(e->base);
- delexpr(e->cond.t);
- delexpr(e->cond.f);
+ delexpr(e->u.cond.t);
+ delexpr(e->u.cond.f);
break;
/*
XXX: compound assignment causes some reuse of expressions,
@@ -79,7 +79,7 @@ mkconstexpr(struct type *t, uint64_t n)
struct expr *e;
e = mkexpr(EXPRCONST, t, NULL);
- e->constant.u = n;
+ e->u.constant.u = n;
return e;
}
@@ -93,7 +93,7 @@ decay(struct expr *e)
struct type *t;
enum typequal tq;
- // XXX: combine with decl.c:adjust in some way?
+ /* XXX: combine with decl.c:adjust in some way? */
t = e->type;
tq = e->qual;
switch (t->kind) {
@@ -145,6 +145,7 @@ mkunaryexpr(enum tokenkind op, struct expr *base)
}
/* other unary operators get compiled as equivalent binary ones */
fatal("internal error: unknown unary operator %d", op);
+ return NULL;
}
static unsigned
@@ -152,7 +153,7 @@ bitfieldwidth(struct expr *e)
{
if (e->kind != EXPRBITFIELD)
return -1;
- return e->type->size * 8 - e->bitfield.bits.before - e->bitfield.bits.after;
+ return e->type->size * 8 - e->u.bitfield.bits.before - e->u.bitfield.bits.after;
}
struct expr *
@@ -183,7 +184,7 @@ nullpointer(struct expr *e)
return false;
if (!(e->type->prop & PROPINT) && (e->type->kind != TYPEPOINTER || e->type->base != &typevoid))
return false;
- return e->constant.u == 0;
+ return e->u.constant.u == 0;
}
static struct expr *
@@ -311,8 +312,8 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct exp
}
e = mkexpr(EXPRBINARY, t, NULL);
e->op = op;
- e->binary.l = l;
- e->binary.r = r;
+ e->u.binary.l = l;
+ e->u.binary.r = r;
return e;
}
@@ -347,7 +348,7 @@ inttype(unsigned long long val, bool decimal, char *end)
step = i % 2 || decimal ? 2 : 1;
for (; i < LEN(limits); i += step) {
t = limits[i].type;
- if (val <= 0xffffffffffffffffu >> (8 - t->size << 3) + t->basic.issigned)
+ if (val <= 0xffffffffffffffffu >> (8 - t->size << 3) + t->u.basic.issigned)
return t;
}
error(&tok.loc, "no suitable type for constant '%s'", tok.lit);
@@ -487,22 +488,18 @@ stringconcat(struct stringlit *str, bool forceutf8)
case 1:
width = 1;
encodechar = encodechar8;
- buf = xreallocarray(NULL, len, 1);
- str->data = buf;
break;
case 2:
width = sizeof(uint_least16_t);
encodechar = encodechar16;
- buf = xreallocarray(NULL, len, width);
- str->data16 = (uint_least16_t *)buf;
break;
case 4:
width = sizeof(uint_least32_t);
encodechar = encodechar32;
- buf = xreallocarray(NULL, len, width);
- str->data32 = (uint_least32_t *)buf;
break;
}
+ buf = xreallocarray(NULL, len, width);
+ str->data = buf;
dst = buf;
arrayforeach(&parts, p) {
src = p->str;
@@ -582,15 +579,15 @@ primaryexpr(struct scope *s)
e = mkexpr(EXPRIDENT, d->type, NULL);
e->qual = d->qual;
e->lvalue = d->kind == DECLOBJECT;
- e->ident.decl = d;
+ e->u.ident.decl = d;
if (d->kind != DECLBUILTIN)
e = decay(e);
next();
break;
case TSTRINGLIT:
e = mkexpr(EXPRSTRING, NULL, NULL);
- t = stringconcat(&e->string, false);
- e->type = mkarraytype(t, QUALNONE, e->string.size);
+ t = stringconcat(&e->u.string, false);
+ e->type = mkarraytype(t, QUALNONE, e->u.string.size);
e->lvalue = true;
e = decay(e);
break;
@@ -623,7 +620,7 @@ primaryexpr(struct scope *s)
}
if (strpbrk(tok.lit, base == 16 ? ".pP" : ".eE")) {
/* floating constant */
- e->constant.f = strtod(tok.lit, &end);
+ e->u.constant.f = strtod(tok.lit, &end);
if (end == tok.lit)
error(&tok.loc, "invalid floating constant '%s'", tok.lit);
if (!end[0])
@@ -639,10 +636,10 @@ primaryexpr(struct scope *s)
if (base == 2)
src += 2;
/* integer constant */
- e->constant.u = strtoull(src, &end, base);
+ e->u.constant.u = strtoull(src, &end, base);
if (end == src)
error(&tok.loc, "invalid integer constant '%s'", tok.lit);
- e->type = inttype(e->constant.u, base == 10, end);
+ e->type = inttype(e->u.constant.u, base == 10, end);
}
next();
break;
@@ -712,7 +709,7 @@ builtinfunc(struct scope *s, enum builtinkind kind)
case BUILTINALLOCA:
e = exprconvert(assignexpr(s), &typeulong);
e = mkexpr(EXPRBUILTIN, mkpointertype(&typevoid, QUALNONE), e);
- e->builtin.kind = BUILTINALLOCA;
+ e->u.builtin.kind = BUILTINALLOCA;
break;
case BUILTINCONSTANTP:
e = mkconstexpr(&typeint, eval(condexpr(s), EVALARITH)->kind == EXPRCONST);
@@ -727,15 +724,15 @@ builtinfunc(struct scope *s, enum builtinkind kind)
case BUILTININFF:
e = mkexpr(EXPRCONST, &typefloat, NULL);
/* TODO: use INFINITY here when we can handle musl's math.h */
- e->constant.f = strtod("inf", NULL);
+ e->u.constant.f = strtod("inf", NULL);
break;
case BUILTINNANF:
e = assignexpr(s);
- if (!e->decayed || e->base->kind != EXPRSTRING || e->base->string.size > 1)
+ if (!e->decayed || e->base->kind != EXPRSTRING || e->base->u.string.size > 1)
error(&tok.loc, "__builtin_nanf currently only supports empty string literals");
e = mkexpr(EXPRCONST, &typefloat, NULL);
/* TODO: use NAN here when we can handle musl's math.h */
- e->constant.f = strtod("nan", NULL);
+ e->u.constant.f = strtod("nan", NULL);
break;
case BUILTINOFFSETOF:
t = typename(s, NULL);
@@ -758,11 +755,11 @@ builtinfunc(struct scope *s, enum builtinkind kind)
break;
case BUILTINUNREACHABLE:
e = mkexpr(EXPRBUILTIN, &typevoid, NULL);
- e->builtin.kind = BUILTINUNREACHABLE;
+ e->u.builtin.kind = BUILTINUNREACHABLE;
break;
case BUILTINVAARG:
e = mkexpr(EXPRBUILTIN, NULL, assignexpr(s));
- e->builtin.kind = BUILTINVAARG;
+ e->u.builtin.kind = BUILTINVAARG;
if (!typesame(e->base->type, typeadjvalist))
error(&tok.loc, "va_arg argument must have type va_list");
if (typeadjvalist == targ->typevalist)
@@ -772,17 +769,17 @@ builtinfunc(struct scope *s, enum builtinkind kind)
break;
case BUILTINVACOPY:
e = mkexpr(EXPRASSIGN, &typevoid, NULL);
- e->assign.l = assignexpr(s);
- if (!typesame(e->assign.l->type, typeadjvalist))
+ e->u.assign.l = assignexpr(s);
+ if (!typesame(e->u.assign.l->type, typeadjvalist))
error(&tok.loc, "va_copy destination must have type va_list");
if (typeadjvalist != targ->typevalist)
- e->assign.l = mkunaryexpr(TMUL, e->assign.l);
+ e->u.assign.l = mkunaryexpr(TMUL, e->u.assign.l);
expect(TCOMMA, "after target va_list");
- e->assign.r = assignexpr(s);
- if (!typesame(e->assign.r->type, typeadjvalist))
+ e->u.assign.r = assignexpr(s);
+ if (!typesame(e->u.assign.r->type, typeadjvalist))
error(&tok.loc, "va_copy source must have type va_list");
if (typeadjvalist != targ->typevalist)
- e->assign.r = mkunaryexpr(TMUL, e->assign.r);
+ e->u.assign.r = mkunaryexpr(TMUL, e->u.assign.r);
break;
case BUILTINVAEND:
e = assignexpr(s);
@@ -792,7 +789,7 @@ builtinfunc(struct scope *s, enum builtinkind kind)
break;
case BUILTINVASTART:
e = mkexpr(EXPRBUILTIN, &typevoid, assignexpr(s));
- e->builtin.kind = BUILTINVASTART;
+ e->u.builtin.kind = BUILTINVASTART;
if (!typesame(e->base->type, typeadjvalist))
error(&tok.loc, "va_start argument must have type va_list");
if (typeadjvalist == targ->typevalist)
@@ -802,7 +799,7 @@ builtinfunc(struct scope *s, enum builtinkind kind)
if (param->kind != EXPRIDENT)
error(&tok.loc, "expected parameter identifier");
delexpr(param);
- // XXX: check that this was actually a parameter name?
+ /* XXX: check that this was actually a parameter name? */
break;
default:
fatal("internal error; unknown builtin");
@@ -821,7 +818,7 @@ mkincdecexpr(enum tokenkind op, struct expr *base, bool post)
error(&tok.loc, "operand of '%s' operator is const qualified", tokstr[op]);
e = mkexpr(EXPRINCDEC, base->type, base);
e->op = op;
- e->incdec.post = post;
+ e->u.incdec.post = post;
return e;
}
@@ -861,8 +858,8 @@ postfixexpr(struct scope *s, struct expr *r)
break;
case TLPAREN: /* function call */
next();
- if (r->kind == EXPRIDENT && r->ident.decl->kind == DECLBUILTIN) {
- e = builtinfunc(s, r->ident.decl->builtin);
+ if (r->kind == EXPRIDENT && r->u.ident.decl->kind == DECLBUILTIN) {
+ e = builtinfunc(s, r->u.ident.decl->builtin);
expect(TRPAREN, "after builtin parameters");
break;
}
@@ -870,26 +867,26 @@ postfixexpr(struct scope *s, struct expr *r)
error(&tok.loc, "called object is not a function");
t = r->type->base;
e = mkexpr(EXPRCALL, t->base, r);
- e->call.args = NULL;
- e->call.nargs = 0;
- p = t->func.params;
- end = &e->call.args;
+ e->u.call.args = NULL;
+ e->u.call.nargs = 0;
+ p = t->u.func.params;
+ end = &e->u.call.args;
while (tok.kind != TRPAREN) {
- if (e->call.args)
+ if (e->u.call.args)
expect(TCOMMA, "or ')' after function call argument");
- if (!p && !t->func.isvararg && t->func.paraminfo)
+ if (!p && !t->u.func.isvararg && t->u.func.paraminfo)
error(&tok.loc, "too many arguments for function call");
*end = assignexpr(s);
- if (!t->func.isprototype || (t->func.isvararg && !p))
+ if (!t->u.func.isprototype || (t->u.func.isvararg && !p))
*end = exprpromote(*end);
else
*end = exprconvert(*end, p->type);
end = &(*end)->next;
- ++e->call.nargs;
+ ++e->u.call.nargs;
if (p)
p = p->next;
}
- if (p && !t->func.isvararg && t->func.paraminfo)
+ if (p && !t->u.func.isvararg && t->u.func.paraminfo)
error(&tok.loc, "not enough arguments for function call");
e = decay(e);
next();
@@ -921,7 +918,7 @@ postfixexpr(struct scope *s, struct expr *r)
if (m->bits.before || m->bits.after) {
e = mkexpr(EXPRBITFIELD, r->type, r);
e->lvalue = lvalue;
- e->bitfield.bits = m->bits;
+ e->u.bitfield.bits = m->bits;
} else {
e = r;
}
@@ -1056,13 +1053,13 @@ castexpr(struct scope *s)
e = mkexpr(EXPRCOMPOUND, t, NULL);
e->qual = tq;
e->lvalue = true;
- e->compound.init = parseinit(s, t);
+ e->u.compound.init = parseinit(s, t);
e = decay(e);
*end = postfixexpr(s, e);
return r;
}
e = mkexpr(EXPRCAST, t, NULL);
- // XXX check types 6.5.4
+ /* XXX check types 6.5.4 */
*end = e;
end = &e->base;
}
@@ -1165,10 +1162,10 @@ condexpr(struct scope *s)
}
e = eval(e, EVALARITH);
if (e->kind == EXPRCONST && e->type->prop & PROPINT)
- return exprconvert(e->constant.u ? l : r, t);
+ return exprconvert(e->u.constant.u ? l : r, t);
e = mkexpr(EXPRCOND, t, e);
- e->cond.t = l;
- e->cond.f = r;
+ e->u.cond.t = l;
+ e->u.cond.f = r;
return e;
}
@@ -1186,9 +1183,9 @@ intconstexpr(struct scope *s, bool allowneg)
e = constexpr(s);
if (e->kind != EXPRCONST || !(e->type->prop & PROPINT))
error(&tok.loc, "not an integer constant expression");
- if (!allowneg && e->type->basic.issigned && e->constant.u > INT64_MAX)
+ if (!allowneg && e->type->u.basic.issigned && e->u.constant.u > INT64_MAX)
error(&tok.loc, "integer constant expression cannot be negative");
- return e->constant.u;
+ return e->u.constant.u;
}
static struct expr *
@@ -1197,8 +1194,8 @@ mkassignexpr(struct expr *l, struct expr *r)
struct expr *e;
e = mkexpr(EXPRASSIGN, l->type, NULL);
- e->assign.l = l;
- e->assign.r = exprconvert(r, l->type);
+ e->u.assign.l = l;
+ e->u.assign.r = exprconvert(r, l->type);
return e;
}
@@ -1241,7 +1238,7 @@ assignexpr(struct scope *s)
}
tmp = mkexpr(EXPRTEMP, mkpointertype(l->type, l->qual), NULL);
tmp->lvalue = true;
- tmp->temp = NULL;
+ tmp->u.temp = NULL;
e = mkassignexpr(tmp, mkunaryexpr(TBAND, l));
l = mkunaryexpr(TMUL, tmp);
if (bit) {
diff --git a/init.c b/init.c
index 08018bc..58bd89a 100644
--- a/init.c
+++ b/init.c
@@ -12,7 +12,7 @@ struct object {
union {
struct member *mem;
size_t idx;
- };
+ } u;
bool iscur;
};
@@ -68,8 +68,8 @@ updatearray(struct type *t, unsigned long long i)
{
if (!t->incomplete)
return;
- if (++i > t->array.length) {
- t->array.length = i;
+ if (++i > t->u.array.length) {
+ t->u.array.length = i;
t->size = i * t->base->size;
}
}
@@ -90,10 +90,10 @@ findmember(struct initparser *p, char *name)
{
struct member *m;
- for (m = p->sub->type->structunion.members; m; m = m->next) {
+ for (m = p->sub->type->u.structunion.members; m; m = m->next) {
if (m->name) {
if (strcmp(m->name, name) == 0) {
- p->sub->mem = m;
+ p->sub->u.mem = m;
subobj(p, m->type, m->offset);
return true;
}
@@ -122,13 +122,13 @@ designator(struct scope *s, struct initparser *p)
if (t->kind != TYPEARRAY)
error(&tok.loc, "index designator is only valid for array types");
next();
- p->sub->idx = intconstexpr(s, false);
+ p->sub->u.idx = intconstexpr(s, false);
if (t->incomplete)
- updatearray(t, p->sub->idx);
- else if (p->sub->idx >= t->array.length)
+ updatearray(t, p->sub->u.idx);
+ else if (p->sub->u.idx >= t->u.array.length)
error(&tok.loc, "index designator is larger than array length");
expect(TRBRACK, "for index designator");
- subobj(p, t->base, p->sub->idx * t->base->size);
+ subobj(p, t->base, p->sub->u.idx * t->base->size);
break;
case TPERIOD:
if (t->kind != TYPESTRUCT && t->kind != TYPEUNION)
@@ -153,15 +153,15 @@ focus(struct initparser *p)
switch (p->sub->type->kind) {
case TYPEARRAY:
- p->sub->idx = 0;
+ p->sub->u.idx = 0;
if (p->sub->type->incomplete)
- updatearray(p->sub->type, p->sub->idx);
+ updatearray(p->sub->type, 0);
t = p->sub->type->base;
break;
case TYPESTRUCT:
case TYPEUNION:
- p->sub->mem = p->sub->type->structunion.members;
- t = p->sub->mem->type;
+ p->sub->u.mem = p->sub->type->u.structunion.members;
+ t = p->sub->u.mem->type;
break;
default:
fatal("internal error: init cursor has unexpected type");
@@ -179,18 +179,18 @@ advance(struct initparser *p)
t = p->sub->type;
switch (t->kind) {
case TYPEARRAY:
- ++p->sub->idx;
+ ++p->sub->u.idx;
if (t->incomplete)
- updatearray(t, p->sub->idx);
- if (p->sub->idx < t->array.length) {
- subobj(p, t->base, t->base->size * p->sub->idx);
+ updatearray(t, p->sub->u.idx);
+ if (p->sub->u.idx < t->u.array.length) {
+ subobj(p, t->base, t->base->size * p->sub->u.idx);
return;
}
break;
case TYPESTRUCT:
- p->sub->mem = p->sub->mem->next;
- if (p->sub->mem) {
- subobj(p, p->sub->mem->type, p->sub->mem->offset);
+ p->sub->u.mem = p->sub->u.mem->next;
+ if (p->sub->u.mem) {
+ subobj(p, p->sub->u.mem->type, p->sub->u.mem->offset);
return;
}
break;
@@ -216,7 +216,7 @@ parseinit(struct scope *s, struct type *t)
p.sub->iscur = false;
p.init = NULL;
p.last = &p.init;
- if (t->incomplete && !(t->kind == TYPEARRAY && t->array.length == 0))
+ if (t->incomplete && !(t->kind == TYPEARRAY && t->u.array.length == 0))
error(&tok.loc, "initializer specified for incomplete type");
for (;;) {
if (p.cur) {
@@ -250,7 +250,7 @@ parseinit(struct scope *s, struct type *t)
if (!(base->prop & PROPCHAR && expr->type->base->prop & PROPCHAR) && !typecompatible(base, expr->type->base))
error(&tok.loc, "cannot initialize array with string literal of different width");
if (t->incomplete)
- updatearray(t, expr->string.size - 1);
+ updatearray(t, expr->u.string.size - 1);
goto add;
case TYPESTRUCT:
case TYPEUNION:
@@ -266,7 +266,7 @@ parseinit(struct scope *s, struct type *t)
}
add:
if (p.sub > p.obj && (p.sub[-1].type->kind == TYPESTRUCT || p.sub[-1].type->kind == TYPEUNION))
- bits = p.sub[-1].mem->bits;
+ bits = p.sub[-1].u.mem->bits;
else
bits = (struct bitfield){0};
initadd(&p, mkinit(p.sub->offset, p.sub->offset + p.sub->type->size, bits, expr));
diff --git a/map.c b/map.c
index f01efc1..9464b38 100644
--- a/map.c
+++ b/map.c
@@ -15,7 +15,7 @@ static uint64_t
hash(const void *ptr, size_t len)
{
extern int siphash(const uint8_t *, const size_t, const uint8_t *, uint8_t *, const size_t);
- static const uint8_t k[16] = {0}; // XXX: we don't have a way to get entropy in standard C
+ static const uint8_t k[16] = {0}; /* XXX: we don't have a way to get entropy in standard C */
uint64_t r;
siphash(ptr, len, k, (uint8_t *)&r, sizeof(r));
diff --git a/qbe.c b/qbe.c
index 36fb0e4..f9be5a1 100644
--- a/qbe.c
+++ b/qbe.c
@@ -24,7 +24,7 @@ struct value {
char *name;
uint64_t i;
double f;
- };
+ } u;
};
struct lvalue {
@@ -116,7 +116,7 @@ mkblock(char *name)
b = xmalloc(sizeof(*b));
b->label.kind = VALUE_LABEL;
- b->label.name = name;
+ b->label.u.name = name;
b->label.id = ++id;
b->insts = (struct array){0};
b->jump.kind = JUMP_NONE;
@@ -134,7 +134,7 @@ mkglobal(char *name, bool private)
v = xmalloc(sizeof(*v));
v->kind = VALUE_GLOBAL;
- v->name = name;
+ v->u.name = name;
v->id = private ? ++id : 0;
return v;
@@ -144,7 +144,7 @@ char *
globalname(struct value *v)
{
assert(v->kind == VALUE_GLOBAL && !v->id);
- return v->name;
+ return v->u.name;
}
struct value *
@@ -154,7 +154,7 @@ mkintconst(uint64_t n)
v = xmalloc(sizeof(*v));
v->kind = VALUE_INTCONST;
- v->i = n;
+ v->u.i = n;
return v;
}
@@ -163,7 +163,7 @@ uint64_t
intconstvalue(struct value *v)
{
assert(v->kind == VALUE_INTCONST);
- return v->i;
+ return v->u.i;
}
static struct value *
@@ -173,7 +173,7 @@ mkfltconst(int kind, double n)
v = xmalloc(sizeof(*v));
v->kind = kind;
- v->f = n;
+ v->u.f = n;
return v;
}
@@ -197,8 +197,8 @@ qbetype(struct type *t)
if (!(t->prop & PROPSCALAR))
return l;
switch (t->size) {
- case 1: return t->basic.issigned ? sb : ub;
- case 2: return t->basic.issigned ? sh : uh;
+ case 1: return t->u.basic.issigned ? sb : ub;
+ case 2: return t->u.basic.issigned ? sh : uh;
case 4: return t->prop & PROPFLOAT ? s : w;
case 8: return t->prop & PROPFLOAT ? d : l;
case 16: fatal("long double is not yet supported");
@@ -215,7 +215,7 @@ static void
functemp(struct func *f, struct value *v)
{
v->kind = VALUE_TEMP;
- v->name = NULL;
+ v->u.name = NULL;
v->id = ++f->lastid;
}
@@ -301,7 +301,7 @@ funcbits(struct func *f, struct type *t, struct value *v, struct bitfield b)
}
bits += b.before;
if (bits)
- v = funcinst(f, t->basic.issigned ? ISAR : ISHR, class, v, mkintconst(bits));
+ v = funcinst(f, t->u.basic.issigned ? ISAR : ISHR, class, v, mkintconst(bits));
return v;
}
@@ -509,20 +509,20 @@ convert(struct func *f, struct type *dst, struct type *src, struct value *l)
if (dst->size <= src->size)
return l;
switch (src->size) {
- case 4: op = src->basic.issigned ? IEXTSW : IEXTUW; break;
- case 2: op = src->basic.issigned ? IEXTSH : IEXTUH; break;
- case 1: op = src->basic.issigned ? IEXTSB : IEXTUB; break;
+ case 4: op = src->u.basic.issigned ? IEXTSW : IEXTUW; break;
+ case 2: op = src->u.basic.issigned ? IEXTSH : IEXTUH; break;
+ case 1: op = src->u.basic.issigned ? IEXTSB : IEXTUB; break;
default: fatal("internal error; unknown integer conversion");
}
} else {
- if (!dst->basic.issigned)
+ if (!dst->u.basic.issigned)
return ftou(f, class, src->size == 8 ? 'd' : 's', l);
op = src->size == 8 ? IDTOSI : ISTOSI;
}
} else {
class = dst->size == 8 ? 'd' : 's';
if (src->prop & PROPINT) {
- if (!src->basic.issigned)
+ if (!src->u.basic.issigned)
return utof(f, class, src->size == 8 ? 'l' : 'w', l);
op = src->size == 8 ? ISLTOF : ISWTOF;
} else {
@@ -555,10 +555,10 @@ mkfunc(struct decl *decl, char *name, struct type *t, struct scope *s)
emittype(t->base);
/* allocate space for parameters */
- for (p = t->func.params; p; p = p->next) {
+ for (p = t->u.func.params; p; p = p->next) {
if (!p->name)
error(&tok.loc, "parameter name omitted in definition of function '%s'", name);
- pt = t->func.isprototype ? p->type : typepromote(p->type, -1);
+ pt = t->u.func.isprototype ? p->type : typepromote(p->type, -1);
emittype(pt);
p->value = xmalloc(sizeof(*p->value));
functemp(f, p->value);
@@ -687,14 +687,14 @@ funclval(struct func *f, struct expr *e)
struct decl *d;
if (e->kind == EXPRBITFIELD) {
- lval.bits = e->bitfield.bits;
+ lval.bits = e->u.bitfield.bits;
e = e->base;
}
switch (e->kind) {
case EXPRIDENT:
- d = e->ident.decl;
+ d = e->u.ident.decl;
if (d->kind != DECLOBJECT && d->kind != DECLFUNC)
- error(&tok.loc, "identifier is not an object or function"); // XXX: fix location, var name
+ error(&tok.loc, "identifier is not an object or function"); /* XXX: fix location, var name */
if (d == f->namedecl) {
fputs("data ", stdout);
emitvalue(d->value);
@@ -709,7 +709,7 @@ funclval(struct func *f, struct expr *e)
break;
case EXPRCOMPOUND:
d = mkdecl(DECLOBJECT, e->type, e->qual, LINKNONE);
- funcinit(f, d, e->compound.init);
+ funcinit(f, d, e->u.compound.init);
lval.addr = d->value;
break;
case EXPRUNARY:
@@ -739,7 +739,7 @@ funcexpr(struct func *f, struct expr *e)
switch (e->kind) {
case EXPRIDENT:
- d = e->ident.decl;
+ d = e->u.ident.decl;
switch (d->kind) {
case DECLOBJECT: return funcload(f, d->type, (struct lvalue){d->value});
case DECLCONST: return d->value;
@@ -750,9 +750,9 @@ funcexpr(struct func *f, struct expr *e)
case EXPRCONST:
t = e->type;
if (t->prop & PROPINT || t->kind == TYPEPOINTER)
- return mkintconst(e->constant.u);
+ return mkintconst(e->u.constant.u);
assert(t->prop & PROPFLOAT);
- return mkfltconst(t->size == 4 ? VALUE_FLTCONST : VALUE_DBLCONST, e->constant.f);
+ return mkfltconst(t->size == 4 ? VALUE_FLTCONST : VALUE_DBLCONST, e->u.constant.f);
case EXPRBITFIELD:
case EXPRCOMPOUND:
lval = funclval(f, e);
@@ -771,10 +771,10 @@ funcexpr(struct func *f, struct expr *e)
fatal("not a scalar");
v = funcinst(f, e->op == TINC ? IADD : ISUB, qbetype(t).base, l, r);
v = funcstore(f, e->type, e->qual, lval, v);
- return e->incdec.post ? l : v;
+ return e->u.incdec.post ? l : v;
case EXPRCALL:
- argvals = xreallocarray(NULL, e->call.nargs, sizeof(argvals[0]));
- for (arg = e->call.args, i = 0; arg; arg = arg->next, ++i) {
+ argvals = xreallocarray(NULL, e->u.call.nargs, sizeof(argvals[0]));
+ for (arg = e->u.call.args, i = 0; arg; arg = arg->next, ++i) {
emittype(arg->type);
argvals[i] = funcexpr(f, arg);
}
@@ -782,14 +782,16 @@ funcexpr(struct func *f, struct expr *e)
emittype(t);
v = funcinst(f, ICALL, qbetype(t).base, funcexpr(f, e->base), t->value);
functype = e->base->type->base;
- for (arg = e->call.args, i = 0; arg; arg = arg->next, ++i) {
- if (functype->func.isvararg && i == functype->func.nparam)
+ for (arg = e->u.call.args, i = 0; arg; arg = arg->next, ++i) {
+ if (functype->u.func.isvararg && i == functype->u.func.nparam)
funcinst(f, IVARARG, 0, NULL, NULL);
t = arg->type;
funcinst(f, IARG, qbetype(t).base, argvals[i], t->value);
}
- //if (functype->func.isnoreturn)
- // funcret(f, NULL);
+ /*
+ if (functype->func.isnoreturn)
+ funcret(f, NULL);
+ */
return v;
case EXPRUNARY:
switch (e->op) {
@@ -806,11 +808,11 @@ funcexpr(struct func *f, struct expr *e)
l = funcexpr(f, e->base);
return convert(f, e->type, e->base->type, l);
case EXPRBINARY:
- l = funcexpr(f, e->binary.l);
+ l = funcexpr(f, e->u.binary.l);
if (e->op == TLOR || e->op == TLAND) {
b[0] = mkblock("logic_right");
b[1] = mkblock("logic_join");
- t = e->binary.l->type;
+ t = e->u.binary.l->type;
if (e->op == TLOR) {
funcjnz(f, l, t, b[1], b[0]);
b[1]->phi.val[0] = mkintconst(1);
@@ -820,16 +822,16 @@ funcexpr(struct func *f, struct expr *e)
}
b[1]->phi.blk[0] = f->end;
funclabel(f, b[0]);
- r = funcexpr(f, e->binary.r);
- b[1]->phi.val[1] = convert(f, &typebool, e->binary.r->type, r);
+ r = funcexpr(f, e->u.binary.r);
+ b[1]->phi.val[1] = convert(f, &typebool, e->u.binary.r->type, r);
b[1]->phi.blk[1] = f->end;
funclabel(f, b[1]);
functemp(f, &b[1]->phi.res);
b[1]->phi.class = 'w';
return &b[1]->phi.res;
}
- r = funcexpr(f, e->binary.r);
- t = e->binary.l->type;
+ r = funcexpr(f, e->u.binary.r);
+ t = e->u.binary.l->type;
if (t->kind == TYPEPOINTER)
t = &typeulong;
switch (e->op) {
@@ -837,10 +839,10 @@ funcexpr(struct func *f, struct expr *e)
op = IMUL;
break;
case TDIV:
- op = !(t->prop & PROPINT) || t->basic.issigned ? IDIV : IUDIV;
+ op = !(t->prop & PROPINT) || t->u.basic.issigned ? IDIV : IUDIV;
break;
case TMOD:
- op = t->basic.issigned ? IREM : IUREM;
+ op = t->u.basic.issigned ? IREM : IUREM;
break;
case TADD:
op = IADD;
@@ -852,7 +854,7 @@ funcexpr(struct func *f, struct expr *e)
op = ISHL;
break;
case TSHR:
- op = t->basic.issigned ? ISAR : ISHR;
+ op = t->u.basic.issigned ? ISAR : ISHR;
break;
case TBOR:
op = IOR;
@@ -865,27 +867,27 @@ funcexpr(struct func *f, struct expr *e)
break;
case TLESS:
if (t->size <= 4)
- op = t->prop & PROPFLOAT ? ICLTS : t->basic.issigned ? ICSLTW : ICULTW;
+ op = t->prop & PROPFLOAT ? ICLTS : t->u.basic.issigned ? ICSLTW : ICULTW;
else
- op = t->prop & PROPFLOAT ? ICLTD : t->basic.issigned ? ICSLTL : ICULTL;
+ op = t->prop & PROPFLOAT ? ICLTD : t->u.basic.issigned ? ICSLTL : ICULTL;
break;
case TGREATER:
if (t->size <= 4)
- op = t->prop & PROPFLOAT ? ICGTS : t->basic.issigned ? ICSGTW : ICUGTW;
+ op = t->prop & PROPFLOAT ? ICGTS : t->u.basic.issigned ? ICSGTW : ICUGTW;
else
- op = t->prop & PROPFLOAT ? ICGTD : t->basic.issigned ? ICSGTL : ICUGTL;
+ op = t->prop & PROPFLOAT ? ICGTD : t->u.basic.issigned ? ICSGTL : ICUGTL;
break;
case TLEQ:
if (t->size <= 4)
- op = t->prop & PROPFLOAT ? ICLES : t->basic.issigned ? ICSLEW : ICULEW;
+ op = t->prop & PROPFLOAT ? ICLES : t->u.basic.issigned ? ICSLEW : ICULEW;
else
- op = t->prop & PROPFLOAT ? ICLED : t->basic.issigned ? ICSLEL : ICULEL;
+ op = t->prop & PROPFLOAT ? ICLED : t->u.basic.issigned ? ICSLEL : ICULEL;
break;
case TGEQ:
if (t->size <= 4)
- op = t->prop & PROPFLOAT ? ICGES : t->basic.issigned ? ICSGEW : ICUGEW;
+ op = t->prop & PROPFLOAT ? ICGES : t->u.basic.issigned ? ICSGEW : ICUGEW;
else
- op = t->prop & PROPFLOAT ? ICGED : t->basic.issigned ? ICSGEL : ICUGEL;
+ op = t->prop & PROPFLOAT ? ICGED : t->u.basic.issigned ? ICSGEL : ICUGEL;
break;
case TEQL:
if (t->size <= 4)
@@ -912,12 +914,12 @@ funcexpr(struct func *f, struct expr *e)
funcjnz(f, v, e->base->type, b[0], b[1]);
funclabel(f, b[0]);
- b[2]->phi.val[0] = funcexpr(f, e->cond.t);
+ b[2]->phi.val[0] = funcexpr(f, e->u.cond.t);
b[2]->phi.blk[0] = f->end;
funcjmp(f, b[2]);
funclabel(f, b[1]);
- b[2]->phi.val[1] = funcexpr(f, e->cond.f);
+ b[2]->phi.val[1] = funcexpr(f, e->u.cond.f);
b[2]->phi.blk[1] = f->end;
funclabel(f, b[2]);
@@ -927,12 +929,12 @@ funcexpr(struct func *f, struct expr *e)
b[2]->phi.class = qbetype(e->type).base;
return &b[2]->phi.res;
case EXPRASSIGN:
- r = funcexpr(f, e->assign.r);
- if (e->assign.l->kind == EXPRTEMP) {
- e->assign.l->temp = r;
+ r = funcexpr(f, e->u.assign.r);
+ if (e->u.assign.l->kind == EXPRTEMP) {
+ e->u.assign.l->u.temp = r;
} else {
- lval = funclval(f, e->assign.l);
- r = funcstore(f, e->assign.l->type, e->assign.l->qual, lval, r);
+ lval = funclval(f, e->u.assign.l);
+ r = funcstore(f, e->u.assign.l->type, e->u.assign.l->qual, lval, r);
}
return r;
case EXPRCOMMA:
@@ -940,7 +942,7 @@ funcexpr(struct func *f, struct expr *e)
funcexpr(f, e);
return funcexpr(f, e);
case EXPRBUILTIN:
- switch (e->builtin.kind) {
+ switch (e->u.builtin.kind) {
case BUILTINVASTART:
l = funcexpr(f, e->base);
funcinst(f, IVASTART, 0, l, NULL);
@@ -961,11 +963,11 @@ funcexpr(struct func *f, struct expr *e)
}
return NULL;
case EXPRTEMP:
- assert(e->temp);
- return e->temp;
- default:
- fatal("unimplemented expression %d", e->kind);
+ assert(e->u.temp);
+ return e->u.temp;
}
+ fatal("unimplemented expression %d", e->kind);
+ return NULL;
}
static void
@@ -1008,13 +1010,13 @@ funcinit(struct func *func, struct decl *d, struct init *init)
dst.bits = init->bits;
if (init->expr->kind == EXPRSTRING) {
w = init->expr->type->base->size;
- for (i = 0; i < init->expr->string.size && i * w < init->end - init->start; ++i) {
+ for (i = 0; i < init->expr->u.string.size && i * w < init->end - init->start; ++i) {
v = mkintconst(init->start + i * w);
dst.addr = funcinst(func, IADD, ptrclass, d->value, v);
switch (w) {
- case 1: v = mkintconst(init->expr->string.data[i]); break;
- case 2: v = mkintconst(init->expr->string.data16[i]); break;
- case 4: v = mkintconst(init->expr->string.data32[i]); break;
+ case 1: v = mkintconst(((unsigned char *)init->expr->u.string.data)[i]); break;
+ case 2: v = mkintconst(((uint_least16_t *)init->expr->u.string.data)[i]); break;
+ case 4: v = mkintconst(((uint_least32_t *)init->expr->u.string.data)[i]); break;
}
funcstore(func, init->expr->type->base, QUALNONE, dst, v);
}
@@ -1053,7 +1055,7 @@ casesearch(struct func *f, int class, struct value *v, struct switchcase *c, str
label[1] = mkblock("switch_lt");
label[2] = mkblock("switch_gt");
- // XXX: linear search if c->node.height < 4
+ /* XXX: linear search if c->node.height < 4 */
key = mkintconst(c->node.key);
res = funcinst(f, class == 'w' ? ICEQW : ICEQL, 'w', v, key);
funcjnz(f, res, NULL, c->body, label[0]);
@@ -1086,13 +1088,13 @@ emitvalue(struct value *v)
switch (v->kind) {
case VALUE_INTCONST:
- printf("%" PRIu64, v->i);
+ printf("%" PRIu64, v->u.i);
break;
case VALUE_FLTCONST:
- printf("s_%.17g", v->f);
+ printf("s_%.17g", v->u.f);
break;
case VALUE_DBLCONST:
- printf("d_%.17g", v->f);
+ printf("d_%.17g", v->u.f);
break;
default:
if (v->kind >= LEN(sigil) || !sigil[v->kind])
@@ -1100,8 +1102,8 @@ emitvalue(struct value *v)
putchar(sigil[v->kind]);
if (v->kind == VALUE_GLOBAL && v->id)
fputs(".L", stdout);
- if (v->name)
- fputs(v->name, stdout);
+ if (v->u.name)
+ fputs(v->u.name, stdout);
if (v->id)
printf(".%u", v->id);
}
@@ -1131,9 +1133,9 @@ emittype(struct type *t)
return;
t->value = xmalloc(sizeof(*t->value));
t->value->kind = VALUE_TYPE;
- t->value->name = t->structunion.tag;
+ t->value->u.name = t->u.structunion.tag;
t->value->id = ++id;
- for (m = t->structunion.members; m; m = m->next) {
+ for (m = t->u.structunion.members; m; m = m->next) {
for (sub = m->type; sub->kind == TYPEARRAY; sub = sub->base)
;
emittype(sub);
@@ -1145,7 +1147,7 @@ emittype(struct type *t)
return;
}
fputs(" = { ", stdout);
- for (m = t->structunion.members, off = 0; m;) {
+ for (m = t->u.structunion.members, off = 0; m;) {
if (t->kind == TYPESTRUCT) {
/* look for a subsequent member with a larger storage unit */
for (other = m->next; other; other = other->next) {
@@ -1159,7 +1161,7 @@ emittype(struct type *t)
fputs("{ ", stdout);
}
for (i = 1, sub = m->type; sub->kind == TYPEARRAY; sub = sub->base)
- i *= sub->array.length;
+ i *= sub->u.array.length;
emitclass(qbetype(sub).data, sub->value);
if (i > 1)
printf(" %" PRIu64, i);
@@ -1273,14 +1275,14 @@ emitfunc(struct func *f, bool global)
}
emitvalue(f->decl->value);
putchar('(');
- for (p = f->type->func.params; p; p = p->next) {
- if (p != f->type->func.params)
+ for (p = f->type->u.func.params; p; p = p->next) {
+ if (p != f->type->u.func.params)
fputs(", ", stdout);
emitclass(qbetype(p->type).base, p->type->value);
putchar(' ');
emitvalue(p->value);
}
- if (f->type->func.isvararg)
+ if (f->type->u.func.isvararg)
fputs(", ...", stdout);
puts(") {");
for (b = f->start; b; b = b->next) {
@@ -1321,30 +1323,30 @@ dataitem(struct expr *expr, uint64_t size)
expr = expr->base;
if (expr->kind != EXPRIDENT)
error(&tok.loc, "initializer is not a constant expression");
- decl = expr->ident.decl;
+ decl = expr->u.ident.decl;
if (decl->value->kind != VALUE_GLOBAL)
fatal("not a global");
emitvalue(decl->value);
break;
case EXPRBINARY:
- if (expr->op != TADD || expr->binary.l->kind != EXPRUNARY || expr->binary.r->kind != EXPRCONST)
+ if (expr->op != TADD || expr->u.binary.l->kind != EXPRUNARY || expr->u.binary.r->kind != EXPRCONST)
error(&tok.loc, "initializer is not a constant expression");
- dataitem(expr->binary.l, 0);
+ dataitem(expr->u.binary.l, 0);
fputs(" + ", stdout);
- dataitem(expr->binary.r, 0);
+ dataitem(expr->u.binary.r, 0);
break;
case EXPRCONST:
if (expr->type->prop & PROPFLOAT)
- printf("%c_%.17g", expr->type->size == 4 ? 's' : 'd', expr->constant.f);
+ printf("%c_%.17g", expr->type->size == 4 ? 's' : 'd', expr->u.constant.f);
else
- printf("%" PRIu64, expr->constant.u);
+ printf("%" PRIu64, expr->u.constant.u);
break;
case EXPRSTRING:
w = expr->type->base->size;
if (w == 1) {
fputc('"', stdout);
- for (i = 0; i < expr->string.size && i < size; ++i) {
- c = expr->string.data[i];
+ for (i = 0; i < expr->u.string.size && i < size; ++i) {
+ c = ((unsigned char *)expr->u.string.data)[i];
if (isprint(c) && c != '"' && c != '\\')
putchar(c);
else
@@ -1352,10 +1354,10 @@ dataitem(struct expr *expr, uint64_t size)
}
fputc('"', stdout);
} else {
- for (i = 0; i < expr->string.size && i * w < size; ++i) {
+ for (i = 0; i < expr->u.string.size && i * w < size; ++i) {
switch (w) {
- case 2: printf("%hu ", expr->string.data16[i]); break;
- case 4: printf("%u ", expr->string.data32[i]); break;
+ case 2: printf("%" PRIuLEAST16 " ", ((uint_least16_t *)expr->u.string.data)[i]); break;
+ case 4: printf("%" PRIuLEAST32 " ", ((uint_least32_t *)expr->u.string.data)[i]); break;
default: assert(0);
}
}
@@ -1400,9 +1402,9 @@ emitdata(struct decl *d, struct init *init)
assert(init->expr->kind == EXPRCONST);
i = (init->start - cur->start) / cur->expr->type->base->size;
switch (cur->expr->type->base->size) {
- case 1: cur->expr->string.data[i] = init->expr->constant.u; break;
- case 2: cur->expr->string.data16[i] = init->expr->constant.u; break;
- case 4: cur->expr->string.data32[i] = init->expr->constant.u; break;
+ case 1: ((unsigned char *)cur->expr->u.string.data)[i] = init->expr->u.constant.u; break;
+ case 2: ((uint_least16_t *)cur->expr->u.string.data)[i] = init->expr->u.constant.u; break;
+ case 4: ((uint_least32_t *)cur->expr->u.string.data)[i] = init->expr->u.constant.u; break;
}
}
start = cur->start + cur->bits.before / 8;
@@ -1418,7 +1420,7 @@ emitdata(struct decl *d, struct init *init)
/* XXX: little-endian specific */
assert(cur->expr->type->prop & PROPINT);
assert(cur->expr->kind == EXPRCONST);
- bits |= cur->expr->constant.u << cur->bits.before % 8;
+ bits |= cur->expr->u.constant.u << cur->bits.before % 8;
for (offset = start; offset < end; ++offset, bits >>= 8)
printf("b %u, ", (unsigned)bits & 0xff);
/*
diff --git a/targ.c b/targ.c
index 6e89c51..7e43555 100644
--- a/targ.c
+++ b/targ.c
@@ -12,7 +12,7 @@ static const struct target alltargs[] = {
.typevalist = &(struct type){
.kind = TYPEARRAY, .prop = PROPOBJECT|PROPDERIVED|PROPAGGR,
.align = 8, .size = 24,
- .array = {1}, .base = &(struct type){
+ .u.array = {1}, .base = &(struct type){
.kind = TYPESTRUCT, .prop = PROPOBJECT|PROPAGGR,
.align = 8, .size = 24,
},
@@ -24,7 +24,7 @@ static const struct target alltargs[] = {
.typevalist = &(struct type){
.kind = TYPESTRUCT, .prop = PROPOBJECT|PROPAGGR,
.align = 8, .size = 32,
- .structunion.tag = "va_list",
+ .u.structunion.tag = "va_list",
},
.typewchar = &typeuint,
},
@@ -54,6 +54,6 @@ targinit(const char *name)
}
if (!targ)
fatal("unknown target '%s'", name);
- typechar.basic.issigned = targ->signedchar;
+ typechar.u.basic.issigned = targ->signedchar;
typeadjvalist = typeadjust(targ->typevalist);
}
diff --git a/type.c b/type.c
index 82a2da6..b3453b9 100644
--- a/type.c
+++ b/type.c
@@ -7,7 +7,7 @@
#include "cc.h"
#define INTTYPE(k, n, s, p) { \
- .kind = k, .size = n, .align = n, .basic.issigned = s, \
+ .kind = k, .size = n, .align = n, .u.basic.issigned = s, \
.prop = PROPOBJECT|PROPSCALAR|PROPARITH|PROPREAL|PROPINT|p, \
}
#define FLTTYPE(k, n) { \
@@ -78,11 +78,11 @@ mkarraytype(struct type *base, enum typequal qual, unsigned long long len)
t = mktype(TYPEARRAY, PROPOBJECT|PROPDERIVED|PROPAGGR);
t->base = base;
t->qual = qual;
- t->array.length = len;
+ t->u.array.length = len;
t->incomplete = !len;
if (t->base) {
t->align = t->base->align;
- t->size = t->base->size * len; // XXX: overflow?
+ t->size = t->base->size * len; /* XXX: overflow? */
}
return t;
@@ -100,9 +100,9 @@ typerank(struct type *t)
case TYPEINT: return 4;
case TYPELONG: return 5;
case TYPELLONG: return 6;
- default:
- fatal("internal error; unhandled integer type");
}
+ fatal("internal error; unhandled integer type");
+ return 0;
}
bool
@@ -118,32 +118,32 @@ typecompatible(struct type *t1, struct type *t2)
each other (unless they are the same type) */
return (t1->kind == TYPEENUM && t2->kind == TYPEINT ||
t1->kind == TYPEINT && t2->kind == TYPEENUM) &&
- t1->basic.issigned == t2->basic.issigned;
+ t1->u.basic.issigned == t2->u.basic.issigned;
}
switch (t1->kind) {
case TYPEPOINTER:
goto derived;
case TYPEARRAY:
- if (t1->array.length && t2->array.length && t1->array.length != t2->array.length)
+ if (t1->u.array.length && t2->u.array.length && t1->u.array.length != t2->u.array.length)
return false;
goto derived;
case TYPEFUNC:
- if (!t1->func.isprototype) {
- if (!t2->func.isprototype)
+ if (!t1->u.func.isprototype) {
+ if (!t2->u.func.isprototype)
return true;
tmp = t1, t1 = t2, t2 = tmp;
}
- if (t1->func.isvararg != t2->func.isvararg)
+ if (t1->u.func.isvararg != t2->u.func.isvararg)
return false;
- if (!t2->func.paraminfo) {
- for (p1 = t1->func.params; p1; p1 = p1->next) {
+ if (!t2->u.func.paraminfo) {
+ for (p1 = t1->u.func.params; p1; p1 = p1->next) {
if (!typecompatible(p1->type, typepromote(p1->type, -1)))
return false;
}
return true;
}
- for (p1 = t1->func.params, p2 = t2->func.params; p1 && p2; p1 = p1->next, p2 = p2->next) {
- tmp = t2->func.isprototype ? p2->type : typepromote(p2->type, -1);
+ for (p1 = t1->u.func.params, p2 = t2->u.func.params; p1 && p2; p1 = p1->next, p2 = p2->next) {
+ tmp = t2->u.func.isprototype ? p2->type : typepromote(p2->type, -1);
if (!typecompatible(p1->type, tmp))
return false;
}
@@ -159,15 +159,15 @@ typecompatible(struct type *t1, struct type *t2)
bool
typesame(struct type *t1, struct type *t2)
{
- // XXX: implement
+ /* XXX: implement */
return typecompatible(t1, t2);
}
struct type *
typecomposite(struct type *t1, struct type *t2)
{
- // XXX: implement 6.2.7
- // XXX: merge with typecompatible?
+ /* XXX: implement 6.2.7 */
+ /* XXX: merge with typecompatible? */
return t1;
}
@@ -179,7 +179,7 @@ typepromote(struct type *t, unsigned width)
if (t->prop & PROPINT && (typerank(t) <= typerank(&typeint) || width <= typeint.size * 8)) {
if (width == -1)
width = t->size * 8;
- return width - t->basic.issigned < typeint.size * 8 ? &typeint : &typeuint;
+ return width - t->u.basic.issigned < typeint.size * 8 ? &typeint : &typeuint;
}
return t;
}
@@ -200,9 +200,9 @@ typecommonreal(struct type *t1, unsigned w1, struct type *t2, unsigned w2)
t2 = typepromote(t2, w2);
if (t1 == t2)
return t1;
- if (t1->basic.issigned == t2->basic.issigned)
+ if (t1->u.basic.issigned == t2->u.basic.issigned)
return typerank(t1) > typerank(t2) ? t1 : t2;
- if (t1->basic.issigned) {
+ if (t1->u.basic.issigned) {
tmp = t1;
t1 = t2;
t2 = tmp;
@@ -216,6 +216,7 @@ typecommonreal(struct type *t1, unsigned w1, struct type *t2, unsigned w2)
if (t2 == &typellong)
return &typeullong;
fatal("internal error; could not find common real type");
+ return NULL;
}
/* function parameter type adjustment (C11 6.7.6.3p7) */
@@ -240,7 +241,7 @@ typemember(struct type *t, const char *name, unsigned long long *offset)
struct member *m, *sub;
assert(t->kind == TYPESTRUCT || t->kind == TYPEUNION);
- for (m = t->structunion.members; m; m = m->next) {
+ for (m = t->u.structunion.members; m; m = m->next) {
if (m->name) {
if (strcmp(m->name, name) == 0) {
*offset += m->offset;
diff --git a/util.h b/util.h
index 3a06874..a3f0baa 100644
--- a/util.h
+++ b/util.h
@@ -27,7 +27,7 @@ extern char *argv0;
#define ALIGNUP(x, n) ALIGNDOWN((x) + (n) - 1, n)
void warn(const char *, ...);
-_Noreturn void fatal(const char *fmt, ...);
+void fatal(const char *fmt, ...);
void *reallocarray(void *, size_t, size_t);
void *xreallocarray(void *, size_t, size_t);