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