// Inferno utils/cc/dcl.c
// http://code.google.com/p/inferno-os/source/browse/utils/cc/dcl.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "cc.h"

Node*
dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n)
{
	Sym *s;
	Node *n1;
	int32 v;

	nearln = lineno;
	lastfield = 0;

loop:
	if(n != Z)
	switch(n->op) {
	default:
		diag(n, "unknown declarator: %O", n->op);
		break;

	case OARRAY:
		t = typ(TARRAY, t);
		t->width = 0;
		n1 = n->right;
		n = n->left;
		if(n1 != Z) {
			complex(n1);
			v = -1;
			if(n1->op == OCONST)
				v = n1->vconst;
			if(v <= 0) {
				diag(n, "array size must be a positive constant");
				v = 1;
			}
			t->width = v * t->link->width;
		}
		goto loop;

	case OIND:
		t = typ(TIND, t);
		t->garb = n->garb;
		n = n->left;
		goto loop;

	case OFUNC:
		t = typ(TFUNC, t);
		t->down = fnproto(n);
		n = n->left;
		goto loop;

	case OBIT:
		n1 = n->right;
		complex(n1);
		lastfield = -1;
		if(n1->op == OCONST)
			lastfield = n1->vconst;
		if(lastfield < 0) {
			diag(n, "field width must be non-negative constant");
			lastfield = 1;
		}
		if(lastfield == 0) {
			lastbit = 0;
			firstbit = 1;
			if(n->left != Z) {
				diag(n, "zero width named field");
				lastfield = 1;
			}
		}
		if(!typei[t->etype]) {
			diag(n, "field type must be int-like");
			t = types[TINT];
			lastfield = 1;
		}
		if(lastfield > tfield->width*8) {
			diag(n, "field width larger than field unit");
			lastfield = 1;
		}
		lastbit += lastfield;
		if(lastbit > tfield->width*8) {
			lastbit = lastfield;
			firstbit = 1;
		}
		n = n->left;
		goto loop;

	case ONAME:
		if(f == NODECL)
			break;
		s = n->sym;
		(*f)(c, t, s);
		if(s->class == CLOCAL)
			s = mkstatic(s);
		firstbit = 0;
		n->sym = s;
		n->type = s->type;
		n->xoffset = s->offset;
		n->class = s->class;
		n->etype = TVOID;
		if(n->type != T)
			n->etype = n->type->etype;
		if(debug['d'])
			dbgdecl(s);
		acidvar(s);
		s->varlineno = lineno;
		break;
	}
	lastdcl = t;
	return n;
}

Sym*
mkstatic(Sym *s)
{
	Sym *s1;

	if(s->class != CLOCAL)
		return s;
	snprint(symb, NSYMB, "%s$%d", s->name, s->block);
	s1 = lookup();
	if(s1->class != CSTATIC) {
		s1->type = s->type;
		s1->offset = s->offset;
		s1->block = s->block;
		s1->class = CSTATIC;
	}
	return s1;
}

/*
 * make a copy of a typedef
 * the problem is to split out incomplete
 * arrays so that it is in the variable
 * rather than the typedef.
 */
Type*
tcopy(Type *t)
{
	Type *tl, *tx;
	int et;

	if(t == T)
		return t;
	et = t->etype;
	if(typesu[et])
		return t;
	tl = tcopy(t->link);
	if(tl != t->link ||
	  (et == TARRAY && t->width == 0)) {
		tx = copytyp(t);
		tx->link = tl;
		return tx;
	}
	return t;
}

Node*
doinit(Sym *s, Type *t, int32 o, Node *a)
{
	Node *n;

	if(t == T)
		return Z;
	if(s->class == CEXTERN) {
		s->class = CGLOBL;
		if(debug['d'])
			dbgdecl(s);
	}
	if(debug['i']) {
		print("t = %T; o = %ld; n = %s\n", t, o, s->name);
		prtree(a, "doinit value");
	}


	n = initlist;
	if(a->op == OINIT)
		a = a->left;
	initlist = a;

	a = init1(s, t, o, 0);
	if(initlist != Z)
		diag(initlist, "more initializers than structure: %s",
			s->name);
	initlist = n;

	return a;
}

/*
 * get next major operator,
 * dont advance initlist.
 */
Node*
peekinit(void)
{
	Node *a;

	a = initlist;

loop:
	if(a == Z)
		return a;
	if(a->op == OLIST) {
		a = a->left;
		goto loop;
	}
	return a;
}

/*
 * consume and return next element on
 * initlist. expand strings.
 */
