|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/expr2.c 1.9" */ ! 2: /*************************************************************************** ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All rights Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: expr2.c: ! 11: ! 12: type check expressions ! 13: ! 14: ************************************************************************/ ! 15: ! 16: #include "cfront.h" ! 17: #include "size.h" ! 18: extern Pname conv_dominates(Pname,Pname); ! 19: extern int pr_dominate(Ptype, Ptype); ! 20: static Pname dominate(Pname,Pname,Pexpr,int); ! 21: static int const_obj1,const_obj2; ! 22: ! 23: Pname really_dominate(Pname on1, Pname on2, bit tc) ! 24: { ! 25: Pfct f1 = on1->get_fct(); ! 26: Pfct f2 = on2->get_fct(); ! 27: ! 28: Ptype t1=f1->returns; ! 29: Ptype t2=f2->returns; ! 30: ! 31: if (!t1 || !t2 || (t1->check(t2,OVERLOAD) && !const_problem)) ! 32: return 0; ! 33: ! 34: // const check ! 35: int c1 = f1->f_const; ! 36: int c2 = f2->f_const; ! 37: ! 38: if(c1 == c2) ; ! 39: else if(c1 && !c2) return tc ? on1 : on2; ! 40: else if(c2 && !c1) return tc ? on2 : on1; ! 41: ! 42: // hierarchy check ! 43: Pname on = conv_dominates(on1,on2); ! 44: if(on) return on; ! 45: else return 0; ! 46: } ! 47: ! 48: void name::assign() ! 49: { ! 50: if (n_assigned_to++ == 0) { ! 51: switch (n_scope) { ! 52: case FCT: ! 53: if (n_used && n_addr_taken==0) { ! 54: Ptype t = tp->skiptypedefs(); ! 55: switch (t->base) { ! 56: case VEC: ! 57: break; ! 58: default: ! 59: if (curr_loop) ! 60: error('w',&where,"%n may have been used before set",this); ! 61: else ! 62: error('w',&where,"%n used before set",this); ! 63: } ! 64: } ! 65: } ! 66: } ! 67: } ! 68: ! 69: void name::take_addr() ! 70: { ! 71: // error('d', "%n->take_addr tp: %t", this, tp?tp:0 ); ! 72: // error('d', "%n->take_addr tp: %d %d", this, tp?tp:0, tp?tp->base:0 ); ! 73: if ( (warning_opt) && (! n_addr_taken) && (tp) && (tp->base==FCT) && Pfct (tp)->f_inline) ! 74: error('w',"can't take address of inline function %n, %n not inlined", this, this); ! 75: n_addr_taken++; ! 76: if ( n_sto == EXTERN && tp ) { ! 77: Ptype t = tp->skiptypedefs(); ! 78: switch ( t->base ) { ! 79: case COBJ: ! 80: t = Pbase(t)->b_name->tp; // no break ! 81: case CLASS: { ! 82: Pclass cl = Pclass(t); ! 83: if ( cl->c_body == 1 ) ! 84: cl->dcl_print(0); ! 85: } ! 86: } ! 87: } ! 88: } ! 89: ! 90: int ignore_const; // for use by ref_init ! 91: static is_dataMemPtr(Pexpr); ! 92: ! 93: int expr::lval(TOK oper) ! 94: { ! 95: register Pexpr ee = this; ! 96: register Pname n; ! 97: int deref = 0; ! 98: char* es; ! 99: ! 100: //error('d',"%k expr::lval %k",base,oper); ! 101: ! 102: switch (oper) { ! 103: case ADDROF: ! 104: case G_ADDROF: es = "address of"; break; ! 105: case DEREF: es = "dereference of"; break; ! 106: case INCR: es = "increment of"; goto def; ! 107: case DECR: es = "decrement of"; goto def; ! 108: default: es = "assignment to"; ! 109: def: ! 110: if (ignore_const==0 && tp->tconst()) { ! 111: if (oper) { ! 112: if (base == NAME) { ! 113: if (vec_const && Pname(this)->n_scope==ARG) break; ! 114: error("%s constant%n",es,this); ! 115: } ! 116: else ! 117: error("%s constant",es); ! 118: } ! 119: return 0; ! 120: } ! 121: } ! 122: ! 123: for(;;) { ! 124: //error('d',"loop %k",ee->base); ! 125: switch (ee->base) { ! 126: // case G_CALL: ! 127: // case CALL: ! 128: default: ! 129: defa: ! 130: if (deref == 0) { ! 131: if (oper) error("%s%k (not an lvalue)",es,ee->base); ! 132: return 0; ! 133: } ! 134: return 1; ! 135: case ZERO: ! 136: case CCON: ! 137: case ICON: ! 138: case FCON: ! 139: if (oper) error("%s numeric constant",es); ! 140: return 0; ! 141: case STRING: ! 142: if (oper) error('w',"%s string constant",es); ! 143: return 1; ! 144: case CAST: ! 145: switch( oper ) { ! 146: case 0: ! 147: case ADDROF: ! 148: case G_ADDROF: ! 149: case DEREF: ! 150: goto defa; ! 151: default: ! 152: if ( ee->tp->base == PTR ! 153: && is_dataMemPtr(ee) ) ! 154: { // check for const class object ! 155: Pexpr te; ! 156: te = ee->e1->e1->e1; ! 157: if ( te->base == G_ADDROF ) ! 158: te = te->e2; ! 159: if ( te->base == NAME ) { ! 160: Ptype pt = te->tp; ! 161: if ( pt->base == PTR ) ! 162: pt = Pptr(pt)->typ; ! 163: if ( pt->tconst() ) ! 164: error("%sCMP of const%n",es,te); ! 165: return 0; ! 166: } ! 167: } ! 168: goto defa; ! 169: } ! 170: ! 171: case DEREF: ! 172: { ! 173: Pexpr ee1 = ee->e1; ! 174: // error( 'd', "ee1: %k", ee1->base ); ! 175: switch (ee1->base) { // *& vanishes ! 176: case ADDROF: // *& ! 177: return 1; ! 178: case G_CM: ! 179: case CM: // look for *(a,&b) ! 180: if (ee1->e2->base==G_ADDROF ! 181: || ee1->e2->base==ADDROF) ! 182: return 1; ! 183: goto defaa; ! 184: case QUEST: // look for *(q?&a:&b) ! 185: if ((ee1->e1->base==G_ADDROF ! 186: || ee1->e1->base==ADDROF) ! 187: && (ee1->e2->base==G_ADDROF ! 188: || ee1->e2->base==ADDROF)) ! 189: return 1; ! 190: // no break ! 191: default: ! 192: defaa: ! 193: ee = ee1; ! 194: deref = 1; ! 195: } ! 196: break; ! 197: } ! 198: ! 199: case QUEST: ! 200: { int x1 = ee->e1->lval(deref?0:oper); ! 201: int x2 = ee->e2->lval(deref?0:oper); ! 202: if (ee->e1->tp->check(ee->e2->tp,0)) return 0; ! 203: if (deref) return 1; ! 204: return x1 && x2; ! 205: } ! 206: ! 207: case INCR: ! 208: case DECR: ! 209: if (e1) goto defa; // postfix does not preserve lval ! 210: case ASSIGN: ! 211: case ASPLUS: ! 212: case ASMINUS: ! 213: case ASMUL: ! 214: case ASDIV: ! 215: case ASMOD: ! 216: case ASAND: ! 217: case ASOR: ! 218: case ASER: ! 219: case ASLS: ! 220: case ASRS: ! 221: return 1; ! 222: ! 223: case CM: ! 224: case G_CM: ! 225: if (ee->e2->lval(deref?0:oper)==0) return deref; ! 226: return 1; ! 227: ! 228: case MEMPTR: ! 229: ee = ee->e2; ! 230: break; ! 231: ! 232: case MDOT: ! 233: ee = ee->mem; ! 234: break; ! 235: ! 236: case DOT: ! 237: { ! 238: // error('d',"dot %k oper %k",ee->e1->base,oper); ! 239: Pexpr e = 0; ! 240: int e_const = 0; // to catch x.y.val = 1, where x is const ! 241: ! 242: switch (ee->e1->base) { // update use counts, etc. ! 243: case NAME: ! 244: switch (oper) { ! 245: case ADDROF: ! 246: case G_ADDROF: Pname(ee->e1)->take_addr(); ! 247: case 0: break; ! 248: case ASSIGN: Pname(ee->e1)->n_used--; ! 249: default: Pname(ee->e1)->assign(); // asop ! 250: } ! 251: break; ! 252: case DOT: ! 253: e = ee->e1; ! 254: do e=e->e1; while (e->base==DOT); ! 255: if (e->base == NAME) { ! 256: e_const = e->tp->tconst(); ! 257: switch (oper) { ! 258: case ADDROF: ! 259: case G_ADDROF: Pname(e)->take_addr(); ! 260: case 0: break; ! 261: case ASSIGN: Pname(e)->n_used--; ! 262: default: Pname(e)->assign(); // asop ! 263: } ! 264: } ! 265: } ! 266: ! 267: n = Pname(ee->mem); ! 268: while (n->base == MDOT) n = Pname(Pref(n)->mem); ! 269: ! 270: if (deref==0 && ! 271: (ee->e1->tp->tconst() || e_const)) { ! 272: ! 273: switch (oper) { ! 274: case 0: ! 275: case ADDROF: ! 276: case G_ADDROF: ! 277: case DEREF: ! 278: break; ! 279: default: ! 280: error("%sM%n of%t",es,n,e_const?e->tp:ee->e1->tp); ! 281: } ! 282: return 0; ! 283: } ! 284: } ! 285: goto xx; ! 286: ! 287: case REF: ! 288: n = Pname(ee->mem); ! 289: while (n->base == MDOT) n = Pname(Pref(n)->mem); ! 290: ! 291: if (deref==0 && ee->e1) { //BR ! 292: Ptype p = ee->e1->tp->skiptypedefs(); ! 293: ! 294: switch (p->base) { ! 295: case PTR: ! 296: case VEC: break; ! 297: default: error('i',"expr::lval %t->%n",p,n); ! 298: } ! 299: if (Pptr(p)->typ->tconst()) { ! 300: switch (oper) { ! 301: case 0: ! 302: case G_ADDROF: ! 303: case DEREF: ! 304: break; ! 305: case ADDROF: ! 306: if ( cm_const_save == 0 && const_ptr == 0 ) ! 307: error(strict_opt?0:'w',"%sM%n of%t",es,n,Pptr(p)->typ); ! 308: break; ! 309: default: ! 310: error("%sM%n of%t",es,n,Pptr(p)->typ); ! 311: } ! 312: return 0; ! 313: } ! 314: } ! 315: goto xx; ! 316: ! 317: case NAME: ! 318: n = Pname(ee); ! 319: xx: ! 320: // error('d',"name xx: %n oper %d lex_level: %d",n,oper,n->lex_level); ! 321: if (deref) return 1; ! 322: if (oper==0) return n->n_stclass != ENUM ; ! 323: ! 324: if (n->tp->base==FIELD && Pbase(n->tp)->b_bits==0) { ! 325: error("%s 0-length field%n",es,n); ! 326: return 0; ! 327: } ! 328: ! 329: switch (oper) { ! 330: case ADDROF: ! 331: case G_ADDROF: ! 332: { Pfct f = (Pfct)n->tp; ! 333: ! 334: if (n->n_sto == REGISTER) { ! 335: if (warning_opt) error('w',"& register%n",n); ! 336: // return 0; ! 337: n->n_sto = 0; ! 338: n->n_stclass = AUTO; ! 339: } ! 340: ! 341: if (f == 0) { ! 342: error("& label%n",n); ! 343: return 0; ! 344: } ! 345: ! 346: if (n->n_stclass == ENUM) { ! 347: error("& enumerator%n",n); ! 348: return 0; ! 349: } ! 350: ! 351: if (n->tp->base == FIELD) { ! 352: error("& field%n",n); ! 353: return 0; ! 354: } ! 355: ! 356: n->n_used--; ! 357: if (n->n_qualifier) { // oops, not the real one ! 358: Pname tn = Pclass(n->n_table->t_name->tp)->memtbl->look(n->string,0); ! 359: n = tn ? tn : n; ! 360: } ! 361: n->take_addr(); ! 362: ! 363: // suppress hoisting of local consts ! 364: int statmem = n->n_scope==0 || n->n_scope==PUBLIC || n->n_scope == FCT; ! 365: if (n->n_evaluated && n->n_scope!=ARG) { // &const ! 366: if (statmem == 0 && n->n_dcl_printed==0) { ! 367: n->n_initializer = new ival(n->n_val); ! 368: n->dcl_print(0); ! 369: } ! 370: } ! 371: else if (f->base==FCT && n->n_dcl_printed==0) ! 372: n->dcl_print(0); ! 373: break; ! 374: } ! 375: ! 376: case ASSIGN: ! 377: //error('d',"ass %n %d",n,n->n_used); ! 378: n->n_used--; ! 379: n->assign(); ! 380: break; ! 381: // goto check_void; ! 382: default: /* incr ops, and asops */ ! 383: if (cc->tot && n==cc->c_this) { ! 384: error("%n%k",n,oper); ! 385: return 0; ! 386: } ! 387: // check_void: ! 388: // { Ptype t = n->tp; ! 389: // while (t->base==TYPE) t = Pbase(t)->b_name->tp; ! 390: // if (t==Pvoid_type) { ! 391: // error("%s%t",es,n->tp); ! 392: // return 0; ! 393: // } ! 394: // } ! 395: n->assign(); ! 396: } ! 397: return 1; ! 398: } ! 399: } ! 400: } ! 401: ! 402: int char_to_int(char* s) ! 403: /* assume s points to a string: ! 404: 'c' ! 405: or '\c' ! 406: or '\0' ! 407: or '\ddd' ! 408: or multi-character versions of the above ! 409: (hex constants have been converted to octal by the parser) ! 410: */ ! 411: { ! 412: register int i = 0; ! 413: register char c, d, e; ! 414: ! 415: switch (*s) { ! 416: default: ! 417: error('i',"char constant store corrupted"); ! 418: case '`': ! 419: error("bcd constant"); ! 420: return 0; ! 421: case '\'': ! 422: break; ! 423: } ! 424: ! 425: for(;;) /* also handle multi-character constants */ ! 426: switch (c = *++s) { ! 427: case '\'': ! 428: return i; ! 429: case '\\': /* special character */ ! 430: switch (c = *++s) { ! 431: case '0': case '1': case '2': case '3': case '4': ! 432: case '5': case '6': case '7': /* octal representation */ ! 433: c -= '0'; ! 434: switch (d = *++s) { /* try for 2 */ ! 435: ! 436: case '0': case '1': case '2': case '3': case '4': ! 437: case '5': case '6': case '7': ! 438: d -= '0'; ! 439: switch (e = *++s) { /* try for 3 */ ! 440: ! 441: case '0': case '1': case '2': case '3': case '4': ! 442: case '5': case '6': case '7': ! 443: c = c*64+d*8+e-'0'; ! 444: break; ! 445: default: ! 446: c = c*8+d; ! 447: s--; ! 448: } ! 449: break; ! 450: default: ! 451: s--; ! 452: } ! 453: break; ! 454: case 'a': ! 455: c = '\a'; ! 456: break; ! 457: case 'b': ! 458: c = '\b'; ! 459: break; ! 460: case 'f': ! 461: c = '\f'; ! 462: break; ! 463: case 'n': ! 464: c = '\n'; ! 465: break; ! 466: case 'r': ! 467: c = '\r'; ! 468: break; ! 469: case 't': ! 470: c = '\t'; ! 471: break; ! 472: case 'v': ! 473: c = '\v'; ! 474: break; ! 475: case '\\': ! 476: c = '\\'; ! 477: break; ! 478: case '\'': ! 479: c = '\''; ! 480: break; ! 481: } ! 482: /* no break */ ! 483: default: ! 484: if (i) i <<= BI_IN_BYTE; ! 485: i += c; ! 486: } ! 487: } ! 488: ! 489: const A10 = 'A'-10; ! 490: const a10 = 'a'-10; ! 491: ! 492: long str_to_long(register const char* p) ! 493: { ! 494: register c; ! 495: register unsigned long i= 0; ! 496: const char* pp = p; ! 497: ! 498: // error( 'd', "str_to_long: %s", p ); ! 499: ! 500: if ((c=*p++) == '0') { ! 501: switch (c = *p++) { ! 502: case 0: ! 503: return 0; ! 504: ! 505: case 'l': ! 506: case 'L': /* long zero */ ! 507: return 0; ! 508: ! 509: case 'x': ! 510: case 'X': /* hexadecimal */ ! 511: while (c=*p++) { ! 512: switch (c) { ! 513: case 'l': ! 514: case 'L': ! 515: case 'U': ! 516: case 'u': ! 517: return i; ! 518: case 'A': ! 519: case 'B': ! 520: case 'C': ! 521: case 'D': ! 522: case 'E': ! 523: case 'F': ! 524: i = i*16 + c-A10; ! 525: break; ! 526: case 'a': ! 527: case 'b': ! 528: case 'c': ! 529: case 'd': ! 530: case 'e': ! 531: case 'f': ! 532: i = i*16 + c-a10; ! 533: break; ! 534: default: ! 535: i = i*16 + c-'0'; ! 536: } ! 537: } ! 538: return i; ! 539: ! 540: default: /* octal */ ! 541: do ! 542: switch (c) { ! 543: case 'l': ! 544: case 'L': ! 545: case 'U': ! 546: case 'u': ! 547: return i; ! 548: default: ! 549: i = i*8 + c-'0'; ! 550: } ! 551: while (c=*p++); ! 552: return i; ! 553: } ! 554: } ! 555: /* decimal */ ! 556: i = c-'0'; ! 557: while (c=*p++) ! 558: switch (c) { ! 559: case 'l': ! 560: case 'L': ! 561: case 'U': ! 562: case 'u': ! 563: return i; ! 564: default: ! 565: { unsigned long ii = i; ! 566: i = i*10 + c-'0'; ! 567: if (i<ii) goto bad; ! 568: } ! 569: } ! 570: return i; ! 571: bad: ! 572: error("integer constant %s larger than the largest long",pp); ! 573: return i; ! 574: ! 575: ! 576: } ! 577: ! 578: bit type::is_unsigned() ! 579: { ! 580: Ptype t = skiptypedefs(); ! 581: if (t->base == PTR) return 0; ! 582: return Pbase(t)->b_unsigned; ! 583: } ! 584: ! 585: char* Neval; ! 586: bit binary_val; ! 587: ! 588: unsigned long expr::ueval(long x1, long x2) ! 589: { ! 590: unsigned long i1 = (unsigned long) x1; ! 591: unsigned long i2 = (unsigned long) x2; ! 592: //error('d',"ueval %k %ld %ld",base,x1,x2); ! 593: switch (base) { ! 594: case UMINUS: return -i2; ! 595: case UPLUS: return i2; ! 596: case NOT: return !i2; ! 597: case COMPL: return ~i2; ! 598: case CAST: return i1; ! 599: case PLUS: return i1+i2; ! 600: case MINUS: return i1-i2; ! 601: case MUL: return i1*i2; ! 602: case LS: return i1<<i2; ! 603: case RS: return i1>>i2; ! 604: case NE: return i1!=i2; ! 605: case EQ: return i1==i2; ! 606: case LT: return i1<i2; ! 607: case LE: return i1<=i2; ! 608: case GT: return i1>i2; ! 609: case GE: return i1>=i2; ! 610: case AND: return i1&i2; ! 611: case ANDAND: return i1&&i2; ! 612: case OR: return i1|i2; ! 613: case OROR: return i1||i2; ! 614: case ER: return i1^i2; ! 615: case MOD: if (i2 == 0) { ! 616: if (Neval == 0) { ! 617: Neval = "mod zero"; ! 618: error("mod zero"); ! 619: } ! 620: return 1; ! 621: } ! 622: return i1%i2; ! 623: case QUEST: return (cond->eval()) ? i1 : i2; ! 624: case DIV: if (i2 == 0) { ! 625: if (Neval == 0) { ! 626: Neval = "divide by zero"; ! 627: error("divide by zero"); ! 628: } ! 629: return 1; ! 630: } ! 631: return i1/i2; ! 632: case CM: ! 633: case G_CM: ! 634: return i2; ! 635: } ! 636: ! 637: Neval = "unsigned expression"; ! 638: return 0; ! 639: } ! 640: ! 641: long expr::eval() ! 642: { ! 643: if (Neval) return 1; ! 644: // error('d',"eval %k",base); ! 645: ! 646: static int targno=0; ! 647: static int icallflag=0; ! 648: ! 649: switch (base) { ! 650: case ZERO: return 0; ! 651: case IVAL: return i1; ! 652: case ICON: return str_to_long(string); ! 653: case CCON: return char_to_int(string); ! 654: case FCON: Neval = "float in constant expression"; return 1; ! 655: case STRING: Neval = "string in constant expression"; return 1; ! 656: case EOBJ: return Pname(this)->n_val; ! 657: case SIZEOF: ! 658: extern no_sizeof; ! 659: if (no_sizeof) Neval = "sizeof"; ! 660: return tp2->tsizeof(); ! 661: ! 662: case NAME: ! 663: { Pname n = Pname(this); ! 664: // error('d',"eval %n eval %d %d",n,n->n_evaluated,n->n_val); ! 665: // error('d',"eval tp->tconst() %d, n->n_initializer: %k", n->tp->tconst(), n->n_initializer?n->n_initializer->base:0 ); ! 666: if (n->n_evaluated && n->n_scope!=ARG) return n->n_val; ! 667: if (binary_val && strcmp(string,"_result")==0) return 8888; ! 668: Neval = "cannot evaluate constant"; ! 669: return 1; ! 670: } ! 671: case ICALL: ! 672: if (e1) { ! 673: icallflag=1; ! 674: targno=0; ! 675: il->i_next = curr_icall; ! 676: curr_icall = il; ! 677: long i = e1->eval(); ! 678: curr_icall = il->i_next; ! 679: icallflag=0; ! 680: return i; ! 681: } ! 682: Neval = "void inlineF"; ! 683: return 1; ! 684: case ANAME: ! 685: { Pname n = (Pname)this; ! 686: ! 687: /* ! 688: int argno; ! 689: if (icallflag) { ! 690: argno=targno; ! 691: targno++; ! 692: } ! 693: */ ! 694: int argno = (int) n->n_val; ! 695: ! 696: Pin il; ! 697: for (il=curr_icall; il; il=il->i_next) ! 698: if (il->i_table == n->n_table) goto aok; ! 699: goto bok; ! 700: aok: ! 701: if (il->i_args[argno].local) { ! 702: bok: ! 703: Neval = "inlineF call too complicated for constant expression"; ! 704: return 1; ! 705: } ! 706: Pexpr aa = il->i_args[argno].arg; ! 707: return aa->eval(); ! 708: } ! 709: case CAST: ! 710: { if (e1->base==FCON && tp2->base!=FLOAT && tp2->base!=DOUBLE) { ! 711: char* p = e1->string; ! 712: while (*p!='.') p++; ! 713: if (p==e1->string) *p++ = '0'; ! 714: *p = 0; ! 715: e1->base = ICON; ! 716: } ! 717: long i = e1->eval(); ! 718: Ptype tt = tp2->skiptypedefs(); ! 719: ! 720: switch (tt->base) { ! 721: default: ! 722: Neval = "cast to non-integral type in constant expression"; ! 723: break; ! 724: case EOBJ: ! 725: case LONG: ! 726: case INT: ! 727: case CHAR: ! 728: case SHORT: ! 729: i &= ~(((~(unsigned long)0)<<(BI_IN_BYTE*(tp2->tsizeof()-1)))<<BI_IN_BYTE); ! 730: break; ! 731: } ! 732: return i; ! 733: } ! 734: case UMINUS: ! 735: case UPLUS: ! 736: case NOT: ! 737: case COMPL: ! 738: case PLUS: ! 739: case MINUS: ! 740: case MUL: ! 741: case LS: ! 742: case RS: ! 743: case NE: ! 744: case LT: ! 745: case LE: ! 746: case GT: ! 747: case GE: ! 748: case AND: ! 749: case OR: ! 750: case ER: ! 751: case DIV: ! 752: case MOD: ! 753: case QUEST: ! 754: case EQ: ! 755: case ANDAND: ! 756: break; ! 757: case OROR: ! 758: if (binary_val) { // a||b, don't evaluate b if a!=0 ! 759: long i1 = (e1) ? e1->eval() : 0; ! 760: if (Neval==0 && i1 && e1->tp->is_unsigned()==0) return i1; ! 761: } ! 762: break; ! 763: case CM: ! 764: case G_CM: ! 765: break; ! 766: case G_ADDROF: ! 767: case ADDROF: ! 768: if (binary_val) { // beware of &*(T*)0 ! 769: switch (e2->base) { ! 770: case NAME: ! 771: case DOT: ! 772: case REF: return 9999; ! 773: } ! 774: } ! 775: default: ! 776: Neval = "bad operator in constant expression"; ! 777: return 1; ! 778: } ! 779: ! 780: long i1 = (e1) ? e1->eval() : 0; ! 781: long i2 = (e2) ? e2->eval() : 0; ! 782: ! 783: if (binary_val && i1==9999 && i2==9999) { ! 784: Neval = ""; ! 785: return 1; ! 786: } ! 787: ! 788: if (Neval==0 ! 789: && ((e1&&e1->tp->is_unsigned()) || (e2&&e2->tp->is_unsigned()))) ! 790: return (long) ueval(i1,i2); ! 791: ! 792: switch (base) { ! 793: case UMINUS: return -i2; ! 794: case UPLUS: return i2; ! 795: case NOT: return !i2; ! 796: case COMPL: return ~i2; ! 797: case CAST: return i1; ! 798: case PLUS: return i1+i2; ! 799: case MINUS: return i1-i2; ! 800: case MUL: return i1*i2; ! 801: case LS: return i1<<i2; ! 802: case RS: return i1>>i2; ! 803: case NE: return i1!=i2; ! 804: case EQ: return i1==i2; ! 805: case LT: return i1<i2; ! 806: case LE: return i1<=i2; ! 807: case GT: return i1>i2; ! 808: case GE: return i1>=i2; ! 809: case AND: return i1&i2; ! 810: case ANDAND: return i1&&i2; ! 811: case OR: return i1|i2; ! 812: case OROR: return i1||i2; ! 813: case ER: return i1^i2; ! 814: case MOD: if (i2 == 0) { ! 815: if (Neval == 0) { ! 816: Neval = "mod zero"; ! 817: error("mod zero"); ! 818: } ! 819: return 1; ! 820: } ! 821: return i1%i2; ! 822: case QUEST: return (cond->eval()) ? i1 : i2; ! 823: case DIV: if (i2 == 0) { ! 824: if (Neval == 0) { ! 825: Neval = "divide by zero"; ! 826: error("divide by zero"); ! 827: } ! 828: return 1; ! 829: } ! 830: return i1/i2; ! 831: case CM: ! 832: case G_CM: ! 833: return i2; ! 834: } ! 835: } ! 836: bit classdef::baseof(Pname f) ! 837: /* ! 838: is ``this'' class a public base class of "f"'s class ! 839: or its immediate base class ! 840: */ ! 841: { ! 842: Ptable ctbl = f->n_table; ! 843: Pname b = ctbl->t_name; ! 844: ! 845: if (b == 0) return 0; ! 846: Pclass cl = Pclass(b->tp); ! 847: if (cl == 0) return 0; ! 848: if (cl == this) return 1; ! 849: ppbase = PUBLIC; ! 850: Pclass bcl = is_base(cl->string); ! 851: return (bcl && ppbase==PUBLIC); ! 852: } ! 853: ! 854: bit classdef::baseof(Pclass cl) ! 855: /* ! 856: is ``this'' class a public base class of "cl" ! 857: */ ! 858: { ! 859: if (cl == 0) return 0; ! 860: if (cl == this) return 1; ! 861: ppbase = PUBLIC; ! 862: Pclass bcl = is_base(cl->string); ! 863: return (bcl && ppbase==PUBLIC); ! 864: } ! 865: ! 866: static int mem_match(Pfct f1, Pfct f2) ! 867: /* ! 868: check class membership. ! 869: ! 870: For some reason checking f_this==0 works and f_static doesn't ! 871: */ ! 872: { ! 873: // if (f1->memof) return f2->f_this ?f2->memof==f1->memof : 0; ! 874: // if (f1 && f1->memof) return f2->f_this?f2->memof==f1->memof : 0; ! 875: // return f2->f_this==0; ! 876: if (f1==0 || f2==0) return 0; ! 877: if (f1->memof && f2->f_this && f2->memof!=f1->memof) return 0; ! 878: if (f2->f_this) return 0; ! 879: if (f1->memof && f2->f_static) return 0; ! 880: if (f1->check(f2,ASSIGN)) return 0; ! 881: return 1; ! 882: } ! 883: ! 884: int Pchecked; ! 885: ! 886: Pexpr ptof(Pfct ef, Pexpr e, Ptable tbl) ! 887: /* ! 888: a kludge: initialize/assign-to pointer to function ! 889: */ ! 890: { ! 891: Pfct f; ! 892: Pname n = 0; ! 893: eee: ! 894: //error('d',"ptof %t %t %k",ef,e->tp,e->base); ! 895: switch (e->base) { ! 896: case QUEST: ! 897: e->e1 = ptof(ef,e->e1,tbl); ! 898: e->e2 = ptof(ef,e->e2,tbl); ! 899: return e; ! 900: case CM: ! 901: case G_CM: ! 902: e->e2 = ptof(ef,e->e2,tbl); ! 903: return e; ! 904: case NAME: ! 905: f = Pfct(e->tp); ! 906: Pname nn = Pname(e); ! 907: ! 908: switch (f->base) { ! 909: case OVERLOAD: ! 910: e = Pgen(f)->find(ef,0); ! 911: if (e == 0) { ! 912: error("cannot deduceT for &overloaded%n",nn); ! 913: return e; ! 914: } ! 915: // e = n; ! 916: // no break ! 917: case FCT: ! 918: Pchecked = mem_match(ef,Pfct(e->tp)); ! 919: e = new expr(G_ADDROF,0,e); ! 920: return e->typ(tbl); // handle &B::f ! 921: //e->tp = f; ! 922: } ! 923: goto ad; ! 924: ! 925: case ZERO: ! 926: if (ef->memof) { ! 927: e = new expr(ELIST,zero,zero); ! 928: e = new expr(ILIST,e,zero); ! 929: e->tp = zero_type; ! 930: return e; ! 931: } ! 932: break; ! 933: ! 934: case MDOT: ! 935: // ?? error('s',"P toM of not firstB"); ! 936: do e = e->mem; while (e->base == MDOT); ! 937: goto eee; ! 938: ! 939: case DOT: ! 940: case REF: ! 941: f = Pfct(e->mem->tp); ! 942: ! 943: switch (f->base) { ! 944: case OVERLOAD: ! 945: n = Pgen(f)->find(ef,0); ! 946: if (n == 0) error("cannot deduceT for &overloaded%n",e->mem); ! 947: else e = n; ! 948: // no break ! 949: case FCT: ! 950: Pchecked = mem_match(ef,Pfct(e->tp)); ! 951: e = new expr(G_ADDROF,0,e); ! 952: return e->typ(tbl); // handle &B::f ! 953: // n = Pname(e->mem); ! 954: // e = n->address(); ! 955: } ! 956: goto ad; ! 957: ! 958: case ADDROF: ! 959: case G_ADDROF: ! 960: f = Pfct(e->e2->tp); ! 961: ad: ! 962: if (f->base == OVERLOAD) { ! 963: n = Pgen(f)->find(ef,0); ! 964: if (n == 0) error("cannot deduceT for &overloaded %s()",Pgen(f)->fct_list->f->string); ! 965: Pchecked = mem_match(ef,Pfct(n->tp)); ! 966: e->e2 = n; ! 967: e->tp = n->tp; ! 968: } ! 969: if (n) n->lval(ADDROF); ! 970: break; ! 971: ! 972: case CAST: ! 973: { ! 974: Pexpr te = e->e1; ! 975: if (e->e1->base == G_ADDROF) te = e->e1->e2; ! 976: (void) ptof(ef,te,tbl); ! 977: } ! 978: } ! 979: return e; ! 980: } ! 981: ! 982: Pexpr ptr_init(Pptr p, Pexpr init, Ptable tbl) ! 983: /* ! 984: check for silly initializers ! 985: ! 986: char* p = 0L; ?? fudge to allow redundant and incorrect `L' ! 987: char* p = 2 - 2; ?? worse ! 988: */ ! 989: { ! 990: // error('d',"ptr_init: p=%t init->tp=%t init->base %k",p,init->tp,init->base); ! 991: ! 992: Pchecked = 0; ! 993: ! 994: Ptype it = init->tp->skiptypedefs(); ! 995: ! 996: switch (it->base) { ! 997: case ZTYPE: ! 998: // if (init == zero) break; ! 999: break; ! 1000: case EOBJ: ! 1001: case INT: ! 1002: case CHAR: ! 1003: case SHORT: ! 1004: case LONG: ! 1005: { Neval = 0; ! 1006: long i = init->eval(); ! 1007: if (Neval) ! 1008: error("badPIr: %s",Neval); ! 1009: else ! 1010: if (i) ! 1011: error("badPIr value %d",i); ! 1012: else { ! 1013: DEL(init); ! 1014: init = zero; ! 1015: } ! 1016: break; ! 1017: } ! 1018: } ! 1019: ! 1020: Pclass c1 = p->memof; ! 1021: ! 1022: if (c1) { ! 1023: if (init==zero) ! 1024: ; ! 1025: else { ! 1026: Pclass c2; ! 1027: // error('d',"it %t %d",it,it->base); ! 1028: switch (it->base) { ! 1029: case FCT: ! 1030: c2 = Pfct(it)->memof; ! 1031: break; ! 1032: case OVERLOAD: ! 1033: c2 = Pfct(Pgen(it)->fct_list->f->tp)->memof; ! 1034: break; ! 1035: case PTR: ! 1036: case RPTR: ! 1037: c2 = Pptr(it)->memof; ! 1038: break; ! 1039: default: ! 1040: c2 = 0; ! 1041: } ! 1042: ! 1043: if (c2 == 0) { ! 1044: // initialization by &A::f ! 1045: //error('d',"curious"); ! 1046: } ! 1047: else if (c1 != c2) { ! 1048: Nptr = 0; ! 1049: Noffset = 0; ! 1050: vcllist->clear(); ! 1051: vcllist=0; ! 1052: int u1 = is_unique_base(c1,c2->string,0); ! 1053: //error('d',"c1 %t c2 %t u1 %d off %d",c1,c2,u1,Noffset); ! 1054: if (u1 && (Nptr || Noffset)) { ! 1055: // requires offset manipulation ! 1056: int bad = 0; ! 1057: if (u1 == 1 && !Nptr) { ! 1058: if (init->base==ILIST) { ! 1059: // d = d+Noffset; ! 1060: switch (init->e1->e1->base) { ! 1061: case IVAL: ! 1062: init->e1->e1->i1 += Noffset; ! 1063: break; ! 1064: case ZERO: ! 1065: init->e1->e1 = new ival(Noffset); ! 1066: break; ! 1067: default: ! 1068: bad = 1; ! 1069: } ! 1070: ! 1071: // if (i<0) f = vptroffset ! 1072: switch (init->e1->e2->base) { ! 1073: case IVAL: ! 1074: if (0<init->e1->e2->i1) { ! 1075: // extern Ptype Pfct_type; ! 1076: // store vptr offset ! 1077: // init->e2=new cast(Pfct_type,zero); ! 1078: } ! 1079: else ! 1080: break; ! 1081: default: ! 1082: bad = 1; ! 1083: } ! 1084: } // end if (init->base==ILIST) ! 1085: else ! 1086: bad = 1; ! 1087: } // end if (u1 == 1 ... ! 1088: else ! 1089: bad = 1; ! 1090: ! 1091: if (bad) error('s',"%t assigned to %t (too complicated)",init->tp,p); ! 1092: } // end if (u1 && ... ! 1093: ! 1094: Nptr = 0; ! 1095: Noffset = 0; ! 1096: vcllist->clear(); ! 1097: vcllist=0; ! 1098: int u2 = is_unique_base(c2,c1->string,0); ! 1099: //error('d',"c1 %t c2 %t u2 %d off %d",c1,c2,u2,Noffset); ! 1100: if (u2 && (Nptr || Noffset)) { ! 1101: // requires offset manipulation ! 1102: error('s',"%t assigned to %t",init->tp,p); ! 1103: } ! 1104: } // end if (c1 != c2 ! 1105: } // end else ! 1106: } // end if (c1) ! 1107: ! 1108: Ptype pit = p->typ->skiptypedefs(); ! 1109: // error('d',"p %t pit %t",p,pit); ! 1110: switch (pit->base) { ! 1111: case FCT: ! 1112: return ptof(Pfct(pit),init,tbl); ! 1113: case COBJ: ! 1114: { Pptr r; ! 1115: // error('d',"cobj: ptr %t, ref %t",it->is_ptr(),it->is_ref()); ! 1116: if (r=it->is_ptr_or_ref()) { ! 1117: Pchecked = 1; ! 1118: TOK b = p->base; // could be REF ! 1119: TOK bb = r->base; ! 1120: if (b==RPTR) p->base = PTR; ! 1121: if (bb==RPTR) r->base = PTR; ! 1122: if (p->check(r,ASSIGN)) { ! 1123: if ( cc && cc->nof && ! 1124: Pfct(cc->nof->tp)->f_const && ! 1125: cc->c_this == init ) ! 1126: error("%n const: assignment of%n (%t) to%t",cc->nof,init,init->tp,p); ! 1127: else ! 1128: error("no standard conversion of %t to %t",init->tp,p); ! 1129: } ! 1130: p->base = b; ! 1131: r->base = bb; ! 1132: Pexpr cp = cast_cptr(Pclass(Pbase(pit)->b_name->tp),init,tbl,0); ! 1133: if (cp != init) { ! 1134: PERM(p); // or else it will be deleted twice! ! 1135: return new cast(p,cp); ! 1136: } ! 1137: } ! 1138: // no break ! 1139: } ! 1140: default: ! 1141: return init; ! 1142: } ! 1143: } ! 1144: ! 1145: static Pname Lcoerce, Rcoerce; ! 1146: extern int suppress_error; ! 1147: ! 1148: int try_to_demote(TOK oper, Ptype t1, Ptype t2) ! 1149: /* ! 1150: look at t1 and t2 and see if there are ``demotions'' of t1 and/or t2 ! 1151: so that ``t1 oper t2'' can be made legal ! 1152: ! 1153: return 0 is not ! 1154: 1 if there is exactly one way ! 1155: >1 if there is more than one way (if in doubt return 2) ! 1156: */ ! 1157: { ! 1158: //error('d',"try_to_demote(%k : %t : %t)",oper,t1,t2); ! 1159: ! 1160: Pname n1 = t1 ? t1->is_cl_obj() : 0; ! 1161: Pclass c1 = n1 ? Pclass(n1->tp) : 0; ! 1162: Pname n2 = t2 ? t2->is_cl_obj() : 0; ! 1163: Pclass c2 = n2 ? Pclass(n2->tp) : 0; ! 1164: ! 1165: Ptype lt = t1; ! 1166: Ptype rt = t2; ! 1167: ! 1168: Lcoerce = Rcoerce = 0; ! 1169: ! 1170: // if (oper == DOT) return 0; ! 1171: ! 1172: if (c1) ! 1173: switch (oper) { ! 1174: case ASSIGN: ! 1175: case ASPLUS: ! 1176: case ASMINUS: ! 1177: case ASMUL: ! 1178: case ASDIV: ! 1179: case ASMOD: ! 1180: case ASAND: ! 1181: case ASOR: ! 1182: case ASER: ! 1183: case ASLS: ! 1184: case ASRS: // don't coerce left hand side of assignment ! 1185: // c1 = 0; ! 1186: if (c1->memtbl->look("__as",0)) return 0; ! 1187: } ! 1188: else ! 1189: switch (oper) { ! 1190: case ADDROF: ! 1191: case INCR: ! 1192: case DECR: // don't coerce unary requiring an lval ! 1193: return 0; ! 1194: } ! 1195: ! 1196: if (c1) { ! 1197: //error('d',"c1 %t",c1); ! 1198: for (Pname on1 = c1->conv; on1; on1=on1->n_list) { ! 1199: // error( 'd', "on1: %s tp: %k", on1->string, on1->tp->base ); ! 1200: Pfct f = on1->get_fct(); ! 1201: lt = f->returns; ! 1202: Pname cn = lt->is_cl_obj(); ! 1203: ! 1204: if (cn && (Lcoerce==0 || Lcoerce->tp->check(f,0))) { ! 1205: Pclass cl = Pclass(cn->tp); ! 1206: Pname n = cl->has_oper(oper); ! 1207: if (n == 0) continue; ! 1208: // while (n->base==REF || n->base==MDOT) n=Pname(n->mem) ; ! 1209: Pfct nf = Pfct(n->tp); ! 1210: // error( 'd', "nf: %d %k", nf->base, nf->base ); ! 1211: if (nf->base == FCT) { ! 1212: if (nf->nargs==1 ! 1213: && t2 ! 1214: && (nf->argtype->tp->check(t2,ARG)==0 ! 1215: || can_coerce(nf->argtype->tp,t2)==1) ! 1216: ) { ! 1217: if (Lcoerce) return 2; ! 1218: Lcoerce = on1; ! 1219: } ! 1220: } ! 1221: else { ! 1222: for (Plist gl=Pgen(nf)->fct_list; gl; gl=gl->l) { ! 1223: Pfct nf = Pfct(gl->f->tp); ! 1224: if (nf->nargs==1 ! 1225: && t2 ! 1226: && (nf->argtype->tp->check(t2,ARG)==0 ! 1227: || can_coerce(nf->argtype->tp,t2)==1) ! 1228: ) { ! 1229: if (Lcoerce) return 2; ! 1230: Lcoerce = on1; ! 1231: } ! 1232: } ! 1233: } ! 1234: continue; ! 1235: } ! 1236: //if (lt->is_cl_obj()) continue; ! 1237: if (c2) { ! 1238: //error('d',"c2 %t",c2); ! 1239: for (Pname on2 = c2->conv; on2; on2=on2->n_list) { ! 1240: Pfct f = on2->get_fct(); ! 1241: rt = f->returns; ! 1242: if (rt->is_cl_obj()) continue; ! 1243: ! 1244: suppress_error = 1; ! 1245: int r1 = lt->kind(oper,0); ! 1246: int r2 = rt->kind(oper,0); ! 1247: if (np_promote(oper,r1,r2,lt,rt,1)!=any_type) { ! 1248: Pname sn = on1; ! 1249: if (Lcoerce) { ! 1250: Pname tn = really_dominate( ! 1251: Lcoerce, ! 1252: on1, ! 1253: const_obj1 ! 1254: ); ! 1255: if(!tn) { ! 1256: suppress_error = 0; ! 1257: return 2; ! 1258: } ! 1259: else sn = tn; ! 1260: } ! 1261: Lcoerce = sn; ! 1262: Rcoerce = on2; ! 1263: ! 1264: } ! 1265: suppress_error = 0; ! 1266: } ! 1267: ! 1268: } ! 1269: else if (rt) { ! 1270: suppress_error = 1; ! 1271: int r1 = lt->kind(oper,0); ! 1272: int r2 = rt->kind(oper,0); ! 1273: if (np_promote(oper,r1,r2,lt,rt,1)!=any_type) { ! 1274: Pname sn = on1; ! 1275: if (Lcoerce) { ! 1276: Pname tn = really_dominate( ! 1277: Lcoerce, ! 1278: on1, ! 1279: const_obj1 ! 1280: ); ! 1281: if(!tn) { ! 1282: suppress_error = 0; ! 1283: return 2; ! 1284: } ! 1285: else sn = tn; ! 1286: } ! 1287: Lcoerce = sn; ! 1288: } ! 1289: suppress_error = 0; ! 1290: } ! 1291: else { ! 1292: Pname sn = on1; ! 1293: if (Lcoerce) { ! 1294: Pname tn = really_dominate( ! 1295: Lcoerce, ! 1296: on1, ! 1297: const_obj1 ! 1298: ); ! 1299: if(!tn) return 2; ! 1300: else sn = tn; ! 1301: } ! 1302: Lcoerce = sn; ! 1303: } ! 1304: } ! 1305: } ! 1306: else if (c2) { ! 1307: //error('d',"c2 %n",c2); ! 1308: for (Pname on = c2->conv; on; on=on->n_list) { ! 1309: Pfct f = on->get_fct(); ! 1310: rt = f->returns; ! 1311: Pname cn = rt->is_cl_obj(); ! 1312: //error('d',"cn %n",cn); ! 1313: if (cn && (Rcoerce==0 || Rcoerce->tp->check(f,0))) { ! 1314: Pclass cl = Pclass(cn->tp); ! 1315: Pname n = cl->has_oper(oper); ! 1316: if (n == 0) continue; ! 1317: ! 1318: // while (n->base==REF || n->base==MDOT) n=Pname(n->mem); ! 1319: Pfct nf = Pfct(n->tp); ! 1320: if (nf->base == FCT) { ! 1321: if (nf->nargs == 0) { ! 1322: if (Lcoerce || Rcoerce) return 2; ! 1323: Rcoerce = on; ! 1324: } ! 1325: } ! 1326: else { ! 1327: for (Plist gl=Pgen(nf)->fct_list; gl; gl=gl->l) ! 1328: if (Pfct(gl->f->tp)->nargs == 0) { ! 1329: if (Lcoerce || Rcoerce) return 2; ! 1330: Rcoerce = on; ! 1331: } ! 1332: } ! 1333: continue; ! 1334: } ! 1335: //if (rt->is_cl_obj()) continue; ! 1336: if( lt ) { ! 1337: suppress_error = 1; ! 1338: int r1 = lt->kind(oper,0); ! 1339: int r2 = rt->kind(oper,0); ! 1340: ! 1341: if (np_promote(oper,r1,r2,lt,rt,1)!=any_type) { ! 1342: Pname sn = on; ! 1343: if (Lcoerce || Rcoerce) { ! 1344: Pname tn = really_dominate( ! 1345: Rcoerce, ! 1346: on, ! 1347: const_obj2 ! 1348: ); ! 1349: if(!tn) { ! 1350: suppress_error = 0; ! 1351: return 2; ! 1352: } ! 1353: else sn = tn; ! 1354: } ! 1355: Rcoerce = sn; ! 1356: } ! 1357: suppress_error = 0; ! 1358: } ! 1359: } ! 1360: } ! 1361: ! 1362: //error('d',"->%d || %d",Lcoerce,Rcoerce); ! 1363: return (Lcoerce || Rcoerce); ! 1364: } ! 1365: ! 1366: Pexpr expr::try_to_overload(Ptable tbl) ! 1367: { ! 1368: ! 1369: //error('d',"try_to_overload %k %d",base,base); ! 1370: const int STD = 3; ! 1371: Pname n1 = 0; ! 1372: Ptype t1 = 0; ! 1373: const_obj1 = 0; ! 1374: const_obj2 = 0; ! 1375: ! 1376: if (e1) { ! 1377: t1 = e1->tp; ! 1378: Ptype tpx = t1->skiptypedefs(); ! 1379: n1 = tpx->is_cl_obj(); ! 1380: const_obj1 = t1->tconst(); ! 1381: ! 1382: Pexpr ee = e1; ! 1383: while (ee && (ee->base==DOT || ee->base==REF)) { ! 1384: Pexpr m = ee->mem; ! 1385: if ( ee->base==REF && m->tp && m->tp->is_ptr()) ! 1386: break; ! 1387: ee = ee->e1; ! 1388: } ! 1389: if (ee) { ! 1390: int tc; ! 1391: Ptype ttt = ee->tp; ! 1392: switch (e1->base) { ! 1393: case REF: ! 1394: Pptr p = ttt?ttt->is_ptr():0; ! 1395: if (p && p->typ->tconst()) ! 1396: const_obj1 = 1; ! 1397: break; ! 1398: case DOT: ! 1399: tc = ttt ? ttt->tconst() : 0; ! 1400: if (ttt && tc && (!strict_opt || tc!=2)) ! 1401: const_obj1 = 1; ! 1402: } ! 1403: } ! 1404: } ! 1405: ! 1406: TOK bb = base; ! 1407: switch (bb) { ! 1408: case DEREF: ! 1409: if (e2 == 0) bb = MUL; ! 1410: // no break; ! 1411: case CALL: ! 1412: case G_CALL: ! 1413: if (n1 == 0) return 0; // ignore type of argument list ! 1414: } ! 1415: ! 1416: Pname n2 = 0; ! 1417: Ptype t2 = 0; ! 1418: ! 1419: if (e2 && e2->base!=ELIST) { ! 1420: t2 = e2->tp; ! 1421: Ptype tpx = t2->skiptypedefs(); ! 1422: n2 = tpx->is_cl_obj(); ! 1423: const_obj2 = t2->tconst(); ! 1424: Pexpr ee = e2; ! 1425: while (ee && (ee->base==DOT || ee->base==REF)) { ! 1426: Pexpr m = ee->mem; ! 1427: if ( ee->base==REF && m->tp && m->tp->is_ptr()) ! 1428: break; ! 1429: ee = ee->e1; ! 1430: } ! 1431: if (ee) { ! 1432: int tc; ! 1433: Ptype ttt = ee->tp; ! 1434: switch (e2->base) { ! 1435: case REF: ! 1436: Pptr p = ttt?ttt->is_ptr():0; ! 1437: if (p && p->typ->tconst()) ! 1438: const_obj2 = 1; ! 1439: break; ! 1440: case DOT: ! 1441: tc = ttt ? ttt->tconst() : 0; ! 1442: if (ttt && tc && (!strict_opt || tc!=2)) ! 1443: const_obj2 = 1; ! 1444: } ! 1445: } ! 1446: } ! 1447: ! 1448: if (n1==0 && n2==0) return 0; ! 1449: if (n1 && n1->tp == 0) return 0; // make_assign() fudge ! 1450: // error('d',"e1: %k e2: %k", e1?e1->base:0, e2?e2->base:0 ); ! 1451: // error('d',"t1 %t t2 %t",t1,t2); ! 1452: // error('d',"n1 %n n2 %n",n1,n2); ! 1453: /* first try for non-member function: op(e1,e2) or op(e2) or op(e1) */ ! 1454: Pexpr oe2 = e2; ! 1455: Pexpr ee2 = (e2 && e2->base!=ELIST) ? e2 = new expr(ELIST,e2,0) : 0; ! 1456: Pexpr ee1 = e1 ? new expr(ELIST,e1,e2) : ee2; ! 1457: char* obb = oper_name(bb); ! 1458: Pname gname = tbl->look(obb,0); ! 1459: // if necessary check for ambiguities ! 1460: int go = gname ? over_call(gname,ee1) : 0; ! 1461: //error('d',"go %d",go); ! 1462: if (go) gname = Nover; ! 1463: ! 1464: if (n1) { ! 1465: if (bb == ASSIGN) { ! 1466: Pclass c1 = Pclass(n1->tp); ! 1467: //error('d',"look %k %d",bb,c1->memtbl->look(obb,0)); ! 1468: if (c1->memtbl->look(obb,0)==0) { ! 1469: Pclass bcl = c1->baselist?c1->baselist->bclass:0; ! 1470: if (n2==0 ! 1471: || (Pclass(n2->tp)!=c1 ! 1472: && Pclass(n2->tp)->has_base(c1)==0)) { ! 1473: // if legal, a=1 can be optimized to a.ctor(1) ! 1474: if (STD < go) goto glob; ! 1475: return 0; ! 1476: } ! 1477: ! 1478: if (bcl ! 1479: && c1->obj_size!=bcl->obj_size ! 1480: && bcl->memtbl->look(obb,0)) { ! 1481: // cannot inherit from smaller base class ! 1482: // make_assignment(n1); ! 1483: // return try_to_overload(tbl); ! 1484: goto mkas; ! 1485: } ! 1486: ! 1487: if (c1->c_xref&(C_VBASE|C_VPTR|C_ASS)) { ! 1488: // make operator=() if ! 1489: // no base (shouldn't happen ! 1490: // different (smaller) sized base ! 1491: // two bases ! 1492: mkas: ! 1493: if (STD < go) goto glob; ! 1494: // make_assignment(n1); ! 1495: // return try_to_overload(tbl); ! 1496: return make_assignment(n1) ? try_to_overload(tbl) : 0; ! 1497: } ! 1498: // error('d',"n2 %n",n2); ! 1499: // if (n2 && Pclass(n2->tp)==c1) ! 1500: return 0; ! 1501: } ! 1502: // now take care of other assignments, ! 1503: } ! 1504: ! 1505: int dbconv = 0; ! 1506: Pclass ccl = Pclass(n1->tp); ! 1507: // Pexpr mn = Pclass(n1->tp)->memtbl->look(obb,0); ! 1508: Pexpr mn = ccl->memtbl->look(obb,0); ! 1509: // error('d', "tcl %d %t cl %d %t", tcl, tcl, ccl, ccl); ! 1510: if(strcmp(obb,"__as")) { ! 1511: tcl = ccl; // ugh!!! ! 1512: if(!mn) dbconv = STD; ! 1513: } ! 1514: // tcl = ccl; // ugh!!! ! 1515: mn = ccl->find_name(obb,0); ! 1516: ! 1517: Pname mname = Pname(mn); ! 1518: // error('d',"mn %n %d %k %s",mname,mn,mn?mn->base:0,obb); ! 1519: if (mname == 0) goto glob; ! 1520: ! 1521: zaq: ! 1522: switch (mname->base) { ! 1523: case REF: ! 1524: case MDOT: ! 1525: mname = Pname(Pexpr(mname)->mem); ! 1526: goto zaq; ! 1527: } ! 1528: ! 1529: int mo = over_call(mname,e2); ! 1530: int smo = mo; ! 1531: if(mo && dbconv && mo >= dbconv) mo = dbconv; ! 1532: //error('d',"mo %d (go %d)",mo,go); ! 1533: if (mo==0 || mo<go) ! 1534: goto glob; ! 1535: else if (mo && mo==go) { ! 1536: //error('d',"t1 %t t2 %t",t1,t2); ! 1537: if (gname->tp->base == OVERLOAD) { // find right version ! 1538: for (Plist l = Pgen(gname->tp)->fct_list; l; l=l->l) { ! 1539: Pname n = l->f; ! 1540: int x = over_call(n,ee1); ! 1541: if (x == go) { ! 1542: gname = n; ! 1543: break; ! 1544: } ! 1545: } ! 1546: } ! 1547: //error('d',"gname %n: %t",gname,gname->tp); ! 1548: Pname aa = Pfct(gname->tp)->argtype; ! 1549: Pptr p; ! 1550: Ptype gt1 = aa->tp; ! 1551: if (p = gt1->is_ref()) gt1 = p->typ; ! 1552: Ptype gt2 = aa->n_list->tp; ! 1553: //error('d',"gt1 %t gt2 %t",gt1,gt2); ! 1554: if (mname->tp->base == OVERLOAD) { // find right version ! 1555: for (Plist l = Pgen(mname->tp)->fct_list; l; l=l->l) { ! 1556: Pname n = l->f; ! 1557: int x = over_call(n,e2); ! 1558: if (x == smo) { ! 1559: mname = n; ! 1560: break; ! 1561: } ! 1562: } ! 1563: } ! 1564: //error('d',"mname %n: %t",mname,mname->tp); ! 1565: Ptype mt1 = Pfct(mname->tp)->f_this->tp; ! 1566: mt1 = Pptr(mt1)->typ; ! 1567: Ptype mt2 = Pfct(mname->tp)->argtype->tp; ! 1568: //error('d',"mt1 %t mt2 %t",mt1,mt2); ! 1569: Pname mm = new name; ! 1570: Pname a1 = new name; ! 1571: a1->tp = mt1; ! 1572: Pname a2 = new name; ! 1573: a2->tp = mt2; ! 1574: a1->n_list = a2; ! 1575: mm->tp = new fct(void_type,a1,2); ! 1576: Pname gg = new name; ! 1577: Pname a3 = new name; ! 1578: a3->tp = gt1; ! 1579: Pname a4 = new name; ! 1580: a4->tp = gt2; ! 1581: a3->n_list = a4; ! 1582: gg->tp = new fct(void_type,a3,1); ! 1583: aa = dominate(gg,mm,ee1,0); ! 1584: delete a1; ! 1585: delete a2; ! 1586: delete a3; ! 1587: delete a4; ! 1588: DEL( gg->tp ); ! 1589: DEL( mm->tp ); ! 1590: //delete gg->tp; ! 1591: //delete mm->tp; ! 1592: if (aa == 0) { ! 1593: delete gg; ! 1594: delete mm; ! 1595: error("ambiguous operandTs%n and%t for%k",n1,t2,bb); ! 1596: tp = any_type; ! 1597: return this; ! 1598: } ! 1599: else if (aa == gg) { ! 1600: delete gg; ! 1601: delete mm; ! 1602: goto glob; ! 1603: } ! 1604: delete gg; ! 1605: delete mm; ! 1606: } ! 1607: else if (mo < STD) { // user-defined conversion user ! 1608: ! 1609: if (try_to_demote(bb,t1,t2)) ! 1610: error("ambiguous use of overloaded%k",bb); ! 1611: } ! 1612: ! 1613: base = G_CALL; // e1.op(e2) or e1.op() ! 1614: Pname xx = new name(mname->string); // do another lookup ! 1615: // . suppresses virtual ! 1616: e1 = new ref(DOT,e1,xx); ! 1617: if (ee1) delete ee1; ! 1618: return typ(tbl); ! 1619: } ! 1620: ! 1621: if (n2 && e1==0) { /* look for unary operator */ ! 1622: suppress_error++; ! 1623: Pexpr mn = Pclass(n2->tp)->find_name(obb,0); ! 1624: suppress_error--; ! 1625: Pname mname = Pname(mn); ! 1626: if (mname == 0) goto glob; ! 1627: zaqq: ! 1628: switch (mname->base) { ! 1629: case REF: ! 1630: case MDOT: ! 1631: mname = Pname(Pexpr(mname)->mem); ! 1632: goto zaqq; ! 1633: } ! 1634: ! 1635: switch (mname->n_scope) { ! 1636: default: goto glob; ! 1637: case 0: ! 1638: case PUBLIC: break; // try e2.op() ! 1639: } ! 1640: ! 1641: int mo = over_call(mname,0); ! 1642: //error('d',"e2 mo %d (go %d)",mo,go); ! 1643: if (mo==0 || mo<go) ! 1644: goto glob; ! 1645: else if (mo==go) { ! 1646: error("ambiguous operandT%n for%k",n2,bb); ! 1647: tp = any_type; ! 1648: return this; ! 1649: } ! 1650: else if (mo < STD) { // user-defined conversion user ! 1651: if (try_to_demote(bb,t1,t2)) ! 1652: error("ambiguous use of overloaded%k",bb); ! 1653: } ! 1654: base = G_CALL; // e2.op() ! 1655: Pname xx = new name(Nover->string); // do another lookup ! 1656: // . suppresses virtual ! 1657: e1 = new ref(DOT,oe2,xx); ! 1658: e2 = 0; ! 1659: if (ee2) delete ee2; ! 1660: if (ee1 && ee1!=ee2) delete ee1; ! 1661: return typ(tbl); ! 1662: } ! 1663: ! 1664: glob: ! 1665: //error('d',"glob %d",go); ! 1666: ! 1667: if (go) { ! 1668: if (go < STD) { // user-defined conversion necessary => binary ! 1669: if (try_to_demote(bb,t1,t2)) ! 1670: error("ambiguous use of overloaded%k: %t and %t",bb,t1,t2); ! 1671: } ! 1672: ! 1673: base = gname->n_table == gtbl ? G_CALL : CALL; ! 1674: //error('d',"gname %n %t",gname,gname->tp); ! 1675: e1 = new name(gname->string); ! 1676: // if global scope, look only for globals ! 1677: if(gname->n_table == gtbl) Pname(e1)->n_qualifier = sta_name; ! 1678: e2 = ee1; ! 1679: return typ(tbl); ! 1680: } ! 1681: ! 1682: if (ee2) delete ee2; ! 1683: if (ee1 && ee1!=ee2) delete ee1; ! 1684: e2 = oe2; ! 1685: ! 1686: //error('d',"bb %d %k",bb,bb); ! 1687: switch (bb) { ! 1688: case CM: ! 1689: case G_CM: ! 1690: case G_ADDROF: ! 1691: return 0; ! 1692: case ASSIGN: ! 1693: if (n1 ! 1694: && n2 ! 1695: && (n1->tp==n2->tp || Pclass(n2->tp)->has_base(Pclass(n1->tp)))) { ! 1696: if (make_assignment(n1)) ! 1697: return try_to_overload(tbl); ! 1698: else ! 1699: return 0; ! 1700: } ! 1701: case DEREF: ! 1702: case CALL: ! 1703: if (n1 == 0) break; ! 1704: ! 1705: default: /* look for conversions to basic types */ ! 1706: if (n1 ! 1707: && Pclass(n1->tp)->conv ! 1708: && (bb==ANDAND || bb==OROR)) { ! 1709: e1 = check_cond(e1,bb,tbl); ! 1710: return 0; ! 1711: } ! 1712: ! 1713: if (n2 ! 1714: && Pclass(n2->tp)->conv ! 1715: && (bb==ANDAND || bb==OROR || bb==NOT || ! 1716: bb==UMINUS || bb==UPLUS || bb==COMPL)) { ! 1717: e2 = check_cond(e2,bb,tbl); ! 1718: return 0; ! 1719: } ! 1720: ! 1721: // error( 'd', "bb: %k t1: %k t2: %k", bb, t1?t1->base:0, t2?t2->base:0 ); ! 1722: switch (try_to_demote(bb,t1,t2)) { ! 1723: default: ! 1724: if (Lcoerce) error("ambiguous conversion of%n",n1); ! 1725: if (Rcoerce) error("ambiguous conversion of%n",n2); ! 1726: case 0: ! 1727: break; ! 1728: case 1: ! 1729: if (Lcoerce) { ! 1730: Pname xx = new name(Lcoerce->string); ! 1731: Pref r = new ref(DOT,e1,xx); ! 1732: e1 = new expr(G_CALL,r,0); ! 1733: } ! 1734: ! 1735: if (Rcoerce) { ! 1736: Pname xx = new name(Rcoerce->string); ! 1737: Pref r = new ref(DOT,e2,xx); ! 1738: e2 = new expr(G_CALL,r,0); ! 1739: } ! 1740: return typ(tbl); ! 1741: } ! 1742: ! 1743: switch (bb) { ! 1744: case CM: ! 1745: case ADDROF: // has legal built-in meaning ! 1746: return 0; ! 1747: } ! 1748: ! 1749: if (t1 && t2) ! 1750: error("bad operandTs%t%t for%k",t1,t2,bb); ! 1751: else ! 1752: error("bad operandT%t for%k",t1?t1:t2,bb); ! 1753: ! 1754: tp = any_type; ! 1755: return this; ! 1756: } ! 1757: ! 1758: return 0; ! 1759: } ! 1760: ! 1761: Pexpr cast_cptr(Pclass ccl, Pexpr ee, Ptable tbl, int real_cast) ! 1762: /* ! 1763: "ee" is being cast to pointer object of class "ccl" ! 1764: if necessary modify "ee" ! 1765: */ ! 1766: { ! 1767: ! 1768: // Ptype etp = ee->tp; ! 1769: // error('d',"cast_cptr %k ccl %t ee->tp %t",ee->tp->base,ccl,ee->tp); ! 1770: // if (etp->base!=PTR && etp->base!=RPTR) return ee; ! 1771: Ptype etp = ee->tp->is_ptr_or_ref(); ! 1772: if (etp == 0) return ee; ! 1773: ! 1774: Pname on = Pptr(etp)->typ->is_cl_obj(); ! 1775: if (on == 0) return ee; ! 1776: ! 1777: Pclass ocl = Pclass(on->tp); ! 1778: if (ocl==ccl || ccl==0 || ocl==0) return ee; ! 1779: ! 1780: // error('d',"cast_cptr %t(%t) real %d",ccl,ocl,real_cast); ! 1781: int oo = 0; ! 1782: Pexpr r = 0; ! 1783: ! 1784: if (ocl->baselist ! 1785: && (ocl->baselist->bclass!=ccl || ocl->baselist->base!=NAME)) { ! 1786: // casting derived to second or virtual base? ! 1787: Nptr = 0; ! 1788: Nvis = 0; ! 1789: Nalloc_base = 0; ! 1790: vcllist->clear(); ! 1791: vcllist=0; ! 1792: int x = is_unique_base(ocl,ccl->string,0); ! 1793: if (Nvis) { ! 1794: if (real_cast==0) ! 1795: error("cast:%n* ->B%t*; privateBC",on,ccl); ! 1796: else if (warning_opt) ! 1797: error('w',"cast:%n* ->B%t*; privateBC",on,ccl); ! 1798: real_cast = 1; // suppress further error mesages ! 1799: Nvis = 0; ! 1800: } ! 1801: ! 1802: switch (x) { ! 1803: default: ! 1804: error("cast:%n* ->B%t*;%t isB more than once",on,ccl,ccl); ! 1805: case 0: // unrelated; ! 1806: break; ! 1807: case 1: ! 1808: oo = Noffset; ! 1809: break; ! 1810: } ! 1811: ! 1812: if (Nptr) { // => ee?Nptr:0 ! 1813: if (ocl->c_body==1) ocl->dcl_print(0); ! 1814: Nptr->mem = ee; // ee->Pbase_class ! 1815: if ( Nalloc_base ) { ! 1816: // error('d', "cast_cptr: nalloc_base: %s", Nalloc_base); ! 1817: Nptr->i1 = 5; ! 1818: Nptr->string4 = new char[strlen(Nalloc_base)]; ! 1819: strcpy(Nptr->string4,Nalloc_base); ! 1820: Nalloc_base = 0; ! 1821: } ! 1822: else Nptr->i1 = 3; ! 1823: ! 1824: if (ee->base==ADDROF || ee->base==G_ADDROF) ! 1825: ee = Nptr; ! 1826: else { ! 1827: Pexpr p = new expr(QUEST,Nptr,zero); ! 1828: nin = 1; ! 1829: if (ee->not_simple()) { // need temp ! 1830: Ptype t = ee->tp; ! 1831: Pname pp = make_tmp('N',t,tbl); ! 1832: Pname(pp)->n_assigned_to = 1; ! 1833: ee = new expr(ASSIGN,pp,ee); ! 1834: ee->tp = t; ! 1835: Nptr->mem = pp; ! 1836: } ! 1837: nin = 0; ! 1838: p->cond = ee; ! 1839: p->tp = ee->tp; ! 1840: ee = p; ! 1841: } ! 1842: } ! 1843: } ! 1844: ! 1845: if (ccl->baselist ! 1846: && (ccl->baselist->bclass!=ocl || ccl->baselist->base!=NAME)) { ! 1847: // casting second or virtual base to derived? ! 1848: Nptr = 0; ! 1849: vcllist->clear(); ! 1850: vcllist=0; ! 1851: int x = is_unique_base(ccl,ocl->string,0); ! 1852: switch (x) { ! 1853: default: ! 1854: error("cast:%n* ->derived%t*;%n isB more than once",on,ccl,on); ! 1855: case 0: // unrelated; ! 1856: break; ! 1857: case 1: ! 1858: oo = -Noffset; ! 1859: if (Nptr) ! 1860: error("cast:%n* ->derived%t*;%n is virtualB",on,ccl,on); ! 1861: break; ! 1862: } ! 1863: Nvis = 0; // visibility no concern when converting from base to derived ! 1864: } ! 1865: // error('d',"oo %d ee %k",oo,ee->base); ! 1866: if (oo) { // => ee?ee+offset:0 ! 1867: if (ee->base==ADDROF || ee->base==G_ADDROF) ! 1868: ee = rptr(ee->tp,ee,oo); ! 1869: else { ! 1870: Pexpr p; ! 1871: nin = 1; ! 1872: if (ee->not_simple()) { // need temp ! 1873: Ptype t = ee->base==MDOT?ee->mem->tp:ee->tp; ! 1874: Pname pp = make_tmp('M',t,tbl); ! 1875: Pname(pp)->n_assigned_to = 1; ! 1876: ee = new expr(ASSIGN,pp,ee); ! 1877: ee->tp = t; ! 1878: p = rptr(t,pp,oo); ! 1879: } ! 1880: else ! 1881: p = rptr(ee->base==MDOT?ee->mem->tp:ee->tp,ee,oo); ! 1882: nin = 0; ! 1883: Pexpr pp = new expr(QUEST,p,zero); ! 1884: pp->tp = ee->tp; ! 1885: pp->cond = ee; ! 1886: ee = pp; ! 1887: } ! 1888: } ! 1889: ! 1890: Nvis = 0; // Nvis set by has_base() ! 1891: if (ocl->has_base(ccl) && Nvis) { ! 1892: if (real_cast==0) ! 1893: error("cast:%n* ->B%t*; privateBC",on,ccl); ! 1894: else if (warning_opt) ! 1895: error('w',"cast:%n* ->B%t*; privateBC",on,ccl); ! 1896: Nvis = 0; ! 1897: } ! 1898: ! 1899: // error('d',"return %d %k %t",ee,ee->base,ee->tp); ! 1900: return ee; ! 1901: } ! 1902: ! 1903: Pexpr expr::donew(Ptable tbl) ! 1904: { ! 1905: Ptype tt = tp2; ! 1906: Ptype tpx = tt; ! 1907: bit v = 0; ! 1908: bit old = new_type; ! 1909: int init = 0; // non-constructor initialization ! 1910: new_type = 1; ! 1911: ! 1912: tt->dcl(tbl); ! 1913: new_type = old; ! 1914: // error('d',"donew %d %d (%k) tt %t",e1,e2,e2?e2->base:0,tt); ! 1915: if (e1) e1 = e1->typ(tbl); ! 1916: if (e2) e2 = e2->typ(tbl); ! 1917: ll: ! 1918: //error('d',"ll %d",tt->base); ! 1919: switch (tt->base) { ! 1920: default: ! 1921: if ( e1) { ! 1922: if (v) { ! 1923: error("Ir for array created using \"new\""); ! 1924: break; ! 1925: } ! 1926: init = 1; ! 1927: } ! 1928: // if (e1) { ! 1929: // error("Ir for nonCO created using \"new\""); ! 1930: // e1 = 0; ! 1931: // } ! 1932: break; ! 1933: case VEC: ! 1934: if (v && Pvec(tt)->dim) error("only 1st array dimension can be non-constant"); ! 1935: if (Pvec(tt)->size==0 && Pvec(tt)->dim==0) error("array dimension missing in `new'"); ! 1936: // if (Pvec(tt)->dim==zero) { ! 1937: // Pvec(tt)->size = 0; ! 1938: // Pvec(tt)->dim = 0; ! 1939: // } ! 1940: v++; ! 1941: tt = Pvec(tt)->typ; ! 1942: goto ll; ! 1943: case TYPE: ! 1944: tt = Pbase(tt)->b_name->tp; ! 1945: goto ll; ! 1946: case VOID: ! 1947: error("badT for `new': void"); ! 1948: break; ! 1949: case COBJ: ! 1950: { Pname cn = Pbase(tt)->b_name; ! 1951: Pclass cl = Pclass(cn->tp); ! 1952: Pname icn = 0; ! 1953: ! 1954: if ( e1 ) { // arguments ! 1955: if ( e1->e2 == 0 && e1->base == ELIST ) { ! 1956: e1 = e1->e1; ! 1957: e1 = e1->typ(tbl); ! 1958: } ! 1959: icn = (e1->base!=ELIST)?e1->tp->is_cl_obj():0; ! 1960: } ! 1961: //Pname icn = (e1 && e1->base!=ELIST)?e1->tp->is_cl_obj() : 0; ! 1962: ! 1963: Pclass icl = icn ? Pclass(icn->tp) : 0; ! 1964: ! 1965: if (cl->c_abstract) { ! 1966: error("`new' of abstractC%t",cl); ! 1967: break; ! 1968: } ! 1969: ! 1970: if (v && e1) { ! 1971: error("Ir for array ofCO created using \"new\""); ! 1972: break; ! 1973: } ! 1974: ! 1975: if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) { ! 1976: error("new%n;%n isU",cn,cn); ! 1977: break; ! 1978: } ! 1979: ! 1980: Pname ctor = cl->has_ctor(); ! 1981: ! 1982: if (ctor) { ! 1983: if (v) { ! 1984: Pname ic; ! 1985: if ((ic = cl->has_ictor())==0) { ! 1986: error("array ofC%n that does not have aK taking noAs",cn); ! 1987: break; ! 1988: } ! 1989: ! 1990: if (Pfct(ic->tp)->nargs) { ! 1991: error("defaultAs forK for array ofC%n",cn); ! 1992: break; ! 1993: } ! 1994: } ! 1995: ! 1996: if (icl ! 1997: && cl->has_itor()==0 // incomplete: ! 1998: // what if X(Y&) exists ! 1999: // for class Y : X ? ! 2000: && (icl==cl || icl->has_base(cl))) { ! 2001: init = 1; ! 2002: break; ! 2003: } ! 2004: e1 = call_ctor(tbl,0,ctor,e1); ! 2005: } ! 2006: else if (e1) { ! 2007: if (icl==cl || icl->has_base(cl)) ! 2008: init = 1; ! 2009: else ! 2010: error("new%n(As ); %n does not have aK",cn,cn); ! 2011: } ! 2012: } ! 2013: } ! 2014: ! 2015: if (init) { ! 2016: Pname tmp = make_tmp('N',tt->addrof(),tbl); ! 2017: e1 = e1->typ(tbl); ! 2018: if (tt->check(e1->tp,ASSIGN)) ! 2019: error("badIrT %t for new operator (%t X)",e1->tp,tt); ! 2020: e1 = new expr(0,tmp,e1); ! 2021: tmp->assign(); ! 2022: } ! 2023: ! 2024: // tp = (v) ? tpx : tpx->addrof(); ! 2025: switch (v) { ! 2026: case 0: ! 2027: tp = tpx->addrof(); ! 2028: break; ! 2029: case 1: ! 2030: tp = tpx; ! 2031: break; ! 2032: default: ! 2033: tp = tpx; ! 2034: } ! 2035: //error('d',"donew(%d) -> %t",v,tp); ! 2036: return this; ! 2037: } ! 2038: ! 2039: static is_dataMemPtr( Pexpr ee ) ! 2040: /* this is utterly implementation dependent ! 2041: * called by expr::lval to determine ! 2042: * const objects bounds to pointers to data members ! 2043: */ ! 2044: { ! 2045: Pexpr te = ee->e1; ! 2046: if ( te == 0 ) return 0; ! 2047: if ( te->base != PLUS ) return 0; ! 2048: if ( (te = te->e2) == 0 ) return 0; ! 2049: if ( te->base != MINUS ) return 0; ! 2050: if ( (te = te->e1) == 0 ) return 0; ! 2051: if ( te->base != CAST ) return 0; ! 2052: if ( (te = te->e1) == 0 ) return 0; ! 2053: if ( te->tp->base != PTR ) return 0; ! 2054: if ( Pptr(te->tp)->memof == 0 ) return 0; ! 2055: return 1; ! 2056: } ! 2057: ! 2058: Pname dominate(Pname n1, Pname n2, Pexpr arg, int const_obj) ! 2059: /* ! 2060: the two functions n1 and n2 are equal after the intersect ! 2061: rule is applied. Does the one dominate the other in terms ! 2062: of const? ! 2063: ! 2064: If so return it, otherwise return 0; ! 2065: */ ! 2066: { ! 2067: Pname res = 0; ! 2068: ! 2069: Pfct f1 = Pfct(n1->tp); ! 2070: Pfct f2 = Pfct(n2->tp); ! 2071: ! 2072: Pname a1 = f1->argtype; ! 2073: Pname a2 = f2->argtype; ! 2074: Pexpr e = arg; ! 2075: //error('d',"dominate: %n %t %t e %d",n1,f1,f2,e); ! 2076: ! 2077: if (e == 0) { ! 2078: if (const_obj) { ! 2079: if (f1->f_const && f2->f_const==0) return n1; ! 2080: if (f2->f_const && f1->f_const==0) return n2; ! 2081: } ! 2082: else { ! 2083: if (f1->f_const==0 && f2->f_const) return n1; ! 2084: if (f2->f_const==0 && f1->f_const) return n2; ! 2085: } ! 2086: return 0; ! 2087: } ! 2088: ! 2089: for(; a1 && a2 && e; a1 = a1->n_list, a2 = a2->n_list, e = e->e2) { ! 2090: Ptype t1 = a1->tp; ! 2091: Ptype t2 = a2->tp; ! 2092: Ptype at = e->e1->tp; ! 2093: //error('d',"t1 %t t2 %t at %t",t1,t2,at); ! 2094: if (t1==t2 || t1->check(t2,0)==0 ) ! 2095: continue; ! 2096: Pptr r1 = t1->is_ref(); ! 2097: Pptr r2 = t2->is_ref(); ! 2098: //error('d',"const_problem %t %t %t %d",t1,t2,at,const_problem); ! 2099: if (const_problem) { // t1 and t1 differs only in const ! 2100: Pname rr; ! 2101: if (at->check(t1,0)==0 && const_problem==0) { ! 2102: if (t1->is_ptr()) ! 2103: rr = n1; ! 2104: else ! 2105: goto nc; ! 2106: } ! 2107: else if (at->check(t2,0)==0 && const_problem==0) { ! 2108: if (t2->is_ptr()) ! 2109: rr = n2; ! 2110: else ! 2111: goto nc; ! 2112: } ! 2113: else if (r1 && r1->typ->check(at,0)==0 && const_problem==0) ! 2114: rr = n1; ! 2115: else if (r2 && r2->typ->check(at,0)==0 && const_problem==0) ! 2116: rr = n2; ! 2117: else ! 2118: goto nc; ! 2119: ! 2120: if (res && res!=rr) return 0; // mutual dominace ! 2121: res = rr; ! 2122: continue; // identical ! 2123: } ! 2124: nc: ! 2125: if (r2 && (t1==r2 || t1->check(r2->typ,0)==0)) continue; ! 2126: if (r1 && (t2==r1 || t2->check(r1->typ,0)==0)) continue; ! 2127: ! 2128: Pname rr = 0; ! 2129: if (t1==at || exact1(a1,at)) { ! 2130: rr = n1; ! 2131: if(t2==at || exact1(a2,at)) ! 2132: continue; ! 2133: } ! 2134: else if (t2==at || exact1(a2,at)) ! 2135: rr = n2; ! 2136: else { // try integral promotion ! 2137: if (exact2(a1,at)) ! 2138: rr = n1; ! 2139: if (exact2(a2,at)) { ! 2140: if (rr) rr = 0; ! 2141: else rr = n2; ! 2142: } ! 2143: } ! 2144: if (!rr) { // try standard conversions ! 2145: if (exact3(a1,at)) ! 2146: rr = n1; ! 2147: if (exact3(a2,at)) { ! 2148: if (rr) rr = 0; ! 2149: else rr = n2; ! 2150: } ! 2151: } ! 2152: if (rr) { ! 2153: if (res && res!=rr) return 0; // mutual dominance ! 2154: res = rr; ! 2155: continue; ! 2156: } ! 2157: ! 2158: int r = pr_dominate(t1,t2); ! 2159: //error('d',"pr1 %d",r); ! 2160: if (r) { ! 2161: Pname rr = r==1?n1:n2; ! 2162: if (res && res!=rr) return 0; // mutual dominace ! 2163: res = rr; ! 2164: continue; ! 2165: } ! 2166: ! 2167: r = pr_dominate(t1,at); ! 2168: //error('d',"pr2 %d",r); ! 2169: if (r==2) { ! 2170: r = pr_dominate(t2,at); ! 2171: if (r!=2) res = n1; ! 2172: continue; ! 2173: } ! 2174: ! 2175: r = pr_dominate(t2,at); ! 2176: //error('d',"pr3 %d",r); ! 2177: if (r==2) { ! 2178: if (res && res!=n2) return 0; // mutual dominace ! 2179: res = n2; ! 2180: continue; ! 2181: } ! 2182: ! 2183: } ! 2184: ! 2185: if (e) { ! 2186: //error('d',"more args %t a1 %t a2 %t",e->e1->tp,a1?a1->tp:0,a2?a2->tp:0); ! 2187: int k1 = f1->nargs_known!=ELLIPSIS; ! 2188: int k2 = f2->nargs_known!=ELLIPSIS; ! 2189: if (a1 && a1->tp->check(e->e1->tp,ASSIGN)==0) return n1; ! 2190: if (a2 && a2->tp->check(e->e1->tp,ASSIGN)==0) return n2; ! 2191: if (k1 && k2) return 0; ! 2192: } ! 2193: ! 2194: if (a1==0 && a2 && a2->n_initializer==0) return 0; ! 2195: if (a2==0 && a1 && a1->n_initializer==0) return 0; ! 2196: if (res==0) ! 2197: if (const_obj) { ! 2198: if (f1->f_const && f2->f_const==0) return n1; ! 2199: if (f2->f_const && f1->f_const==0) return n2; ! 2200: } ! 2201: else { ! 2202: if (f1->f_const==0 && f2->f_const) return n1; ! 2203: if (f2->f_const==0 && f1->f_const) return n2; ! 2204: } ! 2205: //error('d'," -> %n %t",res,res?res->tp:0); ! 2206: return res; ! 2207: } ! 2208:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.