aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc.h7
-rw-r--r--expr.c42
-rw-r--r--init.c2
3 files changed, 23 insertions, 28 deletions
diff --git a/cc.h b/cc.h
index 13e6a62..511ad41 100644
--- a/cc.h
+++ b/cc.h
@@ -294,14 +294,9 @@ enum exprkind {
EXPRTEMP,
};
-enum exprflags {
- EXPRFLAG_LVAL = 1<<0,
- EXPRFLAG_DECAYED = 1<<1,
-};
-
struct expr {
enum exprkind kind;
- enum exprflags flags;
+ _Bool lvalue, decayed;
struct type *type;
struct expr *next;
union {
diff --git a/expr.c b/expr.c
index f0746aa..8c354d3 100644
--- a/expr.c
+++ b/expr.c
@@ -11,13 +11,14 @@
#include "cc.h"
static struct expr *
-mkexpr(enum exprkind k, struct type *t, enum exprflags flags)
+mkexpr(enum exprkind k, struct type *t, bool lvalue)
{
struct expr *e;
e = xmalloc(sizeof(*e));
- e->type = flags & EXPRFLAG_LVAL || !t ? t : typeunqual(t, NULL);
- e->flags = flags;
+ e->type = lvalue || !t ? t : typeunqual(t, NULL);
+ e->lvalue = lvalue;
+ e->decayed = false;
e->kind = k;
e->next = NULL;
@@ -56,11 +57,11 @@ decay(struct expr *e)
case TYPEARRAY:
e = mkunaryexpr(TBAND, e);
e->type = mkqualifiedtype(mkpointertype(t->base), tq);
- e->flags |= EXPRFLAG_DECAYED;
+ e->decayed = true;
break;
case TYPEFUNC:
e = mkunaryexpr(TBAND, e);
- e->flags |= EXPRFLAG_DECAYED;
+ e->decayed = true;
break;
}
@@ -71,7 +72,7 @@ static void
lvalueconvert(struct expr *e)
{
e->type = typeunqual(e->type, NULL);
- e->flags &= ~EXPRFLAG_LVAL;
+ e->lvalue = false;
}
static struct expr *
@@ -81,8 +82,8 @@ mkunaryexpr(enum tokenkind op, struct expr *base)
switch (op) {
case TBAND:
- if (base->flags & EXPRFLAG_DECAYED) {
- base->flags &= ~EXPRFLAG_DECAYED;
+ if (base->decayed) {
+ base->decayed = false;
return base;
}
expr = mkexpr(EXPRUNARY, mkpointertype(base->type), 0);
@@ -93,7 +94,7 @@ mkunaryexpr(enum tokenkind op, struct expr *base)
lvalueconvert(base);
if (base->type->kind != TYPEPOINTER)
error(&tok.loc, "cannot dereference non-pointer");
- expr = mkexpr(EXPRUNARY, base->type->base, EXPRFLAG_LVAL);
+ expr = mkexpr(EXPRUNARY, base->type->base, true);
expr->unary.op = op;
expr->unary.base = base;
return decay(expr);
@@ -316,14 +317,14 @@ primaryexpr(struct scope *s)
d = scopegetdecl(s, tok.lit, 1);
if (!d)
error(&tok.loc, "undeclared identifier: %s", tok.lit);
- e = mkexpr(EXPRIDENT, d->type, d->kind == DECLOBJECT ? EXPRFLAG_LVAL : 0);
+ e = mkexpr(EXPRIDENT, d->type, d->kind == DECLOBJECT);
e->ident.decl = d;
if (d->kind != DECLBUILTIN)
e = decay(e);
next();
break;
case TSTRINGLIT:
- e = mkexpr(EXPRSTRING, mkarraytype(&typechar, 0), EXPRFLAG_LVAL);
+ e = mkexpr(EXPRSTRING, mkarraytype(&typechar, 0), true);
e->string.size = 0;
e->string.data = NULL;
do {
@@ -418,7 +419,7 @@ builtinfunc(struct scope *s, enum builtinkind kind)
break;
case BUILTINNANF:
e = assignexpr(s);
- if (!(e->flags & EXPRFLAG_DECAYED) || e->unary.base->kind != EXPRSTRING || e->unary.base->string.size > 0)
+ if (!e->decayed || e->unary.base->kind != EXPRSTRING || e->unary.base->string.size > 0)
error(&tok.loc, "__builtin_nanf currently only supports empty string literals");
e = mkexpr(EXPRCONST, &typefloat, 0);
/* TODO: use NAN here when we can handle musl's math.h */
@@ -560,7 +561,7 @@ postfixexpr(struct scope *s, struct expr *r)
next();
if (tok.kind != TIDENT)
error(&tok.loc, "expected identifier after '->' operator");
- lvalue = op == TARROW || r->unary.base->flags & EXPRFLAG_LVAL;
+ lvalue = op == TARROW || r->unary.base->lvalue;
r = exprconvert(r, mkpointertype(&typechar));
offset = 0;
m = typemember(t, tok.lit, &offset);
@@ -571,8 +572,7 @@ postfixexpr(struct scope *s, struct expr *r)
r = mkbinaryexpr(&tok.loc, TADD, r, mkconstexpr(&typeulong, offset));
r = exprconvert(r, mkpointertype(mkqualifiedtype(m->type, tq)));
e = mkunaryexpr(TMUL, r);
- if (!lvalue)
- e->flags &= ~EXPRFLAG_LVAL;
+ e->lvalue = lvalue;
next();
break;
case TINC:
@@ -605,7 +605,7 @@ unaryexpr(struct scope *s)
case TDEC:
next();
l = unaryexpr(s);
- if (!(l->flags & EXPRFLAG_LVAL))
+ if (!l->lvalue)
error(&tok.loc, "operand of %srement operator must be an lvalue", op == TINC ? "inc" : "dec");
/*
if (l->qualifiers & QUALCONST)
@@ -663,13 +663,13 @@ unaryexpr(struct scope *s)
expect(TRPAREN, "after expression");
if (op == TSIZEOF)
e = postfixexpr(s, e);
- if (e->flags & EXPRFLAG_DECAYED)
+ if (e->decayed)
e = e->unary.base;
t = e->type;
}
} else if (op == TSIZEOF) {
e = unaryexpr(s);
- if (e->flags & EXPRFLAG_DECAYED)
+ if (e->decayed)
e = e->unary.base;
t = e->type;
} else {
@@ -701,7 +701,7 @@ castexpr(struct scope *s)
}
expect(TRPAREN, "after type name");
if (tok.kind == TLBRACE) {
- e = mkexpr(EXPRCOMPOUND, t, EXPRFLAG_LVAL);
+ e = mkexpr(EXPRCOMPOUND, t, true);
e->compound.init = parseinit(s, t);
e = decay(e);
*end = postfixexpr(s, e);
@@ -864,14 +864,14 @@ assignexpr(struct scope *s)
default:
return l;
}
- if (!(l->flags & EXPRFLAG_LVAL))
+ if (!l->lvalue)
error(&tok.loc, "left side of assignment expression is not an lvalue");
next();
r = assignexpr(s);
lvalueconvert(r);
if (op) {
/* rewrite `E1 OP= E2` as `T = &E1, *T = *T OP E2`, where T is a temporary slot */
- tmp = mkexpr(EXPRTEMP, mkpointertype(l->type), EXPRFLAG_LVAL);
+ tmp = mkexpr(EXPRTEMP, mkpointertype(l->type), true);
tmp->temp = NULL;
e = mkexpr(EXPRCOMMA, l->type, 0);
e->comma.exprs = mkexpr(EXPRASSIGN, tmp->type, 0);
diff --git a/init.c b/init.c
index 44acd8f..794b5a4 100644
--- a/init.c
+++ b/init.c
@@ -236,7 +236,7 @@ parseinit(struct scope *s, struct type *t)
t = p.sub->type;
switch (t->kind) {
case TYPEARRAY:
- if (expr->flags & EXPRFLAG_DECAYED && expr->unary.base->kind == EXPRSTRING) {
+ if (expr->decayed && expr->unary.base->kind == EXPRSTRING) {
expr = expr->unary.base;
base = typeunqual(t->base, NULL);
/* XXX: wide string literals */