|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/expr3.c 1.3.5.31" */ ! 2: /*************************************************************************** ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All rigths Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: expr3.c: ! 11: ! 12: type check function calls, casts, and explicit coercions ! 13: ! 14: ************************************************************************/ ! 15: ! 16: #include "cfront.h" ! 17: #include "size.h" ! 18: ! 19: int pr_dominate(Ptype t1, Ptype t2) ! 20: /* ! 21: */ ! 22: { ! 23: Pname cn1 = t1->is_cl_obj(); ! 24: Pname cn2 = t2->is_cl_obj(); ! 25: //error('d',"pr_dominate(%t,%t)",t1,t2); ! 26: ! 27: if (cn1==0 || cn2==0) { ! 28: Ptype p1 = t1->is_ptr(); ! 29: Ptype p2 = t2->is_ptr(); ! 30: if (p1 && p2) { // pointers ! 31: cn1 = Pptr(p1)->typ->is_cl_obj(); ! 32: cn2 = Pptr(p2)->typ->is_cl_obj(); ! 33: if (cn1==0 || cn2==0) return 0; ! 34: } ! 35: else { ! 36: p1 = t1->is_ref(); ! 37: p2 = t2->is_ref(); ! 38: if (p1 && p2) { // references ! 39: cn1 = Pptr(p1)->typ->is_cl_obj(); ! 40: cn2 = Pptr(p2)->typ->is_cl_obj(); ! 41: if (cn1==0 || cn2==0) return 0; ! 42: } ! 43: // else if (p1 && cn2) { ! 44: // cn1 = Pptr(p1)->typ->is_cl_obj(); ! 45: // } ! 46: else ! 47: return 0; // not the same and not classes ! 48: } ! 49: } ! 50: Pclass c1 = Pclass(cn1->tp); ! 51: Pclass c2 = Pclass(cn2->tp); ! 52: //error('d'," c1 : c2 %d; c2 : c1 %d",c1->has_base(c2),c2->has_base(c1)); ! 53: if (c1->has_base(c2)) return 1; ! 54: if (c2->has_base(c1)) return 2; ! 55: } ! 56: ! 57: static exact1(Pname,Ptype); ! 58: static exact2(Pname,Ptype); ! 59: static exact3(Pname,Ptype); ! 60: ! 61: static Pname user_dominate(Pname n1, Pname n2) ! 62: { ! 63: Pfct f1 = Pfct(n1->tp); ! 64: Pfct f2 = Pfct(n2->tp); ! 65: ! 66: Pname a1 = f1->argtype; ! 67: Pname a2 = f2->argtype; ! 68: //error('d',"user_dominate: %n %t %t",n1,f1,f2); ! 69: ! 70: int k1 = f1->nargs_known!=ELLIPSIS; ! 71: int k2 = f2->nargs_known!=ELLIPSIS; ! 72: ! 73: if (k1 && k2==0) return n1; ! 74: if (k2 && k1==0) return n2; ! 75: ! 76: for(; a1 && a2; a1 = a1->n_list, a2 = a2->n_list) { ! 77: Ptype t1 = a1->tp; ! 78: Ptype t2 = a2->tp; ! 79: } ! 80: ! 81: if (a1) return n1; ! 82: if (a2) return n2; ! 83: ! 84: return 0; ! 85: } ! 86: ! 87: Pname dominate(Pname n1, Pname n2, Pexpr arg, int const_obj, int level) ! 88: /* ! 89: the two functions n1 and n2 can each respond to a call using ! 90: standard conversions. Does the one dominate the other in the ! 91: sense that all its arguments are identical to the other or ! 92: classes defived from the class of the corresponding argument ! 93: of the other. ! 94: ! 95: If so return it, otherwise return 0; ! 96: */ ! 97: { ! 98: Pname res = 0; ! 99: ! 100: Pfct f1 = Pfct(n1->tp); ! 101: Pfct f2 = Pfct(n2->tp); ! 102: ! 103: Pname a1 = f1->argtype; ! 104: Pname a2 = f2->argtype; ! 105: Pexpr e = arg; ! 106: //error('d',"dominate: %n %t %t e %d",n1,f1,f2,e); ! 107: ! 108: if (e == 0) { ! 109: if (const_obj) { ! 110: if (f1->f_const && f2->f_const==0) return n1; ! 111: if (f2->f_const && f1->f_const==0) return n2; ! 112: } ! 113: else { ! 114: if (f1->f_const==0 && f2->f_const) return n1; ! 115: if (f2->f_const==0 && f1->f_const) return n2; ! 116: } ! 117: return 0; ! 118: } ! 119: ! 120: for(; a1 && a2 && e; a1 = a1->n_list, a2 = a2->n_list, e = e->e2) { ! 121: Ptype t1 = a1->tp; ! 122: Ptype t2 = a2->tp; ! 123: Ptype at = e->e1->tp; ! 124: //error('d',"t1 %t t2 %t at %t",t1,t2,at); ! 125: if (t1==t2 || t1->check(t2,0)==0) continue; ! 126: Pptr r1 = t1->is_ref(); ! 127: Pptr r2 = t2->is_ref(); ! 128: //error('d',"const_problem %t %t %t %d",t1,t2,at,const_problem); ! 129: if (const_problem) { // t1 and t1 differs only in const ! 130: Pname rr; ! 131: if (at->check(t1,0)==0 && const_problem==0) { ! 132: if (t1->is_ptr()) ! 133: rr = n1; ! 134: else ! 135: goto nc; ! 136: } ! 137: else if (at->check(t2,0)==0 && const_problem==0) { ! 138: if (t2->is_ptr()) ! 139: rr = n2; ! 140: else ! 141: goto nc; ! 142: } ! 143: else if (r1 && r1->typ->check(at,0)==0 && const_problem==0) ! 144: rr = n1; ! 145: else if (r2 && r2->typ->check(at,0)==0 && const_problem==0) ! 146: rr = n2; ! 147: else ! 148: return 0; ! 149: ! 150: if (res && res!=rr) return 0; // mutual dominace ! 151: res = rr; ! 152: continue; // identical ! 153: } ! 154: nc: ! 155: if (r2 && (t1==r2 || t1->check(r2->typ,0)==0)) continue; ! 156: if (r1 && (t2==r1 || t2->check(r1->typ,0)==0)) continue; ! 157: int r = pr_dominate(t1,t2); ! 158: //error('d',"pr1 %d",r); ! 159: if (r) { ! 160: Pname rr = r==1?n1:n2; ! 161: if (res && res!=rr) return 0; // mutual dominace ! 162: res = rr; ! 163: continue; ! 164: } ! 165: ! 166: r = pr_dominate(t1,at); ! 167: //error('d',"pr2 %d",r); ! 168: if (r==2) { ! 169: if (res && res!=n1) return 0; // mutual dominace ! 170: res = n1; ! 171: r = pr_dominate(t2,at); ! 172: if (r==2) return 0; // mutual dominace ! 173: continue; ! 174: } ! 175: ! 176: r = pr_dominate(t2,at); ! 177: //error('d',"pr3 %d",r); ! 178: if (r==2) { ! 179: if (res && res!=n2) return 0; // mutual dominace ! 180: res = n2; ! 181: continue; ! 182: } ! 183: ! 184: Pname rr = 0; ! 185: if (t1==at || exact1(a1,at)) ! 186: rr = n1; ! 187: else if (t2==at || exact1(a2,at)) ! 188: rr = n2; ! 189: else if (1<level) { // try integral promotion ! 190: if (exact2(a1,at)) ! 191: rr = n1; ! 192: if (exact2(a2,at)) { ! 193: if (rr) return 0; ! 194: rr = n2; ! 195: } ! 196: } ! 197: else if (1<level) { // try standard conversions ! 198: if (exact3(a1,at)) ! 199: rr = n1; ! 200: if (exact3(a2,at)) { ! 201: if (rr) return 0; ! 202: rr = n2; ! 203: } ! 204: } ! 205: if (rr) { ! 206: if (res && res!=rr) return 0; // mutual dominance ! 207: res = rr; ! 208: continue; ! 209: } ! 210: } ! 211: //if (a1==0 && a2 && a2->n_initializer==0) return 0; // wrong number of arguments ! 212: //if (a2==0 && a1 && a1->n_initializer==0) return 0; // wrong number of arguments ! 213: ! 214: if (e) { ! 215: //error('d',"more args %t a1 %t a2 %t",e->e1->tp,a1?a1->tp:0,a2?a2->tp:0); ! 216: int k1 = f1->nargs_known!=ELLIPSIS; ! 217: int k2 = f2->nargs_known!=ELLIPSIS; ! 218: if (a1 && a1->tp->check(e->e1->tp,ASSIGN)==0) return n1; ! 219: if (a2 && a2->tp->check(e->e1->tp,ASSIGN)==0) return n2; ! 220: if (k1 && k2) return 0; ! 221: } ! 222: ! 223: if (a1==0 && a2 && a2->n_initializer==0) return 0; ! 224: if (a2==0 && a1 && a1->n_initializer==0) return 0; ! 225: if (res==0) ! 226: if (const_obj) { ! 227: if (f1->f_const && f2->f_const==0) return n1; ! 228: if (f2->f_const && f1->f_const==0) return n2; ! 229: } ! 230: else { ! 231: if (f1->f_const==0 && f2->f_const) return n1; ! 232: if (f2->f_const==0 && f1->f_const) return n2; ! 233: } ! 234: //error('d'," -> %n %t",res,res?res->tp:0); ! 235: return res; ! 236: } ! 237: ! 238: Pname Ntmp; ! 239: ! 240: static refd; // initialization routine called by ref_init, do not apply itor ! 241: extern loc no_where; ! 242: ! 243: Pname make_tmp(char c, Ptype t, Ptable tbl) ! 244: { ! 245: Pname tn = tbl->t_name; ! 246: ! 247: if (tn && tn->tp) error('s',"defaultA too complicated"); ! 248: ! 249: if (Ntmp == 0) { ! 250: Pname cn = t->is_cl_obj(); ! 251: if (cn && Pclass(cn->tp)->has_dtor()) Ntmp = cn; ! 252: } ! 253: ! 254: //error('d',"tbl %d cstmt %d %d sti %d",tbl,Cstmt,Cstmt?Cstmt->memtbl:0,sti_tbl); ! 255: if (Cstmt) { // make Cstmt into a block ! 256: if (Cstmt->memtbl == 0) Cstmt->memtbl = new table(4,tbl,0); ! 257: tbl = Cstmt->memtbl; ! 258: } ! 259: else if (tbl == gtbl) { ! 260: if (sti_tbl == 0) sti_tbl = new table(8,gtbl,0); ! 261: tbl = sti_tbl; ! 262: } ! 263: ! 264: Pname tmpx = new name(make_name(c)); ! 265: tmpx->where = no_where; ! 266: tmpx->tp = t; ! 267: (void) t->tsizeof(); ! 268: if ( t->base == COBJ ) { ! 269: Pclass cl = Pclass(Pbase(t)->b_name->tp); ! 270: // error( 'd', "cl: %s %d", cl->string, cl->lex_level ); ! 271: if ( cl->lex_level ) tmpx->lex_level = cl->lex_level; ! 272: } ! 273: Pname tmp = tmpx->dcl(tbl,ARG); // ARG => no init ! 274: //error('d',"make_tmp %n %t",tmp,t); ! 275: delete tmpx; ! 276: tmp->n_scope = FCT; ! 277: return tmp; ! 278: } ! 279: ! 280: Pexpr init_tmp(Pname tmp, Pexpr init, Ptable tbl) ! 281: { ! 282: Pname cn = tmp->tp->is_cl_obj(); ! 283: Pname ct = cn ? Pclass(cn->tp)->has_itor() : 0; ! 284: ! 285: tmp->n_assigned_to = 1; ! 286: //error('d',"init_tmp %n ct %n refd %d",tmp,ct,refd); ! 287: if (ct) { // must initialize ! 288: if (refd) { ! 289: //error('d',"'orrible %k",init->e1->base); ! 290: switch (init->e1->base) { // 'orrible 'ack ! 291: case NAME: ! 292: case REF: ! 293: case DEREF: ! 294: if (init->e1->tp->is_ptr()) ! 295: init = init->e1; ! 296: else ! 297: init = new expr(G_CM,init,init->e1->address()); ! 298: ! 299: } ! 300: if (ct->tp->base == OVERLOAD) ct = Pgen(ct->tp)->fct_list->f; // first fct ! 301: tbl = 0; ! 302: } ! 303: return call_ctor(tbl,tmp,ct,init,DOT); ! 304: } ! 305: Pexpr ass = new expr(ASSIGN,tmp,init); // no ctor: can assign ! 306: ass->tp = tmp->tp; ! 307: return ass; ! 308: } ! 309: /* ! 310: int exact0(Pname nn, Ptype at) ! 311: // return 1 if ! 312: // exact match ! 313: ! 314: { ! 315: if (nn == 0) return 0; //known==ELLIPSIS; ! 316: Ptype nt = nn->tp; ! 317: if (at == nt) return 1; ! 318: //error('d',"exact0 %d",nt->check(at,0)); ! 319: return nt->check(at,0)==0; ! 320: } ! 321: */ ! 322: ! 323: int exact3(Pname nn, Ptype at) ! 324: /* ! 325: return 1 if ! 326: match with standard conversions ! 327: */ ! 328: { ! 329: if (nn == 0) return 0; //known==ELLIPSIS; ! 330: Ptype nt = nn->tp; ! 331: if (at == nt) return 1; ! 332: ! 333: //error('d',"exact3 %d",nt->check(at,ASSIGN)); ! 334: return nt->check(at,ASSIGN)==0; ! 335: } ! 336: ! 337: int exact1(Pname nn, Ptype at) ! 338: /* ! 339: return 1 if ! 340: exact match with ! 341: T <-> const T ! 342: X -> X& ! 343: T* -> const T* ! 344: T* -> T*const ! 345: taken into account ! 346: */ ! 347: { ! 348: if (nn == 0) return 0;//known==ELLIPSIS; ! 349: Ptype nt = nn->tp; ! 350: if (at == nt) return 1; ! 351: ! 352: //error('d',"exact1 nt %t at %t",nt,at); ! 353: if (nt->check(at,0)) { ! 354: //error('d',"nt %t at %t cp %d",nt,at,const_problem); ! 355: if (const_problem) return 1; // handle T <-> const T ! 356: ! 357: Pptr rt = nt->is_ref(); //handle X -> X& ! 358: if (rt && (at->check(Pptr(rt)->typ,0)==0 || const_problem)) return 1; ! 359: ! 360: Pptr art = at->is_ptr(); ! 361: if (rt && art) return 0; // ptrs do not match refs ! 362: ! 363: // handle T* -> const T* and ! 364: // T* -> T*const ! 365: if (rt || (rt = nt->is_ptr())) { ! 366: if (art == 0) art = at->is_ref(); ! 367: if (art) { ! 368: //error('d',"art %t %t",art->typ,rt->typ); ! 369: if (art->typ->check(rt->typ,0)) { ! 370: if (const_problem) return 1; ! 371: } ! 372: else // T* -> T*const ! 373: return 1; ! 374: } ! 375: } ! 376: return 0; ! 377: } ! 378: return 1; ! 379: } ! 380: ! 381: Pexpr Ninit; // default argument used; ! 382: int Nstd; // standard coercion used (derived* =>base* or int=>long or ...) ! 383: ! 384: bit exact_match(Pname n, Pexpr arg) ! 385: /* ! 386: look for an exact match between "n" and the argument list "arg" ! 387: This function goes through three stages: ! 388: (1) exact match (no coercions at all) ! 389: (2) do integral promotions and float->double and re-try exact match ! 390: (3) try for unique standard conversions ! 391: ! 392: */ ! 393: { ! 394: Pfct f = Pfct(n->tp); ! 395: register Pexpr e; ! 396: register Pname nn; ! 397: ! 398: //error('d',"exact_match(%n) %t",n,n->tp); ! 399: ! 400: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) { ! 401: Pexpr a = e->e1; ! 402: Ptype at = a->tp; ! 403: if (at->base == ANY) return 0; ! 404: if (at->base == ZTYPE) at = int_type; ! 405: if (exact1(nn,at)==0) return 0; ! 406: } ! 407: ! 408: //error('d',"exact %d -> %d",nn,nn?nn->n_initializer!=0:1); ! 409: if (nn) { ! 410: Ninit = nn->n_initializer; ! 411: return Ninit!=0; ! 412: } ! 413: ! 414: //error('d',"return 1"); ! 415: return 1; // exact match without any promotions ! 416: } ! 417: ! 418: int exact2(Pname nn, Ptype at) ! 419: /* ! 420: return 1 if ! 421: do integral promotion and float->double on at, then match ! 422: */ ! 423: { ! 424: //error('d',"exact2 nt %t at %t",nn?nn->tp:0,at); ! 425: atat: ! 426: switch (at->base) { ! 427: case TYPE: ! 428: at = Pbase(at)->b_name->tp; ! 429: goto atat; ! 430: case EOBJ: ! 431: at = Penum(Pbase(at)->b_name->tp)->e_type; ! 432: break; ! 433: case ZTYPE: ! 434: at = int_type; ! 435: break; ! 436: case CHAR: ! 437: case SHORT: ! 438: at = (Pbase(at)->b_unsigned && at->tsizeof()==SZ_INT) ? uint_type : int_type; ! 439: break; ! 440: case FLOAT: ! 441: at = double_type; ! 442: } ! 443: ! 444: if (nn == 0) return 0;//known==ELLIPSIS; ! 445: Ptype nt = nn->tp; ! 446: //error('d'," exact2 nt %t at %t",nt,at); ! 447: if (at == nt) return 1; ! 448: if (nt->check(at,0)) { ! 449: if (const_problem) return 1; ! 450: ! 451: Pptr rt = nt->is_ref(); // handle X -> X& ! 452: if (rt && (at->check(Pptr(rt)->typ,0)==0 || const_problem)) return 1; ! 453: ! 454: Pptr art = at->is_ptr(); ! 455: if (rt && art) return 0; // ptrs do not match refs ! 456: ! 457: // handle T* -> const T* and ! 458: // T* -> T*const ! 459: if (rt || (rt = nt->is_ptr())) { ! 460: if (art == 0) art = at->is_ref(); ! 461: if (art) { ! 462: if (art->typ->check(rt->typ,0)) { ! 463: if (const_problem) return 1; ! 464: } ! 465: else // T* -> T*const ! 466: return 1; ! 467: } ! 468: } ! 469: return 0; ! 470: } ! 471: return 1; ! 472: } ! 473: ! 474: bit prom_match(Pname n, Pexpr arg) ! 475: /* ! 476: look for an exact match between "n" and the argument list "arg" ! 477: using integral promotions and float->double ! 478: ! 479: */ ! 480: { ! 481: Pfct f = Pfct(n->tp); ! 482: register Pexpr e; ! 483: register Pname nn; ! 484: ! 485: //error('d',"prom_match(%n) %t",n,n->tp); ! 486: ! 487: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) { ! 488: Pexpr a = e->e1; ! 489: Ptype at = a->tp; ! 490: if (at->base == ANY) return 0; ! 491: ! 492: if (exact2(nn,at)==0) return 0; ! 493: } ! 494: ! 495: if (nn) { ! 496: Ninit = nn->n_initializer; ! 497: return Ninit!=0; ! 498: } ! 499: ! 500: return 1; // exact match with promotions ! 501: } ! 502: ! 503: bit std_match(Pname n, Pexpr arg) ! 504: /* ! 505: look for an exact match between "n" and the argument list "arg" ! 506: using standard conversions ! 507: ! 508: */ ! 509: { ! 510: Pfct f = Pfct(n->tp); ! 511: register Pexpr e; ! 512: register Pname nn; ! 513: ! 514: //error('d',"std_match(%n) %t",n,n->tp); ! 515: ! 516: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) { ! 517: Pexpr a = e->e1; ! 518: Ptype at = a->tp; ! 519: ! 520: if (at->base == ANY) return 0; ! 521: if (nn == 0) return 0;//f->nargs_known==ELLIPSIS; ! 522: ! 523: Ptype nt = nn->tp; ! 524: tptp: ! 525: switch (nt->base) { ! 526: case TYPE: ! 527: nt = Pbase(nt)->b_name->tp; ! 528: goto tptp; ! 529: case RPTR: ! 530: if (at==zero_type && Pptr(nt)->typ->is_ptr()==0) return 0; //break; ! 531: if (nt->check(at,COERCE)) { ! 532: Pptr pt = at->addrof(); ! 533: nt->base = PTR; // handle derived classes ! 534: if (nt->check(pt,COERCE)) { ! 535: nt->base = RPTR; ! 536: delete pt; ! 537: return 0; ! 538: } ! 539: nt->base = RPTR; ! 540: delete pt; ! 541: } ! 542: break; ! 543: default: ! 544: // if (nt->check(at,COERCE)) return 0; ! 545: switch (at->base) { ! 546: default: ! 547: if (nt->check(at,COERCE)) return 0; ! 548: break; ! 549: case OVERLOAD: ! 550: { ! 551: // the actual argument is an overloaded function ! 552: // we'll try each instance until one matches ! 553: register Plist gl; ! 554: int no_match = 1; ! 555: ! 556: for (gl = Pgen(at)->fct_list; gl; gl=gl->l) { ! 557: if (nt->check(gl->f->tp,COERCE)==0) { ! 558: no_match = 0; ! 559: break; ! 560: } ! 561: } ! 562: ! 563: if ( no_match ) return 0; ! 564: } ! 565: } // end at->base switch ! 566: ! 567: } ! 568: } ! 569: ! 570: if (nn) { ! 571: Ninit = nn->n_initializer; ! 572: return Ninit!=0; ! 573: } ! 574: ! 575: return 1; ! 576: } ! 577: ! 578: Pname Ncoerce; ! 579: int ref_cast; ! 580: ! 581: bit can_coerce(Ptype t1, Ptype t2) ! 582: /* return number of possible coercions of t2 into t1, ! 583: Ncoerce holds a coercion function (not constructor), if found ! 584: */ ! 585: { ! 586: int zz = 0; ! 587: Ncoerce = 0; ! 588: if (t2->base == ANY) return 0; ! 589: //error('d',"can_coerce t1 %t t2 %t",t1,t2); ! 590: ! 591: tptp: ! 592: switch (t1->base) { ! 593: case TYPE: ! 594: t1 = Pbase(t1)->b_name->tp; ! 595: goto tptp; ! 596: case RPTR: ! 597: rloop: ! 598: switch (t2->base) { ! 599: case TYPE: ! 600: t2 = Pbase(t2)->b_name->tp; ! 601: goto rloop; ! 602: // case VEC: ! 603: // case PTR: ! 604: // case RPTR: ! 605: // if (t1->check(t2,COERCE) == 0) return 1; ! 606: default: ! 607: { Ptype tt2 = t2->addrof(); ! 608: if (t1->check(tt2,COERCE) == 0) return 1; ! 609: if (ref_cast) break;//return 0; // (T&): no coercions ! 610: // except operator T&() ! 611: Ptype tt1 = Pptr(t1)->typ; ! 612: while (tt1->base==TYPE) tt1 = Pbase(tt1)->b_name->tp; ! 613: int bc = Pbase(tt1)->b_const; ! 614: Pbase(tt1)->b_const = 0; ! 615: int i = can_coerce(tt1,t2); ! 616: Pbase(tt1)->b_const = bc; ! 617: if (i) return i; ! 618: zz = 1; ! 619: } ! 620: } ! 621: } ! 622: ! 623: Pname c1 = t1->is_cl_obj(); ! 624: Pname c2 = t2->is_cl_obj(); ! 625: int val = 0; ! 626: if (ref_cast || zz) goto oper_coerce; ! 627: if (c1) { ! 628: Pclass cl = Pclass(c1->tp); ! 629: if (c2 && c2->tp==cl) return 1; ! 630: // A more comprehensive test for template classes ! 631: if (c2 && (Pclass(c1->tp)->same_class(Pclass(c2->tp)))) return 1 ; ! 632: ! 633: /* look for constructor ! 634: with one argument ! 635: or with default for second argument ! 636: of acceptable type ! 637: */ ! 638: Pname ctor = cl->has_ctor(); ! 639: if (ctor == 0) goto oper_coerce; ! 640: register Pfct f = Pfct(ctor->tp); ! 641: //error('d',"ctor %n f %t",ctor,f); ! 642: switch (f->base) { ! 643: case FCT: ! 644: switch (f->nargs) { ! 645: case 1: ! 646: one: ! 647: { Ptype tt = f->argtype->tp; ! 648: //error('d',"tt %t t2 %t -> %d cp %d",tt,t2,tt->check(t2,COERCE),const_problem); ! 649: if (tt->check(t2,COERCE)==0) ! 650: val = 1; ! 651: else if (const_problem) { ! 652: Pptr p1 = tt->is_ptr_or_ref(); ! 653: if (p1==0 || p1->typ->tconst()) val = 1; ! 654: } ! 655: if (tt = tt->is_ref()) { ! 656: Pptr pt = t2->addrof(); // handle derived classed ! 657: tt->base = PTR; ! 658: if (tt->check(pt,COERCE) == 0) val = 1; ! 659: tt->base = RPTR; ! 660: delete pt; ! 661: } ! 662: goto oper_coerce; ! 663: } ! 664: default: ! 665: if (f->argtype->n_list->n_initializer) goto one; ! 666: case 0: ! 667: goto oper_coerce; ! 668: } ! 669: case OVERLOAD: ! 670: { register Plist gl; ! 671: ! 672: for (gl=Pgen(f)->fct_list; gl; gl=gl->l) { // look for match ! 673: Pname nn = gl->f; ! 674: Pfct ff = Pfct(nn->tp); ! 675: ! 676: switch (ff->nargs) { ! 677: case 0: ! 678: break; ! 679: case 1: ! 680: over_one: ! 681: { Ptype tt = ff->argtype->tp; ! 682: //error('d',"over one %t %t -> %d %d",tt,t2,tt->check(t2,COERCE),const_problem); ! 683: if (tt->check(t2,COERCE)==0) ! 684: val = 1; ! 685: else if (const_problem) { ! 686: Pptr p1 = tt->is_ptr_or_ref(); ! 687: if (p1==0 || p1->typ->tconst()) val = 1; ! 688: } ! 689: if (tt=tt->is_ref()) { ! 690: Pptr pt = t2->addrof(); // handle derived classed ! 691: tt->base = PTR; ! 692: if (tt->check(pt,COERCE) == 0) { ! 693: tt->base = RPTR; ! 694: delete pt; ! 695: val = 1; ! 696: goto oper_coerce; ! 697: } ! 698: tt->base = RPTR; ! 699: delete pt; ! 700: } ! 701: break; ! 702: } ! 703: default: ! 704: if (ff->argtype->n_list->n_initializer) goto over_one; ! 705: } ! 706: } ! 707: goto oper_coerce; ! 708: } ! 709: default: ! 710: error('i',"cannot_coerce(%k)\n",f->base); ! 711: } ! 712: } ! 713: ! 714: oper_coerce: ! 715: //error('d',"oper_coerce %d",val); ! 716: if (c2) { ! 717: Pclass cl = Pclass(c2->tp); ! 718: int std = 0; ! 719: int oval = val; ! 720: extern Pname conv_dominates(Pname,Pname); ! 721: for (Pname ox, on=cl->conv; on; on=ox) { ! 722: Pfct f = Pfct(on->tp); ! 723: ox = on->n_list; ! 724: Nstd = 0; ! 725: //error('d',"on %n -> %d",on,t1->check(f->returns,COERCE)); ! 726: if (t1->check(f->returns,COERCE) == 0) { ! 727: if (Nstd==0) { // forget solutions involving standard conversions ! 728: Pname old = Ncoerce; ! 729: if (std) { // forget ! 730: val = oval+1; ! 731: std = 0; ! 732: Ncoerce = on; ! 733: } ! 734: else if (Ncoerce == 0) { ! 735: // val = 1; ! 736: val++; ! 737: Ncoerce = on; ! 738: } ! 739: else if ((Ncoerce = conv_dominates(Ncoerce,on))==0) { ! 740: if (val == 1) { ! 741: //error('d',"val==1 on %n old %n",on,old); ! 742: Ptype ton = Pfct(on->tp)->returns; ! 743: Ptype tco = Pfct(old->tp)->returns; ! 744: if (t1->check(ton,0)==0) ! 745: ; ! 746: else if (t1->check(tco,0)==0) ! 747: on = old; ! 748: else ! 749: val++; ! 750: } ! 751: else ! 752: val++; ! 753: Ncoerce = on; ! 754: } ! 755: } ! 756: else { // take note only if no exact match seen ! 757: if (Ncoerce==0 || on->tp->check(Ncoerce->tp,0)) { ! 758: if (val==0 || std) { ! 759: ! 760: if (Ncoerce) Ncoerce = conv_dominates(Ncoerce,on); ! 761: if (Ncoerce == 0) { ! 762: Ncoerce = on; ! 763: val++; ! 764: std = 1; ! 765: } ! 766: } ! 767: } ! 768: } ! 769: } ! 770: ! 771: } ! 772: } ! 773: //error('d',"val %d",val); ! 774: if (val) return val; ! 775: if (c1 && Pclass(c1->tp)->has_itor()) return 0; ! 776: //error('d',"%t->check(%t) -> %d",t1,t2,t1->check(t2,COERCE)); ! 777: if (t1->check(t2,COERCE)) return 0; ! 778: return 1; ! 779: } ! 780: ! 781: int gen_coerce(Pname n, Pexpr arg) ! 782: /* ! 783: look to see if the argument list "arg" can be coerced into a call of "n" ! 784: 1: it can ! 785: 0: it cannot or it can be done in more than one way ! 786: */ ! 787: { ! 788: Pfct f = (Pfct) n->tp; ! 789: register Pexpr e; ! 790: register Pname nn; ! 791: ! 792: //error('d',"gen_coerce(%n,%d) %t",n,arg,n->tp); ! 793: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) { ! 794: if (nn == 0) return f->nargs_known==ELLIPSIS; ! 795: Pexpr a = e->e1; ! 796: Ptype at = a->tp; ! 797: int i = can_coerce(nn->tp,at); ! 798: //error('d',"i %d",i); ! 799: if (i != 1) return 0; ! 800: } ! 801: if (nn && nn->n_initializer==0) return 0; ! 802: return 1; ! 803: } ! 804: ! 805: ! 806: Pname Nover; ! 807: // int Nover_coerce; ! 808: ! 809: int over_call(Pname n, Pexpr arg) ! 810: /* ! 811: return 4 if n(arg) can be performed without coercion of arg ! 812: return 3 if n(arg) can be performed only with promotion coercion of arg ! 813: return 2 if n(arg) can be performed only with standard coercion of arg ! 814: return 1 if n(arg) can be performed only with user defined coercion of arg ! 815: return 0 if n(arg) is an error ! 816: Nover is the function found, if any ! 817: Nstd is the number of standard coercions used ! 818: */ ! 819: { ! 820: register Plist gl; ! 821: Pgen g = Pgen(n->tp); ! 822: if (arg && arg->base!= ELIST) error('i',"ALX"); ! 823: ! 824: //error('d',"over_call(%n) %k",n,n->tp->base); ! 825: extern suppress_error; ! 826: suppress_error = 1; ! 827: // Nover_coerce = 0; ! 828: Nstd = 0; ! 829: switch (g->base) { ! 830: default: error('i',"over_call(%t)\n",g); ! 831: case OVERLOAD: break; ! 832: case FCT: ! 833: Nover = n; ! 834: Ninit = 0; ! 835: if (exact_match(n,arg)) {suppress_error = 0; return 4;} ! 836: if (prom_match(n,arg)) {suppress_error = 0; return 3;} ! 837: if (std_match(n,arg) && Ninit==0) {suppress_error = 0; return 2;} ! 838: Nstd = 0; ! 839: suppress_error = 0; ! 840: return gen_coerce(n,arg); ! 841: } ! 842: ! 843: Pname exact = 0; ! 844: int no_exact = 0; ! 845: int ret = 0; ! 846: Pname nret; ! 847: for (gl=g->fct_list; gl; gl=gl->l) { /* look for match */ ! 848: Nover = gl->f; ! 849: Ninit = 0; ! 850: Nstd = 0; ! 851: if (exact_match(Nover,arg)) {suppress_error = 0; return 4;} // no coercion ! 852: // if (prom_match(Nover,arg)) return 3; // only promotion ! 853: // if (std_match(Nover,arg) && Ninit==0) return 2; // only built-in conversion ! 854: if (ret<3 && prom_match(Nover,arg)) { ! 855: nret = Nover; ! 856: ret = 3; ! 857: } ! 858: if (ret<2 && std_match(Nover,arg) && Ninit==0) { ! 859: nret = Nover; ! 860: ret = 2; ! 861: } ! 862: } ! 863: ! 864: suppress_error = 0; ! 865: if (ret) { ! 866: Nover = nret; ! 867: return ret; ! 868: } ! 869: ! 870: Nover = 0; ! 871: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */ ! 872: Pname nn = gl->f; ! 873: if (gen_coerce(nn,arg)) { ! 874: Nover = nn; ! 875: return 1; ! 876: } ! 877: } ! 878: return 0; ! 879: ! 880: } ! 881: ! 882: Ptype expr::call_fct(Ptable tbl) ! 883: /* ! 884: check "this" call: ! 885: e1(e2) ! 886: e1->typ() and e2->typ() has been done ! 887: */ ! 888: { ! 889: Pfct f; ! 890: Pname fn; ! 891: int x; ! 892: int k; ! 893: Pname nn; ! 894: Pexpr e; ! 895: Ptype t; ! 896: Pexpr arg = e2; ! 897: Ptype t1 = e1?e1->tp:0; ! 898: int argno; ! 899: Pexpr etail = 0; ! 900: Pname no_virt = 0; // set if explicit qualifier was used: c::f() ! 901: Pname chk = 0; // set if visibility check is needed ! 902: // that is if function name might have been ! 903: // found without use of find_name() ! 904: int const_obj = 0; ! 905: ! 906: if (t1 == any_type) return any_type; ! 907: ! 908: switch (base) { ! 909: case CALL: ! 910: case G_CALL: break; ! 911: default: error('i',"call_fct(%k)",base); ! 912: } ! 913: ! 914: //error('d',"call %d %k %n arg %d",this,e1->base,e1->base==NAME?e1:0,arg); ! 915: if (t1 == 0) error('i',"call_fct(e1=%d,e1->tp=%t)",e1,t1); ! 916: if (arg && arg->base!=ELIST) error('i',"badAL%d%k",arg,arg->base); ! 917: ! 918: switch (e1->base) { ! 919: case NAME: ! 920: fn = Pname(e1); ! 921: //error('d',"name %n %k",fn,fn->n_oper); ! 922: switch (fn->n_oper) { ! 923: case 0: ! 924: case CTOR: ! 925: case DTOR: ! 926: case TYPE: ! 927: case NEW: ! 928: case DELETE: ! 929: break; ! 930: default: // real operator: check for operator+(1,2); ! 931: if (arg == 0) break; ! 932: Pexpr a = arg->e1; // first operand ! 933: ! 934: if (Pfct(fn->tp)->memof // obj.operator(1) is OK ! 935: || a->tp->is_cl_obj() ! 936: || a->tp->is_ref()) break; ! 937: a = arg->e2; ! 938: if (a == 0) // unary ! 939: error("%k of basicT",fn->n_oper); ! 940: else { // binary ! 941: a = a->e1; // second operand ! 942: if (a->tp->is_cl_obj() || a->tp->is_ref()) break; ! 943: error("%k of basicTs",fn->n_oper); ! 944: } ! 945: break; ! 946: } ! 947: break; ! 948: case REF: ! 949: case DOT: ! 950: no_virt = Pname(e1->n_initializer); ! 951: e1->n_initializer = 0; ! 952: // const_obj = (e1&&e1->e1)?e1->e1->tp->tconst():0; ! 953: if (e1 && e1->e1) { ! 954: Ptype t = e1->e1->tp; ! 955: Pptr tt = t->is_ptr_or_ref(); ! 956: //error('d',"t %t tt %t",t,tt); ! 957: const_obj = (tt ? tt->typ : t)->tconst(); ! 958: } ! 959: case MDOT: ! 960: { Pexpr n = e1->mem; ! 961: lxlx: ! 962: switch (n->base) { ! 963: case MDOT: ! 964: // reverse mdot (see expr::print()) ! 965: // p->a.b() => (&p->a)->b() => b(&p->a) ! 966: // or p->a->b() => (p->a)->b() => b(p->a) ! 967: // or oo.a.b() => (&oo.a)->b() => b(&oo.a) ! 968: // or oo.a->b() => (oo.a)->b() => b(oo.a) ! 969: { ! 970: Pexpr r = e1; ! 971: Pexpr p = r->e1; ! 972: for (Pexpr m = r->mem; m->base==MDOT; m = r->mem) { ! 973: p = new mdot(m->string2,p); ! 974: p->i1 = m->i1+2; ! 975: p->tp = p->mem->tp; ! 976: r->mem = m->mem; ! 977: r->e1 = p; ! 978: } ! 979: } ! 980: case REF: ! 981: case DOT: ! 982: n = n->mem; ! 983: goto lxlx; ! 984: case NAME: ! 985: break; ! 986: default: ! 987: error('i',"ref %k",n->base); ! 988: } ! 989: fn = Pname(n); ! 990: //error('d',"mem %n",fn); ! 991: break; ! 992: } ! 993: case MEMPTR: ! 994: default: ! 995: fn = 0; ! 996: }; ! 997: ! 998: lll: ! 999: //error('d',"lll: %t %k",t1,t1->base); ! 1000: switch (t1->base) { ! 1001: case TYPE: ! 1002: t1 = Pbase(t1)->b_name->tp; ! 1003: goto lll; ! 1004: ! 1005: case PTR: // pf() allowed as shorthand for (*pf)() ! 1006: switch (Pptr(t1)->typ->base) { ! 1007: case FCT: ! 1008: case OVERLOAD: ! 1009: if (Pptr(t1)->memof) error("O missing in call throughP toMF"); ! 1010: t1 = Pptr(t1)->typ; ! 1011: fn = 0; ! 1012: goto lll; ! 1013: } ! 1014: ! 1015: default: ! 1016: if (fn) ! 1017: error("call of%n;%n is a%t",fn,fn,e1->tp); ! 1018: else ! 1019: error("call of%kE ofT%t",e1->base,e1->tp); ! 1020: ! 1021: case ANY: ! 1022: return any_type; ! 1023: ! 1024: case OVERLOAD: ! 1025: { register Plist gl; ! 1026: Pgen g = Pgen(t1); ! 1027: Pname found = 0; ! 1028: Pname exact = 0; ! 1029: int no_exact = 0; ! 1030: ! 1031: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match ! 1032: register Pname nn = gl->f; ! 1033: if (exact_match(nn,arg)) { ! 1034: //error('d',"found exact %n %t",nn,nn->tp); ! 1035: if (found) { ! 1036: // check if one fct dominates the other ! 1037: Pname d = dominate(found,nn,arg,const_obj,0); ! 1038: if (d) ! 1039: nn = d; ! 1040: else ! 1041: error("two exact matches for%n:%t and%t",nn,nn->tp,found->tp); ! 1042: } ! 1043: found = nn; ! 1044: } ! 1045: } ! 1046: //error('d',"found exact2 %n",found); ! 1047: if (found) goto fnd; ! 1048: ! 1049: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match ! 1050: register Pname nn = gl->f; ! 1051: ! 1052: if (prom_match(nn,arg)) { ! 1053: if (found) { ! 1054: // check if one fct dominates the other ! 1055: Pname d = dominate(found,nn,arg,const_obj,1); ! 1056: if (d) ! 1057: nn = d; ! 1058: else ! 1059: error("two exact matches (after integral promotions) for%n:%t and%t",nn,nn->tp,found->tp); ! 1060: } ! 1061: found = nn; ! 1062: } ! 1063: } ! 1064: //error('d',"found exact2 %n",found); ! 1065: if (found) goto fnd; ! 1066: ! 1067: // for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match ! 1068: // register Pname nn = gl->f; ! 1069: // ! 1070: // if (exact_match(nn,arg) || prom_match(nn,arg)) { ! 1071: // found = nn; ! 1072: // goto fnd; ! 1073: // } ! 1074: // } ! 1075: ! 1076: Pname mvec[10]; ! 1077: for (gl=g->fct_list; gl; gl=gl->l) { // look for match ! 1078: // with standard conversion ! 1079: register Pname nn = gl->f; ! 1080: Ninit = 0; ! 1081: Nstd = 0; ! 1082: if (std_match(nn,arg)) { ! 1083: // if (Nstd == 0) { ! 1084: // found = nn; ! 1085: // goto fnd; ! 1086: // } ! 1087: if (exact) { ! 1088: // check if one fct dominates the other ! 1089: Pname d = dominate(exact,nn,arg,const_obj,2); ! 1090: if (d == 0) { ! 1091: mvec[no_exact++] = nn; ! 1092: // no_exact++; ! 1093: // error("two standard conversions possible for%n: %t and %t",fn,exact->tp,nn->tp); ! 1094: } ! 1095: else ! 1096: exact = d; ! 1097: } ! 1098: else ! 1099: exact = nn; ! 1100: } ! 1101: ! 1102: } ! 1103: ! 1104: //error('d',"excact %n",exact); ! 1105: if (exact) { ! 1106: if (no_exact) { ! 1107: while (no_exact) { ! 1108: Pname d = dominate(exact,mvec[--no_exact],arg,const_obj,2); ! 1109: if (d) ! 1110: exact = d; ! 1111: else ! 1112: error("two standard conversions possible for%n: %t and %t",fn,exact->tp,mvec[no_exact]->tp); ! 1113: } ! 1114: ! 1115: } ! 1116: //error('d',"found exact3 %n",found); ! 1117: found = exact; ! 1118: goto fnd; ! 1119: } ! 1120: ! 1121: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */ ! 1122: register Pname nn = gl->f; ! 1123: if (gen_coerce(nn,arg)) { ! 1124: //error('d',"user2 %n %t",nn,nn->tp); ! 1125: if (found) { ! 1126: // check if one fct dominates the other ! 1127: Pname d = dominate(found,nn,arg,const_obj,3); ! 1128: if (d == 0) d = user_dominate(found,nn); ! 1129: if (d == 0) { ! 1130: error("ambiguousA for%n: %t and %t",fn,found->tp,nn->tp); ! 1131: goto fnd; ! 1132: } ! 1133: else ! 1134: found = d; ! 1135: } ! 1136: else ! 1137: found = nn; ! 1138: } ! 1139: } ! 1140: ! 1141: fnd: ! 1142: //error('d',"fnd %t",found?found->tp:0); ! 1143: if (found) { ! 1144: chk = fn = found; ! 1145: f = Pfct(fn->tp); ! 1146: } ! 1147: else { ! 1148: error("badAL for%n (no match against any %n)",fn,fn); ! 1149: return any_type; ! 1150: } ! 1151: break; ! 1152: } ! 1153: case FCT: ! 1154: f = Pfct(t1); ! 1155: if (fn) { ! 1156: switch (fn->n_oper) { ! 1157: case CTOR: ! 1158: case TYPE: ! 1159: chk = fn; ! 1160: } ! 1161: } ! 1162: } ! 1163: ! 1164: //error('d',"chk %n",chk); ! 1165: if (chk) { ! 1166: Ptype t = 0; ! 1167: Pexpr ee = e1->e1; ! 1168: ! 1169: switch (e1->base) { ! 1170: case REF: // ptr->chk() ! 1171: if (ee == 0) { // 0->x() fudge handling new x() ! 1172: check_visibility(chk,no_virt,Pclass(chk->n_table->t_name->tp),tbl,cc->nof); ! 1173: break; ! 1174: }; ! 1175: t = ee->tp; ! 1176: while(t->base==TYPE) t = Pbase(t)->b_name->tp; ! 1177: t = Pptr(t)->typ; ! 1178: break; ! 1179: case DOT: // obj.chk() ! 1180: t = ee->tp; ! 1181: } ! 1182: ! 1183: Pname cn = t?t->is_cl_obj():0; ! 1184: Pclass cl = cn?Pclass(cn->tp):0; // class of ``this'' for chk ! 1185: ! 1186: if (cl) { ! 1187: if (chk->n_oper==CTOR ! 1188: && chk->n_protect ! 1189: && cc->nof ! 1190: && cc->nof->n_oper==CTOR) ! 1191: // BUG: cannot handle protected base ! 1192: // class constructor ! 1193: ; ! 1194: else { ! 1195: check_visibility(chk,no_virt,cl,tbl,cc->nof); ! 1196: } ! 1197: } ! 1198: } ! 1199: ! 1200: if (fn && f->f_result==0) { ! 1201: // protect against class cn; cn f(); ... class cn { cn(cn&); ... }; ! 1202: make_res(f); ! 1203: //error('d',"returns %t",f->returns); ! 1204: f->returns->tsizeof(); // make sure it is declared ! 1205: } ! 1206: ! 1207: //error('d',"fn %n %t printed %d",fn,fn?fn->tp:0,fn?fn->n_dcl_printed:0); ! 1208: if (fn && fn->n_dcl_printed==0) { ! 1209: if (f->f_inline==0 && f->f_imeasure) { ! 1210: extern void uninline(Pname fn); ! 1211: uninline(fn); ! 1212: } ! 1213: ! 1214: // ensure printout of class declaration: ! 1215: for (Pname nn=f->argtype; nn; nn=nn->n_list) ! 1216: if (nn->tp->is_cl_obj()) (void) nn->tp->tsizeof(); ! 1217: ! 1218: fn->dcl_print(0); ! 1219: } ! 1220: ! 1221: if (no_virt && f->f_static==0) { ! 1222: if (e1->base==REF || e1->base==DOT) e1->n_initializer = fn; ! 1223: } ! 1224: else ! 1225: fct_name = fn; ! 1226: //error('d',"fn %n %t %d %d",fn,f,f->f_this,f->f_static); ! 1227: if (f->f_this) { //SSS call of non-static memberfunction ! 1228: switch (e1->base) { ! 1229: case MEMPTR: ! 1230: case REF: ! 1231: case DOT: ! 1232: break; ! 1233: default: ! 1234: error("O orP missing for%n ofT %t",fct_name,f); ! 1235: } ! 1236: } ! 1237: else if (fn) { //SSS call of static function ! 1238: sss: ! 1239: switch (e1->base) { ! 1240: case REF: ! 1241: case DOT: ! 1242: e1 = e1->mem; ! 1243: goto sss; ! 1244: } ! 1245: } ! 1246: ! 1247: if (fn) fn->use(); // a patch: ctors are sometimes not use()d ! 1248: ! 1249: if (f->f_const==0 ! 1250: && (fn==0 || (fn->n_oper!=CTOR && fn->n_oper!=DTOR))) { //CCC ! 1251: Pexpr ee = e1->e1; ! 1252: if (ee) { ! 1253: Ptype tt = ee->tp; ! 1254: switch (e1->base) { ! 1255: case REF: ! 1256: { Pptr p = tt?tt->is_ptr():0; ! 1257: if (p && p->typ->tconst()) ! 1258: error(strict_opt?0:'w',"non-constMF%n called for constO",fn); ! 1259: // is really an error, but only warn to help transition ! 1260: break; ! 1261: } ! 1262: case DOT: ! 1263: if (tt && tt->tconst()) ! 1264: error(strict_opt?0:'w',"non-constMF%n called for constO",fn); ! 1265: // is really an error, but only warn to help transition ! 1266: } ! 1267: } ! 1268: } ! 1269: ! 1270: t = f->returns; ! 1271: x = f->nargs; ! 1272: k = f->nargs_known; ! 1273: ! 1274: e = arg; ! 1275: if (k == 0) goto rlab; ! 1276: ! 1277: for (nn=f->argtype, argno=1; e||nn; nn=nn->n_list, e=etail->e2, argno++) { ! 1278: Pexpr a; ! 1279: ! 1280: if (e) { ! 1281: a = e->e1; ! 1282: etail = e; ! 1283: ! 1284: if (nn) { /* type check */ ! 1285: Ptype t1 = nn->tp; ! 1286: //error('d',"argtp %t etp %t a %k",t1,a->tp,a->base); ! 1287: ! 1288: lx: ! 1289: switch (t1->base) { ! 1290: case TYPE: ! 1291: t1 = Pbase(t1)->b_name->tp; ! 1292: goto lx; ! 1293: case RPTR: ! 1294: { Ptype pt = Pptr(t1)->typ; ! 1295: if (pt->base != FCT || ! 1296: ( pt->base == FCT && ! 1297: pt->check(a->tp,0))) ! 1298: a = ref_init(Pptr(nn->tp),a,tbl); ! 1299: goto cbcb; ! 1300: } ! 1301: case COBJ: ! 1302: if (a->base!=G_CM ! 1303: || nn->tp->check(a->tp,ASSIGN)) ! 1304: a = class_init(0,t1,a,tbl); ! 1305: if (nn->n_xref) { ! 1306: // (temp.ctor(arg),&arg) ! 1307: a = a->address(); ! 1308: } ! 1309: else { ! 1310: // defend against: ! 1311: // int f(X); ... X(X&); ! 1312: Pname cln = Pbase(t1)->b_name; ! 1313: if (cln && Pclass(cln->tp)->has_itor()) { ! 1314: // mark X(X&) arguments ! 1315: nn->n_xref = 1; ! 1316: a = a->address(); ! 1317: } ! 1318: } ! 1319: cbcb: ! 1320: //error('d',"cbcb: a %d %k %t",a->base,a->base,a->tp); ! 1321: if (a->base==G_CM) { ! 1322: if (a->e1->base==DEREF) a->e1 = a->e1->e2; // (*e1,e2) => (e1,e2) ! 1323: //error('d'," a %d %k",a->e1->base,a->e1->base); ! 1324: if (a->e1->base==G_CALL ! 1325: && Pname(a->e1->fct_name) ! 1326: && Pname(a->e1->fct_name)->n_oper==CTOR ! 1327: && (a->e2->base==G_ADDROF || a->e2->base==ADDROF)) { ! 1328: a = a->e1; // (ctor(&tmp),&tmp) => ctor(&tmp) ! 1329: //error('d',"tmp %k %n",a->e2->base,a->e2->e2); ! 1330: goto cccc; ! 1331: } ! 1332: else if (a->e2->base==G_ADDROF ! 1333: && a->e2->e2->base==NAME) { ! 1334: cccc: ! 1335: //error('d',"cccc: a %d %k %t",a->base,a->base,a->tp); ! 1336: if (t1->base==RPTR ! 1337: && Pptr(t1)->typ->tconst()==0) { // temporary used ! 1338: if (warning_opt) ! 1339: error('w',"temporary used for non-const%tA",nn->tp); ! 1340: else { ! 1341: Ptype atp = a->tp; ! 1342: if (atp==void_type ! 1343: && a->base==G_CALL ! 1344: && a->e1->tp->base==FCT) ! 1345: atp = Pfct(a->e1->tp)->s_returns; ! 1346: ! 1347: Ptype tt = t1->is_ref(); ! 1348: //error('d',"tt %t atp %t",tt,atp); ! 1349: if (tt) { ! 1350: if (Pptr(tt)->typ->tsizeof()!=atp->tsizeof()) { // sliced ! 1351: Ptype aat = atp->is_ptr_or_ref(); ! 1352: if (aat==0 ! 1353: || Pptr(tt)->typ->tsizeof()!=Pptr(aat)->typ->tsizeof()) ! 1354: error('w',"temporary used for non-const%tA",nn->tp); ! 1355: } ! 1356: } ! 1357: else if (t1->tsizeof()!=atp->tsizeof()) // sliced ! 1358: error('w',"temporary used for non-const%tA",nn->tp); ! 1359: } ! 1360: ! 1361: // if (warning_opt // blabber ! 1362: // || t1->tsizeof()!=a->tp->tsizeof())) // sliced ! 1363: // error('w',"temporary used for non-const%tA",nn->tp); ! 1364: ! 1365: } ! 1366: } ! 1367: } ! 1368: e->e1 = a; ! 1369: break; ! 1370: case ANY: ! 1371: goto rlab; ! 1372: case PTR: ! 1373: {// Pexpr x = a; ! 1374: e->e1/* = a */= ptr_init(Pptr(t1),a,tbl); ! 1375: // if (x==a || x==a->e2) goto def; // needs checking ! 1376: if (Pchecked == 0) goto def; ! 1377: break; ! 1378: } ! 1379: // e->e1 = a = ptr_init(Pptr(t1),a,tbl); ! 1380: // goto def; ! 1381: case CHAR: ! 1382: case SHORT: ! 1383: case INT: ! 1384: // if (a->base==ICON && a->tp==long_type) ! 1385: // error('w',"long constantA for%n,%kX",fn,t1->base); ! 1386: { Ptype t = a->tp; ! 1387: csi: ! 1388: switch (t->base) { ! 1389: case TYPE: ! 1390: t = Pbase(t)->b_name->tp; goto csi; ! 1391: case LONG: ! 1392: case FLOAT: ! 1393: case DOUBLE: ! 1394: case LDOUBLE: ! 1395: error('w',"%t passed as %t",a->tp,t1); ! 1396: } ! 1397: } ! 1398: // no break ! 1399: case LONG: ! 1400: if (Pbase(t1)->b_unsigned ! 1401: && a->base==UMINUS ! 1402: && a->e2->base==ICON) ! 1403: error('w',"negativeA for%n, unsignedX",fn); ! 1404: default: ! 1405: def: ! 1406: { Pexpr x = try_to_coerce(t1,a,"argument",tbl); ! 1407: //error('d',"x %d t1 %t nn %t a1 %t",x,t1,nn->tp,a->tp); ! 1408: if (x) ! 1409: e->e1 = x; ! 1410: else if (nn->tp->check(a->tp,ARG)) { ! 1411: error("badA %dT for%n:%t (%tX)",argno,fn,a->tp,nn->tp); ! 1412: return any_type; ! 1413: } ! 1414: } ! 1415: } ! 1416: ! 1417: Pexpr tt = e->e1; ! 1418: while ( tt->base == CAST ) ! 1419: tt = tt->e1; ! 1420: if ( tt->base == ILIST ) ! 1421: e->e1 = tt; ! 1422: ! 1423: if (e->e1->base == ILIST) { ! 1424: extern Pbase mptr_type; ! 1425: Pexpr mptr_assign(Pexpr, Pexpr); ! 1426: // memptr constant ! 1427: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t)) ! 1428: Pname temp = make_tmp('A',mptr_type,tbl); ! 1429: e->e1 = mptr_assign(temp,e->e1); ! 1430: e->e1 = a = new expr(G_CM,e->e1,temp); ! 1431: a->tp = temp->tp; ! 1432: } ! 1433: ! 1434: } ! 1435: else { ! 1436: if (k != ELLIPSIS) { ! 1437: error("unexpected %dA for%n",argno,fn); ! 1438: return any_type; ! 1439: } ! 1440: goto rlab; ! 1441: } ! 1442: } ! 1443: else { /* default argument? */ ! 1444: a = nn->n_initializer; ! 1445: if (a == 0) { ! 1446: error("A %d ofT%tX for%n",argno,nn->tp,fn); ! 1447: return any_type; ! 1448: } ! 1449: if (a->base == ILIST) { ! 1450: extern Pbase mptr_type; ! 1451: Pexpr mptr_assign(Pexpr, Pexpr); ! 1452: // memptr constant ! 1453: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t)) ! 1454: Pname temp = make_tmp('A',mptr_type,tbl); ! 1455: a = mptr_assign(temp,a); ! 1456: a = new expr(G_CM,a,temp); ! 1457: a->tp = temp->tp; ! 1458: } ! 1459: a->permanent = 2; // ought not be necessary, but it is ! 1460: e = new expr(ELIST,a,0); ! 1461: if (etail) ! 1462: etail->e2 = e; ! 1463: else ! 1464: e2 = e; ! 1465: etail = e; ! 1466: } ! 1467: } ! 1468: ! 1469: rlab: ! 1470: //error('d',"rlab fct_name %n %t",fct_name,fct_name?fct_name->tp:0); ! 1471: for (; e; e = e->e2) { // unchecked arguments ! 1472: Pexpr a = e->e1; ! 1473: Pname cn; ! 1474: ! 1475: if (a->base==NAME && a->tp->base==FCT) { ! 1476: // function name that escaped the type system: ! 1477: // update use count ! 1478: a->lval(ADDROF); ! 1479: } ! 1480: else if (cn = a->tp->is_cl_obj()) { ! 1481: Pclass cl = Pclass(cn->tp); ! 1482: if (cl->has_ctor() || cl->memtbl->look("__as",0)/*cl->has_oper(ASSIGN)*/) ! 1483: error("O ofC%t withK or = copied",cl); ! 1484: } ! 1485: else if (a->tp->is_ref()) ! 1486: e->e1 = a->contents(); ! 1487: } ! 1488: ! 1489: if (f->f_result) { // f(args) => (f(&temp,args),temp) ! 1490: Pname tn = make_tmp('R',f->returns,tbl); ! 1491: e2 = new expr(ELIST,tn->address(),e2); ! 1492: //error('d',"result %n",fn); ! 1493: Pexpr ee = new expr(0,0,0); ! 1494: *ee = *this; ! 1495: base = G_CM; // (f(&temp,args),temp) ! 1496: e1 = ee; ! 1497: e2 = tn; ! 1498: tp = tn->tp; ! 1499: } ! 1500: ! 1501: return t; ! 1502: } ! 1503: ! 1504: Pexpr ref_init(Pptr p, Pexpr init, Ptable tbl) ! 1505: /* ! 1506: initialize the "p" with the "init" ! 1507: remember to call ptr_init to ensure that pointers to second bases ! 1508: are handled correctly. ! 1509: */ ! 1510: { ! 1511: register Ptype it = init->tp; ! 1512: Pptr px = p; ! 1513: while (px->base == TYPE) px = Pptr(Pbase(px)->b_name->tp); ! 1514: Ptype p1 = px->typ; ! 1515: Pname c1 = p1->is_cl_obj(); ! 1516: //error('d',"ref_init: p %t, p1 %t, px %t, init->tp %t",p,p1,px,it); ! 1517: ! 1518: if (init->base == ILIST) error("IrL as RIr"); ! 1519: ! 1520: if (init->base==NAME ! 1521: && Pname(init)->n_scope==ARG ! 1522: && init->tp->base==FLOAT) ! 1523: error('w',"initializing a float& with floatA is non-portable"); ! 1524: ! 1525: Ptype itb = it; ! 1526: while(itb->base == TYPE) itb = Pbase(itb)->b_name->tp; ! 1527: { Ptype tt = itb->addrof(); ! 1528: px->base = PTR; // allow &x for y& when y : public x ! 1529: // but not &char for int& ! 1530: int x = px->check(tt,COERCE); ! 1531: if(const_problem) x = 0; /* handled here */ ! 1532: if (x == 0) { //CCC type is fine check for constness: ! 1533: if (init->tp->tconst() ! 1534: && vec_const==0 ! 1535: && fct_const==0) { ! 1536: // not ``it'' ! 1537: if (init->base == ELIST) init = init->e1; ! 1538: if (px->typ->tconst() == 0) error("R to constO"); ! 1539: px->base = RPTR; ! 1540: // if we have a const lvalue we can still pass its address ! 1541: extern ignore_const; ! 1542: ignore_const++; ! 1543: if (init->lval(0)) { ! 1544: init->lval(ADDROF); // force output ! 1545: ignore_const--; ! 1546: //error('d',"in1 %t",init->tp); ! 1547: return ptr_init(px,init->address(),tbl);//return init->address(); ! 1548: } ! 1549: ignore_const--; ! 1550: goto xxx; ! 1551: } ! 1552: px->base = RPTR; ! 1553: if (init->lval(0)) { // can pass the address // no temporary needed ! 1554: init->lval(ADDROF); // force output ! 1555: //error('d',"px %t init %t init %t",px,init->tp,init->tp); ! 1556: return ptr_init(px,init->address(),tbl); ! 1557: } ! 1558: goto xxx; ! 1559: } ! 1560: ! 1561: px->base = RPTR; ! 1562: } ! 1563: ! 1564: //error('d',"c1 %n",c1); ! 1565: if (c1) { // assigning to a const X & is fine ! 1566: ref_cast++; ! 1567: Pexpr x = try_to_coerce(p,init,"reference initialization",tbl); ! 1568: ref_cast--; ! 1569: if (x) { ! 1570: init = x; ! 1571: goto xxx; ! 1572: } ! 1573: Ptype p1b = p1; ! 1574: while (p1b->base==TYPE) p1b = Pbase(p1b)->b_name->tp; ! 1575: int bc = Pbase(p1b)->b_const; ! 1576: Pbase(p1b)->b_const = 0; ! 1577: refd = 1; /* disable itor */ ! 1578: Pexpr a = class_init(0,p1,init,tbl); ! 1579: Pbase(p1b)->b_const = bc; ! 1580: refd = 0; ! 1581: if (a==init && init->tp!=any_type) goto xxx; ! 1582: //error('d',"ri a %d %k",a->base,a->base); ! 1583: switch (a->base) { ! 1584: case G_CALL: ! 1585: // case CM: ! 1586: // case G_CM: ! 1587: init = a; ! 1588: goto xxx; ! 1589: } ! 1590: a = a->address(); ! 1591: //error('d',"ri2 a %d %k",a->base,a->base); ! 1592: a = ptr_init(px,a,tbl); ! 1593: //error('d',"ri3 a %d %k",a->base,a->base); ! 1594: return a; ! 1595: // return ptr_init(px,a->address(),tbl);//a->address(); ! 1596: } ! 1597: ! 1598: //error('d',"p1 %t it %t",p1,it); ! 1599: /* NOTE: in this region, several uses of "it" were left even though ! 1600: the resolution of it to its basetype was removed above. ! 1601: Since these are type checks, it seems a a bad idea to ignore signed/unsigned ! 1602: and related items. --benson */ ! 1603: if (p1->check(it,0)) { ! 1604: ! 1605: if (p1->check(it,ASSIGN) == 0) { ! 1606: // if (p1->is_ptr()) // check for base* = derived* ! 1607: // goto xxx; ! 1608: ! 1609: // things like ``double& rr = 1;'' temporary needed ! 1610: // warn in case of ``slightly wrong lvalue'', e.g. ! 1611: // int i; double& r = i; ! 1612: if (init->lval(0) && p1->tconst()==0) error('w',"conversion of lvalue needed: temporary used toI reference"); ! 1613: goto def; ! 1614: } ! 1615: ! 1616: Pexpr x = try_to_coerce(p1,init,"reference",tbl); // x==init ! 1617: if (x==0) x = try_to_coerce(px,init,"reference",tbl); // x&=init ! 1618: if (x) { ! 1619: init = x; ! 1620: goto def; ! 1621: } ! 1622: ! 1623: error("badIrT:%t (%tX)",it,p); ! 1624: if (init->base != NAME) init->tp = any_type; ! 1625: return init; ! 1626: } ! 1627: ! 1628: xxx: /* ! 1629: here comes the test of a ``fundamental theorem'': ! 1630: a structure valued expression is ! 1631: (1) an lvalue of type T (possibly const) ! 1632: or (2) the result of a function (a _result if X(X&) is defined) ! 1633: or (3) a * or [] or ? or , expression ! 1634: */ ! 1635: //error('d',"xxx %k %d %t",init->base,init->base,init->tp); ! 1636: ! 1637: switch (init->base) { ! 1638: case NAME: ! 1639: case DEREF: ! 1640: case REF: ! 1641: case DOT: // init => &init ! 1642: if (it->tconst() && vec_const==0 && fct_const==0) goto def; ! 1643: init->lval(ADDROF); ! 1644: if (vec_const) return init; ! 1645: if (fct_const && p1->is_ptr()) goto def; // fptr& = fct ! 1646: // no break ! 1647: case CM: ! 1648: case G_CM: // & (f(&temp), temp) ! 1649: return ptr_init(px,init->address(),tbl);//init->address(); ! 1650: default: ! 1651: def: ! 1652: { ! 1653: //error('d',"def: init->tp %t p1 %t",init->tp,p1); ! 1654: if (tbl == gtbl) error("Ir for staticR not an lvalue"); ! 1655: ! 1656: Pname tcl = p1->is_cl_obj (); ! 1657: if(tcl && Pclass(tcl->tp)->c_abstract) ! 1658: error("a temporary is needed for a parameter, but the argument type is abstract class %t.", tcl->tp); ! 1659: ! 1660: Pname n = make_tmp('I',p1,tbl); ! 1661: Pexpr a; ! 1662: Pname ic = init->tp->is_cl_obj(); ! 1663: ! 1664: if (p1->tconst()==0 ! 1665: && (init->tp->tconst() && vec_const==0 && fct_const==0) ! 1666: && p1->check(it,ASSIGN)==0) ! 1667: error('w',"constIr: temporary used toI reference"); ! 1668: ! 1669: switch (p1->base) { ! 1670: case INT: ! 1671: case CHAR: ! 1672: case SHORT: ! 1673: switch (it->base) { ! 1674: case LONG: ! 1675: case FLOAT: ! 1676: case DOUBLE: ! 1677: case LDOUBLE: ! 1678: error('w',"%t assigned to %t inRIr",it,p1); ! 1679: } ! 1680: } ! 1681: ! 1682: if (ic!=c1 && Pclass(ic->tp) != Pclass(c1->tp)) { ! 1683: // derived class1 => must cast: ``it Ix; (Ix=init,(p)&Ix);'' ! 1684: n->tp = init->tp; ! 1685: a = ptr_init(px,n->address(),tbl);//n->address(); ! 1686: PERM(p); ! 1687: a = new texpr(CAST,p,a); ! 1688: a->tp = p; ! 1689: } ! 1690: else ! 1691: a = n->address(); ! 1692: ! 1693: refd = 1; ! 1694: Pexpr as = init_tmp(n,init,tbl); ! 1695: refd = 0; ! 1696: a = new expr(G_CM,as,a); ! 1697: a->tp = a->e2->tp; ! 1698: return a; ! 1699: } ! 1700: } ! 1701: } ! 1702: ! 1703: Pexpr class_init(Pexpr nn, Ptype tt, Pexpr init, Ptable tbl) ! 1704: /* ! 1705: initialize "nn" of type "tt" with "init" ! 1706: if nn==0 make a temporary, ! 1707: nn may not be a name ! 1708: */ ! 1709: { ! 1710: if (init == dummy) return 0; ! 1711: //error('d',"class_init %t with %t init %k refd %d",tt,init->tp,init->base,refd); ! 1712: Pname c1 = tt->is_cl_obj(); ! 1713: ! 1714: if (init == 0) { ! 1715: error("emptyIr"); ! 1716: return dummy; ! 1717: } ! 1718: ! 1719: if (c1) { ! 1720: Pclass cl = Pclass(c1->tp); ! 1721: Pname c2 = init->tp->is_cl_obj(); ! 1722: ! 1723: if (c1!=c2 || (refd==0 && cl->has_itor())) { ! 1724: /* really ought to make a temp if refd, ! 1725: but ref_init can do that ! 1726: */ ! 1727: int i = can_coerce(tt,init->tp); ! 1728: //error('d',"i %d nn %n",i,nn); ! 1729: switch (i) { ! 1730: default: ! 1731: error("%d ways of making a%n from a%t",i,c1,init->tp); ! 1732: init->tp = any_type; ! 1733: return init; ! 1734: case 0: ! 1735: if (c2 && Pclass(c2->tp)->has_base(cl)) { ! 1736: init = init->address(); ! 1737: Pexpr x = cast_cptr(cl,init,tbl,0); ! 1738: ! 1739: if (x == init) { ! 1740: Ptype pt = tt->addrof(); ! 1741: PERM(pt); ! 1742: x = new cast(pt,init); ! 1743: } ! 1744: ! 1745: return x->contents(); ! 1746: } ! 1747: error("cannot make a%n from a%t",c1,init->tp); ! 1748: init->tp = any_type; ! 1749: return init; ! 1750: case 1: ! 1751: //error('d',"ncoerce %n %k %d",Ncoerce,init->base,init->base); ! 1752: if (Ncoerce == 0) { ! 1753: Pexpr a = new expr(ELIST,init,0); ! 1754: a = new texpr(VALUE,tt,a); ! 1755: a->e2 = nn; ! 1756: // return a->typ(tbl); ! 1757: a = a->typ(tbl); ! 1758: //error('d',"ci a %k %d %t",a->base,a->base,a->tp); ! 1759: return a; ! 1760: } ! 1761: ! 1762: switch (init->base) { ! 1763: case CM: ! 1764: case G_CM: //ddd ! 1765: case NAME: /* init.coerce() */ ! 1766: /* *ref */ case DEREF: ! 1767: { Pref r = new ref(DOT,init,Ncoerce); ! 1768: Pexpr rr = r->typ(tbl); ! 1769: init = new expr(G_CALL,rr,0); ! 1770: init->fct_name = Ncoerce; ! 1771: break; ! 1772: } ! 1773: default: // (temp=init,temp.coerce()) ! 1774: { Pname tmp = make_tmp('U',init->tp,tbl); ! 1775: int x = refd; ! 1776: refd = 0; // ?? ! 1777: Pexpr ass = init_tmp(tmp,init,tbl); ! 1778: refd = x; ! 1779: Pref r = new ref(DOT,tmp,Ncoerce); ! 1780: Pexpr rr = r->typ(tbl); ! 1781: Pexpr c = new expr(G_CALL,rr,0); ! 1782: c->fct_name = Ncoerce; ! 1783: c = c->typ(tbl); ! 1784: init = new expr(CM,ass,c); ! 1785: init->tp = c->tp; ! 1786: if (refd) { // &f() => (t=f(), &t) ! 1787: Pname tmp2 = make_tmp('L',c->tp,tbl); ! 1788: ass = init_tmp(tmp2,init,tbl); ! 1789: init = new expr(G_CM,ass,tmp2); ! 1790: } ! 1791: } ! 1792: } ! 1793: //error('d',"nn %n",nn); ! 1794: if (nn) { ! 1795: Pexpr a = new expr(ELIST,init,0); ! 1796: a = new texpr(VALUE,tt,a); ! 1797: a->e2 = nn; ! 1798: return a->typ(tbl); ! 1799: } ! 1800: } ! 1801: //error('d',"c1 %n c2 %n",c1,c2); ! 1802: return init->typ(tbl); ! 1803: } ! 1804: return init; ! 1805: } ! 1806: //error('d',"ci check tt %t init->tp %t",tt,init->tp); ! 1807: if (tt->check(init->tp,ASSIGN) && refd==0) { ! 1808: error("badIrT:%t (%tX)",init->tp,tt); ! 1809: init->tp = any_type; ! 1810: } ! 1811: ! 1812: return init; ! 1813: } ! 1814: ! 1815: extern int bound; // fudge for bound pointers to functions ! 1816: ! 1817: Pexpr expr::docast(Ptable tbl) ! 1818: { ! 1819: // check cast against value, INCOMPLETE ! 1820: ! 1821: //error('d',"docast %d %t %k",this,tp2,e1->base); ! 1822: if (e1 == dummy) { ! 1823: error("E missing for cast"); ! 1824: tp = any_type; ! 1825: return this; ! 1826: } ! 1827: ! 1828: int pmf = 0; ! 1829: int ptom_cast = 0; ! 1830: Pexpr ee = e1; ! 1831: ! 1832: //error('d',"ee %k %d",ee->base,ee->base); ! 1833: switch (ee->base) { ! 1834: case ADDROF: ! 1835: ee = ee->e2; ! 1836: switch (ee->base) { ! 1837: case NAME: goto nm; ! 1838: case REF: goto rf; ! 1839: } ! 1840: break; ! 1841: ! 1842: case NAME: ! 1843: nm: ! 1844: if (Pname(ee)->n_qualifier) pmf = 1; ! 1845: break; ! 1846: ! 1847: case REF: ! 1848: rf: ! 1849: if (ee->e1->base == THIS) bound = 1; ! 1850: break; ! 1851: } ! 1852: ! 1853: e1 = e1->typ(tbl); ! 1854: ! 1855: int b = bound; // distinguish between explicit and implicit THIS ! 1856: bound = 0; ! 1857: pmf = pmf && e1->base==CAST; ! 1858: ! 1859: Ptype etp = e1->tp; ! 1860: Ptype tt = tp2; ! 1861: Ptype t = tt; ! 1862: tt->dcl(tbl); ! 1863: ! 1864: while (etp->base == TYPE) etp = Pbase(etp)->b_name->tp; ! 1865: while (tt->base == TYPE) tt = Pbase(tt)->b_name->tp; ! 1866: ! 1867: //error('d',"e1 %k etp %t tt %t",e1->base,etp,tt); ! 1868: ! 1869: switch (etp->base) { ! 1870: case PTR: ! 1871: case RPTR: ! 1872: if (Pptr(etp)->typ->base == OVERLOAD) goto over; ! 1873: ! 1874: if (warning_opt && i2==0 && Pptr(etp)->typ->tconst()) { ! 1875: switch (tt->base) { ! 1876: case FCT: ! 1877: break; ! 1878: case PTR: ! 1879: case RPTR: ! 1880: if (Pptr(tt)->typ->tconst()) break; ! 1881: default: ! 1882: // casting away const ! 1883: // should be an error ! 1884: // but ANSI says OK so I chicken out ! 1885: // to be able to compile strtok(), etc. ! 1886: error('w',"const cast away:%t->%t",e1->tp,tp2); ! 1887: } ! 1888: } ! 1889: else ! 1890: i2 = 0; // to allow cfront to escape its own checking ! 1891: break; ! 1892: case COBJ: ! 1893: { ref_cast = 1; ! 1894: Pexpr x = try_to_coerce(tt,e1,"cast",tbl); ! 1895: ref_cast = 0; ! 1896: //error('d',"x %k %t tt %d %t",x?x->base:0,x?x->tp:0,tt,tt); ! 1897: if (x) { ! 1898: if (x!=e1 && x->base==DEREF && tt->is_ref()) x = x->e1; ! 1899: if (tt==x->tp || tt->check(x->tp,0)==0 || const_problem) ! 1900: return x; ! 1901: else ! 1902: return new cast(tt,x); ! 1903: } ! 1904: // else if (e1->base==DEREF && tt->is_ref()) return e1; ! 1905: break; ! 1906: } ! 1907: case VOID: ! 1908: if (tt->base == VOID) { ! 1909: tp = t; ! 1910: return this; ! 1911: } ! 1912: error("cast of void value"); ! 1913: // no break; ! 1914: case ANY: ! 1915: any: ! 1916: tp = any_type; ! 1917: return this; ! 1918: case FCT: ! 1919: if (tt->base == PTR && Pptr(tt)->typ->base != FCT) ! 1920: error('w',"P toF cast toP to nonF"); ! 1921: break; ! 1922: case OVERLOAD: ! 1923: over: ! 1924: error("cast of overloaded"); ! 1925: goto any; ! 1926: } ! 1927: ! 1928: //error('d',"tt %t",tt); ! 1929: switch (tt->base) { ! 1930: case PTR: ! 1931: if (Pptr(tt)->typ->base==FCT && Pptr(tt)->memof) { ! 1932: if (etp->base!=PTR ! 1933: || Pptr(etp)->typ->base!=FCT ! 1934: || Pptr(etp)->memof==0) ! 1935: error("cast toP toM %t",tt); ! 1936: else { // adjust delta in MI case ! 1937: // for the moment just suppress the cast ! 1938: // all pmfs are the same to cc ! 1939: /* ! 1940: Pclass c1 = Pptr(tt)->memof; ! 1941: Pclass c2 = Pptr(etp)->memof; ! 1942: */ ! 1943: ptom_cast = 1; ! 1944: tp2 = void_type; ! 1945: } ! 1946: } ! 1947: ! 1948: switch (etp->base) { ! 1949: case COBJ: ! 1950: error("cannot castCO toP"); ! 1951: break; ! 1952: case FCT: ! 1953: e1 = new expr(G_ADDROF,0,e1); ! 1954: bound = b; ! 1955: e1 = e1->typ(tbl); ! 1956: bound = 0; ! 1957: if (e1->base == CAST) ! 1958: pmf = 1; ! 1959: else ! 1960: break; ! 1961: // no break; ! 1962: ! 1963: case PTR: ! 1964: { Pname cn = Pptr(tt)->typ->is_cl_obj(); ! 1965: if (cn) { ! 1966: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1); ! 1967: ! 1968: if (x == e1) { ! 1969: PERM(tt); ! 1970: e1 = new cast(tt,e1); ! 1971: e1->i2 = i2; ! 1972: } ! 1973: else ! 1974: e1 = x; ! 1975: } ! 1976: if (pmf) { ! 1977: zaqq: ! 1978: switch (tt->base) { ! 1979: case TYPE: ! 1980: tt = Pbase(tt)->b_name->tp; goto zaqq; ! 1981: case PTR: ! 1982: if (Pptr(tt)->memof) break; ! 1983: default: ! 1984: error("%t cast to%t (%t is not aP toM)",e1->tp,tp2,tp2); ! 1985: } ! 1986: } ! 1987: } ! 1988: } ! 1989: break; ! 1990: ! 1991: case RPTR: // (x&)e: pretend e is an x ! 1992: { Ptype er = etp; ! 1993: Ptype cr = tt; ! 1994: do { ! 1995: if (er = er->is_ptr_or_ref()) er = Pptr(er)->typ; ! 1996: if (cr = cr->is_ptr_or_ref()) cr = Pptr(cr)->typ; ! 1997: } while (er && cr); ! 1998: int pp = er!=0; // if `e' is a suitable pointer cast it: ! 1999: // (x&)e => (x*)e, otherwise ! 2000: // (x&)e => *(x*)&e ! 2001: //error('d',"rptr tt %t e1->base %k e1->tp %t",tt,e1->base,e1->tp); ! 2002: // if (Pptr(tt)->typ->tsizeof()>etp->tsizeof()) goto zse; ! 2003: // we need to be able to ``raise the type'' from base to derived ! 2004: // if (etp->is_cl_obj() && Pptr(tt)->typ->is_cl_obj()==0) goto zse; ! 2005: ! 2006: if (e1->base==G_CM ! 2007: || e1->base==CALL ! 2008: || e1->base==G_CALL ! 2009: || e1->lval(0)) ! 2010: ; ! 2011: else if (e1->tp->tconst()) { ! 2012: // casting away const ! 2013: // should be an error ! 2014: // but ANSI says OK so I chicken out ! 2015: // to be able to compile strtok(), etc. ! 2016: if (warning_opt && Pptr(tt)->typ->tconst()==0) ! 2017: error('w',"const cast away:%t->%t",e1->tp,tp2); ! 2018: ! 2019: } ! 2020: else ! 2021: error("cannot cast%t to%t",etp,t); ! 2022: //error('d',"e1 %k %t %d",e1->base,e1->tp,pp); ! 2023: if (pp == 0) e1 = e1->address(); // *(x*)&e ! 2024: tp = t; ! 2025: ! 2026: // do proper pointer manipulation for multiple inheritance ! 2027: Pname cn = Pptr(tt)->typ->is_cl_obj(); ! 2028: if (cn) { ! 2029: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1); ! 2030: ! 2031: if (x == e1) { ! 2032: PERM(tt); ! 2033: e1 = new cast(tt,e1); ! 2034: e1->i2 = i2; ! 2035: } ! 2036: else ! 2037: e1 = x; ! 2038: } ! 2039: ! 2040: return pp ? this : contents(); ! 2041: // zse: ! 2042: // error("cannot cast%t to%t",etp,t); ! 2043: // tp2 = tt = any_type; ! 2044: // break; ! 2045: } ! 2046: case COBJ: ! 2047: base = VALUE; // (x)e => x(e): construct an x from e ! 2048: e1 = new expr(ELIST,e1,0); ! 2049: return typ(tbl); ! 2050: ! 2051: case CHAR: ! 2052: case INT: ! 2053: case SHORT: ! 2054: case LONG: ! 2055: case FLOAT: ! 2056: case DOUBLE: ! 2057: case LDOUBLE: ! 2058: switch (etp->base) { ! 2059: case FCT: ! 2060: e1 = new expr(ADDROF,0,e1); ! 2061: e1 = e1->typ(tbl); ! 2062: break; ! 2063: case COBJ: ! 2064: error("cannot castCO to%k",tt->base); ! 2065: break; ! 2066: } ! 2067: break; ! 2068: } ! 2069: ! 2070: tp = t; ! 2071: ! 2072: if (e1->base==ILIST && ptom_cast==0) { // pointer to member constant ! 2073: Pexpr ee = e1->e1; // ELIST ! 2074: int i; ! 2075: switch (ee->e2->base) { ! 2076: case IVAL: ! 2077: i = int(ee->e2->i1); ! 2078: break; ! 2079: case ZERO: ! 2080: i = 0; ! 2081: } ! 2082: ! 2083: if (i<0) ! 2084: e1 = e1->e2; // just the function ! 2085: else ! 2086: e1 = ee->e2; // just the index ! 2087: return this; ! 2088: } ! 2089: ! 2090: if (etp->base==PTR && Pptr(etp)->memof && Pptr(etp)->typ->base==FCT) { ! 2091: Pclass cl = Pptr(etp)->memof; ! 2092: ! 2093: if (Pptr(tt)->memof==0 && b == 0 ) { ! 2094: Pexpr y = new mdot("f",e1); ! 2095: y->i1 = 9; ! 2096: y = new cast(tt,y); ! 2097: if (cl->virt_count && b==0) { ! 2098: // ERROR: no check for side effects ! 2099: Pexpr z = new mdot("i",e1); ! 2100: Pexpr x = new mdot("i",e1); ! 2101: x->i1 = 9; ! 2102: x = new cast(tt,x); ! 2103: z->i1 = 9; ! 2104: Pexpr q = new expr (QUEST,x,y); ! 2105: q->cond = new expr(LE,zero,z); ! 2106: q->tp = tt; ! 2107: delete this; ! 2108: return q; ! 2109: } ! 2110: delete this; ! 2111: return y; ! 2112: } ! 2113: } ! 2114: ! 2115: return this; ! 2116: } ! 2117: ! 2118: Pexpr expr::dovalue(Ptable tbl) ! 2119: { ! 2120: Ptype tt = tp2; ! 2121: Pclass cl; ! 2122: Pname cn ; ! 2123: ! 2124: //error('d',"value %d %t e1 %d e2 %d",tt,tt,e1,e2); ! 2125: ! 2126: tt->dcl(tbl); ! 2127: vv: ! 2128: switch (tt->base) { ! 2129: case TYPE: ! 2130: tt = Pbase(tt)->b_name->tp; ! 2131: goto vv; ! 2132: ! 2133: case EOBJ: ! 2134: default: ! 2135: if (e1 == 0) { ! 2136: error("value missing in conversion to%t",tt); ! 2137: return dummy; ! 2138: } ! 2139: base = CAST; ! 2140: e1 = e1->e1; // strip ELIST ! 2141: return typ(tbl); ! 2142: ! 2143: case CLASS: ! 2144: cl = Pclass(tt); ! 2145: tp2 = Pptr(cl->this_type)->typ; ! 2146: break; ! 2147: ! 2148: case COBJ: ! 2149: cn = Pbase(tt)->b_name; ! 2150: cl = Pclass(cn->tp); ! 2151: } ! 2152: ! 2153: //error('d',"e1 %k e1->e2 %k",e1->base,e1?e1->e2->base:0); ! 2154: if (e1 && e1->e2==0) { // single argument ! 2155: if (e1->e1->base==ELIST) e1->e1 = e1->e1->e1; // spurious elist ! 2156: e1->e1 = e1->e1->typ(tbl); ! 2157: if (tt->base==COBJ) { ! 2158: Pexpr x = try_to_coerce(tt,e1->e1,"type conversion",tbl); ! 2159: if (x) return x; ! 2160: } ! 2161: ! 2162: Pname acn = e1->e1->tp->is_cl_obj(); ! 2163: //error('d',"acn %n %d",acn,cl->has_itor()); ! 2164: if (acn && cl->has_itor()==0) { ! 2165: Pclass acl = Pclass(acn->tp); ! 2166: int hb = acl->has_base(cl); ! 2167: ! 2168: if (acl==cl || hb) { ! 2169: vcllist->clear(); ! 2170: vcllist=0; ! 2171: if (1<is_unique_base(acl,cl->string,0)) error("ambiguous assignment to base %t",cl); ! 2172: Pexpr ee = e1->e1; ! 2173: if (ee->base == ELIST) ee = ee->e1; // ??? ! 2174: if (hb) { // ee => *(tp2*)&ee ! 2175: // remember = may be overloaded ! 2176: //error('d',"hb %k %t %d",ee->base,ee->tp,ee->lval(0)); ! 2177: if (ee->lval(0)==0) { ! 2178: Pname tmp = make_tmp('T',ee->tp,tbl); ! 2179: ee = init_tmp(tmp,ee,tbl); ! 2180: ee = new expr(G_CM,ee,tmp->address()); ! 2181: } ! 2182: else ! 2183: ee = ee->address(); ! 2184: ee = new texpr(CAST,new ptr(PTR,tp2),ee); //new cast(new ptr(PTR,tp2),ee); ! 2185: ee = ee->contents(); ! 2186: ee->typ(tbl); ! 2187: } ! 2188: ! 2189: if (e2) { // x(x_obj) => e2=x_obj ! 2190: base = ASSIGN; ! 2191: e1 = e2; ! 2192: e2 = ee; ! 2193: tp = tp2; ! 2194: return this; ! 2195: } ! 2196: return ee; // strip ELIST: x(x_obj) => x_obj ! 2197: } ! 2198: } ! 2199: } ! 2200: ! 2201: ! 2202: /* x(a) => obj.ctor(a); where e1==obj */ ! 2203: Pname ctor = cl->has_ctor(); ! 2204: if (ctor == 0) { ! 2205: error("cannot make a%t",cl); ! 2206: return dummy; ! 2207: } ! 2208: ! 2209: //error('d',"e2 %k",e2?e2->base:0); ! 2210: if (e2 == 0) { // x(a) => x temp; (temp.x(a),temp) ! 2211: Pname n = make_tmp('V',tp2,tbl); ! 2212: n->assign(); ! 2213: if (tbl == gtbl) n->dcl_print(0); // a hack ! 2214: Pexpr c = call_ctor(tbl,n,ctor,e1,DOT); ! 2215: c = new expr(G_CM,c,n); ! 2216: c->tp = n->tp; ! 2217: //error('d',"tp1 %t",c->tp); ! 2218: return c; ! 2219: } ! 2220: else { ! 2221: Pexpr c = call_ctor(tbl,e2,ctor,e1,DOT); ! 2222: c = new expr(DEREF,c,0); // deref value returned by constructor ! 2223: c->tp = c->e1->tp; ! 2224: //error('d',"tp2 %t",c->tp); ! 2225: return c; ! 2226: } ! 2227: } ! 2228: ! 2229: /* ODI notes ! 2230: ! 2231: fixes for template classes and to get const right ! 2232: by not discarding const information from typedefs ! 2233: ! 2234: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.