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