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