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