aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc.h3
-rw-r--r--decl.c10
-rw-r--r--targ.c4
-rw-r--r--type.c10
4 files changed, 18 insertions, 9 deletions
diff --git a/cc.h b/cc.h
index aea792f..d659872 100644
--- a/cc.h
+++ b/cc.h
@@ -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);
diff --git a/decl.c b/decl.c
index 05700f7..23dc778 100644
--- a/decl.c
+++ b/decl.c
@@ -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;
diff --git a/targ.c b/targ.c
index 19be0c9..9d0c179 100644
--- a/targ.c
+++ b/targ.c
@@ -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);
}
diff --git a/type.c b/type.c
index 8a9c440..b533f1c 100644
--- a/type.c
+++ b/type.c
@@ -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;
}