diff options
| author | Michael Forney <mforney@mforney.org> | 2019-04-05 16:15:17 -0700 | 
|---|---|---|
| committer | Michael Forney <mforney@mforney.org> | 2019-04-06 12:01:50 -0700 | 
| commit | 952b5b29818a1f9c36736c7d04f03309a4e1b5a5 (patch) | |
| tree | 599c530d3800a156299c85ea1ba07aaf5cc45193 | |
| parent | abec185dead30d4034721619befc847f4c05621c (diff) | |
| download | cproc-952b5b29818a1f9c36736c7d04f03309a4e1b5a5.tar.xz | |
Separate unqualified type and qualifiers in struct decl
| -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); | 
