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