Node*
nextinit(void)
{
	Node *a, *b, *n;

	a = initlist;
	n = Z;

	if(a == Z)
		return a;
	if(a->op == OLIST) {
		n = a->right;
		a = a->left;
	}
	if(a->op == OUSED) {
		a = a->left;
		b = new(OCONST, Z, Z);
		b->type = a->type->link;
		if(a->op == OSTRING) {
			b->vconst = convvtox(*a->cstring, TCHAR);
			a->cstring++;
		}
		if(a->op == OLSTRING) {
			b->vconst = convvtox(*a->rstring, TUSHORT);
			a->rstring++;
		}
		a->type->width -= b->type->width;
		if(a->type->width <= 0)
			initlist = n;
		return b;
	}
	initlist = n;
	return a;
}

int
isstruct(Node *a, Type *t)
{
	Node *n;

	switch(a->op) {
	case ODOTDOT:
		n = a->left;
		if(n && n->type && sametype(n->type, t))
			return 1;
	case OSTRING:
	case OLSTRING:
	case OCONST:
	case OINIT:
	case OELEM:
		return 0;
	}

	n = new(ODOTDOT, Z, Z);
	*n = *a;

	/*
	 * ODOTDOT is a flag for tcom
	 * a second tcom will not be performed
	 */
	a->op = ODOTDOT;
	a->left = n;
	a->right = Z;

	if(tcom(n))
		return 0;

	if(sametype(n->type, t))
		return 1;
	return 0;
}

Node*
init1(Sym *s, Type *t, int32 o, int exflag)
{
	Node *a, *l, *r, nod;
	Type *t1;
	int32 e, w, so, mw;

	a = peekinit();
	if(a == Z)
		return Z;

	if(debug['i']) {
		print("t = %T; o = %ld; n = %s\n", t, o, s->name);
		prtree(a, "init1 value");
	}

	if(exflag && a->op == OINIT)
		return doinit(s, t, o, nextinit());

	switch(t->etype) {
	default:
		diag(Z, "unknown type in initialization: %T to: %s", t, s->name);
		return Z;

	case TCHAR:
	case TUCHAR:
	case TINT:
	case TUINT:
	case TSHORT:
	case TUSHORT:
	case TLONG:
	case TULONG:
	case TVLONG:
	case TUVLONG:
	case TFLOAT:
	case TDOUBLE:
	case TIND:
	single:
		if(a->op == OARRAY || a->op == OELEM)
			return Z;

		a = nextinit();
		if(a == Z)
			return Z;

		if(t->nbits)
			diag(Z, "cannot initialize bitfields");
		if(s->class == CAUTO) {
			l = new(ONAME, Z, Z);
			l->sym = s;
			l->type = t;
			l->etype = TVOID;
			if(s->type)
				l->etype = s->type->etype;
			l->xoffset = s->offset + o;
			l->class = s->class;

			l = new(OASI, l, a);
			return l;
		}

		complex(a);
		if(a->type == T)
			return Z;

		if(a->op == OCONST) {
			if(vconst(a) && t->etype == TIND && a->type && a->type->etype != TIND){
				diag(a, "initialize pointer to an integer: %s", s->name);
				return Z;
			}
			if(!sametype(a->type, t)) {
				/* hoop jumping to save malloc */
				if(nodcast == Z)
					nodcast = new(OCAST, Z, Z);
				nod = *nodcast;
				nod.left = a;
				nod.type = t;
				nod.lineno = a->lineno;
				complex(&nod);
				if(nod.type)
					*a = nod;
			}
			if(a->op != OCONST) {
				diag(a, "initializer is not a constant: %s",
					s->name);
				return Z;
			}
			if(vconst(a) == 0)
				return Z;
			goto gext;
		}
		if(t->etype == TIND) {
			while(a->op == OCAST) {
				warn(a, "CAST in initialization ignored");
				a = a->left;
			}
			if(!sametype(t, a->type)) {
				diag(a, "initialization of incompatible pointers: %s\n%T and %T",
					s->name, t, a->type);
			}
			if(a->op == OADDR)
				a = a->left;
			goto gext;
		}

		while(a->op == OCAST)
			a = a->left;
		if(a->op == OADDR) {
			warn(a, "initialize pointer to an integer: %s", s->name);
			a = a->left;
			goto gext;
		}
		diag(a, "initializer is not a constant: %s", s->name);
		return Z;

	gext:
		gextern(s, a, o, t->width);

		return Z;

	case TARRAY:
		w = t->link->width;
		if(a->op == OSTRING || a->op == OLSTRING)
		if(typei[t->link->etype]) {
			/*
			 * get rid of null if sizes match exactly
			 */
			a = nextinit();
			mw = t->width/w;
			so = a->type->width/a->type->link->width;
			if(mw && so > mw) {
				if(so != mw+1)
					diag(a, "string initialization larger than array");
				a->type->width -= a->type->link->width;
			}

			/*
			 * arrange strings to be expanded
			 * inside OINIT braces.
			 */
			a = new(OUSED, a, Z);
			return doinit(s, t, o, a);
		}

		mw = -w;
		l = Z;
		for(e=0;;) {
			/*
			 * peek ahead for element initializer
			 */
			a = peekinit();
			if(a == Z)
				break;
			if(a->op == OELEM && t->link->etype != TSTRUCT)
				break;
			if(a->op == OARRAY) {
				if(e && exflag)
					break;
				a = nextinit();
				r = a->left;
				complex(r);
				if(r->op != OCONST) {
					diag(r, "initializer subscript must be constant");
					return Z;
				}
				e = r->vconst;
				if(t->width != 0)
					if(e < 0 || e*w >= t->width) {
						diag(a, "initialization index out of range: %ld", e);
						continue;
					}
			}

			so = e*w;
			if(so > mw)
				mw = so;
			if(t->width != 0)
				if(mw >= t->width)
					break;
			r = init1(s, t->link, o+so, 1);
			l = newlist(l, r);
			e++;
		}
		if(t->width == 0)
			t->width = mw+w;
		return l;

	case TUNION:
	case TSTRUCT:
		/*
		 * peek ahead to find type of rhs.
		 * if its a structure, then treat
		 * this element as a variable
		 * rather than an aggregate.
		 */
		if(isstruct(a, t))
			goto single;

		if(t->width <= 0) {
			diag(Z, "incomplete structure: %s", s->name);
			return Z;
		}
		l = Z;

	again:
		for(t1 = t->link; t1 != T; t1 = t1->down) {
			if(a->op == OARRAY && t1->etype != TARRAY)
				break;
			if(a->op == OELEM) {
				if(t1->sym != a->sym)
					continue;
				nextinit();
			}
			r = init1(s, t1, o+t1->offset, 1);
			l = newlist(l, r);
			a = peekinit();
			if(a == Z)
				break;
			if(a->op == OELEM)
				goto again;
		}
		if(a && a->op == OELEM)
			diag(a, "structure element not found %F", a);
		return l;
	}
}

