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

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

unix.superglobalmegacorp.com

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