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

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

unix.superglobalmegacorp.com

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