|
|
1.1 ! root 1: /*ident "@(#)ctrans:src/print.c 1.6" */ ! 2: /************************************************************************** ! 3: ! 4: C++ source for cfront, the C++ compiler front-end ! 5: written in the computer science research center of Bell Labs ! 6: ! 7: Copyright (c) 1984 AT&T, Inc. All rights Reserved ! 8: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC. ! 9: ! 10: print.c: ! 11: ! 12: print statements and expressions ! 13: ! 14: ****************************************************************************/ ! 15: ! 16: #include "cfront.h" ! 17: ! 18: static int addrof_cm ; ! 19: extern void puttok(TOK); ! 20: ! 21: #define eprint(e) if (e) Eprint(e) ! 22: ! 23: void Eprint(Pexpr e) ! 24: { ! 25: switch (e->base) { ! 26: case REF: ! 27: if (Pref(e)->mem && Pref(e)->mem->tp && Pref(e)->mem->tp->base == FCT) { ! 28: // suppress ``this'' in ``this->f'' ! 29: Pref(e)->mem->print(); ! 30: break; ! 31: } ! 32: case NAME: ! 33: case MDOT: ! 34: case ID: ! 35: case ZERO: ! 36: case ICON: ! 37: case CCON: ! 38: case FCON: ! 39: case STRING: ! 40: case IVAL: ! 41: case TEXT: ! 42: case CM: ! 43: case G_CM: ! 44: case ELIST: ! 45: case COLON: ! 46: case ILIST: ! 47: case DOT: ! 48: case THIS: ! 49: case CALL: ! 50: case G_CALL: ! 51: case ICALL: ! 52: case ANAME: ! 53: e->print(); ! 54: case DUMMY: ! 55: break; ! 56: default: ! 57: putch('('); ! 58: e->print(); ! 59: putch(')'); ! 60: } ! 61: } ! 62: ! 63: void expr::print() ! 64: { ! 65: if (this == 0) error('i',"0->E::print()"); ! 66: if (this==e1 || this==e2) error('i',"(%p%k)->E::print(%p %p)",this,base,e1,e2); ! 67: // error('d',"(%d %k)->expr::print(%d %d)",this,base,e1,e2); ! 68: ! 69: switch (base) { ! 70: case MDOT: ! 71: { ! 72: // error('d',"mdot %s i1 %d %t",string2,i1,mem->tp); ! 73: int not_allocated = 0; ! 74: switch (i1) { ! 75: case 0: ! 76: putcat('O',string2); ! 77: puttok(DOT); // use sub-object directly ! 78: mem->print(); ! 79: break; ! 80: case 1: ! 81: putcat('P',string2); ! 82: puttok(REF); // use through pointer ! 83: mem->print(); ! 84: break; ! 85: case 2: ! 86: if (mem->tp->is_ptr_or_ref()==0) { ! 87: mem->print(); ! 88: puttok(DOT); ! 89: putcat('O',string2); ! 90: } ! 91: else ! 92: { ! 93: putch('('); // REF turns pointer into object: add & ! 94: putch('&'); // ``this'' is a pointer ! 95: putch('('); ! 96: eprint(mem); ! 97: puttok(REF); // call sub-object directly ! 98: putcat('O',string2); ! 99: putch(')'); ! 100: putch(')'); ! 101: } ! 102: break; ! 103: case 5: ! 104: not_allocated = 1; ! 105: // no break; ! 106: case 3: ! 107: if (mem->tp->is_ptr_or_ref()==0) { ! 108: putch('('); // Px is a pointer (T*) turn it back to a T ! 109: putch('*'); // *Px ! 110: putch('('); ! 111: eprint(mem);//mem->print(); ! 112: puttok(DOT); // call through pointer ! 113: putcat('P',string2); ! 114: putch(')'); ! 115: putch(')'); ! 116: } ! 117: else { ! 118: if (not_allocated) { ! 119: putch('('); ! 120: mem->print(); ! 121: if ( mem->base == NAME ) ! 122: puttok(REF); ! 123: else puttok(DOT); ! 124: putcat('O',string4); ! 125: putch(')'); ! 126: } ! 127: else eprint(mem); ! 128: if (mem->base == NAME && not_allocated) ! 129: puttok(DOT); ! 130: else puttok(REF); // call through pointer ! 131: putcat('P',string2); ! 132: } ! 133: break; ! 134: case 9: // vtbl entry: (p->_vtbl).f, (p->_vtbl).i, (p->_vtbl).d ! 135: // or memptr: mp.f, mp.i, mp.d ! 136: eprint(mem); ! 137: putch('.'); ! 138: putstring(string2); ! 139: } // end switch(i1) ! 140: break; ! 141: } // end MDOT ! 142: ! 143: case NAME: ! 144: { Pname n = Pname(this); ! 145: if (n->n_evaluated ! 146: && n->n_scope!=ARG) { ! 147: Ptype t = tp->skiptypedefs(); ! 148: if (t->base == EOBJ) t = Penum(Pbase(t)->b_name->tp)->e_type; ! 149: if (t->base!=INT || t->is_unsigned()) { ! 150: putstring("(("); ! 151: bit oc = Cast; ! 152: Cast = 1; ! 153: t->print(); ! 154: Cast = oc; ! 155: fprintf(out_file,")%d)",n->n_val); ! 156: } ! 157: else ! 158: fprintf(out_file,"%d",n->n_val); ! 159: } ! 160: else ! 161: n->print(); ! 162: break; ! 163: } ! 164: case ANAME: ! 165: if (curr_icall) { // in expansion: look it up ! 166: Pname n = Pname(this); ! 167: int argno = int(n->n_val); ! 168: ! 169: for (Pin il=curr_icall; il; il=il->i_next) ! 170: if (n->n_table == il->i_table) goto aok; ! 171: goto bok; ! 172: aok: ! 173: if (n = il->i_args[argno].local) { ! 174: n->print(); ! 175: } ! 176: else { ! 177: Pexpr ee = il->i_args[argno].arg; ! 178: Ptype t = il->i_args[argno].tp; ! 179: if (ee==0 || ee==this) error('i',"%p->E::print(A %p)",this,ee); ! 180: if (ee->tp==0 ! 181: || (t!=ee->tp && t->check(ee->tp,0) && t->is_cl_obj()==0) ! 182: ) { ! 183: putstring("(("); ! 184: bit oc = Cast; ! 185: Cast = 1; ! 186: t->print(); ! 187: Cast = oc; ! 188: putch(')'); ! 189: eprint(ee); ! 190: putch(')'); ! 191: } ! 192: else ! 193: eprint(ee); ! 194: } ! 195: } ! 196: else { ! 197: bok: /* in body: print it: */ ! 198: Pname(this)->print(); ! 199: } ! 200: break; ! 201: ! 202: case ICALL: ! 203: { il->i_next = curr_icall; ! 204: curr_icall = il; ! 205: //error('d',"icall %n",il->fct_name); ! 206: if (il == 0) error('i',"E::print: iline missing"); ! 207: Pexpr a0 = il->i_args[0].arg; ! 208: int val = QUEST; ! 209: if (il->fct_name->n_oper != CTOR) goto dumb; ! 210: ! 211: /* ! 212: find the value of "this" ! 213: if the argument is a "this" NOT assigned to ! 214: by the programmer, it was initialized ! 215: */ ! 216: switch (a0->base) { ! 217: case ZERO: ! 218: val = 0; ! 219: break; ! 220: case ADDROF: ! 221: case G_ADDROF: ! 222: val = 1; ! 223: break; ! 224: case CAST: ! 225: if (a0->e1->base == ANAME || a0->e1->base == NAME) { ! 226: Pname a = (Pname)a0->e1; ! 227: if (a->n_assigned_to == FUDGE111) val = FUDGE111; ! 228: } ! 229: } ! 230: if (val==QUEST) goto dumb; ! 231: /* ! 232: now find the test: "(this==0) ? _new(sizeof(X)) : 0" ! 233: ! 234: e1 is a comma expression, ! 235: the test is either the first sub-expression ! 236: or the first sub-expression after the assignments ! 237: initializing temporary variables ! 238: */ ! 239: dumb: ! 240: eprint(e1); ! 241: if (e2) Pstmt(e2)->print(); ! 242: curr_icall = il->i_next; ! 243: break; ! 244: } ! 245: case REF: ! 246: case DOT: ! 247: eprint(e1); ! 248: puttok(base); ! 249: if (mem == 0) { ! 250: fprintf(out_file,"MEM0"); ! 251: break; ! 252: } ! 253: if (mem->base == NAME) ! 254: Pname(mem)->print(); ! 255: else ! 256: mem->print(); ! 257: break; ! 258: ! 259: case MEMPTR: ! 260: error("P toMF not called"); ! 261: break; ! 262: ! 263: case VALUE: ! 264: tp2->print(); ! 265: puttok(LP); ! 266: if (e1) e1->print(); ! 267: puttok(RP); ! 268: break; ! 269: ! 270: case SIZEOF: ! 271: puttok(SIZEOF); ! 272: if (e1 && e1!=dummy) { ! 273: eprint(e1); ! 274: } ! 275: else if (tp2) { ! 276: putch('('); ! 277: if (tp2->base == CLASS) { ! 278: Pclass cl = Pclass(tp2); ! 279: putstring((cl->csu == UNION)?"union ":"struct "); ! 280: char *str = 0; ! 281: // nested local class does not encode name ! 282: if ( cl->lex_level && cl->nested_sig == 0 ) ! 283: str = make_local_name( cl ); ! 284: putstring(str?str:(cl->nested_sig?cl->nested_sig:cl->string)); ! 285: delete str; ! 286: } ! 287: else ! 288: tp2->print(); ! 289: putch(')'); ! 290: } ! 291: break; ! 292: ! 293: case CAST: ! 294: putch('('); ! 295: //error('d',"print cast %t",tp2); ! 296: if (tp2->base != VOID && tp2->memptr() == 0 ) { ! 297: // when VOID is represented as CHAR not everything ! 298: // can be cast to VOID ! 299: putch('('); ! 300: bit oc = Cast; ! 301: Cast = 1; ! 302: tp2->print(); ! 303: Cast = oc; ! 304: putch(')'); ! 305: } ! 306: eprint(e1); ! 307: putch(')'); ! 308: break; ! 309: ! 310: case ICON: ! 311: case FCON: ! 312: case CCON: ! 313: case ID: ! 314: if (string) putst(string); ! 315: break; ! 316: ! 317: case STRING: ! 318: // avoid printing very long lines ! 319: ntok += 4; ! 320: fprintf(out_file,"\"%s\"",string); ! 321: break; ! 322: ! 323: case THIS: ! 324: case ZERO: ! 325: putstring("0 "); ! 326: break; ! 327: ! 328: case IVAL: ! 329: fprintf(out_file,"%d",i1); ! 330: break; ! 331: ! 332: case TEXT: ! 333: { ! 334: int oo = vtbl_opt; // make `simulated static' name ! 335: vtbl_opt = -1; ! 336: char* s = vtbl_name(string,string2); ! 337: vtbl_opt = oo; ! 338: s[2] = 'p'; // pointer, not tbl itself ! 339: char* t = ptbl_lookup(s); ! 340: fprintf(out_file, " %s",t); ! 341: delete t; ! 342: ! 343: char *str = 0; ! 344: if ( string ) { ! 345: str = new char[ strlen(string) + strlen(string2) + 1 ]; ! 346: strcpy( str, string ); ! 347: strcat( str, string2 ); ! 348: } ! 349: ! 350: if ( ptbl->look( str?str:string2, 0 ) == 0 && ! 351: ptbl->look( str?str:string2, HIDDEN ) == 0 ) { ! 352: Pname nn = ptbl->insert(new name(str?str:string2),0); ! 353: nn->string2 = new char[strlen(s)+1]; ! 354: strcpy(nn->string2,s); ! 355: } ! 356: ! 357: delete str; ! 358: delete s; ! 359: } ! 360: // no break; ! 361: ! 362: case DUMMY: ! 363: break; ! 364: ! 365: case G_CALL: ! 366: case CALL: ! 367: { Pname fn = fct_name; ! 368: Pname at; ! 369: int m_ptr = 0; ! 370: ! 371: if (fn) { ! 372: Pfct f = Pfct(fn->tp); ! 373: ! 374: if (f->base==OVERLOAD) { // overloaded after call ! 375: fct_name = fn = Pgen(f)->fct_list->f; ! 376: f = Pfct(fn->tp); ! 377: } ! 378: ! 379: fn->print(); ! 380: at = f->f_args; ! 381: } ! 382: else { ! 383: Pfct f = Pfct(e1->tp); ! 384: ! 385: if (f) { // pointer to fct ! 386: Pexpr exex = e1; ! 387: if ( exex->base == DEREF ) { ! 388: exex = exex->e1; ! 389: while ( exex->base == CAST ) ! 390: exex = exex->e1; ! 391: if ( exex->base == MDOT ) ! 392: m_ptr = 1; ! 393: } ! 394: ! 395: if (f->base == OVERLOAD) { // overloaded after call ! 396: fct_name = fn = Pgen(f)->fct_list->f; ! 397: f = Pfct(fn->tp); ! 398: } ! 399: ! 400: f = Pfct(f->skiptypedefs()); ! 401: if (f->base == PTR) { ! 402: putstring("(*"); ! 403: e1->print(); ! 404: putch(')'); ! 405: f = Pfct(Pptr(f)->typ->skiptypedefs()); ! 406: } ! 407: else ! 408: eprint(e1); ! 409: ! 410: at = f->f_args; ! 411: } ! 412: else { // virtual: argtype encoded ! 413: // f_this already linked to f_result and/or argtype ! 414: at = (e1->base==QUEST) ? Pname(e1->e1->tp2) : Pname(e1->tp2); ! 415: eprint(e1); ! 416: } ! 417: } ! 418: ! 419: puttok(LP); ! 420: ! 421: if (e2) { ! 422: if (at) { ! 423: Pexpr e = e2; ! 424: while (at) { ! 425: Pexpr ex; ! 426: Ptype t = at->tp; ! 427: ! 428: if (t == 0) error('i',"T ofA missing for%n",fn); ! 429: if (e == 0) error('i',"%tA missing for%n",t,fn); ! 430: if (e->base == ELIST) { ! 431: ex = e->e1; ! 432: e = e->e2; ! 433: } ! 434: else ! 435: ex = e; ! 436: ! 437: if (ex == 0) error('i',"A ofT%t missing",t); ! 438: if (t!=ex->tp ! 439: && ex->tp ! 440: && t->check(ex->tp,0) ! 441: && t->is_cl_obj()==0 ! 442: && eobj==0 ! 443: && m_ptr == 0 ! 444: && (t->is_ptr()==0 || Mptr==0)) { ! 445: putch('('); ! 446: bit oc = Cast; ! 447: Cast = 1; ! 448: t->print(); ! 449: Cast = oc; ! 450: putch(')'); ! 451: #ifdef sun ! 452: if (ex->base == DIV) { // defend against perverse SUN cc bug ! 453: putstring("(0+"); ! 454: eprint(ex); ! 455: putch(')'); ! 456: } ! 457: else ! 458: #endif ! 459: eprint(ex); ! 460: } ! 461: else ! 462: ex->print(); ! 463: ! 464: // if m_ptr is set, then don't advance at ! 465: // at does not know about generated `this' ! 466: if ( m_ptr ) { ! 467: m_ptr = 0; ! 468: if (at) puttok(CM); ! 469: continue; ! 470: } ! 471: ! 472: at = at->n_list; ! 473: if (at) puttok(CM); ! 474: } ! 475: if (e) { ! 476: puttok(CM); ! 477: e->print(); ! 478: } ! 479: } ! 480: else ! 481: e2->print(); ! 482: } ! 483: puttok(RP); ! 484: break; ! 485: } ! 486: ! 487: case ASSIGN: ! 488: if (e1->base==ANAME && Pname(e1)->n_assigned_to==FUDGE111) { ! 489: // suppress assignment to "this" that has been optimized away ! 490: Pname n = Pname(e1); ! 491: int argno = int(n->n_val); ! 492: for (Pin il=curr_icall; il; il=il->i_next) ! 493: if (il->i_table == n->n_table) goto akk; ! 494: goto bkk; ! 495: akk: ! 496: if (il->i_args[argno].local == 0) { ! 497: e2->print(); ! 498: break; ! 499: } ! 500: } ! 501: //no break ! 502: case EQ: ! 503: case NE: ! 504: case GT: ! 505: case GE: ! 506: case LE: ! 507: case LT: ! 508: bkk: ! 509: { ! 510: Ptype t2 = e2->tp; ! 511: ! 512: eprint(e1); ! 513: puttok(base); ! 514: ! 515: if (e1->tp && e1->tp!=e2->tp && e2->base!=ZERO) { ! 516: // cast, but beware of int!=long etc. ! 517: Ptype t1 = e1->tp->skiptypedefs(); ! 518: switch (t1->base) { ! 519: default: ! 520: break; ! 521: case PTR: ! 522: case RPTR: ! 523: case VEC: ! 524: { Ptype t2 = e2->tp->skiptypedefs(); ! 525: ! 526: if (e2->tp==0 ! 527: || (Pptr(t1)->typ!=Pptr(t2)->typ && t1->check(t2,0))) { ! 528: putch('('); ! 529: bit oc = Cast; ! 530: Cast = 1; ! 531: e1->tp->print(); ! 532: Cast = oc; ! 533: putch(')'); ! 534: } ! 535: } ! 536: } ! 537: } ! 538: ! 539: eprint(e2); ! 540: break; ! 541: } ! 542: ! 543: case DEREF: ! 544: if (e2) { ! 545: ! 546: eprint(e1); ! 547: putch('['); ! 548: eprint(e2); ! 549: putch(']'); ! 550: } ! 551: else { ! 552: putch('('); ! 553: putch('*'); ! 554: eprint(e1); ! 555: putch(')'); ! 556: } ! 557: break; ! 558: ! 559: case ILIST: ! 560: puttok(LC); ! 561: if (e1) e1->print(); ! 562: if (e2) { // member pointer initiliazers ! 563: puttok(CM); ! 564: e2->print(); ! 565: } ! 566: puttok(RC); ! 567: break; ! 568: ! 569: case ELIST: ! 570: { Pexpr e = this; ! 571: for(;;) { ! 572: if (e->base == ELIST) { ! 573: e->e1->print(); ! 574: if (e = e->e2) { ! 575: puttok(CM); ! 576: } ! 577: else ! 578: return; ! 579: } ! 580: else { ! 581: e->print(); ! 582: return; ! 583: } ! 584: } ! 585: } ! 586: ! 587: case QUEST: ! 588: { // look for (&a == 0) etc. ! 589: Neval = 0; ! 590: binary_val = 1; ! 591: long i = cond->eval(); ! 592: binary_val = 0; ! 593: if (Neval == 0) ! 594: (i?e1:e2)->print(); ! 595: else { ! 596: eprint(cond); ! 597: putch('?'); ! 598: eprint(e1); ! 599: putch(':'); ! 600: eprint(e2); ! 601: } ! 602: break; ! 603: } ! 604: ! 605: case CM: // do &(a,b) => (a,&b) for previously checked inlines ! 606: case G_CM: ! 607: puttok(LP); ! 608: switch (e1->base) { ! 609: case ZERO: ! 610: case IVAL: ! 611: case ICON: ! 612: case NAME: ! 613: case MDOT: ! 614: case DOT: ! 615: case REF: ! 616: case FCON: ! 617: case STRING: ! 618: goto le2; // suppress constant a: &(a,b) => (&b) ! 619: default: ! 620: { int oo = addrof_cm; // &(a,b) does not affect a ! 621: addrof_cm = 0; ! 622: eprint(e1); ! 623: addrof_cm = oo; ! 624: } ! 625: puttok(CM); ! 626: le2: ! 627: if (addrof_cm) { ! 628: switch (e2->base) { ! 629: case CAST: ! 630: if (e2->e2) ! 631: switch (e2->e2->base) { ! 632: case CM: ! 633: case G_CM: ! 634: case ICALL: goto ec; ! 635: } ! 636: case NAME: ! 637: case MDOT: ! 638: case DOT: ! 639: case DEREF: ! 640: case REF: ! 641: case ANAME: ! 642: puttok(ADDROF); ! 643: addrof_cm--; ! 644: eprint(e2); ! 645: addrof_cm++; ! 646: break; ! 647: case ICALL: ! 648: case CM: ! 649: case G_CM: ! 650: ec: ! 651: eprint(e2); ! 652: break; ! 653: case G_CALL: ! 654: /* & ( e, ctor() ) with temporary optimized away */ ! 655: if (e2->fct_name ! 656: && e2->fct_name->n_oper==CTOR) { ! 657: addrof_cm--; ! 658: eprint(e2); ! 659: addrof_cm++; ! 660: break; ! 661: } ! 662: default: ! 663: error('i',"& inlineF call (%k)",e2->base); ! 664: } ! 665: } ! 666: else ! 667: eprint(e2); ! 668: puttok(RP); ! 669: } ! 670: break; ! 671: ! 672: case ADDROF: ! 673: case G_ADDROF: ! 674: switch (e2->base) { // & *e1 or &e1[e2] ! 675: case DEREF: ! 676: if (e2->e2 == 0) { // &*e == e ! 677: e2->e1->print(); ! 678: return; ! 679: } ! 680: break; ! 681: case ICALL: ! 682: addrof_cm++; // assumes inline expanded into ,-expression ! 683: eprint(e2); ! 684: addrof_cm--; ! 685: return; ! 686: case ASSIGN: // &(a=b) ??? works on many cc s ! 687: eprint(e2); // make sure it breaks! ! 688: return; ! 689: case NAME: { ! 690: Pname n = Pname(e2); ! 691: if(n->n_evaluated) { ! 692: n->n_evaluated=0; ! 693: puttok(ADDROF); ! 694: eprint(e2); ! 695: n->n_evaluated=1; ! 696: return; ! 697: } ! 698: break; ! 699: } ! 700: } ! 701: ! 702: // suppress cc warning on &fct ! 703: if (e2->tp==0 || e2->tp->base!=FCT) puttok(ADDROF); ! 704: ! 705: eprint(e2); ! 706: break; ! 707: ! 708: case PLUS: ! 709: case MINUS: ! 710: case MUL: ! 711: case DIV: ! 712: case MOD: ! 713: case LS: ! 714: case RS: ! 715: case AND: ! 716: case OR: ! 717: case ER: ! 718: case ANDAND: ! 719: case OROR: ! 720: case DECR: ! 721: case INCR: ! 722: case ASOR: ! 723: case ASER: ! 724: case ASAND: ! 725: case ASPLUS: ! 726: case ASMINUS: ! 727: case ASMUL: ! 728: case ASMOD: ! 729: case ASDIV: ! 730: case ASLS: ! 731: case ASRS: ! 732: eprint(e1); ! 733: // no break ! 734: case UPLUS: // only preserved for ansi_opt==1 ! 735: case UMINUS: ! 736: case NOT: ! 737: case COMPL: ! 738: puttok(base); ! 739: eprint(e2); ! 740: break; ! 741: ! 742: default: ! 743: error('i',"%p->E::print%k",this,base); ! 744: } ! 745: } ! 746: ! 747: Pexpr aval(Pname a) ! 748: { ! 749: int argno = int(a->n_val); ! 750: Pin il; ! 751: for (il=curr_icall; il; il=il->i_next) ! 752: if (il->i_table == a->n_table) goto aok; ! 753: return 0; ! 754: aok: ! 755: Pexpr aa = il->i_args[argno].arg; ! 756: ll: ! 757: switch (aa->base) { ! 758: case CAST: aa = aa->e1; goto ll; ! 759: case ANAME: return aval(Pname(aa)); ! 760: default: return aa; ! 761: } ! 762: } ! 763: ! 764: #define putcond() putch('('); e->print(); putch(')') ! 765: ! 766: static loc csloc = { 0, 0 }; // loc of last stmt with line!=0 ! 767: ! 768: void stmt::print() ! 769: { ! 770: //error('d',"S::print %d:%k s %d s_list %d",this,base,s,s_list); ! 771: if (where.line == 0) { ! 772: if (csloc.line) csloc.putline(); ! 773: } else { ! 774: csloc = where; ! 775: if (where.line!=last_line.line) ! 776: if (last_ll = where.line) ! 777: where.putline(); ! 778: else ! 779: last_line.putline(); ! 780: } ! 781: ! 782: if (memtbl && base!=BLOCK) { /* also print declarations of temporaries */ ! 783: puttok(LC); ! 784: Ptable tbl = memtbl; ! 785: memtbl = 0; ! 786: int i; ! 787: int bl = 1; ! 788: for (Pname n=tbl->get_mem(i=1); n; n=tbl->get_mem(++i)){ ! 789: if (n->tp == any_type) continue; ! 790: /* avoid double declarartion of temporaries from inlines */ ! 791: char* s = n->string; ! 792: if (s[0]!='_' || s[1]!='_' || s[2]!='X') { ! 793: n->dcl_print(0); ! 794: bl = 0; ! 795: } ! 796: Pname cn; ! 797: if (bl ! 798: && (cn=n->tp->is_cl_obj()) ! 799: && Pclass(cn->tp)->has_dtor()) bl = 0; ! 800: } ! 801: if ( last_ll==0 && (last_ll = where.line) ) ! 802: where.putline(); ! 803: if (bl) { ! 804: Pstmt sl = s_list; ! 805: s_list = 0; ! 806: print(); ! 807: memtbl = tbl; ! 808: puttok(RC); ! 809: if (sl) { ! 810: s_list = sl; ! 811: sl->print(); ! 812: } ! 813: } ! 814: else { ! 815: print(); ! 816: memtbl = tbl; ! 817: puttok(RC); ! 818: } ! 819: return; ! 820: } ! 821: ! 822: switch (base) { ! 823: default: ! 824: error('i',"S::print(base=%k)",base); ! 825: ! 826: case ASM: ! 827: fprintf(out_file,"asm(\"%s\");\n",(char*)e); ! 828: break; ! 829: ! 830: case DCL: ! 831: d->dcl_print(SM); ! 832: break; ! 833: ! 834: case BREAK: ! 835: case CONTINUE: ! 836: puttok(base); ! 837: puttok(SM); ! 838: break; ! 839: ! 840: case DEFAULT: ! 841: puttok(base); ! 842: putch(':'); ! 843: s->print(); ! 844: break; ! 845: ! 846: case SM: ! 847: if (e) { ! 848: e->print(); ! 849: if (e->base==ICALL && e->e2) break; /* a block: no SM */ ! 850: } ! 851: puttok(SM); ! 852: break; ! 853: ! 854: case WHILE: ! 855: puttok(WHILE); ! 856: putcond(); ! 857: if (s->s_list) { ! 858: puttok(LC); ! 859: s->print(); ! 860: puttok(RC); ! 861: } ! 862: else ! 863: s->print(); ! 864: break; ! 865: ! 866: case DO: ! 867: puttok(DO); ! 868: s->print(); ! 869: puttok(WHILE); ! 870: putcond(); ! 871: puttok(SM); ! 872: break; ! 873: ! 874: case SWITCH: ! 875: puttok(SWITCH); ! 876: putcond(); ! 877: s->print(); ! 878: break; ! 879: ! 880: case RETURN: ! 881: { ! 882: puttok(RETURN); ! 883: if (e) { ! 884: //error('d',"print return rt %t etp %t",ret_tp,e->tp); ! 885: if (ret_tp && ret_tp!=e->tp) { ! 886: Ptype tt = ret_tp->skiptypedefs(); ! 887: ! 888: switch (tt->base) { ! 889: case COBJ: ! 890: break; // cannot cast to struct ! 891: case RPTR: ! 892: case PTR: ! 893: if (Pptr(tt)->typ==Pptr(e->tp)->typ) break; ! 894: if (Pptr(tt)->memof) break; ! 895: default: ! 896: if (e->tp==0 || ret_tp->check(e->tp,0)) { ! 897: int oc = Cast; ! 898: putch('('); ! 899: Cast = 1; ! 900: ret_tp->print(); ! 901: Cast = oc; ! 902: putch(')'); ! 903: } ! 904: } ! 905: } ! 906: eprint(e); ! 907: } ! 908: puttok(SM); ! 909: } ! 910: while (s_list && s_list->base==SM) s_list = s_list->s_list; // FUDGE!! ! 911: break; ! 912: ! 913: case CASE: ! 914: puttok(CASE); ! 915: eprint(e); ! 916: putch(':'); ! 917: s->print(); ! 918: break; ! 919: ! 920: case GOTO: ! 921: puttok(GOTO); ! 922: d->print(); ! 923: puttok(SM); ! 924: break; ! 925: ! 926: case LABEL: ! 927: d->print(); ! 928: putch(':'); ! 929: s->print(); ! 930: break; ! 931: ! 932: case IF: ! 933: { int val = QUEST; ! 934: if (e->base == ANAME) { ! 935: Pname a = Pname(e); ! 936: Pexpr arg = aval(a); ! 937: //error('d',"arg %d%k %d (%d)",arg,arg?arg->base:0,arg?arg->base:0,arg?arg->e1:0); ! 938: if (arg) ! 939: switch (arg->base) { ! 940: case ZERO: val = 0; break; ! 941: case ADDROF: ! 942: case G_ADDROF: val = 1; break; ! 943: case IVAL: val = arg->i1!=0; ! 944: } ! 945: } ! 946: //error('d',"val %d",val); ! 947: switch (val) { ! 948: case 1: ! 949: s->print(); ! 950: break; ! 951: case 0: ! 952: if (else_stmt) ! 953: else_stmt->print(); ! 954: else ! 955: puttok(SM); /* null statement */ ! 956: break; ! 957: default: ! 958: puttok(IF); ! 959: putcond(); ! 960: if (s->s_list) { ! 961: puttok(LC); ! 962: s->print(); ! 963: puttok(RC); ! 964: } ! 965: else ! 966: s->print(); ! 967: if (else_stmt) { ! 968: if (else_stmt->where.line == 0) { ! 969: if (csloc.line) csloc.putline(); ! 970: } else { ! 971: csloc = else_stmt->where; ! 972: if (else_stmt->where.line!=last_line.line) ! 973: if (last_ll = else_stmt->where.line) ! 974: else_stmt->where.putline(); ! 975: else ! 976: last_line.putline(); ! 977: } ! 978: puttok(ELSE); ! 979: if (else_stmt->s_list) { ! 980: puttok(LC); ! 981: else_stmt->print(); ! 982: puttok(RC); ! 983: } ! 984: else ! 985: else_stmt->print(); ! 986: } ! 987: } ! 988: break; ! 989: } ! 990: ! 991: case FOR: ! 992: { ! 993: int fi = 0; // is the initializer statement an expression? ! 994: if (for_init) { ! 995: fi = 1; ! 996: if (for_init->memtbl==0 && for_init->s_list==0) ! 997: if (for_init->base==SM) ! 998: if (for_init->e->base!=ICALL || for_init->e->e1) ! 999: fi = 0; ! 1000: } ! 1001: //error('d',"for(; %d%k; %d%k)",e,e->base,e2,e2->base); ! 1002: if (fi) { ! 1003: puttok(LC); ! 1004: for_init->print(); ! 1005: } ! 1006: putstring("for("); ! 1007: if (fi==0 && for_init) for_init->e->print(); ! 1008: putch(';'); // to avoid newline: not puttok(SM) ! 1009: if (e) e->print(); ! 1010: putch(';'); ! 1011: if (e2) e2->print(); ! 1012: puttok(RP); ! 1013: s->print(); ! 1014: if (fi) puttok(RC); ! 1015: break; ! 1016: } ! 1017: ! 1018: case PAIR: ! 1019: if (s&&s2) { ! 1020: puttok(LC); ! 1021: s->print(); ! 1022: s2->print(); ! 1023: puttok(RC); ! 1024: } ! 1025: else { ! 1026: if (s) s->print(); ! 1027: if (s2) s2->print(); ! 1028: } ! 1029: break; ! 1030: ! 1031: case BLOCK: ! 1032: puttok(LC); ! 1033: //error('d',"block %d d %d memtbl %d own_tbl %d",this,d,memtbl,own_tbl); ! 1034: if (d) d->dcl_print(SM); ! 1035: if (memtbl && own_tbl) { ! 1036: Pname n; ! 1037: int i; ! 1038: for (n=memtbl->get_mem(i=1); n; n=memtbl->get_mem(++i)) { ! 1039: if (n->tp && n->n_union==0 && n->tp!=any_type) ! 1040: switch (n->n_scope) { ! 1041: case ARGT: ! 1042: case ARG: ! 1043: break; ! 1044: default: ! 1045: // error('d', "n: %s %k n_key: %k", n->string, n->base, n->n_key); ! 1046: if ( n->base == TNAME && n->n_key == NESTED ) ! 1047: continue; // printed from nested class ! 1048: n->dcl_print(0); ! 1049: } ! 1050: } ! 1051: if (last_ll==0 && s && (last_ll=s->where.line)) ! 1052: s->where.putline(); ! 1053: } ! 1054: if (s) s->print(); ! 1055: if (where2.line == 0) { ! 1056: if (csloc.line) csloc.putline(); ! 1057: } else { ! 1058: csloc = where2; ! 1059: if (where2.line!=last_line.line) ! 1060: if (last_ll = where2.line) ! 1061: where2.putline(); ! 1062: else ! 1063: last_line.putline(); ! 1064: } ! 1065: putstring("}\n"); ! 1066: if (last_ll && where.line) last_line.line++; ! 1067: } ! 1068: ! 1069: if (s_list) s_list->print(); ! 1070: } ! 1071: ! 1072: /* ! 1073: void table::dcl_print(TOK s, TOK pub) ! 1074: ! 1075: // print the declarations of the entries in the order they were inserted ! 1076: // ignore labels (tp==0) ! 1077: ! 1078: { ! 1079: register Pname* np; ! 1080: register int i; ! 1081: ! 1082: if (this == 0) return; ! 1083: ! 1084: np = entries; ! 1085: for (i=1; i<free_slot; i++) { ! 1086: register Pname n = np[i]; ! 1087: switch (s) { ! 1088: case 0: ! 1089: n->dcl_print(0); ! 1090: break; ! 1091: case EQ: ! 1092: if (n->tp && n->n_scope == pub) n->dcl_print(0); ! 1093: break; ! 1094: case NE: ! 1095: if (n->tp && n->n_scope != pub) n->dcl_print(0); ! 1096: break; ! 1097: } ! 1098: } ! 1099: } ! 1100: */ ! 1101: ! 1102: struct ptbl_rec { ! 1103: char* pname; ! 1104: char* vname; ! 1105: ptbl_rec* next; ! 1106: }; ! 1107: ! 1108: static char* ptbl_name; ! 1109: static ptbl_rec* ptbl_rec_lookup_head = 0; ! 1110: static ptbl_rec* ptbl_rec_pair_head = 0; ! 1111: ! 1112: void ptbl_init(int flag) ! 1113: { ! 1114: if (!flag) { ! 1115: char *p = st_name( "__ptbl_vec__" ); ! 1116: ptbl_name = new char[strlen(p)+1]; ! 1117: strcpy(ptbl_name, p); ! 1118: delete p; ! 1119: fprintf(out_file, "extern struct __mptr* %s[];\n", ptbl_name); ! 1120: if (last_ll) last_line.line++; ! 1121: } ! 1122: else { ! 1123: ptbl_rec *r, *p = ptbl_rec_lookup_head; ! 1124: if ( p == 0 ) return; // don't generate an empty object ! 1125: fprintf(out_file, "struct __mptr* %s[] = {\n", ptbl_name); ! 1126: if (last_ll) last_line.line++; ! 1127: int i = 0; ! 1128: while (p != 0) { ! 1129: r = ptbl_rec_pair_head; ! 1130: while (r && strcmp(r->pname, p->pname)) ! 1131: r = r->next; ! 1132: fprintf(out_file, "%s,\n", r->vname); ! 1133: if (last_ll) last_line.line++; ! 1134: p = p->next; ! 1135: } ! 1136: fprintf(out_file, "\n};\n"); ! 1137: if (last_ll) last_line.line += 2; ! 1138: } ! 1139: } ! 1140: ! 1141: char* ptbl_lookup(char *name) ! 1142: { ! 1143: ptbl_rec *r, *s, *p = ptbl_rec_lookup_head; ! 1144: int i = 0; ! 1145: ! 1146: while (p && strcmp(name, p->pname)) { ! 1147: r = p; ! 1148: p = p->next; ! 1149: i++; ! 1150: } ! 1151: ! 1152: if (p == 0) { ! 1153: s = new ptbl_rec; ! 1154: s->pname = new char[strlen(name) + 1]; ! 1155: s->vname = 0; ! 1156: s->next = 0; ! 1157: strcpy(s->pname, name); ! 1158: if (ptbl_rec_lookup_head == 0) ! 1159: ptbl_rec_lookup_head = s; ! 1160: else r->next = s; ! 1161: } ! 1162: ! 1163: char *pp = new char[ strlen(ptbl_name) + 10 ]; ! 1164: sprintf(pp, "%s[%d]", ptbl_name, i); ! 1165: return(pp); ! 1166: } ! 1167: ! 1168: void ptbl_add_pair(char* ptbl, char* vtbl) ! 1169: { ! 1170: // error('d', "ptbl_add_pair: ptbl: %s, vtbl: %s", ptbl, vtbl ); ! 1171: ptbl_rec *p = new ptbl_rec; ! 1172: ! 1173: p->pname = new char[strlen(ptbl) + 1]; ! 1174: strcpy(p->pname, ptbl); ! 1175: p->vname = new char[strlen(vtbl) + 1]; ! 1176: ! 1177: strcpy(p->vname, vtbl); ! 1178: p->next = ptbl_rec_pair_head; ! 1179: ! 1180: ptbl_rec_pair_head = p; ! 1181: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.