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