Annotation of researchv10no/cmd/cfront/xptcfront/dcl3.c, revision 1.1.1.1

1.1       root        1: /*ident        "@(#)ctrans:src/dcl3.c  1.7" */
                      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: dcl3.c:
                     11:        Routines used by ::dcl fucntions: fct::dcl() etc.
                     12: 
                     13: *****************************************************************************/
                     14: 
                     15: #include "cfront.h"
                     16: #include "size.h"
                     17: #include "template.h"
                     18: 
                     19: static void vbase_pointers(Pname fn, Pclass cl)
                     20: /*
                     21:        insert argument for virtual base pointers (if any)
                     22:        after f_this and before f_argtype
                     23: */
                     24: {
                     25: //error('d',"vbase_pointers(%n,%t) %d %k",fn,cl,fn->tp,fn->n_oper);
                     26:        Pfct f = Pfct(fn->tp);
                     27:        if (fn->n_oper == CTOR) {
                     28:                Pname d = 0;
                     29:                for (Pbcl b = cl->baselist; b; b=b->next) {
                     30:                        if (b->base != VIRTUAL) continue;
                     31:                        Pname a = new name(b->bclass->string);
                     32:                        a->tp = b->bclass->this_type;
                     33:                        a->n_list = d;
                     34:                        a->n_table = f->body ? f->body->memtbl : 0;
                     35:                        a->where = fn->where;
                     36:                        d = a;
                     37:                }       
                     38:                                
                     39:                if (d) {
                     40:                        for (Pname dd =d;;) {
                     41:                                if (d->n_list == 0) {
                     42:                                        d->n_list = f->f_args->n_list;
                     43:                                        break;
                     44:                                }
                     45:                                d = d->n_list;
                     46:                        }
                     47:                        f->f_args->n_list = dd;
                     48:                }
                     49:        }
                     50:        if (fn->n_oper == DTOR) {       // add __free argument
                     51: //error('d',"add __free to %n",fn);
                     52:                Pname fa = new name;
                     53:                fa->tp = int_type;
                     54:                fa->n_scope = ARG;
                     55:                fa->where = fn->where;
                     56: 
                     57:                Pname a = f->f_args;
                     58:                if (a == 0)
                     59:                        f->f_args = fa;
                     60:                else {
                     61:                        for(;;a = a->n_list) {
                     62: // error('d',"a %d %t",a,a->tp);
                     63:                                if (a->n_list == 0) {
                     64:                                        a->n_list = fa;
                     65:                                        break;
                     66:                                }
                     67:                        }
                     68:                }
                     69:        }
                     70: }
                     71: 
                     72: void make_res(Pfct f)
                     73: /*
                     74:        returns X where X(X&) has been declared
                     75:        add "_result" argument of type X*
                     76: */
                     77: {
                     78:        Pname cl = f->returns->is_cl_obj();
                     79:        if (cl==0 || Pclass(cl->tp)->has_itor()==0) return;
                     80: 
                     81:        Pname rv = new name("_result");
                     82:        rv->tp  = f->returns->addrof();
                     83:        rv->n_scope = FCT;      // not a ``real'' argument
                     84:        rv->n_used = 1;
                     85:        rv->n_list = f->argtype;
                     86:        if (f->f_this)
                     87:                f->f_this->n_list = rv;
                     88:        else
                     89:                f->f_args = rv;
                     90:        f->f_result = rv;
                     91:        f->s_returns = void_type;
                     92: }
                     93: 
                     94: void name::check_oper(Pname cn)
                     95: /*
                     96:        check declarations of operators, ctors, dtors
                     97: */
                     98: {
                     99: // error('d', "%n->check_oper( %n ): n_oper: %k", this, cn, n_oper );
                    100:        switch (n_oper) {
                    101:        case CALL:
                    102:        case DEREF:
                    103:        case REF:
                    104:                if (cn == 0) error("operator%s must be aM",keys[n_oper]);
                    105:                break;
                    106:        case ASPLUS:
                    107:        case ASMINUS:
                    108:        case ASMUL:
                    109:        case ASDIV:
                    110:        case ASMOD:
                    111:        case ASAND:
                    112:        case ASOR:
                    113:        case ASER:
                    114:        case ASLS:
                    115:        case ASRS:
                    116:                if ( warning_opt ) {
                    117:                        if ( cn == 0 || Pfct(tp)->f_static )
                    118:                                error('w', "operator%s should be a non-staticMF",keys[n_oper]);
                    119:                }
                    120:                break;
                    121:        case ASSIGN:
                    122:                if (cn == 0) 
                    123:                        error(strict_opt?0:'w',"non-member operator%k() (anachronism)",n_oper);
                    124:                break;
                    125:        case NOT:       /* unary operators only */
                    126:        case COMPL:
                    127:        // case INCR:
                    128:        // case DECR:
                    129:                Pfct f = Pfct(tp);
                    130:                if (cn && f->argtype) 
                    131:                        error("%n::%n takes noA",cn, this);
                    132:                else if (f->nargs == 2)
                    133:                        error("%n takes 1A only",this);
                    134:                break;
                    135:        case INCR:
                    136:        case DECR:
                    137:                // check for postscript instance
                    138:                f = Pfct(tp);
                    139:                if (cn) { // member
                    140:                        if ( f->argtype && f->nargs == 1 ) {
                    141:                                Pname n = f->argtype;
                    142:                                if ( n->tp->base != INT )
                    143:                                        error("%n must takeA ofT int, not %t",this,n->tp);
                    144:                        }
                    145:                }
                    146:                else 
                    147:                if (f->nargs == 2) { // non-member
                    148:                        Pname n = f->argtype->n_list;
                    149:                        if ( n->tp->base != INT )
                    150:                                error("%n must takeA ofT int, not %t",this,n->tp);
                    151:                }
                    152:                break;
                    153: 
                    154:        case 0:
                    155:        case TNAME:     /* may be a constructor */
                    156:                if (cn && ((strcmp(cn->string,string)==0) ||
                    157:                        ((Pclass(cn->tp)->class_base == 
                    158:                                instantiated_template_class) &&
                    159:                        (strcmp(string, 
                    160:                                Ptclass(cn->tp)->unparametrized_tname()->string) == 0)))) 
                    161:                {
                    162:                        if (tp->base == FCT) {
                    163:                                Pfct f = Pfct(tp);
                    164:                                if (f->returns!=defa_type)
                    165:                                        error("%s::%s()W returnT",string,string);
                    166:                                f->returns = void_type;
                    167:                                string = "__ct";
                    168:                                n_oper = CTOR;
                    169:                        }
                    170:                        else
                    171:                                error('s',"struct%nM%n",cn,cn);
                    172:                }
                    173:                else
                    174:                        n_oper = 0;
                    175:                break;
                    176:        case DTOR:      /* must be a destructor */
                    177: //error('d',"dtor %s",string);
                    178:                if (cn == 0) {
                    179:                        n_oper = 0;
                    180:                        error("destructor ~%s() not inC",string);
                    181:                }
                    182:                 else 
                    183:                if ((strcmp(cn->string,string) == 0) ||
                    184:                        ((Pclass(cn->tp)->class_base ==
                    185:                                instantiated_template_class) &&
                    186:                          (strcmp(string,
                    187:                                Ptclass(cn->tp)->unparametrized_tname()->string)==0)))
                    188:                {
                    189:                dto:
                    190:                        Pfct f = (Pfct)tp;
                    191:                        string = "__dt";
                    192:                        if (tp->base != FCT) {
                    193:                                error("%s::~%s notF",cn->string,cn->string);
                    194:                                tp = new fct(void_type,0,1);
                    195:                        }
                    196:                        else if (f->returns!=defa_type/* && f->returns!=void_type*/) {
                    197:                                if ( f->returns != void_type ||
                    198:                                        f->body != 0 || friend_in_class == 0 ) 
                    199:                                                error("%s::~%s()W returnT",cn->string,cn->string);
                    200:                        }
                    201: 
                    202:                        if (f->argtype) {
                    203:                                error("%s::~%s()WAs",cn->string,cn->string);
                    204:                                f->nargs = 0;
                    205:                                f->nargs_known = 1;
                    206:                                f->argtype = 0;
                    207:                        }
                    208:                        f->returns = void_type;
                    209:                }
                    210:                else {
                    211:                        if (strcmp(string,"__dt") == 0) goto dto;
                    212:                        error("~%s in %s",string,cn->string);
                    213:                        n_oper = 0;
                    214:                }
                    215:                break;
                    216:        case TYPE:
                    217: // cond stores the type of the operator function
                    218: // error('d',"type %t",cond);
                    219:                if (cn == 0) {
                    220:                        // error("operator%t() not aM",Ptype(n_initializer));
                    221:                        error("operator%t() not aM",Ptype(cond));
                    222:                        n_oper = 0;
                    223:                        // n_initializer = 0;
                    224:                        cond = 0;
                    225:                }
                    226:                else {
                    227:                        Pfct f = Pfct(tp);
                    228:                        // n_initializer = 0;
                    229:                        Ptype tx = Ptype(cond);
                    230:                        cond = 0;
                    231:                        if (f->base != FCT) error("badT for%n::operator%t()",cn,tx);
                    232:                        if (f->returns != defa_type) {
                    233:                        //      if (f->returns->check(tx,0)) error("bad resultT for%n::operator%t()",cn,tx);
                    234:                                error("resultT for%n::operator%t()",cn,tx);
                    235:                                DEL(f->returns);
                    236:                        }
                    237:                        if (f->argtype) {
                    238:                                error("%n::operator%t()WAs",cn,tx);
                    239:                                f->argtype = 0;
                    240:                        }
                    241:                        f->returns = tx;
                    242:                        Pname nx = tx->is_cl_obj();
                    243:                        if (nx && can_coerce(tx,cn->tp)) error("both %n::%n(%n) and %n::operator%t()",cn,cn,nx,tx);
                    244:                        char buf[1024];
                    245:                        char* bb = tx->signature(buf);
                    246:                        int l2 = bb-buf;
                    247:                        if (1023<l2) error('i',"N::check_oper():N buffer overflow");
                    248:                        char* p = new char[l2+5];
                    249:                        p[0] = '_';
                    250:                        p[1] = '_';
                    251:                        p[2] = 'o';
                    252:                        p[3] = 'p';
                    253:                        strcpy(p+4,buf);
                    254:                        string = p;
                    255:                }
                    256:                break;
                    257:        }
                    258: }
                    259: 
                    260: Pexpr vbase_args(Pfct a, Pname bn)
                    261: /*
                    262:        constructor a calls the constructor bn for a base class
                    263:        generate argument list needed for virtual base arguments
                    264: */
                    265: {
                    266:        Pfct b = Pfct(bn->tp);
                    267: //error('d',"vbase_args%n: %t %k",bn,b,b->base);
                    268:        Pexpr args = 0;
                    269:        Pexpr tail = 0;
                    270:        if (b->base == OVERLOAD) b = Pfct(Pgen(b)->fct_list->f->tp);    // doesn't matter which
                    271:        for (Pname d = b->f_args->n_list; d!=b->argtype; d=d->n_list) {
                    272:                for (Pname dd = a->f_args->n_list; dd; dd=dd->n_list)
                    273:                        // using strcmp is a trick
                    274:                        if (strcmp(dd->string,d->string)==0) break;
                    275: 
                    276:                Pexpr aa = new expr(ELIST,dd,0);
                    277:                if (args == 0)
                    278:                        args = aa;
                    279:                else
                    280:                        tail->e2 = aa;
                    281:                tail = aa;
                    282:        }
                    283:        return args;
                    284: }
                    285: 
                    286: void fct::init_bases(Pclass cl, Pexpr)
                    287: /*
                    288:        in "cl"'s constructor "this" generate code to initialize base classes
                    289:        and members using the initializers "f->f_init"
                    290:        
                    291:        this->f_init == list of names of classes to be initialized
                    292:                COLON(b)        => base class b
                    293:                                => constructor call in f_init->n_initializer
                    294:                COLON()         => unnamed base class
                    295:                                => constructor call in f_init->n_initializer
                    296:                NAME(m)         => member m
                    297:                                => constructor call in m->n_initializer
                    298: */
                    299: {
                    300:        Ptable ftbl = body->memtbl;
                    301:        DB( if(Ddebug>=1) error('d',"init_bases %t init %d",cl,f_init); );
                    302: 
                    303:        // explicit initializers
                    304:        if ( cl && cl->csu == UNION && f_init && f_init->n_list )
                    305:                error(&f_init->where,"multipleIrs in unionK %s:: %s",cl->string,cl->string);
                    306:        for (Pname nx, nn=f_init; nn; delete nn,(nn=nx) ) {
                    307:                Pexpr i = nn->n_initializer;
                    308:                nn->n_initializer = 0;
                    309:                nx = nn->n_list;
                    310: 
                    311: // error('d',"init_base %s %d",nn->string,i);
                    312:                if (nn->string) {
                    313:                        // lookup in case type name hides a "real" member
                    314:                        { Pname mmm = cl->memtbl->look(nn->string,0);
                    315:                          if ( mmm ) nn->base = mmm->base;
                    316:                        }
                    317:                        if (nn->base == TNAME) {        // base class
                    318:                                char *bn;
                    319:                                while ( nn->tp && nn->tp->base == TYPE )
                    320:                                        nn->tp = Pbase(nn->tp)->b_name->tp;
                    321:                                if ( nn->tp && nn->tp->base == COBJ )
                    322:                                    bn = Pbase(nn->tp)->b_name->string;
                    323:                                else
                    324:                                    bn = nn->string;
                    325:                                for (Pbcl l = cl->baselist; l; l=l->next) {
                    326:                                        Pclass bcl = l->bclass;
                    327:                                        if ((strcmp(bcl->string,bn) == 0) ||
                    328:                                                ((bcl->class_base ==
                    329:                                                        instantiated_template_class) &&
                    330:                                                ((strcmp(nn->string,
                    331:                                                        Ptclass(bcl)->unparametrized_tname()->string)) == 0)))
                    332:                                        {
                    333: 
                    334:                                                // l->init is zeroed out in ctor_simpl
                    335:                                                // if error_count, simpl() not invoked
                    336:                                                if (l->init && error_count == 0) 
                    337:                                                        error("twoIrs for%t",bcl);
                    338:                                                else
                    339:                                                        l->init = base_init(bcl,i,ftbl,l->obj_offset);
                    340:                                                goto con;
                    341:                                        }
                    342:                                }
                    343:                                error(&nn->where,"unexpectedAL: noBC%n",nn);
                    344:                        con:
                    345:                                continue;
                    346:                        }
                    347:                        else {  // member initializer
                    348:                                Pname m = cl->memtbl->look(nn->string,0);
                    349:                                if (m && m->n_table==cl->memtbl)
                    350:                                        m->n_initializer = mem_init(m,i,ftbl);
                    351:                                else
                    352:                                        error(&nn->where,"%n not inC %s",nn,cl->string);
                    353:                        }
                    354:                }
                    355:                else {                  // unnamed base class
                    356:                        Pbcl l = cl->baselist;
                    357:                        if (l == 0) {
                    358:                                error("unexpectedAL: noBC called");
                    359:                                continue;
                    360:                        }
                    361: 
                    362:                        if (l->next) {
                    363:                                bit cnt = 0, rvb = 0; // remote virtual base classes
                    364:                                for (Pbcl ll = l; ll; ll = ll->next, ++cnt ) 
                    365:                                        if (ll->base==VIRTUAL && ll->promoted) ++rvb;
                    366:                                if ( rvb ) 
                    367:                                        error("unnamedBCIr: %dBCes(%d non-explicit virtualBC%s)",cnt,rvb,rvb==1?"":"es");
                    368:                                else error("unnamedBCIr: %dBCes",cnt);
                    369:                                continue;
                    370:                        }
                    371:                        
                    372:                        if (l->init)
                    373:                                error("twoIrs for%t",l->bclass);
                    374:                        else {
                    375:                                error(strict_opt?0:'w',&nn->where,"N ofBC%t missing from BCIr (anachronism)",l->bclass);
                    376:                                l->init = base_init(l->bclass,i,ftbl,l->obj_offset);
                    377:                        }
                    378:                }
                    379:        } // for
                    380: 
                    381:        for (Pbcl l = cl->baselist; l; l=l->next) {
                    382:                // default initialization of base classes
                    383:                Pname ctor;
                    384:                Pclass bcl = l->bclass;
                    385:                if (l->init==0 && (ctor=bcl->has_ctor()))
                    386:                        l->init = base_init(bcl,0,ftbl,l->obj_offset);
                    387:        }
                    388: }
                    389: 
                    390: int inline_restr;      /* report use of constructs that the inline expanded
                    391:                           cannot handle here */
                    392: 
                    393: void fct::dcl(Pname n)
                    394: {
                    395:        int nmem = TBLSIZE;
                    396:        Pname a;
                    397:        Pname ll;
                    398:        Ptable ftbl;
                    399: 
                    400:        Pptr cct = 0;
                    401:        int const_old = const_save;
                    402: 
                    403:        int bit_old = bit_offset;
                    404:        int byte_old = byte_offset;
                    405:        int max_old = max_align;
                    406: 
                    407:        if (base != FCT) error('i',"F::dcl(%d)",base);
                    408:        if (body == 0) error('i',"F::dcl(body=%d)",body);
                    409:        if (n==0 || n->base!=NAME) error('i',"F::dcl(N=%d %d)",n,(n)?n->base:0);
                    410:        DB( if(Ddebug>=1) error('d',"fct::dcl(%n) %k %d %t",n,n->n_scope,body->own_tbl,this); );
                    411:        if (body->own_tbl) return;      // done already
                    412: 
                    413: //     if (f_inline==0 ) n->n_dcl_printed = 1; // beware of recursive calls, no decl needed
                    414: //     if (f_inline && debug_opt) n->n_dcl_printed = 2;
                    415:        if (body->memtbl == 0) body->memtbl = new table(nmem+3,gtbl,0);
                    416:        body->own_tbl = 1;
                    417:        ftbl = body->memtbl;
                    418:        ftbl->real_block = body;
                    419: 
                    420:        max_align = 0;//AL_FRAME;
                    421:        bit_offset = 0;
                    422: 
                    423:        cc->stack();
                    424:        cc->nof = n;
                    425:        cc->ftbl = ftbl;
                    426: 
                    427:        switch (n->n_scope) {
                    428:        case 0:
                    429:        case PUBLIC:
                    430:        {       cc->not = n->n_table->t_name;
                    431:                cc->cot = Pclass(cc->not->tp);
                    432:                cc->tot = cc->cot->this_type;
                    433:        //      if (f_this==0 || cc->tot==0) error('i',"F::dcl(%n): f_this=%d cc->tot=%d",n,f_this,cc->tot);
                    434:                if (f_this) f_this->n_table = ftbl;     // fake for inline printout
                    435:                cc->c_this = f_this;
                    436: 
                    437: 
                    438:                Pclass cl = Pclass(cc->not->tp);
                    439: 
                    440:                if (cl->c_body!=3
                    441:                || n->n_initializer
                    442:                || n->n_sto==STATIC
                    443:                || f_inline
                    444:                || f_imeasure
                    445:                || f_virtual==0)
                    446:                        ;
                    447:                else {          // could be the function where we need to
                    448:                                // output the vtbl
                    449:                        int i;
                    450:                        for (Pname nn=cl->memtbl->get_mem(i=1); nn; nn=cl->memtbl->get_mem(++i) ) {
                    451:                        Ptype t = nn->tp;
                    452:                        if (t)
                    453:                        switch (t->base) {
                    454:                        case FCT:
                    455:                                if (nn == n) goto prnt;
                    456:                                if (nn->n_initializer
                    457:                                || nn->n_sto==STATIC
                    458:                                || Pfct(nn->tp)->f_inline
                    459:                                || Pfct(nn->tp)->f_imeasure
                    460:                                || Pfct(nn->tp)->f_virtual==0) break;
                    461:                                goto zaq;
                    462: 
                    463:                        case OVERLOAD:
                    464:                        {       for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l) {
                    465:                                        Pname nn = gl->f;
                    466:                                        if (nn == n) goto prnt;
                    467:                                        if (nn->n_initializer
                    468:                                        || nn->n_sto==STATIC
                    469:                                        || Pfct(nn->tp)->f_inline
                    470:                                        || Pfct(nn->tp)->f_imeasure
                    471:                                        || Pfct(nn->tp)->f_virtual==0) continue;
                    472:                                        goto zaq;
                    473:                                }
                    474:                        }
                    475:                        }
                    476:                }
                    477:                        goto zaq;
                    478:                prnt:
                    479:                        cl->print_all_vtbls(cl);
                    480:                        goto zaq;
                    481:                }
                    482:        }
                    483:        }
                    484: zaq:
                    485:                // protect against: class x; x f(); class x { x(x&); ....
                    486:        if (f_result == 0) make_res(this);
                    487:        if (f_result) f_result->n_table = ftbl;         // fake for inline printout
                    488: 
                    489:        returns->tsizeof();     // make sure size is known
                    490: 
                    491:        Pname ax;
                    492:        for (a=argtype, ll=0; a; a=ax) {
                    493:                ax = a->n_list;
                    494:                Pname nn = a->dcl(ftbl,ARG);
                    495:                Pname cn = nn->tp->is_cl_obj();
                    496:                if (cn == 0) cn = cl_obj_vec;
                    497:                if (cn) (void)cn->tp->tsizeof();        // make sure it is printed
                    498:                nn->n_assigned_to = nn->n_used = nn->n_addr_taken = 0;
                    499:                nn->n_list = 0;
                    500: 
                    501:                switch (nn->tp->base) {
                    502:                case CLASS:
                    503:                case ENUM:      /* unlink types declared in arg list */
                    504:                        nn->dcl_print(0);
                    505:                        break;
                    506:                default:
                    507:                        if (ll)
                    508:                                ll->n_list = nn;
                    509:                        else
                    510:                                f_args = argtype = nn;
                    511:                        ll = nn;
                    512:                }
                    513:                delete a;
                    514:        }
                    515: 
                    516:        if (f_result) {         // link in f_result
                    517:                f_args = f_result;
                    518:                f_result->n_list = argtype;
                    519:        }
                    520: 
                    521:        if (f_this) {           // link in f_this
                    522:                f_args = f_this;
                    523:                f_this->n_list = f_result ? f_result : argtype;
                    524:        }
                    525: 
                    526:        if (n->n_oper==CTOR || n->n_oper==DTOR) vbase_pointers(n,cc->cot);
                    527: 
                    528:        if (n->n_oper == CTOR) {
                    529:                const_save = 1;
                    530:                init_bases(cc->cot,f_init);
                    531:        }
                    532:        else if (f_init)
                    533:                error(0,"unexpectedAL: not aK");
                    534: 
                    535:        PERM(returns);
                    536:        const_save = f_inline&&debug_opt==0;
                    537:        inline_restr = 0;
                    538:        body->dcl(ftbl);
                    539:        
                    540:        defined |= DEFINED;
                    541:        if (f_inline && inline_restr && returns->base!=VOID) {
                    542:                f_inline = 0;
                    543:                char* s = (inline_restr & 32) ? "continue"
                    544:                        : (inline_restr & 16) ? "break"
                    545:                        : (inline_restr & 8) ? "loop"
                    546:                        : (inline_restr & 4) ? "switch"
                    547:                        : (inline_restr & 2) ? "goto"
                    548:                        : (inline_restr & 1) ? "label"
                    549:                        : "" ;
                    550:                if (warning_opt) {
                    551:                        error('w', "\"inline\" ignored, %n contains %s",n,s);
                    552:                        error('w', "out-of-line copy of %n created",n);
                    553:                }
                    554:        //      if (cc->cot)
                    555:                n->simpl();     //BS6
                    556:                n->dcl_print(0);
                    557:        }
                    558:        const_save = const_old;
                    559: 
                    560:        if (f_inline && debug_opt==0) isf_list = new name_list(n,isf_list);
                    561: 
                    562:        bit_offset = bit_old;
                    563:        byte_offset = byte_old;
                    564:        max_align = max_old;
                    565:        cc->unstack();
                    566: 
                    567: //error('d',"fct-> returns %t",returns);
                    568: }
                    569: 
                    570: Pexpr fct::base_init(Pclass bcl, Pexpr i, Ptable ftbl, int offset)
                    571: /*
                    572:        have base class bcl and expr list i
                    573:        return "( *(base*)this ) . ctor( i )"
                    574:        ctor call generated in expr.typ()
                    575: */
                    576: {
                    577:        Ptype ty = bcl->this_type;
                    578:        Pexpr th = rptr(ty,f_this,offset);              // base*
                    579:        Pname ctor = bcl->has_ctor();
                    580: 
                    581: //error('d',"fct::B_init(C %t, i %d, %d) ctor %n",bcl,i,i?i->tp:0,ctor);
                    582: 
                    583:        Pexpr ii = (i && i->base==ELIST)?i->e1:i;
                    584: 
                    585:        if (ii
                    586:        && ii->base==DEREF
                    587:        && ii->e1->base==CAST
                    588:        && th->base==CAST) th->i2 = ii->e1->i2;
                    589: 
                    590:        if (ctor == 0) {
                    591:                if (i && i->base!=ELIST) i = new expr(ELIST,i,0);
                    592: 
                    593:                Pexpr v = new texpr(VALUE,bcl,i);       // ?.base(i)
                    594:                v->e2 = new expr(DEREF,th,0);           // (*(base*)this).base(i)
                    595:                v = v->typ(ftbl);                       // *base(&*(base*)this,i)
                    596: //error('d',"v %k",v->base);
                    597:                switch (v->base) {
                    598:                case DEREF:
                    599:                        return v->e1;                   // base(&*(base*)this,i)
                    600:                case ASSIGN:            // degenerate base(base&): *(base*)this=i
                    601:                        th = new texpr(CAST,ty,f_this);
                    602:                        v = new expr(CM,v,th);          // (*(base*)this=i,(base*)this);
                    603:                        return v->typ(ftbl);
                    604:                default:
                    605:                        return 0;
                    606:                }
                    607:        }
                    608: 
                    609: 
                    610:        Pname icn;
                    611:        if (i) {
                    612:                ii = ii->typ(ftbl);
                    613:                if (bcl->has_itor()==0
                    614:                && (icn=ii->tp->is_cl_obj())
                    615:                && (Pclass(icn->tp)==bcl || Pclass(icn->tp)->has_base(bcl))) {
                    616:                        // degenerate base(base&): *(base*)this=i
                    617:                        // memberwise copy
                    618: //error('d',"copy %t",ty);
                    619:                //      th = new cast(ty,f_this);
                    620:                //      th = th->contents();
                    621:                        th = new texpr(CAST,ty,f_this);
                    622:                        th = th->contents();
                    623:                        th = th->typ(ftbl);
                    624:                        if (Pclass(icn->tp)!=bcl) {     // cast needed
                    625:                                Pptr r = new ptr(RPTR,Pptr(ty)->typ);
                    626:                                ii = new texpr(CAST,r,ii);
                    627:                                ii = ii->typ(ftbl);
                    628:                        }
                    629:                        ii = new expr(ASSIGN,th,ii);
                    630:                        ii->tp = th->tp;
                    631:                                        // simulate `return this':
                    632:                                        // *(base*)this=i,(base*)this
                    633:                        ii = new expr(CM,ii,new cast(ty,f_this));
                    634:                        ii->tp = th->tp;
                    635:                        return ii;
                    636:                //      return ii->typ(ftbl);   // don't find cl::operator=()
                    637:                }
                    638:                if (i->base == ELIST) i->e1 = ii;
                    639:        }
                    640: //Pexpr x = call_ctor(ftbl,th,ctor,i,REF,vbase_args(this,ctor));
                    641: //error('d',"call %n %t -> %d %k",ctor,ctor->tp,x,x->base);
                    642: //     return x;
                    643:        return call_ctor(ftbl,th,ctor,i,REF,vbase_args(this,ctor));
                    644: }
                    645: 
                    646: 
                    647: Pexpr fct::mem_init(Pname mn, Pexpr i, Ptable ftbl)
                    648: /*
                    649:        return "member_ctor( m, i )"
                    650: */
                    651: {
                    652: // a new entry for B::B_pub, in general, has no tp and no
                    653: // real info: all the tp-> only work on our systems because
                    654: // 0 pointer dereference isn't system memory.  it core dumps
                    655: // in set_const since no test is made on this == 0.
                    656: //error('d',"mem_init %n",mn);
                    657: 
                    658: //     if (mn->n_stclass == STATIC) error('s',"MIr for static%n",mn);
                    659:         switch (mn->n_stclass) {
                    660:         case STATIC:
                    661:                 error("MIr for static%n",mn);
                    662:                 break;
                    663:         case ENUM:
                    664:                 error("MIr for enumeration constant%n", mn);     
                    665:                 break;
                    666:         }
                    667: 
                    668:        Pname member = (mn->base==PUBLIC && mn->n_qualifier) ? mn->n_qualifier : mn;
                    669: 
                    670:        if (i) i = i->typ(ftbl);
                    671:        Pname cn = member->tp->is_cl_obj();     // first find the class name
                    672: 
                    673: //     if (member->n_stclass == STATIC) error('s',"MIr for static%n",member);
                    674: //     if (i) i = i->typ(ftbl);
                    675: //     Pname cn = member->tp->is_cl_obj();     // first find the class name
                    676:        Pref tn = new ref(REF,f_this,member);
                    677:        tn->tp = member->tp;
                    678: //error('d',"MI for %n %t = %t",member,member->tp,i?i->tp:0);
                    679: //error('d',"fthis %d %t member %n tp %t",f_this,f_this->tp,member,tn->tp);
                    680:        if (cn) {
                    681:                Pclass mcl = Pclass(cn->tp);    // then find the classdef
                    682:                Pname ctor = mcl->has_ctor();
                    683:                Pname icn;
                    684: 
                    685:                if (i
                    686:                && mcl->has_itor()==0
                    687:                && (icn=i->tp->is_cl_obj())
                    688:                && Pclass(icn->tp)==mcl) {      // bitwise copy
                    689:                        Pexpr init = new expr(ASSIGN,tn,i);
                    690:                        init->tp = tn->tp;
                    691:                //      return init->typ(ftbl); // don't look for mcl.operator=()
                    692:                        member->assign();
                    693:                        return init;
                    694:                }
                    695:                
                    696:                if (ctor) return call_ctor(ftbl,tn,ctor,i,DOT);
                    697: 
                    698:                error("Ir forM%nW noK",member);
                    699:                return 0;
                    700:        }
                    701: 
                    702:        if (cl_obj_vec) {
                    703:                if (i && i->base == ELIST)
                    704:                        error("illegalIrL for %t%nWinM initializationL",mn->tp,mn);
                    705:                else error('s',"Ir forCM %t%nWK",mn->tp,mn);
                    706:                return 0;
                    707:        }
                    708: 
                    709:        if (i && i->base == ELIST) {
                    710:                if (i->e2) error("Ir for%n not a simpleE",member);
                    711:                i = i->e1;
                    712:        }
                    713: 
                    714:        if (member->tp->is_ref() && (i == 0)) {
                    715:                error("empty Ir for reference %n", member);
                    716:                return 0 ;
                    717:        }
                    718: 
                    719: // error( 'd', "fct_mem_init: %n %k", member, member->tp->base );
                    720:        switch (member->tp->base) {
                    721:        // case RPTR:
                    722:        //      if ( i == 0 ) {
                    723:        //              error( "empty Ir for reference %n", member );
                    724:        //              return 0;
                    725:        //      }
                    726:        //      break;
                    727:        case VEC:
                    728:        case FCT:
                    729:        case OVERLOAD:
                    730:                error("Ir for%n ofT %t",member,member->tp);
                    731:                return 0;
                    732:        }
                    733: 
                    734: //error('d',"tp %t",member->tp);
                    735:        if (member->tp->tconst()) {
                    736:                 int save_ignore_const = ignore_const;
                    737:                 ignore_const = 1;
                    738:                 i = new expr(ASSIGN,tn,i);
                    739:                 i = i->typ(ftbl);
                    740:                 ignore_const = save_ignore_const;
                    741:                 return i;
                    742:        }
                    743: 
                    744:        Pptr pt;
                    745:        if (pt = member->tp->is_ref()) {
                    746:                switch (pt->typ->base) {
                    747:                case FCT:
                    748:                case OVERLOAD:
                    749:                        i = ptr_init(pt,i,ftbl);
                    750:                        break;
                    751:                default:
                    752:                        i = ref_init(pt,i,ftbl);
                    753:                }
                    754:                i = new expr(ASSIGN,tn,i);
                    755:                i->tp = tn->tp;
                    756:                member->assign();       // cannot call typ: would cause dereference
                    757:                return i;
                    758:        }
                    759: 
                    760:        i = new expr(ASSIGN,tn,i);
                    761:        return i->typ(ftbl);    // typ performs the type check on the assignment
                    762: }
                    763: 
                    764: Pexpr replace_temp(Pexpr e, Pexpr n)
                    765: /*
                    766:        e is on the form
                    767:                                f(&temp,arg) , temp
                    768:                        or
                    769:                                &temp->ctor(arg) , temp
                    770:                        or
                    771:                                x->f(&temp,arg) , temp
                    772:        change it to
                    773:                                f(n,arg)
                    774:                        or
                    775:                                n->ctor(arg)
                    776: */
                    777: {
                    778:        Pexpr c = e->e1;        // f(&temp,arg) or &temp->ctor(args)
                    779:        Pexpr ff = c->e1;
                    780:        Pexpr a = c->e2;        // maybe ELIST(&temp,arg)
                    781:        Pexpr tmp = e->e2;
                    782: 
                    783: //error('d',"suppress(%d %k) %n",tmp->base,tmp->base,tmp->base==NAME?tmp:0);
                    784:        if (tmp->base==DEREF) tmp = tmp->e1;
                    785:        if (tmp->base==CAST) tmp = tmp->e1;
                    786:        if (tmp->base==ADDROF || tmp->base==G_ADDROF) tmp = tmp->e2;
                    787:         if (tmp->base != NAME) return e; //error('i',"replace %k",tmp->base);
                    788:        tmp->tp = any_type;     // temporary not used: suppress it
                    789: 
                    790: //error('d',"replace_temp(%k %k) c %k ff %k",e->base,n->base,c->base,ff->base);
                    791:        switch (ff->base) {
                    792:        case REF:
                    793:                if (ff->e1->base==G_ADDROF && ff->e1->e2==tmp)
                    794:                        a = ff;                         // &tmp -> f()
                    795:                break;
                    796:        case DOT:
                    797:                if (ff->e1->base==NAME && ff->e1==tmp) {
                    798:                        a = ff;                         // tmp . f()
                    799:                        a->base = REF;
                    800:                }
                    801:                break;
                    802:        }
                    803:        a->e1 = n;
                    804:        return c;
                    805: }
                    806: 
                    807: Pname classdef::has_ictor()
                    808: /*
                    809:        does this class have a constructor taking no arguments?
                    810: */
                    811: {
                    812:        Pname c = has_ctor();
                    813:        if (c == 0) return 0;
                    814:        
                    815:        Pfct f = Pfct(c->tp);
                    816: 
                    817:        switch (f->base) {
                    818:        default:
                    819:                error('i',"%s: badK (%k)",string,c->tp->base);
                    820:        
                    821:        case FCT:
                    822:                switch (f->nargs) {
                    823:                case 0:         return c;
                    824:                default:        if (f->argtype->n_initializer) return c;
                    825:                }
                    826:                return 0;
                    827: 
                    828:        case OVERLOAD:
                    829:        {       for (Plist l=Pgen(f)->fct_list; l; l=l->l) {
                    830:                        Pname n = l->f;
                    831:                        f = (Pfct)n->tp;
                    832:                        switch (f->nargs) {
                    833:                        case 0:         return n;
                    834:                        default:        if (f->argtype->n_initializer) return n;
                    835:                        }
                    836:                }
                    837:                return 0;
                    838:        }
                    839:        }
                    840: }
                    841: 
                    842: int add_first; // fudge, use ctor arg instead
                    843: Pname gen::add(Pname n)
                    844: /*
                    845:        add "n" to the tail of "fct_list"
                    846:        (overloaded names are searched in declaration order)
                    847: 
                    848:        detect:         multiple identical declarations
                    849:                        declaration after use
                    850:                        multiple definitions
                    851: */
                    852: {
                    853:        Pfct f = Pfct(n->tp);
                    854:        Pname nx;
                    855: //error('d',"add(%n) %d",n,add_first);
                    856:        if (f->base != FCT) error("%n: overloaded nonF",n);
                    857: 
                    858:        if ( fct_list && (nx=find(f,1)) ) {
                    859: //error('d',"found %n %t",nx,nx->tp);
                    860:                Linkage l1 = Pfct(nx->tp)->f_linkage;
                    861:                Linkage l2 = f->f_linkage;
                    862:                if ( l2 != linkage_default && l1 != l2 )
                    863:                        error("inconsistent linkage specifications for%n",n);
                    864:                Nold = 1;
                    865:        }
                    866:        else {
                    867:                if (add_first==0 && f->f_signature==0) f->sign();
                    868: //error('d',"signature: %d \"%s\" fct_list %d",f->f_signature,f->f_signature,fct_list);
                    869:                nx = new name;
                    870:                *nx = *n;
                    871:                // nx->n_tbl_list = Pname(n->string);
                    872:                 nx->n_gen_fct_name = n->string;
                    873:                PERM(nx);
                    874:                Nold = 0;
                    875:                if (fct_list) {
                    876:                        int clink = (f->f_linkage==linkage_C);
                    877:                        Plist gl=fct_list;
                    878:                        for(;;) {
                    879:                                if (clink
                    880:                                && Pfct(gl->f->tp)->f_linkage == linkage_C ) {
                    881:                                        error("two%ns with c linkage",n);
                    882:                                        if(f->f_signature==0) f->sign();
                    883:                                }
                    884:                                if (gl->l)
                    885:                                        gl = gl->l;
                    886:                                else
                    887:                                        break;
                    888:                        }
                    889:                        gl->l = new name_list(nx,0); 
                    890:                }
                    891:                else
                    892:                        fct_list = new name_list(nx,0);
                    893:                nx->n_list = 0;
                    894:        }
                    895:        return nx;
                    896: }
                    897: 
                    898: void fct::sign()
                    899: {
                    900:        switch ( f_linkage ) {
                    901:        case linkage_C:
                    902:                f_signature = "";
                    903:                return;
                    904:        case linkage_Cplusplus:
                    905:        case linkage_default:
                    906:                break;
                    907:        }
                    908:        char buf[1024];
                    909:        char* bb = signature(buf);
                    910:        int ll = bb-buf;
                    911:        if (1023 < ll) error('i',"gen::add():N buffer overflow");
                    912:        char* p = new char[ll+1];
                    913:        strcpy(p,buf);
                    914:        f_signature = p;
                    915: //error('d',"fct::sign %s",p);
                    916: }
                    917: 
                    918: Pname gen::find(Pfct f, bit warn)
                    919: {      
                    920:        for (Plist gl=fct_list; gl; gl=gl->l) {
                    921:                Pname n = match(gl->f,f,warn);
                    922:                if (n) return n;
                    923:        }
                    924:        return 0;
                    925: }
                    926: 
                    927: Pname gen::match(Pname nx, Pfct f, bit warn)
                    928: {
                    929:        Pfct fx = Pfct(nx->tp);
                    930:        Pname a, ax;
                    931:        int op = 0;     // overloading problem: const, ref, vec/ptr, or basetype
                    932: //error('d',"fx %d %d f %d %d",fx->nargs_known,fx->nargs,f->nargs_known,f->nargs);
                    933: 
                    934:        if (f->nargs_known != fx->nargs_known) return 0; // the bets are off
                    935:                                                         // must rely on checks at
                    936:                                                         // call points
                    937:        if (f->f_const != fx->f_const) return 0;
                    938: 
                    939:        if (fx->nargs != f->nargs
                    940:        && fx->nargs_known==1
                    941:        && f->nargs_known==1) return 0; // no warning for potential
                    942:                                        // problems due to default args
                    943:        
                    944:        for (ax=fx->argtype, a=f->argtype; a&&ax; ax=ax->n_list, a=a->n_list) {
                    945:                Ptype at = ax->tp;
                    946:                Ptype atp = a->tp;
                    947: //error('d',"at %t atp %t",at,atp);
                    948:                if (at->check(atp,OVERLOAD) == 0) {
                    949: //error('d',"at %t atp %t cp %d vrp %d",at,atp,const_problem,vrp_equiv);
                    950:                        continue;
                    951:                }
                    952: //error('d',"warn %d",warn);
                    953:                if (warn == 0) goto xx;
                    954: 
                    955:                /*
                    956:                        warn against:
                    957:                                overload f(X&), f(X);           error
                    958:                                overload f(int), f(const);      error
                    959:                                overload f(int*), f(int[10]);   warn
                    960:                        etc.
                    961:                */
                    962: 
                    963: //error('d',"vrp_equiv %d const_problem %d",vrp_equiv,const_problem);
                    964:                if (const_problem) {    // differ only in X vs const X
                    965:                        if (at->is_ptr_or_ref()) return 0;
                    966:                        op++;
                    967:                        continue;
                    968:                }
                    969: 
                    970:        aaa:
                    971:                switch (atp->base) {
                    972:                case TYPE:
                    973:                        atp = Pbase(atp)->b_name->tp;
                    974:                        goto aaa;
                    975:        //      case EOBJ:
                    976:        //              atp = Penum(Pbase(atp)->b_name->tp)->e_type;
                    977:        //              goto aaa;
                    978:                case RPTR:      // differ only by X vs X& ?
                    979:                        if (Pptr(atp)->typ->check(at,0)==0) {
                    980:                                op++;
                    981:                                continue;
                    982:                        }
                    983:                }
                    984: 
                    985:        atl:
                    986:                switch (at->base) {
                    987:                case TYPE:
                    988:                        at = Pbase(at)->b_name->tp;
                    989:                        goto atl;
                    990:        //      case EOBJ:
                    991:        //              at = Penum(Pbase(at)->b_name->tp)->e_type;
                    992:        //              goto atl;
                    993:                case RPTR:      // differ only by X& vs X ?
                    994:                        if (Pptr(at)->typ->check(atp,0)==0) {
                    995:                                op++;
                    996:                                continue;
                    997:                        }
                    998:                        break;
                    999:        //      case CHAR:      // differ only by int vs char ?
                   1000:        //      case SHORT:
                   1001:        //      case INT:
                   1002:                //      if (atp->base!=at->base && atp->base==EOBJ) {
                   1003:                //              op++;
                   1004:                //              continue;
                   1005:                //      }
                   1006:        //              break;
                   1007:                }
                   1008: //error('d',"return 0");
                   1009:                //goto xx;
                   1010:                // some argument is really different
                   1011:                // e.g. f(int), f(char*);
                   1012:                return 0;
                   1013:        }
                   1014: 
                   1015:        // arguments checked. Now look at leftover args, return type,etc.
                   1016: 
                   1017: //     if (warn && a && fx->nargs_known==ELLIPSIS) error('w',"... in%n'sAT hidesATs from the overloading mechanism",nx);
                   1018: 
                   1019:        if (a || ax) return 0;
                   1020: 
                   1021:        if (op == 0) {
                   1022:                if (warn && fx->returns->check(f->returns,0))
                   1023:                        error("two different return valueTs for%n: %t and %t",nx,fx->returns,f->returns);
                   1024: 
                   1025:                return nx;
                   1026:        }
                   1027: xx:
                   1028:        if (warn && op)
                   1029:                error("the overloading mechanism cannot tell a%t from a%t",fx,f);
                   1030: 
                   1031:        return 0;
                   1032: }
                   1033: 
                   1034: int name::no_of_names()
                   1035: {
                   1036:        register int i = 0;
                   1037:        register Pname n;
                   1038:        for (n=this; n; n=n->n_list) i++;
                   1039:        return i;
                   1040: }
                   1041: 
                   1042: static Pexpr lvec[20], *lll, *curr_e;
                   1043: static Pexpr last_il = 0;
                   1044: static Pexpr list_back = 0;
                   1045: static Pexpr last_el = 0, *last_lll;
                   1046: 
                   1047: void new_list(Pexpr lx)
                   1048: {
                   1049:        if (lx->base != ILIST) error('i',"IrLX");
                   1050: 
                   1051:        lll = last_lll = lvec;
                   1052:        lll++;
                   1053:        *lll = last_el = lx->e1;
                   1054: }
                   1055: 
                   1056: Pexpr next_elem()
                   1057: {
                   1058:        Pexpr e;
                   1059:        Pexpr lx;
                   1060: 
                   1061:        if (lll == lvec) return 0;
                   1062: 
                   1063:        lx = *lll;
                   1064: 
                   1065:        if (list_back) {
                   1066:                e = list_back;
                   1067:                list_back = 0;
                   1068:                return e;
                   1069:        }
                   1070: 
                   1071:        if (lx == 0) {                          /* end of list */
                   1072:                lll--;
                   1073:                return 0;
                   1074:        }
                   1075: 
                   1076:        switch (lx->base) {
                   1077:        case ELIST:
                   1078:                e = lx->e1;
                   1079:                curr_e = &lx->e1;
                   1080:                last_el = lx;
                   1081:                last_lll = lll;
                   1082:                *lll = lx->e2;
                   1083:                switch (e->base) {
                   1084:                case ILIST:
                   1085:                        lll++;
                   1086:                        *lll = e->e1;
                   1087:                        last_il = e;
                   1088:                        return Pexpr(1);        // start of new ILIST
                   1089:                case ELIST:
                   1090:                        error("nestedEL");
                   1091:                        return 0;
                   1092:                default:
                   1093:                {
                   1094:                        if (need_sti(e)) error('s',"generalIr inIrL");
                   1095:                        return e;
                   1096:                }
                   1097:                }
                   1098:        case IVAL:
                   1099:        case ZERO:
                   1100:                lll--;
                   1101:                return 0;
                   1102:        default:
                   1103:                error('i',"IrL %k",lx->base);
                   1104:        }
                   1105: }
                   1106: 
                   1107: static Pexpr insert_init(Pexpr newval) {
                   1108: // splice an initializer in front of the next element in the
                   1109: // initializer list.  Provides initializers for unnamed bitfields.
                   1110:        Pexpr t = new expr(ELIST,last_el->e1,last_el->e2);
                   1111: 
                   1112:        last_el->e1=newval;
                   1113:        last_el->e2=t;
                   1114:        lll = last_lll;
                   1115:        *lll = last_el;
                   1116:        return next_elem();
                   1117: }
                   1118: 
                   1119: void skip_ilist()
                   1120: // skip ilist use to represent pointer to member function literal
                   1121: {
                   1122:        Pexpr e = next_elem();
                   1123:        e = next_elem();
                   1124: }
                   1125: 
                   1126: void list_check(Pname nn, Ptype t, Pexpr il, Ptable tbl)
                   1127: /*
                   1128:        see if the list "lll" can be assigned to something of type "t"
                   1129:        "nn" is the name of the variable for which the assignment is taking place.
                   1130:        "il" is the last list element returned by next_elem()
                   1131: */
                   1132: {
                   1133:        Pexpr e;
                   1134:        bit lst = 0;
                   1135:        int i;
                   1136:        Pclass cl;
                   1137:        int tdef = 0;
                   1138: 
                   1139: //error('d',"list_check%n: %t (%d)",nn,t,il);
                   1140:        if (il == Pexpr(1)) {
                   1141:                lst = 1;
                   1142:                e = il;
                   1143:        }
                   1144:        else if (il)
                   1145:                list_back = il;
                   1146: 
                   1147: zzz:
                   1148:        switch (t->base) {
                   1149:        case TYPE:
                   1150:                t = Pbase(t)->b_name->tp;
                   1151:                tdef = 1;
                   1152: 
                   1153:                // did it used to be a VEC before arg_fudge was applied?
                   1154:                 if (t->base==PTR && Pvec(t)->size)
                   1155:                         t->base=VEC;
                   1156:                 goto zzz;
                   1157: 
                   1158:        case VEC:
                   1159:        {       Pvec v = Pvec(t);
                   1160:                Ptype vt = v->typ;
                   1161: 
                   1162:                if (v->size) {  /* get at most v->size initializers */
                   1163:                        if (v->typ->base == CHAR) {
                   1164:                                e = next_elem();
                   1165:                                if (e->base == STRING) {        // v[size] = "..."
                   1166:                                        int isz = Pvec(e->tp)->size;
                   1167:                                        if (v->size < isz) error("Ir too long (%d characters) for%n[%d]",isz,nn,v->size);
                   1168:                                        break;
                   1169:                                }
                   1170:                                else
                   1171:                                        list_back = e;
                   1172:                        }
                   1173:                        for (i=0; i<v->size; i++) { // check next list element type
                   1174:                                Pfct MP = 0;
                   1175:                        ee:
                   1176:                                e = next_elem();
                   1177:                                if (e == 0) goto xsw; // too few initializers are ok
                   1178:                        vtz:
                   1179: //error('d',"vtz: %d",vt->base);
                   1180:                                switch (vt->base) {
                   1181:                                case TYPE:
                   1182:                                        vt = Pbase(vt)->b_name->tp;
                   1183:                                        goto vtz;
                   1184:                                case VEC:
                   1185:                                case COBJ:
                   1186:                                        list_check(nn,vt,e);
                   1187:                                        break;
                   1188:                                case PTR:
                   1189:                                        if ((MP = vt->memptr()) &&
                   1190:                                            e==Pexpr(1)) {
                   1191:                                                if (vt->check(last_il->tp,ASSIGN))
                   1192:                                                        error("badIrT for%n:%t (%tX)",v,last_il->tp,vt);
                   1193:                                                skip_ilist();
                   1194:                                                break;
                   1195:                                        }
                   1196:                                        if (MP && e && e->base==ZERO) {
                   1197:                                                *curr_e = new expr(ELIST,zero,zero);
                   1198:                                                *curr_e = new expr(ILIST,*curr_e,zero);
                   1199:                                                (*curr_e)->tp = zero_type;
                   1200:                                                break;
                   1201:                                        }
                   1202:                                        if (MP && e && e->tp->base==OVERLOAD) {
                   1203:                                                Pexpr op = ptof(Pfct(Pptr(vt)->typ),e,tbl);
                   1204:                                                if(op) {
                   1205:                                                        *curr_e = op;
                   1206:                                                        break;
                   1207:                                                }
                   1208:                                        }
                   1209:                                        // no break
                   1210:                                default:
                   1211:                                {
                   1212:                                        if (e == (Pexpr)1) {
                   1213:                                                error("unexpectedIrL");
                   1214:                                                goto ee;
                   1215:                                        }
                   1216: 
                   1217:                                        if (vt->check(e->tp,ASSIGN))
                   1218:                                                error("badIrT for%n:%t (%tX)",nn,e->tp,vt);
                   1219: 
                   1220:                                        Pptr p;
                   1221:                                        if (vt->check(e->tp,0)
                   1222:                                        && (p=vt->is_ptr())
                   1223:                                        && Ptype(p)!=zero_type
                   1224:                                        && p->typ!=char_type) {
                   1225:                                                Pexpr te = e;
                   1226:                                                Ptype t = p->typ;
                   1227:                                                while ( t->base == TYPE ) t = Pbase(t)->b_name->tp;
                   1228:                                                if ( t->base == COBJ )
                   1229:                                                        te = ptr_init( p, e, tbl );
                   1230:                                                if ( te == e )
                   1231:                                                        *curr_e = new cast(vt,e);
                   1232:                                                else *curr_e = te;
                   1233:                                        }
                   1234:                                }
                   1235:                                }
                   1236:                        }
                   1237:                        if ( lst && (e=next_elem()) ) error("end ofIrLX after array");
                   1238:                xsw:;
                   1239:                }
                   1240:                else {          /* determine v->size */
                   1241:                        i = 0;
                   1242:                        (void) v->typ->tsizeof();
                   1243:                xx:
                   1244:                        while ( e=next_elem() ) {       // get another initializer
                   1245:                                Pfct MP = 0;
                   1246:                                i++;
                   1247:                        vtzz:
                   1248: //error('d',"vtzz");
                   1249:                                switch (vt->base) {
                   1250:                                case TYPE:
                   1251:                                        vt = Pbase(vt)->b_name->tp;
                   1252:                                        goto vtzz;
                   1253:                                case VEC:
                   1254:                                case COBJ:
                   1255:                                        list_check(nn,vt,e);
                   1256:                                        break;
                   1257:                                case PTR:
                   1258:                                        if((MP = vt->memptr()) &&
                   1259:                                            e==Pexpr(1)) {
                   1260:                                                if (vt->check(last_il->tp,ASSIGN))
                   1261:                                                        error("badIrT for%n:%t (%tX)",v,last_il->tp,vt);
                   1262:                                                skip_ilist();
                   1263:                                                break;
                   1264:                                        }
                   1265:                                        if (MP && e && e->base==ZERO) {
                   1266:                                                *curr_e = new expr(ELIST,zero,zero);
                   1267:                                                *curr_e = new expr(ILIST,*curr_e,zero);
                   1268:                                                (*curr_e)->tp = zero_type;
                   1269:                                                break;
                   1270:                                        }
                   1271:                                        if (MP && e && e->tp->base==OVERLOAD) {
                   1272:                                                Pexpr op = ptof(Pfct(Pptr(vt)->typ),e,tbl);
                   1273:                                                if(op) {
                   1274:                                                        *curr_e = op;
                   1275:                                                        break;
                   1276:                                                }
                   1277:                                        }
                   1278:                                        // no break
                   1279:                                default:
                   1280:                                {       if (e == Pexpr(1)) {
                   1281:                                                error("unexpectedIrL");
                   1282:                                                goto xx;
                   1283:                                        }
                   1284: 
                   1285:                                        if (vt->check(e->tp,ASSIGN))
                   1286:                                                error("badIrT for%n:%t (%tX)",nn,e->tp,vt);
                   1287: 
                   1288:                                        Pptr p;
                   1289:                                        if (vt->check(e->tp,0)
                   1290:                                        && (p=vt->is_ptr())
                   1291:                                        && Ptype(p)!=zero_type
                   1292:                                        && p->typ!=char_type) {
                   1293:                                                Pexpr te = e;
                   1294:                                                Ptype t = p->typ;
                   1295:                                                while ( t->base == TYPE ) t = Pbase(t)->b_name->tp;
                   1296:                                                if ( t->base == COBJ )
                   1297:                                                        te = ptr_init( p, e, tbl );
                   1298:                                                if ( te == e )
                   1299:                                                        *curr_e = new cast(vt,e);
                   1300:                                                else *curr_e = te;
                   1301:                                        }
                   1302:                                }
                   1303:                                }
                   1304:                        }
                   1305:                        if (tdef==0) v->size = i;
                   1306:                }
                   1307:                break;
                   1308:        }
                   1309: 
                   1310:        case CLASS:
                   1311:                cl = Pclass(t);
                   1312:                goto ccc;
                   1313: 
                   1314:        case COBJ:      /* initialize members */
                   1315:                cl = Pclass(Pbase(t)->b_name->tp);
                   1316:        ccc:
                   1317:                if (cl->defined == 0) {
                   1318:                        lll = lvec;     // we are lost: ignore rest of list
                   1319:                        return;
                   1320:                }
                   1321: 
                   1322:                if (cl->c_body == 1) cl->dcl_print(0);
                   1323: 
                   1324:        {       Ptable tbl = cl->memtbl;
                   1325:                Pname m;
                   1326: 
                   1327:                if (cl->baselist) {
                   1328:                        if (cl->baselist->next) error("IrL forO ofC with multipleBCs");
                   1329:                        list_check(nn,cl->baselist->bclass,0);
                   1330:                }
                   1331: 
                   1332:                for (m=tbl->get_mem(i=1); m; m=tbl->get_mem(++i)) {
                   1333:                        Ptype mt = m->tp;
                   1334:                        Pfct MP = 0;
                   1335:                        switch (mt->base) {
                   1336:                        case FCT:
                   1337:                        case OVERLOAD:
                   1338:                        case CLASS:
                   1339:                        case ENUM:
                   1340:                                continue;
                   1341:                        }
                   1342:                        if (m->n_stclass == STATIC ||
                   1343:                                m->n_stclass == ENUM ) continue;
                   1344:                        /* check assignment to next member */
                   1345:                dd:
                   1346:                        while (mt->base == TYPE)
                   1347:                                mt = Pbase(mt)->b_name->tp;
                   1348: 
                   1349:                        if ((MP = mt->memptr()) &&
                   1350:                            e==Pexpr(1) &&
                   1351:                                last_il->tp->base == PTR) {
                   1352:                                if(i==1) lst=0;
                   1353:                        }
                   1354:                        else e = next_elem();
                   1355: 
                   1356:                        if (e == 0) return; //break;
                   1357: 
                   1358:                        if(
                   1359:                                mt->base == FIELD
                   1360:                                        &&
                   1361:                                m->string[0]=='_'
                   1362:                                        &&
                   1363:                                m->string[1]=='_'
                   1364:                                        &&
                   1365:                                m->string[2]=='F'       // unnamed bitfield
                   1366:                        ) {
                   1367:                                e = insert_init(zero);
                   1368:                        }
                   1369: 
                   1370: //error('d',"mtz%n: %d",m,mt->base);
                   1371:                        switch (mt->base) {
                   1372:                        case CLASS:
                   1373:                        case ENUM:
                   1374:                                break;
                   1375:                        case VEC:
                   1376:                        case COBJ:
                   1377:                                list_check(nn,m->tp,e);
                   1378:                                break;
                   1379:                        case PTR:
                   1380:                                if (MP && e==Pexpr(1)) {
                   1381:                                        if (mt->check(last_il->tp,ASSIGN))
                   1382:                                                error("badIrT for%n:%t (%tX)",m,last_il->tp,mt);
                   1383:                                        skip_ilist();
                   1384:                                        break;
                   1385:                                }
                   1386:                                if (MP && e && e->base==ZERO) {
                   1387:                                        *curr_e = new expr(ELIST,zero,zero);
                   1388:                                        *curr_e = new expr(ILIST,*curr_e,zero);
                   1389:                                        (*curr_e)->tp = zero_type;
                   1390:                                        break;
                   1391:                                }
                   1392:                                if (MP && e && e->tp->base==OVERLOAD) {
                   1393:                                        Pexpr op = ptof(Pfct(Pptr(mt)->typ),e,tbl);
                   1394:                                        if(op) {
                   1395:                                                *curr_e = op;
                   1396:                                                break;
                   1397:                                        }
                   1398:                                }
                   1399:                                // no break
                   1400:                        default:
                   1401:                        {       if (e == Pexpr(1)) {
                   1402:                                        error("unexpectedIrL");
                   1403:                                        goto dd;
                   1404:                                }
                   1405: 
                   1406:                                if (mt->check(e->tp,ASSIGN))
                   1407:                                        error("badIrT for%n:%t (%tX)",m,e->tp,m->tp);
                   1408: 
                   1409:                                if(MP && e && e->base==CAST)
                   1410:                                        *curr_e = e->e1;
                   1411: 
                   1412:                                Pptr p;
                   1413:                                if (mt->check(e->tp,0)
                   1414:                                && (p=mt->is_ptr())
                   1415:                                && Ptype(p)!=zero_type
                   1416:                                && p->typ!=char_type)
                   1417:                                        *curr_e = new cast(mt,e);
                   1418:                        }
                   1419:                        }
                   1420:                }
                   1421:                if (lst && (e=next_elem()) ) error("end ofIrLX afterCO");
                   1422:                break;
                   1423:        }
                   1424:        default:
                   1425:                e = next_elem();
                   1426: 
                   1427:                if (e == 0) {
                   1428:                        error("noIr forO");
                   1429:                        break;
                   1430:                }
                   1431:                
                   1432:                if (e == Pexpr(1)) {
                   1433:                        error("unexpectedIrL");
                   1434:                        break;
                   1435:                }
                   1436: //error('d',"t %t e->tp %t",t,e->tp);
                   1437:                if (t->check(e->tp,ASSIGN)) error("badIrT for%n:%t (%tX)",nn,e->tp,t);
                   1438:                Pptr p;
                   1439:                if (t->check(e->tp,0)
                   1440:                && (p=t->is_ptr())
                   1441:                && Ptype(p)!=zero_type
                   1442:                && p->typ!=char_type)
                   1443:                        *curr_e = new cast(t,e);
                   1444:                if (lst && (e=next_elem()) ) error("end ofIrLX afterO");
                   1445:                break;
                   1446:        }
                   1447: }
                   1448: 
                   1449: int
                   1450: is_anon(char* string) {
                   1451: // error('d',"is_anon: %s", string );
                   1452:        if ( string == 0 )
                   1453:                return 0;
                   1454: 
                   1455:        if ( string[0]=='_' && string[1]=='_' &&
                   1456:                (string[2]=='C' || string[2]=='E')) 
                   1457:                        return 1;
                   1458:        return 0;
                   1459: }
                   1460: 
                   1461: Pname dclass(Pname n, Ptable tbl)
                   1462: {      
                   1463:        Pclass cl;
                   1464:        Pbase bt;
                   1465:        Pname bn;
                   1466:        Pname ntbl = tbl->t_name;
                   1467:        Ptype ntp = 0; 
                   1468:        TOK tscope;
                   1469: 
                   1470:        Pname nx = ktbl->look(n->string,0);             // TNAME
                   1471:        if (ntbl && ntbl->tp) ntp = ntbl->tp;
                   1472: 
                   1473:        tscope = ntp&&ntp->base==CLASS?NESTED:(n->lex_level?LOCAL:HIDDEN);
                   1474: 
                   1475:        DB( if(Ddebug>=1) error( 'd', &n->where, "dclass n %n %d nx %d", n,n->lex_level, nx); );
                   1476: // error( 'd', &n->where, "dclass n %n ll %d nx %d tbl: %n", n,n->lex_level, nx, tbl->t_name); 
                   1477:        if (nx == 0 || n->lex_level || 
                   1478:                ntp && is_anon(n->string) == 0 && ntp->base == CLASS 
                   1479:                && (ktbl->look(n->string,tscope))) 
                   1480:        {
                   1481:                if ( nx && ntp && ntp->base == CLASS ) { 
                   1482:                        bt = (Pbase)nx->tp;
                   1483:                        bn = bt->b_name;
                   1484:                        cl = bn ? (Pclass)bn->tp : 0;
                   1485:                        if (cl && cl->lcl && 
                   1486:                                strcmp(cl->lcl,"FUDGE007")==0)
                   1487:                                        goto bbb;
                   1488:                        else { bt=0; bn=0; cl=0; }
                   1489:                }
                   1490: 
                   1491:                int tn = 0;
                   1492:                for (nx=ktbl->look(n->string,tscope); nx; nx=nx->n_tbl_list) 
                   1493:                {
                   1494:                        if (nx->n_key != tscope) continue;
                   1495:                        if (tscope==LOCAL && 
                   1496:                                nx->lex_level != n->lex_level ) continue;
                   1497: 
                   1498:                        if (nx->tp->base != COBJ) {
                   1499:                                tn = 1;
                   1500:                                continue;
                   1501:                        }
                   1502: 
                   1503:                        bt = (Pbase)nx->tp;
                   1504:                        bn = bt->b_name;
                   1505:                        cl = (Pclass)bn->tp;
                   1506: 
                   1507:                        if (cl == 0) continue;
                   1508: 
                   1509:                        // is this class nested within class table?
                   1510:                        if (tscope==NESTED && 
                   1511:                                strcmp(ntbl->string,cl->in_class->string))
                   1512:                                        continue;
                   1513:                        else
                   1514:                        if ( tscope==LOCAL && 
                   1515:                                (cl->lcl==0 || strcmp(cl->lcl,Pclass(n->tp)->lcl))) 
                   1516:                                        continue;
                   1517: 
                   1518:                        goto bbb;
                   1519:                }
                   1520: 
                   1521:                if (tn)
                   1522:                        error("%n redefined using Tdef",n);
                   1523:                else
                   1524:                        error('i',"%n is not aCN",n);
                   1525:        }
                   1526:        else {
                   1527:                bt = Pbase(nx->tp);                     // COBJ
                   1528:                 if ( bt->base != COBJ ) {
                   1529:                         error("%n redefined using typedef",n);
                   1530:                         Pname tn = ktbl->look(n->string,HIDDEN); 
                   1531:                         if ( tn->tp->base == COBJ )  
                   1532:                                 bt = Pbase(tn->tp);
                   1533:                         else error('i',"%n is not a CN", n );
                   1534:                 }
                   1535:                bn = bt->b_name;
                   1536:        }
                   1537: bbb:
                   1538:        bn->where = nx->where;
                   1539:        Pname bnn = tbl->insert(bn,CLASS);              // copy for member lookup
                   1540:        cl = Pclass(bn->tp);
                   1541: 
                   1542:        if (cl->class_base == template_class)
                   1543:                error("C%n defined previously asYC", bn);
                   1544:                                                        
                   1545:        if (cl->defined&(DEFINED|SIMPLIFIED))
                   1546:                error("C%n defined twice",n);
                   1547:        else {
                   1548:                if (bn->n_scope == ARG) bn->n_scope = ARGT;
                   1549:                cl->dcl(bn,tbl);
                   1550:        }
                   1551:        n->tp = cl;
                   1552:        return bnn;
                   1553: }
                   1554: 
                   1555: Pname denum(Pname n, Ptable tbl)
                   1556: {
                   1557:        Penum en;
                   1558:        Pbase bt;
                   1559:        Pname bn;
                   1560:        Pname ntbl = tbl->t_name;
                   1561:        Ptype ntp = 0; 
                   1562:        TOK tscope;
                   1563: 
                   1564:        Pname nx = ktbl->look(n->string,0);             // TNAME
                   1565:        if (ntbl && ntbl->tp) ntp = ntbl->tp;
                   1566: 
                   1567: // note: ***** add for local enumeration declaration
                   1568: // error( 'd', &n->where, "denum n %n ll %d nx %d tbl: %n", n,n->lex_level, nx, tbl->t_name); 
                   1569:        if (nx == 0 || /* n->lex_level ||*/ 
                   1570:                ntp && is_anon(n->string)==0 && ntp->base == CLASS ) 
                   1571:        {
                   1572:                int tn = 0;
                   1573:                tscope = ntp&&ntp->base==CLASS?NESTED:(/*n->lex_level?LOCAL:*/HIDDEN);
                   1574:                for (nx=ktbl->look(n->string,tscope); nx; nx=nx->n_tbl_list) 
                   1575:                {
                   1576:                        if (nx->n_key != tscope) continue;
                   1577: //                     if (tscope==LOCAL && 
                   1578: //                             nx->lex_level != n->lex_level ) continue;
                   1579: 
                   1580:                        bt = (Pbase)nx->tp;
                   1581:                        bn = bt->b_name;
                   1582:                        en = (Penum)bn->tp;
                   1583: 
                   1584:                        // is this class nested within class table?
                   1585:                        if (tscope==NESTED && en->in_class &&
                   1586:                                strcmp(ntbl->string,en->in_class->string))
                   1587:                                        continue;
                   1588:                }
                   1589:        }
                   1590:        else {
                   1591:                        bt = (Pbase)nx->tp;
                   1592:                        bn = bt->b_name;
                   1593:                        en = (Penum)bn->tp;
                   1594:        }
                   1595: 
                   1596:        Pname bnn = tbl->insert(bn,CLASS);
                   1597:        if (en->defined&(DEFINED|SIMPLIFIED))
                   1598:                error("enum%n defined twice",n);
                   1599:        else {
                   1600:                if (bn->n_scope == ARG) bn->n_scope = ARGT;
                   1601:                en->dcl(bn,tbl);
                   1602:        }
                   1603:        n->tp = en;
                   1604:        return bnn;
                   1605: }
                   1606: 
                   1607: static int
                   1608: is_probably_temp( char *str ) 
                   1609: {
                   1610: // error( 'd', "is_probably_temp( %s )", str );
                   1611: 
                   1612:        if ( str[0] != '_' || str[1] != '_' )
                   1613:                return 0;
                   1614: 
                   1615:        switch (str[2]) {
                   1616:                default:
                   1617:                        return 0;
                   1618:                case 'A': case 'C': case 'D': case 'E': case 'F': 
                   1619:                case 'I': case 'K': case 'L': case 'M': case 'N': 
                   1620:                case 'Q': case 'R': case 'S': case 'T': case 'U': 
                   1621:                case 'V': case 'W': case 'X':
                   1622:                        return 1;
                   1623:        }
                   1624: 
                   1625: }
                   1626: 
                   1627: static void
                   1628: check_for_local( Pexpr ee )
                   1629: {
                   1630:        static Pname n[2] = {0,0}; // try not to flag multiple errors 
                   1631:        static index = 0;
                   1632: 
                   1633:        if ( ee==0 ) return; 
                   1634: 
                   1635: // error('d', "check_for_local( %k ) e1: %d e2: %d", ee->base, ee->e1, ee->e2);
                   1636: 
                   1637:        switch ( ee->base ) {
                   1638:                case NAME:  
                   1639:                {
                   1640:                        Pname nn = Pname(ee);
                   1641:                        if ((nn->n_scope==FCT || nn->n_scope==ARG) 
                   1642:                            && is_probably_temp(nn->string) == 0  
                   1643:                            && n[0]!=nn && n[1]!=nn) 
                   1644:                        {
                   1645:                                error("local%n used as defaultA", nn );
                   1646:                                n[index] = nn;
                   1647:                                index = index==0?1:0;
                   1648:                        }       
                   1649:                        // no break;
                   1650:                }
                   1651:                case TNAME: case STRING: case IVAL:
                   1652:                case ICON: case CCON: case FCON:
                   1653:                case ZERO: case DUMMY: case SIZEOF:
                   1654:                        return;
                   1655:                case QUEST:
                   1656:                        check_for_local( ee->cond );
                   1657:                        break;
                   1658:                case MDOT:
                   1659:                        check_for_local( ee->mem );
                   1660:                        return;
                   1661:        }
                   1662: 
                   1663:        check_for_local( ee->e1 );
                   1664:        check_for_local( ee->e2 );
                   1665: }
                   1666: 
                   1667: void dargs(Pname, Pfct f, Ptable tbl)
                   1668: {
                   1669:        int argnamesize = 0; // if +a1, make sure arg names can be printed
                   1670:        int oo = const_save;
                   1671:        const_save = 1;
                   1672:        if ( ansi_opt ) {
                   1673:            Pname th = f->f_this;
                   1674:            if ( th && th->string ) argnamesize += strlen(th->string) + 1;
                   1675:            th = f->f_result;
                   1676:            if ( th && th->string ) argnamesize += strlen(th->string) + 1;
                   1677:        }
                   1678: 
                   1679:        for (Pname a=f->argtype; a; a=a->n_list) {
                   1680:                Pexpr init;
                   1681: 
                   1682:                if (a->tp == 0) {
                   1683:                        error( "A has noT" );
                   1684:                        a->tp = any_type;
                   1685:                        continue;
                   1686:                }
                   1687:                if (ansi_opt && a->string) argnamesize += strlen(a->string) + 1;
                   1688: 
                   1689:                Pname cln = a->tp->is_cl_obj();
                   1690: //error('d',"dargs %t",a->tp);
                   1691:                if (cln && Pclass(cln->tp)->has_itor()) // mark X(X&) arguments
                   1692:                        a->n_xref = 1;
                   1693:                else {
                   1694:                        Ptype t = a->tp;
                   1695:                        while (t->base == TYPE) t = Pbase(t)->b_name->tp;
                   1696:                        if (t->base == FCT) a->tp = new ptr(PTR,a->tp);
                   1697:                }
                   1698: 
                   1699: //             if (init = a->n_initializer) {  // default argument
                   1700:                 if ( a->n_key != NESTED &&
                   1701:                     (init = a->n_initializer)) { // default argument
                   1702:                        Pptr pt;
                   1703:                        if (init == dummy) {
                   1704:                                error("emptyIr");
                   1705:                                a->n_initializer = 0;
                   1706:                                continue;
                   1707:                        }
                   1708:                        if (cln) {
                   1709:                                if (init->base==VALUE) {
                   1710:                                        switch (init->tp2->base) {
                   1711:                                        case CLASS:
                   1712:                                                if (Pclass(init->tp2)!=Pclass(cln->tp)) goto inin2;
                   1713:                                                break;
                   1714:                                        default:
                   1715:                                                Pname n2 = init->tp2->is_cl_obj();
                   1716:                                                if (n2==0 || Pclass(n2->tp)!=Pclass(cln->tp)) goto inin2;
                   1717:                                        }
                   1718: 
                   1719:                                        a->n_initializer = init = 0;
                   1720:                                        error('s',"K as defaultA");
                   1721:                                }
                   1722:                                else {
                   1723:                                inin2:
                   1724:                                        if (init->base == ILIST) error("list as AIr");
                   1725:                                        Pexpr i = init->typ(tbl);
                   1726:                                        init = class_init(a,a->tp,i,tbl);
                   1727:                                        if (i!=init && init->base==DEREF) {
                   1728:                                                error('s',"K needed forAIr");
                   1729:                                                init = 0;
                   1730:                                        }
                   1731:                                        else {
                   1732:                                                dosimpl(init,cc->nof);
                   1733:                                        //      init->simpl();
                   1734:                                                init->permanent = 2;
                   1735:                                        }
                   1736:                                        a->n_initializer = init;
                   1737:                                }
                   1738:                        }
                   1739:                        else if (pt = a->tp->is_ref()) {
                   1740:                                ref_initializer++;
                   1741:                                init = init->typ(tbl);
                   1742:                                ref_initializer--;
                   1743:                                int tcount = stcount;
                   1744:                                init = ref_init(pt,init,tbl);
                   1745:                                if (tcount != stcount) {
                   1746:                                        error('s',"needs temporaryV to evaluateAIr");
                   1747:                                        init = 0;
                   1748:                                }
                   1749:                                else {
                   1750:                                        dosimpl(init,cc->nof);
                   1751:                                //      init->simpl();
                   1752:                                        init->permanent = 2;
                   1753:                                }
                   1754:                                a->n_initializer = init;
                   1755:                        }
                   1756:                        else {
                   1757:                                Pptr p = a->tp->is_ptr();
                   1758:                                init = init->typ(tbl);
                   1759:                                if (p) init = ptr_init(p,init,tbl);
                   1760: 
                   1761:                                if (a->tp->check(init->tp,ARG)) {
                   1762:                                        int i = can_coerce(a->tp,init->tp);
                   1763: 
                   1764:                                        switch (i) {
                   1765:                                        case 1:
                   1766:                                                if (Ncoerce) {
                   1767:                                                        Pname cn = init->tp->is_cl_obj();
                   1768:                                                        Pname xx = new name(Ncoerce->string);
                   1769:                                                        Pref r = new ref(DOT,init,xx);
                   1770:                                                        init = new expr(G_CALL,r,0);
                   1771:                                                        init = init->typ(tbl);
                   1772:                                                }
                   1773:                                                break;
                   1774:                                        default:
                   1775:                                                error("%d possible conversions for defaultA",i);
                   1776:                                        case 0:
                   1777:                                                error("badIrT%t forA%n (%tX)",init->tp,a,a->tp);
                   1778:                                                DEL(init);
                   1779:                                                a->n_initializer = init = 0;
                   1780:                                        }
                   1781:                                }
                   1782:                                
                   1783:                                if (init) {
                   1784:                                        dosimpl(init,cc->nof);
                   1785:                                //      init->simpl();
                   1786:                                        init->permanent = 2;
                   1787:                                        a->n_initializer = init;
                   1788:                                        Neval = 0;
                   1789:                                        long i = init->eval();
                   1790:                                        if (Neval == 0) {
                   1791:                                                a->n_evaluated = 1;
                   1792:                                                a->n_val = i;
                   1793:                                        }
                   1794:                                }
                   1795:                        }
                   1796:                        if ( a->n_initializer ) 
                   1797:                                check_for_local(a->n_initializer);
                   1798:                }
                   1799:        }
                   1800:        if ( ansi_opt && argnamesize ) {
                   1801:                char* ps = new char[ argnamesize ];
                   1802:                Pname a = f->f_this;
                   1803:                if ( a && a->string ) {
                   1804:                        int i = strlen(a->string) + 1;
                   1805:                        if ( (argnamesize -= i) < 0 ) goto bad;
                   1806:                        strcpy(ps,a->string);
                   1807:                        a->string = ps;
                   1808:                        ps += i;
                   1809:                }
                   1810:                a = f->f_result;
                   1811:                if ( a && a->string ) {
                   1812:                        int i = strlen(a->string) + 1;
                   1813:                        if ( (argnamesize -= i) < 0 ) goto bad;
                   1814:                        strcpy(ps,a->string);
                   1815:                        a->string = ps;
                   1816:                        ps += i;
                   1817:                }
                   1818:                for ( a = f->argtype;  a;  a = a->n_list ) {
                   1819:                        if ( a->string == 0 ) continue;
                   1820:                        int i = strlen(a->string) + 1;
                   1821:                        if ( (argnamesize -= i) < 0 ) goto bad;
                   1822:                        strcpy(ps,a->string);
                   1823:                        a->string = ps;
                   1824:                        ps += i;
                   1825:                }
                   1826:                if ( argnamesize ) bad:error('i',"bad argN size for%t",f);
                   1827:        }
                   1828:        const_save = oo;
                   1829: }
                   1830: 
                   1831: void merge_init(Pname nn, Pfct f, Pfct nf)
                   1832: {
                   1833: //     Pname a1 = f->f_args; if (a1==0) a1 = f->argtype;
                   1834: //     Pname a2 = nf->f_args;//nf->argtype; 
                   1835:        Pname a1 = f->argtype;
                   1836:        Pname a2 = nf->argtype; 
                   1837: 
                   1838:        for (; a1; a1=a1->n_list, a2=a2->n_list) {
                   1839:                int i1 = a1->n_initializer || a1->n_evaluated;
                   1840:                int i2 = a2->n_initializer || a2->n_evaluated;
                   1841: 
                   1842:                if (i1 && i2) error(&a1->where,"twoIrs for%nA%n",nn,a1);
                   1843: 
                   1844:                if (i1) {
                   1845:                        a2->n_initializer = a1->n_initializer;
                   1846:                        a2->n_evaluated = a1->n_evaluated;
                   1847:                        a2->n_val = a1->n_val;
                   1848:                }
                   1849:                if (i2) {
                   1850:                        a1->n_initializer = a2->n_initializer;
                   1851:                        a1->n_evaluated = a2->n_evaluated;
                   1852:                        a1->n_val = a2->n_val;
                   1853:                }
                   1854: 
                   1855:        }
                   1856: }
                   1857: 
                   1858: Pexpr try_to_coerce(Ptype rt, Pexpr e, char* s, Ptable tbl)
                   1859: /*
                   1860:        ``e'' is of class ``cn'' coerce it to type ``rt''
                   1861: */
                   1862: {
                   1863:        int i;
                   1864:        Pname cn;
                   1865: //error('d',"try_to_coerce(%t, %t, %s, %d)",rt,e->tp,s,tbl);
                   1866: 
                   1867:        if ((cn=e->tp->is_cl_obj()) && (i=can_coerce(rt,e->tp)) && Ncoerce) {
                   1868:                if (1 < i) error("%d possible conversions for %s",i,s);
                   1869: //error('d',"coerce %n",Ncoerce);
                   1870:                Pclass cl = Pclass(cn->tp);
                   1871:        //      Pref r = new ref(DOT,e,Ncoerce);
                   1872:        //      Pexpr rr = r->typ(tbl);
                   1873:        //      Pexpr c = new expr(G_CALL,rr,0);
                   1874:        //      c->fct_name = Ncoerce;
                   1875:                Pname xx = new name(Ncoerce->string);
                   1876:                Pref r = new ref(DOT,e,xx);
                   1877:                Pexpr c = new expr(G_CALL,r,0);
                   1878:        //      return c->typ(tbl);
                   1879:                c = c->typ(tbl);
                   1880: //error('d',"coerce -> %k %t",c->base,c->tp);
                   1881:                return c;
                   1882:        }
                   1883: //error('d',"coerce ->0");
                   1884:        return 0;
                   1885: }
                   1886: 
                   1887: int in_class_dcl;
                   1888: 
                   1889: Pname name::dofct(Ptable tbl, TOK scope)
                   1890: {      
                   1891:        Pfct f = Pfct(tp);
                   1892:        Pname class_name;
                   1893:        Ptable etbl;
                   1894:        in_class_dcl = cc->not!=0;
                   1895:        int just_made = 0;
                   1896: //     int fvirt = 0;  //BSopt
                   1897:        DB( if(Ddebug>=1) error('d',"dofct %n %d %t %s",this,tp,tp,tbl==gtbl?"global":""); );
                   1898: // error( 'd', "%n->dofct(): n_initializer: %d f->f_virtual: %d", this, n_initializer, f->f_virtual);
                   1899: 
                   1900:        if (f->f_inline) n_sto = STATIC;
                   1901: 
                   1902:        if (n_stclass)
                   1903:                switch (n_stclass) {
                   1904:                case EXTERN:
                   1905:                case STATIC:
                   1906:                case OVERLOAD:
                   1907:                        break;
                   1908:                default:
                   1909:                        error("%n declared%k",this,n_stclass);
                   1910:                        n_stclass = EXTERN;
                   1911:                }
                   1912: 
                   1913:        tp->dcl(tbl);           // must be done before the type check
                   1914: 
                   1915:        if (n_qualifier) {      // qualified name: c::f() checked above
                   1916:                class_name = Pbase(n_qualifier->tp)->b_name;
                   1917:                etbl = Pclass(class_name->tp)->memtbl;
                   1918: 
                   1919:                if (f->f_virtual) {
                   1920:                          error("virtual specifier illegal outsideCD(%n::%s())",class_name,this->string);
                   1921:                         f->f_virtual = 0;
                   1922:                }
                   1923: 
                   1924: 
                   1925:                if (n_sto
                   1926:                && n_sto!=FRIEND        // friend X::f();
                   1927:                && f->f_inline==0) {    // inline causes n_sto==STATIC
                   1928:                        error("%k specified for QdN%n",n_sto,this);
                   1929:                        n_sto = 0;
                   1930:                }
                   1931:        }
                   1932:        else {
                   1933:                class_name = cc->not;
                   1934: 
                   1935:                // beware of local function declarations in member functions
                   1936:                if (class_name && tbl!=cc->cot->memtbl) {
                   1937:                        class_name = 0;
                   1938:                        in_class_dcl = 0;
                   1939:                }
                   1940: 
                   1941:                if (f->f_static && f->f_virtual) {
                   1942:                         error("virtual staticM");
                   1943:                         f->f_virtual = 0;
                   1944:                }
                   1945: 
                   1946:                if (n_oper) check_oper(class_name);
                   1947:                etbl = tbl;
                   1948:        }
                   1949: 
                   1950: //     Pfct(tp)->memof = class_name ? Pclass(class_name->tp) : 0;
                   1951: 
                   1952:        if (class_name) {
                   1953:                Pclass cl;
                   1954:                f->memof = cl = Pclass(class_name->tp);
                   1955:                if (f->f_virtual==0 && find_virtual(f->memof,this))
                   1956:                        f->f_virtual = VTOK;
                   1957: //error('d',"class_name: %s fct: %s virtual: %d", class_name->string, string, f->f_virtual );
                   1958: 
                   1959:                if (f->f_static && f->f_virtual) {
                   1960:                         error("virtual staticM");
                   1961:                         f->f_virtual = 0;
                   1962:                }
                   1963: 
                   1964:                if ( cl->csu == UNION && f->f_virtual ) // don't worry about ANON
                   1965:                        error( "%n: cannot declare a virtualFWin union", this ); 
                   1966:         }
                   1967: 
                   1968:        if(f->f_const && f->memof==0) {
                   1969:                error("onlyMFs can be constant");
                   1970:        }
                   1971: 
                   1972:        if (etbl==0 || etbl->base!=TABLE) error('i',"N::dcl: etbl=%d",etbl);
                   1973: 
                   1974:        switch (n_oper) {
                   1975:        case CTOR:
                   1976:                if (f->f_virtual) {
                   1977:                        error("virtualK");
                   1978:                        f->f_virtual = 0;
                   1979:                }
                   1980: 
                   1981: //     case DTOR:
                   1982: //             f->f_const = 1;
                   1983:                break;
                   1984: 
                   1985:        case REF:
                   1986:                if (f->argtype) 
                   1987:                        error("%n takes no argument",this);
                   1988:                else if (f->returns->is_ptr() == 0) {
                   1989:                        Pname cn = f->returns->is_cl_obj();
                   1990:                        if (cn==0 && f->returns->base==RPTR) cn = Pptr(f->returns)->typ->is_cl_obj();
                   1991:                        if (cn==0 || Pclass(cn->tp)->has_oper(REF)==0) {
                   1992:                                if ( cn && class_name &&  // B B::operator->();
                   1993:                                        strcmp(cn->string, class_name->string)==0 )
                   1994:                                                error("%s::%n cannot return aR orCO ofC%n",cn->string,this,cn);
                   1995:                                else error("%n must return aP toCO, aR toCO, or aCO",this);
                   1996:                                tp = any_type; // suppress further checking
                   1997:                        }
                   1998:                }
                   1999:                break;
                   2000: 
                   2001:        case NEW:       // void* operator new(long)
                   2002:                if (f->f_virtual)
                   2003:                        error("virtual%n (operator new() is static)",this);
                   2004:                if (class_name) f->f_static = 1;        // if member: static by default
                   2005:                if (f->nargs_known != 1)
                   2006:                        error("ATs must be fully specified for%n",this);
                   2007:                else if (f->nargs<1)
                   2008:                        error("%n requires a firstA ofT size_t",this);
                   2009:                else if (f->argtype->tp->check(size_t_type,0)) {
                   2010:                                if (strict_opt==0
                   2011:                                && ( f->argtype->tp->check(long_type,0)==0 ||
                   2012:                                     f->argtype->tp->check(ulong_type,0)==0)) {
                   2013:                                        error('w',"%n firstA should be size_t (anachronism)",this);
                   2014:                                        f->argtype->tp = size_t_type;
                   2015:                                        if (f->f_signature) f->sign();
                   2016:                                }
                   2017:                                else
                   2018:                                        error("%n requires a firstA ofT size_t",this);
                   2019:                }
                   2020:                else {
                   2021:                        Ptype t = f->s_returns  ? f->s_returns : f->returns;
                   2022:                        if (t->check(Pvoid_type,0)) error("bad returnT for %n",this);
                   2023:                }
                   2024:                break;
                   2025: 
                   2026:                case DELETE:    // void operator delete(void*) or
                   2027:                                // void operator delete(void*, long)
                   2028:                        if (f->f_virtual)
                   2029:                                error("virtual%n (operator delete() is static)",this);
                   2030:                        if (class_name) f->f_static = 1;        // if member: static by default
                   2031:                        if (f->nargs_known != 1)
                   2032:                                        error("ATs must be fully specified for%n",this);
                   2033:                        else {
                   2034:                                Ptype t = f->s_returns ? f->s_returns : f->returns;
                   2035:                                if (t->base != VOID)
                   2036:                                        error("bad returnT for %n", this);
                   2037:                                else {
                   2038:                                        switch (f->nargs) {
                   2039:                                        default:
                   2040:                                                error("%n takes 1 or 2As",this);
                   2041:                                                break;
                   2042:                                        case 1:
                   2043:                                        case 2:
                   2044:                                        {       Pname a = f->argtype;
                   2045:                                                if (a->tp->check(Pvoid_type,0))
                   2046:                                                                error("%n's 1stA must be a void*",this);
                   2047:                                                else if (a = a->n_list) {
                   2048:                                                        if (class_name == 0)
                   2049:                                                                error("%n takes only oneA",this);
                   2050:                                                        else if (a->tp->check(size_t_type,0)) {
                   2051:                                                                if (strict_opt==0
                   2052:                                                                && a->tp->check(long_type,0)==0) {
                   2053:                                                                        error('w',"%n's 2ndA should be a size_t (anachronism)",this);
                   2054:                                                                        a->tp = size_t_type;
                   2055:                                                                        if (f->f_signature) f->sign();
                   2056:                                                                }
                   2057:                                                                else
                   2058:                                                                        error("%n's 2ndA must be a size_t",this);
                   2059:                                                        }
                   2060:                                                }
                   2061:                                        }
                   2062:                                        }
                   2063:                                }
                   2064:                                }
                   2065:                break;
                   2066: 
                   2067:        case ASSIGN:
                   2068:                if (class_name && f->nargs==1) {
                   2069:                        Ptype t = f->argtype->tp;
                   2070:                        Pname an = t->is_cl_obj();  // X::operator=(X) ?
                   2071:                        if (an==0 && (t=t->is_ref())) { // X::operator=(X&) ?
                   2072:                                t = Pptr(t)->typ;
                   2073:                        rx1:
                   2074:                                switch (t->base) {
                   2075:                                case TYPE:      t = Pbase(t)->b_name->tp; goto rx1;
                   2076:                                case COBJ:      an = Pbase(t)->b_name;
                   2077:                                }
                   2078:                        }
                   2079:                        if (an && an==class_name) Pclass(an->tp)->c_xref |= C_ASS;
                   2080:                }
                   2081:                else if (f->nargs == 2) {
                   2082:                        Ptype t = f->argtype->tp;
                   2083:                        Pname an1;
                   2084:                        if (t=t->is_ref()) { // operator=(X&,?) ?
                   2085:                                t = Pptr(t)->typ;
                   2086:                        rx2:
                   2087:                                switch (t->base) {
                   2088:                                case TYPE:      t = Pbase(t)->b_name->tp; goto rx2;
                   2089:                                case COBJ:      an1 = Pbase(t)->b_name;
                   2090:                                }
                   2091:                        }
                   2092:                        t = f->argtype->n_list->tp;
                   2093:                        Pname an2 = t->is_cl_obj(); // operator=(X&,X) ?
                   2094:                        if (an2==0 && (t=t->is_ref())) { // operator=(X&,X&) ?
                   2095:                                t = Pptr(t)->typ;
                   2096:                        rx3:
                   2097:                                switch (t->base) {
                   2098:                                case TYPE:      t = Pbase(t)->b_name->tp; goto rx3;
                   2099:                                case COBJ:      an2 = Pbase(t)->b_name;
                   2100:                                }
                   2101:                        }
                   2102:                        if (an1 && an1==an2) Pclass(an1->tp)->c_xref |= C_ASS;
                   2103:                }
                   2104:        }
                   2105: 
                   2106:        switch (scope) {
                   2107:        case FCT:
                   2108:        case ARG:
                   2109:                if (n_sto == STATIC) error("D of staticF in aF");
                   2110:                else { // detect local re-definition
                   2111:                        Pname nx = gtbl->look(string,0);
                   2112:                        if (nx) {
                   2113:                                switch (nx->tp->base) {
                   2114:                                case FCT:
                   2115:                                        if (tp->check(nx->tp,0))
                   2116:                                                error('w',"%n has been locally re-declared as%t",this,tp);
                   2117:                                        else {
                   2118:                                                if(Pfct(nx->tp)->f_signature==0)
                   2119:                                                        Pfct(nx->tp)->sign();
                   2120:                                                if (Pfct(tp)->f_signature == 0)
                   2121:                                                        Pfct(tp)->sign();
                   2122:                                                if ( strcmp(Pfct(nx->tp)->f_signature,Pfct(tp)->f_signature))
                   2123:                                                        error('w',"%n of type %t has been locally re-declared with different linkage",this,tp);
                   2124:                                        }
                   2125:                                        break;
                   2126:                                case OVERLOAD:
                   2127:                                {       Pname ny = Pgen(nx->tp)->find(f,0);
                   2128:                                        if (ny == 0)
                   2129:                                                error('w',"overloadedF%n has been locally declared as%t",this,tp);
                   2130:                                        else {
                   2131:                                                if(Pfct(ny->tp)->f_signature==0)
                   2132:                                                        Pfct(ny->tp)->sign();
                   2133:                                                if (Pfct(tp)->f_signature == 0)
                   2134:                                                        Pfct(tp)->sign();
                   2135:                                                if (strcmp(Pfct(ny->tp)->f_signature,Pfct(tp)->f_signature))
                   2136:                                                        error('w',"overloadedF%n of type %t has been locally re-declared with different linkage",this,tp);
                   2137:                                        }
                   2138:                                }
                   2139:                                        break;
                   2140:                                } // switch nx->base
                   2141:                        } // if nx
                   2142:                } // else
                   2143:        } // switch scope
                   2144: 
                   2145:        Pname nn = etbl->insert(this,0);
                   2146:        if ( f->body ) nn->where = where;
                   2147:        nn->assign();
                   2148:        n_table = etbl;
                   2149: //error('d',"%n->dofct(): n_initializer:%d f->f_virtual:%d",this,n_initializer,f->f_virtual);
                   2150:        if (n_initializer) {
                   2151:                if (f->f_virtual == 0) error("Ir for non-virtualF%n",this);
                   2152:                if (n_initializer != zero) error("virtualFIr must be 0");
                   2153:        }
                   2154:                        
                   2155:        if (Nold) {
                   2156:                Pfct nf = Pfct(nn->tp);
                   2157: // error('d',"old %n: %t and %t",nn,nf,tp);
                   2158:                int flag = 0;
                   2159:                Pname af=0,anf=0;
                   2160:                if (nf->base==ANY || f->base==ANY)
                   2161:                        ; // wild card -- do nothing
                   2162:                else 
                   2163:                if (nf->base == OVERLOAD) {
                   2164:                        string = nn->string;
                   2165:                        nn = Pgen(nf)->add(this);
                   2166: 
                   2167:                        if (Nold == 0) {
                   2168:                                if (f->body && n_qualifier) {
                   2169:                                        error("badAL for%n",this);
                   2170:                                        return 0;
                   2171:                                }
                   2172:                                goto thth;
                   2173:                        }
                   2174:                //      else {
                   2175:                //              if (f->body==0 && friend_in_class==0) error('w',"%n redeclared",nn);
                   2176:                //      }
                   2177:                        nf = Pfct(nn->tp);
                   2178:                        if (f->body && nf->body) {
                   2179:                                // Preserve the original definition 
                   2180:                                // in the case of a PT class; i.e, 
                   2181:                                // the one supplied by the user
                   2182:                                if (!(class_name &&
                   2183:                                        (Pclass(class_name->tp)->class_base ==
                   2184:                                                instantiated_template_class) && 
                   2185:                                        nn->n_redefined))
                   2186:                                        {
                   2187:                                        error("two definitions of%n",nn);
                   2188:                                        f->body = 0;
                   2189:                                }
                   2190:                                return 0;
                   2191:                        }
                   2192:                        if (f->body) goto bdbd;
                   2193:                        goto stst;
                   2194:                }
                   2195:                else if (nf->base != FCT) {
                   2196:                        error("%n declared both as%t and asF",this,nf);
                   2197:                        f->body = 0;
                   2198:                }
                   2199:                else  {
                   2200: // error('d',"%t->check(%t) -> %d %d",nf,f,nf->check(f,OVERLOAD));
                   2201:                        if (nf->check(f,OVERLOAD) || const_problem) {
                   2202:                                if (f->body && n_qualifier) {
                   2203:                                        error("%nT mismatch: %t and %t",nn,nf,f);
                   2204:                                        return 0;
                   2205:                                }
                   2206:                                Pgen g = new gen;
                   2207:                                add_first = 1;
                   2208:                                Pname n1 = g->add(nn);
                   2209:                                add_first = 0;
                   2210:                                string = nn->string;
                   2211:                                Pname n2 = g->add(this);
                   2212:                                nn->tp = g;
                   2213:                                nn = n2;
                   2214:                                goto thth;
                   2215:                        }
                   2216: 
                   2217:                         af = f->argtype;
                   2218:                         anf = nf->argtype;
                   2219:                        for (; af && anf; af=af->n_list,anf=anf->n_list) {
                   2220:                                Ptype at = af->tp;
                   2221:                                Ptype atp = anf->tp;
                   2222:                                if(!exact1(af,atp)) break;
                   2223:                                if(at->base!=PTR || 
                   2224:                                   Pptr(at)->rdo == Pptr(atp)->rdo) continue;
                   2225:                                int k = Pptr(at)->typ->tconst();
                   2226:                                int l = Pptr(atp)->typ->tconst();
                   2227:                                if(k==l) flag=1;
                   2228:                        }
                   2229:                        if ( flag && !af && !anf) {
                   2230:                                error("the overloading mechanism cannot tell a%t from a%t",nf,f);
                   2231:                        }
                   2232:                                
                   2233:                        if (in_class_dcl) {
                   2234:                        //      error("twoDs of%n",this);
                   2235:                        //      f->body = 0;
                   2236:                        //      return 0;
                   2237:                        }
                   2238:                        else if (nf->f_static && f->f_inline==0 && n_sto==STATIC) {
                   2239:                                //error('d',"MF%n declared static outsideF",this);
                   2240:                                n_sto = 0;
                   2241:                        }
                   2242:                        else if (n_sto && n_sto!=nn->n_scope) {
                   2243:                                if (n_sto==EXTERN && nn->n_scope==STATIC)
                   2244:                                        error('w',"%n declared extern after being declared static",this);
                   2245:                                else if (nf->f_inline==0 && f->f_inline==0) {
                   2246:                                        if (nn->tp==new_fct->tp || nn->tp==del_fct->tp)
                   2247:                                                nn->n_sto = n_sto;
                   2248:                                        else
                   2249:                                                error("%n declared as both%k and%k",this,n_sto,(nn->n_sto)?nn->n_sto:EXTERN);
                   2250:                                }
                   2251:                        }
                   2252: 
                   2253: //error('d',"fct %n: %k %k scope %k",this,n_sto,nn->n_sto,nn->n_scope);        
                   2254: //error('d',"link %d lcount %d sig %s",linkage,lcount,nf->f_signature);
                   2255: 
                   2256:                        { 
                   2257:                                Linkage l1 = nf->f_linkage;
                   2258:                                Linkage l2 = f->f_linkage;
                   2259:                                if ( l2!=linkage_default && l1!=l2)
                   2260:                                        error("inconsistent linkage specifications for%n",this);
                   2261:                        }
                   2262:                        if (nf->body && f->body) {
                   2263:                                // Preserve the original definition 
                   2264:                                // in the case of a PT class; i.e, 
                   2265:                                // the one supplied by the user
                   2266:                                if (!(class_name &&
                   2267:                                        (Pclass(class_name->tp)->class_base ==
                   2268:                                                instantiated_template_class) && 
                   2269:                                        nn->n_redefined))
                   2270:                                        {
                   2271:                                error("two definitions of%n",this);
                   2272:                                f->body = 0;
                   2273:                                }
                   2274:                                return 0;
                   2275:                        }
                   2276:                                
                   2277:                        if (f->body) goto bdbd;
                   2278: 
                   2279:                        goto stst;
                   2280:        
                   2281:                bdbd: 
                   2282: // error('d',"nn %n init: %d f_virt: %d f->body: %d", nn,nn->n_initializer,nf->f_virtual,f->body);
                   2283:                        if (f->nargs_known && nf->nargs_known) merge_init(nn,f,nf);
                   2284:                        f->f_virtual = nf->f_virtual;
                   2285:                        f->f_this = nf->f_this;
                   2286:                        f->f_result = nf->f_result;
                   2287:                        f->s_returns = nf->s_returns;
                   2288:                        f->f_args = nf->f_args;
                   2289:                //      f->argtype = nf->argtype;
                   2290:                        f->f_signature = nf->f_signature;
                   2291:                        f->f_const = nf->f_const;
                   2292:                        f->f_static = nf->f_static;
                   2293:                        nn->tp = f;
                   2294:                        if (f->f_inline) {
                   2295:                                if (nf->f_inline==0) {
                   2296:                                           if (nn->n_used && nn->n_sto!=STATIC)
                   2297:                                                error("%n declared with external linkage and called before defined as inline",nn);
                   2298:                                //      else if (nf->memof)
                   2299:                                //              error('w',"%n declared as non-inline but defined as inline",nn);
                   2300:                                        else if (nn->n_used) {
                   2301:                                                nn->take_addr(); // force printout
                   2302:                                                if (warning_opt) error('w',"%n called before defined as inline",nn);
                   2303:                                }
                   2304:                                }
                   2305:                                nf->f_inline = 1;
                   2306:                                nn->n_sto = STATIC;
                   2307:                        }
                   2308:                        else if (nf->f_inline) {
                   2309:                //              error('w',"%n defined as inline but not declared as inline",this);
                   2310:                                f->f_inline = 1;
                   2311:                        }
                   2312:                        goto stst2;
                   2313: 
                   2314:                stst:
                   2315: //error('d',"stst");
                   2316:                        if (f->nargs_known && nf->nargs_known) merge_init(nn,f,nf);
                   2317:                        f->f_args = nf->f_args;
                   2318:                //      f->argtype = nf->argtype;
                   2319:                stst2:
                   2320: //error('d',"stst2 %n printed %d",nn,nn->n_dcl_printed);
                   2321:                        if (f->f_inline) n_sto = STATIC;
                   2322: 
                   2323: /* superceded above (line 1978 and following)
                   2324:                        if (n_sto
                   2325:                        && nn->n_scope!=n_sto
                   2326:                        && friend_in_class==0
                   2327:                        && f->f_inline==0){ // allow re-def to "static"
                   2328:                                if (n_sto == STATIC)
                   2329:                                        nn->n_sto = STATIC;
                   2330:                                else {
                   2331:                                        error("%n both%k and%k",this,n_sto,nn->n_scope);
                   2332:                                }
                   2333:                        }
                   2334: */
                   2335: 
                   2336: //// addition for 2.1
                   2337: 
                   2338:                        if(n_sto == STATIC && nn->n_sto == EXTERN &&
                   2339:                            (!strcmp(string,"__nw") || !strcmp(string,"__dl")))
                   2340:                                nn->n_sto = STATIC;
                   2341: 
                   2342: //// end of addition
                   2343: 
                   2344:                        n_scope = nn->n_scope; // first specifier wins
                   2345:                        n_sto = nn->n_sto;
                   2346:                }
                   2347:        }
                   2348:        else {  // new function: make f_this for member functions
                   2349:        thth:
                   2350:                just_made = 1;
                   2351:                if (f->f_inline)
                   2352:                        nn->n_sto = STATIC;
                   2353:                else if (class_name==0 && n_sto==0 && f->body==0)
                   2354:                        nn->n_sto = EXTERN;
                   2355: //error('d',"thth %n %t static %d sto %k",nn,f,f->f_static,nn->n_sto);
                   2356:                if (f->f_static)
                   2357:                        switch (n_oper) {       // what about + ??
                   2358:                        case CTOR:
                   2359:                        case DTOR:
                   2360:                        case TYPE:
                   2361:                        case CALL:
                   2362:                        case DEREF:
                   2363:                        case REF:
                   2364:                        case ASSIGN:
                   2365:                                error("%n cannot be a staticMF",nn);
                   2366:                                f->f_static = 0;
                   2367:                        }
                   2368: 
                   2369:                if (class_name
                   2370:                && f->f_static==0       // no ``this'' in static members
                   2371:                && n_oper!=NEW          // X::operator new() static by default
                   2372:                && n_oper!=DELETE       // X::operator delete() static by default
                   2373:                && etbl!=gtbl) {        // beware of implicit declaration 
                   2374:                        Pname cn = nn->n_table->t_name;
                   2375:                        Pname tt = new name("this");
                   2376:                        tt->n_scope = ARG;
                   2377:                        tt->where = no_where;
                   2378:                //      tt->n_sto = ARG;
                   2379:                        tt->tp = Pclass(class_name->tp)->this_type;
                   2380:                        PERM(tt);
                   2381:                        Pfct(nn->tp)->f_this = f->f_this = Pfct(nn->tp)->f_args = f->f_args = tt;
                   2382:                        tt->n_list = f->argtype;
                   2383: //error('d',"nn %n tp %t const %d",nn,nn->tp,f->f_const);
                   2384:                        if (f->f_const /*&& n_oper!=CTOR && n_oper!=DTOR*/) {
                   2385:                                Pbase x = Pbase(Pptr(tt->tp)->typ);
                   2386:                                Pbase y = new basetype(COBJ,0);
                   2387:                                *y = *x;
                   2388:                                y->b_const = 1;
                   2389:                                tt->tp = new ptr(PTR,y);
                   2390:                                Pptr(tt->tp)->rdo = 1;
                   2391:                                PERM(tt->tp);
                   2392:                        }
                   2393:                }
                   2394:                else {
                   2395:                        Pfct(nn->tp)->f_args = f->f_args = f->f_result?f->f_result:f->argtype;
                   2396:                        Pfct(nn->tp)->f_signature = f->f_signature;
                   2397:                        Pfct(nn->tp)->f_const = f->f_const;
                   2398:                        Pfct(nn->tp)->f_static = f->f_static;
                   2399:                }
                   2400: 
                   2401:                // if C++ linkage encode type in function name
                   2402:                if (Pfct(nn->tp)->f_signature==0) Pfct(nn->tp)->sign();
                   2403: 
                   2404:                if (f->f_result == 0) {
                   2405: //error('d',"re1 %n %t %d",this,f,f);
                   2406:                        make_res(f);
                   2407:                }
                   2408:                else if (f->f_this)
                   2409:                        f->f_this->n_list = f->f_result;
                   2410: 
                   2411:                if (nn->n_oper==CTOR || nn->n_oper==DTOR) vbase_pointers(nn,Pclass(class_name->tp));
                   2412: 
                   2413:                if (f->f_virtual) {
                   2414:                        switch (nn->n_scope) {
                   2415:                        default:
                   2416:                                error("nonC virtual%n",this);
                   2417:                                break;
                   2418:                        case 0:
                   2419:                        case PUBLIC:
                   2420:                                //      if (fvirt)      //BSopt
                   2421:                                cc->cot->virt_count = 1;
                   2422:                                Pfct(nn->tp)->f_virtual = f->f_virtual;
                   2423:                                break;
                   2424:                        }
                   2425:                }
                   2426:        }
                   2427: 
                   2428:                /*      an operator must take at least one class object or
                   2429:                        reference to class object argument
                   2430:                */
                   2431: 
                   2432:        if (just_made)
                   2433:        switch (n_oper) {
                   2434:        case CTOR:
                   2435:                switch (f->nargs) {     // check for X(X) and X(X&)
                   2436:                case 0:
                   2437:                        break;
                   2438:                default:                // handle X(X&, int i = 0)
                   2439:                {       Pname n2 = f->argtype->n_list;
                   2440:                        if (n2->n_initializer==0 && n2->n_evaluated==0) break;
                   2441:                }
                   2442:                case 1:
                   2443:                {
                   2444:                        Ptype t = f->argtype->tp;
                   2445:                clll:
                   2446:                        switch (t->base) {
                   2447:                        case TYPE:
                   2448:                                t = Pbase(t)->b_name->tp;
                   2449:                                goto clll;
                   2450:                        case RPTR:                      /* X(X&) ? */
                   2451:                                t = Pptr(t)->typ;
                   2452:                        cxll:
                   2453:                                switch (t->base) {
                   2454:                                case TYPE:
                   2455:                                        t = Pbase(t)->b_name->tp;
                   2456:                                        goto cxll;
                   2457:                                case COBJ:
                   2458:                                        if (class_name == Pbase(t)->b_name)
                   2459:                                                Pclass(class_name->tp)->c_itor = nn;
                   2460:                                }
                   2461:                                break;
                   2462:                        case COBJ:                      /* X(X) ? */
                   2463:                                if (class_name == Pbase(t)->b_name) {
                   2464:                                        error("badK %s(%s) use %s(%s&)",class_name->string,class_name->string,class_name->string,class_name->string);
                   2465:                                        f->argtype->tp = any_type;
                   2466:                                }
                   2467:                        }
                   2468:                }
                   2469:                }
                   2470:                if (Pclass(class_name->tp)->c_ctor == 0) Pclass(class_name->tp)->c_ctor = nn;
                   2471:                break;
                   2472: 
                   2473:        case TYPE:
                   2474:                // somewhat simple minded solution to the inheritance of
                   2475:                // conversion operator problem
                   2476:                nn->n_list = Pclass(class_name->tp)->conv;
                   2477:                Pclass(class_name->tp)->conv = nn;
                   2478:                break;
                   2479: 
                   2480:        case DTOR:
                   2481:                Pclass(class_name->tp)->c_dtor = nn;
                   2482:                break;
                   2483: 
                   2484:        case NEW:       
                   2485:        case DELETE:
                   2486:        case CALL:
                   2487:        case 0:
                   2488:                break;
                   2489: 
                   2490:        default:
                   2491:                for (Pname a=f->argtype; a; a=a->n_list) {
                   2492:                        if ( a->n_initializer )
                   2493:                                error( "%n: operatorFs cannot take defaultA", this );
                   2494:                }
                   2495: 
                   2496:                if (f->nargs_known != 1) {
                   2497:                        error("ATs must be fully specified for%n",nn);
                   2498:                }
                   2499:                // this doesn't catch unary operator off by one errors
                   2500:                // for simplicity, placed that check in check_oper(), above
                   2501:                else if (class_name == 0) {
                   2502:                        switch (f->nargs) {
                   2503:                        case 1:
                   2504:                        case 2:
                   2505:                                for (a=f->argtype; a; a=a->n_list) {
                   2506:                                        Ptype tx = a->tp;
                   2507:                                        while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp;
                   2508:                                        if (tx->is_ref()) tx = Pptr(tx)->typ;
                   2509:                                        if (tx->is_cl_obj()) goto cok;
                   2510:                                }
                   2511:                                error("%n must take at least oneCTA",nn);
                   2512:                                break;
                   2513:                        default:
                   2514:                                error("%n must take 1 or 2As",nn);
                   2515:                        }
                   2516:                }
                   2517:                else {
                   2518:                        switch (f->nargs) {
                   2519:                        case 0:
                   2520:                        case 1:
                   2521:                                break;
                   2522:                        default:
                   2523:                                error("%n must take 0 or 1As",nn);
                   2524:                        }
                   2525:                }
                   2526:        cok:;
                   2527:        }
                   2528: 
                   2529:        int i = 0;      // check that every argument after an argument with
                   2530:                        // initializer have an initializer
                   2531:        for (Pname a = f->f_args/*f->argtype*/; a; a=a->n_list) {
                   2532:                if (a->n_initializer)
                   2533:                        i = 1;
                   2534:                else if (i)
                   2535:                        error("trailingA%n withoutIr",a);
                   2536:        }
                   2537: 
                   2538:        /*
                   2539:                the body cannot be checked until the name
                   2540:                has been checked and entered into its table
                   2541:        */
                   2542:        if (f->body) f->dcl(nn);
                   2543:        return nn;
                   2544: }
                   2545: 

unix.superglobalmegacorp.com

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