117749Sralph #ifndef lint 2*32852Sdonn static char *sccsid ="@(#)trees.c 4.27 (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 115332850Sdonn if( asgop(o) ){ 115432850Sdonn #else 115525750Sdonn if( o == ASSIGN || o == CAST || o == RETURN ){ 115632850Sdonn #endif 115716179Sralph tu = p->in.left->in.type; 115816179Sralph t = t1; 115916179Sralph } 116016179Sralph else { 116116179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; 116216179Sralph } 116316179Sralph 116416179Sralph /* because expressions have values that are at least as wide 116516179Sralph as INT or UNSIGNED, the only conversions needed 116616179Sralph are those involving FLOAT/DOUBLE, and those 116716179Sralph from LONG to INT and ULONG to UNSIGNED */ 116816179Sralph 116932850Sdonn #ifdef tahoe 117032850Sdonn if( t != t1 ) 117132850Sdonn #else 117225750Sdonn if( t != t1 && ! asgop(o) ) 117332850Sdonn #endif 117425750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu ); 117516179Sralph 117632840Sdonn if( t != t2 || o==CAST) 117732840Sdonn if ( tu == ENUMTY ) {/* always asgop */ 117832840Sdonn p->in.right = makety( p->in.right, INT, 0, INT ); 117932840Sdonn p->in.right->in.type = tu; 118032840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim; 118132840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz; 118232840Sdonn } 118332840Sdonn else 118432840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu ); 118516179Sralph 118616179Sralph if( asgop(o) ){ 118716179Sralph p->in.type = p->in.left->in.type; 118816179Sralph p->fn.cdim = p->in.left->fn.cdim; 118916179Sralph p->fn.csiz = p->in.left->fn.csiz; 119016179Sralph } 119116179Sralph else if( !logop(o) ){ 119216179Sralph p->in.type = tu; 119316179Sralph p->fn.cdim = 0; 119416179Sralph p->fn.csiz = t; 119516179Sralph } 119616179Sralph 119716179Sralph # ifndef BUG1 119816179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); 119916179Sralph # endif 120016179Sralph 120116179Sralph return(p); 120216179Sralph } 120316179Sralph 120416179Sralph NODE * 120516179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; { 120616179Sralph /* make p into type t by inserting a conversion */ 120716179Sralph 120816179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); 120916179Sralph if( t == p->in.type ){ 121016179Sralph p->fn.cdim = d; 121116179Sralph p->fn.csiz = s; 121216179Sralph return( p ); 121316179Sralph } 121416179Sralph 121516179Sralph if( t & TMASK ){ 121616179Sralph /* non-simple type */ 121717228Sralph return( block( PCONV, p, NIL, t, d, s ) ); 121816179Sralph } 121916179Sralph 122016179Sralph if( p->in.op == ICON ){ 122117749Sralph if (t == DOUBLE) { 122217749Sralph p->in.op = DCON; 122317749Sralph if (ISUNSIGNED(p->in.type)) 122432847Sdonn p->dpn.dval = (unsigned CONSZ) p->tn.lval; 122517749Sralph else 122617749Sralph p->dpn.dval = p->tn.lval; 122717749Sralph p->in.type = p->fn.csiz = t; 122817749Sralph return (clocal(p)); 122917749Sralph } 123017749Sralph if (t == FLOAT) { 123116179Sralph p->in.op = FCON; 123216179Sralph if( ISUNSIGNED(p->in.type) ){ 123332847Sdonn p->fpn.fval = (unsigned CONSZ) p->tn.lval; 123416179Sralph } 123516179Sralph else { 123617749Sralph p->fpn.fval = p->tn.lval; 123716179Sralph } 123816179Sralph 123916179Sralph p->in.type = p->fn.csiz = t; 124016179Sralph return( clocal(p) ); 124116179Sralph } 124216179Sralph } 124317749Sralph else if (p->in.op == FCON && t == DOUBLE) { 124417749Sralph double db; 124516179Sralph 124617749Sralph p->in.op = DCON; 124717749Sralph db = p->fpn.fval; 124817749Sralph p->dpn.dval = db; 124917749Sralph p->in.type = p->fn.csiz = t; 125017749Sralph return (clocal(p)); 125117749Sralph } else if (p->in.op == DCON && t == FLOAT) { 125217749Sralph float fl; 125317749Sralph 125417749Sralph p->in.op = FCON; 125517749Sralph fl = p->dpn.dval; 125617749Sralph #ifdef notdef 125717749Sralph if (fl != p->dpn.dval) 125817749Sralph werror("float conversion loses precision"); 125917749Sralph #endif 126017749Sralph p->fpn.fval = fl; 126117749Sralph p->in.type = p->fn.csiz = t; 126217749Sralph return (clocal(p)); 126317749Sralph } 126417749Sralph 126517049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) ); 126616179Sralph 126716179Sralph } 126816179Sralph 126916179Sralph NODE * 127016179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { 127116179Sralph 127216179Sralph register NODE *p; 127316179Sralph 127416179Sralph p = talloc(); 127516179Sralph p->in.op = o; 127616179Sralph p->in.left = l; 127716179Sralph p->in.right = r; 127816179Sralph p->in.type = t; 127916179Sralph p->fn.cdim = d; 128016179Sralph p->fn.csiz = s; 128116179Sralph return(p); 128216179Sralph } 128316179Sralph 128416179Sralph icons(p) register NODE *p; { 128516179Sralph /* if p is an integer constant, return its value */ 128616179Sralph int val; 128716179Sralph 128816179Sralph if( p->in.op != ICON ){ 128916179Sralph uerror( "constant expected"); 129016179Sralph val = 1; 129116179Sralph } 129216179Sralph else { 129316179Sralph val = p->tn.lval; 129416179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); 129516179Sralph } 129616179Sralph tfree( p ); 129716179Sralph return(val); 129816179Sralph } 129916179Sralph 130016179Sralph /* the intent of this table is to examine the 130116179Sralph operators, and to check them for 130216179Sralph correctness. 130316179Sralph 130416179Sralph The table is searched for the op and the 130516179Sralph modified type (where this is one of the 130616179Sralph types INT (includes char and short), LONG, 130716179Sralph DOUBLE (includes FLOAT), and POINTER 130816179Sralph 130916179Sralph The default action is to make the node type integer 131016179Sralph 131116179Sralph The actions taken include: 131216179Sralph PUN check for puns 131316179Sralph CVTL convert the left operand 131416179Sralph CVTR convert the right operand 131516179Sralph TYPL the type is determined by the left operand 131616179Sralph TYPR the type is determined by the right operand 131716179Sralph TYMATCH force type of left and right to match, by inserting conversions 131816179Sralph PTMATCH like TYMATCH, but for pointers 131916179Sralph LVAL left operand must be lval 132016179Sralph CVTO convert the op 132116179Sralph NCVT do not convert the operands 132216179Sralph OTHER handled by code 132316179Sralph NCVTR convert the left operand, not the right... 132416179Sralph 132516179Sralph */ 132616179Sralph 132716179Sralph # define MINT 01 /* integer */ 132816179Sralph # define MDBI 02 /* integer or double */ 132916179Sralph # define MSTR 04 /* structure */ 133016179Sralph # define MPTR 010 /* pointer */ 133116179Sralph # define MPTI 020 /* pointer or integer */ 133216179Sralph # define MENU 040 /* enumeration variable or member */ 133324408Smckusick # define MVOID 0100000 /* void type */ 133416179Sralph 133516179Sralph opact( p ) NODE *p; { 133616179Sralph 133716179Sralph register mt12, mt1, mt2, o; 133816179Sralph 133924408Smckusick mt1 = mt2 = mt12 = 0; 134016179Sralph 134116179Sralph switch( optype(o=p->in.op) ){ 134216179Sralph 134316179Sralph case BITYPE: 134424408Smckusick mt2 = moditype( p->in.right->in.type ); 134516179Sralph case UTYPE: 134624408Smckusick mt1 = moditype( p->in.left->in.type ); 134724408Smckusick break; 134816179Sralph 134916179Sralph } 135016179Sralph 135124408Smckusick if( ((mt1 | mt2) & MVOID) && 135224408Smckusick o != COMOP && 135332845Sdonn o != COLON && 135432845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) && 135524408Smckusick !(o == CAST && (mt1 & MVOID)) ){ 135624408Smckusick /* if lhs of RETURN is void, grammar will complain */ 135724408Smckusick if( o != RETURN ) 135824408Smckusick uerror( "value of void expression used" ); 135924408Smckusick return( NCVT ); 136024408Smckusick } 136124408Smckusick mt12 = mt1 & mt2; 136224408Smckusick 136316179Sralph switch( o ){ 136416179Sralph 136516179Sralph case NAME : 136616179Sralph case STRING : 136716179Sralph case ICON : 136816179Sralph case FCON : 136917749Sralph case DCON : 137016179Sralph case CALL : 137116179Sralph case UNARY CALL: 137216179Sralph case UNARY MUL: 137316179Sralph { return( OTHER ); } 137416179Sralph case UNARY MINUS: 137532844Sdonn if( mt1 & MENU ) return( 0 ); 137616179Sralph if( mt1 & MDBI ) return( TYPL ); 137716179Sralph break; 137816179Sralph 137916179Sralph case COMPL: 138032844Sdonn if( mt1 & MENU ) return( 0 ); 138116179Sralph if( mt1 & MINT ) return( TYPL ); 138216179Sralph break; 138316179Sralph 138416179Sralph case UNARY AND: 138516179Sralph { return( NCVT+OTHER ); } 138616179Sralph case INIT: 138716179Sralph case CM: 138816180Sralph return( 0 ); 138916180Sralph 139016179Sralph case NOT: 139116179Sralph case CBRANCH: 139216180Sralph if( mt1 & MSTR ) break; 139316180Sralph return( 0 ); 139416180Sralph 139516179Sralph case ANDAND: 139616179Sralph case OROR: 139716180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break; 139816179Sralph return( 0 ); 139916179Sralph 140016179Sralph case MUL: 140116179Sralph case DIV: 140216179Sralph if( mt12 & MDBI ) return( TYMATCH ); 140316179Sralph break; 140416179Sralph 140516179Sralph case MOD: 140616179Sralph case AND: 140716179Sralph case OR: 140816179Sralph case ER: 140916179Sralph if( mt12 & MINT ) return( TYMATCH ); 141016179Sralph break; 141116179Sralph 141216179Sralph case LS: 141316179Sralph case RS: 141416179Sralph if( mt12 & MINT ) return( TYMATCH+OTHER ); 141516179Sralph break; 141616179Sralph 141716179Sralph case EQ: 141816179Sralph case NE: 141916179Sralph case LT: 142016179Sralph case LE: 142116179Sralph case GT: 142216179Sralph case GE: 142332844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN ); 142432844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO ); 142516179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN ); 142616179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN ); 142716179Sralph else break; 142816179Sralph 142916179Sralph case QUEST: 143016179Sralph case COMOP: 143116179Sralph if( mt2&MENU ) return( TYPR+NCVTR ); 143216179Sralph return( TYPR ); 143316179Sralph 143416179Sralph case STREF: 143516179Sralph return( NCVTR+OTHER ); 143616179Sralph 143716179Sralph case FORCE: 143816179Sralph return( TYPL ); 143916179Sralph 144016179Sralph case COLON: 144132844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH ); 144232844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH ); 144316179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 144416179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 144516179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 144616179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 144732845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL ); 144816179Sralph break; 144916179Sralph 145016179Sralph case ASSIGN: 145116179Sralph case RETURN: 145216179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 145332844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN ); 145416179Sralph case CAST: 145532846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH); 145632844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH ); 145732846Sdonn else if( mt2 == MVOID && 145818436Smckusick ( p->in.right->in.op == CALL || 145918436Smckusick p->in.right->in.op == UNARY CALL)) break; 146016179Sralph else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN ); 146116179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 146216179Sralph break; 146316179Sralph 146416179Sralph case ASG LS: 146516179Sralph case ASG RS: 146616179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 146716179Sralph break; 146816179Sralph 146916179Sralph case ASG MUL: 147016179Sralph case ASG DIV: 147116179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH ); 147216179Sralph break; 147316179Sralph 147416179Sralph case ASG MOD: 147516179Sralph case ASG AND: 147616179Sralph case ASG OR: 147716179Sralph case ASG ER: 147816179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH ); 147916179Sralph break; 148016179Sralph 148116179Sralph case ASG PLUS: 148216179Sralph case ASG MINUS: 148316179Sralph case INCR: 148416179Sralph case DECR: 148516179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL ); 148616179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); 148716179Sralph break; 148816179Sralph 148916179Sralph case MINUS: 149016179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); 149116179Sralph if( mt2 & MPTR ) break; 149216179Sralph case PLUS: 149316179Sralph if( mt12 & MDBI ) return( TYMATCH ); 149416179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); 149516179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); 149616179Sralph 149716179Sralph } 149824408Smckusick if( mt12 == MSTR ) 149924408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] ); 150024408Smckusick else 150124408Smckusick uerror( "operands of %s have incompatible types", opst[o] ); 150216179Sralph return( NCVT ); 150316179Sralph } 150416179Sralph 150516179Sralph moditype( ty ) TWORD ty; { 150616179Sralph 150716179Sralph switch( ty ){ 150816179Sralph 150916179Sralph case TVOID: 151017206Sralph return( MPTR ); 151116179Sralph case UNDEF: 151224408Smckusick return( MVOID ); 151316179Sralph case ENUMTY: 151416179Sralph case MOETY: 151532840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */ 151616179Sralph 151716179Sralph case STRTY: 151816179Sralph case UNIONTY: 151916179Sralph return( MSTR ); 152016179Sralph 152116179Sralph case CHAR: 152216179Sralph case SHORT: 152316179Sralph case UCHAR: 152416179Sralph case USHORT: 152516179Sralph return( MINT|MPTI|MDBI ); 152616179Sralph case UNSIGNED: 152716179Sralph case ULONG: 152816179Sralph case INT: 152916179Sralph case LONG: 153016179Sralph return( MINT|MDBI|MPTI ); 153116179Sralph case FLOAT: 153216179Sralph case DOUBLE: 153316179Sralph return( MDBI ); 153416179Sralph default: 153516179Sralph return( MPTR|MPTI ); 153616179Sralph 153716179Sralph } 153816179Sralph } 153916179Sralph 154016179Sralph NODE * 154116179Sralph doszof( p ) register NODE *p; { 154216179Sralph /* do sizeof p */ 154316179Sralph int i; 154416179Sralph 154516179Sralph /* whatever is the meaning of this if it is a bitfield? */ 154616179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; 154716179Sralph 154816179Sralph tfree(p); 154916179Sralph if( i <= 0 ) werror( "sizeof returns 0" ); 155016179Sralph return( bcon( i ) ); 155116179Sralph } 155216179Sralph 155316179Sralph # ifndef BUG2 155416179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; { 155516179Sralph register ty; 155616179Sralph 155716179Sralph *a = *b = down+1; 155816179Sralph while( down > 1 ){ 155916179Sralph printf( "\t" ); 156016179Sralph down -= 2; 156116179Sralph } 156216179Sralph if( down ) printf( " " ); 156316179Sralph 156416179Sralph ty = optype( p->in.op ); 156516179Sralph 156616179Sralph printf("%o) %s, ", p, opst[p->in.op] ); 156716179Sralph if( ty == LTYPE ){ 156816179Sralph printf( CONFMT, p->tn.lval ); 156916179Sralph printf( ", %d, ", p->tn.rval ); 157016179Sralph } 157116179Sralph tprint( p->in.type ); 157216179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); 157316179Sralph } 157416179Sralph # endif 157516179Sralph 157632850Sdonn #ifndef PRTDCON 157716179Sralph prtdcon( p ) register NODE *p; { 157817749Sralph int o = p->in.op, i; 157916179Sralph 158017749Sralph if( o == DCON || o == FCON ){ 1581*32852Sdonn (void) locctr( DATA ); 158217749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT ); 158316179Sralph deflab( i = getlab() ); 158417749Sralph if( o == FCON ) 158517749Sralph fincode( p->fpn.fval, SZFLOAT ); 158617749Sralph else 158717749Sralph fincode( p->dpn.dval, SZDOUBLE ); 158816179Sralph p->tn.lval = 0; 158916179Sralph p->tn.rval = -i; 159017749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT); 159116179Sralph p->in.op = NAME; 159216179Sralph } 159316179Sralph } 159432850Sdonn #endif PRTDCON 159516179Sralph 159616179Sralph 159716179Sralph int edebug = 0; 159816179Sralph ecomp( p ) register NODE *p; { 159916179Sralph # ifndef BUG2 160016179Sralph if( edebug ) fwalk( p, eprint, 0 ); 160116179Sralph # endif 160216179Sralph if( !reached ){ 160316179Sralph werror( "statement not reached" ); 160416179Sralph reached = 1; 160516179Sralph } 160616179Sralph p = optim(p); 160716179Sralph walkf( p, prtdcon ); 1608*32852Sdonn (void) locctr( PROG ); 160916179Sralph ecode( p ); 161016179Sralph tfree(p); 161116179Sralph } 161216179Sralph 161316179Sralph # ifdef STDPRTREE 161416179Sralph # ifndef ONEPASS 161516179Sralph 161616179Sralph prtree(p) register NODE *p; { 161716179Sralph 161816179Sralph register struct symtab *q; 161916179Sralph register ty; 162016179Sralph 162116179Sralph # ifdef MYPRTREE 162216179Sralph MYPRTREE(p); /* local action can be taken here; then return... */ 162316179Sralph #endif 162416179Sralph 162516179Sralph ty = optype(p->in.op); 162616179Sralph 162716179Sralph printf( "%d\t", p->in.op ); 162816179Sralph 162916179Sralph if( ty == LTYPE ) { 163016179Sralph printf( CONFMT, p->tn.lval ); 163116179Sralph printf( "\t" ); 163216179Sralph } 163316179Sralph if( ty != BITYPE ) { 163416179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); 163516179Sralph else printf( "%d\t", p->tn.rval ); 163616179Sralph } 163716179Sralph 163816179Sralph printf( "%o\t", p->in.type ); 163916179Sralph 164016179Sralph /* handle special cases */ 164116179Sralph 164216179Sralph switch( p->in.op ){ 164316179Sralph 164416179Sralph case NAME: 164516179Sralph case ICON: 164616179Sralph /* print external name */ 164716179Sralph if( p->tn.rval == NONAME ) printf( "\n" ); 164816179Sralph else if( p->tn.rval >= 0 ){ 164916179Sralph q = &stab[p->tn.rval]; 165016179Sralph printf( "%s\n", exname(q->sname) ); 165116179Sralph } 165216179Sralph else { /* label */ 165316179Sralph printf( LABFMT, -p->tn.rval ); 165416179Sralph } 165516179Sralph break; 165616179Sralph 165716179Sralph case STARG: 165816179Sralph case STASG: 165916179Sralph case STCALL: 166016179Sralph case UNARY STCALL: 166116179Sralph /* print out size */ 166216179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */ 166316179Sralph 166416179Sralph /* note: p->in.left not a field... */ 166516179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); 166616179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); 166716179Sralph break; 166816179Sralph 166916179Sralph default: 167016179Sralph printf( "\n" ); 167116179Sralph } 167216179Sralph 167316179Sralph if( ty != LTYPE ) prtree( p->in.left ); 167416179Sralph if( ty == BITYPE ) prtree( p->in.right ); 167516179Sralph 167616179Sralph } 167716179Sralph 167816179Sralph # else 167916179Sralph 168016179Sralph p2tree(p) register NODE *p; { 168116179Sralph register ty; 168216179Sralph 168316179Sralph # ifdef MYP2TREE 168416179Sralph MYP2TREE(p); /* local action can be taken here; then return... */ 168516179Sralph # endif 168616179Sralph 168716179Sralph ty = optype(p->in.op); 168816179Sralph 168916179Sralph switch( p->in.op ){ 169016179Sralph 169116179Sralph case NAME: 169216179Sralph case ICON: 169316179Sralph #ifndef FLEXNAMES 169416179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; 169516179Sralph #else 169616179Sralph if( p->tn.rval == NONAME ) p->in.name = ""; 169716179Sralph #endif 169816179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */ 169916179Sralph register char *cp; 170016179Sralph cp = exname( stab[p->tn.rval].sname ); 170116179Sralph #ifndef FLEXNAMES 1702*32852Sdonn { 1703*32852Sdonn register i; 1704*32852Sdonn for( i=0; i<NCHNAM; ++i ) 1705*32852Sdonn p->in.name[i] = *cp++; 1706*32852Sdonn } 170716179Sralph #else 170816179Sralph p->in.name = tstr(cp); 170916179Sralph #endif 171016179Sralph } 171116179Sralph #ifndef FLEXNAMES 171216179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval ); 171316179Sralph #else 171416179Sralph else { 171516179Sralph char temp[32]; 171616179Sralph sprintf( temp, LABFMT, -p->tn.rval ); 171716179Sralph p->in.name = tstr(temp); 171816179Sralph } 171916179Sralph #endif 172016179Sralph break; 172116179Sralph 172216179Sralph case STARG: 172316179Sralph case STASG: 172416179Sralph case STCALL: 172516179Sralph case UNARY STCALL: 172616179Sralph /* set up size parameters */ 172716179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; 172816179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; 172916179Sralph break; 173016179Sralph 173116179Sralph case REG: 173216179Sralph rbusy( p->tn.rval, p->in.type ); 173316179Sralph default: 173416179Sralph #ifndef FLEXNAMES 173516179Sralph p->in.name[0] = '\0'; 173616179Sralph #else 173716179Sralph p->in.name = ""; 173816179Sralph #endif 173916179Sralph } 174016179Sralph 174116179Sralph p->in.rall = NOPREF; 174216179Sralph 174316179Sralph if( ty != LTYPE ) p2tree( p->in.left ); 174416179Sralph if( ty == BITYPE ) p2tree( p->in.right ); 174516179Sralph } 174616179Sralph 174716179Sralph # endif 174816179Sralph # endif 1749