117749Sralph #ifndef lint 2*34092Sbostic static char *sccsid ="@(#)trees.c 4.35 (Berkeley) 04/24/88"; 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; 66032857Sdonn TWORD utype; 66116179Sralph 66216179Sralph val = q->tn.lval; 66316179Sralph u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type); 66416179Sralph if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 66516179Sralph 66616179Sralph if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0); 66716179Sralph if( q->tn.rval != NONAME && o!=PLUS ) return(0); 66816179Sralph if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0); 66916179Sralph 67032857Sdonn /* usual type conversions -- handle casts of constants */ 67132859Sdonn #define ISLONG(t) ((t) == LONG || (t) == ULONG) 67232859Sdonn if (ISLONG(p->in.type) || ISLONG(q->in.type)) 67332859Sdonn utype = u ? ULONG : LONG; 67432859Sdonn else 67532859Sdonn utype = u ? UNSIGNED : INT; 67632857Sdonn if( !ISPTR(p->in.type) && p->in.type != utype ) 67732857Sdonn p = makety(p, utype, 0, (int)utype); 67832857Sdonn if( q->in.type != utype ) 67932857Sdonn q = makety(q, utype, 0, (int)utype); 68032842Sdonn 68116179Sralph switch( o ){ 68216179Sralph 68316179Sralph case PLUS: 68416179Sralph p->tn.lval += val; 68516179Sralph if( p->tn.rval == NONAME ){ 68616179Sralph p->tn.rval = q->tn.rval; 68716179Sralph p->in.type = q->in.type; 68816179Sralph } 68916179Sralph break; 69016179Sralph case MINUS: 69116179Sralph p->tn.lval -= val; 69216179Sralph break; 69316179Sralph case MUL: 69432840Sdonn p->tn.lval *= val; 69516179Sralph break; 69616179Sralph case DIV: 69716179Sralph if( val == 0 ) uerror( "division by 0" ); 69817749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval / val; 69916179Sralph else p->tn.lval /= val; 70016179Sralph break; 70116179Sralph case MOD: 70216179Sralph if( val == 0 ) uerror( "division by 0" ); 70317749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval % val; 70416179Sralph else p->tn.lval %= val; 70516179Sralph break; 70616179Sralph case AND: 70716179Sralph p->tn.lval &= val; 70816179Sralph break; 70916179Sralph case OR: 71016179Sralph p->tn.lval |= val; 71116179Sralph break; 71216179Sralph case ER: 71317749Sralph p->tn.lval ^= val; 71416179Sralph break; 71516179Sralph case LS: 71616179Sralph i = val; 71716179Sralph p->tn.lval = p->tn.lval << i; 71816179Sralph break; 71916179Sralph case RS: 72016179Sralph i = val; 72117749Sralph if ( u ) p->tn.lval = (unsigned) p->tn.lval >> i; 72217749Sralph else p->tn.lval = p->tn.lval >> i; 72316179Sralph break; 72416179Sralph 72516179Sralph case UNARY MINUS: 72616179Sralph p->tn.lval = - p->tn.lval; 72716179Sralph break; 72816179Sralph case COMPL: 72916179Sralph p->tn.lval = ~p->tn.lval; 73016179Sralph break; 73116179Sralph case NOT: 73216179Sralph p->tn.lval = !p->tn.lval; 73316179Sralph break; 73416179Sralph case LT: 73516179Sralph p->tn.lval = p->tn.lval < val; 73616179Sralph break; 73716179Sralph case LE: 73816179Sralph p->tn.lval = p->tn.lval <= val; 73916179Sralph break; 74016179Sralph case GT: 74116179Sralph p->tn.lval = p->tn.lval > val; 74216179Sralph break; 74316179Sralph case GE: 74416179Sralph p->tn.lval = p->tn.lval >= val; 74516179Sralph break; 74616179Sralph case ULT: 74732848Sdonn p->tn.lval = p->tn.lval < (unsigned) val; 74816179Sralph break; 74916179Sralph case ULE: 75032848Sdonn p->tn.lval = p->tn.lval <= (unsigned) val; 75116179Sralph break; 75232848Sdonn case UGT: 75332848Sdonn p->tn.lval = p->tn.lval > (unsigned) val; 75432848Sdonn break; 75532840Sdonn case UGE: 75632848Sdonn p->tn.lval = p->tn.lval >= (unsigned) val; 75732840Sdonn break; 75816179Sralph case EQ: 75916179Sralph p->tn.lval = p->tn.lval == val; 76016179Sralph break; 76116179Sralph case NE: 76216179Sralph p->tn.lval = p->tn.lval != val; 76316179Sralph break; 76416179Sralph default: 76516179Sralph return(0); 76616179Sralph } 76716179Sralph return(1); 76816179Sralph } 76916179Sralph 77016179Sralph chkpun(p) register NODE *p; { 77116179Sralph 77216179Sralph /* checks p for the existance of a pun */ 77316179Sralph 77416179Sralph /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */ 77516179Sralph 77616179Sralph /* one case is when enumerations are used: this applies only to lint */ 77716179Sralph /* in the other case, one operand is a pointer, the other integer type */ 77816179Sralph /* we check that this integer is in fact a constant zero... */ 77916179Sralph 78016179Sralph /* in the case of ASSIGN, any assignment of pointer to integer is illegal */ 78116179Sralph /* this falls out, because the LHS is never 0 */ 78216179Sralph 78316179Sralph register NODE *q; 78416179Sralph register t1, t2; 78516179Sralph register d1, d2; 78632844Sdonn int ref1, ref2; 78716179Sralph 78816179Sralph t1 = p->in.left->in.type; 78916179Sralph t2 = p->in.right->in.type; 79016179Sralph 79116179Sralph if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */ 79232841Sdonn /* rob pike says this is obnoxious... 79332840Sdonn if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) 79432841Sdonn werror( "comparison of enums" ); */ 79532841Sdonn if( t1==ENUMTY && t2==ENUMTY ) { 79632841Sdonn if ( p->in.left->fn.csiz!=p->in.right->fn.csiz ) 79732841Sdonn werror( "enumeration type clash, operator %s", opst[p->in.op] ); 79832841Sdonn return; 79932841Sdonn } 80032841Sdonn if ( t1 == ENUMTY ) t1 = INT; 80132841Sdonn if ( t2 == ENUMTY ) t2 = INT; 80216179Sralph } 80316179Sralph 80432844Sdonn ref1 = ISPTR(t1) || ISARY(t1); 80532844Sdonn ref2 = ISPTR(t2) || ISARY(t2); 80616179Sralph 80732844Sdonn if( ref1 ^ ref2 ){ 80832844Sdonn if( ref1 ) q = p->in.right; 80932844Sdonn else q = p->in.left; 81016179Sralph if( q->in.op != ICON || q->tn.lval != 0 ){ 81116179Sralph werror( "illegal combination of pointer and integer, op %s", 81216179Sralph opst[p->in.op] ); 81316179Sralph } 81416179Sralph } 81532844Sdonn else if( ref1 ){ 81632843Sdonn if( t1 == t2 ) { 81732843Sdonn if( p->in.left->fn.csiz != p->in.right->fn.csiz ) { 81832843Sdonn werror( "illegal structure pointer combination" ); 81916179Sralph return; 82016179Sralph } 82132843Sdonn d1 = p->in.left->fn.cdim; 82232843Sdonn d2 = p->in.right->fn.cdim; 82332843Sdonn for( ;; ){ 82432843Sdonn if( ISARY(t1) ){ 82532843Sdonn if( dimtab[d1] != dimtab[d2] ){ 82632843Sdonn werror( "illegal array size combination" ); 82732843Sdonn return; 82832843Sdonn } 82932843Sdonn ++d1; 83032843Sdonn ++d2; 83116179Sralph } 83232843Sdonn else if( !ISPTR(t1) ) break; 83332843Sdonn t1 = DECREF(t1); 83416179Sralph } 83516179Sralph } 83632843Sdonn else 83732843Sdonn werror( "illegal pointer combination" ); 83816179Sralph } 83916179Sralph 84016179Sralph } 84116179Sralph 84216179Sralph NODE * 84316179Sralph stref( p ) register NODE *p; { 84416179Sralph 84516179Sralph TWORD t; 84616179Sralph int d, s, dsc, align; 84716179Sralph OFFSZ off; 84816179Sralph register struct symtab *q; 84916179Sralph 85016179Sralph /* make p->x */ 85116179Sralph /* this is also used to reference automatic variables */ 85216179Sralph 85316179Sralph q = &stab[p->in.right->tn.rval]; 85416179Sralph p->in.right->in.op = FREE; 85516179Sralph p->in.op = FREE; 85616179Sralph p = pconvert( p->in.left ); 85716179Sralph 85816179Sralph /* make p look like ptr to x */ 85916179Sralph 86016179Sralph if( !ISPTR(p->in.type)){ 86116179Sralph p->in.type = PTR+UNIONTY; 86216179Sralph } 86316179Sralph 86416179Sralph t = INCREF( q->stype ); 86516179Sralph d = q->dimoff; 86616179Sralph s = q->sizoff; 86716179Sralph 86816179Sralph p = makety( p, t, d, s ); 86916179Sralph 87016179Sralph /* compute the offset to be added */ 87116179Sralph 87216179Sralph off = q->offset; 87316179Sralph dsc = q->sclass; 87416179Sralph 87516179Sralph if( dsc & FIELD ) { /* normalize offset */ 87616179Sralph align = ALINT; 87716179Sralph s = INT; 87816179Sralph off = (off/align)*align; 87916179Sralph } 88016179Sralph if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); 88116179Sralph 88216179Sralph p = buildtree( UNARY MUL, p, NIL ); 88316179Sralph 88416179Sralph /* if field, build field info */ 88516179Sralph 88616179Sralph if( dsc & FIELD ){ 88716179Sralph p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); 88816179Sralph p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); 88916179Sralph } 89016179Sralph 89116179Sralph return( clocal(p) ); 89216179Sralph } 89316179Sralph 89416179Sralph notlval(p) register NODE *p; { 89516179Sralph 89616179Sralph /* return 0 if p an lvalue, 1 otherwise */ 89716179Sralph 89816179Sralph again: 89916179Sralph 90016179Sralph switch( p->in.op ){ 90116179Sralph 90216179Sralph case FLD: 90316179Sralph p = p->in.left; 90416179Sralph goto again; 90516179Sralph 90616179Sralph case UNARY MUL: 90716179Sralph /* fix the &(a=b) bug, given that a and b are structures */ 90816179Sralph if( p->in.left->in.op == STASG ) return( 1 ); 90916179Sralph /* and the f().a bug, given that f returns a structure */ 91016179Sralph if( p->in.left->in.op == UNARY STCALL || 91116179Sralph p->in.left->in.op == STCALL ) return( 1 ); 91216179Sralph case NAME: 91316179Sralph case OREG: 91416179Sralph if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); 91516179Sralph case REG: 91616179Sralph return(0); 91716179Sralph 91816179Sralph default: 91916179Sralph return(1); 92016179Sralph 92116179Sralph } 92216179Sralph 92316179Sralph } 92416179Sralph 92516179Sralph NODE * 92616179Sralph bcon( i ){ /* make a constant node with value i */ 92716179Sralph register NODE *p; 92816179Sralph 92916179Sralph p = block( ICON, NIL, NIL, INT, 0, INT ); 93016179Sralph p->tn.lval = i; 93116179Sralph p->tn.rval = NONAME; 93216179Sralph return( clocal(p) ); 93316179Sralph } 93416179Sralph 93516179Sralph NODE * 93616179Sralph bpsize(p) register NODE *p; { 93716179Sralph return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); 93816179Sralph } 93916179Sralph 94016179Sralph OFFSZ 94116179Sralph psize( p ) NODE *p; { 94216179Sralph /* p is a node of type pointer; psize returns the 94316179Sralph size of the thing pointed to */ 94416179Sralph 94516179Sralph if( !ISPTR(p->in.type) ){ 94616179Sralph uerror( "pointer required"); 94716179Sralph return( SZINT ); 94816179Sralph } 94916179Sralph /* note: no pointers to fields */ 95016179Sralph return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); 95116179Sralph } 95216179Sralph 95316179Sralph NODE * 95416179Sralph convert( p, f ) register NODE *p; { 95516179Sralph /* convert an operand of p 95616179Sralph f is either CVTL or CVTR 95716179Sralph operand has type int, and is converted by the size of the other side 95816179Sralph */ 95916179Sralph 96016179Sralph register NODE *q, *r; 96116179Sralph 96216179Sralph q = (f==CVTL)?p->in.left:p->in.right; 96316179Sralph 96416179Sralph r = block( PMCONV, 96516179Sralph q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT ); 96616179Sralph r = clocal(r); 96716179Sralph if( f == CVTL ) 96816179Sralph p->in.left = r; 96916179Sralph else 97016179Sralph p->in.right = r; 97116179Sralph return(p); 97216179Sralph 97316179Sralph } 97416179Sralph 97525750Sdonn #ifndef econvert 97616179Sralph econvert( p ) register NODE *p; { 97716179Sralph 97816179Sralph /* change enums to ints, or appropriate types */ 97916179Sralph 98016179Sralph register TWORD ty; 98116179Sralph 98216179Sralph if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) { 98316179Sralph if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; 98416179Sralph else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; 98516179Sralph else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; 98616179Sralph else ty = LONG; 98716179Sralph ty = ctype( ty ); 98816179Sralph p->fn.csiz = ty; 98916179Sralph MODTYPE(p->in.type,ty); 99016179Sralph if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT; 99116179Sralph } 99216179Sralph } 99325750Sdonn #endif 99416179Sralph 99516179Sralph NODE * 99616179Sralph pconvert( p ) register NODE *p; { 99716179Sralph 99816179Sralph /* if p should be changed into a pointer, do so */ 99916179Sralph 100016179Sralph if( ISARY( p->in.type) ){ 100116179Sralph p->in.type = DECREF( p->in.type ); 100216179Sralph ++p->fn.cdim; 100316179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100416179Sralph } 100516179Sralph if( ISFTN( p->in.type) ) 100616179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100716179Sralph 100816179Sralph return( p ); 100916179Sralph } 101016179Sralph 101116179Sralph NODE * 101216179Sralph oconvert(p) register NODE *p; { 101316179Sralph /* convert the result itself: used for pointer and unsigned */ 101416179Sralph 101516179Sralph switch(p->in.op) { 101616179Sralph 101716179Sralph case LE: 101816179Sralph case LT: 101916179Sralph case GE: 102016179Sralph case GT: 102116179Sralph if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE); 102216179Sralph case EQ: 102316179Sralph case NE: 102416179Sralph return( p ); 102516179Sralph 102616179Sralph case MINUS: 102716179Sralph return( clocal( block( PVCONV, 102816179Sralph p, bpsize(p->in.left), INT, 0, INT ) ) ); 102916179Sralph } 103016179Sralph 103116179Sralph cerror( "illegal oconvert: %d", p->in.op ); 103216179Sralph 103316179Sralph return(p); 103416179Sralph } 103516179Sralph 103616179Sralph NODE * 103716179Sralph ptmatch(p) register NODE *p; { 103816179Sralph 103916179Sralph /* makes the operands of p agree; they are 104016179Sralph either pointers or integers, by this time */ 104116179Sralph /* with MINUS, the sizes must be the same */ 104216179Sralph /* with COLON, the types must be the same */ 104316179Sralph 104416179Sralph TWORD t1, t2, t; 104516179Sralph int o, d2, d, s2, s; 104616179Sralph 104716179Sralph o = p->in.op; 104816179Sralph t = t1 = p->in.left->in.type; 104916179Sralph t2 = p->in.right->in.type; 105016179Sralph d = p->in.left->fn.cdim; 105116179Sralph d2 = p->in.right->fn.cdim; 105216179Sralph s = p->in.left->fn.csiz; 105316179Sralph s2 = p->in.right->fn.csiz; 105416179Sralph 105516179Sralph switch( o ){ 105616179Sralph 105716179Sralph case ASSIGN: 105816179Sralph case RETURN: 105916179Sralph case CAST: 106016179Sralph { break; } 106116179Sralph 106216179Sralph case MINUS: 106316179Sralph { if( psize(p->in.left) != psize(p->in.right) ){ 106416179Sralph uerror( "illegal pointer subtraction"); 106516179Sralph } 106616179Sralph break; 106716179Sralph } 106816179Sralph case COLON: 106916179Sralph { if( t1 != t2 ) uerror( "illegal types in :"); 107016179Sralph break; 107116179Sralph } 107216179Sralph default: /* must work harder: relationals or comparisons */ 107316179Sralph 107416179Sralph if( !ISPTR(t1) ){ 107516179Sralph t = t2; 107616179Sralph d = d2; 107716179Sralph s = s2; 107816179Sralph break; 107916179Sralph } 108016179Sralph if( !ISPTR(t2) ){ 108116179Sralph break; 108216179Sralph } 108316179Sralph 108416179Sralph /* both are pointers */ 108516179Sralph if( talign(t2,s2) < talign(t,s) ){ 108616179Sralph t = t2; 108716179Sralph s = s2; 108816179Sralph } 108916179Sralph break; 109016179Sralph } 109116179Sralph 109216179Sralph p->in.left = makety( p->in.left, t, d, s ); 109316179Sralph p->in.right = makety( p->in.right, t, d, s ); 109416179Sralph if( o!=MINUS && !logop(o) ){ 109516179Sralph 109616179Sralph p->in.type = t; 109716179Sralph p->fn.cdim = d; 109816179Sralph p->fn.csiz = s; 109916179Sralph } 110016179Sralph 110116179Sralph return(clocal(p)); 110216179Sralph } 110316179Sralph 110416179Sralph int tdebug = 0; 110516179Sralph 110616179Sralph NODE * 110716179Sralph tymatch(p) register NODE *p; { 110816179Sralph 110916179Sralph /* satisfy the types of various arithmetic binary ops */ 111016179Sralph 111116179Sralph /* rules are: 111225750Sdonn if assignment, type of LHS 111316179Sralph if any float or doubles, make double 111416179Sralph if any longs, make long 111516179Sralph otherwise, make int 111616179Sralph if either operand is unsigned, the result is... 111716179Sralph */ 111816179Sralph 111916179Sralph register TWORD t1, t2, t, tu; 112016179Sralph register o, u; 112116179Sralph 112216179Sralph o = p->in.op; 112316179Sralph 112416179Sralph t1 = p->in.left->in.type; 112516179Sralph t2 = p->in.right->in.type; 112616179Sralph if( (t1==UNDEF || t2==UNDEF) && o!=CAST ) 112716179Sralph uerror("void type illegal in expression"); 112816179Sralph 112916179Sralph u = 0; 113016179Sralph if( ISUNSIGNED(t1) ){ 113116179Sralph u = 1; 113216179Sralph t1 = DEUNSIGN(t1); 113316179Sralph } 113416179Sralph if( ISUNSIGNED(t2) ){ 113516179Sralph u = 1; 113616179Sralph t2 = DEUNSIGN(t2); 113716179Sralph } 113816179Sralph 113916179Sralph if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT; 114016179Sralph if( t2 == CHAR || t2 == SHORT ) t2 = INT; 114116179Sralph 114217749Sralph #ifdef SPRECC 114317749Sralph if( t1 == DOUBLE || t2 == DOUBLE ) 114417749Sralph t = DOUBLE; 114517749Sralph else if( t1 == FLOAT || t2 == FLOAT ) 114617749Sralph t = FLOAT; 114717749Sralph #else 114817749Sralph if (t1 == DOUBLE || t1 == FLOAT || t2 == DOUBLE || t2 == FLOAT) 114917749Sralph t = DOUBLE; 115017749Sralph #endif 115116179Sralph else if( t1==LONG || t2==LONG ) t = LONG; 115216179Sralph else t = INT; 115316179Sralph 115432853Sdonn if( o == ASSIGN || o == CAST || o == RETURN ) 115532853Sdonn { 115616179Sralph tu = p->in.left->in.type; 115716179Sralph t = t1; 115816179Sralph } 115916179Sralph else { 116016179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; 116116179Sralph } 116216179Sralph 116316179Sralph /* because expressions have values that are at least as wide 116416179Sralph as INT or UNSIGNED, the only conversions needed 116516179Sralph are those involving FLOAT/DOUBLE, and those 116616179Sralph from LONG to INT and ULONG to UNSIGNED */ 116716179Sralph 116832858Sdonn if( (t != t1 || (u && !ISUNSIGNED(p->in.left->in.type))) && ! asgop(o) ) 116925750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu ); 117016179Sralph 117132858Sdonn if( t != t2 || (u && !ISUNSIGNED(p->in.right->in.type)) || o==CAST) 117232840Sdonn if ( tu == ENUMTY ) {/* always asgop */ 117332840Sdonn p->in.right = makety( p->in.right, INT, 0, INT ); 117432840Sdonn p->in.right->in.type = tu; 117532840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim; 117632840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz; 117732840Sdonn } 117832840Sdonn else 117932840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu ); 118016179Sralph 118116179Sralph if( asgop(o) ){ 118216179Sralph p->in.type = p->in.left->in.type; 118316179Sralph p->fn.cdim = p->in.left->fn.cdim; 118416179Sralph p->fn.csiz = p->in.left->fn.csiz; 118516179Sralph } 118616179Sralph else if( !logop(o) ){ 118716179Sralph p->in.type = tu; 118816179Sralph p->fn.cdim = 0; 118916179Sralph p->fn.csiz = t; 119016179Sralph } 119116179Sralph 119216179Sralph # ifndef BUG1 119316179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); 119416179Sralph # endif 119516179Sralph 119616179Sralph return(p); 119716179Sralph } 119816179Sralph 119916179Sralph NODE * 120016179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; { 120116179Sralph /* make p into type t by inserting a conversion */ 120216179Sralph 120316179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); 120416179Sralph if( t == p->in.type ){ 120516179Sralph p->fn.cdim = d; 120616179Sralph p->fn.csiz = s; 120716179Sralph return( p ); 120816179Sralph } 120916179Sralph 121016179Sralph if( t & TMASK ){ 121116179Sralph /* non-simple type */ 121217228Sralph return( block( PCONV, p, NIL, t, d, s ) ); 121316179Sralph } 121416179Sralph 121516179Sralph if( p->in.op == ICON ){ 121617749Sralph if (t == DOUBLE) { 121717749Sralph p->in.op = DCON; 121817749Sralph if (ISUNSIGNED(p->in.type)) 1219*34092Sbostic p->dpn.dval = (U_CONSZ) p->tn.lval; 122017749Sralph else 122117749Sralph p->dpn.dval = p->tn.lval; 122217749Sralph p->in.type = p->fn.csiz = t; 122317749Sralph return (clocal(p)); 122417749Sralph } 122517749Sralph if (t == FLOAT) { 122616179Sralph p->in.op = FCON; 122716179Sralph if( ISUNSIGNED(p->in.type) ){ 1228*34092Sbostic p->fpn.fval = (U_CONSZ) p->tn.lval; 122916179Sralph } 123016179Sralph else { 123117749Sralph p->fpn.fval = p->tn.lval; 123216179Sralph } 123316179Sralph 123416179Sralph p->in.type = p->fn.csiz = t; 123516179Sralph return( clocal(p) ); 123616179Sralph } 123716179Sralph } 123817749Sralph else if (p->in.op == FCON && t == DOUBLE) { 123917749Sralph double db; 124016179Sralph 124117749Sralph p->in.op = DCON; 124217749Sralph db = p->fpn.fval; 124317749Sralph p->dpn.dval = db; 124417749Sralph p->in.type = p->fn.csiz = t; 124517749Sralph return (clocal(p)); 124617749Sralph } else if (p->in.op == DCON && t == FLOAT) { 124717749Sralph float fl; 124817749Sralph 124917749Sralph p->in.op = FCON; 125017749Sralph fl = p->dpn.dval; 125117749Sralph #ifdef notdef 125217749Sralph if (fl != p->dpn.dval) 125317749Sralph werror("float conversion loses precision"); 125417749Sralph #endif 125517749Sralph p->fpn.fval = fl; 125617749Sralph p->in.type = p->fn.csiz = t; 125717749Sralph return (clocal(p)); 125817749Sralph } 125917749Sralph 126017049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) ); 126116179Sralph 126216179Sralph } 126316179Sralph 126416179Sralph NODE * 126516179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { 126616179Sralph 126716179Sralph register NODE *p; 126816179Sralph 126916179Sralph p = talloc(); 127016179Sralph p->in.op = o; 127116179Sralph p->in.left = l; 127216179Sralph p->in.right = r; 127316179Sralph p->in.type = t; 127416179Sralph p->fn.cdim = d; 127516179Sralph p->fn.csiz = s; 127616179Sralph return(p); 127716179Sralph } 127816179Sralph 127916179Sralph icons(p) register NODE *p; { 128016179Sralph /* if p is an integer constant, return its value */ 128116179Sralph int val; 128216179Sralph 128316179Sralph if( p->in.op != ICON ){ 128416179Sralph uerror( "constant expected"); 128516179Sralph val = 1; 128616179Sralph } 128716179Sralph else { 128816179Sralph val = p->tn.lval; 128916179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); 129016179Sralph } 129116179Sralph tfree( p ); 129216179Sralph return(val); 129316179Sralph } 129416179Sralph 129516179Sralph /* the intent of this table is to examine the 129616179Sralph operators, and to check them for 129716179Sralph correctness. 129816179Sralph 129916179Sralph The table is searched for the op and the 130016179Sralph modified type (where this is one of the 130116179Sralph types INT (includes char and short), LONG, 130216179Sralph DOUBLE (includes FLOAT), and POINTER 130316179Sralph 130416179Sralph The default action is to make the node type integer 130516179Sralph 130616179Sralph The actions taken include: 130716179Sralph PUN check for puns 130816179Sralph CVTL convert the left operand 130916179Sralph CVTR convert the right operand 131016179Sralph TYPL the type is determined by the left operand 131116179Sralph TYPR the type is determined by the right operand 131216179Sralph TYMATCH force type of left and right to match, by inserting conversions 131316179Sralph PTMATCH like TYMATCH, but for pointers 131416179Sralph LVAL left operand must be lval 131516179Sralph CVTO convert the op 131616179Sralph NCVT do not convert the operands 131716179Sralph OTHER handled by code 131816179Sralph NCVTR convert the left operand, not the right... 131916179Sralph 132016179Sralph */ 132116179Sralph 132216179Sralph # define MINT 01 /* integer */ 132316179Sralph # define MDBI 02 /* integer or double */ 132416179Sralph # define MSTR 04 /* structure */ 132516179Sralph # define MPTR 010 /* pointer */ 132616179Sralph # define MPTI 020 /* pointer or integer */ 132716179Sralph # define MENU 040 /* enumeration variable or member */ 132824408Smckusick # define MVOID 0100000 /* void type */ 132916179Sralph 133016179Sralph opact( p ) NODE *p; { 133116179Sralph 133216179Sralph register mt12, mt1, mt2, o; 133316179Sralph 133424408Smckusick mt1 = mt2 = mt12 = 0; 133516179Sralph 133616179Sralph switch( optype(o=p->in.op) ){ 133716179Sralph 133816179Sralph case BITYPE: 133924408Smckusick mt2 = moditype( p->in.right->in.type ); 134016179Sralph case UTYPE: 134124408Smckusick mt1 = moditype( p->in.left->in.type ); 134224408Smckusick break; 134316179Sralph 134416179Sralph } 134516179Sralph 134624408Smckusick if( ((mt1 | mt2) & MVOID) && 134724408Smckusick o != COMOP && 134832845Sdonn o != COLON && 134932845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) && 135024408Smckusick !(o == CAST && (mt1 & MVOID)) ){ 135124408Smckusick /* if lhs of RETURN is void, grammar will complain */ 135224408Smckusick if( o != RETURN ) 135324408Smckusick uerror( "value of void expression used" ); 135424408Smckusick return( NCVT ); 135524408Smckusick } 135624408Smckusick mt12 = mt1 & mt2; 135724408Smckusick 135816179Sralph switch( o ){ 135916179Sralph 136016179Sralph case NAME : 136116179Sralph case STRING : 136216179Sralph case ICON : 136316179Sralph case FCON : 136417749Sralph case DCON : 136516179Sralph case CALL : 136616179Sralph case UNARY CALL: 136716179Sralph case UNARY MUL: 136816179Sralph { return( OTHER ); } 136916179Sralph case UNARY MINUS: 137032844Sdonn if( mt1 & MENU ) return( 0 ); 137116179Sralph if( mt1 & MDBI ) return( TYPL ); 137216179Sralph break; 137316179Sralph 137416179Sralph case COMPL: 137532844Sdonn if( mt1 & MENU ) return( 0 ); 137616179Sralph if( mt1 & MINT ) return( TYPL ); 137716179Sralph break; 137816179Sralph 137916179Sralph case UNARY AND: 138016179Sralph { return( NCVT+OTHER ); } 138116179Sralph case INIT: 138216179Sralph case CM: 138316180Sralph return( 0 ); 138416180Sralph 138516179Sralph case NOT: 138616179Sralph case CBRANCH: 138716180Sralph if( mt1 & MSTR ) break; 138816180Sralph return( 0 ); 138916180Sralph 139016179Sralph case ANDAND: 139116179Sralph case OROR: 139216180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break; 139316179Sralph return( 0 ); 139416179Sralph 139516179Sralph case MUL: 139616179Sralph case DIV: 139716179Sralph if( mt12 & MDBI ) return( TYMATCH ); 139816179Sralph break; 139916179Sralph 140016179Sralph case MOD: 140116179Sralph case AND: 140216179Sralph case OR: 140316179Sralph case ER: 140416179Sralph if( mt12 & MINT ) return( TYMATCH ); 140516179Sralph break; 140616179Sralph 140716179Sralph case LS: 140816179Sralph case RS: 140916179Sralph if( mt12 & MINT ) return( TYMATCH+OTHER ); 141016179Sralph break; 141116179Sralph 141216179Sralph case EQ: 141316179Sralph case NE: 141416179Sralph case LT: 141516179Sralph case LE: 141616179Sralph case GT: 141716179Sralph case GE: 141832844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN ); 141932844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO ); 142016179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN ); 142116179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN ); 142216179Sralph else break; 142316179Sralph 142416179Sralph case QUEST: 142516179Sralph case COMOP: 142616179Sralph if( mt2&MENU ) return( TYPR+NCVTR ); 142716179Sralph return( TYPR ); 142816179Sralph 142916179Sralph case STREF: 143016179Sralph return( NCVTR+OTHER ); 143116179Sralph 143216179Sralph case FORCE: 143316179Sralph return( TYPL ); 143416179Sralph 143516179Sralph case COLON: 143632844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH ); 143732844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH ); 143816179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 143916179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 144016179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 144116179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 144232845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL ); 144316179Sralph break; 144416179Sralph 144516179Sralph case ASSIGN: 144616179Sralph case RETURN: 144716179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 144832844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN ); 144916179Sralph case CAST: 145032846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH); 145132844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH ); 145232846Sdonn else if( mt2 == MVOID && 145318436Smckusick ( p->in.right->in.op == CALL || 145418436Smckusick p->in.right->in.op == UNARY CALL)) break; 145532854Sdonn else if( (mt1 & MPTR) && (mt2 & MPTI) ) 145632854Sdonn return( LVAL+PTMATCH+PUN ); 145716179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 145816179Sralph break; 145916179Sralph 146016179Sralph case ASG LS: 146116179Sralph case ASG RS: 146216179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 146316179Sralph break; 146416179Sralph 146516179Sralph case ASG MUL: 146616179Sralph case ASG DIV: 146716179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH ); 146816179Sralph break; 146916179Sralph 147016179Sralph case ASG MOD: 147116179Sralph case ASG AND: 147216179Sralph case ASG OR: 147316179Sralph case ASG ER: 147416179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH ); 147516179Sralph break; 147616179Sralph 147716179Sralph case ASG PLUS: 147816179Sralph case ASG MINUS: 147916179Sralph case INCR: 148016179Sralph case DECR: 148116179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL ); 148216179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); 148316179Sralph break; 148416179Sralph 148516179Sralph case MINUS: 148616179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); 148716179Sralph if( mt2 & MPTR ) break; 148816179Sralph case PLUS: 148916179Sralph if( mt12 & MDBI ) return( TYMATCH ); 149016179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); 149116179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); 149216179Sralph 149316179Sralph } 149424408Smckusick if( mt12 == MSTR ) 149524408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] ); 149624408Smckusick else 149724408Smckusick uerror( "operands of %s have incompatible types", opst[o] ); 149816179Sralph return( NCVT ); 149916179Sralph } 150016179Sralph 150116179Sralph moditype( ty ) TWORD ty; { 150216179Sralph 150316179Sralph switch( ty ){ 150416179Sralph 150516179Sralph case UNDEF: 150624408Smckusick return( MVOID ); 150716179Sralph case ENUMTY: 150816179Sralph case MOETY: 150932840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */ 151016179Sralph 151116179Sralph case STRTY: 151216179Sralph case UNIONTY: 151316179Sralph return( MSTR ); 151416179Sralph 151516179Sralph case CHAR: 151616179Sralph case SHORT: 151716179Sralph case UCHAR: 151816179Sralph case USHORT: 151916179Sralph return( MINT|MPTI|MDBI ); 152016179Sralph case UNSIGNED: 152116179Sralph case ULONG: 152216179Sralph case INT: 152316179Sralph case LONG: 152416179Sralph return( MINT|MDBI|MPTI ); 152516179Sralph case FLOAT: 152616179Sralph case DOUBLE: 152716179Sralph return( MDBI ); 152816179Sralph default: 152916179Sralph return( MPTR|MPTI ); 153016179Sralph 153116179Sralph } 153216179Sralph } 153316179Sralph 153416179Sralph NODE * 153516179Sralph doszof( p ) register NODE *p; { 153616179Sralph /* do sizeof p */ 153716179Sralph int i; 153816179Sralph 153916179Sralph /* whatever is the meaning of this if it is a bitfield? */ 154016179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; 154116179Sralph 154216179Sralph tfree(p); 154316179Sralph if( i <= 0 ) werror( "sizeof returns 0" ); 154416179Sralph return( bcon( i ) ); 154516179Sralph } 154616179Sralph 154716179Sralph # ifndef BUG2 154816179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; { 154916179Sralph register ty; 155016179Sralph 155116179Sralph *a = *b = down+1; 155216179Sralph while( down > 1 ){ 155316179Sralph printf( "\t" ); 155416179Sralph down -= 2; 155516179Sralph } 155616179Sralph if( down ) printf( " " ); 155716179Sralph 155816179Sralph ty = optype( p->in.op ); 155916179Sralph 156016179Sralph printf("%o) %s, ", p, opst[p->in.op] ); 156116179Sralph if( ty == LTYPE ){ 156216179Sralph printf( CONFMT, p->tn.lval ); 156316179Sralph printf( ", %d, ", p->tn.rval ); 156416179Sralph } 156516179Sralph tprint( p->in.type ); 156616179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); 156716179Sralph } 156816179Sralph # endif 156916179Sralph 157032850Sdonn #ifndef PRTDCON 157116179Sralph prtdcon( p ) register NODE *p; { 157217749Sralph int o = p->in.op, i; 157316179Sralph 157417749Sralph if( o == DCON || o == FCON ){ 157532852Sdonn (void) locctr( DATA ); 157617749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT ); 157716179Sralph deflab( i = getlab() ); 157817749Sralph if( o == FCON ) 157917749Sralph fincode( p->fpn.fval, SZFLOAT ); 158017749Sralph else 158117749Sralph fincode( p->dpn.dval, SZDOUBLE ); 158216179Sralph p->tn.lval = 0; 158316179Sralph p->tn.rval = -i; 158417749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT); 158516179Sralph p->in.op = NAME; 158616179Sralph } 158716179Sralph } 158832850Sdonn #endif PRTDCON 158916179Sralph 159016179Sralph 159116179Sralph int edebug = 0; 159216179Sralph ecomp( p ) register NODE *p; { 159316179Sralph # ifndef BUG2 159416179Sralph if( edebug ) fwalk( p, eprint, 0 ); 159516179Sralph # endif 159616179Sralph if( !reached ){ 159716179Sralph werror( "statement not reached" ); 159816179Sralph reached = 1; 159916179Sralph } 160016179Sralph p = optim(p); 160116179Sralph walkf( p, prtdcon ); 160232852Sdonn (void) locctr( PROG ); 160316179Sralph ecode( p ); 160416179Sralph tfree(p); 160516179Sralph } 160616179Sralph 160716179Sralph # ifdef STDPRTREE 160816179Sralph # ifndef ONEPASS 160916179Sralph 161016179Sralph prtree(p) register NODE *p; { 161116179Sralph 161216179Sralph register struct symtab *q; 161316179Sralph register ty; 161416179Sralph 161516179Sralph # ifdef MYPRTREE 161616179Sralph MYPRTREE(p); /* local action can be taken here; then return... */ 161716179Sralph #endif 161816179Sralph 161916179Sralph ty = optype(p->in.op); 162016179Sralph 162116179Sralph printf( "%d\t", p->in.op ); 162216179Sralph 162316179Sralph if( ty == LTYPE ) { 162416179Sralph printf( CONFMT, p->tn.lval ); 162516179Sralph printf( "\t" ); 162616179Sralph } 162716179Sralph if( ty != BITYPE ) { 162816179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); 162916179Sralph else printf( "%d\t", p->tn.rval ); 163016179Sralph } 163116179Sralph 163216179Sralph printf( "%o\t", p->in.type ); 163316179Sralph 163416179Sralph /* handle special cases */ 163516179Sralph 163616179Sralph switch( p->in.op ){ 163716179Sralph 163816179Sralph case NAME: 163916179Sralph case ICON: 164016179Sralph /* print external name */ 164116179Sralph if( p->tn.rval == NONAME ) printf( "\n" ); 164216179Sralph else if( p->tn.rval >= 0 ){ 164316179Sralph q = &stab[p->tn.rval]; 164416179Sralph printf( "%s\n", exname(q->sname) ); 164516179Sralph } 164616179Sralph else { /* label */ 164716179Sralph printf( LABFMT, -p->tn.rval ); 164816179Sralph } 164916179Sralph break; 165016179Sralph 165116179Sralph case STARG: 165216179Sralph case STASG: 165316179Sralph case STCALL: 165416179Sralph case UNARY STCALL: 165516179Sralph /* print out size */ 165616179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */ 165716179Sralph 165816179Sralph /* note: p->in.left not a field... */ 165916179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); 166016179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); 166116179Sralph break; 166216179Sralph 166316179Sralph default: 166416179Sralph printf( "\n" ); 166516179Sralph } 166616179Sralph 166716179Sralph if( ty != LTYPE ) prtree( p->in.left ); 166816179Sralph if( ty == BITYPE ) prtree( p->in.right ); 166916179Sralph 167016179Sralph } 167116179Sralph 167216179Sralph # else 167316179Sralph 167416179Sralph p2tree(p) register NODE *p; { 167516179Sralph register ty; 167616179Sralph 167716179Sralph # ifdef MYP2TREE 167816179Sralph MYP2TREE(p); /* local action can be taken here; then return... */ 167916179Sralph # endif 168016179Sralph 168116179Sralph ty = optype(p->in.op); 168216179Sralph 168316179Sralph switch( p->in.op ){ 168416179Sralph 168516179Sralph case NAME: 168616179Sralph case ICON: 168716179Sralph #ifndef FLEXNAMES 168816179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; 168916179Sralph #else 169016179Sralph if( p->tn.rval == NONAME ) p->in.name = ""; 169116179Sralph #endif 169216179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */ 169316179Sralph register char *cp; 169416179Sralph cp = exname( stab[p->tn.rval].sname ); 169516179Sralph #ifndef FLEXNAMES 169632852Sdonn { 169732852Sdonn register i; 169832852Sdonn for( i=0; i<NCHNAM; ++i ) 169932852Sdonn p->in.name[i] = *cp++; 170032852Sdonn } 170116179Sralph #else 170216179Sralph p->in.name = tstr(cp); 170316179Sralph #endif 170416179Sralph } 170516179Sralph #ifndef FLEXNAMES 170616179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval ); 170716179Sralph #else 170816179Sralph else { 170916179Sralph char temp[32]; 171016179Sralph sprintf( temp, LABFMT, -p->tn.rval ); 171116179Sralph p->in.name = tstr(temp); 171216179Sralph } 171316179Sralph #endif 171416179Sralph break; 171516179Sralph 171616179Sralph case STARG: 171716179Sralph case STASG: 171816179Sralph case STCALL: 171916179Sralph case UNARY STCALL: 172016179Sralph /* set up size parameters */ 172116179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; 172216179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; 172316179Sralph break; 172416179Sralph 172516179Sralph case REG: 172616179Sralph rbusy( p->tn.rval, p->in.type ); 172716179Sralph default: 172816179Sralph #ifndef FLEXNAMES 172916179Sralph p->in.name[0] = '\0'; 173016179Sralph #else 173116179Sralph p->in.name = ""; 173216179Sralph #endif 173316179Sralph } 173416179Sralph 173516179Sralph p->in.rall = NOPREF; 173616179Sralph 173716179Sralph if( ty != LTYPE ) p2tree( p->in.left ); 173816179Sralph if( ty == BITYPE ) p2tree( p->in.right ); 173916179Sralph } 174016179Sralph 174116179Sralph # endif 174216179Sralph # endif 1743