📄 print.c
字号:
/* @(#) print.c 1.7 1/27/86 17:49:19 */ /*ident "@(#)cfront:src/print.c 1.7" *//************************************************************************** C++ source for cfront, the C++ compiler front-end written in the computer science research center of Bell Labs Copyright (c) 1984 AT&T, Inc. All Rights Reserved THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.print.c: print the output of simpl, typ, or syn in a form suitable for cc input****************************************************************************/#include "cfront.h"extern FILE* out_file;/* print the declaration tree*/bit print_mode = 0;extern int ntok; int ntok = 0;int forced_sm = 0;bit Cast = 0;Pin curr_icall;int MAIN = 0; // fudge to get _main() called by main()void puttok(TOK t)/* print the output representation of "t"*/{ char * s; if (t<=0 || MAXTOK<=t) error("illegal token %d",t); s = keys[t]; if (s == 0) error("V representation token %d",t); putst(s); if (12<ntok++) { forced_sm = 1; ntok = 0; /* putch('\n');*/ last_line.putline(); } else if (t == SM) { forced_sm = 1; ntok = 0; putch('\n'); last_line.line++; }}#define MX 20#define NTBUF 10class dcl_buf { /* buffer for assembling declaration (or cast) left contains CONST_PTR => *CONST CONST_RPTR => &CONST PTR => * RPTR => & LP => ( right contains RP => ) VEC => [ rnode ] FCT => ( rnode ) FIELD => : rnode */ Pbase b; Pname n; TOK left[MX], right[MX]; Pnode rnode[MX]; int li, ri;public: void init(Pname nn) { b=0; n=nn; li=ri=0; }; void base(Pbase bb) { b = bb; }; void front(TOK t) { left[++li] = t; }; void back(TOK t, Pnode nod) { right[++ri] = t; rnode[ri] = nod; }; void paran() { front(LP); back(RP,0); }; void put();} *tbufvec[NTBUF] = {0}, *tbuf = 0;int freetbuf = 0;void dcl_buf.put(){ int i; if (MX<=li || MX<=ri) error('i',"T buffer overflow"); if (b == 0) error('i',"noBT%s",Cast?" in cast":""); if (n && n->n_sto) puttok(n->n_sto); b->dcl_print(); for( ; li; li--) switch (left[li]) { case LP: puttok(LP); break; case CONST_PTR: puttok(MUL); if (print_mode != SIMPL) puttok(CONST); break; case CONST_RPTR: if (print_mode == SIMPL) puttok(MUL); else puttok(ADDROF); if (print_mode != SIMPL) puttok(CONST); break; case PTR: puttok(MUL); break; case RPTR: if (print_mode == SIMPL) puttok(MUL); else puttok(ADDROF); } if (n) n->print(); for(i=1; i<=ri; i++) switch (right[i]) { case RP: puttok(RP); break; case VEC: puttok(LB); { Pvec v = (Pvec) rnode[i]; Pexpr d = v->dim; int s = v->size; if (d) d->print(); if (s) fprintf(out_file,"%d",s); } puttok(RB); break; case FCT: { Pfct f = (Pfct) rnode[i]; f->dcl_print(); } break; case FIELD: { Pbase f = (Pbase) rnode[i]; Pexpr d = (Pexpr)f->b_name; int s = f->b_bits; puttok(COLON); if (d) d->print(); if (s) fprintf(out_file,"%d",s); } break; }}#define eprint(e) if (e) Eprint(e)void Eprint(Pexpr e){ switch (e->base) { case DUMMY: break; case NAME: case ID: case ZERO: case ICON: case CCON: case FCON: case STRING: case IVAL: case TEXT: case CM: case ELIST: case COLON: case ILIST: case DOT: case REF: case THIS: case CALL: case G_CALL: case ICALL: case ANAME: e->print(); break; default: puttok(LP); e->print(); puttok(RP); break; }}void name.dcl_print(TOK list)/* Print the declaration for a name (list==0) or a name list (list!=0): For each name (1) print storage class (2) print base type (3) print the name with its declarators Avoid (illegal) repetition of basetypes which are class or enum declarations (A name list may contain names with different base types) list == SM : terminator SM list == 0: single declaration with terminator SM list == CM : separator CM*/{ Pname n; if (this == 0) error("0->name.dcl_print()"); for (n=this; n; n=n->n_list) { Ptype t = n->tp; int sm = 0; if (t == 0) error('i',"name.dcl_print(%n)T missing",n); if (print_mode==SIMPL && n->n_stclass==ENUM) continue; if (n->n_stclass == STATIC) n->where.putline(); switch (t->base) { case CLASS: { Pclass cl = (Pclass)t; if (n->base == TNAME) break; cl->dcl_print(n); sm = 1; break; } case ENUM: Penum(t)->dcl_print(n); sm = 1; break; case FCT: { Pfct f = (Pfct) t; if (n->base == TNAME) puttok(TYPEDEF); if (debug==0 && f->f_inline) { if (print_mode==SIMPL) { if (f->f_virtual || n->n_addr_taken) { TOK st = n->n_sto; Pblock b = f->body; f->body = 0; /* n->n_sto = 0; */ t->dcl_print(n); n->n_sto = st; f->body = b; } } else { if (print_mode != SIMPL) puttok(INLINE); else putst("/* inline */"); t->dcl_print(n); } } else { if (n->n_table==gtbl && strcmp(n->string,"main")==0) { MAIN = 1; gtbl->look("main",0)->use(); t->dcl_print(n); MAIN = 0; } else t->dcl_print(n); } break; } case OVERLOAD: { Pgen g = (Pgen) t; Plist gl; fprintf(out_file,"\t/* overload %s: */\n",g->string); for (gl=g->fct_list; gl; gl=gl->l) { Pname nn = gl->f; nn->dcl_print(0); sm = 1; } break; } case ASM: fprintf(out_file,"asm(\"%s\")\n",(char*)Pbase(t)->b_name); break; case INT: case CHAR: case LONG: case SHORT: // do not allocate space for constants unless necessary if (print_mode==SIMPL && Pbase(t)->b_const && n->n_sto!=EXTERN // extern const one; // const one = 1; // allocates storage && (n->n_scope==EXTERN // FUDGE const one = 1; // is treated as static // need loader support || n->n_scope==STATIC || n->n_scope==FCT) ) { if (n->n_evaluated) { sm = 1; /* no ; */ break; } } default: { Pexpr i = n->n_initializer; if (n->base == TNAME) puttok(TYPEDEF);//error('d',"%s: init %d %d tbl %d %d sto %d sc %d scope %d\n",n->string?n->string:"",i,i?i->base:0,n->n_table,gtbl,n->n_sto,n->n_stclass,n->n_scope); if (i) { if (n->n_sto==EXTERN && n->n_stclass==STATIC) { n->n_initializer = 0; t->dcl_print(n); puttok(SM); n->n_initializer = i; n->n_sto = 0; t->dcl_print(n); n->n_sto = EXTERN; } else t->dcl_print(n); } else { if (fct_void==0 && n->n_sto==0 && n_stclass==STATIC && n->n_table==gtbl) { switch (t->base) { case CHAR: case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: case EOBJ: case PTR: // "int a;" == "int a = 0;" n->n_initializer = i = zero; } } t->dcl_print(n); } if (n->n_scope!=ARG) { if (i) { puttok(ASSIGN); if (t!=i->tp && i->base!=ZERO && i->base!=ILIST /*&& i->tp!=Pchar_type*/) { Ptype t1 = n->tp; cmp://error('d',"t1%t",t1); switch (t1->base) { default: i->print(); break; case TYPE: t1 = Pbase(t1)->b_name->tp; goto cmp; case VEC: if (Pvec(t1)->typ->base==CHAR) { i->print(); break; } case PTR: case RPTR: puttok(LP); { bit oc = Cast; Cast = 1; t->print(); Cast = oc; } puttok(RP); eprint(i); } } else i->print(); } else if (n->n_evaluated) { puttok(ASSIGN); if (n->tp->base != INT) { puttok(LP); puttok(LP); { bit oc = Cast; Cast = 1; n->tp->print(); Cast = oc; } fprintf(out_file,")%d)",n->n_val); } else fprintf(out_file,"%d",n->n_val); } } } } switch (list) { case SM: if (sm==0) puttok(SM); break; case 0: if (sm==0) puttok(SM); return; case CM: if (n->n_list) puttok(CM); break; } }} void name.print()/* print just the name itself*/{ if (this == 0) error('i',"0->name.print()"); if (string == 0) { if (print_mode == ERROR) putst(" ?"); return; } switch (base) { default: error('i',"%d->name.print() base=%d",this,base); case TNAME: putst(string); return; case NAME: case ANAME: break; } switch (print_mode) { case SIMPL: { Ptable tbl; int i = n_union; if (tp) { switch (tp->base) { default: if (tbl=n_table) { Pname tn;//fprintf(stderr,"%s: tbl %d gtbl %d\n",string,tbl,gtbl); if (tbl == gtbl) break; if (tn=tbl->t_name) { if (i) fprintf(out_file,"_%s__O%d.__C%d_",tn->string,i,i); else fprintf(out_file,"_%s_",tn->string); break; } }//fprintf(stderr,"%s: stc %d\n",string,n_stclass); switch (n_stclass) { case STATIC: case EXTERN: if (i) fprintf(out_file,"_O%d.__C%d_",i,i); else if (n_sto==STATIC && tp->base!=FCT) fprintf(out_file,"_static_"); break; default: if (i) fprintf(out_file,"_auto__O%d.__C%d_",i,i); else fprintf(out_file,"_auto_"); } break; case CLASS: case ENUM: break; } } break; } case ERROR: { Ptable tbl; char* cs = 0; bit f = 0; if (tp) { switch (tp->base) { case OVERLOAD: case FCT: f = 1; default: if (tbl=n_table) { if (tbl == gtbl) { if (f == 0) putstring("::"); } else { if (tbl->t_name) { cs = tbl->t_name->string; fprintf(out_file,"%s::",cs); } } } if (n_sto==REGISTER && n_scope==ARG && strcmp(string,"this")==0) { Ptype tt = Pptr(tp)->typ; Pname cn = Pbase(tt)->b_name; fprintf(out_file,"%s::",cn->string); } break; case CLASS: case ENUM: // case TYPE: break; } switch (n_oper) { case TYPE: putstring("operator "); Pfct(tp)->returns->dcl_print(0); break; case 0: putstring(string); break; case DTOR: puttok(COMPL); case CTOR: if (cs) putstring(cs); else { putstring("constructor"); f = 0; } break; default: putstring("operator "); putstring(keys[n_oper]); break; } if (f) putstring("()"); } else if (string) putstring(string); return; } default: if (n_qualifier) { n_qualifier->print(); puttok(DOT); } } if (string) putst(string);}void type.print(){/*fprintf(stderr,"type %d %d\n",this,base); fflush(stderr);*/ switch (base) { case PTR: case RPTR: Pptr(this)->dcl_print(0); break; case FCT: Pfct(this)->dcl_print(); break; case VEC: Pvec(this)->dcl_print(0); break; case CLASS: case ENUM: if (print_mode == ERROR) fprintf(out_file,"%s",base==CLASS?"class":"enum"); else error('i',"%d->T.print(%k)",this,base); break; case TYPE: if (Cast) { Pbase(this)->b_name->tp->print(); break; } default: Pbase(this)->dcl_print(); }}char* type.signature(register char* p)/* take a signature suitable for argument types for overloaded function names*/{#define SDEL '_' Ptype t = this; int pp = 0;xx: switch (t->base) { case TYPE: t = Pbase(t)->b_name->tp; goto xx; case PTR: *p++ = 'P'; t = Pptr(t)->typ; pp=1; goto xx; case RPTR: *p++ = 'R'; t = Pptr(t)->typ; pp=1; goto xx; case VEC: *p++ = 'V'; t = Pvec(t)->typ; pp=1; goto xx; case FCT: { Pfct f = (Pfct)this; Pname n; t = (f->s_returns) ? f->s_returns : f->returns; *p++ = 'F'; for (n=f->argtype; n; n=n->n_list) { p = n->tp->signature(p); *p++ = SDEL; } *p++ = SDEL; if (f->nargs_known == ELLIPSIS) *p++ = 'E'; *p =0; return p; } } if ( Pbase(t)->b_unsigned ) *p++ = 'U'; switch (t->base) { case ANY: *p++ = 'A'; break; case ZTYPE: *p++ = 'Z'; break; case VOID: *p++ = 'V'; break; case CHAR: *p++ = (pp)?'C':'I'; break; case SHORT: *p++ = (pp)?'S':'I'; break; case EOBJ: case INT: *p++ = 'I'; break; case LONG: *p++ = 'L'; break; case FLOAT: *p++ = 'F'; break; case DOUBLE: *p++ = 'D'; break; case COBJ: *p++ = 'C'; strcpy(p,Pbase(t)->b_name->string);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -