Annotation of researchv10no/cmd/cfront/optcfront/print2.c, revision 1.1

1.1     ! root        1: /*ident        "@(#)ctrans:src/print2.c        1.6" */
        !             2: /**************************************************************************
        !             3: 
        !             4:        C++ source for cfront, the C++ compiler front-end
        !             5:        written in the computer science research center of Bell Labs
        !             6: 
        !             7:        Copyright (c) 1984 AT&T, Inc. All Rights Reserved
        !             8:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
        !             9: 
        !            10: print2.c:
        !            11: 
        !            12:        print names and declarations
        !            13: 
        !            14: ****************************************************************************/
        !            15: 
        !            16: #include "cfront.h"
        !            17: #include "template.h"
        !            18: 
        !            19: bit Cast;
        !            20: int last_ll = 1;
        !            21: Pin curr_icall;
        !            22: char emode;
        !            23: int ntok;
        !            24: 
        !            25: static int MAIN;       // fudge to get _main() called by main()
        !            26: 
        !            27: #define eprint(e) if (e) Eprint(e)
        !            28: 
        !            29: #ifdef DENSE
        !            30: void chop(char*);
        !            31: #endif
        !            32: 
        !            33: void puttok(TOK t)
        !            34: /*
        !            35:        print the output representation of "t"
        !            36: */
        !            37: {
        !            38: //     if (t<=0 || MAXTOK<t) error("illegal token %d",t);
        !            39: //     char* s = keys[t];
        !            40: //     if (s == 0) error("V representation token %d",t);
        !            41: 
        !            42:        putstring(keys[t]);
        !            43: 
        !            44:        if (12<ntok++) {
        !            45:                ntok = 0;
        !            46:                last_line.putline();
        !            47:        }
        !            48:        else if (t == SM) {
        !            49:                ntok = 0;
        !            50:                putch('\n');
        !            51:                if (last_ll) last_line.line++;
        !            52:        }
        !            53:        else
        !            54:                putch(' ');
        !            55: }
        !            56: 
        !            57: #define MX     20
        !            58: #define NTBUF  10
        !            59: class dcl_buf {
        !            60:        /*
        !            61:                buffer for assembling declaration (or cast)
        !            62:                left contains CONST_PTR => *CONST
        !            63:                             CONST_RPTR => &CONST
        !            64:                                PTR     => *
        !            65:                                RPTR    => &
        !            66:                                LP      => (
        !            67:                right contains  RP      => )
        !            68:                                VEC     => [ rnode ]
        !            69:                                FCT     => ( rnode )
        !            70:                                FIELD   => : rnode
        !            71:        */
        !            72:        Pbase b;
        !            73:        Pname n;
        !            74:        TOK left[MX], right[MX];
        !            75:        Pnode   rnode[MX];
        !            76:        Pclass  lnode[MX];
        !            77:        int li, ri;
        !            78: public:
        !            79:        void    init(Pname nn)          { b=0; n=nn; li=ri=0; }
        !            80:        void    base(Pbase bb)          { b = bb; }
        !            81:        void    front(TOK t)            { left[++li] = t; }
        !            82:        void    front(Pclass c)         { left[++li] = MEMPTR; lnode[li] = c; }
        !            83:        void    back(TOK t, Pnode nod)  { right[++ri] = t; rnode[ri] = nod; }
        !            84:        void    paran()                 { front(LP); back(RP,0); }
        !            85:        void    put();
        !            86: } *tbufvec[NTBUF] = {0}, *tbuf = 0;
        !            87: 
        !            88: int freetbuf = 0;
        !            89: 
        !            90: void dcl_buf::put()
        !            91: {
        !            92:        int i;
        !            93:        Pfct ff = 0;
        !            94: 
        !            95:        if (MX<=li || MX<=ri) error('i',"T buffer overflow");
        !            96:        if (b == 0) error('i',"noBT%s",Cast?" in cast":"");
        !            97: 
        !            98:        if (n && n->n_sto && n->n_sto!=REGISTER) puttok(n->n_sto);
        !            99: 
        !           100:        b->dcl_print();
        !           101:        
        !           102:        for( ; li; li--) {
        !           103:                switch (left[li]) {
        !           104:                case LP:
        !           105:                        putch('(');
        !           106:                        break;
        !           107:                case PTR:
        !           108:                        putch('*');
        !           109:                        break;
        !           110:                case RPTR:
        !           111:                        if (emode)
        !           112:                                putch('&');
        !           113:                        else
        !           114:                                putch('*');
        !           115:                        break;
        !           116:                case CONST_PTR:
        !           117:                        if (emode)
        !           118:                                putstring("*const ");
        !           119:                        else
        !           120:                                putch('*');
        !           121:                        break;
        !           122:                case CONST_RPTR:
        !           123:                        if (emode)
        !           124:                                putstring("&const ");
        !           125:                        else
        !           126:                                putch('*');
        !           127:                        break;
        !           128:                case MEMPTR:
        !           129:                        if (lnode[li]) fprintf(out_file,"%s::",lnode[li]->string);
        !           130:                }
        !           131:        }
        !           132: 
        !           133:        if (n) n->print();
        !           134: 
        !           135:        for(i=1; i<=ri; i++) {
        !           136:                switch (right[i]) {
        !           137:                case RP:
        !           138:                        putch(')');
        !           139:                        break;
        !           140:                case VEC:
        !           141:                        putch('[');
        !           142:                        {       Pvec v = (Pvec) rnode[i];
        !           143:                                Pexpr d = v->dim;
        !           144:                                int s = v->size;
        !           145:                                if (d) d->print();
        !           146:                                if (s) fprintf(out_file,"%d",s);
        !           147:                        }
        !           148:                        putch(']');
        !           149:                        break;
        !           150:                case FCT:       // beware of function returning pointer to
        !           151:                                // function expressed witout typedef
        !           152:                {       Pfct f = Pfct(rnode[i]);
        !           153:                        if (f->body) ff = f;
        !           154:                        f->dcl_print();
        !           155:                        break;
        !           156:                }
        !           157:                case FIELD:
        !           158:                 {       Pbase f = (Pbase) rnode[i];
        !           159:                         Pexpr d = (Pexpr)f->b_name;
        !           160:                         int s = f->b_bits;
        !           161:                         putch(':');
        !           162:                         if (d)
        !           163:                                 d->print();
        !           164:                         else if (s)
        !           165:                                 fprintf(out_file,"%d",s);
        !           166:                         else
        !           167:                                 puttok(ZERO);
        !           168:                         break;
        !           169:                 }
        !           170:                }
        !           171:        }
        !           172: void print_body(Pfct);
        !           173:        if (ff && emode==0) print_body(ff);
        !           174: }
        !           175: 
        !           176: static Pexpr mk_zero_init( Ptype tt, Pname obname, Pname currname )
        !           177: /*
        !           178:        creates 0 initializer for defined objects
        !           179:        side effect: generates right nesting level for {}
        !           180: */
        !           181: {
        !           182: zaq:
        !           183:        switch (tt->base) {
        !           184:        case TYPE:
        !           185:                tt = Pbase(tt)->b_name->tp; goto zaq;
        !           186:        case VEC: // type a[size]; => type a[size] = {0};
        !           187:        {
        !           188:                if ( obname == currname ) {
        !           189:                //xxx initializing vectors blows up the size of some programs
        !           190:                        return 0;
        !           191:                } else {
        !           192:                        Pexpr i = mk_zero_init(Pvec(tt)->typ,obname,currname);
        !           193:                        if ( i == 0 ) return 0;
        !           194:                        return new expr( ILIST, i, 0 );
        !           195:                }
        !           196:        }
        !           197:        case COBJ: // "X a;" == "X a = {0};"
        !           198:        {
        !           199:                Pclass cl = Pclass(Pbase(tt)->b_name->tp);
        !           200:                if ( !ansi_opt && (cl->csu == ANON || cl->csu == UNION) ) {
        !           201:                    if ( warning_opt ) {
        !           202:                        // ridiculous handstands to avoid printing
        !           203:                        // compiler generated names in warning
        !           204:                        Ptype tn = obname->tp;
        !           205:                        for(;;) if(tn->base==VEC) tn=Pvec(tn)->typ; else break;
        !           206:                        if ( obname == currname && tt == tn ) {
        !           207:                            if ( cl->string[0]=='_' && cl->string[1]=='_' )
        !           208:                                error('w',&obname->where,"cannot generate zeroIr for%n ofT union; toI, compile with +a1 or insert non-union object as first member",obname);
        !           209:                            else
        !           210:                                error('w',&obname->where,"cannot generate zeroIr for%n ofT%t; toI, compile with +a1 or insert non-union object as first member",obname,obname->tp);
        !           211:                        } else { Pclass cx;
        !           212:                            if ( tn->base == COBJ
        !           213:                            &&   (cx=(Pclass)Pbase(tn)->b_name->tp,
        !           214:                                  cx->string[0]=='_' && cx->string[1]=='_') )
        !           215:                                error('w',&obname->where,"cannot generate zeroIr for%n (union or aggregate with union as first element); toI, compile with +a1 or insert non-union object as first member",obname);
        !           216:                            else
        !           217:                                error('w',&obname->where,"cannot generate zeroIr for%n ofT%t (union or aggregate with union as first element); toI, compile with +a1 or insert non-union object as first member",obname,obname->tp);
        !           218:                        }
        !           219:                    } // if warning_opt
        !           220:                    return 0;
        !           221:                }
        !           222:                Pbcl l = cl->baselist;
        !           223:                while ( l ) {
        !           224:                        if ( l->base == NAME ) cl = l->bclass;
        !           225:                        else return new expr(ILIST,zero,0);
        !           226:                        l = cl->baselist;
        !           227:                }
        !           228:                int i = 1;
        !           229:                Pname nn = cl->memtbl->get_mem(i);
        !           230:                for ( ;  nn;  nn = cl->memtbl->get_mem(++i) ) {
        !           231:                        Ptype tx = nn->tp;
        !           232:                        while ( tx->base == TYPE ) tx = Pbase(tx)->b_name->tp;
        !           233:                        if (nn->base==NAME
        !           234:                        && nn->n_union==0
        !           235:                        && tx->base!=FCT
        !           236:                        && tx->base!=OVERLOAD
        !           237:                        && tx->base!=CLASS
        !           238:                        && tx->base!=ENUM
        !           239:                        && nn->n_stclass != STATIC) {
        !           240:                                Pexpr i = mk_zero_init(tx,obname,nn);
        !           241:                                if ( i == 0 ) return 0;
        !           242:                                return new expr(ILIST,i,0);
        !           243:                        }
        !           244:                }
        !           245:                return 0;
        !           246:        }
        !           247:        case PTR:
        !           248:                if (tt->memptr()) {
        !           249:                        Pexpr i = new expr(ELIST,zero,zero);
        !           250:                        return new expr(ILIST,i,zero);
        !           251:                }
        !           252:                // no break
        !           253:        case RPTR:
        !           254:        case CHAR:
        !           255:        case SHORT:
        !           256:        case INT:
        !           257:        case EOBJ:
        !           258:        case LONG:
        !           259:        case FLOAT:
        !           260:        case DOUBLE:
        !           261:        case LDOUBLE:   // "int a;" == "int a = 0;"
        !           262:        case FIELD:
        !           263:        case ANY:
        !           264:                return zero;
        !           265:        }
        !           266:        return 0;
        !           267: }
        !           268: 
        !           269: void name::dcl_print(TOK list)
        !           270: /*
        !           271:        Print the declaration for a name (list==0) or a name list (list!=0):
        !           272:                For each name
        !           273:                (1) print storage class
        !           274:                (2) print base type
        !           275:                (3) print the name with its declarators
        !           276:        Avoid (illegal) repetition of basetypes which are class or enum declarations
        !           277:        (A name list may contain names with different base types)
        !           278:        list == SM :    terminator SM
        !           279:        list == 0:      single declaration with terminator SM
        !           280:        list == CM :    separator CM
        !           281: */
        !           282: {
        !           283:        if (error_count) return;
        !           284: 
        !           285:        for (Pname n=this; n; n=n->n_list) {
        !           286:                Ptype t = n->tp;
        !           287:                int sm = 0;
        !           288: 
        !           289: // error('d',"%s->dcl_print() tp %t sto %k",n->string,t,n->n_sto);
        !           290:                if (t == 0) error('i',"N::dcl_print(%n)T missing",n);
        !           291: 
        !           292:                if (n->n_stclass==ENUM) if (list) continue; else return;
        !           293: 
        !           294:                if (n->where.line!=last_line.line || n->where.file!=last_line.file)
        !           295: //fprintf(stderr,"%s ",n->string?n->string:"<0>"); n->where.put(stderr); fprintf(stderr,"  last "); last_line.put(stderr); putc('\n',stderr);
        !           296:                        if (last_ll = n->where.line)
        !           297:                                n->where.putline();
        !           298:                        else
        !           299:                                last_line.putline();
        !           300:        
        !           301:                int tc = Pbase(t)->b_const;
        !           302:                for (Ptype tt = t; tt->base==TYPE; tt = Pbase(tt)->b_name->tp)
        !           303:                        tc |= Pbase(tt)->b_const;
        !           304:  
        !           305:                switch (t->base) {
        !           306:                case CLASS:
        !           307: //fprintf(stderr,"class %s->dcl_print()\n",n->string);
        !           308:                        if (n->base != TNAME) {
        !           309:                                Pclass(t)->dcl_print(n);
        !           310:                                sm = 1;
        !           311:                        }
        !           312:                        break;
        !           313: 
        !           314:                case ENUM:
        !           315:                         Penum(t)->dcl_print(0);
        !           316:                        sm = 1;
        !           317:                        break;
        !           318: 
        !           319:                case FCT:
        !           320:                {       Pfct f = Pfct(t);
        !           321: 
        !           322:                        if (n->base == TNAME) puttok(TYPEDEF);
        !           323: 
        !           324: // error('d',"fct %n->dcl_print() printed %d body %d defined %d",n,n->n_dcl_printed,f->body,f->defined);
        !           325: // error('d',"n %d tbl %d tp %t inline %d",n,n->n_table,n->tp,f->f_inline);
        !           326:                        if (n->n_dcl_printed==2 // definition already printed
        !           327:                        || (n->n_dcl_printed==1 && f->body==0)
        !           328:                                                // declaration already printed
        !           329:                        ) {
        !           330:                                // don't print again
        !           331:                                sm = 1; // no SM
        !           332:                                break;
        !           333:                        }
        !           334: 
        !           335:                        if (f->f_result == 0) make_res(f);
        !           336: 
        !           337:                        if (f->body && n->n_sto==EXTERN) n->n_sto = 0;
        !           338: 
        !           339:                        if (f->f_inline && ((n->n_table!=gtbl) || strcmp(n->string,"main"))) {
        !           340:                                if (debug_opt)  {
        !           341: //error('d',"f %t defined %d inline %d",f,f->defined,f->f_inline);
        !           342:                                        if (f->defined&DEFINED
        !           343:                                        && f->defined&SIMPLIFIED
        !           344:                                        && f->f_inline!=ITOR)
        !           345:                                                goto prnt_def;
        !           346:                                        else if (n->n_dcl_printed==0)
        !           347:                                                goto prnt_dcl;
        !           348:                                        else {
        !           349:                                                sm = 1;
        !           350:                                                break;
        !           351:                                        }
        !           352:                                }
        !           353:                                if (f->f_virtual || n->n_addr_taken) {
        !           354:                                prnt_dcl:
        !           355: //error('d',"prnt_dcl %d %n %k",n,n,n->n_sto);
        !           356:                                        TOK st = n->n_sto;
        !           357:                                        Pblock b = f->body;
        !           358:                                        f->body = 0;
        !           359:                                        t->dcl_print(n);
        !           360:                                        n->n_dcl_printed = 1;
        !           361:                                        n->n_sto = st;
        !           362:                                        f->body = b;
        !           363:                                        break;
        !           364:                                }
        !           365:                                else
        !           366:                                        sm = 1; // no SM
        !           367:                        }
        !           368:                        else if ((f->defined&DEFINED)==0
        !           369:                                || (f->defined&SIMPLIFIED)==0)
        !           370:                                goto prnt_dcl;
        !           371:                        else if (n->n_table==gtbl && strcmp(n->string,"main")==0) {
        !           372:                                if (f->f_inline) {
        !           373:                                        if (warning_opt) {
        !           374:                                                error('w',"main() cannot be inlined");
        !           375:                                                error('w',"out-of-line copy of main() created");
        !           376:                                        }
        !           377:                                        n->n_sto=0;
        !           378:                                }
        !           379:                                MAIN = 1;
        !           380:                                gtbl->look("main",0)->use();
        !           381:                                f->f_signature = 0;
        !           382:                                t->dcl_print(n);
        !           383:                                n->n_dcl_printed = f->body?2:1;
        !           384:                                MAIN = 0;
        !           385:                        }
        !           386:                        else {
        !           387:                        prnt_def:
        !           388: // error('d',"prnt_def %n %k %d %k",n,n->n_oper,n,n->n_sto);
        !           389:                                if (n->n_oper==CTOR || n->n_oper==DTOR) {
        !           390:                                        Pclass cl = Pclass(n->n_table->t_name->tp);
        !           391:                                        if (cl->c_body == 3) cl->print_all_vtbls(cl);
        !           392:                                }
        !           393: 
        !           394:                                if ( n->n_sto == STATIC && 
        !           395:                                        pdef_name == 0 && def_name == 0 ) {
        !           396: // error('d', "printing ptbl_vec without first definition" );
        !           397:                                                pdef_name = n;
        !           398:                                                ptbl_init(0);
        !           399:                                }
        !           400:                                t->dcl_print(n);
        !           401:                                n->n_dcl_printed = f->body?2:1;
        !           402:                        }
        !           403:                        if (f->body) sm = 1;
        !           404:                        break;
        !           405:                }
        !           406: 
        !           407:                case OVERLOAD:
        !           408:                {
        !           409:                        for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l) {
        !           410:                                Pname nn = gl->f;
        !           411:                                Pfct f=(Pfct) nn->tp;
        !           412:                                if (f->defined) nn->dcl_print(0);
        !           413:                                sm = 1;
        !           414:                        }
        !           415:                        break;
        !           416:                }
        !           417: 
        !           418:                case ASM:
        !           419:                        fprintf(out_file,"asm(\"%s\")\n",(char*)Pbase(t)->b_name);
        !           420:                        break;
        !           421: 
        !           422:                case INT:
        !           423:                case EOBJ:
        !           424:                case CHAR:
        !           425:                case LONG:
        !           426:                case SHORT:
        !           427:                tcx:
        !           428:                        // do not allocate space for constants unless necessary
        !           429:                        if (tc
        !           430:                        && n->n_sto!=EXTERN     // extern const one;
        !           431:                                                // const one = 1;
        !           432:                                                // allocates storage
        !           433:                        && (n->n_scope==EXTERN  // FUDGE const one = 1;
        !           434:                                                // is treated as static
        !           435:                                                // need loader support
        !           436:                                || n->n_scope==STATIC
        !           437:                                || n->n_scope==FCT)
        !           438:                        ) {
        !           439:                                if (n->n_evaluated && n->n_addr_taken==0) {
        !           440:                                        sm = 1; /* no ; */
        !           441:                                        break;
        !           442:                                }
        !           443:                        }
        !           444:                        tc = 0;
        !           445:                        // no break;
        !           446: 
        !           447:                default:
        !           448:                {
        !           449: /*     
        !           450: //  don't print local instance of const
        !           451:                        if ( n->n_dcl_printed == 3 ) {
        !           452:                                sm = 1;
        !           453:                                break;
        !           454:                        }
        !           455: */
        !           456:                        Pexpr i = n->n_initializer;
        !           457:                        if (n->base == TNAME && n->n_key == NESTED) i = 0;
        !           458:                        if (tc) {
        !           459:                                switch (tt->base) {
        !           460:                                case CHAR:
        !           461:                                case SHORT:
        !           462:                                case INT:
        !           463:                                case LONG:
        !           464:                                case EOBJ:
        !           465:                                        goto tcx;
        !           466:                                }
        !           467:                        }
        !           468: 
        !           469:                        if (n->base == TNAME) {
        !           470:                                /* Always print template formals, even when they have the same 
        !           471:                         * formal name, since the instantiation name is different. This 
        !           472:                         * fix should not be required when the copy mechanism is in place. */
        !           473:                                if (! n_template_arg)
        !           474:                                        for (Pname tn=ktbl->look(n->string,HIDDEN); tn; tn=tn->n_tbl_list) 
        !           475:                                                if (tn && tn->lex_level && t==tn->tp) return;
        !           476:                                puttok(TYPEDEF);
        !           477:                        }
        !           478: 
        !           479:                        if (n->n_stclass == REGISTER) {
        !           480:                                // (imperfect) check against member functions
        !           481:                                // register s a; a.f() illegal
        !           482:                                Pname cln = n->tp->is_cl_obj();
        !           483:                                if (cln) {
        !           484:                                        Pclass cl = Pclass(cln->tp);
        !           485:                                        if (cl->csu!=CLASS
        !           486:                                        && cl->baselist==0
        !           487:                                        && cl->has_itor()==0
        !           488:                                        && cl->virt_count==0) puttok(REGISTER);
        !           489:                                }
        !           490:                                else
        !           491:                                        puttok(REGISTER);
        !           492:                        }
        !           493: 
        !           494:                        if (i) {
        !           495:                                if (n->n_sto==EXTERN && n->n_stclass==STATIC) {
        !           496:                                        n->n_initializer = 0;
        !           497:                                        t->dcl_print(n);
        !           498:                                        puttok(SM);
        !           499:                                        n->n_initializer = i;
        !           500:                                        n->n_sto = 0;
        !           501:                                        t->dcl_print(n);
        !           502:                                        n->n_sto = EXTERN;
        !           503:                                }
        !           504:                                else
        !           505:                                        t->dcl_print(n);
        !           506:                                if(n->n_table) {
        !           507:                                        Pname nn = n->n_table->look(n->string,0);
        !           508:                                        if(nn)
        !           509:                                                nn->n_dcl_printed = 1;
        !           510:                                        else
        !           511:                                                n->n_dcl_printed = 1;
        !           512:                                }
        !           513:                                else
        !           514:                                        n->n_dcl_printed = 1;
        !           515:                        }
        !           516:                        else if (n->n_evaluated && Pbase(t)->b_const) {
        !           517:                                if (n->n_sto==EXTERN && n->n_stclass==STATIC) {
        !           518:                                        int v = n->n_evaluated;
        !           519:                                        n->n_evaluated = 0;
        !           520:                                        t->dcl_print(n);
        !           521:                                        puttok(SM);
        !           522:                                        if (n->where.line!=last_line.line || n->where.file!=last_line.file)
        !           523:                                                if (last_ll = n->where.line)
        !           524:                                                        n->where.putline();
        !           525:                                                else
        !           526:                                                        last_line.putline();
        !           527:                                        n->n_evaluated = v;
        !           528:                                        n->n_sto = 0;
        !           529:                                        t->dcl_print(n);
        !           530:                                        n->n_sto = EXTERN;
        !           531:                                }
        !           532:                                else
        !           533:                                        t->dcl_print(n);
        !           534:                                if(n->n_table) {
        !           535:                                        Pname nn = n->n_table->look(n->string,0);
        !           536:                                        if(nn)
        !           537:                                                nn->n_dcl_printed = 1;
        !           538:                                        else
        !           539:                                                n->n_dcl_printed = 1;
        !           540:                                }
        !           541:                                else
        !           542:                                        n->n_dcl_printed = 1;
        !           543:                        }
        !           544:                        else {
        !           545: //error('d',"%n sto %k val %d stc %k",n,n->n_sto,n->n_val,n_stclass);
        !           546:                                if ((n->n_sto==0 || (n->n_val && n->n_evaluated==0))
        !           547:                                 && n_stclass==STATIC
        !           548:                                && n->n_sto!=STATIC
        !           549:                                 && n->n_table==gtbl) {
        !           550:                                         if (n->n_val && n->n_evaluated==0) { 
        !           551:                                                 // extern x = f();
        !           552:                                                 // generate int x = 0;       
        !           553:                                                 // plus dynamic initialization
        !           554:                                                 n->n_sto = 0;
        !           555:                                         }
        !           556: 
        !           557:                                        n->n_initializer = i = mk_zero_init(t,n,n);
        !           558:                                }
        !           559:                                t->dcl_print(n);
        !           560:                                if(n->n_table) {
        !           561:                                        Pname nn = n->n_table->look(n->string,0);
        !           562:                                        if(nn)
        !           563:                                                nn->n_dcl_printed = 1;
        !           564:                                        else
        !           565:                                                n->n_dcl_printed = 1;
        !           566:                                }
        !           567:                                else
        !           568:                                        n->n_dcl_printed = 1;
        !           569:                        }
        !           570: 
        !           571:                        if (n->n_scope!=ARG) {
        !           572:                                if (i) {
        !           573:                                        puttok(ASSIGN);
        !           574: 
        !           575:                                        Pexpr i2 = i;
        !           576:                                        while (i2->base == CAST) i2 = i2->e1;
        !           577:                                        if (i2->base == ILIST) i = i2;
        !           578:                                        if (t!=i->tp
        !           579:                                        && i->base!=ZERO
        !           580:                                        && i->base!=ILIST /*&& i->tp!=Pchar_type*/) {
        !           581:                                                Ptype t1 = n->tp;
        !           582:                                        cmp:
        !           583:                                                switch (t1->base) {
        !           584:                                                case TYPE:      
        !           585:                                                        t1 = Pbase(t1)->b_name->tp;
        !           586:                                                        goto cmp;
        !           587:                                                default:
        !           588:                                                        i->print();
        !           589:                                                        break;
        !           590:                                        //      case EOBJ:
        !           591:                                        //              goto cst;
        !           592:                                                case VEC:
        !           593:                                                        if (Pvec(t1)->typ->base==CHAR) {
        !           594:                                                                i->print();
        !           595:                                                                break;
        !           596:                                                        }
        !           597:                                                        // no break
        !           598:                                                case PTR:
        !           599:                                                case RPTR:
        !           600:                                                        if (i->tp==0 || n->tp->check(i->tp,0)) {
        !           601:                                           //      cst:
        !           602:                                                                putch('(');
        !           603:                                                                bit oc = Cast;
        !           604:                                                                Cast = 1;
        !           605:                                                                t->print();
        !           606:                                                                Cast = oc;
        !           607:                                                                putch(')');
        !           608:                                                        }
        !           609:                                                        eprint(i);
        !           610:                                                }
        !           611:                                        }
        !           612:                                        else {
        !           613:                                                if (i==zero) {
        !           614:                                                        while (t->base == TYPE) t = Pbase(t)->b_name->tp;
        !           615:                                        //              if (t->base == EOBJ) {
        !           616:                                        //                      putch('(');
        !           617:                                        //                      bit oc = Cast;
        !           618:                                        //                      Cast = 1;
        !           619:                                        //                      t->print();
        !           620:                                        //                      Cast = oc;
        !           621:                                        //                      putch(')');
        !           622:                                        //              }
        !           623:                                                }
        !           624:                                                eprint(i);
        !           625:                                                
        !           626:                                        //      i->print();
        !           627:                                        }
        !           628:                                }
        !           629:                                else if (n->n_evaluated) {
        !           630:                                        puttok(ASSIGN);
        !           631:                                        if (n->tp->base!=INT || n->tp->is_unsigned()) {
        !           632:                                                putstring("((");
        !           633:                                                bit oc = Cast;
        !           634:                                                Cast = 1;
        !           635:                                                n->tp->print();
        !           636:                                                Cast = oc;
        !           637:                                                fprintf(out_file,")%d)",n->n_val);
        !           638:                                        }
        !           639:                                        else
        !           640:                                                fprintf(out_file,"%d",n->n_val);
        !           641:                                }
        !           642:                        }
        !           643:                }
        !           644:                }
        !           645: 
        !           646:                switch (list) {
        !           647:                case SM:
        !           648:                        if (sm==0) puttok(SM);
        !           649:                        break;
        !           650:                case 0:
        !           651:                        if (sm==0) puttok(SM);
        !           652:                        return;
        !           653:                case CM:
        !           654:                        if (n->n_list) puttok(CM);
        !           655:                        break;
        !           656:                }
        !           657:        }
        !           658: } 
        !           659: 
        !           660: char *local_sign( Ptype pt )
        !           661: { // get function signature for local class
        !           662:        char buf[1024];
        !           663:        char* bb = pt->signature(buf);
        !           664:        int ll = bb-buf;
        !           665:        if (1023 < ll) error('i',"local class N buffer overflow");
        !           666:        char *p = new char[ll+1];
        !           667:        strcpy(p,buf);
        !           668:        return p;
        !           669: }
        !           670: 
        !           671: void enumdef::dcl_print(Pname cln)
        !           672: /*
        !           673: */
        !           674: {
        !           675:        // note: ***** modify to handle local enums 
        !           676: // error('d', "%t::dcl_print(%n) in_class: %t nested_sig: %s", this, cln, in_class, nested_sig );
        !           677:        char* s = nested_sig?nested_sig:(cln ? cln->string:0);
        !           678:        if ( nested_sig )
        !           679:                fprintf(out_file,"enum __%s { ",nested_sig);
        !           680:        else fprintf(out_file,"enum %s { ",string);
        !           681: 
        !           682:        for (Pname px, p=mem; p; p=px) {
        !           683:                px = p->n_list;
        !           684:                if (s) {
        !           685:                        if (p->n_evaluated)
        !           686:                                fprintf(out_file,"%s__%s = %d",p->string,s,p->n_val);
        !           687:                        else
        !           688:                                fprintf(out_file,"%s__%s",p->string,s);
        !           689:                }
        !           690:                else {
        !           691:                        if (p->n_evaluated)
        !           692:                                fprintf(out_file,"%s = %d",p->string,p->n_val);
        !           693:                        else
        !           694:                                fprintf(out_file,"%s",p->string);
        !           695:                }
        !           696:                if (px) puttok(CM);
        !           697:                p->n_initializer = 0;
        !           698:                delete p;
        !           699:        }
        !           700:        mem = 0;
        !           701:        puttok(RC);
        !           702:        puttok(SM);
        !           703: }
        !           704: 
        !           705: void name::print()
        !           706: { // print just the name itself
        !           707:        if (this == 0) error('i',"0->N::print()");
        !           708:        if (string == 0) {
        !           709:                if (emode) putch('?');
        !           710:                return;
        !           711:        }
        !           712: 
        !           713: // error( 'd', "%s->name::print(), base: %k", string, base );
        !           714:        switch (base) {
        !           715:        case TNAME:
        !           716:                if (n_key == NESTED && tpdef &&
        !           717:                        tpdef->nested_sig) {
        !           718:                        if ( emode == 0 ) {
        !           719:                                putstring( " __" );
        !           720:                                putst(tpdef->nested_sig);
        !           721:                        }
        !           722:                        else {
        !           723:                                putst(tpdef->in_class->string);
        !           724:                                putstring( "::" );
        !           725:                                putst(string);
        !           726:                        }
        !           727:                        return;
        !           728:                }
        !           729: 
        !           730:                if (emode && tp) {
        !           731:                        if (n_template_arg_string) {
        !           732:                                tp->dcl_print(0); return;
        !           733:                        } else
        !           734:                        if(tp->base == COBJ) {
        !           735:                                Pclass cl = Pclass(Pbase(tp)->b_name->tp);
        !           736:                                if(cl && cl->base == CLASS && 
        !           737:                                  (cl->class_base == instantiated_template_class)) {
        !           738:                                        Ptclass(cl)->inst->print_pretty_name(); return;
        !           739:                                }
        !           740:                        }
        !           741:                }
        !           742: 
        !           743:                putst(n_template_arg_string ? n_template_arg_string : string);
        !           744:                return;
        !           745: 
        !           746:        case MDOT:
        !           747:                Pexpr(this)->print();
        !           748:                return;
        !           749:        }
        !           750: 
        !           751:        if (emode) {
        !           752:                Ptable tbl;
        !           753:                char* cs = 0;
        !           754:                bit f = 0;
        !           755:                if (tp) {
        !           756:                        switch (tp->base) {
        !           757:                        case OVERLOAD:
        !           758:                        case FCT:
        !           759:                                f = 1;
        !           760:                        default:
        !           761:                                if (tbl=n_table) {
        !           762:                                        if (tbl == gtbl) {
        !           763:                                                if (f == 0) putstring("::");
        !           764:                                        }
        !           765:                                        else {
        !           766:                                                if (tbl->t_name) {
        !           767:                                                        Ptclass pc = Ptclass(tbl->t_name->tp);
        !           768:                                                        cs = tbl->t_name->string;
        !           769:                                                        if ((pc->base == CLASS)  && 
        !           770:                                                                (pc->class_base == instantiated_template_class))
        !           771:                                                                        pc->inst->print_pretty_name();
        !           772:                                                        else fprintf(out_file,"%s",cs);
        !           773:                                                        fprintf (out_file, "::") ;
        !           774:                                                }
        !           775:                                        }
        !           776:                                }
        !           777: 
        !           778:                                if (n_scope==ARG && strcmp(string,"this")==0) {
        !           779:                                        // tell which "this" it is
        !           780:                                        Ptype tt = Pptr(tp)->typ;
        !           781:                                        Pname cn = Pbase(tt)->b_name;
        !           782:                                        fprintf(out_file,"%s::",cn->string);
        !           783:                                }
        !           784: 
        !           785:                        case CLASS:
        !           786:                        case ENUM:
        !           787:                //      case TYPE:
        !           788:                                break;
        !           789:                        }
        !           790:                nop:
        !           791:                        switch (n_oper) {
        !           792:                        case TYPE:
        !           793:                                putstring("operator ");
        !           794:                                if (tp) Pfct(tp)->returns->dcl_print(0);
        !           795:                                break;
        !           796:                        case 0:
        !           797:                                putstring(string);
        !           798:                                break;
        !           799:                        case DTOR:
        !           800:                                putch('~');
        !           801:                        case CTOR:
        !           802:                                if (cs) {
        !           803:                                        if(tbl->t_name) {
        !           804:                                                Ptclass pc = Ptclass(tbl->t_name->tp);
        !           805:                                                if ((pc->base == CLASS) && 
        !           806:                                                        (pc->class_base == instantiated_template_class))
        !           807:                                                                pc->inst->print_pretty_name();
        !           808:                                                else putstring(cs);
        !           809:                                        }
        !           810:                                }
        !           811:                                else {
        !           812:                                        if (string)
        !           813:                                                fprintf(out_file,"%s()", n_template_arg_string 
        !           814:                                                        ? n_template_arg_string : string);
        !           815:                                        else putstring("constructor");
        !           816:                                        f = 0;
        !           817:                                }
        !           818:                                break;
        !           819:                        case TNAME:
        !           820:                                putstring(string);
        !           821:                                break;
        !           822:                        default:
        !           823:                                putstring("operator ");
        !           824:                                putstring(keys[n_oper]);
        !           825:                                break;
        !           826:                        }
        !           827:                        if (f) putstring("()");
        !           828:                }
        !           829:                else {
        !           830:                        if (n_oper) goto nop;
        !           831:                        if (string) 
        !           832:                                putstring(n_template_arg_string 
        !           833:                                        ? n_template_arg_string : string);
        !           834:                }
        !           835:                return;
        !           836:        }
        !           837:        
        !           838:        char* sig = 0;
        !           839:        Pclass cl = 0;
        !           840:        Penum en = 0;
        !           841:        int i = n_union;
        !           842: 
        !           843:        if (tp) {
        !           844:                Ptable tbl;
        !           845: 
        !           846:                switch (tp->base) {
        !           847:                default:
        !           848:                        if (tbl=n_table) {      // global or member
        !           849:                                Pname tn;
        !           850:                                if (tbl == gtbl) {
        !           851:                                        // if (i) fprintf(out_file,"__O%d.",i);
        !           852:                                        if ( i ) {
        !           853:                                                if (n_anon) 
        !           854:                                                fprintf(out_file,"__O%d.%s.", i, n_anon );
        !           855:                                        else fprintf(out_file,"__O%d.",i);
        !           856:                                        }
        !           857:                                        break;
        !           858:                                }
        !           859: 
        !           860:                                if (tn=tbl->t_name) { 
        !           861:                                        cl = Pclass(tn->tp);
        !           862:                                        if (i) { 
        !           863:                                                if (cl->string[0]=='_'  
        !           864:                                                    && cl->string[1]=='_'
        !           865:                                                    && cl->string[2]=='C' ) {
        !           866:                                                        if (n_anon)
        !           867:                                                                fprintf(out_file,"__O%d.%s.", i, n_anon );
        !           868:                                                        else fprintf(out_file,"__O%d.",i);
        !           869:                                                }
        !           870:                                                else
        !           871:                                                if ( cl->nested_sig ) 
        !           872:                                                        fprintf(out_file,"__O%d__%s.",i,cl->nested_sig);
        !           873:                                                else
        !           874:                                                if ( cl->lex_level ) {
        !           875:                                                        char *str = make_local_name(cl,1);
        !           876:                                                        fprintf(out_file,"__O%d%s.",i,str);
        !           877:                                                        delete str;
        !           878:                                                }
        !           879:                                                else fprintf(out_file,"__O%d__%d%s.",i,cl->strlen,cl->string);
        !           880:                                                cl = 0;
        !           881:                                        }
        !           882:                                        else 
        !           883:                                        if (cl->string[0]=='_'
        !           884:                                                && cl->string[1]=='_'
        !           885:                                                && cl->string[2]=='C'
        !           886:                                                && n_stclass != STATIC )
        !           887:                                                        cl = 0;
        !           888:                                        break;
        !           889:                                }
        !           890:                        }
        !           891: 
        !           892:                        switch (n_stclass) {    // local variable
        !           893:                        case STATIC:
        !           894:                        case EXTERN:
        !           895:                                if (i)
        !           896:                                        fprintf(out_file,"__O%d.",i);
        !           897:                                else if (n_sto==STATIC && tp->base!=FCT) {
        !           898:                                        if (lex_level == 0)
        !           899:                                                putstring("__S");
        !           900:                                        else
        !           901:                                                fprintf(out_file,"__%d",lex_level);
        !           902:                                }
        !           903:                                break;
        !           904:                        default:
        !           905:                                // encode with lexical level UNLESS ``special''
        !           906:                                // e.g. __builtin
        !           907:                                if (string[0]!='_' || string[1]!='_' || string[2] != 'C' ) {
        !           908:                                        if (i)
        !           909:                                        {
        !           910:                                                if (n_anon)
        !           911:                                                    fprintf(out_file,"__%d__O%d.%s.",lex_level-1,i,n_anon);
        !           912:                                                else fprintf(out_file,"__%d__O%d.",lex_level-1,i);
        !           913:                                        }
        !           914:                                        else
        !           915:                                                fprintf(out_file,"__%d",lex_level);
        !           916:                                }
        !           917:                        }
        !           918:                        break;
        !           919:                case CLASS:
        !           920:                case ENUM:
        !           921:                        if (tp->in_class && tp->nested_sig) en = Penum(tp);
        !           922:                        break;
        !           923:                }
        !           924: 
        !           925:                if (tp->base==FCT) {
        !           926:                        sig = Pfct(tp)->f_signature;
        !           927:                        if (sig && sig[0]==0) sig = 0;
        !           928:                }
        !           929:        }
        !           930: 
        !           931:        if (string) {
        !           932: #ifdef DENSE
        !           933:                int i = strlen(string);
        !           934:                if (cl) i += cl->strlen+4;      // __dd<class name>
        !           935:                if (sig) {
        !           936:                        if (cl == 0) i += 2;
        !           937:                        i += strlen(sig);
        !           938:                }
        !           939: 
        !           940:                if (31<i) {
        !           941:                        char buf[256];
        !           942:                        if (cl && sig)
        !           943:                                sprintf(buf,"%s__%d%s%s",string,cl->strlen,cl->string,sig);
        !           944:                        else if (cl)
        !           945:                                sprintf(buf,"%s__%d%s",string,cl->strlen,cl->string);
        !           946:                        else if (sig)
        !           947:                                sprintf(buf,"%s__%s",string,sig);
        !           948:                        else 
        !           949:                                sprintf(buf,"%s",string);
        !           950:                        chop(buf);
        !           951:                        fprintf(out_file,"%s ",buf);
        !           952:                        return;
        !           953:                }
        !           954: #endif
        !           955: 
        !           956:                if ( en )
        !           957:                        fprintf(out_file,"__%s", en->nested_sig);
        !           958:                else 
        !           959:                        putstring(n_template_arg_string 
        !           960:                                ? n_template_arg_string : string);
        !           961: 
        !           962:                if ( cl ) {
        !           963:                        if ( cl->nested_sig )
        !           964:                                fprintf(out_file,"__%s",cl->nested_sig);
        !           965:                        else
        !           966:                        if ( cl->lex_level ) {
        !           967:                                char *str = make_local_name( cl, 1 );
        !           968:                                putstring( str );
        !           969:                                delete str;
        !           970:                        }
        !           971:                        else fprintf(out_file,"__%d%s",cl->strlen,cl->string);
        !           972:                }
        !           973: 
        !           974:                if (sig) {
        !           975:                        if (cl == 0) putstring("__");
        !           976:                        putstring(sig);
        !           977:                }
        !           978:                putch(' ');
        !           979:        }
        !           980: }
        !           981: 
        !           982: #ifdef DENSE
        !           983: void chop(char* buf)
        !           984: {
        !           985:        static char alpha[] = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        !           986:        static const asz = sizeof(alpha)-1;
        !           987:        int hash = 0;
        !           988:        char* p = &buf[29];
        !           989:                        
        !           990:        while (*p) {
        !           991:                hash <<= 1;
        !           992:                if (hash & (1<<12)) {
        !           993:                        hash &= ~(1<<12);
        !           994:                        hash++;
        !           995:                }
        !           996:                hash ^= *p++;
        !           997:        }
        !           998: 
        !           999:        buf[29] = alpha[(int)(hash%asz)];
        !          1000:        buf[30] = alpha[(int)((hash/asz)%asz)];
        !          1001:        buf[31] = 0;
        !          1002: }
        !          1003: #endif
        !          1004: 
        !          1005: void type::print()
        !          1006: {
        !          1007:        switch (base) {
        !          1008:        case PTR:
        !          1009:        case RPTR:
        !          1010:        case VEC:
        !          1011:                Pptr(this)->dcl_print(0);
        !          1012:                break;
        !          1013:        case FCT:
        !          1014:                Pfct(this)->dcl_print();
        !          1015:                break;
        !          1016: //     case VEC:
        !          1017: //             Pvec(this)->dcl_print(0);
        !          1018: //             break;
        !          1019:        case CLASS:
        !          1020:        case ENUM:
        !          1021:                if (emode)
        !          1022:                        fprintf(out_file,"%k",base);
        !          1023:                else
        !          1024:                //      error('i',"%p->T::print(%k %s)",this,base,Pclass(this)->string);        
        !          1025:                        fprintf(out_file,"struct %s *",Pclass(this)->string);
        !          1026:                break;
        !          1027:        case TYPE:
        !          1028:                if (Cast||Pbase(this)->b_name->lex_level) {
        !          1029:                        Pbase(this)->b_name->tp->print();
        !          1030:                        break;
        !          1031:                }
        !          1032:                // no break
        !          1033:        default:
        !          1034:                Pbase(this)->dcl_print();
        !          1035:        }
        !          1036: }
        !          1037: 
        !          1038: char* type::signature(register char* p)
        !          1039: /*
        !          1040:        take a signature suitable for argument types for overloaded
        !          1041:        function names
        !          1042: */
        !          1043: {
        !          1044:        Ptype t = this;
        !          1045:        int pp = 0;     // pointer to
        !          1046: 
        !          1047: xx:
        !          1048: //error('d',"xx(%d) %d %k",this,t,t->base);
        !          1049: 
        !          1050:        // first unroll typedefs and handle derived types:
        !          1051: 
        !          1052:        switch (t->base) {
        !          1053:        case TYPE:
        !          1054:                if (Pbase(t)->b_const) *p++ = 'C';
        !          1055:                t = Pbase(t)->b_name->tp;
        !          1056:                goto xx;
        !          1057: 
        !          1058:        case VEC:
        !          1059:                if (pp && Pvec(t)->size) {           // A<size>_
        !          1060:                        *p++ = 'A';
        !          1061:                        sprintf(p,"%d\0",Pvec(t)->size); // don't trust
        !          1062:                                                         // sprintf return value
        !          1063:                        while (*++p);
        !          1064:                        *p++ = '_';
        !          1065:                }
        !          1066:                else
        !          1067:                        *p++ = 'P';
        !          1068:                t = Pvec(t)->typ;
        !          1069:                pp = 1;
        !          1070:                goto xx;
        !          1071: 
        !          1072:        case PTR:
        !          1073:                if (Pptr(t)->rdo) *p++ = 'C';           // *const
        !          1074:                if (Pptr(t)->memof) {                   // M<size><classname>
        !          1075:                        Pclass cl = Pptr(t)->memof;
        !          1076:                        register char* s = cl->string;
        !          1077:                        int d = cl->strlen;
        !          1078:                        if (d==0) cl->strlen = d = strlen(s);
        !          1079:                        *p++ = 'M';
        !          1080:                        if (d/10) *p++ = '0'+d/10;
        !          1081:                        *p++ = '0'+ d%10;       // assume <100 char
        !          1082:                        while (*p++ = *s++);
        !          1083:                        --p;                            // not the '\0'
        !          1084:                }
        !          1085:                else
        !          1086:                        *p++ = 'P';
        !          1087:                t = Pptr(t)->typ;
        !          1088:                pp = 1;
        !          1089:                goto xx;
        !          1090: 
        !          1091:        case RPTR:
        !          1092:                *p++ = 'R';
        !          1093:                t = Pptr(t)->typ;
        !          1094:                pp = 1;
        !          1095:                goto xx;
        !          1096: 
        !          1097:        case FCT:
        !          1098:        {       Pfct f = Pfct(t);
        !          1099:                Pname n = f->argtype;
        !          1100: 
        !          1101:                if (f->f_const) *p++ = 'C';     // constant member function
        !          1102:                if (f->f_static) *p++ = 'S';    // static member function
        !          1103:        //      if (f->memof && f->f_this==0) *p++ = 'S';       //SSS static member function
        !          1104:                *p++ = 'F';
        !          1105:                if (n == 0)
        !          1106:                        *p++ = 'v';     // VOID, that is f() == f(void)
        !          1107:                else
        !          1108:        for ( ; n; n=n->n_list) {       // print argument encoding
        !          1109:                                        // check if argtype is the same
        !          1110:                                        // as previously seen argtype
        !          1111:                int i = 0;
        !          1112:                for (Pname nn=f->argtype; n!=nn; nn=nn->n_list) {
        !          1113:                        i++;
        !          1114:                        if (nn->tp==n->tp || nn->tp->check(n->tp,0)==0) {
        !          1115:                                // typeof (n) == typeof(arg i)
        !          1116:                                int x = 1;      // try for a run after n
        !          1117:                                Pname nnn = n;
        !          1118:                                while ((nnn=nnn->n_list) && x<9) {
        !          1119:                                        if (nnn->tp==n->tp
        !          1120:                                        || nnn->tp->check(n->tp,0)==0) {
        !          1121:                                                x++;
        !          1122:                                                n = nnn;
        !          1123:                                        }
        !          1124:                                        else
        !          1125:                                                break;
        !          1126:                                }
        !          1127: 
        !          1128:                                if (x == 1)             // Ti
        !          1129:                                        *p++ = 'T';
        !          1130:                                else {                  // Nxi
        !          1131:                                        *p++ = 'N';
        !          1132:                                        *p++ = '0'+x;
        !          1133:                                }
        !          1134:        
        !          1135:                                // assume <100 arguments
        !          1136:                                if (9<i) *p++ = '0'+i/10;
        !          1137:                                *p++ = '0'+i%10;
        !          1138:                                goto zk;
        !          1139:                        }       
        !          1140:                }
        !          1141: 
        !          1142:                // ``normal'' case print argument type signature
        !          1143:        //      if (n->n_xref) *p++ = 'R';
        !          1144:                p = n->tp->signature(p);
        !          1145:                zk:;
        !          1146:        }
        !          1147: 
        !          1148:                if (f->nargs_known == ELLIPSIS) *p++ = 'e';
        !          1149: 
        !          1150:                if (pp) {               // '_' result type
        !          1151:                        *p++ = '_';
        !          1152:                        p = f->returns->signature(p);
        !          1153:                }
        !          1154: 
        !          1155:                *p = 0;
        !          1156:                return p;
        !          1157:        }
        !          1158:        }
        !          1159: 
        !          1160:        // base type modifiers:
        !          1161: 
        !          1162:        if ( Pbase(t)->b_const )        *p++ = 'C';
        !          1163: //     if ( Pbase(t)->b_signed )       *p++ = 'S';
        !          1164:        if ( Pbase(t)->b_unsigned )     *p++ = 'U';
        !          1165: //     if ( Pbase(t)->b_volatile )     *p++ = 'V';
        !          1166: 
        !          1167: 
        !          1168:        // now base types:
        !          1169: 
        !          1170:        register char *s, *ns = 0;;
        !          1171:        int d;
        !          1172:        Pclass cl;
        !          1173: //lll:
        !          1174:        switch (t->base) {
        !          1175: //     case TNAME:     t = Pbase(t)->b_name->tp; goto lll;
        !          1176:        case ANY:                       break;
        !          1177:        case ZTYPE:                     break;
        !          1178:        case VOID:      *p++ = 'v';     break;
        !          1179:        case CHAR:      *p++ = 'c';     break;
        !          1180:        case SHORT:     *p++ = 's';     break;
        !          1181: //     case EOBJ:
        !          1182:        case INT:       *p++ = 'i';     break;
        !          1183:        case LONG:      *p++ = 'l';     break;
        !          1184:        case FLOAT:     *p++ = 'f';     break;
        !          1185:        case DOUBLE:    *p++ = 'd';     break;
        !          1186:        case LDOUBLE:   *p++ = 'r';     break;
        !          1187:        case EOBJ:
        !          1188: //             *p++ = 'i';
        !          1189: //             break;
        !          1190:        {       Penum en = Penum(Pbase(t)->b_name->tp);
        !          1191:        //      t = en->e_type;
        !          1192:        //      goto lll;
        !          1193:                ns = en->nested_sig; 
        !          1194:                s = en->string;
        !          1195:                d = en->strlen;
        !          1196:                if (d==0) en->strlen = d = strlen(s);
        !          1197:                goto pppp;
        !          1198:        }
        !          1199: 
        !          1200:        case COBJ:
        !          1201:        {       cl = Pclass(Pbase(t)->b_name->tp);
        !          1202:                ns = cl->nested_sig;
        !          1203:                s = cl->string;
        !          1204:                d = cl->strlen;
        !          1205:                if (d==0) cl->strlen = d = strlen(s);
        !          1206:        pppp:
        !          1207:                if ( ns == 0 ) {
        !          1208:                        if (d/10) *p++ = '0'+d/10;
        !          1209:                        *p++ = '0'+ d%10;       // assume less that 99 characters
        !          1210:                }
        !          1211:                else s = ns;
        !          1212: 
        !          1213:                while (*p++ = *s++);
        !          1214:                --p;
        !          1215:                break;
        !          1216:        }
        !          1217:        case FIELD:
        !          1218:        default:
        !          1219:                error('i',"signature of %k",t->base);
        !          1220:        }
        !          1221: 
        !          1222:        *p = 0;
        !          1223:        return p;
        !          1224: }
        !          1225: 
        !          1226: void basetype::dcl_print()
        !          1227: {
        !          1228:        Pname nn;
        !          1229:        Pclass cl;
        !          1230: 
        !          1231:        if (emode) {
        !          1232:                if (b_virtual) puttok(VIRTUAL);
        !          1233:                if (b_inline) puttok(INLINE);
        !          1234:        }
        !          1235:        if(ansi_opt || emode)
        !          1236:                if (b_const) puttok(CONST);
        !          1237:        if (b_unsigned) puttok(UNSIGNED);
        !          1238: 
        !          1239:        switch (base) {
        !          1240:        case ANY:
        !          1241:                if (emode)
        !          1242:                        putstring("any ");
        !          1243:                else
        !          1244:                        putstring("int ");
        !          1245:                break;
        !          1246: 
        !          1247:        case ZTYPE:
        !          1248:                if (emode)
        !          1249:                        putstring("zero ");
        !          1250:                else
        !          1251:                        putstring("int ");
        !          1252:                break;
        !          1253: 
        !          1254:        case VOID:
        !          1255:                 if (emode==0 && ansi_opt==0) {
        !          1256:                         // silly trick to bypass BSD C compiler bug
        !          1257:                         // void* (*)() dosn't work there
        !          1258:                         // note simpl.c knows that VOID -> CHAR grep for VCVC
        !          1259:                         puttok(CHAR);
        !          1260:                        break;
        !          1261:                 } 
        !          1262:        case CHAR:
        !          1263:        case SHORT:
        !          1264:        case INT:
        !          1265:        case LONG:
        !          1266:        case FLOAT:
        !          1267:        case DOUBLE:
        !          1268:         case LDOUBLE:
        !          1269:                puttok(base);
        !          1270:                break;
        !          1271: 
        !          1272:        case EOBJ:
        !          1273:                nn = b_name;
        !          1274:        eob:
        !          1275:                if (emode == 0)
        !          1276:                //      puttok(INT);
        !          1277:                        Penum(nn->tp)->e_type->dcl_print();
        !          1278:                else {
        !          1279:                         puttok(ENUM);
        !          1280:                         nn->print();
        !          1281:                }
        !          1282:                 break;
        !          1283: 
        !          1284:        case COBJ:
        !          1285:                nn = b_name;
        !          1286:        cob:
        !          1287:                cl = Pclass(nn->tp);
        !          1288:                if (emode && (cl->base == CLASS)  &&
        !          1289:                        (cl->class_base == instantiated_template_class)) {
        !          1290:                                Ptclass(cl)->inst->print_pretty_name();
        !          1291:                                break;
        !          1292:                } else
        !          1293:                if (cl && (cl->csu==UNION || cl->csu==ANON))
        !          1294:                        puttok(UNION);
        !          1295:                else puttok(STRUCT);
        !          1296:                { 
        !          1297:                        char* s = 0;
        !          1298:                        if ( cl && cl->nested_sig )
        !          1299:                                fprintf(out_file," __%s ",cl->nested_sig);
        !          1300:                        else {
        !          1301:                                if ( cl && cl->lex_level )
        !          1302:                                        s = make_local_name( cl );
        !          1303:                                putst(s?s:nn->string);
        !          1304:                                delete s;
        !          1305:                        }
        !          1306:                }
        !          1307:                break;
        !          1308: 
        !          1309:        case TYPE:
        !          1310:                if (emode == 0) {
        !          1311:                        switch (b_name->tp->base) {
        !          1312:                        case COBJ:
        !          1313:                                nn = Pbase(b_name->tp)->b_name;
        !          1314:                                goto cob;
        !          1315:                        case EOBJ:
        !          1316:                                nn = Pbase(b_name->tp)->b_name;
        !          1317:                                goto eob;
        !          1318:                        }
        !          1319:                }
        !          1320:                b_name->print();
        !          1321:                break;
        !          1322: 
        !          1323:        default:
        !          1324:                if (emode) {
        !          1325:                        if (0<base && base<=MAXTOK && keys[base])
        !          1326:                                fprintf(out_file," %s",keys[base]);
        !          1327:                        else
        !          1328:                                putch('?');
        !          1329:                }
        !          1330:                else
        !          1331:                        error('i',"%p->BT::dcl_print(%d)",this,base);
        !          1332:        }
        !          1333: }
        !          1334: Pbase memptr_type;
        !          1335: 
        !          1336: void type::dcl_print(Pname n)
        !          1337: /*
        !          1338:        "this" type is the type of "n". Print the declaration
        !          1339: */
        !          1340: {
        !          1341: //error('d',"%p::dcl_print(%n)",this,n);
        !          1342:        Ptype t = this;
        !          1343:        Pptr p;
        !          1344:        TOK pre = 0;
        !          1345: 
        !          1346:        if (t == 0) error('i',"0->dcl_print()");
        !          1347:        if (n && n->tp!=t) error('i',"not %n'sT (%p)",n,t);
        !          1348: 
        !          1349:        if (base == OVERLOAD) {
        !          1350:                for (Plist gl=Pgen(this)->fct_list; gl; gl=gl->l) {
        !          1351:                        Pname nn = gl->f;
        !          1352:                        nn->tp->dcl_print(nn);
        !          1353:                        if (gl->l) puttok(SM);
        !          1354:                }
        !          1355:                return;
        !          1356:        }
        !          1357: 
        !          1358:        tbuf = tbufvec[freetbuf];
        !          1359:        if (tbuf == 0) {
        !          1360:                if (freetbuf == NTBUF-1) error('i',"AT nesting overflow");
        !          1361:                tbufvec[freetbuf] = tbuf = new class dcl_buf;
        !          1362:        }
        !          1363:        freetbuf++;
        !          1364:        if ( base==FIELD && Pbase(this)->b_bits == 0 )
        !          1365:                tbuf->init(0);// some compilers can't handle mangled names here
        !          1366:        else
        !          1367:                tbuf->init(n);
        !          1368:        if (n && n->n_xref) tbuf->front(PTR);
        !          1369: 
        !          1370:        while (t) {
        !          1371:                TOK k;
        !          1372: 
        !          1373:                switch (t->base) {
        !          1374:                case PTR:
        !          1375:                        p = Pptr(t);
        !          1376:                        k = (p->rdo) ? CONST_PTR : PTR;
        !          1377:                        goto ppp;
        !          1378:                case RPTR:
        !          1379:                        p = Pptr(t);
        !          1380:                        k = (p->rdo) ? CONST_RPTR : RPTR;
        !          1381:                ppp:
        !          1382:                        if (p->memof) {
        !          1383:                                if (emode) {
        !          1384:                                        tbuf->front(k);
        !          1385:                                        tbuf->front(p->memof);
        !          1386:                                }
        !          1387:                                else {
        !          1388:                                        t = p->typ;
        !          1389:                                        while (t->base==TYPE) t = Pbase(t)->b_name->tp;
        !          1390:                                        if (t->base == FCT) {
        !          1391:                                                tbuf->base(mptr_type);
        !          1392:                                                goto zaq;
        !          1393:                                        }
        !          1394:                                        else
        !          1395:                                                tbuf->front(k);
        !          1396:                                }
        !          1397:                        }
        !          1398:                        else
        !          1399:                                tbuf->front(k);
        !          1400:                        pre = PTR;
        !          1401:                        t = p->typ;
        !          1402:                        break;
        !          1403:                case VEC:
        !          1404:                {       Pvec v = Pvec(t);
        !          1405:                        if (Cast && pre != PTR && pre != VEC) { // for Macintosh: ptr to array uses [] notation
        !          1406:                                tbuf->front(PTR);
        !          1407:                                pre = PTR;
        !          1408:                        }
        !          1409:                        else {
        !          1410:                                if (pre == PTR) tbuf->paran();
        !          1411:                                tbuf->back(VEC,v);
        !          1412:                                pre = VEC;
        !          1413:                        }
        !          1414:                        t = v->typ;
        !          1415:                        break;
        !          1416:                }
        !          1417: 
        !          1418:                case FCT:
        !          1419:                {       Pfct f = Pfct(t);
        !          1420:                        if (pre == PTR)
        !          1421:                                tbuf->paran();
        !          1422:                        else if (emode && f->memof && n==0)
        !          1423:                                tbuf->front(f->memof);
        !          1424:                        tbuf->back(FCT,f);
        !          1425:                        pre = FCT;
        !          1426:                        t = (f->s_returns) ? f->s_returns : f->returns;
        !          1427:                        break;
        !          1428:                }
        !          1429:                case FIELD:
        !          1430:                        tbuf->back(FIELD,t);
        !          1431:                        tbuf->base( Pbase(Pbase(t)->b_fieldtype) );
        !          1432:                        t = 0;
        !          1433:                        break;
        !          1434:                case 0:
        !          1435:                        if(!emode)error('i',"noBT(B=0)");
        !          1436:                        goto dobase;
        !          1437:                case TYPE:
        !          1438:                        if (Cast||Pbase(t)->b_name->lex_level) { // unravel type in case it contains vectors
        !          1439:                                t = Pbase(t)->b_name->tp;
        !          1440:                                break;
        !          1441:                        }
        !          1442:                default: // the base has been reached
        !          1443:                dobase:
        !          1444:                        if (emode) {
        !          1445:                                char* s;
        !          1446:                                for (Ptype tt = t; tt->base==TYPE; tt=Pbase(tt)->b_name->tp);
        !          1447:                                switch (tt->base) {
        !          1448:                                case CLASS:
        !          1449:                                        s = Pclass(tt)->string;
        !          1450:                                         if (Ptclass(this)->class_base == instantiated_template_class ||
        !          1451:                                             Ptclass(this)->class_base == uninstantiated_template_class) {
        !          1452:                                                Ptclass(this)->inst->print_pretty_name();
        !          1453:                                                --freetbuf;
        !          1454:                                                return;
        !          1455:                                         }
        !          1456:                                        if (s[0]=='_' &&s[1]=='_' && s[2]=='C') s="class";
        !          1457:                                        goto fret;
        !          1458:                                case ENUM:
        !          1459:                                        s = "enum";
        !          1460:                                        goto fret;
        !          1461:                                case OVERLOAD:
        !          1462:                                        s = "overloaded";
        !          1463:                                fret:
        !          1464:                                        putstring(s);
        !          1465:                                        freetbuf--;
        !          1466:                                        return;
        !          1467:                                }
        !          1468:                        }
        !          1469: 
        !          1470:                        tbuf->base( Pbase(t) );
        !          1471:                        goto zaq;
        !          1472:                } // switch
        !          1473:        } // while
        !          1474: zaq:
        !          1475:        tbuf->put();
        !          1476:        freetbuf--;
        !          1477: }
        !          1478: 
        !          1479: void fct::dcl_print()
        !          1480: {
        !          1481:        Pname nn;
        !          1482: //error('d',"fct::dcl_print()");
        !          1483:        if (emode) {
        !          1484:                putch('(');
        !          1485:                for (nn=argtype; nn;) {
        !          1486:                        nn->tp->dcl_print(0);
        !          1487:                        if (nn=nn->n_list) puttok(CM); else break;
        !          1488:                }
        !          1489:                switch (nargs_known) {
        !          1490:                case 0:         //      putst("?"); break;
        !          1491:                case ELLIPSIS:  puttok(ELLIPSIS); break;
        !          1492:                }
        !          1493:                putch(')');
        !          1494:                if (f_const) puttok(CONST);     
        !          1495:                if (f_static) puttok(STATIC);   // wrong place for ``static''
        !          1496:                return;
        !          1497:        }
        !          1498: 
        !          1499:        Pname at = f_args;
        !          1500:        putch('(');
        !          1501: 
        !          1502:        if (ansi_opt) {
        !          1503:                // print typed arguments:
        !          1504:                at = (f_this) ? f_this : (f_result) ? f_result : argtype; 
        !          1505:                // WNG -- note:  at = f_args had 0 value with ansi_opt set
        !          1506:                //               mystery fix added here
        !          1507:                if (at == 0) {
        !          1508:                        if (nargs_known == ELLIPSIS) {
        !          1509:                                putch(')');
        !          1510:                                return;
        !          1511:                        }
        !          1512:                        puttok(VOID);
        !          1513:                }
        !          1514:                else if (body && Cast==0)
        !          1515:                        at->dcl_print(CM);      // print argument type and name
        !          1516:                else {
        !          1517:                        for (nn=at; nn;) {
        !          1518:                        //      nn->tp->dcl_print(0);   // print argument type
        !          1519:                                nn->tp->dcl_print(nn);  // print argument type
        !          1520:                                                        // (there may not be a name)
        !          1521:                                if (nn=nn->n_list) puttok(CM); else break;
        !          1522:                        }
        !          1523:                }
        !          1524:                if (nargs_known == ELLIPSIS) putstring(",...");
        !          1525:                putch(')');
        !          1526:        }
        !          1527:        else {
        !          1528:                // print argument names followed by argument type declarations:
        !          1529:                if (body && Cast==0) {
        !          1530:                        for (nn=at; nn;) {
        !          1531:                                nn->print();
        !          1532:                                if (nn=nn->n_list) puttok(CM); else break;
        !          1533:                        }
        !          1534: #ifdef mips
        !          1535:                        if (nargs_known == ELLIPSIS)
        !          1536:                                putstring(", va_alist");
        !          1537: #endif
        !          1538: #ifdef sparc
        !          1539:                         if (nargs_known == ELLIPSIS)
        !          1540:                                 putstring(", __builtin_va_alist");
        !          1541: #endif
        !          1542:                        putch(')');
        !          1543:                }
        !          1544:                else
        !          1545:                        putch(')');
        !          1546:        }
        !          1547: }
        !          1548: 
        !          1549: void print_body(Pfct f)
        !          1550: {
        !          1551:        if (Cast==0) {
        !          1552:                
        !          1553:                if (ansi_opt==0 && f->f_args) {
        !          1554:                        f->f_args->dcl_print(SM);
        !          1555:                        if ( last_ll==0 && (last_ll = f->body->where.line) )
        !          1556:                                f->body->where.putline();
        !          1557:                }
        !          1558: 
        !          1559:                if (MAIN) {
        !          1560:                        putstring("{ _main(); ");       // call constructors
        !          1561:                        f->body->print();
        !          1562:                        puttok(RC);
        !          1563:                }
        !          1564:                else 
        !          1565:                        f->body->print();
        !          1566:        }
        !          1567: }
        !          1568: 
        !          1569: Pbcl shared_seen;
        !          1570: 
        !          1571: void classdef::print_members()
        !          1572: {
        !          1573:        int i;
        !          1574:        
        !          1575:        Pbcl l = baselist;
        !          1576: // error('d',"%t->print_members()",this);
        !          1577:        if (l) {
        !          1578:                if (l->base == NAME) {
        !          1579:                        l->bclass->print_members();     // first base only
        !          1580:                        // pad to ensure alignment:
        !          1581:                        int boff = l->bclass->real_size;
        !          1582:                        int ba = l->bclass->align();
        !          1583:                        int xtra = boff%ba;
        !          1584:                        int waste = (xtra) ? ba-xtra : 0;       // padding
        !          1585: //error('d',"%s: size % align %d waste %d",string,boff,ba,waste);
        !          1586:                        if (waste) {
        !          1587:                                // waste it to protect against structure
        !          1588:                                // assignments to the base class
        !          1589:                                char* s = make_name('W');
        !          1590:                                fprintf(out_file,"char %s[%d];\n",s,waste);
        !          1591:                                delete s;
        !          1592:                        }
        !          1593:                        l = l->next;
        !          1594:                }
        !          1595: 
        !          1596:                for (; l; l=l->next)
        !          1597:                /*      for second base etc. one must allocate as an object
        !          1598:                        (rather than a list of members) to ensure proper alignment
        !          1599:                        for shared base allocate a pointer
        !          1600:                        size, alignment, & offset handled in cassdef::dcl()
        !          1601:                */
        !          1602:                        if (l->base == NAME) {
        !          1603:                                Pclass bcl = l->bclass;
        !          1604:                                char *str =  0;
        !          1605:                                char *cs = bcl->nested_sig?bcl->nested_sig:bcl->string;
        !          1606:                                if (bcl->lex_level && 
        !          1607:                                        bcl->nested_sig==0) 
        !          1608:                                                str=make_local_name(bcl);
        !          1609:                                puttok(STRUCT);
        !          1610:                                putst(str?str:cs);
        !          1611:                                putcat('O',bcl->string); // leave as unencoded
        !          1612:                                puttok(SM);
        !          1613:                                delete str;
        !          1614:                        }
        !          1615:        }
        !          1616: 
        !          1617:        // Sam: A class or an enum type declared within a class can hide a
        !          1618:        // member with the same name, so make sure that it gets printed by
        !          1619:        // traversing the n_tbl_list to get at these names.
        !          1620:        for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i)) {
        !          1621:          do { if (nn->base==NAME
        !          1622:                && nn->n_union==0
        !          1623:                && nn->tp->base!=FCT
        !          1624:                && nn->tp->base!=OVERLOAD
        !          1625:                && nn->tp->base!=CLASS
        !          1626:                && nn->tp->base!=ENUM
        !          1627:                && nn->n_stclass != STATIC) {
        !          1628:                //      if (nn->tp->base==FIELD && Pbase(nn->tp)->b_bits==0) continue;
        !          1629:                        Pexpr i = nn->n_initializer;
        !          1630:                        nn->n_initializer = 0;
        !          1631:                        nn->dcl_print(0);
        !          1632:                        nn->n_initializer = i;
        !          1633:                }
        !          1634:          } while ((nn->base == NAME) &&
        !          1635:                 ((nn->tp->base!=CLASS) || (nn->tp->base!=ENUM)) &&
        !          1636:                 (nn = nn->n_tbl_list)) ;
        !          1637:        }
        !          1638: 
        !          1639:        for (l=baselist; l; l=l->next)
        !          1640:                if (l->base==VIRTUAL && l->ptr_offset) {
        !          1641:                        Pclass bcl = l->bclass;
        !          1642:                                char* str =  0;
        !          1643:                        char *cs = bcl->nested_sig?bcl->nested_sig:bcl->string;
        !          1644:                        if (bcl->lex_level && 
        !          1645:                                bcl->nested_sig==0) 
        !          1646:                                        str=make_local_name(bcl);
        !          1647:                        puttok(STRUCT);
        !          1648:                        putst(str?str:cs);
        !          1649:                        putch('*');
        !          1650:                        putcat('P',bcl->string); // leave unencoded
        !          1651:                        puttok(SM);
        !          1652:                        delete str;
        !          1653:                }
        !          1654: }
        !          1655: 
        !          1656: // void classdef::print_vtbl(Pvirt vtab)
        !          1657: // {
        !          1658: // error('d',"%s->print_vtbl(%s) vtbl_opt %d",string,vtab->string,vtbl_opt);
        !          1659: // error('d',"print_vtbl: lex_level: %d", lex_level );
        !          1660: // 
        !          1661: //     switch (vtbl_opt) {
        !          1662: //     case -1:
        !          1663: //     case 1:
        !          1664: //             vlist = new vl(this,vtab,vlist);
        !          1665: //     }
        !          1666: //
        !          1667: //     int oo = vtbl_opt;      // make `simulated static' name
        !          1668: //     vtbl_opt = -1;
        !          1669: //      char* str =  lex_level ? make_local_name(this) : 0;
        !          1670: //      char* s = vtbl_name(vtab->string,str?str:string);
        !          1671: //     vtbl_opt = oo;
        !          1672: //     fprintf(out_file,"extern struct __mptr %s[];\n",s);
        !          1673: //     s[2] = 'p';     // pointer, not tbl itself
        !          1674: //     fprintf(out_file,"extern struct __mptr* %s;\n",s);
        !          1675: //
        !          1676: //       delete s;
        !          1677: //     delete str;
        !          1678: // }
        !          1679: 
        !          1680: vl* vlist;
        !          1681: 
        !          1682: void really_really_print(Pclass cl, Pvirt vtab, char* s, char* ss);
        !          1683: 
        !          1684: int p2(Pname nn, Ptype t, Pclass cl, Pvirt vtab, char* s)
        !          1685: {
        !          1686:        int init;
        !          1687: 
        !          1688:        if (t->base == FCT) {
        !          1689:                Pfct f = Pfct(t);
        !          1690: 
        !          1691: //error('d',"p2 %n init %d inline %d virtual %d",nn,nn->n_initializer,f->f_inline,f->f_virtual);
        !          1692: //error('d',"p2 %s expr %d imeasure %d body %d",s,f->f_expr,f->f_imeasure,f->body);
        !          1693: //error('d',"sto %k",nn->n_sto);
        !          1694:                if (nn->n_initializer
        !          1695:                || nn->n_sto==STATIC
        !          1696:                || f->f_inline
        !          1697:                || f->f_imeasure
        !          1698:                || f->f_virtual==0) return 0;
        !          1699:                init = f->body!=0;
        !          1700:        }
        !          1701:        else
        !          1702:                init = nn->n_initializer!=0;
        !          1703: 
        !          1704:        int oo = vtbl_opt;
        !          1705:        vtbl_opt = 1;   // make sure the name is universal
        !          1706:        char *cs = cl->nested_sig?cl->nested_sig:cl->string;
        !          1707:         char* sstr = (cl->lex_level&&cl->nested_sig==0)? make_local_name(cl) : 0;
        !          1708:         char* ss = vtbl_name(vtab->string,sstr?sstr:cs);
        !          1709: 
        !          1710:        if (init) {     // unique definition here
        !          1711:                really_really_print(cl,vtab,ss,s);
        !          1712:        }
        !          1713:        else {  // unique definition elsewhere
        !          1714:                char *vstr = 0;
        !          1715:                if ( vtab && vtab->string ) {
        !          1716:                        vstr = new char[strlen(vtab->string)+cl->strlen+1];
        !          1717:                        strcpy( vstr, vtab->string );
        !          1718:                        strcat( vstr, cl->string );
        !          1719:                }
        !          1720:                Pname nn;
        !          1721:                if (nn=ptbl->look(vstr?vstr:cl->string,0)) { // use of ptbl in file
        !          1722:                        fprintf(out_file,"extern struct __mptr %s[];\n",ss);
        !          1723:                        s[2] = 'p';
        !          1724:                        // fprintf(out_file,"struct __mptr* %s = ",s);
        !          1725:                        // fprintf(out_file,"%s;\n",ss);
        !          1726:                        ptbl_add_pair(s, ss);
        !          1727:                        nn->n_key=HIDDEN; 
        !          1728:                }
        !          1729:                delete vstr;
        !          1730:        }
        !          1731:        vtbl_opt = oo;
        !          1732: 
        !          1733:        delete ss;
        !          1734:        delete sstr;
        !          1735: 
        !          1736:        return 1;
        !          1737: }
        !          1738: 
        !          1739: void classdef::really_print(Pvirt vtab)
        !          1740: {
        !          1741: // error('d',"really_print %t %d",this,vtbl_opt);
        !          1742:        int oo = vtbl_opt;      // make `simulated static' name
        !          1743:        vtbl_opt = -1;
        !          1744:        char *cs = nested_sig?nested_sig:string;
        !          1745:         char* str = (lex_level&&nested_sig==0) ? make_local_name(this) : 0;
        !          1746:         char* s = vtbl_name(vtab->string,str?str:cs);
        !          1747: // error('d', "really_print: %s, vtab: %s, s: %s", string, vtab->string, s );
        !          1748:        vtbl_opt = oo;
        !          1749: 
        !          1750:        // see if needed
        !          1751:        int i;
        !          1752:        for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
        !          1753:                Ptype t = nn->tp;
        !          1754:        zse:
        !          1755:                if (t)
        !          1756:                switch (t->base) {
        !          1757:                case TYPE:
        !          1758:                        t = Pbase(t)->b_name->tp;
        !          1759:                        goto zse;
        !          1760: /*
        !          1761:                case COBJ:
        !          1762:                        if (nn->n_sto == EXTERN)
        !          1763:                        {       Pclass cl = Pclass(Pbase(t)->b_name->tp);
        !          1764:                                if (cl->has_ctor()) {
        !          1765:                                        p2(nn,t,this,vtab,s);
        !          1766:                                        return;
        !          1767:                                }
        !          1768:                        }
        !          1769:                        break;
        !          1770: */
        !          1771:                case FCT:
        !          1772:                        if (p2(nn,t,this,vtab,s))
        !          1773:                                goto xyzzy;
        !          1774:                        break;
        !          1775: 
        !          1776:                case OVERLOAD:
        !          1777:                {       for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l)
        !          1778:                                if (p2(gl->f,gl->f->tp,this,vtab,s))
        !          1779:                                        goto xyzzy;
        !          1780:                }
        !          1781:                }
        !          1782:        }
        !          1783: 
        !          1784:         { // must be initialized var in block to permit goto
        !          1785:        char* ss = vtbl_name(vtab->string,str?str:cs);
        !          1786: // error('d', "really_print: %s, vtab: %s, ss: %s", cs, vtab->string, s );
        !          1787: 
        !          1788:        if (vtbl_opt)
        !          1789:                really_really_print(this,vtab,ss,s);
        !          1790:        else {
        !          1791:                char *vstr = 0;
        !          1792:                if ( vtab && vtab->string ) {
        !          1793:                        vstr = new char[::strlen(vtab->string)+strlen+1];
        !          1794:                        strcpy( vstr, vtab->string );
        !          1795:                        strcat( vstr, string );
        !          1796:                }
        !          1797:                Pname nn;
        !          1798:                if (nn=ptbl->look(vstr?vstr:string,0)) { // use of ptbl in file
        !          1799:                        fprintf(out_file,"extern struct __mptr %s[];\n",ss);
        !          1800:                        s[2] = 'p';
        !          1801:                        // fprintf(out_file,"struct __mptr* %s = ",s);
        !          1802:                        // fprintf(out_file,"%s;\n",ss);
        !          1803:                        ptbl_add_pair(s, ss);
        !          1804:                        nn->n_key=HIDDEN; 
        !          1805:                }
        !          1806:                delete vstr;
        !          1807:        }
        !          1808:        delete ss;
        !          1809:        }
        !          1810: xyzzy:
        !          1811:        delete s;
        !          1812:        delete str;
        !          1813: }
        !          1814: 
        !          1815: void really_really_print(Pclass cl, Pvirt vtab, char* s, char* ss)
        !          1816: {
        !          1817: // error('d',"really %s %s",s, ss);
        !          1818:        // make sure function is declared before using
        !          1819:        // it in vtbl initializer
        !          1820:        Pname nn;
        !          1821:        int i;
        !          1822:        for (i=0; nn = vtab->virt_init[i].n; i++) {
        !          1823:                Pfct f = Pfct(nn->tp);
        !          1824:                 if (nn->n_initializer) {       // pure virtual
        !          1825:                        static pv;
        !          1826:                        if (pv == 0) {  // VCVC void->char assumed
        !          1827:                                fprintf(out_file,"char __pure_virtual_called();\n");
        !          1828:                                pv = 1;
        !          1829:                        }
        !          1830:                        continue;
        !          1831:                }
        !          1832:                if (f->base != FCT) error('i',"vtbl %n",nn);
        !          1833: //extern void expand_dtor(Pclass cl);
        !          1834: //             if (f->f_inline == IDTOR) expand_dtor(f->memof);
        !          1835: 
        !          1836:                if (nn->n_dcl_printed==0 /*|| f->f_inline*/) {
        !          1837:                        if (f->f_inline && vtbl_opt) puttok(STATIC);
        !          1838:                        if (f->f_result == 0) make_res(f);
        !          1839:                        Ptype r = f->s_returns ? f->s_returns : f->returns;
        !          1840:                        r->print();
        !          1841:                        nn->print();
        !          1842:                        putstring("()");
        !          1843:                        puttok(SM);
        !          1844:                        nn->n_dcl_printed = 1;
        !          1845:                }
        !          1846:        }
        !          1847: 
        !          1848: //     if (vtbl_opt == -1) puttok(STATIC);
        !          1849: 
        !          1850: 
        !          1851:         fprintf(out_file,"struct __mptr %s[] = {0,0,0,\n",s);
        !          1852: 
        !          1853:        Pname n;
        !          1854:        for (i=0; n=vtab->virt_init[i].n; i++) {
        !          1855:                if (n->n_initializer)
        !          1856:                        putstring("0,0,(__vptp)__pure_virtual_called,\n");
        !          1857:                else {
        !          1858:                        fprintf(out_file,"%d,0,(__vptp)",-vtab->virt_init[i].offset);
        !          1859:                        n->print();
        !          1860:                        n->n_addr_taken = 1;
        !          1861:                        putstring(",\n");
        !          1862:                }
        !          1863:        }
        !          1864:        putstring("0,0,0};\n");
        !          1865: 
        !          1866:        ss[2] = 'p';
        !          1867:         // fprintf(out_file,"struct __mptr* %s = ",ss);
        !          1868:        s[2] = 'v';
        !          1869:         // fprintf(out_file,"%s;\n",s);
        !          1870:        ptbl_add_pair(ss,s);
        !          1871: 
        !          1872:         Pname nm;
        !          1873:        char *cstr = 0;
        !          1874:        char *vstr = 0;
        !          1875:        char *cs = cl->nested_sig?cl->nested_sig:cl->string;
        !          1876:        if (cl->lex_level && cl->nested_sig==0) cstr = make_local_name( cl );
        !          1877:        if ( vtab && vtab->string ) {
        !          1878:                vstr = new char[strlen(vtab->string)+(cstr?strlen(cstr):strlen(cs))+1];
        !          1879:                strcpy( vstr, vtab->string );
        !          1880:                strcat( vstr, cstr?cstr:cs );
        !          1881:        }
        !          1882: 
        !          1883:        if ( vstr == 0 ) vstr = cstr;
        !          1884:        if ( nm = ptbl->look(vstr?vstr:cl->string,0) ) 
        !          1885:                nm->n_key = HIDDEN;
        !          1886:        else 
        !          1887:        if ( ptbl->look(vstr?vstr:cl->string,HIDDEN) == 0 )
        !          1888:                ptbl->insert(new name(vstr?vstr:cl->string),HIDDEN);
        !          1889:         if (cstr == vstr) delete cstr;
        !          1890:         else {
        !          1891:                 delete cstr;
        !          1892:                 delete vstr;
        !          1893:         }
        !          1894: 
        !          1895: //error('d',"really-> %s",s);
        !          1896: }
        !          1897: 
        !          1898: #include <ctype.h>
        !          1899: char* vtbl_name(char* s1, char* s2)
        !          1900: {
        !          1901:        char* s3 = (vtbl_opt == -1 && *src_file_name) ? src_file_name : 0;
        !          1902:                // if vtbl_opt == -1 fake a static (there are no portable
        !          1903:                // way of doing a forward declaration of a static in C)
        !          1904:        int ll = s1 ? strlen(s1) : 0;
        !          1905:        int ll2 = strlen(s2);
        !          1906:        int ll3 = s3 ? strlen(s3) : 0;
        !          1907:         int sz = (ll+ll2+ll3+20)/32+1;  // avoid fragmentation
        !          1908: 
        !          1909:         sz *= 32;
        !          1910: // error('d',"vtbl_name(%s,%s,%s) %d",s1?s1:"",s2,s3?s3:"",sz);
        !          1911:         char* buf = new char[sz];
        !          1912:        if (s3) {
        !          1913:                if (s1)
        !          1914:                        sprintf(buf,"__vtbl__%d%s__%d%s__%s",ll,s1,ll2,s2,s3);
        !          1915:                else
        !          1916:                        sprintf(buf,"__vtbl__%d%s__%s",ll2,s2,s3);
        !          1917:        }
        !          1918:        else if (s1)
        !          1919:                sprintf(buf,"__vtbl__%d%s__%d%s",ll,s1,ll2,s2);
        !          1920:        else
        !          1921:                sprintf(buf,"__vtbl__%d%s",ll2,s2);
        !          1922: 
        !          1923:        if (vtbl_opt == -1) {
        !          1924:                for (char* p = buf+ll2+11; *p; p++)
        !          1925:                        if (!isalpha(*p) && !isdigit(*p)) *p = '_';
        !          1926:        }
        !          1927: #ifdef DENSE
        !          1928:        chop(buf);
        !          1929: #endif
        !          1930:        return buf;
        !          1931: }
        !          1932: 
        !          1933: void classdef::print_all_vtbls(Pclass bcl)
        !          1934: {
        !          1935: //error('d',"%t->print_all_vtbls(%t) vlt %d bl %d",this,bcl,virt_list,baselist);
        !          1936: 
        !          1937:        for (Pvirt blist = bcl->virt_list; blist; blist = blist->next) {
        !          1938:                if (this != blist->vclass) continue;
        !          1939:                if (blist->printed) continue;
        !          1940:         //      if (blist->string==0 && find_vptr(this)==0) {        //BSopt
        !          1941:         //              continue;
        !          1942:         //      }
        !          1943:        //      print_vtbl(blist);
        !          1944:                vlist = new vl(this,blist,vlist);
        !          1945:                blist->printed = 1;
        !          1946:        }
        !          1947: 
        !          1948:        for (Pbcl b = bcl->baselist; b; b = b->next)
        !          1949:                print_all_vtbls(b->bclass);
        !          1950: 
        !          1951:        if (this==bcl) c_body = 0;
        !          1952: }
        !          1953: 
        !          1954: extern Pclass current_instantiation;
        !          1955: void classdef::dcl_print(Pname)
        !          1956: { 
        !          1957: //error('d',"%t->classdef::dcl_print() -- c_body==%d defined==0%o",this,c_body,defined);
        !          1958:        defined |= REF_SEEN;
        !          1959: // ensure template instantiations are printed exactly once.
        !          1960:         if (class_base != vanilla_class && current_instantiation != this) return;
        !          1961: 
        !          1962:        if (c_body==0 || c_body==3 || (defined&DEFINED)==0) return;
        !          1963:        c_body = 3;
        !          1964: 
        !          1965:        int i;
        !          1966:        for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
        !          1967:                if (nn->base==NAME
        !          1968:                && nn->n_union==0
        !          1969:                && nn->tp->base==CLASS
        !          1970:                && Pclass(nn->tp)->c_body==1)
        !          1971:                        Pclass(nn->tp)->dcl_print(nn);
        !          1972:                else if (nn->base == TNAME && Pbase(nn->tp)->base != COBJ)
        !          1973:                        nn->dcl_print(0);
        !          1974:                 else if (nn->tp && nn->tp->base == ENUM) {
        !          1975:                        if(nn->n_union==0) Penum(nn->tp)->dcl_print(nn);
        !          1976:                }
        !          1977:        }
        !          1978: 
        !          1979:        TOK lvl = in_class ? NESTED : lex_level ? LOCAL : 0;
        !          1980:        Pname n = ktbl->look(string,lvl);
        !          1981:        if (n==0) n = ktbl->look(string,HIDDEN);
        !          1982: 
        !          1983:        if (n) {
        !          1984:                if (n->where.line!=last_line.line
        !          1985:                || n->where.file!=last_line.file)
        !          1986:                        if (last_ll = n->where.line)
        !          1987:                                n->where.putline();
        !          1988:                        else
        !          1989:                                last_line.putline();
        !          1990:        }
        !          1991: 
        !          1992:        TOK c = csu==CLASS ? STRUCT : csu;
        !          1993:        puttok(c);
        !          1994: //     if (string[0]!='_' || string[1]!='_' || string[2]!='C')
        !          1995: 
        !          1996:         char *str = 0;
        !          1997:        if ( lex_level && nested_sig == 0) str = make_local_name( this );
        !          1998:        if ( nested_sig ) putstring( " __" );
        !          1999:        putst(str?str:(nested_sig?nested_sig:string));
        !          2000: 
        !          2001:        int sm = 0;
        !          2002:        int sz = tsizeof();
        !          2003:        int dvirt = 0;
        !          2004: 
        !          2005:        if ( nested_sig )
        !          2006:                fprintf(out_file,"{\t/* sizeof __%s == %d */\n",nested_sig,obj_size);
        !          2007:        else
        !          2008:                fprintf(out_file,"{\t/* sizeof %s == %d */\n",str?str:string,obj_size);
        !          2009:        if ( last_ll ) last_line.line++;
        !          2010:        delete str;
        !          2011: 
        !          2012:        print_members();
        !          2013:        for (Pbcl b = baselist; b; b = b->next) {       // declare virtual classes
        !          2014:                if (b->base != VIRTUAL) continue;
        !          2015:                Pclass bcl = b->bclass;
        !          2016:                dvirt += bcl->virt_count;
        !          2017: //error('d',"%t in %t %d",b->bclass,this,b->allocated);
        !          2018:                if (b->allocated==0) continue;
        !          2019:                char* str =  0;
        !          2020:                if (bcl->lex_level) str = make_local_name(bcl);
        !          2021:                puttok(STRUCT);                 // struct bcl Obcl;
        !          2022:                putst(str?str:bcl->string);
        !          2023:                putcat('O',bcl->string); // leave unencoded
        !          2024:                puttok(SM);
        !          2025:                delete str;
        !          2026:        }
        !          2027:        putstring("};\n");
        !          2028:        if ( last_ll ) last_line.line++;
        !          2029: 
        !          2030:        for (nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
        !          2031:                if (nn->base==NAME && nn->n_union==0) {
        !          2032:                        Ptype t = nn->tp;
        !          2033:                        switch (t->base) {
        !          2034:                        case FCT:
        !          2035:                        case OVERLOAD:
        !          2036:                                break;
        !          2037:                        default:
        !          2038:                                if (nn->n_stclass == STATIC) {
        !          2039:                                        TOK b = nn->n_sto;
        !          2040: //error('d',"print nn %n tp %t b %k eval %d",nn,nn->tp,b,nn->n_evaluated);
        !          2041:                                /*
        !          2042:                                        Pname cn;
        !          2043:                                        TOK bb = ((cn=nn->tp->is_cl_obj())
        !          2044:                                        && Pclass(cn->tp)->has_ctor())==0
        !          2045:                                                ?0:b; // force explicit initialization
        !          2046:                                        nn->n_sto = (nn->n_evaluated) ? STATIC : bb;
        !          2047:                                */
        !          2048:                                        nn->n_sto = (nn->n_evaluated) ? STATIC : b;
        !          2049:                                        nn->dcl_print(0);
        !          2050:                                        nn->n_sto = b;
        !          2051:                                }
        !          2052:                        }
        !          2053:                }
        !          2054:        }
        !          2055:        if (vtbl_opt != -1) print_all_vtbls(this);      // force declaration
        !          2056: //error('d',"dcl_print -> ");
        !          2057: }
        !          2058: 
        !          2059: 
        !          2060: char *
        !          2061: make_local_name( Pclass cl, int ln ) 
        !          2062: {
        !          2063:     char *buf; 
        !          2064:     if ( cl->in_fct == 0 ) error( 'i', "localC %s missingFN", cl->string ); 
        !          2065:     char *fsig = Pfct(cl->in_fct->tp)->f_signature;
        !          2066:     if ( fsig == 0 ) fsig = local_sign( cl->in_fct->tp );
        !          2067:     char *fs = cl->in_fct->string;
        !          2068:     int class_len=cl->strlen+strlen(fsig)+strlen(fs)+strlen(cl->lcl)+4;
        !          2069:     int sz = (class_len+20)/32+1; // from vtbl_name()
        !          2070: 
        !          2071:     if ( Pfct(cl->in_fct->tp)->memof == 0 ) {
        !          2072:         sz *= 32;
        !          2073:         buf = new char[ sz ];
        !          2074: // error('d', "make_local_name: sz: %d", sz );
        !          2075: 
        !          2076:          if (ln) 
        !          2077:              sprintf(buf, "__%d%s__%s__%s%s", class_len, cl->string, fs, fsig, cl->lcl);
        !          2078:         else
        !          2079:              sprintf(buf, "%s__%s__%s%s", cl->string, fs, fsig, cl->lcl);
        !          2080:     }
        !          2081:     else 
        !          2082:     {
        !          2083:         char *cs = Pclass(Pfct(cl->in_fct->tp)->memof)->string;
        !          2084:         int len = Pclass(Pfct(cl->in_fct->tp)->memof)->strlen;
        !          2085:         if ( len < 10 )
        !          2086:             ++class_len;
        !          2087:        else 
        !          2088:         if ( len > 99 )
        !          2089:             class_len += 3;
        !          2090:        else class_len += 2;
        !          2091:        class_len += len;
        !          2092:         sz = (class_len+20)/32+1; 
        !          2093:        sz *= 32;
        !          2094:         buf = new char[ sz ];
        !          2095: // error('d', "make_local_name: sz: %d", sz );
        !          2096: 
        !          2097:        if ( ln )
        !          2098:              sprintf(buf, "__%d%s__%s__%d%s%s%s",class_len,cl->string,fs,len,cs,fsig,cl->lcl);
        !          2099:         else sprintf(buf, "%s__%s__%d%s%s%s",cl->string,fs,len,cs,fsig,cl->lcl);
        !          2100:     }
        !          2101: 
        !          2102: #ifdef DENSE
        !          2103:     chop( buf );
        !          2104: #endif
        !          2105: 
        !          2106:     return buf;
        !          2107: }
        !          2108: 

unix.superglobalmegacorp.com

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