117749Sralph #ifndef lint 2*34253Sdonn static char *sccsid ="@(#)trees.c 4.36 (Berkeley) 05/11/88"; 317749Sralph #endif 417749Sralph 518396Sralph # include "pass1.h" 616179Sralph 724408Smckusick # include <setjmp.h> 824408Smckusick 917749Sralph int bdebug = 0; 1017749Sralph int adebug = 0; 1117749Sralph extern ddebug; 1217749Sralph extern eprint(); 1317749Sralph 1416179Sralph /* corrections when in violation of lint */ 1516179Sralph 1616179Sralph /* some special actions, used in finding the type of nodes */ 1716179Sralph # define NCVT 01 1816179Sralph # define PUN 02 1916179Sralph # define TYPL 04 2016179Sralph # define TYPR 010 2116179Sralph # define TYMATCH 040 2216179Sralph # define LVAL 0100 2316179Sralph # define CVTO 0200 2416179Sralph # define CVTL 0400 2516179Sralph # define CVTR 01000 2616179Sralph # define PTMATCH 02000 2716179Sralph # define OTHER 04000 2816179Sralph # define NCVTR 010000 2916179Sralph 3017749Sralph #ifndef BUG1 3117749Sralph printact(t, acts) 3217749Sralph NODE *t; 3317749Sralph int acts; 3417749Sralph { 3517749Sralph static struct actions { 3617749Sralph int a_bit; 3717749Sralph char *a_name; 3817749Sralph } actions[] = { 3917749Sralph { PUN, "PUN" }, 4017749Sralph { CVTL, "CVTL" }, 4117749Sralph { CVTR, "CVTR" }, 4217749Sralph { TYPL, "TYPL" }, 4317749Sralph { TYPR, "TYPR" }, 4417749Sralph { TYMATCH, "TYMATCH" }, 4517749Sralph { PTMATCH, "PTMATCH" }, 4617749Sralph { LVAL, "LVAL" }, 4717749Sralph { CVTO, "CVTO" }, 4817749Sralph { NCVT, "NCVT" }, 4917749Sralph { OTHER, "OTHER" }, 5017749Sralph { NCVTR, "NCVTR" }, 5117749Sralph { 0 } 5217749Sralph }; 5317749Sralph register struct actions *p; 5417749Sralph char *sep = " "; 5517749Sralph 5617749Sralph printf("actions"); 5717749Sralph for (p = actions; p->a_name; p++) 5817749Sralph if (p->a_bit & acts) { 5917749Sralph printf("%s%s", sep, p->a_name); 6017749Sralph sep = "|"; 6117749Sralph } 6217749Sralph if (!bdebug) { 6317749Sralph printf(" for:\n"); 6417749Sralph fwalk(t, eprint, 0); 6517749Sralph } else 6617749Sralph putchar('\n'); 6717749Sralph } 6817749Sralph #endif 6917749Sralph 7016179Sralph /* node conventions: 7116179Sralph 7216179Sralph NAME: rval>0 is stab index for external 7316179Sralph rval<0 is -inlabel number 7416179Sralph lval is offset in bits 7516179Sralph ICON: lval has the value 7616179Sralph rval has the STAB index, or - label number, 7716179Sralph if a name whose address is in the constant 7816179Sralph rval = NONAME means no name 7916179Sralph REG: rval is reg. identification cookie 8016179Sralph 8116179Sralph */ 8216179Sralph 8316179Sralph NODE * 8416179Sralph buildtree( o, l, r ) register NODE *l, *r; { 8516179Sralph register NODE *p, *q; 8616179Sralph register actions; 8716179Sralph register opty; 8816179Sralph register struct symtab *sp; 8916179Sralph register NODE *lr, *ll; 9017749Sralph NODE *fixargs(); 9116179Sralph int i; 9216179Sralph 9316179Sralph # ifndef BUG1 9416179Sralph if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r ); 9516179Sralph # endif 9616179Sralph opty = optype(o); 9716179Sralph 9816179Sralph /* check for constants */ 9916179Sralph 10016179Sralph if( opty == UTYPE && l->in.op == ICON ){ 10116179Sralph 10216179Sralph switch( o ){ 10316179Sralph 10416179Sralph case NOT: 10516179Sralph if( hflag ) werror( "constant argument to NOT" ); 10616179Sralph case UNARY MINUS: 10716179Sralph case COMPL: 10816179Sralph if( conval( l, o, l ) ) return(l); 10916179Sralph break; 11016179Sralph 11116179Sralph } 11216179Sralph } 11316179Sralph 114*34253Sdonn else if( opty == UTYPE && (l->in.op == FCON || l->in.op == DCON) ){ 11516179Sralph 116*34253Sdonn switch( o ){ 117*34253Sdonn 118*34253Sdonn case NOT: 119*34253Sdonn if( hflag ) werror( "constant argument to NOT" ); 120*34253Sdonn if( l->in.op == FCON ) 121*34253Sdonn l->tn.lval = l->fpn.fval == 0.0; 122*34253Sdonn else 123*34253Sdonn l->tn.lval = l->dpn.dval == 0.0; 124*34253Sdonn l->tn.rval = NONAME; 125*34253Sdonn l->in.op = ICON; 126*34253Sdonn l->fn.csiz = l->in.type = INT; 127*34253Sdonn l->fn.cdim = 0; 128*34253Sdonn return(l); 129*34253Sdonn case UNARY MINUS: 130*34253Sdonn if( l->in.op == FCON ) 131*34253Sdonn l->fpn.fval = -l->fpn.fval; 132*34253Sdonn else 133*34253Sdonn l->dpn.dval = -l->dpn.dval; 134*34253Sdonn return(l); 135*34253Sdonn } 13617749Sralph } 13717749Sralph 13816179Sralph else if( o==QUEST && l->in.op==ICON ) { 13916179Sralph l->in.op = FREE; 14016179Sralph r->in.op = FREE; 14116179Sralph if( l->tn.lval ){ 14216179Sralph tfree( r->in.right ); 14316179Sralph return( r->in.left ); 14416179Sralph } 14516179Sralph else { 14616179Sralph tfree( r->in.left ); 14716179Sralph return( r->in.right ); 14816179Sralph } 14916179Sralph } 15016179Sralph 15116179Sralph else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn; 15216179Sralph 15316179Sralph else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ){ 15416179Sralph 15516179Sralph switch( o ){ 15616179Sralph 15716179Sralph case ULT: 15816179Sralph case UGT: 15916179Sralph case ULE: 16016179Sralph case UGE: 16116179Sralph case LT: 16216179Sralph case GT: 16316179Sralph case LE: 16416179Sralph case GE: 16516179Sralph case EQ: 16616179Sralph case NE: 16732851Sdonn if( l->in.type == ENUMTY && r->in.type == ENUMTY ){ 16832851Sdonn p = block( o, l, r, INT, 0, INT ); 16932840Sdonn chkpun( p ); 17032851Sdonn p->in.op = FREE; 17132851Sdonn } 17232840Sdonn 17316179Sralph case ANDAND: 17416179Sralph case OROR: 17516179Sralph case CBRANCH: 17616179Sralph 17716179Sralph ccwarn: 17816179Sralph if( hflag ) werror( "constant in conditional context" ); 17916179Sralph 18016179Sralph case PLUS: 18116179Sralph case MINUS: 18216179Sralph case MUL: 18316179Sralph case DIV: 18416179Sralph case MOD: 18516179Sralph case AND: 18616179Sralph case OR: 18716179Sralph case ER: 18816179Sralph case LS: 18916179Sralph case RS: 19016179Sralph if( conval( l, o, r ) ) { 19116179Sralph r->in.op = FREE; 19216179Sralph return(l); 19316179Sralph } 19416179Sralph break; 19516179Sralph } 19616179Sralph } 19724408Smckusick else if (opty == BITYPE && 19824408Smckusick (l->in.op == FCON || l->in.op == DCON || l->in.op == ICON) && 19924408Smckusick (r->in.op == FCON || r->in.op == DCON || r->in.op == ICON)) { 20024408Smckusick if (o == PLUS || o == MINUS || o == MUL || o == DIV) { 20124408Smckusick extern int fpe_count; 20224408Smckusick extern jmp_buf gotfpe; 20316179Sralph 20424408Smckusick fpe_count = 0; 20524408Smckusick if (setjmp(gotfpe)) 20624408Smckusick goto treatfpe; 20717749Sralph if (l->in.op == ICON) 20817749Sralph l->dpn.dval = l->tn.lval; 20924408Smckusick else if (l->in.op == FCON) 21024408Smckusick l->dpn.dval = l->fpn.fval; 21117749Sralph if (r->in.op == ICON) 21217749Sralph r->dpn.dval = r->tn.lval; 21324408Smckusick else if (r->in.op == FCON) 21424408Smckusick r->dpn.dval = r->fpn.fval; 21517749Sralph switch (o) { 21617749Sralph 21717749Sralph case PLUS: 21817749Sralph l->dpn.dval += r->dpn.dval; 21924408Smckusick break; 22017749Sralph 22117749Sralph case MINUS: 22217749Sralph l->dpn.dval -= r->dpn.dval; 22324408Smckusick break; 22417749Sralph 22517749Sralph case MUL: 22617749Sralph l->dpn.dval *= r->dpn.dval; 22724408Smckusick break; 22817749Sralph 22917749Sralph case DIV: 23017749Sralph if (r->dpn.dval == 0) 23117749Sralph uerror("division by 0."); 23217749Sralph else 23317749Sralph l->dpn.dval /= r->dpn.dval; 23424408Smckusick break; 23524408Smckusick } 23624408Smckusick treatfpe: 23724408Smckusick if (fpe_count > 0) { 23824408Smckusick uerror("floating point exception in constant expression"); 23924408Smckusick l->dpn.dval = 1.0; /* Fairly harmless */ 24024408Smckusick } 24124408Smckusick fpe_count = -1; 24224408Smckusick l->in.op = DCON; 24324408Smckusick l->in.type = l->fn.csiz = DOUBLE; 24424408Smckusick r->in.op = FREE; 24524408Smckusick return (l); 24616179Sralph } 24724408Smckusick } 24816179Sralph 24924408Smckusick /* it's real; we must make a new node */ 25016179Sralph 25116179Sralph p = block( o, l, r, INT, 0, INT ); 25216179Sralph 25316179Sralph actions = opact(p); 25417749Sralph #ifndef BUG1 25517749Sralph if (adebug) 25617749Sralph printact(p, actions); 25717749Sralph #endif 25816179Sralph 25916179Sralph if( actions&LVAL ){ /* check left descendent */ 26016179Sralph if( notlval(p->in.left) ) { 26132849Sdonn uerror( "illegal lvalue operand of assignment operator" ); 26216179Sralph } 26316179Sralph } 26416179Sralph 26516179Sralph if( actions & NCVTR ){ 26616179Sralph p->in.left = pconvert( p->in.left ); 26716179Sralph } 26816179Sralph else if( !(actions & NCVT ) ){ 26916179Sralph switch( opty ){ 27016179Sralph 27116179Sralph case BITYPE: 27216179Sralph p->in.right = pconvert( p->in.right ); 27316179Sralph case UTYPE: 27416179Sralph p->in.left = pconvert( p->in.left ); 27516179Sralph 27616179Sralph } 27716179Sralph } 27816179Sralph 27916179Sralph if( (actions&PUN) && (o!=CAST||cflag) ){ 28016179Sralph chkpun(p); 28116179Sralph } 28216179Sralph 28316179Sralph if( actions & (TYPL|TYPR) ){ 28416179Sralph 28516179Sralph q = (actions&TYPL) ? p->in.left : p->in.right; 28616179Sralph 28716179Sralph p->in.type = q->in.type; 28816179Sralph p->fn.cdim = q->fn.cdim; 28916179Sralph p->fn.csiz = q->fn.csiz; 29016179Sralph } 29116179Sralph 29216179Sralph if( actions & CVTL ) p = convert( p, CVTL ); 29316179Sralph if( actions & CVTR ) p = convert( p, CVTR ); 29416179Sralph if( actions & TYMATCH ) p = tymatch(p); 29516179Sralph if( actions & PTMATCH ) p = ptmatch(p); 29616179Sralph 29716179Sralph if( actions & OTHER ){ 29816179Sralph l = p->in.left; 29916179Sralph r = p->in.right; 30016179Sralph 30116179Sralph switch(o){ 30216179Sralph 30316179Sralph case NAME: 30416179Sralph sp = &stab[idname]; 30516179Sralph if( sp->stype == UNDEF ){ 30616179Sralph #ifndef FLEXNAMES 30716179Sralph uerror( "%.8s undefined", sp->sname ); 30816179Sralph #else 30916179Sralph uerror( "%s undefined", sp->sname ); 31016179Sralph #endif 31116179Sralph /* make p look reasonable */ 312*34253Sdonn p->in.type = p->fn.csiz = INT; 313*34253Sdonn p->fn.cdim = 0; 31416179Sralph p->tn.rval = idname; 31516179Sralph p->tn.lval = 0; 31616179Sralph defid( p, SNULL ); 31716179Sralph break; 31816179Sralph } 31916179Sralph p->in.type = sp->stype; 32016179Sralph p->fn.cdim = sp->dimoff; 32116179Sralph p->fn.csiz = sp->sizoff; 32216179Sralph p->tn.lval = 0; 32316179Sralph p->tn.rval = idname; 32416179Sralph /* special case: MOETY is really an ICON... */ 32516179Sralph if( p->in.type == MOETY ){ 32616179Sralph p->tn.rval = NONAME; 32716179Sralph p->tn.lval = sp->offset; 32816179Sralph p->fn.cdim = 0; 32916179Sralph p->in.type = ENUMTY; 33016179Sralph p->in.op = ICON; 33116179Sralph } 33216179Sralph break; 33316179Sralph 33416179Sralph case ICON: 33516179Sralph p->in.type = INT; 33616179Sralph p->fn.cdim = 0; 33716179Sralph p->fn.csiz = INT; 33816179Sralph break; 33916179Sralph 34016179Sralph case STRING: 34116179Sralph p->in.op = NAME; 34216179Sralph p->in.type = CHAR+ARY; 34316179Sralph p->tn.lval = 0; 34416179Sralph p->tn.rval = NOLAB; 34516179Sralph p->fn.cdim = curdim; 34616179Sralph p->fn.csiz = CHAR; 34716179Sralph break; 34816179Sralph 34916179Sralph case FCON: 35016179Sralph p->tn.lval = 0; 35116179Sralph p->tn.rval = 0; 35217749Sralph p->in.type = FLOAT; 35317749Sralph p->fn.cdim = 0; 35417749Sralph p->fn.csiz = FLOAT; 35517749Sralph break; 35617749Sralph 35717749Sralph case DCON: 35817749Sralph p->tn.lval = 0; 35917749Sralph p->tn.rval = 0; 36016179Sralph p->in.type = DOUBLE; 36116179Sralph p->fn.cdim = 0; 36216179Sralph p->fn.csiz = DOUBLE; 36316179Sralph break; 36416179Sralph 36516179Sralph case STREF: 36616179Sralph /* p->x turned into *(p+offset) */ 36716179Sralph /* rhs must be a name; check correctness */ 36816179Sralph 36916179Sralph i = r->tn.rval; 37016179Sralph if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){ 37116179Sralph uerror( "member of structure or union required" ); 37216179Sralph }else 37316179Sralph /* if this name is non-unique, find right one */ 37416179Sralph if( stab[i].sflags & SNONUNIQ && 37516179Sralph (l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) && 37616179Sralph (l->fn.csiz +1) >= 0 ){ 37716179Sralph /* nonunique name && structure defined */ 37816179Sralph char * memnam, * tabnam; 37916179Sralph int j; 38016179Sralph int memi; 38116179Sralph j=dimtab[l->fn.csiz+1]; 38216179Sralph for( ; (memi=dimtab[j]) >= 0; ++j ){ 38316179Sralph tabnam = stab[memi].sname; 38416179Sralph memnam = stab[i].sname; 38516179Sralph # ifndef BUG1 38616179Sralph if( ddebug>1 ){ 38716179Sralph #ifndef FLEXNAMES 38816179Sralph printf("member %.8s==%.8s?\n", 38916179Sralph #else 39016179Sralph printf("member %s==%s?\n", 39116179Sralph #endif 39216179Sralph memnam, tabnam); 39316179Sralph } 39416179Sralph # endif 39516179Sralph if( stab[memi].sflags & SNONUNIQ ){ 39616179Sralph #ifndef FLEXNAMES 39732851Sdonn register k; 39816179Sralph for( k=0; k<NCHNAM; ++k ){ 39916179Sralph if(*memnam++!=*tabnam) 40016179Sralph goto next; 40116179Sralph if(!*tabnam++) break; 40216179Sralph } 40316179Sralph #else 40416179Sralph if (memnam != tabnam) 40516179Sralph goto next; 40616179Sralph #endif 40716179Sralph r->tn.rval = i = memi; 40816179Sralph break; 40916179Sralph } 41016179Sralph next: continue; 41116179Sralph } 41216179Sralph if( memi < 0 ) 41316179Sralph #ifndef FLEXNAMES 41416179Sralph uerror("illegal member use: %.8s", 41516179Sralph #else 41616179Sralph uerror("illegal member use: %s", 41716179Sralph #endif 41816179Sralph stab[i].sname); 41916179Sralph } 42016179Sralph else { 42116179Sralph register j; 42216179Sralph if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){ 42316179Sralph if( stab[i].sflags & SNONUNIQ ){ 42416179Sralph uerror( "nonunique name demands struct/union or struct/union pointer" ); 42516179Sralph } 42616179Sralph else werror( "struct/union or struct/union pointer required" ); 42716179Sralph } 42816179Sralph else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" ); 42916179Sralph else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){ 43016179Sralph #ifndef FLEXNAMES 43116179Sralph werror( "illegal member use: %.8s", stab[i].sname ); 43216179Sralph #else 43316179Sralph werror( "illegal member use: %s", stab[i].sname ); 43416179Sralph #endif 43516179Sralph } 43616179Sralph } 43716179Sralph 43816179Sralph p = stref( p ); 43916179Sralph break; 44016179Sralph 44116179Sralph case UNARY MUL: 44216179Sralph if( l->in.op == UNARY AND ){ 44316179Sralph p->in.op = l->in.op = FREE; 44416179Sralph p = l->in.left; 44516179Sralph } 44616179Sralph if( !ISPTR(l->in.type))uerror("illegal indirection"); 44716179Sralph p->in.type = DECREF(l->in.type); 44816179Sralph p->fn.cdim = l->fn.cdim; 44916179Sralph p->fn.csiz = l->fn.csiz; 45016179Sralph break; 45116179Sralph 45216179Sralph case UNARY AND: 45316179Sralph switch( l->in.op ){ 45416179Sralph 45516179Sralph case UNARY MUL: 45616179Sralph p->in.op = l->in.op = FREE; 45716179Sralph p = l->in.left; 45816179Sralph case NAME: 45916179Sralph p->in.type = INCREF( l->in.type ); 46016179Sralph p->fn.cdim = l->fn.cdim; 46116179Sralph p->fn.csiz = l->fn.csiz; 46216179Sralph break; 46316179Sralph 46416179Sralph case COMOP: 46516179Sralph lr = buildtree( UNARY AND, l->in.right, NIL ); 46616179Sralph p->in.op = l->in.op = FREE; 46716179Sralph p = buildtree( COMOP, l->in.left, lr ); 46816179Sralph break; 46916179Sralph 47016179Sralph case QUEST: 47116179Sralph lr = buildtree( UNARY AND, l->in.right->in.right, NIL ); 47216179Sralph ll = buildtree( UNARY AND, l->in.right->in.left, NIL ); 47316179Sralph p->in.op = l->in.op = l->in.right->in.op = FREE; 47416179Sralph p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) ); 47516179Sralph break; 47616179Sralph 47716179Sralph # ifdef ADDROREG 47816179Sralph case OREG: 47916179Sralph /* OREG was built in clocal() 48016179Sralph * for an auto or formal parameter 48116179Sralph * now its address is being taken 48216179Sralph * local code must unwind it 48316179Sralph * back to PLUS/MINUS REG ICON 48416179Sralph * according to local conventions 48516179Sralph */ 48616179Sralph { 48716179Sralph extern NODE * addroreg(); 48816179Sralph p->in.op = FREE; 48916179Sralph p = addroreg( l ); 49016179Sralph } 49116179Sralph break; 49216179Sralph 49316179Sralph # endif 49416179Sralph default: 49516179Sralph uerror( "unacceptable operand of &" ); 49616179Sralph break; 49716179Sralph } 49816179Sralph break; 49916179Sralph 50016179Sralph case LS: 50116179Sralph case RS: 502*34253Sdonn if( l->in.type == CHAR || l->in.type == SHORT ) 503*34253Sdonn p->in.type = INT; 504*34253Sdonn else if( l->in.type == UCHAR || l->in.type == USHORT ) 505*34253Sdonn p->in.type = UNSIGNED; 506*34253Sdonn else 507*34253Sdonn p->in.type = l->in.type; 50816179Sralph case ASG LS: 50916179Sralph case ASG RS: 510*34253Sdonn if( r->in.type != INT ) 511*34253Sdonn p->in.right = r = makety(r, INT, 0, INT ); 51216179Sralph break; 51316179Sralph 51416179Sralph case RETURN: 51516179Sralph case ASSIGN: 51616179Sralph case CAST: 51716179Sralph /* structure assignment */ 51816179Sralph /* take the addresses of the two sides; then make an 51916179Sralph /* operator using STASG and 52016179Sralph /* the addresses of left and right */ 52116179Sralph 52216179Sralph { 52316179Sralph register TWORD t; 52416179Sralph register d, s; 52516179Sralph 52616179Sralph if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" ); 52716179Sralph 52816179Sralph r = buildtree( UNARY AND, r, NIL ); 52916179Sralph t = r->in.type; 53016179Sralph d = r->fn.cdim; 53116179Sralph s = r->fn.csiz; 53216179Sralph 53316179Sralph l = block( STASG, l, r, t, d, s ); 53416179Sralph 53516179Sralph if( o == RETURN ){ 53616179Sralph p->in.op = FREE; 53716179Sralph p = l; 53816179Sralph break; 53916179Sralph } 54016179Sralph 54116179Sralph p->in.op = UNARY MUL; 54216179Sralph p->in.left = l; 54316179Sralph p->in.right = NIL; 54416179Sralph break; 54516179Sralph } 54616179Sralph case COLON: 54716179Sralph /* structure colon */ 54816179Sralph 54916179Sralph if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" ); 55016179Sralph break; 55116179Sralph 55216179Sralph case CALL: 55317749Sralph p->in.right = r = fixargs( p->in.right ); 55416179Sralph case UNARY CALL: 55516179Sralph if( !ISPTR(l->in.type)) uerror("illegal function"); 55616179Sralph p->in.type = DECREF(l->in.type); 55716179Sralph if( !ISFTN(p->in.type)) uerror("illegal function"); 55816179Sralph p->in.type = DECREF( p->in.type ); 55916179Sralph p->fn.cdim = l->fn.cdim; 56016179Sralph p->fn.csiz = l->fn.csiz; 56116179Sralph if( l->in.op == UNARY AND && l->in.left->in.op == NAME && 56216179Sralph l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME && 56316179Sralph ( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){ 56416179Sralph p->in.op += (FORTCALL-CALL); 56516179Sralph } 56616179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){ 56716179Sralph /* function returning structure */ 56816179Sralph /* make function really return ptr to str., with * */ 56916179Sralph 57016179Sralph p->in.op += STCALL-CALL; 57116179Sralph p->in.type = INCREF( p->in.type ); 57216179Sralph p = buildtree( UNARY MUL, p, NIL ); 57316179Sralph 57416179Sralph } 57516179Sralph break; 57616179Sralph 57716179Sralph default: 57816179Sralph cerror( "other code %d", o ); 57916179Sralph } 58016179Sralph 58116179Sralph } 58216179Sralph 58316179Sralph if( actions & CVTO ) p = oconvert(p); 58416179Sralph p = clocal(p); 58516179Sralph 58616179Sralph # ifndef BUG1 58716179Sralph if( bdebug ) fwalk( p, eprint, 0 ); 58816179Sralph # endif 58916179Sralph 59016179Sralph return(p); 59116179Sralph 59216179Sralph } 59316179Sralph 59424408Smckusick int fpe_count = -1; 59524408Smckusick jmp_buf gotfpe; 59624408Smckusick 59724408Smckusick fpe() { 59824408Smckusick if (fpe_count < 0) 59924408Smckusick cerror("floating point exception"); 60024408Smckusick ++fpe_count; 60124408Smckusick longjmp(gotfpe, 1); 60224408Smckusick } 60324408Smckusick 60417749Sralph /* 60517749Sralph * Rewrite arguments in a function call. 60617749Sralph * Structure arguments are massaged, single 60717749Sralph * precision floating point constants are 60817749Sralph * cast to double (to eliminate convert code). 60917749Sralph */ 61016179Sralph NODE * 61117749Sralph fixargs( p ) register NODE *p; { 61217749Sralph int o = p->in.op; 61316179Sralph 61417749Sralph if( o == CM ){ 61517749Sralph p->in.left = fixargs( p->in.left ); 61617749Sralph p->in.right = fixargs( p->in.right ); 61716179Sralph return( p ); 61816179Sralph } 61916179Sralph 62016179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){ 62116179Sralph p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz ); 62216179Sralph p->in.left = buildtree( UNARY AND, p->in.left, NIL ); 62316179Sralph p = clocal(p); 62416179Sralph } 62517749Sralph else if( o == FCON ) 62617749Sralph p = makety(p, DOUBLE, 0, 0); 62716179Sralph return( p ); 62816179Sralph } 62916179Sralph 63016179Sralph chkstr( i, j, type ) TWORD type; { 63116179Sralph /* is the MOS or MOU at stab[i] OK for strict reference by a ptr */ 63216179Sralph /* i has been checked to contain a MOS or MOU */ 63316179Sralph /* j is the index in dimtab of the members... */ 63416179Sralph int k, kk; 63516179Sralph 63616179Sralph extern int ddebug; 63716179Sralph 63816179Sralph # ifndef BUG1 63916179Sralph #ifndef FLEXNAMES 64016179Sralph if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j ); 64116179Sralph #else 64216179Sralph if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j ); 64316179Sralph #endif 64416179Sralph # endif 64516179Sralph if( (k = j) < 0 ) uerror( "undefined structure or union" ); 64616179Sralph else { 64716179Sralph for( ; (kk = dimtab[k] ) >= 0; ++k ){ 64816179Sralph if( kk >= SYMTSZ ){ 64916179Sralph cerror( "gummy structure" ); 65016179Sralph return(1); 65116179Sralph } 65216179Sralph if( kk == i ) return( 1 ); 65316179Sralph switch( stab[kk].stype ){ 65416179Sralph 65516179Sralph case STRTY: 65616179Sralph case UNIONTY: 65716179Sralph if( type == STRTY ) continue; /* no recursive looking for strs */ 65816179Sralph if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){ 65916179Sralph if( stab[kk].sname[0] == '$' ) return(0); /* $FAKE */ 66016179Sralph werror( 66116179Sralph #ifndef FLEXNAMES 66216179Sralph "illegal member use: perhaps %.8s.%.8s?", 66316179Sralph #else 66416179Sralph "illegal member use: perhaps %s.%s?", 66516179Sralph #endif 66616179Sralph stab[kk].sname, stab[i].sname ); 66716179Sralph return(1); 66816179Sralph } 66916179Sralph } 67016179Sralph } 67116179Sralph } 67216179Sralph return( 0 ); 67316179Sralph } 67416179Sralph 67516179Sralph conval( p, o, q ) register NODE *p, *q; { 67616179Sralph /* apply the op o to the lval part of p; if binary, rhs is val */ 67732842Sdonn /* works only on integer constants */ 67832842Sdonn NODE *r; 67916179Sralph int i, u; 68016179Sralph CONSZ val; 68132857Sdonn TWORD utype; 68216179Sralph 68316179Sralph val = q->tn.lval; 68416179Sralph u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type); 68516179Sralph if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 68616179Sralph 68716179Sralph if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0); 68816179Sralph if( q->tn.rval != NONAME && o!=PLUS ) return(0); 68916179Sralph if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0); 69016179Sralph 69132857Sdonn /* usual type conversions -- handle casts of constants */ 69232859Sdonn #define ISLONG(t) ((t) == LONG || (t) == ULONG) 69332859Sdonn if (ISLONG(p->in.type) || ISLONG(q->in.type)) 69432859Sdonn utype = u ? ULONG : LONG; 69532859Sdonn else 69632859Sdonn utype = u ? UNSIGNED : INT; 69732857Sdonn if( !ISPTR(p->in.type) && p->in.type != utype ) 69832857Sdonn p = makety(p, utype, 0, (int)utype); 69932857Sdonn if( q->in.type != utype ) 70032857Sdonn q = makety(q, utype, 0, (int)utype); 70132842Sdonn 70216179Sralph switch( o ){ 70316179Sralph 70416179Sralph case PLUS: 70516179Sralph p->tn.lval += val; 70616179Sralph if( p->tn.rval == NONAME ){ 70716179Sralph p->tn.rval = q->tn.rval; 70816179Sralph p->in.type = q->in.type; 70916179Sralph } 71016179Sralph break; 71116179Sralph case MINUS: 71216179Sralph p->tn.lval -= val; 71316179Sralph break; 71416179Sralph case MUL: 71532840Sdonn p->tn.lval *= val; 71616179Sralph break; 71716179Sralph case DIV: 71816179Sralph if( val == 0 ) uerror( "division by 0" ); 71917749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval / val; 72016179Sralph else p->tn.lval /= val; 72116179Sralph break; 72216179Sralph case MOD: 72316179Sralph if( val == 0 ) uerror( "division by 0" ); 72417749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval % val; 72516179Sralph else p->tn.lval %= val; 72616179Sralph break; 72716179Sralph case AND: 72816179Sralph p->tn.lval &= val; 72916179Sralph break; 73016179Sralph case OR: 73116179Sralph p->tn.lval |= val; 73216179Sralph break; 73316179Sralph case ER: 73417749Sralph p->tn.lval ^= val; 73516179Sralph break; 73616179Sralph case LS: 73716179Sralph i = val; 73816179Sralph p->tn.lval = p->tn.lval << i; 73916179Sralph break; 74016179Sralph case RS: 74116179Sralph i = val; 74217749Sralph if ( u ) p->tn.lval = (unsigned) p->tn.lval >> i; 74317749Sralph else p->tn.lval = p->tn.lval >> i; 74416179Sralph break; 74516179Sralph 74616179Sralph case UNARY MINUS: 74716179Sralph p->tn.lval = - p->tn.lval; 74816179Sralph break; 74916179Sralph case COMPL: 75016179Sralph p->tn.lval = ~p->tn.lval; 75116179Sralph break; 75216179Sralph case NOT: 75316179Sralph p->tn.lval = !p->tn.lval; 75416179Sralph break; 75516179Sralph case LT: 75616179Sralph p->tn.lval = p->tn.lval < val; 75716179Sralph break; 75816179Sralph case LE: 75916179Sralph p->tn.lval = p->tn.lval <= val; 76016179Sralph break; 76116179Sralph case GT: 76216179Sralph p->tn.lval = p->tn.lval > val; 76316179Sralph break; 76416179Sralph case GE: 76516179Sralph p->tn.lval = p->tn.lval >= val; 76616179Sralph break; 76716179Sralph case ULT: 76832848Sdonn p->tn.lval = p->tn.lval < (unsigned) val; 76916179Sralph break; 77016179Sralph case ULE: 77132848Sdonn p->tn.lval = p->tn.lval <= (unsigned) val; 77216179Sralph break; 77332848Sdonn case UGT: 77432848Sdonn p->tn.lval = p->tn.lval > (unsigned) val; 77532848Sdonn break; 77632840Sdonn case UGE: 77732848Sdonn p->tn.lval = p->tn.lval >= (unsigned) val; 77832840Sdonn break; 77916179Sralph case EQ: 78016179Sralph p->tn.lval = p->tn.lval == val; 78116179Sralph break; 78216179Sralph case NE: 78316179Sralph p->tn.lval = p->tn.lval != val; 78416179Sralph break; 78516179Sralph default: 78616179Sralph return(0); 78716179Sralph } 78816179Sralph return(1); 78916179Sralph } 79016179Sralph 79116179Sralph chkpun(p) register NODE *p; { 79216179Sralph 79316179Sralph /* checks p for the existance of a pun */ 79416179Sralph 79516179Sralph /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */ 79616179Sralph 79716179Sralph /* one case is when enumerations are used: this applies only to lint */ 79816179Sralph /* in the other case, one operand is a pointer, the other integer type */ 79916179Sralph /* we check that this integer is in fact a constant zero... */ 80016179Sralph 80116179Sralph /* in the case of ASSIGN, any assignment of pointer to integer is illegal */ 80216179Sralph /* this falls out, because the LHS is never 0 */ 80316179Sralph 80416179Sralph register NODE *q; 80516179Sralph register t1, t2; 80616179Sralph register d1, d2; 80732844Sdonn int ref1, ref2; 80816179Sralph 80916179Sralph t1 = p->in.left->in.type; 81016179Sralph t2 = p->in.right->in.type; 81116179Sralph 81216179Sralph if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */ 81332841Sdonn /* rob pike says this is obnoxious... 81432840Sdonn if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) 81532841Sdonn werror( "comparison of enums" ); */ 81632841Sdonn if( t1==ENUMTY && t2==ENUMTY ) { 81732841Sdonn if ( p->in.left->fn.csiz!=p->in.right->fn.csiz ) 81832841Sdonn werror( "enumeration type clash, operator %s", opst[p->in.op] ); 81932841Sdonn return; 82032841Sdonn } 82132841Sdonn if ( t1 == ENUMTY ) t1 = INT; 82232841Sdonn if ( t2 == ENUMTY ) t2 = INT; 82316179Sralph } 82416179Sralph 82532844Sdonn ref1 = ISPTR(t1) || ISARY(t1); 82632844Sdonn ref2 = ISPTR(t2) || ISARY(t2); 82716179Sralph 82832844Sdonn if( ref1 ^ ref2 ){ 82932844Sdonn if( ref1 ) q = p->in.right; 83032844Sdonn else q = p->in.left; 83116179Sralph if( q->in.op != ICON || q->tn.lval != 0 ){ 83216179Sralph werror( "illegal combination of pointer and integer, op %s", 83316179Sralph opst[p->in.op] ); 83416179Sralph } 83516179Sralph } 83632844Sdonn else if( ref1 ){ 83732843Sdonn if( t1 == t2 ) { 83832843Sdonn if( p->in.left->fn.csiz != p->in.right->fn.csiz ) { 83932843Sdonn werror( "illegal structure pointer combination" ); 84016179Sralph return; 84116179Sralph } 84232843Sdonn d1 = p->in.left->fn.cdim; 84332843Sdonn d2 = p->in.right->fn.cdim; 84432843Sdonn for( ;; ){ 84532843Sdonn if( ISARY(t1) ){ 84632843Sdonn if( dimtab[d1] != dimtab[d2] ){ 84732843Sdonn werror( "illegal array size combination" ); 84832843Sdonn return; 84932843Sdonn } 85032843Sdonn ++d1; 85132843Sdonn ++d2; 85216179Sralph } 85332843Sdonn else if( !ISPTR(t1) ) break; 85432843Sdonn t1 = DECREF(t1); 85516179Sralph } 85616179Sralph } 857*34253Sdonn else if( t1 != INCREF(UNDEF) && t2 != INCREF(UNDEF) ) 85832843Sdonn werror( "illegal pointer combination" ); 85916179Sralph } 86016179Sralph 86116179Sralph } 86216179Sralph 86316179Sralph NODE * 86416179Sralph stref( p ) register NODE *p; { 86516179Sralph 86616179Sralph TWORD t; 86716179Sralph int d, s, dsc, align; 86816179Sralph OFFSZ off; 86916179Sralph register struct symtab *q; 87016179Sralph 87116179Sralph /* make p->x */ 87216179Sralph /* this is also used to reference automatic variables */ 87316179Sralph 87416179Sralph q = &stab[p->in.right->tn.rval]; 87516179Sralph p->in.right->in.op = FREE; 87616179Sralph p->in.op = FREE; 87716179Sralph p = pconvert( p->in.left ); 87816179Sralph 87916179Sralph /* make p look like ptr to x */ 88016179Sralph 88116179Sralph if( !ISPTR(p->in.type)){ 88216179Sralph p->in.type = PTR+UNIONTY; 88316179Sralph } 88416179Sralph 88516179Sralph t = INCREF( q->stype ); 88616179Sralph d = q->dimoff; 88716179Sralph s = q->sizoff; 88816179Sralph 88916179Sralph p = makety( p, t, d, s ); 89016179Sralph 89116179Sralph /* compute the offset to be added */ 89216179Sralph 89316179Sralph off = q->offset; 89416179Sralph dsc = q->sclass; 89516179Sralph 89616179Sralph if( dsc & FIELD ) { /* normalize offset */ 89716179Sralph align = ALINT; 89816179Sralph s = INT; 89916179Sralph off = (off/align)*align; 90016179Sralph } 90116179Sralph if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); 90216179Sralph 90316179Sralph p = buildtree( UNARY MUL, p, NIL ); 90416179Sralph 90516179Sralph /* if field, build field info */ 90616179Sralph 90716179Sralph if( dsc & FIELD ){ 90816179Sralph p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); 90916179Sralph p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); 91016179Sralph } 91116179Sralph 91216179Sralph return( clocal(p) ); 91316179Sralph } 91416179Sralph 91516179Sralph notlval(p) register NODE *p; { 91616179Sralph 91716179Sralph /* return 0 if p an lvalue, 1 otherwise */ 91816179Sralph 91916179Sralph again: 92016179Sralph 92116179Sralph switch( p->in.op ){ 92216179Sralph 92316179Sralph case FLD: 92416179Sralph p = p->in.left; 92516179Sralph goto again; 92616179Sralph 92716179Sralph case UNARY MUL: 92816179Sralph /* fix the &(a=b) bug, given that a and b are structures */ 92916179Sralph if( p->in.left->in.op == STASG ) return( 1 ); 93016179Sralph /* and the f().a bug, given that f returns a structure */ 93116179Sralph if( p->in.left->in.op == UNARY STCALL || 93216179Sralph p->in.left->in.op == STCALL ) return( 1 ); 93316179Sralph case NAME: 93416179Sralph case OREG: 93516179Sralph if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); 93616179Sralph case REG: 93716179Sralph return(0); 93816179Sralph 93916179Sralph default: 94016179Sralph return(1); 94116179Sralph 94216179Sralph } 94316179Sralph 94416179Sralph } 94516179Sralph 94616179Sralph NODE * 94716179Sralph bcon( i ){ /* make a constant node with value i */ 94816179Sralph register NODE *p; 94916179Sralph 95016179Sralph p = block( ICON, NIL, NIL, INT, 0, INT ); 95116179Sralph p->tn.lval = i; 95216179Sralph p->tn.rval = NONAME; 95316179Sralph return( clocal(p) ); 95416179Sralph } 95516179Sralph 95616179Sralph NODE * 95716179Sralph bpsize(p) register NODE *p; { 95816179Sralph return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); 95916179Sralph } 96016179Sralph 96116179Sralph OFFSZ 96216179Sralph psize( p ) NODE *p; { 96316179Sralph /* p is a node of type pointer; psize returns the 96416179Sralph size of the thing pointed to */ 96516179Sralph 96616179Sralph if( !ISPTR(p->in.type) ){ 96716179Sralph uerror( "pointer required"); 96816179Sralph return( SZINT ); 96916179Sralph } 97016179Sralph /* note: no pointers to fields */ 97116179Sralph return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); 97216179Sralph } 97316179Sralph 97416179Sralph NODE * 97516179Sralph convert( p, f ) register NODE *p; { 97616179Sralph /* convert an operand of p 97716179Sralph f is either CVTL or CVTR 97816179Sralph operand has type int, and is converted by the size of the other side 97916179Sralph */ 98016179Sralph 98116179Sralph register NODE *q, *r; 98216179Sralph 98316179Sralph q = (f==CVTL)?p->in.left:p->in.right; 98416179Sralph 98516179Sralph r = block( PMCONV, 98616179Sralph q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT ); 98716179Sralph r = clocal(r); 98816179Sralph if( f == CVTL ) 98916179Sralph p->in.left = r; 99016179Sralph else 99116179Sralph p->in.right = r; 99216179Sralph return(p); 99316179Sralph 99416179Sralph } 99516179Sralph 99625750Sdonn #ifndef econvert 99716179Sralph econvert( p ) register NODE *p; { 99816179Sralph 99916179Sralph /* change enums to ints, or appropriate types */ 100016179Sralph 100116179Sralph register TWORD ty; 100216179Sralph 100316179Sralph if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) { 100416179Sralph if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; 100516179Sralph else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; 100616179Sralph else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; 100716179Sralph else ty = LONG; 100816179Sralph ty = ctype( ty ); 100916179Sralph p->fn.csiz = ty; 101016179Sralph MODTYPE(p->in.type,ty); 101116179Sralph if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT; 101216179Sralph } 101316179Sralph } 101425750Sdonn #endif 101516179Sralph 101616179Sralph NODE * 101716179Sralph pconvert( p ) register NODE *p; { 101816179Sralph 101916179Sralph /* if p should be changed into a pointer, do so */ 102016179Sralph 102116179Sralph if( ISARY( p->in.type) ){ 102216179Sralph p->in.type = DECREF( p->in.type ); 102316179Sralph ++p->fn.cdim; 102416179Sralph return( buildtree( UNARY AND, p, NIL ) ); 102516179Sralph } 102616179Sralph if( ISFTN( p->in.type) ) 102716179Sralph return( buildtree( UNARY AND, p, NIL ) ); 102816179Sralph 102916179Sralph return( p ); 103016179Sralph } 103116179Sralph 103216179Sralph NODE * 103316179Sralph oconvert(p) register NODE *p; { 103416179Sralph /* convert the result itself: used for pointer and unsigned */ 103516179Sralph 103616179Sralph switch(p->in.op) { 103716179Sralph 103816179Sralph case LE: 103916179Sralph case LT: 104016179Sralph case GE: 104116179Sralph case GT: 104216179Sralph if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE); 104316179Sralph case EQ: 104416179Sralph case NE: 104516179Sralph return( p ); 104616179Sralph 104716179Sralph case MINUS: 104816179Sralph return( clocal( block( PVCONV, 104916179Sralph p, bpsize(p->in.left), INT, 0, INT ) ) ); 105016179Sralph } 105116179Sralph 105216179Sralph cerror( "illegal oconvert: %d", p->in.op ); 105316179Sralph 105416179Sralph return(p); 105516179Sralph } 105616179Sralph 105716179Sralph NODE * 105816179Sralph ptmatch(p) register NODE *p; { 105916179Sralph 106016179Sralph /* makes the operands of p agree; they are 106116179Sralph either pointers or integers, by this time */ 106216179Sralph /* with MINUS, the sizes must be the same */ 106316179Sralph /* with COLON, the types must be the same */ 106416179Sralph 106516179Sralph TWORD t1, t2, t; 106616179Sralph int o, d2, d, s2, s; 106716179Sralph 106816179Sralph o = p->in.op; 106916179Sralph t = t1 = p->in.left->in.type; 107016179Sralph t2 = p->in.right->in.type; 107116179Sralph d = p->in.left->fn.cdim; 107216179Sralph d2 = p->in.right->fn.cdim; 107316179Sralph s = p->in.left->fn.csiz; 107416179Sralph s2 = p->in.right->fn.csiz; 107516179Sralph 107616179Sralph switch( o ){ 107716179Sralph 107816179Sralph case ASSIGN: 107916179Sralph case RETURN: 108016179Sralph case CAST: 108116179Sralph { break; } 108216179Sralph 108316179Sralph case MINUS: 108416179Sralph { if( psize(p->in.left) != psize(p->in.right) ){ 108516179Sralph uerror( "illegal pointer subtraction"); 108616179Sralph } 108716179Sralph break; 108816179Sralph } 108916179Sralph case COLON: 109016179Sralph { if( t1 != t2 ) uerror( "illegal types in :"); 109116179Sralph break; 109216179Sralph } 109316179Sralph default: /* must work harder: relationals or comparisons */ 109416179Sralph 109516179Sralph if( !ISPTR(t1) ){ 109616179Sralph t = t2; 109716179Sralph d = d2; 109816179Sralph s = s2; 109916179Sralph break; 110016179Sralph } 110116179Sralph if( !ISPTR(t2) ){ 110216179Sralph break; 110316179Sralph } 110416179Sralph 110516179Sralph /* both are pointers */ 110616179Sralph if( talign(t2,s2) < talign(t,s) ){ 110716179Sralph t = t2; 110816179Sralph s = s2; 110916179Sralph } 111016179Sralph break; 111116179Sralph } 111216179Sralph 111316179Sralph p->in.left = makety( p->in.left, t, d, s ); 111416179Sralph p->in.right = makety( p->in.right, t, d, s ); 111516179Sralph if( o!=MINUS && !logop(o) ){ 111616179Sralph 111716179Sralph p->in.type = t; 111816179Sralph p->fn.cdim = d; 111916179Sralph p->fn.csiz = s; 112016179Sralph } 112116179Sralph 112216179Sralph return(clocal(p)); 112316179Sralph } 112416179Sralph 112516179Sralph int tdebug = 0; 112616179Sralph 112716179Sralph NODE * 112816179Sralph tymatch(p) register NODE *p; { 112916179Sralph 113016179Sralph /* satisfy the types of various arithmetic binary ops */ 113116179Sralph 113216179Sralph /* rules are: 113325750Sdonn if assignment, type of LHS 113416179Sralph if any float or doubles, make double 113516179Sralph if any longs, make long 113616179Sralph otherwise, make int 113716179Sralph if either operand is unsigned, the result is... 113816179Sralph */ 113916179Sralph 114016179Sralph register TWORD t1, t2, t, tu; 114116179Sralph register o, u; 114216179Sralph 114316179Sralph o = p->in.op; 114416179Sralph 114516179Sralph t1 = p->in.left->in.type; 114616179Sralph t2 = p->in.right->in.type; 114716179Sralph if( (t1==UNDEF || t2==UNDEF) && o!=CAST ) 114816179Sralph uerror("void type illegal in expression"); 114916179Sralph 115016179Sralph u = 0; 115116179Sralph if( ISUNSIGNED(t1) ){ 115216179Sralph u = 1; 115316179Sralph t1 = DEUNSIGN(t1); 115416179Sralph } 115516179Sralph if( ISUNSIGNED(t2) ){ 115616179Sralph u = 1; 115716179Sralph t2 = DEUNSIGN(t2); 115816179Sralph } 115916179Sralph 116016179Sralph if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT; 116116179Sralph if( t2 == CHAR || t2 == SHORT ) t2 = INT; 116216179Sralph 116317749Sralph #ifdef SPRECC 116417749Sralph if( t1 == DOUBLE || t2 == DOUBLE ) 116517749Sralph t = DOUBLE; 116617749Sralph else if( t1 == FLOAT || t2 == FLOAT ) 116717749Sralph t = FLOAT; 116817749Sralph #else 116917749Sralph if (t1 == DOUBLE || t1 == FLOAT || t2 == DOUBLE || t2 == FLOAT) 117017749Sralph t = DOUBLE; 117117749Sralph #endif 117216179Sralph else if( t1==LONG || t2==LONG ) t = LONG; 117316179Sralph else t = INT; 117416179Sralph 117532853Sdonn if( o == ASSIGN || o == CAST || o == RETURN ) 117632853Sdonn { 117716179Sralph tu = p->in.left->in.type; 117816179Sralph t = t1; 117916179Sralph } 118016179Sralph else { 118116179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; 118216179Sralph } 118316179Sralph 118416179Sralph /* because expressions have values that are at least as wide 118516179Sralph as INT or UNSIGNED, the only conversions needed 118616179Sralph are those involving FLOAT/DOUBLE, and those 118716179Sralph from LONG to INT and ULONG to UNSIGNED */ 118816179Sralph 118932858Sdonn if( (t != t1 || (u && !ISUNSIGNED(p->in.left->in.type))) && ! asgop(o) ) 119025750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu ); 119116179Sralph 119232858Sdonn if( t != t2 || (u && !ISUNSIGNED(p->in.right->in.type)) || o==CAST) 119332840Sdonn if ( tu == ENUMTY ) {/* always asgop */ 119432840Sdonn p->in.right = makety( p->in.right, INT, 0, INT ); 119532840Sdonn p->in.right->in.type = tu; 119632840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim; 119732840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz; 119832840Sdonn } 119932840Sdonn else 120032840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu ); 120116179Sralph 120216179Sralph if( asgop(o) ){ 120316179Sralph p->in.type = p->in.left->in.type; 120416179Sralph p->fn.cdim = p->in.left->fn.cdim; 120516179Sralph p->fn.csiz = p->in.left->fn.csiz; 120616179Sralph } 120716179Sralph else if( !logop(o) ){ 120816179Sralph p->in.type = tu; 120916179Sralph p->fn.cdim = 0; 121016179Sralph p->fn.csiz = t; 121116179Sralph } 121216179Sralph 121316179Sralph # ifndef BUG1 121416179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); 121516179Sralph # endif 121616179Sralph 121716179Sralph return(p); 121816179Sralph } 121916179Sralph 122016179Sralph NODE * 122116179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; { 122216179Sralph /* make p into type t by inserting a conversion */ 122316179Sralph 122416179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); 122516179Sralph if( t == p->in.type ){ 122616179Sralph p->fn.cdim = d; 122716179Sralph p->fn.csiz = s; 122816179Sralph return( p ); 122916179Sralph } 123016179Sralph 123116179Sralph if( t & TMASK ){ 123216179Sralph /* non-simple type */ 123317228Sralph return( block( PCONV, p, NIL, t, d, s ) ); 123416179Sralph } 123516179Sralph 123616179Sralph if( p->in.op == ICON ){ 123717749Sralph if (t == DOUBLE) { 123817749Sralph p->in.op = DCON; 123917749Sralph if (ISUNSIGNED(p->in.type)) 124034092Sbostic p->dpn.dval = (U_CONSZ) p->tn.lval; 124117749Sralph else 124217749Sralph p->dpn.dval = p->tn.lval; 124317749Sralph p->in.type = p->fn.csiz = t; 124417749Sralph return (clocal(p)); 124517749Sralph } 124617749Sralph if (t == FLOAT) { 124716179Sralph p->in.op = FCON; 124816179Sralph if( ISUNSIGNED(p->in.type) ){ 124934092Sbostic p->fpn.fval = (U_CONSZ) p->tn.lval; 125016179Sralph } 125116179Sralph else { 125217749Sralph p->fpn.fval = p->tn.lval; 125316179Sralph } 125416179Sralph 125516179Sralph p->in.type = p->fn.csiz = t; 125616179Sralph return( clocal(p) ); 125716179Sralph } 125816179Sralph } 125917749Sralph else if (p->in.op == FCON && t == DOUBLE) { 126017749Sralph double db; 126116179Sralph 126217749Sralph p->in.op = DCON; 126317749Sralph db = p->fpn.fval; 126417749Sralph p->dpn.dval = db; 126517749Sralph p->in.type = p->fn.csiz = t; 126617749Sralph return (clocal(p)); 126717749Sralph } else if (p->in.op == DCON && t == FLOAT) { 126817749Sralph float fl; 126917749Sralph 127017749Sralph p->in.op = FCON; 127117749Sralph fl = p->dpn.dval; 127217749Sralph #ifdef notdef 127317749Sralph if (fl != p->dpn.dval) 127417749Sralph werror("float conversion loses precision"); 127517749Sralph #endif 127617749Sralph p->fpn.fval = fl; 127717749Sralph p->in.type = p->fn.csiz = t; 127817749Sralph return (clocal(p)); 127917749Sralph } 128017749Sralph 128117049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) ); 128216179Sralph 128316179Sralph } 128416179Sralph 128516179Sralph NODE * 128616179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { 128716179Sralph 128816179Sralph register NODE *p; 128916179Sralph 129016179Sralph p = talloc(); 129116179Sralph p->in.op = o; 129216179Sralph p->in.left = l; 129316179Sralph p->in.right = r; 129416179Sralph p->in.type = t; 129516179Sralph p->fn.cdim = d; 129616179Sralph p->fn.csiz = s; 129716179Sralph return(p); 129816179Sralph } 129916179Sralph 130016179Sralph icons(p) register NODE *p; { 130116179Sralph /* if p is an integer constant, return its value */ 130216179Sralph int val; 130316179Sralph 130416179Sralph if( p->in.op != ICON ){ 130516179Sralph uerror( "constant expected"); 130616179Sralph val = 1; 130716179Sralph } 130816179Sralph else { 130916179Sralph val = p->tn.lval; 131016179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); 131116179Sralph } 131216179Sralph tfree( p ); 131316179Sralph return(val); 131416179Sralph } 131516179Sralph 131616179Sralph /* the intent of this table is to examine the 131716179Sralph operators, and to check them for 131816179Sralph correctness. 131916179Sralph 132016179Sralph The table is searched for the op and the 132116179Sralph modified type (where this is one of the 132216179Sralph types INT (includes char and short), LONG, 132316179Sralph DOUBLE (includes FLOAT), and POINTER 132416179Sralph 132516179Sralph The default action is to make the node type integer 132616179Sralph 132716179Sralph The actions taken include: 132816179Sralph PUN check for puns 132916179Sralph CVTL convert the left operand 133016179Sralph CVTR convert the right operand 133116179Sralph TYPL the type is determined by the left operand 133216179Sralph TYPR the type is determined by the right operand 133316179Sralph TYMATCH force type of left and right to match, by inserting conversions 133416179Sralph PTMATCH like TYMATCH, but for pointers 133516179Sralph LVAL left operand must be lval 133616179Sralph CVTO convert the op 133716179Sralph NCVT do not convert the operands 133816179Sralph OTHER handled by code 133916179Sralph NCVTR convert the left operand, not the right... 134016179Sralph 134116179Sralph */ 134216179Sralph 134316179Sralph # define MINT 01 /* integer */ 134416179Sralph # define MDBI 02 /* integer or double */ 134516179Sralph # define MSTR 04 /* structure */ 134616179Sralph # define MPTR 010 /* pointer */ 134716179Sralph # define MPTI 020 /* pointer or integer */ 134816179Sralph # define MENU 040 /* enumeration variable or member */ 134924408Smckusick # define MVOID 0100000 /* void type */ 135016179Sralph 135116179Sralph opact( p ) NODE *p; { 135216179Sralph 135316179Sralph register mt12, mt1, mt2, o; 135416179Sralph 135524408Smckusick mt1 = mt2 = mt12 = 0; 135616179Sralph 135716179Sralph switch( optype(o=p->in.op) ){ 135816179Sralph 135916179Sralph case BITYPE: 136024408Smckusick mt2 = moditype( p->in.right->in.type ); 136116179Sralph case UTYPE: 136224408Smckusick mt1 = moditype( p->in.left->in.type ); 136324408Smckusick break; 136416179Sralph 136516179Sralph } 136616179Sralph 136724408Smckusick if( ((mt1 | mt2) & MVOID) && 136824408Smckusick o != COMOP && 136932845Sdonn o != COLON && 137032845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) && 137124408Smckusick !(o == CAST && (mt1 & MVOID)) ){ 137224408Smckusick /* if lhs of RETURN is void, grammar will complain */ 137324408Smckusick if( o != RETURN ) 137424408Smckusick uerror( "value of void expression used" ); 137524408Smckusick return( NCVT ); 137624408Smckusick } 137724408Smckusick mt12 = mt1 & mt2; 137824408Smckusick 137916179Sralph switch( o ){ 138016179Sralph 138116179Sralph case NAME : 138216179Sralph case STRING : 138316179Sralph case ICON : 138416179Sralph case FCON : 138517749Sralph case DCON : 138616179Sralph case CALL : 138716179Sralph case UNARY CALL: 138816179Sralph case UNARY MUL: 138916179Sralph { return( OTHER ); } 139016179Sralph case UNARY MINUS: 139132844Sdonn if( mt1 & MENU ) return( 0 ); 139216179Sralph if( mt1 & MDBI ) return( TYPL ); 139316179Sralph break; 139416179Sralph 139516179Sralph case COMPL: 139632844Sdonn if( mt1 & MENU ) return( 0 ); 139716179Sralph if( mt1 & MINT ) return( TYPL ); 139816179Sralph break; 139916179Sralph 140016179Sralph case UNARY AND: 1401*34253Sdonn return( NCVT+OTHER ); 140216179Sralph case INIT: 140316179Sralph case CM: 140416180Sralph return( 0 ); 140516180Sralph 140616179Sralph case NOT: 140716179Sralph case CBRANCH: 140816180Sralph if( mt1 & MSTR ) break; 140916180Sralph return( 0 ); 141016180Sralph 141116179Sralph case ANDAND: 141216179Sralph case OROR: 141316180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break; 141416179Sralph return( 0 ); 141516179Sralph 141616179Sralph case MUL: 141716179Sralph case DIV: 141816179Sralph if( mt12 & MDBI ) return( TYMATCH ); 141916179Sralph break; 142016179Sralph 142116179Sralph case MOD: 142216179Sralph case AND: 142316179Sralph case OR: 142416179Sralph case ER: 142516179Sralph if( mt12 & MINT ) return( TYMATCH ); 142616179Sralph break; 142716179Sralph 142816179Sralph case LS: 142916179Sralph case RS: 1430*34253Sdonn if( mt12 & MINT ) return( OTHER ); 143116179Sralph break; 143216179Sralph 143316179Sralph case EQ: 143416179Sralph case NE: 143516179Sralph case LT: 143616179Sralph case LE: 143716179Sralph case GT: 143816179Sralph case GE: 143932844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN ); 144032844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO ); 144116179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN ); 144216179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN ); 144316179Sralph else break; 144416179Sralph 144516179Sralph case QUEST: 144616179Sralph case COMOP: 144716179Sralph if( mt2&MENU ) return( TYPR+NCVTR ); 144816179Sralph return( TYPR ); 144916179Sralph 145016179Sralph case STREF: 145116179Sralph return( NCVTR+OTHER ); 145216179Sralph 145316179Sralph case FORCE: 145416179Sralph return( TYPL ); 145516179Sralph 145616179Sralph case COLON: 145732844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH ); 145832844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH ); 145916179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 146016179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 146116179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 146216179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 146332845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL ); 146416179Sralph break; 146516179Sralph 146616179Sralph case ASSIGN: 146716179Sralph case RETURN: 146816179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 146932844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN ); 147016179Sralph case CAST: 147132846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH); 147232844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH ); 147332846Sdonn else if( mt2 == MVOID && 147418436Smckusick ( p->in.right->in.op == CALL || 147518436Smckusick p->in.right->in.op == UNARY CALL)) break; 147632854Sdonn else if( (mt1 & MPTR) && (mt2 & MPTI) ) 147732854Sdonn return( LVAL+PTMATCH+PUN ); 147816179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 147916179Sralph break; 148016179Sralph 148116179Sralph case ASG LS: 148216179Sralph case ASG RS: 148316179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 148416179Sralph break; 148516179Sralph 148616179Sralph case ASG MUL: 148716179Sralph case ASG DIV: 148816179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH ); 148916179Sralph break; 149016179Sralph 149116179Sralph case ASG MOD: 149216179Sralph case ASG AND: 149316179Sralph case ASG OR: 149416179Sralph case ASG ER: 149516179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH ); 149616179Sralph break; 149716179Sralph 149816179Sralph case ASG PLUS: 149916179Sralph case ASG MINUS: 150016179Sralph case INCR: 150116179Sralph case DECR: 150216179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL ); 150316179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); 150416179Sralph break; 150516179Sralph 150616179Sralph case MINUS: 150716179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); 150816179Sralph if( mt2 & MPTR ) break; 150916179Sralph case PLUS: 151016179Sralph if( mt12 & MDBI ) return( TYMATCH ); 151116179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); 151216179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); 151316179Sralph 151416179Sralph } 151524408Smckusick if( mt12 == MSTR ) 151624408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] ); 151724408Smckusick else 151824408Smckusick uerror( "operands of %s have incompatible types", opst[o] ); 151916179Sralph return( NCVT ); 152016179Sralph } 152116179Sralph 152216179Sralph moditype( ty ) TWORD ty; { 152316179Sralph 152416179Sralph switch( ty ){ 152516179Sralph 152616179Sralph case UNDEF: 152724408Smckusick return( MVOID ); 152816179Sralph case ENUMTY: 152916179Sralph case MOETY: 153032840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */ 153116179Sralph 153216179Sralph case STRTY: 153316179Sralph case UNIONTY: 153416179Sralph return( MSTR ); 153516179Sralph 153616179Sralph case CHAR: 153716179Sralph case SHORT: 153816179Sralph case UCHAR: 153916179Sralph case USHORT: 154016179Sralph return( MINT|MPTI|MDBI ); 154116179Sralph case UNSIGNED: 154216179Sralph case ULONG: 154316179Sralph case INT: 154416179Sralph case LONG: 154516179Sralph return( MINT|MDBI|MPTI ); 154616179Sralph case FLOAT: 154716179Sralph case DOUBLE: 154816179Sralph return( MDBI ); 154916179Sralph default: 155016179Sralph return( MPTR|MPTI ); 155116179Sralph 155216179Sralph } 155316179Sralph } 155416179Sralph 155516179Sralph NODE * 155616179Sralph doszof( p ) register NODE *p; { 155716179Sralph /* do sizeof p */ 155816179Sralph int i; 155916179Sralph 156016179Sralph /* whatever is the meaning of this if it is a bitfield? */ 156116179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; 156216179Sralph 156316179Sralph tfree(p); 156416179Sralph if( i <= 0 ) werror( "sizeof returns 0" ); 156516179Sralph return( bcon( i ) ); 156616179Sralph } 156716179Sralph 156816179Sralph # ifndef BUG2 156916179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; { 157016179Sralph register ty; 157116179Sralph 157216179Sralph *a = *b = down+1; 157316179Sralph while( down > 1 ){ 157416179Sralph printf( "\t" ); 157516179Sralph down -= 2; 157616179Sralph } 157716179Sralph if( down ) printf( " " ); 157816179Sralph 157916179Sralph ty = optype( p->in.op ); 158016179Sralph 158116179Sralph printf("%o) %s, ", p, opst[p->in.op] ); 158216179Sralph if( ty == LTYPE ){ 158316179Sralph printf( CONFMT, p->tn.lval ); 158416179Sralph printf( ", %d, ", p->tn.rval ); 158516179Sralph } 158616179Sralph tprint( p->in.type ); 158716179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); 158816179Sralph } 158916179Sralph # endif 159016179Sralph 159132850Sdonn #ifndef PRTDCON 159216179Sralph prtdcon( p ) register NODE *p; { 159317749Sralph int o = p->in.op, i; 159416179Sralph 159517749Sralph if( o == DCON || o == FCON ){ 159632852Sdonn (void) locctr( DATA ); 159717749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT ); 159816179Sralph deflab( i = getlab() ); 159917749Sralph if( o == FCON ) 160017749Sralph fincode( p->fpn.fval, SZFLOAT ); 160117749Sralph else 160217749Sralph fincode( p->dpn.dval, SZDOUBLE ); 160316179Sralph p->tn.lval = 0; 160416179Sralph p->tn.rval = -i; 160517749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT); 160616179Sralph p->in.op = NAME; 160716179Sralph } 160816179Sralph } 160932850Sdonn #endif PRTDCON 161016179Sralph 161116179Sralph 161216179Sralph int edebug = 0; 161316179Sralph ecomp( p ) register NODE *p; { 161416179Sralph # ifndef BUG2 161516179Sralph if( edebug ) fwalk( p, eprint, 0 ); 161616179Sralph # endif 161716179Sralph if( !reached ){ 161816179Sralph werror( "statement not reached" ); 161916179Sralph reached = 1; 162016179Sralph } 162116179Sralph p = optim(p); 162216179Sralph walkf( p, prtdcon ); 162332852Sdonn (void) locctr( PROG ); 162416179Sralph ecode( p ); 162516179Sralph tfree(p); 162616179Sralph } 162716179Sralph 162816179Sralph # ifdef STDPRTREE 162916179Sralph # ifndef ONEPASS 163016179Sralph 163116179Sralph prtree(p) register NODE *p; { 163216179Sralph 163316179Sralph register struct symtab *q; 163416179Sralph register ty; 163516179Sralph 163616179Sralph # ifdef MYPRTREE 163716179Sralph MYPRTREE(p); /* local action can be taken here; then return... */ 163816179Sralph #endif 163916179Sralph 164016179Sralph ty = optype(p->in.op); 164116179Sralph 164216179Sralph printf( "%d\t", p->in.op ); 164316179Sralph 164416179Sralph if( ty == LTYPE ) { 164516179Sralph printf( CONFMT, p->tn.lval ); 164616179Sralph printf( "\t" ); 164716179Sralph } 164816179Sralph if( ty != BITYPE ) { 164916179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); 165016179Sralph else printf( "%d\t", p->tn.rval ); 165116179Sralph } 165216179Sralph 165316179Sralph printf( "%o\t", p->in.type ); 165416179Sralph 165516179Sralph /* handle special cases */ 165616179Sralph 165716179Sralph switch( p->in.op ){ 165816179Sralph 165916179Sralph case NAME: 166016179Sralph case ICON: 166116179Sralph /* print external name */ 166216179Sralph if( p->tn.rval == NONAME ) printf( "\n" ); 166316179Sralph else if( p->tn.rval >= 0 ){ 166416179Sralph q = &stab[p->tn.rval]; 166516179Sralph printf( "%s\n", exname(q->sname) ); 166616179Sralph } 166716179Sralph else { /* label */ 166816179Sralph printf( LABFMT, -p->tn.rval ); 166916179Sralph } 167016179Sralph break; 167116179Sralph 167216179Sralph case STARG: 167316179Sralph case STASG: 167416179Sralph case STCALL: 167516179Sralph case UNARY STCALL: 167616179Sralph /* print out size */ 167716179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */ 167816179Sralph 167916179Sralph /* note: p->in.left not a field... */ 168016179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); 168116179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); 168216179Sralph break; 168316179Sralph 168416179Sralph default: 168516179Sralph printf( "\n" ); 168616179Sralph } 168716179Sralph 168816179Sralph if( ty != LTYPE ) prtree( p->in.left ); 168916179Sralph if( ty == BITYPE ) prtree( p->in.right ); 169016179Sralph 169116179Sralph } 169216179Sralph 169316179Sralph # else 169416179Sralph 169516179Sralph p2tree(p) register NODE *p; { 169616179Sralph register ty; 169716179Sralph 169816179Sralph # ifdef MYP2TREE 169916179Sralph MYP2TREE(p); /* local action can be taken here; then return... */ 170016179Sralph # endif 170116179Sralph 170216179Sralph ty = optype(p->in.op); 170316179Sralph 170416179Sralph switch( p->in.op ){ 170516179Sralph 170616179Sralph case NAME: 170716179Sralph case ICON: 170816179Sralph #ifndef FLEXNAMES 170916179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; 171016179Sralph #else 171116179Sralph if( p->tn.rval == NONAME ) p->in.name = ""; 171216179Sralph #endif 171316179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */ 171416179Sralph register char *cp; 171516179Sralph cp = exname( stab[p->tn.rval].sname ); 171616179Sralph #ifndef FLEXNAMES 171732852Sdonn { 171832852Sdonn register i; 171932852Sdonn for( i=0; i<NCHNAM; ++i ) 172032852Sdonn p->in.name[i] = *cp++; 172132852Sdonn } 172216179Sralph #else 172316179Sralph p->in.name = tstr(cp); 172416179Sralph #endif 172516179Sralph } 172616179Sralph #ifndef FLEXNAMES 172716179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval ); 172816179Sralph #else 172916179Sralph else { 173016179Sralph char temp[32]; 173116179Sralph sprintf( temp, LABFMT, -p->tn.rval ); 173216179Sralph p->in.name = tstr(temp); 173316179Sralph } 173416179Sralph #endif 173516179Sralph break; 173616179Sralph 173716179Sralph case STARG: 173816179Sralph case STASG: 173916179Sralph case STCALL: 174016179Sralph case UNARY STCALL: 174116179Sralph /* set up size parameters */ 174216179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; 174316179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; 174416179Sralph break; 174516179Sralph 174616179Sralph case REG: 174716179Sralph rbusy( p->tn.rval, p->in.type ); 174816179Sralph default: 174916179Sralph #ifndef FLEXNAMES 175016179Sralph p->in.name[0] = '\0'; 175116179Sralph #else 175216179Sralph p->in.name = ""; 175316179Sralph #endif 175416179Sralph } 175516179Sralph 175616179Sralph p->in.rall = NOPREF; 175716179Sralph 175816179Sralph if( ty != LTYPE ) p2tree( p->in.left ); 175916179Sralph if( ty == BITYPE ) p2tree( p->in.right ); 176016179Sralph } 176116179Sralph 176216179Sralph # endif 176316179Sralph # endif 1764