117749Sralph #ifndef lint
2*43235Sbostic static char *sccsid ="@(#)trees.c 4.37 (Berkeley) 06/18/90";
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
printact(t,acts)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 *
buildtree(o,l,r)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
11434253Sdonn else if( opty == UTYPE && (l->in.op == FCON || l->in.op == DCON) ){
11516179Sralph
11634253Sdonn switch( o ){
11734253Sdonn
11834253Sdonn case NOT:
11934253Sdonn if( hflag ) werror( "constant argument to NOT" );
12034253Sdonn if( l->in.op == FCON )
12134253Sdonn l->tn.lval = l->fpn.fval == 0.0;
12234253Sdonn else
12334253Sdonn l->tn.lval = l->dpn.dval == 0.0;
12434253Sdonn l->tn.rval = NONAME;
12534253Sdonn l->in.op = ICON;
12634253Sdonn l->fn.csiz = l->in.type = INT;
12734253Sdonn l->fn.cdim = 0;
12834253Sdonn return(l);
12934253Sdonn case UNARY MINUS:
13034253Sdonn if( l->in.op == FCON )
13134253Sdonn l->fpn.fval = -l->fpn.fval;
13234253Sdonn else
13334253Sdonn l->dpn.dval = -l->dpn.dval;
13434253Sdonn return(l);
13534253Sdonn }
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 */
31234253Sdonn p->in.type = p->fn.csiz = INT;
31334253Sdonn 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:
50234253Sdonn if( l->in.type == CHAR || l->in.type == SHORT )
50334253Sdonn p->in.type = INT;
50434253Sdonn else if( l->in.type == UCHAR || l->in.type == USHORT )
50534253Sdonn p->in.type = UNSIGNED;
50634253Sdonn else
50734253Sdonn p->in.type = l->in.type;
50816179Sralph case ASG LS:
50916179Sralph case ASG RS:
51034253Sdonn if( r->in.type != INT )
51134253Sdonn 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
597*43235Sbostic void
fpe()59824408Smckusick fpe() {
59924408Smckusick if (fpe_count < 0)
60024408Smckusick cerror("floating point exception");
60124408Smckusick ++fpe_count;
60224408Smckusick longjmp(gotfpe, 1);
60324408Smckusick }
60424408Smckusick
60517749Sralph /*
60617749Sralph * Rewrite arguments in a function call.
60717749Sralph * Structure arguments are massaged, single
60817749Sralph * precision floating point constants are
60917749Sralph * cast to double (to eliminate convert code).
61017749Sralph */
61116179Sralph NODE *
fixargs(p)61217749Sralph fixargs( p ) register NODE *p; {
61317749Sralph int o = p->in.op;
61416179Sralph
61517749Sralph if( o == CM ){
61617749Sralph p->in.left = fixargs( p->in.left );
61717749Sralph p->in.right = fixargs( p->in.right );
61816179Sralph return( p );
61916179Sralph }
62016179Sralph
62116179Sralph if( p->in.type == STRTY || p->in.type == UNIONTY ){
62216179Sralph p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz );
62316179Sralph p->in.left = buildtree( UNARY AND, p->in.left, NIL );
62416179Sralph p = clocal(p);
62516179Sralph }
62617749Sralph else if( o == FCON )
62717749Sralph p = makety(p, DOUBLE, 0, 0);
62816179Sralph return( p );
62916179Sralph }
63016179Sralph
chkstr(i,j,type)63116179Sralph chkstr( i, j, type ) TWORD type; {
63216179Sralph /* is the MOS or MOU at stab[i] OK for strict reference by a ptr */
63316179Sralph /* i has been checked to contain a MOS or MOU */
63416179Sralph /* j is the index in dimtab of the members... */
63516179Sralph int k, kk;
63616179Sralph
63716179Sralph extern int ddebug;
63816179Sralph
63916179Sralph # ifndef BUG1
64016179Sralph #ifndef FLEXNAMES
64116179Sralph if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j );
64216179Sralph #else
64316179Sralph if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j );
64416179Sralph #endif
64516179Sralph # endif
64616179Sralph if( (k = j) < 0 ) uerror( "undefined structure or union" );
64716179Sralph else {
64816179Sralph for( ; (kk = dimtab[k] ) >= 0; ++k ){
64916179Sralph if( kk >= SYMTSZ ){
65016179Sralph cerror( "gummy structure" );
65116179Sralph return(1);
65216179Sralph }
65316179Sralph if( kk == i ) return( 1 );
65416179Sralph switch( stab[kk].stype ){
65516179Sralph
65616179Sralph case STRTY:
65716179Sralph case UNIONTY:
65816179Sralph if( type == STRTY ) continue; /* no recursive looking for strs */
65916179Sralph if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){
66016179Sralph if( stab[kk].sname[0] == '$' ) return(0); /* $FAKE */
66116179Sralph werror(
66216179Sralph #ifndef FLEXNAMES
66316179Sralph "illegal member use: perhaps %.8s.%.8s?",
66416179Sralph #else
66516179Sralph "illegal member use: perhaps %s.%s?",
66616179Sralph #endif
66716179Sralph stab[kk].sname, stab[i].sname );
66816179Sralph return(1);
66916179Sralph }
67016179Sralph }
67116179Sralph }
67216179Sralph }
67316179Sralph return( 0 );
67416179Sralph }
67516179Sralph
conval(p,o,q)67616179Sralph conval( p, o, q ) register NODE *p, *q; {
67716179Sralph /* apply the op o to the lval part of p; if binary, rhs is val */
67832842Sdonn /* works only on integer constants */
67932842Sdonn NODE *r;
68016179Sralph int i, u;
68116179Sralph CONSZ val;
68232857Sdonn TWORD utype;
68316179Sralph
68416179Sralph val = q->tn.lval;
68516179Sralph u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type);
68616179Sralph if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
68716179Sralph
68816179Sralph if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0);
68916179Sralph if( q->tn.rval != NONAME && o!=PLUS ) return(0);
69016179Sralph if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0);
69116179Sralph
69232857Sdonn /* usual type conversions -- handle casts of constants */
69332859Sdonn #define ISLONG(t) ((t) == LONG || (t) == ULONG)
69432859Sdonn if (ISLONG(p->in.type) || ISLONG(q->in.type))
69532859Sdonn utype = u ? ULONG : LONG;
69632859Sdonn else
69732859Sdonn utype = u ? UNSIGNED : INT;
69832857Sdonn if( !ISPTR(p->in.type) && p->in.type != utype )
69932857Sdonn p = makety(p, utype, 0, (int)utype);
70032857Sdonn if( q->in.type != utype )
70132857Sdonn q = makety(q, utype, 0, (int)utype);
70232842Sdonn
70316179Sralph switch( o ){
70416179Sralph
70516179Sralph case PLUS:
70616179Sralph p->tn.lval += val;
70716179Sralph if( p->tn.rval == NONAME ){
70816179Sralph p->tn.rval = q->tn.rval;
70916179Sralph p->in.type = q->in.type;
71016179Sralph }
71116179Sralph break;
71216179Sralph case MINUS:
71316179Sralph p->tn.lval -= val;
71416179Sralph break;
71516179Sralph case MUL:
71632840Sdonn p->tn.lval *= val;
71716179Sralph break;
71816179Sralph case DIV:
71916179Sralph if( val == 0 ) uerror( "division by 0" );
72017749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval / val;
72116179Sralph else p->tn.lval /= val;
72216179Sralph break;
72316179Sralph case MOD:
72416179Sralph if( val == 0 ) uerror( "division by 0" );
72517749Sralph else if ( u ) p->tn.lval = (unsigned) p->tn.lval % val;
72616179Sralph else p->tn.lval %= val;
72716179Sralph break;
72816179Sralph case AND:
72916179Sralph p->tn.lval &= val;
73016179Sralph break;
73116179Sralph case OR:
73216179Sralph p->tn.lval |= val;
73316179Sralph break;
73416179Sralph case ER:
73517749Sralph p->tn.lval ^= val;
73616179Sralph break;
73716179Sralph case LS:
73816179Sralph i = val;
73916179Sralph p->tn.lval = p->tn.lval << i;
74016179Sralph break;
74116179Sralph case RS:
74216179Sralph i = val;
74317749Sralph if ( u ) p->tn.lval = (unsigned) p->tn.lval >> i;
74417749Sralph else p->tn.lval = p->tn.lval >> i;
74516179Sralph break;
74616179Sralph
74716179Sralph case UNARY MINUS:
74816179Sralph p->tn.lval = - p->tn.lval;
74916179Sralph break;
75016179Sralph case COMPL:
75116179Sralph p->tn.lval = ~p->tn.lval;
75216179Sralph break;
75316179Sralph case NOT:
75416179Sralph p->tn.lval = !p->tn.lval;
75516179Sralph break;
75616179Sralph case LT:
75716179Sralph p->tn.lval = p->tn.lval < val;
75816179Sralph break;
75916179Sralph case LE:
76016179Sralph p->tn.lval = p->tn.lval <= val;
76116179Sralph break;
76216179Sralph case GT:
76316179Sralph p->tn.lval = p->tn.lval > val;
76416179Sralph break;
76516179Sralph case GE:
76616179Sralph p->tn.lval = p->tn.lval >= val;
76716179Sralph break;
76816179Sralph case ULT:
76932848Sdonn p->tn.lval = p->tn.lval < (unsigned) val;
77016179Sralph break;
77116179Sralph case ULE:
77232848Sdonn p->tn.lval = p->tn.lval <= (unsigned) val;
77316179Sralph break;
77432848Sdonn case UGT:
77532848Sdonn p->tn.lval = p->tn.lval > (unsigned) val;
77632848Sdonn break;
77732840Sdonn case UGE:
77832848Sdonn p->tn.lval = p->tn.lval >= (unsigned) val;
77932840Sdonn break;
78016179Sralph case EQ:
78116179Sralph p->tn.lval = p->tn.lval == val;
78216179Sralph break;
78316179Sralph case NE:
78416179Sralph p->tn.lval = p->tn.lval != val;
78516179Sralph break;
78616179Sralph default:
78716179Sralph return(0);
78816179Sralph }
78916179Sralph return(1);
79016179Sralph }
79116179Sralph
chkpun(p)79216179Sralph chkpun(p) register NODE *p; {
79316179Sralph
79416179Sralph /* checks p for the existance of a pun */
79516179Sralph
79616179Sralph /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */
79716179Sralph
79816179Sralph /* one case is when enumerations are used: this applies only to lint */
79916179Sralph /* in the other case, one operand is a pointer, the other integer type */
80016179Sralph /* we check that this integer is in fact a constant zero... */
80116179Sralph
80216179Sralph /* in the case of ASSIGN, any assignment of pointer to integer is illegal */
80316179Sralph /* this falls out, because the LHS is never 0 */
80416179Sralph
80516179Sralph register NODE *q;
80616179Sralph register t1, t2;
80716179Sralph register d1, d2;
80832844Sdonn int ref1, ref2;
80916179Sralph
81016179Sralph t1 = p->in.left->in.type;
81116179Sralph t2 = p->in.right->in.type;
81216179Sralph
81316179Sralph if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */
81432841Sdonn /* rob pike says this is obnoxious...
81532840Sdonn if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE )
81632841Sdonn werror( "comparison of enums" ); */
81732841Sdonn if( t1==ENUMTY && t2==ENUMTY ) {
81832841Sdonn if ( p->in.left->fn.csiz!=p->in.right->fn.csiz )
81932841Sdonn werror( "enumeration type clash, operator %s", opst[p->in.op] );
82032841Sdonn return;
82132841Sdonn }
82232841Sdonn if ( t1 == ENUMTY ) t1 = INT;
82332841Sdonn if ( t2 == ENUMTY ) t2 = INT;
82416179Sralph }
82516179Sralph
82632844Sdonn ref1 = ISPTR(t1) || ISARY(t1);
82732844Sdonn ref2 = ISPTR(t2) || ISARY(t2);
82816179Sralph
82932844Sdonn if( ref1 ^ ref2 ){
83032844Sdonn if( ref1 ) q = p->in.right;
83132844Sdonn else q = p->in.left;
83216179Sralph if( q->in.op != ICON || q->tn.lval != 0 ){
83316179Sralph werror( "illegal combination of pointer and integer, op %s",
83416179Sralph opst[p->in.op] );
83516179Sralph }
83616179Sralph }
83732844Sdonn else if( ref1 ){
83832843Sdonn if( t1 == t2 ) {
83932843Sdonn if( p->in.left->fn.csiz != p->in.right->fn.csiz ) {
84032843Sdonn werror( "illegal structure pointer combination" );
84116179Sralph return;
84216179Sralph }
84332843Sdonn d1 = p->in.left->fn.cdim;
84432843Sdonn d2 = p->in.right->fn.cdim;
84532843Sdonn for( ;; ){
84632843Sdonn if( ISARY(t1) ){
84732843Sdonn if( dimtab[d1] != dimtab[d2] ){
84832843Sdonn werror( "illegal array size combination" );
84932843Sdonn return;
85032843Sdonn }
85132843Sdonn ++d1;
85232843Sdonn ++d2;
85316179Sralph }
85432843Sdonn else if( !ISPTR(t1) ) break;
85532843Sdonn t1 = DECREF(t1);
85616179Sralph }
85716179Sralph }
85834253Sdonn else if( t1 != INCREF(UNDEF) && t2 != INCREF(UNDEF) )
85932843Sdonn werror( "illegal pointer combination" );
86016179Sralph }
86116179Sralph
86216179Sralph }
86316179Sralph
86416179Sralph NODE *
stref(p)86516179Sralph stref( p ) register NODE *p; {
86616179Sralph
86716179Sralph TWORD t;
86816179Sralph int d, s, dsc, align;
86916179Sralph OFFSZ off;
87016179Sralph register struct symtab *q;
87116179Sralph
87216179Sralph /* make p->x */
87316179Sralph /* this is also used to reference automatic variables */
87416179Sralph
87516179Sralph q = &stab[p->in.right->tn.rval];
87616179Sralph p->in.right->in.op = FREE;
87716179Sralph p->in.op = FREE;
87816179Sralph p = pconvert( p->in.left );
87916179Sralph
88016179Sralph /* make p look like ptr to x */
88116179Sralph
88216179Sralph if( !ISPTR(p->in.type)){
88316179Sralph p->in.type = PTR+UNIONTY;
88416179Sralph }
88516179Sralph
88616179Sralph t = INCREF( q->stype );
88716179Sralph d = q->dimoff;
88816179Sralph s = q->sizoff;
88916179Sralph
89016179Sralph p = makety( p, t, d, s );
89116179Sralph
89216179Sralph /* compute the offset to be added */
89316179Sralph
89416179Sralph off = q->offset;
89516179Sralph dsc = q->sclass;
89616179Sralph
89716179Sralph if( dsc & FIELD ) { /* normalize offset */
89816179Sralph align = ALINT;
89916179Sralph s = INT;
90016179Sralph off = (off/align)*align;
90116179Sralph }
90216179Sralph if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) );
90316179Sralph
90416179Sralph p = buildtree( UNARY MUL, p, NIL );
90516179Sralph
90616179Sralph /* if field, build field info */
90716179Sralph
90816179Sralph if( dsc & FIELD ){
90916179Sralph p = block( FLD, p, NIL, q->stype, 0, q->sizoff );
91016179Sralph p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align );
91116179Sralph }
91216179Sralph
91316179Sralph return( clocal(p) );
91416179Sralph }
91516179Sralph
notlval(p)91616179Sralph notlval(p) register NODE *p; {
91716179Sralph
91816179Sralph /* return 0 if p an lvalue, 1 otherwise */
91916179Sralph
92016179Sralph again:
92116179Sralph
92216179Sralph switch( p->in.op ){
92316179Sralph
92416179Sralph case FLD:
92516179Sralph p = p->in.left;
92616179Sralph goto again;
92716179Sralph
92816179Sralph case UNARY MUL:
92916179Sralph /* fix the &(a=b) bug, given that a and b are structures */
93016179Sralph if( p->in.left->in.op == STASG ) return( 1 );
93116179Sralph /* and the f().a bug, given that f returns a structure */
93216179Sralph if( p->in.left->in.op == UNARY STCALL ||
93316179Sralph p->in.left->in.op == STCALL ) return( 1 );
93416179Sralph case NAME:
93516179Sralph case OREG:
93616179Sralph if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1);
93716179Sralph case REG:
93816179Sralph return(0);
93916179Sralph
94016179Sralph default:
94116179Sralph return(1);
94216179Sralph
94316179Sralph }
94416179Sralph
94516179Sralph }
94616179Sralph
94716179Sralph NODE *
bcon(i)94816179Sralph bcon( i ){ /* make a constant node with value i */
94916179Sralph register NODE *p;
95016179Sralph
95116179Sralph p = block( ICON, NIL, NIL, INT, 0, INT );
95216179Sralph p->tn.lval = i;
95316179Sralph p->tn.rval = NONAME;
95416179Sralph return( clocal(p) );
95516179Sralph }
95616179Sralph
95716179Sralph NODE *
bpsize(p)95816179Sralph bpsize(p) register NODE *p; {
95916179Sralph return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) );
96016179Sralph }
96116179Sralph
96216179Sralph OFFSZ
psize(p)96316179Sralph psize( p ) NODE *p; {
96416179Sralph /* p is a node of type pointer; psize returns the
96516179Sralph size of the thing pointed to */
96616179Sralph
96716179Sralph if( !ISPTR(p->in.type) ){
96816179Sralph uerror( "pointer required");
96916179Sralph return( SZINT );
97016179Sralph }
97116179Sralph /* note: no pointers to fields */
97216179Sralph return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) );
97316179Sralph }
97416179Sralph
97516179Sralph NODE *
convert(p,f)97616179Sralph convert( p, f ) register NODE *p; {
97716179Sralph /* convert an operand of p
97816179Sralph f is either CVTL or CVTR
97916179Sralph operand has type int, and is converted by the size of the other side
98016179Sralph */
98116179Sralph
98216179Sralph register NODE *q, *r;
98316179Sralph
98416179Sralph q = (f==CVTL)?p->in.left:p->in.right;
98516179Sralph
98616179Sralph r = block( PMCONV,
98716179Sralph q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT );
98816179Sralph r = clocal(r);
98916179Sralph if( f == CVTL )
99016179Sralph p->in.left = r;
99116179Sralph else
99216179Sralph p->in.right = r;
99316179Sralph return(p);
99416179Sralph
99516179Sralph }
99616179Sralph
99725750Sdonn #ifndef econvert
econvert(p)99816179Sralph econvert( p ) register NODE *p; {
99916179Sralph
100016179Sralph /* change enums to ints, or appropriate types */
100116179Sralph
100216179Sralph register TWORD ty;
100316179Sralph
100416179Sralph if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) {
100516179Sralph if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR;
100616179Sralph else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT;
100716179Sralph else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT;
100816179Sralph else ty = LONG;
100916179Sralph ty = ctype( ty );
101016179Sralph p->fn.csiz = ty;
101116179Sralph MODTYPE(p->in.type,ty);
101216179Sralph if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT;
101316179Sralph }
101416179Sralph }
101525750Sdonn #endif
101616179Sralph
101716179Sralph NODE *
pconvert(p)101816179Sralph pconvert( p ) register NODE *p; {
101916179Sralph
102016179Sralph /* if p should be changed into a pointer, do so */
102116179Sralph
102216179Sralph if( ISARY( p->in.type) ){
102316179Sralph p->in.type = DECREF( p->in.type );
102416179Sralph ++p->fn.cdim;
102516179Sralph return( buildtree( UNARY AND, p, NIL ) );
102616179Sralph }
102716179Sralph if( ISFTN( p->in.type) )
102816179Sralph return( buildtree( UNARY AND, p, NIL ) );
102916179Sralph
103016179Sralph return( p );
103116179Sralph }
103216179Sralph
103316179Sralph NODE *
oconvert(p)103416179Sralph oconvert(p) register NODE *p; {
103516179Sralph /* convert the result itself: used for pointer and unsigned */
103616179Sralph
103716179Sralph switch(p->in.op) {
103816179Sralph
103916179Sralph case LE:
104016179Sralph case LT:
104116179Sralph case GE:
104216179Sralph case GT:
104316179Sralph if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE);
104416179Sralph case EQ:
104516179Sralph case NE:
104616179Sralph return( p );
104716179Sralph
104816179Sralph case MINUS:
104916179Sralph return( clocal( block( PVCONV,
105016179Sralph p, bpsize(p->in.left), INT, 0, INT ) ) );
105116179Sralph }
105216179Sralph
105316179Sralph cerror( "illegal oconvert: %d", p->in.op );
105416179Sralph
105516179Sralph return(p);
105616179Sralph }
105716179Sralph
105816179Sralph NODE *
ptmatch(p)105916179Sralph ptmatch(p) register NODE *p; {
106016179Sralph
106116179Sralph /* makes the operands of p agree; they are
106216179Sralph either pointers or integers, by this time */
106316179Sralph /* with MINUS, the sizes must be the same */
106416179Sralph /* with COLON, the types must be the same */
106516179Sralph
106616179Sralph TWORD t1, t2, t;
106716179Sralph int o, d2, d, s2, s;
106816179Sralph
106916179Sralph o = p->in.op;
107016179Sralph t = t1 = p->in.left->in.type;
107116179Sralph t2 = p->in.right->in.type;
107216179Sralph d = p->in.left->fn.cdim;
107316179Sralph d2 = p->in.right->fn.cdim;
107416179Sralph s = p->in.left->fn.csiz;
107516179Sralph s2 = p->in.right->fn.csiz;
107616179Sralph
107716179Sralph switch( o ){
107816179Sralph
107916179Sralph case ASSIGN:
108016179Sralph case RETURN:
108116179Sralph case CAST:
108216179Sralph { break; }
108316179Sralph
108416179Sralph case MINUS:
108516179Sralph { if( psize(p->in.left) != psize(p->in.right) ){
108616179Sralph uerror( "illegal pointer subtraction");
108716179Sralph }
108816179Sralph break;
108916179Sralph }
109016179Sralph case COLON:
109116179Sralph { if( t1 != t2 ) uerror( "illegal types in :");
109216179Sralph break;
109316179Sralph }
109416179Sralph default: /* must work harder: relationals or comparisons */
109516179Sralph
109616179Sralph if( !ISPTR(t1) ){
109716179Sralph t = t2;
109816179Sralph d = d2;
109916179Sralph s = s2;
110016179Sralph break;
110116179Sralph }
110216179Sralph if( !ISPTR(t2) ){
110316179Sralph break;
110416179Sralph }
110516179Sralph
110616179Sralph /* both are pointers */
110716179Sralph if( talign(t2,s2) < talign(t,s) ){
110816179Sralph t = t2;
110916179Sralph s = s2;
111016179Sralph }
111116179Sralph break;
111216179Sralph }
111316179Sralph
111416179Sralph p->in.left = makety( p->in.left, t, d, s );
111516179Sralph p->in.right = makety( p->in.right, t, d, s );
111616179Sralph if( o!=MINUS && !logop(o) ){
111716179Sralph
111816179Sralph p->in.type = t;
111916179Sralph p->fn.cdim = d;
112016179Sralph p->fn.csiz = s;
112116179Sralph }
112216179Sralph
112316179Sralph return(clocal(p));
112416179Sralph }
112516179Sralph
112616179Sralph int tdebug = 0;
112716179Sralph
112816179Sralph NODE *
tymatch(p)112916179Sralph tymatch(p) register NODE *p; {
113016179Sralph
113116179Sralph /* satisfy the types of various arithmetic binary ops */
113216179Sralph
113316179Sralph /* rules are:
113425750Sdonn if assignment, type of LHS
113516179Sralph if any float or doubles, make double
113616179Sralph if any longs, make long
113716179Sralph otherwise, make int
113816179Sralph if either operand is unsigned, the result is...
113916179Sralph */
114016179Sralph
114116179Sralph register TWORD t1, t2, t, tu;
114216179Sralph register o, u;
114316179Sralph
114416179Sralph o = p->in.op;
114516179Sralph
114616179Sralph t1 = p->in.left->in.type;
114716179Sralph t2 = p->in.right->in.type;
114816179Sralph if( (t1==UNDEF || t2==UNDEF) && o!=CAST )
114916179Sralph uerror("void type illegal in expression");
115016179Sralph
115116179Sralph u = 0;
115216179Sralph if( ISUNSIGNED(t1) ){
115316179Sralph u = 1;
115416179Sralph t1 = DEUNSIGN(t1);
115516179Sralph }
115616179Sralph if( ISUNSIGNED(t2) ){
115716179Sralph u = 1;
115816179Sralph t2 = DEUNSIGN(t2);
115916179Sralph }
116016179Sralph
116116179Sralph if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT;
116216179Sralph if( t2 == CHAR || t2 == SHORT ) t2 = INT;
116316179Sralph
116417749Sralph #ifdef SPRECC
116517749Sralph if( t1 == DOUBLE || t2 == DOUBLE )
116617749Sralph t = DOUBLE;
116717749Sralph else if( t1 == FLOAT || t2 == FLOAT )
116817749Sralph t = FLOAT;
116917749Sralph #else
117017749Sralph if (t1 == DOUBLE || t1 == FLOAT || t2 == DOUBLE || t2 == FLOAT)
117117749Sralph t = DOUBLE;
117217749Sralph #endif
117316179Sralph else if( t1==LONG || t2==LONG ) t = LONG;
117416179Sralph else t = INT;
117516179Sralph
117632853Sdonn if( o == ASSIGN || o == CAST || o == RETURN )
117732853Sdonn {
117816179Sralph tu = p->in.left->in.type;
117916179Sralph t = t1;
118016179Sralph }
118116179Sralph else {
118216179Sralph tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t;
118316179Sralph }
118416179Sralph
118516179Sralph /* because expressions have values that are at least as wide
118616179Sralph as INT or UNSIGNED, the only conversions needed
118716179Sralph are those involving FLOAT/DOUBLE, and those
118816179Sralph from LONG to INT and ULONG to UNSIGNED */
118916179Sralph
119032858Sdonn if( (t != t1 || (u && !ISUNSIGNED(p->in.left->in.type))) && ! asgop(o) )
119125750Sdonn p->in.left = makety( p->in.left, tu, 0, (int)tu );
119216179Sralph
119332858Sdonn if( t != t2 || (u && !ISUNSIGNED(p->in.right->in.type)) || o==CAST)
119432840Sdonn if ( tu == ENUMTY ) {/* always asgop */
119532840Sdonn p->in.right = makety( p->in.right, INT, 0, INT );
119632840Sdonn p->in.right->in.type = tu;
119732840Sdonn p->in.right->fn.cdim = p->in.left->fn.cdim;
119832840Sdonn p->in.right->fn.csiz = p->in.left->fn.csiz;
119932840Sdonn }
120032840Sdonn else
120132840Sdonn p->in.right = makety( p->in.right, tu, 0, (int)tu );
120216179Sralph
120316179Sralph if( asgop(o) ){
120416179Sralph p->in.type = p->in.left->in.type;
120516179Sralph p->fn.cdim = p->in.left->fn.cdim;
120616179Sralph p->fn.csiz = p->in.left->fn.csiz;
120716179Sralph }
120816179Sralph else if( !logop(o) ){
120916179Sralph p->in.type = tu;
121016179Sralph p->fn.cdim = 0;
121116179Sralph p->fn.csiz = t;
121216179Sralph }
121316179Sralph
121416179Sralph # ifndef BUG1
121516179Sralph if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu );
121616179Sralph # endif
121716179Sralph
121816179Sralph return(p);
121916179Sralph }
122016179Sralph
122116179Sralph NODE *
makety(p,t,d,s)122216179Sralph makety( p, t, d, s ) register NODE *p; TWORD t; {
122316179Sralph /* make p into type t by inserting a conversion */
122416179Sralph
122516179Sralph if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p);
122616179Sralph if( t == p->in.type ){
122716179Sralph p->fn.cdim = d;
122816179Sralph p->fn.csiz = s;
122916179Sralph return( p );
123016179Sralph }
123116179Sralph
123216179Sralph if( t & TMASK ){
123316179Sralph /* non-simple type */
123417228Sralph return( block( PCONV, p, NIL, t, d, s ) );
123516179Sralph }
123616179Sralph
123716179Sralph if( p->in.op == ICON ){
123817749Sralph if (t == DOUBLE) {
123917749Sralph p->in.op = DCON;
124017749Sralph if (ISUNSIGNED(p->in.type))
124134092Sbostic p->dpn.dval = (U_CONSZ) p->tn.lval;
124217749Sralph else
124317749Sralph p->dpn.dval = p->tn.lval;
124417749Sralph p->in.type = p->fn.csiz = t;
124517749Sralph return (clocal(p));
124617749Sralph }
124717749Sralph if (t == FLOAT) {
124816179Sralph p->in.op = FCON;
124916179Sralph if( ISUNSIGNED(p->in.type) ){
125034092Sbostic p->fpn.fval = (U_CONSZ) p->tn.lval;
125116179Sralph }
125216179Sralph else {
125317749Sralph p->fpn.fval = p->tn.lval;
125416179Sralph }
125516179Sralph
125616179Sralph p->in.type = p->fn.csiz = t;
125716179Sralph return( clocal(p) );
125816179Sralph }
125916179Sralph }
126017749Sralph else if (p->in.op == FCON && t == DOUBLE) {
126117749Sralph double db;
126216179Sralph
126317749Sralph p->in.op = DCON;
126417749Sralph db = p->fpn.fval;
126517749Sralph p->dpn.dval = db;
126617749Sralph p->in.type = p->fn.csiz = t;
126717749Sralph return (clocal(p));
126817749Sralph } else if (p->in.op == DCON && t == FLOAT) {
126917749Sralph float fl;
127017749Sralph
127117749Sralph p->in.op = FCON;
127217749Sralph fl = p->dpn.dval;
127317749Sralph #ifdef notdef
127417749Sralph if (fl != p->dpn.dval)
127517749Sralph werror("float conversion loses precision");
127617749Sralph #endif
127717749Sralph p->fpn.fval = fl;
127817749Sralph p->in.type = p->fn.csiz = t;
127917749Sralph return (clocal(p));
128017749Sralph }
128117749Sralph
128217049Sralph return( clocal( block( SCONV, p, NIL, t, d, s ) ) );
128316179Sralph
128416179Sralph }
128516179Sralph
128616179Sralph NODE *
block(o,l,r,t,d,s)128716179Sralph block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; {
128816179Sralph
128916179Sralph register NODE *p;
129016179Sralph
129116179Sralph p = talloc();
129216179Sralph p->in.op = o;
129316179Sralph p->in.left = l;
129416179Sralph p->in.right = r;
129516179Sralph p->in.type = t;
129616179Sralph p->fn.cdim = d;
129716179Sralph p->fn.csiz = s;
129816179Sralph return(p);
129916179Sralph }
130016179Sralph
icons(p)130116179Sralph icons(p) register NODE *p; {
130216179Sralph /* if p is an integer constant, return its value */
130316179Sralph int val;
130416179Sralph
130516179Sralph if( p->in.op != ICON ){
130616179Sralph uerror( "constant expected");
130716179Sralph val = 1;
130816179Sralph }
130916179Sralph else {
131016179Sralph val = p->tn.lval;
131116179Sralph if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" );
131216179Sralph }
131316179Sralph tfree( p );
131416179Sralph return(val);
131516179Sralph }
131616179Sralph
131716179Sralph /* the intent of this table is to examine the
131816179Sralph operators, and to check them for
131916179Sralph correctness.
132016179Sralph
132116179Sralph The table is searched for the op and the
132216179Sralph modified type (where this is one of the
132316179Sralph types INT (includes char and short), LONG,
132416179Sralph DOUBLE (includes FLOAT), and POINTER
132516179Sralph
132616179Sralph The default action is to make the node type integer
132716179Sralph
132816179Sralph The actions taken include:
132916179Sralph PUN check for puns
133016179Sralph CVTL convert the left operand
133116179Sralph CVTR convert the right operand
133216179Sralph TYPL the type is determined by the left operand
133316179Sralph TYPR the type is determined by the right operand
133416179Sralph TYMATCH force type of left and right to match, by inserting conversions
133516179Sralph PTMATCH like TYMATCH, but for pointers
133616179Sralph LVAL left operand must be lval
133716179Sralph CVTO convert the op
133816179Sralph NCVT do not convert the operands
133916179Sralph OTHER handled by code
134016179Sralph NCVTR convert the left operand, not the right...
134116179Sralph
134216179Sralph */
134316179Sralph
134416179Sralph # define MINT 01 /* integer */
134516179Sralph # define MDBI 02 /* integer or double */
134616179Sralph # define MSTR 04 /* structure */
134716179Sralph # define MPTR 010 /* pointer */
134816179Sralph # define MPTI 020 /* pointer or integer */
134916179Sralph # define MENU 040 /* enumeration variable or member */
135024408Smckusick # define MVOID 0100000 /* void type */
135116179Sralph
opact(p)135216179Sralph opact( p ) NODE *p; {
135316179Sralph
135416179Sralph register mt12, mt1, mt2, o;
135516179Sralph
135624408Smckusick mt1 = mt2 = mt12 = 0;
135716179Sralph
135816179Sralph switch( optype(o=p->in.op) ){
135916179Sralph
136016179Sralph case BITYPE:
136124408Smckusick mt2 = moditype( p->in.right->in.type );
136216179Sralph case UTYPE:
136324408Smckusick mt1 = moditype( p->in.left->in.type );
136424408Smckusick break;
136516179Sralph
136616179Sralph }
136716179Sralph
136824408Smckusick if( ((mt1 | mt2) & MVOID) &&
136924408Smckusick o != COMOP &&
137032845Sdonn o != COLON &&
137132845Sdonn !(o == QUEST && (mt1 & MVOID) == 0) &&
137224408Smckusick !(o == CAST && (mt1 & MVOID)) ){
137324408Smckusick /* if lhs of RETURN is void, grammar will complain */
137424408Smckusick if( o != RETURN )
137524408Smckusick uerror( "value of void expression used" );
137624408Smckusick return( NCVT );
137724408Smckusick }
137824408Smckusick mt12 = mt1 & mt2;
137924408Smckusick
138016179Sralph switch( o ){
138116179Sralph
138216179Sralph case NAME :
138316179Sralph case STRING :
138416179Sralph case ICON :
138516179Sralph case FCON :
138617749Sralph case DCON :
138716179Sralph case CALL :
138816179Sralph case UNARY CALL:
138916179Sralph case UNARY MUL:
139016179Sralph { return( OTHER ); }
139116179Sralph case UNARY MINUS:
139232844Sdonn if( mt1 & MENU ) return( 0 );
139316179Sralph if( mt1 & MDBI ) return( TYPL );
139416179Sralph break;
139516179Sralph
139616179Sralph case COMPL:
139732844Sdonn if( mt1 & MENU ) return( 0 );
139816179Sralph if( mt1 & MINT ) return( TYPL );
139916179Sralph break;
140016179Sralph
140116179Sralph case UNARY AND:
140234253Sdonn return( NCVT+OTHER );
140316179Sralph case INIT:
140416179Sralph case CM:
140516180Sralph return( 0 );
140616180Sralph
140716179Sralph case NOT:
140816179Sralph case CBRANCH:
140916180Sralph if( mt1 & MSTR ) break;
141016180Sralph return( 0 );
141116180Sralph
141216179Sralph case ANDAND:
141316179Sralph case OROR:
141416180Sralph if( (mt1 & MSTR) || (mt2 & MSTR) ) break;
141516179Sralph return( 0 );
141616179Sralph
141716179Sralph case MUL:
141816179Sralph case DIV:
141916179Sralph if( mt12 & MDBI ) return( TYMATCH );
142016179Sralph break;
142116179Sralph
142216179Sralph case MOD:
142316179Sralph case AND:
142416179Sralph case OR:
142516179Sralph case ER:
142616179Sralph if( mt12 & MINT ) return( TYMATCH );
142716179Sralph break;
142816179Sralph
142916179Sralph case LS:
143016179Sralph case RS:
143134253Sdonn if( mt12 & MINT ) return( OTHER );
143216179Sralph break;
143316179Sralph
143416179Sralph case EQ:
143516179Sralph case NE:
143616179Sralph case LT:
143716179Sralph case LE:
143816179Sralph case GT:
143916179Sralph case GE:
144032844Sdonn if( mt12 & MENU ) return( TYMATCH+NCVT+PUN );
144132844Sdonn if( mt12 & MDBI ) return( TYMATCH+NCVT+CVTO );
144216179Sralph else if( mt12 & MPTR ) return( PTMATCH+PUN );
144316179Sralph else if( mt12 & MPTI ) return( PTMATCH+PUN );
144416179Sralph else break;
144516179Sralph
144616179Sralph case QUEST:
144716179Sralph case COMOP:
144816179Sralph if( mt2&MENU ) return( TYPR+NCVTR );
144916179Sralph return( TYPR );
145016179Sralph
145116179Sralph case STREF:
145216179Sralph return( NCVTR+OTHER );
145316179Sralph
145416179Sralph case FORCE:
145516179Sralph return( TYPL );
145616179Sralph
145716179Sralph case COLON:
145832844Sdonn if( mt12 & MENU ) return( NCVT+PUN+TYMATCH );
145932844Sdonn else if( mt12 & MDBI ) return( NCVT+TYMATCH );
146016179Sralph else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
146116179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
146216179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
146316179Sralph else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
146432845Sdonn else if( mt12 == MVOID ) return( NCVT+TYPL );
146516179Sralph break;
146616179Sralph
146716179Sralph case ASSIGN:
146816179Sralph case RETURN:
146916179Sralph if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
147032844Sdonn else if( mt12 & MENU ) return( LVAL+NCVT+TYPL+TYMATCH+PUN );
147116179Sralph case CAST:
147232846Sdonn if(o==CAST && mt1==MVOID)return(TYPL+TYMATCH);
147332844Sdonn else if( mt12 & MDBI ) return( TYPL+LVAL+NCVT+TYMATCH );
147432846Sdonn else if( mt2 == MVOID &&
147518436Smckusick ( p->in.right->in.op == CALL ||
147618436Smckusick p->in.right->in.op == UNARY CALL)) break;
147732854Sdonn else if( (mt1 & MPTR) && (mt2 & MPTI) )
147832854Sdonn return( LVAL+PTMATCH+PUN );
147916179Sralph else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
148016179Sralph break;
148116179Sralph
148216179Sralph case ASG LS:
148316179Sralph case ASG RS:
148416179Sralph if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
148516179Sralph break;
148616179Sralph
148716179Sralph case ASG MUL:
148816179Sralph case ASG DIV:
148916179Sralph if( mt12 & MDBI ) return( LVAL+TYMATCH );
149016179Sralph break;
149116179Sralph
149216179Sralph case ASG MOD:
149316179Sralph case ASG AND:
149416179Sralph case ASG OR:
149516179Sralph case ASG ER:
149616179Sralph if( mt12 & MINT ) return( LVAL+TYMATCH );
149716179Sralph break;
149816179Sralph
149916179Sralph case ASG PLUS:
150016179Sralph case ASG MINUS:
150116179Sralph case INCR:
150216179Sralph case DECR:
150316179Sralph if( mt12 & MDBI ) return( TYMATCH+LVAL );
150416179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR );
150516179Sralph break;
150616179Sralph
150716179Sralph case MINUS:
150816179Sralph if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN );
150916179Sralph if( mt2 & MPTR ) break;
151016179Sralph case PLUS:
151116179Sralph if( mt12 & MDBI ) return( TYMATCH );
151216179Sralph else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR );
151316179Sralph else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL );
151416179Sralph
151516179Sralph }
151624408Smckusick if( mt12 == MSTR )
151724408Smckusick uerror( "%s is not a permitted struct/union operation", opst[o] );
151824408Smckusick else
151924408Smckusick uerror( "operands of %s have incompatible types", opst[o] );
152016179Sralph return( NCVT );
152116179Sralph }
152216179Sralph
moditype(ty)152316179Sralph moditype( ty ) TWORD ty; {
152416179Sralph
152516179Sralph switch( ty ){
152616179Sralph
152716179Sralph case UNDEF:
152824408Smckusick return( MVOID );
152916179Sralph case ENUMTY:
153016179Sralph case MOETY:
153132840Sdonn return( MENU|MINT|MDBI|MPTI ); /* enums are ints */
153216179Sralph
153316179Sralph case STRTY:
153416179Sralph case UNIONTY:
153516179Sralph return( MSTR );
153616179Sralph
153716179Sralph case CHAR:
153816179Sralph case SHORT:
153916179Sralph case UCHAR:
154016179Sralph case USHORT:
154116179Sralph return( MINT|MPTI|MDBI );
154216179Sralph case UNSIGNED:
154316179Sralph case ULONG:
154416179Sralph case INT:
154516179Sralph case LONG:
154616179Sralph return( MINT|MDBI|MPTI );
154716179Sralph case FLOAT:
154816179Sralph case DOUBLE:
154916179Sralph return( MDBI );
155016179Sralph default:
155116179Sralph return( MPTR|MPTI );
155216179Sralph
155316179Sralph }
155416179Sralph }
155516179Sralph
155616179Sralph NODE *
doszof(p)155716179Sralph doszof( p ) register NODE *p; {
155816179Sralph /* do sizeof p */
155916179Sralph int i;
156016179Sralph
156116179Sralph /* whatever is the meaning of this if it is a bitfield? */
156216179Sralph i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR;
156316179Sralph
156416179Sralph tfree(p);
156516179Sralph if( i <= 0 ) werror( "sizeof returns 0" );
156616179Sralph return( bcon( i ) );
156716179Sralph }
156816179Sralph
156916179Sralph # ifndef BUG2
eprint(p,down,a,b)157016179Sralph eprint( p, down, a, b ) register NODE *p; int *a, *b; {
157116179Sralph register ty;
157216179Sralph
157316179Sralph *a = *b = down+1;
157416179Sralph while( down > 1 ){
157516179Sralph printf( "\t" );
157616179Sralph down -= 2;
157716179Sralph }
157816179Sralph if( down ) printf( " " );
157916179Sralph
158016179Sralph ty = optype( p->in.op );
158116179Sralph
158216179Sralph printf("%o) %s, ", p, opst[p->in.op] );
158316179Sralph if( ty == LTYPE ){
158416179Sralph printf( CONFMT, p->tn.lval );
158516179Sralph printf( ", %d, ", p->tn.rval );
158616179Sralph }
158716179Sralph tprint( p->in.type );
158816179Sralph printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz );
158916179Sralph }
159016179Sralph # endif
159116179Sralph
159232850Sdonn #ifndef PRTDCON
prtdcon(p)159316179Sralph prtdcon( p ) register NODE *p; {
159417749Sralph int o = p->in.op, i;
159516179Sralph
159617749Sralph if( o == DCON || o == FCON ){
159732852Sdonn (void) locctr( DATA );
159817749Sralph defalign( o == DCON ? ALDOUBLE : ALFLOAT );
159916179Sralph deflab( i = getlab() );
160017749Sralph if( o == FCON )
160117749Sralph fincode( p->fpn.fval, SZFLOAT );
160217749Sralph else
160317749Sralph fincode( p->dpn.dval, SZDOUBLE );
160416179Sralph p->tn.lval = 0;
160516179Sralph p->tn.rval = -i;
160617749Sralph p->in.type = (o == DCON ? DOUBLE : FLOAT);
160716179Sralph p->in.op = NAME;
160816179Sralph }
160916179Sralph }
161032850Sdonn #endif PRTDCON
161116179Sralph
161216179Sralph
161316179Sralph int edebug = 0;
ecomp(p)161416179Sralph ecomp( p ) register NODE *p; {
161516179Sralph # ifndef BUG2
161616179Sralph if( edebug ) fwalk( p, eprint, 0 );
161716179Sralph # endif
161816179Sralph if( !reached ){
161916179Sralph werror( "statement not reached" );
162016179Sralph reached = 1;
162116179Sralph }
162216179Sralph p = optim(p);
162316179Sralph walkf( p, prtdcon );
162432852Sdonn (void) locctr( PROG );
162516179Sralph ecode( p );
162616179Sralph tfree(p);
162716179Sralph }
162816179Sralph
162916179Sralph # ifdef STDPRTREE
163016179Sralph # ifndef ONEPASS
163116179Sralph
prtree(p)163216179Sralph prtree(p) register NODE *p; {
163316179Sralph
163416179Sralph register struct symtab *q;
163516179Sralph register ty;
163616179Sralph
163716179Sralph # ifdef MYPRTREE
163816179Sralph MYPRTREE(p); /* local action can be taken here; then return... */
163916179Sralph #endif
164016179Sralph
164116179Sralph ty = optype(p->in.op);
164216179Sralph
164316179Sralph printf( "%d\t", p->in.op );
164416179Sralph
164516179Sralph if( ty == LTYPE ) {
164616179Sralph printf( CONFMT, p->tn.lval );
164716179Sralph printf( "\t" );
164816179Sralph }
164916179Sralph if( ty != BITYPE ) {
165016179Sralph if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" );
165116179Sralph else printf( "%d\t", p->tn.rval );
165216179Sralph }
165316179Sralph
165416179Sralph printf( "%o\t", p->in.type );
165516179Sralph
165616179Sralph /* handle special cases */
165716179Sralph
165816179Sralph switch( p->in.op ){
165916179Sralph
166016179Sralph case NAME:
166116179Sralph case ICON:
166216179Sralph /* print external name */
166316179Sralph if( p->tn.rval == NONAME ) printf( "\n" );
166416179Sralph else if( p->tn.rval >= 0 ){
166516179Sralph q = &stab[p->tn.rval];
166616179Sralph printf( "%s\n", exname(q->sname) );
166716179Sralph }
166816179Sralph else { /* label */
166916179Sralph printf( LABFMT, -p->tn.rval );
167016179Sralph }
167116179Sralph break;
167216179Sralph
167316179Sralph case STARG:
167416179Sralph case STASG:
167516179Sralph case STCALL:
167616179Sralph case UNARY STCALL:
167716179Sralph /* print out size */
167816179Sralph /* use lhs size, in order to avoid hassles with the structure `.' operator */
167916179Sralph
168016179Sralph /* note: p->in.left not a field... */
168116179Sralph printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) );
168216179Sralph printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) );
168316179Sralph break;
168416179Sralph
168516179Sralph default:
168616179Sralph printf( "\n" );
168716179Sralph }
168816179Sralph
168916179Sralph if( ty != LTYPE ) prtree( p->in.left );
169016179Sralph if( ty == BITYPE ) prtree( p->in.right );
169116179Sralph
169216179Sralph }
169316179Sralph
169416179Sralph # else
169516179Sralph
p2tree(p)169616179Sralph p2tree(p) register NODE *p; {
169716179Sralph register ty;
169816179Sralph
169916179Sralph # ifdef MYP2TREE
170016179Sralph MYP2TREE(p); /* local action can be taken here; then return... */
170116179Sralph # endif
170216179Sralph
170316179Sralph ty = optype(p->in.op);
170416179Sralph
170516179Sralph switch( p->in.op ){
170616179Sralph
170716179Sralph case NAME:
170816179Sralph case ICON:
170916179Sralph #ifndef FLEXNAMES
171016179Sralph if( p->tn.rval == NONAME ) p->in.name[0] = '\0';
171116179Sralph #else
171216179Sralph if( p->tn.rval == NONAME ) p->in.name = "";
171316179Sralph #endif
171416179Sralph else if( p->tn.rval >= 0 ){ /* copy name from exname */
171516179Sralph register char *cp;
171616179Sralph cp = exname( stab[p->tn.rval].sname );
171716179Sralph #ifndef FLEXNAMES
171832852Sdonn {
171932852Sdonn register i;
172032852Sdonn for( i=0; i<NCHNAM; ++i )
172132852Sdonn p->in.name[i] = *cp++;
172232852Sdonn }
172316179Sralph #else
172416179Sralph p->in.name = tstr(cp);
172516179Sralph #endif
172616179Sralph }
172716179Sralph #ifndef FLEXNAMES
172816179Sralph else sprintf( p->in.name, LABFMT, -p->tn.rval );
172916179Sralph #else
173016179Sralph else {
173116179Sralph char temp[32];
173216179Sralph sprintf( temp, LABFMT, -p->tn.rval );
173316179Sralph p->in.name = tstr(temp);
173416179Sralph }
173516179Sralph #endif
173616179Sralph break;
173716179Sralph
173816179Sralph case STARG:
173916179Sralph case STASG:
174016179Sralph case STCALL:
174116179Sralph case UNARY STCALL:
174216179Sralph /* set up size parameters */
174316179Sralph p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR;
174416179Sralph p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR;
174516179Sralph break;
174616179Sralph
174716179Sralph case REG:
174816179Sralph rbusy( p->tn.rval, p->in.type );
174916179Sralph default:
175016179Sralph #ifndef FLEXNAMES
175116179Sralph p->in.name[0] = '\0';
175216179Sralph #else
175316179Sralph p->in.name = "";
175416179Sralph #endif
175516179Sralph }
175616179Sralph
175716179Sralph p->in.rall = NOPREF;
175816179Sralph
175916179Sralph if( ty != LTYPE ) p2tree( p->in.left );
176016179Sralph if( ty == BITYPE ) p2tree( p->in.right );
176116179Sralph }
176216179Sralph
176316179Sralph # endif
176416179Sralph # endif
1765