117749Sralph #ifndef lint 2*32857Sdonn static char *sccsid ="@(#)trees.c 4.32 (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; 660*32857Sdonn TWORD utype; 66116179Sralph 66216179Sralph val = q->tn.lval; 66316179Sralph u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type); 66416179Sralph if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 66516179Sralph 66616179Sralph if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0); 66716179Sralph if( q->tn.rval != NONAME && o!=PLUS ) return(0); 66816179Sralph if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0); 66916179Sralph 670*32857Sdonn /* usual type conversions -- handle casts of constants */ 671*32857Sdonn utype = u ? UNSIGNED : INT; 672*32857Sdonn if( !ISPTR(p->in.type) && p->in.type != utype ) 673*32857Sdonn p = makety(p, utype, 0, (int)utype); 674*32857Sdonn if( q->in.type != utype ) 675*32857Sdonn q = makety(q, utype, 0, (int)utype); 67632842Sdonn 67716179Sralph switch( o ){ 67816179Sralph 67916179Sralph case PLUS: 68016179Sralph p->tn.lval += val; 68116179Sralph if( p->tn.rval == NONAME ){ 68216179Sralph p->tn.rval = q->tn.rval; 68316179Sralph p->in.type = q->in.type; 68416179Sralph } 68516179Sralph break; 68616179Sralph case MINUS: 68716179Sralph p->tn.lval -= val; 68816179Sralph break; 68916179Sralph case MUL: 69032840Sdonn p->tn.lval *= val; 69116179Sralph break; 69216179Sralph case DIV: 69316179Sralph if( val == 0 ) uerror( "division by 0" ); 69417749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval / val; 69516179Sralph else p->tn.lval /= val; 69616179Sralph break; 69716179Sralph case MOD: 69816179Sralph if( val == 0 ) uerror( "division by 0" ); 69917749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval % val; 70016179Sralph else p->tn.lval %= val; 70116179Sralph break; 70216179Sralph case AND: 70316179Sralph p->tn.lval &= val; 70416179Sralph break; 70516179Sralph case OR: 70616179Sralph p->tn.lval |= val; 70716179Sralph break; 70816179Sralph case ER: 70917749Sralph p->tn.lval ^= val; 71016179Sralph break; 71116179Sralph case LS: 71216179Sralph i = val; 71316179Sralph p->tn.lval = p->tn.lval << i; 71416179Sralph break; 71516179Sralph case RS: 71616179Sralph i = val; 71717749Sralph if ( u ) p->tn.lval = (unsigned) p->tn.lval >> i; 71817749Sralph else p->tn.lval = p->tn.lval >> i; 71916179Sralph break; 72016179Sralph 72116179Sralph case UNARY MINUS: 72216179Sralph p->tn.lval = - p->tn.lval; 72316179Sralph break; 72416179Sralph case COMPL: 72516179Sralph p->tn.lval = ~p->tn.lval; 72616179Sralph break; 72716179Sralph case NOT: 72816179Sralph p->tn.lval = !p->tn.lval; 72916179Sralph break; 73016179Sralph case LT: 73116179Sralph p->tn.lval = p->tn.lval < val; 73216179Sralph break; 73316179Sralph case LE: 73416179Sralph p->tn.lval = p->tn.lval <= val; 73516179Sralph break; 73616179Sralph case GT: 73716179Sralph p->tn.lval = p->tn.lval > val; 73816179Sralph break; 73916179Sralph case GE: 74016179Sralph p->tn.lval = p->tn.lval >= val; 74116179Sralph break; 74216179Sralph case ULT: 74332848Sdonn p->tn.lval = p->tn.lval < (unsigned) val; 74416179Sralph break; 74516179Sralph case ULE: 74632848Sdonn p->tn.lval = p->tn.lval <= (unsigned) val; 74716179Sralph break; 74832848Sdonn case UGT: 74932848Sdonn p->tn.lval = p->tn.lval > (unsigned) val; 75032848Sdonn break; 75132840Sdonn case UGE: 75232848Sdonn p->tn.lval = p->tn.lval >= (unsigned) val; 75332840Sdonn break; 75416179Sralph case EQ: 75516179Sralph p->tn.lval = p->tn.lval == val; 75616179Sralph break; 75716179Sralph case NE: 75816179Sralph p->tn.lval = p->tn.lval != val; 75916179Sralph break; 76016179Sralph default: 76116179Sralph return(0); 76216179Sralph } 76316179Sralph return(1); 76416179Sralph } 76516179Sralph 76616179Sralph chkpun(p) register NODE *p; { 76716179Sralph 76816179Sralph /* checks p for the existance of a pun */ 76916179Sralph 77016179Sralph /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */ 77116179Sralph 77216179Sralph /* one case is when enumerations are used: this applies only to lint */ 77316179Sralph /* in the other case, one operand is a pointer, the other integer type */ 77416179Sralph /* we check that this integer is in fact a constant zero... */ 77516179Sralph 77616179Sralph /* in the case of ASSIGN, any assignment of pointer to integer is illegal */ 77716179Sralph /* this falls out, because the LHS is never 0 */ 77816179Sralph 77916179Sralph register NODE *q; 78016179Sralph register t1, t2; 78116179Sralph register d1, d2; 78232844Sdonn int ref1, ref2; 78316179Sralph 78416179Sralph t1 = p->in.left->in.type; 78516179Sralph t2 = p->in.right->in.type; 78616179Sralph 78716179Sralph if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */ 78832841Sdonn /* rob pike says this is obnoxious... 78932840Sdonn if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) 79032841Sdonn werror( "comparison of enums" ); */ 79132841Sdonn if( t1==ENUMTY && t2==ENUMTY ) { 79232841Sdonn if ( p->in.left->fn.csiz!=p->in.right->fn.csiz ) 79332841Sdonn werror( "enumeration type clash, operator %s", opst[p->in.op] ); 79432841Sdonn return; 79532841Sdonn } 79632841Sdonn if ( t1 == ENUMTY ) t1 = INT; 79732841Sdonn if ( t2 == ENUMTY ) t2 = INT; 79816179Sralph } 79916179Sralph 80032844Sdonn ref1 = ISPTR(t1) || ISARY(t1); 80132844Sdonn ref2 = ISPTR(t2) || ISARY(t2); 80216179Sralph 80332844Sdonn if( ref1 ^ ref2 ){ 80432844Sdonn if( ref1 ) q = p->in.right; 80532844Sdonn else q = p->in.left; 80616179Sralph if( q->in.op != ICON || q->tn.lval != 0 ){ 80716179Sralph werror( "illegal combination of pointer and integer, op %s", 80816179Sralph opst[p->in.op] ); 80916179Sralph } 81016179Sralph } 81132844Sdonn else if( ref1 ){ 81232843Sdonn if( t1 == t2 ) { 81332843Sdonn if( p->in.left->fn.csiz != p->in.right->fn.csiz ) { 81432843Sdonn werror( "illegal structure pointer combination" ); 81516179Sralph return; 81616179Sralph } 81732843Sdonn d1 = p->in.left->fn.cdim; 81832843Sdonn d2 = p->in.right->fn.cdim; 81932843Sdonn for( ;; ){ 82032843Sdonn if( ISARY(t1) ){ 82132843Sdonn if( dimtab[d1] != dimtab[d2] ){ 82232843Sdonn werror( "illegal array size combination" ); 82332843Sdonn return; 82432843Sdonn } 82532843Sdonn ++d1; 82632843Sdonn ++d2; 82716179Sralph } 82832843Sdonn else if( !ISPTR(t1) ) break; 82932843Sdonn t1 = DECREF(t1); 83016179Sralph } 83116179Sralph } 83232843Sdonn else 83332843Sdonn werror( "illegal pointer combination" ); 83416179Sralph } 83516179Sralph 83616179Sralph } 83716179Sralph 83816179Sralph NODE * 83916179Sralph stref( p ) register NODE *p; { 84016179Sralph 84116179Sralph TWORD t; 84216179Sralph int d, s, dsc, align; 84316179Sralph OFFSZ off; 84416179Sralph register struct symtab *q; 84516179Sralph 84616179Sralph /* make p->x */ 84716179Sralph /* this is also used to reference automatic variables */ 84816179Sralph 84916179Sralph q = &stab[p->in.right->tn.rval]; 85016179Sralph p->in.right->in.op = FREE; 85116179Sralph p->in.op = FREE; 85216179Sralph p = pconvert( p->in.left ); 85316179Sralph 85416179Sralph /* make p look like ptr to x */ 85516179Sralph 85616179Sralph if( !ISPTR(p->in.type)){ 85716179Sralph p->in.type = PTR+UNIONTY; 85816179Sralph } 85916179Sralph 86016179Sralph t = INCREF( q->stype ); 86116179Sralph d = q->dimoff; 86216179Sralph s = q->sizoff; 86316179Sralph 86416179Sralph p = makety( p, t, d, s ); 86516179Sralph 86616179Sralph /* compute the offset to be added */ 86716179Sralph 86816179Sralph off = q->offset; 86916179Sralph dsc = q->sclass; 87016179Sralph 87116179Sralph if( dsc & FIELD ) { /* normalize offset */ 87216179Sralph align = ALINT; 87316179Sralph s = INT; 87416179Sralph off = (off/align)*align; 87516179Sralph } 87616179Sralph if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); 87716179Sralph 87816179Sralph p = buildtree( UNARY MUL, p, NIL ); 87916179Sralph 88016179Sralph /* if field, build field info */ 88116179Sralph 88216179Sralph if( dsc & FIELD ){ 88316179Sralph p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); 88416179Sralph p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); 88516179Sralph } 88616179Sralph 88716179Sralph return( clocal(p) ); 88816179Sralph } 88916179Sralph 89016179Sralph notlval(p) register NODE *p; { 89116179Sralph 89216179Sralph /* return 0 if p an lvalue, 1 otherwise */ 89316179Sralph 89416179Sralph again: 89516179Sralph 89616179Sralph switch( p->in.op ){ 89716179Sralph 89816179Sralph case FLD: 89916179Sralph p = p->in.left; 90016179Sralph goto again; 90116179Sralph 90216179Sralph case UNARY MUL: 90316179Sralph /* fix the &(a=b) bug, given that a and b are structures */ 90416179Sralph if( p->in.left->in.op == STASG ) return( 1 ); 90516179Sralph /* and the f().a bug, given that f returns a structure */ 90616179Sralph if( p->in.left->in.op == UNARY STCALL || 90716179Sralph p->in.left->in.op == STCALL ) return( 1 ); 90816179Sralph case NAME: 90916179Sralph case OREG: 91016179Sralph if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); 91116179Sralph case REG: 91216179Sralph return(0); 91316179Sralph 91416179Sralph default: 91516179Sralph return(1); 91616179Sralph 91716179Sralph } 91816179Sralph 91916179Sralph } 92016179Sralph 92116179Sralph NODE * 92216179Sralph bcon( i ){ /* make a constant node with value i */ 92316179Sralph register NODE *p; 92416179Sralph 92516179Sralph p = block( ICON, NIL, NIL, INT, 0, INT ); 92616179Sralph p->tn.lval = i; 92716179Sralph p->tn.rval = NONAME; 92816179Sralph return( clocal(p) ); 92916179Sralph } 93016179Sralph 93116179Sralph NODE * 93216179Sralph bpsize(p) register NODE *p; { 93316179Sralph return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); 93416179Sralph } 93516179Sralph 93616179Sralph OFFSZ 93716179Sralph psize( p ) NODE *p; { 93816179Sralph /* p is a node of type pointer; psize returns the 93916179Sralph size of the thing pointed to */ 94016179Sralph 94116179Sralph if( !ISPTR(p->in.type) ){ 94216179Sralph uerror( "pointer required"); 94316179Sralph return( SZINT ); 94416179Sralph } 94516179Sralph /* note: no pointers to fields */ 94616179Sralph return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); 94716179Sralph } 94816179Sralph 94916179Sralph NODE * 95016179Sralph convert( p, f ) register NODE *p; { 95116179Sralph /* convert an operand of p 95216179Sralph f is either CVTL or CVTR 95316179Sralph operand has type int, and is converted by the size of the other side 95416179Sralph */ 95516179Sralph 95616179Sralph register NODE *q, *r; 95716179Sralph 95816179Sralph q = (f==CVTL)?p->in.left:p->in.right; 95916179Sralph 96016179Sralph r = block( PMCONV, 96116179Sralph q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT ); 96216179Sralph r = clocal(r); 96316179Sralph if( f == CVTL ) 96416179Sralph p->in.left = r; 96516179Sralph else 96616179Sralph p->in.right = r; 96716179Sralph return(p); 96816179Sralph 96916179Sralph } 97016179Sralph 97125750Sdonn #ifndef econvert 97216179Sralph econvert( p ) register NODE *p; { 97316179Sralph 97416179Sralph /* change enums to ints, or appropriate types */ 97516179Sralph 97616179Sralph register TWORD ty; 97716179Sralph 97816179Sralph if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) { 97916179Sralph if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; 98016179Sralph else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; 98116179Sralph else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; 98216179Sralph else ty = LONG; 98316179Sralph ty = ctype( ty ); 98416179Sralph p->fn.csiz = ty; 98516179Sralph MODTYPE(p->in.type,ty); 98616179Sralph if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT; 98716179Sralph } 98816179Sralph } 98925750Sdonn #endif 99016179Sralph 99116179Sralph NODE * 99216179Sralph pconvert( p ) register NODE *p; { 99316179Sralph 99416179Sralph /* if p should be changed into a pointer, do so */ 99516179Sralph 99616179Sralph if( ISARY( p->in.type) ){ 99716179Sralph p->in.type = DECREF( p->in.type ); 99816179Sralph ++p->fn.cdim; 99916179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100016179Sralph } 100116179Sralph if( ISFTN( p->in.type) ) 100216179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100316179Sralph 100416179Sralph return( p ); 100516179Sralph } 100616179Sralph 100716179Sralph NODE * 100816179Sralph oconvert(p) register NODE *p; { 100916179Sralph /* convert the result itself: used for pointer and unsigned */ 101016179Sralph 101116179Sralph switch(p->in.op) { 101216179Sralph 101316179Sralph case LE: 101416179Sralph case LT: 101516179Sralph case GE: 101616179Sralph case GT: 101716179Sralph if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE); 101816179Sralph case EQ: 101916179Sralph case NE: 102016179Sralph return( p ); 102116179Sralph 102216179Sralph case MINUS: 102316179Sralph return( clocal( block( PVCONV, 102416179Sralph p, bpsize(p->in.left), INT, 0, INT ) ) ); 102516179Sralph } 102616179Sralph 102716179Sralph cerror( "illegal oconvert: %d", p->in.op ); 102816179Sralph 102916179Sralph return(p); 103016179Sralph } 103116179Sralph 103216179Sralph NODE * 103316179Sralph ptmatch(p) register NODE *p; { 103416179Sralph 103516179Sralph /* makes the operands of p agree; they are 103616179Sralph either pointers or integers, by this time */ 103716179Sralph /* with MINUS, the sizes must be the same */ 103816179Sralph /* with COLON, the types must be the same */ 103916179Sralph 104016179Sralph TWORD t1, t2, t; 104116179Sralph int o, d2, d, s2, s; 104216179Sralph 104316179Sralph o = p->in.op; 104416179Sralph t = t1 = p->in.left->in.type; 104516179Sralph t2 = p->in.right->in.type; 104616179Sralph d = p->in.left->fn.cdim; 104716179Sralph d2 = p->in.right->fn.cdim; 104816179Sralph s = p->in.left->fn.csiz; 104916179Sralph s2 = p->in.right->fn.csiz; 105016179Sralph 105116179Sralph switch( o ){ 105216179Sralph 105316179Sralph case ASSIGN: 105416179Sralph case RETURN: 105516179Sralph case CAST: 105616179Sralph { break; } 105716179Sralph 105816179Sralph case MINUS: 105916179Sralph { if( psize(p->in.left) != psize(p->in.right) ){ 106016179Sralph uerror( "illegal pointer subtraction"); 106116179Sralph } 106216179Sralph break; 106316179Sralph } 106416179Sralph case COLON: 106516179Sralph { if( t1 != t2 ) uerror( "illegal types in :"); 106616179Sralph break; 106716179Sralph } 106816179Sralph default: /* must work harder: relationals or comparisons */ 106916179Sralph 107016179Sralph if( !ISPTR(t1) ){ 107116179Sralph t = t2; 107216179Sralph d = d2; 107316179Sralph s = s2; 107416179Sralph break; 107516179Sralph } 107616179Sralph if( !ISPTR(t2) ){ 107716179Sralph break; 107816179Sralph } 107916179Sralph 108016179Sralph /* both are pointers */ 108116179Sralph if( talign(t2,s2) < talign(t,s) ){ 108216179Sralph t = t2; 108316179Sralph s = s2; 108416179Sralph } 108516179Sralph break; 108616179Sralph } 108716179Sralph 108816179Sralph p->in.left = makety( p->in.left, t, d, s ); 108916179Sralph p->in.right = makety( p->in.right, t, d, s ); 109016179Sralph if( o!=MINUS && !logop(o) ){ 109116179Sralph 109216179Sralph p->in.type = t; 109316179Sralph p->fn.cdim = d; 109416179Sralph p->fn.csiz = s; 109516179Sralph } 109616179Sralph 109716179Sralph return(clocal(p)); 109816179Sralph } 109916179Sralph 110016179Sralph int tdebug = 0; 110116179Sralph 110216179Sralph NODE * 110316179Sralph tymatch(p) register NODE *p; { 110416179Sralph 110516179Sralph /* satisfy the types of various arithmetic binary ops */ 110616179Sralph 110716179Sralph /* rules are: 110825750Sdonn if assignment, type of LHS 110916179Sralph if any float or doubles, make double 111016179Sralph if any longs, make long 111116179Sralph otherwise, make int 111216179Sralph if either operand is unsigned, the result is... 111316179Sralph */ 111416179Sralph 111516179Sralph register TWORD t1, t2, t, tu; 111616179Sralph register o, u; 111716179Sralph 111816179Sralph o = p->in.op; 111916179Sralph 112016179Sralph t1 = p->in.left->in.type; 112116179Sralph t2 = p->in.right->in.type; 112216179Sralph if( (t1==UNDEF || t2==UNDEF) && o!=CAST ) 112316179Sralph uerror("void type illegal in expression"); 112416179Sralph 112516179Sralph u = 0; 112616179Sralph if( ISUNSIGNED(t1) ){ 112716179Sralph u = 1; 112816179Sralph t1 = DEUNSIGN(t1); 112916179Sralph } 113016179Sralph if( ISUNSIGNED(t2) ){ 113116179Sralph u = 1; 113216179Sralph t2 = DEUNSIGN(t2); 113316179Sralph } 113416179Sralph 113516179Sralph if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT; 113616179Sralph if( t2 == CHAR || t2 == SHORT ) t2 = INT; 113716179Sralph 113817749Sralph #ifdef SPRECC 113917749Sralph if( t1 == DOUBLE || t2 == DOUBLE ) 114017749Sralph t = DOUBLE; 114117749Sralph else if( t1 == FLOAT || t2 == FLOAT ) 114217749Sralph t = FLOAT; 114317749Sralph #else 114417749Sralph if (t1 == DOUBLE || t1 == FLOAT || t2 == DOUBLE || t2 == FLOAT) 114517749Sralph t = DOUBLE; 114617749Sralph #endif 114716179Sralph else if( t1==LONG || t2==LONG ) t = LONG; 114816179Sralph else t = INT; 114916179Sralph 115032853Sdonn if( o == ASSIGN || o == CAST || o == RETURN ) 115132853Sdonn { 115216179Sralph tu = p->in.left->in.type; 115316179Sralph t = t1; 115416179Sralph } 115516179Sralph else { 115616179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; 115716179Sralph } 115816179Sralph 115916179Sralph /* because expressions have values that are at least as wide 116016179Sralph as INT or UNSIGNED, the only conversions needed 116116179Sralph are those involving FLOAT/DOUBLE, and those 116216179Sralph from LONG to INT and ULONG to UNSIGNED */ 116316179Sralph 116425750Sdonn if( t != t1 && ! asgop(o) ) 116525750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu ); 116616179Sralph 116732840Sdonn if( t != t2 || o==CAST) 116832840Sdonn if ( tu == ENUMTY ) {/* always asgop */ 116932840Sdonn p->in.right = makety( p->in.right, INT, 0, INT ); 117032840Sdonn p->in.right->in.type = tu; 117132840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim; 117232840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz; 117332840Sdonn } 117432840Sdonn else 117532840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu ); 117616179Sralph 117716179Sralph if( asgop(o) ){ 117816179Sralph p->in.type = p->in.left->in.type; 117916179Sralph p->fn.cdim = p->in.left->fn.cdim; 118016179Sralph p->fn.csiz = p->in.left->fn.csiz; 118116179Sralph } 118216179Sralph else if( !logop(o) ){ 118316179Sralph p->in.type = tu; 118416179Sralph p->fn.cdim = 0; 118516179Sralph p->fn.csiz = t; 118616179Sralph } 118716179Sralph 118816179Sralph # ifndef BUG1 118916179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); 119016179Sralph # endif 119116179Sralph 119216179Sralph return(p); 119316179Sralph } 119416179Sralph 119516179Sralph NODE * 119616179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; { 119716179Sralph /* make p into type t by inserting a conversion */ 119816179Sralph 119916179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); 120016179Sralph if( t == p->in.type ){ 120116179Sralph p->fn.cdim = d; 120216179Sralph p->fn.csiz = s; 120316179Sralph return( p ); 120416179Sralph } 120516179Sralph 120616179Sralph if( t & TMASK ){ 120716179Sralph /* non-simple type */ 120817228Sralph return( block( PCONV, p, NIL, t, d, s ) ); 120916179Sralph } 121016179Sralph 121116179Sralph if( p->in.op == ICON ){ 121217749Sralph if (t == DOUBLE) { 121317749Sralph p->in.op = DCON; 121417749Sralph if (ISUNSIGNED(p->in.type)) 121532847Sdonn p->dpn.dval = (unsigned CONSZ) p->tn.lval; 121617749Sralph else 121717749Sralph p->dpn.dval = p->tn.lval; 121817749Sralph p->in.type = p->fn.csiz = t; 121917749Sralph return (clocal(p)); 122017749Sralph } 122117749Sralph if (t == FLOAT) { 122216179Sralph p->in.op = FCON; 122316179Sralph if( ISUNSIGNED(p->in.type) ){ 122432847Sdonn p->fpn.fval = (unsigned CONSZ) p->tn.lval; 122516179Sralph } 122616179Sralph else { 122717749Sralph p->fpn.fval = p->tn.lval; 122816179Sralph } 122916179Sralph 123016179Sralph p->in.type = p->fn.csiz = t; 123116179Sralph return( clocal(p) ); 123216179Sralph } 123316179Sralph } 123417749Sralph else if (p->in.op == FCON && t == DOUBLE) { 123517749Sralph double db; 123616179Sralph 123717749Sralph p->in.op = DCON; 123817749Sralph db = p->fpn.fval; 123917749Sralph p->dpn.dval = db; 124017749Sralph p->in.type = p->fn.csiz = t; 124117749Sralph return (clocal(p)); 124217749Sralph } else if (p->in.op == DCON && t == FLOAT) { 124317749Sralph float fl; 124417749Sralph 124517749Sralph p->in.op = FCON; 124617749Sralph fl = p->dpn.dval; 124717749Sralph #ifdef notdef 124817749Sralph if (fl != p->dpn.dval) 124917749Sralph werror("float conversion loses precision"); 125017749Sralph #endif 125117749Sralph p->fpn.fval = fl; 125217749Sralph p->in.type = p->fn.csiz = t; 125317749Sralph return (clocal(p)); 125417749Sralph } 125517749Sralph 125617049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) ); 125716179Sralph 125816179Sralph } 125916179Sralph 126016179Sralph NODE * 126116179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { 126216179Sralph 126316179Sralph register NODE *p; 126416179Sralph 126516179Sralph p = talloc(); 126616179Sralph p->in.op = o; 126716179Sralph p->in.left = l; 126816179Sralph p->in.right = r; 126916179Sralph p->in.type = t; 127016179Sralph p->fn.cdim = d; 127116179Sralph p->fn.csiz = s; 127216179Sralph return(p); 127316179Sralph } 127416179Sralph 127516179Sralph icons(p) register NODE *p; { 127616179Sralph /* if p is an integer constant, return its value */ 127716179Sralph int val; 127816179Sralph 127916179Sralph if( p->in.op != ICON ){ 128016179Sralph uerror( "constant expected"); 128116179Sralph val = 1; 128216179Sralph } 128316179Sralph else { 128416179Sralph val = p->tn.lval; 128516179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); 128616179Sralph } 128716179Sralph tfree( p ); 128816179Sralph return(val); 128916179Sralph } 129016179Sralph 129116179Sralph /* the intent of this table is to examine the 129216179Sralph operators, and to check them for 129316179Sralph correctness. 129416179Sralph 129516179Sralph The table is searched for the op and the 129616179Sralph modified type (where this is one of the 129716179Sralph types INT (includes char and short), LONG, 129816179Sralph DOUBLE (includes FLOAT), and POINTER 129916179Sralph 130016179Sralph The default action is to make the node type integer 130116179Sralph 130216179Sralph The actions taken include: 130316179Sralph PUN check for puns 130416179Sralph CVTL convert the left operand 130516179Sralph CVTR convert the right operand 130616179Sralph TYPL the type is determined by the left operand 130716179Sralph TYPR the type is determined by the right operand 130816179Sralph TYMATCH force type of left and right to match, by inserting conversions 130916179Sralph PTMATCH like TYMATCH, but for pointers 131016179Sralph LVAL left operand must be lval 131116179Sralph CVTO convert the op 131216179Sralph NCVT do not convert the operands 131316179Sralph OTHER handled by code 131416179Sralph NCVTR convert the left operand, not the right... 131516179Sralph 131616179Sralph */ 131716179Sralph 131816179Sralph # define MINT 01 /* integer */ 131916179Sralph # define MDBI 02 /* integer or double */ 132016179Sralph # define MSTR 04 /* structure */ 132116179Sralph # define MPTR 010 /* pointer */ 132216179Sralph # define MPTI 020 /* pointer or integer */ 132316179Sralph # define MENU 040 /* enumeration variable or member */ 132424408Smckusick # define MVOID 0100000 /* void type */ 132516179Sralph 132616179Sralph opact( p ) NODE *p; { 132716179Sralph 132816179Sralph register mt12, mt1, mt2, o; 132916179Sralph 133024408Smckusick mt1 = mt2 = mt12 = 0; 133116179Sralph 133216179Sralph switch( optype(o=p->in.op) ){ 133316179Sralph 133416179Sralph case BITYPE: 133524408Smckusick mt2 = moditype( p->in.right->in.type ); 133616179Sralph case UTYPE: 133724408Smckusick mt1 = moditype( p->in.left->in.type ); 133824408Smckusick break; 133916179Sralph 134016179Sralph } 134116179Sralph 134224408Smckusick if( ((mt1 | mt2) & MVOID) && 134324408Smckusick o != COMOP && 134432845Sdonn o != COLON && 134532845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) && 134624408Smckusick !(o == CAST && (mt1 & MVOID)) ){ 134724408Smckusick /* if lhs of RETURN is void, grammar will complain */ 134824408Smckusick if( o != RETURN ) 134924408Smckusick uerror( "value of void expression used" ); 135024408Smckusick return( NCVT ); 135124408Smckusick } 135224408Smckusick mt12 = mt1 & mt2; 135324408Smckusick 135416179Sralph switch( o ){ 135516179Sralph 135616179Sralph case NAME : 135716179Sralph case STRING : 135816179Sralph case ICON : 135916179Sralph case FCON : 136017749Sralph case DCON : 136116179Sralph case CALL : 136216179Sralph case UNARY CALL: 136316179Sralph case UNARY MUL: 136416179Sralph { return( OTHER ); } 136516179Sralph case UNARY MINUS: 136632844Sdonn if( mt1 & MENU ) return( 0 ); 136716179Sralph if( mt1 & MDBI ) return( TYPL ); 136816179Sralph break; 136916179Sralph 137016179Sralph case COMPL: 137132844Sdonn if( mt1 & MENU ) return( 0 ); 137216179Sralph if( mt1 & MINT ) return( TYPL ); 137316179Sralph break; 137416179Sralph 137516179Sralph case UNARY AND: 137616179Sralph { return( NCVT+OTHER ); } 137716179Sralph case INIT: 137816179Sralph case CM: 137916180Sralph return( 0 ); 138016180Sralph 138116179Sralph case NOT: 138216179Sralph case CBRANCH: 138316180Sralph if( mt1 & MSTR ) break; 138416180Sralph return( 0 ); 138516180Sralph 138616179Sralph case ANDAND: 138716179Sralph case OROR: 138816180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break; 138916179Sralph return( 0 ); 139016179Sralph 139116179Sralph case MUL: 139216179Sralph case DIV: 139316179Sralph if( mt12 & MDBI ) return( TYMATCH ); 139416179Sralph break; 139516179Sralph 139616179Sralph case MOD: 139716179Sralph case AND: 139816179Sralph case OR: 139916179Sralph case ER: 140016179Sralph if( mt12 & MINT ) return( TYMATCH ); 140116179Sralph break; 140216179Sralph 140316179Sralph case LS: 140416179Sralph case RS: 140516179Sralph if( mt12 & MINT ) return( TYMATCH+OTHER ); 140616179Sralph break; 140716179Sralph 140816179Sralph case EQ: 140916179Sralph case NE: 141016179Sralph case LT: 141116179Sralph case LE: 141216179Sralph case GT: 141316179Sralph case GE: 141432844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN ); 141532844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO ); 141616179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN ); 141716179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN ); 141816179Sralph else break; 141916179Sralph 142016179Sralph case QUEST: 142116179Sralph case COMOP: 142216179Sralph if( mt2&MENU ) return( TYPR+NCVTR ); 142316179Sralph return( TYPR ); 142416179Sralph 142516179Sralph case STREF: 142616179Sralph return( NCVTR+OTHER ); 142716179Sralph 142816179Sralph case FORCE: 142916179Sralph return( TYPL ); 143016179Sralph 143116179Sralph case COLON: 143232844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH ); 143332844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH ); 143416179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 143516179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 143616179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 143716179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 143832845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL ); 143916179Sralph break; 144016179Sralph 144116179Sralph case ASSIGN: 144216179Sralph case RETURN: 144316179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 144432844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN ); 144516179Sralph case CAST: 144632846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH); 144732844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH ); 144832846Sdonn else if( mt2 == MVOID && 144918436Smckusick ( p->in.right->in.op == CALL || 145018436Smckusick p->in.right->in.op == UNARY CALL)) break; 145132854Sdonn else if( (mt1 & MPTR) && (mt2 & MPTI) ) 145232854Sdonn return( LVAL+PTMATCH+PUN ); 145316179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 145416179Sralph break; 145516179Sralph 145616179Sralph case ASG LS: 145716179Sralph case ASG RS: 145816179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 145916179Sralph break; 146016179Sralph 146116179Sralph case ASG MUL: 146216179Sralph case ASG DIV: 146316179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH ); 146416179Sralph break; 146516179Sralph 146616179Sralph case ASG MOD: 146716179Sralph case ASG AND: 146816179Sralph case ASG OR: 146916179Sralph case ASG ER: 147016179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH ); 147116179Sralph break; 147216179Sralph 147316179Sralph case ASG PLUS: 147416179Sralph case ASG MINUS: 147516179Sralph case INCR: 147616179Sralph case DECR: 147716179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL ); 147816179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); 147916179Sralph break; 148016179Sralph 148116179Sralph case MINUS: 148216179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); 148316179Sralph if( mt2 & MPTR ) break; 148416179Sralph case PLUS: 148516179Sralph if( mt12 & MDBI ) return( TYMATCH ); 148616179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); 148716179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); 148816179Sralph 148916179Sralph } 149024408Smckusick if( mt12 == MSTR ) 149124408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] ); 149224408Smckusick else 149324408Smckusick uerror( "operands of %s have incompatible types", opst[o] ); 149416179Sralph return( NCVT ); 149516179Sralph } 149616179Sralph 149716179Sralph moditype( ty ) TWORD ty; { 149816179Sralph 149916179Sralph switch( ty ){ 150016179Sralph 150116179Sralph case UNDEF: 150224408Smckusick return( MVOID ); 150316179Sralph case ENUMTY: 150416179Sralph case MOETY: 150532840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */ 150616179Sralph 150716179Sralph case STRTY: 150816179Sralph case UNIONTY: 150916179Sralph return( MSTR ); 151016179Sralph 151116179Sralph case CHAR: 151216179Sralph case SHORT: 151316179Sralph case UCHAR: 151416179Sralph case USHORT: 151516179Sralph return( MINT|MPTI|MDBI ); 151616179Sralph case UNSIGNED: 151716179Sralph case ULONG: 151816179Sralph case INT: 151916179Sralph case LONG: 152016179Sralph return( MINT|MDBI|MPTI ); 152116179Sralph case FLOAT: 152216179Sralph case DOUBLE: 152316179Sralph return( MDBI ); 152416179Sralph default: 152516179Sralph return( MPTR|MPTI ); 152616179Sralph 152716179Sralph } 152816179Sralph } 152916179Sralph 153016179Sralph NODE * 153116179Sralph doszof( p ) register NODE *p; { 153216179Sralph /* do sizeof p */ 153316179Sralph int i; 153416179Sralph 153516179Sralph /* whatever is the meaning of this if it is a bitfield? */ 153616179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; 153716179Sralph 153816179Sralph tfree(p); 153916179Sralph if( i <= 0 ) werror( "sizeof returns 0" ); 154016179Sralph return( bcon( i ) ); 154116179Sralph } 154216179Sralph 154316179Sralph # ifndef BUG2 154416179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; { 154516179Sralph register ty; 154616179Sralph 154716179Sralph *a = *b = down+1; 154816179Sralph while( down > 1 ){ 154916179Sralph printf( "\t" ); 155016179Sralph down -= 2; 155116179Sralph } 155216179Sralph if( down ) printf( " " ); 155316179Sralph 155416179Sralph ty = optype( p->in.op ); 155516179Sralph 155616179Sralph printf("%o) %s, ", p, opst[p->in.op] ); 155716179Sralph if( ty == LTYPE ){ 155816179Sralph printf( CONFMT, p->tn.lval ); 155916179Sralph printf( ", %d, ", p->tn.rval ); 156016179Sralph } 156116179Sralph tprint( p->in.type ); 156216179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); 156316179Sralph } 156416179Sralph # endif 156516179Sralph 156632850Sdonn #ifndef PRTDCON 156716179Sralph prtdcon( p ) register NODE *p; { 156817749Sralph int o = p->in.op, i; 156916179Sralph 157017749Sralph if( o == DCON || o == FCON ){ 157132852Sdonn (void) locctr( DATA ); 157217749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT ); 157316179Sralph deflab( i = getlab() ); 157417749Sralph if( o == FCON ) 157517749Sralph fincode( p->fpn.fval, SZFLOAT ); 157617749Sralph else 157717749Sralph fincode( p->dpn.dval, SZDOUBLE ); 157816179Sralph p->tn.lval = 0; 157916179Sralph p->tn.rval = -i; 158017749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT); 158116179Sralph p->in.op = NAME; 158216179Sralph } 158316179Sralph } 158432850Sdonn #endif PRTDCON 158516179Sralph 158616179Sralph 158716179Sralph int edebug = 0; 158816179Sralph ecomp( p ) register NODE *p; { 158916179Sralph # ifndef BUG2 159016179Sralph if( edebug ) fwalk( p, eprint, 0 ); 159116179Sralph # endif 159216179Sralph if( !reached ){ 159316179Sralph werror( "statement not reached" ); 159416179Sralph reached = 1; 159516179Sralph } 159616179Sralph p = optim(p); 159716179Sralph walkf( p, prtdcon ); 159832852Sdonn (void) locctr( PROG ); 159916179Sralph ecode( p ); 160016179Sralph tfree(p); 160116179Sralph } 160216179Sralph 160316179Sralph # ifdef STDPRTREE 160416179Sralph # ifndef ONEPASS 160516179Sralph 160616179Sralph prtree(p) register NODE *p; { 160716179Sralph 160816179Sralph register struct symtab *q; 160916179Sralph register ty; 161016179Sralph 161116179Sralph # ifdef MYPRTREE 161216179Sralph MYPRTREE(p); /* local action can be taken here; then return... */ 161316179Sralph #endif 161416179Sralph 161516179Sralph ty = optype(p->in.op); 161616179Sralph 161716179Sralph printf( "%d\t", p->in.op ); 161816179Sralph 161916179Sralph if( ty == LTYPE ) { 162016179Sralph printf( CONFMT, p->tn.lval ); 162116179Sralph printf( "\t" ); 162216179Sralph } 162316179Sralph if( ty != BITYPE ) { 162416179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); 162516179Sralph else printf( "%d\t", p->tn.rval ); 162616179Sralph } 162716179Sralph 162816179Sralph printf( "%o\t", p->in.type ); 162916179Sralph 163016179Sralph /* handle special cases */ 163116179Sralph 163216179Sralph switch( p->in.op ){ 163316179Sralph 163416179Sralph case NAME: 163516179Sralph case ICON: 163616179Sralph /* print external name */ 163716179Sralph if( p->tn.rval == NONAME ) printf( "\n" ); 163816179Sralph else if( p->tn.rval >= 0 ){ 163916179Sralph q = &stab[p->tn.rval]; 164016179Sralph printf( "%s\n", exname(q->sname) ); 164116179Sralph } 164216179Sralph else { /* label */ 164316179Sralph printf( LABFMT, -p->tn.rval ); 164416179Sralph } 164516179Sralph break; 164616179Sralph 164716179Sralph case STARG: 164816179Sralph case STASG: 164916179Sralph case STCALL: 165016179Sralph case UNARY STCALL: 165116179Sralph /* print out size */ 165216179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */ 165316179Sralph 165416179Sralph /* note: p->in.left not a field... */ 165516179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); 165616179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); 165716179Sralph break; 165816179Sralph 165916179Sralph default: 166016179Sralph printf( "\n" ); 166116179Sralph } 166216179Sralph 166316179Sralph if( ty != LTYPE ) prtree( p->in.left ); 166416179Sralph if( ty == BITYPE ) prtree( p->in.right ); 166516179Sralph 166616179Sralph } 166716179Sralph 166816179Sralph # else 166916179Sralph 167016179Sralph p2tree(p) register NODE *p; { 167116179Sralph register ty; 167216179Sralph 167316179Sralph # ifdef MYP2TREE 167416179Sralph MYP2TREE(p); /* local action can be taken here; then return... */ 167516179Sralph # endif 167616179Sralph 167716179Sralph ty = optype(p->in.op); 167816179Sralph 167916179Sralph switch( p->in.op ){ 168016179Sralph 168116179Sralph case NAME: 168216179Sralph case ICON: 168316179Sralph #ifndef FLEXNAMES 168416179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; 168516179Sralph #else 168616179Sralph if( p->tn.rval == NONAME ) p->in.name = ""; 168716179Sralph #endif 168816179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */ 168916179Sralph register char *cp; 169016179Sralph cp = exname( stab[p->tn.rval].sname ); 169116179Sralph #ifndef FLEXNAMES 169232852Sdonn { 169332852Sdonn register i; 169432852Sdonn for( i=0; i<NCHNAM; ++i ) 169532852Sdonn p->in.name[i] = *cp++; 169632852Sdonn } 169716179Sralph #else 169816179Sralph p->in.name = tstr(cp); 169916179Sralph #endif 170016179Sralph } 170116179Sralph #ifndef FLEXNAMES 170216179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval ); 170316179Sralph #else 170416179Sralph else { 170516179Sralph char temp[32]; 170616179Sralph sprintf( temp, LABFMT, -p->tn.rval ); 170716179Sralph p->in.name = tstr(temp); 170816179Sralph } 170916179Sralph #endif 171016179Sralph break; 171116179Sralph 171216179Sralph case STARG: 171316179Sralph case STASG: 171416179Sralph case STCALL: 171516179Sralph case UNARY STCALL: 171616179Sralph /* set up size parameters */ 171716179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; 171816179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; 171916179Sralph break; 172016179Sralph 172116179Sralph case REG: 172216179Sralph rbusy( p->tn.rval, p->in.type ); 172316179Sralph default: 172416179Sralph #ifndef FLEXNAMES 172516179Sralph p->in.name[0] = '\0'; 172616179Sralph #else 172716179Sralph p->in.name = ""; 172816179Sralph #endif 172916179Sralph } 173016179Sralph 173116179Sralph p->in.rall = NOPREF; 173216179Sralph 173316179Sralph if( ty != LTYPE ) p2tree( p->in.left ); 173416179Sralph if( ty == BITYPE ) p2tree( p->in.right ); 173516179Sralph } 173616179Sralph 173716179Sralph # endif 173816179Sralph # endif 1739