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