diff options
-rw-r--r-- | cc.h | 3 | ||||
-rw-r--r-- | decl.c | 28 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | expr.c | 1 | ||||
-rw-r--r-- | qbe.c | 8 |
5 files changed, 24 insertions, 18 deletions
@@ -252,6 +252,7 @@ struct decl { enum declkind kind; enum linkage linkage; struct type *type; + enum typequal qual; struct value *value; /* objects and functions */ @@ -416,7 +417,7 @@ extern struct type typevalist, typevalistptr; /* decl */ -struct decl *mkdecl(enum declkind, struct type *, enum linkage); +struct decl *mkdecl(enum declkind, struct type *, enum typequal, enum linkage); _Bool decl(struct scope *, struct func *); struct type *typename(struct scope *); @@ -56,14 +56,16 @@ struct structbuilder { }; struct decl * -mkdecl(enum declkind k, struct type *t, enum linkage linkage) +mkdecl(enum declkind k, struct type *t, enum typequal tq, enum linkage linkage) { struct decl *d; + assert(t->kind != TYPEQUALIFIED); d = xmalloc(sizeof(*d)); d->kind = k; d->linkage = linkage; d->type = t; + d->qual = tq; d->tentative = false; d->defined = false; d->align = 0; @@ -208,7 +210,7 @@ tagspec(struct scope *s) break; case TYPEBASIC: /* enum */ for (i = 0; tok.kind == TIDENT; ++i) { - d = mkdecl(DECLCONST, &typeint, LINKNONE); + d = mkdecl(DECLCONST, &typeint, QUALNONE, LINKNONE); scopeputdecl(s, tok.lit, d); next(); if (consume(TASSIGN)) @@ -741,6 +743,7 @@ bool decl(struct scope *s, struct func *f) { struct type *t, *base; + enum typequal tq; enum storageclass sc; enum funcspec fs; struct init *init; @@ -779,7 +782,8 @@ decl(struct scope *s, struct func *f) return true; } for (;;) { - t = declarator(s, base, &name, false); + tq = QUALNONE; + t = typeunqual(declarator(s, base, &name, false), &tq); kind = sc & SCTYPEDEF ? DECLTYPE : t->kind == TYPEFUNC ? DECLFUNC : DECLOBJECT; d = scopegetdecl(s, name, false); if (d && d->kind != kind) @@ -789,8 +793,8 @@ decl(struct scope *s, struct func *f) if (align) error(&tok.loc, "typedef '%s' declared with alignment specifier", name); if (!d) - scopeputdecl(s, name, mkdecl(DECLTYPE, t, LINKNONE)); - else if (!typesame(d->type, t)) + scopeputdecl(s, name, mkdecl(DECLTYPE, t, tq, LINKNONE)); + else if (!typesame(d->type, t) || d->qual != tq) error(&tok.loc, "typedef '%s' redefined with different type", name); break; case DECLOBJECT: @@ -802,7 +806,7 @@ decl(struct scope *s, struct func *f) if (d->linkage != linkage) error(&tok.loc, "object '%s' redeclared with different linkage", name); } - if (!typecompatible(d->type, t)) + if (!typecompatible(d->type, t) || d->qual != tq) error(&tok.loc, "object '%s' redeclared with incompatible type", name); d->type = typecomposite(t, d->type); } else { @@ -814,7 +818,7 @@ decl(struct scope *s, struct func *f) if (d) { if (d->linkage != linkage) error(&tok.loc, "object '%s' redeclared with different linkage", name); - if (!typecompatible(d->type, t)) + if (!typecompatible(d->type, t) || d->qual != tq) error(&tok.loc, "object '%s' redeclared with incompatible type", name); t = typecomposite(t, d->type); } @@ -822,7 +826,7 @@ decl(struct scope *s, struct func *f) linkage = f ? LINKNONE : sc & SCSTATIC ? LINKINTERN : LINKEXTERN; } - d = mkdecl(kind, t, linkage); + d = mkdecl(kind, t, tq, linkage); scopeputdecl(s, name, d); if (linkage != LINKNONE || sc & SCSTATIC) d->value = mkglobal(name, linkage == LINKNONE); @@ -875,7 +879,7 @@ decl(struct scope *s, struct func *f) } } if (d) { - if (!typecompatible(t, d->type)) + if (!typecompatible(t, d->type) || tq != d->qual) error(&tok.loc, "function '%s' redeclared with incompatible type", name); d->type = typecomposite(t, d->type); } else { @@ -883,13 +887,13 @@ decl(struct scope *s, struct func *f) d = scopegetdecl(s->parent, name, 1); if (d && d->linkage != LINKNONE) { linkage = d->linkage; - if (!typecompatible(t, d->type)) + if (!typecompatible(t, d->type) || tq != d->qual) error(&tok.loc, "function '%s' redeclared with incompatible type", name); t = typecomposite(t, d->type); } else { linkage = sc & SCSTATIC ? LINKINTERN : LINKEXTERN; } - d = mkdecl(kind, t, linkage); + d = mkdecl(kind, t, tq, linkage); d->value = mkglobal(name, false); scopeputdecl(s, name, d); } @@ -936,7 +940,7 @@ struct decl *stringdecl(struct expr *expr) entry = htabput(strings, &key); d = *entry; if (!d) { - d = mkdecl(DECLOBJECT, expr->type, LINKNONE); + d = mkdecl(DECLOBJECT, expr->type, QUALNONE, LINKNONE); d->value = mkglobal("string", true); emitdata(d, mkinit(0, expr->type->size, expr)); *entry = d; @@ -78,7 +78,7 @@ eval(struct expr *expr) expr->constant.i = intconstvalue(expr->ident.decl->value); break; case EXPRCOMPOUND: - d = mkdecl(DECLOBJECT, mkqualifiedtype(expr->type, expr->qual), LINKNONE); + d = mkdecl(DECLOBJECT, expr->type, expr->qual, LINKNONE); d->value = mkglobal(NULL, true); emitdata(d, expr->compound.init); expr->kind = EXPRIDENT; @@ -312,6 +312,7 @@ primaryexpr(struct scope *s) if (!d) error(&tok.loc, "undeclared identifier: %s", tok.lit); e = mkexpr(EXPRIDENT, d->type); + e->qual = d->qual; e->lvalue = d->kind == DECLOBJECT; e->ident.decl = d; if (d->kind != DECLBUILTIN) @@ -364,7 +364,7 @@ mkfunc(char *name, struct type *t, struct scope *s) if (!t->func.isprototype && !typecompatible(p->type, typeargpromote(p->type))) error(&tok.loc, "old-style function definition with parameter type incompatible with promoted type is not yet supported"); emittype(p->type); - d = mkdecl(DECLOBJECT, mkqualifiedtype(p->type, p->qual), LINKNONE); + d = mkdecl(DECLOBJECT, p->type, p->qual, LINKNONE); p->value = xmalloc(sizeof(*p->value)); functemp(f, p->value, p->type->repr); if (p->type->repr->abi.id) { @@ -379,7 +379,7 @@ mkfunc(char *name, struct type *t, struct scope *s) } t = mkarraytype(mkqualifiedtype(&typechar, QUALCONST), strlen(name) + 1); - d = mkdecl(DECLOBJECT, t, LINKNONE); + d = mkdecl(DECLOBJECT, t, QUALNONE, LINKNONE); d->value = mkglobal("__func__", true); scopeputdecl(s, "__func__", d); /* @@ -469,7 +469,7 @@ objectaddr(struct func *f, struct expr *e) d = stringdecl(e); return d->value; case EXPRCOMPOUND: - d = mkdecl(DECLOBJECT, mkqualifiedtype(e->type, e->qual), LINKNONE); + d = mkdecl(DECLOBJECT, e->type, e->qual, LINKNONE); funcinit(f, d, e->compound.init); return d->value; case EXPRUNARY: @@ -578,7 +578,7 @@ funcexpr(struct func *f, struct expr *e) case EXPRIDENT: d = e->ident.decl; switch (d->kind) { - case DECLOBJECT: return funcload(f, typeunqual(d->type, NULL), d->value); + case DECLOBJECT: return funcload(f, d->type, d->value); case DECLCONST: return d->value; default: fatal("unimplemented declaration kind %d", d->kind); |