Annotation of researchv10no/cmd/cfront/ocfront/dcl.c, revision 1.1

1.1     ! root        1: /*ident        "@(#)ctrans:src/dcl.c   1.3.5.41" */
        !             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 rigths Reserved
        !             8:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
        !             9: 
        !            10: dcl.c:
        !            11: 
        !            12:        ``declare'' all names, that is insert them in the appropriate symbol tables.
        !            13: 
        !            14:        Calculate the size for all objects (incl. stack frames),
        !            15:        and find store the offsets for all members (incl. auto variables).
        !            16:        "size.h" holds the constants needed for calculating sizes.
        !            17: 
        !            18:        Note that (due to errors) functions may nest
        !            19: 
        !            20: *****************************************************************************/
        !            21: 
        !            22: 
        !            23: #include "cfront.h"
        !            24: #include "size.h"
        !            25: 
        !            26: class dcl_context ccvec[MAXCONT], * cc = ccvec;
        !            27: int byte_offset;
        !            28: int bit_offset;
        !            29: int max_align;
        !            30: int friend_in_class;
        !            31: static Pstmt itail;
        !            32: 
        !            33: Pname dclass(Pname, Ptable);
        !            34: Pname denum(Pname, Ptable);
        !            35: void merge_init(Pname, Pfct, Pfct);
        !            36: 
        !            37: void dosimpl(Pexpr e, Pname n)
        !            38: {
        !            39: //error('d',"dosimpl %k %n",e?e->base:0,n);
        !            40:        if (n==0) {
        !            41:                if (dummy_fct == 0) make_dummy();
        !            42:                n = dummy_fct;
        !            43:        }
        !            44:        Pname cf = curr_fct;
        !            45:        curr_fct = n;
        !            46:        e->simpl();
        !            47:        curr_fct = cf;
        !            48: }
        !            49: 
        !            50: static Pexpr co_array_init(Pname n, Ptable tbl)
        !            51: /*
        !            52:        handle simple arrays only. To be done well list_check() must
        !            53:        be rewritten to handle dynamic initialization.
        !            54: */
        !            55: {
        !            56: // error('d',"Ir forCO%n\[\]",n);
        !            57:        Pexpr init = n->n_initializer;
        !            58: 
        !            59:        if (init->base != ILIST) {
        !            60:                error("badIr for array ofCOs %n",n);
        !            61:                return 0;
        !            62:        }
        !            63: 
        !            64:        Pexpr el = 0;
        !            65:        Pvec v = Pvec(n->tp);
        !            66:        while (v->base==TYPE) v = Pvec(Pbase(v)->b_name->tp);
        !            67:        Pname cn = v->typ->is_cl_obj();
        !            68:        Pclass cl = cn ? Pclass(cn->tp) : 0;
        !            69: //error('d',"v %t cl %d %t",v,cl,cl);
        !            70:        int i = v->size;
        !            71: 
        !            72:        int count = 0;
        !            73:        Pexpr il2;
        !            74:        for (Pexpr il = init->e1; il; il = il2) {
        !            75:                        // generate     n[0].cl(initializer),
        !            76:                        //              ...
        !            77:                        //              n[max].cl(initializer),
        !            78:                Pexpr e = il->e1;
        !            79:                il2 = il->e2;
        !            80:                il->e2 = 0;
        !            81:                if  (e == dummy) break;
        !            82: //error('d',"il %k e %k",il->base,e?e->base:0);
        !            83:                if (e->base == VALUE) {
        !            84:                        switch (e->tp2->base) {
        !            85:                        case CLASS:
        !            86:                                if (Pclass(e->tp2)!=cl) e = new texpr(VALUE,cl,il);
        !            87:                                break;
        !            88:                        default:
        !            89:                                Pname n2 = e->tp2->is_cl_obj();
        !            90:                                if (n2==0 || Pclass(n2->tp)!=cl) e = new texpr(VALUE,cl,il);
        !            91:                        }
        !            92:                }
        !            93:                else
        !            94:                        e = new texpr(VALUE,cl,il);
        !            95:                e->e2 = new expr(DEREF,n,new ival(count++));
        !            96:                e = e->typ(tbl);
        !            97:                dosimpl(e,cc->nof);
        !            98:        //      e->simpl();
        !            99:                if (sti_tbl == tbl) {
        !           100:                        Pstmt ist = new estmt(SM,no_where,e,0);
        !           101:                        if (st_ilist == 0)
        !           102:                                st_ilist = ist;
        !           103:                        else
        !           104:                                itail->s_list = ist;
        !           105:                        itail = ist;
        !           106:                }
        !           107:                else {
        !           108:                        el = el ? new expr(G_CM,el,e) : e;
        !           109:                }
        !           110:        }
        !           111: 
        !           112:        if (i==0)
        !           113:                v->size = count;
        !           114:        else if (i==count)
        !           115:                ;
        !           116:        else if (i<count) {
        !           117:                 error("too manyIrs for%n (%d)",n, count);
        !           118:                return 0;
        !           119:        }       
        !           120:        else {
        !           121: //              error('d',"too fewIrs for%n (%d)",n, count);
        !           122:                if (cl->has_ictor())
        !           123:                        error('s',"too fewIrs for%n",n);
        !           124:                else error( "too fewIrs for%n (C %srequires a defaultK)", n, cl->string );
        !           125:                return 0;
        !           126:        }
        !           127:        return el;
        !           128: }
        !           129: 
        !           130: int need_sti(Pexpr e, Ptable tbl, bit accept_name)
        !           131: /*
        !           132:        check if non-static variables or operations are used
        !           133:        INCOMPLETE 
        !           134: */
        !           135: {
        !           136:        if (e == 0) return 0;
        !           137: // error('d',"need_sti: %d - %d %k %t",tbl?1:0,accept_name,e->base,e->tp);
        !           138: 
        !           139:        switch (e->base) {
        !           140:        case QUEST:
        !           141:                if (need_sti(e->cond,tbl,0) && tbl==0) return 1;
        !           142:        case PLUS:
        !           143:        case MINUS:
        !           144:        case MUL:
        !           145:        case DIV:
        !           146:        case MOD:
        !           147:        case ER:
        !           148:        case OR:
        !           149:        case ANDAND:
        !           150:        case OROR:
        !           151:        case LS:
        !           152:        case RS:
        !           153:        case EQ:
        !           154:        case NE:
        !           155:        case LT:
        !           156:        case LE:
        !           157:        case GT:
        !           158:        case GE:
        !           159:        case INCR:
        !           160:        case DECR:
        !           161:        case ASSIGN:
        !           162:                if (need_sti(e->e1,tbl,accept_name) && tbl==0) return 1;
        !           163:                // no break;
        !           164: 
        !           165:        case UMINUS:
        !           166:        case UPLUS:
        !           167:        case NOT:
        !           168:        case COMPL:
        !           169:                if (need_sti(e->e2,tbl,accept_name) && tbl==0) return 1;
        !           170:                // no break
        !           171: 
        !           172:        case SIZEOF:
        !           173:        default:
        !           174: 
        !           175:                return 0;
        !           176: 
        !           177:        case CAST:
        !           178: 
        !           179:                return need_sti(e->e1,tbl,accept_name);
        !           180: 
        !           181:        case ADDROF:
        !           182:        {
        !           183:                int i = need_sti(e->e2,tbl,1);
        !           184:                return i;
        !           185:        }
        !           186: 
        !           187:        case NAME:
        !           188:                if (accept_name && Pname(e)->n_stclass==STATIC) return 0;
        !           189: 
        !           190: //             if ((Pname(e)->n_stclass==AUTO || Pname(e)->n_stclass==REGISTER)
        !           191: //             &&   strncmp(Pname(e)->string,"__Q",3) != 0 ) {
        !           192: //                     error("localN%n inIr for static",e);
        !           193: //                     return 0;
        !           194: //             }
        !           195: 
        !           196:                if (e->tp->tconst()) {
        !           197:                        if (vec_const || fct_const) return 0;
        !           198:                        Neval = 0;
        !           199:                        e->eval();
        !           200:                        if (Neval == 0) return 0;
        !           201:                }
        !           202:                return 1;
        !           203: 
        !           204:        case DEREF:
        !           205:        case REF:
        !           206:        case DOT:
        !           207:                if (accept_name||(e->tp && e->tp->base==VEC)) {
        !           208:                        int x1 = need_sti(e->e1,tbl,e->base == DOT);
        !           209:                        int x2 = need_sti(e->e2,tbl,0);
        !           210:                        return x1 || x2;
        !           211:                }
        !           212:                // no break
        !           213: 
        !           214:        case ELIST:
        !           215: //     case ILIST:
        !           216:        case G_CM:
        !           217:        case CM:
        !           218:        case CALL:
        !           219:        case G_CALL:
        !           220:        case NEW:
        !           221:        case GNEW:
        !           222:        case 0:                 // hack for `new type (expr)'
        !           223:                if (tbl) {
        !           224:                        need_sti(e->e1,tbl,accept_name);
        !           225:                        need_sti(e->e2,tbl,accept_name);
        !           226:                        if ( e->tp && e->tp->base == VEC &&
        !           227:                                e->base == NEW || e->base == GNEW )
        !           228:                                // preserve ICON,STRING,CCON,FCON
        !           229:                                need_sti(Pvec(e->tp)->dim,tbl);
        !           230:                }
        !           231:                 else if (e->base == 0)
        !           232:                       return 0;
        !           233:                // no break
        !           234:        case ICALL:
        !           235:                return 1;
        !           236:        case ICON:
        !           237:        case STRING:
        !           238:        case CCON:
        !           239:        case FCON:
        !           240: //error('d',"save %k tbl %d",e->base,tbl);
        !           241:                if (tbl) {
        !           242:                        char* p = new char[strlen(e->string)+1];
        !           243:                        strcpy(p,e->string);
        !           244:                        e->string = p;
        !           245:                }
        !           246:                return 0;
        !           247:        }
        !           248: }
        !           249: 
        !           250: void check_def_name( Pname nn, int scope ) 
        !           251: {
        !           252: // error('d', "check_def_name: nn: %n n_sto: %k scope: %k", nn,nn->n_sto,scope );
        !           253:        if ( def_name==0 && pdef_name==0 && friend_in_class == 0 &&
        !           254:                scope == EXTERN && nn->n_scope != STATIC &&  
        !           255:                nn->n_oper != NEW && nn->n_oper != DELETE ) { 
        !           256:                        Pfct f = Pfct(nn->tp);
        !           257:                        if (f->body && 
        !           258:                                f->f_inline == 0 && 
        !           259:                                f->f_imeasure == 0) {
        !           260: // error('d', "check_def_name: do it: %n", nn );
        !           261:                                        pdef_name = def_name = nn;
        !           262:                                        ptbl_init(0);
        !           263:                                        def_name = 0;
        !           264:                        }
        !           265:        }
        !           266: }
        !           267: 
        !           268: Pname name::dcl(Ptable tbl, TOK scope)
        !           269: /*
        !           270:        enter a copy of this name into symbol table "tbl";
        !           271:                - create local symbol tables as needed
        !           272:        
        !           273:        "scope" gives the scope in which the declaration was found
        !           274:                - EXTERN, FCT, ARG, PUBLIC, or 0
        !           275:        Compare "scope" with the specified storage class "n_sto"
        !           276:                - AUTO, STATIC, REGISTER, EXTERN, OVERLOAD, FRIEND, or 0
        !           277: 
        !           278:        After name::dcl()
        !           279:        n_stclass ==    0               class or enum member
        !           280:                        REGISTER        auto variables declared register
        !           281:                        AUTO            auto variables not registers
        !           282:                        STATIC          statically allocated object
        !           283:        n_scope ==      0               private class member
        !           284:                        PUBLIC          public class member
        !           285:                        EXTERN          name valid in this and other files
        !           286:                        STATIC          name valid for this file only
        !           287:                        FCT             name local to a function
        !           288:                        ARG             name of a function argument
        !           289:                        ARGT            name of a type defined in an
        !           290:                                        argument list
        !           291: 
        !           292:        typecheck function bodies;
        !           293:        typecheck initializers;
        !           294: 
        !           295:        note that functions (error recovery) and classes (legal) nest
        !           296: 
        !           297:        The return value is used to chain symbol table entries, but cannot
        !           298:        be used for printout because it denotes the sum of all type information
        !           299:        for the name
        !           300: 
        !           301:        names of typenames are marked with n_oper==TNAME
        !           302: 
        !           303:        WARNING: The handling of scope and storage class is cursed!
        !           304: */
        !           305: {
        !           306:        Pname nn;
        !           307:        Ptype nnt = 0;
        !           308:        Pname odcl = Cdcl;
        !           309:        int sti_vb = 0; // set if initialize with virtual base class
        !           310: 
        !           311: //     if (this == 0) error('i',"0->N::dcl()");
        !           312: //     if (tbl == 0) error('i',"%n->N::dcl(tbl=0,%k)",this,scope);
        !           313: //     if (tbl->base != TABLE) error('i',"%n->N::dcl(tbl=%d,%k)",this,tbl->base,scope);
        !           314: //     if (tp == 0) error('i',"N::dcl(%n,%k)T missing",this,scope);
        !           315: 
        !           316:        Cdcl = this;
        !           317:        Ptype tx = tp;
        !           318: 
        !           319:        DB( if(Ddebug>=1) error('d',"dcl %n %t",this,tx); );
        !           320: // error('d',"dcl %n %t cc->cot: %d",this,tx,cc?cc->cot:0); 
        !           321:        while (tx->base == TYPE) tx = Pbase(tx)->b_name->tp;
        !           322: 
        !           323:        switch (base) {
        !           324:        case TNAME:
        !           325:                nn = tbl->look(string,0);
        !           326:                tp->dcl(tbl);
        !           327:                 if (nn && nn->lex_level == lex_level) {
        !           328: //error('d', "dcl: cot: %s ccl: %s", cc->cot?cc->cot->string:"notset", ccl?ccl->string:"notset");
        !           329: 
        !           330:                         if ( tp->check(nn->tp,0) )
        !           331:                                 error("%n declared as %t and %t",nn,nn->tp,tp);
        !           332:                         else if ( nn->base == NAME && cc->cot == 0 &&
        !           333:                        (tp->base != COBJ || tp->base != EOBJ))
        !           334:                                 error("%n declared as identifier and typedef", nn );
        !           335:                         Cdcl = odcl;
        !           336:                         return 0;
        !           337: 
        !           338:                 }
        !           339:                PERM(tp);
        !           340:                nn = new name(string);
        !           341:                nn->base = TNAME;
        !           342:                nn->tp = tp;
        !           343:                Pname tn = tbl->insert(nn,0);
        !           344:                if (n_key == NESTED) {
        !           345:                        tn->n_key = NESTED;
        !           346:                        tn->tpdef = tpdef;
        !           347:                }
        !           348:                delete nn;
        !           349:                Cdcl = odcl;
        !           350:                return this;
        !           351:        
        !           352:        case NAME:
        !           353:                switch (n_oper) {
        !           354:                case COMPL:
        !           355:                        if (tp->base != FCT) {
        !           356:                                error("~%s notF",string);
        !           357:                                n_oper = 0;
        !           358:                        }
        !           359:                        break;
        !           360:                case TNAME:
        !           361:                        if (tp->base != FCT) n_oper = 0;
        !           362:                        break;
        !           363:                }
        !           364:                break;
        !           365:        default:
        !           366:                error('i',"NX in N::dcl()");
        !           367:        }
        !           368: 
        !           369:        if (n_qualifier) {      
        !           370:                                // c::f()
        !           371:                                // class function,
        !           372:                                // friend declaration, or 
        !           373:                                // static member initializer
        !           374: 
        !           375:        //III   if (tp->base != FCT) {
        !           376:        //              error("QdN%n inD of nonF",this);
        !           377:        //              Cdcl = odcl;
        !           378:        //              return 0;
        !           379:        //      }
        !           380: 
        !           381:                Pname cn = n_qualifier;
        !           382: 
        !           383:                switch (cn->base) {
        !           384:                case TNAME:
        !           385:                        break;
        !           386:                case NAME:
        !           387:                        cn = gtbl->look(cn->string,0);
        !           388:                        if (cn && cn->base==TNAME) break;
        !           389:                default:
        !           390:                        error("badQr%n for%n",n_qualifier,this);
        !           391:                        Cdcl = odcl;
        !           392:                        return 0;
        !           393:                }
        !           394: 
        !           395:                while (cn->tp->base == TYPE) cn->tp = Pbase(cn->tp)->b_name->tp;
        !           396: // error('d',"actualQr%n %t",cn,cn->tp);
        !           397:                if (cn->tp->base != COBJ) {
        !           398:                        error(&where,"Qr%nnot aCN",n_qualifier);
        !           399:                        Cdcl = odcl;
        !           400:                        return 0;
        !           401:                }
        !           402: 
        !           403:                cn = Pbase(cn->tp)->b_name;
        !           404:                if (n_oper) check_oper(cn);
        !           405: 
        !           406:                Pclass cl = Pclass(cn->tp);
        !           407:                if (cl == cc->cot) {
        !           408:                        n_qualifier = 0;
        !           409:                        goto xdr;
        !           410:                }
        !           411:                else if ((cl->defined&(DEFINED|SIMPLIFIED)) == 0) {
        !           412:                        error("C%nU",cn);
        !           413:                        Cdcl = odcl;
        !           414:                        return 0;
        !           415:                }
        !           416:                else if (cl->c_body==1) //III
        !           417:                        cl->dcl_print(0);
        !           418: 
        !           419:                Ptable etbl = cl->memtbl;
        !           420:                Pname x = etbl->look(string,0);
        !           421:                if (x==0 || x->n_table!=etbl) {
        !           422:                        error("%n is not aM of%n",this,cn);
        !           423:                        Cdcl = odcl;
        !           424:                        return 0;
        !           425:                }
        !           426: 
        !           427:                if (tp->base == FCT) {  //III
        !           428:                //      if (friend_in_class==0 && Pfct(tp)->body==0) {  // c::f(); needed for friend
        !           429:                        if (friend_in_class==0
        !           430:                        && n_sto!=FRIEND
        !           431:                        && Pfct(tp)->body==0) { // c::f(); needed for friend
        !           432:                                error("QdN%n inFD",x);
        !           433:                                Cdcl = odcl;
        !           434:                                return 0;
        !           435:                        }
        !           436: 
        !           437:                        if (Pfct(tp)->body==0) {
        !           438:                                Pfct(tp)->memof = cl;
        !           439:                                int xx;
        !           440:                                if (x->tp->base==OVERLOAD)
        !           441:                                        xx = Pgen(x->tp)->find(Pfct(tp),0)==0;
        !           442:                                else
        !           443:                                        xx = x->tp->check(tp,0);
        !           444: 
        !           445:                                if (xx) {
        !           446:                                        error("%n is not aM of%n",this,cn);
        !           447:                                        Cdcl = odcl;
        !           448:                                        return 0;
        !           449:                                }
        !           450:                        }
        !           451:                }
        !           452:                else {
        !           453:                        if (x->n_stclass != STATIC) {   // e.g. int c::i = 7
        !           454:                                error("D of non staticCM %n",this);
        !           455:                                Cdcl = odcl;
        !           456:                                return 0;
        !           457:                        }
        !           458:                        if (n_sto) error("staticCM declared%k",n_sto);
        !           459:                        tbl = etbl;
        !           460:                }
        !           461:        }
        !           462: xdr:
        !           463:        if (n_oper
        !           464:        && tp->base!=FCT
        !           465:        && n_sto!=OVERLOAD) error("operator%k not aF",n_oper);
        !           466: 
        !           467: 
        !           468:        /*      if a storage class was specified
        !           469:                        check that it is legal in the scope 
        !           470:                else
        !           471:                        provide default storage class
        !           472:                some details must be left until the type of the object is known
        !           473:        */
        !           474: 
        !           475:        n_stclass = n_sto;
        !           476:        n_scope = scope;        /* default scope & storage class */
        !           477: 
        !           478:        switch (n_sto) {
        !           479:        default:
        !           480:                error('i',"unX %k",n_sto);
        !           481:        case FRIEND:
        !           482:        {
        !           483:                Pclass cl = cc->cot;
        !           484: 
        !           485:                switch (scope) {
        !           486:                case 0:
        !           487:                case PUBLIC:
        !           488:                        break;
        !           489:                default:
        !           490:                        error("friend%n not inCD(%k)",this,scope);
        !           491:                        base = 0;
        !           492:                        Cdcl = odcl;
        !           493:                        return 0;
        !           494:                }
        !           495: 
        !           496:                switch (n_oper) {
        !           497:                case 0:
        !           498:                case NEW:
        !           499:                case DELETE:
        !           500:                case CTOR:
        !           501:                case DTOR:
        !           502:                case TYPE:
        !           503:                        n_sto = 0;
        !           504:                        break;
        !           505:                default:
        !           506:                        n_sto = OVERLOAD;
        !           507:                }
        !           508: 
        !           509:                switch (tx->base) {
        !           510:                case COBJ:
        !           511:                        nn = Pbase(tx)->b_name;
        !           512:                        break;
        !           513:                case CLASS:
        !           514:                        nn = this;
        !           515:                        break;
        !           516:                case FCT:
        !           517:                        cc->stack();
        !           518:                        cc->not = 0;
        !           519:                        cc->tot = 0;
        !           520:                        cc->cot = 0;
        !           521:                        friend_in_class++;
        !           522:                //      n_sto = EXTERN;
        !           523:                        n_sto = 0;
        !           524:                        nn = dcl(gtbl,EXTERN);
        !           525:                        if (nn == 0) {
        !           526:                                Cdcl = odcl;
        !           527:                                return 0;
        !           528:                        }
        !           529:                        friend_in_class--;
        !           530:                        cc->unstack();
        !           531:                        if (nn->tp->base == OVERLOAD) nn = Pgen(nn->tp)->find(Pfct(tx),1);
        !           532:                        break;
        !           533:                default:
        !           534:                        error("badT%tof friend%n",tp,this);
        !           535:                        Cdcl = odcl;
        !           536:                        return 0;
        !           537:                }
        !           538:                PERM(nn);
        !           539:                cl->friend_list = new name_list(nn,cl->friend_list);
        !           540:                Cdcl = odcl;
        !           541:                return nn;
        !           542:        }
        !           543:        case OVERLOAD:
        !           544:                if (strict_opt||warning_opt)
        !           545:                        error(strict_opt?0:'w',"`overload' used (anachronism)");
        !           546:                n_sto = 0;
        !           547:                                // ignore overload!
        !           548:        //      switch (scope) {
        !           549:        //      case 0:
        !           550:        //      case PUBLIC:
        !           551:        //              error('w',"overload inCD (ignored)");
        !           552:                        switch (tp->base) {
        !           553:                        case FCT:
        !           554:                                break;
        !           555:                        default:
        !           556:                                base = 0;
        !           557:                                Cdcl = odcl;
        !           558:                                return this;
        !           559:        //              case FCT:
        !           560:        //                      Cdcl = odcl;
        !           561:        //                      return dcl(tbl,scope);
        !           562:                        }
        !           563:        //      }
        !           564:        //      if (n_oper && tp->base==FCT) break;
        !           565:        //      nn = tbl->insert(this,0);
        !           566:        //
        !           567:        //      if (Nold) {
        !           568:        //              if (nn->tp->base != OVERLOAD) {
        !           569:        //                      error("%n redefined as overloaded",this);
        !           570:        //                      nn->tp = new gen;
        !           571:        //              }
        !           572:        //      }
        !           573:        //      else {
        !           574:        //              nn->tp = new gen;
        !           575:        //      }
        !           576:        //
        !           577:        //      switch (tx->base) {
        !           578:        //      case INT:
        !           579:        //              base = 0;
        !           580:        //              Cdcl = odcl;
        !           581:        //              return nn;
        !           582:        //      case FCT:
        !           583:        //              break;
        !           584:        //      default:
        !           585:        //              error("N%n ofT%k cannot be overloaded",this,tp->base);
        !           586:        //              Cdcl = odcl;
        !           587:        //              return nn;
        !           588:        //      }
        !           589:                break;
        !           590:        case REGISTER:
        !           591:                if (tp->base == FCT) {
        !           592:                        error('w',"%n: register (ignored)",this);
        !           593:                        goto ddd;
        !           594:                }
        !           595:        case AUTO:
        !           596:                switch (scope) {
        !           597:                case 0:
        !           598:                case PUBLIC:
        !           599:                case EXTERN:
        !           600:                        error("%k not inF",n_sto);
        !           601:                        goto ddd;
        !           602:                }
        !           603:                if (n_sto==AUTO) n_sto = 0;     // always redundant
        !           604:                break;
        !           605:        case EXTERN:
        !           606:                switch (scope) {
        !           607:                case ARG:
        !           608:                        //error("externA");
        !           609:                        goto ddd;
        !           610:                case 0:
        !           611:                case PUBLIC:
        !           612:                        /* extern is provided as a default for functions without body */
        !           613:                        if (tp->base != FCT) error("externM%n",this);
        !           614:                        goto ddd;
        !           615:                case FCT:
        !           616:                        {
        !           617:                        Pname nn = gtbl->look( string, 0 );
        !           618:                        if ( nn && tp->base != FCT &&
        !           619:                                tp->check(nn->tp,0)) 
        !           620:                                {
        !           621:                                error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp);
        !           622:                                Cdcl = odcl;
        !           623:                                return 0;
        !           624:                                }
        !           625:                        }
        !           626:                }
        !           627:                n_stclass = STATIC;
        !           628:                n_scope = EXTERN;       /* avoid FCT scoped externs to allow better checking */
        !           629:                break;
        !           630:        case STATIC:
        !           631:                switch (scope) {
        !           632:                case ARG:
        !           633:                        //error("static used forA%n",this);
        !           634:                        goto ddd;
        !           635:                case 0:
        !           636:                case PUBLIC:
        !           637:                        n_stclass = STATIC;
        !           638:                        n_scope = scope;
        !           639:                        break;
        !           640:                default:
        !           641:                        n_scope = STATIC;
        !           642:                }
        !           643:                break;
        !           644:        case 0:
        !           645:        ddd:
        !           646:                switch (scope) {        /* default storage classes */
        !           647:                case EXTERN:
        !           648:                        n_scope = EXTERN;
        !           649:                        n_stclass = STATIC;
        !           650:                        break;
        !           651:                case FCT:
        !           652:                        if (tp->base == FCT) {
        !           653:                                n_stclass = STATIC;
        !           654:                                n_scope = EXTERN;
        !           655:                        }
        !           656:                        else
        !           657:                                n_stclass = AUTO;
        !           658:                        break;
        !           659:                case ARG:
        !           660:                        n_stclass = AUTO;
        !           661:                        break;
        !           662:                case 0:
        !           663:                case PUBLIC:
        !           664:                        n_stclass = 0;
        !           665:                        break;
        !           666:                }
        !           667:        }
        !           668: 
        !           669:        
        !           670:        /*
        !           671:                now insert the name into the appropriate symbol table,
        !           672:                and compare types with previous declarations of that name
        !           673: 
        !           674:                do type dependent adjustments of the scope
        !           675:        */
        !           676: //error('d',"sw %d",tx->base);
        !           677:        switch (tx->base) {
        !           678:        case ASM:
        !           679:        {       Pbase b = Pbase(tp);
        !           680:                Pname n = tbl->insert(this,0);
        !           681:                n->assign();
        !           682:                n->use();
        !           683:                char* s = (char*) b->b_name;    // save asm string. Shoddy
        !           684:                int ll = strlen(s);
        !           685:                char* s2 = new char[ll+1];
        !           686:                strcpy(s2,s);
        !           687:                b->b_name = Pname(s2);
        !           688:                Cdcl = odcl;
        !           689:                return this;
        !           690:        }
        !           691: 
        !           692:        case CLASS:
        !           693:                tp = tx;
        !           694:                nn = dclass(this,tbl);
        !           695:                Cdcl = odcl;
        !           696:                return nn;
        !           697: 
        !           698:        case ENUM:
        !           699:                tp = tx;
        !           700:                nn = denum(this,tbl);
        !           701:                Cdcl = odcl;
        !           702:                return nn;
        !           703:        
        !           704:        case FCT:
        !           705:                tp = tx;
        !           706:                nn = dofct(tbl,scope);
        !           707:                if (nn == 0) {
        !           708:                        Cdcl = odcl;
        !           709:                        return 0;
        !           710:                }
        !           711: 
        !           712: // error('d', "%s n_oper: %k, scope: %k", string, n_oper, scope );
        !           713:                if (pdef_name == 0) check_def_name(nn, scope);
        !           714:                break;
        !           715: 
        !           716:        case FIELD:
        !           717:                switch (n_stclass) {
        !           718:                case 0:
        !           719:                case PUBLIC:
        !           720:                        break;
        !           721:                default:
        !           722:                        error("%k field",n_stclass);
        !           723:                        n_stclass = 0;
        !           724:                }
        !           725: 
        !           726:                if (cc->not==0 || cc->cot->csu==UNION || cc->cot->csu==ANON) {
        !           727:                        error(cc->not?"field in union":"field not inC");
        !           728:                        PERM(tp);
        !           729:                        Cdcl = odcl;
        !           730:                        return this;
        !           731:                }
        !           732: 
        !           733:                if (string) {
        !           734:                        nn = tbl->insert(this,0);
        !           735:                        n_table = nn->n_table;
        !           736:                        if (Nold) error("twoDs of field%n",this);
        !           737:                }
        !           738: 
        !           739:                tp->dcl(tbl);
        !           740:                field_align();
        !           741:                break;
        !           742:        
        !           743:        case COBJ:
        !           744:        {       Pclass cl = Pclass(Pbase(tx)->b_name->tp);
        !           745: //error('d',&where,"dcl %n; tx->base == cobj",this);
        !           746:                if (cl->lex_level > lex_level) 
        !           747:                        error("C%t is not visible in this scope",cl);
        !           748: 
        !           749:                if (cl->csu == ANON) {  // export member names to enclosing scope
        !           750:                         if (tbl==gtbl && n_sto!=STATIC) error("extern anonymous union (declare as static)");
        !           751:                        char* p = cl->string;
        !           752:                        while (*p++ != 'C');    /* sneaky */
        !           753:                        int uindex = (int)str_to_long(p);
        !           754: 
        !           755: // error('d', "%n->dcl() n_scope: %k n_protect: %k", this, n_scope, n_protect );
        !           756:                // cannot cope with use counts for ANONs:
        !           757:                        Pbase(tp)->b_name->n_used = 1;
        !           758:                        Pbase(tp)->b_name->n_assigned_to = 1;
        !           759: 
        !           760:                        Ptable mtbl = cl->memtbl;
        !           761:                         int i, err_msg = 0;
        !           762:                        for (Pname nn=mtbl->get_mem(i=1); nn; nn=mtbl->get_mem(++i)) {
        !           763:                                if (nn->tp->base == FCT) {
        !           764:                                        error("FM%n for anonymous union",nn);
        !           765:                                        break;
        !           766:                                }
        !           767:                                Ptable tb = nn->n_table;
        !           768:                                nn->n_table = 0;
        !           769:                                nn->n_scope = n_protect?n_protect:n_scope; 
        !           770:                                Pname n = tbl->insert(nn,0);
        !           771:                                if (Nold) {
        !           772:                                        error("twoDs of%n (one in anonymous union)",nn);
        !           773:                                        break;
        !           774:                                }
        !           775: 
        !           776:                                Pclass tc;
        !           777:                                if (tc = cl->in_class) 
        !           778:                                        --n->lex_level;
        !           779:                                if ( tc && tc->csu == ANON) {
        !           780: //error('d', "tc->csu anon %k %s", tc->csu, string );
        !           781:                                        if ( n->n_anon ) {
        !           782:                                                if ( !err_msg ) 
        !           783:                                                        error('s', "anonymous unions nested deeper than 2 levels" );
        !           784:                                                err_msg = 1;
        !           785:                                        }
        !           786:                                        n->n_anon = string;
        !           787:                                }
        !           788: 
        !           789:                                n->n_union = uindex;
        !           790:                                nn->n_table = tb;
        !           791:                        }
        !           792:                }
        !           793:                if (cl->c_abstract) error("D ofO of abstractC%t",cl);
        !           794:                goto cde;
        !           795:        }
        !           796: 
        !           797:        case VOID:
        !           798:                if (n_scope != ARG) {
        !           799:                        error("badBT:%k%n",tx->base,this);
        !           800:                        Cdcl = odcl;
        !           801:                        return 0;
        !           802:                }
        !           803:                break;
        !           804: 
        !           805: 
        !           806:        case PTR:
        !           807:        case VEC:
        !           808:        case RPTR:
        !           809:                tp->dcl(tbl);
        !           810: //             if (tp->base==PTR && Pptr(tp)->memof) {
        !           811: //                     Ptype t = Pptr(tp)->typ;
        !           812: //                     while (t->base==TYPE) t = Pbase(t)->b_name->tp;
        !           813: //                     if (t->base == FCT) {
        !           814: //                             // size and align
        !           815: //                     }
        !           816: //             }
        !           817: 
        !           818:        default:
        !           819:        cde:
        !           820: //error('d',"cde: %n %t",this,tp);
        !           821:                nn = tbl->insert(this,0);
        !           822:                n_table = nn->n_table;
        !           823: 
        !           824:                if (Nold) {
        !           825: 
        !           826:                        if ( nn->base == PUBLIC ) { // X::i
        !           827:                                error("twoDs ofCM%n", nn);
        !           828:                                Cdcl = odcl;
        !           829:                                return 0;
        !           830:                        }
        !           831: 
        !           832:                        if (nn->tp->base == ANY) goto zzz;
        !           833: 
        !           834:                        if (tp->check(nn->tp,0)) {
        !           835:                                error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp);
        !           836:                                Cdcl = odcl;
        !           837:                                return 0;
        !           838:                        }
        !           839: //error('d',"%n: %k %k scope %k",this,n_sto,nn->n_sto,nn->n_scope);
        !           840:                        if (n_sto && n_sto!=nn->n_scope) {
        !           841:                                if (n_sto==EXTERN && nn->n_scope==STATIC) {
        !           842:                                        error('w',"%n declared extern after being declared static",this);
        !           843:                                        goto ext_fudge;
        !           844:                                }
        !           845:                                else
        !           846:                                        error("%n declared as both%k and%k",this,n_sto,(nn->n_sto)?nn->n_sto:(scope==FCT?AUTO:EXTERN));
        !           847:                        }
        !           848:                        else if (nn->n_scope==STATIC && n_scope==EXTERN) {
        !           849:                                error('w',"static%n followed by definition",this);
        !           850:                        ext_fudge:
        !           851:                                if (n_initializer) {
        !           852: //                                     error('d',"static%n redefined (WIr)",this);
        !           853:                                        n_initializer = 0;
        !           854:                                }
        !           855:                                n_sto = EXTERN;
        !           856:                        }
        !           857:                        else if (nn->n_sto==STATIC && n_sto==STATIC ) 
        !           858:                                error("static%n declared twice",this);
        !           859:                        else {
        !           860:                                if (n_sto==0
        !           861:                                && nn->n_sto==EXTERN
        !           862:                                && n_initializer
        !           863:                                && tp->tconst())
        !           864:                                        n_sto = EXTERN;
        !           865:                                n_scope = nn->n_scope;
        !           866: 
        !           867:                                switch (scope) {
        !           868:                                case FCT:
        !           869:                                        if (n_sto != EXTERN) {
        !           870:                                                error("twoDs of%n",this);
        !           871:                                                Cdcl = odcl;
        !           872:                                                return 0;
        !           873:                                        }
        !           874:                                        break;
        !           875:                                case ARG:
        !           876:                                        error("twoAs%n",this);
        !           877:                                        Cdcl = odcl;
        !           878:                                        return 0;
        !           879:                                case 0:
        !           880:                                case PUBLIC:
        !           881:                                        error("twoDs ofM%n",this);
        !           882:                                        Cdcl = odcl;
        !           883:                                        return 0;
        !           884:                                case EXTERN:
        !           885:                                        if (n_sto==0) {
        !           886:                                                switch(nn->n_sto) {
        !           887:                                                case 0:
        !           888:                                                        error("two definitions of%n",this);
        !           889:                                                        Cdcl = odcl;
        !           890:                                                        return 0;
        !           891:                                                case EXTERN:
        !           892:                                                        if(nn->n_initializer) {
        !           893:                                                                error("two definitions of%n",this);
        !           894:                                                                Cdcl = odcl;
        !           895:                                                        }
        !           896:                                                        else
        !           897:                                                                nn->n_sto=0;
        !           898:                                                        break;
        !           899:                                                }
        !           900:                                        }
        !           901:                                        else if(n_sto==EXTERN && n_initializer) {
        !           902:                                                switch(nn->n_sto) {
        !           903:                                                case 0:
        !           904:                                                        error("two definitions of%n",this);
        !           905:                                                        Cdcl = odcl;
        !           906:                                                        return 0;
        !           907:                                                case EXTERN:
        !           908:                                                        nn->n_sto=0;
        !           909:                                                        break;
        !           910:                                                }
        !           911:                                        }
        !           912:                                        break;
        !           913:                                }
        !           914:                        }
        !           915:                        n_scope = nn->n_scope;
        !           916: /* n_val */
        !           917:                        if (n_initializer) {
        !           918:                                if (nn->n_initializer || nn->n_val) error("twoIrs for%n",this);
        !           919:                                nn->n_initializer = n_initializer;
        !           920:                        }
        !           921:                        if (tp->base == VEC) {
        !           922:                        //      handle:  extern v[]; v[200];
        !           923:                        //      and     extern u[10]; u[11];
        !           924: 
        !           925:                                Ptype ntp = nn->tp;
        !           926:                                while (ntp->base == TYPE) ntp = Pbase(ntp)->b_name->tp;
        !           927:                                if (Pvec(ntp)->dim == 0) Pvec(ntp)->dim = Pvec(tp)->dim;
        !           928:                                if (Pvec(ntp)->size) {
        !           929:                                        if (Pvec(tp)->size
        !           930:                                        && Pvec(ntp)->size!=Pvec(tp)->size)
        !           931:                                                error("bad array size for%n: %d %dX",this,Pvec(tp)->size,Pvec(ntp)->size);
        !           932:                                }
        !           933:                                else
        !           934:                                        Pvec(ntp)->size = Pvec(tp)->size;
        !           935:                        }
        !           936:                }
        !           937:                else {
        !           938: //error('d',"%n %t scope %d sto %k",this,tp,scope,n_sto);              
        !           939:                        if (scope!=ARG
        !           940:                        && n_sto!=EXTERN
        !           941:                        && (!((scope==0 || scope==PUBLIC) && n_sto==STATIC)) // static member
        !           942:                        && n_initializer==0
        !           943:                        && tp->base==VEC
        !           944:                        && Pvec(tp)->size==0)
        !           945:                                error(&where,"dimension missing for array%n",this);
        !           946: 
        !           947:                        if (scope==EXTERN
        !           948:                        && n_sto==0
        !           949:                        && tp->tconst()
        !           950:                        && vec_const==0
        !           951:                        && fct_const==0)
        !           952:                                nn->n_sto = n_sto = STATIC;
        !           953:                }
        !           954:        
        !           955:        zzz:
        !           956:                if (base != TNAME) {
        !           957:                        Ptype t = nn->tp;
        !           958: 
        !           959:                        if (t->base == TYPE) {
        !           960:                                Ptype tt = Pbase(t)->b_name->tp;
        !           961:                                if (tt->base == FCT) nn->tp = t = tt;
        !           962:                        }
        !           963: 
        !           964:                        switch (t->base) {
        !           965:                        case FCT:
        !           966:                        case OVERLOAD:
        !           967:                                break;
        !           968:                        default:
        !           969:                                fake_sizeof = 1;
        !           970:                                switch (nn->n_stclass) {
        !           971:                                default:
        !           972:                                        if (nn->n_scope != ARG) {
        !           973:                                                int x = t->align();
        !           974:                                                int y = t->tsizeof();
        !           975: 
        !           976:                                                if (max_align < x) max_align = x;
        !           977: 
        !           978:                                                while (0 < bit_offset) {
        !           979:                                                        byte_offset++;
        !           980:                                                        bit_offset -= BI_IN_BYTE;
        !           981:                                                }
        !           982:                                                bit_offset = 0;
        !           983: 
        !           984:                                                if (byte_offset && 1<x) byte_offset = ((byte_offset-1)/x)*x+x;
        !           985:                                                nn->n_offset = byte_offset;
        !           986:                                                byte_offset += y;
        !           987:                                        }
        !           988:                                        break;
        !           989:                                case STATIC:
        !           990:                                        if (n_sto != EXTERN
        !           991:                                        && nn->n_scope
        !           992:                                        && nn->n_scope!=PUBLIC)
        !           993:                                        t->tsizeof();   // check that size is known
        !           994:                                }
        !           995:                                fake_sizeof = 0;
        !           996:                        }
        !           997:                }
        !           998: 
        !           999:        {       Ptype t = nn->tp;
        !          1000:                int const_old = const_save;
        !          1001:                bit vec_seen = 0;
        !          1002:                Pexpr init = n_initializer;
        !          1003: 
        !          1004:        lll:
        !          1005: // error('d',"lll %n %t init %d %k",this,t,init,init?init->base:0);
        !          1006:                switch (t->base) {
        !          1007:                case COBJ:
        !          1008:                {       Pname cn = Pbase(t)->b_name;
        !          1009:                        Pclass cl = (Pclass)cn->tp;
        !          1010:                        Pname ctor = cl->has_ctor();
        !          1011:                        Pname dtor = cl->has_dtor();
        !          1012:                        int stct = 0;
        !          1013: //error('d',"obj %n; class '%s'; ctor '%s'; dtor '%s'",nn,cn->string,ctor?ctor->string:"???",dtor?dtor->string:"???");
        !          1014:                        if (dtor) {
        !          1015:                                Pstmt dls;
        !          1016: 
        !          1017:                                // if dtor is not public check scope of class object
        !          1018: 
        !          1019: //error('d',"dcl %n has dtor",nn);
        !          1020:                                if (dtor->n_scope != PUBLIC)  {
        !          1021: //error('d',"dcl %n->n_scope: %d fct %n",nn,nn->n_scope,cc->nof);
        !          1022:                                        switch (nn->n_scope) {
        !          1023:                                        case ARG:
        !          1024:                                        case 0:
        !          1025:                                        case PUBLIC:
        !          1026:                                                break;
        !          1027:                                        default: 
        !          1028:                                                check_visibility( dtor, 0, cl, tbl, cc->nof );
        !          1029:                                        }
        !          1030:                        //              if (nn->n_scope == FCT) 
        !          1031:                        //                      check_visibility( dtor, 0, cl, tbl, cc->nof );
        !          1032:                        //              else if ( nn->n_sto != EXTERN )
        !          1033:                        //                      error("%k%n cannot access%n: %sM",nn->n_scope,nn,dtor,dtor->n_protect?"protected":"private");
        !          1034:                                }
        !          1035: 
        !          1036:                                switch ( nn->n_scope ) {
        !          1037:                                case 0:
        !          1038:                                case PUBLIC:
        !          1039: //error('d',"%n->n_scope == %s",nn,nn->n_scope?"public":"0");
        !          1040:                                        if (n_stclass==STATIC) { //III
        !          1041:                                                Pclass cl = Pclass(nn->n_table->t_name->tp);
        !          1042: //error('d',"sto_class static;  %t",cl);
        !          1043:                                                if (cl->defined&DEFINED) goto dtdt;
        !          1044:                                        }
        !          1045:                                        break;
        !          1046:                                case EXTERN:
        !          1047: //error('d',"%n->n_scope == extern;  n_sto==%d",nn,n_sto);
        !          1048:                                        if (n_sto==EXTERN) break;
        !          1049: 
        !          1050:                                case STATIC:
        !          1051: //error('d',"%n->n_scope == static",nn);
        !          1052:                                {       Pexpr c;
        !          1053:                                dtdt:
        !          1054: // local static class objects have destructors set up in simpl2.c
        !          1055:                                        if ( nn->lex_level
        !          1056:                                        &&   nn->n_sto == STATIC ) {
        !          1057: //error('d',"%n->dcl nn->ll: %d nn->n_sto: %k", nn, nn->lex_level, nn->n_sto );
        !          1058: //error('d',"dtor:  ctor: %d", ctor ); 
        !          1059:                                                if (ctor==0) 
        !          1060:                                                    error('s',"local static%n has%n but noK(add%n::%n())", nn, dtor, cn, cn );
        !          1061:                                                goto stat_init;
        !          1062:                                        }
        !          1063: 
        !          1064:                                        Ptable otbl = tbl;
        !          1065:                                            // to collect temporaries generated
        !          1066:                                            // in static destructors where we
        !          1067:                                            // can find them again (in std_tbl)
        !          1068:                                        if (std_tbl == 0) std_tbl = new table(8,gtbl,0);
        !          1069:                                        tbl = std_tbl;
        !          1070:                                        if (vec_seen) {
        !          1071:                                                c = cdvec(vec_del_fct,nn,cl,dtor,0,zero);
        !          1072:                                        } else {        // nn->cl::~cl(0);
        !          1073:                                                c = call_dtor(nn,dtor,0,DOT,one);
        !          1074:                                        }
        !          1075:                                        c->tp = any_type; // avoid another check
        !          1076:                                        dls = new estmt(SM,nn->where,c,0);
        !          1077:                                        
        !          1078:                                        // destructors for statics are executed in reverse order
        !          1079:                                        if (st_dlist) dls->s_list = st_dlist;
        !          1080:                                        st_dlist = dls;
        !          1081:                                        tbl = otbl;
        !          1082:                                } // case STATIC
        !          1083:                                } // switch nn->n_scope
        !          1084:                        } // if dtor
        !          1085: 
        !          1086: // local static class objects must defer setting up static dtor
        !          1087: stat_init:
        !          1088:                        if (ctor) {
        !          1089: // error('d',"ctor %n scope %k",ctor,nn->n_scope);
        !          1090:                                Pexpr oo = nn;
        !          1091:                                for (int vi=vec_seen; vi; vi--) oo = oo->contents();
        !          1092:                                int sti = 0;
        !          1093:                                switch (nn->n_scope) {
        !          1094:                                case EXTERN:
        !          1095:                                        if (init==0 && n_sto==EXTERN) goto ggg;
        !          1096:                                case STATIC:
        !          1097:                                        if (tbl == gtbl)
        !          1098:                                                sti = 1;
        !          1099:                                        else
        !          1100:                                                stct = 1;
        !          1101:                                default:
        !          1102:                                        if (vec_seen && init) {
        !          1103:                                                if (1<vec_seen) {
        !          1104: /* ?????
        !          1105:                                                        if (init->base != ILIST)
        !          1106:                                                                error("badIr forO ofC %t withK%n",cl,this);
        !          1107:                                                        else
        !          1108: */
        !          1109:                                                                error('s',"Ir for multi-dimensional array%n ofOsofC %t withK",this,cl);
        !          1110:                                                        }
        !          1111:                                                else {
        !          1112:                                                        if (sti) {
        !          1113:                                                                if (sti_tbl==0) sti_tbl = new table(8,gtbl,0);
        !          1114:                                                                const_save = 1;
        !          1115:                                                                (void) co_array_init(nn,sti_tbl);
        !          1116:                                                                const_save = 0;
        !          1117:                                                                n_initializer = init = 0;
        !          1118:                                                        }
        !          1119:                                                        else {
        !          1120:                                                                n_initializer = init = co_array_init(nn,tbl);
        !          1121:                                                                if (stct)  
        !          1122:                                                                        nn->n_initializer = n_initializer = init = new expr( STAT_INIT, init, 0 );
        !          1123:                                                        }
        !          1124:                                                }
        !          1125:                                                goto ggg;
        !          1126:                                        }
        !          1127:                                        break;
        !          1128:                                case PUBLIC:
        !          1129:                                case 0:
        !          1130:                                        if (n_stclass==STATIC) { //III
        !          1131:                                                Pclass cl = Pclass(nn->n_table->t_name->tp);
        !          1132:                                                if (cl->defined&DEFINED) {
        !          1133:                                                        sti = 1;
        !          1134:                                                        break;
        !          1135:                                                }
        !          1136:                                        }
        !          1137:                                        {
        !          1138:                                                Pname c;
        !          1139:                                                if (vec_seen) {
        !          1140:                                                        c = cl->has_ictor();
        !          1141:                                                        if (c == 0)
        !          1142:                                                                error("array ofC%n that does not have aK taking noAs",cn);
        !          1143:                                                        else if (Pfct(c->tp)->nargs)
        !          1144:                                                                error("defaultAs forK for array ofC%n",cn);
        !          1145:                                                }
        !          1146:                                        }
        !          1147:                                        // no break
        !          1148:                                case ARG:
        !          1149:                                        goto ggg;
        !          1150:                                }
        !          1151: 
        !          1152:                                const_save = 1;
        !          1153:                                nn->assign();
        !          1154:                                Ptable otbl = tbl;
        !          1155:                                if (sti) {      // to collect temporaries generated
        !          1156:                                                // in static initializers where we
        !          1157:                                                // can find them again (in sti_tbl)
        !          1158:                                        if (sti_tbl == 0) sti_tbl = new table(8,gtbl,0);
        !          1159:                                        tbl = sti_tbl;
        !          1160:                                        if (n_sto == EXTERN) nn->n_sto = n_sto = 0;
        !          1161:                                }
        !          1162: 
        !          1163:                                if (init) {
        !          1164: // error('d',"init %k",init->base);
        !          1165:                                        if (init->base==VALUE) {
        !          1166:                                                switch (init->tp2->base) {
        !          1167:                                                case CLASS:
        !          1168: // error('d',"class %t %t",Pclass(init->tp2),cl);
        !          1169:                                                        if (Pclass(init->tp2)!=cl) goto inin;
        !          1170:                                                        break;
        !          1171:                                                default:
        !          1172:                                                        Pname  n2 = init->tp2->is_cl_obj();
        !          1173: // error('d',"default %t %t",n2->tp,cl);
        !          1174:                                                        if (n2==0 || Pclass(n2->tp)!=cl) goto inin;
        !          1175:                                                }
        !          1176: 
        !          1177:                                                Pexpr ee = init->e1;
        !          1178: // error('d',"init->e1 %k",ee->base);
        !          1179:                                                if (ee && vec_seen==0)
        !          1180:                                                switch (ee->base) {
        !          1181:                                                case CALL:      // T a = f();
        !          1182:                                                        init = ee;
        !          1183:                                                        goto inin;
        !          1184:                                                case ELIST:     // T a(f());
        !          1185:                                                        if (ee->e1->base==CALL
        !          1186:                                                        && ee->e2 == 0) {
        !          1187:                                                                init = ee->e1;
        !          1188:                                                                goto inin;
        !          1189:                                                        }
        !          1190:                                                } // end switch
        !          1191: 
        !          1192:                                                init->e2 = oo;
        !          1193:                                                init = init->typ(tbl);
        !          1194: 
        !          1195:                                                if (init->base == G_CM) // beware of type conversion operators
        !          1196:                                                switch (init->tp2->base) {
        !          1197:                                                case CLASS:
        !          1198:                                                        if (Pclass(init->tp2)!=cl) goto inin;
        !          1199:                                                        break;
        !          1200:                                                default:
        !          1201:                                                        Pname  n2 = init->tp2->is_cl_obj();
        !          1202:                                                        if (n2==0 || Pclass(n2->tp)!=cl) goto inin;
        !          1203:                                                }
        !          1204:                                        }
        !          1205:                                        else {
        !          1206:                                        inin:
        !          1207: // error('d',"inin %k",init->base);
        !          1208:                                                init = init->typ(tbl);
        !          1209: //error('d', "inin: init->typ: %d %k n->tp %t init->tp %t",init->base,init->base,nn->tp,init->tp);
        !          1210:                                                if (init->base==G_CM
        !          1211:                                                && nn->tp->check(init->tp,0)==0)
        !          1212:                                                        (void) replace_temp(init,nn->address());
        !          1213:                                                else
        !          1214:                                                        init = class_init(nn,nn->tp,init,tbl);
        !          1215:                                        }
        !          1216:                                }
        !          1217:                                else if (vec_seen == 0) {
        !          1218: //error('d',"make value");
        !          1219:                                        init = new texpr(VALUE,cl,0);
        !          1220:                                        init->e2 = oo;
        !          1221:                                        init = init->typ(tbl);
        !          1222:                                }
        !          1223: 
        !          1224:                                Pname c;
        !          1225:                                if (vec_seen) {
        !          1226:                                        c = cl->has_ictor();
        !          1227:                                        if (c == 0)
        !          1228:                                                error("array ofC%n that does not have aK taking noAs",cn);
        !          1229:                                        else if (Pfct(c->tp)->nargs)
        !          1230:                                                error("defaultAs forK for array ofC%n",cn);
        !          1231:                                }
        !          1232: 
        !          1233: // error( 'd', "stct: %d init: %d", stct, init );
        !          1234:                                if (stct) {
        !          1235:                                        if (tbl!=gtbl && nn->n_sto==EXTERN) {
        !          1236:                                                error(&where,"Id local extern%n",this);
        !          1237:                                                init = 0;
        !          1238:                                        }
        !          1239:                                        else if (init) 
        !          1240:                                                init->base = STAT_INIT;
        !          1241:                                        else {
        !          1242:                                                if (tp->base == VEC && Pvec(tp)->size ) {
        !          1243:                                                        Pexpr ilist = 0;
        !          1244:                                                        for (int i=Pvec(tp)->size; i>0; i--) {
        !          1245:                                                                Pexpr e = new texpr(VALUE,cl,0);
        !          1246:                                                                ilist = new expr(ELIST, e, ilist);
        !          1247:                                                        }
        !          1248:                                                        nn->n_initializer=new expr(ILIST,ilist,0);
        !          1249:                                                        init = co_array_init(nn,tbl);
        !          1250:                                                        nn->n_initializer = n_initializer = init = new expr( STAT_INIT, init, 0 );
        !          1251:                                                }
        !          1252:                                                else
        !          1253:                                                error('s',"local staticC%n (%t)",this, tp);
        !          1254:                                        }
        !          1255:                                }
        !          1256: 
        !          1257: // error('d', "%n->sti: %d vec_seen: %d n_stclass: %k", this, sti, vec_seen, n_stclass );
        !          1258:        if (sti) {
        !          1259:                if (vec_seen) { // _vec_new(vec,noe,sz,ctor);
        !          1260: // error('d', "%n->dcl: n_stclass: %k ", this, n_stclass );
        !          1261:                        if ( n_stclass == STATIC && n_initializer ) {
        !          1262:                                const_save = 1;
        !          1263:                                (void) co_array_init(nn,sti_tbl);
        !          1264:                                const_save = 0;
        !          1265:                                n_initializer = init = 0;
        !          1266:                                goto ggg;
        !          1267:                        }
        !          1268: 
        !          1269:                        init = cdvec(vec_new_fct,nn,cl,c,-1,0);
        !          1270:                        init->tp = any_type;
        !          1271:                }
        !          1272:                else {
        !          1273:                        switch (init->base) {
        !          1274:                        case DEREF:             // *constructor?
        !          1275:                                if (init->e1->base == G_CALL) { 
        !          1276:                                        Pname fn = init->e1->fct_name;
        !          1277:                                        if (fn==0 || fn->n_oper!=CTOR) goto as;
        !          1278:                                        init = init->e1;
        !          1279:                                        break;
        !          1280:                                }
        !          1281:                                goto as;
        !          1282:                        case G_CM:
        !          1283:                                init = init->e1;
        !          1284:                                        // suppress further type checking
        !          1285:                                if (init->tp == 0) init->tp= any_type; 
        !          1286:                                break;
        !          1287:                        case ASSIGN:
        !          1288:                                if (init->e1 == nn) break;      // simple assignment
        !          1289:                        as:     
        !          1290:                        default:        
        !          1291:                                init = new expr(ASSIGN,nn,init);
        !          1292:                        }
        !          1293:                }
        !          1294:                Pstmt ist = new estmt(SM,nn->where,init,0);
        !          1295:                // constructors for statics are executed in order
        !          1296:                if (st_ilist == 0)
        !          1297:                        st_ilist = ist;
        !          1298:                else
        !          1299:                        itail->s_list = ist;
        !          1300:                itail = ist;
        !          1301:                init = 0;       // suppress further processing
        !          1302:        } // if (sti)
        !          1303:                                nn->n_initializer = n_initializer = init;
        !          1304:                                const_save = const_old;
        !          1305:                                tbl = otbl;
        !          1306:                        }
        !          1307:                        else if (init == 0)             // no initializer
        !          1308:                                goto str;
        !          1309:                        else if (cl->is_simple()
        !          1310:                        //      && cl->csu!=UNION       // accept ANSIism
        !          1311:                                && cl->csu!=ANON
        !          1312:                                ) {     // struct
        !          1313:                                init = init->typ(tbl);
        !          1314:                                if (nn->tp->check(init->tp,0)==0
        !          1315:                                && init->base==G_CM) 
        !          1316:                                        (void) replace_temp(init,nn->address());
        !          1317:                                else {
        !          1318:                                        if (ansi_opt==0
        !          1319:                                        && init->base==ILIST
        !          1320:                                        && cl->csu==UNION)
        !          1321:                                                error('s',"initialization of union withIL");
        !          1322:                                        goto str;
        !          1323:                                }
        !          1324:                        }
        !          1325:                        else if (init->base == ILIST) { // class or union
        !          1326:                                error("cannotI%nWIrL",nn);
        !          1327:                        }
        !          1328:                        else {                  // bitwise copy ok?
        !          1329:                                                // possible to get here?
        !          1330:                                init = init->typ(tbl);
        !          1331: //error('d',"init22 %t %t",nn->tp,init->tp);
        !          1332:                                if (nn->tp->check(init->tp,0)==0) {
        !          1333:                                        if (init->base==G_CM) 
        !          1334:                                                (void) replace_temp(init,nn->address());
        !          1335:                                        else
        !          1336:                                                goto str;
        !          1337:                                }
        !          1338:                                goto str;
        !          1339:                        //      else
        !          1340:                        //              error("cannotI%n:%k %s has noK",nn,cl->csu,cl->string);
        !          1341:                        }
        !          1342:                        break;
        !          1343:                }
        !          1344:                case VEC:       
        !          1345:                        t = Pvec(t)->typ;
        !          1346:                        vec_seen++;
        !          1347:                        goto lll;
        !          1348:                case TYPE:
        !          1349:                        if (init==0 && Pbase(t)->b_const) {
        !          1350:                                switch (n_scope) {
        !          1351:                                case ARG:
        !          1352:                                        break;
        !          1353:                                case 0:
        !          1354:                                case PUBLIC:
        !          1355:                                        if ( cc->cot ) break;
        !          1356:                                default: {
        !          1357:                                        Pname n = t->is_cl_obj();
        !          1358:                                        Pclass cl;
        !          1359:                                        if ( n ) cl = Pclass( n->tp );
        !          1360: 
        !          1361:                                        if (n_sto!=EXTERN && 
        !          1362:                                           (n==0 || (cl->has_ctor()==0 && is_empty(cl,1)==0))) 
        !          1363:                                                error("uninitialized const%n",this);
        !          1364:                                        }
        !          1365:                                }
        !          1366:                        }
        !          1367:                        t = Pbase(t)->b_name->tp;
        !          1368:                        goto lll;
        !          1369:                case RPTR:
        !          1370:                        if (init) {
        !          1371:                                if (nn->n_scope == ARG) break;
        !          1372:                                if (Pptr(nn->tp)->memof) error("R toCM%n ofT%t illegal",nn,nn->tp);
        !          1373:                                ref_initializer++;
        !          1374:                                init = init->typ(tbl);
        !          1375:                                ref_initializer--;
        !          1376:                                Nvirt = 0; // set within ref_init() call
        !          1377:                                const_ptr = Pbase(Pptr(t)->typ)->tconst(); 
        !          1378: 
        !          1379:                                if (n_sto==STATIC
        !          1380:                                && init->lval(0)==0
        !          1381:                                && fct_const==0)
        !          1382:                                        error("Ir for staticR%n not an lvalue",this);
        !          1383:                                else
        !          1384:                                        nn->n_initializer = n_initializer = init = ref_init(Pptr(t),init,tbl);
        !          1385: 
        !          1386:                                const_ptr = 0;
        !          1387:                                if (Nvirt == VIRTUAL) sti_vb = 1;
        !          1388:                                nn->assign();
        !          1389: 
        !          1390:                                if (init->base==ILIST && init->e2==0) {
        !          1391:                                        new_list(init);
        !          1392:                                        list_check(nn,nn->tp,0,tbl);
        !          1393:                                        if (next_elem()) error(&where,"IrL too long");
        !          1394:                                }
        !          1395: 
        !          1396:                        }
        !          1397:                        else {
        !          1398:                                switch (nn->n_scope) {
        !          1399:                                default:
        !          1400:                                        if (n_sto == EXTERN) break;
        !          1401:                                        error("uninitializedR%n",this);
        !          1402:                                case ARG:
        !          1403:                                        break;
        !          1404:                                case PUBLIC:
        !          1405:                                case 0:
        !          1406:                        //III           if (n_sto == STATIC) error("a staticM%n cannot be aR",this);
        !          1407: // error('d', "%n->dcl cot: %s", this, cc->cot?cc->cot->string:"notset");
        !          1408:                                        if ( cc->cot == 0 )
        !          1409:                                                error("uninitializedR%n",this);
        !          1410:                                        break;
        !          1411:                                }
        !          1412:                        }
        !          1413:                        goto stgg;
        !          1414:                default:
        !          1415:                str:
        !          1416: // error('d',"str %n %t %k %t",this,tp,init?init->base:0,init?init->tp:0);
        !          1417:                        if (init == 0) {
        !          1418:                                switch (n_scope) {
        !          1419:                                case ARG:
        !          1420:                                        break;
        !          1421:                                case 0:
        !          1422:                                case PUBLIC:
        !          1423:                                        if ( cc->cot ) break;
        !          1424:                                default:
        !          1425:                                        if (n_sto!=EXTERN && t->tconst()) error("uninitialized const%n",this);
        !          1426:                                }
        !          1427: 
        !          1428:                                break;
        !          1429:                        }
        !          1430: 
        !          1431:                        const_save =       const_save
        !          1432:                                        || n_scope==ARG
        !          1433:                                        || (t->tconst() && vec_const==0);
        !          1434: 
        !          1435:                        if ( tp->base == PTR ) {
        !          1436:                                if ( cc && cc->nof 
        !          1437:                                        && Pfct(cc->nof->tp)->f_const ) 
        !          1438:                                                cm_const_save = Pbase(Pptr(tp)->typ)->b_const; 
        !          1439:                                const_ptr = Pbase(Pptr(tp)->typ)->b_const; 
        !          1440:                        }
        !          1441:                        nn->n_initializer = n_initializer = init = init->typ(tbl);
        !          1442:                        cm_const_save = 0;
        !          1443:                        const_ptr = 0;
        !          1444: 
        !          1445:                        if (const_save) PERM(init);
        !          1446:                        nn->assign();
        !          1447:                        const_save = const_old;
        !          1448: //error('d',"init2 %k %t",init->base,init->tp);
        !          1449:                        switch (init->base) {
        !          1450:                        case ILIST:
        !          1451:                                if (init->e2) goto dfdf;//break; // pointer to member
        !          1452:                                new_list(init);
        !          1453:                                list_check(nn,nn->tp,0,tbl);
        !          1454:                                if (next_elem()) error(&where,"IrL too long");
        !          1455:                                break;
        !          1456:                        case STRING:
        !          1457:                        {       Ptype v = nn->tp;
        !          1458:                                while (v->base == TYPE) v = Pbase(v)->b_name->tp;
        !          1459:                                if (v->base==VEC) {
        !          1460:                                        Ptype vv = Pvec(v)->typ;
        !          1461:                                        while(vv->base==TYPE) vv = Pbase(vv)->b_name->tp;
        !          1462:                                        if(vv->base==CHAR) {
        !          1463:                                                int sz = Pvec(v)->size;
        !          1464:                                                int isz = Pvec(init->tp)->size;
        !          1465:                                                if (sz == 0)
        !          1466:                                                        Pvec(v)->size = isz;
        !          1467:                                                else if (sz < isz)
        !          1468:                                                        error(&where,"Ir too long (%d characters) for%n[%d]",isz,nn,sz);
        !          1469:                                                break;
        !          1470:                                        }
        !          1471:                                }
        !          1472:                                // no break
        !          1473:                        }
        !          1474:                        default:
        !          1475:                        dfdf:
        !          1476:                        {       Ptype nt = nn->tp;
        !          1477:                                int ntc = Pbase(nt)->b_const;
        !          1478: 
        !          1479:                                if (vec_seen) {
        !          1480:                                        error("badIr for array%n",nn);
        !          1481:                                        break;
        !          1482:                                }
        !          1483:                        tlx:
        !          1484:                                switch (nt->base) {
        !          1485:                                case TYPE:
        !          1486:                                        nt = Pbase(nt)->b_name->tp;
        !          1487:                                        ntc |= Pbase(nt)->b_const;
        !          1488:                                        goto tlx;
        !          1489:                                case INT:
        !          1490:                                case CHAR:
        !          1491:                                case SHORT:
        !          1492:                                case EOBJ:
        !          1493:                                //      if (init->base==ICON && init->tp==long_type)
        !          1494:                                //              error('w',"longIr constant for%k%n",nn->tp->base,nn);
        !          1495:                                {       Ptype t = init->tp;
        !          1496:                                csi:
        !          1497:                                        switch (t->base) {
        !          1498:                                        case TYPE:
        !          1499:                                                t = Pbase(t)->b_name->tp; goto csi;
        !          1500:                                        case LONG:
        !          1501:                                        case FLOAT:
        !          1502:                                        case DOUBLE:
        !          1503:                                        case LDOUBLE:
        !          1504:                                                error('w',"%tIdW %t",nt,init->tp);
        !          1505:                                        }
        !          1506:                                }
        !          1507:                                        // no break
        !          1508:                                case LONG:
        !          1509:                                        if (Pbase(nt)->b_unsigned
        !          1510:                                        && init->base==UMINUS
        !          1511:                                        && init->e2->base==ICON)
        !          1512:                                                error('w',"negativeIr for unsigned%n",nn);
        !          1513:                                        if (ntc && scope!=ARG) {
        !          1514:                                                long i;
        !          1515:                                                Neval = 0;
        !          1516:                                                i = init->eval();
        !          1517:                                                if (Neval == 0) {
        !          1518:                                                        DEL(init);
        !          1519:                                                        nn->n_evaluated = n_evaluated = 1;
        !          1520:                                                        nn->n_val = n_val = i;
        !          1521:                                                        DEL(init);
        !          1522:                                                        nn->n_initializer = n_initializer = 0;
        !          1523:                                                }
        !          1524:                                        }
        !          1525:                                        break;
        !          1526:                                case PTR:
        !          1527:                                        Nvirt = 0;
        !          1528:                                        nn->n_initializer = n_initializer = init = ptr_init(Pptr(nt),init,tbl);
        !          1529: //display_expr(init,string);
        !          1530:                                        if (Nvirt == VIRTUAL) sti_vb = 1;
        !          1531:                                        if (Pchecked) goto stgg;
        !          1532:                                } 
        !          1533: 
        !          1534:                        {       Pexpr x = try_to_coerce(nt,init,"initializer",tbl);
        !          1535:                                if (x) {
        !          1536:                                        nn->n_initializer = n_initializer = init = x;
        !          1537:                                        goto stgg;
        !          1538:                                }
        !          1539:                        }
        !          1540: //error('d',"check %t %t %k",nt,init->tp,init->base);
        !          1541:                //      if (nt->check(init->tp,ASSIGN)) {
        !          1542:                                Pname c1 = nt->is_cl_obj();
        !          1543:                                Pname c2 = init->tp->is_cl_obj();
        !          1544:                                if (c1
        !          1545:                                && c2
        !          1546:                                && Pclass(c2->tp)->has_base(Pclass(c1->tp))) {
        !          1547:                                        init = new texpr(CAST,new ptr(PTR,nt),init->address());
        !          1548:                                        init = init->typ(tbl);
        !          1549:                                        nn->n_initializer = n_initializer = init = init->contents();
        !          1550:                                        goto stgg;
        !          1551:                                }
        !          1552: 
        !          1553:                                if (nt->check(init->tp,ASSIGN)) {
        !          1554:                                        error("badIrT%t for%n (%tX)",init->tp,this,nn->tp);
        !          1555:                                        break;
        !          1556:                                }
        !          1557:                }
        !          1558: 
        !          1559:                stgg:
        !          1560: // error('d',"stgg %n init %k %t Nvirt: %k",this,init?init->base:0,init?init->tp:0, Nvirt);
        !          1561:                        if (init && n_stclass==STATIC && (sti_vb || need_sti(init))) {
        !          1562:                                /* check if non-static variables are used */
        !          1563:                                int local = (0<lex_level);
        !          1564: // error('d',"init %n %t local %d",nn,init->tp,local);
        !          1565:                                if (local==0) need_sti(init,tbl);       // save consts
        !          1566: 
        !          1567:                                Pptr r = nn->tp->is_ref();      //III
        !          1568: 
        !          1569:                                if (r) init = init->address();
        !          1570:                                init = new expr(ASSIGN,nn,init);
        !          1571: // error('d',"init r %t: nn %n %t init %t",r,nn,nn->tp,init->tp);
        !          1572:                                if (r)
        !          1573:                                        init->tp = nn->tp;
        !          1574:                                else if (nn->tp!=init->tp) { // static member refs
        !          1575:                                        TOK t = nn->tp->set_const(0);   //JJJ
        !          1576:                                        init = init->typ(tbl);
        !          1577:                                        nn->tp->set_const(t);           //JJJ
        !          1578:                                }
        !          1579: 
        !          1580:                                if (local) {
        !          1581:                                        if (init->base != ASSIGN) error('s',"Ir for local static too complicated");
        !          1582:                                        if (nn->n_sto == EXTERN) {
        !          1583:                                                error(&where,"Id local extern%n",this);
        !          1584:                                                        init = 0;
        !          1585:                                        }
        !          1586:                                        else init->base = STAT_INIT;
        !          1587:                                        nn->n_initializer = n_initializer = init;
        !          1588:                                        
        !          1589:                                }
        !          1590:                                else {
        !          1591:                                        Pstmt ist = new estmt(SM,nn->where,init,0);
        !          1592:                                        // constructors for statics are executed in order
        !          1593:                
        !          1594:                                        if (st_ilist == 0)
        !          1595:                                                st_ilist = ist;
        !          1596:                                        else
        !          1597:                                                itail->s_list = ist;
        !          1598:                                        itail = ist;
        !          1599:                                        nn->n_initializer = n_initializer = init = 0;   // suppress further processing
        !          1600:                                        nn->n_val = n_val = 1;
        !          1601:                                }
        !          1602:                        }
        !          1603:                        
        !          1604:                
        !          1605:                } /* switch */
        !          1606:        } /* block */
        !          1607:        } /* default */
        !          1608: 
        !          1609:        } /* switch */
        !          1610: ggg:
        !          1611: //error('d',"ggg");
        !          1612:        PERM(nn);
        !          1613:        switch (n_scope) {
        !          1614:        case FCT:
        !          1615:                nn->n_initializer = n_initializer;
        !          1616:                break;
        !          1617:        default:
        !          1618:        {       Ptype t = nn->tp;
        !          1619:        px:
        !          1620:                PERM(t);
        !          1621:                switch (t->base) {
        !          1622:                case PTR:
        !          1623:                case RPTR:
        !          1624:                case VEC:       t = Pptr(t)->typ; goto px;
        !          1625:                case TYPE:      t = Pbase(t)->b_name->tp; goto px;
        !          1626:                case FCT:       t = Pfct(t)->returns; goto px; /* args? */
        !          1627:                } 
        !          1628:        }
        !          1629:        }
        !          1630:        
        !          1631:        Cdcl = odcl;
        !          1632:        return nn;
        !          1633: }

unix.superglobalmegacorp.com

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