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