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