1471 lines · 24.1 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "cc.h" typedef struct Com Com;struct Com{	int	n;	Node	*t[500];}; int compar(Node*, int);static void comma(Node*);static Node*	commas(Com*, Node*); voidcomplex(Node *n){ 	if(n == Z)		return; 	nearln = n->lineno;	if(debug['t'])		if(n->op != OCONST)			prtree(n, "pre complex");	if(tcom(n))		return;	if(debug['y'] || 1)		comma(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "t complex");	ccom(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "c complex");	acom(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "a complex");	xcom(n);	if(debug['t'])		if(n->op != OCONST)			prtree(n, "x complex");} /* * 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;	static TRune zer; 	if(n == Z) {		diag(Z, "Z in tcom");		errorexit();	}	n->addable = 0;	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(isfunct(n))			break;		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:		o = tcom(l);		if(o | tcom(r))			goto bad;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		typeext(l->type, r);		if(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;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		typeext1(l->type, r);		if(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) && !mixedasop(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;		if(tlvalue(l))			goto bad;		if(isfunct(n))			break;		typeext1(l->type, r);		if(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) && !mixedasop(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))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		n->type = l->type;		n->right = new1(OCAST, r, Z);		n->right->type = types[TINT];		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))			goto bad;		if(isfunct(n))			break;		if(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) && !mixedasop(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))			goto bad;		if(isfunct(n))			break;		if(tcompat(n, l->type, types[TINT], tadd))			goto bad;		n->type = l->type;		if(n->type->etype == TIND)		if(n->type->link->width < 1) {			snap(n->type->link);			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;		if(isfunct(n))			break;		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;		if(isfunct(n))			break;		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(isfunct(n))			break;		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(isfunct(n))			break;		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(isfunct(n))			break;		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(isfunct(n))			break;		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(isfunct(n))			break;		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(isfunct(n))			break;		if(tcompat(n, l->type, r->type, tand))			goto bad;		arith(n, 1);		if(typeu[n->type->etype])			n->op = OLMOD;		break; 	case OPOS:		if(tcom(l))			goto bad;		if(isfunct(n))			break; 		r = l;		l = new(OCONST, Z, Z);		l->vconst = 0;		l->type = types[TINT];		n->op = OADD;		n->right = r;		n->left = l; 		if(tcom(l))			goto bad;		if(tcompat(n, l->type, r->type, tsub))			goto bad;		arith(n, 1);		break; 	case ONEG:		if(tcom(l))			goto bad;		if(isfunct(n))			break; 		if(!machcap(n)) {			r = l;			l = new(OCONST, Z, Z);			l->vconst = 0;			l->type = types[TINT];			n->op = OSUB;			n->right = r;			n->left = l; 			if(tcom(l))				goto bad;			if(tcompat(n, l->type, r->type, tsub))				goto bad;		}		arith(n, 1);		break; 	case OCOM:		if(tcom(l))			goto bad;		if(isfunct(n))			break; 		if(!machcap(n)) {

Lines 1–500 of 1471.