xref: /csrg-svn/old/pcc/mip/trees.c (revision 16179)
1*16179Sralph static char *sccsid ="@(#)trees.c	4.1 (Berkeley) 03/14/84";
2*16179Sralph # include "mfile1"
3*16179Sralph 
4*16179Sralph 	    /* corrections when in violation of lint */
5*16179Sralph 
6*16179Sralph /*	some special actions, used in finding the type of nodes */
7*16179Sralph # define NCVT 01
8*16179Sralph # define PUN 02
9*16179Sralph # define TYPL 04
10*16179Sralph # define TYPR 010
11*16179Sralph # define TYMATCH 040
12*16179Sralph # define LVAL 0100
13*16179Sralph # define CVTO 0200
14*16179Sralph # define CVTL 0400
15*16179Sralph # define CVTR 01000
16*16179Sralph # define PTMATCH 02000
17*16179Sralph # define OTHER 04000
18*16179Sralph # define NCVTR 010000
19*16179Sralph 
20*16179Sralph /* node conventions:
21*16179Sralph 
22*16179Sralph 	NAME:	rval>0 is stab index for external
23*16179Sralph 		rval<0 is -inlabel number
24*16179Sralph 		lval is offset in bits
25*16179Sralph 	ICON:	lval has the value
26*16179Sralph 		rval has the STAB index, or - label number,
27*16179Sralph 			if a name whose address is in the constant
28*16179Sralph 		rval = NONAME means no name
29*16179Sralph 	REG:	rval is reg. identification cookie
30*16179Sralph 
31*16179Sralph 	*/
32*16179Sralph 
33*16179Sralph int bdebug = 0;
34*16179Sralph extern ddebug;
35*16179Sralph 
36*16179Sralph NODE *
37*16179Sralph buildtree( o, l, r ) register NODE *l, *r; {
38*16179Sralph 	register NODE *p, *q;
39*16179Sralph 	register actions;
40*16179Sralph 	register opty;
41*16179Sralph 	register struct symtab *sp;
42*16179Sralph 	register NODE *lr, *ll;
43*16179Sralph 	int i;
44*16179Sralph 	extern int eprint();
45*16179Sralph 
46*16179Sralph # ifndef BUG1
47*16179Sralph 	if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r );
48*16179Sralph # endif
49*16179Sralph 	opty = optype(o);
50*16179Sralph 
51*16179Sralph 	/* check for constants */
52*16179Sralph 
53*16179Sralph 	if( opty == UTYPE && l->in.op == ICON ){
54*16179Sralph 
55*16179Sralph 		switch( o ){
56*16179Sralph 
57*16179Sralph 		case NOT:
58*16179Sralph 			if( hflag ) werror( "constant argument to NOT" );
59*16179Sralph 		case UNARY MINUS:
60*16179Sralph 		case COMPL:
61*16179Sralph 			if( conval( l, o, l ) ) return(l);
62*16179Sralph 			break;
63*16179Sralph 
64*16179Sralph 			}
65*16179Sralph 		}
66*16179Sralph 
67*16179Sralph 	else if( o==UNARY MINUS && l->in.op==FCON ){
68*16179Sralph 		l->fpn.dval = -l->fpn.dval;
69*16179Sralph 		return(l);
70*16179Sralph 		}
71*16179Sralph 
72*16179Sralph 	else if( o==QUEST && l->in.op==ICON ) {
73*16179Sralph 		l->in.op = FREE;
74*16179Sralph 		r->in.op = FREE;
75*16179Sralph 		if( l->tn.lval ){
76*16179Sralph 			tfree( r->in.right );
77*16179Sralph 			return( r->in.left );
78*16179Sralph 			}
79*16179Sralph 		else {
80*16179Sralph 			tfree( r->in.left );
81*16179Sralph 			return( r->in.right );
82*16179Sralph 			}
83*16179Sralph 		}
84*16179Sralph 
85*16179Sralph 	else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn;
86*16179Sralph 
87*16179Sralph 	else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ){
88*16179Sralph 
89*16179Sralph 		switch( o ){
90*16179Sralph 
91*16179Sralph 		case ULT:
92*16179Sralph 		case UGT:
93*16179Sralph 		case ULE:
94*16179Sralph 		case UGE:
95*16179Sralph 		case LT:
96*16179Sralph 		case GT:
97*16179Sralph 		case LE:
98*16179Sralph 		case GE:
99*16179Sralph 		case EQ:
100*16179Sralph 		case NE:
101*16179Sralph 		case ANDAND:
102*16179Sralph 		case OROR:
103*16179Sralph 		case CBRANCH:
104*16179Sralph 
105*16179Sralph 		ccwarn:
106*16179Sralph 			if( hflag ) werror( "constant in conditional context" );
107*16179Sralph 
108*16179Sralph 		case PLUS:
109*16179Sralph 		case MINUS:
110*16179Sralph 		case MUL:
111*16179Sralph 		case DIV:
112*16179Sralph 		case MOD:
113*16179Sralph 		case AND:
114*16179Sralph 		case OR:
115*16179Sralph 		case ER:
116*16179Sralph 		case LS:
117*16179Sralph 		case RS:
118*16179Sralph 			if( conval( l, o, r ) ) {
119*16179Sralph 				r->in.op = FREE;
120*16179Sralph 				return(l);
121*16179Sralph 				}
122*16179Sralph 			break;
123*16179Sralph 			}
124*16179Sralph 		}
125*16179Sralph 
126*16179Sralph 	else if( opty == BITYPE && (l->in.op==FCON||l->in.op==ICON) &&
127*16179Sralph 		(r->in.op==FCON||r->in.op==ICON) ){
128*16179Sralph 		switch(o){
129*16179Sralph 		case PLUS:
130*16179Sralph 		case MINUS:
131*16179Sralph 		case MUL:
132*16179Sralph 		case DIV:
133*16179Sralph 			if( l->in.op == ICON ){
134*16179Sralph 				l->fpn.dval = l->tn.lval;
135*16179Sralph 				}
136*16179Sralph 			if( r->in.op == ICON ){
137*16179Sralph 				r->fpn.dval = r->tn.lval;
138*16179Sralph 				}
139*16179Sralph 			l->in.op = FCON;
140*16179Sralph 			l->in.type = l->fn.csiz = DOUBLE;
141*16179Sralph 			r->in.op = FREE;
142*16179Sralph 			switch(o){
143*16179Sralph 			case PLUS:
144*16179Sralph 				l->fpn.dval += r->fpn.dval;
145*16179Sralph 				return(l);
146*16179Sralph 			case MINUS:
147*16179Sralph 				l->fpn.dval -= r->fpn.dval;
148*16179Sralph 				return(l);
149*16179Sralph 			case MUL:
150*16179Sralph 				l->fpn.dval *= r->fpn.dval;
151*16179Sralph 				return(l);
152*16179Sralph 			case DIV:
153*16179Sralph 				if( r->fpn.dval == 0 ) uerror( "division by 0." );
154*16179Sralph 				else l->fpn.dval /= r->fpn.dval;
155*16179Sralph 				return(l);
156*16179Sralph 				}
157*16179Sralph 			}
158*16179Sralph 		}
159*16179Sralph 
160*16179Sralph 	/* its real; we must make a new node */
161*16179Sralph 
162*16179Sralph 	p = block( o, l, r, INT, 0, INT );
163*16179Sralph 
164*16179Sralph 	actions = opact(p);
165*16179Sralph 
166*16179Sralph 	if( actions&LVAL ){ /* check left descendent */
167*16179Sralph 		if( notlval(p->in.left) ) {
168*16179Sralph 			uerror( "illegal lhs of assignment operator" );
169*16179Sralph 			}
170*16179Sralph 		}
171*16179Sralph 
172*16179Sralph 	if( actions & NCVTR ){
173*16179Sralph 		p->in.left = pconvert( p->in.left );
174*16179Sralph 		}
175*16179Sralph 	else if( !(actions & NCVT ) ){
176*16179Sralph 		switch( opty ){
177*16179Sralph 
178*16179Sralph 		case BITYPE:
179*16179Sralph 			p->in.right = pconvert( p->in.right );
180*16179Sralph 		case UTYPE:
181*16179Sralph 			p->in.left = pconvert( p->in.left );
182*16179Sralph 
183*16179Sralph 			}
184*16179Sralph 		}
185*16179Sralph 
186*16179Sralph 	if( (actions&PUN) && (o!=CAST||cflag) ){
187*16179Sralph 		chkpun(p);
188*16179Sralph 		}
189*16179Sralph 
190*16179Sralph 	if( actions & (TYPL|TYPR) ){
191*16179Sralph 
192*16179Sralph 		q = (actions&TYPL) ? p->in.left : p->in.right;
193*16179Sralph 
194*16179Sralph 		p->in.type = q->in.type;
195*16179Sralph 		p->fn.cdim = q->fn.cdim;
196*16179Sralph 		p->fn.csiz = q->fn.csiz;
197*16179Sralph 		}
198*16179Sralph 
199*16179Sralph 	if( actions & CVTL ) p = convert( p, CVTL );
200*16179Sralph 	if( actions & CVTR ) p = convert( p, CVTR );
201*16179Sralph 	if( actions & TYMATCH ) p = tymatch(p);
202*16179Sralph 	if( actions & PTMATCH ) p = ptmatch(p);
203*16179Sralph 
204*16179Sralph 	if( actions & OTHER ){
205*16179Sralph 		l = p->in.left;
206*16179Sralph 		r = p->in.right;
207*16179Sralph 
208*16179Sralph 		switch(o){
209*16179Sralph 
210*16179Sralph 		case NAME:
211*16179Sralph 			sp = &stab[idname];
212*16179Sralph 			if( sp->stype == UNDEF ){
213*16179Sralph #ifndef FLEXNAMES
214*16179Sralph 				uerror( "%.8s undefined", sp->sname );
215*16179Sralph #else
216*16179Sralph 				uerror( "%s undefined", sp->sname );
217*16179Sralph #endif
218*16179Sralph 				/* make p look reasonable */
219*16179Sralph 				p->in.type = p->fn.cdim = p->fn.csiz = INT;
220*16179Sralph 				p->tn.rval = idname;
221*16179Sralph 				p->tn.lval = 0;
222*16179Sralph 				defid( p, SNULL );
223*16179Sralph 				break;
224*16179Sralph 				}
225*16179Sralph 			p->in.type = sp->stype;
226*16179Sralph 			p->fn.cdim = sp->dimoff;
227*16179Sralph 			p->fn.csiz = sp->sizoff;
228*16179Sralph 			p->tn.lval = 0;
229*16179Sralph 			p->tn.rval = idname;
230*16179Sralph 			/* special case: MOETY is really an ICON... */
231*16179Sralph 			if( p->in.type == MOETY ){
232*16179Sralph 				p->tn.rval = NONAME;
233*16179Sralph 				p->tn.lval = sp->offset;
234*16179Sralph 				p->fn.cdim = 0;
235*16179Sralph 				p->in.type = ENUMTY;
236*16179Sralph 				p->in.op = ICON;
237*16179Sralph 				}
238*16179Sralph 			break;
239*16179Sralph 
240*16179Sralph 		case ICON:
241*16179Sralph 			p->in.type = INT;
242*16179Sralph 			p->fn.cdim = 0;
243*16179Sralph 			p->fn.csiz = INT;
244*16179Sralph 			break;
245*16179Sralph 
246*16179Sralph 		case STRING:
247*16179Sralph 			p->in.op = NAME;
248*16179Sralph 			p->in.type = CHAR+ARY;
249*16179Sralph 			p->tn.lval = 0;
250*16179Sralph 			p->tn.rval = NOLAB;
251*16179Sralph 			p->fn.cdim = curdim;
252*16179Sralph 			p->fn.csiz = CHAR;
253*16179Sralph 			break;
254*16179Sralph 
255*16179Sralph 		case FCON:
256*16179Sralph 			p->tn.lval = 0;
257*16179Sralph 			p->tn.rval = 0;
258*16179Sralph 			p->in.type = DOUBLE;
259*16179Sralph 			p->fn.cdim = 0;
260*16179Sralph 			p->fn.csiz = DOUBLE;
261*16179Sralph 			break;
262*16179Sralph 
263*16179Sralph 		case STREF:
264*16179Sralph 			/* p->x turned into *(p+offset) */
265*16179Sralph 			/* rhs must be a name; check correctness */
266*16179Sralph 
267*16179Sralph 			i = r->tn.rval;
268*16179Sralph 			if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){
269*16179Sralph 				uerror( "member of structure or union required" );
270*16179Sralph 				}else
271*16179Sralph 			/* if this name is non-unique, find right one */
272*16179Sralph 			if( stab[i].sflags & SNONUNIQ &&
273*16179Sralph 				(l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) &&
274*16179Sralph 				(l->fn.csiz +1) >= 0 ){
275*16179Sralph 				/* nonunique name && structure defined */
276*16179Sralph 				char * memnam, * tabnam;
277*16179Sralph 				register k;
278*16179Sralph 				int j;
279*16179Sralph 				int memi;
280*16179Sralph 				j=dimtab[l->fn.csiz+1];
281*16179Sralph 				for( ; (memi=dimtab[j]) >= 0; ++j ){
282*16179Sralph 					tabnam = stab[memi].sname;
283*16179Sralph 					memnam = stab[i].sname;
284*16179Sralph # ifndef BUG1
285*16179Sralph 					if( ddebug>1 ){
286*16179Sralph #ifndef FLEXNAMES
287*16179Sralph 						printf("member %.8s==%.8s?\n",
288*16179Sralph #else
289*16179Sralph 						printf("member %s==%s?\n",
290*16179Sralph #endif
291*16179Sralph 							memnam, tabnam);
292*16179Sralph 						}
293*16179Sralph # endif
294*16179Sralph 					if( stab[memi].sflags & SNONUNIQ ){
295*16179Sralph #ifndef FLEXNAMES
296*16179Sralph 						for( k=0; k<NCHNAM; ++k ){
297*16179Sralph 							if(*memnam++!=*tabnam)
298*16179Sralph 								goto next;
299*16179Sralph 							if(!*tabnam++) break;
300*16179Sralph 							}
301*16179Sralph #else
302*16179Sralph 						if (memnam != tabnam)
303*16179Sralph 							goto next;
304*16179Sralph #endif
305*16179Sralph 						r->tn.rval = i = memi;
306*16179Sralph 						break;
307*16179Sralph 						}
308*16179Sralph 					next: continue;
309*16179Sralph 					}
310*16179Sralph 				if( memi < 0 )
311*16179Sralph #ifndef FLEXNAMES
312*16179Sralph 					uerror("illegal member use: %.8s",
313*16179Sralph #else
314*16179Sralph 					uerror("illegal member use: %s",
315*16179Sralph #endif
316*16179Sralph 						stab[i].sname);
317*16179Sralph 				}
318*16179Sralph 			else {
319*16179Sralph 				register j;
320*16179Sralph 				if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){
321*16179Sralph 					if( stab[i].sflags & SNONUNIQ ){
322*16179Sralph 						uerror( "nonunique name demands struct/union or struct/union pointer" );
323*16179Sralph 						}
324*16179Sralph 					else werror( "struct/union or struct/union pointer required" );
325*16179Sralph 					}
326*16179Sralph 				else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" );
327*16179Sralph 				else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){
328*16179Sralph #ifndef FLEXNAMES
329*16179Sralph 					werror( "illegal member use: %.8s", stab[i].sname );
330*16179Sralph #else
331*16179Sralph 					werror( "illegal member use: %s", stab[i].sname );
332*16179Sralph #endif
333*16179Sralph 					}
334*16179Sralph 				}
335*16179Sralph 
336*16179Sralph 			p = stref( p );
337*16179Sralph 			break;
338*16179Sralph 
339*16179Sralph 		case UNARY MUL:
340*16179Sralph 			if( l->in.op == UNARY AND ){
341*16179Sralph 				p->in.op = l->in.op = FREE;
342*16179Sralph 				p = l->in.left;
343*16179Sralph 				}
344*16179Sralph 			if( !ISPTR(l->in.type))uerror("illegal indirection");
345*16179Sralph 			p->in.type = DECREF(l->in.type);
346*16179Sralph 			p->fn.cdim = l->fn.cdim;
347*16179Sralph 			p->fn.csiz = l->fn.csiz;
348*16179Sralph 			break;
349*16179Sralph 
350*16179Sralph 		case UNARY AND:
351*16179Sralph 			switch( l->in.op ){
352*16179Sralph 
353*16179Sralph 			case UNARY MUL:
354*16179Sralph 				p->in.op = l->in.op = FREE;
355*16179Sralph 				p = l->in.left;
356*16179Sralph 			case NAME:
357*16179Sralph 				p->in.type = INCREF( l->in.type );
358*16179Sralph 				p->fn.cdim = l->fn.cdim;
359*16179Sralph 				p->fn.csiz = l->fn.csiz;
360*16179Sralph 				break;
361*16179Sralph 
362*16179Sralph 			case COMOP:
363*16179Sralph 				lr = buildtree( UNARY AND, l->in.right, NIL );
364*16179Sralph 				p->in.op = l->in.op = FREE;
365*16179Sralph 				p = buildtree( COMOP, l->in.left, lr );
366*16179Sralph 				break;
367*16179Sralph 
368*16179Sralph 			case QUEST:
369*16179Sralph 				lr = buildtree( UNARY AND, l->in.right->in.right, NIL );
370*16179Sralph 				ll = buildtree( UNARY AND, l->in.right->in.left, NIL );
371*16179Sralph 				p->in.op = l->in.op = l->in.right->in.op = FREE;
372*16179Sralph 				p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) );
373*16179Sralph 				break;
374*16179Sralph 
375*16179Sralph # ifdef ADDROREG
376*16179Sralph 			case OREG:
377*16179Sralph 				/* OREG was built in clocal()
378*16179Sralph 				 * for an auto or formal parameter
379*16179Sralph 				 * now its address is being taken
380*16179Sralph 				 * local code must unwind it
381*16179Sralph 				 * back to PLUS/MINUS REG ICON
382*16179Sralph 				 * according to local conventions
383*16179Sralph 				 */
384*16179Sralph 				{
385*16179Sralph 				extern NODE * addroreg();
386*16179Sralph 				p->in.op = FREE;
387*16179Sralph 				p = addroreg( l );
388*16179Sralph 				}
389*16179Sralph 				break;
390*16179Sralph 
391*16179Sralph # endif
392*16179Sralph 			default:
393*16179Sralph 				uerror( "unacceptable operand of &" );
394*16179Sralph 				break;
395*16179Sralph 				}
396*16179Sralph 			break;
397*16179Sralph 
398*16179Sralph 		case LS:
399*16179Sralph 		case RS:
400*16179Sralph 		case ASG LS:
401*16179Sralph 		case ASG RS:
402*16179Sralph 			if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT)
403*16179Sralph 				p->in.right = makety(p->in.right, INT, 0, INT );
404*16179Sralph 			break;
405*16179Sralph 
406*16179Sralph 		case RETURN:
407*16179Sralph 		case ASSIGN:
408*16179Sralph 		case CAST:
409*16179Sralph 			/* structure assignment */
410*16179Sralph 			/* take the addresses of the two sides; then make an
411*16179Sralph 			/* operator using STASG and
412*16179Sralph 			/* the addresses of left and right */
413*16179Sralph 
414*16179Sralph 			{
415*16179Sralph 				register TWORD t;
416*16179Sralph 				register d, s;
417*16179Sralph 
418*16179Sralph 				if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" );
419*16179Sralph 
420*16179Sralph 				r = buildtree( UNARY AND, r, NIL );
421*16179Sralph 				t = r->in.type;
422*16179Sralph 				d = r->fn.cdim;
423*16179Sralph 				s = r->fn.csiz;
424*16179Sralph 
425*16179Sralph 				l = block( STASG, l, r, t, d, s );
426*16179Sralph 
427*16179Sralph 				if( o == RETURN ){
428*16179Sralph 					p->in.op = FREE;
429*16179Sralph 					p = l;
430*16179Sralph 					break;
431*16179Sralph 					}
432*16179Sralph 
433*16179Sralph 				p->in.op = UNARY MUL;
434*16179Sralph 				p->in.left = l;
435*16179Sralph 				p->in.right = NIL;
436*16179Sralph 				break;
437*16179Sralph 				}
438*16179Sralph 		case COLON:
439*16179Sralph 			/* structure colon */
440*16179Sralph 
441*16179Sralph 			if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" );
442*16179Sralph 			break;
443*16179Sralph 
444*16179Sralph 		case CALL:
445*16179Sralph 			p->in.right = r = strargs( p->in.right );
446*16179Sralph 		case UNARY CALL:
447*16179Sralph 			if( !ISPTR(l->in.type)) uerror("illegal function");
448*16179Sralph 			p->in.type = DECREF(l->in.type);
449*16179Sralph 			if( !ISFTN(p->in.type)) uerror("illegal function");
450*16179Sralph 			p->in.type = DECREF( p->in.type );
451*16179Sralph 			p->fn.cdim = l->fn.cdim;
452*16179Sralph 			p->fn.csiz = l->fn.csiz;
453*16179Sralph 			if( l->in.op == UNARY AND && l->in.left->in.op == NAME &&
454*16179Sralph 				l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME &&
455*16179Sralph 				( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){
456*16179Sralph 				p->in.op += (FORTCALL-CALL);
457*16179Sralph 				}
458*16179Sralph 			if( p->in.type == STRTY || p->in.type == UNIONTY ){
459*16179Sralph 				/* function returning structure */
460*16179Sralph 				/*  make function really return ptr to str., with * */
461*16179Sralph 
462*16179Sralph 				p->in.op += STCALL-CALL;
463*16179Sralph 				p->in.type = INCREF( p->in.type );
464*16179Sralph 				p = buildtree( UNARY MUL, p, NIL );
465*16179Sralph 
466*16179Sralph 				}
467*16179Sralph 			break;
468*16179Sralph 
469*16179Sralph 		default:
470*16179Sralph 			cerror( "other code %d", o );
471*16179Sralph 			}
472*16179Sralph 
473*16179Sralph 		}
474*16179Sralph 
475*16179Sralph 	if( actions & CVTO ) p = oconvert(p);
476*16179Sralph 	p = clocal(p);
477*16179Sralph 
478*16179Sralph # ifndef BUG1
479*16179Sralph 	if( bdebug ) fwalk( p, eprint, 0 );
480*16179Sralph # endif
481*16179Sralph 
482*16179Sralph 	return(p);
483*16179Sralph 
484*16179Sralph 	}
485*16179Sralph 
486*16179Sralph NODE *
487*16179Sralph strargs( p ) register NODE *p;  { /* rewrite structure flavored arguments */
488*16179Sralph 
489*16179Sralph 	if( p->in.op == CM ){
490*16179Sralph 		p->in.left = strargs( p->in.left );
491*16179Sralph 		p->in.right = strargs( p->in.right );
492*16179Sralph 		return( p );
493*16179Sralph 		}
494*16179Sralph 
495*16179Sralph 	if( p->in.type == STRTY || p->in.type == UNIONTY ){
496*16179Sralph 		p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz );
497*16179Sralph 		p->in.left = buildtree( UNARY AND, p->in.left, NIL );
498*16179Sralph 		p = clocal(p);
499*16179Sralph 		}
500*16179Sralph 	return( p );
501*16179Sralph 	}
502*16179Sralph 
503*16179Sralph chkstr( i, j, type ) TWORD type; {
504*16179Sralph 	/* is the MOS or MOU at stab[i] OK for strict reference by a ptr */
505*16179Sralph 	/* i has been checked to contain a MOS or MOU */
506*16179Sralph 	/* j is the index in dimtab of the members... */
507*16179Sralph 	int k, kk;
508*16179Sralph 
509*16179Sralph 	extern int ddebug;
510*16179Sralph 
511*16179Sralph # ifndef BUG1
512*16179Sralph #ifndef FLEXNAMES
513*16179Sralph 	if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j );
514*16179Sralph #else
515*16179Sralph 	if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j );
516*16179Sralph #endif
517*16179Sralph # endif
518*16179Sralph 	if( (k = j) < 0 ) uerror( "undefined structure or union" );
519*16179Sralph 	else {
520*16179Sralph 		for( ; (kk = dimtab[k] ) >= 0; ++k ){
521*16179Sralph 			if( kk >= SYMTSZ ){
522*16179Sralph 				cerror( "gummy structure" );
523*16179Sralph 				return(1);
524*16179Sralph 				}
525*16179Sralph 			if( kk == i ) return( 1 );
526*16179Sralph 			switch( stab[kk].stype ){
527*16179Sralph 
528*16179Sralph 			case STRTY:
529*16179Sralph 			case UNIONTY:
530*16179Sralph 				if( type == STRTY ) continue;  /* no recursive looking for strs */
531*16179Sralph 				if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){
532*16179Sralph 					if( stab[kk].sname[0] == '$' ) return(0);  /* $FAKE */
533*16179Sralph 					werror(
534*16179Sralph #ifndef FLEXNAMES
535*16179Sralph 					"illegal member use: perhaps %.8s.%.8s?",
536*16179Sralph #else
537*16179Sralph 					"illegal member use: perhaps %s.%s?",
538*16179Sralph #endif
539*16179Sralph 					stab[kk].sname, stab[i].sname );
540*16179Sralph 					return(1);
541*16179Sralph 					}
542*16179Sralph 				}
543*16179Sralph 			}
544*16179Sralph 		}
545*16179Sralph 	return( 0 );
546*16179Sralph 	}
547*16179Sralph 
548*16179Sralph conval( p, o, q ) register NODE *p, *q; {
549*16179Sralph 	/* apply the op o to the lval part of p; if binary, rhs is val */
550*16179Sralph 	int i, u;
551*16179Sralph 	CONSZ val;
552*16179Sralph 
553*16179Sralph 	val = q->tn.lval;
554*16179Sralph 	u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type);
555*16179Sralph 	if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
556*16179Sralph 
557*16179Sralph 	if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0);
558*16179Sralph 	if( q->tn.rval != NONAME && o!=PLUS ) return(0);
559*16179Sralph 	if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0);
560*16179Sralph 
561*16179Sralph 	switch( o ){
562*16179Sralph 
563*16179Sralph 	case PLUS:
564*16179Sralph 		p->tn.lval += val;
565*16179Sralph 		if( p->tn.rval == NONAME ){
566*16179Sralph 			p->tn.rval = q->tn.rval;
567*16179Sralph 			p->in.type = q->in.type;
568*16179Sralph 			}
569*16179Sralph 		break;
570*16179Sralph 	case MINUS:
571*16179Sralph 		p->tn.lval -= val;
572*16179Sralph 		break;
573*16179Sralph 	case MUL:
574*16179Sralph 		p->tn.lval *= val;
575*16179Sralph 		break;
576*16179Sralph 	case DIV:
577*16179Sralph 		if( val == 0 ) uerror( "division by 0" );
578*16179Sralph 		else p->tn.lval /= val;
579*16179Sralph 		break;
580*16179Sralph 	case MOD:
581*16179Sralph 		if( val == 0 ) uerror( "division by 0" );
582*16179Sralph 		else p->tn.lval %= val;
583*16179Sralph 		break;
584*16179Sralph 	case AND:
585*16179Sralph 		p->tn.lval &= val;
586*16179Sralph 		break;
587*16179Sralph 	case OR:
588*16179Sralph 		p->tn.lval |= val;
589*16179Sralph 		break;
590*16179Sralph 	case ER:
591*16179Sralph 		p->tn.lval ^=  val;
592*16179Sralph 		break;
593*16179Sralph 	case LS:
594*16179Sralph 		i = val;
595*16179Sralph 		p->tn.lval = p->tn.lval << i;
596*16179Sralph 		break;
597*16179Sralph 	case RS:
598*16179Sralph 		i = val;
599*16179Sralph 		p->tn.lval = p->tn.lval >> i;
600*16179Sralph 		break;
601*16179Sralph 
602*16179Sralph 	case UNARY MINUS:
603*16179Sralph 		p->tn.lval = - p->tn.lval;
604*16179Sralph 		break;
605*16179Sralph 	case COMPL:
606*16179Sralph 		p->tn.lval = ~p->tn.lval;
607*16179Sralph 		break;
608*16179Sralph 	case NOT:
609*16179Sralph 		p->tn.lval = !p->tn.lval;
610*16179Sralph 		break;
611*16179Sralph 	case LT:
612*16179Sralph 		p->tn.lval = p->tn.lval < val;
613*16179Sralph 		break;
614*16179Sralph 	case LE:
615*16179Sralph 		p->tn.lval = p->tn.lval <= val;
616*16179Sralph 		break;
617*16179Sralph 	case GT:
618*16179Sralph 		p->tn.lval = p->tn.lval > val;
619*16179Sralph 		break;
620*16179Sralph 	case GE:
621*16179Sralph 		p->tn.lval = p->tn.lval >= val;
622*16179Sralph 		break;
623*16179Sralph 	case ULT:
624*16179Sralph 		p->tn.lval = (p->tn.lval-val)<0;
625*16179Sralph 		break;
626*16179Sralph 	case ULE:
627*16179Sralph 		p->tn.lval = (p->tn.lval-val)<=0;
628*16179Sralph 		break;
629*16179Sralph 	case UGE:
630*16179Sralph 		p->tn.lval = (p->tn.lval-val)>=0;
631*16179Sralph 		break;
632*16179Sralph 	case UGT:
633*16179Sralph 		p->tn.lval = (p->tn.lval-val)>0;
634*16179Sralph 		break;
635*16179Sralph 	case EQ:
636*16179Sralph 		p->tn.lval = p->tn.lval == val;
637*16179Sralph 		break;
638*16179Sralph 	case NE:
639*16179Sralph 		p->tn.lval = p->tn.lval != val;
640*16179Sralph 		break;
641*16179Sralph 	default:
642*16179Sralph 		return(0);
643*16179Sralph 		}
644*16179Sralph 	return(1);
645*16179Sralph 	}
646*16179Sralph 
647*16179Sralph chkpun(p) register NODE *p; {
648*16179Sralph 
649*16179Sralph 	/* checks p for the existance of a pun */
650*16179Sralph 
651*16179Sralph 	/* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */
652*16179Sralph 
653*16179Sralph 	/* one case is when enumerations are used: this applies only to lint */
654*16179Sralph 	/* in the other case, one operand is a pointer, the other integer type */
655*16179Sralph 	/* we check that this integer is in fact a constant zero... */
656*16179Sralph 
657*16179Sralph 	/* in the case of ASSIGN, any assignment of pointer to integer is illegal */
658*16179Sralph 	/* this falls out, because the LHS is never 0 */
659*16179Sralph 
660*16179Sralph 	register NODE *q;
661*16179Sralph 	register t1, t2;
662*16179Sralph 	register d1, d2;
663*16179Sralph 
664*16179Sralph 	t1 = p->in.left->in.type;
665*16179Sralph 	t2 = p->in.right->in.type;
666*16179Sralph 
667*16179Sralph 	if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */
668*16179Sralph 		if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) {
669*16179Sralph 			uerror( "illegal comparison of enums" );
670*16179Sralph 			return;
671*16179Sralph 			}
672*16179Sralph 		if( t1==ENUMTY && t2==ENUMTY && p->in.left->fn.csiz==p->in.right->fn.csiz ) return;
673*16179Sralph 		werror( "enumeration type clash, operator %s", opst[p->in.op] );
674*16179Sralph 		return;
675*16179Sralph 		}
676*16179Sralph 
677*16179Sralph 	if( ISPTR(t1) || ISARY(t1) ) q = p->in.right;
678*16179Sralph 	else q = p->in.left;
679*16179Sralph 
680*16179Sralph 	if( !ISPTR(q->in.type) && !ISARY(q->in.type) ){
681*16179Sralph 		if( q->in.op != ICON || q->tn.lval != 0 ){
682*16179Sralph 			werror( "illegal combination of pointer and integer, op %s",
683*16179Sralph 				opst[p->in.op] );
684*16179Sralph 			}
685*16179Sralph 		}
686*16179Sralph 	else {
687*16179Sralph 		d1 = p->in.left->fn.cdim;
688*16179Sralph 		d2 = p->in.right->fn.cdim;
689*16179Sralph 		for( ;; ){
690*16179Sralph 			if( t1 == t2 ) {;
691*16179Sralph 				if( p->in.left->fn.csiz != p->in.right->fn.csiz ) {
692*16179Sralph 					werror( "illegal structure pointer combination" );
693*16179Sralph 					}
694*16179Sralph 				return;
695*16179Sralph 				}
696*16179Sralph 			if( ISARY(t1) || ISPTR(t1) ){
697*16179Sralph 				if( !ISARY(t2) && !ISPTR(t2) ) break;
698*16179Sralph 				if( ISARY(t1) && ISARY(t2) && dimtab[d1] != dimtab[d2] ){
699*16179Sralph 					werror( "illegal array size combination" );
700*16179Sralph 					return;
701*16179Sralph 					}
702*16179Sralph 				if( ISARY(t1) ) ++d1;
703*16179Sralph 				if( ISARY(t2) ) ++d2;
704*16179Sralph 				}
705*16179Sralph 			else break;
706*16179Sralph 			t1 = DECREF(t1);
707*16179Sralph 			t2 = DECREF(t2);
708*16179Sralph 			}
709*16179Sralph 		werror( "illegal pointer combination" );
710*16179Sralph 		}
711*16179Sralph 
712*16179Sralph 	}
713*16179Sralph 
714*16179Sralph NODE *
715*16179Sralph stref( p ) register NODE *p; {
716*16179Sralph 
717*16179Sralph 	TWORD t;
718*16179Sralph 	int d, s, dsc, align;
719*16179Sralph 	OFFSZ off;
720*16179Sralph 	register struct symtab *q;
721*16179Sralph 
722*16179Sralph 	/* make p->x */
723*16179Sralph 	/* this is also used to reference automatic variables */
724*16179Sralph 
725*16179Sralph 	q = &stab[p->in.right->tn.rval];
726*16179Sralph 	p->in.right->in.op = FREE;
727*16179Sralph 	p->in.op = FREE;
728*16179Sralph 	p = pconvert( p->in.left );
729*16179Sralph 
730*16179Sralph 	/* make p look like ptr to x */
731*16179Sralph 
732*16179Sralph 	if( !ISPTR(p->in.type)){
733*16179Sralph 		p->in.type = PTR+UNIONTY;
734*16179Sralph 		}
735*16179Sralph 
736*16179Sralph 	t = INCREF( q->stype );
737*16179Sralph 	d = q->dimoff;
738*16179Sralph 	s = q->sizoff;
739*16179Sralph 
740*16179Sralph 	p = makety( p, t, d, s );
741*16179Sralph 
742*16179Sralph 	/* compute the offset to be added */
743*16179Sralph 
744*16179Sralph 	off = q->offset;
745*16179Sralph 	dsc = q->sclass;
746*16179Sralph 
747*16179Sralph 	if( dsc & FIELD ) {  /* normalize offset */
748*16179Sralph 		align = ALINT;
749*16179Sralph 		s = INT;
750*16179Sralph 		off = (off/align)*align;
751*16179Sralph 		}
752*16179Sralph 	if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) );
753*16179Sralph 
754*16179Sralph 	p = buildtree( UNARY MUL, p, NIL );
755*16179Sralph 
756*16179Sralph 	/* if field, build field info */
757*16179Sralph 
758*16179Sralph 	if( dsc & FIELD ){
759*16179Sralph 		p = block( FLD, p, NIL, q->stype, 0, q->sizoff );
760*16179Sralph 		p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align );
761*16179Sralph 		}
762*16179Sralph 
763*16179Sralph 	return( clocal(p) );
764*16179Sralph 	}
765*16179Sralph 
766*16179Sralph notlval(p) register NODE *p; {
767*16179Sralph 
768*16179Sralph 	/* return 0 if p an lvalue, 1 otherwise */
769*16179Sralph 
770*16179Sralph 	again:
771*16179Sralph 
772*16179Sralph 	switch( p->in.op ){
773*16179Sralph 
774*16179Sralph 	case FLD:
775*16179Sralph 		p = p->in.left;
776*16179Sralph 		goto again;
777*16179Sralph 
778*16179Sralph 	case UNARY MUL:
779*16179Sralph 		/* fix the &(a=b) bug, given that a and b are structures */
780*16179Sralph 		if( p->in.left->in.op == STASG ) return( 1 );
781*16179Sralph 		/* and the f().a bug, given that f returns a structure */
782*16179Sralph 		if( p->in.left->in.op == UNARY STCALL ||
783*16179Sralph 		    p->in.left->in.op == STCALL ) return( 1 );
784*16179Sralph 	case NAME:
785*16179Sralph 	case OREG:
786*16179Sralph 		if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1);
787*16179Sralph 	case REG:
788*16179Sralph 		return(0);
789*16179Sralph 
790*16179Sralph 	default:
791*16179Sralph 		return(1);
792*16179Sralph 
793*16179Sralph 		}
794*16179Sralph 
795*16179Sralph 	}
796*16179Sralph 
797*16179Sralph NODE *
798*16179Sralph bcon( i ){ /* make a constant node with value i */
799*16179Sralph 	register NODE *p;
800*16179Sralph 
801*16179Sralph 	p = block( ICON, NIL, NIL, INT, 0, INT );
802*16179Sralph 	p->tn.lval = i;
803*16179Sralph 	p->tn.rval = NONAME;
804*16179Sralph 	return( clocal(p) );
805*16179Sralph 	}
806*16179Sralph 
807*16179Sralph NODE *
808*16179Sralph bpsize(p) register NODE *p; {
809*16179Sralph 	return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) );
810*16179Sralph 	}
811*16179Sralph 
812*16179Sralph OFFSZ
813*16179Sralph psize( p ) NODE *p; {
814*16179Sralph 	/* p is a node of type pointer; psize returns the
815*16179Sralph 	   size of the thing pointed to */
816*16179Sralph 
817*16179Sralph 	if( !ISPTR(p->in.type) ){
818*16179Sralph 		uerror( "pointer required");
819*16179Sralph 		return( SZINT );
820*16179Sralph 		}
821*16179Sralph 	/* note: no pointers to fields */
822*16179Sralph 	return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) );
823*16179Sralph 	}
824*16179Sralph 
825*16179Sralph NODE *
826*16179Sralph convert( p, f )  register NODE *p; {
827*16179Sralph 	/*  convert an operand of p
828*16179Sralph 	    f is either CVTL or CVTR
829*16179Sralph 	    operand has type int, and is converted by the size of the other side
830*16179Sralph 	    */
831*16179Sralph 
832*16179Sralph 	register NODE *q, *r;
833*16179Sralph 
834*16179Sralph 	q = (f==CVTL)?p->in.left:p->in.right;
835*16179Sralph 
836*16179Sralph 	r = block( PMCONV,
837*16179Sralph 		q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT );
838*16179Sralph 	r = clocal(r);
839*16179Sralph 	if( f == CVTL )
840*16179Sralph 		p->in.left = r;
841*16179Sralph 	else
842*16179Sralph 		p->in.right = r;
843*16179Sralph 	return(p);
844*16179Sralph 
845*16179Sralph 	}
846*16179Sralph 
847*16179Sralph econvert( p ) register NODE *p; {
848*16179Sralph 
849*16179Sralph 	/* change enums to ints, or appropriate types */
850*16179Sralph 
851*16179Sralph 	register TWORD ty;
852*16179Sralph 
853*16179Sralph 	if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) {
854*16179Sralph 		if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR;
855*16179Sralph 		else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT;
856*16179Sralph 		else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT;
857*16179Sralph 		else ty = LONG;
858*16179Sralph 		ty = ctype( ty );
859*16179Sralph 		p->fn.csiz = ty;
860*16179Sralph 		MODTYPE(p->in.type,ty);
861*16179Sralph 		if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT;
862*16179Sralph 		}
863*16179Sralph 	}
864*16179Sralph 
865*16179Sralph NODE *
866*16179Sralph pconvert( p ) register NODE *p; {
867*16179Sralph 
868*16179Sralph 	/* if p should be changed into a pointer, do so */
869*16179Sralph 
870*16179Sralph 	if( ISARY( p->in.type) ){
871*16179Sralph 		p->in.type = DECREF( p->in.type );
872*16179Sralph 		++p->fn.cdim;
873*16179Sralph 		return( buildtree( UNARY AND, p, NIL ) );
874*16179Sralph 		}
875*16179Sralph 	if( ISFTN( p->in.type) )
876*16179Sralph 		return( buildtree( UNARY AND, p, NIL ) );
877*16179Sralph 
878*16179Sralph 	return( p );
879*16179Sralph 	}
880*16179Sralph 
881*16179Sralph NODE *
882*16179Sralph oconvert(p) register NODE *p; {
883*16179Sralph 	/* convert the result itself: used for pointer and unsigned */
884*16179Sralph 
885*16179Sralph 	switch(p->in.op) {
886*16179Sralph 
887*16179Sralph 	case LE:
888*16179Sralph 	case LT:
889*16179Sralph 	case GE:
890*16179Sralph 	case GT:
891*16179Sralph 		if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) )  p->in.op += (ULE-LE);
892*16179Sralph 	case EQ:
893*16179Sralph 	case NE:
894*16179Sralph 		return( p );
895*16179Sralph 
896*16179Sralph 	case MINUS:
897*16179Sralph 		return(  clocal( block( PVCONV,
898*16179Sralph 			p, bpsize(p->in.left), INT, 0, INT ) ) );
899*16179Sralph 		}
900*16179Sralph 
901*16179Sralph 	cerror( "illegal oconvert: %d", p->in.op );
902*16179Sralph 
903*16179Sralph 	return(p);
904*16179Sralph 	}
905*16179Sralph 
906*16179Sralph NODE *
907*16179Sralph ptmatch(p)  register NODE *p; {
908*16179Sralph 
909*16179Sralph 	/* makes the operands of p agree; they are
910*16179Sralph 	   either pointers or integers, by this time */
911*16179Sralph 	/* with MINUS, the sizes must be the same */
912*16179Sralph 	/* with COLON, the types must be the same */
913*16179Sralph 
914*16179Sralph 	TWORD t1, t2, t;
915*16179Sralph 	int o, d2, d, s2, s;
916*16179Sralph 
917*16179Sralph 	o = p->in.op;
918*16179Sralph 	t = t1 = p->in.left->in.type;
919*16179Sralph 	t2 = p->in.right->in.type;
920*16179Sralph 	d = p->in.left->fn.cdim;
921*16179Sralph 	d2 = p->in.right->fn.cdim;
922*16179Sralph 	s = p->in.left->fn.csiz;
923*16179Sralph 	s2 = p->in.right->fn.csiz;
924*16179Sralph 
925*16179Sralph 	switch( o ){
926*16179Sralph 
927*16179Sralph 	case ASSIGN:
928*16179Sralph 	case RETURN:
929*16179Sralph 	case CAST:
930*16179Sralph 		{  break; }
931*16179Sralph 
932*16179Sralph 	case MINUS:
933*16179Sralph 		{  if( psize(p->in.left) != psize(p->in.right) ){
934*16179Sralph 			uerror( "illegal pointer subtraction");
935*16179Sralph 			}
936*16179Sralph 		   break;
937*16179Sralph 		   }
938*16179Sralph 	case COLON:
939*16179Sralph 		{  if( t1 != t2 ) uerror( "illegal types in :");
940*16179Sralph 		   break;
941*16179Sralph 		   }
942*16179Sralph 	default:  /* must work harder: relationals or comparisons */
943*16179Sralph 
944*16179Sralph 		if( !ISPTR(t1) ){
945*16179Sralph 			t = t2;
946*16179Sralph 			d = d2;
947*16179Sralph 			s = s2;
948*16179Sralph 			break;
949*16179Sralph 			}
950*16179Sralph 		if( !ISPTR(t2) ){
951*16179Sralph 			break;
952*16179Sralph 			}
953*16179Sralph 
954*16179Sralph 		/* both are pointers */
955*16179Sralph 		if( talign(t2,s2) < talign(t,s) ){
956*16179Sralph 			t = t2;
957*16179Sralph 			s = s2;
958*16179Sralph 			}
959*16179Sralph 		break;
960*16179Sralph 		}
961*16179Sralph 
962*16179Sralph 	p->in.left = makety( p->in.left, t, d, s );
963*16179Sralph 	p->in.right = makety( p->in.right, t, d, s );
964*16179Sralph 	if( o!=MINUS && !logop(o) ){
965*16179Sralph 
966*16179Sralph 		p->in.type = t;
967*16179Sralph 		p->fn.cdim = d;
968*16179Sralph 		p->fn.csiz = s;
969*16179Sralph 		}
970*16179Sralph 
971*16179Sralph 	return(clocal(p));
972*16179Sralph 	}
973*16179Sralph 
974*16179Sralph int tdebug = 0;
975*16179Sralph 
976*16179Sralph NODE *
977*16179Sralph tymatch(p)  register NODE *p; {
978*16179Sralph 
979*16179Sralph 	/* satisfy the types of various arithmetic binary ops */
980*16179Sralph 
981*16179Sralph 	/* rules are:
982*16179Sralph 		if assignment, op, type of LHS
983*16179Sralph 		if any float or doubles, make double
984*16179Sralph 		if any longs, make long
985*16179Sralph 		otherwise, make int
986*16179Sralph 		if either operand is unsigned, the result is...
987*16179Sralph 	*/
988*16179Sralph 
989*16179Sralph 	register TWORD t1, t2, t, tu;
990*16179Sralph 	register o, u;
991*16179Sralph 
992*16179Sralph 	o = p->in.op;
993*16179Sralph 
994*16179Sralph 	t1 = p->in.left->in.type;
995*16179Sralph 	t2 = p->in.right->in.type;
996*16179Sralph 	if( (t1==UNDEF || t2==UNDEF) && o!=CAST )
997*16179Sralph 		uerror("void type illegal in expression");
998*16179Sralph 
999*16179Sralph 	u = 0;
1000*16179Sralph 	if( ISUNSIGNED(t1) ){
1001*16179Sralph 		u = 1;
1002*16179Sralph 		t1 = DEUNSIGN(t1);
1003*16179Sralph 		}
1004*16179Sralph 	if( ISUNSIGNED(t2) ){
1005*16179Sralph 		u = 1;
1006*16179Sralph 		t2 = DEUNSIGN(t2);
1007*16179Sralph 		}
1008*16179Sralph 
1009*16179Sralph 	if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT;
1010*16179Sralph 	if( t2 == CHAR || t2 == SHORT ) t2 = INT;
1011*16179Sralph 
1012*16179Sralph 	if( t1==DOUBLE || t1==FLOAT || t2==DOUBLE || t2==FLOAT ) t = DOUBLE;
1013*16179Sralph 	else if( t1==LONG || t2==LONG ) t = LONG;
1014*16179Sralph 	else t = INT;
1015*16179Sralph 
1016*16179Sralph 	if( asgop(o) ){
1017*16179Sralph 		tu = p->in.left->in.type;
1018*16179Sralph 		t = t1;
1019*16179Sralph 		}
1020*16179Sralph 	else {
1021*16179Sralph 		tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t;
1022*16179Sralph 		}
1023*16179Sralph 
1024*16179Sralph 	/* because expressions have values that are at least as wide
1025*16179Sralph 	   as INT or UNSIGNED, the only conversions needed
1026*16179Sralph 	   are those involving FLOAT/DOUBLE, and those
1027*16179Sralph 	   from LONG to INT and ULONG to UNSIGNED */
1028*16179Sralph 
1029*16179Sralph 	if( t != t1 ) p->in.left = makety( p->in.left, tu, 0, (int)tu );
1030*16179Sralph 
1031*16179Sralph 	if( t != t2 || o==CAST ) p->in.right = makety( p->in.right, tu, 0, (int)tu );
1032*16179Sralph 
1033*16179Sralph 	if( asgop(o) ){
1034*16179Sralph 		p->in.type = p->in.left->in.type;
1035*16179Sralph 		p->fn.cdim = p->in.left->fn.cdim;
1036*16179Sralph 		p->fn.csiz = p->in.left->fn.csiz;
1037*16179Sralph 		}
1038*16179Sralph 	else if( !logop(o) ){
1039*16179Sralph 		p->in.type = tu;
1040*16179Sralph 		p->fn.cdim = 0;
1041*16179Sralph 		p->fn.csiz = t;
1042*16179Sralph 		}
1043*16179Sralph 
1044*16179Sralph # ifndef BUG1
1045*16179Sralph 	if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu );
1046*16179Sralph # endif
1047*16179Sralph 
1048*16179Sralph 	return(p);
1049*16179Sralph 	}
1050*16179Sralph 
1051*16179Sralph NODE *
1052*16179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; {
1053*16179Sralph 	/* make p into type t by inserting a conversion */
1054*16179Sralph 
1055*16179Sralph 	if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p);
1056*16179Sralph 	if( t == p->in.type ){
1057*16179Sralph 		p->fn.cdim = d;
1058*16179Sralph 		p->fn.csiz = s;
1059*16179Sralph 		return( p );
1060*16179Sralph 		}
1061*16179Sralph 
1062*16179Sralph 	if( t & TMASK ){
1063*16179Sralph 		/* non-simple type */
1064*16179Sralph 		return( block( PCONV, p, NIL, t, d, s ) );
1065*16179Sralph 		}
1066*16179Sralph 
1067*16179Sralph 	if( p->in.op == ICON ){
1068*16179Sralph 		if( t==DOUBLE||t==FLOAT ){
1069*16179Sralph 			p->in.op = FCON;
1070*16179Sralph 			if( ISUNSIGNED(p->in.type) ){
1071*16179Sralph 				p->fpn.dval = /* (unsigned CONSZ) */ p->tn.lval;
1072*16179Sralph 				}
1073*16179Sralph 			else {
1074*16179Sralph 				p->fpn.dval = p->tn.lval;
1075*16179Sralph 				}
1076*16179Sralph 
1077*16179Sralph 			p->in.type = p->fn.csiz = t;
1078*16179Sralph 			return( clocal(p) );
1079*16179Sralph 			}
1080*16179Sralph 		}
1081*16179Sralph 
1082*16179Sralph 	return( block( SCONV, p, NIL, t, d, s ) );
1083*16179Sralph 
1084*16179Sralph 	}
1085*16179Sralph 
1086*16179Sralph NODE *
1087*16179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; {
1088*16179Sralph 
1089*16179Sralph 	register NODE *p;
1090*16179Sralph 
1091*16179Sralph 	p = talloc();
1092*16179Sralph 	p->in.op = o;
1093*16179Sralph 	p->in.left = l;
1094*16179Sralph 	p->in.right = r;
1095*16179Sralph 	p->in.type = t;
1096*16179Sralph 	p->fn.cdim = d;
1097*16179Sralph 	p->fn.csiz = s;
1098*16179Sralph 	return(p);
1099*16179Sralph 	}
1100*16179Sralph 
1101*16179Sralph icons(p) register NODE *p; {
1102*16179Sralph 	/* if p is an integer constant, return its value */
1103*16179Sralph 	int val;
1104*16179Sralph 
1105*16179Sralph 	if( p->in.op != ICON ){
1106*16179Sralph 		uerror( "constant expected");
1107*16179Sralph 		val = 1;
1108*16179Sralph 		}
1109*16179Sralph 	else {
1110*16179Sralph 		val = p->tn.lval;
1111*16179Sralph 		if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" );
1112*16179Sralph 		}
1113*16179Sralph 	tfree( p );
1114*16179Sralph 	return(val);
1115*16179Sralph 	}
1116*16179Sralph 
1117*16179Sralph /* 	the intent of this table is to examine the
1118*16179Sralph 	operators, and to check them for
1119*16179Sralph 	correctness.
1120*16179Sralph 
1121*16179Sralph 	The table is searched for the op and the
1122*16179Sralph 	modified type (where this is one of the
1123*16179Sralph 	types INT (includes char and short), LONG,
1124*16179Sralph 	DOUBLE (includes FLOAT), and POINTER
1125*16179Sralph 
1126*16179Sralph 	The default action is to make the node type integer
1127*16179Sralph 
1128*16179Sralph 	The actions taken include:
1129*16179Sralph 		PUN	  check for puns
1130*16179Sralph 		CVTL	  convert the left operand
1131*16179Sralph 		CVTR	  convert the right operand
1132*16179Sralph 		TYPL	  the type is determined by the left operand
1133*16179Sralph 		TYPR	  the type is determined by the right operand
1134*16179Sralph 		TYMATCH	  force type of left and right to match, by inserting conversions
1135*16179Sralph 		PTMATCH	  like TYMATCH, but for pointers
1136*16179Sralph 		LVAL	  left operand must be lval
1137*16179Sralph 		CVTO	  convert the op
1138*16179Sralph 		NCVT	  do not convert the operands
1139*16179Sralph 		OTHER	  handled by code
1140*16179Sralph 		NCVTR	  convert the left operand, not the right...
1141*16179Sralph 
1142*16179Sralph 	*/
1143*16179Sralph 
1144*16179Sralph # define MINT 01  /* integer */
1145*16179Sralph # define MDBI 02   /* integer or double */
1146*16179Sralph # define MSTR 04  /* structure */
1147*16179Sralph # define MPTR 010  /* pointer */
1148*16179Sralph # define MPTI 020  /* pointer or integer */
1149*16179Sralph # define MENU 040 /* enumeration variable or member */
1150*16179Sralph 
1151*16179Sralph opact( p )  NODE *p; {
1152*16179Sralph 
1153*16179Sralph 	register mt12, mt1, mt2, o;
1154*16179Sralph 
1155*16179Sralph 	mt12 = 0;
1156*16179Sralph 
1157*16179Sralph 	switch( optype(o=p->in.op) ){
1158*16179Sralph 
1159*16179Sralph 	case BITYPE:
1160*16179Sralph 		mt12=mt2 = moditype( p->in.right->in.type );
1161*16179Sralph 	case UTYPE:
1162*16179Sralph 		mt12 &= (mt1 = moditype( p->in.left->in.type ));
1163*16179Sralph 
1164*16179Sralph 		}
1165*16179Sralph 
1166*16179Sralph 	switch( o ){
1167*16179Sralph 
1168*16179Sralph 	case NAME :
1169*16179Sralph 	case STRING :
1170*16179Sralph 	case ICON :
1171*16179Sralph 	case FCON :
1172*16179Sralph 	case CALL :
1173*16179Sralph 	case UNARY CALL:
1174*16179Sralph 	case UNARY MUL:
1175*16179Sralph 		{  return( OTHER ); }
1176*16179Sralph 	case UNARY MINUS:
1177*16179Sralph 		if( mt1 & MDBI ) return( TYPL );
1178*16179Sralph 		break;
1179*16179Sralph 
1180*16179Sralph 	case COMPL:
1181*16179Sralph 		if( mt1 & MINT ) return( TYPL );
1182*16179Sralph 		break;
1183*16179Sralph 
1184*16179Sralph 	case UNARY AND:
1185*16179Sralph 		{  return( NCVT+OTHER ); }
1186*16179Sralph 	case INIT:
1187*16179Sralph 	case CM:
1188*16179Sralph 	case NOT:
1189*16179Sralph 	case CBRANCH:
1190*16179Sralph 	case ANDAND:
1191*16179Sralph 	case OROR:
1192*16179Sralph 		return( 0 );
1193*16179Sralph 
1194*16179Sralph 	case MUL:
1195*16179Sralph 	case DIV:
1196*16179Sralph 		if( mt12 & MDBI ) return( TYMATCH );
1197*16179Sralph 		break;
1198*16179Sralph 
1199*16179Sralph 	case MOD:
1200*16179Sralph 	case AND:
1201*16179Sralph 	case OR:
1202*16179Sralph 	case ER:
1203*16179Sralph 		if( mt12 & MINT ) return( TYMATCH );
1204*16179Sralph 		break;
1205*16179Sralph 
1206*16179Sralph 	case LS:
1207*16179Sralph 	case RS:
1208*16179Sralph 		if( mt12 & MINT ) return( TYMATCH+OTHER );
1209*16179Sralph 		break;
1210*16179Sralph 
1211*16179Sralph 	case EQ:
1212*16179Sralph 	case NE:
1213*16179Sralph 	case LT:
1214*16179Sralph 	case LE:
1215*16179Sralph 	case GT:
1216*16179Sralph 	case GE:
1217*16179Sralph 		if( (mt1&MENU)||(mt2&MENU) ) return( PTMATCH+PUN+NCVT );
1218*16179Sralph 		if( mt12 & MDBI ) return( TYMATCH+CVTO );
1219*16179Sralph 		else if( mt12 & MPTR ) return( PTMATCH+PUN );
1220*16179Sralph 		else if( mt12 & MPTI ) return( PTMATCH+PUN );
1221*16179Sralph 		else break;
1222*16179Sralph 
1223*16179Sralph 	case QUEST:
1224*16179Sralph 	case COMOP:
1225*16179Sralph 		if( mt2&MENU ) return( TYPR+NCVTR );
1226*16179Sralph 		return( TYPR );
1227*16179Sralph 
1228*16179Sralph 	case STREF:
1229*16179Sralph 		return( NCVTR+OTHER );
1230*16179Sralph 
1231*16179Sralph 	case FORCE:
1232*16179Sralph 		return( TYPL );
1233*16179Sralph 
1234*16179Sralph 	case COLON:
1235*16179Sralph 		if( mt12 & MENU ) return( NCVT+PUN+PTMATCH );
1236*16179Sralph 		else if( mt12 & MDBI ) return( TYMATCH );
1237*16179Sralph 		else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
1238*16179Sralph 		else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
1239*16179Sralph 		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
1240*16179Sralph 		else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
1241*16179Sralph 		break;
1242*16179Sralph 
1243*16179Sralph 	case ASSIGN:
1244*16179Sralph 	case RETURN:
1245*16179Sralph 		if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
1246*16179Sralph 	case CAST:
1247*16179Sralph 		if(o==CAST && mt1==0)return(TYPL+TYMATCH);
1248*16179Sralph 		if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
1249*16179Sralph 		else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
1250*16179Sralph 		else if( mt12 == 0 ) break;
1251*16179Sralph 		else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
1252*16179Sralph 		else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
1253*16179Sralph 		break;
1254*16179Sralph 
1255*16179Sralph 	case ASG LS:
1256*16179Sralph 	case ASG RS:
1257*16179Sralph 		if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
1258*16179Sralph 		break;
1259*16179Sralph 
1260*16179Sralph 	case ASG MUL:
1261*16179Sralph 	case ASG DIV:
1262*16179Sralph 		if( mt12 & MDBI ) return( LVAL+TYMATCH );
1263*16179Sralph 		break;
1264*16179Sralph 
1265*16179Sralph 	case ASG MOD:
1266*16179Sralph 	case ASG AND:
1267*16179Sralph 	case ASG OR:
1268*16179Sralph 	case ASG ER:
1269*16179Sralph 		if( mt12 & MINT ) return( LVAL+TYMATCH );
1270*16179Sralph 		break;
1271*16179Sralph 
1272*16179Sralph 	case ASG PLUS:
1273*16179Sralph 	case ASG MINUS:
1274*16179Sralph 	case INCR:
1275*16179Sralph 	case DECR:
1276*16179Sralph 		if( mt12 & MDBI ) return( TYMATCH+LVAL );
1277*16179Sralph 		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR );
1278*16179Sralph 		break;
1279*16179Sralph 
1280*16179Sralph 	case MINUS:
1281*16179Sralph 		if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN );
1282*16179Sralph 		if( mt2 & MPTR ) break;
1283*16179Sralph 	case PLUS:
1284*16179Sralph 		if( mt12 & MDBI ) return( TYMATCH );
1285*16179Sralph 		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR );
1286*16179Sralph 		else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL );
1287*16179Sralph 
1288*16179Sralph 		}
1289*16179Sralph 	uerror( "operands of %s have incompatible types", opst[o] );
1290*16179Sralph 	return( NCVT );
1291*16179Sralph 	}
1292*16179Sralph 
1293*16179Sralph moditype( ty ) TWORD ty; {
1294*16179Sralph 
1295*16179Sralph 	switch( ty ){
1296*16179Sralph 
1297*16179Sralph 	case TVOID:
1298*16179Sralph 	case UNDEF:
1299*16179Sralph 		return(0); /* type is void */
1300*16179Sralph 	case ENUMTY:
1301*16179Sralph 	case MOETY:
1302*16179Sralph 		return( MENU );
1303*16179Sralph 
1304*16179Sralph 	case STRTY:
1305*16179Sralph 	case UNIONTY:
1306*16179Sralph 		return( MSTR );
1307*16179Sralph 
1308*16179Sralph 	case CHAR:
1309*16179Sralph 	case SHORT:
1310*16179Sralph 	case UCHAR:
1311*16179Sralph 	case USHORT:
1312*16179Sralph 		return( MINT|MPTI|MDBI );
1313*16179Sralph 	case UNSIGNED:
1314*16179Sralph 	case ULONG:
1315*16179Sralph 	case INT:
1316*16179Sralph 	case LONG:
1317*16179Sralph 		return( MINT|MDBI|MPTI );
1318*16179Sralph 	case FLOAT:
1319*16179Sralph 	case DOUBLE:
1320*16179Sralph 		return( MDBI );
1321*16179Sralph 	default:
1322*16179Sralph 		return( MPTR|MPTI );
1323*16179Sralph 
1324*16179Sralph 		}
1325*16179Sralph 	}
1326*16179Sralph 
1327*16179Sralph NODE *
1328*16179Sralph doszof( p )  register NODE *p; {
1329*16179Sralph 	/* do sizeof p */
1330*16179Sralph 	int i;
1331*16179Sralph 
1332*16179Sralph 	/* whatever is the meaning of this if it is a bitfield? */
1333*16179Sralph 	i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR;
1334*16179Sralph 
1335*16179Sralph 	tfree(p);
1336*16179Sralph 	if( i <= 0 ) werror( "sizeof returns 0" );
1337*16179Sralph 	return( bcon( i ) );
1338*16179Sralph 	}
1339*16179Sralph 
1340*16179Sralph # ifndef BUG2
1341*16179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; {
1342*16179Sralph 	register ty;
1343*16179Sralph 
1344*16179Sralph 	*a = *b = down+1;
1345*16179Sralph 	while( down > 1 ){
1346*16179Sralph 		printf( "\t" );
1347*16179Sralph 		down -= 2;
1348*16179Sralph 		}
1349*16179Sralph 	if( down ) printf( "    " );
1350*16179Sralph 
1351*16179Sralph 	ty = optype( p->in.op );
1352*16179Sralph 
1353*16179Sralph 	printf("%o) %s, ", p, opst[p->in.op] );
1354*16179Sralph 	if( ty == LTYPE ){
1355*16179Sralph 		printf( CONFMT, p->tn.lval );
1356*16179Sralph 		printf( ", %d, ", p->tn.rval );
1357*16179Sralph 		}
1358*16179Sralph 	tprint( p->in.type );
1359*16179Sralph 	printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz );
1360*16179Sralph 	}
1361*16179Sralph # endif
1362*16179Sralph 
1363*16179Sralph prtdcon( p ) register NODE *p; {
1364*16179Sralph 	int i;
1365*16179Sralph 
1366*16179Sralph 	if( p->in.op == FCON ){
1367*16179Sralph 		locctr( DATA );
1368*16179Sralph 		defalign( ALDOUBLE );
1369*16179Sralph 		deflab( i = getlab() );
1370*16179Sralph 		fincode( p->fpn.dval, SZDOUBLE );
1371*16179Sralph 		p->tn.lval = 0;
1372*16179Sralph 		p->tn.rval = -i;
1373*16179Sralph 		p->in.type = DOUBLE;
1374*16179Sralph 		p->in.op = NAME;
1375*16179Sralph 		}
1376*16179Sralph 	}
1377*16179Sralph 
1378*16179Sralph 
1379*16179Sralph int edebug = 0;
1380*16179Sralph ecomp( p ) register NODE *p; {
1381*16179Sralph # ifndef BUG2
1382*16179Sralph 	if( edebug ) fwalk( p, eprint, 0 );
1383*16179Sralph # endif
1384*16179Sralph 	if( !reached ){
1385*16179Sralph 		werror( "statement not reached" );
1386*16179Sralph 		reached = 1;
1387*16179Sralph 		}
1388*16179Sralph 	p = optim(p);
1389*16179Sralph 	walkf( p, prtdcon );
1390*16179Sralph 	locctr( PROG );
1391*16179Sralph 	ecode( p );
1392*16179Sralph 	tfree(p);
1393*16179Sralph 	}
1394*16179Sralph 
1395*16179Sralph # ifdef STDPRTREE
1396*16179Sralph # ifndef ONEPASS
1397*16179Sralph 
1398*16179Sralph prtree(p) register NODE *p; {
1399*16179Sralph 
1400*16179Sralph 	register struct symtab *q;
1401*16179Sralph 	register ty;
1402*16179Sralph 
1403*16179Sralph # ifdef MYPRTREE
1404*16179Sralph 	MYPRTREE(p);  /* local action can be taken here; then return... */
1405*16179Sralph #endif
1406*16179Sralph 
1407*16179Sralph 	ty = optype(p->in.op);
1408*16179Sralph 
1409*16179Sralph 	printf( "%d\t", p->in.op );
1410*16179Sralph 
1411*16179Sralph 	if( ty == LTYPE ) {
1412*16179Sralph 		printf( CONFMT, p->tn.lval );
1413*16179Sralph 		printf( "\t" );
1414*16179Sralph 		}
1415*16179Sralph 	if( ty != BITYPE ) {
1416*16179Sralph 		if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" );
1417*16179Sralph 		else printf( "%d\t", p->tn.rval );
1418*16179Sralph 		}
1419*16179Sralph 
1420*16179Sralph 	printf( "%o\t", p->in.type );
1421*16179Sralph 
1422*16179Sralph 	/* handle special cases */
1423*16179Sralph 
1424*16179Sralph 	switch( p->in.op ){
1425*16179Sralph 
1426*16179Sralph 	case NAME:
1427*16179Sralph 	case ICON:
1428*16179Sralph 		/* print external name */
1429*16179Sralph 		if( p->tn.rval == NONAME ) printf( "\n" );
1430*16179Sralph 		else if( p->tn.rval >= 0 ){
1431*16179Sralph 			q = &stab[p->tn.rval];
1432*16179Sralph 			printf(  "%s\n", exname(q->sname) );
1433*16179Sralph 			}
1434*16179Sralph 		else { /* label */
1435*16179Sralph 			printf( LABFMT, -p->tn.rval );
1436*16179Sralph 			}
1437*16179Sralph 		break;
1438*16179Sralph 
1439*16179Sralph 	case STARG:
1440*16179Sralph 	case STASG:
1441*16179Sralph 	case STCALL:
1442*16179Sralph 	case UNARY STCALL:
1443*16179Sralph 		/* print out size */
1444*16179Sralph 		/* use lhs size, in order to avoid hassles with the structure `.' operator */
1445*16179Sralph 
1446*16179Sralph 		/* note: p->in.left not a field... */
1447*16179Sralph 		printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) );
1448*16179Sralph 		printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) );
1449*16179Sralph 		break;
1450*16179Sralph 
1451*16179Sralph 	default:
1452*16179Sralph 		printf(  "\n" );
1453*16179Sralph 		}
1454*16179Sralph 
1455*16179Sralph 	if( ty != LTYPE ) prtree( p->in.left );
1456*16179Sralph 	if( ty == BITYPE ) prtree( p->in.right );
1457*16179Sralph 
1458*16179Sralph 	}
1459*16179Sralph 
1460*16179Sralph # else
1461*16179Sralph 
1462*16179Sralph p2tree(p) register NODE *p; {
1463*16179Sralph 	register ty;
1464*16179Sralph 
1465*16179Sralph # ifdef MYP2TREE
1466*16179Sralph 	MYP2TREE(p);  /* local action can be taken here; then return... */
1467*16179Sralph # endif
1468*16179Sralph 
1469*16179Sralph 	ty = optype(p->in.op);
1470*16179Sralph 
1471*16179Sralph 	switch( p->in.op ){
1472*16179Sralph 
1473*16179Sralph 	case NAME:
1474*16179Sralph 	case ICON:
1475*16179Sralph #ifndef FLEXNAMES
1476*16179Sralph 		if( p->tn.rval == NONAME ) p->in.name[0] = '\0';
1477*16179Sralph #else
1478*16179Sralph 		if( p->tn.rval == NONAME ) p->in.name = "";
1479*16179Sralph #endif
1480*16179Sralph 		else if( p->tn.rval >= 0 ){ /* copy name from exname */
1481*16179Sralph 			register char *cp;
1482*16179Sralph 			register i;
1483*16179Sralph 			cp = exname( stab[p->tn.rval].sname );
1484*16179Sralph #ifndef FLEXNAMES
1485*16179Sralph 			for( i=0; i<NCHNAM; ++i ) p->in.name[i] = *cp++;
1486*16179Sralph #else
1487*16179Sralph 			p->in.name = tstr(cp);
1488*16179Sralph #endif
1489*16179Sralph 			}
1490*16179Sralph #ifndef FLEXNAMES
1491*16179Sralph 		else sprintf( p->in.name, LABFMT, -p->tn.rval );
1492*16179Sralph #else
1493*16179Sralph 		else {
1494*16179Sralph 			char temp[32];
1495*16179Sralph 			sprintf( temp, LABFMT, -p->tn.rval );
1496*16179Sralph 			p->in.name = tstr(temp);
1497*16179Sralph 		}
1498*16179Sralph #endif
1499*16179Sralph 		break;
1500*16179Sralph 
1501*16179Sralph 	case STARG:
1502*16179Sralph 	case STASG:
1503*16179Sralph 	case STCALL:
1504*16179Sralph 	case UNARY STCALL:
1505*16179Sralph 		/* set up size parameters */
1506*16179Sralph 		p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR;
1507*16179Sralph 		p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR;
1508*16179Sralph 		break;
1509*16179Sralph 
1510*16179Sralph 	case REG:
1511*16179Sralph 		rbusy( p->tn.rval, p->in.type );
1512*16179Sralph 	default:
1513*16179Sralph #ifndef FLEXNAMES
1514*16179Sralph 		p->in.name[0] = '\0';
1515*16179Sralph #else
1516*16179Sralph 		p->in.name = "";
1517*16179Sralph #endif
1518*16179Sralph 		}
1519*16179Sralph 
1520*16179Sralph 	p->in.rall = NOPREF;
1521*16179Sralph 
1522*16179Sralph 	if( ty != LTYPE ) p2tree( p->in.left );
1523*16179Sralph 	if( ty == BITYPE ) p2tree( p->in.right );
1524*16179Sralph 	}
1525*16179Sralph 
1526*16179Sralph # endif
1527*16179Sralph # endif
1528