Node*
newlist(Node *l, Node *r)
{
	if(r == Z)
		return l;
	if(l == Z)
		return r;
	return new(OLIST, l, r);
}

void
suallign(Type *t)
{
	Type *l;
	int32 o, w;

	o = 0;
	switch(t->etype) {

	case TSTRUCT:
		t->offset = 0;
		w = 0;
		for(l = t->link; l != T; l = l->down) {
			if(l->nbits) {
				if(l->shift <= 0) {
					l->shift = -l->shift;
					w = xround(w, tfield->width);
					o = w;
					w += tfield->width;
				}
				l->offset = o;
			} else {
				if(l->width <= 0)
				if(l->down != T)
					if(l->sym)
						diag(Z, "incomplete structure element: %s",
							l->sym->name);
					else
						diag(Z, "incomplete structure element");
				w = align(w, l, Ael1);
				l->offset = w;
				w = align(w, l, Ael2);
			}
		}
		w = align(w, t, Asu2);
		t->width = w;
		acidtype(t);
		pickletype(t);
		return;

	case TUNION:
		t->offset = 0;
		w = 0;
		for(l = t->link; l != T; l = l->down) {
			if(l->width <= 0)
				if(l->sym)
					diag(Z, "incomplete union element: %s",
						l->sym->name);
				else
					diag(Z, "incomplete union element");
			l->offset = 0;
			l->shift = 0;
			o = align(align(0, l, Ael1), l, Ael2);
			if(o > w)
				w = o;
		}
		w = align(w, t, Asu2);
		t->width = w;
		acidtype(t);
		pickletype(t);
		return;

	default:
		diag(Z, "unknown type in suallign: %T", t);
		break;
	}
}

int32
xround(int32 v, int w)
{
	int r;

	if(w <= 0 || w > 8) {
		diag(Z, "rounding by %d", w);
		w = 1;
	}
	r = v%w;
	if(r)
		v += w-r;
	return v;
}

Type*
ofnproto(Node *n)
{
	Type *tl, *tr, *t;

	if(n == Z)
		return T;
	switch(n->op) {
	case OLIST:
		tl = ofnproto(n->left);
		tr = ofnproto(n->right);
		if(tl == T)
			return tr;
		tl->down = tr;
		return tl;

	case ONAME:
		t = copytyp(n->sym->type);
		t->down = T;
		return t;
	}
	return T;
}

