Annotation of researchv10no/cmd/cfront/xptcfront/expr3.c, revision 1.1

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

unix.superglobalmegacorp.com

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