Annotation of researchv10no/cmd/cfront/ooptcfront/print2.c, revision 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.