Charles.Forsyth20060303644188019 years agoHistory
918 lines · 15.0 KB · C
RawDownload
#include "cc.h" voidcomplex(Node *n){ 	if(n == Z)		return; 	nearln = n->lineno;	if(tcom(n))		return;	ccom(n);	acom(n);} /* * evaluate types * evaluate lvalues (addable == 1) */enum{	ADDROF	= 1<<0,	CASTOF	= 1<<1,	ADDROP	= 1<<2,}; inttcom(Node *n){ 	return tcomo(n, ADDROF);} inttcomo(Node *n, int f){	Node *l, *r;	Type *t;	int o; 	if(n == Z) {		diag(Z, "Z in tcom");		errorexit();	}	l = n->left;	r = n->right;			switch(n->op) {	default:		diag(n, "unknown op in type complex: %O", n->op);		goto bad; 	case ODOTDOT:		/*		 * tcom has already been called on this subtree		 */		*n = *n->left;		if(n->type == T)			goto bad;		break; 	case OCAST:		if(n->type == T)			break;		if(n->type->width == types[TLONG]->width) {			if(tcomo(l, ADDROF|CASTOF))					goto bad;		} else			if(tcom(l))				goto bad;		if(tcompat(n, l->type, n->type, tcast))			goto bad;		break; 	case ORETURN:		if(l == Z) {			if(n->type->etype != TVOID)				warn(n, "null return of a typed function");			break;		}		if(tcom(l))			goto bad;		typeext(n->type, l);		if(tcompat(n, n->type, l->type, tasign))			break;		constas(n, n->type, l->type);		if(!sametype(n->type, l->type)) {			l = new1(OCAST, l, Z);			l->type = n->type;			n->left = l;		}		break; 	case OASI:	/* same as as, but no test for const */		n->op = OAS;		o = tcom(l);		if(o | tcom(r))			goto bad; 		typeext(l->type, r);		if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))			goto bad;		if(!sametype(l->type, r->type)) {			r = new1(OCAST, r, Z);			r->type = l->type;			n->right = r;		}		n->type = l->type;		break; 	case OAS:	case OASD:		o = tcom(l);		if(o | tcom(r))			goto bad; 		typeext(l->type, r);		if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))			goto bad;		constas(n, l->type, r->type);		if(!sametype(l->type, r->type)) {			r = new1(OCAST, r, Z);			r->type = l->type;			n->right = r;		}		n->type = l->type;		break; 	case OASADD:	case OASSUB:		o = tcom(l);		if(o | tcom(r))			goto bad;		typeext1(l->type, r);		if(tlvalue(l) || tcompat(n, l->type, r->type, tasadd))			goto bad;		constas(n, l->type, r->type);		t = l->type;		arith(n, 0);		while(n->left->op == OCAST)			n->left = n->left->left;		if(!sametype(t, n->type)) {			r = new1(OCAST, n->right, Z);			r->type = t;			n->right = r;			n->type = t;		}		break; 	case OASMUL:	case OASLMUL:	case OASDIV:	case OASLDIV:		o = tcom(l);		if(o | tcom(r))			goto bad;		typeext1(l->type, r);		if(tlvalue(l) || tcompat(n, l->type, r->type, tmul))			goto bad;		constas(n, l->type, r->type);		t = l->type;		arith(n, 0);		while(n->left->op == OCAST)			n->left = n->left->left;		if(!sametype(t, n->type)) {			r = new1(OCAST, n->right, Z);			r->type = t;			n->right = r;			n->type = t;		}		if(typeu[n->type->etype]) {			if(n->op == OASDIV)				n->op = OASLDIV;			if(n->op == OASMUL)				n->op = OASLMUL;		}		break; 	case OASLSHR:	case OASASHR:	case OASASHL:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l) || tcompat(n, l->type, r->type, tand))			goto bad;		n->type = l->type;		if(typeu[n->type->etype]) {			if(n->op == OASASHR)				n->op = OASLSHR;		}		break; 	case OASMOD:	case OASLMOD:	case OASOR:	case OASAND:	case OASXOR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l) || tcompat(n, l->type, r->type, tand))			goto bad;		t = l->type;		arith(n, 0);		while(n->left->op == OCAST)			n->left = n->left->left;		if(!sametype(t, n->type)) {			r = new1(OCAST, n->right, Z);			r->type = t;			n->right = r;			n->type = t;		}		if(typeu[n->type->etype]) {			if(n->op == OASMOD)				n->op = OASLMOD;		}		break; 	case OPREINC:	case OPREDEC:	case OPOSTINC:	case OPOSTDEC:		if(tcom(l))			goto bad;		if(tlvalue(l) || tcompat(n, l->type, types[TINT], tadd))			goto bad;		n->type = l->type;		if(n->type->etype == TIND)		if(n->type->link->width < 1)			diag(n, "inc/dec of a void pointer");		break; 	case OEQ:	case ONE:		o = tcom(l);		if(o | tcom(r))			goto bad;		typeext(l->type, r);		typeext(r->type, l);		if(tcompat(n, l->type, r->type, trel))			goto bad;		arith(n, 0);		n->type = types[TINT];		break; 	case OLT:	case OGE:	case OGT:	case OLE:		o = tcom(l);		if(o | tcom(r))			goto bad;		typeext1(l->type, r);		typeext1(r->type, l);		if(tcompat(n, l->type, r->type, trel))			goto bad;		arith(n, 0);		if(typeu[n->type->etype])			n->op = logrel[relindex(n->op)];		n->type = types[TINT];		break; 	case OCOND:		o = tcom(l);		o |= tcom(r->left);		if(o | tcom(r->right))			goto bad;		if(r->right->type->etype == TIND && vconst(r->left) == 0) {			r->left->type = r->right->type;			r->left->vconst = 0;		}		if(r->left->type->etype == TIND && vconst(r->right) == 0) {			r->right->type = r->left->type;			r->right->vconst = 0;		}		if(sametype(r->right->type, r->left->type)) {			r->type = r->right->type;			n->type = r->type;			break;		}		if(tcompat(r, r->left->type, r->right->type, trel))			goto bad;		arith(r, 0);		n->type = r->type;		break; 	case OADD:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, l->type, r->type, tadd))			goto bad;		arith(n, 1);		break; 	case OSUB:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, l->type, r->type, tsub))			goto bad;		arith(n, 1);		break; 	case OMUL:	case OLMUL:	case ODIV:	case OLDIV:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, l->type, r->type, tmul))			goto bad;		arith(n, 1);		if(typeu[n->type->etype]) {			if(n->op == ODIV)				n->op = OLDIV;			if(n->op == OMUL)				n->op = OLMUL;		}		break; 	case OLSHR:	case OASHL:	case OASHR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, l->type, r->type, tand))			goto bad;		n->right = Z;		arith(n, 1);		n->right = new1(OCAST, r, Z);		n->right->type = types[TINT];		if(typeu[n->type->etype])			if(n->op == OASHR)				n->op = OLSHR;		break; 	case OAND:	case OOR:	case OXOR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, l->type, r->type, tand))			goto bad;		arith(n, 1);		break; 	case OMOD:	case OLMOD:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, l->type, r->type, tand))			goto bad;		arith(n, 1);		if(typeu[n->type->etype])			n->op = OLMOD;		break; 	case ONOT:		if(tcom(l))			goto bad;		if(tcompat(n, T, l->type, tnot))			goto bad;		n->type = types[TINT];		break; 	case OPOS:	case ONEG:	case OCOM:		if(tcom(l))			goto bad; 		n->type = l->type;		break; 	case ONUL:		break; 	case OIOTA:		n->type = types[TINT];		break; 	case ODAS:		n->type = n->left->type;		break; 	case OANDAND:	case OOROR:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tcompat(n, T, l->type, tnot) |		   tcompat(n, T, r->type, tnot))			goto bad;		n->type = types[TINT];		break; 	case OCOMMA:		o = tcom(l);		if(o | tcom(r))			goto bad;		n->type = r->type;		break;  	case OSIGN:	/* extension signof(type) returns a hash */		if(l != Z) {			if(l->op != OSTRING && l->op != OLSTRING)				if(tcomo(l, 0))					goto bad;			if(l->op == OBIT) {				diag(n, "signof bitfield");				goto bad;			}			n->type = l->type;		}		if(n->type == T)			goto bad;		if(n->type->width < 0) {			diag(n, "signof undefined type");			goto bad;		}		n->right = ncopy(n);		n->op = OCONST;		n->left = Z;		/* n->right = Z; */		n->vconst = convvtox(signature(n->type, 10), TULONG);		n->type = types[TULONG];		break; 	case OSIZE:		if(l != Z) {			if(l->op != OSTRING && l->op != OLSTRING)				if(tcomo(l, 0))					goto bad;			if(l->op == OBIT) {				diag(n, "sizeof bitfield");				goto bad;			}			n->type = l->type;		}		if(n->type == T)			goto bad;		if(n->type->width <= 0) {			diag(n, "sizeof undefined type");			goto bad;		}		if(n->type->etype == TFUNC) {			diag(n, "sizeof function");			goto bad;		}		n->right = ncopy(n);		n->op = OCONST;		n->left = Z;		/* n->right = Z; */		n->vconst = convvtox(n->type->width, TINT);		n->type = types[TINT];		break; 	case OFUNC:		o = tcomo(l, 0);		if(o)			goto bad;		if(l->type->etype == TIND && l->type->link->etype == TFUNC) {			l = new1(OIND, l, Z);			l->type = l->left->type->link;			n->left = l;		}		if(tcompat(n, T, l->type, tfunct))			goto bad;		if(o | tcoma(l, r, l->type->down, 1))			goto bad;		n->type = l->type->link;		if(1)			if(l->type->down == T || l->type->down->etype == TOLD) {				nerrors--;				diag(n, "function args not checked: %F", l);			}		dpcheck(n);		break; 	case ONAME:		if(n->type == T) {			diag(n, "name not declared: %F", n);			goto bad;		}		if(n->type->etype == TENUM) {			if(n->sym->tenum->etype == TIND){				/* n->op = OSTRING; */				n->type = n->sym->tenum;				/* n->cstring = n->sym->sconst; */				break;			}			n->left = ncopy(n);			n->op = OCONST;

Lines 1–500 of 918.