1 /* Id: trees.c,v 1.248 2010/06/02 10:39:52 ragge Exp */ 2 /* $NetBSD: trees.c,v 1.1.1.3 2010/06/03 18:57:45 plunky Exp $ */ 3 /* 4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 37 * Redistributions of source code and documentation must retain the above 38 * copyright notice, this list of conditions and the following disclaimer. 39 * Redistributions in binary form must reproduce the above copyright 40 * notice, this list of conditionsand the following disclaimer in the 41 * documentation and/or other materials provided with the distribution. 42 * All advertising materials mentioning features or use of this software 43 * must display the following acknowledgement: 44 * This product includes software developed or owned by Caldera 45 * International, Inc. 46 * Neither the name of Caldera International, Inc. nor the names of other 47 * contributors may be used to endorse or promote products derived from 48 * this software without specific prior written permission. 49 * 50 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA 51 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 54 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE 55 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, 59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 60 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 /* 64 * Some of the changes from 32V include: 65 * - Understand "void" as type. 66 * - Handle enums as ints everywhere. 67 * - Convert some C-specific ops into branches. 68 */ 69 70 # include "pass1.h" 71 # include "pass2.h" 72 73 # include <stdarg.h> 74 # include <string.h> 75 76 static void chkpun(NODE *p); 77 static int opact(NODE *p); 78 static int moditype(TWORD); 79 static NODE *strargs(NODE *); 80 static void rmcops(NODE *p); 81 static void putjops(NODE *, void *); 82 static struct symtab *findmember(struct symtab *, char *); 83 int inftn; /* currently between epilog/prolog */ 84 85 static char *tnames[] = { 86 "undef", 87 "farg", 88 "char", 89 "unsigned char", 90 "short", 91 "unsigned short", 92 "int", 93 "unsigned int", 94 "long", 95 "unsigned long", 96 "long long", 97 "unsigned long long", 98 "float", 99 "double", 100 "long double", 101 "strty", 102 "unionty", 103 "enumty", 104 "moety", 105 "void", 106 "signed", /* pass1 */ 107 "bool", /* pass1 */ 108 "fimag", /* pass1 */ 109 "dimag", /* pass1 */ 110 "limag", /* pass1 */ 111 "fcomplex", /* pass1 */ 112 "dcomplex", /* pass1 */ 113 "lcomplex", /* pass1 */ 114 "enumty", /* pass1 */ 115 "?", "?" 116 }; 117 118 /* some special actions, used in finding the type of nodes */ 119 # define NCVT 01 120 # define PUN 02 121 # define TYPL 04 122 # define TYPR 010 123 # define TYMATCH 040 124 # define LVAL 0100 125 # define CVTO 0200 126 # define CVTL 0400 127 # define CVTR 01000 128 # define PTMATCH 02000 129 # define OTHER 04000 130 # define NCVTR 010000 131 132 /* node conventions: 133 134 NAME: rval>0 is stab index for external 135 rval<0 is -inlabel number 136 lval is offset in bits 137 ICON: lval has the value 138 rval has the STAB index, or - label number, 139 if a name whose address is in the constant 140 rval = NONAME means no name 141 REG: rval is reg. identification cookie 142 143 */ 144 145 int bdebug = 0; 146 extern int negrel[]; 147 148 NODE * 149 buildtree(int o, NODE *l, NODE *r) 150 { 151 NODE *p, *q; 152 int actions; 153 int opty; 154 struct symtab *sp = NULL; /* XXX gcc */ 155 NODE *lr, *ll; 156 157 #ifdef PCC_DEBUG 158 if (bdebug) { 159 printf("buildtree(%s, %p, %p)\n", copst(o), l, r); 160 if (l) fwalk(l, eprint, 0); 161 if (r) fwalk(r, eprint, 0); 162 } 163 #endif 164 opty = coptype(o); 165 166 /* check for constants */ 167 168 if( opty == UTYPE && l->n_op == ICON ){ 169 170 switch( o ){ 171 172 case NOT: 173 case UMINUS: 174 case COMPL: 175 if( conval( l, o, l ) ) return(l); 176 break; 177 } 178 } else if (o == NOT && l->n_op == FCON) { 179 l = clocal(block(SCONV, l, NIL, INT, 0, MKSUE(INT))); 180 } else if( o == UMINUS && l->n_op == FCON ){ 181 l->n_dcon = FLOAT_NEG(l->n_dcon); 182 return(l); 183 184 } else if( o==QUEST && l->n_op==ICON ) { 185 CONSZ c = l->n_lval; 186 nfree(l); 187 if (c) { 188 walkf(r->n_right, putjops, 0); 189 tfree(r->n_right); 190 l = r->n_left; 191 } else { 192 walkf(r->n_left, putjops, 0); 193 tfree(r->n_left); 194 l = r->n_right; 195 } 196 nfree(r); 197 return(l); 198 } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){ 199 200 switch( o ){ 201 202 case PLUS: 203 case MINUS: 204 case MUL: 205 case DIV: 206 case MOD: 207 /* 208 * Do type propagation for simple types here. 209 * The constant value is correct anyway. 210 * Maybe this op shortcut should be removed? 211 */ 212 if (l->n_sp == NULL && r->n_sp == NULL && 213 l->n_type < BTMASK && r->n_type < BTMASK) { 214 if (l->n_type > r->n_type) 215 r->n_type = l->n_type; 216 else 217 l->n_type = r->n_type; 218 } 219 /* FALLTHROUGH */ 220 case ULT: 221 case UGT: 222 case ULE: 223 case UGE: 224 case LT: 225 case GT: 226 case LE: 227 case GE: 228 case EQ: 229 case NE: 230 case ANDAND: 231 case OROR: 232 case AND: 233 case OR: 234 case ER: 235 case LS: 236 case RS: 237 if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) { 238 if( conval( l, o, r ) ) { 239 nfree(r); 240 return(l); 241 } 242 } 243 break; 244 } 245 } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) && 246 (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS || 247 o == MUL || o == DIV || (o >= EQ && o <= GT) )) { 248 if (l->n_op == ICON) 249 l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type); 250 if (r->n_op == ICON) 251 r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type); 252 switch(o){ 253 case PLUS: 254 case MINUS: 255 case MUL: 256 case DIV: 257 switch (o) { 258 case PLUS: 259 l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon); 260 break; 261 case MINUS: 262 l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon); 263 break; 264 case MUL: 265 l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon); 266 break; 267 case DIV: 268 if (FLOAT_ISZERO(r->n_dcon)) 269 goto runtime; 270 l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon); 271 break; 272 } 273 l->n_op = FCON; 274 l->n_type = DOUBLE; 275 l->n_sue = MKSUE(DOUBLE); 276 nfree(r); 277 return(l); 278 case EQ: 279 case NE: 280 case LE: 281 case LT: 282 case GE: 283 case GT: 284 switch (o) { 285 case EQ: 286 l->n_lval = FLOAT_EQ(l->n_dcon, r->n_dcon); 287 break; 288 case NE: 289 l->n_lval = FLOAT_NE(l->n_dcon, r->n_dcon); 290 break; 291 case LE: 292 l->n_lval = FLOAT_LE(l->n_dcon, r->n_dcon); 293 break; 294 case LT: 295 l->n_lval = FLOAT_LT(l->n_dcon, r->n_dcon); 296 break; 297 case GE: 298 l->n_lval = FLOAT_GE(l->n_dcon, r->n_dcon); 299 break; 300 case GT: 301 l->n_lval = FLOAT_GT(l->n_dcon, r->n_dcon); 302 break; 303 } 304 nfree(r); 305 r = bcon(l->n_lval); 306 nfree(l); 307 return r; 308 } 309 } 310 runtime: 311 /* its real; we must make a new node */ 312 313 p = block(o, l, r, INT, 0, MKSUE(INT)); 314 315 actions = opact(p); 316 317 if (actions & LVAL) { /* check left descendent */ 318 if (notlval(p->n_left)) { 319 uerror("lvalue required"); 320 nfree(p); 321 return l; 322 #ifdef notyet 323 } else { 324 if ((l->n_type > BTMASK && ISCON(l->n_qual)) || 325 (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT))) 326 if (blevel > 0) 327 uerror("lvalue is declared const"); 328 #endif 329 } 330 } 331 332 if( actions & NCVTR ){ 333 p->n_left = pconvert( p->n_left ); 334 } 335 else if( !(actions & NCVT ) ){ 336 switch( opty ){ 337 338 case BITYPE: 339 p->n_right = pconvert( p->n_right ); 340 case UTYPE: 341 p->n_left = pconvert( p->n_left ); 342 343 } 344 } 345 346 if ((actions&PUN) && (o!=CAST)) 347 chkpun(p); 348 349 if( actions & (TYPL|TYPR) ){ 350 351 q = (actions&TYPL) ? p->n_left : p->n_right; 352 353 p->n_type = q->n_type; 354 p->n_qual = q->n_qual; 355 p->n_df = q->n_df; 356 p->n_sue = q->n_sue; 357 } 358 359 if( actions & CVTL ) p = convert( p, CVTL ); 360 if( actions & CVTR ) p = convert( p, CVTR ); 361 if( actions & TYMATCH ) p = tymatch(p); 362 if( actions & PTMATCH ) p = ptmatch(p); 363 364 if( actions & OTHER ){ 365 struct suedef *sue2; 366 struct suedef *sue; 367 368 l = p->n_left; 369 r = p->n_right; 370 371 switch(o){ 372 373 case NAME: 374 cerror("buildtree NAME"); 375 376 case STREF: 377 /* p->x turned into *(p+offset) */ 378 /* rhs must be a name; check correctness */ 379 380 /* Find member symbol struct */ 381 if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){ 382 uerror("struct or union required"); 383 break; 384 } 385 386 /* find type sue */ 387 GETSUE(sue, l->n_sue); 388 if ((sp = sue->suem) == NULL) { 389 uerror("undefined struct or union"); 390 break; 391 } 392 393 sp = findmember(sp, r->n_name); 394 #ifdef notdef 395 name = r->n_name; 396 for (; sp != NULL; sp = sp->snext) { 397 if (sp->sname == name) 398 break; 399 } 400 #endif 401 if (sp == NULL) { 402 uerror("member '%s' not declared", r->n_name); 403 break; 404 } 405 406 r->n_sp = sp; 407 p = stref(p); 408 break; 409 410 case UMUL: 411 if (l->n_op == ADDROF) { 412 nfree(p); 413 p = l->n_left; 414 nfree(l); 415 } 416 if( !ISPTR(l->n_type))uerror("illegal indirection"); 417 p->n_type = DECREF(l->n_type); 418 p->n_qual = DECREF(l->n_qual); 419 p->n_df = l->n_df; 420 p->n_sue = l->n_sue; 421 break; 422 423 case ADDROF: 424 switch( l->n_op ){ 425 426 case UMUL: 427 nfree(p); 428 p = l->n_left; 429 nfree(l); 430 case TEMP: 431 case NAME: 432 p->n_type = INCREF(l->n_type); 433 p->n_qual = INCQAL(l->n_qual); 434 p->n_df = l->n_df; 435 p->n_sue = l->n_sue; 436 break; 437 438 case COMOP: 439 nfree(p); 440 lr = buildtree(ADDROF, l->n_right, NIL); 441 p = buildtree( COMOP, l->n_left, lr ); 442 nfree(l); 443 break; 444 445 case QUEST: 446 lr = buildtree( ADDROF, l->n_right->n_right, NIL ); 447 ll = buildtree( ADDROF, l->n_right->n_left, NIL ); 448 nfree(p); nfree(l->n_right); 449 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) ); 450 nfree(l); 451 break; 452 453 default: 454 uerror("unacceptable operand of &: %d", l->n_op ); 455 break; 456 } 457 break; 458 459 case LS: 460 case RS: /* must make type size at least int... */ 461 if (p->n_type == CHAR || p->n_type == SHORT) { 462 p->n_left = makety(l, INT, 0, 0, MKSUE(INT)); 463 } else if (p->n_type == UCHAR || p->n_type == USHORT) { 464 p->n_left = makety(l, UNSIGNED, 0, 0, 465 MKSUE(UNSIGNED)); 466 } 467 l = p->n_left; 468 p->n_type = l->n_type; 469 p->n_qual = l->n_qual; 470 p->n_df = l->n_df; 471 p->n_sue = l->n_sue; 472 473 /* FALLTHROUGH */ 474 case LSEQ: 475 case RSEQ: /* ...but not for assigned types */ 476 if(tsize(r->n_type, r->n_df, r->n_sue) > SZINT) 477 p->n_right = makety(r, INT, 0, 0, MKSUE(INT)); 478 break; 479 480 case RETURN: 481 case ASSIGN: 482 case CAST: 483 /* structure assignment */ 484 /* take the addresses of the two sides; then make an 485 * operator using STASG and 486 * the addresses of left and right */ 487 488 { 489 TWORD t; 490 union dimfun *d; 491 492 GETSUE(sue, l->n_sue); 493 GETSUE(sue2, r->n_sue); 494 if (sue->suem != sue2->suem) 495 uerror("assignment of different structures"); 496 497 r = buildtree(ADDROF, r, NIL); 498 t = r->n_type; 499 d = r->n_df; 500 sue = r->n_sue; 501 502 l = block(STASG, l, r, t, d, sue); 503 l = clocal(l); 504 505 if( o == RETURN ){ 506 nfree(p); 507 p = l; 508 break; 509 } 510 511 p->n_op = UMUL; 512 p->n_left = l; 513 p->n_right = NIL; 514 break; 515 } 516 case COLON: 517 /* structure colon */ 518 519 GETSUE(sue, l->n_sue); 520 GETSUE(sue2, r->n_sue); 521 if (sue->suem != sue2->suem) 522 uerror( "type clash in conditional" ); 523 break; 524 525 case CALL: 526 p->n_right = r = strargs(p->n_right); 527 p = funcode(p); 528 /* FALLTHROUGH */ 529 case UCALL: 530 if (!ISPTR(l->n_type)) 531 uerror("illegal function"); 532 p->n_type = DECREF(l->n_type); 533 if (!ISFTN(p->n_type)) 534 uerror("illegal function"); 535 p->n_type = DECREF(p->n_type); 536 p->n_df = l->n_df; 537 p->n_sue = l->n_sue; 538 if (l->n_op == ADDROF && l->n_left->n_op == NAME && 539 l->n_left->n_sp != NULL && l->n_left->n_sp != NULL && 540 (l->n_left->n_sp->sclass == FORTRAN || 541 l->n_left->n_sp->sclass == UFORTRAN)) { 542 p->n_op += (FORTCALL-CALL); 543 } 544 if (p->n_type == STRTY || p->n_type == UNIONTY) { 545 /* function returning structure */ 546 /* make function really return ptr to str., with * */ 547 548 p->n_op += STCALL-CALL; 549 p->n_type = INCREF(p->n_type); 550 p = clocal(p); /* before recursing */ 551 p = buildtree(UMUL, p, NIL); 552 553 } 554 break; 555 556 default: 557 cerror( "other code %d", o ); 558 } 559 560 } 561 562 /* 563 * Allow (void)0 casts. 564 * XXX - anything on the right side must be possible to cast. 565 * XXX - remove void types further on. 566 */ 567 if (p->n_op == CAST && p->n_type == VOID && 568 p->n_right->n_op == ICON) 569 p->n_right->n_type = VOID; 570 571 if (actions & CVTO) 572 p = oconvert(p); 573 p = clocal(p); 574 575 #ifdef PCC_DEBUG 576 if (bdebug) { 577 printf("End of buildtree:\n"); 578 fwalk(p, eprint, 0); 579 } 580 #endif 581 582 return(p); 583 584 } 585 586 /* Find a member in a struct or union. May be an unnamed member */ 587 static struct symtab * 588 findmember(struct symtab *sp, char *s) 589 { 590 struct symtab *sp2, *sp3; 591 592 for (; sp != NULL; sp = sp->snext) { 593 if (sp->sname[0] == '*') { 594 /* unnamed member, recurse down */ 595 if ((sp2 = findmember(sp->ssue->suem, s))) { 596 sp3 = tmpalloc(sizeof (struct symtab)); 597 *sp3 = *sp2; 598 sp3->soffset += sp->soffset; 599 return sp3; 600 } 601 } else if (sp->sname == s) 602 return sp; 603 } 604 return NULL; 605 } 606 607 608 /* 609 * Check if there will be a lost label destination inside of a ?: 610 * It cannot be reached so just print it out. 611 */ 612 static void 613 putjops(NODE *p, void *arg) 614 { 615 if (p->n_op == COMOP && p->n_left->n_op == GOTO) 616 plabel(p->n_left->n_left->n_lval+1); 617 } 618 619 /* 620 * Build a name node based on a symtab entry. 621 * broken out from buildtree(). 622 */ 623 NODE * 624 nametree(struct symtab *sp) 625 { 626 NODE *p; 627 628 p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->ssue); 629 p->n_qual = sp->squal; 630 p->n_sp = sp; 631 632 #ifndef NO_C_BUILTINS 633 if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0) 634 return p; /* do not touch builtins here */ 635 636 #endif 637 638 if (sp->sflags & STNODE) { 639 /* Generated for optimizer */ 640 p->n_op = TEMP; 641 p->n_rval = sp->soffset; 642 } 643 644 #ifdef GCC_COMPAT 645 /* Get a label name */ 646 if (sp->sflags == SLBLNAME) { 647 p->n_type = VOID; 648 p->n_sue = MKSUE(VOID); 649 } 650 #endif 651 if (sp->stype == UNDEF) { 652 uerror("%s undefined", sp->sname); 653 /* make p look reasonable */ 654 p->n_type = INT; 655 p->n_sue = MKSUE(INT); 656 p->n_df = NULL; 657 defid(p, SNULL); 658 } 659 if (sp->sclass == MOE) { 660 p->n_op = ICON; 661 p->n_lval = sp->soffset; 662 p->n_df = NULL; 663 p->n_sp = NULL; 664 } 665 return clocal(p); 666 } 667 668 /* 669 * Cast a node to another type by inserting a cast. 670 * Just a nicer interface to buildtree. 671 * Returns the new tree. 672 */ 673 NODE * 674 cast(NODE *p, TWORD t, TWORD u) 675 { 676 NODE *q; 677 678 q = block(NAME, NIL, NIL, t, 0, MKSUE(BTYPE(t))); 679 q->n_qual = u; 680 q = buildtree(CAST, q, p); 681 p = q->n_right; 682 nfree(q->n_left); 683 nfree(q); 684 return p; 685 } 686 687 /* 688 * Cast and complain if necessary by not inserining a cast. 689 */ 690 NODE * 691 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct suedef *sue) 692 { 693 NODE *q; 694 695 /* let buildtree do typechecking (and casting) */ 696 q = block(NAME, NIL, NIL, t, df, sue); 697 p = buildtree(ASSIGN, q, p); 698 nfree(p->n_left); 699 q = optim(p->n_right); 700 nfree(p); 701 return q; 702 } 703 704 /* 705 * Do a conditional branch. 706 */ 707 void 708 cbranch(NODE *p, NODE *q) 709 { 710 p = buildtree(CBRANCH, p, q); 711 if (p->n_left->n_op == ICON) { 712 if (p->n_left->n_lval != 0) { 713 branch(q->n_lval); /* branch always */ 714 reached = 0; 715 } 716 tfree(p); 717 tfree(q); 718 return; 719 } 720 ecomp(p); 721 } 722 723 NODE * 724 strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */ 725 726 if( p->n_op == CM ){ 727 p->n_left = strargs( p->n_left ); 728 p->n_right = strargs( p->n_right ); 729 return( p ); 730 } 731 732 if( p->n_type == STRTY || p->n_type == UNIONTY ){ 733 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_sue); 734 p->n_left = buildtree( ADDROF, p->n_left, NIL ); 735 p = clocal(p); 736 } 737 return( p ); 738 } 739 740 /* 741 * apply the op o to the lval part of p; if binary, rhs is val 742 */ 743 int 744 conval(NODE *p, int o, NODE *q) 745 { 746 int i, u; 747 CONSZ val; 748 U_CONSZ v1, v2; 749 750 val = q->n_lval; 751 u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type); 752 if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE); 753 754 if (p->n_sp != NULL && q->n_sp != NULL) 755 return(0); 756 if (q->n_sp != NULL && o != PLUS) 757 return(0); 758 if (p->n_sp != NULL && o != PLUS && o != MINUS) 759 return(0); 760 v1 = p->n_lval; 761 v2 = q->n_lval; 762 switch( o ){ 763 764 case PLUS: 765 p->n_lval += val; 766 if (p->n_sp == NULL) { 767 p->n_right = q->n_right; 768 p->n_type = q->n_type; 769 } 770 break; 771 case MINUS: 772 p->n_lval -= val; 773 break; 774 case MUL: 775 p->n_lval *= val; 776 break; 777 case DIV: 778 if (val == 0) 779 uerror("division by 0"); 780 else { 781 if (u) { 782 v1 /= v2; 783 p->n_lval = v1; 784 } else 785 p->n_lval /= val; 786 } 787 break; 788 case MOD: 789 if (val == 0) 790 uerror("division by 0"); 791 else { 792 if (u) { 793 v1 %= v2; 794 p->n_lval = v1; 795 } else 796 p->n_lval %= val; 797 } 798 break; 799 case AND: 800 p->n_lval &= val; 801 break; 802 case OR: 803 p->n_lval |= val; 804 break; 805 case ER: 806 p->n_lval ^= val; 807 break; 808 case LS: 809 i = (int)val; 810 p->n_lval = p->n_lval << i; 811 break; 812 case RS: 813 i = (int)val; 814 if (u) { 815 v1 = v1 >> i; 816 p->n_lval = v1; 817 } else 818 p->n_lval = p->n_lval >> i; 819 break; 820 821 case UMINUS: 822 p->n_lval = - p->n_lval; 823 break; 824 case COMPL: 825 p->n_lval = ~p->n_lval; 826 break; 827 case NOT: 828 p->n_lval = !p->n_lval; 829 break; 830 case LT: 831 p->n_lval = p->n_lval < val; 832 break; 833 case LE: 834 p->n_lval = p->n_lval <= val; 835 break; 836 case GT: 837 p->n_lval = p->n_lval > val; 838 break; 839 case GE: 840 p->n_lval = p->n_lval >= val; 841 break; 842 case ULT: 843 p->n_lval = v1 < v2; 844 break; 845 case ULE: 846 p->n_lval = v1 <= v2; 847 break; 848 case UGT: 849 p->n_lval = v1 > v2; 850 break; 851 case UGE: 852 p->n_lval = v1 >= v2; 853 break; 854 case EQ: 855 p->n_lval = p->n_lval == val; 856 break; 857 case NE: 858 p->n_lval = p->n_lval != val; 859 break; 860 case ANDAND: 861 p->n_lval = p->n_lval && val; 862 break; 863 case OROR: 864 p->n_lval = p->n_lval || val; 865 break; 866 default: 867 return(0); 868 } 869 return(1); 870 } 871 872 /* 873 * Checks p for the existance of a pun. This is called when the op of p 874 * is ASSIGN, RETURN, CAST, COLON, or relational. 875 * One case is when enumerations are used: this applies only to lint. 876 * In the other case, one operand is a pointer, the other integer type 877 * we check that this integer is in fact a constant zero... 878 * in the case of ASSIGN, any assignment of pointer to integer is illegal 879 * this falls out, because the LHS is never 0. 880 * XXX - check for COMOPs in assignment RHS? 881 */ 882 void 883 chkpun(NODE *p) 884 { 885 union dimfun *d1, *d2; 886 NODE *q; 887 int t1, t2; 888 889 t1 = p->n_left->n_type; 890 t2 = p->n_right->n_type; 891 892 switch (p->n_op) { 893 case RETURN: 894 /* return of void allowed but nothing else */ 895 if (t1 == VOID && t2 == VOID) 896 return; 897 if (t1 == VOID) { 898 werror("returning value from void function"); 899 return; 900 } 901 if (t2 == VOID) { 902 uerror("using void value"); 903 return; 904 } 905 case COLON: 906 if (t1 == VOID && t2 == VOID) 907 return; 908 break; 909 default: 910 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) { 911 uerror("value of void expression used"); 912 return; 913 } 914 break; 915 } 916 917 /* allow void pointer assignments in any direction */ 918 if (BTYPE(t1) == VOID && (t2 & TMASK)) 919 return; 920 if (BTYPE(t2) == VOID && (t1 & TMASK)) 921 return; 922 923 if (ISPTR(t1) || ISARY(t1)) 924 q = p->n_right; 925 else 926 q = p->n_left; 927 928 if (!ISPTR(q->n_type) && !ISARY(q->n_type)) { 929 if (q->n_op != ICON || q->n_lval != 0) 930 werror("illegal combination of pointer and integer"); 931 } else { 932 d1 = p->n_left->n_df; 933 d2 = p->n_right->n_df; 934 if (t1 == t2) { 935 struct suedef *s1, *s2; 936 937 GETSUE(s1, p->n_left->n_sue); 938 GETSUE(s2, p->n_right->n_sue); 939 if (s1->suem != s2->suem) 940 werror("illegal structure pointer combination"); 941 return; 942 } 943 for (;;) { 944 if (ISARY(t1) || ISPTR(t1)) { 945 if (!ISARY(t2) && !ISPTR(t2)) 946 break; 947 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) { 948 werror("illegal array size combination"); 949 return; 950 } 951 if (ISARY(t1)) 952 ++d1; 953 if (ISARY(t2)) 954 ++d2; 955 } else if (ISFTN(t1)) { 956 if (chkftn(d1->dfun, d2->dfun)) { 957 werror("illegal function " 958 "pointer combination"); 959 return; 960 } 961 ++d1; 962 ++d2; 963 } else 964 break; 965 t1 = DECREF(t1); 966 t2 = DECREF(t2); 967 } 968 if (Wpointer_sign) 969 werror("illegal pointer combination"); 970 } 971 } 972 973 NODE * 974 stref(NODE *p) 975 { 976 NODE *r; 977 struct suedef *sue; 978 union dimfun *d; 979 TWORD t, q; 980 int dsc; 981 OFFSZ off; 982 struct symtab *s; 983 984 /* make p->x */ 985 /* this is also used to reference automatic variables */ 986 987 s = p->n_right->n_sp; 988 nfree(p->n_right); 989 r = p->n_left; 990 nfree(p); 991 p = pconvert(r); 992 993 /* make p look like ptr to x */ 994 995 if (!ISPTR(p->n_type)) 996 p->n_type = PTR+UNIONTY; 997 998 t = INCREF(s->stype); 999 q = INCQAL(s->squal); 1000 d = s->sdf; 1001 sue = s->ssue; 1002 1003 p = makety(p, t, q, d, sue); 1004 1005 /* compute the offset to be added */ 1006 1007 off = s->soffset; 1008 dsc = s->sclass; 1009 1010 #ifndef CAN_UNALIGN 1011 /* 1012 * If its a packed struct, and the target cannot do unaligned 1013 * accesses, then split it up in two bitfield operations. 1014 * LHS and RHS accesses are different, so must delay 1015 * it until we know. Do the bitfield construct here though. 1016 */ 1017 if ((dsc & FIELD) == 0 && (off % talign(s->stype, s->ssue))) { 1018 #if 0 1019 int sz = tsize(s->stype, s->sdf, s->ssue); 1020 int al = talign(s->stype, s->ssue); 1021 int sz1 = al - (off % al); 1022 #endif 1023 } 1024 #endif 1025 1026 if (dsc & FIELD) { /* make fields look like ints */ 1027 off = (off/ALINT)*ALINT; 1028 sue = MKSUE(INT); 1029 } 1030 if (off != 0) { 1031 p = block(PLUS, p, offcon(off, t, d, sue), t, d, sue); 1032 p->n_qual = q; 1033 p = optim(p); 1034 } 1035 1036 p = buildtree(UMUL, p, NIL); 1037 1038 /* if field, build field info */ 1039 1040 if (dsc & FIELD) { 1041 p = block(FLD, p, NIL, s->stype, 0, s->ssue); 1042 p->n_qual = q; 1043 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%ALINT); 1044 } 1045 1046 p = clocal(p); 1047 return p; 1048 } 1049 1050 int 1051 notlval(p) register NODE *p; { 1052 1053 /* return 0 if p an lvalue, 1 otherwise */ 1054 1055 again: 1056 1057 switch( p->n_op ){ 1058 1059 case FLD: 1060 p = p->n_left; 1061 goto again; 1062 1063 case NAME: 1064 case OREG: 1065 case UMUL: 1066 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1); 1067 case TEMP: 1068 case REG: 1069 return(0); 1070 1071 default: 1072 return(1); 1073 1074 } 1075 1076 } 1077 /* make a constant node with value i */ 1078 NODE * 1079 bcon(int i) 1080 { 1081 return xbcon(i, NULL, INT); 1082 } 1083 1084 NODE * 1085 xbcon(CONSZ val, struct symtab *sp, TWORD type) 1086 { 1087 NODE *p; 1088 1089 p = block(ICON, NIL, NIL, type, 0, MKSUE(type)); 1090 p->n_lval = val; 1091 p->n_sp = sp; 1092 return clocal(p); 1093 } 1094 1095 NODE * 1096 bpsize(NODE *p) 1097 { 1098 return(offcon(psize(p), p->n_type, p->n_df, p->n_sue)); 1099 } 1100 1101 /* 1102 * p is a node of type pointer; psize returns the 1103 * size of the thing pointed to 1104 */ 1105 OFFSZ 1106 psize(NODE *p) 1107 { 1108 1109 if (!ISPTR(p->n_type)) { 1110 uerror("pointer required"); 1111 return(SZINT); 1112 } 1113 /* note: no pointers to fields */ 1114 return(tsize(DECREF(p->n_type), p->n_df, p->n_sue)); 1115 } 1116 1117 /* 1118 * convert an operand of p 1119 * f is either CVTL or CVTR 1120 * operand has type int, and is converted by the size of the other side 1121 * convert is called when an integer is to be added to a pointer, for 1122 * example in arrays or structures. 1123 */ 1124 NODE * 1125 convert(NODE *p, int f) 1126 { 1127 union dimfun *df; 1128 TWORD ty, ty2; 1129 NODE *q, *r, *s, *rv; 1130 1131 if (f == CVTL) { 1132 q = p->n_left; 1133 s = p->n_right; 1134 } else { 1135 q = p->n_right; 1136 s = p->n_left; 1137 } 1138 ty2 = ty = DECREF(s->n_type); 1139 while (ISARY(ty)) 1140 ty = DECREF(ty); 1141 1142 r = offcon(tsize(ty, s->n_df, s->n_sue), s->n_type, s->n_df, s->n_sue); 1143 ty = ty2; 1144 rv = bcon(1); 1145 df = s->n_df; 1146 while (ISARY(ty)) { 1147 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) : 1148 tempnode(-df->ddim, INT, 0, MKSUE(INT))); 1149 df++; 1150 ty = DECREF(ty); 1151 } 1152 rv = clocal(block(PMCONV, rv, r, INT, 0, MKSUE(INT))); 1153 rv = optim(rv); 1154 1155 r = block(PMCONV, q, rv, INT, 0, MKSUE(INT)); 1156 r = clocal(r); 1157 /* 1158 * Indexing is only allowed with integer arguments, so insert 1159 * SCONV here if arg is not an integer. 1160 * XXX - complain? 1161 */ 1162 if (r->n_type != INTPTR) 1163 r = clocal(block(SCONV, r, NIL, INTPTR, 0, MKSUE(INTPTR))); 1164 if (f == CVTL) 1165 p->n_left = r; 1166 else 1167 p->n_right = r; 1168 return(p); 1169 } 1170 1171 NODE * 1172 pconvert( p ) register NODE *p; { 1173 1174 /* if p should be changed into a pointer, do so */ 1175 1176 if( ISARY( p->n_type) ){ 1177 p->n_type = DECREF( p->n_type ); 1178 ++p->n_df; 1179 return( buildtree( ADDROF, p, NIL ) ); 1180 } 1181 if( ISFTN( p->n_type) ) 1182 return( buildtree( ADDROF, p, NIL ) ); 1183 1184 return( p ); 1185 } 1186 1187 NODE * 1188 oconvert(p) register NODE *p; { 1189 /* convert the result itself: used for pointer and unsigned */ 1190 1191 switch(p->n_op) { 1192 1193 case LE: 1194 case LT: 1195 case GE: 1196 case GT: 1197 if(ISUNSIGNED(p->n_left->n_type) || 1198 ISUNSIGNED(p->n_right->n_type) || 1199 ISPTR(p->n_left->n_type) || 1200 ISPTR(p->n_right->n_type)) 1201 p->n_op += (ULE-LE); 1202 /* FALLTHROUGH */ 1203 case EQ: 1204 case NE: 1205 return( p ); 1206 1207 case MINUS: 1208 return( clocal( block( PVCONV, 1209 p, bpsize(p->n_left), INT, 0, MKSUE(INT)))); 1210 } 1211 1212 cerror( "illegal oconvert: %d", p->n_op ); 1213 1214 return(p); 1215 } 1216 1217 /* 1218 * makes the operands of p agree; they are 1219 * either pointers or integers, by this time 1220 * with MINUS, the sizes must be the same 1221 * with COLON, the types must be the same 1222 */ 1223 NODE * 1224 ptmatch(NODE *p) 1225 { 1226 struct suedef *sue, *sue2; 1227 union dimfun *d, *d2; 1228 TWORD t1, t2, t, q1, q2, q; 1229 int o; 1230 1231 o = p->n_op; 1232 t = t1 = p->n_left->n_type; 1233 q = q1 = p->n_left->n_qual; 1234 t2 = p->n_right->n_type; 1235 q2 = p->n_right->n_qual; 1236 d = p->n_left->n_df; 1237 d2 = p->n_right->n_df; 1238 sue = p->n_left->n_sue; 1239 sue2 = p->n_right->n_sue; 1240 1241 switch( o ){ 1242 1243 case ASSIGN: 1244 case RETURN: 1245 case CAST: 1246 { break; } 1247 1248 case MINUS: 1249 { if( psize(p->n_left) != psize(p->n_right) ){ 1250 uerror( "illegal pointer subtraction"); 1251 } 1252 break; 1253 } 1254 case COLON: 1255 if (t1 != t2) { 1256 /* 1257 * Check for void pointer types. They are allowed 1258 * to cast to/from any pointers. 1259 */ 1260 if (ISPTR(t1) && ISPTR(t2) && 1261 (BTYPE(t1) == VOID || BTYPE(t2) == VOID)) 1262 break; 1263 uerror("illegal types in :"); 1264 } 1265 break; 1266 1267 default: /* must work harder: relationals or comparisons */ 1268 1269 if( !ISPTR(t1) ){ 1270 t = t2; 1271 q = q2; 1272 d = d2; 1273 sue = sue2; 1274 break; 1275 } 1276 if( !ISPTR(t2) ){ 1277 break; 1278 } 1279 1280 /* both are pointers */ 1281 if( talign(t2,sue2) < talign(t,sue) ){ 1282 t = t2; 1283 q = q2; 1284 sue = sue2; 1285 } 1286 break; 1287 } 1288 1289 p->n_left = makety( p->n_left, t, q, d, sue ); 1290 p->n_right = makety( p->n_right, t, q, d, sue ); 1291 if( o!=MINUS && !clogop(o) ){ 1292 1293 p->n_type = t; 1294 p->n_qual = q; 1295 p->n_df = d; 1296 p->n_sue = sue; 1297 } 1298 1299 return(clocal(p)); 1300 } 1301 1302 int tdebug = 0; 1303 1304 NODE * 1305 tymatch(p) register NODE *p; { 1306 1307 /* satisfy the types of various arithmetic binary ops */ 1308 1309 /* rules are: 1310 if assignment, type of LHS 1311 if any doubles, make double 1312 else if any float make float 1313 else if any longlongs, make long long 1314 else if any longs, make long 1315 else etcetc. 1316 if either operand is unsigned, the result is... 1317 */ 1318 1319 TWORD t1, t2, t, tu; 1320 int o, lu, ru; 1321 1322 o = p->n_op; 1323 1324 t1 = p->n_left->n_type; 1325 t2 = p->n_right->n_type; 1326 1327 lu = ru = 0; 1328 if( ISUNSIGNED(t1) ){ 1329 lu = 1; 1330 t1 = DEUNSIGN(t1); 1331 } 1332 if( ISUNSIGNED(t2) ){ 1333 ru = 1; 1334 t2 = DEUNSIGN(t2); 1335 } 1336 1337 if (Wsign_compare && clogop(o) && t1 == t2 && lu != ru && 1338 p->n_left->n_op != ICON && p->n_right->n_op != ICON) 1339 werror("comparison between signed and unsigned"); 1340 1341 #if 0 1342 if ((t1 == CHAR || t1 == SHORT) && o!= RETURN) 1343 t1 = INT; 1344 if (t2 == CHAR || t2 == SHORT) 1345 t2 = INT; 1346 #endif 1347 1348 if (t1 == LDOUBLE || t2 == LDOUBLE) 1349 t = LDOUBLE; 1350 else if (t1 == DOUBLE || t2 == DOUBLE) 1351 t = DOUBLE; 1352 else if (t1 == FLOAT || t2 == FLOAT) 1353 t = FLOAT; 1354 else if (t1==LONGLONG || t2 == LONGLONG) 1355 t = LONGLONG; 1356 else if (t1==LONG || t2==LONG) 1357 t = LONG; 1358 else /* if (t1==INT || t2==INT) */ 1359 t = INT; 1360 #if 0 1361 else if (t1==SHORT || t2==SHORT) 1362 t = SHORT; 1363 else 1364 t = CHAR; 1365 #endif 1366 1367 if( casgop(o) ){ 1368 tu = p->n_left->n_type; 1369 t = t1; 1370 } else { 1371 tu = ((ru|lu) && UNSIGNABLE(t))?ENUNSIGN(t):t; 1372 } 1373 1374 /* because expressions have values that are at least as wide 1375 as INT or UNSIGNED, the only conversions needed 1376 are those involving FLOAT/DOUBLE, and those 1377 from LONG to INT and ULONG to UNSIGNED */ 1378 1379 if (t != t1 || (ru && !lu)) { 1380 if (Wtruncate && o != CAST && p->n_right->n_op != ICON && 1381 tsize(t1, 0, MKSUE(t2)) > tsize(tu, 0, MKSUE(tu))) 1382 werror("conversion to '%s' from '%s' may alter its value", 1383 tnames[tu], tnames[t1]); 1384 p->n_left = makety( p->n_left, tu, 0, 0, MKSUE(tu)); 1385 } 1386 1387 if (t != t2 || o==CAST || (lu && !ru)) { 1388 if (Wtruncate && o != CAST && p->n_right->n_op != ICON && 1389 tsize(t2, 0, MKSUE(t2)) > tsize(tu, 0, MKSUE(tu))) 1390 werror("conversion to '%s' from '%s' may alter its value", 1391 tnames[tu], tnames[t2]); 1392 p->n_right = makety(p->n_right, tu, 0, 0, MKSUE(tu)); 1393 } 1394 1395 if( casgop(o) ){ 1396 p->n_type = p->n_left->n_type; 1397 p->n_df = p->n_left->n_df; 1398 p->n_sue = p->n_left->n_sue; 1399 } 1400 else if( !clogop(o) ){ 1401 p->n_type = tu; 1402 p->n_df = NULL; 1403 p->n_sue = MKSUE(t); 1404 } 1405 1406 #ifdef PCC_DEBUG 1407 if (tdebug) { 1408 printf("tymatch(%p): ", p); 1409 tprint(stdout, t1, 0); 1410 printf(" %s ", copst(o)); 1411 tprint(stdout, t2, 0); 1412 printf(" => "); 1413 tprint(stdout, tu, 0); 1414 printf("\n"); 1415 fwalk(p, eprint, 0); 1416 } 1417 #endif 1418 1419 return(p); 1420 } 1421 1422 /* 1423 * Create a float const node of zero. 1424 */ 1425 static NODE * 1426 fzero(TWORD t) 1427 { 1428 NODE *p = block(FCON, NIL, NIL, t, 0, MKSUE(t)); 1429 1430 p->n_dcon = FLOAT_CAST(0, INT); 1431 return p; 1432 } 1433 1434 /* 1435 * make p into type t by inserting a conversion 1436 */ 1437 NODE * 1438 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct suedef *sue) 1439 { 1440 1441 if (t == p->n_type) { 1442 p->n_df = d; 1443 p->n_sue = sue; 1444 p->n_qual = q; 1445 return(p); 1446 } 1447 1448 if (p->n_op == FCON && (t >= FLOAT && t <= LDOUBLE)) { 1449 if (t == FLOAT) 1450 p->n_dcon = (float)p->n_dcon; 1451 else if (t == DOUBLE) 1452 p->n_dcon = (double)p->n_dcon; 1453 else 1454 p->n_dcon = (long double)p->n_dcon; 1455 p->n_type = t; 1456 return p; 1457 } 1458 1459 if (p->n_op == FCON) { 1460 int isf = ISFTY(t); 1461 NODE *r; 1462 1463 if (isf||ISITY(t)) { 1464 if (isf == ISFTY(p->n_type)) { 1465 p->n_type = t; 1466 p->n_qual = q; 1467 p->n_df = d; 1468 p->n_sue = sue; 1469 return(p); 1470 } else if (isf == ISITY(p->n_type)) { 1471 /* will be zero */ 1472 nfree(p); 1473 return fzero(t); 1474 } else if (ISCTY(p->n_type)) 1475 cerror("complex constant"); 1476 } else if (ISCTY(t)) { 1477 if (ISITY(p->n_type)) { 1478 /* convert to correct subtype */ 1479 r = fzero(t - (COMPLEX-DOUBLE)); 1480 p->n_type = t + (IMAG-COMPLEX); 1481 p->n_qual = q; 1482 p->n_df = d; 1483 p->n_sue = MKSUE(p->n_type); 1484 return block(CM, r, p, t, 0, MKSUE(t)); 1485 } else if (ISFTY(p->n_type)) { 1486 /* convert to correct subtype */ 1487 r = fzero(t + (IMAG-COMPLEX)); 1488 p->n_type = t - (COMPLEX-DOUBLE); 1489 p->n_qual = q; 1490 p->n_df = d; 1491 p->n_sue = MKSUE(p->n_type); 1492 return block(CM, p, r, t, 0, MKSUE(t)); 1493 } else if (ISCTY(p->n_type)) 1494 cerror("complex constant2"); 1495 } 1496 } 1497 1498 if (t & TMASK) { 1499 /* non-simple type */ 1500 p = block(PCONV, p, NIL, t, d, sue); 1501 p->n_qual = q; 1502 return clocal(p); 1503 } 1504 1505 if (p->n_op == ICON) { 1506 if (ISFTY(t)) { 1507 p->n_op = FCON; 1508 p->n_dcon = FLOAT_CAST(p->n_lval, p->n_type); 1509 p->n_type = t; 1510 p->n_qual = q; 1511 p->n_sue = MKSUE(t); 1512 return (clocal(p)); 1513 } else if (ISCTY(t) || ISITY(t)) 1514 cerror("complex constant3"); 1515 } 1516 1517 p = block(SCONV, p, NIL, t, d, sue); 1518 p->n_qual = q; 1519 return clocal(p); 1520 1521 } 1522 1523 NODE * 1524 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct suedef *sue) 1525 { 1526 register NODE *p; 1527 1528 p = talloc(); 1529 p->n_rval = 0; 1530 p->n_op = o; 1531 p->n_lval = 0; /* Protect against large lval */ 1532 p->n_left = l; 1533 p->n_right = r; 1534 p->n_type = t; 1535 p->n_qual = 0; 1536 p->n_df = d; 1537 p->n_sue = sue; 1538 #if !defined(MULTIPASS) 1539 /* p->n_reg = */p->n_su = 0; 1540 p->n_regw = 0; 1541 #endif 1542 return(p); 1543 } 1544 1545 /* 1546 * Return the constant value from an ICON. 1547 */ 1548 CONSZ 1549 icons(NODE *p) 1550 { 1551 /* if p is an integer constant, return its value */ 1552 CONSZ val; 1553 1554 if (p->n_op != ICON || p->n_sp != NULL) { 1555 uerror( "constant expected"); 1556 val = 1; 1557 } else 1558 val = p->n_lval; 1559 tfree(p); 1560 return(val); 1561 } 1562 1563 /* 1564 * the intent of this table is to examine the 1565 * operators, and to check them for 1566 * correctness. 1567 * 1568 * The table is searched for the op and the 1569 * modified type (where this is one of the 1570 * types INT (includes char and short), LONG, 1571 * DOUBLE (includes FLOAT), and POINTER 1572 * 1573 * The default action is to make the node type integer 1574 * 1575 * The actions taken include: 1576 * PUN check for puns 1577 * CVTL convert the left operand 1578 * CVTR convert the right operand 1579 * TYPL the type is determined by the left operand 1580 * TYPR the type is determined by the right operand 1581 * TYMATCH force type of left and right to match,by inserting conversions 1582 * PTMATCH like TYMATCH, but for pointers 1583 * LVAL left operand must be lval 1584 * CVTO convert the op 1585 * NCVT do not convert the operands 1586 * OTHER handled by code 1587 * NCVTR convert the left operand, not the right... 1588 * 1589 */ 1590 1591 # define MINT 01 /* integer */ 1592 # define MDBI 02 /* integer or double */ 1593 # define MSTR 04 /* structure */ 1594 # define MPTR 010 /* pointer */ 1595 # define MPTI 020 /* pointer or integer */ 1596 1597 int 1598 opact(NODE *p) 1599 { 1600 int mt12, mt1, mt2, o; 1601 1602 mt1 = mt2 = mt12 = 0; 1603 1604 switch (coptype(o = p->n_op)) { 1605 case BITYPE: 1606 mt12=mt2 = moditype(p->n_right->n_type); 1607 case UTYPE: 1608 mt12 &= (mt1 = moditype(p->n_left->n_type)); 1609 break; 1610 } 1611 1612 switch( o ){ 1613 1614 case NAME : 1615 case ICON : 1616 case FCON : 1617 case CALL : 1618 case UCALL: 1619 case UMUL: 1620 { return( OTHER ); } 1621 case UMINUS: 1622 if( mt1 & MDBI ) return( TYPL ); 1623 break; 1624 1625 case COMPL: 1626 if( mt1 & MINT ) return( TYPL ); 1627 break; 1628 1629 case ADDROF: 1630 return( NCVT+OTHER ); 1631 case NOT: 1632 /* case INIT: */ 1633 case CM: 1634 case CBRANCH: 1635 case ANDAND: 1636 case OROR: 1637 return( 0 ); 1638 1639 case MUL: 1640 case DIV: 1641 if( mt12 & MDBI ) return( TYMATCH ); 1642 break; 1643 1644 case MOD: 1645 case AND: 1646 case OR: 1647 case ER: 1648 if( mt12 & MINT ) return( TYMATCH ); 1649 break; 1650 1651 case LS: 1652 case RS: 1653 if( mt12 & MINT ) return( TYPL+OTHER ); 1654 break; 1655 1656 case EQ: 1657 case NE: 1658 case LT: 1659 case LE: 1660 case GT: 1661 case GE: 1662 if( mt12 & MDBI ) return( TYMATCH+CVTO ); 1663 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO ); 1664 else if( mt12 & MPTI ) return( PTMATCH+PUN ); 1665 else break; 1666 1667 case QUEST: 1668 case COMOP: 1669 return( TYPR ); 1670 1671 case STREF: 1672 return( NCVTR+OTHER ); 1673 1674 case FORCE: 1675 return( TYPL ); 1676 1677 case COLON: 1678 if( mt12 & MDBI ) return( TYMATCH ); 1679 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN ); 1680 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN ); 1681 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN ); 1682 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER ); 1683 break; 1684 1685 case ASSIGN: 1686 case RETURN: 1687 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER ); 1688 case CAST: 1689 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH ); 1690 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN ); 1691 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN ); 1692 break; 1693 1694 case LSEQ: 1695 case RSEQ: 1696 if( mt12 & MINT ) return( TYPL+LVAL+OTHER ); 1697 break; 1698 1699 case MULEQ: 1700 case DIVEQ: 1701 if( mt12 & MDBI ) return( LVAL+TYMATCH ); 1702 break; 1703 1704 case MODEQ: 1705 case ANDEQ: 1706 case OREQ: 1707 case EREQ: 1708 if (mt12 & MINT) 1709 return(LVAL+TYMATCH); 1710 break; 1711 1712 case PLUSEQ: 1713 case MINUSEQ: 1714 case INCR: 1715 case DECR: 1716 if (mt12 & MDBI) 1717 return(TYMATCH+LVAL); 1718 else if ((mt1&MPTR) && (mt2&MINT)) 1719 return(TYPL+LVAL+CVTR); 1720 break; 1721 1722 case MINUS: 1723 if (mt12 & MPTR) 1724 return(CVTO+PTMATCH+PUN); 1725 if (mt2 & MPTR) 1726 break; 1727 /* FALLTHROUGH */ 1728 case PLUS: 1729 if (mt12 & MDBI) 1730 return(TYMATCH); 1731 else if ((mt1&MPTR) && (mt2&MINT)) 1732 return(TYPL+CVTR); 1733 else if ((mt1&MINT) && (mt2&MPTR)) 1734 return(TYPR+CVTL); 1735 1736 } 1737 uerror("operands of %s have incompatible types", copst(o)); 1738 return(NCVT); 1739 } 1740 1741 int 1742 moditype(TWORD ty) 1743 { 1744 switch (ty) { 1745 1746 case STRTY: 1747 case UNIONTY: 1748 return( MSTR ); 1749 1750 case BOOL: 1751 case CHAR: 1752 case SHORT: 1753 case UCHAR: 1754 case USHORT: 1755 case UNSIGNED: 1756 case ULONG: 1757 case ULONGLONG: 1758 case INT: 1759 case LONG: 1760 case LONGLONG: 1761 return( MINT|MDBI|MPTI ); 1762 case FLOAT: 1763 case DOUBLE: 1764 case LDOUBLE: 1765 #ifndef NO_COMPLEX 1766 case FCOMPLEX: 1767 case COMPLEX: 1768 case LCOMPLEX: 1769 case FIMAG: 1770 case IMAG: 1771 case LIMAG: 1772 #endif 1773 return( MDBI ); 1774 default: 1775 return( MPTR|MPTI ); 1776 1777 } 1778 } 1779 1780 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100; 1781 1782 /* 1783 * Returns a TEMP node with temp number nr. 1784 * If nr == 0, return a node with a new number. 1785 */ 1786 NODE * 1787 tempnode(int nr, TWORD type, union dimfun *df, struct suedef *sue) 1788 { 1789 NODE *r; 1790 1791 r = block(TEMP, NIL, NIL, type, df, sue); 1792 regno(r) = nr ? nr : tvaloff; 1793 tvaloff += szty(type); 1794 return r; 1795 } 1796 1797 /* 1798 * Do sizeof on p. 1799 */ 1800 NODE * 1801 doszof(NODE *p) 1802 { 1803 extern NODE *arrstk[10]; 1804 extern int arrstkp; 1805 union dimfun *df; 1806 TWORD ty; 1807 NODE *rv, *q; 1808 int astkp; 1809 1810 if (p->n_op == FLD) 1811 uerror("can't apply sizeof to bit-field"); 1812 1813 /* 1814 * Arrays may be dynamic, may need to make computations. 1815 */ 1816 1817 rv = bcon(1); 1818 df = p->n_df; 1819 ty = p->n_type; 1820 astkp = 0; 1821 while (ISARY(ty)) { 1822 if (df->ddim == NOOFFSET) 1823 uerror("sizeof of incomplete type"); 1824 if (df->ddim < 0) { 1825 if (arrstkp) 1826 q = arrstk[astkp++]; 1827 else 1828 q = tempnode(-df->ddim, INT, 0, MKSUE(INT)); 1829 } else 1830 q = bcon(df->ddim); 1831 rv = buildtree(MUL, rv, q); 1832 df++; 1833 ty = DECREF(ty); 1834 } 1835 rv = buildtree(MUL, rv, bcon(tsize(ty, p->n_df, p->n_sue)/SZCHAR)); 1836 tfree(p); 1837 arrstkp = 0; /* XXX - may this fail? */ 1838 return rv; 1839 } 1840 1841 #ifdef PCC_DEBUG 1842 void 1843 eprint(NODE *p, int down, int *a, int *b) 1844 { 1845 int ty; 1846 1847 *a = *b = down+1; 1848 while( down > 1 ){ 1849 printf( "\t" ); 1850 down -= 2; 1851 } 1852 if( down ) printf( " " ); 1853 1854 ty = coptype( p->n_op ); 1855 1856 printf("%p) %s, ", p, copst(p->n_op)); 1857 if (p->n_op == XARG || p->n_op == XASM) 1858 printf("id '%s', ", p->n_name); 1859 if (ty == LTYPE) { 1860 printf(CONFMT, p->n_lval); 1861 printf(", %d, ", (p->n_op != NAME && p->n_op != ICON) ? 1862 p->n_rval : 0); 1863 } 1864 tprint(stdout, p->n_type, p->n_qual); 1865 printf( ", %p, %p\n", p->n_df, p->n_sue ); 1866 } 1867 # endif 1868 1869 /* 1870 * Emit everything that should be emitted on the left side 1871 * of a comma operator, and remove the operator. 1872 * Do not traverse through QUEST, ANDAND and OROR. 1873 * Enable this for all targets when stable enough. 1874 */ 1875 static void 1876 comops(NODE *p) 1877 { 1878 int o; 1879 NODE *q; 1880 1881 while (p->n_op == COMOP) { 1882 /* XXX hack for GCC ({ }) ops */ 1883 if (p->n_left->n_op == GOTO) { 1884 int v = (int)p->n_left->n_left->n_lval; 1885 ecomp(p->n_left); 1886 plabel(v+1); 1887 } else 1888 ecomp(p->n_left); /* will recurse if more COMOPs */ 1889 q = p->n_right; 1890 *p = *q; 1891 nfree(q); 1892 } 1893 o = coptype(p->n_op); 1894 if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR) 1895 o = UTYPE; 1896 if (o != LTYPE) 1897 comops(p->n_left); 1898 if (o == BITYPE) 1899 comops(p->n_right); 1900 } 1901 1902 /* 1903 * Walk up through the tree from the leaves, 1904 * removing constant operators. 1905 */ 1906 static void 1907 logwalk(NODE *p) 1908 { 1909 int o = coptype(p->n_op); 1910 NODE *l, *r; 1911 1912 l = p->n_left; 1913 r = p->n_right; 1914 switch (o) { 1915 case LTYPE: 1916 return; 1917 case BITYPE: 1918 logwalk(r); 1919 case UTYPE: 1920 logwalk(l); 1921 } 1922 if (!clogop(p->n_op)) 1923 return; 1924 if (p->n_op == NOT && l->n_op == ICON) { 1925 p->n_lval = l->n_lval == 0; 1926 nfree(l); 1927 p->n_op = ICON; 1928 } 1929 if (l->n_op == ICON && r->n_op == ICON) { 1930 if (conval(l, p->n_op, r) == 0) { 1931 /* 1932 * people sometimes tend to do really odd compares, 1933 * like "if ("abc" == "def")" etc. 1934 * do it runtime instead. 1935 */ 1936 } else { 1937 p->n_lval = l->n_lval; 1938 p->n_op = ICON; 1939 nfree(l); 1940 nfree(r); 1941 } 1942 } 1943 } 1944 1945 /* 1946 * Removes redundant logical operators for branch conditions. 1947 */ 1948 static void 1949 fixbranch(NODE *p, int label) 1950 { 1951 1952 logwalk(p); 1953 1954 if (p->n_op == ICON) { 1955 if (p->n_lval != 0) 1956 branch(label); 1957 nfree(p); 1958 } else { 1959 if (!clogop(p->n_op)) /* Always conditional */ 1960 p = buildtree(NE, p, bcon(0)); 1961 ecode(buildtree(CBRANCH, p, bcon(label))); 1962 } 1963 } 1964 1965 /* 1966 * Write out logical expressions as branches. 1967 */ 1968 static void 1969 andorbr(NODE *p, int true, int false) 1970 { 1971 NODE *q; 1972 int o, lab; 1973 1974 lab = -1; 1975 switch (o = p->n_op) { 1976 case EQ: 1977 case NE: 1978 /* 1979 * Remove redundant EQ/NE nodes. 1980 */ 1981 while (((o = p->n_left->n_op) == EQ || o == NE) && 1982 p->n_right->n_op == ICON) { 1983 o = p->n_op; 1984 q = p->n_left; 1985 if (p->n_right->n_lval == 0) { 1986 nfree(p->n_right); 1987 *p = *q; 1988 nfree(q); 1989 if (o == EQ) 1990 p->n_op = negrel[p->n_op - EQ]; 1991 #if 0 1992 p->n_op = NE; /* toggla */ 1993 #endif 1994 } else if (p->n_right->n_lval == 1) { 1995 nfree(p->n_right); 1996 *p = *q; 1997 nfree(q); 1998 if (o == NE) 1999 p->n_op = negrel[p->n_op - EQ]; 2000 #if 0 2001 p->n_op = EQ; /* toggla */ 2002 #endif 2003 } else 2004 break; /* XXX - should always be false */ 2005 2006 } 2007 /* FALLTHROUGH */ 2008 case LE: 2009 case LT: 2010 case GE: 2011 case GT: 2012 calc: if (true < 0) { 2013 p->n_op = negrel[p->n_op - EQ]; 2014 true = false; 2015 false = -1; 2016 } 2017 2018 rmcops(p->n_left); 2019 rmcops(p->n_right); 2020 fixbranch(p, true); 2021 if (false >= 0) 2022 branch(false); 2023 break; 2024 2025 case ULE: 2026 case UGT: 2027 /* Convert to friendlier ops */ 2028 if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) 2029 p->n_op = o == ULE ? EQ : NE; 2030 goto calc; 2031 2032 case UGE: 2033 case ULT: 2034 /* Already true/false by definition */ 2035 if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) { 2036 if (true < 0) { 2037 o = o == ULT ? UGE : ULT; 2038 true = false; 2039 } 2040 rmcops(p->n_left); 2041 ecode(p->n_left); 2042 rmcops(p->n_right); 2043 ecode(p->n_right); 2044 nfree(p); 2045 if (o == UGE) /* true */ 2046 branch(true); 2047 break; 2048 } 2049 goto calc; 2050 2051 case ANDAND: 2052 lab = false<0 ? getlab() : false ; 2053 andorbr(p->n_left, -1, lab); 2054 comops(p->n_right); 2055 andorbr(p->n_right, true, false); 2056 if (false < 0) 2057 plabel( lab); 2058 nfree(p); 2059 break; 2060 2061 case OROR: 2062 lab = true<0 ? getlab() : true; 2063 andorbr(p->n_left, lab, -1); 2064 comops(p->n_right); 2065 andorbr(p->n_right, true, false); 2066 if (true < 0) 2067 plabel( lab); 2068 nfree(p); 2069 break; 2070 2071 case NOT: 2072 andorbr(p->n_left, false, true); 2073 nfree(p); 2074 break; 2075 2076 default: 2077 rmcops(p); 2078 if (true >= 0) 2079 fixbranch(p, true); 2080 if (false >= 0) { 2081 if (true >= 0) 2082 branch(false); 2083 else 2084 fixbranch(buildtree(EQ, p, bcon(0)), false); 2085 } 2086 } 2087 } 2088 2089 /* 2090 * Massage the output trees to remove C-specific nodes: 2091 * COMOPs are split into separate statements. 2092 * QUEST/COLON are rewritten to branches. 2093 * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation. 2094 * CBRANCH conditions are rewritten for lazy-evaluation. 2095 */ 2096 static void 2097 rmcops(NODE *p) 2098 { 2099 TWORD type; 2100 NODE *q, *r; 2101 int o, ty, lbl, lbl2, tval = 0; 2102 2103 o = p->n_op; 2104 ty = coptype(o); 2105 if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */ 2106 MODTYPE(p->n_type, p->n_sue->suem->stype); 2107 /* 2108 * XXX may fail if these are true: 2109 * - variable-sized enums 2110 * - non-byte-addressed targets. 2111 */ 2112 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type)) 2113 MODTYPE(p->n_type, INT); /* INT ok? */ 2114 } 2115 switch (o) { 2116 case QUEST: 2117 2118 /* 2119 * Create a branch node from ?: 2120 * || and && must be taken special care of. 2121 */ 2122 type = p->n_type; 2123 andorbr(p->n_left, -1, lbl = getlab()); 2124 2125 /* Make ASSIGN node */ 2126 /* Only if type is not void */ 2127 q = p->n_right->n_left; 2128 comops(q); 2129 if (type != VOID) { 2130 r = tempnode(0, q->n_type, q->n_df, q->n_sue); 2131 tval = regno(r); 2132 q = buildtree(ASSIGN, r, q); 2133 } 2134 rmcops(q); 2135 ecode(q); /* Done with assign */ 2136 branch(lbl2 = getlab()); 2137 plabel( lbl); 2138 2139 q = p->n_right->n_right; 2140 comops(q); 2141 if (type != VOID) { 2142 r = tempnode(tval, q->n_type, q->n_df, q->n_sue); 2143 q = buildtree(ASSIGN, r, q); 2144 } 2145 rmcops(q); 2146 ecode(q); /* Done with assign */ 2147 2148 plabel( lbl2); 2149 2150 nfree(p->n_right); 2151 if (p->n_type != VOID) { 2152 r = tempnode(tval, p->n_type, p->n_df, p->n_sue); 2153 *p = *r; 2154 nfree(r); 2155 } else { 2156 p->n_op = ICON; 2157 p->n_lval = 0; 2158 p->n_sp = NULL; 2159 } 2160 break; 2161 2162 case ULE: 2163 case ULT: 2164 case UGE: 2165 case UGT: 2166 case EQ: 2167 case NE: 2168 case LE: 2169 case LT: 2170 case GE: 2171 case GT: 2172 case ANDAND: 2173 case OROR: 2174 case NOT: 2175 #ifdef SPECIAL_CCODES 2176 #error fix for private CCODES handling 2177 #else 2178 r = talloc(); 2179 *r = *p; 2180 andorbr(r, -1, lbl = getlab()); 2181 q = tempnode(0, p->n_type, p->n_df, p->n_sue); 2182 tval = regno(q); 2183 r = tempnode(tval, p->n_type, p->n_df, p->n_sue); 2184 ecode(buildtree(ASSIGN, q, bcon(1))); 2185 branch(lbl2 = getlab()); 2186 plabel( lbl); 2187 ecode(buildtree(ASSIGN, r, bcon(0))); 2188 plabel( lbl2); 2189 r = tempnode(tval, p->n_type, p->n_df, p->n_sue); 2190 *p = *r; 2191 nfree(r); 2192 #endif 2193 break; 2194 case CBRANCH: 2195 andorbr(p->n_left, p->n_right->n_lval, -1); 2196 nfree(p->n_right); 2197 p->n_op = ICON; p->n_type = VOID; 2198 break; 2199 case COMOP: 2200 cerror("COMOP error"); 2201 2202 default: 2203 if (ty == LTYPE) 2204 return; 2205 rmcops(p->n_left); 2206 if (ty == BITYPE) 2207 rmcops(p->n_right); 2208 } 2209 } 2210 2211 /* 2212 * Return 1 if an assignment is found. 2213 */ 2214 static int 2215 has_se(NODE *p) 2216 { 2217 if (cdope(p->n_op) & ASGFLG) 2218 return 1; 2219 if (coptype(p->n_op) == LTYPE) 2220 return 0; 2221 if (has_se(p->n_left)) 2222 return 1; 2223 if (coptype(p->n_op) == BITYPE) 2224 return has_se(p->n_right); 2225 return 0; 2226 } 2227 2228 /* 2229 * Find and convert asgop's to separate statements. 2230 * Be careful about side effects. 2231 * assign tells whether ASSIGN should be considered giving 2232 * side effects or not. 2233 */ 2234 static NODE * 2235 delasgop(NODE *p) 2236 { 2237 NODE *q, *r; 2238 int tval; 2239 2240 if (p->n_op == INCR || p->n_op == DECR) { 2241 /* 2242 * Rewrite x++ to (x += 1) -1; and deal with it further down. 2243 * Pass2 will remove -1 if unnecessary. 2244 */ 2245 q = ccopy(p); 2246 tfree(p->n_left); 2247 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ; 2248 p->n_op = (p->n_op==INCR)?MINUS:PLUS; 2249 p->n_left = delasgop(q); 2250 2251 } else if ((cdope(p->n_op)&ASGOPFLG) && 2252 p->n_op != RETURN && p->n_op != CAST) { 2253 NODE *l = p->n_left; 2254 NODE *ll = l->n_left; 2255 2256 if (has_se(l)) { 2257 q = tempnode(0, ll->n_type, ll->n_df, ll->n_sue); 2258 tval = regno(q); 2259 r = tempnode(tval, ll->n_type, ll->n_df,ll->n_sue); 2260 l->n_left = q; 2261 /* Now the left side of node p has no side effects. */ 2262 /* side effects on the right side must be obeyed */ 2263 p = delasgop(p); 2264 2265 r = buildtree(ASSIGN, r, ll); 2266 r = delasgop(r); 2267 ecode(r); 2268 } else { 2269 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */ 2270 p->n_right = buildtree(UNASG p->n_op, ccopy(l), 2271 p->n_right); 2272 #else 2273 p->n_right = block(UNASG p->n_op, ccopy(l), 2274 p->n_right, p->n_type, p->n_df, p->n_sue); 2275 #endif 2276 p->n_op = ASSIGN; 2277 p->n_right = delasgop(p->n_right); 2278 p->n_right = clocal(p->n_right); 2279 } 2280 2281 } else { 2282 if (coptype(p->n_op) == LTYPE) 2283 return p; 2284 p->n_left = delasgop(p->n_left); 2285 if (coptype(p->n_op) == BITYPE) 2286 p->n_right = delasgop(p->n_right); 2287 } 2288 return p; 2289 } 2290 2291 int edebug = 0; 2292 void 2293 ecomp(NODE *p) 2294 { 2295 2296 #ifdef PCC_DEBUG 2297 if (edebug) 2298 fwalk(p, eprint, 0); 2299 #endif 2300 if (!reached) { 2301 if (Wunreachable_code) 2302 werror("statement not reached"); 2303 reached = 1; 2304 } 2305 p = optim(p); 2306 comops(p); 2307 rmcops(p); 2308 p = delasgop(p); 2309 if (p->n_op == ICON && p->n_type == VOID) 2310 tfree(p); 2311 else 2312 ecode(p); 2313 } 2314 2315 2316 #if defined(MULTIPASS) 2317 void 2318 p2tree(NODE *p) 2319 { 2320 struct symtab *q; 2321 int ty; 2322 2323 myp2tree(p); /* local action can be taken here */ 2324 2325 ty = coptype(p->n_op); 2326 2327 printf("%d\t", p->n_op); 2328 2329 if (ty == LTYPE) { 2330 printf(CONFMT, p->n_lval); 2331 printf("\t"); 2332 } 2333 if (ty != BITYPE) { 2334 if (p->n_op == NAME || p->n_op == ICON) 2335 printf("0\t"); 2336 else 2337 printf("%d\t", p->n_rval); 2338 } 2339 2340 printf("%o\t", p->n_type); 2341 2342 /* handle special cases */ 2343 2344 switch (p->n_op) { 2345 2346 case NAME: 2347 case ICON: 2348 /* print external name */ 2349 if ((q = p->n_sp) != NULL) { 2350 if ((q->sclass == STATIC && q->slevel > 0)) { 2351 printf(LABFMT, q->soffset); 2352 } else 2353 printf("%s\n", 2354 q->soname ? q->soname : exname(q->sname)); 2355 } else 2356 printf("\n"); 2357 break; 2358 2359 case STARG: 2360 case STASG: 2361 case STCALL: 2362 case USTCALL: 2363 /* print out size */ 2364 /* use lhs size, in order to avoid hassles 2365 * with the structure `.' operator 2366 */ 2367 2368 /* note: p->left not a field... */ 2369 printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df, 2370 p->n_left->n_sue)); 2371 printf("\t%d\t\n", talign(STRTY, p->n_left->n_sue)); 2372 break; 2373 2374 case XARG: 2375 case XASM: 2376 break; 2377 2378 default: 2379 printf( "\n" ); 2380 } 2381 2382 if (ty != LTYPE) 2383 p2tree(p->n_left); 2384 if (ty == BITYPE) 2385 p2tree(p->n_right); 2386 } 2387 #else 2388 static char * 2389 sptostr(struct symtab *sp) 2390 { 2391 char *cp = inlalloc(32); 2392 int n = sp->soffset; 2393 if (n < 0) 2394 n = -n; 2395 snprintf(cp, 32, LABFMT, n); 2396 return cp; 2397 } 2398 2399 void 2400 p2tree(NODE *p) 2401 { 2402 struct symtab *q; 2403 int ty; 2404 2405 myp2tree(p); /* local action can be taken here */ 2406 2407 ty = coptype(p->n_op); 2408 2409 switch( p->n_op ){ 2410 2411 case NAME: 2412 case ICON: 2413 if ((q = p->n_sp) != NULL) { 2414 if ((q->sclass == STATIC && q->slevel > 0) 2415 #ifdef GCC_COMPAT 2416 || q->sflags == SLBLNAME 2417 #endif 2418 ) { 2419 p->n_name = sptostr(q); 2420 } else { 2421 if ((p->n_name = q->soname) == NULL) 2422 p->n_name = addname(exname(q->sname)); 2423 } 2424 } else 2425 p->n_name = ""; 2426 break; 2427 2428 case STASG: 2429 /* STASG used for stack array init */ 2430 if (ISARY(p->n_type)) { 2431 int size1 = (int)tsize(p->n_type, p->n_left->n_df, 2432 p->n_left->n_sue)/SZCHAR; 2433 p->n_stsize = (int)tsize(p->n_type, p->n_right->n_df, 2434 p->n_right->n_sue)/SZCHAR; 2435 if (size1 < p->n_stsize) 2436 p->n_stsize = size1; 2437 p->n_stalign = talign(p->n_type, 2438 p->n_left->n_sue)/SZCHAR; 2439 break; 2440 } 2441 /* FALLTHROUGH */ 2442 case STARG: 2443 case STCALL: 2444 case USTCALL: 2445 /* set up size parameters */ 2446 p->n_stsize = (int)((tsize(STRTY, p->n_left->n_df, 2447 p->n_left->n_sue)+SZCHAR-1)/SZCHAR); 2448 p->n_stalign = talign(STRTY,p->n_left->n_sue)/SZCHAR; 2449 if (p->n_stalign == 0) 2450 p->n_stalign = 1; /* At least char for packed structs */ 2451 break; 2452 2453 case XARG: 2454 case XASM: 2455 break; 2456 2457 default: 2458 p->n_name = ""; 2459 } 2460 2461 if( ty != LTYPE ) p2tree( p->n_left ); 2462 if( ty == BITYPE ) p2tree( p->n_right ); 2463 } 2464 2465 #endif 2466 2467 /* 2468 * Change void data types into char. 2469 */ 2470 static void 2471 delvoid(NODE *p, void *arg) 2472 { 2473 /* Convert "PTR undef" (void *) to "PTR uchar" */ 2474 if (BTYPE(p->n_type) == VOID) 2475 p->n_type = (p->n_type & ~BTMASK) | UCHAR; 2476 if (BTYPE(p->n_type) == BOOL) { 2477 if (p->n_op == SCONV && p->n_type == BOOL) { 2478 /* create a jump and a set */ 2479 NODE *q, *r, *s; 2480 int l, val; 2481 2482 q = talloc(); 2483 *q = *p; 2484 q->n_type = BOOL_TYPE; 2485 r = tempnode(0, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE)); 2486 val = regno(r); 2487 s = tempnode(val, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE)); 2488 *p = *s; 2489 q = buildtree(ASSIGN, r, q); 2490 cbranch(buildtree(EQ, q, bcon(0)), bcon(l = getlab())); 2491 ecode(buildtree(ASSIGN, s, bcon(1))); 2492 plabel(l); 2493 } else 2494 p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE; 2495 } 2496 2497 } 2498 2499 void 2500 ecode(NODE *p) 2501 { 2502 /* walk the tree and write out the nodes.. */ 2503 2504 if (nerrors) 2505 return; 2506 2507 #ifdef GCC_COMPAT 2508 { 2509 NODE *q = p; 2510 2511 if (q->n_op == UMUL) 2512 q = p->n_left; 2513 if (cdope(q->n_op)&CALLFLG && 2514 gcc_get_attr(q->n_sue, GCC_ATYP_WARN_UNUSED_RESULT)) 2515 werror("return value ignored"); 2516 } 2517 #endif 2518 p = optim(p); 2519 p = delasgop(p); 2520 walkf(p, delvoid, 0); 2521 #ifdef PCC_DEBUG 2522 if (xdebug) { 2523 printf("Fulltree:\n"); 2524 fwalk(p, eprint, 0); 2525 } 2526 #endif 2527 p2tree(p); 2528 #if !defined(MULTIPASS) 2529 send_passt(IP_NODE, p); 2530 #endif 2531 } 2532 2533 /* 2534 * Send something further on to the next pass. 2535 */ 2536 void 2537 send_passt(int type, ...) 2538 { 2539 struct interpass *ip; 2540 struct interpass_prolog *ipp; 2541 extern int crslab; 2542 va_list ap; 2543 int sz; 2544 2545 va_start(ap, type); 2546 if (type == IP_PROLOG || type == IP_EPILOG) 2547 sz = sizeof(struct interpass_prolog); 2548 else 2549 sz = sizeof(struct interpass); 2550 2551 ip = inlalloc(sz); 2552 ip->type = type; 2553 ip->lineno = lineno; 2554 switch (type) { 2555 case IP_NODE: 2556 ip->ip_node = va_arg(ap, NODE *); 2557 break; 2558 case IP_EPILOG: 2559 if (!isinlining) 2560 defloc(cftnsp); 2561 /* FALLTHROUGH */ 2562 case IP_PROLOG: 2563 inftn = type == IP_PROLOG ? 1 : 0; 2564 ipp = (struct interpass_prolog *)ip; 2565 memset(ipp->ipp_regs, (type == IP_PROLOG)? -1 : 0, 2566 sizeof(ipp->ipp_regs)); 2567 ipp->ipp_autos = va_arg(ap, int); 2568 ipp->ipp_name = va_arg(ap, char *); 2569 ipp->ipp_type = va_arg(ap, TWORD); 2570 ipp->ipp_vis = va_arg(ap, int); 2571 ip->ip_lbl = va_arg(ap, int); 2572 ipp->ip_tmpnum = va_arg(ap, int); 2573 ipp->ip_lblnum = crslab; 2574 if (type == IP_PROLOG) 2575 ipp->ip_lblnum--; 2576 break; 2577 case IP_DEFLAB: 2578 ip->ip_lbl = va_arg(ap, int); 2579 break; 2580 case IP_ASM: 2581 if (blevel == 0) { /* outside function */ 2582 printf("\t"); 2583 printf("%s", va_arg(ap, char *)); 2584 printf("\n"); 2585 va_end(ap); 2586 defloc(NULL); 2587 return; 2588 } 2589 ip->ip_asm = va_arg(ap, char *); 2590 break; 2591 default: 2592 cerror("bad send_passt type %d", type); 2593 } 2594 va_end(ap); 2595 pass1_lastchance(ip); /* target-specific info */ 2596 if (isinlining) 2597 inline_addarg(ip); 2598 else 2599 pass2_compile(ip); 2600 } 2601 2602 char * 2603 copst(int op) 2604 { 2605 if (op <= MAXOP) 2606 return opst[op]; 2607 #define SNAM(x,y) case x: return #y; 2608 switch (op) { 2609 SNAM(QUALIFIER,QUALIFIER) 2610 SNAM(CLASS,CLASS) 2611 SNAM(RB,]) 2612 SNAM(DOT,.) 2613 SNAM(ELLIPSIS,...) 2614 SNAM(LB,[) 2615 SNAM(TYPE,TYPE) 2616 SNAM(COMOP,COMOP) 2617 SNAM(QUEST,?) 2618 SNAM(COLON,:) 2619 SNAM(ANDAND,&&) 2620 SNAM(OROR,||) 2621 SNAM(NOT,!) 2622 SNAM(CAST,CAST) 2623 SNAM(PLUSEQ,+=) 2624 SNAM(MINUSEQ,-=) 2625 SNAM(MULEQ,*=) 2626 SNAM(DIVEQ,/=) 2627 SNAM(MODEQ,%=) 2628 SNAM(ANDEQ,&=) 2629 SNAM(OREQ,|=) 2630 SNAM(EREQ,^=) 2631 SNAM(LSEQ,<<=) 2632 SNAM(RSEQ,>>=) 2633 SNAM(INCR,++) 2634 SNAM(DECR,--) 2635 SNAM(STRING,STRING) 2636 SNAM(SZOF,SIZEOF) 2637 SNAM(ATTRIB,ATTRIBUTE) 2638 #ifdef GCC_COMPAT 2639 SNAM(XREAL,__real__) 2640 SNAM(XIMAG,__imag__) 2641 #endif 2642 default: 2643 cerror("bad copst %d", op); 2644 } 2645 return 0; /* XXX gcc */ 2646 } 2647 2648 int 2649 cdope(int op) 2650 { 2651 if (op <= MAXOP) 2652 return dope[op]; 2653 switch (op) { 2654 case CLOP: 2655 case STRING: 2656 case QUALIFIER: 2657 case CLASS: 2658 case RB: 2659 case ELLIPSIS: 2660 case TYPE: 2661 return LTYPE; 2662 case DOT: 2663 case SZOF: 2664 case COMOP: 2665 case QUEST: 2666 case COLON: 2667 case LB: 2668 return BITYPE; 2669 case XIMAG: 2670 case XREAL: 2671 case ATTRIB: 2672 return UTYPE; 2673 case ANDAND: 2674 case OROR: 2675 return BITYPE|LOGFLG; 2676 case NOT: 2677 return UTYPE|LOGFLG; 2678 case CAST: 2679 return BITYPE|ASGFLG|ASGOPFLG; 2680 case PLUSEQ: 2681 return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG; 2682 case MINUSEQ: 2683 return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG; 2684 case MULEQ: 2685 return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG; 2686 case OREQ: 2687 case EREQ: 2688 case ANDEQ: 2689 return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG; 2690 case DIVEQ: 2691 return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG; 2692 case MODEQ: 2693 return BITYPE|DIVFLG|ASGFLG|ASGOPFLG; 2694 case LSEQ: 2695 case RSEQ: 2696 return BITYPE|SHFFLG|ASGFLG|ASGOPFLG; 2697 case INCR: 2698 case DECR: 2699 return BITYPE|ASGFLG; 2700 } 2701 cerror("cdope missing op %d", op); 2702 return 0; /* XXX gcc */ 2703 } 2704 2705 /* 2706 * make a fresh copy of p 2707 */ 2708 NODE * 2709 ccopy(NODE *p) 2710 { 2711 NODE *q; 2712 2713 q = talloc(); 2714 *q = *p; 2715 2716 switch (coptype(q->n_op)) { 2717 case BITYPE: 2718 q->n_right = ccopy(p->n_right); 2719 case UTYPE: 2720 q->n_left = ccopy(p->n_left); 2721 } 2722 2723 return(q); 2724 } 2725 2726 /* 2727 * set PROG-seg label. 2728 */ 2729 void 2730 plabel(int label) 2731 { 2732 reached = 1; /* Will this always be correct? */ 2733 send_passt(IP_DEFLAB, label); 2734 } 2735 2736 /* 2737 * Perform integer promotion on node n. 2738 */ 2739 NODE * 2740 intprom(NODE *n) 2741 { 2742 if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) { 2743 if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) || 2744 (n->n_type == USHORT && MAX_USHORT > MAX_INT)) 2745 return makety(n, UNSIGNED, 0, 0, MKSUE(UNSIGNED)); 2746 return makety(n, INT, 0, 0, MKSUE(INT)); 2747 } 2748 return n; 2749 } 2750 2751 /* 2752 * Return CON/VOL/0, whichever are active for the current type. 2753 */ 2754 int 2755 cqual(TWORD t, TWORD q) 2756 { 2757 while (ISARY(t)) 2758 t = DECREF(t), q = DECQAL(q); 2759 if (t <= BTMASK) 2760 q <<= TSHIFT; 2761 return q & (CON|VOL); 2762 } 2763 2764 int crslab = 10; 2765 /* 2766 * Return a number for internal labels. 2767 */ 2768 int 2769 getlab(void) 2770 { 2771 return crslab++; 2772 } 2773