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