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

1.1       root        1: /*ident        "@(#)ctrans:src/print2.c        1.3.6.27" */
                      2: /**************************************************************************
                      3: 
                      4:        C++ source for cfront, the C++ compiler front-end
                      5:        written in the computer science research center of Bell Labs
                      6: 
                      7:        Copyright (c) 1984 AT&T, Inc. All rigths Reserved
                      8:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.
                      9: 
                     10: print.c:
                     11: 
                     12:        print names and declarations
                     13: 
                     14: ****************************************************************************/
                     15: 
                     16: #include "cfront.h"
                     17: #include <string.h>
                     18: #include "template.h"
                     19: 
                     20: extern FILE* out_file;
                     21: bit Cast;
                     22: int last_ll = 1;
                     23: Pin curr_icall;
                     24: char emode;
                     25: int ntok;
                     26: 
                     27: static int MAIN;       // fudge to get _main() called by main()
                     28: 
                     29: #define eprint(e) if (e) Eprint(e)
                     30: 
                     31: #ifdef DENSE
                     32: void chop(char*);
                     33: #endif
                     34: 
                     35: 
                     36: /* The following strings (new_string and tmp_string) are
                     37:    used to capture a transformed string. The captured
                     38:    string is then assigned to "name::output_string".
                     39:    This is done in "name::print". */
                     40: 
                     41: static char new_string[1024];  // The transformed string.
                     42: static char tmp_string[1024];  // Used to format the transformed string.
                     43: 
                     44: /* Rick, ODI, 6-20-89: The following #define is used to control whether
                     45:    renamings are saved. */
                     46: 
                     47: #define OUTPUT_PAIR_FUNCTIONALITY 0
                     48: 
                     49: #if OUTPUT_PAIR_FUNCTIONALITY
                     50: static void output_pair (name *declarator);
                     51: #endif
                     52: 
                     53: /* Rick, ODI, 6-20-89: Local functions used in renaming work. */
                     54: 
                     55: extern bit capture_renaming;/* Rick, ODI; used to switch off cfront renaming 
                     56:                               capture. */
                     57: static Pname is_data_member (Pname p_name);
                     58: static Pname matches_base_member (Pname p_name, Pclass class_);
                     59: static Pname look_any (Ptable p_table, char* s);
                     60: 
                     61: void puttok(TOK t)
                     62: /*
                     63:        print the output representation of "t"
                     64: */
                     65: {
                     66: //     if (t<=0 || MAXTOK<t) error("illegal token %d",t);
                     67: //     char* s = keys[t];
                     68: //     if (s == 0) error("V representation token %d",t);
                     69: 
                     70:        putstring(keys[t]);
                     71: 
                     72:        if(!emode) {
                     73:            if (12<ntok++) {
                     74:                ntok = 0;
                     75:                last_line.putline();
                     76:            }
                     77:            else if (t == SM) {
                     78:                ntok = 0;
                     79:                putch('\n');
                     80:                if (last_ll) last_line.line++;
                     81:            }
                     82:            else
                     83:                putch(' ');
                     84:        } else putch(' ');
                     85: }
                     86: 
                     87: #define MX     20
                     88: #define NTBUF  10
                     89: class dcl_buf {
                     90:        /*
                     91:                buffer for assembling declaration (or cast)
                     92:                left contains CONST_PTR => *CONST
                     93:                             CONST_RPTR => &CONST
                     94:                                PTR     => *
                     95:                                RPTR    => &
                     96:                                LP      => (
                     97:                right contains  RP      => )
                     98:                                VEC     => [ rnode ]
                     99:                                FCT     => ( rnode )
                    100:                                FIELD   => : rnode
                    101:        */
                    102:        Pbase b;
                    103:        Pname n;
                    104:        TOK left[MX], right[MX];
                    105:        Pnode   rnode[MX];
                    106:        Pclass  lnode[MX];
                    107:        int li, ri;
                    108: public:
                    109:        void    init(Pname nn)          { b=0; n=nn; li=ri=0; }
                    110:        void    base(Pbase bb)          { b = bb; }
                    111:        void    front(TOK t)            { left[++li] = t; }
                    112:        void    front(Pclass c)         { left[++li] = MEMPTR; lnode[li] = c; }
                    113:        void    back(TOK t, Pnode nod)  { right[++ri] = t; rnode[ri] = nod; }
                    114:        void    paran()                 { front(LP); back(RP,0); }
                    115:        void    put();
                    116: } *tbufvec[NTBUF] = {0}, *tbuf = 0;
                    117: 
                    118: int freetbuf = 0;
                    119: 
                    120: void dcl_buf::put()
                    121: {
                    122:        int i;
                    123:        Pfct ff = 0;
                    124: 
                    125:        if (MX<=li || MX<=ri) error('i',"T buffer overflow");
                    126:        if (b == 0) error('i',"noBT%s",Cast?" in cast":"");
                    127: 
                    128:        if (n && n->n_sto && n->n_sto!=REGISTER) puttok(n->n_sto);
                    129: 
                    130:        b->dcl_print();
                    131:        
                    132:        for( ; li; li--) {
                    133:                switch (left[li]) {
                    134:                case LP:
                    135:                        putch('(');
                    136:                        break;
                    137:                case PTR:
                    138:                        putch('*');
                    139:                        break;
                    140:                case RPTR:
                    141:                        if (emode)
                    142:                                putch('&');
                    143:                        else
                    144:                                putch('*');
                    145:                        break;
                    146:                case CONST_PTR:
                    147:                        if (emode)
                    148:                                putstring("*const ");
                    149:                        else
                    150:                                putch('*');
                    151:                        break;
                    152:                case CONST_RPTR:
                    153:                        if (emode)
                    154:                                putstring("&const ");
                    155:                        else
                    156:                                putch('*');
                    157:                        break;
                    158:                case MEMPTR:
                    159:                        if (lnode[li]) {
                    160:                          char buff[1024] ;
                    161:                          fprintf(out_file,"%s::", (lnode[li]->string)) ;
                    162:                        }
                    163:                }
                    164:        }
                    165: 
                    166:        if (n) n->print();
                    167: 
                    168:        for(i=1; i<=ri; i++) {
                    169:                switch (right[i]) {
                    170:                case RP:
                    171:                        putch(')');
                    172:                        break;
                    173:                case VEC:
                    174:                        putch('[');
                    175:                        {       Pvec v = (Pvec) rnode[i];
                    176:                                Pexpr d = v->dim;
                    177:                                int s = v->size;
                    178:                                if (d) d->print();
                    179:                                if (s) fprintf(out_file,"%d",s);
                    180:                        }
                    181:                        putch(']');
                    182:                        break;
                    183:                case FCT:       // beware of function returning pointer to
                    184:                                // function expressed witout typedef
                    185:                {       Pfct f = Pfct(rnode[i]);
                    186:                        if (f->body) ff = f;
                    187:                        f->dcl_print();
                    188:                        break;
                    189:                }
                    190:                case FIELD:
                    191:                 {       Pbase f = (Pbase) rnode[i];
                    192:                         Pexpr d = (Pexpr)f->b_name;
                    193:                         int s = f->b_bits;
                    194:                         putch(':');
                    195:                         if (d)
                    196:                                 d->print();
                    197:                         else if (s)
                    198:                                 fprintf(out_file,"%d",s);
                    199:                         else
                    200:                                 puttok(ZERO);
                    201:                         break;
                    202:                 }
                    203:                }
                    204:        }
                    205: void print_body(Pfct);
                    206:        if (ff && emode==0) print_body(ff);
                    207: }
                    208: 
                    209: void name::dcl_print(TOK list)
                    210: /*
                    211:        Print the declaration for a name (list==0) or a name list (list!=0):
                    212:                For each name
                    213:                (1) print storage class
                    214:                (2) print base type
                    215:                (3) print the name with its declarators
                    216:        Avoid (illegal) repetition of basetypes which are class or enum declarations
                    217:        (A name list may contain names with different base types)
                    218:        list == SM :    terminator SM
                    219:        list == 0:      single declaration with terminator SM
                    220:        list == CM :    separator CM
                    221: */
                    222: {
                    223:        if (error_count) return;
                    224: 
                    225:        if (capture_renaming) { /* rick, ODI, 3-28-89; used to switch off some
                    226:                                    cfront renaming. */
                    227:            new_string[0] = '\0';
                    228:            tmp_string[0] = '\0';
                    229:        }
                    230: 
                    231:        for (Pname n=this; n; n=n->n_list) {
                    232:                Ptype t = n->tp;
                    233:                int sm = 0;
                    234: 
                    235: //error('d',"%s->dcl_print() tp %t sto %k",n->string,t,n->n_sto);
                    236: 
                    237:                if (t == 0) error('i',"N::dcl_print(%n)T missing",n);
                    238: 
                    239:                if (t->base == TYPE) {  // unroll local typedefs:
                    240:                        Pname bn = Pbase(t)->b_name;
                    241:                        if (bn->lex_level && (! bn->n_template_arg)
                    242:                        && bn->tp->base != COBJ 
                    243:                        && bn->tp->base != EOBJ )
                    244:                                n->tp = t = bn->tp;
                    245:                }
                    246: 
                    247:                switch (t->base) {      // HACK, recursive unroller needed
                    248:                case RPTR:
                    249:                case PTR:
                    250:                case VEC:
                    251:                        if (Pptr(t)->typ->base == TYPE) { // unroll local typedefs:
                    252:                                Pname bn = Pbase(Pptr(t)->typ)->b_name;
                    253:                                if (bn->lex_level && (! bn->n_template_arg)
                    254:                                && bn->tp->base != COBJ 
                    255:                                && bn->tp->base != EOBJ )
                    256:                                        Pptr(t)->typ = bn->tp;
                    257:                        }
                    258:                }
                    259: 
                    260:                if (n->n_stclass==ENUM) if (list) continue; else return;
                    261: 
                    262:                if (n->where.line!=last_line.line || n->where.file!=last_line.file)
                    263:                        if (last_ll = n->where.line)
                    264:                                n->where.putline();
                    265:                        else
                    266:                                last_line.putline();
                    267:        
                    268:                int tc = Pbase(t)->b_const;
                    269:                for (Ptype tt = t; tt->base==TYPE; tt = Pbase(tt)->b_name->tp)
                    270:                        tc |= Pbase(tt)->b_const;
                    271:  
                    272:                switch (t->base) {
                    273:                case CLASS:
                    274: //fprintf(stderr,"class %s->dcl_print()\n",n->string);
                    275:                        if (n->base != TNAME) {
                    276:                                Pclass(t)->dcl_print(n);
                    277:                                sm = 1;
                    278:                        }
                    279:                        break;
                    280: 
                    281:                case ENUM:
                    282:                         Penum(t)->dcl_print(0);
                    283:                        sm = 1;
                    284:                        break;
                    285: 
                    286:                case FCT:
                    287:                {       Pfct f = Pfct(t);
                    288: 
                    289:                        if (n->base == TNAME) puttok(TYPEDEF);
                    290: 
                    291: //error('d',"fct %n->dcl_print() printed %d body %d defined %d",n,n->n_dcl_printed,f->body,f->defined);
                    292: //error('d',"n %d tbl %d tp %t inline %d",n,n->n_table,n->tp,f->f_inline);
                    293:                        if (n->n_dcl_printed==2 // definition already printed
                    294:                        || (n->n_dcl_printed==1 && f->body==0)
                    295:                                                // declaration already printed
                    296:                        ) {
                    297:                                // don't print again
                    298:                                sm = 1; // no SM
                    299:                                break;
                    300:                        }
                    301: 
                    302:                        if (f->f_result == 0) make_res(f);
                    303: 
                    304:                        if (f->body && n->n_sto==EXTERN) n->n_sto = 0;
                    305: 
                    306:                        if (f->f_inline) {
                    307:                                if (debug_opt)  {
                    308: //error('d',"f %t defined %d inline %d",f,f->defined,f->f_inline);
                    309:                                        if (f->defined&DEFINED
                    310:                                        && f->defined&SIMPLIFIED
                    311:                                        && f->f_inline!=ITOR)
                    312:                                                goto prnt_def;
                    313:                                        else if (n->n_dcl_printed==0)
                    314:                                                goto prnt_dcl;
                    315:                                        else {
                    316:                                                sm = 1;
                    317:                                                break;
                    318:                                        }
                    319:                                }
                    320:                                if (f->f_virtual || n->n_addr_taken) {
                    321:                                prnt_dcl:
                    322: //error('d',"prnt_dcl %d %n %k",n,n,n->n_sto);
                    323:                                        TOK st = n->n_sto;
                    324:                                        Pblock b = f->body;
                    325:                                        f->body = 0;
                    326:                                        t->dcl_print(n);
                    327:                                        n->n_dcl_printed = 1;
                    328:                                        n->n_sto = st;
                    329:                                        f->body = b;
                    330:                                        break;
                    331:                                }
                    332:                                else
                    333:                                        sm = 1; // no SM
                    334:                        }
                    335:                        else if ((f->defined&DEFINED)==0
                    336:                                || (f->defined&SIMPLIFIED)==0)
                    337:                                goto prnt_dcl;
                    338:                        else if (n->n_table==gtbl && strcmp(n->string,"main")==0) {
                    339:                                MAIN = 1;
                    340:                                gtbl->look("main",0)->use();
                    341:                                f->f_signature = 0;
                    342:                                t->dcl_print(n);
                    343:                                n->n_dcl_printed = f->body?2:1;
                    344:                                MAIN = 0;
                    345:                        }
                    346:                        else {
                    347:                        prnt_def:
                    348: //error('d',"prnt_def %n %k %d %k",n,n->n_oper,n,n->n_sto);
                    349:                                if (n->n_oper==CTOR || n->n_oper==DTOR) {
                    350:                                        Pclass cl = Pclass(n->n_table->t_name->tp);
                    351:                                        if (cl->c_body == 3) cl->print_all_vtbls(cl);
                    352:                                }
                    353:                                t->dcl_print(n);
                    354:                                n->n_dcl_printed = f->body?2:1;
                    355:                        }
                    356:                        if (f->body) sm = 1;
                    357:                        break;
                    358:                }
                    359: 
                    360:                case OVERLOAD:
                    361:                {
                    362:                        for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l) {
                    363:                                Pname nn = gl->f;
                    364:                                nn->dcl_print(0);
                    365:                                sm = 1;
                    366:                        }
                    367:                        break;
                    368:                }
                    369: 
                    370:                case ASM:
                    371:                        fprintf(out_file,"asm(\"%s\")\n",(char*)Pbase(t)->b_name);
                    372:                        break;
                    373: 
                    374:                case INT:
                    375:                case EOBJ:
                    376:                case CHAR:
                    377:                case LONG:
                    378:                case SHORT:
                    379:                tcx:
                    380:                        // do not allocate space for constants unless necessary
                    381:                        if (tc
                    382:                        && n->n_sto!=EXTERN     // extern const one;
                    383:                                                // const one = 1;
                    384:                                                // allocates storage
                    385:                        && (n->n_scope==EXTERN  // FUDGE const one = 1;
                    386:                                                // is treated as static
                    387:                                                // need loader support
                    388:                                || n->n_scope==STATIC
                    389:                                || n->n_scope==FCT)
                    390:                        ) {
                    391:                                if (n->n_evaluated) {
                    392:                                        sm = 1; /* no ; */
                    393:                                        break;
                    394:                                }
                    395:                        }
                    396:                        tc = 0;
                    397:                        // no break;
                    398: 
                    399:                default:
                    400:                {
                    401: /*     
                    402: //  don't print local instance of const
                    403:                        if ( n->n_dcl_printed == 3 ) {
                    404:                                sm = 1;
                    405:                                break;
                    406:                        }
                    407: */
                    408:                        Pexpr i = n->n_initializer;
                    409:                        if (tc) {
                    410:                                switch (tt->base) {
                    411:                                case CHAR:
                    412:                                case SHORT:
                    413:                                case INT:
                    414:                                case LONG:
                    415:                                case EOBJ:
                    416:                                        goto tcx;
                    417:                                }
                    418:                        }
                    419: 
                    420:                        if (n->base == TNAME) {
                    421:                                // Always print template formals, even when
                    422:                                // they have the same formal name, since the
                    423:                                // instantiation name is different. This fix
                    424:                                // should not be required when the copy
                    425:                                // mechanism is in place.
                    426:                                if (! n_template_arg)
                    427:                                  for (Pname tn=ktbl->look(n->string,HIDDEN); tn; tn=tn->n_tbl_list) 
                    428:                                        if (tn
                    429:                                        && tn->lex_level
                    430:                                        && t==tn->tp) return;
                    431:                                puttok(TYPEDEF);
                    432:                        }
                    433: 
                    434:                        if (n->n_stclass == REGISTER) {
                    435:                                // (imperfect) check against member functions
                    436:                                // register s a; a.f() illegal
                    437:                                Pname cln = n->tp->is_cl_obj();
                    438:                                if (cln) {
                    439:                                        Pclass cl = Pclass(cln->tp);
                    440:                                        if (cl->csu!=CLASS
                    441:                                        && cl->baselist==0
                    442:                                        && cl->has_itor()==0
                    443:                                        && cl->virt_count==0) puttok(REGISTER);
                    444:                                }
                    445:                                else
                    446:                                        puttok(REGISTER);
                    447:                        }
                    448: 
                    449:                        if (i) {
                    450:                                if (n->n_sto==EXTERN && n->n_stclass==STATIC) {
                    451:                                        n->n_initializer = 0;
                    452:                                        t->dcl_print(n);
                    453:                                        puttok(SM);
                    454:                                        n->n_initializer = i;
                    455:                                        n->n_sto = 0;
                    456:                                        t->dcl_print(n);
                    457:                                        n->n_sto = EXTERN;
                    458:                                }
                    459:                                else
                    460:                                        t->dcl_print(n);
                    461:                        }
                    462:                        else if (n->n_evaluated && Pbase(t)->b_const) {
                    463:                                if (n->n_sto==EXTERN && n->n_stclass==STATIC) {
                    464:                                        int v = n->n_evaluated;
                    465:                                        n->n_evaluated = 0;
                    466:                                        t->dcl_print(n);
                    467:                                        puttok(SM);
                    468:                                        n->n_evaluated = v;
                    469:                                        n->n_sto = 0;
                    470:                                        t->dcl_print(n);
                    471:                                        n->n_sto = EXTERN;
                    472:                                }
                    473:                                else
                    474:                                        t->dcl_print(n);
                    475:                        }
                    476:                        else {
                    477: //error('d',"%n sto %k val %d stc %k",n,n->n_sto,n->n_val,n_stclass);
                    478:                                if ((n->n_sto==0 || (n->n_val && n->n_evaluated==0))
                    479:                                 && n_stclass==STATIC
                    480:                                && n->n_sto!=STATIC
                    481:                                 && n->n_table==gtbl) {
                    482:                                         if (n->n_val && n->n_evaluated==0) { 
                    483:                                                 // extern x = f();
                    484:                                                 // generate int x = 0;       
                    485:                                                 // plus dynamic initialization
                    486:                                                 n->n_sto = 0;
                    487:                                         }
                    488:                                         Ptype tt = t;
                    489:                                zaq:
                    490:                                        switch (tt->base) {
                    491:                                        case TYPE:
                    492:                                                tt = Pbase(tt)->b_name->tp; goto zaq;
                    493:                                        case COBJ:      // "X a;" == "X a = {0};"
                    494:                                        {
                    495:                                                TOK csu = Pclass(Pbase(tt)->b_name->tp)->csu;
                    496:                                                if (csu != UNION)
                    497:                                                        n->n_initializer = i = new expr(ILIST,zero,0);
                    498:                                                break;
                    499:                                        }
                    500:                                        case PTR:
                    501:                                                if (tt->memptr()) {
                    502:                                                        i = new expr(ELIST,zero,zero);
                    503:                                                        n->n_initializer = i = new expr(ILIST,i,zero);
                    504:                                                        break;
                    505:                                                }
                    506:                                                // no break
                    507:                                        case CHAR:
                    508:                                        case SHORT:
                    509:                                        case INT:
                    510:                                        case EOBJ:
                    511:                                        case LONG:
                    512:                                        case FLOAT:
                    513:                                        case DOUBLE:
                    514:                                         case LDOUBLE:  // "int a;" == "int a = 0;"
                    515:                                                n->n_initializer = i = zero;
                    516:                                        }
                    517:                                }
                    518:                                t->dcl_print(n);
                    519:                        }
                    520: 
                    521:                        if (n->n_scope!=ARG) {
                    522:                                if (i) {
                    523:                                        puttok(ASSIGN);
                    524: 
                    525:                                        Pexpr i2 = i;
                    526:                                        while (i2->base == CAST) i2 = i2->e1;
                    527:                                        if (i2->base == ILIST) i = i2;
                    528:                                        if (t!=i->tp
                    529:                                        && i->base!=ZERO
                    530:                                        && i->base!=ILIST /*&& i->tp!=Pchar_type*/) {
                    531:                                                Ptype t1 = n->tp;
                    532:                                        cmp:
                    533:                                                switch (t1->base) {
                    534:                                                case TYPE:      
                    535:                                                        t1 = Pbase(t1)->b_name->tp;
                    536:                                                        goto cmp;
                    537:                                                default:
                    538:                                                        i->print();
                    539:                                                        break;
                    540:                                        //      case EOBJ:
                    541:                                        //              goto cst;
                    542:                                                case VEC:
                    543:                                                        if (Pvec(t1)->typ->base==CHAR) {
                    544:                                                                i->print();
                    545:                                                                break;
                    546:                                                        }
                    547:                                                        // no break
                    548:                                                case PTR:
                    549:                                                case RPTR:
                    550:                                                        if (i->tp==0 || n->tp->check(i->tp,0)) {
                    551:                                           //      cst:
                    552:                                                                putch('(');
                    553:                                                                bit oc = Cast;
                    554:                                                                Cast = 1;
                    555:                                                                t->print();
                    556:                                                                Cast = oc;
                    557:                                                                putch(')');
                    558:                                                        }
                    559:                                                        eprint(i);
                    560:                                                }
                    561:                                        }
                    562:                                        else {
                    563:                                                if (i==zero) {
                    564:                                                        while (t->base == TYPE) t = Pbase(t)->b_name->tp;
                    565:                                        //              if (t->base == EOBJ) {
                    566:                                        //                      putch('(');
                    567:                                        //                      bit oc = Cast;
                    568:                                        //                      Cast = 1;
                    569:                                        //                      t->print();
                    570:                                        //                      Cast = oc;
                    571:                                        //                      putch(')');
                    572:                                        //              }
                    573:                                                }
                    574:                                                eprint(i);
                    575:                                                
                    576:                                        //      i->print();
                    577:                                        }
                    578:                                }
                    579:                                else if (n->n_evaluated) {
                    580:                                        puttok(ASSIGN);
                    581:                                        if (n->tp->base!=INT || n->tp->is_unsigned()) {
                    582:                                                putstring("((");
                    583:                                                bit oc = Cast;
                    584:                                                Cast = 1;
                    585:                                                n->tp->print();
                    586:                                                Cast = oc;
                    587:                                                fprintf(out_file,")%d)",n->n_val);
                    588:                                        }
                    589:                                        else
                    590:                                                fprintf(out_file,"%d",n->n_val);
                    591:                                }
                    592:                        }
                    593:                }
                    594:                }
                    595: 
                    596:                switch (list) {
                    597:                case SM:
                    598:                        if (sm==0) puttok(SM);
                    599:                        break;
                    600:                case 0:
                    601:                        if (sm==0) puttok(SM);
                    602: #if OUTPUT_PAIR_FUNCTIONALITY
                    603:                        if (capture_renaming) { /* Rick, ODI, 3-28-89; used 
                    604:                                                   to switch on renaming 
                    605:                                                   capture. */
                    606:                            output_pair(this);
                    607:                        }
                    608: #endif     
                    609:                        return;
                    610:                case CM:
                    611:                        if (n->n_list) puttok(CM);
                    612:                        break;
                    613:                }
                    614:        }
                    615: 
                    616: #if OUTPUT_PAIR_FUNCTIONALITY
                    617:        if (capture_renaming) { /* rick, ODI, 3-28-89; used 
                    618:                                  to switch off some cfront
                    619:                                      renaming. */
                    620:            if (list != SM)
                    621:                output_pair(this);
                    622:        }
                    623: #endif
                    624: 
                    625: } 
                    626: 
                    627: char *local_sign( Ptype pt )
                    628: { // get function signature for local class
                    629:        char buf[1024];
                    630:        char* bb = pt->signature(buf);
                    631:        int ll = bb-buf;
                    632:        if (1023 < ll) error('i',"local class N buffer overflow");
                    633:        char *p = new char[ll+1];
                    634:        strcpy(p,buf);
                    635:        return p;
                    636: }
                    637: 
                    638: 
                    639: void enumdef::dcl_print(Pname cln)
                    640: /*
                    641: */
                    642: {
                    643:        char* s = cln ? cln->string : 0;
                    644:        fprintf(out_file,"enum %s { ",string);
                    645:        for (Pname px, p=mem; p; p=px) {
                    646:                px = p->n_list;
                    647:                if (s) {
                    648:                        if (p->n_initializer)
                    649:                                fprintf(out_file,"%s__%s = %d",p->string,s,p->n_val);
                    650:                        else
                    651:                                fprintf(out_file,"%s__%s",p->string,s);
                    652:                }
                    653:                else {
                    654:                        if (p->n_initializer)
                    655:                                fprintf(out_file,"%s = %d",p->string,p->n_val);
                    656:                        else
                    657:                                fprintf(out_file,"%s",p->string);
                    658:                }
                    659:                if (px) puttok(CM);
                    660:                p->n_initializer = 0;
                    661:                delete p;
                    662:        }
                    663: /* Sam says: don't zap MEM. It may be needed for the program database later. */
                    664: //     mem = 0;
                    665:        puttok(RC);
                    666:        puttok(SM);
                    667: }
                    668: 
                    669: 
                    670: extern char *make_local_name(Pclass,int=0);
                    671: 
                    672: void name::print()
                    673: 
                    674:     /* print just the name itself */
                    675: 
                    676: {
                    677: 
                    678:     /* Rick, ODI, 3-28-89: This function transforms the names of name
                    679:        instances. In fact, with default cfront renaming, only types and
                    680:        globals pass though unscathed. This makes debugging a real pain
                    681:        in the ass. Consequently, a mode has been introduced to cfront which
                    682:        limits renaming (see main.c:main:case "+gx"). Using this mode reduces
                    683:        the renaming to the following cases:
                    684: 
                    685:        -- static data members are suffixed with the name of their
                    686:          class with '__#' at the beginning of the class name. The '#'
                    687:          is the length of the class name. So, for example, given 
                    688:          "class C { static int i; }", "i" would become the global variable 
                    689:          "i__1C"--this makes global name clashes less likely;
                    690: 
                    691:        -- data members are prefixed just like static data members
                    692:          only when the data member's name is identical to the name
                    693:          of a data member in a base class. For example, given
                    694:          "class B { int i; } class D : B { float i; }" the first
                    695:          would not be renamed, so its name would be "i", while
                    696:          the second would be renamed to "i__1D";
                    697: 
                    698:        -- functions are transformed as before. Given overloading
                    699:          and the fact that function members are transformed into
                    700:          global functions, function renaming must be preserved;
                    701: 
                    702:        -- anonymous unions have names generated for them (someone's
                    703:          got to do it).
                    704: 
                    705:        All other cases are not renamed using the the "gx" mode. Additionally,
                    706:        the generated names of anonymous unions have been simplified. Finally,
                    707:        all names which are transformed into global objects have must have
                    708:        any renamings be exactly as with default renaming. */
                    709: 
                    710:     if (this == 0) error('i',"0->N::print()");
                    711: 
                    712:     if (capture_renaming) {    /* rick, ODI, 3-28-89; used to switch on 
                    713:                                   renaming capture. */
                    714:        new_string[0] = '\0';
                    715:        tmp_string[0] = '\0';
                    716:       }
                    717: 
                    718:     if (string == 0) {
                    719:        if (emode) putch('?');
                    720:        if (capture_renaming) {         /* rick, ODI, 3-28-89; used to switch 
                    721:                                           on renaming capture. */
                    722:            new_string[0] = '\0';
                    723:            goto handle_new_string;
                    724:          }
                    725:        return;
                    726:       }
                    727: 
                    728:     // error( 'd', "%s->name::print(), base: %k", string, base );
                    729:     
                    730:     switch (base) {
                    731:     case TNAME:
                    732:         if ((n_template_arg_string) && emode &&tp) {
                    733:          // hide the mangled type name, and use the type instead, since it is
                    734:          // more useful 
                    735:          tp->dcl_print(0) ;
                    736:          return ;
                    737:        } ;
                    738:       
                    739:        if( emode && tp && tp->base == COBJ) {
                    740:            Pclass cl = Pclass(Pbase(tp)->b_name->tp);
                    741:            if(cl && cl->base == CLASS && 
                    742:               (cl->class_base == instantiated_template_class)) {
                    743:                   Ptclass(cl)->inst->print_pretty_name() ;
                    744:                   return;
                    745:               }
                    746:        }
                    747: 
                    748:        putst(n_template_arg_string ? n_template_arg_string : string);
                    749:        if (capture_renaming) {
                    750:            /* Rick, ODI, 3-28-89: capture renaming. */
                    751:            strcat(new_string,
                    752:                   (n_template_arg_string ? n_template_arg_string : string));
                    753:            goto handle_new_string;
                    754:          }
                    755:        return;
                    756: 
                    757:       case MDOT:
                    758:        Pexpr(this)->print();
                    759:        return;
                    760:       }
                    761:     
                    762:     if (emode) {
                    763:        Ptable tbl;
                    764:        char* cs = 0;
                    765:        bit f = 0;
                    766:        if (tp) {
                    767:            switch (tp->base) {
                    768:              case OVERLOAD:
                    769:              case FCT:
                    770:                f = 1;
                    771:              default:
                    772:                if (tbl=n_table) {
                    773:                    if (tbl == gtbl) {
                    774:                        if (f == 0) {
                    775:                            putstring("::");
                    776:                            if (capture_renaming) {
                    777:                                /* Rick, ODI, 3-28-89: capture renaming. */
                    778:                                strcat(new_string, "::");
                    779:                              }
                    780:                          }
                    781:                      }
                    782:                    else {
                    783:                      if (tbl->t_name) {
                    784:                        Ptclass pc = Ptclass(tbl->t_name->tp) ;
                    785:                        cs = tbl->t_name->string;
                    786:                        if ((pc->base == CLASS)  && 
                    787:                            (pc->class_base == instantiated_template_class))
                    788:                          pc->inst->print_pretty_name() ;
                    789:                        else fprintf(out_file,"%s",cs);
                    790:                        fprintf (out_file, "::") ;
                    791:                        
                    792:                            if (capture_renaming) {
                    793:                                 // Sam: I think this is not necessary in
                    794:                                 // "emode" context 
                    795:                                /* Rick, ODI, 3-28-89: capture renaming. */
                    796:                                sprintf(tmp_string,"%s::",cs);
                    797:                                strcat(new_string, tmp_string);
                    798:                              }
                    799:                          }
                    800:                      }
                    801:                  }
                    802:                
                    803:                // local class will need to modify ???
                    804: 
                    805:                if (n_scope==ARG && strcmp(string,"this")==0) {
                    806:                    // tell which "this" it is
                    807:                    Ptype tt = Pptr(tp)->typ;
                    808:                    Pname cn = Pbase(tt)->b_name;
                    809:                    fprintf(out_file,"%s::",cn->string);
                    810:                    if (capture_renaming) {
                    811:                        /* Rick, ODI, 3-28-89: capture renaming. */
                    812:                        sprintf(tmp_string, "%s::",cn->string);
                    813:                        strcat(new_string, tmp_string);
                    814:                      }
                    815: 
                    816:                  }
                    817:                
                    818:              case CLASS:
                    819:              case ENUM:
                    820:                //      case TYPE:
                    821:                break;
                    822:              }
                    823:          nop:
                    824:            switch (n_oper) {
                    825:              case TYPE:
                    826:                putstring("operator ");
                    827:                if (capture_renaming) {
                    828:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    829:                    strcat(new_string, "operator ");
                    830:                  }
                    831:                if (tp) Pfct(tp)->returns->dcl_print(0);
                    832:                break;
                    833:              case 0:
                    834:                putstring(string);
                    835:                if (capture_renaming) {
                    836:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    837:                    strcat(new_string, string);
                    838:                  }
                    839:                break;
                    840:              case DTOR:
                    841:                putch('~');
                    842:                if (capture_renaming) {
                    843:                    /* Rick, ODI, 6-6-89: capture renaming. */
                    844:                    strcat(new_string, "~");
                    845:                  }
                    846:              case CTOR:
                    847:                if (cs) {
                    848:                    if(tbl->t_name) {
                    849:                        Ptclass pc = Ptclass(tbl->t_name->tp) ;
                    850:                        if ((pc->base == CLASS)  && 
                    851:                            (pc->class_base == instantiated_template_class))
                    852:                            pc->inst->print_pretty_name() ;
                    853:                        } else putstring(cs);
                    854:                    if (capture_renaming) {
                    855:                        /* Rick, ODI, 3-28-89: capture renaming. */
                    856:                        strcat(new_string, cs);
                    857:                      }
                    858:                  }
                    859: 
                    860:                else {
                    861:                    putstring("constructor");
                    862:                    if (capture_renaming) {
                    863:                        /* Rick, ODI, 3-28-89: capture renaming. */
                    864:                        strcat(new_string, "constructor");
                    865:                      }
                    866:                    f = 0;
                    867:                  }
                    868:                break;
                    869:              case TNAME:
                    870:                putstring(string);
                    871:                if (capture_renaming) {
                    872:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    873:                    strcat(new_string, string);
                    874:                  }
                    875:                break;
                    876:              default:
                    877:                putstring("operator ");
                    878:                if (capture_renaming) {
                    879:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    880:                    strcat(new_string,"operator " );
                    881:                  }
                    882:                putstring(keys[n_oper]);
                    883:                if (capture_renaming) {
                    884:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    885:                    strcat(new_string, keys[n_oper]);
                    886:                  }
                    887:                break;
                    888:              }
                    889:            if (f) {
                    890:                putstring("()");
                    891:                if (capture_renaming) {
                    892:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    893:                    strcat(new_string,"()");
                    894:                  }
                    895:              }
                    896:          }
                    897:        else {
                    898:            if (n_oper) goto nop;
                    899:            if (string) {
                    900:                putstring(n_template_arg_string ?
                    901:                          n_template_arg_string : string);
                    902:                if (capture_renaming) {
                    903:                    /* Rick, ODI, 3-28-89: capture renaming. */
                    904:                    strcat(new_string,
                    905:                           (n_template_arg_string ?
                    906:                            n_template_arg_string : string));
                    907:                  }
                    908:              }
                    909:          }
                    910:        if (capture_renaming) { /* rick, ODI, 3-28-89; used 
                    911:                                    to switch on renaming capture. */
                    912:            goto handle_new_string;
                    913:          }
                    914:        return;
                    915:       }
                    916:     
                    917:     // AT&T used initializations. Rick's goto povoked a diagnostic. so...
                    918:     char* sig; sig = 0;
                    919:     Pclass cl; cl = 0;
                    920:     int i; i = n_union;
                    921: 
                    922:     if (tp) {
                    923:        Ptable tbl;
                    924:        
                    925:        switch (tp->base) {
                    926:          default:
                    927:            if (tbl=n_table) {  // global or member
                    928:                Pname tn;
                    929:                if (tbl == gtbl) {
                    930:                    
                    931:                    /* Rick, ODI, 3-28-89: "gtbl" is the table of global 
                    932:                       names (see cfront.h:124). So, "tbl" is the table 
                    933:                       of global names here. */
                    934: 
                    935:                    // if (i) fprintf(out_file,"__O%d.",i);
                    936: 
                    937:                    if ( i ) {
                    938:                        /* Rick, ODI, 3-28-89: If "i" is greater than 0, then
                    939:                           then "this" refers to an anonymous union member,
                    940:                           whose union is global (see closest-containing 
                    941:                           if). */
                    942: 
                    943:                        if ( ! capture_renaming) {
                    944:                            /* Rick, ODI, 3-28-89: use full cfront
                    945:                               renaming. */ 
                    946:                            if (n_anon) 
                    947:                                fprintf(out_file,"__O%d.%s.", i, n_anon );
                    948:                            else fprintf(out_file,"__O%d.",i);
                    949:                          }
                    950:                        else {
                    951:                            /* Capture the transformed name. */
                    952:                            if (n_anon) {
                    953:                                fprintf(out_file,"__O%d.%s.", i, n_anon );
                    954:                                sprintf(tmp_string, "__O%d.%s.", i, n_anon);
                    955:                              }
                    956:                            else {
                    957:                                fprintf(out_file,"__O%d.",i);
                    958:                                sprintf(tmp_string, "__O%d.", i);
                    959:                              }
                    960:                            strcat(new_string, tmp_string);
                    961:                          }
                    962:                      }
                    963:                    break;
                    964:                  }
                    965:                
                    966:                if (tn=tbl->t_name) {
                    967:                    cl = Pclass(tn->tp);
                    968:                    /* Rick, ODI: The table associated with "this" has a 
                    969:                       name--it corresponds to a named scope. */
                    970:                    if (i) {
                    971:                        
                    972:                        /* Rick, ODI, 3-28-89: If "i" is greater than 0, then
                    973:                           then "this" refers to an anonymous union member,
                    974:                           whose union is NOT global (see if(tbl == gtbl)
                    975:                           above, note case global anonymous union has
                    976:                           break). */
                    977: 
                    978:                        if (cl->string[0]=='_'  
                    979:                            && cl->string[1]=='_'
                    980:                            && cl->string[2]=='C' )
                    981:                          {
                    982:                            if ( ! capture_renaming) {
                    983:                                /* Rick, ODI, 3-28-89; use full cfront 
                    984:                                   renaming. */
                    985:                                if (n_anon)
                    986:                                    fprintf(out_file,"__O%d.%s.", i, n_anon );
                    987:                                else fprintf(out_file,"__O%d.",i);
                    988:                              }
                    989:                            else {
                    990:                                /* Rick, ODI: Capture the transformed name. */
                    991:                                if (n_anon) {
                    992:                                    fprintf(out_file,"__O%d.%s.", i, n_anon );
                    993:                                    sprintf(tmp_string, "__O%d.%s", i, n_anon);
                    994:                                  }
                    995:                                else {
                    996:                                    fprintf(out_file,"__O%d.",i);
                    997:                                    sprintf(tmp_string, "__O%d.", i);
                    998:                                  }
                    999:                                strcat(new_string, tmp_string);
                   1000:                              }
                   1001:                          }
                   1002:                        else if ( cl->lex_level ) {
                   1003:                            char *str = make_local_name(cl,1);
                   1004:                            if ( ! capture_renaming) {
                   1005:                                /* Rick, ODI, 3-28-89; use full cfront 
                   1006:                                   renaming. */
                   1007:                                fprintf(out_file,"__O%d%s.",i,str);
                   1008:                              }
                   1009:                            else {
                   1010:                                /* Rick, ODI: Capture the transformed name. */
                   1011:                                fprintf(out_file,"__O%d%s.",i,str);
                   1012:                                sprintf(tmp_string, "__O%d%s.", i, str);
                   1013:                                strcat(new_string, tmp_string);
                   1014:                              }
                   1015:                            delete str;
                   1016:                          }
                   1017:                        else {
                   1018:                            if ( ! capture_renaming) {
                   1019:                                /* Rick, ODI, 3-28-89; use full cfront 
                   1020:                                   renaming. */
                   1021:                                fprintf(out_file,"__O%d__%d%s.",
                   1022:                                        i,cl->strlen,cl->string);
                   1023:                              }
                   1024:                            else if ( ! limit_renaming) {
                   1025:                                /* Rick, ODI: Capture the transformed name. */
                   1026:                                fprintf(out_file,"__O%d__%d%s.", 
                   1027:                                        i,cl->strlen,cl->string);
                   1028:                                sprintf(tmp_string, "__O%d__%d%s.",
                   1029:                                        i,cl->strlen,cl->string);
                   1030:                                strcat(new_string, tmp_string);
                   1031:                              }
                   1032:                            else {
                   1033:                                /* Rick, ODI: Capture the transformed name. 
                   1034:                                   Note, that renaming less extensive than
                   1035:                                   if part. */
                   1036:                                fprintf(out_file,"__O%d.", i);
                   1037:                                sprintf(tmp_string, "__O%d.", i);
                   1038:                                strcat(new_string, tmp_string);
                   1039:                              }
                   1040:                          }
                   1041:                        cl = 0;
                   1042:                      }
                   1043:                    else if (cl->string[0]=='_'
                   1044:                             && cl->string[1]=='_'
                   1045:                             && cl->string[2]=='C'
                   1046:                             && n_stclass != STATIC )
                   1047:                        cl = 0;
                   1048:                    break;
                   1049:                  }
                   1050:              }
                   1051:            
                   1052:            switch (n_stclass) {        // local variable
                   1053:              case STATIC:
                   1054:              case EXTERN:
                   1055:                if (i) {
                   1056:                    /* Rick, ODI, 3-28-89: If "i" is greater than 0, then
                   1057:                       then "this" refers to a an anonymous union member.  */
                   1058:                    
                   1059:                    if ( ! capture_renaming) {
                   1060:                        /* Rick, ODI, 3-28-89; use full cfront renaming. */ 
                   1061:                        fprintf(out_file,"__O%d.",i);
                   1062:                      }
                   1063:                    else {
                   1064:                        /* Capture the renaming. */
                   1065:                        fprintf(out_file,"__O%d.",i);
                   1066:                        sprintf(tmp_string, "__O%d.", i);
                   1067:                        strcat(new_string, tmp_string);
                   1068:                      }
                   1069:                  }
                   1070:                else if (n_sto==STATIC && tp->base!=FCT) {
                   1071:                    /* Rick, ODI, 3-28-89: With full renaming, if the 
                   1072:                       transformation of "this" is static (n_sto == STATIC)
                   1073:                       and not a function, then the name is prefixed with 
                   1074:                       "_static_". I'm not sure why this transformation is
                   1075:                       ever necessary. Static variables never seem to have
                   1076:                       their scopes changed, so there aren't any conflicts.
                   1077:                       As for static data members, their n_sto == EXTERN
                   1078:                       since they are transformed into global variables. */
                   1079:                    // Benson sez: death to __0 names!
                   1080:                    if (capture_renaming && ! limit_renaming) {
                   1081:                        /* rick, ODI, 3-28-89; use full cfront renaming. */ 
                   1082:                        if (lex_level == 0) {
                   1083:                            putstring("__S");
                   1084:                            strcat(new_string, "__S");
                   1085:                          }
                   1086:                        else {
                   1087:                            fprintf(out_file,"__%d",lex_level);
                   1088:                            sprintf(tmp_string, "__%d", lex_level);
                   1089:                            strcat(new_string, tmp_string);
                   1090:                          }
                   1091:                      }
                   1092:                    else if ( ! capture_renaming && ! limit_renaming) {
                   1093:                        /* rick, ODI, 3-28-89; use full cfront renaming. */ 
                   1094:                        if (lex_level == 0)
                   1095:                            putstring("__S");
                   1096:                        else
                   1097:                            fprintf(out_file,"__%d",lex_level);
                   1098:                      }
                   1099:                  }
                   1100:                break;
                   1101:              default:
                   1102:                // encode with lexicallevel UNLESS ``special''
                   1103:                // e.g. __builtin
                   1104:                if (string[0]!='_' || string[1]!='_' || string[2] != 'C' ) {
                   1105:                    // error( 'd', "print2 i: %d, lex_level: %d this: %n", i, lex_level,this );
                   1106:                    if (i) {
                   1107:                        if ( ! capture_renaming) {
                   1108:                            /* Rick, ODI: WARNING: should check that new 
                   1109:                               version doesn't have problem with anonymous 
                   1110:                               classes at the file level or within a block. */
                   1111: 
                   1112:                             /* Rick, ODI, 6-20-89: Lex lexel can't be
                   1113:                               printed here unless it is also printed in
                   1114:                               the union's declaration which is handled
                   1115:                                above. The simplest fix is to get rid of
                   1116:                                the lex level output. */
                   1117:                            /* Previous version's prints: 
                   1118:                               fprintf(out_file,"__%d__O%d.",lex_level-1,i,i);
                   1119:                               fprintf(out_file,"__O%d.",i,i); */
                   1120:                            if (n_anon)
                   1121:                                fprintf(out_file,"__%d__O%d.%s.",
                   1122:                                        lex_level-1,i,n_anon);
                   1123:                            else fprintf(out_file,"__%d__O%d.",lex_level-1,i);
                   1124:                          }
                   1125:                        else if (capture_renaming && ! limit_renaming) {
                   1126:                            /* Rick, ODI: WARNING: should check that new 
                   1127:                               version doesn't have problem with anonymous 
                   1128:                               classes at the file level or within a block. */
                   1129: 
                   1130:                             /* Rick, ODI, 6-20-89: Lex lexel can't be
                   1131:                               printed here unless it is also printed in
                   1132:                               the union's declaration which is handled
                   1133:                                above. The simplest fix is to get rid of
                   1134:                                the lex level output. */
                   1135:                            /* Previous version's prints: 
                   1136:                               fprintf(out_file,"__%d__O%d.",lex_level-1,i,i);
                   1137:                               fprintf(out_file,"__O%d.",i,i); */
                   1138:                            if (n_anon) {
                   1139:                                fprintf(out_file,"__%d__O%d.%s.",
                   1140:                                        lex_level-1,i,n_anon);
                   1141:                                sprintf(tmp_string, "__%d__O%d.%s.",
                   1142:                                        lex_level-1,i,n_anon);
                   1143:                                strcat(new_string, tmp_string);
                   1144:                              }
                   1145:                            else {
                   1146:                                fprintf(out_file,"__%d__O%d.",lex_level-1,i);
                   1147:                                sprintf(tmp_string, "__%d__O%d.",
                   1148:                                        lex_level-1,i);
                   1149:                                strcat(new_string, tmp_string);
                   1150:                              }
                   1151:                          }
                   1152:                        else {
                   1153:                            /* Capture the renaming. Note, the renaming is not
                   1154:                               as extensive as the if part. */
                   1155:                            if (n_anon) {
                   1156:                                fprintf(out_file,"__O%d.%s.", i,n_anon);
                   1157:                                sprintf(tmp_string,"__O%d.%s.", i,n_anon);
                   1158:                              }
                   1159:                            else {
                   1160:                                fprintf(out_file,"__O%d.", i);
                   1161:                                sprintf(tmp_string,"__O%d.", i);
                   1162:                              }
                   1163:                            strcat(new_string, tmp_string);
                   1164:                          }
                   1165:                      }
                   1166:                    else
                   1167:                        if( ! limit_renaming) {
                   1168:                            /* rick, ODI, 3-28-89; use full cfront renaming. */
                   1169:                            fprintf(out_file,"__%d",lex_level);
                   1170:                            if (capture_renaming) {
                   1171:                                sprintf(tmp_string, "__%d", lex_level);
                   1172:                                strcat(new_string, tmp_string);
                   1173:                              }
                   1174:                          }     
                   1175:                  }
                   1176:              }
                   1177:            break;
                   1178:          case CLASS:
                   1179:          case ENUM:
                   1180:            break;
                   1181:          }
                   1182:        
                   1183:        if (tp->base==FCT) {
                   1184:            sig = Pfct(tp)->f_signature;
                   1185:            if (sig && sig[0]==0) sig = 0;
                   1186:          }
                   1187:       }
                   1188:     
                   1189:     if (string) {
                   1190: #ifdef DENSE
                   1191:        /* Rick, ODI, 6-6-89: This is suppose to be for machines with a 31 
                   1192:           character limit on the length of an identifier. Only the first
                   1193:           29 [0..28] characters are perserved, the remaining characters are
                   1194:           hashed and the result is used to generate characters [29] and
                   1195:           [30] out of a choice of 63 characters (see chop() below). In a
                   1196:           uniform distribution, the two characters positions would produce 
                   1197:           3969 possibilities. The real question is what are the likely
                   1198:           distributions? We might want to analyse the reliability
                   1199:           of this algorithm to determine whether or not it should be 
                   1200:           removed. At least the authors gave the #define an appropriate 
                   1201:           name. */
                   1202:        int i = strlen(string);
                   1203:        if (cl) i += cl->strlen+4;      // __dd<class name>
                   1204:        if (sig) {
                   1205:            if (cl == 0) i += 2;
                   1206:            i += strlen(sig);
                   1207:          }
                   1208:        
                   1209:        if (31<i) {
                   1210:            char buf[1024];
                   1211: 
                   1212:            if ( ! limit_renaming || tp->base == FCT || tp->base == INLINE ||
                   1213:                tp->base == VIRTUAL || tp->base == OVERLOAD ||
                   1214:                tp->base == OPERATOR) {
                   1215: 
                   1216:                /* Rick, ODI, 3-28-89: Not much can be done with
                   1217:                   functions. Given overloading and the fact that 
                   1218:                   all class function members are transformed into 
                   1219:                   global functions, function name transformation
                   1220:                   must be left alone. */
                   1221: 
                   1222:                if (cl && sig)
                   1223:                    sprintf(buf,"%s__%d%s%s",string,cl->strlen,cl->string,sig);
                   1224:                else if (cl)
                   1225:                    sprintf(buf,"%s__%d%s",string,cl->strlen,cl->string);
                   1226:                else if (sig)
                   1227:                    sprintf(buf,"%s__%s",string,sig);
                   1228:                else 
                   1229:                    sprintf(buf,"%s",string);
                   1230: 
                   1231:              }
                   1232: 
                   1233:            else if ((class_name = is_data_member(this)) &&
                   1234:                     (n_stclass == STATIC ||
                   1235:                      matches_base_member(this, Pclass(class_name->tp)))) {
                   1236: 
                   1237:                /* Rick, ODI, 3-28-89: There are two cases where
                   1238:                   a data member must have its name transformed:
                   1239:                       -- when the data member is static;
                   1240:                       -- when the data member has the same name
                   1241:                          as data member belonging to any of the
                   1242:                          class's base types. 
                   1243:                   Capture the name transformation. */
                   1244: 
                   1245:                if (cl)
                   1246:                    sprintf(buf,"%s__%d%s",string,cl->strlen,cl->string);
                   1247:                else 
                   1248:                    sprintf(buf,"%s",string);
                   1249:                
                   1250:              }
                   1251: 
                   1252:            else /* Don't rename. */
                   1253:                sprintf(buf,"%s",string);
                   1254: 
                   1255:            chop(buf);
                   1256:            fprintf(out_file,"%s ",buf);
                   1257:            if (capture_renaming) {
                   1258:                /* Capture renaming. */
                   1259:                strcat(new_string, buf);
                   1260:              }
                   1261:            if (capture_renaming)
                   1262:                goto handle_new_string;
                   1263:            return;
                   1264:          }
                   1265: #endif
                   1266:        putstring(n_template_arg_string ? n_template_arg_string : string);
                   1267:        if (capture_renaming) { /* Capture renaming. */
                   1268:          strcat(new_string,
                   1269:                 (n_template_arg_string ? n_template_arg_string : string));
                   1270:          }
                   1271:        
                   1272:        // local class
                   1273: 
                   1274:        /* Rick, ODI, 6-7-89: I don't know why the previous comment
                   1275:           asserts that "cl" is a "local class". As near as I can tell
                   1276:           any class will set cl to non-zero and only the cases of
                   1277:           unions and classes whose names begin with "__C" and have
                   1278:           non-static data members clear cl. */
                   1279: 
                   1280:        Pname class_name;       /* Rick, ODI, 6-7-89: Used to hold
                   1281:                                   a data member's class name. */
                   1282: 
                   1283:        if ( cl ) {
                   1284:            if ( cl->lex_level ) { /* Rick, ODI, 6-7-89: Can assert here
                   1285:                                      that "cl" is a local class. */
                   1286:                char *str = str = make_local_name( cl, 1 );
                   1287:                putstring( str );
                   1288:                delete str;
                   1289:              }
                   1290:            else { // Rick, ODI, 6-7-89: Global class (cl->lex_level == 0).
                   1291: 
                   1292:                if ( ! limit_renaming || tp->base == FCT || 
                   1293:                    tp->base == INLINE || tp->base == VIRTUAL || 
                   1294:                    tp->base == OVERLOAD || tp->base == OPERATOR) {
                   1295: 
                   1296:                    /* Rick, ODI, 3-28-89: Not much can be done with
                   1297:                       functions. Given overloading and the fact that 
                   1298:                       all class function members are transformed into 
                   1299:                       global functions, function name transformation
                   1300:                       must be left alone. */
                   1301: 
                   1302:                    fprintf(out_file,"__%d%s",cl->strlen,cl->string);
                   1303:                    if (capture_renaming) { /* Capture renaming. */
                   1304:                        sprintf(tmp_string, "__%d%s", cl->strlen,cl->string);
                   1305:                        strcat(new_string, tmp_string);
                   1306:                      }
                   1307:                  }
                   1308: 
                   1309:                else if ((class_name = is_data_member(this)) &&
                   1310:                         (n_stclass == STATIC ||
                   1311:                          matches_base_member(this, Pclass(class_name->tp)))) {
                   1312: 
                   1313:                    /* Rick, ODI, 3-28-89: There are two cases where
                   1314:                       a data member must have its name transformed:
                   1315:                           -- when the data member is static;
                   1316:                           -- when the data member has the same name
                   1317:                              as data member belonging to any of the
                   1318:                              class's base types. 
                   1319:                       Capture the name transformation. */
                   1320: 
                   1321:                    fprintf(out_file,"__%d%s",cl->strlen,cl->string);
                   1322:                    if (capture_renaming) { /* Capture renaming. */
                   1323:                        sprintf(tmp_string, "__%d%s", cl->strlen,cl->string);
                   1324:                        strcat(new_string, tmp_string);
                   1325:                      }
                   1326:                  }
                   1327:              }
                   1328:          }
                   1329:        
                   1330:        if (sig) { /* Rick, ODI, 6-7-89: Function, so output signiture */
                   1331:            if (cl == 0) {
                   1332:                putstring("__");
                   1333:                if (capture_renaming) { /* Capture renaming. */
                   1334:                    strcat(new_string, "__");
                   1335:                  }
                   1336:              }
                   1337:            putstring(sig);
                   1338:            if (capture_renaming) { /* Capture renaming. */
                   1339:                strcat(new_string, sig);
                   1340:              }
                   1341:          }
                   1342:        putch(' ');
                   1343:        
                   1344:       }
                   1345: 
                   1346:   handle_new_string:
                   1347:  
                   1348:     if (capture_renaming) {
                   1349: 
                   1350:        /* Rick, ODI, 3-28-89: If the renaming has not been seen before,
                   1351:           then set "this"'s "output_string" to refer to the renaming. */
                   1352:  
                   1353:        if (string && new_string[0] != '\0' &&
                   1354:            strcmp(string, new_string) != 0 &&
                   1355:            ! (tp->base == FCT && ! Pfct(tp)->body)) {
                   1356:            if ( ! output_string || strcmp(output_string, new_string) != 0) {
                   1357:                if (output_string)
                   1358:                    delete output_string;
                   1359:                output_string = new char[strlen(new_string) + 1];
                   1360:                strcpy(output_string, new_string);
                   1361:              }
                   1362: #if OUTPUT_PAIR_FUNCTIONALITY
                   1363:            if (tp->base == FCT)
                   1364:                output_pair(this);
                   1365: #endif
                   1366:          }
                   1367:        else
                   1368:            output_string = (char *) 0;
                   1369:       }
                   1370: 
                   1371: } // name::print
                   1372: 
                   1373: 
                   1374: #ifdef DENSE
                   1375: void chop(char* buf)
                   1376: {
                   1377:        static char alpha[] = "_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                   1378:        static const asz = sizeof(alpha)-1;
                   1379:        int hash = 0;
                   1380:        char* p = &buf[29];
                   1381:                        
                   1382:        while (*p) {
                   1383:                hash <<= 1;
                   1384:                if (hash & (1<<12)) {
                   1385:                        hash &= ~(1<<12);
                   1386:                        hash++;
                   1387:                }
                   1388:                hash ^= *p++;
                   1389:        }
                   1390: 
                   1391:        buf[29] = alpha[(int)(hash%asz)];
                   1392:        buf[30] = alpha[(int)((hash/asz)%asz)];
                   1393:        buf[31] = 0;
                   1394: }
                   1395: #endif
                   1396: 
                   1397: void type::print()
                   1398: {
                   1399:        switch (base) {
                   1400:        case PTR:
                   1401:        case RPTR:
                   1402:        case VEC:
                   1403:                Pptr(this)->dcl_print(0);
                   1404:                break;
                   1405:        case FCT:
                   1406:                Pfct(this)->dcl_print();
                   1407:                break;
                   1408: //     case VEC:
                   1409: //             Pvec(this)->dcl_print(0);
                   1410: //             break;
                   1411:        case CLASS:
                   1412:        case ENUM:
                   1413:                if (emode)
                   1414:                        fprintf(out_file,"%k",base);
                   1415:                else
                   1416:                //      error('i',"%p->T::print(%k %s)",this,base,Pclass(this)->string);        
                   1417:                        fprintf(out_file,"struct %s *",Pclass(this)->string);
                   1418:                break;
                   1419:        case TYPE:
                   1420:                if (Cast) {
                   1421:                        Pbase(this)->b_name->tp->print();
                   1422:                        break;
                   1423:                }
                   1424:                // no break
                   1425:        default:
                   1426:                Pbase(this)->dcl_print();
                   1427:        }
                   1428: }
                   1429: 
                   1430: char* type::signature(register char* p)
                   1431: /*
                   1432:        take a signature suitable for argument types for overloaded
                   1433:        function names
                   1434: */
                   1435: {
                   1436:        Ptype t = this;
                   1437:        int pp = 0;     // pointer to
                   1438: 
                   1439: xx:
                   1440: //error('d',"xx(%d) %d %k",this,t,t->base);
                   1441: 
                   1442:        // first unroll typedefs and handle derived types:
                   1443: 
                   1444:        switch (t->base) {
                   1445:        case TYPE:
                   1446:                if (Pbase(t)->b_const) *p++ = 'C';
                   1447:                t = Pbase(t)->b_name->tp;
                   1448:                goto xx;
                   1449: 
                   1450:        case VEC:
                   1451:                if (pp && Pvec(t)->size) {           // A<size>_
                   1452:                        *p++ = 'A';
                   1453:                        sprintf(p,"%d\0",Pvec(t)->size); // don't trust
                   1454:                                                         // sprintf return value
                   1455:                        while (*++p);
                   1456:                        *p++ = '_';
                   1457:                }
                   1458:                else
                   1459:                        *p++ = 'P';
                   1460:                t = Pvec(t)->typ;
                   1461:                pp = 1;
                   1462:                goto xx;
                   1463: 
                   1464:        case PTR:
                   1465:                if (Pptr(t)->rdo) *p++ = 'C';           // *const
                   1466:                if (Pptr(t)->memof) {                   // M<size><classname>
                   1467:                        Pclass cl = Pptr(t)->memof;
                   1468:                        register char* s = cl->string;
                   1469:                        int d = cl->strlen;
                   1470:                        if (d==0) cl->strlen = d = strlen(s);
                   1471:                        *p++ = 'M';
                   1472:                        if (d/10) *p++ = '0'+d/10;
                   1473:                        *p++ = '0'+ d%10;       // assume <100 char
                   1474:                        while (*p++ = *s++);
                   1475:                        --p;                            // not the '\0'
                   1476:                }
                   1477:                else
                   1478:                        *p++ = 'P';
                   1479:                t = Pptr(t)->typ;
                   1480:                pp = 1;
                   1481:                goto xx;
                   1482: 
                   1483:        case RPTR:
                   1484:                *p++ = 'R';
                   1485:                t = Pptr(t)->typ;
                   1486:                pp = 1;
                   1487:                goto xx;
                   1488: 
                   1489:        case FCT:
                   1490:        {       Pfct f = Pfct(t);
                   1491:                Pname n = f->argtype;
                   1492: 
                   1493:                if (f->f_const) *p++ = 'C';     // constant member function
                   1494:                if (f->f_static) *p++ = 'S';    // static member function
                   1495:        //      if (f->memof && f->f_this==0) *p++ = 'S';       //SSS static member function
                   1496:                *p++ = 'F';
                   1497:                if (n == 0)
                   1498:                        *p++ = 'v';     // VOID, that is f() == f(void)
                   1499:                else
                   1500:        for ( ; n; n=n->n_list) {       // print argument encoding
                   1501:                                        // check if argtype is the same
                   1502:                                        // as previously seen argtype
                   1503:                int i = 0;
                   1504:                for (Pname nn=f->argtype; n!=nn; nn=nn->n_list) {
                   1505:                        i++;
                   1506:                        if (nn->tp==n->tp || nn->tp->check(n->tp,0)==0) {
                   1507:                                // typeof (n) == typeof(arg i)
                   1508:                                int x = 1;      // try for a run after n
                   1509:                                Pname nnn = n;
                   1510:                                while ((nnn=nnn->n_list) && x<9) {
                   1511:                                        if (nnn->tp==n->tp
                   1512:                                        || nnn->tp->check(n->tp,0)==0) {
                   1513:                                                x++;
                   1514:                                                n = nnn;
                   1515:                                        }
                   1516:                                        else
                   1517:                                                break;
                   1518:                                }
                   1519: 
                   1520:                                if (x == 1)             // Ti
                   1521:                                        *p++ = 'T';
                   1522:                                else {                  // Nxi
                   1523:                                        *p++ = 'N';
                   1524:                                        *p++ = '0'+x;
                   1525:                                }
                   1526:        
                   1527:                                // assume <100 arguments
                   1528:                                if (9<i) *p++ = '0'+i/10;
                   1529:                                *p++ = '0'+i%10;
                   1530:                                goto zk;
                   1531:                        }       
                   1532:                }
                   1533: 
                   1534:                // ``normal'' case print argument type signature
                   1535:        //      if (n->n_xref) *p++ = 'R';
                   1536:                p = n->tp->signature(p);
                   1537:                zk:;
                   1538:        }
                   1539: 
                   1540:                if (f->nargs_known == ELLIPSIS) *p++ = 'e';
                   1541: 
                   1542:                if (pp) {               // '_' result type
                   1543:                        *p++ = '_';
                   1544:                        p = f->returns->signature(p);
                   1545:                }
                   1546: 
                   1547:                *p = 0;
                   1548:                return p;
                   1549:        }
                   1550:        }
                   1551: 
                   1552:        // base type modifiers:
                   1553: 
                   1554:        if ( Pbase(t)->b_const )        *p++ = 'C';
                   1555: //     if ( Pbase(t)->b_signed )       *p++ = 'S';
                   1556:        if ( Pbase(t)->b_unsigned )     *p++ = 'U';
                   1557: //     if ( Pbase(t)->b_volatile )     *p++ = 'V';
                   1558: 
                   1559: 
                   1560:        // now base types:
                   1561: 
                   1562:        register char* s;
                   1563:        int d;
                   1564:        Pclass cl;
                   1565: //lll:
                   1566:        switch (t->base) {
                   1567: //     case TNAME:     t = Pbase(t)->b_name->tp; goto lll;
                   1568:        case ANY:                       break;
                   1569:        case ZTYPE:                     break;
                   1570:        case VOID:      *p++ = 'v';     break;
                   1571:        case CHAR:      *p++ = 'c';     break;
                   1572:        case SHORT:     *p++ = 's';     break;
                   1573: //     case EOBJ:
                   1574:        case INT:       *p++ = 'i';     break;
                   1575:        case LONG:      *p++ = 'l';     break;
                   1576:        case FLOAT:     *p++ = 'f';     break;
                   1577:        case DOUBLE:    *p++ = 'd';     break;
                   1578:        case LDOUBLE:   *p++ = 'r';     break;
                   1579:        case EOBJ:
                   1580: //             *p++ = 'i';
                   1581: //             break;
                   1582:        {       Penum en = Penum(Pbase(t)->b_name->tp);
                   1583:        //      t = en->e_type;
                   1584:        //      goto lll;
                   1585:                s = en->string;
                   1586:                d = en->strlen;
                   1587:                if (d==0) en->strlen = d = strlen(s);
                   1588:                goto pppp;
                   1589:        }
                   1590: 
                   1591:        case COBJ:
                   1592:        {       cl = Pclass(Pbase(t)->b_name->tp);
                   1593:                s = cl->string;
                   1594:                d = cl->strlen;
                   1595:                if (d==0) cl->strlen = d = strlen(s);
                   1596:              pppp:   
                   1597:                sprintf(p, "%d", d) ;
                   1598:                while (*p++) ; --p ;
                   1599:                while (*p++ = *s++);
                   1600:                --p;
                   1601:                break;
                   1602: 
                   1603: //     pppp:
                   1604: //             if (d/10) *p++ = '0'+d/10;
                   1605: //             *p++ = '0'+ d%10;       // assume less that 99 characters
                   1606: //             while (*p++ = *s++);
                   1607: //             --p;
                   1608: //             break;
                   1609:        }
                   1610:        case FIELD:
                   1611:        default:
                   1612:                error('i',"signature of %k",t->base);
                   1613:        }
                   1614: 
                   1615:        *p = 0;
                   1616:        return p;
                   1617: }
                   1618: 
                   1619: void basetype::dcl_print()
                   1620: {
                   1621:        Pname nn;
                   1622:        Pclass cl;
                   1623: 
                   1624:        if (emode) {
                   1625:                if (b_virtual) puttok(VIRTUAL);
                   1626:                if (b_inline) puttok(INLINE);
                   1627:                if (b_const) puttok(CONST);
                   1628:        }
                   1629:        if (b_unsigned) puttok(UNSIGNED);
                   1630: 
                   1631:        switch (base) {
                   1632:        case ANY:
                   1633:                if (emode)
                   1634:                        putstring("any ");
                   1635:                else
                   1636:                        putstring("int ");
                   1637:                break;
                   1638: 
                   1639:        case ZTYPE:
                   1640:                if (emode)
                   1641:                        putstring("zero ");
                   1642:                else
                   1643:                        putstring("int ");
                   1644:                break;
                   1645: 
                   1646:        case VOID:
                   1647: /* sun's compiler, and most all others, support void */
                   1648: #ifndef sun
                   1649:                if (emode==0 && ansi_opt==0
                   1650:                    ) {
                   1651:                        // silly trick to bypass BSD C compiler bug
                   1652:                        // void* (*)() dosn't work there
                   1653:                         // note simpl.c knows that VOID -> CHAR grep for VCVC
                   1654:                        puttok(CHAR);
                   1655:                } else puttok(VOID);
                   1656: #else
                   1657:                    puttok(VOID);
                   1658: #endif
                   1659:                break;
                   1660: 
                   1661:        case CHAR:
                   1662:        case SHORT:
                   1663:        case INT:
                   1664:        case LONG:
                   1665:        case FLOAT:
                   1666:        case DOUBLE:
                   1667:         case LDOUBLE:
                   1668:                puttok(base);
                   1669:                break;
                   1670: 
                   1671:        case EOBJ:
                   1672:                nn = b_name;
                   1673:        eob:
                   1674:                if (emode == 0)
                   1675:                //      puttok(INT);
                   1676:                        Penum(nn->tp)->e_type->dcl_print();
                   1677:                else {
                   1678:                         puttok(ENUM);
                   1679:                         nn->print();
                   1680:                }
                   1681:                 break;
                   1682: 
                   1683:        case COBJ:
                   1684:                nn = b_name;
                   1685:        cob:
                   1686:                cl = Pclass(nn->tp);
                   1687:                if (emode && (cl->base == CLASS)  && 
                   1688:                    (cl->class_base == instantiated_template_class)) {
                   1689:                      Ptclass(cl)->inst->print_pretty_name() ;
                   1690:                      break ;
                   1691:                }else if (cl && (cl->csu==UNION || cl->csu==ANON))
                   1692:                        puttok(UNION);
                   1693:                else
                   1694:                        puttok(STRUCT);
                   1695:                { // local class        
                   1696:                        char* s = 0;
                   1697:                        if ( cl && cl->lex_level ) s = make_local_name( cl );
                   1698:                        putst(s?s:nn->string);
                   1699:                        delete s;
                   1700:                }
                   1701:                break;
                   1702: 
                   1703:        case TYPE:
                   1704:                if (emode == 0) {
                   1705:                        switch (b_name->tp->base) {
                   1706:                        case COBJ:
                   1707:                                nn = Pbase(b_name->tp)->b_name;
                   1708:                                goto cob;
                   1709:                        case EOBJ:
                   1710:                                nn = Pbase(b_name->tp)->b_name;
                   1711:                                goto eob;
                   1712: //                     default:        
                   1713: // { 
                   1714: // if (b_name->lex_level !=0 ) 
                   1715: // { 
                   1716: // error('d', "default: %n %t", b_name, b_name->tp );
                   1717: // Pbase(b_name->tp)->dcl_print(); 
                   1718: // b_name->tp->print(); 
                   1719: // return; 
                   1720: // }
                   1721: // }
                   1722: 
                   1723:                        }
                   1724:                }
                   1725:                b_name->print();
                   1726:                break;
                   1727: 
                   1728:        default:
                   1729:                if (emode) {
                   1730:                        if (0<base && base<=MAXTOK && keys[base])
                   1731:                                fprintf(out_file," %s",keys[base]);
                   1732:                        else
                   1733:                                putch('?');
                   1734:                }
                   1735:                else
                   1736:                        error('i',"%p->BT::dcl_print(%d)",this,base);
                   1737:        }
                   1738: }
                   1739: Pbase memptr_type;
                   1740: 
                   1741: void type::dcl_print(Pname n)
                   1742: /*
                   1743:        "this" type is the type of "n". Print the declaration
                   1744: */
                   1745: {
                   1746: //error('d',"%p::dcl_print(%n)",this,n);
                   1747:        Ptype t = this;
                   1748:        Pptr p;
                   1749:        TOK pre = 0;
                   1750: 
                   1751:        if (t == 0) error('i',"0->dcl_print()");
                   1752:        if (n && n->tp!=t) error('i',"not %n'sT (%p)",n,t);
                   1753: 
                   1754:        if (base == OVERLOAD) {
                   1755:                for (Plist gl=Pgen(this)->fct_list; gl; gl=gl->l) {
                   1756:                        Pname nn = gl->f;
                   1757:                        nn->tp->dcl_print(nn);
                   1758:                        if (gl->l) puttok(SM);
                   1759:                }
                   1760:                return;
                   1761:        }
                   1762: 
                   1763:        tbuf = tbufvec[freetbuf];
                   1764:        if (tbuf == 0) {
                   1765:                if (freetbuf == NTBUF-1) error('i',"AT nesting overflow");
                   1766:                tbufvec[freetbuf] = tbuf = new class dcl_buf;
                   1767:        }
                   1768:        freetbuf++;
                   1769:        tbuf->init(n);
                   1770:        if (n && n->n_xref) tbuf->front(PTR);
                   1771: 
                   1772:        while (t) {
                   1773:                TOK k;
                   1774: 
                   1775:                switch (t->base) {
                   1776:                case PTR:
                   1777:                        p = Pptr(t);
                   1778:                        k = (p->rdo) ? CONST_PTR : PTR;
                   1779:                        goto ppp;
                   1780:                case RPTR:
                   1781:                        p = Pptr(t);
                   1782:                        k = (p->rdo) ? CONST_RPTR : RPTR;
                   1783:                ppp:
                   1784:                        if (p->memof) {
                   1785:                                if (emode) {
                   1786:                                        tbuf->front(k);
                   1787:                                        tbuf->front(p->memof);
                   1788:                                }
                   1789:                                else {
                   1790:                                        t = p->typ;
                   1791:                                        while (t->base==TYPE) t = Pbase(t)->b_name->tp;
                   1792:                                        if (t->base == FCT) {
                   1793: extern Pbase mptr_type;
                   1794:                                                tbuf->base(mptr_type);
                   1795:                                                goto zaq;
                   1796:                                        }
                   1797:                                        else
                   1798:                                                tbuf->front(k);
                   1799:                                }
                   1800:                        }
                   1801:                        else
                   1802:                                tbuf->front(k);
                   1803:                        pre = PTR;
                   1804:                        t = p->typ;
                   1805:                        break;
                   1806:                case VEC:
                   1807:                {       Pvec v = Pvec(t);
                   1808:                        if (Cast && pre != PTR && pre != VEC) { // for Macintosh: ptr to array uses [] notation
                   1809:                                tbuf->front(PTR);
                   1810:                                pre = PTR;
                   1811:                        }
                   1812:                        else {
                   1813:                                if (pre == PTR) tbuf->paran();
                   1814:                                tbuf->back(VEC,v);
                   1815:                                pre = VEC;
                   1816:                        }
                   1817:                        t = v->typ;
                   1818:                        break;
                   1819:                }
                   1820: 
                   1821:                case FCT:
                   1822:                {       Pfct f = Pfct(t);
                   1823:                        if (pre == PTR)
                   1824:                                tbuf->paran();
                   1825:                        else if (emode && f->memof && n==0)
                   1826:                                tbuf->front(f->memof);
                   1827:                        tbuf->back(FCT,f);
                   1828:                        pre = FCT;
                   1829:                        t = (f->s_returns) ? f->s_returns : f->returns;
                   1830:                        break;
                   1831:                }
                   1832:                case FIELD:
                   1833:                        tbuf->back(FIELD,t);
                   1834:                        tbuf->base( Pbase(Pbase(t)->b_fieldtype) );
                   1835:                        t = 0;
                   1836:                        break;
                   1837:                case 0:
                   1838:                        error('i',"noBT(B=0)");
                   1839:                case TYPE:
                   1840:                        if (Cast) { // unravel type in case it contains vectors
                   1841:                                t = Pbase(t)->b_name->tp;
                   1842:                                break;
                   1843:                        }
                   1844: 
                   1845:                default: // the base has been reached
                   1846: /* This is WRONG. What happens to all the CONST, etc, stuff that 
                   1847:     basetype::dcl_print knows about ? */
                   1848: #if 0
                   1849:                        if (emode) {
                   1850:                            tbuf->base(Pbase(t));
                   1851:                                for (Ptype tt = t; tt->base==TYPE; tt=Pbase(tt)->b_name->tp);
                   1852:                                switch (tt->base) {
                   1853:                                case COBJ:
                   1854:                                    tt == Pbase(tt)->b_name->tp;
                   1855:                                    /* and fall through into the CLASS case */
                   1856:                                case CLASS:
                   1857:                                    s = Pclass(tt)->string;
                   1858:                                    if (Ptclass(this)->class_base == instantiated_template_class ||
                   1859:                                        Ptclass(this)->class_base == uninstantiated_template_class)
                   1860:                                      {
                   1861:                                        Ptclass(this)->inst->print_pretty_name() ;
                   1862:                                        freetbuf-- ;
                   1863:                                        return ;
                   1864:                                      } else { 
                   1865:                                        if (s[0]=='_' &&s[1]=='_' && s[2]=='C') s="class";
                   1866:                                        putstring(s);
                   1867:                                      }
                   1868:                                    break ;
                   1869:                                case ENUM:
                   1870:                                        s = "enum";
                   1871:                                        goto fret;
                   1872:                                case OVERLOAD:
                   1873:                                        s = "overloaded";
                   1874:                                fret:
                   1875:                                        putstring(s);
                   1876:                                        freetbuf--;
                   1877:                                        return;
                   1878:                                }
                   1879: 
                   1880:                        }
                   1881: #endif
                   1882: 
                   1883:                        tbuf->base( Pbase(t) );
                   1884:                        goto zaq;
                   1885:                } // switch
                   1886:        } // while
                   1887: zaq:
                   1888:        tbuf->put();
                   1889:        freetbuf--;
                   1890: }
                   1891: 
                   1892: void fct::dcl_print()
                   1893: {
                   1894:        Pname nn;
                   1895: //error('d',"fct::dcl_print()");
                   1896:        if (emode) {
                   1897:                putch('(');
                   1898:                for (nn=argtype; nn;) {
                   1899:                        nn->tp->dcl_print(0);
                   1900:                        if (nn=nn->n_list) puttok(CM); else break;
                   1901:                }
                   1902:                switch (nargs_known) {
                   1903:                case 0:         //      putst("?"); break;
                   1904:                case ELLIPSIS:  puttok(ELLIPSIS); break;
                   1905:                }
                   1906:                putch(')');
                   1907:                if (f_const) puttok(CONST);     
                   1908:                if (f_static) puttok(STATIC);   // wrong place for ``static''
                   1909:                return;
                   1910:        }
                   1911: 
                   1912:        Pname at = f_args;
                   1913:        putch('(');
                   1914: 
                   1915:        if (ansi_opt) {
                   1916:                // print typed arguments:
                   1917:                at = (f_this) ? f_this : (f_result) ? f_result : argtype; 
                   1918:                // WNG -- note:  at = f_args had 0 value with ansi_opt set
                   1919:                //               mystery fix added here
                   1920:                if (at == 0) {
                   1921:                        if (nargs_known == ELLIPSIS) {
                   1922:                                putch(')');
                   1923:                                return;
                   1924:                        }
                   1925:                        puttok(VOID);
                   1926:                }
                   1927:                else if (body && Cast==0)
                   1928:                        at->dcl_print(CM);      // print argument type and name
                   1929:                else {
                   1930:                        for (nn=at; nn;) {
                   1931:                        //      nn->tp->dcl_print(0);   // print argument type
                   1932:                                nn->tp->dcl_print(nn);  // print argument type
                   1933:                                                        // (there may not be a name)
                   1934:                                if (nn=nn->n_list) puttok(CM); else break;
                   1935:                        }
                   1936:                }
                   1937:                if (nargs_known == ELLIPSIS) putstring(",...");
                   1938:                putch(')');
                   1939:        }
                   1940:        else {
                   1941:                // print argument names followed by argument type declarations:
                   1942:                if (body && Cast==0) {
                   1943:                        for (nn=at; nn;) {
                   1944:                                nn->print();
                   1945: #if OUTPUT_PAIR_FUNCTIONALITY
                   1946:                                if (capture_renaming) { /* rick, ODI, 3-28-89; used 
                   1947:                                                          to switch off some cfront
                   1948:                                                              renaming. */
                   1949:                                    output_pair(nn);
                   1950:                                }
                   1951: #endif
                   1952:                                if (nn=nn->n_list) puttok(CM); else break;
                   1953:                        }
                   1954:                        putch(')');
                   1955:                }
                   1956:                else
                   1957:                        putch(')');
                   1958:        }
                   1959: }
                   1960: 
                   1961: void print_body(Pfct f)
                   1962: {
                   1963:        if (Cast==0) {
                   1964:                
                   1965:                if (ansi_opt==0 && f->f_args) f->f_args->dcl_print(SM);
                   1966: 
                   1967:                if (MAIN) {
                   1968:                        putstring("{ _main(); ");       // call constructors
                   1969:                        f->body->print();
                   1970:                        puttok(RC);
                   1971:                }
                   1972:                else 
                   1973:                        f->body->print();
                   1974:        }
                   1975: }
                   1976: 
                   1977: Pbcl shared_seen;
                   1978: 
                   1979: void classdef::print_members()
                   1980: {
                   1981:        int i;
                   1982:        
                   1983:        Pbcl l = baselist;
                   1984: // error('d',"%t->print_members()",this);
                   1985:        if (l) {
                   1986:                if (l->base == NAME) {
                   1987:                        l->bclass->print_members();     // first base only
                   1988:                        // pad to ensure alignment:
                   1989:                        int boff = l->bclass->real_size;
                   1990:                        int ba = l->bclass->align();
                   1991:                        int xtra = boff%ba;
                   1992:                        int waste = (xtra) ? ba-xtra : 0;       // padding
                   1993: //error('d',"%s: size % align %d waste %d",string,boff,ba,waste);
                   1994:                        if (waste) {
                   1995:                                // waste it to protect against structure
                   1996:                                // assignments to the base class
                   1997:                                char* s = make_name('W');
                   1998:                                fprintf(out_file,"char %s[%d];\n",s,waste);
                   1999:                                delete s;
                   2000:                        }
                   2001:                        l = l->next;
                   2002:                }
                   2003: 
                   2004:                for (; l; l=l->next)
                   2005:                /*      for second base etc. one must allocate as an object
                   2006:                        (rather than a list of members) to ensure proper alignment
                   2007:                        for shared base allocate a pointer
                   2008:                        size, alignment, & offset handled in cassdef::dcl()
                   2009:                */
                   2010:                        if (l->base == NAME) {
                   2011:                                Pclass bcl = l->bclass;
                   2012:                                puttok(STRUCT);
                   2013:                                putst(bcl->string);
                   2014:                                putcat('O',bcl->string);
                   2015:                                puttok(SM);
                   2016:                        }
                   2017:        }
                   2018: 
                   2019:        // Sam: A class or an enum type declared within a class can hide a
                   2020:        // member with the same name, so make sure that it gets printed by
                   2021:        // traversing the n_tbl_list to get at these names.
                   2022:        for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i))
                   2023:          do if (nn->base==NAME
                   2024:                && nn->n_union==0
                   2025:                && nn->tp->base!=FCT
                   2026:                && nn->tp->base!=OVERLOAD
                   2027:                && nn->tp->base!=CLASS
                   2028:                && nn->tp->base!=ENUM
                   2029:                && nn->n_stclass != STATIC) {
                   2030:                        if (nn->tp->base==FIELD && Pbase(nn->tp)->b_bits==0) continue;
                   2031:                        Pexpr i = nn->n_initializer;
                   2032:                        nn->n_initializer = 0;
                   2033:                        nn->dcl_print(0);
                   2034:                        nn->n_initializer = i;
                   2035:                      }
                   2036:          // The while condition can be true for atmost one iteration per
                   2037:          // outer iteration.
                   2038:          while ((nn->base == NAME) &&
                   2039:                 ((nn->tp->base!=CLASS) || (nn->tp->base!=ENUM)) &&
                   2040:                 (nn = nn->n_tbl_list)) ;
                   2041: 
                   2042:        for (l=baselist; l; l=l->next)
                   2043:                if (l->base==VIRTUAL && l->ptr_offset) {
                   2044:                        Pclass bcl = l->bclass;
                   2045:                        char* bs = bcl->string;
                   2046: 
                   2047:                        puttok(STRUCT);                 // struct bcl* Pbcl;
                   2048:                        putst(bs);
                   2049:                        putch('*');
                   2050:                        putcat('P',bs);
                   2051:                        puttok(SM);
                   2052:                }
                   2053: }
                   2054: 
                   2055: void classdef::print_vtbl(Pvirt vtab)
                   2056: {
                   2057: //error('d',"%s->print_vtbl(%s) vtbl_opt %d",string,vtab->string,vtbl_opt);
                   2058: // error('d',"print_vtbl: lex_level: %d", lex_level );
                   2059: 
                   2060: //     switch (vtbl_opt) {
                   2061: //     case -1:
                   2062: //     case 1:
                   2063:                vlist = new vl(this,vtab,vlist);
                   2064: //     }
                   2065: 
                   2066:        int oo = vtbl_opt;      // make `simulated static' name
                   2067:        vtbl_opt = -1;
                   2068:         char* str =  lex_level ? make_local_name(this) : 0;
                   2069:         char* s = vtbl_name(vtab->string,str?str:string);
                   2070:        vtbl_opt = oo;
                   2071:         // char* s = vtbl_name(vtab->string,string);
                   2072: //        fprintf(out_file,"extern struct __mptr %s[];\n",s);
                   2073:        s[2] = 'p';     // pointer, not tbl itself
                   2074:        fprintf(out_file,"extern struct __mptr* %s;\n",s);
                   2075: 
                   2076:         delete s;
                   2077:         delete str;
                   2078: }
                   2079: 
                   2080: vl* vlist;
                   2081: 
                   2082: void really_really_print(Pclass cl, Pvirt vtab, char* s, char* ss);
                   2083: 
                   2084: int p2(Pname nn, Ptype t, Pclass cl, Pvirt vtab, char* s)
                   2085: {
                   2086:        int init;
                   2087: 
                   2088:        if (t->base == FCT) {
                   2089:                Pfct f = Pfct(t);
                   2090: 
                   2091: //error('d',"p2 %n init %d inline %d virtual %d",nn,nn->n_initializer,f->f_inline,f->f_virtual);
                   2092: //error('d',"p2 %s expr %d imeasure %d body %d",s,f->f_expr,f->f_imeasure,f->body);
                   2093: //error('d',"sto %k",nn->n_sto);
                   2094:                if (nn->n_initializer
                   2095:                || nn->n_sto==STATIC
                   2096:                || f->f_inline
                   2097:                || f->f_imeasure
                   2098:                || f->f_virtual==0) return 0;
                   2099:                init = f->body!=0;
                   2100:        }
                   2101:        else
                   2102:                init = nn->n_initializer!=0;
                   2103: 
                   2104:        int oo = vtbl_opt;
                   2105:        vtbl_opt = 1;   // make sure the name is universal
                   2106:         char* sstr =  cl->lex_level ? make_local_name(cl) : 0;
                   2107:         char* ss = vtbl_name(vtab->string,sstr?sstr:cl->string);
                   2108: 
                   2109:        if (init) {     // unique definition here
                   2110:                really_really_print(cl,vtab,ss,s);
                   2111:        }
                   2112:        else {  // unique definition elsewhere
                   2113: //error('d',"elsewhere %n %s",nn,ss);
                   2114:                fprintf(out_file,"extern struct __mptr %s[];\n",ss);
                   2115:                s[2] = 'p';
                   2116:                fprintf(out_file,"struct __mptr* %s = ",s);
                   2117:                fprintf(out_file,"%s;\n",ss);
                   2118:        }
                   2119:        vtbl_opt = oo;
                   2120: 
                   2121:        delete ss;
                   2122:        delete sstr;
                   2123: 
                   2124:        return 1;
                   2125: }
                   2126: 
                   2127: void classdef::really_print(Pvirt vtab)
                   2128: {
                   2129: //error('d',"really_print %t %d",this,vtbl_opt);
                   2130:        int oo = vtbl_opt;      // make `simulated static' name
                   2131:        vtbl_opt = -1;
                   2132:         char* str = lex_level ? make_local_name(this) : 0;
                   2133:         char* s = vtbl_name(vtab->string,str?str:string);
                   2134:        vtbl_opt = oo;
                   2135: 
                   2136:        // see if needed
                   2137:        int i;
                   2138:        for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
                   2139:                Ptype t = nn->tp;
                   2140:        zse:
                   2141:                if (t)
                   2142:                switch (t->base) {
                   2143:                case TYPE:
                   2144:                        t = Pbase(t)->b_name->tp;
                   2145:                        goto zse;
                   2146: /*
                   2147:                case COBJ:
                   2148:                        if (nn->n_sto == EXTERN)
                   2149:                        {       Pclass cl = Pclass(Pbase(t)->b_name->tp);
                   2150:                                if (cl->has_ctor()) {
                   2151:                                        p2(nn,t,this,vtab,s);
                   2152:                                        return;
                   2153:                                }
                   2154:                        }
                   2155:                        break;
                   2156: */
                   2157:                case FCT:
                   2158:                        if (p2(nn,t,this,vtab,s)) return;
                   2159:                        break;
                   2160: 
                   2161:                case OVERLOAD:
                   2162:                {       for (Plist gl=Pgen(t)->fct_list; gl; gl=gl->l)
                   2163:                                if (p2(gl->f,gl->f->tp,this,vtab,s)) return;
                   2164:                }
                   2165:                }
                   2166:        }
                   2167: 
                   2168:        if (vtbl_opt) {
                   2169:                // make vtbl name according to option:
                   2170:                char* sstr = lex_level ? make_local_name(this) : 0;
                   2171:                char* ss = vtbl_name(vtab->string,str?str:string);
                   2172:                really_really_print(this,vtab,ss,s);
                   2173: 
                   2174:                delete ss;
                   2175:                delete sstr;
                   2176:        }
                   2177: 
                   2178:        delete s;
                   2179:        delete str;
                   2180: }
                   2181: 
                   2182: void really_really_print(Pclass, Pvirt vtab, char* s, char* ss)
                   2183: {
                   2184: //error('d',"really %s",s);
                   2185:        // make sure function is declared before using
                   2186:        // it in vtbl initializer
                   2187:        Pname nn;
                   2188:        int i;
                   2189:        for (i=0; nn = vtab->virt_init[i].n; i++) {
                   2190:                Pfct f = Pfct(nn->tp);
                   2191:                 if (nn->n_initializer) {       // pure virtual
                   2192:                        static pv;
                   2193:                        if (pv == 0) {  // VCVC void->char assumed
                   2194: #ifdef sun
                   2195:                                fprintf(out_file,"void __pure_virtual_called();\n");
                   2196: #else
                   2197:                                fprintf(out_file,"char __pure_virtual_called();\n");
                   2198: #endif
                   2199:                                pv = 1;
                   2200:                        }
                   2201:                        continue;
                   2202:                }
                   2203:                if (f->base != FCT) error('i',"vtbl %n",nn);
                   2204: //void expand_dtor(Pclass cl);
                   2205: //             if (f->f_inline == IDTOR) expand_dtor(f->memof);
                   2206: 
                   2207:                if (nn->n_dcl_printed==0 /*|| f->f_inline*/) {
                   2208:                        if (f->f_inline && vtbl_opt) puttok(STATIC);
                   2209:                        if (f->f_result == 0) make_res(f);
                   2210:                        Ptype r = f->s_returns ? f->s_returns : f->returns;
                   2211:                        r->print();
                   2212:                        nn->print();
                   2213:                        putstring("()");
                   2214:                        puttok(SM);
                   2215:                        nn->n_dcl_printed = 1;
                   2216:                }
                   2217:        }
                   2218: 
                   2219: //     if (vtbl_opt == -1) puttok(STATIC);
                   2220: 
                   2221: 
                   2222:         fprintf(out_file,"struct __mptr %s[] = {0,0,0,\n",s);
                   2223: 
                   2224:        Pname n;
                   2225:        for (i=0; n=vtab->virt_init[i].n; i++) {
                   2226:                if (n->n_initializer)
                   2227:                        putstring("0,0,(__vptp)__pure_virtual_called,\n");
                   2228:                else {
                   2229:                        fprintf(out_file,"%d,0,(__vptp)",-vtab->virt_init[i].offset);
                   2230:                        n->print();
                   2231:                        n->n_addr_taken = 1;
                   2232:                        putstring(",\n");
                   2233:                }
                   2234:        }
                   2235:        putstring("0,0,0};\n");
                   2236: 
                   2237:        ss[2] = 'p';
                   2238:         fprintf(out_file,"struct __mptr* %s = ",ss);
                   2239:        s[2] = 'v';
                   2240:         fprintf(out_file,"%s;\n",s);
                   2241: 
                   2242: //error('d',"really-> %s",s);
                   2243: }
                   2244: 
                   2245: #include <ctype.h>
                   2246: extern char* src_file_name;
                   2247: char* vtbl_name(char* s1, char* s2)
                   2248: {
                   2249: //extern Pname def_name;
                   2250:        char* s3 = (vtbl_opt == -1 && src_file_name) ? src_file_name : 0;
                   2251:                // if vtbl_opt == -1 fake a static (there are no portable
                   2252:                // way of doing a forward declaration of a static in C)
                   2253:        int ll = s1 ? strlen(s1) : 0;
                   2254:        int ll2 = strlen(s2);
                   2255:        int ll3 = s3 ? strlen(s3) : 0;
                   2256: //     int ll4 = s3&&def_name ? strlen(def_name->string) : 0;
                   2257: //     int sz = (ll+ll2+ll3+ll4+22)/32+1;  // avoid fragmentation
                   2258:         int sz = (ll+ll2+ll3+20)/32+1;  // avoid fragmentation
                   2259: 
                   2260:         sz *= 32;
                   2261: //error('d',"vtbl_name(%s,%s,%s) %d",s1?s1:"",s2,s3?s3:"",sz);
                   2262:         char* buf = new char[sz];
                   2263:        if (s3) {
                   2264:        //      if (s1 && def_name)
                   2265:        //              sprintf(buf,"__vtbl__%d%s__%d%s__%s__%s",ll,s1,ll2,s2,s3,def_name->string);
                   2266:        //      else
                   2267:                if (s1)
                   2268:                        sprintf(buf,"__vtbl__%d%s__%d%s__%s",ll,s1,ll2,s2,s3);
                   2269:        //      else if (def_name)
                   2270:        //              sprintf(buf,"__vtbl__%d%s__%s__%s",ll2,s2,s3,def_name->string);
                   2271:                else
                   2272:                        sprintf(buf,"__vtbl__%d%s__%s",ll2,s2,s3);
                   2273:        }
                   2274:        else if (s1)
                   2275:                sprintf(buf,"__vtbl__%d%s__%d%s",ll,s1,ll2,s2);
                   2276:        else
                   2277:                sprintf(buf,"__vtbl__%d%s",ll2,s2);
                   2278: 
                   2279:        if (vtbl_opt == -1) {
                   2280:                for (char* p = buf+ll2+11; *p; p++)
                   2281:                        if (!isalpha(*p) && !isdigit(*p)) *p = '_';
                   2282:        }
                   2283: #ifdef DENSE
                   2284:        chop(buf);
                   2285: #endif
                   2286:        return buf;
                   2287: }
                   2288: 
                   2289: void classdef::print_all_vtbls(Pclass bcl)
                   2290: {
                   2291: //error('d',"%t->print_all_vtbls(%t) vlt %d bl %d",this,bcl,virt_list,baselist);
                   2292: 
                   2293:        for (Pvirt blist = bcl->virt_list; blist; blist = blist->next) {
                   2294:                if (this != blist->vclass) continue;
                   2295:                if (blist->printed) continue;
                   2296:         //      if (blist->string==0 && find_vptr(this)==0) {        //BSopt
                   2297:         //              continue;
                   2298:         //      }
                   2299:                print_vtbl(blist);
                   2300:                blist->printed = 1;
                   2301:        }
                   2302: 
                   2303:        for (Pbcl b = bcl->baselist; b; b = b->next)
                   2304:                print_all_vtbls(b->bclass);
                   2305: 
                   2306:        if (this==bcl) c_body = 0;
                   2307: }
                   2308: 
                   2309: void classdef::dcl_print(Pname)
                   2310: {
                   2311:        extern Pclass current_instantiation ;
                   2312:         // Sam: this kludge needs to be there in the absence of a true tree
                   2313:        // copy for templates, to ensure that template instantiations are
                   2314:        // printed exactly once.
                   2315:         if ((class_base != vanilla_class) && (current_instantiation != this))
                   2316:          return ;
                   2317: 
                   2318: 
                   2319:        if (c_body==0 || c_body==3 || (defined&DEFINED)==0) return;
                   2320:        c_body = 3;
                   2321: 
                   2322:        int i;
                   2323: //error('d',"%t->classdef::dcl_print",this);
                   2324:        for (Pname nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
                   2325:                if (nn->base==NAME
                   2326:                && nn->n_union==0
                   2327:                && nn->tp->base==CLASS
                   2328:                && Pclass(nn->tp)->c_body==1)
                   2329:                        Pclass(nn->tp)->dcl_print(nn);
                   2330:                else if (nn->base == TNAME && Pbase(nn->tp)->base != COBJ)
                   2331:                        nn->dcl_print(0);
                   2332:                 else if (nn->tp && nn->tp->base == ENUM)
                   2333:                         Penum(nn->tp)->dcl_print(nn);
                   2334:        }
                   2335: 
                   2336:        TOK lvl = lex_level ? LOCAL : 0;
                   2337:        Pname n = ktbl->look(string,lvl);
                   2338:        if (n==0) n = ktbl->look(string,HIDDEN);
                   2339: 
                   2340:        if (n) {
                   2341:                if (n->where.line!=last_line.line
                   2342:                || n->where.file!=last_line.file)
                   2343:                        if (last_ll = n->where.line)
                   2344:                                n->where.putline();
                   2345:                        else
                   2346:                                last_line.putline();
                   2347:        }
                   2348: 
                   2349:        TOK c = csu==CLASS ? STRUCT : csu;
                   2350:        puttok(c);
                   2351: //     if (string[0]!='_' || string[1]!='_' || string[2]!='C')
                   2352: 
                   2353:         char *str = 0;
                   2354:        if ( lex_level ) str = make_local_name( this );
                   2355:        putst(str?str:string);
                   2356: 
                   2357:        int sm = 0;
                   2358:        int sz = tsizeof();
                   2359:        int dvirt = 0;
                   2360: 
                   2361:        fprintf(out_file,"{\t/* sizeof %s == %d */\n",str?str:string,obj_size);
                   2362:        delete str;
                   2363: 
                   2364:        print_members();
                   2365:        for (Pbcl b = baselist; b; b = b->next) {       // declare virtual classes
                   2366:                if (b->base != VIRTUAL) continue;
                   2367:                Pclass bcl = b->bclass;
                   2368:                dvirt += bcl->virt_count;
                   2369: //error('d',"%t in %t %d",b->bclass,this,b->allocated);
                   2370:                if (b->allocated==0) continue;
                   2371:                puttok(STRUCT);                 // struct bcl Obcl;
                   2372:                putst(bcl->string);
                   2373:                putcat('O',bcl->string);
                   2374:                puttok(SM);
                   2375:        }
                   2376:        putstring("};\n");
                   2377: 
                   2378:        for (nn=memtbl->get_mem(i=1); nn; nn=memtbl->get_mem(++i) ) {
                   2379:                if (nn->base==NAME && nn->n_union==0) {
                   2380:                        Ptype t = nn->tp;
                   2381:                        switch (t->base) {
                   2382:                        case FCT:
                   2383:                        case OVERLOAD:
                   2384:                                break;
                   2385:                        default:
                   2386:                                if (nn->n_stclass == STATIC) {
                   2387:                                        TOK b = nn->n_sto;
                   2388: //error('d',"print nn %n tp %t b %k eval %d",nn,nn->tp,b,nn->n_evaluated);
                   2389:                                /*
                   2390:                                        Pname cn;
                   2391:                                        TOK bb = ((cn=nn->tp->is_cl_obj())
                   2392:                                        && Pclass(cn->tp)->has_ctor())==0
                   2393:                                                ?0:b; // force explicit initialization
                   2394:                                        nn->n_sto = (nn->n_evaluated) ? STATIC : bb;
                   2395:                                */
                   2396:                                        nn->n_sto = (nn->n_evaluated) ? STATIC : b;
                   2397:                                        nn->dcl_print(0);
                   2398:                                        nn->n_sto = b;
                   2399:                                }
                   2400:                        }
                   2401:                }
                   2402:        }
                   2403:        if (vtbl_opt != -1) print_all_vtbls(this);      // force declaration
                   2404: //error('d',"dcl_print -> ");
                   2405: }
                   2406: 
                   2407: 
                   2408: #if OUTPUT_PAIR_FUNCTIONALITY
                   2409:   
                   2410: static FILE *name_pairs = (FILE *) 0;
                   2411:  
                   2412:  
                   2413: static void output_pair (name *decl)
                   2414:  
                   2415:     /* This function can be used to remember an original name and 
                   2416:        its transformation. These pairs can then be used in a mapping
                   2417:        function which maps the original name to the transformed name.
                   2418:  
                   2419:        Currently, this routine outputs the pairs to a file. At some
                   2420:        point, the routine might be adapted to place the pair in the
                   2421:        .o file or in the program database. However, it would be better
                   2422:        if the information was simply kept on the database symbol
                   2423:        (whatever that is) like it is currently kept on cfront names
                   2424:        using the fields "expr::string" and "name::output_string". Should
                   2425:        the database symbol provide this facility, then this function
                   2426:        can be removed. */
                   2427:  
                   2428: {
                   2429:  
                   2430:     extern char* file_name[];
                   2431:     char function_member_string[100];
                   2432:     char name[1024];
                   2433: 
                   2434:  
                   2435:     if ( ! name_pairs) {
                   2436:        if (src_file_name) {
                   2437:            strcpy(name, src_file_name);
                   2438:            strcat(name, "_pairs");
                   2439:            if ( ! (name_pairs = fopen(name, "w")))
                   2440:                error('i',"output_pair' ! (name_pairs = fopen())");
                   2441:          }
                   2442:        else if ( ! (name_pairs = stderr))
                   2443:            error('i',"output_pair' ! (name_pairs = stderr)");
                   2444:       }
                   2445:  
                   2446:     if (decl->output_string) {
                   2447:  
                   2448:  
                   2449:        fprintf(name_pairs, "%s\n%s\n\n", decl->string, decl->output_string);
                   2450:  
                   2451: #if 0
                   2452:        fprintf(name_pairs, "\"%s\",\"%s\"\n", decl->string,
                   2453:                decl->output_string);
                   2454: #endif
                   2455:  
                   2456:        delete decl->output_string;
                   2457:        decl->output_string = (char *) 0;
                   2458:        
                   2459:       }
                   2460:  
                   2461: #if 0
                   2462:     else
                   2463:        fprintf(name_pairs, "%s\n", decl->string);
                   2464: #endif
                   2465:  
                   2466:     new_string[0] = '\0';
                   2467:     tmp_string[0] = '\0';
                   2468:  
                   2469: } // output_pair
                   2470:  
                   2471: #endif
                   2472:  
                   2473:  
                   2474:  
                   2475:  
                   2476: static Pname is_data_member (Pname p_name)
                   2477:  
                   2478:     /* Returns the member's class if the given name is a data member.
                   2479:        Otherwise returns (Pname) 0. */
                   2480:  
                   2481: {
                   2482:  
                   2483:     TOK base = p_name->tp->base;
                   2484:     Ptable p_table;
                   2485:     Pname table_name;
                   2486:     char *table_string;
                   2487:     Ptable outer_table;
                   2488:     Pname class_name;
                   2489:  
                   2490:     /* If the name is any kind of function, return false. */
                   2491:  
                   2492:     if (base == FCT || base == INLINE || base == VIRTUAL ||
                   2493:        base == OPERATOR || base == OVERLOAD)
                   2494:        return (Pname) 0;
                   2495:  
                   2496:     /* Get the member's table. Get the table's name. Get the table's
                   2497:        outer table. Lookup the table's name in the outer table.
                   2498:        If the name is a class, struct, or union, then return the
                   2499:        name. Otherwise, return (Pname) 0. */
                   2500:  
                   2501:     if ( ! (p_table = p_name->n_table)) return (Pname) 0;
                   2502:     if ( ! (table_name = p_table->t_name)) return (Pname) 0;
                   2503:     if ( ! (table_string = table_name->string)) return (Pname) 0;
                   2504:     
                   2505:     /* If there is no outer table, then assume that outer_table
                   2506:        is gtbl (the module level table). In 1.2, no outer table implied
                   2507:        that p_name was not a data member, that p_table == gtbl and
                   2508:        p_name was a module level name. */
                   2509:  
                   2510:     if ( ! (outer_table = p_table->next)) {
                   2511:        outer_table = gtbl;
                   2512:       }
                   2513:  
                   2514:     /* Look for a class, struct, or union matching the table string.
                   2515:        Verify that the table containing the given name (p_table) is
                   2516:        the table associated with the class (class_name->tp->memtbl). */
                   2517:  
                   2518:     if ((class_name = outer_table->look(table_string, CLASS)) ||
                   2519:        (class_name = outer_table->look(table_string, STRUCT)) ||
                   2520:        (class_name = outer_table->look(table_string, UNION))) {
                   2521:        if (((struct classdef *)(class_name->tp))->memtbl == p_table)
                   2522:            return class_name;
                   2523:       }
                   2524:  
                   2525:     return (Pname) 0;
                   2526:  
                   2527: } // is_data_member
                   2528:  
                   2529:  
                   2530:  
                   2531: static Pname matches_base_member (Pname p_name, Pclass class_)
                   2532:  
                   2533:     /* Returns the matching member if found, otherwise returns
                   2534:        (Pname) 0. */
                   2535:  
                   2536: {
                   2537:  
                   2538:     Pbcl base_class;
                   2539:     Pname matching_member;
                   2540:  
                   2541:     /* For each base class, look for a matching member, if
                   2542:        found return the member. Otherwise, return (Pname) 0. */
                   2543: 
                   2544:     // in 1.2, this used classdef.cl_base. Now it uses baselist --benson 
                   2545:  
                   2546:     for (base_class = class_->baselist; base_class;
                   2547:         base_class = base_class->next) {
                   2548:        if ((matching_member
                   2549:             = look_any(base_class->bclass->memtbl,
                   2550:                        p_name->string)))
                   2551:            return matching_member;
                   2552:        else if (matching_member
                   2553:                 = matches_base_member(p_name, base_class->bclass))
                   2554:            return matching_member;
                   2555:       }
                   2556:     
                   2557:     return (Pname) 0;
                   2558:     
                   2559: } // matches_base_member
                   2560:  
                   2561:  
                   2562:  
                   2563:  
                   2564: static Pname look_any (Ptable p_table, char* s)
                   2565:  
                   2566:     /* This was ripped off from table.c:table::look. The TOK
                   2567:        argument is not considered and has been removed. The first
                   2568:        matching name is returned. If none are found, then (Pname) 0
                   2569:        if returned.
                   2570:  
                   2571:        look for "s" in table,
                   2572:        look and insert MUST be the same lookup algorithm */
                   2573: {
                   2574: 
                   2575:     Ptable t;
                   2576:     register char * p;
                   2577:     register char * q;
                   2578:     register int i;
                   2579:     Pname n;
                   2580:     int rr;
                   2581:      
                   2582:     // if (s == 0) error('i',"%d->look(0)",p_table);
                   2583:     // if (p_table == 0) error('i',"0->look(%s)",s);
                   2584:     // if (base != TABLE) error('i',"(%d,%d)->look(%s)",p_table,base,s);
                   2585:     
                   2586:     /* use simple hashing with linear search for overflow */
                   2587:     
                   2588:     p = s;
                   2589:     i = 0;
                   2590:     while (*p) i += (i + *p++); /* i<<1 ^ *p++ better?*/
                   2591:     rr = (0<=i) ? i : -i;
                   2592:     
                   2593:     for (t=p_table; t; t=t->next) {    
                   2594:        /* in this and all enclosing scopes look for name "s" */
                   2595:        Pname* np = t->entries;
                   2596:        int mx = t->hashsize;
                   2597:        short* hash = t->hashtbl;
                   2598:        int firsti = i = rr%mx;
                   2599:        
                   2600:        do {                    
                   2601:            if (hash[i] == 0) goto not_found;
                   2602:            n = np[hash[i]];
                   2603:            if (n == 0) error('i',"hashed lookup");
                   2604:            p = n->string;              /* strcmp(n->n_string,s) */
                   2605:            q = s;
                   2606:            while (*p && *q)
                   2607:                if (*p++ != *q++) goto nxt;
                   2608:            if (*p == *q) goto found;
                   2609:          nxt:
                   2610:            if (mx <= ++i) i = 0;               /* wrap around */
                   2611:        } while (i != firsti);
                   2612:        
                   2613:       found:
                   2614: #if 0
                   2615:        for (; n; n=n->n_tbl_list) { /* for  all name "s"s look for a key 
                   2616:                                        match */
                   2617:            if (n->n_key == k) return n;
                   2618:        }
                   2619: #endif
                   2620:        return n;
                   2621:        
                   2622:       not_found:;
                   2623:     }
                   2624:     
                   2625:     return 0;  /* not found && no enclosing scope */
                   2626:     
                   2627: } // look_any
                   2628: 
                   2629: 
                   2630: 
                   2631: char *
                   2632: make_local_name( Pclass cl, int ln ) 
                   2633: {
                   2634:     char *buf; 
                   2635:     if ( cl->in_fct == 0 ) error( 'i', "localC %s missingFN", cl->string ); 
                   2636:     char *fsig = Pfct(cl->in_fct->tp)->f_signature;
                   2637:     if ( fsig == 0 ) fsig = local_sign( cl->in_fct->tp );
                   2638:     char *fs = cl->in_fct->string;
                   2639:     int class_len=cl->strlen+strlen(fsig)+strlen(fs)+strlen(cl->lcl)+4;
                   2640:     int sz = (class_len+20)/32+1; // from vtbl_name()
                   2641: 
                   2642:     if ( Pfct(cl->in_fct->tp)->memof == 0 ) {
                   2643:         sz *= 32;
                   2644:         buf = new char[ sz ];
                   2645: // error('d', "make_local_name: sz: %d", sz );
                   2646: 
                   2647:          if (ln) 
                   2648:              sprintf(buf, "__%d%s__%s__%s%s", class_len, cl->string, fs, fsig, cl->lcl);
                   2649:         else
                   2650:              sprintf(buf, "%s__%s__%s%s", cl->string, fs, fsig, cl->lcl);
                   2651:     }
                   2652:     else 
                   2653:     {
                   2654:         char *cs = Pclass(Pfct(cl->in_fct->tp)->memof)->string;
                   2655:         int len = Pclass(Pfct(cl->in_fct->tp)->memof)->strlen;
                   2656:         if ( len < 10 )
                   2657:             ++class_len;
                   2658:        else 
                   2659:         if ( len > 99 )
                   2660:             class_len += 3;
                   2661:        else class_len += 2;
                   2662:        class_len += len;
                   2663:         sz = (class_len+20)/32+1; 
                   2664:        sz *= 32;
                   2665:         buf = new char[ sz ];
                   2666: // error('d', "make_local_name: sz: %d", sz );
                   2667: 
                   2668:        if ( ln )
                   2669:              sprintf(buf, "__%d%s__%s__%d%s%s%s",class_len,cl->string,fs,len,cs,fsig,cl->lcl);
                   2670:         else sprintf(buf, "%s__%s__%d%s%s%s",cl->string,fs,len,cs,fsig,cl->lcl);
                   2671:     }
                   2672: 
                   2673: #ifdef DENSE
                   2674:     chop( buf );
                   2675: #endif
                   2676: 
                   2677:     return buf;
                   2678: }
                   2679: 
                   2680: /* ODI notes
                   2681:    
                   2682:    template classes
                   2683: 
                   2684:    limit renaming
                   2685: 
                   2686:    on sun's print void as void.
                   2687: */
                   2688: 
                   2689:    

unix.superglobalmegacorp.com

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