#define	ANSIPROTO	1
#define	OLDPROTO	2

void
argmark(Node *n, int pass)
{
	Type *t;

	autoffset = align(0, thisfn->link, Aarg0);
	stkoff = 0;
	for(; n->left != Z; n = n->left) {
		if(n->op != OFUNC || n->left->op != ONAME)
			continue;
		walkparam(n->right, pass);
		if(pass != 0 && anyproto(n->right) == OLDPROTO) {
			t = typ(TFUNC, n->left->sym->type->link);
			t->down = typ(TOLD, T);
			t->down->down = ofnproto(n->right);
			tmerge(t, n->left->sym);
			n->left->sym->type = t;
		}
		break;
	}
	autoffset = 0;
	stkoff = 0;
}

void
walkparam(Node *n, int pass)
{
	Sym *s;
	Node *n1;

	if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID])
		return;

loop:
	if(n == Z)
		return;
	switch(n->op) {
	default:
		diag(n, "argument not a name/prototype: %O", n->op);
		break;

	case OLIST:
		walkparam(n->left, pass);
		n = n->right;
		goto loop;

	case OPROTO:
		for(n1 = n; n1 != Z; n1=n1->left)
			if(n1->op == ONAME) {
				if(pass == 0) {
					s = n1->sym;
					push1(s);
					s->offset = -1;
					break;
				}
				dodecl(pdecl, CPARAM, n->type, n->left);
				break;
			}
		if(n1)
			break;
		if(pass == 0) {
			/*
			 * extension:
			 *	allow no name in argument declaration
			diag(Z, "no name in argument declaration");
			 */
			break;
		}
		dodecl(NODECL, CPARAM, n->type, n->left);
		pdecl(CPARAM, lastdcl, S);
		break;

	case ODOTDOT:
		break;
	
	case ONAME:
		s = n->sym;
		if(pass == 0) {
			push1(s);
			s->offset = -1;
			break;
		}
		if(s->offset != -1) {
			if(autoffset == 0) {
				firstarg = s;
				firstargtype = s->type;
			}
			autoffset = align(autoffset, s->type, Aarg1);
			s->offset = autoffset;
			autoffset = align(autoffset, s->type, Aarg2);
		} else
			dodecl(pdecl, CXXX, types[TINT], n);
		break;
	}
}

void
markdcl(void)
{
	Decl *d;

	blockno++;
	d = push();
	d->val = DMARK;
	d->offset = autoffset;
	d->block = autobn;
	autobn = blockno;
}

Node*
revertdcl(void)
{
	Decl *d;
	Sym *s;
	Node *n, *n1;

	n = Z;
	for(;;) {
		d = dclstack;
		if(d == D) {
			diag(Z, "pop off dcl stack");
			break;
		}
		dclstack = d->link;
		s = d->sym;
		switch(d->val) {
		case DMARK:
			autoffset = d->offset;
			autobn = d->block;
			return n;

		case DAUTO:
			if(debug['d'])
				print("revert1 \"%s\"\n", s->name);
			if(s->aused == 0) {
				nearln = s->varlineno;
				if(s->class == CAUTO)
					warn(Z, "auto declared and not used: %s", s->name);
				if(s->class == CPARAM)
					warn(Z, "param declared and not used: %s", s->name);
			}
			if(s->type && (s->type->garb & GVOLATILE)) {
				n1 = new(ONAME, Z, Z);
				n1->sym = s;
				n1->type = s->type;
				n1->etype = TVOID;
				if(n1->type != T)
					n1->etype = n1->type->etype;
				n1->xoffset = s->offset;
				n1->class = s->class;

				n1 = new(OADDR, n1, Z);
				n1 = new(OUSED, n1, Z);
				if(n == Z)
					n = n1;
				else
					n = new(OLIST, n1, n);
			}
			s->type = d->type;
			s->class = d->class;
			s->offset = d->offset;
			s->block = d->block;
			s->varlineno = d->varlineno;
			s->aused = d->aused;
			break;

		case DSUE:
			if(debug['d'])
				print("revert2 \"%s\"\n", s->name);
			s->suetag = d->type;
			s->sueblock = d->block;
			break;

		case DLABEL:
			if(debug['d'])
				print("revert3 \"%s\"\n", s->name);
			if(s->label && s->label->addable == 0)
				warn(s->label, "label declared and not used \"%s\"", s->name);
			s->label = Z;
			break;
		}
	}
	return n;
}

