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

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

unix.superglobalmegacorp.com

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