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