Type*
fnproto(Node *n)
{
	int r;

	r = anyproto(n->right);
	if(r == 0 || (r & OLDPROTO)) {
		if(r & ANSIPROTO)
			diag(n, "mixed ansi/old function declaration: %F", n->left);
		return T;
	}
	return fnproto1(n->right);
}

int
anyproto(Node *n)
{
	int r;

	r = 0;

loop:
	if(n == Z)
		return r;
	switch(n->op) {
	case OLIST:
		r |= anyproto(n->left);
		n = n->right;
		goto loop;

	case ODOTDOT:
	case OPROTO:
		return r | ANSIPROTO;
	}
	return r | OLDPROTO;
}

Type*
fnproto1(Node *n)
{
	Type *t;

	if(n == Z)
		return T;
	switch(n->op) {
	case OLIST:
		t = fnproto1(n->left);
		if(t != T)
			t->down = fnproto1(n->right);
		return t;

	case OPROTO:
		lastdcl = T;
		dodecl(NODECL, CXXX, n->type, n->left);
		t = typ(TXXX, T);
		if(lastdcl != T)
			*t = *paramconv(lastdcl, 1);
		return t;

	case ONAME:
		diag(n, "incomplete argument prototype");
		return typ(TINT, T);

	case ODOTDOT:
		return typ(TDOT, T);
	}
	diag(n, "unknown op in fnproto");
	return T;
}

void
dbgdecl(Sym *s)
{
	print("decl \"%s\": C=%s [B=%d:O=%ld] T=%T\n",
		s->name, cnames[s->class], s->block, s->offset, s->type);
}

Decl*
push(void)
{
	Decl *d;

	d = alloc(sizeof(*d));
	d->link = dclstack;
	dclstack = d;
	return d;
}

Decl*
push1(Sym *s)
{
	Decl *d;

	d = push();
	d->sym = s;
	d->val = DAUTO;
	d->type = s->type;
	d->class = s->class;
	d->offset = s->offset;
	d->block = s->block;
	d->varlineno = s->varlineno;
	d->aused = s->aused;
	return d;
}

int
sametype(Type *t1, Type *t2)
{

	if(t1 == t2)
		return 1;
	return rsametype(t1, t2, 5, 1);
}

int
rsametype(Type *t1, Type *t2, int n, int f)
{
	int et;

	n--;
	for(;;) {
		if(t1 == t2)
			return 1;
		if(t1 == T || t2 == T)
			return 0;
		if(n <= 0)
			return 1;
		et = t1->etype;
		if(et != t2->etype)
			return 0;
		if(et == TFUNC) {
			if(!rsametype(t1->link, t2->link, n, 0))
				return 0;
			t1 = t1->down;
			t2 = t2->down;
			while(t1 != T && t2 != T) {
				if(t1->etype == TOLD) {
					t1 = t1->down;
					continue;
				}
				if(t2->etype == TOLD) {
					t2 = t2->down;
					continue;
				}
				while(t1 != T || t2 != T) {
					if(!rsametype(t1, t2, n, 0))
						return 0;
					t1 = t1->down;
					t2 = t2->down;
				}
				break;
			}
			return 1;
		}
		if(et == TARRAY)
			if(t1->width != t2->width && t1->width != 0 && t2->width != 0)
				return 0;
		if(typesu[et]) {
			if(t1->link == T)
				snap(t1);
			if(t2->link == T)
				snap(t2);
			t1 = t1->link;
			t2 = t2->link;
			for(;;) {
				if(t1 == t2)
					return 1;
				if(!rsametype(t1, t2, n, 0))
					return 0;
				t1 = t1->down;
				t2 = t2->down;
			}
		}
		t1 = t1->link;
		t2 = t2->link;
		if((f || !debug['V']) && et == TIND) {
			if(t1 != T && t1->etype == TVOID)
				return 1;
			if(t2 != T && t2->etype == TVOID)
				return 1;
		}
	}
}

typedef struct Typetab Typetab;

struct Typetab{
	int n;
	Type **a;
};

static int
sigind(Type *t, Typetab *tt)
{
	int n;
	Type **a, **na, **p, **e;

	n = tt->n;
	a = tt->a;
	e = a+n;
	/* linear search seems ok */
	for(p = a ; p < e; p++)
		if(sametype(*p, t))
			return p-a;
	if((n&15) == 0){
		na = malloc((n+16)*sizeof(Type*));
		memmove(na, a, n*sizeof(Type*));
		free(a);
		a = tt->a = na;
	}
	a[tt->n++] = t;
	return -1;
}

