Annotation of researchv10no/cmd/cfront/ooptcfront/expr3.c, revision 1.1.1.1

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: */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.