117749Sralph #ifndef lint 2*32847Sdonn static char *sccsid ="@(#)trees.c 4.22 (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: 15332840Sdonn if( l->in.type == ENUMTY && r->in.type == ENUMTY ) 15432840Sdonn chkpun( p ); 15532840Sdonn 15616179Sralph case ANDAND: 15716179Sralph case OROR: 15816179Sralph case CBRANCH: 15916179Sralph 16016179Sralph ccwarn: 16116179Sralph if( hflag ) werror( "constant in conditional context" ); 16216179Sralph 16316179Sralph case PLUS: 16416179Sralph case MINUS: 16516179Sralph case MUL: 16616179Sralph case DIV: 16716179Sralph case MOD: 16816179Sralph case AND: 16916179Sralph case OR: 17016179Sralph case ER: 17116179Sralph case LS: 17216179Sralph case RS: 17316179Sralph if( conval( l, o, r ) ) { 17416179Sralph r->in.op = FREE; 17516179Sralph return(l); 17616179Sralph } 17716179Sralph break; 17816179Sralph } 17916179Sralph } 18024408Smckusick else if (opty == BITYPE && 18124408Smckusick (l->in.op == FCON || l->in.op == DCON || l->in.op == ICON) && 18224408Smckusick (r->in.op == FCON || r->in.op == DCON || r->in.op == ICON)) { 18324408Smckusick if (o == PLUS || o == MINUS || o == MUL || o == DIV) { 18424408Smckusick extern int fpe_count; 18524408Smckusick extern jmp_buf gotfpe; 18616179Sralph 18724408Smckusick fpe_count = 0; 18824408Smckusick if (setjmp(gotfpe)) 18924408Smckusick goto treatfpe; 19017749Sralph if (l->in.op == ICON) 19117749Sralph l->dpn.dval = l->tn.lval; 19224408Smckusick else if (l->in.op == FCON) 19324408Smckusick l->dpn.dval = l->fpn.fval; 19417749Sralph if (r->in.op == ICON) 19517749Sralph r->dpn.dval = r->tn.lval; 19624408Smckusick else if (r->in.op == FCON) 19724408Smckusick r->dpn.dval = r->fpn.fval; 19817749Sralph switch (o) { 19917749Sralph 20017749Sralph case PLUS: 20117749Sralph l->dpn.dval += r->dpn.dval; 20224408Smckusick break; 20317749Sralph 20417749Sralph case MINUS: 20517749Sralph l->dpn.dval -= r->dpn.dval; 20624408Smckusick break; 20717749Sralph 20817749Sralph case MUL: 20917749Sralph l->dpn.dval *= r->dpn.dval; 21024408Smckusick break; 21117749Sralph 21217749Sralph case DIV: 21317749Sralph if (r->dpn.dval == 0) 21417749Sralph uerror("division by 0."); 21517749Sralph else 21617749Sralph l->dpn.dval /= r->dpn.dval; 21724408Smckusick break; 21824408Smckusick } 21924408Smckusick treatfpe: 22024408Smckusick if (fpe_count > 0) { 22124408Smckusick uerror("floating point exception in constant expression"); 22224408Smckusick l->dpn.dval = 1.0; /* Fairly harmless */ 22324408Smckusick } 22424408Smckusick fpe_count = -1; 22524408Smckusick l->in.op = DCON; 22624408Smckusick l->in.type = l->fn.csiz = DOUBLE; 22724408Smckusick r->in.op = FREE; 22824408Smckusick return (l); 22916179Sralph } 23024408Smckusick } 23116179Sralph 23224408Smckusick /* it's real; we must make a new node */ 23316179Sralph 23416179Sralph p = block( o, l, r, INT, 0, INT ); 23516179Sralph 23616179Sralph actions = opact(p); 23717749Sralph #ifndef BUG1 23817749Sralph if (adebug) 23917749Sralph printact(p, actions); 24017749Sralph #endif 24116179Sralph 24216179Sralph if( actions&LVAL ){ /* check left descendent */ 24316179Sralph if( notlval(p->in.left) ) { 24416179Sralph uerror( "illegal lhs of assignment operator" ); 24516179Sralph } 24616179Sralph } 24716179Sralph 24816179Sralph if( actions & NCVTR ){ 24916179Sralph p->in.left = pconvert( p->in.left ); 25016179Sralph } 25116179Sralph else if( !(actions & NCVT ) ){ 25216179Sralph switch( opty ){ 25316179Sralph 25416179Sralph case BITYPE: 25516179Sralph p->in.right = pconvert( p->in.right ); 25616179Sralph case UTYPE: 25716179Sralph p->in.left = pconvert( p->in.left ); 25816179Sralph 25916179Sralph } 26016179Sralph } 26116179Sralph 26216179Sralph if( (actions&PUN) && (o!=CAST||cflag) ){ 26316179Sralph chkpun(p); 26416179Sralph } 26516179Sralph 26616179Sralph if( actions & (TYPL|TYPR) ){ 26716179Sralph 26816179Sralph q = (actions&TYPL) ? p->in.left : p->in.right; 26916179Sralph 27016179Sralph p->in.type = q->in.type; 27116179Sralph p->fn.cdim = q->fn.cdim; 27216179Sralph p->fn.csiz = q->fn.csiz; 27316179Sralph } 27416179Sralph 27516179Sralph if( actions & CVTL ) p = convert( p, CVTL ); 27616179Sralph if( actions & CVTR ) p = convert( p, CVTR ); 27716179Sralph if( actions & TYMATCH ) p = tymatch(p); 27816179Sralph if( actions & PTMATCH ) p = ptmatch(p); 27916179Sralph 28016179Sralph if( actions & OTHER ){ 28116179Sralph l = p->in.left; 28216179Sralph r = p->in.right; 28316179Sralph 28416179Sralph switch(o){ 28516179Sralph 28616179Sralph case NAME: 28716179Sralph sp = &stab[idname]; 28816179Sralph if( sp->stype == UNDEF ){ 28916179Sralph #ifndef FLEXNAMES 29016179Sralph uerror( "%.8s undefined", sp->sname ); 29116179Sralph #else 29216179Sralph uerror( "%s undefined", sp->sname ); 29316179Sralph #endif 29416179Sralph /* make p look reasonable */ 29516179Sralph p->in.type = p->fn.cdim = p->fn.csiz = INT; 29616179Sralph p->tn.rval = idname; 29716179Sralph p->tn.lval = 0; 29816179Sralph defid( p, SNULL ); 29916179Sralph break; 30016179Sralph } 30116179Sralph p->in.type = sp->stype; 30216179Sralph p->fn.cdim = sp->dimoff; 30316179Sralph p->fn.csiz = sp->sizoff; 30416179Sralph p->tn.lval = 0; 30516179Sralph p->tn.rval = idname; 30616179Sralph /* special case: MOETY is really an ICON... */ 30716179Sralph if( p->in.type == MOETY ){ 30816179Sralph p->tn.rval = NONAME; 30916179Sralph p->tn.lval = sp->offset; 31016179Sralph p->fn.cdim = 0; 31116179Sralph p->in.type = ENUMTY; 31216179Sralph p->in.op = ICON; 31316179Sralph } 31416179Sralph break; 31516179Sralph 31616179Sralph case ICON: 31716179Sralph p->in.type = INT; 31816179Sralph p->fn.cdim = 0; 31916179Sralph p->fn.csiz = INT; 32016179Sralph break; 32116179Sralph 32216179Sralph case STRING: 32316179Sralph p->in.op = NAME; 32416179Sralph p->in.type = CHAR+ARY; 32516179Sralph p->tn.lval = 0; 32616179Sralph p->tn.rval = NOLAB; 32716179Sralph p->fn.cdim = curdim; 32816179Sralph p->fn.csiz = CHAR; 32916179Sralph break; 33016179Sralph 33116179Sralph case FCON: 33216179Sralph p->tn.lval = 0; 33316179Sralph p->tn.rval = 0; 33417749Sralph p->in.type = FLOAT; 33517749Sralph p->fn.cdim = 0; 33617749Sralph p->fn.csiz = FLOAT; 33717749Sralph break; 33817749Sralph 33917749Sralph case DCON: 34017749Sralph p->tn.lval = 0; 34117749Sralph p->tn.rval = 0; 34216179Sralph p->in.type = DOUBLE; 34316179Sralph p->fn.cdim = 0; 34416179Sralph p->fn.csiz = DOUBLE; 34516179Sralph break; 34616179Sralph 34716179Sralph case STREF: 34816179Sralph /* p->x turned into *(p+offset) */ 34916179Sralph /* rhs must be a name; check correctness */ 35016179Sralph 35116179Sralph i = r->tn.rval; 35216179Sralph if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){ 35316179Sralph uerror( "member of structure or union required" ); 35416179Sralph }else 35516179Sralph /* if this name is non-unique, find right one */ 35616179Sralph if( stab[i].sflags & SNONUNIQ && 35716179Sralph (l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) && 35816179Sralph (l->fn.csiz +1) >= 0 ){ 35916179Sralph /* nonunique name && structure defined */ 36016179Sralph char * memnam, * tabnam; 36116179Sralph register k; 36216179Sralph int j; 36316179Sralph int memi; 36416179Sralph j=dimtab[l->fn.csiz+1]; 36516179Sralph for( ; (memi=dimtab[j]) >= 0; ++j ){ 36616179Sralph tabnam = stab[memi].sname; 36716179Sralph memnam = stab[i].sname; 36816179Sralph # ifndef BUG1 36916179Sralph if( ddebug>1 ){ 37016179Sralph #ifndef FLEXNAMES 37116179Sralph printf("member %.8s==%.8s?\n", 37216179Sralph #else 37316179Sralph printf("member %s==%s?\n", 37416179Sralph #endif 37516179Sralph memnam, tabnam); 37616179Sralph } 37716179Sralph # endif 37816179Sralph if( stab[memi].sflags & SNONUNIQ ){ 37916179Sralph #ifndef FLEXNAMES 38016179Sralph for( k=0; k<NCHNAM; ++k ){ 38116179Sralph if(*memnam++!=*tabnam) 38216179Sralph goto next; 38316179Sralph if(!*tabnam++) break; 38416179Sralph } 38516179Sralph #else 38616179Sralph if (memnam != tabnam) 38716179Sralph goto next; 38816179Sralph #endif 38916179Sralph r->tn.rval = i = memi; 39016179Sralph break; 39116179Sralph } 39216179Sralph next: continue; 39316179Sralph } 39416179Sralph if( memi < 0 ) 39516179Sralph #ifndef FLEXNAMES 39616179Sralph uerror("illegal member use: %.8s", 39716179Sralph #else 39816179Sralph uerror("illegal member use: %s", 39916179Sralph #endif 40016179Sralph stab[i].sname); 40116179Sralph } 40216179Sralph else { 40316179Sralph register j; 40416179Sralph if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){ 40516179Sralph if( stab[i].sflags & SNONUNIQ ){ 40616179Sralph uerror( "nonunique name demands struct/union or struct/union pointer" ); 40716179Sralph } 40816179Sralph else werror( "struct/union or struct/union pointer required" ); 40916179Sralph } 41016179Sralph else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" ); 41116179Sralph else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){ 41216179Sralph #ifndef FLEXNAMES 41316179Sralph werror( "illegal member use: %.8s", stab[i].sname ); 41416179Sralph #else 41516179Sralph werror( "illegal member use: %s", stab[i].sname ); 41616179Sralph #endif 41716179Sralph } 41816179Sralph } 41916179Sralph 42016179Sralph p = stref( p ); 42116179Sralph break; 42216179Sralph 42316179Sralph case UNARY MUL: 42416179Sralph if( l->in.op == UNARY AND ){ 42516179Sralph p->in.op = l->in.op = FREE; 42616179Sralph p = l->in.left; 42716179Sralph } 42816179Sralph if( !ISPTR(l->in.type))uerror("illegal indirection"); 42916179Sralph p->in.type = DECREF(l->in.type); 43016179Sralph p->fn.cdim = l->fn.cdim; 43116179Sralph p->fn.csiz = l->fn.csiz; 43216179Sralph break; 43316179Sralph 43416179Sralph case UNARY AND: 43516179Sralph switch( l->in.op ){ 43616179Sralph 43716179Sralph case UNARY MUL: 43816179Sralph p->in.op = l->in.op = FREE; 43916179Sralph p = l->in.left; 44016179Sralph case NAME: 44116179Sralph p->in.type = INCREF( l->in.type ); 44216179Sralph p->fn.cdim = l->fn.cdim; 44316179Sralph p->fn.csiz = l->fn.csiz; 44416179Sralph break; 44516179Sralph 44616179Sralph case COMOP: 44716179Sralph lr = buildtree( UNARY AND, l->in.right, NIL ); 44816179Sralph p->in.op = l->in.op = FREE; 44916179Sralph p = buildtree( COMOP, l->in.left, lr ); 45016179Sralph break; 45116179Sralph 45216179Sralph case QUEST: 45316179Sralph lr = buildtree( UNARY AND, l->in.right->in.right, NIL ); 45416179Sralph ll = buildtree( UNARY AND, l->in.right->in.left, NIL ); 45516179Sralph p->in.op = l->in.op = l->in.right->in.op = FREE; 45616179Sralph p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) ); 45716179Sralph break; 45816179Sralph 45916179Sralph # ifdef ADDROREG 46016179Sralph case OREG: 46116179Sralph /* OREG was built in clocal() 46216179Sralph * for an auto or formal parameter 46316179Sralph * now its address is being taken 46416179Sralph * local code must unwind it 46516179Sralph * back to PLUS/MINUS REG ICON 46616179Sralph * according to local conventions 46716179Sralph */ 46816179Sralph { 46916179Sralph extern NODE * addroreg(); 47016179Sralph p->in.op = FREE; 47116179Sralph p = addroreg( l ); 47216179Sralph } 47316179Sralph break; 47416179Sralph 47516179Sralph # endif 47616179Sralph default: 47716179Sralph uerror( "unacceptable operand of &" ); 47816179Sralph break; 47916179Sralph } 48016179Sralph break; 48116179Sralph 48216179Sralph case LS: 48316179Sralph case RS: 48416179Sralph case ASG LS: 48516179Sralph case ASG RS: 48616179Sralph if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT) 48716179Sralph p->in.right = makety(p->in.right, INT, 0, INT ); 48816179Sralph break; 48916179Sralph 49016179Sralph case RETURN: 49116179Sralph case ASSIGN: 49216179Sralph case CAST: 49316179Sralph /* structure assignment */ 49416179Sralph /* take the addresses of the two sides; then make an 49516179Sralph /* operator using STASG and 49616179Sralph /* the addresses of left and right */ 49716179Sralph 49816179Sralph { 49916179Sralph register TWORD t; 50016179Sralph register d, s; 50116179Sralph 50216179Sralph if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" ); 50316179Sralph 50416179Sralph r = buildtree( UNARY AND, r, NIL ); 50516179Sralph t = r->in.type; 50616179Sralph d = r->fn.cdim; 50716179Sralph s = r->fn.csiz; 50816179Sralph 50916179Sralph l = block( STASG, l, r, t, d, s ); 51016179Sralph 51116179Sralph if( o == RETURN ){ 51216179Sralph p->in.op = FREE; 51316179Sralph p = l; 51416179Sralph break; 51516179Sralph } 51616179Sralph 51716179Sralph p->in.op = UNARY MUL; 51816179Sralph p->in.left = l; 51916179Sralph p->in.right = NIL; 52016179Sralph break; 52116179Sralph } 52216179Sralph case COLON: 52316179Sralph /* structure colon */ 52416179Sralph 52516179Sralph if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" ); 52616179Sralph break; 52716179Sralph 52816179Sralph case CALL: 52917749Sralph p->in.right = r = fixargs( p->in.right ); 53016179Sralph case UNARY CALL: 53116179Sralph if( !ISPTR(l->in.type)) uerror("illegal function"); 53216179Sralph p->in.type = DECREF(l->in.type); 53316179Sralph if( !ISFTN(p->in.type)) uerror("illegal function"); 53416179Sralph p->in.type = DECREF( p->in.type ); 53516179Sralph p->fn.cdim = l->fn.cdim; 53616179Sralph p->fn.csiz = l->fn.csiz; 53716179Sralph if( l->in.op == UNARY AND && l->in.left->in.op == NAME && 53816179Sralph l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME && 53916179Sralph ( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){ 54016179Sralph p->in.op += (FORTCALL-CALL); 54116179Sralph } 54216179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){ 54316179Sralph /* function returning structure */ 54416179Sralph /* make function really return ptr to str., with * */ 54516179Sralph 54616179Sralph p->in.op += STCALL-CALL; 54716179Sralph p->in.type = INCREF( p->in.type ); 54816179Sralph p = buildtree( UNARY MUL, p, NIL ); 54916179Sralph 55016179Sralph } 55116179Sralph break; 55216179Sralph 55316179Sralph default: 55416179Sralph cerror( "other code %d", o ); 55516179Sralph } 55616179Sralph 55716179Sralph } 55816179Sralph 55916179Sralph if( actions & CVTO ) p = oconvert(p); 56016179Sralph p = clocal(p); 56116179Sralph 56216179Sralph # ifndef BUG1 56316179Sralph if( bdebug ) fwalk( p, eprint, 0 ); 56416179Sralph # endif 56516179Sralph 56616179Sralph return(p); 56716179Sralph 56816179Sralph } 56916179Sralph 57024408Smckusick int fpe_count = -1; 57124408Smckusick jmp_buf gotfpe; 57224408Smckusick 57324408Smckusick fpe() { 57424408Smckusick if (fpe_count < 0) 57524408Smckusick cerror("floating point exception"); 57624408Smckusick ++fpe_count; 57724408Smckusick longjmp(gotfpe, 1); 57824408Smckusick } 57924408Smckusick 58017749Sralph /* 58117749Sralph * Rewrite arguments in a function call. 58217749Sralph * Structure arguments are massaged, single 58317749Sralph * precision floating point constants are 58417749Sralph * cast to double (to eliminate convert code). 58517749Sralph */ 58616179Sralph NODE * 58717749Sralph fixargs( p ) register NODE *p; { 58817749Sralph int o = p->in.op; 58916179Sralph 59017749Sralph if( o == CM ){ 59117749Sralph p->in.left = fixargs( p->in.left ); 59217749Sralph p->in.right = fixargs( p->in.right ); 59316179Sralph return( p ); 59416179Sralph } 59516179Sralph 59616179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){ 59716179Sralph p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz ); 59816179Sralph p->in.left = buildtree( UNARY AND, p->in.left, NIL ); 59916179Sralph p = clocal(p); 60016179Sralph } 60117749Sralph else if( o == FCON ) 60217749Sralph p = makety(p, DOUBLE, 0, 0); 60316179Sralph return( p ); 60416179Sralph } 60516179Sralph 60616179Sralph chkstr( i, j, type ) TWORD type; { 60716179Sralph /* is the MOS or MOU at stab[i] OK for strict reference by a ptr */ 60816179Sralph /* i has been checked to contain a MOS or MOU */ 60916179Sralph /* j is the index in dimtab of the members... */ 61016179Sralph int k, kk; 61116179Sralph 61216179Sralph extern int ddebug; 61316179Sralph 61416179Sralph # ifndef BUG1 61516179Sralph #ifndef FLEXNAMES 61616179Sralph if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j ); 61716179Sralph #else 61816179Sralph if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j ); 61916179Sralph #endif 62016179Sralph # endif 62116179Sralph if( (k = j) < 0 ) uerror( "undefined structure or union" ); 62216179Sralph else { 62316179Sralph for( ; (kk = dimtab[k] ) >= 0; ++k ){ 62416179Sralph if( kk >= SYMTSZ ){ 62516179Sralph cerror( "gummy structure" ); 62616179Sralph return(1); 62716179Sralph } 62816179Sralph if( kk == i ) return( 1 ); 62916179Sralph switch( stab[kk].stype ){ 63016179Sralph 63116179Sralph case STRTY: 63216179Sralph case UNIONTY: 63316179Sralph if( type == STRTY ) continue; /* no recursive looking for strs */ 63416179Sralph if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){ 63516179Sralph if( stab[kk].sname[0] == '$' ) return(0); /* $FAKE */ 63616179Sralph werror( 63716179Sralph #ifndef FLEXNAMES 63816179Sralph "illegal member use: perhaps %.8s.%.8s?", 63916179Sralph #else 64016179Sralph "illegal member use: perhaps %s.%s?", 64116179Sralph #endif 64216179Sralph stab[kk].sname, stab[i].sname ); 64316179Sralph return(1); 64416179Sralph } 64516179Sralph } 64616179Sralph } 64716179Sralph } 64816179Sralph return( 0 ); 64916179Sralph } 65016179Sralph 65116179Sralph conval( p, o, q ) register NODE *p, *q; { 65216179Sralph /* apply the op o to the lval part of p; if binary, rhs is val */ 65332842Sdonn /* works only on integer constants */ 65432842Sdonn NODE *r; 65516179Sralph int i, u; 65616179Sralph CONSZ val; 65716179Sralph 65816179Sralph val = q->tn.lval; 65916179Sralph u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type); 66016179Sralph if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 66116179Sralph 66216179Sralph if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0); 66316179Sralph if( q->tn.rval != NONAME && o!=PLUS ) return(0); 66416179Sralph if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0); 66516179Sralph 66632842Sdonn if( p->in.type != INT || q->in.type != INT ){ 66732842Sdonn /* will this always work if p == q and o is UTYPE? */ 66832842Sdonn r = block( o, p, q, INT, 0, INT ); 66932842Sdonn r = tymatch( r ); 67032842Sdonn p->in.type = r->in.type; 67132842Sdonn p->fn.cdim = r->fn.cdim; 67232842Sdonn p->fn.csiz = r->fn.csiz; 67332842Sdonn r->in.op = FREE; 67432842Sdonn } 67532842Sdonn 67616179Sralph switch( o ){ 67716179Sralph 67816179Sralph case PLUS: 67916179Sralph p->tn.lval += val; 68016179Sralph if( p->tn.rval == NONAME ){ 68116179Sralph p->tn.rval = q->tn.rval; 68216179Sralph p->in.type = q->in.type; 68316179Sralph } 68416179Sralph break; 68516179Sralph case MINUS: 68616179Sralph p->tn.lval -= val; 68716179Sralph break; 68816179Sralph case MUL: 68932840Sdonn p->tn.lval *= val; 69016179Sralph break; 69116179Sralph case DIV: 69216179Sralph if( val == 0 ) uerror( "division by 0" ); 69317749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval / val; 69416179Sralph else p->tn.lval /= val; 69516179Sralph break; 69616179Sralph case MOD: 69716179Sralph if( val == 0 ) uerror( "division by 0" ); 69817749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval % val; 69916179Sralph else p->tn.lval %= val; 70016179Sralph break; 70116179Sralph case AND: 70216179Sralph p->tn.lval &= val; 70316179Sralph break; 70416179Sralph case OR: 70516179Sralph p->tn.lval |= val; 70616179Sralph break; 70716179Sralph case ER: 70817749Sralph p->tn.lval ^= val; 70916179Sralph break; 71016179Sralph case LS: 71116179Sralph i = val; 71216179Sralph p->tn.lval = p->tn.lval << i; 71316179Sralph break; 71416179Sralph case RS: 71516179Sralph i = val; 71617749Sralph if ( u ) p->tn.lval = (unsigned) p->tn.lval >> i; 71717749Sralph else p->tn.lval = p->tn.lval >> i; 71816179Sralph break; 71916179Sralph 72016179Sralph case UNARY MINUS: 72116179Sralph p->tn.lval = - p->tn.lval; 72216179Sralph break; 72316179Sralph case COMPL: 72416179Sralph p->tn.lval = ~p->tn.lval; 72516179Sralph break; 72616179Sralph case NOT: 72716179Sralph p->tn.lval = !p->tn.lval; 72816179Sralph break; 72916179Sralph case LT: 73016179Sralph p->tn.lval = p->tn.lval < val; 73116179Sralph break; 73216179Sralph case LE: 73316179Sralph p->tn.lval = p->tn.lval <= val; 73416179Sralph break; 73516179Sralph case GT: 73616179Sralph p->tn.lval = p->tn.lval > val; 73716179Sralph break; 73816179Sralph case GE: 73916179Sralph p->tn.lval = p->tn.lval >= val; 74016179Sralph break; 74116179Sralph case ULT: 74232840Sdonn p->tn.lval = (p->tn.lval-val)<0; 74316179Sralph break; 74416179Sralph case ULE: 74532840Sdonn p->tn.lval = (p->tn.lval-val)<=0; 74616179Sralph break; 74732840Sdonn case UGE: 74832840Sdonn p->tn.lval = (p->tn.lval-val)>=0; 74932840Sdonn break; 75030242Sbostic case UGT: 75132840Sdonn p->tn.lval = (p->tn.lval-val)>0; 75230242Sbostic break; 75316179Sralph case EQ: 75416179Sralph p->tn.lval = p->tn.lval == val; 75516179Sralph break; 75616179Sralph case NE: 75716179Sralph p->tn.lval = p->tn.lval != val; 75816179Sralph break; 75916179Sralph default: 76016179Sralph return(0); 76116179Sralph } 76216179Sralph return(1); 76316179Sralph } 76416179Sralph 76516179Sralph chkpun(p) register NODE *p; { 76616179Sralph 76716179Sralph /* checks p for the existance of a pun */ 76816179Sralph 76916179Sralph /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */ 77016179Sralph 77116179Sralph /* one case is when enumerations are used: this applies only to lint */ 77216179Sralph /* in the other case, one operand is a pointer, the other integer type */ 77316179Sralph /* we check that this integer is in fact a constant zero... */ 77416179Sralph 77516179Sralph /* in the case of ASSIGN, any assignment of pointer to integer is illegal */ 77616179Sralph /* this falls out, because the LHS is never 0 */ 77716179Sralph 77816179Sralph register NODE *q; 77916179Sralph register t1, t2; 78016179Sralph register d1, d2; 78132844Sdonn int ref1, ref2; 78216179Sralph 78316179Sralph t1 = p->in.left->in.type; 78416179Sralph t2 = p->in.right->in.type; 78516179Sralph 78616179Sralph if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */ 78732841Sdonn /* rob pike says this is obnoxious... 78832840Sdonn if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) 78932841Sdonn werror( "comparison of enums" ); */ 79032841Sdonn if( t1==ENUMTY && t2==ENUMTY ) { 79132841Sdonn if ( p->in.left->fn.csiz!=p->in.right->fn.csiz ) 79232841Sdonn werror( "enumeration type clash, operator %s", opst[p->in.op] ); 79332841Sdonn return; 79432841Sdonn } 79532841Sdonn if ( t1 == ENUMTY ) t1 = INT; 79632841Sdonn if ( t2 == ENUMTY ) t2 = INT; 79716179Sralph } 79816179Sralph 79932844Sdonn ref1 = ISPTR(t1) || ISARY(t1); 80032844Sdonn ref2 = ISPTR(t2) || ISARY(t2); 80116179Sralph 80232844Sdonn if( ref1 ^ ref2 ){ 80332844Sdonn if( ref1 ) q = p->in.right; 80432844Sdonn else q = p->in.left; 80516179Sralph if( q->in.op != ICON || q->tn.lval != 0 ){ 80616179Sralph werror( "illegal combination of pointer and integer, op %s", 80716179Sralph opst[p->in.op] ); 80816179Sralph } 80916179Sralph } 81032844Sdonn else if( ref1 ){ 81132843Sdonn if( t1 == t2 ) { 81232843Sdonn if( p->in.left->fn.csiz != p->in.right->fn.csiz ) { 81332843Sdonn werror( "illegal structure pointer combination" ); 81416179Sralph return; 81516179Sralph } 81632843Sdonn d1 = p->in.left->fn.cdim; 81732843Sdonn d2 = p->in.right->fn.cdim; 81832843Sdonn for( ;; ){ 81932843Sdonn if( ISARY(t1) ){ 82032843Sdonn if( dimtab[d1] != dimtab[d2] ){ 82132843Sdonn werror( "illegal array size combination" ); 82232843Sdonn return; 82332843Sdonn } 82432843Sdonn ++d1; 82532843Sdonn ++d2; 82616179Sralph } 82732843Sdonn else if( !ISPTR(t1) ) break; 82832843Sdonn t1 = DECREF(t1); 82916179Sralph } 83016179Sralph } 83132843Sdonn else 83232843Sdonn werror( "illegal pointer combination" ); 83316179Sralph } 83416179Sralph 83516179Sralph } 83616179Sralph 83716179Sralph NODE * 83816179Sralph stref( p ) register NODE *p; { 83916179Sralph 84016179Sralph TWORD t; 84116179Sralph int d, s, dsc, align; 84216179Sralph OFFSZ off; 84316179Sralph register struct symtab *q; 84416179Sralph 84516179Sralph /* make p->x */ 84616179Sralph /* this is also used to reference automatic variables */ 84716179Sralph 84816179Sralph q = &stab[p->in.right->tn.rval]; 84916179Sralph p->in.right->in.op = FREE; 85016179Sralph p->in.op = FREE; 85116179Sralph p = pconvert( p->in.left ); 85216179Sralph 85316179Sralph /* make p look like ptr to x */ 85416179Sralph 85516179Sralph if( !ISPTR(p->in.type)){ 85616179Sralph p->in.type = PTR+UNIONTY; 85716179Sralph } 85816179Sralph 85916179Sralph t = INCREF( q->stype ); 86016179Sralph d = q->dimoff; 86116179Sralph s = q->sizoff; 86216179Sralph 86316179Sralph p = makety( p, t, d, s ); 86416179Sralph 86516179Sralph /* compute the offset to be added */ 86616179Sralph 86716179Sralph off = q->offset; 86816179Sralph dsc = q->sclass; 86916179Sralph 87016179Sralph if( dsc & FIELD ) { /* normalize offset */ 87116179Sralph align = ALINT; 87216179Sralph s = INT; 87316179Sralph off = (off/align)*align; 87416179Sralph } 87516179Sralph if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); 87616179Sralph 87716179Sralph p = buildtree( UNARY MUL, p, NIL ); 87816179Sralph 87916179Sralph /* if field, build field info */ 88016179Sralph 88116179Sralph if( dsc & FIELD ){ 88216179Sralph p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); 88316179Sralph p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); 88416179Sralph } 88516179Sralph 88616179Sralph return( clocal(p) ); 88716179Sralph } 88816179Sralph 88916179Sralph notlval(p) register NODE *p; { 89016179Sralph 89116179Sralph /* return 0 if p an lvalue, 1 otherwise */ 89216179Sralph 89316179Sralph again: 89416179Sralph 89516179Sralph switch( p->in.op ){ 89616179Sralph 89716179Sralph case FLD: 89816179Sralph p = p->in.left; 89916179Sralph goto again; 90016179Sralph 90116179Sralph case UNARY MUL: 90216179Sralph /* fix the &(a=b) bug, given that a and b are structures */ 90316179Sralph if( p->in.left->in.op == STASG ) return( 1 ); 90416179Sralph /* and the f().a bug, given that f returns a structure */ 90516179Sralph if( p->in.left->in.op == UNARY STCALL || 90616179Sralph p->in.left->in.op == STCALL ) return( 1 ); 90716179Sralph case NAME: 90816179Sralph case OREG: 90916179Sralph if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); 91016179Sralph case REG: 91116179Sralph return(0); 91216179Sralph 91316179Sralph default: 91416179Sralph return(1); 91516179Sralph 91616179Sralph } 91716179Sralph 91816179Sralph } 91916179Sralph 92016179Sralph NODE * 92116179Sralph bcon( i ){ /* make a constant node with value i */ 92216179Sralph register NODE *p; 92316179Sralph 92416179Sralph p = block( ICON, NIL, NIL, INT, 0, INT ); 92516179Sralph p->tn.lval = i; 92616179Sralph p->tn.rval = NONAME; 92716179Sralph return( clocal(p) ); 92816179Sralph } 92916179Sralph 93016179Sralph NODE * 93116179Sralph bpsize(p) register NODE *p; { 93216179Sralph return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); 93316179Sralph } 93416179Sralph 93516179Sralph OFFSZ 93616179Sralph psize( p ) NODE *p; { 93716179Sralph /* p is a node of type pointer; psize returns the 93816179Sralph size of the thing pointed to */ 93916179Sralph 94016179Sralph if( !ISPTR(p->in.type) ){ 94116179Sralph uerror( "pointer required"); 94216179Sralph return( SZINT ); 94316179Sralph } 94416179Sralph /* note: no pointers to fields */ 94516179Sralph return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); 94616179Sralph } 94716179Sralph 94816179Sralph NODE * 94916179Sralph convert( p, f ) register NODE *p; { 95016179Sralph /* convert an operand of p 95116179Sralph f is either CVTL or CVTR 95216179Sralph operand has type int, and is converted by the size of the other side 95316179Sralph */ 95416179Sralph 95516179Sralph register NODE *q, *r; 95616179Sralph 95716179Sralph q = (f==CVTL)?p->in.left:p->in.right; 95816179Sralph 95916179Sralph r = block( PMCONV, 96016179Sralph q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT ); 96116179Sralph r = clocal(r); 96216179Sralph if( f == CVTL ) 96316179Sralph p->in.left = r; 96416179Sralph else 96516179Sralph p->in.right = r; 96616179Sralph return(p); 96716179Sralph 96816179Sralph } 96916179Sralph 97025750Sdonn #ifndef econvert 97116179Sralph econvert( p ) register NODE *p; { 97216179Sralph 97316179Sralph /* change enums to ints, or appropriate types */ 97416179Sralph 97516179Sralph register TWORD ty; 97616179Sralph 97716179Sralph if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) { 97816179Sralph if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; 97916179Sralph else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; 98016179Sralph else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; 98116179Sralph else ty = LONG; 98216179Sralph ty = ctype( ty ); 98316179Sralph p->fn.csiz = ty; 98416179Sralph MODTYPE(p->in.type,ty); 98516179Sralph if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT; 98616179Sralph } 98716179Sralph } 98825750Sdonn #endif 98916179Sralph 99016179Sralph NODE * 99116179Sralph pconvert( p ) register NODE *p; { 99216179Sralph 99316179Sralph /* if p should be changed into a pointer, do so */ 99416179Sralph 99516179Sralph if( ISARY( p->in.type) ){ 99616179Sralph p->in.type = DECREF( p->in.type ); 99716179Sralph ++p->fn.cdim; 99816179Sralph return( buildtree( UNARY AND, p, NIL ) ); 99916179Sralph } 100016179Sralph if( ISFTN( p->in.type) ) 100116179Sralph return( buildtree( UNARY AND, p, NIL ) ); 100216179Sralph 100316179Sralph return( p ); 100416179Sralph } 100516179Sralph 100616179Sralph NODE * 100716179Sralph oconvert(p) register NODE *p; { 100816179Sralph /* convert the result itself: used for pointer and unsigned */ 100916179Sralph 101016179Sralph switch(p->in.op) { 101116179Sralph 101216179Sralph case LE: 101316179Sralph case LT: 101416179Sralph case GE: 101516179Sralph case GT: 101616179Sralph if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE); 101716179Sralph case EQ: 101816179Sralph case NE: 101916179Sralph return( p ); 102016179Sralph 102116179Sralph case MINUS: 102216179Sralph return( clocal( block( PVCONV, 102316179Sralph p, bpsize(p->in.left), INT, 0, INT ) ) ); 102416179Sralph } 102516179Sralph 102616179Sralph cerror( "illegal oconvert: %d", p->in.op ); 102716179Sralph 102816179Sralph return(p); 102916179Sralph } 103016179Sralph 103116179Sralph NODE * 103216179Sralph ptmatch(p) register NODE *p; { 103316179Sralph 103416179Sralph /* makes the operands of p agree; they are 103516179Sralph either pointers or integers, by this time */ 103616179Sralph /* with MINUS, the sizes must be the same */ 103716179Sralph /* with COLON, the types must be the same */ 103816179Sralph 103916179Sralph TWORD t1, t2, t; 104016179Sralph int o, d2, d, s2, s; 104116179Sralph 104216179Sralph o = p->in.op; 104316179Sralph t = t1 = p->in.left->in.type; 104416179Sralph t2 = p->in.right->in.type; 104516179Sralph d = p->in.left->fn.cdim; 104616179Sralph d2 = p->in.right->fn.cdim; 104716179Sralph s = p->in.left->fn.csiz; 104816179Sralph s2 = p->in.right->fn.csiz; 104916179Sralph 105016179Sralph switch( o ){ 105116179Sralph 105216179Sralph case ASSIGN: 105316179Sralph case RETURN: 105416179Sralph case CAST: 105516179Sralph { break; } 105616179Sralph 105716179Sralph case MINUS: 105816179Sralph { if( psize(p->in.left) != psize(p->in.right) ){ 105916179Sralph uerror( "illegal pointer subtraction"); 106016179Sralph } 106116179Sralph break; 106216179Sralph } 106316179Sralph case COLON: 106416179Sralph { if( t1 != t2 ) uerror( "illegal types in :"); 106516179Sralph break; 106616179Sralph } 106716179Sralph default: /* must work harder: relationals or comparisons */ 106816179Sralph 106916179Sralph if( !ISPTR(t1) ){ 107016179Sralph t = t2; 107116179Sralph d = d2; 107216179Sralph s = s2; 107316179Sralph break; 107416179Sralph } 107516179Sralph if( !ISPTR(t2) ){ 107616179Sralph break; 107716179Sralph } 107816179Sralph 107916179Sralph /* both are pointers */ 108016179Sralph if( talign(t2,s2) < talign(t,s) ){ 108116179Sralph t = t2; 108216179Sralph s = s2; 108316179Sralph } 108416179Sralph break; 108516179Sralph } 108616179Sralph 108716179Sralph p->in.left = makety( p->in.left, t, d, s ); 108816179Sralph p->in.right = makety( p->in.right, t, d, s ); 108916179Sralph if( o!=MINUS && !logop(o) ){ 109016179Sralph 109116179Sralph p->in.type = t; 109216179Sralph p->fn.cdim = d; 109316179Sralph p->fn.csiz = s; 109416179Sralph } 109516179Sralph 109616179Sralph return(clocal(p)); 109716179Sralph } 109816179Sralph 109916179Sralph int tdebug = 0; 110016179Sralph 110116179Sralph NODE * 110216179Sralph tymatch(p) register NODE *p; { 110316179Sralph 110416179Sralph /* satisfy the types of various arithmetic binary ops */ 110516179Sralph 110616179Sralph /* rules are: 110725750Sdonn if assignment, type of LHS 110816179Sralph if any float or doubles, make double 110916179Sralph if any longs, make long 111016179Sralph otherwise, make int 111116179Sralph if either operand is unsigned, the result is... 111216179Sralph */ 111316179Sralph 111416179Sralph register TWORD t1, t2, t, tu; 111516179Sralph register o, u; 111616179Sralph 111716179Sralph o = p->in.op; 111816179Sralph 111916179Sralph t1 = p->in.left->in.type; 112016179Sralph t2 = p->in.right->in.type; 112116179Sralph if( (t1==UNDEF || t2==UNDEF) && o!=CAST ) 112216179Sralph uerror("void type illegal in expression"); 112316179Sralph 112416179Sralph u = 0; 112516179Sralph if( ISUNSIGNED(t1) ){ 112616179Sralph u = 1; 112716179Sralph t1 = DEUNSIGN(t1); 112816179Sralph } 112916179Sralph if( ISUNSIGNED(t2) ){ 113016179Sralph u = 1; 113116179Sralph t2 = DEUNSIGN(t2); 113216179Sralph } 113316179Sralph 113416179Sralph if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT; 113516179Sralph if( t2 == CHAR || t2 == SHORT ) t2 = INT; 113616179Sralph 113717749Sralph #ifdef SPRECC 113817749Sralph if( t1 == DOUBLE || t2 == DOUBLE ) 113917749Sralph t = DOUBLE; 114017749Sralph else if( t1 == FLOAT || t2 == FLOAT ) 114117749Sralph t = FLOAT; 114217749Sralph #else 114317749Sralph if (t1 == DOUBLE || t1 == FLOAT || t2 == DOUBLE || t2 == FLOAT) 114417749Sralph t = DOUBLE; 114517749Sralph #endif 114616179Sralph else if( t1==LONG || t2==LONG ) t = LONG; 114716179Sralph else t = INT; 114816179Sralph 114925750Sdonn if( o == ASSIGN || o == CAST || o == RETURN ){ 115016179Sralph tu = p->in.left->in.type; 115116179Sralph t = t1; 115216179Sralph } 115316179Sralph else { 115416179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; 115516179Sralph } 115616179Sralph 115716179Sralph /* because expressions have values that are at least as wide 115816179Sralph as INT or UNSIGNED, the only conversions needed 115916179Sralph are those involving FLOAT/DOUBLE, and those 116016179Sralph from LONG to INT and ULONG to UNSIGNED */ 116116179Sralph 116225750Sdonn if( t != t1 && ! asgop(o) ) 116325750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu ); 116416179Sralph 116532840Sdonn if( t != t2 || o==CAST) 116632840Sdonn if ( tu == ENUMTY ) {/* always asgop */ 116732840Sdonn p->in.right = makety( p->in.right, INT, 0, INT ); 116832840Sdonn p->in.right->in.type = tu; 116932840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim; 117032840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz; 117132840Sdonn } 117232840Sdonn else 117332840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu ); 117416179Sralph 117516179Sralph if( asgop(o) ){ 117616179Sralph p->in.type = p->in.left->in.type; 117716179Sralph p->fn.cdim = p->in.left->fn.cdim; 117816179Sralph p->fn.csiz = p->in.left->fn.csiz; 117916179Sralph } 118016179Sralph else if( !logop(o) ){ 118116179Sralph p->in.type = tu; 118216179Sralph p->fn.cdim = 0; 118316179Sralph p->fn.csiz = t; 118416179Sralph } 118516179Sralph 118616179Sralph # ifndef BUG1 118716179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); 118816179Sralph # endif 118916179Sralph 119016179Sralph return(p); 119116179Sralph } 119216179Sralph 119316179Sralph NODE * 119416179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; { 119516179Sralph /* make p into type t by inserting a conversion */ 119616179Sralph 119716179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); 119816179Sralph if( t == p->in.type ){ 119916179Sralph p->fn.cdim = d; 120016179Sralph p->fn.csiz = s; 120116179Sralph return( p ); 120216179Sralph } 120316179Sralph 120416179Sralph if( t & TMASK ){ 120516179Sralph /* non-simple type */ 120617228Sralph return( block( PCONV, p, NIL, t, d, s ) ); 120716179Sralph } 120816179Sralph 120916179Sralph if( p->in.op == ICON ){ 121017749Sralph if (t == DOUBLE) { 121117749Sralph p->in.op = DCON; 121217749Sralph if (ISUNSIGNED(p->in.type)) 1213*32847Sdonn p->dpn.dval = (unsigned CONSZ) p->tn.lval; 121417749Sralph else 121517749Sralph p->dpn.dval = p->tn.lval; 121617749Sralph p->in.type = p->fn.csiz = t; 121717749Sralph return (clocal(p)); 121817749Sralph } 121917749Sralph if (t == FLOAT) { 122016179Sralph p->in.op = FCON; 122116179Sralph if( ISUNSIGNED(p->in.type) ){ 1222*32847Sdonn p->fpn.fval = (unsigned CONSZ) p->tn.lval; 122316179Sralph } 122416179Sralph else { 122517749Sralph p->fpn.fval = p->tn.lval; 122616179Sralph } 122716179Sralph 122816179Sralph p->in.type = p->fn.csiz = t; 122916179Sralph return( clocal(p) ); 123016179Sralph } 123116179Sralph } 123217749Sralph else if (p->in.op == FCON && t == DOUBLE) { 123317749Sralph double db; 123416179Sralph 123517749Sralph p->in.op = DCON; 123617749Sralph db = p->fpn.fval; 123717749Sralph p->dpn.dval = db; 123817749Sralph p->in.type = p->fn.csiz = t; 123917749Sralph return (clocal(p)); 124017749Sralph } else if (p->in.op == DCON && t == FLOAT) { 124117749Sralph float fl; 124217749Sralph 124317749Sralph p->in.op = FCON; 124417749Sralph fl = p->dpn.dval; 124517749Sralph #ifdef notdef 124617749Sralph if (fl != p->dpn.dval) 124717749Sralph werror("float conversion loses precision"); 124817749Sralph #endif 124917749Sralph p->fpn.fval = fl; 125017749Sralph p->in.type = p->fn.csiz = t; 125117749Sralph return (clocal(p)); 125217749Sralph } 125317749Sralph 125417049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) ); 125516179Sralph 125616179Sralph } 125716179Sralph 125816179Sralph NODE * 125916179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { 126016179Sralph 126116179Sralph register NODE *p; 126216179Sralph 126316179Sralph p = talloc(); 126416179Sralph p->in.op = o; 126516179Sralph p->in.left = l; 126616179Sralph p->in.right = r; 126716179Sralph p->in.type = t; 126816179Sralph p->fn.cdim = d; 126916179Sralph p->fn.csiz = s; 127016179Sralph return(p); 127116179Sralph } 127216179Sralph 127316179Sralph icons(p) register NODE *p; { 127416179Sralph /* if p is an integer constant, return its value */ 127516179Sralph int val; 127616179Sralph 127716179Sralph if( p->in.op != ICON ){ 127816179Sralph uerror( "constant expected"); 127916179Sralph val = 1; 128016179Sralph } 128116179Sralph else { 128216179Sralph val = p->tn.lval; 128316179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); 128416179Sralph } 128516179Sralph tfree( p ); 128616179Sralph return(val); 128716179Sralph } 128816179Sralph 128916179Sralph /* the intent of this table is to examine the 129016179Sralph operators, and to check them for 129116179Sralph correctness. 129216179Sralph 129316179Sralph The table is searched for the op and the 129416179Sralph modified type (where this is one of the 129516179Sralph types INT (includes char and short), LONG, 129616179Sralph DOUBLE (includes FLOAT), and POINTER 129716179Sralph 129816179Sralph The default action is to make the node type integer 129916179Sralph 130016179Sralph The actions taken include: 130116179Sralph PUN check for puns 130216179Sralph CVTL convert the left operand 130316179Sralph CVTR convert the right operand 130416179Sralph TYPL the type is determined by the left operand 130516179Sralph TYPR the type is determined by the right operand 130616179Sralph TYMATCH force type of left and right to match, by inserting conversions 130716179Sralph PTMATCH like TYMATCH, but for pointers 130816179Sralph LVAL left operand must be lval 130916179Sralph CVTO convert the op 131016179Sralph NCVT do not convert the operands 131116179Sralph OTHER handled by code 131216179Sralph NCVTR convert the left operand, not the right... 131316179Sralph 131416179Sralph */ 131516179Sralph 131616179Sralph # define MINT 01 /* integer */ 131716179Sralph # define MDBI 02 /* integer or double */ 131816179Sralph # define MSTR 04 /* structure */ 131916179Sralph # define MPTR 010 /* pointer */ 132016179Sralph # define MPTI 020 /* pointer or integer */ 132116179Sralph # define MENU 040 /* enumeration variable or member */ 132224408Smckusick # define MVOID 0100000 /* void type */ 132316179Sralph 132416179Sralph opact( p ) NODE *p; { 132516179Sralph 132616179Sralph register mt12, mt1, mt2, o; 132716179Sralph 132824408Smckusick mt1 = mt2 = mt12 = 0; 132916179Sralph 133016179Sralph switch( optype(o=p->in.op) ){ 133116179Sralph 133216179Sralph case BITYPE: 133324408Smckusick mt2 = moditype( p->in.right->in.type ); 133416179Sralph case UTYPE: 133524408Smckusick mt1 = moditype( p->in.left->in.type ); 133624408Smckusick break; 133716179Sralph 133816179Sralph } 133916179Sralph 134024408Smckusick if( ((mt1 | mt2) & MVOID) && 134124408Smckusick o != COMOP && 134232845Sdonn o != COLON && 134332845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) && 134424408Smckusick !(o == CAST && (mt1 & MVOID)) ){ 134524408Smckusick /* if lhs of RETURN is void, grammar will complain */ 134624408Smckusick if( o != RETURN ) 134724408Smckusick uerror( "value of void expression used" ); 134824408Smckusick return( NCVT ); 134924408Smckusick } 135024408Smckusick mt12 = mt1 & mt2; 135124408Smckusick 135216179Sralph switch( o ){ 135316179Sralph 135416179Sralph case NAME : 135516179Sralph case STRING : 135616179Sralph case ICON : 135716179Sralph case FCON : 135817749Sralph case DCON : 135916179Sralph case CALL : 136016179Sralph case UNARY CALL: 136116179Sralph case UNARY MUL: 136216179Sralph { return( OTHER ); } 136316179Sralph case UNARY MINUS: 136432844Sdonn if( mt1 & MENU ) return( 0 ); 136516179Sralph if( mt1 & MDBI ) return( TYPL ); 136616179Sralph break; 136716179Sralph 136816179Sralph case COMPL: 136932844Sdonn if( mt1 & MENU ) return( 0 ); 137016179Sralph if( mt1 & MINT ) return( TYPL ); 137116179Sralph break; 137216179Sralph 137316179Sralph case UNARY AND: 137416179Sralph { return( NCVT+OTHER ); } 137516179Sralph case INIT: 137616179Sralph case CM: 137716180Sralph return( 0 ); 137816180Sralph 137916179Sralph case NOT: 138016179Sralph case CBRANCH: 138116180Sralph if( mt1 & MSTR ) break; 138216180Sralph return( 0 ); 138316180Sralph 138416179Sralph case ANDAND: 138516179Sralph case OROR: 138616180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break; 138716179Sralph return( 0 ); 138816179Sralph 138916179Sralph case MUL: 139016179Sralph case DIV: 139116179Sralph if( mt12 & MDBI ) return( TYMATCH ); 139216179Sralph break; 139316179Sralph 139416179Sralph case MOD: 139516179Sralph case AND: 139616179Sralph case OR: 139716179Sralph case ER: 139816179Sralph if( mt12 & MINT ) return( TYMATCH ); 139916179Sralph break; 140016179Sralph 140116179Sralph case LS: 140216179Sralph case RS: 140316179Sralph if( mt12 & MINT ) return( TYMATCH+OTHER ); 140416179Sralph break; 140516179Sralph 140616179Sralph case EQ: 140716179Sralph case NE: 140816179Sralph case LT: 140916179Sralph case LE: 141016179Sralph case GT: 141116179Sralph case GE: 141232844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN ); 141332844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO ); 141416179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN ); 141516179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN ); 141616179Sralph else break; 141716179Sralph 141816179Sralph case QUEST: 141916179Sralph case COMOP: 142016179Sralph if( mt2&MENU ) return( TYPR+NCVTR ); 142116179Sralph return( TYPR ); 142216179Sralph 142316179Sralph case STREF: 142416179Sralph return( NCVTR+OTHER ); 142516179Sralph 142616179Sralph case FORCE: 142716179Sralph return( TYPL ); 142816179Sralph 142916179Sralph case COLON: 143032844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH ); 143132844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH ); 143216179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 143316179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 143416179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 143516179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 143632845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL ); 143716179Sralph break; 143816179Sralph 143916179Sralph case ASSIGN: 144016179Sralph case RETURN: 144116179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 144232844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN ); 144316179Sralph case CAST: 144432846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH); 144532844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH ); 144632846Sdonn else if( mt2 == MVOID && 144718436Smckusick ( p->in.right->in.op == CALL || 144818436Smckusick p->in.right->in.op == UNARY CALL)) break; 144916179Sralph else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN ); 145016179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 145116179Sralph break; 145216179Sralph 145316179Sralph case ASG LS: 145416179Sralph case ASG RS: 145516179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 145616179Sralph break; 145716179Sralph 145816179Sralph case ASG MUL: 145916179Sralph case ASG DIV: 146016179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH ); 146116179Sralph break; 146216179Sralph 146316179Sralph case ASG MOD: 146416179Sralph case ASG AND: 146516179Sralph case ASG OR: 146616179Sralph case ASG ER: 146716179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH ); 146816179Sralph break; 146916179Sralph 147016179Sralph case ASG PLUS: 147116179Sralph case ASG MINUS: 147216179Sralph case INCR: 147316179Sralph case DECR: 147416179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL ); 147516179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); 147616179Sralph break; 147716179Sralph 147816179Sralph case MINUS: 147916179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); 148016179Sralph if( mt2 & MPTR ) break; 148116179Sralph case PLUS: 148216179Sralph if( mt12 & MDBI ) return( TYMATCH ); 148316179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); 148416179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); 148516179Sralph 148616179Sralph } 148724408Smckusick if( mt12 == MSTR ) 148824408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] ); 148924408Smckusick else 149024408Smckusick uerror( "operands of %s have incompatible types", opst[o] ); 149116179Sralph return( NCVT ); 149216179Sralph } 149316179Sralph 149416179Sralph moditype( ty ) TWORD ty; { 149516179Sralph 149616179Sralph switch( ty ){ 149716179Sralph 149816179Sralph case TVOID: 149917206Sralph return( MPTR ); 150016179Sralph case UNDEF: 150124408Smckusick return( MVOID ); 150216179Sralph case ENUMTY: 150316179Sralph case MOETY: 150432840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */ 150516179Sralph 150616179Sralph case STRTY: 150716179Sralph case UNIONTY: 150816179Sralph return( MSTR ); 150916179Sralph 151016179Sralph case CHAR: 151116179Sralph case SHORT: 151216179Sralph case UCHAR: 151316179Sralph case USHORT: 151416179Sralph return( MINT|MPTI|MDBI ); 151516179Sralph case UNSIGNED: 151616179Sralph case ULONG: 151716179Sralph case INT: 151816179Sralph case LONG: 151916179Sralph return( MINT|MDBI|MPTI ); 152016179Sralph case FLOAT: 152116179Sralph case DOUBLE: 152216179Sralph return( MDBI ); 152316179Sralph default: 152416179Sralph return( MPTR|MPTI ); 152516179Sralph 152616179Sralph } 152716179Sralph } 152816179Sralph 152916179Sralph NODE * 153016179Sralph doszof( p ) register NODE *p; { 153116179Sralph /* do sizeof p */ 153216179Sralph int i; 153316179Sralph 153416179Sralph /* whatever is the meaning of this if it is a bitfield? */ 153516179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; 153616179Sralph 153716179Sralph tfree(p); 153816179Sralph if( i <= 0 ) werror( "sizeof returns 0" ); 153916179Sralph return( bcon( i ) ); 154016179Sralph } 154116179Sralph 154216179Sralph # ifndef BUG2 154316179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; { 154416179Sralph register ty; 154516179Sralph 154616179Sralph *a = *b = down+1; 154716179Sralph while( down > 1 ){ 154816179Sralph printf( "\t" ); 154916179Sralph down -= 2; 155016179Sralph } 155116179Sralph if( down ) printf( " " ); 155216179Sralph 155316179Sralph ty = optype( p->in.op ); 155416179Sralph 155516179Sralph printf("%o) %s, ", p, opst[p->in.op] ); 155616179Sralph if( ty == LTYPE ){ 155716179Sralph printf( CONFMT, p->tn.lval ); 155816179Sralph printf( ", %d, ", p->tn.rval ); 155916179Sralph } 156016179Sralph tprint( p->in.type ); 156116179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); 156216179Sralph } 156316179Sralph # endif 156416179Sralph 156516179Sralph prtdcon( p ) register NODE *p; { 156617749Sralph int o = p->in.op, i; 156716179Sralph 156817749Sralph if( o == DCON || o == FCON ){ 156916179Sralph locctr( DATA ); 157017749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT ); 157116179Sralph deflab( i = getlab() ); 157217749Sralph if( o == FCON ) 157317749Sralph fincode( p->fpn.fval, SZFLOAT ); 157417749Sralph else 157517749Sralph fincode( p->dpn.dval, SZDOUBLE ); 157616179Sralph p->tn.lval = 0; 157716179Sralph p->tn.rval = -i; 157817749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT); 157916179Sralph p->in.op = NAME; 158016179Sralph } 158116179Sralph } 158216179Sralph 158316179Sralph 158416179Sralph int edebug = 0; 158516179Sralph ecomp( p ) register NODE *p; { 158616179Sralph # ifndef BUG2 158716179Sralph if( edebug ) fwalk( p, eprint, 0 ); 158816179Sralph # endif 158916179Sralph if( !reached ){ 159016179Sralph werror( "statement not reached" ); 159116179Sralph reached = 1; 159216179Sralph } 159316179Sralph p = optim(p); 159416179Sralph walkf( p, prtdcon ); 159516179Sralph locctr( PROG ); 159616179Sralph ecode( p ); 159716179Sralph tfree(p); 159816179Sralph } 159916179Sralph 160016179Sralph # ifdef STDPRTREE 160116179Sralph # ifndef ONEPASS 160216179Sralph 160316179Sralph prtree(p) register NODE *p; { 160416179Sralph 160516179Sralph register struct symtab *q; 160616179Sralph register ty; 160716179Sralph 160816179Sralph # ifdef MYPRTREE 160916179Sralph MYPRTREE(p); /* local action can be taken here; then return... */ 161016179Sralph #endif 161116179Sralph 161216179Sralph ty = optype(p->in.op); 161316179Sralph 161416179Sralph printf( "%d\t", p->in.op ); 161516179Sralph 161616179Sralph if( ty == LTYPE ) { 161716179Sralph printf( CONFMT, p->tn.lval ); 161816179Sralph printf( "\t" ); 161916179Sralph } 162016179Sralph if( ty != BITYPE ) { 162116179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); 162216179Sralph else printf( "%d\t", p->tn.rval ); 162316179Sralph } 162416179Sralph 162516179Sralph printf( "%o\t", p->in.type ); 162616179Sralph 162716179Sralph /* handle special cases */ 162816179Sralph 162916179Sralph switch( p->in.op ){ 163016179Sralph 163116179Sralph case NAME: 163216179Sralph case ICON: 163316179Sralph /* print external name */ 163416179Sralph if( p->tn.rval == NONAME ) printf( "\n" ); 163516179Sralph else if( p->tn.rval >= 0 ){ 163616179Sralph q = &stab[p->tn.rval]; 163716179Sralph printf( "%s\n", exname(q->sname) ); 163816179Sralph } 163916179Sralph else { /* label */ 164016179Sralph printf( LABFMT, -p->tn.rval ); 164116179Sralph } 164216179Sralph break; 164316179Sralph 164416179Sralph case STARG: 164516179Sralph case STASG: 164616179Sralph case STCALL: 164716179Sralph case UNARY STCALL: 164816179Sralph /* print out size */ 164916179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */ 165016179Sralph 165116179Sralph /* note: p->in.left not a field... */ 165216179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); 165316179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); 165416179Sralph break; 165516179Sralph 165616179Sralph default: 165716179Sralph printf( "\n" ); 165816179Sralph } 165916179Sralph 166016179Sralph if( ty != LTYPE ) prtree( p->in.left ); 166116179Sralph if( ty == BITYPE ) prtree( p->in.right ); 166216179Sralph 166316179Sralph } 166416179Sralph 166516179Sralph # else 166616179Sralph 166716179Sralph p2tree(p) register NODE *p; { 166816179Sralph register ty; 166916179Sralph 167016179Sralph # ifdef MYP2TREE 167116179Sralph MYP2TREE(p); /* local action can be taken here; then return... */ 167216179Sralph # endif 167316179Sralph 167416179Sralph ty = optype(p->in.op); 167516179Sralph 167616179Sralph switch( p->in.op ){ 167716179Sralph 167816179Sralph case NAME: 167916179Sralph case ICON: 168016179Sralph #ifndef FLEXNAMES 168116179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; 168216179Sralph #else 168316179Sralph if( p->tn.rval == NONAME ) p->in.name = ""; 168416179Sralph #endif 168516179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */ 168616179Sralph register char *cp; 168716179Sralph register i; 168816179Sralph cp = exname( stab[p->tn.rval].sname ); 168916179Sralph #ifndef FLEXNAMES 169016179Sralph for( i=0; i<NCHNAM; ++i ) p->in.name[i] = *cp++; 169116179Sralph #else 169216179Sralph p->in.name = tstr(cp); 169316179Sralph #endif 169416179Sralph } 169516179Sralph #ifndef FLEXNAMES 169616179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval ); 169716179Sralph #else 169816179Sralph else { 169916179Sralph char temp[32]; 170016179Sralph sprintf( temp, LABFMT, -p->tn.rval ); 170116179Sralph p->in.name = tstr(temp); 170216179Sralph } 170316179Sralph #endif 170416179Sralph break; 170516179Sralph 170616179Sralph case STARG: 170716179Sralph case STASG: 170816179Sralph case STCALL: 170916179Sralph case UNARY STCALL: 171016179Sralph /* set up size parameters */ 171116179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; 171216179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; 171316179Sralph break; 171416179Sralph 171516179Sralph case REG: 171616179Sralph rbusy( p->tn.rval, p->in.type ); 171716179Sralph default: 171816179Sralph #ifndef FLEXNAMES 171916179Sralph p->in.name[0] = '\0'; 172016179Sralph #else 172116179Sralph p->in.name = ""; 172216179Sralph #endif 172316179Sralph } 172416179Sralph 172516179Sralph p->in.rall = NOPREF; 172616179Sralph 172716179Sralph if( ty != LTYPE ) p2tree( p->in.left ); 172816179Sralph if( ty == BITYPE ) p2tree( p->in.right ); 172916179Sralph } 173016179Sralph 173116179Sralph # endif 173216179Sralph # endif 1733