static uint32
signat(Type *t, Typetab *tt)
{
	int i;
	Type *t1;
	int32 s;

	s = 0;
	for(; t; t=t->link) {
		s = s*thash1 + thash[t->etype];
		if(t->garb&GINCOMPLETE)
			return s;
		switch(t->etype) {
		default:
			return s;
		case TARRAY:
			s = s*thash2 + 0;	/* was t->width */
			break;
		case TFUNC:
			for(t1=t->down; t1; t1=t1->down)
				s = s*thash3 + signat(t1, tt);
			break;
		case TSTRUCT:
		case TUNION:
			if((i = sigind(t, tt)) >= 0){
				s = s*thash2 + i;
				return s;
			}
			for(t1=t->link; t1; t1=t1->down)
				s = s*thash3 + signat(t1, tt);
			return s;
		case TIND:
			break;
		}
	}
	return s;
}

uint32
signature(Type *t)
{
	uint32 s;
	Typetab tt;

	tt.n = 0;
	tt.a = nil;
	s = signat(t, &tt);
	free(tt.a);
	return s;
}

uint32
sign(Sym *s)
{
	uint32 v;
	Type *t;

	if(s->sig == SIGINTERN)
		return SIGNINTERN;
	if((t = s->type) == T)
		return 0;
	v = signature(t);
	if(v == 0)
		v = SIGNINTERN;
	return v;
}

void
snap(Type *t)
{
	if(typesu[t->etype])
	if(t->link == T && t->tag && t->tag->suetag) {
		t->link = t->tag->suetag->link;
		t->width = t->tag->suetag->width;
	}
}

Type*
dotag(Sym *s, int et, int bn)
{
	Decl *d;

	if(bn != 0 && bn != s->sueblock) {
		d = push();
		d->sym = s;
		d->val = DSUE;
		d->type = s->suetag;
		d->block = s->sueblock;
		s->suetag = T;
	}
	if(s->suetag == T) {
		s->suetag = typ(et, T);
		s->sueblock = autobn;
	}
	if(s->suetag->etype != et)
		diag(Z, "tag used for more than one type: %s",
			s->name);
	if(s->suetag->tag == S)
		s->suetag->tag = s;
	return s->suetag;
}

Node*
dcllabel(Sym *s, int f)
{
	Decl *d, d1;
	Node *n;

	n = s->label;
	if(n != Z) {
		if(f) {
			if(n->complex)
				diag(Z, "label reused: %s", s->name);
			n->complex = 1;	// declared
		} else
			n->addable = 1;	// used
		return n;
	}

	d = push();
	d->sym = s;
	d->val = DLABEL;
	dclstack = d->link;

	d1 = *firstdcl;
	*firstdcl = *d;
	*d = d1;

	firstdcl->link = d;
	firstdcl = d;

	n = new(OXXX, Z, Z);
	n->sym = s;
	n->complex = f;
	n->addable = !f;
	s->label = n;

	if(debug['d'])
		dbgdecl(s);
	return n;
}

Type*
paramconv(Type *t, int f)
{

	switch(t->etype) {
	case TUNION:
	case TSTRUCT:
		if(t->width <= 0)
			diag(Z, "incomplete structure: %s", t->tag->name);
		break;

	case TARRAY:
		t = typ(TIND, t->link);
		t->width = types[TIND]->width;
		break;

	case TFUNC:
		t = typ(TIND, t);
		t->width = types[TIND]->width;
		break;

	case TFLOAT:
		if(!f)
			t = types[TDOUBLE];
		break;

	case TCHAR:
	case TSHORT:
		if(!f)
			t = types[TINT];
		break;

	case TUCHAR:
	case TUSHORT:
		if(!f)
			t = types[TUINT];
		break;
	}
	return t;
}

void
adecl(int c, Type *t, Sym *s)
{

	if(c == CSTATIC)
		c = CLOCAL;
	if(t->etype == TFUNC) {
		if(c == CXXX)
			c = CEXTERN;
		if(c == CLOCAL)
			c = CSTATIC;
		if(c == CAUTO || c == CEXREG)
			diag(Z, "function cannot be %s %s", cnames[c], s->name);
	}
	if(c == CXXX)
		c = CAUTO;
	if(s) {
		if(s->class == CSTATIC)
			if(c == CEXTERN || c == CGLOBL) {
				warn(Z, "just say static: %s", s->name);
				c = CSTATIC;
			}
		if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL)
		if(s->block == autobn)
			diag(Z, "auto redeclaration of: %s", s->name);
		if(c != CPARAM)
			push1(s);
		s->block = autobn;
		s->offset = 0;
		s->type = t;
		s->class = c;
		s->aused = 0;
	}
	switch(c) {
	case CAUTO:
		autoffset = align(autoffset, t, Aaut3);
		stkoff = maxround(stkoff, autoffset);
		s->offset = -autoffset;
		break;

	case CPARAM:
		if(autoffset == 0) {
			firstarg = s;
			firstargtype = t;
		}
		autoffset = align(autoffset, t, Aarg1);
		if(s)
			s->offset = autoffset;
		autoffset = align(autoffset, t, Aarg2);
		break;
	}
}

