|
|
1.1 ! root 1: # include "mfile1" ! 2: ! 3: /* corrections when in violation of lint */ ! 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 bits ! 24: ICON: lval has the value ! 25: rval has the STAB index, or - label number, ! 26: if a name whose address is in the constant ! 27: rval = NONAME means no name ! 28: REG: rval is reg. identification cookie ! 29: ! 30: */ ! 31: ! 32: int bdebug = 0; ! 33: extern ddebug; ! 34: ! 35: NODE * ! 36: buildtree( o, l, r ) register NODE *l, *r; { ! 37: register NODE *p, *q; ! 38: register int actions; ! 39: register int opty; ! 40: register struct symtab *sp; ! 41: register NODE *lr, *ll; ! 42: int i; ! 43: extern int eprint(); ! 44: ! 45: # ifndef BUG1 ! 46: if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r ); ! 47: # endif ! 48: opty = optype(o); ! 49: ! 50: /* check for constants */ ! 51: ! 52: if( opty == UTYPE && l->in.op == ICON ){ ! 53: ! 54: switch( o ){ ! 55: ! 56: case NOT: ! 57: if( hflag ) werror( "constant argument to NOT" ); ! 58: case UNARY MINUS: ! 59: case COMPL: ! 60: if( conval( l, o, l ) ) return(l); ! 61: break; ! 62: ! 63: } ! 64: } ! 65: ! 66: else if( o==UNARY MINUS && l->in.op==FCON ){ ! 67: l->fpn.dval = -l->fpn.dval; ! 68: return(l); ! 69: } ! 70: ! 71: else if( o==QUEST && l->in.op==ICON ) { ! 72: l->in.op = FREE; ! 73: r->in.op = FREE; ! 74: if( l->tn.lval ){ ! 75: tfree( r->in.right ); ! 76: return( r->in.left ); ! 77: } ! 78: else { ! 79: tfree( r->in.left ); ! 80: return( r->in.right ); ! 81: } ! 82: } ! 83: ! 84: else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn; ! 85: ! 86: else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ){ ! 87: ! 88: switch( o ){ ! 89: ! 90: case ULT: ! 91: case UGT: ! 92: case ULE: ! 93: case UGE: ! 94: case LT: ! 95: case GT: ! 96: case LE: ! 97: case GE: ! 98: case EQ: ! 99: case NE: ! 100: case ANDAND: ! 101: case OROR: ! 102: case CBRANCH: ! 103: ! 104: ccwarn: ! 105: if( hflag ) werror( "constant in conditional context" ); ! 106: ! 107: case PLUS: ! 108: case MINUS: ! 109: case MUL: ! 110: case DIV: ! 111: case MOD: ! 112: case AND: ! 113: case OR: ! 114: case ER: ! 115: case LS: ! 116: case RS: ! 117: if( conval( l, o, r ) ) { ! 118: r->in.op = FREE; ! 119: return(l); ! 120: } ! 121: break; ! 122: } ! 123: } ! 124: ! 125: else if( opty == BITYPE && (l->in.op==FCON||l->in.op==ICON) && ! 126: (r->in.op==FCON||r->in.op==ICON) ){ ! 127: switch(o){ ! 128: case PLUS: ! 129: case MINUS: ! 130: case MUL: ! 131: case DIV: ! 132: if( l->in.op == ICON ){ ! 133: l->fpn.dval = l->tn.lval; ! 134: } ! 135: if( r->in.op == ICON ){ ! 136: r->fpn.dval = r->tn.lval; ! 137: } ! 138: l->in.op = FCON; ! 139: l->in.type = l->fn.csiz = DOUBLE; ! 140: r->in.op = FREE; ! 141: switch(o){ ! 142: case PLUS: ! 143: l->fpn.dval += r->fpn.dval; ! 144: return(l); ! 145: case MINUS: ! 146: l->fpn.dval -= r->fpn.dval; ! 147: return(l); ! 148: case MUL: ! 149: l->fpn.dval *= r->fpn.dval; ! 150: return(l); ! 151: case DIV: ! 152: if( r->fpn.dval == 0 ) uerror( "division by 0." ); ! 153: else l->fpn.dval /= r->fpn.dval; ! 154: return(l); ! 155: } ! 156: } ! 157: } ! 158: ! 159: /* its real; we must make a new node */ ! 160: ! 161: p = block( o, l, r, INT, 0, INT ); ! 162: ! 163: actions = opact(p); ! 164: ! 165: if( actions&LVAL ){ /* check left descendent */ ! 166: if( notlval(p->in.left) ) { ! 167: uerror( "illegal lhs of assignment operator" ); ! 168: } ! 169: } ! 170: ! 171: if( actions & NCVTR ){ ! 172: p->in.left = pconvert( p->in.left ); ! 173: } ! 174: else if( !(actions & NCVT ) ){ ! 175: switch( opty ){ ! 176: ! 177: case BITYPE: ! 178: p->in.right = pconvert( p->in.right ); ! 179: case UTYPE: ! 180: p->in.left = pconvert( p->in.left ); ! 181: ! 182: } ! 183: } ! 184: ! 185: if( (actions&PUN) && (o!=CAST||cflag) ){ ! 186: chkpun(p); ! 187: } ! 188: ! 189: if( actions & (TYPL|TYPR) ){ ! 190: ! 191: q = (actions&TYPL) ? p->in.left : p->in.right; ! 192: ! 193: p->in.type = q->in.type; ! 194: p->fn.cdim = q->fn.cdim; ! 195: p->fn.csiz = q->fn.csiz; ! 196: } ! 197: ! 198: if( actions & CVTL ) p = convert( p, CVTL ); ! 199: if( actions & CVTR ) p = convert( p, CVTR ); ! 200: if( actions & TYMATCH ) p = tymatch(p); ! 201: if( actions & PTMATCH ) p = ptmatch(p); ! 202: ! 203: if( actions & OTHER ){ ! 204: l = p->in.left; ! 205: r = p->in.right; ! 206: ! 207: switch(o){ ! 208: ! 209: case NAME: ! 210: sp = &stab[idname]; ! 211: if( sp->stype == UNDEF ){ ! 212: #ifndef FLEXNAMES ! 213: uerror( "%.8s undefined", sp->sname ); ! 214: #else ! 215: uerror( "%s undefined", sp->sname ); ! 216: #endif ! 217: /* make p look reasonable */ ! 218: p->in.type = p->fn.cdim = p->fn.csiz = INT; ! 219: p->tn.rval = idname; ! 220: p->tn.lval = 0; ! 221: defid( p, SNULL ); ! 222: break; ! 223: } ! 224: p->in.type = sp->stype; ! 225: p->fn.cdim = sp->dimoff; ! 226: p->fn.csiz = sp->sizoff; ! 227: p->tn.lval = 0; ! 228: p->tn.rval = idname; ! 229: /* special case: MOETY is really an ICON... */ ! 230: if( p->in.type == MOETY ){ ! 231: p->tn.rval = NONAME; ! 232: p->tn.lval = sp->offset; ! 233: p->fn.cdim = 0; ! 234: p->in.type = ENUMTY; ! 235: p->in.op = ICON; ! 236: } ! 237: break; ! 238: ! 239: case ICON: ! 240: p->in.type = INT; ! 241: p->fn.cdim = 0; ! 242: p->fn.csiz = INT; ! 243: break; ! 244: ! 245: case STRING: ! 246: p->in.op = NAME; ! 247: p->in.type = CHAR+ARY; ! 248: p->tn.lval = 0; ! 249: p->tn.rval = NOLAB; ! 250: p->fn.cdim = curdim; ! 251: p->fn.csiz = CHAR; ! 252: break; ! 253: ! 254: case FCON: ! 255: p->tn.lval = 0; ! 256: p->tn.rval = 0; ! 257: p->in.type = DOUBLE; ! 258: p->fn.cdim = 0; ! 259: p->fn.csiz = DOUBLE; ! 260: break; ! 261: ! 262: case STREF: ! 263: /* p->x turned into *(p+offset) */ ! 264: /* rhs must be a name; check correctness */ ! 265: ! 266: i = r->tn.rval; ! 267: if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){ ! 268: uerror( "member of structure or union required" ); ! 269: }else ! 270: /* if this name is non-unique, find right one */ ! 271: if( stab[i].sflags & SNONUNIQ && ! 272: (l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) && ! 273: (l->fn.csiz +1) >= 0 ){ ! 274: /* nonunique name && structure defined */ ! 275: char * memnam, * tabnam; ! 276: register int k; ! 277: int j; ! 278: int memi; ! 279: j=dimtab[l->fn.csiz+1]; ! 280: for( ; (memi=dimtab[j]) >= 0; ++j ){ ! 281: tabnam = stab[memi].sname; ! 282: memnam = stab[i].sname; ! 283: # ifndef BUG1 ! 284: if( ddebug>1 ){ ! 285: #ifndef FLEXNAMES ! 286: printf("member %.8s==%.8s?\n", ! 287: #else ! 288: printf("member %s==%s?\n", ! 289: #endif ! 290: memnam, tabnam); ! 291: } ! 292: # endif ! 293: if( stab[memi].sflags & SNONUNIQ ){ ! 294: #ifndef FLEXNAMES ! 295: for( k=0; k<NCHNAM; ++k ){ ! 296: if(*memnam++!=*tabnam) ! 297: goto next; ! 298: if(!*tabnam++) break; ! 299: } ! 300: #else ! 301: if (memnam != tabnam) ! 302: goto next; ! 303: #endif ! 304: r->tn.rval = i = memi; ! 305: break; ! 306: } ! 307: next: continue; ! 308: } ! 309: if( memi < 0 ) ! 310: #ifndef FLEXNAMES ! 311: uerror("illegal member use: %.8s", ! 312: #else ! 313: uerror("illegal member use: %s", ! 314: #endif ! 315: stab[i].sname); ! 316: } ! 317: else { ! 318: register int j; ! 319: if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){ ! 320: if( stab[i].sflags & SNONUNIQ ){ ! 321: uerror( "nonunique name demands struct/union or struct/union pointer" ); ! 322: } ! 323: else werror( "struct/union or struct/union pointer required" ); ! 324: } ! 325: else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" ); ! 326: else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){ ! 327: #ifndef FLEXNAMES ! 328: werror( "illegal member use: %.8s", stab[i].sname ); ! 329: #else ! 330: werror( "illegal member use: %s", stab[i].sname ); ! 331: #endif ! 332: } ! 333: } ! 334: ! 335: p = stref( p ); ! 336: break; ! 337: ! 338: case UNARY MUL: ! 339: if( l->in.op == UNARY AND ){ ! 340: p->in.op = l->in.op = FREE; ! 341: p = l->in.left; ! 342: } ! 343: if( !ISPTR(l->in.type))uerror("illegal indirection"); ! 344: p->in.type = DECREF(l->in.type); ! 345: p->fn.cdim = l->fn.cdim; ! 346: p->fn.csiz = l->fn.csiz; ! 347: break; ! 348: ! 349: case UNARY AND: ! 350: switch( l->in.op ){ ! 351: ! 352: case UNARY MUL: ! 353: p->in.op = l->in.op = FREE; ! 354: p = l->in.left; ! 355: case NAME: ! 356: p->in.type = INCREF( l->in.type ); ! 357: p->fn.cdim = l->fn.cdim; ! 358: p->fn.csiz = l->fn.csiz; ! 359: break; ! 360: ! 361: case COMOP: ! 362: lr = buildtree( UNARY AND, l->in.right, NIL ); ! 363: p->in.op = l->in.op = FREE; ! 364: p = buildtree( COMOP, l->in.left, lr ); ! 365: break; ! 366: ! 367: case QUEST: ! 368: lr = buildtree( UNARY AND, l->in.right->in.right, NIL ); ! 369: ll = buildtree( UNARY AND, l->in.right->in.left, NIL ); ! 370: p->in.op = l->in.op = l->in.right->in.op = FREE; ! 371: p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) ); ! 372: break; ! 373: ! 374: # ifdef ADDROREG ! 375: case OREG: ! 376: /* OREG was built in clocal() ! 377: * for an auto or formal parameter ! 378: * now its address is being taken ! 379: * local code must unwind it ! 380: * back to PLUS/MINUS REG ICON ! 381: * according to local conventions ! 382: */ ! 383: { ! 384: extern NODE * addroreg(); ! 385: p->in.op = FREE; ! 386: p = addroreg( l ); ! 387: } ! 388: break; ! 389: ! 390: # endif ! 391: default: ! 392: uerror( "unacceptable operand of &" ); ! 393: break; ! 394: } ! 395: break; ! 396: ! 397: case LS: ! 398: case RS: ! 399: case ASG LS: ! 400: case ASG RS: ! 401: if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT) ! 402: p->in.right = makety(p->in.right, INT, 0, INT ); ! 403: break; ! 404: ! 405: case RETURN: ! 406: case ASSIGN: ! 407: case CAST: ! 408: /* structure assignment */ ! 409: /* take the addresses of the two sides; then make an ! 410: /* operator using STASG and ! 411: /* the addresses of left and right */ ! 412: ! 413: { ! 414: register TWORD t; ! 415: register int d, s; ! 416: ! 417: if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" ); ! 418: ! 419: r = buildtree( UNARY AND, r, NIL ); ! 420: t = r->in.type; ! 421: d = r->fn.cdim; ! 422: s = r->fn.csiz; ! 423: ! 424: l = block( STASG, l, r, t, d, s ); ! 425: ! 426: if( o == RETURN ){ ! 427: p->in.op = FREE; ! 428: p = l; ! 429: break; ! 430: } ! 431: ! 432: p->in.op = UNARY MUL; ! 433: p->in.left = l; ! 434: p->in.right = NIL; ! 435: break; ! 436: } ! 437: case COLON: ! 438: /* structure colon */ ! 439: ! 440: if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" ); ! 441: break; ! 442: ! 443: case CALL: ! 444: p->in.right = r = strargs( p->in.right ); ! 445: case UNARY CALL: ! 446: if( !ISPTR(l->in.type)) uerror("illegal function"); ! 447: p->in.type = DECREF(l->in.type); ! 448: if( !ISFTN(p->in.type)) uerror("illegal function"); ! 449: p->in.type = DECREF( p->in.type ); ! 450: p->fn.cdim = l->fn.cdim; ! 451: p->fn.csiz = l->fn.csiz; ! 452: if( l->in.op == UNARY AND && l->in.left->in.op == NAME && ! 453: l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME && ! 454: ( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){ ! 455: p->in.op += (FORTCALL-CALL); ! 456: } ! 457: if( p->in.type == STRTY || p->in.type == UNIONTY ){ ! 458: /* function returning structure */ ! 459: /* make function really return ptr to str., with * */ ! 460: ! 461: p->in.op += STCALL-CALL; ! 462: p->in.type = INCREF( p->in.type ); ! 463: p = buildtree( UNARY MUL, p, NIL ); ! 464: ! 465: } ! 466: break; ! 467: ! 468: default: ! 469: cerror( "other code %d", o ); ! 470: } ! 471: ! 472: } ! 473: ! 474: if( actions & CVTO ) p = oconvert(p); ! 475: p = clocal(p); ! 476: ! 477: # ifndef BUG1 ! 478: if( bdebug ) fwalk( p, eprint, 0 ); ! 479: # endif ! 480: ! 481: return(p); ! 482: ! 483: } ! 484: ! 485: NODE * ! 486: strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */ ! 487: ! 488: if( p->in.op == CM ){ ! 489: p->in.left = strargs( p->in.left ); ! 490: p->in.right = strargs( p->in.right ); ! 491: return( p ); ! 492: } ! 493: ! 494: if( p->in.type == STRTY || p->in.type == UNIONTY ){ ! 495: p = block( STARG, p, NIL, p->in.type, p->fn.cdim, p->fn.csiz ); ! 496: p->in.left = buildtree( UNARY AND, p->in.left, NIL ); ! 497: p = clocal(p); ! 498: } ! 499: return( p ); ! 500: } ! 501: ! 502: chkstr( i, j, type ) TWORD type; { ! 503: /* is the MOS or MOU at stab[i] OK for strict reference by a ptr */ ! 504: /* i has been checked to contain a MOS or MOU */ ! 505: /* j is the index in dimtab of the members... */ ! 506: int k, kk; ! 507: ! 508: extern int ddebug; ! 509: ! 510: # ifndef BUG1 ! 511: #ifndef FLEXNAMES ! 512: if( ddebug > 1 ) printf( "chkstr( %.8s(%d), %d )\n", stab[i].sname, i, j ); ! 513: #else ! 514: if( ddebug > 1 ) printf( "chkstr( %s(%d), %d )\n", stab[i].sname, i, j ); ! 515: #endif ! 516: # endif ! 517: if( (k = j) < 0 ) uerror( "undefined structure or union" ); ! 518: else { ! 519: for( ; (kk = dimtab[k] ) >= 0; ++k ){ ! 520: if( kk >= SYMTSZ ){ ! 521: cerror( "gummy structure" ); ! 522: return(1); ! 523: } ! 524: if( kk == i ) return( 1 ); ! 525: switch( stab[kk].stype ){ ! 526: ! 527: case STRTY: ! 528: case UNIONTY: ! 529: if( type == STRTY ) continue; /* no recursive looking for strs */ ! 530: if( hflag && chkstr( i, dimtab[stab[kk].sizoff+1], stab[kk].stype ) ){ ! 531: if( stab[kk].sname[0] == '$' ) return(0); /* $FAKE */ ! 532: werror( ! 533: #ifndef FLEXNAMES ! 534: "illegal member use: perhaps %.8s.%.8s?", ! 535: #else ! 536: "illegal member use: perhaps %s.%s?", ! 537: #endif ! 538: stab[kk].sname, stab[i].sname ); ! 539: return(1); ! 540: } ! 541: } ! 542: } ! 543: } ! 544: return( 0 ); ! 545: } ! 546: ! 547: conval( p, o, q ) register NODE *p, *q; { ! 548: /* apply the op o to the lval part of p; if binary, rhs is val */ ! 549: int i, u; ! 550: CONSZ val; ! 551: unsigned long uval; ! 552: ! 553: val = q->tn.lval; ! 554: u = ISUNSIGNED(p->in.type) || ISUNSIGNED(q->in.type); ! 555: if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); ! 556: ! 557: if( p->tn.rval != NONAME && q->tn.rval != NONAME ) return(0); ! 558: if( q->tn.rval != NONAME && o!=PLUS ) return(0); ! 559: if( p->tn.rval != NONAME && o!=PLUS && o!=MINUS ) return(0); ! 560: ! 561: switch( o ){ ! 562: ! 563: case PLUS: ! 564: p->tn.lval += val; ! 565: if( p->tn.rval == NONAME ){ ! 566: p->tn.rval = q->tn.rval; ! 567: p->in.type = q->in.type; ! 568: } ! 569: break; ! 570: case MINUS: ! 571: p->tn.lval -= val; ! 572: break; ! 573: case MUL: ! 574: if ( u ){ ! 575: uval = val; ! 576: p->tn.lval *= uval; ! 577: } ! 578: else ! 579: p->tn.lval *= val; ! 580: break; ! 581: case DIV: ! 582: if( val == 0 ) uerror( "division by 0" ); ! 583: else p->tn.lval /= val; ! 584: break; ! 585: case MOD: ! 586: if( val == 0 ) uerror( "division by 0" ); ! 587: else p->tn.lval %= val; ! 588: break; ! 589: case AND: ! 590: p->tn.lval &= val; ! 591: break; ! 592: case OR: ! 593: p->tn.lval |= val; ! 594: break; ! 595: case ER: ! 596: p->tn.lval ^= val; ! 597: break; ! 598: case LS: ! 599: i = val; ! 600: p->tn.lval = p->tn.lval << i; ! 601: break; ! 602: case RS: ! 603: i = val; ! 604: p->tn.lval = p->tn.lval >> i; ! 605: break; ! 606: ! 607: case UNARY MINUS: ! 608: p->tn.lval = - p->tn.lval; ! 609: break; ! 610: case COMPL: ! 611: p->tn.lval = ~p->tn.lval; ! 612: break; ! 613: case NOT: ! 614: p->tn.lval = !p->tn.lval; ! 615: break; ! 616: case LT: ! 617: p->tn.lval = p->tn.lval < val; ! 618: break; ! 619: case LE: ! 620: p->tn.lval = p->tn.lval <= val; ! 621: break; ! 622: case GT: ! 623: p->tn.lval = p->tn.lval > val; ! 624: break; ! 625: case GE: ! 626: p->tn.lval = p->tn.lval >= val; ! 627: break; ! 628: case ULT: ! 629: p->tn.lval = (p->tn.lval-val)<0; ! 630: break; ! 631: case ULE: ! 632: p->tn.lval = (p->tn.lval-val)<=0; ! 633: break; ! 634: case UGE: ! 635: p->tn.lval = (p->tn.lval-val)>=0; ! 636: break; ! 637: case UGT: ! 638: p->tn.lval = (p->tn.lval-val)>0; ! 639: break; ! 640: case EQ: ! 641: p->tn.lval = p->tn.lval == val; ! 642: break; ! 643: case NE: ! 644: p->tn.lval = p->tn.lval != val; ! 645: break; ! 646: default: ! 647: return(0); ! 648: } ! 649: return(1); ! 650: } ! 651: ! 652: chkpun(p) register NODE *p; { ! 653: ! 654: /* checks p for the existance of a pun */ ! 655: ! 656: /* this is called when the op of p is ASSIGN, RETURN, CAST, COLON, or relational */ ! 657: ! 658: /* one case is when enumerations are used: this applies only to lint */ ! 659: /* in the other case, one operand is a pointer, the other integer type */ ! 660: /* we check that this integer is in fact a constant zero... */ ! 661: ! 662: /* in the case of ASSIGN, any assignment of pointer to integer is illegal */ ! 663: /* this falls out, because the LHS is never 0 */ ! 664: ! 665: register NODE *q; ! 666: register int t1, t2; ! 667: register int d1, d2; ! 668: ! 669: t1 = p->in.left->in.type; ! 670: t2 = p->in.right->in.type; ! 671: ! 672: if( t1==ENUMTY || t2==ENUMTY ) { /* check for enumerations */ ! 673: if( logop( p->in.op ) && p->in.op != EQ && p->in.op != NE ) { ! 674: uerror( "illegal comparison of enums" ); ! 675: return; ! 676: } ! 677: if( t1==ENUMTY && t2==ENUMTY && p->in.left->fn.csiz==p->in.right->fn.csiz ) return; ! 678: werror( "enumeration type clash, operator %s", opst[p->in.op] ); ! 679: return; ! 680: } ! 681: ! 682: if( ISPTR(t1) || ISARY(t1) ) q = p->in.right; ! 683: else q = p->in.left; ! 684: ! 685: if( !ISPTR(q->in.type) && !ISARY(q->in.type) ){ ! 686: if( q->in.op != ICON || q->tn.lval != 0 ){ ! 687: werror( "illegal combination of pointer and integer, op %s", ! 688: opst[p->in.op] ); ! 689: } ! 690: } ! 691: else { ! 692: d1 = p->in.left->fn.cdim; ! 693: d2 = p->in.right->fn.cdim; ! 694: for( ;; ){ ! 695: if( t1 == t2 ) {; ! 696: if( p->in.left->fn.csiz != p->in.right->fn.csiz ) { ! 697: werror( "illegal structure pointer combination" ); ! 698: } ! 699: return; ! 700: } ! 701: if( ISARY(t1) || ISPTR(t1) ){ ! 702: if( !ISARY(t2) && !ISPTR(t2) ) break; ! 703: if( ISARY(t1) && ISARY(t2) && dimtab[d1] != dimtab[d2] ){ ! 704: werror( "illegal array size combination" ); ! 705: return; ! 706: } ! 707: if( ISARY(t1) ) ++d1; ! 708: if( ISARY(t2) ) ++d2; ! 709: } ! 710: else break; ! 711: t1 = DECREF(t1); ! 712: t2 = DECREF(t2); ! 713: } ! 714: werror( "illegal pointer combination" ); ! 715: } ! 716: ! 717: } ! 718: ! 719: NODE * ! 720: stref( p ) register NODE *p; { ! 721: ! 722: TWORD t; ! 723: int d, s, dsc, align; ! 724: OFFSZ off; ! 725: register struct symtab *q; ! 726: ! 727: /* make p->x */ ! 728: /* this is also used to reference automatic variables */ ! 729: ! 730: q = &stab[p->in.right->tn.rval]; ! 731: p->in.right->in.op = FREE; ! 732: p->in.op = FREE; ! 733: p = pconvert( p->in.left ); ! 734: ! 735: /* make p look like ptr to x */ ! 736: ! 737: if( !ISPTR(p->in.type)){ ! 738: p->in.type = PTR+UNIONTY; ! 739: } ! 740: ! 741: t = INCREF( q->stype ); ! 742: d = q->dimoff; ! 743: s = q->sizoff; ! 744: ! 745: p = makety( p, t, d, s ); ! 746: ! 747: /* compute the offset to be added */ ! 748: ! 749: off = q->offset; ! 750: dsc = q->sclass; ! 751: ! 752: if( dsc & FIELD ) { /* normalize offset */ ! 753: align = ALINT; ! 754: s = INT; ! 755: off = (off/align)*align; ! 756: } ! 757: if( off != 0 ) p = clocal( block( PLUS, p, offcon( off, t, d, s ), t, d, s ) ); ! 758: ! 759: p = buildtree( UNARY MUL, p, NIL ); ! 760: ! 761: /* if field, build field info */ ! 762: ! 763: if( dsc & FIELD ){ ! 764: p = block( FLD, p, NIL, q->stype, 0, q->sizoff ); ! 765: p->tn.rval = PKFIELD( dsc&FLDSIZ, q->offset%align ); ! 766: } ! 767: ! 768: return( clocal(p) ); ! 769: } ! 770: ! 771: notlval(p) register NODE *p; { ! 772: ! 773: /* return 0 if p an lvalue, 1 otherwise */ ! 774: ! 775: again: ! 776: ! 777: switch( p->in.op ){ ! 778: ! 779: case FLD: ! 780: p = p->in.left; ! 781: goto again; ! 782: ! 783: case UNARY MUL: ! 784: /* fix the &(a=b) bug, given that a and b are structures */ ! 785: if( p->in.left->in.op == STASG ) return( 1 ); ! 786: /* and the f().a bug, given that f returns a structure */ ! 787: if( p->in.left->in.op == UNARY STCALL || ! 788: p->in.left->in.op == STCALL ) return( 1 ); ! 789: case NAME: ! 790: case OREG: ! 791: if( ISARY(p->in.type) || ISFTN(p->in.type) ) return(1); ! 792: case REG: ! 793: return(0); ! 794: ! 795: default: ! 796: return(1); ! 797: ! 798: } ! 799: ! 800: } ! 801: ! 802: NODE * ! 803: bcon( i ){ /* make a constant node with value i */ ! 804: register NODE *p; ! 805: ! 806: p = block( ICON, NIL, NIL, INT, 0, INT ); ! 807: p->tn.lval = i; ! 808: p->tn.rval = NONAME; ! 809: return( clocal(p) ); ! 810: } ! 811: ! 812: NODE * ! 813: bpsize(p) register NODE *p; { ! 814: return( offcon( psize(p), p->in.type, p->fn.cdim, p->fn.csiz ) ); ! 815: } ! 816: ! 817: OFFSZ ! 818: psize( p ) NODE *p; { ! 819: /* p is a node of type pointer; psize returns the ! 820: size of the thing pointed to */ ! 821: ! 822: if( !ISPTR(p->in.type) ){ ! 823: uerror( "pointer required"); ! 824: return( SZINT ); ! 825: } ! 826: /* note: no pointers to fields */ ! 827: return( tsize( DECREF(p->in.type), p->fn.cdim, p->fn.csiz ) ); ! 828: } ! 829: ! 830: NODE * ! 831: convert( p, f ) register NODE *p; { ! 832: /* convert an operand of p ! 833: f is either CVTL or CVTR ! 834: operand has type int, and is converted by the size of the other side ! 835: */ ! 836: ! 837: register NODE *q, *r; ! 838: ! 839: q = (f==CVTL)?p->in.left:p->in.right; ! 840: ! 841: r = block( PMCONV, ! 842: q, bpsize(f==CVTL?p->in.right:p->in.left), INT, 0, INT ); ! 843: r = clocal(r); ! 844: if( f == CVTL ) ! 845: p->in.left = r; ! 846: else ! 847: p->in.right = r; ! 848: return(p); ! 849: ! 850: } ! 851: ! 852: econvert( p ) register NODE *p; { ! 853: ! 854: /* change enums to ints, or appropriate types */ ! 855: ! 856: register TWORD ty; ! 857: ! 858: if( (ty=BTYPE(p->in.type)) == ENUMTY || ty == MOETY ) { ! 859: if( dimtab[ p->fn.csiz ] == SZCHAR ) ty = CHAR; ! 860: else if( dimtab[ p->fn.csiz ] == SZINT ) ty = INT; ! 861: else if( dimtab[ p->fn.csiz ] == SZSHORT ) ty = SHORT; ! 862: else ty = LONG; ! 863: ty = ctype( ty ); ! 864: p->fn.csiz = ty; ! 865: MODTYPE(p->in.type,ty); ! 866: if( p->in.op == ICON && ty != LONG ) p->in.type = p->fn.csiz = INT; ! 867: } ! 868: } ! 869: ! 870: NODE * ! 871: pconvert( p ) register NODE *p; { ! 872: ! 873: /* if p should be changed into a pointer, do so */ ! 874: ! 875: if( ISARY( p->in.type) ){ ! 876: p->in.type = DECREF( p->in.type ); ! 877: ++p->fn.cdim; ! 878: return( buildtree( UNARY AND, p, NIL ) ); ! 879: } ! 880: if( ISFTN( p->in.type) ) ! 881: return( buildtree( UNARY AND, p, NIL ) ); ! 882: ! 883: return( p ); ! 884: } ! 885: ! 886: NODE * ! 887: oconvert(p) register NODE *p; { ! 888: /* convert the result itself: used for pointer and unsigned */ ! 889: ! 890: switch(p->in.op) { ! 891: ! 892: case LE: ! 893: case LT: ! 894: case GE: ! 895: case GT: ! 896: if( ISUNSIGNED(p->in.left->in.type) || ISUNSIGNED(p->in.right->in.type) ) p->in.op += (ULE-LE); ! 897: case EQ: ! 898: case NE: ! 899: return( p ); ! 900: ! 901: case MINUS: ! 902: return( clocal( block( PVCONV, ! 903: p, bpsize(p->in.left), INT, 0, INT ) ) ); ! 904: } ! 905: ! 906: cerror( "illegal oconvert: %d", p->in.op ); ! 907: ! 908: return(p); ! 909: } ! 910: ! 911: NODE * ! 912: ptmatch(p) register NODE *p; { ! 913: ! 914: /* makes the operands of p agree; they are ! 915: either pointers or integers, by this time */ ! 916: /* with MINUS, the sizes must be the same */ ! 917: /* with COLON, the types must be the same */ ! 918: ! 919: TWORD t1, t2, t; ! 920: int o, d2, d, s2, s; ! 921: ! 922: o = p->in.op; ! 923: t = t1 = p->in.left->in.type; ! 924: t2 = p->in.right->in.type; ! 925: d = p->in.left->fn.cdim; ! 926: d2 = p->in.right->fn.cdim; ! 927: s = p->in.left->fn.csiz; ! 928: s2 = p->in.right->fn.csiz; ! 929: ! 930: switch( o ){ ! 931: ! 932: case ASSIGN: ! 933: case RETURN: ! 934: case CAST: ! 935: { break; } ! 936: ! 937: case MINUS: ! 938: { if( psize(p->in.left) != psize(p->in.right) ){ ! 939: uerror( "illegal pointer subtraction"); ! 940: } ! 941: break; ! 942: } ! 943: case COLON: ! 944: { if( t1 != t2 ) uerror( "illegal types in :"); ! 945: break; ! 946: } ! 947: default: /* must work harder: relationals or comparisons */ ! 948: ! 949: if( !ISPTR(t1) ){ ! 950: t = t2; ! 951: d = d2; ! 952: s = s2; ! 953: break; ! 954: } ! 955: if( !ISPTR(t2) ){ ! 956: break; ! 957: } ! 958: ! 959: /* both are pointers */ ! 960: if( talign(t2,s2) < talign(t,s) ){ ! 961: t = t2; ! 962: s = s2; ! 963: } ! 964: break; ! 965: } ! 966: ! 967: p->in.left = makety( p->in.left, t, d, s ); ! 968: p->in.right = makety( p->in.right, t, d, s ); ! 969: if( o!=MINUS && !logop(o) ){ ! 970: ! 971: p->in.type = t; ! 972: p->fn.cdim = d; ! 973: p->fn.csiz = s; ! 974: } ! 975: ! 976: return(clocal(p)); ! 977: } ! 978: ! 979: int tdebug = 0; ! 980: ! 981: NODE * ! 982: tymatch(p) register NODE *p; { ! 983: ! 984: /* satisfy the types of various arithmetic binary ops */ ! 985: ! 986: /* rules are: ! 987: if assignment, op, type of LHS ! 988: if any float or doubles, make double ! 989: if any longs, make long ! 990: otherwise, make int ! 991: if either operand is unsigned, the result is... ! 992: */ ! 993: ! 994: register TWORD t1, t2, t, tu; ! 995: register int o, u; ! 996: ! 997: o = p->in.op; ! 998: ! 999: t1 = p->in.left->in.type; ! 1000: t2 = p->in.right->in.type; ! 1001: if( (t1==UNDEF || t2==UNDEF) && o!=CAST ) ! 1002: uerror("void type illegal in expression"); ! 1003: ! 1004: u = 0; ! 1005: if( ISUNSIGNED(t1) ){ ! 1006: u = 1; ! 1007: t1 = DEUNSIGN(t1); ! 1008: } ! 1009: if( ISUNSIGNED(t2) ){ ! 1010: u = 1; ! 1011: t2 = DEUNSIGN(t2); ! 1012: } ! 1013: ! 1014: if( ( t1 == CHAR || t1 == SHORT ) && o!= RETURN ) t1 = INT; ! 1015: if( t2 == CHAR || t2 == SHORT ) t2 = INT; ! 1016: ! 1017: if( t1==DOUBLE || t1==FLOAT || t2==DOUBLE || t2==FLOAT ) t = DOUBLE; ! 1018: else if( t1==LONG || t2==LONG ) t = LONG; ! 1019: else t = INT; ! 1020: ! 1021: if( asgop(o) ){ ! 1022: tu = p->in.left->in.type; ! 1023: t = t1; ! 1024: } ! 1025: else { ! 1026: tu = (u && UNSIGNABLE(t))?ENUNSIGN(t):t; ! 1027: } ! 1028: ! 1029: /* because expressions have values that are at least as wide ! 1030: as INT or UNSIGNED, the only conversions needed ! 1031: are those involving FLOAT/DOUBLE, and those ! 1032: from LONG to INT and ULONG to UNSIGNED */ ! 1033: ! 1034: if( t != t1 ) p->in.left = makety( p->in.left, tu, 0, (int)tu ); ! 1035: ! 1036: if( t != t2 || o==CAST ) p->in.right = makety( p->in.right, tu, 0, (int)tu ); ! 1037: ! 1038: if( asgop(o) ){ ! 1039: p->in.type = p->in.left->in.type; ! 1040: p->fn.cdim = p->in.left->fn.cdim; ! 1041: p->fn.csiz = p->in.left->fn.csiz; ! 1042: } ! 1043: else if( !logop(o) ){ ! 1044: p->in.type = tu; ! 1045: p->fn.cdim = 0; ! 1046: p->fn.csiz = t; ! 1047: } ! 1048: ! 1049: # ifndef BUG1 ! 1050: if( tdebug ) printf( "tymatch(%o): %o %s %o => %o\n",p,t1,opst[o],t2,tu ); ! 1051: # endif ! 1052: ! 1053: return(p); ! 1054: } ! 1055: ! 1056: NODE * ! 1057: makety( p, t, d, s ) register NODE *p; TWORD t; { ! 1058: /* make p into type t by inserting a conversion */ ! 1059: ! 1060: if( p->in.type == ENUMTY && p->in.op == ICON ) econvert(p); ! 1061: if( t == p->in.type ){ ! 1062: p->fn.cdim = d; ! 1063: p->fn.csiz = s; ! 1064: return( p ); ! 1065: } ! 1066: ! 1067: if( t & TMASK ){ ! 1068: /* non-simple type */ ! 1069: return( block( PCONV, p, NIL, t, d, s ) ); ! 1070: } ! 1071: ! 1072: if( p->in.op == ICON ){ ! 1073: if( t==DOUBLE||t==FLOAT ){ ! 1074: p->in.op = FCON; ! 1075: if( ISUNSIGNED(p->in.type) ){ ! 1076: p->fpn.dval = (unsigned CONSZ) p->tn.lval; ! 1077: } ! 1078: else { ! 1079: p->fpn.dval = p->tn.lval; ! 1080: } ! 1081: ! 1082: p->in.type = p->fn.csiz = t; ! 1083: return( clocal(p) ); ! 1084: } ! 1085: } ! 1086: ! 1087: return( block( SCONV, p, NIL, t, d, s ) ); ! 1088: ! 1089: } ! 1090: ! 1091: NODE * ! 1092: block( o, l, r, t, d, s ) register NODE *l, *r; TWORD t; { ! 1093: ! 1094: register NODE *p; ! 1095: ! 1096: p = talloc(); ! 1097: p->in.op = o; ! 1098: p->in.left = l; ! 1099: p->in.right = r; ! 1100: p->in.type = t; ! 1101: p->fn.cdim = d; ! 1102: p->fn.csiz = s; ! 1103: return(p); ! 1104: } ! 1105: ! 1106: icons(p) register NODE *p; { ! 1107: /* if p is an integer constant, return its value */ ! 1108: int val; ! 1109: ! 1110: if( p->in.op != ICON ){ ! 1111: uerror( "constant expected"); ! 1112: val = 1; ! 1113: } ! 1114: else { ! 1115: val = p->tn.lval; ! 1116: if( val != p->tn.lval ) uerror( "constant too big for cross-compiler" ); ! 1117: } ! 1118: tfree( p ); ! 1119: return(val); ! 1120: } ! 1121: ! 1122: /* the intent of this table is to examine the ! 1123: operators, and to check them for ! 1124: correctness. ! 1125: ! 1126: The table is searched for the op and the ! 1127: modified type (where this is one of the ! 1128: types INT (includes char and short), LONG, ! 1129: DOUBLE (includes FLOAT), and POINTER ! 1130: ! 1131: The default action is to make the node type integer ! 1132: ! 1133: The actions taken include: ! 1134: PUN check for puns ! 1135: CVTL convert the left operand ! 1136: CVTR convert the right operand ! 1137: TYPL the type is determined by the left operand ! 1138: TYPR the type is determined by the right operand ! 1139: TYMATCH force type of left and right to match, by inserting conversions ! 1140: PTMATCH like TYMATCH, but for pointers ! 1141: LVAL left operand must be lval ! 1142: CVTO convert the op ! 1143: NCVT do not convert the operands ! 1144: OTHER handled by code ! 1145: NCVTR convert the left operand, not the right... ! 1146: ! 1147: */ ! 1148: ! 1149: # define MINT 01 /* integer */ ! 1150: # define MDBI 02 /* integer or double */ ! 1151: # define MSTR 04 /* structure */ ! 1152: # define MPTR 010 /* pointer */ ! 1153: # define MPTI 020 /* pointer or integer */ ! 1154: # define MENU 040 /* enumeration variable or member */ ! 1155: ! 1156: opact( p ) NODE *p; { ! 1157: ! 1158: register int mt12, mt1, mt2, o; ! 1159: ! 1160: mt12 = 0; ! 1161: ! 1162: switch( optype(o=p->in.op) ){ ! 1163: ! 1164: case BITYPE: ! 1165: mt12=mt2 = moditype( p->in.right->in.type ); ! 1166: case UTYPE: ! 1167: mt12 &= (mt1 = moditype( p->in.left->in.type )); ! 1168: ! 1169: } ! 1170: ! 1171: switch( o ){ ! 1172: ! 1173: case NAME : ! 1174: case STRING : ! 1175: case ICON : ! 1176: case FCON : ! 1177: case CALL : ! 1178: case UNARY CALL: ! 1179: case UNARY MUL: ! 1180: { return( OTHER ); } ! 1181: case UNARY MINUS: ! 1182: if( mt1 & MDBI ) return( TYPL ); ! 1183: break; ! 1184: ! 1185: case COMPL: ! 1186: if( mt1 & MINT ) return( TYPL ); ! 1187: break; ! 1188: ! 1189: case UNARY AND: ! 1190: { return( NCVT+OTHER ); } ! 1191: case INIT: ! 1192: case CM: ! 1193: case NOT: ! 1194: case CBRANCH: ! 1195: case ANDAND: ! 1196: case OROR: ! 1197: return( 0 ); ! 1198: ! 1199: case MUL: ! 1200: case DIV: ! 1201: if( mt12 & MDBI ) return( TYMATCH ); ! 1202: break; ! 1203: ! 1204: case MOD: ! 1205: case AND: ! 1206: case OR: ! 1207: case ER: ! 1208: if( mt12 & MINT ) return( TYMATCH ); ! 1209: break; ! 1210: ! 1211: case LS: ! 1212: case RS: ! 1213: if( mt12 & MINT ) return( TYMATCH+OTHER ); ! 1214: break; ! 1215: ! 1216: case EQ: ! 1217: case NE: ! 1218: case LT: ! 1219: case LE: ! 1220: case GT: ! 1221: case GE: ! 1222: if( (mt1&MENU)||(mt2&MENU) ) return( PTMATCH+PUN+NCVT ); ! 1223: if( mt12 & MDBI ) return( TYMATCH+CVTO ); ! 1224: else if( mt12 & MPTR ) return( PTMATCH+PUN ); ! 1225: else if( mt12 & MPTI ) return( PTMATCH+PUN ); ! 1226: else break; ! 1227: ! 1228: case QUEST: ! 1229: case COMOP: ! 1230: if( mt2&MENU ) return( TYPR+NCVTR ); ! 1231: return( TYPR ); ! 1232: ! 1233: case STREF: ! 1234: return( NCVTR+OTHER ); ! 1235: ! 1236: case FORCE: ! 1237: return( TYPL ); ! 1238: ! 1239: case COLON: ! 1240: if( mt12 & MENU ) return( NCVT+PUN+PTMATCH ); ! 1241: else if( mt12 & MDBI ) return( TYMATCH ); ! 1242: else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); ! 1243: else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); ! 1244: else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); ! 1245: else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); ! 1246: break; ! 1247: ! 1248: case ASSIGN: ! 1249: case RETURN: ! 1250: if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); ! 1251: case CAST: ! 1252: if(o==CAST && mt1==0)return(TYPL+TYMATCH); ! 1253: if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); ! 1254: else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN ); ! 1255: else if( mt12 == 0 ) break; ! 1256: else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN ); ! 1257: else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); ! 1258: break; ! 1259: ! 1260: case ASG LS: ! 1261: case ASG RS: ! 1262: if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); ! 1263: break; ! 1264: ! 1265: case ASG MUL: ! 1266: case ASG DIV: ! 1267: if( mt12 & MDBI ) return( LVAL+TYMATCH ); ! 1268: break; ! 1269: ! 1270: case ASG MOD: ! 1271: case ASG AND: ! 1272: case ASG OR: ! 1273: case ASG ER: ! 1274: if( mt12 & MINT ) return( LVAL+TYMATCH ); ! 1275: break; ! 1276: ! 1277: case ASG PLUS: ! 1278: case ASG MINUS: ! 1279: case INCR: ! 1280: case DECR: ! 1281: if( mt12 & MDBI ) return( TYMATCH+LVAL ); ! 1282: else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+LVAL+CVTR ); ! 1283: break; ! 1284: ! 1285: case MINUS: ! 1286: if( mt12 & MPTR ) return( CVTO+PTMATCH+PUN ); ! 1287: if( mt2 & MPTR ) break; ! 1288: case PLUS: ! 1289: if( mt12 & MDBI ) return( TYMATCH ); ! 1290: else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+CVTR ); ! 1291: else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+CVTL ); ! 1292: ! 1293: } ! 1294: uerror( "operands of %s have incompatible types", opst[o] ); ! 1295: return( NCVT ); ! 1296: } ! 1297: ! 1298: moditype( ty ) TWORD ty; { ! 1299: ! 1300: switch( ty ){ ! 1301: ! 1302: case TVOID: ! 1303: case UNDEF: ! 1304: return(0); /* type is void */ ! 1305: case ENUMTY: ! 1306: case MOETY: ! 1307: return( MENU ); ! 1308: ! 1309: case STRTY: ! 1310: case UNIONTY: ! 1311: return( MSTR ); ! 1312: ! 1313: case CHAR: ! 1314: case SHORT: ! 1315: case UCHAR: ! 1316: case USHORT: ! 1317: return( MINT|MPTI|MDBI ); ! 1318: case UNSIGNED: ! 1319: case ULONG: ! 1320: case INT: ! 1321: case LONG: ! 1322: return( MINT|MDBI|MPTI ); ! 1323: case FLOAT: ! 1324: case DOUBLE: ! 1325: return( MDBI ); ! 1326: default: ! 1327: return( MPTR|MPTI ); ! 1328: ! 1329: } ! 1330: } ! 1331: ! 1332: NODE * ! 1333: doszof( p ) register NODE *p; { ! 1334: /* do sizeof p */ ! 1335: int i; ! 1336: ! 1337: /* whatever is the meaning of this if it is a bitfield? */ ! 1338: i = tsize( p->in.type, p->fn.cdim, p->fn.csiz )/SZCHAR; ! 1339: ! 1340: tfree(p); ! 1341: if( i <= 0 ) werror( "sizeof returns 0" ); ! 1342: return( bcon( i ) ); ! 1343: } ! 1344: ! 1345: # ifndef BUG2 ! 1346: eprint( p, down, a, b ) register NODE *p; int *a, *b; { ! 1347: register int ty; ! 1348: ! 1349: *a = *b = down+1; ! 1350: while( down > 1 ){ ! 1351: printf( "\t" ); ! 1352: down -= 2; ! 1353: } ! 1354: if( down ) printf( " " ); ! 1355: ! 1356: ty = optype( p->in.op ); ! 1357: ! 1358: printf("%o) %s, ", p, opst[p->in.op] ); ! 1359: if( ty == LTYPE ){ ! 1360: printf( CONFMT, p->tn.lval ); ! 1361: printf( ", %d, ", p->tn.rval ); ! 1362: } ! 1363: tprint( p->in.type ); ! 1364: printf( ", %d, %d\n", p->fn.cdim, p->fn.csiz ); ! 1365: } ! 1366: # endif ! 1367: ! 1368: # ifndef PRTDCON ! 1369: prtdcon( p ) register NODE *p; { ! 1370: int i; ! 1371: ! 1372: if( p->in.op == FCON ){ ! 1373: locctr( DATA ); ! 1374: defalign( ALDOUBLE ); ! 1375: deflab( i = getlab() ); ! 1376: # ifndef SFCON ! 1377: fincode( p->fpn.dval, SZDOUBLE ); ! 1378: p->in.type = DOUBLE; ! 1379: # else ! 1380: p->in.type = fincode( p->fpn.dval, 0 ); ! 1381: # endif ! 1382: p->tn.lval = 0; ! 1383: p->tn.rval = -i; ! 1384: p->in.op = NAME; ! 1385: } ! 1386: } ! 1387: # endif ! 1388: ! 1389: ! 1390: int edebug = 0; ! 1391: ecomp( p ) register NODE *p; { ! 1392: extern prtdcon(); ! 1393: ! 1394: # ifndef BUG2 ! 1395: if( edebug ) fwalk( p, eprint, 0 ); ! 1396: # endif ! 1397: if( !reached ){ ! 1398: werror( "statement not reached" ); ! 1399: reached = 1; ! 1400: } ! 1401: p = optim(p); ! 1402: walkf( p, prtdcon ); ! 1403: locctr( PROG ); ! 1404: ecode( p ); ! 1405: tfree(p); ! 1406: } ! 1407: ! 1408: # ifdef STDPRTREE ! 1409: # ifndef ONEPASS ! 1410: ! 1411: prtree(p) register NODE *p; { ! 1412: ! 1413: register struct symtab *q; ! 1414: register int ty; ! 1415: ! 1416: # ifdef MYPRTREE ! 1417: MYPRTREE(p); /* local action can be taken here; then return... */ ! 1418: #endif ! 1419: ! 1420: ty = optype(p->in.op); ! 1421: ! 1422: printf( "%d\t", p->in.op ); ! 1423: ! 1424: if( ty == LTYPE ) { ! 1425: printf( CONFMT, p->tn.lval ); ! 1426: printf( "\t" ); ! 1427: } ! 1428: if( ty != BITYPE ) { ! 1429: if( p->in.op == NAME || p->in.op == ICON ) printf( "0\t" ); ! 1430: else printf( "%d\t", p->tn.rval ); ! 1431: } ! 1432: ! 1433: printf( "%o\t", p->in.type ); ! 1434: ! 1435: /* handle special cases */ ! 1436: ! 1437: switch( p->in.op ){ ! 1438: ! 1439: case NAME: ! 1440: case ICON: ! 1441: /* print external name */ ! 1442: if( p->tn.rval == NONAME ) printf( "\n" ); ! 1443: else if( p->tn.rval >= 0 ){ ! 1444: q = &stab[p->tn.rval]; ! 1445: printf( "%s\n", exname(q->sname) ); ! 1446: } ! 1447: else { /* label */ ! 1448: printf( LABFMT, -p->tn.rval ); ! 1449: } ! 1450: break; ! 1451: ! 1452: case STARG: ! 1453: case STASG: ! 1454: case STCALL: ! 1455: case UNARY STCALL: ! 1456: /* print out size */ ! 1457: /* use lhs size, in order to avoid hassles with the structure `.' operator */ ! 1458: ! 1459: /* note: p->in.left not a field... */ ! 1460: printf( CONFMT, (CONSZ) tsize( STRTY, p->in.left->fn.cdim, p->in.left->fn.csiz ) ); ! 1461: printf( "\t%d\t\n", talign( STRTY, p->in.left->fn.csiz ) ); ! 1462: break; ! 1463: ! 1464: default: ! 1465: printf( "\n" ); ! 1466: } ! 1467: ! 1468: if( ty != LTYPE ) prtree( p->in.left ); ! 1469: if( ty == BITYPE ) prtree( p->in.right ); ! 1470: ! 1471: } ! 1472: ! 1473: # else ! 1474: ! 1475: p2tree(p) register NODE *p; { ! 1476: register int ty; ! 1477: ! 1478: # ifdef MYP2TREE ! 1479: MYP2TREE(p); /* local action can be taken here; then return... */ ! 1480: # endif ! 1481: ! 1482: ty = optype(p->in.op); ! 1483: ! 1484: switch( p->in.op ){ ! 1485: ! 1486: case NAME: ! 1487: case ICON: ! 1488: #ifndef FLEXNAMES ! 1489: if( p->tn.rval == NONAME ) p->in.name[0] = '\0'; ! 1490: #else ! 1491: if( p->tn.rval == NONAME ) p->in.name = ""; ! 1492: #endif ! 1493: else if( p->tn.rval >= 0 ){ /* copy name from exname */ ! 1494: register char *cp; ! 1495: register int i; ! 1496: cp = exname( stab[p->tn.rval].sname ); ! 1497: #ifndef FLEXNAMES ! 1498: for( i=0; i<NCHNAM; ++i ) p->in.name[i] = *cp++; ! 1499: #else ! 1500: p->in.name = tstr(cp); ! 1501: #endif ! 1502: } ! 1503: #ifndef FLEXNAMES ! 1504: else sprintf( p->in.name, LABFMT, -p->tn.rval ); ! 1505: #else ! 1506: else { ! 1507: char temp[32]; ! 1508: sprintf( temp, LABFMT, -p->tn.rval ); ! 1509: p->in.name = tstr(temp); ! 1510: } ! 1511: #endif ! 1512: break; ! 1513: ! 1514: case STARG: ! 1515: case STASG: ! 1516: case STCALL: ! 1517: case UNARY STCALL: ! 1518: /* set up size parameters */ ! 1519: p->stn.stsize = (tsize(STRTY,p->in.left->fn.cdim,p->in.left->fn.csiz)+SZCHAR-1)/SZCHAR; ! 1520: p->stn.stalign = talign(STRTY,p->in.left->fn.csiz)/SZCHAR; ! 1521: break; ! 1522: ! 1523: case REG: ! 1524: rbusy( p->tn.rval, p->in.type ); ! 1525: default: ! 1526: #ifndef FLEXNAMES ! 1527: p->in.name[0] = '\0'; ! 1528: #else ! 1529: p->in.name = ""; ! 1530: #endif ! 1531: } ! 1532: ! 1533: p->in.rall = NOPREF; ! 1534: ! 1535: if( ty != LTYPE ) p2tree( p->in.left ); ! 1536: if( ty == BITYPE ) p2tree( p->in.right ); ! 1537: } ! 1538: ! 1539: # endif ! 1540: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.