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