diff options
-rw-r--r-- | cc.h | 3 | ||||
-rw-r--r-- | decl.c | 10 | ||||
-rw-r--r-- | targ.c | 4 | ||||
-rw-r--r-- | type.c | 10 |
4 files changed, 18 insertions, 9 deletions
@@ -220,6 +220,7 @@ struct type { } basic; struct { unsigned long long length; + enum typequal ptrqual; } array; struct { bool isprototype, isvararg, isnoreturn, paraminfo; @@ -439,7 +440,7 @@ struct type *typecomposite(struct type *, struct type *); struct type *typeunqual(struct type *, enum typequal *); struct type *typecommonreal(struct type *, unsigned, struct type *, unsigned); struct type *typepromote(struct type *, unsigned); -struct type *typeadjust(struct type *); +struct type *typeadjust(struct type *, enum typequal *); enum typeprop typeprop(struct type *); struct member *typemember(struct type *, const char *, unsigned long long *); bool typehasint(struct type *, unsigned long long, bool); @@ -647,12 +647,11 @@ declaratortypes(struct scope *s, struct list *result, char **name, bool allowabs if (allowattr && attr(NULL, 0)) goto attr; next(); - tq = QUALNONE; - while (consume(TSTATIC) || typequal(&tq)) + t = mkarraytype(NULL, QUALNONE, 0); + while (consume(TSTATIC) || typequal(&t->u.array.ptrqual)) ; if (tok.kind == TMUL) error(&tok.loc, "VLAs are not yet supported"); - t = mkarraytype(NULL, tq, 0); if (tok.kind != TRBRACK) { e = eval(assignexpr(s)); if (e->kind != EXPRCONST || !(e->type->prop & PROPINT)) @@ -732,8 +731,9 @@ parameter(struct scope *s) if (sc && sc != SCREGISTER) error(&tok.loc, "parameter declaration has invalid storage-class specifier"); t = declarator(s, t, &name, true); + t.type = typeadjust(t.type, &t.qual); - return mkparam(name, typeadjust(t.type), t.qual); + return mkparam(name, t.type, t.qual); } static bool @@ -755,7 +755,7 @@ paramdecl(struct scope *s, struct param *params) ; if (!p) error(&tok.loc, "old-style function declarator has no parameter named '%s'", name); - p->type = typeadjust(t.type); + p->type = typeadjust(t.type, &t.qual); p->qual = t.qual; if (tok.kind == TSEMICOLON) break; @@ -43,6 +43,7 @@ void targinit(const char *name) { size_t i; + enum typequal qual; if (!name) { /* TODO: provide a way to set this default */ @@ -55,5 +56,6 @@ targinit(const char *name) if (!targ) fatal("unknown target '%s'", name); typechar.u.basic.issigned = targ->signedchar; - typeadjvalist = typeadjust(targ->typevalist); + qual = QUALNONE; + typeadjvalist = typeadjust(targ->typevalist, &qual); } @@ -80,6 +80,7 @@ mkarraytype(struct type *base, enum typequal qual, unsigned long long len) t->base = base; t->qual = qual; t->u.array.length = len; + t->u.array.ptrqual = QUALNONE; t->incomplete = !len; if (t->base) { t->align = t->base->align; @@ -225,13 +226,18 @@ typecommonreal(struct type *t1, unsigned w1, struct type *t2, unsigned w2) /* function parameter type adjustment (C11 6.7.6.3p7) */ struct type * -typeadjust(struct type *t) +typeadjust(struct type *t, enum typequal *tq) { + enum typequal ptrqual; + switch (t->kind) { case TYPEARRAY: - t = mkpointertype(t->base, t->qual); + ptrqual = t->u.array.ptrqual; + t = mkpointertype(t->base, *tq | t->qual); + *tq = ptrqual; break; case TYPEFUNC: + assert(*tq == QUALNONE); t = mkpointertype(t, QUALNONE); break; } |