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