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