|
|
1.1 ! root 1: /* @(#) trees.c: 1.3 3/4/84 */ ! 2: ! 3: # include "mfile1.h" ! 4: ! 5: /* some special actions, used in finding the type of nodes */ ! 6: # define NCVT 01 ! 7: # define PUN 02 ! 8: # define TYPL 04 ! 9: # define TYPR 010 ! 10: # define TYMATCH 040 ! 11: # define LVAL 0100 ! 12: # define CVTO 0200 ! 13: # define CVTL 0400 ! 14: # define CVTR 01000 ! 15: # define PTMATCH 02000 ! 16: # define OTHER 04000 ! 17: # define NCVTR 010000 ! 18: ! 19: /* node conventions: ! 20: ** ! 21: ** NAME: rval>0 is stab index for external ! 22: ** rval<0 is -inlabel number ! 23: ** lval is offset in address units ! 24: ** (NAME really means "STATIC VARIABLE") ! 25: ** ICON: lval has the value ! 26: ** rval has the STAB index, or - label number, ! 27: ** if a name whose address is in the constant ! 28: ** rval = NONAME means no name ! 29: ** VAUTO: automatic name: lval has offset in address units ! 30: ** VPARAM: parameter: lval has offset in address units ! 31: ** REG: rval is reg. number ! 32: ** ! 33: */ ! 34: extern int maxarg; ! 35: ! 36: TWORD ! 37: indtype( t ) ! 38: register TWORD t; ! 39: { ! 40: /* return the type of an intermediate expression of type t */ ! 41: switch( t ) ! 42: { ! 43: ! 44: case CHAR: ! 45: case SHORT: ! 46: return( INT ); ! 47: ! 48: case UCHAR: ! 49: case USHORT: ! 50: return( UNSIGNED ); ! 51: ! 52: /*rick: no! case FLOAT: ! 53: /* return( DOUBLE ); ! 54: */ ! 55: ! 56: } ! 57: return( t ); ! 58: } ! 59: ! 60: int bdebug = 0; ! 61: extern ddebug; ! 62: ! 63: # ifndef XI ! 64: NODE * ! 65: xicolon( l, r1, r2 ) register NODE *l, *r1, *r2; ! 66: ! 67: { ! 68: uerror( "syntax error: colon in subscript" ); ! 69: tfree( r2 ); ! 70: return( buildtree( LB, l, r1 ) ); ! 71: } ! 72: # endif ! 73: ! 74: NODE * ! 75: buildtree( o, l, r ) ! 76: register NODE *l, *r; ! 77: register o; ! 78: { ! 79: register NODE *p, *q; ! 80: register struct symtab *sp; ! 81: register NODE *lr, *ll; ! 82: register actions; ! 83: register opty; ! 84: int i, tlineno; ! 85: ! 86: # ifndef NODBG ! 87: if( bdebug ) ! 88: printf( "buildtree( %s, %d, %d )\n", opst[o], l-node, r-node ); ! 89: # endif ! 90: ! 91: /* special case to recognize subscripting explicitly */ ! 92: ! 93: # ifdef XI ! 94: if( o == LB && l->tn.type == LONG ) ! 95: return( xicolon( l, r, (NODE *) 0 ) ); ! 96: # endif ! 97: ! 98: if( o == LB ) return( buildtree( STAR, buildtree( PLUS, l, r ), NIL ) ); ! 99: opty = optype(o); ! 100: ! 101: /* check for constants */ ! 102: ! 103: if( o == NOT && l->in.op == ICON && hflag ) ! 104: { ! 105: werror( "constant argument to NOT" ); ! 106: } ! 107: ! 108: else if( o==UNARY MINUS && l->in.op==FCON ) ! 109: { ! 110: l->fpn.dval = -l->fpn.dval; ! 111: return(l); ! 112: } ! 113: ! 114: else if( o==QUEST && l->in.op==ICON && l->tn.rval==NONAME ) ! 115: { ! 116: l->in.op = FREE; ! 117: r->in.op = FREE; ! 118: if( l->tn.lval ) ! 119: { ! 120: tfree( r->in.right ); ! 121: return( r->in.left ); ! 122: } ! 123: else ! 124: { ! 125: tfree( r->in.left ); ! 126: return( r->in.right ); ! 127: } ! 128: } ! 129: ! 130: else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) ! 131: goto ccwarn; ! 132: ! 133: else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ) ! 134: { ! 135: ! 136: switch( o ) ! 137: { ! 138: ! 139: case ULT: ! 140: case UGT: ! 141: case ULE: ! 142: case UGE: ! 143: case LT: ! 144: case GT: ! 145: case LE: ! 146: case GE: ! 147: case EQ: ! 148: case NE: ! 149: case ANDAND: ! 150: case OROR: ! 151: case CBRANCH: ! 152: ! 153: ccwarn: ! 154: if( hflag ) werror( "constant in conditional context" ); ! 155: } ! 156: } ! 157: if (o == CBRANCH) switch (BTYPE(l->in.type)) { ! 158: case STRTY: ! 159: case UNIONTY: ! 160: if (!ISPTR(l->in.type)) ! 161: uerror("struct or union as conditional"); ! 162: case ENUMTY: ! 163: break; ! 164: } ! 165: ! 166: /* we make a real node, and look for shrinking later */ ! 167: ! 168: tlineno = lineno; ! 169: if (l && l->ln.lineno && l->ln.lineno < tlineno) ! 170: tlineno = l->ln.lineno; ! 171: if (r && r->ln.lineno && r->ln.lineno < tlineno) ! 172: tlineno = r->ln.lineno; ! 173: p = block( o, l, r, INT, 0, INT ); ! 174: ! 175: actions = opact(p); ! 176: # ifdef MYOPACT ! 177: actions = MYOPACT(p,actions); ! 178: # endif ! 179: ! 180: if( actions&LVAL ) ! 181: { ! 182: /* check left descendent */ ! 183: if( notlval(p->in.left) ) ! 184: { ! 185: uerror( "illegal lhs of assignment operator" ); ! 186: } ! 187: } ! 188: ! 189: if( actions & NCVTR ) ! 190: { ! 191: p->in.left = pconvert( p->in.left ); ! 192: } ! 193: else if( !(actions & NCVT ) ) ! 194: { ! 195: switch( opty ) ! 196: { ! 197: ! 198: case BITYPE: ! 199: p->in.right = pconvert( p->in.right ); ! 200: case UTYPE: ! 201: if( !(actions&LVAL) ) ! 202: p->in.left = pconvert( p->in.left ); ! 203: ! 204: } ! 205: } ! 206: ! 207: if( (actions&PUN) && (o!=CAST||cflag) ) ! 208: { ! 209: chkpun(p); ! 210: } ! 211: ! 212: if( actions & (TYPL|TYPR) ) ! 213: { ! 214: ! 215: q = (actions&TYPL) ? p->in.left : p->in.right; ! 216: ! 217: p->in.type = q->in.type; ! 218: p->fn.cdim = q->fn.cdim; ! 219: p->fn.csiz = q->fn.csiz; ! 220: } ! 221: ! 222: if( actions & CVTL ) p = convert( p, CVTL ); ! 223: if( actions & CVTR ) p = convert( p, CVTR ); ! 224: ! 225: if( actions & TYMATCH ) p = tymatch(p); ! 226: if( actions & PTMATCH ) p = ptmatch(p); ! 227: ! 228: if( actions & SPFLG ) p = clocal(p); ! 229: ! 230: if( actions & OTHER ) ! 231: { ! 232: l = p->in.left; ! 233: r = p->in.right; ! 234: ! 235: switch(o) ! 236: { ! 237: ! 238: case NAME: ! 239: sp = &stab[idname]; ! 240: if( sp->stype == UNDEF ) ! 241: { ! 242: uerror( "%s undefined", sp->sname ); ! 243: /* make p look reasonable */ ! 244: p->in.type = p->fn.cdim = p->fn.csiz = INT; ! 245: p->tn.rval = idname; ! 246: p->tn.lval = 0; ! 247: defid( p, SNULL ); ! 248: break; ! 249: } ! 250: #if defined(M32B) && defined(IMPREGAL) ! 251: p->in.pad[0] = '@'; /*mark as un-raname()'d*/ ! 252: #endif ! 253: p->in.type = sp->stype; ! 254: p->fn.cdim = sp->dimoff; ! 255: p->fn.csiz = sp->sizoff; ! 256: /* special case: MOETY is really an ICON... */ ! 257: if( p->in.type == MOETY ) ! 258: { ! 259: p->tn.rval = NONAME; ! 260: p->tn.lval = sp->offset; ! 261: p->fn.cdim = 0; ! 262: p->in.type = ENUMTY; ! 263: p->in.op = ICON; ! 264: } ! 265: else ! 266: { ! 267: switch( sp->sclass ) ! 268: { ! 269: ! 270: case AUTO: ! 271: p->in.op = VAUTO; ! 272: p->tn.rval = NONAME; ! 273: p->tn.lval = BITOOR(sp->offset); ! 274: break; ! 275: ! 276: case PARAM: ! 277: p->in.op = VPARAM; ! 278: p->tn.rval = NONAME; ! 279: p->tn.lval = BITOOR(sp->offset); ! 280: break; ! 281: ! 282: case REGISTER: ! 283: p->in.op = REG; ! 284: p->tn.lval = 0; ! 285: p->tn.rval = sp->offset; ! 286: break; ! 287: ! 288: case ULABEL: ! 289: case LABEL: ! 290: case STATIC: ! 291: if( sp->slevel != 0 ) ! 292: { ! 293: p->tn.lval = 0; ! 294: p->tn.rval = -sp->offset; ! 295: break; ! 296: } ! 297: /* FALLTHRU */ ! 298: ! 299: default: ! 300: p->tn.lval = 0; ! 301: p->tn.rval = idname; ! 302: } ! 303: } ! 304: break; ! 305: ! 306: case ICON: ! 307: p->in.type = INT; ! 308: p->fn.cdim = 0; ! 309: p->fn.csiz = INT; ! 310: break; ! 311: ! 312: case STRING: ! 313: p->in.op = NAME; ! 314: p->in.type = CHAR+ARY; ! 315: p->tn.lval = 0; ! 316: p->tn.rval = NOLAB; ! 317: p->fn.cdim = curdim; ! 318: p->fn.csiz = CHAR; ! 319: break; ! 320: ! 321: case FCON: ! 322: p->tn.lval = 0; ! 323: p->tn.rval = 0; ! 324: p->in.type = DOUBLE; ! 325: p->fn.cdim = 0; ! 326: p->fn.csiz = DOUBLE; ! 327: #ifdef MYFCON ! 328: MYFCON(p); ! 329: #endif ! 330: break; ! 331: ! 332: case STREF: ! 333: /* p->x turned into *(p+offset) */ ! 334: /* rhs must be a name; check correctness */ ! 335: ! 336: i = r->tn.rval; ! 337: if(i<0 || i>=SYMTSZ || ((sp= &stab[i])->sclass != MOS && ! 338: sp->sclass != MOU && !(sp->sclass&FIELD)) ) ! 339: { ! 340: uerror( "%s not structure/union member", ! 341: sp->sname); ! 342: break; ! 343: } ! 344: else ! 345: /* if this name is non-unique, find right one */ ! 346: if( stab[i].sflags&SNONUNIQ && (l->in.type==PTR+STRTY || ! 347: l->in.type == PTR+UNIONTY) && ! 348: (l->fn.csiz+1) >= 0 ) ! 349: { ! 350: /* nonunique name && structure defined */ ! 351: char * memnam, * tabnam; ! 352: register j; ! 353: int memi; ! 354: j=dimtab[l->fn.csiz+1]; ! 355: for( ; (memi=dimtab[j]) >= 0; ++j ) ! 356: { ! 357: tabnam = stab[memi].sname; ! 358: memnam = stab[i].sname; ! 359: # ifndef NODBG ! 360: if( ddebug>1 ) ! 361: { ! 362: printf("member %s==%s?\n", ! 363: memnam, tabnam); ! 364: } ! 365: # endif ! 366: if( stab[memi].sflags & SNONUNIQ ) ! 367: { ! 368: if ( memnam != tabnam ) ! 369: continue; ! 370: r->tn.rval = i = memi; ! 371: break; ! 372: } ! 373: continue; ! 374: } ! 375: if( memi < 0 ) ! 376: uerror("illegal member use: %s", ! 377: stab[i].sname); ! 378: } ! 379: else ! 380: { ! 381: register j; ! 382: if( l->in.type != PTR+STRTY && ! 383: l->in.type != PTR+UNIONTY ) ! 384: { ! 385: if( stab[i].sflags & SNONUNIQ ) ! 386: { ! 387: uerror( ! 388: "nonunique name (%s) demands struct/union or struct/union pointer", stab[i].sname); ! 389: } ! 390: else werror( ! 391: "struct/union or struct/union pointer required" ); ! 392: } ! 393: else if( (j=l->fn.csiz+1)<0 ) ! 394: cerror( "undefined structure or union"); ! 395: else if( !chkstr( i, dimtab[j], ! 396: DECREF(l->in.type) ) ) ! 397: { ! 398: werror( "illegal member use: %s", ! 399: stab[i].sname ); ! 400: } ! 401: } ! 402: p = stref( p ); ! 403: break; ! 404: ! 405: case STAR: ! 406: if( l->in.op == UNARY AND ) ! 407: { ! 408: p->in.op = l->in.op = FREE; ! 409: p = l->in.left; ! 410: } ! 411: if( !ISPTR(l->in.type) ) uerror("illegal indirection"); ! 412: p->in.type = DECREF(l->in.type); ! 413: p->fn.cdim = l->fn.cdim; ! 414: p->fn.csiz = l->fn.csiz; ! 415: break; ! 416: ! 417: case UNARY AND: ! 418: switch( l->in.op ) { ! 419: case CONV: ! 420: uerror("type mismatch"); ! 421: break; ! 422: case STAR: ! 423: p->in.op = l->in.op = FREE; ! 424: p = l->in.left; ! 425: case NAME: ! 426: case VAUTO: ! 427: case VPARAM: ! 428: case TEMP: ! 429: case STCALL: ! 430: case UNARY STCALL: ! 431: refinc: ! 432: p->in.type = INCREF( l->in.type ); ! 433: p->fn.cdim = l->fn.cdim; ! 434: p->fn.csiz = l->fn.csiz; ! 435: break; ! 436: case RNODE: ! 437: #ifdef TMPSRET ! 438: /* don't bother, let optim clean up */ ! 439: if (simpstr(l->fn.cdim, l->fn.csiz) != STRTY) ! 440: goto refinc; ! 441: p->in.op = STAR; ! 442: p->in.type = STRTY; ! 443: p->fn.csiz = l->fn.csiz; ! 444: p->fn.cdim = l->fn.cdim; ! 445: l->in.op = FREE; ! 446: idname = lookup(hash(".stfake"), 0); ! 447: p->in.left = buildtree(NAME, NIL, NIL); ! 448: p->in.left->fn.csiz = p->fn.csiz; ! 449: p->in.left->fn.cdim = p->fn.cdim; ! 450: break; ! 451: #else ! 452: goto refinc; ! 453: #endif ! 454: case COMOP: ! 455: lr = buildtree( UNARY AND, l->in.right, NIL ); ! 456: p->in.op = l->in.op = FREE; ! 457: p = buildtree( COMOP, l->in.left, lr ); ! 458: break; ! 459: case QUEST: ! 460: lr = buildtree(UNARY AND, ! 461: l->in.right->in.right, NIL); ! 462: ll = buildtree(UNARY AND, ! 463: l->in.right->in.left, NIL); ! 464: p->in.op = l->in.op = l->in.right->in.op = FREE; ! 465: p = buildtree(QUEST, l->in.left, ! 466: buildtree( COLON, ll, lr)); ! 467: break; ! 468: default: ! 469: uerror( "unacceptable operand of &" ); ! 470: break; ! 471: } ! 472: break; ! 473: case RETURN: ! 474: case ASSIGN: ! 475: case CAST: ! 476: /* structure assignment */ ! 477: /* take the addresses of the two sides; then make an ! 478: ** operator using STASG and ! 479: ** the addresses of left and right ! 480: */ ! 481: { ! 482: register TWORD t; ! 483: register d, s, sz; ! 484: ! 485: if( l->fn.csiz != r->fn.csiz ) ! 486: uerror( ! 487: "assignment of different structures" ); ! 488: ! 489: r = buildtree( UNARY AND, r, NIL ); ! 490: l = buildtree( UNARY AND, l, NIL ); ! 491: t = r->in.type; ! 492: d = r->fn.cdim; ! 493: s = r->fn.csiz; ! 494: #ifdef ENDSTRUCT ! 495: sz = tsize( STRTY, d, s ); ! 496: l = aadjust( l, sz ); ! 497: r = aadjust( r, sz ); ! 498: #endif ! 499: ! 500: l = block( STASG, l, r, t, d, s ); ! 501: ! 502: if( o == RETURN ) ! 503: { ! 504: p->in.op = FREE; ! 505: p = l; ! 506: break; ! 507: } ! 508: ! 509: p->in.op = STAR; ! 510: p->in.left = clocal(l); ! 511: p->in.right = NIL; ! 512: break; ! 513: } ! 514: case COLON: ! 515: if( l->fn.csiz != r->fn.csiz ) ! 516: uerror( "type clash in conditional" ); ! 517: break; ! 518: ! 519: case CALL: ! 520: i = 0; ! 521: p->in.right = r = strargs( p->in.right, &i ); ! 522: if( i > maxarg ) maxarg = i; ! 523: case UNARY CALL: ! 524: if( !ISPTR(l->in.type)) uerror("call of non-function"); ! 525: p->in.type = DECREF(l->in.type); ! 526: if( !ISFTN(p->in.type)) uerror("call of non-function"); ! 527: p->in.type = DECREF( p->in.type ); ! 528: p->fn.cdim = l->fn.cdim; ! 529: p->fn.csiz = l->fn.csiz; ! 530: if( l->in.op == UNARY AND && ! 531: l->in.left->in.op == NAME && ! 532: l->in.left->tn.rval >= 0 && ! 533: l->in.left->tn.rval != NONAME && ! 534: ((i=stab[l->in.left->tn.rval].sclass)==FORTRAN ! 535: || i == UFORTRAN ) ) ! 536: { ! 537: p->in.op += (FORTCALL-CALL); ! 538: } ! 539: if( p->in.type == STRTY || p->in.type == UNIONTY ) ! 540: { ! 541: /* function returning structure */ ! 542: /* function really returns ptr with * */ ! 543: ! 544: # ifdef ARGSRET ! 545: /* set aside argument space for return val */ ! 546: i = tsize( p->in.type, p->fn.cdim, p->fn.csiz ); ! 547: /* alignment??? */ ! 548: if( i > maxarg ) maxarg = i; ! 549: # endif ! 550: p->in.op += STCALL-CALL; ! 551: p->in.type = INCREF( p->in.type ); ! 552: p = buildtree( STAR, p, NIL ); ! 553: break; ! 554: } ! 555: ! 556: /* fix up type of return value from call */ ! 557: { ! 558: register TWORD t; ! 559: t = indtype( p->tn.type ); ! 560: if( t != p->tn.type ) ! 561: { ! 562: p->fn.csiz = p->tn.type = t; ! 563: } ! 564: /* pjw if (p->fn.type == FLOAT) ! 565: p->fn.type = p->fn.csiz = DOUBLE; ! 566: */ } ! 567: # ifdef ARGALLRET ! 568: /* set aside argument space for return val */ ! 569: i = tsize( p->in.type, p->fn.cdim, p->fn.csiz ); ! 570: /* alignment??? */ ! 571: if( i > maxarg ) maxarg = i; ! 572: # endif ! 573: break; ! 574: ! 575: default: ! 576: cerror( "other code %d", o ); ! 577: } ! 578: ! 579: } ! 580: ! 581: if( actions & CVTO ) p = oconvert(p); ! 582: p = clocal(conval(p)); ! 583: ! 584: # ifndef NODBG ! 585: if( bdebug ) eprint(p); ! 586: # endif ! 587: p->ln.lineno = tlineno; ! 588: return(p); ! 589: ! 590: } ! 591: ! 592: NODE * ! 593: strargs( p, off ) ! 594: register NODE *p; ! 595: register *off; ! 596: { ! 597: /* rewrite arguments */ ! 598: /* allocate the arguments at *off, and update *off */ ! 599: register TWORD t; ! 600: int workoff; ! 601: ! 602: t = p->fn.type; ! 603: if( p->in.op == CM ) ! 604: { ! 605: #if defined(BACKARGS) && defined(BACKPARAM) || \ ! 606: !defined(BACKARGS) && !defined(BACKPARAM) ! 607: ! 608: p->in.left = strargs( p->in.left, off ); ! 609: p->in.right = strargs( p->in.right, off ); ! 610: ! 611: #else ! 612: ! 613: p->in.right = strargs(p->in.right, off); ! 614: p->in.left = strargs(p->in.left, off); ! 615: ! 616: #endif ! 617: return( p ); ! 618: } ! 619: ! 620: if (t == FLOAT) ! 621: p = makety(p, t = DOUBLE, 0, DOUBLE); ! 622: p = block( STARG, p, NIL, t, p->fn.cdim, p->fn.csiz ); ! 623: if( t == STRTY || t == UNIONTY ) ! 624: { ! 625: p->in.left = buildtree( UNARY AND, p->in.left, NIL ); ! 626: } ! 627: else ! 628: { ! 629: p->in.op = FUNARG; ! 630: } ! 631: ! 632: /* SETOFF( *off, talign( t, p->fn.csiz ) ); */ ! 633: SETOFF( *off, ALSTACK ); ! 634: workoff = tsize( t, p->fn.cdim, p->fn.csiz ); ! 635: ! 636: #ifdef BACKARGS ! 637: *off += workoff; ! 638: p->tn.rval = -*off; ! 639: #else ! 640: p->tn.rval = *off; ! 641: *off += workoff; ! 642: #endif ! 643: return( clocal(p) ); ! 644: } ! 645: ! 646: chkstr( i, j, type ) ! 647: register TWORD type; ! 648: register i,j; ! 649: { ! 650: /* is the MOS or MOU at stab[i] OK for strict reference by a ptr */ ! 651: /* i has been checked to contain a MOS or MOU */ ! 652: /* j is the index in dimtab of the members... */ ! 653: register k, kk; ! 654: ! 655: extern int ddebug; ! 656: ! 657: # ifndef NODBG ! 658: if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j ); ! 659: # endif ! 660: if( (k = j) < 0 ) uerror( "undefined structure or union %s", stab[i].sname); ! 661: else ! 662: { ! 663: for( ; (kk = dimtab[k] ) >= 0; ++k ) ! 664: { ! 665: if( kk >= SYMTSZ ) ! 666: { ! 667: cerror( "gummy structure" ); ! 668: return(1); ! 669: } ! 670: if( kk == i ) return( 1 ); ! 671: switch( stab[kk].stype ) ! 672: { ! 673: ! 674: case STRTY: ! 675: case UNIONTY: ! 676: if( type == STRTY ) continue; /* no recursive looking for strs */ ! 677: if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ) ! 678: { ! 679: if( stab[kk].sname[0] == '$' ) return(0); /* $FAKE */ ! 680: werror( ! 681: "illegal member use: perhaps %s.%s?", ! 682: stab[kk].sname, stab[i].sname); ! 683: return(1); ! 684: } ! 685: } ! 686: } ! 687: } ! 688: return( 0 ); ! 689: } ! 690: ! 691: NODE * ! 692: conval( p ) ! 693: register NODE *p; ! 694: { ! 695: register NODE *l, *r; ! 696: register o, i, f, u; ! 697: register CONSZ val; ! 698: ! 699: f = (p->tn.type==FLOAT || p->tn.type == DOUBLE); ! 700: u = ISUNSIGNED(p->tn.type); ! 701: ! 702: switch( optype(o = p->tn.op) ) ! 703: { ! 704: case BITYPE: ! 705: l = p->in.left; ! 706: r = p->in.right; ! 707: break; ! 708: ! 709: case UTYPE: ! 710: r = l = p->in.left; ! 711: break; ! 712: ! 713: case LTYPE: ! 714: return( p ); ! 715: } ! 716: ! 717: if( l->tn.op != ( f ? FCON : ICON ) ) return( p ); ! 718: if( r->tn.op != ( f ? FCON : ICON ) ) return( p ); ! 719: ! 720: if( !f ) ! 721: { ! 722: /* weed out unprofitable cases */ ! 723: val = r->tn.lval; ! 724: if( l->tn.rval != NONAME && r->tn.rval != NONAME ) return(p); ! 725: if( r->tn.rval != NONAME && o!=PLUS ) return(p); ! 726: if( l->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(p); ! 727: } ! 728: else if( logop(o) ) return( p ); ! 729: ! 730: switch( o ) ! 731: { ! 732: ! 733: case PLUS: ! 734: if( f ) ! 735: { ! 736: l->fpn.dval += r->fpn.dval; ! 737: break; ! 738: } ! 739: l->tn.lval += val; ! 740: if( l->tn.rval == NONAME ) ! 741: { ! 742: l->tn.rval = r->tn.rval; ! 743: l->in.type = r->in.type; ! 744: } ! 745: break; ! 746: ! 747: case MINUS: ! 748: if( f ) l->fpn.dval -= r->fpn.dval; ! 749: else l->tn.lval -= val; ! 750: break; ! 751: ! 752: case MUL: ! 753: if( f ) l->fpn.dval *= r->fpn.dval; ! 754: else l->tn.lval *= val; ! 755: break; ! 756: ! 757: case DIV: ! 758: if( f ) ! 759: { ! 760: if( r->fpn.dval == 0. ) uerror( "division by 0" ); ! 761: else l->fpn.dval /= r->fpn.dval; ! 762: } ! 763: else ! 764: { ! 765: if( val == 0 ) uerror( "division by 0" ); ! 766: else if( u ) ! 767: l->tn.lval = (unsigned long)l->tn.lval / val; ! 768: else l->tn.lval /= val; ! 769: } ! 770: break; ! 771: ! 772: case MOD: ! 773: if( val == 0 ) uerror( "division by 0" ); ! 774: else if( u ) l->tn.lval = (unsigned long)l->tn.lval % val; ! 775: else l->tn.lval %= val; ! 776: break; ! 777: ! 778: case AND: ! 779: l->tn.lval &= val; ! 780: break; ! 781: ! 782: case OR: ! 783: l->tn.lval |= val; ! 784: break; ! 785: ! 786: case ER: ! 787: l->tn.lval ^= val; ! 788: break; ! 789: ! 790: case LS: ! 791: i = val; ! 792: l->tn.lval = l->tn.lval << i; ! 793: break; ! 794: ! 795: case RS: ! 796: i = val; ! 797: if( u ) l->tn.lval = (unsigned long)l->tn.lval >> i; ! 798: else l->tn.lval = l->tn.lval >> i; ! 799: break; ! 800: ! 801: case UNARY MINUS: ! 802: if( f ) l->fpn.dval = -l->fpn.dval; ! 803: else l->tn.lval = - l->tn.lval; ! 804: break; ! 805: ! 806: case COMPL: ! 807: l->tn.lval = ~l->tn.lval; ! 808: break; ! 809: ! 810: case NOT: ! 811: if( l->tn.type == FLOAT || l->tn.type == DOUBLE ) ! 812: { ! 813: l->tn.op = ICON; ! 814: l->tn.lval = !l->fpn.dval; ! 815: } ! 816: else l->tn.lval = !l->tn.lval; ! 817: break; ! 818: ! 819: case LT: ! 820: l->tn.lval = l->tn.lval < val; ! 821: break; ! 822: ! 823: case LE: ! 824: l->tn.lval = l->tn.lval <= val; ! 825: break; ! 826: ! 827: case GT: ! 828: l->tn.lval = l->tn.lval > val; ! 829: break; ! 830: ! 831: case GE: ! 832: l->tn.lval = l->tn.lval >= val; ! 833: break; ! 834: ! 835: case ULT: ! 836: l->tn.lval = (l->tn.lval-val)<0; ! 837: break; ! 838: ! 839: case ULE: ! 840: l->tn.lval = (l->tn.lval-val)<=0; ! 841: break; ! 842: ! 843: case UGE: ! 844: l->tn.lval = (l->tn.lval-val)>=0; ! 845: break; ! 846: ! 847: case UGT: ! 848: l->tn.lval = (l->tn.lval-val)>0; ! 849: break; ! 850: ! 851: case EQ: ! 852: l->tn.lval = l->tn.lval == val; ! 853: break; ! 854: ! 855: case NE: ! 856: l->tn.lval = l->tn.lval != val; ! 857: break; ! 858: ! 859: default: ! 860: return(p); ! 861: } ! 862: ! 863: if( l != r ) r->tn.op = FREE; /* don't clobber unary answer */ ! 864: l = makety( l, p->tn.type, p->fn.cdim, p->fn.csiz ); ! 865: p->tn.op = FREE; ! 866: return( l ); ! 867: } ! 868: ! 869: chkpun(p) ! 870: register NODE *p; ! 871: { ! 872: /* checks p for the existance of a pun */ ! 873: /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, ! 874: ** or relational ! 875: */ ! 876: ! 877: /* one case is when enumerations are used: this applies only to lint */ ! 878: /* in the other case, one operand is a pointer, the other integer */ ! 879: /* we check that this integer is in fact a constant zero... */ ! 880: /* if it is, we redo the type of the 0 to match the other side */ ! 881: ! 882: /* with ASSIGN, assignment of pointer to integer is illegal */ ! 883: /* this falls out, because the LHS is never 0 */ ! 884: ! 885: register NODE *q1, *q2; ! 886: register t1, t2; ! 887: register d1, d2; ! 888: ! 889: q1 = p->in.left; ! 890: q2 = p->in.right; ! 891: t1 = q1->in.type; ! 892: t2 = q2->in.type; ! 893: ! 894: if( t1==ENUMTY || t2==ENUMTY ) ! 895: { ! 896: /* check for enumerations */ ! 897: /*(pjw)if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) ! 898: { ! 899: uerror( "illegal comparison of enums" ); ! 900: return; ! 901: }*/ ! 902: if( t1==ENUMTY && t2==ENUMTY && q1->fn.csiz==q2->fn.csiz ) ! 903: return; ! 904: werror( "enumeration type clash, operator %s", opst[p->in.op] ); ! 905: return; ! 906: } ! 907: ! 908: if( ISPTR(t1) || ISARY(t1) ) ! 909: { /* switch roles: q1 should be non-pointer */ ! 910: q1 = q2; ! 911: q2 = p->in.left; ! 912: } ! 913: ! 914: if( !ISPTR(q1->in.type) && !ISARY(q1->in.type) ) ! 915: { ! 916: if( q1->in.op == ICON && q1->tn.lval == 0 && q1->tn.rval == NONAME ) ! 917: { /* make the 0 have the type of the other side */ ! 918: q1->fn.type = q2->fn.type; ! 919: q1->fn.cdim = q2->fn.cdim; ! 920: q1->fn.csiz = q2->fn.type; ! 921: } ! 922: else ! 923: { ! 924: combo( "pointer/integer", p ); ! 925: } ! 926: return; ! 927: } ! 928: else ! 929: { /* q1 and q2 still mean left and right */ ! 930: d1 = q1->fn.cdim; ! 931: d2 = q2->fn.cdim; ! 932: for( ;; ) ! 933: { ! 934: if( t1 == t2 ) ! 935: { ! 936: ; ! 937: if(q1->fn.csiz!=q2->fn.csiz) ! 938: { ! 939: combo( "structure pointer", p ); ! 940: } ! 941: return; ! 942: } ! 943: /****** LINT Change: Turn on only if LINT is to be used with this pcc2 ******/ ! 944: /* /* complain about pointer casts if cflag is set ! 945: /* /* (this implies that pflag is set) ! 946: /* */ ! 947: /* if (p->in.op == CAST) ! 948: /* { ! 949: /* if (ISPTR(tl) && ISPTR(t2)) ! 950: /* { ! 951: /* werror( ! 952: /* "pointer casts may be troublesome"); ! 953: /* return; ! 954: /* } ! 955: /* } ! 956: /****************************************************************************/ ! 957: if( ISARY(t1) || ISPTR(t1) ) ! 958: { ! 959: if( !ISARY(t2) && !ISPTR(t2) ) break; ! 960: if( ISARY(t1) && ISARY(t2) && ! 961: dimtab[d1] != dimtab[d2] ) ! 962: { ! 963: combo( "array size", p ); ! 964: return; ! 965: } ! 966: if( ISARY(t1) ) ++d1; ! 967: if( ISARY(t2) ) ++d2; ! 968: } ! 969: else break; ! 970: t1 = DECREF(t1); ! 971: t2 = DECREF(t2); ! 972: } ! 973: combo( "pointer", p ); ! 974: } ! 975: } ! 976: ! 977: combo( s, p ) ! 978: char *s; ! 979: NODE *p; ! 980: { ! 981: char buf[100]; ! 982: sprintf( buf, "illegal %s combination, op %s", s, opst[p->tn.op] ); ! 983: werror( buf ); ! 984: } ! 985: ! 986: NODE * ! 987: stref( p ) ! 988: register NODE *p; ! 989: { ! 990: register TWORD t; ! 991: register d, s, dsc, align; ! 992: register OFFSZ off; ! 993: register struct symtab *q; ! 994: ! 995: /* make p->x */ ! 996: /* this is also used to reference automatic variables */ ! 997: ! 998: q = &stab[p->in.right->tn.rval]; ! 999: q->suse = -lineno; ! 1000: p->in.right->in.op = FREE; ! 1001: p->in.op = FREE; ! 1002: p = pconvert( p->in.left ); ! 1003: ! 1004: /* make p look like ptr to x */ ! 1005: ! 1006: if( !ISPTR(p->in.type)) ! 1007: { ! 1008: p->in.type = PTR+UNIONTY; ! 1009: } ! 1010: ! 1011: t = INCREF( q->stype ); ! 1012: d = q->dimoff; ! 1013: s = q->sizoff; ! 1014: ! 1015: p = makety( p, t, d, s ); ! 1016: ! 1017: /* compute the offset to be added */ ! 1018: ! 1019: off = q->offset; ! 1020: dsc = q->sclass; ! 1021: ! 1022: if( dsc & FIELD ) ! 1023: { ! 1024: /* normalize offset */ ! 1025: switch(q->stype) ! 1026: { ! 1027: ! 1028: case CHAR: ! 1029: case UCHAR: ! 1030: align = ALCHAR; ! 1031: s = CHAR; ! 1032: break; ! 1033: ! 1034: case SHORT: ! 1035: case USHORT: ! 1036: align = ALSHORT; ! 1037: s = SHORT; ! 1038: break; ! 1039: ! 1040: case ENUMTY: ! 1041: case INT: ! 1042: case UNSIGNED: ! 1043: align = ALINT; ! 1044: s = INT; ! 1045: break; ! 1046: ! 1047: # ifdef LONGFIELDS ! 1048: case LONG: ! 1049: case ULONG: ! 1050: align = ALLONG; ! 1051: s = LONG; ! 1052: break; ! 1053: # endif ! 1054: ! 1055: default: ! 1056: cerror( "undefined bit field type" ); ! 1057: } ! 1058: off = (off/align)*align; ! 1059: } ! 1060: if( off != 0 ) ! 1061: p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); ! 1062: ! 1063: p = buildtree( STAR, p, NIL ); ! 1064: ! 1065: /* if field, build field info */ ! 1066: ! 1067: if( dsc & FIELD ) ! 1068: { ! 1069: p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); ! 1070: p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); ! 1071: } ! 1072: ! 1073: return( clocal(p) ); ! 1074: } ! 1075: ! 1076: notlval(p) ! 1077: register NODE *p; ! 1078: { ! 1079: ! 1080: /* return 0 if p an lvalue, 1 otherwise */ ! 1081: ! 1082: again: ! 1083: switch( p->in.op ) ! 1084: { ! 1085: ! 1086: case FLD: ! 1087: p = p->in.left; ! 1088: goto again; ! 1089: ! 1090: case STAR: ! 1091: /* is there a special case for structs? */ ! 1092: case NAME: ! 1093: case VAUTO: ! 1094: case VPARAM: ! 1095: case RNODE: ! 1096: case QNODE: ! 1097: case SNODE: ! 1098: if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); ! 1099: case REG: ! 1100: return(0); ! 1101: ! 1102: default: ! 1103: return(1); ! 1104: ! 1105: } ! 1106: ! 1107: } ! 1108: ! 1109: NODE * ! 1110: bcon( i ) ! 1111: { ! 1112: /* make a constant node with value i */ ! 1113: register NODE *p; ! 1114: ! 1115: p = block( ICON, NIL, NIL, INT, 0, INT ); ! 1116: p->tn.lval = i; ! 1117: p->tn.rval = NONAME; ! 1118: return( clocal(p) ); ! 1119: } ! 1120: ! 1121: NODE * ! 1122: bpsize(p) ! 1123: register NODE *p; ! 1124: { ! 1125: return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); ! 1126: } ! 1127: ! 1128: OFFSZ ! 1129: psize( p ) ! 1130: register NODE *p; ! 1131: { ! 1132: /* p is a node of type pointer; psize returns the ! 1133: ** size of the thing pointed to ! 1134: */ ! 1135: ! 1136: if( !ISPTR(p->in.type) ) ! 1137: { ! 1138: uerror( "pointer required"); ! 1139: return( SZINT ); ! 1140: } ! 1141: /* note: no pointers to fields */ ! 1142: return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); ! 1143: } ! 1144: ! 1145: NODE * ! 1146: unconvert( p, q ) ! 1147: register NODE *p, *q; ! 1148: { ! 1149: /* p is divided by the size of q */ ! 1150: /* q had better have type pointer */ ! 1151: ! 1152: # ifdef MYPDIV ! 1153: return( clocal( block( PDIV, p, bpsize(q), INT, 0, INT ) ) ); ! 1154: # else ! 1155: p = makety( p, PTRTYPE, 0, PTRTYPE ); ! 1156: p = clocal( buildtree( DIV, p, bpsize(q) ) ); ! 1157: ! 1158: return( makety( p, PTRTYPE, 0, PTRTYPE ) ); ! 1159: # endif ! 1160: } ! 1161: ! 1162: NODE * ! 1163: convert( p, f ) ! 1164: register NODE *p; ! 1165: register f; ! 1166: { ! 1167: /* convert an operand of p ! 1168: ** f is either CVTL or CVTR ! 1169: ** operand has type int, and is converted by the size of the other side ! 1170: */ ! 1171: ! 1172: register NODE *q, *r; ! 1173: ! 1174: if( f == CVTL ) ! 1175: { ! 1176: q = p->in.left; ! 1177: r = bpsize( p->in.right ); ! 1178: } ! 1179: else ! 1180: { ! 1181: q = p->in.right; ! 1182: r = bpsize( p->in.left ); ! 1183: } ! 1184: # ifdef MYPMUL ! 1185: r = clocal( block( PMUL, q, r, PTRTYPE, 0, PTRTYPE ) ); ! 1186: # else ! 1187: /* if PTRTYPE is defined, make q this size; then, the MUL will be */ ! 1188: q = makety( q, PTRTYPE, 0, PTRTYPE ); ! 1189: r = clocal( buildtree( MUL, q, r ) ); ! 1190: # endif ! 1191: if( f == CVTL ) ! 1192: p->in.left = r; ! 1193: else ! 1194: p->in.right = r; ! 1195: return(p); ! 1196: ! 1197: } ! 1198: ! 1199: econvert( p ) ! 1200: register NODE *p; ! 1201: { ! 1202: ! 1203: /* change enums to ints, or appropriate types */ ! 1204: ! 1205: register TWORD ty; ! 1206: ! 1207: if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) ! 1208: { ! 1209: if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; ! 1210: else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; ! 1211: else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; ! 1212: else ty = LONG; ! 1213: ty = ctype( ty ); ! 1214: p->fn.csiz = ty; ! 1215: MODTYPE(p->in.type,ty); ! 1216: if( p->in.op == ICON && ty != LONG ) ! 1217: p->in.type = p->fn.csiz = INT; ! 1218: } ! 1219: } ! 1220: ! 1221: NODE * ! 1222: pconvert( p ) ! 1223: register NODE *p; ! 1224: { ! 1225: register TWORD t; ! 1226: ! 1227: /* if p should be changed into a pointer, do so */ ! 1228: /* also, widen p so it can be used as an operand */ ! 1229: ! 1230: if( ISARY( p->in.type) ) ! 1231: { ! 1232: p->in.type = DECREF( p->in.type ); ! 1233: ++p->fn.cdim; ! 1234: return( buildtree( UNARY AND, p, NIL ) ); ! 1235: } ! 1236: if( ISFTN( p->in.type) ) ! 1237: return( buildtree( UNARY AND, p, NIL ) ); ! 1238: ! 1239: t = indtype( p->tn.type ); ! 1240: if( t == p->tn.type ) return( p ); ! 1241: if( p->tn.op == CONV && cbigger( p ) ) ! 1242: { ! 1243: p->tn.type = p->fn.csiz = t; ! 1244: } ! 1245: else p = makety( p, t, 0, (int) t ); ! 1246: return( p ); ! 1247: } ! 1248: ! 1249: bigsize( t ) ! 1250: TWORD t; ! 1251: { /* return a type size for t */ ! 1252: switch( t ) { ! 1253: case CHAR: ! 1254: case UCHAR: ! 1255: return( SZCHAR ); ! 1256: case SHORT: ! 1257: case USHORT: ! 1258: return( SZSHORT ); ! 1259: case VOID: ! 1260: case INT: ! 1261: case UNSIGNED: ! 1262: case ENUMTY: ! 1263: return( SZINT ); ! 1264: case LONG: ! 1265: case ULONG: ! 1266: return( SZLONG ); ! 1267: case FLOAT: ! 1268: return( SZLONG+1 ); /* must appear > long */ ! 1269: case DOUBLE: ! 1270: return( SZLONG+2 ); ! 1271: case STRTY: ! 1272: uerror("structure appears where arithmetic type required"); ! 1273: return(0); ! 1274: case UNIONTY: ! 1275: uerror("union appears where arithmetic type required"); ! 1276: return(0); ! 1277: } ! 1278: ! 1279: if( ISPTR(t) || ISARY(t) ) return( SZPOINT ); ! 1280: ! 1281: cerror( "bad bigsize: 0%o", t ); ! 1282: /*NOTREACHED*/ ! 1283: } ! 1284: ! 1285: cbigger( p ) ! 1286: register NODE *p; ! 1287: { ! 1288: /* returns 1 if the conversion op p makes things bigger */ ! 1289: ! 1290: if( p->tn.op != CONV ) cerror( "cbigger" ); ! 1291: if(p->tn.type == STRTY || p->tn.type == UNIONTY || p->tn.type == VOID) { ! 1292: uerror("trying to cast to a struct void or union"); ! 1293: return(0); ! 1294: } ! 1295: return( bigsize( p->tn.type ) > bigsize( p->in.left->tn.type ) ); ! 1296: } ! 1297: ! 1298: NODE * ! 1299: oconvert(p) ! 1300: register NODE *p; ! 1301: ! 1302: { ! 1303: /* convert the result itself: used for pointer and unsigned */ ! 1304: register TWORD t; ! 1305: ! 1306: switch(p->in.op) ! 1307: { ! 1308: ! 1309: case LE: ! 1310: case LT: ! 1311: case GE: ! 1312: case GT: ! 1313: t = p->in.left->in.type; ! 1314: if( ISUNSIGNED(t) || ISPTR(t) || ISARY(t) ) ! 1315: { ! 1316: p->in.op += (ULE-LE); ! 1317: } ! 1318: else ! 1319: { ! 1320: t = p->in.right->in.type; ! 1321: if( ISUNSIGNED(t) || ISPTR(t) || ISARY(t) ) ! 1322: { ! 1323: p->in.op += (ULE-LE); ! 1324: } ! 1325: } ! 1326: case EQ: ! 1327: case NE: ! 1328: case ULE: ! 1329: case ULT: ! 1330: case UGE: ! 1331: case UGT: ! 1332: return( p ); ! 1333: ! 1334: case MINUS: ! 1335: return( unconvert( p, p->in.left ) ); ! 1336: } ! 1337: ! 1338: cerror( "illegal oconvert: %d", p->in.op ); ! 1339: ! 1340: return(p); ! 1341: } ! 1342: ! 1343: NODE * ! 1344: ptmatch(p) ! 1345: register NODE *p; ! 1346: { ! 1347: ! 1348: /* makes the operands of p agree; they are ! 1349: ** either pointers or integers, by this time ! 1350: */ ! 1351: /* with MINUS, the sizes must be the same */ ! 1352: /* with COLON, the types must be the same */ ! 1353: ! 1354: register TWORD t1, t2, t; ! 1355: register o, d2, d, s2, s; ! 1356: ! 1357: o = p->in.op; ! 1358: t = t1 = p->in.left->in.type; ! 1359: t2 = p->in.right->in.type; ! 1360: d = p->in.left->fn.cdim; ! 1361: d2 = p->in.right->fn.cdim; ! 1362: s = p->in.left->fn.csiz; ! 1363: s2 = p->in.right->fn.csiz; ! 1364: ! 1365: switch( o ) ! 1366: { ! 1367: ! 1368: case ASSIGN: ! 1369: case RETURN: ! 1370: case CAST: ! 1371: break; ! 1372: ! 1373: case MINUS: ! 1374: if( psize(p->in.left) != psize(p->in.right) ) ! 1375: { ! 1376: uerror( "illegal pointer subtraction"); ! 1377: } ! 1378: p->tn.type = p->fn.csiz = PTRTYPE; ! 1379: p->fn.cdim = 0; ! 1380: return( clocal(p) ); ! 1381: ! 1382: case COLON: ! 1383: if( t1 != t2 ) uerror( "incompatible types in :"); ! 1384: break; ! 1385: ! 1386: default: ! 1387: if( !ISPTR(t1) ) ! 1388: { ! 1389: t = t2; ! 1390: d = d2; ! 1391: s = s2; ! 1392: break; ! 1393: } ! 1394: if( !ISPTR(t2) ) ! 1395: { ! 1396: break; ! 1397: } ! 1398: ! 1399: /* both are pointers */ ! 1400: if( talign(t2,s2) < talign(t,s) ) ! 1401: { ! 1402: t = t2; ! 1403: s = s2; ! 1404: } ! 1405: break; ! 1406: } ! 1407: ! 1408: p->in.left = makety( p->in.left, t, d, s ); ! 1409: p->in.right = makety( p->in.right, t, d, s ); ! 1410: if( !logop(o) ) ! 1411: { ! 1412: p->in.type = t; ! 1413: p->fn.cdim = d; ! 1414: p->fn.csiz = s; ! 1415: } ! 1416: ! 1417: return(clocal(p)); ! 1418: } ! 1419: ! 1420: int tdebug = 0; ! 1421: ! 1422: NODE * ! 1423: tymatch(p) ! 1424: register NODE *p; ! 1425: { ! 1426: ! 1427: /* satisfy the types of various arithmetic binary ops */ ! 1428: ! 1429: /* rules are: ! 1430: ** if any float or doubles, make double ! 1431: ** no, rick changes this rule to ! 1432: ** a. if any doubles, make double ! 1433: ** b. if both floats, make float ! 1434: ** c. if any floats, make double ! 1435: ** the rest proceed as usual ! 1436: ** if any longs, make long ! 1437: ** if any ints, make int ! 1438: ** if any shorts, make short ! 1439: ** otherwise, make char ! 1440: ** if either operand is unsigned, the result is... ! 1441: ** if a simple assignment, type = type of lhs ! 1442: ** if an asg. op, type = type of original lhs ! 1443: ** (under CONV, if any) ! 1444: */ ! 1445: ! 1446: register o; ! 1447: register TWORD t1, t2; ! 1448: TWORD t, tu; ! 1449: register NODE *l, *r; ! 1450: int u; ! 1451: ! 1452: o = p->in.op; ! 1453: ! 1454: t1 = (l=p->in.left)->in.type; ! 1455: t2 = (r=p->in.right)->in.type; ! 1456: ! 1457: /* constants have a kind of "flexible" type */ ! 1458: ! 1459: if( r->tn.op == ICON && r->tn.rval == NONAME && ! 1460: (t1==CHAR || t1==UCHAR || t1==SHORT || t1==USHORT) ) ! 1461: { ! 1462: /* if the constant retains its value when cast to the ! 1463: ** type of the lhs, assume it has the lhs type ! 1464: */ ! 1465: if( r->tn.lval == ccast( r->tn.lval, t1 ) ) ! 1466: { ! 1467: r->in.type = t2 = t1; ! 1468: r->fn.cdim = l->fn.cdim; ! 1469: r->fn.csiz = l->fn.csiz; ! 1470: } ! 1471: } ! 1472: ! 1473: /* this is the opposite case from the above (it is too early ! 1474: to assume that constants are on the right) */ ! 1475: ! 1476: if( l->tn.op == ICON && l->tn.rval == NONAME && ! 1477: (t2==CHAR || t2==UCHAR || t2==SHORT || t2==USHORT) ) ! 1478: { ! 1479: /* if the constant retains its value when cast to the ! 1480: ** type of the rhs, assume it has the rhs type ! 1481: */ ! 1482: if( l->tn.lval == ccast( l->tn.lval, t2 ) ) ! 1483: { ! 1484: l->in.type = t1 = t2; ! 1485: l->fn.cdim = r->fn.cdim; ! 1486: l->fn.csiz = r->fn.csiz; ! 1487: } ! 1488: } ! 1489: if( (t1==VOID || t2==VOID) && o!=CAST ) ! 1490: uerror("void type illegal in expression"); ! 1491: ! 1492: u = 0; ! 1493: if( ISUNSIGNED(t1) ) ! 1494: { ! 1495: u = 1; ! 1496: t1 = DEUNSIGN(t1); ! 1497: } ! 1498: if( ISUNSIGNED(t2) ) ! 1499: { ! 1500: u |= 2; ! 1501: t2 = DEUNSIGN(t2); ! 1502: } ! 1503: /*rick ! 1504: /* if( t1==DOUBLE || t1==FLOAT || t2==DOUBLE || t2==FLOAT ) t = DOUBLE; ! 1505: */ ! 1506: if (t1 == DOUBLE || t2 == DOUBLE) t = DOUBLE; ! 1507: else if (t1 == FLOAT && t2 == FLOAT) t = FLOAT; ! 1508: else if (t1 == FLOAT || t2 == FLOAT) t = DOUBLE; ! 1509: else if( t1==LONG || t2==LONG ) t = LONG; ! 1510: else if( t1==INT || t2==INT ) t = INT; ! 1511: else if( t1==SHORT || t2==SHORT ) t = SHORT; ! 1512: else t = CHAR; ! 1513: ! 1514: if( o == ASSIGN || o == CAST || o == RETURN ) ! 1515: { ! 1516: tu = t1; ! 1517: if( o == RETURN ) ! 1518: { ! 1519: if( tu==FLOAT ) tu = DOUBLE; ! 1520: else if( tu==CHAR || tu==SHORT ) tu = INT; ! 1521: } ! 1522: t = t1 = tu; /* t1 set to avoid lhs conversion */ ! 1523: if( ISUNSIGNED(l->tn.type) ) u=1; ! 1524: else u=0; ! 1525: t2 = r->tn.type; /* back to reality... */ ! 1526: } ! 1527: /* pjw says this is the wrong test, as int -= unsigned should be int ! 1528: tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; */ ! 1529: if(u && UNSIGNABLE(t) && !asgbinop(o)) ! 1530: tu = ENUNSIGN(t); ! 1531: else if(asgbinop(o)) ! 1532: tu = (u & 1? ENUNSIGN(t1): t1); ! 1533: else ! 1534: tu = t; ! 1535: if( tu != t1 ) p->in.left = makety( l, tu, 0, (int)tu ); ! 1536: if( tu != t2 ) p->in.right = makety( r, tu, 0, (int)tu ); ! 1537: ! 1538: if( !logop(o) ) /* the type of the node = type of the operation */ ! 1539: { ! 1540: p->in.type = tu; ! 1541: p->fn.cdim = 0; ! 1542: p->fn.csiz = t; ! 1543: } ! 1544: ! 1545: if( asgop(o) && p->in.left->tn.op == CONV ) ! 1546: { ! 1547: /* original, unconverted type */ ! 1548: /* this will get rewritten to A = A op B, in most cases */ ! 1549: /* if the op is an unsigned op, change the lhs to unsigned */ ! 1550: l = p->in.left->in.left; ! 1551: tu = l->in.type; ! 1552: if( u && (UNSIGNABLE(tu)) ) tu = ENUNSIGN(tu); ! 1553: p->in.type = l->in.type = tu; ! 1554: p->fn.cdim = l->fn.cdim; ! 1555: p->fn.csiz = l->fn.csiz; ! 1556: } ! 1557: ! 1558: # ifndef NODBG ! 1559: if( tdebug ) ! 1560: { ! 1561: printf( "tymatch(%o): %o '%s' %o => %o\n",p,t1,opst[o],t2,tu ); ! 1562: eprint(p); ! 1563: } ! 1564: # endif ! 1565: ! 1566: return(p); ! 1567: } ! 1568: ! 1569: NODE * ! 1570: makety( p, t, d, s ) ! 1571: register NODE *p; ! 1572: register TWORD t; ! 1573: register d,s; ! 1574: { ! 1575: /* make p into type t by inserting a conversion */ ! 1576: register TWORD pt; ! 1577: ! 1578: pt = p->in.type; ! 1579: ! 1580: if( pt == ENUMTY && p->in.op == ICON ) ! 1581: { ! 1582: econvert(p); ! 1583: pt = p->in.type; ! 1584: } ! 1585: ! 1586: if( ISARY(pt) || ISFTN(pt) ) ! 1587: { ! 1588: p = pconvert( p ); ! 1589: pt = p->in.type; ! 1590: } ! 1591: ! 1592: if( t == pt || (p->tn.op == FCON && p->tn.rval == NONAME)) ! 1593: { ! 1594: rew: ! 1595: p->fn.type = t; ! 1596: p->fn.cdim = d; ! 1597: p->fn.csiz = s; ! 1598: return( p ); ! 1599: } ! 1600: ! 1601: if( t & TMASK ) ! 1602: { ! 1603: /* non-simple type */ ! 1604: if( ISPTR(pt) ! 1605: # ifdef TWOPTRS ! 1606: && TWOPTRS(t) == TWOPTRS(pt) ! 1607: # endif ! 1608: ) ! 1609: { ! 1610: /* don't generate CONV: just rewrite type */ ! 1611: goto rew; ! 1612: } ! 1613: ! 1614: return( block( CONV, p, NIL, t, d, s ) ); ! 1615: } ! 1616: ! 1617: if( p->in.op == ICON && p->tn.rval==NONAME ) ! 1618: { ! 1619: if( t==DOUBLE||t==FLOAT ) ! 1620: { ! 1621: p->in.op = FCON; ! 1622: if( ISUNSIGNED(pt) ) ! 1623: { ! 1624: p->fpn.dval = /* (unsigned CONSZ) */ p->tn.lval; ! 1625: } ! 1626: else ! 1627: { ! 1628: p->fpn.dval = p->tn.lval; ! 1629: } ! 1630: goto rew; ! 1631: } ! 1632: p->tn.lval = ccast( p->tn.lval, t ); ! 1633: goto rew; ! 1634: } ! 1635: ! 1636: /* double op ((double) (float op float)) => */ ! 1637: /* double op ((double) float op (double) float) */ ! 1638: /* recursively */ ! 1639: /* don't push a conversion down the lhs of an assign op */ ! 1640: ! 1641: if (pt == FLOAT && t == DOUBLE && optype(p->in.op) == BITYPE && ! 1642: !asgop(p->in.op) && p->in.op != CALL) ! 1643: { ! 1644: p->in.left = makety(p->in.left, t, d, s); ! 1645: p->in.right = makety(p->in.right, t, d, s); ! 1646: goto rew; ! 1647: } ! 1648: return( block( CONV, p, NIL, t, d, s ) ); ! 1649: } ! 1650: ! 1651: NODE * ! 1652: block( o, l, r, t, d, s ) ! 1653: NODE *l, *r; TWORD t; ! 1654: { ! 1655: ! 1656: register NODE *p; ! 1657: ! 1658: p = talloc(); ! 1659: p->in.op = o; ! 1660: p->in.left = l; ! 1661: p->in.right = r; ! 1662: p->in.type = t; ! 1663: p->ln.lineno = 0; ! 1664: p->fn.cdim = d; ! 1665: p->fn.csiz = s; ! 1666: ! 1667: /* for really heavy debugging ! 1668: printf( "block( %s, %d, %d, 0%o, %d, %d ) yields %d\n", ! 1669: opst[o], l-node, r-node, t, d, s, p-node ); ! 1670: */ ! 1671: ! 1672: return(p); ! 1673: } ! 1674: ! 1675: icons(p) ! 1676: register NODE *p; ! 1677: { ! 1678: /* if p is an integer constant, return its value */ ! 1679: register val; ! 1680: ! 1681: if( p->in.op != ICON ) ! 1682: { ! 1683: uerror( "constant expected"); ! 1684: val = 1; ! 1685: } ! 1686: else ! 1687: { ! 1688: val = p->tn.lval; ! 1689: if( val != p->tn.lval ) ! 1690: uerror( "constant too big for cross-compiler" ); ! 1691: } ! 1692: tfree( p ); ! 1693: return(val); ! 1694: } ! 1695: ! 1696: /* the intent of this table is to examine the ! 1697: ** operators, and to check them for ! 1698: ** correctness. ! 1699: ** ! 1700: ** The table is searched for the op and the ! 1701: ** modified type (where this is one of the ! 1702: ** types INT (includes char and short), LONG, ! 1703: ** DOUBLE (includes FLOAT), and POINTER ! 1704: ** ! 1705: ** The default action is to make the node type integer ! 1706: ** ! 1707: ** The actions taken include: ! 1708: ** PUN check for puns ! 1709: ** CVTL convert the left operand ! 1710: ** CVTR convert the right operand ! 1711: ** TYPL the type is determined by the left operand ! 1712: ** TYPR the type is determined by the right operand ! 1713: ** TYMATCH force type of left and right to match, by inserting conversions ! 1714: ** PTMATCH like TYMATCH, but for pointers ! 1715: ** LVAL left operand must be lval ! 1716: ** CVTO convert the op ! 1717: ** NCVT do not convert the operands ! 1718: ** OTHER handled by code ! 1719: ** NCVTR convert the left operand, not the right... ! 1720: ** ! 1721: */ ! 1722: ! 1723: # define MINT 01 /* integer */ ! 1724: # define MDBI 02 /* integer or double */ ! 1725: # define MSTR 04 /* structure */ ! 1726: # define MPTR 010 /* pointer */ ! 1727: # define MPTI 020 /* pointer or integer */ ! 1728: # define MENU 040 /* enumeration variable or member */ ! 1729: ! 1730: opact( p ) ! 1731: register NODE *p; ! 1732: { ! 1733: register mt12, mt1, mt2, o; ! 1734: ! 1735: mt12 = 0; ! 1736: ! 1737: switch( optype(o=p->in.op) ) ! 1738: { ! 1739: ! 1740: case BITYPE: ! 1741: mt12=mt2 = moditype( p->in.right->in.type ); ! 1742: case UTYPE: ! 1743: mt12 &= (mt1 = moditype( p->in.left->in.type )); ! 1744: ! 1745: } ! 1746: ! 1747: switch( o ) ! 1748: { ! 1749: ! 1750: case NAME : ! 1751: case STRING : ! 1752: case ICON : ! 1753: case FCON : ! 1754: case CALL : ! 1755: case UNARY CALL: ! 1756: case STAR: ! 1757: { ! 1758: return( OTHER ); ! 1759: } ! 1760: case UNARY MINUS: ! 1761: if( mt1 & MDBI ) return( TYPL ); ! 1762: break; ! 1763: ! 1764: case COMPL: ! 1765: if( mt1 & MINT ) return( TYPL ); ! 1766: break; ! 1767: ! 1768: case UNARY AND: ! 1769: { ! 1770: return( NCVT+OTHER ); ! 1771: } ! 1772: case INIT: ! 1773: case CM: ! 1774: return( 0 ); ! 1775: case NOT: ! 1776: case CBRANCH: ! 1777: case ANDAND: ! 1778: case OROR: ! 1779: return( NCVT ); ! 1780: ! 1781: case MUL: ! 1782: case DIV: ! 1783: if( mt12 & MDBI ) return( TYMATCH ); ! 1784: break; ! 1785: ! 1786: case MOD: ! 1787: case AND: ! 1788: case OR: ! 1789: case ER: ! 1790: case LS: ! 1791: case RS: ! 1792: if( mt12 & MINT ) return( TYMATCH ); ! 1793: break; ! 1794: ! 1795: case EQ: ! 1796: case NE: ! 1797: case LT: ! 1798: case LE: ! 1799: case GT: ! 1800: case GE: ! 1801: if( (mt1&MENU)||(mt2&MENU) ) return( PTMATCH+PUN ); ! 1802: if( mt12 & MDBI ) return( TYMATCH+CVTO ); ! 1803: else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO ); ! 1804: else if( mt12 & MPTI ) return( PTMATCH+PUN+CVTO ); ! 1805: else break; ! 1806: ! 1807: case QUEST: ! 1808: case COMOP: ! 1809: return( TYPR+NCVTR ); ! 1810: ! 1811: case STREF: ! 1812: return( NCVTR+OTHER ); ! 1813: ! 1814: case COLON: ! 1815: if( mt12 & MENU ) return( NCVT+PUN+PTMATCH ); ! 1816: else if( mt12 & MDBI ) return( TYMATCH ); ! 1817: else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); ! 1818: else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); ! 1819: else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); ! 1820: else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); ! 1821: break; ! 1822: ! 1823: case ASSIGN: ! 1824: case RETURN: ! 1825: if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); ! 1826: case CAST: ! 1827: if(o==CAST && mt1==0)return(TYPL+TYMATCH); ! 1828: if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); ! 1829: else if( (mt1&MENU)||(mt2&MENU) ) ! 1830: { ! 1831: return( LVAL+NCVT+TYPL+PTMATCH+PUN ); ! 1832: } ! 1833: else if( mt12 == 0 ) break; ! 1834: else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN ); ! 1835: else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); ! 1836: break; ! 1837: ! 1838: case ASG MUL: ! 1839: case ASG DIV: ! 1840: if( mt12 & MDBI ) return( LVAL+TYMATCH ); ! 1841: break; ! 1842: ! 1843: case ASG MOD: ! 1844: case ASG AND: ! 1845: case ASG OR: ! 1846: case ASG ER: ! 1847: case ASG LS: ! 1848: case ASG RS: ! 1849: if( mt12 & MINT ) return( LVAL+TYMATCH ); ! 1850: break; ! 1851: ! 1852: case ASG PLUS: ! 1853: case ASG MINUS: ! 1854: case INCR: ! 1855: case DECR: ! 1856: if( mt12 & MDBI ) return( TYMATCH+LVAL ); ! 1857: else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); ! 1858: break; ! 1859: ! 1860: case MINUS: ! 1861: if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); ! 1862: if( mt2 & MPTR ) break; ! 1863: case PLUS: ! 1864: if( mt12 & MDBI ) return( TYMATCH ); ! 1865: else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); ! 1866: else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); ! 1867: else break; ! 1868: /* special operators */ ! 1869: case UOP0: ! 1870: case UOP1: ! 1871: case UOP2: ! 1872: case UOP3: ! 1873: case UOP4: ! 1874: case UOP5: ! 1875: case UOP6: ! 1876: case UOP7: ! 1877: case UOP8: ! 1878: case UOP9: ! 1879: return( TYPL ); ! 1880: } ! 1881: uerror( "operands of %s have incompatible types", opst[o] ); ! 1882: return( NCVT ); ! 1883: } ! 1884: ! 1885: moditype( ty ) ! 1886: register TWORD ty; ! 1887: { ! 1888: ! 1889: switch( ty ) ! 1890: { ! 1891: ! 1892: case UNDEF: ! 1893: case VOID: ! 1894: return(0); /* type is void */ ! 1895: case ENUMTY: ! 1896: case MOETY: ! 1897: /* pjw says enum is int return( MENU ); */ ! 1898: return(MINT|MDBI|MPTI); ! 1899: case STRTY: ! 1900: case UNIONTY: ! 1901: return( MSTR ); ! 1902: ! 1903: case CHAR: ! 1904: case SHORT: ! 1905: case UCHAR: ! 1906: case USHORT: ! 1907: return( MINT|MPTI|MDBI ); ! 1908: ! 1909: case UNSIGNED: ! 1910: case ULONG: ! 1911: case INT: ! 1912: case LONG: ! 1913: return( MINT|MDBI|MPTI ); ! 1914: ! 1915: case FLOAT: ! 1916: case DOUBLE: ! 1917: return( MDBI ); ! 1918: ! 1919: default: ! 1920: return( MPTR|MPTI ); ! 1921: } ! 1922: } ! 1923: ! 1924: # ifndef MYCCAST ! 1925: CONSZ ! 1926: ccast( v, t ) ! 1927: register CONSZ v; ! 1928: register TWORD t; ! 1929: { ! 1930: /* cast value v into simple type t */ ! 1931: /* must be done as it would be on the target machine */ ! 1932: ! 1933: switch( t ) ! 1934: { ! 1935: ! 1936: case CHAR: ! 1937: # ifdef CHSIGN ! 1938: if( v&ONEBIT(SZCHAR-1) ) ! 1939: { ! 1940: return( v | ~BITMASK(SZCHAR) ); ! 1941: } ! 1942: # endif ! 1943: case UCHAR: ! 1944: return( v & BITMASK(SZCHAR) ); ! 1945: ! 1946: case SHORT: ! 1947: if( v&ONEBIT(SZSHORT-1) ) ! 1948: { ! 1949: return( v | ~BITMASK(SZSHORT) ); ! 1950: } ! 1951: case USHORT: ! 1952: return( v & BITMASK(SZSHORT) ); ! 1953: ! 1954: case INT: ! 1955: if( v&ONEBIT(SZINT-1) ) ! 1956: { ! 1957: return( v | ~BITMASK(SZINT) ); ! 1958: } ! 1959: case UNSIGNED: ! 1960: return( v & BITMASK(SZINT) ); ! 1961: ! 1962: default: ! 1963: return( v ); ! 1964: } ! 1965: } ! 1966: # endif ! 1967: ! 1968: ! 1969: NODE * ! 1970: doszof( p ) ! 1971: register NODE *p; ! 1972: { ! 1973: /* do sizeof p */ ! 1974: register i; ! 1975: ! 1976: /* whatever is the meaning of this if it is a bitfield? */ ! 1977: i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; ! 1978: ! 1979: tfree(p); ! 1980: if( i <= 0 ) werror( "sizeof returns 0" ); ! 1981: p = bcon(i); ! 1982: p->tn.type = UNSIGNED; /* damn dmr anyhow! */ ! 1983: return( p ); ! 1984: } ! 1985: ! 1986: # ifndef NODBG ! 1987: eprint(p) ! 1988: NODE *p; ! 1989: { ! 1990: printf("\n++++++++\n"); ! 1991: e1print(p,"T"); ! 1992: printf("---------\n"); ! 1993: } ! 1994: e1print( p ,s) ! 1995: register NODE *p; ! 1996: char *s; ! 1997: { ! 1998: register ty, d; ! 1999: static down = 0; ! 2000: ! 2001: ty = optype( p->tn.op ); ! 2002: ! 2003: if( ty == BITYPE ) ! 2004: { ! 2005: ++down; ! 2006: e1print( p->in.right ,"R"); ! 2007: --down; ! 2008: } ! 2009: ! 2010: for( d=down; d>1; d -= 2 ) printf( "\t" ); ! 2011: if( d ) printf( " " ); ! 2012: ! 2013: printf("%s=%d) %s, ", s, (int) (p-node), opst[p->in.op] ); ! 2014: if( ty == LTYPE ) ! 2015: { ! 2016: printf( "lval=%ld", p->tn.lval ); ! 2017: printf( ", rval=%d, ", p->tn.rval ); ! 2018: } ! 2019: printf("type="); ! 2020: tprint( p->in.type ); ! 2021: printf( ", dim=%d, siz=%d\n", p->fn.cdim, p->fn.csiz ); ! 2022: if( ty != LTYPE ) ! 2023: { ! 2024: ++down; ! 2025: e1print( p->in.left ,"L"); ! 2026: --down; ! 2027: } ! 2028: } ! 2029: ! 2030: tprint( t ) ! 2031: register TWORD t; ! 2032: { ! 2033: /* output a nice description of the type of t */ ! 2034: static char * tnames[] = ! 2035: { ! 2036: "undef", ! 2037: "farg", ! 2038: "char", ! 2039: "short", ! 2040: "int", ! 2041: "long", ! 2042: "float", ! 2043: "double", ! 2044: "strty", ! 2045: "unionty", ! 2046: "enumty", ! 2047: "moety", ! 2048: "uchar", ! 2049: "ushort", ! 2050: "unsigned", ! 2051: "ulong", ! 2052: "?", "?" ! 2053: }; ! 2054: ! 2055: for(;; t = DECREF(t) ) ! 2056: { ! 2057: if( ISPTR(t) ) printf( "PTR " ); ! 2058: else if( ISFTN(t) ) printf( "FTN " ); ! 2059: else if( ISARY(t) ) printf( "ARY " ); ! 2060: else ! 2061: { ! 2062: printf( "%s", tnames[t] ); ! 2063: return; ! 2064: } ! 2065: } ! 2066: } ! 2067: # endif ! 2068: ! 2069: # ifndef MYLOCCTR ! 2070: locctr(l) ! 2071: register l; ! 2072: { ! 2073: register temp, lt; ! 2074: /* look in locnames; print out the location counter name */ ! 2075: /* null means use the next; all null, don't print */ ! 2076: for( lt=l; lt<=STRNG && !locnames[lt]; ++lt ) ! 2077: { ! 2078: /* EMPTY */ ! 2079: } ! 2080: if( lt == curloc ) return( lt ); ! 2081: temp = curloc; ! 2082: if( lt > STRNG ) lt = l; ! 2083: else printx( locnames[lt] ); ! 2084: curloc = lt; ! 2085: return( temp ); ! 2086: } ! 2087: # endif ! 2088: ! 2089: # ifndef NOFLOAT ! 2090: ! 2091: prtdcon( p ) ! 2092: register NODE *p; ! 2093: { ! 2094: register i; ! 2095: register TWORD t; ! 2096: ! 2097: if( p->in.op == FCON ) ! 2098: { ! 2099: locctr( DATA ); ! 2100: t = p->tn.type; ! 2101: defalign( t==DOUBLE?ALDOUBLE:ALFLOAT ); ! 2102: deflab( i = getlab() ); ! 2103: fincode( p->fpn.dval, t==DOUBLE?SZDOUBLE:SZFLOAT ); ! 2104: p->tn.lval = 0; ! 2105: p->tn.rval = -i; ! 2106: p->in.op = NAME; ! 2107: } ! 2108: if( (i = optype(p->in.op)) == BITYPE ) prtdcon( p->in.right ); ! 2109: if( i != LTYPE ) prtdcon( p->in.left ); ! 2110: } ! 2111: # endif ! 2112: ! 2113: # ifndef MYLABELS ! 2114: getlab() ! 2115: { ! 2116: static crslab = 10; ! 2117: return( ++crslab ); ! 2118: } ! 2119: # endif ! 2120: ! 2121: int edebug = 0; ! 2122: ecomp( p ) ! 2123: register NODE *p; ! 2124: { ! 2125: slineno = p->ln.lineno; ! 2126: # ifndef NODBG ! 2127: if( edebug ) eprint(p); ! 2128: # endif ! 2129: if( !reached ) ! 2130: { ! 2131: werror( "statement not reached" ); ! 2132: reached = 1; ! 2133: } ! 2134: # ifdef CLOCAL ! 2135: p = clocal(p); ! 2136: # endif ! 2137: p = optim(p); ! 2138: # ifndef NOFLOAT ! 2139: prtdcon(p); ! 2140: # endif ! 2141: locctr( PROG ); ! 2142: ecode(p); ! 2143: tfree(p); ! 2144: } ! 2145: ! 2146: # ifndef MYECODE ! 2147: ecode( p ) ! 2148: register NODE *p; ! 2149: { ! 2150: /* standard version of writing the tree nodes */ ! 2151: if( nerrors ) return; ! 2152: # ifdef GDEBUG ! 2153: dbline(); ! 2154: # endif ! 2155: p2tree( p ); ! 2156: p2compile( p ); ! 2157: } ! 2158: # endif ! 2159: ! 2160: # ifndef MYPRTREE ! 2161: ! 2162: # ifndef RNODNAME ! 2163: # define RNODNAME LABFMT ! 2164: # endif ! 2165: ! 2166: p2tree(p) ! 2167: register NODE *p; ! 2168: { ! 2169: register ty; ! 2170: register NODE *l; ! 2171: register o; ! 2172: char temp[32]; /* place to dump label stuff */ ! 2173: ! 2174: # ifdef MYP2TREE ! 2175: MYP2TREE(p); /* local action can be taken here; then return... */ ! 2176: # endif ! 2177: ! 2178: /* this routine sits painfully between pass1 and pass2 */ ! 2179: ty = optype(o=p->in.op); ! 2180: p->tn.goal = 0; /* an illegal goal, just to clear it out */ ! 2181: p->tn.type = ttype( p->tn.type ); /* type gets second-pass (bits) */ ! 2182: ! 2183: switch( o ) ! 2184: { ! 2185: ! 2186: case TEMP: ! 2187: case NAME: ! 2188: case ICON: ! 2189: case VAUTO: ! 2190: case VPARAM: ! 2191: if( p->tn.rval == NONAME ) ! 2192: p->in.name = (char *) 0; ! 2193: else if( p->tn.rval >= 0 ) ! 2194: { ! 2195: /* copy name from exname */ ! 2196: register char *cp; ! 2197: cp = exname( stab[p->tn.rval].sname ); ! 2198: p->in.name = tstr( cp ); ! 2199: } ! 2200: else if( p->tn.rval == - strftn ) ! 2201: { ! 2202: sprintf( temp, RNODNAME, -p->tn.rval ); ! 2203: p->in.name = tstr( temp ); ! 2204: } ! 2205: else ! 2206: { ! 2207: sprintf( temp, LABFMT, -p->tn.rval ); ! 2208: p->in.name = tstr( temp ); ! 2209: } ! 2210: break; ! 2211: ! 2212: case STARG: ! 2213: case STASG: ! 2214: case STCALL: ! 2215: case UNARY STCALL: ! 2216: /* set up size parameters */ ! 2217: l = p->in.left; ! 2218: p->stn.stsize = tsize(STRTY,l->fn.cdim,l->fn.csiz); ! 2219: p->stn.stalign = talign(STRTY,l->fn.csiz); ! 2220: break; ! 2221: ! 2222: /* this should do something only if temporary regs are ! 2223: /* built into the tree by machine-dependent actions */ ! 2224: case REG: ! 2225: rbusy( p->tn.rval, p->in.type ); ! 2226: default: ! 2227: p->in.name = (char *) 0; ! 2228: } ! 2229: ! 2230: if( ty != LTYPE ) p2tree( p->in.left ); ! 2231: if( ty == BITYPE ) p2tree( p->in.right ); ! 2232: } ! 2233: ! 2234: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.