void
pdecl(int c, Type *t, Sym *s)
{
	if(s && s->offset != -1) {
		diag(Z, "not a parameter: %s", s->name);
		return;
	}
	t = paramconv(t, c==CPARAM);
	if(c == CXXX)
		c = CPARAM;
	if(c != CPARAM) {
		diag(Z, "parameter cannot have class: %s", s->name);
		c = CPARAM;
	}
	adecl(c, t, s);
}

void
xdecl(int c, Type *t, Sym *s)
{
	int32 o;

	o = 0;
	switch(c) {
	case CEXREG:
		o = exreg(t);
		if(o == 0)
			c = CEXTERN;
		if(s->class == CGLOBL)
			c = CGLOBL;
		break;

	case CEXTERN:
		if(s->class == CGLOBL)
			c = CGLOBL;
		break;

	case CXXX:
		c = CGLOBL;
		if(s->class == CEXTERN)
			s->class = CGLOBL;
		break;

	case CAUTO:
		diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
		c = CEXTERN;
		break;

	case CTYPESTR:
		if(!typesuv[t->etype]) {
			diag(Z, "typestr must be struct/union: %s", s->name);
			break;
		}
		dclfunct(t, s);
		break;
	}

	if(s->class == CSTATIC)
		if(c == CEXTERN || c == CGLOBL) {
			warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]);
			c = CSTATIC;
		}
	if(s->type != T)
		if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) {
			diag(Z, "external redeclaration of: %s", s->name);
			Bprint(&diagbuf, "	%s %T %L\n", cnames[c], t, nearln);
			Bprint(&diagbuf, "	%s %T %L\n", cnames[s->class], s->type, s->varlineno);
		}
	tmerge(t, s);
	s->type = t;
	s->class = c;
	s->block = 0;
	s->offset = o;
}

void
tmerge(Type *t1, Sym *s)
{
	Type *ta, *tb, *t2;

	t2 = s->type;
/*print("merge	%T; %T\n", t1, t2);/**/
	for(;;) {
		if(t1 == T || t2 == T || t1 == t2)
			break;
		if(t1->etype != t2->etype)
			break;
		switch(t1->etype) {
		case TFUNC:
			ta = t1->down;
			tb = t2->down;
			if(ta == T) {
				t1->down = tb;
				break;
			}
			if(tb == T)
				break;
			while(ta != T && tb != T) {
				if(ta == tb)
					break;
				/* ignore old-style flag */
				if(ta->etype == TOLD) {
					ta = ta->down;
					continue;
				}
				if(tb->etype == TOLD) {
					tb = tb->down;
					continue;
				}
				/* checking terminated by ... */
				if(ta->etype == TDOT && tb->etype == TDOT) {
					ta = T;
					tb = T;
					break;
				}
				if(!sametype(ta, tb))
					break;
				ta = ta->down;
				tb = tb->down;
			}
			if(ta != tb)
				diag(Z, "function inconsistently declared: %s", s->name);

			/* take new-style over old-style */
			ta = t1->down;
			tb = t2->down;
			if(ta != T && ta->etype == TOLD)
				if(tb != T && tb->etype != TOLD)
					t1->down = tb;
			break;

		case TARRAY:
			/* should we check array size change? */
			if(t2->width > t1->width)
				t1->width = t2->width;
			break;

		case TUNION:
		case TSTRUCT:
			return;
		}
		t1 = t1->link;
		t2 = t2->link;
	}
}

void
edecl(int c, Type *t, Sym *s)
{
	Type *t1;

	if(s == S) {
		if(!typesu[t->etype])
			diag(Z, "unnamed structure element must be struct/union");
		if(c != CXXX)
			diag(Z, "unnamed structure element cannot have class");
	} else
		if(c != CXXX)
			diag(Z, "structure element cannot have class: %s", s->name);
	t1 = t;
	t = copytyp(t1);
	t->sym = s;
	t->down = T;
	if(lastfield) {
		t->shift = lastbit - lastfield;
		t->nbits = lastfield;
		if(firstbit)
			t->shift = -t->shift;
		if(typeu[t->etype])
			t->etype = tufield->etype;
		else
			t->etype = tfield->etype;
	}
	if(strf == T)
		strf = t;
	else
		strl->down = t;
	strl = t;
}

