|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/expr3.c 1.3.5.29" */ ! 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: ! 631: /* look for constructor ! 632: with one argument ! 633: or with default for second argument ! 634: of acceptable type ! 635: */ ! 636: Pname ctor = cl->has_ctor(); ! 637: if (ctor == 0) goto oper_coerce; ! 638: register Pfct f = Pfct(ctor->tp); ! 639: //error('d',"ctor %n f %t",ctor,f); ! 640: switch (f->base) { ! 641: case FCT: ! 642: switch (f->nargs) { ! 643: case 1: ! 644: one: ! 645: { Ptype tt = f->argtype->tp; ! 646: //error('d',"tt %t t2 %t -> %d cp %d",tt,t2,tt->check(t2,COERCE),const_problem); ! 647: if (tt->check(t2,COERCE)==0) ! 648: val = 1; ! 649: else if (const_problem) { ! 650: Pptr p1 = tt->is_ptr_or_ref(); ! 651: if (p1==0 || p1->typ->tconst()) val = 1; ! 652: } ! 653: if (tt = tt->is_ref()) { ! 654: Pptr pt = t2->addrof(); // handle derived classed ! 655: tt->base = PTR; ! 656: if (tt->check(pt,COERCE) == 0) val = 1; ! 657: tt->base = RPTR; ! 658: delete pt; ! 659: } ! 660: goto oper_coerce; ! 661: } ! 662: default: ! 663: if (f->argtype->n_list->n_initializer) goto one; ! 664: case 0: ! 665: goto oper_coerce; ! 666: } ! 667: case OVERLOAD: ! 668: { register Plist gl; ! 669: ! 670: for (gl=Pgen(f)->fct_list; gl; gl=gl->l) { // look for match ! 671: Pname nn = gl->f; ! 672: Pfct ff = Pfct(nn->tp); ! 673: ! 674: switch (ff->nargs) { ! 675: case 0: ! 676: break; ! 677: case 1: ! 678: over_one: ! 679: { Ptype tt = ff->argtype->tp; ! 680: //error('d',"over one %t %t -> %d %d",tt,t2,tt->check(t2,COERCE),const_problem); ! 681: if (tt->check(t2,COERCE)==0) ! 682: val = 1; ! 683: else if (const_problem) { ! 684: Pptr p1 = tt->is_ptr_or_ref(); ! 685: if (p1==0 || p1->typ->tconst()) val = 1; ! 686: } ! 687: if (tt=tt->is_ref()) { ! 688: Pptr pt = t2->addrof(); // handle derived classed ! 689: tt->base = PTR; ! 690: if (tt->check(pt,COERCE) == 0) { ! 691: tt->base = RPTR; ! 692: delete pt; ! 693: val = 1; ! 694: goto oper_coerce; ! 695: } ! 696: tt->base = RPTR; ! 697: delete pt; ! 698: } ! 699: break; ! 700: } ! 701: default: ! 702: if (ff->argtype->n_list->n_initializer) goto over_one; ! 703: } ! 704: } ! 705: goto oper_coerce; ! 706: } ! 707: default: ! 708: error('i',"cannot_coerce(%k)\n",f->base); ! 709: } ! 710: } ! 711: ! 712: oper_coerce: ! 713: //error('d',"oper_coerce %d",val); ! 714: if (c2) { ! 715: Pclass cl = Pclass(c2->tp); ! 716: int std = 0; ! 717: int oval = val; ! 718: extern Pname conv_dominates(Pname,Pname); ! 719: for (Pname ox, on=cl->conv; on; on=ox) { ! 720: Pfct f = Pfct(on->tp); ! 721: ox = on->n_list; ! 722: Nstd = 0; ! 723: //error('d',"on %n -> %d",on,t1->check(f->returns,COERCE)); ! 724: if (t1->check(f->returns,COERCE) == 0) { ! 725: if (Nstd==0) { // forget solutions involving standard conversions ! 726: Pname old = Ncoerce; ! 727: if (std) { // forget ! 728: val = oval+1; ! 729: std = 0; ! 730: Ncoerce = on; ! 731: } ! 732: else if (Ncoerce == 0) { ! 733: // val = 1; ! 734: val++; ! 735: Ncoerce = on; ! 736: } ! 737: else if ((Ncoerce = conv_dominates(Ncoerce,on))==0) { ! 738: if (val == 1) { ! 739: //error('d',"val==1 on %n old %n",on,old); ! 740: Ptype ton = Pfct(on->tp)->returns; ! 741: Ptype tco = Pfct(old->tp)->returns; ! 742: if (t1->check(ton,0)==0) ! 743: ; ! 744: else if (t1->check(tco,0)==0) ! 745: on = old; ! 746: else ! 747: val++; ! 748: } ! 749: else ! 750: val++; ! 751: Ncoerce = on; ! 752: } ! 753: } ! 754: else { // take note only if no exact match seen ! 755: if (Ncoerce==0 || on->tp->check(Ncoerce->tp,0)) { ! 756: if (val==0 || std) { ! 757: ! 758: if (Ncoerce) Ncoerce = conv_dominates(Ncoerce,on); ! 759: if (Ncoerce == 0) { ! 760: Ncoerce = on; ! 761: val++; ! 762: std = 1; ! 763: } ! 764: } ! 765: } ! 766: } ! 767: } ! 768: ! 769: } ! 770: } ! 771: //error('d',"val %d",val); ! 772: if (val) return val; ! 773: if (c1 && Pclass(c1->tp)->has_itor()) return 0; ! 774: //error('d',"%t->check(%t) -> %d",t1,t2,t1->check(t2,COERCE)); ! 775: if (t1->check(t2,COERCE)) return 0; ! 776: return 1; ! 777: } ! 778: ! 779: int gen_coerce(Pname n, Pexpr arg) ! 780: /* ! 781: look to see if the argument list "arg" can be coerced into a call of "n" ! 782: 1: it can ! 783: 0: it cannot or it can be done in more than one way ! 784: */ ! 785: { ! 786: Pfct f = (Pfct) n->tp; ! 787: register Pexpr e; ! 788: register Pname nn; ! 789: ! 790: //error('d',"gen_coerce(%n,%d) %t",n,arg,n->tp); ! 791: for (e=arg, nn=f->argtype; e; e=e->e2, nn=nn->n_list) { ! 792: if (nn == 0) return f->nargs_known==ELLIPSIS; ! 793: Pexpr a = e->e1; ! 794: Ptype at = a->tp; ! 795: int i = can_coerce(nn->tp,at); ! 796: //error('d',"i %d",i); ! 797: if (i != 1) return 0; ! 798: } ! 799: if (nn && nn->n_initializer==0) return 0; ! 800: return 1; ! 801: } ! 802: ! 803: ! 804: Pname Nover; ! 805: // int Nover_coerce; ! 806: ! 807: int over_call(Pname n, Pexpr arg) ! 808: /* ! 809: return 4 if n(arg) can be performed without coercion of arg ! 810: return 3 if n(arg) can be performed only with promotion coercion of arg ! 811: return 2 if n(arg) can be performed only with standard coercion of arg ! 812: return 1 if n(arg) can be performed only with user defined coercion of arg ! 813: return 0 if n(arg) is an error ! 814: Nover is the function found, if any ! 815: Nstd is the number of standard coercions used ! 816: */ ! 817: { ! 818: register Plist gl; ! 819: Pgen g = Pgen(n->tp); ! 820: if (arg && arg->base!= ELIST) error('i',"ALX"); ! 821: ! 822: //error('d',"over_call(%n) %k",n,n->tp->base); ! 823: extern suppress_error; ! 824: suppress_error = 1; ! 825: // Nover_coerce = 0; ! 826: Nstd = 0; ! 827: switch (g->base) { ! 828: default: error('i',"over_call(%t)\n",g); ! 829: case OVERLOAD: break; ! 830: case FCT: ! 831: Nover = n; ! 832: Ninit = 0; ! 833: if (exact_match(n,arg)) {suppress_error = 0; return 4;} ! 834: if (prom_match(n,arg)) {suppress_error = 0; return 3;} ! 835: if (std_match(n,arg) && Ninit==0) {suppress_error = 0; return 2;} ! 836: Nstd = 0; ! 837: suppress_error = 0; ! 838: return gen_coerce(n,arg); ! 839: } ! 840: ! 841: Pname exact = 0; ! 842: int no_exact = 0; ! 843: int ret = 0; ! 844: Pname nret; ! 845: for (gl=g->fct_list; gl; gl=gl->l) { /* look for match */ ! 846: Nover = gl->f; ! 847: Ninit = 0; ! 848: Nstd = 0; ! 849: if (exact_match(Nover,arg)) {suppress_error = 0; return 4;} // no coercion ! 850: // if (prom_match(Nover,arg)) return 3; // only promotion ! 851: // if (std_match(Nover,arg) && Ninit==0) return 2; // only built-in conversion ! 852: if (ret<3 && prom_match(Nover,arg)) { ! 853: nret = Nover; ! 854: ret = 3; ! 855: } ! 856: if (ret<2 && std_match(Nover,arg) && Ninit==0) { ! 857: nret = Nover; ! 858: ret = 2; ! 859: } ! 860: } ! 861: ! 862: suppress_error = 0; ! 863: if (ret) { ! 864: Nover = nret; ! 865: return ret; ! 866: } ! 867: ! 868: Nover = 0; ! 869: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */ ! 870: Pname nn = gl->f; ! 871: if (gen_coerce(nn,arg)) { ! 872: Nover = nn; ! 873: return 1; ! 874: } ! 875: } ! 876: return 0; ! 877: ! 878: } ! 879: ! 880: Ptype expr::call_fct(Ptable tbl) ! 881: /* ! 882: check "this" call: ! 883: e1(e2) ! 884: e1->typ() and e2->typ() has been done ! 885: */ ! 886: { ! 887: Pfct f; ! 888: Pname fn; ! 889: int x; ! 890: int k; ! 891: Pname nn; ! 892: Pexpr e; ! 893: Ptype t; ! 894: Pexpr arg = e2; ! 895: Ptype t1 = e1?e1->tp:0; ! 896: int argno; ! 897: Pexpr etail = 0; ! 898: Pname no_virt = 0; // set if explicit qualifier was used: c::f() ! 899: Pname chk = 0; // set if visibility check is needed ! 900: // that is if function name might have been ! 901: // found without use of find_name() ! 902: int const_obj = 0; ! 903: ! 904: if (t1 == any_type) return any_type; ! 905: ! 906: switch (base) { ! 907: case CALL: ! 908: case G_CALL: break; ! 909: default: error('i',"call_fct(%k)",base); ! 910: } ! 911: ! 912: //error('d',"call %d %k %n arg %d",this,e1->base,e1->base==NAME?e1:0,arg); ! 913: if (t1 == 0) error('i',"call_fct(e1=%d,e1->tp=%t)",e1,t1); ! 914: if (arg && arg->base!=ELIST) error('i',"badAL%d%k",arg,arg->base); ! 915: ! 916: switch (e1->base) { ! 917: case NAME: ! 918: fn = Pname(e1); ! 919: //error('d',"name %n %k",fn,fn->n_oper); ! 920: switch (fn->n_oper) { ! 921: case 0: ! 922: case CTOR: ! 923: case DTOR: ! 924: case TYPE: ! 925: case NEW: ! 926: case DELETE: ! 927: break; ! 928: default: // real operator: check for operator+(1,2); ! 929: if (arg == 0) break; ! 930: Pexpr a = arg->e1; // first operand ! 931: ! 932: if (Pfct(fn->tp)->memof // obj.operator(1) is OK ! 933: || a->tp->is_cl_obj() ! 934: || a->tp->is_ref()) break; ! 935: a = arg->e2; ! 936: if (a == 0) // unary ! 937: error("%k of basicT",fn->n_oper); ! 938: else { // binary ! 939: a = a->e1; // second operand ! 940: if (a->tp->is_cl_obj() || a->tp->is_ref()) break; ! 941: error("%k of basicTs",fn->n_oper); ! 942: } ! 943: break; ! 944: } ! 945: break; ! 946: case REF: ! 947: case DOT: ! 948: no_virt = Pname(e1->n_initializer); ! 949: e1->n_initializer = 0; ! 950: // const_obj = (e1&&e1->e1)?e1->e1->tp->tconst():0; ! 951: if (e1 && e1->e1) { ! 952: Ptype t = e1->e1->tp; ! 953: Pptr tt = t->is_ptr_or_ref(); ! 954: //error('d',"t %t tt %t",t,tt); ! 955: const_obj = (tt ? tt->typ : t)->tconst(); ! 956: } ! 957: case MDOT: ! 958: { Pexpr n = e1->mem; ! 959: lxlx: ! 960: switch (n->base) { ! 961: case MDOT: ! 962: // reverse mdot (see expr::print()) ! 963: // p->a.b() => (&p->a)->b() => b(&p->a) ! 964: // or p->a->b() => (p->a)->b() => b(p->a) ! 965: // or oo.a.b() => (&oo.a)->b() => b(&oo.a) ! 966: // or oo.a->b() => (oo.a)->b() => b(oo.a) ! 967: { ! 968: Pexpr r = e1; ! 969: Pexpr p = r->e1; ! 970: for (Pexpr m = r->mem; m->base==MDOT; m = r->mem) { ! 971: p = new mdot(m->string2,p); ! 972: p->i1 = m->i1+2; ! 973: p->tp = p->mem->tp; ! 974: r->mem = m->mem; ! 975: r->e1 = p; ! 976: } ! 977: } ! 978: case REF: ! 979: case DOT: ! 980: n = n->mem; ! 981: goto lxlx; ! 982: case NAME: ! 983: break; ! 984: default: ! 985: error('i',"ref %k",n->base); ! 986: } ! 987: fn = Pname(n); ! 988: //error('d',"mem %n",fn); ! 989: break; ! 990: } ! 991: case MEMPTR: ! 992: default: ! 993: fn = 0; ! 994: }; ! 995: ! 996: lll: ! 997: //error('d',"lll: %t %k",t1,t1->base); ! 998: switch (t1->base) { ! 999: case TYPE: ! 1000: t1 = Pbase(t1)->b_name->tp; ! 1001: goto lll; ! 1002: ! 1003: case PTR: // pf() allowed as shorthand for (*pf)() ! 1004: switch (Pptr(t1)->typ->base) { ! 1005: case FCT: ! 1006: case OVERLOAD: ! 1007: if (Pptr(t1)->memof) error("O missing in call throughP toMF"); ! 1008: t1 = Pptr(t1)->typ; ! 1009: fn = 0; ! 1010: goto lll; ! 1011: } ! 1012: ! 1013: default: ! 1014: if (fn) ! 1015: error("call of%n;%n is a%t",fn,fn,e1->tp); ! 1016: else ! 1017: error("call of%kE ofT%t",e1->base,e1->tp); ! 1018: ! 1019: case ANY: ! 1020: return any_type; ! 1021: ! 1022: case OVERLOAD: ! 1023: { register Plist gl; ! 1024: Pgen g = Pgen(t1); ! 1025: Pname found = 0; ! 1026: Pname exact = 0; ! 1027: int no_exact = 0; ! 1028: ! 1029: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match ! 1030: register Pname nn = gl->f; ! 1031: if (exact_match(nn,arg)) { ! 1032: //error('d',"found exact %n %t",nn,nn->tp); ! 1033: if (found) { ! 1034: // check if one fct dominates the other ! 1035: Pname d = dominate(found,nn,arg,const_obj,0); ! 1036: if (d) ! 1037: nn = d; ! 1038: else ! 1039: error("two exact matches for%n:%t and%t",nn,nn->tp,found->tp); ! 1040: } ! 1041: found = nn; ! 1042: } ! 1043: } ! 1044: //error('d',"found exact2 %n",found); ! 1045: if (found) goto fnd; ! 1046: ! 1047: for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match ! 1048: register Pname nn = gl->f; ! 1049: ! 1050: if (prom_match(nn,arg)) { ! 1051: if (found) { ! 1052: // check if one fct dominates the other ! 1053: Pname d = dominate(found,nn,arg,const_obj,1); ! 1054: if (d) ! 1055: nn = d; ! 1056: else ! 1057: error("two exact matches (after integral promotions) for%n:%t and%t",nn,nn->tp,found->tp); ! 1058: } ! 1059: found = nn; ! 1060: } ! 1061: } ! 1062: //error('d',"found exact2 %n",found); ! 1063: if (found) goto fnd; ! 1064: ! 1065: // for (gl=g->fct_list; gl; gl=gl->l) { // look for exact match ! 1066: // register Pname nn = gl->f; ! 1067: // ! 1068: // if (exact_match(nn,arg) || prom_match(nn,arg)) { ! 1069: // found = nn; ! 1070: // goto fnd; ! 1071: // } ! 1072: // } ! 1073: ! 1074: Pname mvec[10]; ! 1075: for (gl=g->fct_list; gl; gl=gl->l) { // look for match ! 1076: // with standard conversion ! 1077: register Pname nn = gl->f; ! 1078: Ninit = 0; ! 1079: Nstd = 0; ! 1080: if (std_match(nn,arg)) { ! 1081: // if (Nstd == 0) { ! 1082: // found = nn; ! 1083: // goto fnd; ! 1084: // } ! 1085: if (exact) { ! 1086: // check if one fct dominates the other ! 1087: Pname d = dominate(exact,nn,arg,const_obj,2); ! 1088: if (d == 0) { ! 1089: mvec[no_exact++] = nn; ! 1090: // no_exact++; ! 1091: // error("two standard conversions possible for%n: %t and %t",fn,exact->tp,nn->tp); ! 1092: } ! 1093: else ! 1094: exact = d; ! 1095: } ! 1096: else ! 1097: exact = nn; ! 1098: } ! 1099: ! 1100: } ! 1101: ! 1102: //error('d',"excact %n",exact); ! 1103: if (exact) { ! 1104: if (no_exact) { ! 1105: while (no_exact) { ! 1106: Pname d = dominate(exact,mvec[--no_exact],arg,const_obj,2); ! 1107: if (d) ! 1108: exact = d; ! 1109: else ! 1110: error("two standard conversions possible for%n: %t and %t",fn,exact->tp,mvec[no_exact]->tp); ! 1111: } ! 1112: ! 1113: } ! 1114: //error('d',"found exact3 %n",found); ! 1115: found = exact; ! 1116: goto fnd; ! 1117: } ! 1118: ! 1119: for (gl=g->fct_list; gl; gl=gl->l) { /* look for coercion */ ! 1120: register Pname nn = gl->f; ! 1121: if (gen_coerce(nn,arg)) { ! 1122: //error('d',"user2 %n %t",nn,nn->tp); ! 1123: if (found) { ! 1124: // check if one fct dominates the other ! 1125: Pname d = dominate(found,nn,arg,const_obj,3); ! 1126: if (d == 0) d = user_dominate(found,nn); ! 1127: if (d == 0) { ! 1128: error("ambiguousA for%n: %t and %t",fn,found->tp,nn->tp); ! 1129: goto fnd; ! 1130: } ! 1131: else ! 1132: found = d; ! 1133: } ! 1134: else ! 1135: found = nn; ! 1136: } ! 1137: } ! 1138: ! 1139: fnd: ! 1140: //error('d',"fnd %t",found?found->tp:0); ! 1141: if (found) { ! 1142: chk = fn = found; ! 1143: f = Pfct(fn->tp); ! 1144: } ! 1145: else { ! 1146: error("badAL for%n (no match against any %n)",fn,fn); ! 1147: return any_type; ! 1148: } ! 1149: break; ! 1150: } ! 1151: case FCT: ! 1152: f = Pfct(t1); ! 1153: if (fn) { ! 1154: switch (fn->n_oper) { ! 1155: case CTOR: ! 1156: case TYPE: ! 1157: chk = fn; ! 1158: } ! 1159: } ! 1160: } ! 1161: ! 1162: //error('d',"chk %n",chk); ! 1163: if (chk) { ! 1164: Ptype t = 0; ! 1165: Pexpr ee = e1->e1; ! 1166: ! 1167: switch (e1->base) { ! 1168: case REF: // ptr->chk() ! 1169: if (ee == 0) { // 0->x() fudge handling new x() ! 1170: check_visibility(chk,no_virt,Pclass(chk->n_table->t_name->tp),tbl,cc->nof); ! 1171: break; ! 1172: }; ! 1173: t = ee->tp; ! 1174: while(t->base==TYPE) t = Pbase(t)->b_name->tp; ! 1175: t = Pptr(t)->typ; ! 1176: break; ! 1177: case DOT: // obj.chk() ! 1178: t = ee->tp; ! 1179: } ! 1180: ! 1181: Pname cn = t?t->is_cl_obj():0; ! 1182: Pclass cl = cn?Pclass(cn->tp):0; // class of ``this'' for chk ! 1183: ! 1184: if (cl) { ! 1185: if (chk->n_oper==CTOR ! 1186: && chk->n_protect ! 1187: && cc->nof ! 1188: && cc->nof->n_oper==CTOR) ! 1189: // BUG: cannot handle protected base ! 1190: // class constructor ! 1191: ; ! 1192: else { ! 1193: check_visibility(chk,no_virt,cl,tbl,cc->nof); ! 1194: } ! 1195: } ! 1196: } ! 1197: ! 1198: if (fn && f->f_result==0) { ! 1199: // protect against class cn; cn f(); ... class cn { cn(cn&); ... }; ! 1200: make_res(f); ! 1201: //error('d',"returns %t",f->returns); ! 1202: f->returns->tsizeof(); // make sure it is declared ! 1203: } ! 1204: ! 1205: //error('d',"fn %n %t printed %d",fn,fn?fn->tp:0,fn?fn->n_dcl_printed:0); ! 1206: if (fn && fn->n_dcl_printed==0) { ! 1207: if (f->f_inline==0 && f->f_imeasure) { ! 1208: extern void uninline(Pname fn); ! 1209: uninline(fn); ! 1210: } ! 1211: ! 1212: // ensure printout of class declaration: ! 1213: for (Pname nn=f->argtype; nn; nn=nn->n_list) ! 1214: if (nn->tp->is_cl_obj()) (void) nn->tp->tsizeof(); ! 1215: ! 1216: fn->dcl_print(0); ! 1217: } ! 1218: ! 1219: if (no_virt && f->f_static==0) { ! 1220: if (e1->base==REF || e1->base==DOT) e1->n_initializer = fn; ! 1221: } ! 1222: else ! 1223: fct_name = fn; ! 1224: //error('d',"fn %n %t %d %d",fn,f,f->f_this,f->f_static); ! 1225: if (f->f_this) { //SSS call of non-static memberfunction ! 1226: switch (e1->base) { ! 1227: case MEMPTR: ! 1228: case REF: ! 1229: case DOT: ! 1230: break; ! 1231: default: ! 1232: error("O orP missing for%n ofT %t",fct_name,f); ! 1233: } ! 1234: } ! 1235: else if (fn) { //SSS call of static function ! 1236: sss: ! 1237: switch (e1->base) { ! 1238: case REF: ! 1239: case DOT: ! 1240: e1 = e1->mem; ! 1241: goto sss; ! 1242: } ! 1243: } ! 1244: ! 1245: if (fn) fn->use(); // a patch: ctors are sometimes not use()d ! 1246: ! 1247: if (f->f_const==0 ! 1248: && (fn==0 || (fn->n_oper!=CTOR && fn->n_oper!=DTOR))) { //CCC ! 1249: Pexpr ee = e1->e1; ! 1250: if (ee) { ! 1251: Ptype tt = ee->tp; ! 1252: switch (e1->base) { ! 1253: case REF: ! 1254: { Pptr p = tt?tt->is_ptr():0; ! 1255: if (p && p->typ->tconst()) ! 1256: error(strict_opt?0:'w',"non-constMF%n called for constO",fn); ! 1257: // is really an error, but only warn to help transition ! 1258: break; ! 1259: } ! 1260: case DOT: ! 1261: if (tt && tt->tconst()) ! 1262: error(strict_opt?0:'w',"non-constMF%n called for constO",fn); ! 1263: // is really an error, but only warn to help transition ! 1264: } ! 1265: } ! 1266: } ! 1267: ! 1268: t = f->returns; ! 1269: x = f->nargs; ! 1270: k = f->nargs_known; ! 1271: ! 1272: e = arg; ! 1273: if (k == 0) goto rlab; ! 1274: ! 1275: for (nn=f->argtype, argno=1; e||nn; nn=nn->n_list, e=etail->e2, argno++) { ! 1276: Pexpr a; ! 1277: ! 1278: if (e) { ! 1279: a = e->e1; ! 1280: etail = e; ! 1281: ! 1282: if (nn) { /* type check */ ! 1283: Ptype t1 = nn->tp; ! 1284: //error('d',"argtp %t etp %t a %k",t1,a->tp,a->base); ! 1285: ! 1286: lx: ! 1287: switch (t1->base) { ! 1288: case TYPE: ! 1289: t1 = Pbase(t1)->b_name->tp; ! 1290: goto lx; ! 1291: case RPTR: ! 1292: { Ptype pt = Pptr(t1)->typ; ! 1293: if (pt->base != FCT || ! 1294: ( pt->base == FCT && ! 1295: pt->check(a->tp,0))) ! 1296: a = ref_init(Pptr(nn->tp),a,tbl); ! 1297: goto cbcb; ! 1298: } ! 1299: case COBJ: ! 1300: if (a->base!=G_CM ! 1301: || nn->tp->check(a->tp,ASSIGN)) ! 1302: a = class_init(0,t1,a,tbl); ! 1303: if (nn->n_xref) { ! 1304: // (temp.ctor(arg),&arg) ! 1305: a = a->address(); ! 1306: } ! 1307: else { ! 1308: // defend against: ! 1309: // int f(X); ... X(X&); ! 1310: Pname cln = Pbase(t1)->b_name; ! 1311: if (cln && Pclass(cln->tp)->has_itor()) { ! 1312: // mark X(X&) arguments ! 1313: nn->n_xref = 1; ! 1314: a = a->address(); ! 1315: } ! 1316: } ! 1317: cbcb: ! 1318: //error('d',"cbcb: a %d %k %t",a->base,a->base,a->tp); ! 1319: if (a->base==G_CM) { ! 1320: if (a->e1->base==DEREF) a->e1 = a->e1->e2; // (*e1,e2) => (e1,e2) ! 1321: //error('d'," a %d %k",a->e1->base,a->e1->base); ! 1322: if (a->e1->base==G_CALL ! 1323: && Pname(a->e1->fct_name) ! 1324: && Pname(a->e1->fct_name)->n_oper==CTOR ! 1325: && (a->e2->base==G_ADDROF || a->e2->base==ADDROF)) { ! 1326: a = a->e1; // (ctor(&tmp),&tmp) => ctor(&tmp) ! 1327: //error('d',"tmp %k %n",a->e2->base,a->e2->e2); ! 1328: goto cccc; ! 1329: } ! 1330: else if (a->e2->base==G_ADDROF ! 1331: && a->e2->e2->base==NAME) { ! 1332: cccc: ! 1333: //error('d',"cccc: a %d %k %t",a->base,a->base,a->tp); ! 1334: if (t1->base==RPTR ! 1335: && Pptr(t1)->typ->tconst()==0) { // temporary used ! 1336: if (warning_opt) ! 1337: error('w',"temporary used for non-const%tA",nn->tp); ! 1338: else { ! 1339: Ptype atp = a->tp; ! 1340: if (atp==void_type ! 1341: && a->base==G_CALL ! 1342: && a->e1->tp->base==FCT) ! 1343: atp = Pfct(a->e1->tp)->s_returns; ! 1344: ! 1345: Ptype tt = t1->is_ref(); ! 1346: //error('d',"tt %t atp %t",tt,atp); ! 1347: if (tt) { ! 1348: if (Pptr(tt)->typ->tsizeof()!=atp->tsizeof()) { // sliced ! 1349: Ptype aat = atp->is_ptr_or_ref(); ! 1350: if (aat==0 ! 1351: || Pptr(tt)->typ->tsizeof()!=Pptr(aat)->typ->tsizeof()) ! 1352: error('w',"temporary used for non-const%tA",nn->tp); ! 1353: } ! 1354: } ! 1355: else if (t1->tsizeof()!=atp->tsizeof()) // sliced ! 1356: error('w',"temporary used for non-const%tA",nn->tp); ! 1357: } ! 1358: ! 1359: // if (warning_opt // blabber ! 1360: // || t1->tsizeof()!=a->tp->tsizeof())) // sliced ! 1361: // error('w',"temporary used for non-const%tA",nn->tp); ! 1362: ! 1363: } ! 1364: } ! 1365: } ! 1366: e->e1 = a; ! 1367: break; ! 1368: case ANY: ! 1369: goto rlab; ! 1370: case PTR: ! 1371: {// Pexpr x = a; ! 1372: e->e1/* = a */= ptr_init(Pptr(t1),a,tbl); ! 1373: // if (x==a || x==a->e2) goto def; // needs checking ! 1374: if (Pchecked == 0) goto def; ! 1375: break; ! 1376: } ! 1377: // e->e1 = a = ptr_init(Pptr(t1),a,tbl); ! 1378: // goto def; ! 1379: case CHAR: ! 1380: case SHORT: ! 1381: case INT: ! 1382: // if (a->base==ICON && a->tp==long_type) ! 1383: // error('w',"long constantA for%n,%kX",fn,t1->base); ! 1384: { Ptype t = a->tp; ! 1385: csi: ! 1386: switch (t->base) { ! 1387: case TYPE: ! 1388: t = Pbase(t)->b_name->tp; goto csi; ! 1389: case LONG: ! 1390: case FLOAT: ! 1391: case DOUBLE: ! 1392: case LDOUBLE: ! 1393: error('w',"%t passed as %t",a->tp,t1); ! 1394: } ! 1395: } ! 1396: // no break ! 1397: case LONG: ! 1398: if (Pbase(t1)->b_unsigned ! 1399: && a->base==UMINUS ! 1400: && a->e2->base==ICON) ! 1401: error('w',"negativeA for%n, unsignedX",fn); ! 1402: default: ! 1403: def: ! 1404: { Pexpr x = try_to_coerce(t1,a,"argument",tbl); ! 1405: //error('d',"x %d t1 %t nn %t a1 %t",x,t1,nn->tp,a->tp); ! 1406: if (x) ! 1407: e->e1 = x; ! 1408: else if (nn->tp->check(a->tp,ARG)) { ! 1409: error("badA %dT for%n:%t (%tX)",argno,fn,a->tp,nn->tp); ! 1410: return any_type; ! 1411: } ! 1412: } ! 1413: } ! 1414: ! 1415: Pexpr tt = e->e1; ! 1416: while ( tt->base == CAST ) ! 1417: tt = tt->e1; ! 1418: if ( tt->base == ILIST ) ! 1419: e->e1 = tt; ! 1420: ! 1421: if (e->e1->base == ILIST) { ! 1422: extern Pbase mptr_type; ! 1423: Pexpr mptr_assign(Pexpr, Pexpr); ! 1424: // memptr constant ! 1425: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t)) ! 1426: Pname temp = make_tmp('A',mptr_type,tbl); ! 1427: e->e1 = mptr_assign(temp,e->e1); ! 1428: e->e1 = a = new expr(G_CM,e->e1,temp); ! 1429: a->tp = temp->tp; ! 1430: } ! 1431: ! 1432: } ! 1433: else { ! 1434: if (k != ELLIPSIS) { ! 1435: error("unexpected %dA for%n",argno,fn); ! 1436: return any_type; ! 1437: } ! 1438: goto rlab; ! 1439: } ! 1440: } ! 1441: else { /* default argument? */ ! 1442: a = nn->n_initializer; ! 1443: if (a == 0) { ! 1444: error("A %d ofT%tX for%n",argno,nn->tp,fn); ! 1445: return any_type; ! 1446: } ! 1447: if (a->base == ILIST) { ! 1448: extern Pbase mptr_type; ! 1449: Pexpr mptr_assign(Pexpr, Pexpr); ! 1450: // memptr constant ! 1451: // f({1,2,f}) ==> memptr t; f((t={1,2,f},t)) ! 1452: Pname temp = make_tmp('A',mptr_type,tbl); ! 1453: a = mptr_assign(temp,a); ! 1454: a = new expr(G_CM,a,temp); ! 1455: a->tp = temp->tp; ! 1456: } ! 1457: a->permanent = 2; // ought not be necessary, but it is ! 1458: e = new expr(ELIST,a,0); ! 1459: if (etail) ! 1460: etail->e2 = e; ! 1461: else ! 1462: e2 = e; ! 1463: etail = e; ! 1464: } ! 1465: } ! 1466: ! 1467: rlab: ! 1468: //error('d',"rlab fct_name %n %t",fct_name,fct_name?fct_name->tp:0); ! 1469: for (; e; e = e->e2) { // unchecked arguments ! 1470: Pexpr a = e->e1; ! 1471: Pname cn; ! 1472: ! 1473: if (a->base==NAME && a->tp->base==FCT) { ! 1474: // function name that escaped the type system: ! 1475: // update use count ! 1476: a->lval(ADDROF); ! 1477: } ! 1478: else if (cn = a->tp->is_cl_obj()) { ! 1479: Pclass cl = Pclass(cn->tp); ! 1480: if (cl->has_ctor() || cl->memtbl->look("__as",0)/*cl->has_oper(ASSIGN)*/) ! 1481: error("O ofC%t withK or = copied",cl); ! 1482: } ! 1483: else if (a->tp->is_ref()) ! 1484: e->e1 = a->contents(); ! 1485: } ! 1486: ! 1487: if (f->f_result) { // f(args) => (f(&temp,args),temp) ! 1488: Pname tn = make_tmp('R',f->returns,tbl); ! 1489: e2 = new expr(ELIST,tn->address(),e2); ! 1490: //error('d',"result %n",fn); ! 1491: Pexpr ee = new expr(0,0,0); ! 1492: *ee = *this; ! 1493: base = G_CM; // (f(&temp,args),temp) ! 1494: e1 = ee; ! 1495: e2 = tn; ! 1496: tp = tn->tp; ! 1497: } ! 1498: ! 1499: return t; ! 1500: } ! 1501: ! 1502: Pexpr ref_init(Pptr p, Pexpr init, Ptable tbl) ! 1503: /* ! 1504: initialize the "p" with the "init" ! 1505: remember to call ptr_init to ensure that pointers to second bases ! 1506: are handled correctly. ! 1507: */ ! 1508: { ! 1509: register Ptype it = init->tp; ! 1510: Pptr px = p; ! 1511: while (px->base == TYPE) px = Pptr(Pbase(px)->b_name->tp); ! 1512: Ptype p1 = px->typ; ! 1513: Pname c1 = p1->is_cl_obj(); ! 1514: //error('d',"ref_init: p %t, p1 %t, px %t, init->tp %t",p,p1,px,it); ! 1515: ! 1516: if (init->base == ILIST) error("IrL as RIr"); ! 1517: ! 1518: if (init->base==NAME ! 1519: && Pname(init)->n_scope==ARG ! 1520: && init->tp->base==FLOAT) ! 1521: error('w',"initializing a float& with floatA is non-portable"); ! 1522: ! 1523: rloop: ! 1524: switch (it->base) { ! 1525: case TYPE: ! 1526: it = Pbase(it)->b_name->tp; goto rloop; ! 1527: default: ! 1528: { Ptype tt = it->addrof(); ! 1529: px->base = PTR; // allow &x for y& when y : public x ! 1530: // but not &char for int& ! 1531: int x = px->check(tt,COERCE); ! 1532: ! 1533: if (x == 0) { //CCC type is fine check for constness: ! 1534: if (init->tp->tconst() ! 1535: && vec_const==0 ! 1536: && fct_const==0) { ! 1537: // not ``it'' ! 1538: if (init->base == ELIST) init = init->e1; ! 1539: if (px->typ->tconst() == 0) error("R to constO"); ! 1540: px->base = RPTR; ! 1541: // if we have a const lvalue we can still pass its address ! 1542: extern ignore_const; ! 1543: ignore_const++; ! 1544: if (init->lval(0)) { ! 1545: init->lval(ADDROF); // force output ! 1546: ignore_const--; ! 1547: //error('d',"in1 %t",init->tp); ! 1548: return ptr_init(px,init->address(),tbl);//return init->address(); ! 1549: } ! 1550: ignore_const--; ! 1551: goto xxx; ! 1552: } ! 1553: px->base = RPTR; ! 1554: if (init->lval(0)) { // can pass the address // no temporary needed ! 1555: init->lval(ADDROF); // force output ! 1556: //error('d',"px %t init %t init %t",px,init->tp,init->tp); ! 1557: return ptr_init(px,init->address(),tbl); ! 1558: } ! 1559: goto xxx; ! 1560: } ! 1561: ! 1562: px->base = RPTR; ! 1563: } ! 1564: } ! 1565: ! 1566: //error('d',"c1 %n",c1); ! 1567: if (c1) { // assigning to a const X & is fine ! 1568: ref_cast++; ! 1569: Pexpr x = try_to_coerce(p,init,"reference initialization",tbl); ! 1570: ref_cast--; ! 1571: if (x) { ! 1572: init = x; ! 1573: goto xxx; ! 1574: } ! 1575: while (p1->base==TYPE) p1 = Pbase(p1)->b_name->tp; ! 1576: int bc = Pbase(p1)->b_const; ! 1577: Pbase(p1)->b_const = 0; ! 1578: refd = 1; /* disable itor */ ! 1579: Pexpr a = class_init(0,p1,init,tbl); ! 1580: Pbase(p1)->b_const = bc; ! 1581: refd = 0; ! 1582: if (a==init && init->tp!=any_type) goto xxx; ! 1583: //error('d',"ri a %d %k",a->base,a->base); ! 1584: switch (a->base) { ! 1585: case G_CALL: ! 1586: // case CM: ! 1587: // case G_CM: ! 1588: init = a; ! 1589: goto xxx; ! 1590: } ! 1591: a = a->address(); ! 1592: //error('d',"ri2 a %d %k",a->base,a->base); ! 1593: a = ptr_init(px,a,tbl); ! 1594: //error('d',"ri3 a %d %k",a->base,a->base); ! 1595: return a; ! 1596: // return ptr_init(px,a->address(),tbl);//a->address(); ! 1597: } ! 1598: ! 1599: //error('d',"p1 %t it %t",p1,it); ! 1600: if (p1->check(it,0)) { ! 1601: ! 1602: if (p1->check(it,ASSIGN) == 0) { ! 1603: // if (p1->is_ptr()) // check for base* = derived* ! 1604: // goto xxx; ! 1605: ! 1606: // things like ``double& rr = 1;'' temporary needed ! 1607: // warn in case of ``slightly wrong lvalue'', e.g. ! 1608: // int i; double& r = i; ! 1609: if (init->lval(0) && p1->tconst()==0) error('w',"conversion of lvalue needed: temporary used toI reference"); ! 1610: goto def; ! 1611: } ! 1612: ! 1613: Pexpr x = try_to_coerce(p1,init,"reference",tbl); // x==init ! 1614: if (x==0) x = try_to_coerce(px,init,"reference",tbl); // x&=init ! 1615: if (x) { ! 1616: init = x; ! 1617: goto def; ! 1618: } ! 1619: ! 1620: error("badIrT:%t (%tX)",it,p); ! 1621: if (init->base != NAME) init->tp = any_type; ! 1622: return init; ! 1623: } ! 1624: ! 1625: xxx: /* ! 1626: here comes the test of a ``fundamental theorem'': ! 1627: a structure valued expression is ! 1628: (1) an lvalue of type T (possibly const) ! 1629: or (2) the result of a function (a _result if X(X&) is defined) ! 1630: or (3) a * or [] or ? or , expression ! 1631: */ ! 1632: //error('d',"xxx %k %d %t",init->base,init->base,init->tp); ! 1633: ! 1634: switch (init->base) { ! 1635: case NAME: ! 1636: case DEREF: ! 1637: case REF: ! 1638: case DOT: // init => &init ! 1639: if (it->tconst() && vec_const==0 && fct_const==0) goto def; ! 1640: init->lval(ADDROF); ! 1641: if (vec_const) return init; ! 1642: if (fct_const && p1->is_ptr()) goto def; // fptr& = fct ! 1643: // no break ! 1644: case CM: ! 1645: case G_CM: // & (f(&temp), temp) ! 1646: return ptr_init(px,init->address(),tbl);//init->address(); ! 1647: default: ! 1648: def: ! 1649: { ! 1650: //error('d',"def: init->tp %t p1 %t",init->tp,p1); ! 1651: if (tbl == gtbl) error("Ir for staticR not an lvalue"); ! 1652: Pname n = make_tmp('I',p1,tbl); ! 1653: Pexpr a; ! 1654: Pname ic = init->tp->is_cl_obj(); ! 1655: ! 1656: if (p1->tconst()==0 ! 1657: && (init->tp->tconst() && vec_const==0 && fct_const==0) ! 1658: && p1->check(it,ASSIGN)==0) ! 1659: error('w',"constIr: temporary used toI reference"); ! 1660: ! 1661: switch (p1->base) { ! 1662: case INT: ! 1663: case CHAR: ! 1664: case SHORT: ! 1665: switch (it->base) { ! 1666: case LONG: ! 1667: case FLOAT: ! 1668: case DOUBLE: ! 1669: case LDOUBLE: ! 1670: error('w',"%t assigned to %t inRIr",it,p1); ! 1671: } ! 1672: } ! 1673: ! 1674: if (ic!=c1 && Pclass(ic->tp) != Pclass(c1->tp)) { ! 1675: // derived class1 => must cast: ``it Ix; (Ix=init,(p)&Ix);'' ! 1676: n->tp = init->tp; ! 1677: a = ptr_init(px,n->address(),tbl);//n->address(); ! 1678: PERM(p); ! 1679: a = new texpr(CAST,p,a); ! 1680: a->tp = p; ! 1681: } ! 1682: else ! 1683: a = n->address(); ! 1684: ! 1685: refd = 1; ! 1686: Pexpr as = init_tmp(n,init,tbl); ! 1687: refd = 0; ! 1688: a = new expr(G_CM,as,a); ! 1689: a->tp = a->e2->tp; ! 1690: return a; ! 1691: } ! 1692: } ! 1693: } ! 1694: ! 1695: Pexpr class_init(Pexpr nn, Ptype tt, Pexpr init, Ptable tbl) ! 1696: /* ! 1697: initialize "nn" of type "tt" with "init" ! 1698: if nn==0 make a temporary, ! 1699: nn may not be a name ! 1700: */ ! 1701: { ! 1702: if (init == dummy) return 0; ! 1703: //error('d',"class_init %t with %t init %k refd %d",tt,init->tp,init->base,refd); ! 1704: Pname c1 = tt->is_cl_obj(); ! 1705: ! 1706: if (init == 0) { ! 1707: error("emptyIr"); ! 1708: return dummy; ! 1709: } ! 1710: ! 1711: if (c1) { ! 1712: Pclass cl = Pclass(c1->tp); ! 1713: Pname c2 = init->tp->is_cl_obj(); ! 1714: ! 1715: if (c1!=c2 || (refd==0 && cl->has_itor())) { ! 1716: /* really ought to make a temp if refd, ! 1717: but ref_init can do that ! 1718: */ ! 1719: int i = can_coerce(tt,init->tp); ! 1720: //error('d',"i %d nn %n",i,nn); ! 1721: switch (i) { ! 1722: default: ! 1723: error("%d ways of making a%n from a%t",i,c1,init->tp); ! 1724: init->tp = any_type; ! 1725: return init; ! 1726: case 0: ! 1727: if (c2 && Pclass(c2->tp)->has_base(cl)) { ! 1728: init = init->address(); ! 1729: Pexpr x = cast_cptr(cl,init,tbl,0); ! 1730: ! 1731: if (x == init) { ! 1732: Ptype pt = tt->addrof(); ! 1733: PERM(pt); ! 1734: x = new cast(pt,init); ! 1735: } ! 1736: ! 1737: return x->contents(); ! 1738: } ! 1739: error("cannot make a%n from a%t",c1,init->tp); ! 1740: init->tp = any_type; ! 1741: return init; ! 1742: case 1: ! 1743: //error('d',"ncoerce %n %k %d",Ncoerce,init->base,init->base); ! 1744: if (Ncoerce == 0) { ! 1745: Pexpr a = new expr(ELIST,init,0); ! 1746: a = new texpr(VALUE,tt,a); ! 1747: a->e2 = nn; ! 1748: // return a->typ(tbl); ! 1749: a = a->typ(tbl); ! 1750: //error('d',"ci a %k %d %t",a->base,a->base,a->tp); ! 1751: return a; ! 1752: } ! 1753: ! 1754: switch (init->base) { ! 1755: case CM: ! 1756: case G_CM: //ddd ! 1757: case NAME: /* init.coerce() */ ! 1758: /* *ref */ case DEREF: ! 1759: { Pref r = new ref(DOT,init,Ncoerce); ! 1760: Pexpr rr = r->typ(tbl); ! 1761: init = new expr(G_CALL,rr,0); ! 1762: init->fct_name = Ncoerce; ! 1763: break; ! 1764: } ! 1765: default: // (temp=init,temp.coerce()) ! 1766: { Pname tmp = make_tmp('U',init->tp,tbl); ! 1767: int x = refd; ! 1768: refd = 0; // ?? ! 1769: Pexpr ass = init_tmp(tmp,init,tbl); ! 1770: refd = x; ! 1771: Pref r = new ref(DOT,tmp,Ncoerce); ! 1772: Pexpr rr = r->typ(tbl); ! 1773: Pexpr c = new expr(G_CALL,rr,0); ! 1774: c->fct_name = Ncoerce; ! 1775: c = c->typ(tbl); ! 1776: init = new expr(CM,ass,c); ! 1777: init->tp = c->tp; ! 1778: if (refd) { // &f() => (t=f(), &t) ! 1779: Pname tmp2 = make_tmp('L',c->tp,tbl); ! 1780: ass = init_tmp(tmp2,init,tbl); ! 1781: init = new expr(G_CM,ass,tmp2); ! 1782: } ! 1783: } ! 1784: } ! 1785: //error('d',"nn %n",nn); ! 1786: if (nn) { ! 1787: Pexpr a = new expr(ELIST,init,0); ! 1788: a = new texpr(VALUE,tt,a); ! 1789: a->e2 = nn; ! 1790: return a->typ(tbl); ! 1791: } ! 1792: } ! 1793: //error('d',"c1 %n c2 %n",c1,c2); ! 1794: return init->typ(tbl); ! 1795: } ! 1796: return init; ! 1797: } ! 1798: //error('d',"ci check tt %t init->tp %t",tt,init->tp); ! 1799: if (tt->check(init->tp,ASSIGN) && refd==0) { ! 1800: error("badIrT:%t (%tX)",init->tp,tt); ! 1801: init->tp = any_type; ! 1802: } ! 1803: ! 1804: return init; ! 1805: } ! 1806: ! 1807: extern int bound; // fudge for bound pointers to functions ! 1808: ! 1809: Pexpr expr::docast(Ptable tbl) ! 1810: { ! 1811: // check cast against value, INCOMPLETE ! 1812: ! 1813: //error('d',"docast %d %t %k",this,tp2,e1->base); ! 1814: if (e1 == dummy) { ! 1815: error("E missing for cast"); ! 1816: tp = any_type; ! 1817: return this; ! 1818: } ! 1819: ! 1820: int pmf = 0; ! 1821: int ptom_cast = 0; ! 1822: Pexpr ee = e1; ! 1823: ! 1824: //error('d',"ee %k %d",ee->base,ee->base); ! 1825: switch (ee->base) { ! 1826: case ADDROF: ! 1827: ee = ee->e2; ! 1828: switch (ee->base) { ! 1829: case NAME: goto nm; ! 1830: case REF: goto rf; ! 1831: } ! 1832: break; ! 1833: ! 1834: case NAME: ! 1835: nm: ! 1836: if (Pname(ee)->n_qualifier) pmf = 1; ! 1837: break; ! 1838: ! 1839: case REF: ! 1840: rf: ! 1841: if (ee->e1->base == THIS) bound = 1; ! 1842: break; ! 1843: } ! 1844: ! 1845: e1 = e1->typ(tbl); ! 1846: ! 1847: int b = bound; // distinguish between explicit and implicit THIS ! 1848: bound = 0; ! 1849: pmf = pmf && e1->base==CAST; ! 1850: ! 1851: Ptype etp = e1->tp; ! 1852: Ptype tt = tp2; ! 1853: Ptype t = tt; ! 1854: tt->dcl(tbl); ! 1855: ! 1856: while (etp->base == TYPE) etp = Pbase(etp)->b_name->tp; ! 1857: while (tt->base == TYPE) tt = Pbase(tt)->b_name->tp; ! 1858: ! 1859: //error('d',"e1 %k etp %t tt %t",e1->base,etp,tt); ! 1860: ! 1861: switch (etp->base) { ! 1862: case PTR: ! 1863: case RPTR: ! 1864: if (Pptr(etp)->typ->base == OVERLOAD) goto over; ! 1865: ! 1866: if (warning_opt && i2==0 && Pptr(etp)->typ->tconst()) { ! 1867: switch (tt->base) { ! 1868: case FCT: ! 1869: break; ! 1870: case PTR: ! 1871: case RPTR: ! 1872: if (Pptr(tt)->typ->tconst()) break; ! 1873: default: ! 1874: // casting away const ! 1875: // should be an error ! 1876: // but ANSI says OK so I chicken out ! 1877: // to be able to compile strtok(), etc. ! 1878: error('w',"const cast away:%t->%t",e1->tp,tp2); ! 1879: } ! 1880: } ! 1881: else ! 1882: i2 = 0; // to allow cfront to escape its own checking ! 1883: break; ! 1884: case COBJ: ! 1885: { ref_cast = 1; ! 1886: Pexpr x = try_to_coerce(tt,e1,"cast",tbl); ! 1887: ref_cast = 0; ! 1888: //error('d',"x %k %t tt %d %t",x?x->base:0,x?x->tp:0,tt,tt); ! 1889: if (x) { ! 1890: if (x!=e1 && x->base==DEREF && tt->is_ref()) x = x->e1; ! 1891: if (tt==x->tp || tt->check(x->tp,0)==0 || const_problem) ! 1892: return x; ! 1893: else ! 1894: return new cast(tt,x); ! 1895: } ! 1896: // else if (e1->base==DEREF && tt->is_ref()) return e1; ! 1897: break; ! 1898: } ! 1899: case VOID: ! 1900: if (tt->base == VOID) { ! 1901: tp = t; ! 1902: return this; ! 1903: } ! 1904: error("cast of void value"); ! 1905: // no break; ! 1906: case ANY: ! 1907: any: ! 1908: tp = any_type; ! 1909: return this; ! 1910: case FCT: ! 1911: if (tt->base == PTR && Pptr(tt)->typ->base != FCT) ! 1912: error('w',"P toF cast toP to nonF"); ! 1913: break; ! 1914: case OVERLOAD: ! 1915: over: ! 1916: error("cast of overloaded"); ! 1917: goto any; ! 1918: } ! 1919: ! 1920: //error('d',"tt %t",tt); ! 1921: switch (tt->base) { ! 1922: case PTR: ! 1923: if (Pptr(tt)->typ->base==FCT && Pptr(tt)->memof) { ! 1924: if (etp->base!=PTR ! 1925: || Pptr(etp)->typ->base!=FCT ! 1926: || Pptr(etp)->memof==0) ! 1927: error("cast toP toM %t",tt); ! 1928: else { // adjust delta in MI case ! 1929: // for the moment just suppress the cast ! 1930: // all pmfs are the same to cc ! 1931: /* ! 1932: Pclass c1 = Pptr(tt)->memof; ! 1933: Pclass c2 = Pptr(etp)->memof; ! 1934: */ ! 1935: ptom_cast = 1; ! 1936: tp2 = void_type; ! 1937: } ! 1938: } ! 1939: ! 1940: switch (etp->base) { ! 1941: case COBJ: ! 1942: error("cannot castCO toP"); ! 1943: break; ! 1944: case FCT: ! 1945: e1 = new expr(G_ADDROF,0,e1); ! 1946: bound = b; ! 1947: e1 = e1->typ(tbl); ! 1948: bound = 0; ! 1949: if (e1->base == CAST) ! 1950: pmf = 1; ! 1951: else ! 1952: break; ! 1953: // no break; ! 1954: ! 1955: case PTR: ! 1956: { Pname cn = Pptr(tt)->typ->is_cl_obj(); ! 1957: if (cn) { ! 1958: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1); ! 1959: ! 1960: if (x == e1) { ! 1961: PERM(tt); ! 1962: e1 = new cast(tt,e1); ! 1963: e1->i2 = i2; ! 1964: } ! 1965: else ! 1966: e1 = x; ! 1967: } ! 1968: if (pmf) { ! 1969: zaqq: ! 1970: switch (tt->base) { ! 1971: case TYPE: ! 1972: tt = Pbase(tt)->b_name->tp; goto zaqq; ! 1973: case PTR: ! 1974: if (Pptr(tt)->memof) break; ! 1975: default: ! 1976: error("%t cast to%t (%t is not aP toM)",e1->tp,tp2,tp2); ! 1977: } ! 1978: } ! 1979: } ! 1980: } ! 1981: break; ! 1982: ! 1983: case RPTR: // (x&)e: pretend e is an x ! 1984: { Ptype er = etp; ! 1985: Ptype cr = tt; ! 1986: do { ! 1987: if (er = er->is_ptr_or_ref()) er = Pptr(er)->typ; ! 1988: if (cr = cr->is_ptr_or_ref()) cr = Pptr(cr)->typ; ! 1989: } while (er && cr); ! 1990: int pp = er!=0; // if `e' is a suitable pointer cast it: ! 1991: // (x&)e => (x*)e, otherwise ! 1992: // (x&)e => *(x*)&e ! 1993: //error('d',"rptr tt %t e1->base %k e1->tp %t",tt,e1->base,e1->tp); ! 1994: // if (Pptr(tt)->typ->tsizeof()>etp->tsizeof()) goto zse; ! 1995: // we need to be able to ``raise the type'' from base to derived ! 1996: // if (etp->is_cl_obj() && Pptr(tt)->typ->is_cl_obj()==0) goto zse; ! 1997: ! 1998: if (e1->base==G_CM ! 1999: || e1->base==CALL ! 2000: || e1->base==G_CALL ! 2001: || e1->lval(0)) ! 2002: ; ! 2003: else if (e1->tp->tconst()) { ! 2004: // casting away const ! 2005: // should be an error ! 2006: // but ANSI says OK so I chicken out ! 2007: // to be able to compile strtok(), etc. ! 2008: if (warning_opt && Pptr(tt)->typ->tconst()==0) ! 2009: error('w',"const cast away:%t->%t",e1->tp,tp2); ! 2010: ! 2011: } ! 2012: else ! 2013: error("cannot cast%t to%t",etp,t); ! 2014: //error('d',"e1 %k %t %d",e1->base,e1->tp,pp); ! 2015: if (pp == 0) e1 = e1->address(); // *(x*)&e ! 2016: tp = t; ! 2017: ! 2018: // do proper pointer manipulation for multiple inheritance ! 2019: Pname cn = Pptr(tt)->typ->is_cl_obj(); ! 2020: if (cn) { ! 2021: Pexpr x = cast_cptr(Pclass(cn->tp),e1,tbl,1); ! 2022: ! 2023: if (x == e1) { ! 2024: PERM(tt); ! 2025: e1 = new cast(tt,e1); ! 2026: e1->i2 = i2; ! 2027: } ! 2028: else ! 2029: e1 = x; ! 2030: } ! 2031: ! 2032: return pp ? this : contents(); ! 2033: // zse: ! 2034: // error("cannot cast%t to%t",etp,t); ! 2035: // tp2 = tt = any_type; ! 2036: // break; ! 2037: } ! 2038: case COBJ: ! 2039: base = VALUE; // (x)e => x(e): construct an x from e ! 2040: e1 = new expr(ELIST,e1,0); ! 2041: return typ(tbl); ! 2042: ! 2043: case CHAR: ! 2044: case INT: ! 2045: case SHORT: ! 2046: case LONG: ! 2047: case FLOAT: ! 2048: case DOUBLE: ! 2049: case LDOUBLE: ! 2050: switch (etp->base) { ! 2051: case FCT: ! 2052: e1 = new expr(ADDROF,0,e1); ! 2053: e1 = e1->typ(tbl); ! 2054: break; ! 2055: case COBJ: ! 2056: error("cannot castCO to%k",tt->base); ! 2057: break; ! 2058: } ! 2059: break; ! 2060: } ! 2061: ! 2062: tp = t; ! 2063: ! 2064: if (e1->base==ILIST && ptom_cast==0) { // pointer to member constant ! 2065: Pexpr ee = e1->e1; // ELIST ! 2066: int i; ! 2067: switch (ee->e2->base) { ! 2068: case IVAL: ! 2069: i = int(ee->e2->i1); ! 2070: break; ! 2071: case ZERO: ! 2072: i = 0; ! 2073: } ! 2074: ! 2075: if (i<0) ! 2076: e1 = e1->e2; // just the function ! 2077: else ! 2078: e1 = ee->e2; // just the index ! 2079: return this; ! 2080: } ! 2081: ! 2082: if (etp->base==PTR && Pptr(etp)->memof && Pptr(etp)->typ->base==FCT) { ! 2083: Pclass cl = Pptr(etp)->memof; ! 2084: ! 2085: if (Pptr(tt)->memof==0 && b == 0 ) { ! 2086: Pexpr y = new mdot("f",e1); ! 2087: y->i1 = 9; ! 2088: y = new cast(tt,y); ! 2089: if (cl->virt_count && b==0) { ! 2090: // ERROR: no check for side effects ! 2091: Pexpr z = new mdot("i",e1); ! 2092: Pexpr x = new mdot("i",e1); ! 2093: x->i1 = 9; ! 2094: x = new cast(tt,x); ! 2095: z->i1 = 9; ! 2096: Pexpr q = new expr (QUEST,x,y); ! 2097: q->cond = new expr(LE,zero,z); ! 2098: q->tp = tt; ! 2099: delete this; ! 2100: return q; ! 2101: } ! 2102: delete this; ! 2103: return y; ! 2104: } ! 2105: } ! 2106: ! 2107: return this; ! 2108: } ! 2109: ! 2110: Pexpr expr::dovalue(Ptable tbl) ! 2111: { ! 2112: Ptype tt = tp2; ! 2113: Pclass cl; ! 2114: Pname cn; ! 2115: ! 2116: //error('d',"value %d %t e1 %d e2 %d",tt,tt,e1,e2); ! 2117: ! 2118: tt->dcl(tbl); ! 2119: vv: ! 2120: switch (tt->base) { ! 2121: case TYPE: ! 2122: tt = Pbase(tt)->b_name->tp; ! 2123: goto vv; ! 2124: ! 2125: case EOBJ: ! 2126: default: ! 2127: if (e1 == 0) { ! 2128: error("value missing in conversion to%t",tt); ! 2129: return dummy; ! 2130: } ! 2131: base = CAST; ! 2132: e1 = e1->e1; // strip ELIST ! 2133: return typ(tbl); ! 2134: ! 2135: case CLASS: ! 2136: cl = Pclass(tt); ! 2137: tp2 = Pptr(cl->this_type)->typ; ! 2138: break; ! 2139: ! 2140: case COBJ: ! 2141: cn = Pbase(tt)->b_name; ! 2142: cl = Pclass(cn->tp); ! 2143: } ! 2144: ! 2145: //error('d',"e1 %k e1->e2 %k",e1->base,e1?e1->e2->base:0); ! 2146: if (e1 && e1->e2==0) { // single argument ! 2147: if (e1->e1->base==ELIST) e1->e1 = e1->e1->e1; // spurious elist ! 2148: e1->e1 = e1->e1->typ(tbl); ! 2149: if (tt->base==COBJ) { ! 2150: Pexpr x = try_to_coerce(tt,e1->e1,"type conversion",tbl); ! 2151: if (x) return x; ! 2152: } ! 2153: ! 2154: Pname acn = e1->e1->tp->is_cl_obj(); ! 2155: //error('d',"acn %n %d",acn,cl->has_itor()); ! 2156: if (acn && cl->has_itor()==0) { ! 2157: Pclass acl = Pclass(acn->tp); ! 2158: int hb = acl->has_base(cl); ! 2159: ! 2160: if (acl==cl || hb) { ! 2161: vcllist->clear(); ! 2162: vcllist=0; ! 2163: if (1<is_unique_base(acl,cl->string,0)) error("ambiguous assignment to base %t",cl); ! 2164: Pexpr ee = e1->e1; ! 2165: if (ee->base == ELIST) ee = ee->e1; // ??? ! 2166: if (hb) { // ee => *(tp2*)&ee ! 2167: // remember = may be overloaded ! 2168: //error('d',"hb %k %t %d",ee->base,ee->tp,ee->lval(0)); ! 2169: if (ee->lval(0)==0) { ! 2170: Pname tmp = make_tmp('T',ee->tp,tbl); ! 2171: ee = init_tmp(tmp,ee,tbl); ! 2172: ee = new expr(G_CM,ee,tmp->address()); ! 2173: } ! 2174: else ! 2175: ee = ee->address(); ! 2176: ee = new texpr(CAST,new ptr(PTR,tp2),ee); //new cast(new ptr(PTR,tp2),ee); ! 2177: ee = ee->contents(); ! 2178: ee->typ(tbl); ! 2179: } ! 2180: ! 2181: if (e2) { // x(x_obj) => e2=x_obj ! 2182: base = ASSIGN; ! 2183: e1 = e2; ! 2184: e2 = ee; ! 2185: tp = tp2; ! 2186: return this; ! 2187: } ! 2188: return ee; // strip ELIST: x(x_obj) => x_obj ! 2189: } ! 2190: } ! 2191: } ! 2192: ! 2193: ! 2194: /* x(a) => obj.ctor(a); where e1==obj */ ! 2195: Pname ctor = cl->has_ctor(); ! 2196: if (ctor == 0) { ! 2197: error("cannot make a%t",cl); ! 2198: return dummy; ! 2199: } ! 2200: ! 2201: //error('d',"e2 %k",e2?e2->base:0); ! 2202: if (e2 == 0) { // x(a) => x temp; (temp.x(a),temp) ! 2203: Pname n = make_tmp('V',tp2,tbl); ! 2204: n->assign(); ! 2205: if (tbl == gtbl) n->dcl_print(0); // a hack ! 2206: Pexpr c = call_ctor(tbl,n,ctor,e1,DOT); ! 2207: c = new expr(G_CM,c,n); ! 2208: c->tp = n->tp; ! 2209: //error('d',"tp1 %t",c->tp); ! 2210: return c; ! 2211: } ! 2212: else { ! 2213: Pexpr c = call_ctor(tbl,e2,ctor,e1,DOT); ! 2214: c = new expr(DEREF,c,0); // deref value returned by constructor ! 2215: c->tp = c->e1->tp; ! 2216: //error('d',"tp2 %t",c->tp); ! 2217: return c; ! 2218: } ! 2219: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.