117749Sralph #ifndef lint 2*32854Sdonn static char *sccsid ="@(#)trees.c 4.29 (Berkeley) 12/10/87"; 317749Sralph #endif 417749Sralph 518396Sralph # include "pass1.h" 616179Sralph 724408Smckusick # include <setjmp.h> 824408Smckusick 917749Sralph int bdebug = 0; 1017749Sralph int adebug = 0; 1117749Sralph extern ddebug; 1217749Sralph extern eprint(); 1317749Sralph 1416179Sralph /* corrections when in violation of lint */ 1516179Sralph 1616179Sralph /* some special actions, used in finding the type of nodes */ 1716179Sralph # define NCVT 01 1816179Sralph # define PUN 02 1916179Sralph # define TYPL 04 2016179Sralph # define TYPR 010 2116179Sralph # define TYMATCH 040 2216179Sralph # define LVAL 0100 2316179Sralph # define CVTO 0200 2416179Sralph # define CVTL 0400 2516179Sralph # define CVTR 01000 2616179Sralph # define PTMATCH 02000 2716179Sralph # define OTHER 04000 2816179Sralph # define NCVTR 010000 2916179Sralph 3017749Sralph #ifndef BUG1 3117749Sralph printact(t, acts) 3217749Sralph NODE *t; 3317749Sralph int acts; 3417749Sralph { 3517749Sralph static struct actions { 3617749Sralph int a_bit; 3717749Sralph char *a_name; 3817749Sralph } actions[] = { 3917749Sralph { PUN, "PUN" }, 4017749Sralph { CVTL, "CVTL" }, 4117749Sralph { CVTR, "CVTR" }, 4217749Sralph { TYPL, "TYPL" }, 4317749Sralph { TYPR, "TYPR" }, 4417749Sralph { TYMATCH, "TYMATCH" }, 4517749Sralph { PTMATCH, "PTMATCH" }, 4617749Sralph { LVAL, "LVAL" }, 4717749Sralph { CVTO, "CVTO" }, 4817749Sralph { NCVT, "NCVT" }, 4917749Sralph { OTHER, "OTHER" }, 5017749Sralph { NCVTR, "NCVTR" }, 5117749Sralph { 0 } 5217749Sralph }; 5317749Sralph register struct actions *p; 5417749Sralph char *sep = " "; 5517749Sralph 5617749Sralph printf("actions"); 5717749Sralph for (p = actions; p->a_name; p++) 5817749Sralph if (p->a_bit & acts) { 5917749Sralph printf("%s%s", sep, p->a_name); 6017749Sralph sep = "|"; 6117749Sralph } 6217749Sralph if (!bdebug) { 6317749Sralph printf(" for:\n"); 6417749Sralph fwalk(t, eprint, 0); 6517749Sralph } else 6617749Sralph putchar('\n'); 6717749Sralph } 6817749Sralph #endif 6917749Sralph 7016179Sralph /* node conventions: 7116179Sralph 7216179Sralph NAME: rval>0 is stab index for external 7316179Sralph rval<0 is -inlabel number 7416179Sralph lval is offset in bits 7516179Sralph ICON: lval has the value 7616179Sralph rval has the STAB index, or - label number, 7716179Sralph if a name whose address is in the constant 7816179Sralph rval = NONAME means no name 7916179Sralph REG: rval is reg. identification cookie 8016179Sralph 8116179Sralph */ 8216179Sralph 8316179Sralph NODE * 8416179Sralph buildtree( o, l, r ) register NODE *l, *r; { 8516179Sralph register NODE *p, *q; 8616179Sralph register actions; 8716179Sralph register opty; 8816179Sralph register struct symtab *sp; 8916179Sralph register NODE *lr, *ll; 9017749Sralph NODE *fixargs(); 9116179Sralph int i; 9216179Sralph 9316179Sralph # ifndef BUG1 9416179Sralph if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r ); 9516179Sralph # endif 9616179Sralph opty = optype(o); 9716179Sralph 9816179Sralph /* check for constants */ 9916179Sralph 10016179Sralph if( opty == UTYPE && l->in.op == ICON ){ 10116179Sralph 10216179Sralph switch( o ){ 10316179Sralph 10416179Sralph case NOT: 10516179Sralph if( hflag ) werror( "constant argument to NOT" ); 10616179Sralph case UNARY MINUS: 10716179Sralph case COMPL: 10816179Sralph if( conval( l, o, l ) ) return(l); 10916179Sralph break; 11016179Sralph 11116179Sralph } 11216179Sralph } 11316179Sralph 11416179Sralph else if( o==UNARY MINUS && l->in.op==FCON ){ 11517749Sralph l->fpn.fval = -l->fpn.fval; 11616179Sralph return(l); 11716179Sralph } 11816179Sralph 11917749Sralph else if( o==UNARY MINUS && l->in.op==DCON ){ 12017749Sralph l->dpn.dval = -l->dpn.dval; 12117749Sralph return(l); 12217749Sralph } 12317749Sralph 12416179Sralph else if( o==QUEST && l->in.op==ICON ) { 12516179Sralph l->in.op = FREE; 12616179Sralph r->in.op = FREE; 12716179Sralph if( l->tn.lval ){ 12816179Sralph tfree( r->in.right ); 12916179Sralph return( r->in.left ); 13016179Sralph } 13116179Sralph else { 13216179Sralph tfree( r->in.left ); 13316179Sralph return( r->in.right ); 13416179Sralph } 13516179Sralph } 13616179Sralph 13716179Sralph else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn; 13816179Sralph 13916179Sralph else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ){ 14016179Sralph 14116179Sralph switch( o ){ 14216179Sralph 14316179Sralph case ULT: 14416179Sralph case UGT: 14516179Sralph case ULE: 14616179Sralph case UGE: 14716179Sralph case LT: 14816179Sralph case GT: 14916179Sralph case LE: 15016179Sralph case GE: 15116179Sralph case EQ: 15216179Sralph case NE: 15332851Sdonn if( l->in.type == ENUMTY && r->in.type == ENUMTY ){ 15432851Sdonn p = block( o, l, r, INT, 0, INT ); 15532840Sdonn chkpun( p ); 15632851Sdonn p->in.op = FREE; 15732851Sdonn } 15832840Sdonn 15916179Sralph case ANDAND: 16016179Sralph case OROR: 16116179Sralph case CBRANCH: 16216179Sralph 16316179Sralph ccwarn: 16416179Sralph if( hflag ) werror( "constant in conditional context" ); 16516179Sralph 16616179Sralph case PLUS: 16716179Sralph case MINUS: 16816179Sralph case MUL: 16916179Sralph case DIV: 17016179Sralph case MOD: 17116179Sralph case AND: 17216179Sralph case OR: 17316179Sralph case ER: 17416179Sralph case LS: 17516179Sralph case RS: 17616179Sralph if( conval( l, o, r ) ) { 17716179Sralph r->in.op = FREE; 17816179Sralph return(l); 17916179Sralph } 18016179Sralph break; 18116179Sralph } 18216179Sralph } 18324408Smckusick else if (opty == BITYPE && 18424408Smckusick (l->in.op == FCON || l->in.op == DCON || l->in.op == ICON) && 18524408Smckusick (r->in.op == FCON || r->in.op == DCON || r->in.op == ICON)) { 18624408Smckusick if (o == PLUS || o == MINUS || o == MUL || o == DIV) { 18724408Smckusick extern int fpe_count; 18824408Smckusick extern jmp_buf gotfpe; 18916179Sralph 19024408Smckusick fpe_count = 0; 19124408Smckusick if (setjmp(gotfpe)) 19224408Smckusick goto treatfpe; 19317749Sralph if (l->in.op == ICON) 19417749Sralph l->dpn.dval = l->tn.lval; 19524408Smckusick else if (l->in.op == FCON) 19624408Smckusick l->dpn.dval = l->fpn.fval; 19717749Sralph if (r->in.op == ICON) 19817749Sralph r->dpn.dval = r->tn.lval; 19924408Smckusick else if (r->in.op == FCON) 20024408Smckusick r->dpn.dval = r->fpn.fval; 20117749Sralph switch (o) { 20217749Sralph 20317749Sralph case PLUS: 20417749Sralph l->dpn.dval += r->dpn.dval; 20524408Smckusick break; 20617749Sralph 20717749Sralph case MINUS: 20817749Sralph l->dpn.dval -= r->dpn.dval; 20924408Smckusick break; 21017749Sralph 21117749Sralph case MUL: 21217749Sralph l->dpn.dval *= r->dpn.dval; 21324408Smckusick break; 21417749Sralph 21517749Sralph case DIV: 21617749Sralph if (r->dpn.dval == 0) 21717749Sralph uerror("division by 0."); 21817749Sralph else 21917749Sralph l->dpn.dval /= r->dpn.dval; 22024408Smckusick break; 22124408Smckusick } 22224408Smckusick treatfpe: 22324408Smckusick if (fpe_count > 0) { 22424408Smckusick uerror("floating point exception in constant expression"); 22524408Smckusick l->dpn.dval = 1.0; /* Fairly harmless */ 22624408Smckusick } 22724408Smckusick fpe_count = -1; 22824408Smckusick l->in.op = DCON; 22924408Smckusick l->in.type = l->fn.csiz = DOUBLE; 23024408Smckusick r->in.op = FREE; 23124408Smckusick return (l); 23216179Sralph } 23324408Smckusick } 23416179Sralph 23524408Smckusick /* it's real; we must make a new node */ 23616179Sralph 23716179Sralph p = block( o, l, r, INT, 0, INT ); 23816179Sralph 23916179Sralph actions = opact(p); 24017749Sralph #ifndef BUG1 24117749Sralph if (adebug) 24217749Sralph printact(p, actions); 24317749Sralph #endif 24416179Sralph 24516179Sralph if( actions&LVAL ){ /* check left descendent */ 24616179Sralph if( notlval(p->in.left) ) { 24732849Sdonn uerror( "illegal lvalue operand of assignment operator" ); 24816179Sralph } 24916179Sralph } 25016179Sralph 25116179Sralph if( actions & NCVTR ){ 25216179Sralph p->in.left = pconvert( p->in.left ); 25316179Sralph } 25416179Sralph else if( !(actions & NCVT ) ){ 25516179Sralph switch( opty ){ 25616179Sralph 25716179Sralph case BITYPE: 25816179Sralph p->in.right = pconvert( p->in.right ); 25916179Sralph case UTYPE: 26016179Sralph p->in.left = pconvert( p->in.left ); 26116179Sralph 26216179Sralph } 26316179Sralph } 26416179Sralph 26516179Sralph if( (actions&PUN) && (o!=CAST||cflag) ){ 26616179Sralph chkpun(p); 26716179Sralph } 26816179Sralph 26916179Sralph if( actions & (TYPL|TYPR) ){ 27016179Sralph 27116179Sralph q = (actions&TYPL) ? p->in.left : p->in.right; 27216179Sralph 27316179Sralph p->in.type = q->in.type; 27416179Sralph p->fn.cdim = q->fn.cdim; 27516179Sralph p->fn.csiz = q->fn.csiz; 27616179Sralph } 27716179Sralph 27816179Sralph if( actions & CVTL ) p = convert( p, CVTL ); 27916179Sralph if( actions & CVTR ) p = convert( p, CVTR ); 28016179Sralph if( actions & TYMATCH ) p = tymatch(p); 28116179Sralph if( actions & PTMATCH ) p = ptmatch(p); 28216179Sralph 28316179Sralph if( actions & OTHER ){ 28416179Sralph l = p->in.left; 28516179Sralph r = p->in.right; 28616179Sralph 28716179Sralph switch(o){ 28816179Sralph 28916179Sralph case NAME: 29016179Sralph sp = &stab[idname]; 29116179Sralph if( sp->stype == UNDEF ){ 29216179Sralph #ifndef FLEXNAMES 29316179Sralph uerror( "%.8s undefined", sp->sname ); 29416179Sralph #else 29516179Sralph uerror( "%s undefined", sp->sname ); 29616179Sralph #endif 29716179Sralph /* make p look reasonable */ 29816179Sralph p->in.type = p->fn.cdim = p->fn.csiz = INT; 29916179Sralph p->tn.rval = idname; 30016179Sralph p->tn.lval = 0; 30116179Sralph defid( p, SNULL ); 30216179Sralph break; 30316179Sralph } 30416179Sralph p->in.type = sp->stype; 30516179Sralph p->fn.cdim = sp->dimoff; 30616179Sralph p->fn.csiz = sp->sizoff; 30716179Sralph p->tn.lval = 0; 30816179Sralph p->tn.rval = idname; 30916179Sralph /* special case: MOETY is really an ICON... */ 31016179Sralph if( p->in.type == MOETY ){ 31116179Sralph p->tn.rval = NONAME; 31216179Sralph p->tn.lval = sp->offset; 31316179Sralph p->fn.cdim = 0; 31416179Sralph p->in.type = ENUMTY; 31516179Sralph p->in.op = ICON; 31616179Sralph } 31716179Sralph break; 31816179Sralph 31916179Sralph case ICON: 32016179Sralph p->in.type = INT; 32116179Sralph p->fn.cdim = 0; 32216179Sralph p->fn.csiz = INT; 32316179Sralph break; 32416179Sralph 32516179Sralph case STRING: 32616179Sralph p->in.op = NAME; 32716179Sralph p->in.type = CHAR+ARY; 32816179Sralph p->tn.lval = 0; 32916179Sralph p->tn.rval = NOLAB; 33016179Sralph p->fn.cdim = curdim; 33116179Sralph p->fn.csiz = CHAR; 33216179Sralph break; 33316179Sralph 33416179Sralph case FCON: 33516179Sralph p->tn.lval = 0; 33616179Sralph p->tn.rval = 0; 33717749Sralph p->in.type = FLOAT; 33817749Sralph p->fn.cdim = 0; 33917749Sralph p->fn.csiz = FLOAT; 34017749Sralph break; 34117749Sralph 34217749Sralph case DCON: 34317749Sralph p->tn.lval = 0; 34417749Sralph p->tn.rval = 0; 34516179Sralph p->in.type = DOUBLE; 34616179Sralph p->fn.cdim = 0; 34716179Sralph p->fn.csiz = DOUBLE; 34816179Sralph break; 34916179Sralph 35016179Sralph case STREF: 35116179Sralph /* p->x turned into *(p+offset) */ 35216179Sralph /* rhs must be a name; check correctness */ 35316179Sralph 35416179Sralph i = r->tn.rval; 35516179Sralph if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){ 35616179Sralph uerror( "member of structure or union required" ); 35716179Sralph }else 35816179Sralph /* if this name is non-unique, find right one */ 35916179Sralph if( stab[i].sflags & SNONUNIQ && 36016179Sralph (l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) && 36116179Sralph (l->fn.csiz +1) >= 0 ){ 36216179Sralph /* nonunique name && structure defined */ 36316179Sralph char * memnam, * tabnam; 36416179Sralph int j; 36516179Sralph int memi; 36616179Sralph j=dimtab[l->fn.csiz+1]; 36716179Sralph for( ; (memi=dimtab[j]) >= 0; ++j ){ 36816179Sralph tabnam = stab[memi].sname; 36916179Sralph memnam = stab[i].sname; 37016179Sralph # ifndef BUG1 37116179Sralph if( ddebug>1 ){ 37216179Sralph #ifndef FLEXNAMES 37316179Sralph printf("member %.8s==%.8s?\n", 37416179Sralph #else 37516179Sralph printf("member %s==%s?\n", 37616179Sralph #endif 37716179Sralph memnam, tabnam); 37816179Sralph } 37916179Sralph # endif 38016179Sralph if( stab[memi].sflags & SNONUNIQ ){ 38116179Sralph #ifndef FLEXNAMES 38232851Sdonn register k; 38316179Sralph for( k=0; k<NCHNAM; ++k ){ 38416179Sralph if(*memnam++!=*tabnam) 38516179Sralph goto next; 38616179Sralph if(!*tabnam++) break; 38716179Sralph } 38816179Sralph #else 38916179Sralph if (memnam != tabnam) 39016179Sralph goto next; 39116179Sralph #endif 39216179Sralph r->tn.rval = i = memi; 39316179Sralph break; 39416179Sralph } 39516179Sralph next: continue; 39616179Sralph } 39716179Sralph if( memi < 0 ) 39816179Sralph #ifndef FLEXNAMES 39916179Sralph uerror("illegal member use: %.8s", 40016179Sralph #else 40116179Sralph uerror("illegal member use: %s", 40216179Sralph #endif 40316179Sralph stab[i].sname); 40416179Sralph } 40516179Sralph else { 40616179Sralph register j; 40716179Sralph if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){ 40816179Sralph if( stab[i].sflags & SNONUNIQ ){ 40916179Sralph uerror( "nonunique name demands struct/union or struct/union pointer" ); 41016179Sralph } 41116179Sralph else werror( "struct/union or struct/union pointer required" ); 41216179Sralph } 41316179Sralph else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" ); 41416179Sralph else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){ 41516179Sralph #ifndef FLEXNAMES 41616179Sralph werror( "illegal member use: %.8s", stab[i].sname ); 41716179Sralph #else 41816179Sralph werror( "illegal member use: %s", stab[i].sname ); 41916179Sralph #endif 42016179Sralph } 42116179Sralph } 42216179Sralph 42316179Sralph p = stref( p ); 42416179Sralph break; 42516179Sralph 42616179Sralph case UNARY MUL: 42716179Sralph if( l->in.op == UNARY AND ){ 42816179Sralph p->in.op = l->in.op = FREE; 42916179Sralph p = l->in.left; 43016179Sralph } 43116179Sralph if( !ISPTR(l->in.type))uerror("illegal indirection"); 43216179Sralph p->in.type = DECREF(l->in.type); 43316179Sralph p->fn.cdim = l->fn.cdim; 43416179Sralph p->fn.csiz = l->fn.csiz; 43516179Sralph break; 43616179Sralph 43716179Sralph case UNARY AND: 43816179Sralph switch( l->in.op ){ 43916179Sralph 44016179Sralph case UNARY MUL: 44116179Sralph p->in.op = l->in.op = FREE; 44216179Sralph p = l->in.left; 44316179Sralph case NAME: 44416179Sralph p->in.type = INCREF( l->in.type ); 44516179Sralph p->fn.cdim = l->fn.cdim; 44616179Sralph p->fn.csiz = l->fn.csiz; 44716179Sralph break; 44816179Sralph 44916179Sralph case COMOP: 45016179Sralph lr = buildtree( UNARY AND, l->in.right, NIL ); 45116179Sralph p->in.op = l->in.op = FREE; 45216179Sralph p = buildtree( COMOP, l->in.left, lr ); 45316179Sralph break; 45416179Sralph 45516179Sralph case QUEST: 45616179Sralph lr = buildtree( UNARY AND, l->in.right->in.right, NIL ); 45716179Sralph ll = buildtree( UNARY AND, l->in.right->in.left, NIL ); 45816179Sralph p->in.op = l->in.op = l->in.right->in.op = FREE; 45916179Sralph p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) ); 46016179Sralph break; 46116179Sralph 46216179Sralph # ifdef ADDROREG 46316179Sralph case OREG: 46416179Sralph /* OREG was built in clocal() 46516179Sralph * for an auto or formal parameter 46616179Sralph * now its address is being taken 46716179Sralph * local code must unwind it 46816179Sralph * back to PLUS/MINUS REG ICON 46916179Sralph * according to local conventions 47016179Sralph */ 47116179Sralph { 47216179Sralph extern NODE * addroreg(); 47316179Sralph p->in.op = FREE; 47416179Sralph p = addroreg( l ); 47516179Sralph } 47616179Sralph break; 47716179Sralph 47816179Sralph # endif 47916179Sralph default: 48016179Sralph uerror( "unacceptable operand of &" ); 48116179Sralph break; 48216179Sralph } 48316179Sralph break; 48416179Sralph 48516179Sralph case LS: 48616179Sralph case RS: 48716179Sralph case ASG LS: 48816179Sralph case ASG RS: 48916179Sralph if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT) 49016179Sralph p->in.right = makety(p->in.right, INT, 0, INT ); 49116179Sralph break; 49216179Sralph 49316179Sralph case RETURN: 49416179Sralph case ASSIGN: 49516179Sralph case CAST: 49616179Sralph /* structure assignment */ 49716179Sralph /* take the addresses of the two sides; then make an 49816179Sralph /* operator using STASG and 49916179Sralph /* the addresses of left and right */ 50016179Sralph 50116179Sralph { 50216179Sralph register TWORD t; 50316179Sralph register d, s; 50416179Sralph 50516179Sralph if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" ); 50616179Sralph 50716179Sralph r = buildtree( UNARY AND, r, NIL ); 50816179Sralph t = r->in.type; 50916179Sralph d = r->fn.cdim; 51016179Sralph s = r->fn.csiz; 51116179Sralph 51216179Sralph l = block( STASG, l, r, t, d, s ); 51316179Sralph 51416179Sralph if( o == RETURN ){ 51516179Sralph p->in.op = FREE; 51616179Sralph p = l; 51716179Sralph break; 51816179Sralph } 51916179Sralph 52016179Sralph p->in.op = UNARY MUL; 52116179Sralph p->in.left = l; 52216179Sralph p->in.right = NIL; 52316179Sralph break; 52416179Sralph } 52516179Sralph case COLON: 52616179Sralph /* structure colon */ 52716179Sralph 52816179Sralph if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" ); 52916179Sralph break; 53016179Sralph 53116179Sralph case CALL: 53217749Sralph p->in.right = r = fixargs( p->in.right ); 53316179Sralph case UNARY CALL: 53416179Sralph if( !ISPTR(l->in.type)) uerror("illegal function"); 53516179Sralph p->in.type = DECREF(l->in.type); 53616179Sralph if( !ISFTN(p->in.type)) uerror("illegal function"); 53716179Sralph p->in.type = DECREF( p->in.type ); 53816179Sralph p->fn.cdim = l->fn.cdim; 53916179Sralph p->fn.csiz = l->fn.csiz; 54016179Sralph if( l->in.op == UNARY AND && l->in.left->in.op == NAME && 54116179Sralph l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME && 54216179Sralph ( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){ 54316179Sralph p->in.op += (FORTCALL-CALL); 54416179Sralph } 54516179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){ 54616179Sralph /* function returning structure */ 54716179Sralph /* make function really return ptr to str., with * */ 54816179Sralph 54916179Sralph p->in.op += STCALL-CALL; 55016179Sralph p->in.type = INCREF( p->in.type ); 55116179Sralph p = buildtree( UNARY MUL, p, NIL ); 55216179Sralph 55316179Sralph } 55416179Sralph break; 55516179Sralph 55616179Sralph default: 55716179Sralph cerror( "other code %d", o ); 55816179Sralph } 55916179Sralph 56016179Sralph } 56116179Sralph 56216179Sralph if( actions & CVTO ) p = oconvert(p); 56316179Sralph p = clocal(p); 56416179Sralph 56516179Sralph # ifndef BUG1 56616179Sralph if( bdebug ) fwalk( p, eprint, 0 ); 56716179Sralph # endif 56816179Sralph 56916179Sralph return(p); 57016179Sralph 57116179Sralph } 57216179Sralph 57324408Smckusick int fpe_count = -1; 57424408Smckusick jmp_buf gotfpe; 57524408Smckusick 57624408Smckusick fpe() { 57724408Smckusick if (fpe_count < 0) 57824408Smckusick cerror("floating point exception"); 57924408Smckusick ++fpe_count; 58024408Smckusick longjmp(gotfpe, 1); 58124408Smckusick } 58224408Smckusick 58317749Sralph /* 58417749Sralph * Rewrite arguments in a function call. 58517749Sralph * Structure arguments are massaged, single 58617749Sralph * precision floating point constants are 58717749Sralph * cast to double (to eliminate convert code). 58817749Sralph */ 58916179Sralph NODE * 59017749Sralph fixargs( p ) register NODE *p; { 59117749Sralph int o = p->in.op; 59216179Sralph 59317749Sralph if( o == CM ){ 59417749Sralph p->in.left = fixargs( p->in.left ); 59517749Sralph p->in.right = fixargs( p->in.right ); 59616179Sralph return( p ); 59716179Sralph } 59816179Sralph 59916179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){ 60016179Sralph p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz ); 60116179Sralph p->in.left = buildtree( UNARY AND, p->in.left, NIL ); 60216179Sralph p = clocal(p); 60316179Sralph } 60417749Sralph else if( o == FCON ) 60517749Sralph p = makety(p, DOUBLE, 0, 0); 60616179Sralph return( p ); 60716179Sralph } 60816179Sralph 60916179Sralph chkstr( i, j, type ) TWORD type; { 61016179Sralph /* is the MOS or MOU at stab[i] OK for strict reference by a ptr */ 61116179Sralph /* i has been checked to contain a MOS or MOU */ 61216179Sralph /* j is the index in dimtab of the members... */ 61316179Sralph int k, kk; 61416179Sralph 61516179Sralph extern int ddebug; 61616179Sralph 61716179Sralph # ifndef BUG1 61816179Sralph #ifndef FLEXNAMES 61916179Sralph if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j ); 62016179Sralph #else 62116179Sralph if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j ); 62216179Sralph #endif 62316179Sralph # endif 62416179Sralph if( (k = j) < 0 ) uerror( "undefined structure or union" ); 62516179Sralph else { 62616179Sralph for( ; (kk = dimtab[k] ) >= 0; ++k ){ 62716179Sralph if( kk >= SYMTSZ ){ 62816179Sralph cerror( "gummy structure" ); 62916179Sralph return(1); 63016179Sralph } 63116179Sralph if( kk == i ) return( 1 ); 63216179Sralph switch( stab[kk].stype ){ 63316179Sralph 63416179Sralph case STRTY: 63516179Sralph case UNIONTY: 63616179Sralph if( type == STRTY ) continue; /* no recursive looking for strs */ 63716179Sralph if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){ 63816179Sralph if( stab[kk].sname[0] == '$' ) return(0); /* $FAKE */ 63916179Sralph werror( 64016179Sralph #ifndef FLEXNAMES 64116179Sralph "illegal member use: perhaps %.8s.%.8s?", 64216179Sralph #else 64316179Sralph "illegal member use: perhaps %s.%s?", 64416179Sralph #endif 64516179Sralph stab[kk].sname, stab[i].sname ); 64616179Sralph return(1); 64716179Sralph } 64816179Sralph } 64916179Sralph } 65016179Sralph } 65116179Sralph return( 0 ); 65216179Sralph } 65316179Sralph 65416179Sralph conval( p, o, q ) register NODE *p, *q; { 65516179Sralph /* apply the op o to the lval part of p; if binary, rhs is val */ 65632842Sdonn /* works only on integer constants */ 65732842Sdonn NODE *r; 65816179Sralph int i, u; 65916179Sralph CONSZ val; 66016179Sralph 66116179Sralph val = q->tn.lval; 66216179Sralph u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type); 66316179Sralph if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 66416179Sralph 66516179Sralph if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0); 66616179Sralph if( q->tn.rval != NONAME && o!=PLUS ) return(0); 66716179Sralph if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0); 66816179Sralph 66932842Sdonn if( p->in.type != INT || q->in.type != INT ){ 67032842Sdonn /* will this always work if p == q and o is UTYPE? */ 67132842Sdonn r = block( o, p, q, INT, 0, INT ); 67232842Sdonn r = tymatch( r ); 67332842Sdonn p->in.type = r->in.type; 67432842Sdonn p->fn.cdim = r->fn.cdim; 67532842Sdonn p->fn.csiz = r->fn.csiz; 67632842Sdonn r->in.op = FREE; 67732842Sdonn } 67832842Sdonn 67916179Sralph switch( o ){ 68016179Sralph 68116179Sralph case PLUS: 68216179Sralph p->tn.lval += val; 68316179Sralph if( p->tn.rval == NONAME ){ 68416179Sralph p->tn.rval = q->tn.rval; 68516179Sralph p->in.type = q->in.type; 68616179Sralph } 68716179Sralph break; 68816179Sralph case MINUS: 68916179Sralph p->tn.lval -= val; 69016179Sralph break; 69116179Sralph case MUL: 69232840Sdonn p->tn.lval *= val; 69316179Sralph break; 69416179Sralph case DIV: 69516179Sralph if( val == 0 ) uerror( "division by 0" ); 69617749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval / val; 69716179Sralph else p->tn.lval /= val; 69816179Sralph break; 69916179Sralph case MOD: 70016179Sralph if( val == 0 ) uerror( "division by 0" ); 70117749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval % val; 70216179Sralph else p->tn.lval %= val; 70316179Sralph break; 70416179Sralph case AND: 70516179Sralph p->tn.lval &= val; 70616179Sralph break; 70716179Sralph case OR: 70816179Sralph p->tn.lval |= val; 70916179Sralph break; 71016179Sralph case ER: 71117749Sralph p->tn.lval ^= val; 71216179Sralph break; 71316179Sralph case LS: 71416179Sralph i = val; 71516179Sralph p->tn.lval = p->tn.lval << i; 71616179Sralph break; 71716179Sralph case RS: 71816179Sralph i = val; 71917749Sralph if ( u ) p->tn.lval = (unsigned) p->tn.lval >> i; 72017749Sralph else p->tn.lval = p->tn.lval >> i; 72116179Sralph break; 72216179Sralph 72316179Sralph case UNARY MINUS: 72416179Sralph p->tn.lval = - p->tn.lval; 72516179Sralph break; 72616179Sralph case COMPL: 72716179Sralph p->tn.lval = ~p->tn.lval; 72816179Sralph break; 72916179Sralph case NOT: 73016179Sralph p->tn.lval = !p->tn.lval; 73116179Sralph break; 73216179Sralph case LT: 73316179Sralph p->tn.lval = p->tn.lval < val; 73416179Sralph break; 73516179Sralph case LE: 73616179Sralph p->tn.lval = p->tn.lval <= val; 73716179Sralph break; 73816179Sralph case GT: 73916179Sralph p->tn.lval = p->tn.lval > val; 74016179Sralph break; 74116179Sralph case GE: 74216179Sralph p->tn.lval = p->tn.lval >= val; 74316179Sralph break; 74416179Sralph case ULT: 74532848Sdonn p->tn.lval = p->tn.lval < (unsigned) val; 74616179Sralph break; 74716179Sralph case ULE: 74832848Sdonn p->tn.lval = p->tn.lval <= (unsigned) val; 74916179Sralph break; 75032848Sdonn case UGT: 75132848Sdonn p->tn.lval = p->tn.lval > (unsigned) val; 75232848Sdonn break; 75332840Sdonn case UGE: 75432848Sdonn p->tn.lval = p->tn.lval >= (unsigned) val; 75532840Sdonn break; 75616179Sralph case EQ: 75716179Sralph p->tn.lval = p->tn.lval == val; 75816179Sralph break; 75916179Sralph case NE: 76016179Sralph p->tn.lval = p->tn.lval != val; 76116179Sralph break; 76216179Sralph default: 76316179Sralph return(0); 76416179Sralph } 76516179Sralph return(1); 76616179Sralph } 76716179Sralph 76816179Sralph chkpun(p) register NODE *p; { 76916179Sralph 77016179Sralph /* checks p for the existance of a pun */ 77116179Sralph 77216179Sralph /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */ 77316179Sralph 77416179Sralph /* one case is when enumerations are used: this applies only to lint */ 77516179Sralph /* in the other case, one operand is a pointer, the other integer type */ 77616179Sralph /* we check that this integer is in fact a constant zero... */ 77716179Sralph 77816179Sralph /* in the case of ASSIGN, any assignment of pointer to integer is illegal */ 77916179Sralph /* this falls out, because the LHS is never 0 */ 78016179Sralph 78116179Sralph register NODE *q; 78216179Sralph register t1, t2; 78316179Sralph register d1, d2; 78432844Sdonn int ref1, ref2; 78516179Sralph 78616179Sralph t1 = p->in.left->in.type; 78716179Sralph t2 = p->in.right->in.type; 78816179Sralph 78916179Sralph if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */ 79032841Sdonn /* rob pike says this is obnoxious... 79132840Sdonn if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) 79232841Sdonn werror( "comparison of enums" ); */ 79332841Sdonn if( t1==ENUMTY && t2==ENUMTY ) { 79432841Sdonn if ( p->in.left->fn.csiz!=p->in.right->fn.csiz ) 79532841Sdonn werror( "enumeration type clash, operator %s", opst[p->in.op] ); 79632841Sdonn return; 79732841Sdonn } 79832841Sdonn if ( t1 == ENUMTY ) t1 = INT; 79932841Sdonn if ( t2 == ENUMTY ) t2 = INT; 80016179Sralph } 80116179Sralph 80232844Sdonn ref1 = ISPTR(t1) || ISARY(t1); 80332844Sdonn ref2 = ISPTR(t2) || ISARY(t2); 80416179Sralph 80532844Sdonn if( ref1 ^ ref2 ){ 80632844Sdonn if( ref1 ) q = p->in.right; 80732844Sdonn else q = p->in.left; 80816179Sralph if( q->in.op != ICON || q->tn.lval != 0 ){ 80916179Sralph werror( "illegal combination of pointer and integer, op %s", 81016179Sralph opst[p->in.op] ); 81116179Sralph } 81216179Sralph } 81332844Sdonn else if( ref1 ){ 81432843Sdonn if( t1 == t2 ) { 81532843Sdonn if( p->in.left->fn.csiz != p->in.right->fn.csiz ) { 81632843Sdonn werror( "illegal structure pointer combination" ); 81716179Sralph return; 81816179Sralph } 81932843Sdonn d1 = p->in.left->fn.cdim; 82032843Sdonn d2 = p->in.right->fn.cdim; 82132843Sdonn for( ;; ){ 82232843Sdonn if( ISARY(t1) ){ 82332843Sdonn if( dimtab[d1] != dimtab[d2] ){ 82432843Sdonn werror( "illegal array size combination" ); 82532843Sdonn return; 82632843Sdonn } 82732843Sdonn ++d1; 82832843Sdonn ++d2; 82916179Sralph } 83032843Sdonn else if( !ISPTR(t1) ) break; 83132843Sdonn t1 = DECREF(t1); 83216179Sralph } 83316179Sralph } 83432843Sdonn else 83532843Sdonn werror( "illegal pointer combination" ); 83616179Sralph } 83716179Sralph 83816179Sralph } 83916179Sralph 84016179Sralph NODE * 84116179Sralph stref( p ) register NODE *p; { 84216179Sralph 84316179Sralph TWORD t; 84416179Sralph int d, s, dsc, align; 84516179Sralph OFFSZ off; 84616179Sralph register struct symtab *q; 84716179Sralph 84816179Sralph /* make p->x */ 84916179Sralph /* this is also used to reference automatic variables */ 85016179Sralph 85116179Sralph q = &stab[p->in.right->tn.rval]; 85216179Sralph p->in.right->in.op = FREE; 85316179Sralph p->in.op = FREE; 85416179Sralph p = pconvert( p->in.left ); 85516179Sralph 85616179Sralph /* make p look like ptr to x */ 85716179Sralph 85816179Sralph if( !ISPTR(p->in.type)){ 85916179Sralph p->in.type = PTR+UNIONTY; 86016179Sralph } 86116179Sralph 86216179Sralph t = INCREF( q->stype ); 86316179Sralph d = q->dimoff; 86416179Sralph s = q->sizoff; 86516179Sralph 86616179Sralph p = makety( p, t, d, s ); 86716179Sralph 86816179Sralph /* compute the offset to be added */ 86916179Sralph 87016179Sralph off = q->offset; 87116179Sralph dsc = q->sclass; 87216179Sralph 87316179Sralph if( dsc & FIELD ) { /* normalize offset */ 87416179Sralph align = ALINT; 87516179Sralph s = INT; 87616179Sralph off = (off/align)*align; 87716179Sralph } 87816179Sralph if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); 87916179Sralph 88016179Sralph p = buildtree( UNARY MUL, p, NIL ); 88116179Sralph 88216179Sralph /* if field, build field info */ 88316179Sralph 88416179Sralph if( dsc & FIELD ){ 88516179Sralph p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); 88616179Sralph p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); 88716179Sralph } 88816179Sralph 88916179Sralph return( clocal(p) ); 89016179Sralph } 89116179Sralph 89216179Sralph notlval(p) register NODE *p; { 89316179Sralph 89416179Sralph /* return 0 if p an lvalue, 1 otherwise */ 89516179Sralph 89616179Sralph again: 89716179Sralph 89816179Sralph switch( p->in.op ){ 89916179Sralph 90016179Sralph case FLD: 90116179Sralph p = p->in.left; 90216179Sralph goto again; 90316179Sralph 90416179Sralph case UNARY MUL: 90516179Sralph /* fix the &(a=b) bug, given that a and b are structures */ 90616179Sralph if( p->in.left->in.op == STASG ) return( 1 ); 90716179Sralph /* and the f().a bug, given that f returns a structure */ 90816179Sralph if( p->in.left->in.op == UNARY STCALL || 90916179Sralph p->in.left->in.op == STCALL ) return( 1 ); 91016179Sralph case NAME: 91116179Sralph case OREG: 91216179Sralph if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); 91316179Sralph case REG: 91416179Sralph return(0); 91516179Sralph 91616179Sralph default: 91716179Sralph return(1); 91816179Sralph 91916179Sralph } 92016179Sralph 92116179Sralph } 92216179Sralph 92316179Sralph NODE * 92416179Sralph bcon( i ){ /* make a constant node with value i */ 92516179Sralph register NODE *p; 92616179Sralph 92716179Sralph p = block( ICON, NIL, NIL, INT, 0, INT ); 92816179Sralph p->tn.lval = i; 92916179Sralph p->tn.rval = NONAME; 93016179Sralph return( clocal(p) ); 93116179Sralph } 93216179Sralph 93316179Sralph NODE * 93416179Sralph bpsize(p) register NODE *p; { 93516179Sralph return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); 93616179Sralph } 93716179Sralph 93816179Sralph OFFSZ 93916179Sralph psize( p ) NODE *p; { 94016179Sralph /* p is a node of type pointer; psize returns the 94116179Sralph size of the thing pointed to */ 94216179Sralph 94316179Sralph if( !ISPTR(p->in.type) ){ 94416179Sralph uerror( "pointer required"); 94516179Sralph return( SZINT ); 94616179Sralph } 94716179Sralph /* note: no pointers to fields */ 94816179Sralph return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); 94916179Sralph } 95016179Sralph 95116179Sralph NODE * 95216179Sralph convert( p, f ) register NODE *p; { 95316179Sralph /* convert an operand of p 95416179Sralph f is either CVTL or CVTR 95516179Sralph operand has type int, and is converted by the size of the other side 95616179Sralph */ 95716179Sralph 95816179Sralph register NODE *q, *r; 95916179Sralph 96016179Sralph q = (f==CVTL)?p->in.left:p->in.right; 96116179Sralph 96216179Sralph r = block( PMCONV, 96316179Sralph q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT ); 96416179Sralph r = clocal(r); 96516179Sralph if( f == CVTL ) 96616179Sralph p->in.left = r; 96716179Sralph else 96816179Sralph p->in.right = r; 96916179Sralph return(p); 97016179Sralph 97116179Sralph } 97216179Sralph 97325750Sdonn #ifndef econvert 97416179Sralph econvert( p ) register NODE *p; { 97516179Sralph 97616179Sralph /* change enums to ints, or appropriate types */ 97716179Sralph 97816179Sralph register TWORD ty; 97916179Sralph 98016179Sralph if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) { 98116179Sralph if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; 98216179Sralph else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; 98316179Sralph else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; 98416179Sralph else ty = LONG; 98516179Sralph ty = ctype( ty ); 98616179Sralph p->fn.csiz = ty; 98716179Sralph MODTYPE(p->in.type,ty); 98816179Sralph if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT; 98916179Sralph } 99016179Sralph } 99125750Sdonn #endif 99216179Sralph 99316179Sralph NODE * 99416179Sralph pconvert( p ) register NODE *p; { 99516179Sralph 99616179Sralph /* if p should be changed into a pointer, do so */ 99716179Sralph 99816179Sralph if( ISARY( p->in.type) ){ 99916179Sralph p->in.type = DECREF( p->in.type ); 100016179Sralph ++p->fn.cdim; 100116179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100216179Sralph } 100316179Sralph if( ISFTN( p->in.type) ) 100416179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100516179Sralph 100616179Sralph return( p ); 100716179Sralph } 100816179Sralph 100916179Sralph NODE * 101016179Sralph oconvert(p) register NODE *p; { 101116179Sralph /* convert the result itself: used for pointer and unsigned */ 101216179Sralph 101316179Sralph switch(p->in.op) { 101416179Sralph 101516179Sralph case LE: 101616179Sralph case LT: 101716179Sralph case GE: 101816179Sralph case GT: 101916179Sralph if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE); 102016179Sralph case EQ: 102116179Sralph case NE: 102216179Sralph return( p ); 102316179Sralph 102416179Sralph case MINUS: 102516179Sralph return( clocal( block( PVCONV, 102616179Sralph p, bpsize(p->in.left), INT, 0, INT ) ) ); 102716179Sralph } 102816179Sralph 102916179Sralph cerror( "illegal oconvert: %d", p->in.op ); 103016179Sralph 103116179Sralph return(p); 103216179Sralph } 103316179Sralph 103416179Sralph NODE * 103516179Sralph ptmatch(p) register NODE *p; { 103616179Sralph 103716179Sralph /* makes the operands of p agree; they are 103816179Sralph either pointers or integers, by this time */ 103916179Sralph /* with MINUS, the sizes must be the same */ 104016179Sralph /* with COLON, the types must be the same */ 104116179Sralph 104216179Sralph TWORD t1, t2, t; 104316179Sralph int o, d2, d, s2, s; 104416179Sralph 104516179Sralph o = p->in.op; 104616179Sralph t = t1 = p->in.left->in.type; 104716179Sralph t2 = p->in.right->in.type; 104816179Sralph d = p->in.left->fn.cdim; 104916179Sralph d2 = p->in.right->fn.cdim; 105016179Sralph s = p->in.left->fn.csiz; 105116179Sralph s2 = p->in.right->fn.csiz; 105216179Sralph 105316179Sralph switch( o ){ 105416179Sralph 105516179Sralph case ASSIGN: 105616179Sralph case RETURN: 105716179Sralph case CAST: 105816179Sralph { break; } 105916179Sralph 106016179Sralph case MINUS: 106116179Sralph { if( psize(p->in.left) != psize(p->in.right) ){ 106216179Sralph uerror( "illegal pointer subtraction"); 106316179Sralph } 106416179Sralph break; 106516179Sralph } 106616179Sralph case COLON: 106716179Sralph { if( t1 != t2 ) uerror( "illegal types in :"); 106816179Sralph break; 106916179Sralph } 107016179Sralph default: /* must work harder: relationals or comparisons */ 107116179Sralph 107216179Sralph if( !ISPTR(t1) ){ 107316179Sralph t = t2; 107416179Sralph d = d2; 107516179Sralph s = s2; 107616179Sralph break; 107716179Sralph } 107816179Sralph if( !ISPTR(t2) ){ 107916179Sralph break; 108016179Sralph } 108116179Sralph 108216179Sralph /* both are pointers */ 108316179Sralph if( talign(t2,s2) < talign(t,s) ){ 108416179Sralph t = t2; 108516179Sralph s = s2; 108616179Sralph } 108716179Sralph break; 108816179Sralph } 108916179Sralph 109016179Sralph p->in.left = makety( p->in.left, t, d, s ); 109116179Sralph p->in.right = makety( p->in.right, t, d, s ); 109216179Sralph if( o!=MINUS && !logop(o) ){ 109316179Sralph 109416179Sralph p->in.type = t; 109516179Sralph p->fn.cdim = d; 109616179Sralph p->fn.csiz = s; 109716179Sralph } 109816179Sralph 109916179Sralph return(clocal(p)); 110016179Sralph } 110116179Sralph 110216179Sralph int tdebug = 0; 110316179Sralph 110416179Sralph NODE * 110516179Sralph tymatch(p) register NODE *p; { 110616179Sralph 110716179Sralph /* satisfy the types of various arithmetic binary ops */ 110816179Sralph 110916179Sralph /* rules are: 111025750Sdonn if assignment, type of LHS 111116179Sralph if any float or doubles, make double 111216179Sralph if any longs, make long 111316179Sralph otherwise, make int 111416179Sralph if either operand is unsigned, the result is... 111516179Sralph */ 111616179Sralph 111716179Sralph register TWORD t1, t2, t, tu; 111816179Sralph register o, u; 111916179Sralph 112016179Sralph o = p->in.op; 112116179Sralph 112216179Sralph t1 = p->in.left->in.type; 112316179Sralph t2 = p->in.right->in.type; 112416179Sralph if( (t1==UNDEF || t2==UNDEF) && o!=CAST ) 112516179Sralph uerror("void type illegal in expression"); 112616179Sralph 112716179Sralph u = 0; 112816179Sralph if( ISUNSIGNED(t1) ){ 112916179Sralph u = 1; 113016179Sralph t1 = DEUNSIGN(t1); 113116179Sralph } 113216179Sralph if( ISUNSIGNED(t2) ){ 113316179Sralph u = 1; 113416179Sralph t2 = DEUNSIGN(t2); 113516179Sralph } 113616179Sralph 113716179Sralph if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT; 113816179Sralph if( t2 == CHAR || t2 == SHORT ) t2 = INT; 113916179Sralph 114017749Sralph #ifdef SPRECC 114117749Sralph if( t1 == DOUBLE || t2 == DOUBLE ) 114217749Sralph t = DOUBLE; 114317749Sralph else if( t1 == FLOAT || t2 == FLOAT ) 114417749Sralph t = FLOAT; 114517749Sralph #else 114617749Sralph if (t1 == DOUBLE || t1 == FLOAT || t2 == DOUBLE || t2 == FLOAT) 114717749Sralph t = DOUBLE; 114817749Sralph #endif 114916179Sralph else if( t1==LONG || t2==LONG ) t = LONG; 115016179Sralph else t = INT; 115116179Sralph 115232850Sdonn #ifdef tahoe 115332853Sdonn if( asgop(o) ) 115432850Sdonn #else 115532853Sdonn if( o == ASSIGN || o == CAST || o == RETURN ) 115632850Sdonn #endif 115732853Sdonn { 115816179Sralph tu = p->in.left->in.type; 115916179Sralph t = t1; 116016179Sralph } 116116179Sralph else { 116216179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; 116316179Sralph } 116416179Sralph 116516179Sralph /* because expressions have values that are at least as wide 116616179Sralph as INT or UNSIGNED, the only conversions needed 116716179Sralph are those involving FLOAT/DOUBLE, and those 116816179Sralph from LONG to INT and ULONG to UNSIGNED */ 116916179Sralph 117032850Sdonn #ifdef tahoe 117132850Sdonn if( t != t1 ) 117232850Sdonn #else 117325750Sdonn if( t != t1 && ! asgop(o) ) 117432850Sdonn #endif 117525750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu ); 117616179Sralph 117732840Sdonn if( t != t2 || o==CAST) 117832840Sdonn if ( tu == ENUMTY ) {/* always asgop */ 117932840Sdonn p->in.right = makety( p->in.right, INT, 0, INT ); 118032840Sdonn p->in.right->in.type = tu; 118132840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim; 118232840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz; 118332840Sdonn } 118432840Sdonn else 118532840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu ); 118616179Sralph 118716179Sralph if( asgop(o) ){ 118816179Sralph p->in.type = p->in.left->in.type; 118916179Sralph p->fn.cdim = p->in.left->fn.cdim; 119016179Sralph p->fn.csiz = p->in.left->fn.csiz; 119116179Sralph } 119216179Sralph else if( !logop(o) ){ 119316179Sralph p->in.type = tu; 119416179Sralph p->fn.cdim = 0; 119516179Sralph p->fn.csiz = t; 119616179Sralph } 119716179Sralph 119816179Sralph # ifndef BUG1 119916179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); 120016179Sralph # endif 120116179Sralph 120216179Sralph return(p); 120316179Sralph } 120416179Sralph 120516179Sralph NODE * 120616179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; { 120716179Sralph /* make p into type t by inserting a conversion */ 120816179Sralph 120916179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); 121016179Sralph if( t == p->in.type ){ 121116179Sralph p->fn.cdim = d; 121216179Sralph p->fn.csiz = s; 121316179Sralph return( p ); 121416179Sralph } 121516179Sralph 121616179Sralph if( t & TMASK ){ 121716179Sralph /* non-simple type */ 121817228Sralph return( block( PCONV, p, NIL, t, d, s ) ); 121916179Sralph } 122016179Sralph 122116179Sralph if( p->in.op == ICON ){ 122217749Sralph if (t == DOUBLE) { 122317749Sralph p->in.op = DCON; 122417749Sralph if (ISUNSIGNED(p->in.type)) 122532847Sdonn p->dpn.dval = (unsigned CONSZ) p->tn.lval; 122617749Sralph else 122717749Sralph p->dpn.dval = p->tn.lval; 122817749Sralph p->in.type = p->fn.csiz = t; 122917749Sralph return (clocal(p)); 123017749Sralph } 123117749Sralph if (t == FLOAT) { 123216179Sralph p->in.op = FCON; 123316179Sralph if( ISUNSIGNED(p->in.type) ){ 123432847Sdonn p->fpn.fval = (unsigned CONSZ) p->tn.lval; 123516179Sralph } 123616179Sralph else { 123717749Sralph p->fpn.fval = p->tn.lval; 123816179Sralph } 123916179Sralph 124016179Sralph p->in.type = p->fn.csiz = t; 124116179Sralph return( clocal(p) ); 124216179Sralph } 124316179Sralph } 124417749Sralph else if (p->in.op == FCON && t == DOUBLE) { 124517749Sralph double db; 124616179Sralph 124717749Sralph p->in.op = DCON; 124817749Sralph db = p->fpn.fval; 124917749Sralph p->dpn.dval = db; 125017749Sralph p->in.type = p->fn.csiz = t; 125117749Sralph return (clocal(p)); 125217749Sralph } else if (p->in.op == DCON && t == FLOAT) { 125317749Sralph float fl; 125417749Sralph 125517749Sralph p->in.op = FCON; 125617749Sralph fl = p->dpn.dval; 125717749Sralph #ifdef notdef 125817749Sralph if (fl != p->dpn.dval) 125917749Sralph werror("float conversion loses precision"); 126017749Sralph #endif 126117749Sralph p->fpn.fval = fl; 126217749Sralph p->in.type = p->fn.csiz = t; 126317749Sralph return (clocal(p)); 126417749Sralph } 126517749Sralph 126617049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) ); 126716179Sralph 126816179Sralph } 126916179Sralph 127016179Sralph NODE * 127116179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { 127216179Sralph 127316179Sralph register NODE *p; 127416179Sralph 127516179Sralph p = talloc(); 127616179Sralph p->in.op = o; 127716179Sralph p->in.left = l; 127816179Sralph p->in.right = r; 127916179Sralph p->in.type = t; 128016179Sralph p->fn.cdim = d; 128116179Sralph p->fn.csiz = s; 128216179Sralph return(p); 128316179Sralph } 128416179Sralph 128516179Sralph icons(p) register NODE *p; { 128616179Sralph /* if p is an integer constant, return its value */ 128716179Sralph int val; 128816179Sralph 128916179Sralph if( p->in.op != ICON ){ 129016179Sralph uerror( "constant expected"); 129116179Sralph val = 1; 129216179Sralph } 129316179Sralph else { 129416179Sralph val = p->tn.lval; 129516179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); 129616179Sralph } 129716179Sralph tfree( p ); 129816179Sralph return(val); 129916179Sralph } 130016179Sralph 130116179Sralph /* the intent of this table is to examine the 130216179Sralph operators, and to check them for 130316179Sralph correctness. 130416179Sralph 130516179Sralph The table is searched for the op and the 130616179Sralph modified type (where this is one of the 130716179Sralph types INT (includes char and short), LONG, 130816179Sralph DOUBLE (includes FLOAT), and POINTER 130916179Sralph 131016179Sralph The default action is to make the node type integer 131116179Sralph 131216179Sralph The actions taken include: 131316179Sralph PUN check for puns 131416179Sralph CVTL convert the left operand 131516179Sralph CVTR convert the right operand 131616179Sralph TYPL the type is determined by the left operand 131716179Sralph TYPR the type is determined by the right operand 131816179Sralph TYMATCH force type of left and right to match, by inserting conversions 131916179Sralph PTMATCH like TYMATCH, but for pointers 132016179Sralph LVAL left operand must be lval 132116179Sralph CVTO convert the op 132216179Sralph NCVT do not convert the operands 132316179Sralph OTHER handled by code 132416179Sralph NCVTR convert the left operand, not the right... 132516179Sralph 132616179Sralph */ 132716179Sralph 132816179Sralph # define MINT 01 /* integer */ 132916179Sralph # define MDBI 02 /* integer or double */ 133016179Sralph # define MSTR 04 /* structure */ 133116179Sralph # define MPTR 010 /* pointer */ 133216179Sralph # define MPTI 020 /* pointer or integer */ 133316179Sralph # define MENU 040 /* enumeration variable or member */ 133424408Smckusick # define MVOID 0100000 /* void type */ 133516179Sralph 133616179Sralph opact( p ) NODE *p; { 133716179Sralph 133816179Sralph register mt12, mt1, mt2, o; 133916179Sralph 134024408Smckusick mt1 = mt2 = mt12 = 0; 134116179Sralph 134216179Sralph switch( optype(o=p->in.op) ){ 134316179Sralph 134416179Sralph case BITYPE: 134524408Smckusick mt2 = moditype( p->in.right->in.type ); 134616179Sralph case UTYPE: 134724408Smckusick mt1 = moditype( p->in.left->in.type ); 134824408Smckusick break; 134916179Sralph 135016179Sralph } 135116179Sralph 135224408Smckusick if( ((mt1 | mt2) & MVOID) && 135324408Smckusick o != COMOP && 135432845Sdonn o != COLON && 135532845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) && 135624408Smckusick !(o == CAST && (mt1 & MVOID)) ){ 135724408Smckusick /* if lhs of RETURN is void, grammar will complain */ 135824408Smckusick if( o != RETURN ) 135924408Smckusick uerror( "value of void expression used" ); 136024408Smckusick return( NCVT ); 136124408Smckusick } 136224408Smckusick mt12 = mt1 & mt2; 136324408Smckusick 136416179Sralph switch( o ){ 136516179Sralph 136616179Sralph case NAME : 136716179Sralph case STRING : 136816179Sralph case ICON : 136916179Sralph case FCON : 137017749Sralph case DCON : 137116179Sralph case CALL : 137216179Sralph case UNARY CALL: 137316179Sralph case UNARY MUL: 137416179Sralph { return( OTHER ); } 137516179Sralph case UNARY MINUS: 137632844Sdonn if( mt1 & MENU ) return( 0 ); 137716179Sralph if( mt1 & MDBI ) return( TYPL ); 137816179Sralph break; 137916179Sralph 138016179Sralph case COMPL: 138132844Sdonn if( mt1 & MENU ) return( 0 ); 138216179Sralph if( mt1 & MINT ) return( TYPL ); 138316179Sralph break; 138416179Sralph 138516179Sralph case UNARY AND: 138616179Sralph { return( NCVT+OTHER ); } 138716179Sralph case INIT: 138816179Sralph case CM: 138916180Sralph return( 0 ); 139016180Sralph 139116179Sralph case NOT: 139216179Sralph case CBRANCH: 139316180Sralph if( mt1 & MSTR ) break; 139416180Sralph return( 0 ); 139516180Sralph 139616179Sralph case ANDAND: 139716179Sralph case OROR: 139816180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break; 139916179Sralph return( 0 ); 140016179Sralph 140116179Sralph case MUL: 140216179Sralph case DIV: 140316179Sralph if( mt12 & MDBI ) return( TYMATCH ); 140416179Sralph break; 140516179Sralph 140616179Sralph case MOD: 140716179Sralph case AND: 140816179Sralph case OR: 140916179Sralph case ER: 141016179Sralph if( mt12 & MINT ) return( TYMATCH ); 141116179Sralph break; 141216179Sralph 141316179Sralph case LS: 141416179Sralph case RS: 141516179Sralph if( mt12 & MINT ) return( TYMATCH+OTHER ); 141616179Sralph break; 141716179Sralph 141816179Sralph case EQ: 141916179Sralph case NE: 142016179Sralph case LT: 142116179Sralph case LE: 142216179Sralph case GT: 142316179Sralph case GE: 142432844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN ); 142532844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO ); 142616179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN ); 142716179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN ); 142816179Sralph else break; 142916179Sralph 143016179Sralph case QUEST: 143116179Sralph case COMOP: 143216179Sralph if( mt2&MENU ) return( TYPR+NCVTR ); 143316179Sralph return( TYPR ); 143416179Sralph 143516179Sralph case STREF: 143616179Sralph return( NCVTR+OTHER ); 143716179Sralph 143816179Sralph case FORCE: 143916179Sralph return( TYPL ); 144016179Sralph 144116179Sralph case COLON: 144232844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH ); 144332844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH ); 144416179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 144516179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 144616179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 144716179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 144832845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL ); 144916179Sralph break; 145016179Sralph 145116179Sralph case ASSIGN: 145216179Sralph case RETURN: 145316179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 145432844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN ); 145516179Sralph case CAST: 145632846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH); 145732844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH ); 145832846Sdonn else if( mt2 == MVOID && 145918436Smckusick ( p->in.right->in.op == CALL || 146018436Smckusick p->in.right->in.op == UNARY CALL)) break; 1461*32854Sdonn else if( (mt1 & MPTR) && (mt2 & MPTI) ) 1462*32854Sdonn return( LVAL+PTMATCH+PUN ); 146316179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 146416179Sralph break; 146516179Sralph 146616179Sralph case ASG LS: 146716179Sralph case ASG RS: 146816179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 146916179Sralph break; 147016179Sralph 147116179Sralph case ASG MUL: 147216179Sralph case ASG DIV: 147316179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH ); 147416179Sralph break; 147516179Sralph 147616179Sralph case ASG MOD: 147716179Sralph case ASG AND: 147816179Sralph case ASG OR: 147916179Sralph case ASG ER: 148016179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH ); 148116179Sralph break; 148216179Sralph 148316179Sralph case ASG PLUS: 148416179Sralph case ASG MINUS: 148516179Sralph case INCR: 148616179Sralph case DECR: 148716179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL ); 148816179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); 148916179Sralph break; 149016179Sralph 149116179Sralph case MINUS: 149216179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); 149316179Sralph if( mt2 & MPTR ) break; 149416179Sralph case PLUS: 149516179Sralph if( mt12 & MDBI ) return( TYMATCH ); 149616179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); 149716179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); 149816179Sralph 149916179Sralph } 150024408Smckusick if( mt12 == MSTR ) 150124408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] ); 150224408Smckusick else 150324408Smckusick uerror( "operands of %s have incompatible types", opst[o] ); 150416179Sralph return( NCVT ); 150516179Sralph } 150616179Sralph 150716179Sralph moditype( ty ) TWORD ty; { 150816179Sralph 150916179Sralph switch( ty ){ 151016179Sralph 151116179Sralph case TVOID: 151217206Sralph return( MPTR ); 151316179Sralph case UNDEF: 151424408Smckusick return( MVOID ); 151516179Sralph case ENUMTY: 151616179Sralph case MOETY: 151732840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */ 151816179Sralph 151916179Sralph case STRTY: 152016179Sralph case UNIONTY: 152116179Sralph return( MSTR ); 152216179Sralph 152316179Sralph case CHAR: 152416179Sralph case SHORT: 152516179Sralph case UCHAR: 152616179Sralph case USHORT: 152716179Sralph return( MINT|MPTI|MDBI ); 152816179Sralph case UNSIGNED: 152916179Sralph case ULONG: 153016179Sralph case INT: 153116179Sralph case LONG: 153216179Sralph return( MINT|MDBI|MPTI ); 153316179Sralph case FLOAT: 153416179Sralph case DOUBLE: 153516179Sralph return( MDBI ); 153616179Sralph default: 153716179Sralph return( MPTR|MPTI ); 153816179Sralph 153916179Sralph } 154016179Sralph } 154116179Sralph 154216179Sralph NODE * 154316179Sralph doszof( p ) register NODE *p; { 154416179Sralph /* do sizeof p */ 154516179Sralph int i; 154616179Sralph 154716179Sralph /* whatever is the meaning of this if it is a bitfield? */ 154816179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; 154916179Sralph 155016179Sralph tfree(p); 155116179Sralph if( i <= 0 ) werror( "sizeof returns 0" ); 155216179Sralph return( bcon( i ) ); 155316179Sralph } 155416179Sralph 155516179Sralph # ifndef BUG2 155616179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; { 155716179Sralph register ty; 155816179Sralph 155916179Sralph *a = *b = down+1; 156016179Sralph while( down > 1 ){ 156116179Sralph printf( "\t" ); 156216179Sralph down -= 2; 156316179Sralph } 156416179Sralph if( down ) printf( " " ); 156516179Sralph 156616179Sralph ty = optype( p->in.op ); 156716179Sralph 156816179Sralph printf("%o) %s, ", p, opst[p->in.op] ); 156916179Sralph if( ty == LTYPE ){ 157016179Sralph printf( CONFMT, p->tn.lval ); 157116179Sralph printf( ", %d, ", p->tn.rval ); 157216179Sralph } 157316179Sralph tprint( p->in.type ); 157416179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); 157516179Sralph } 157616179Sralph # endif 157716179Sralph 157832850Sdonn #ifndef PRTDCON 157916179Sralph prtdcon( p ) register NODE *p; { 158017749Sralph int o = p->in.op, i; 158116179Sralph 158217749Sralph if( o == DCON || o == FCON ){ 158332852Sdonn (void) locctr( DATA ); 158417749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT ); 158516179Sralph deflab( i = getlab() ); 158617749Sralph if( o == FCON ) 158717749Sralph fincode( p->fpn.fval, SZFLOAT ); 158817749Sralph else 158917749Sralph fincode( p->dpn.dval, SZDOUBLE ); 159016179Sralph p->tn.lval = 0; 159116179Sralph p->tn.rval = -i; 159217749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT); 159316179Sralph p->in.op = NAME; 159416179Sralph } 159516179Sralph } 159632850Sdonn #endif PRTDCON 159716179Sralph 159816179Sralph 159916179Sralph int edebug = 0; 160016179Sralph ecomp( p ) register NODE *p; { 160116179Sralph # ifndef BUG2 160216179Sralph if( edebug ) fwalk( p, eprint, 0 ); 160316179Sralph # endif 160416179Sralph if( !reached ){ 160516179Sralph werror( "statement not reached" ); 160616179Sralph reached = 1; 160716179Sralph } 160816179Sralph p = optim(p); 160916179Sralph walkf( p, prtdcon ); 161032852Sdonn (void) locctr( PROG ); 161116179Sralph ecode( p ); 161216179Sralph tfree(p); 161316179Sralph } 161416179Sralph 161516179Sralph # ifdef STDPRTREE 161616179Sralph # ifndef ONEPASS 161716179Sralph 161816179Sralph prtree(p) register NODE *p; { 161916179Sralph 162016179Sralph register struct symtab *q; 162116179Sralph register ty; 162216179Sralph 162316179Sralph # ifdef MYPRTREE 162416179Sralph MYPRTREE(p); /* local action can be taken here; then return... */ 162516179Sralph #endif 162616179Sralph 162716179Sralph ty = optype(p->in.op); 162816179Sralph 162916179Sralph printf( "%d\t", p->in.op ); 163016179Sralph 163116179Sralph if( ty == LTYPE ) { 163216179Sralph printf( CONFMT, p->tn.lval ); 163316179Sralph printf( "\t" ); 163416179Sralph } 163516179Sralph if( ty != BITYPE ) { 163616179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); 163716179Sralph else printf( "%d\t", p->tn.rval ); 163816179Sralph } 163916179Sralph 164016179Sralph printf( "%o\t", p->in.type ); 164116179Sralph 164216179Sralph /* handle special cases */ 164316179Sralph 164416179Sralph switch( p->in.op ){ 164516179Sralph 164616179Sralph case NAME: 164716179Sralph case ICON: 164816179Sralph /* print external name */ 164916179Sralph if( p->tn.rval == NONAME ) printf( "\n" ); 165016179Sralph else if( p->tn.rval >= 0 ){ 165116179Sralph q = &stab[p->tn.rval]; 165216179Sralph printf( "%s\n", exname(q->sname) ); 165316179Sralph } 165416179Sralph else { /* label */ 165516179Sralph printf( LABFMT, -p->tn.rval ); 165616179Sralph } 165716179Sralph break; 165816179Sralph 165916179Sralph case STARG: 166016179Sralph case STASG: 166116179Sralph case STCALL: 166216179Sralph case UNARY STCALL: 166316179Sralph /* print out size */ 166416179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */ 166516179Sralph 166616179Sralph /* note: p->in.left not a field... */ 166716179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); 166816179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); 166916179Sralph break; 167016179Sralph 167116179Sralph default: 167216179Sralph printf( "\n" ); 167316179Sralph } 167416179Sralph 167516179Sralph if( ty != LTYPE ) prtree( p->in.left ); 167616179Sralph if( ty == BITYPE ) prtree( p->in.right ); 167716179Sralph 167816179Sralph } 167916179Sralph 168016179Sralph # else 168116179Sralph 168216179Sralph p2tree(p) register NODE *p; { 168316179Sralph register ty; 168416179Sralph 168516179Sralph # ifdef MYP2TREE 168616179Sralph MYP2TREE(p); /* local action can be taken here; then return... */ 168716179Sralph # endif 168816179Sralph 168916179Sralph ty = optype(p->in.op); 169016179Sralph 169116179Sralph switch( p->in.op ){ 169216179Sralph 169316179Sralph case NAME: 169416179Sralph case ICON: 169516179Sralph #ifndef FLEXNAMES 169616179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; 169716179Sralph #else 169816179Sralph if( p->tn.rval == NONAME ) p->in.name = ""; 169916179Sralph #endif 170016179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */ 170116179Sralph register char *cp; 170216179Sralph cp = exname( stab[p->tn.rval].sname ); 170316179Sralph #ifndef FLEXNAMES 170432852Sdonn { 170532852Sdonn register i; 170632852Sdonn for( i=0; i<NCHNAM; ++i ) 170732852Sdonn p->in.name[i] = *cp++; 170832852Sdonn } 170916179Sralph #else 171016179Sralph p->in.name = tstr(cp); 171116179Sralph #endif 171216179Sralph } 171316179Sralph #ifndef FLEXNAMES 171416179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval ); 171516179Sralph #else 171616179Sralph else { 171716179Sralph char temp[32]; 171816179Sralph sprintf( temp, LABFMT, -p->tn.rval ); 171916179Sralph p->in.name = tstr(temp); 172016179Sralph } 172116179Sralph #endif 172216179Sralph break; 172316179Sralph 172416179Sralph case STARG: 172516179Sralph case STASG: 172616179Sralph case STCALL: 172716179Sralph case UNARY STCALL: 172816179Sralph /* set up size parameters */ 172916179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; 173016179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; 173116179Sralph break; 173216179Sralph 173316179Sralph case REG: 173416179Sralph rbusy( p->tn.rval, p->in.type ); 173516179Sralph default: 173616179Sralph #ifndef FLEXNAMES 173716179Sralph p->in.name[0] = '\0'; 173816179Sralph #else 173916179Sralph p->in.name = ""; 174016179Sralph #endif 174116179Sralph } 174216179Sralph 174316179Sralph p->in.rall = NOPREF; 174416179Sralph 174516179Sralph if( ty != LTYPE ) p2tree( p->in.left ); 174616179Sralph if( ty == BITYPE ) p2tree( p->in.right ); 174716179Sralph } 174816179Sralph 174916179Sralph # endif 175016179Sralph # endif 1751