/*
 * this routine is very suspect.
 * ansi requires the enum type to
 * be represented as an 'int'
 * this means that 0x81234567
 * would be illegal. this routine
 * makes signed and unsigned go
 * to unsigned.
 */
Type*
maxtype(Type *t1, Type *t2)
{

	if(t1 == T)
		return t2;
	if(t2 == T)
		return t1;
	if(t1->etype > t2->etype)
		return t1;
	return t2;
}

void
doenum(Sym *s, Node *n)
{

	if(n) {
		complex(n);
		if(n->op != OCONST) {
			diag(n, "enum not a constant: %s", s->name);
			return;
		}
		en.cenum = n->type;
		en.tenum = maxtype(en.cenum, en.tenum);

		if(!typefd[en.cenum->etype])
			en.lastenum = n->vconst;
		else
			en.floatenum = n->fconst;
	}
	if(dclstack)
		push1(s);
	xdecl(CXXX, types[TENUM], s);

	if(en.cenum == T) {
		en.tenum = types[TINT];
		en.cenum = types[TINT];
		en.lastenum = 0;
	}
	s->tenum = en.cenum;

	if(!typefd[s->tenum->etype]) {
		s->vconst = convvtox(en.lastenum, s->tenum->etype);
		en.lastenum++;
	} else {
		s->fconst = en.floatenum;
		en.floatenum++;
	}

	if(debug['d'])
		dbgdecl(s);
	acidvar(s);
}

void
symadjust(Sym *s, Node *n, int32 del)
{

	switch(n->op) {
	default:
		if(n->left)
			symadjust(s, n->left, del);
		if(n->right)
			symadjust(s, n->right, del);
		return;

	case ONAME:
		if(n->sym == s)
			n->xoffset -= del;
		return;

	case OCONST:
	case OSTRING:
	case OLSTRING:
	case OINDREG:
	case OREGISTER:
		return;
	}
}

Node*
contig(Sym *s, Node *n, int32 v)
{
	Node *p, *r, *q, *m;
	int32 w;
	Type *zt;

	if(debug['i']) {
		print("contig v = %ld; s = %s\n", v, s->name);
		prtree(n, "doinit value");
	}

	if(n == Z)
		goto no;
	w = s->type->width;

	/*
	 * nightmare: an automatic array whose size
	 * increases when it is initialized
	 */
	if(v != w) {
		if(v != 0)
			diag(n, "automatic adjustable array: %s", s->name);
		v = s->offset;
		autoffset = align(autoffset, s->type, Aaut3);
		s->offset = -autoffset;
		stkoff = maxround(stkoff, autoffset);
		symadjust(s, n, v - s->offset);
	}
	if(w <= ewidth[TIND])
		goto no;
	if(n->op == OAS)
		diag(Z, "oops in contig");
/*ZZZ this appears incorrect
need to check if the list completely covers the data.
if not, bail
 */
	if(n->op == OLIST)
		goto no;
	if(n->op == OASI)
		if(n->left->type)
		if(n->left->type->width == w)
			goto no;
	while(w & (ewidth[TIND]-1))
		w++;
/*
 * insert the following code, where long becomes vlong if pointers are fat
 *
	*(long**)&X = (long*)((char*)X + sizeof(X));
	do {
		*(long**)&X -= 1;
		**(long**)&X = 0;
	} while(*(long**)&X);
 */

	for(q=n; q->op != ONAME; q=q->left)
		;

	zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];

	p = new(ONAME, Z, Z);
	*p = *q;
	p->type = typ(TIND, zt);
	p->xoffset = s->offset;

	r = new(ONAME, Z, Z);
	*r = *p;
	r = new(OPOSTDEC, r, Z);

	q = new(ONAME, Z, Z);
	*q = *p;
	q = new(OIND, q, Z);

	m = new(OCONST, Z, Z);
	m->vconst = 0;
	m->type = zt;

	q = new(OAS, q, m);

	r = new(OLIST, r, q);

	q = new(ONAME, Z, Z);
	*q = *p;
	r = new(ODWHILE, q, r);

	q = new(ONAME, Z, Z);
	*q = *p;
	q->type = q->type->link;
	q->xoffset += w;
	q = new(OADDR, q, 0);

	q = new(OASI, p, q);
	r = new(OLIST, q, r);

	n = new(OLIST, r, n);

no:
	return n;
}
