Annotation of researchv10no/cmd/cfront/ooptcfront/expr3.c, revision 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.