📄 simpl.c
字号:
case GOTO: dontknow: break; } } else { if (strcmp(curr_fct->string,"main")) error('w',"no value returned from%n",curr_fct); if (del_list) goto zaq; } } else if (del_list) { /* return may not have been seen */ zaq: if (tail) tail->s_list = del_list; else body->s = del_list; tail = dtail; } if (curr_fct->n_oper == CTOR) { if ( Pname(th)->n_assigned_to == 0 ) { /* generate: if (this==0) this=_new( sizeof(class cl) ); init_list ; */ Pname(th)->n_assigned_to = ass_count ? ass_count : FUDGE111; Pexpr sz = new expr(IVAL,Pexpr(cl->tsizeof()),0); Pexpr ee = new expr(ELIST,sz,0); ee = new call(new_fct,ee); ee->fct_name = new_fct; ee->base = G_CALL; ee->simpl(); ee = new expr(ASSIGN,th,ee); Pstmt es = new estmt(SM,curloc,ee,0); ee = new expr(EQ,th,zero); ifstmt* ifs = new ifstmt(curloc,ee,es,0); /*ifs->simpl(); do not simplify or "this = " will cause an extra call of base.base */ if (init_list) { es = new estmt(SM,curloc,init_list,0); es->s_list = body->s; body->s = es; if (tail == 0) tail = es; } ifs->s_list = body->s; body->s = ifs; if (tail == 0) tail = ifs; } Pstmt st = new estmt(RETURN,curloc,th,0); if (tail) tail->s_list = st; else body->s = st; tail = st; }}Pstmt block.simpl(){ int i; Pname n; Pstmt ss=0, sst; Pstmt dd=0, ddt; Pstmt stail; Ptable old_scope = scope; if (own_tbl == 0) { Pstmt obd = block_del_list; block_del_list = 0; ss = (s) ? s->simpl() : 0; block_del_list = obd; return ss; } scope = memtbl; if(scope->init_stat == 0) scope->init_stat = 1; /* table is simplified. */ for (n=scope->get_mem(i=1); n; n=scope->get_mem(++i)) { Pstmt st = 0; Pname cln; Pexpr in = n->n_initializer;//error('d',"auto %n",n); if (in) scope->init_stat = 2; /* initializer in this scope */ switch (n->n_scope) { case ARG: case 0: case PUBLIC: continue; } if (n->n_stclass == STATIC) continue; if (in && in->base==ILIST) error('s',"initialization of automatic aggregates"); if (n->tp == 0) continue; /* label */ if (n->n_evaluated) continue; /* construction and destruction of temporaries is handled locally */ { char* s = n->string; register char c3 = s[3]; if (s[0]=='_' && s[1]=='D' && isdigit(c3)) continue; }//error('d',"cln %d",n->tp->is_cl_obj()); if ( cln=n->tp->is_cl_obj() ) { Pclass cl = (Pclass)cln->tp; Pname d = cl->has_dtor(); if (d) { // n->cl.dtor(0); Pref r = new ref(DOT,n,d); Pexpr ee = new expr(ELIST,zero,0); Pcall dl = new call(r,ee); Pstmt dls = new estmt(SM,n->where,dl,0); dl->base = G_CALL; dl->fct_name = d; if (dd) ddt->s_list = dls; else dd = dls; ddt = dls; }//error('d',"in %d %k %n",in,in?in->base:0,cln); if (in) { switch (in->base) { case DEREF: // *constructor? if (in->e1->base == G_CALL) { Pname fn = in->e1->fct_name; if (fn==0 || fn->n_oper!=CTOR) goto ddd; st = new estmt(SM,n->where,in->e1,0); n->n_initializer = 0; break; } goto ddd; case ASSIGN: // assignment to "n"? if (in->e1 == n) { st = new estmt(SM,n->where,in,0); n->n_initializer = 0; break; } default: goto ddd; } } } else if (cl_obj_vec) { Pclass cl = (Pclass)cl_obj_vec->tp; Pname d = cl->has_dtor(); Pname c = cl->has_ictor(); if (in) { if (c) { /* _vec_new(vec,noe,sz,ctor); */ Pfct f = Pfct(c->tp); // null constructor? Pblock b = f->body; if (f->f_inline && f->body->empty) { n->n_initializer = 0; goto skip; } int esz = cl->tsizeof(); Pexpr noe = new expr(IVAL,Pexpr(n->tp->tsizeof()/esz),0); Pexpr sz = new expr(IVAL,(Pexpr)esz,0); Pexpr arg = new expr(ELIST,c,0); /*c->take_addr();*/ c->lval(ADDROF); arg = new expr(ELIST,sz,arg); arg = new expr(ELIST,noe,arg); arg = new expr(ELIST,n,arg); arg = new call(vec_new_fct,arg); arg->base = G_CALL; arg->fct_name = vec_new_fct; st = new estmt(SM,n->where,arg,0); n->n_initializer = 0; } else goto ddd; skip:; } if (d) { /* _vec_delete(vec,noe,sz,dtor,0); */ Pstmt dls; int esz = cl->tsizeof(); Pexpr noe = new expr(IVAL, Pexpr(n->tp->tsizeof()/esz),0); Pexpr sz = new expr(IVAL,(Pexpr)esz,0); Pexpr arg = new expr(ELIST,d,zero); /*c->take_addr();*/ d->lval(ADDROF); arg = new expr(ELIST,sz,arg); arg = new expr(ELIST,noe,arg); arg = new expr(ELIST,n,arg); arg = new call(vec_del_fct,arg); arg->base = G_CALL; arg->fct_name = vec_del_fct; dls = new estmt(SM,n->where,arg,0); if (dd) ddt->s_list = dls; else dd = dls; ddt = dls; } } else if (in /*&& n->n_scope==FCT*/) { switch (in->base) { case ILIST: switch (n->n_scope) { case FCT: case ARG: error('s',"Ir list for localV%n",n); } break; case STRING: if (n->tp->base==VEC) break; /* BUG char vec only */ default: ddd: { Pexpr ee = new expr(ASSIGN,n,in); st = new estmt(SM,n->where,ee,0); n->n_initializer = 0; } } } if (st) { if (ss) sst->s_list = st; else ss = st; sst = st; } } if (dd) { Pstmt od = del_list; Pstmt obd = block_del_list; dd->simpl(); /*PERM(dd);*/ if (od) del_list = new pair(curloc,dd,od); else del_list = dd; block_del_list = dd; stail = (s) ? s->simpl() : 0; Pfct f = (Pfct)curr_fct->tp; if (this!=f->body || f->returns->base==VOID || strcmp(curr_fct->string,"main")==0 ) { // not dropping through the bottom of a value returning function if (stail) stail->s_list = dd; else s = dd; stail = ddt; } del_list = od; block_del_list = obd; } else stail = (s) ? s->simpl() : 0; if (ss) { /* place constructor calls */ ss->simpl(); sst->s_list = s; s = ss; if (stail == 0) stail = sst; } scope = old_scope; return stail;}void classdef.simpl(){ int i; Pname m; Pclass oc = in_class; in_class = this; for (m=memtbl->get_mem(i=1); m; m=memtbl->get_mem(++i) ) { Pexpr i = m->n_initializer; m->n_initializer = 0; m->simpl(); m->n_initializer = i; } in_class = oc; Plist fl; /* simplify friends */ for (fl=friend_list; fl; fl=fl->l) { Pname p = fl->f; switch (p->tp->base) { case FCT: case OVERLOAD: p->simpl(); } }}void expr.simpl(){//error('d',"expr.simpl (%d) %d%k e1=%d e2=%d tp2=%d cf%n",permanent,this,base,e1,e2,tp2,curr_fct); if (this==0 || permanent==2) return; switch (base) { case BLOCK: case SM: case IF: case FOR: case WHILE: case SWITCH: error('i',"%k inE",base); case VALUE: error('i',"expr.simpl(value)"); case DELETE: /* delete p => _delete(p); or cl.~cl(p,1); delete[s]p => _delete(p); or vec_del_fct(p,vec_sz,elem_sz,~cl,1); */ { Pname cln; Pclass cl; Pname n; Ptype tt = e1->tp; ttloop: switch (tt->base) { case TYPE: tt = Pbase(tt)->b_name->tp; goto ttloop; case VEC: case PTR: tt = Pptr(tt)->typ; break; } cln = tt->is_cl_obj(); if (cln) cl = (Pclass)cln->tp; if ( cln && (n=cl->has_dtor()) ) { // ~cl() might be virtual//error('d',"%n %d",n,Pfct(n->tp)->f_virtual); if (e2 == 0) { // e1->cl::~cl(1) base = G_CALL; e1 = new ref(REF,e1,n); e2 = new expr(ELIST,one,0); fct_name = n; } else { // del_cl_vec(e1,e2,elem_size,~cl,1); int esz = cl->tsizeof(); Pexpr sz = new expr(IVAL,Pexpr(esz),0); Pexpr arg = one; if (Pfct(n->tp)->f_virtual) { // beware of sideeffects in expression e1 if (e1->base != NAME) error('s',"PE too complicated for delete[]"); Pexpr a = new ref(REF,e1,n); a = a->address(); arg = new expr(ELIST,a,arg); } else { arg = new expr(ELIST,n,arg); n->lval(ADDROF); // n->take_addr(); } arg = new expr(ELIST,sz,arg); arg = new expr(ELIST,e2,arg); arg = new expr(ELIST,e1,arg); base = G_CALL; e1 = vec_del_fct; e2 = arg; fct_name = vec_del_fct; } } else if (cl_obj_vec) { error('i',"expr.simpl: delete vector"); } else { // _delete(e1) base = G_CALL; e2 = new expr(ELIST,e1,0); e1 = fct_name = del_fct; } // *this = *typ(gtbl); Pcall(this)->simpl(); break; } case G_ADDROF: case ADDROF: e2->simpl(); switch (e2->base) { case DOT: case REF: { Pref r = (Pref)e2; Pname m = r->mem; if (m->n_stclass == STATIC) { /* & static member */ Pexpr x; delp: x = e2; e2 = m; r->mem = 0; DEL(x); } else if (m->tp->base == FCT) { /* & member fct */ Pfct f = (Pfct)m->tp; if (f->f_virtual) { /* &p->f ==> p->vtbl[fi] */ int index = f->f_virtual; Pexpr ie = (1<index) ? new expr(IVAL, (Pexpr)(index-1),0) : 0; Pname vp = m->n_table->look("_vptr",0); r->mem = vp; base = DEREF; e1 = e2; e2 = ie; } else { goto delp; } } } } break; default: if (e1) e1->simpl(); if (e2) e2->simpl(); break; case NAME: case DUMMY: case ICON: case FCON: case CCON: case IVAL: case FVAL: case LVAL: case STRING: case ZERO: case ILIST: return; case SIZEOF: base = IVAL; e1 = (Pexpr)tp2->tsizeof(); DEL(tp2); tp2 = 0; break; case G_CALL: case CALL: Pcall(this)->simpl(); break; case QUEST: cond->simpl(); e1->simpl(); e2->simpl(); break; case NEW: /* change NEW node to CALL node */ { Pname cln; Pname ctor; int sz = 1; int esz; Pexpr var_expr = 0; Pexpr const_expr; Ptype tt = tp2; Pexpr arg; if ( cln=tt->is_cl_obj() ) { Pclass cl = (Pclass)cln->tp; if ( ctor=cl->has_ctor() ) { /* 0->cl_ctor(args) */ Pexpr p = zero; if (ctor->n_table != cl->memtbl) { /* no derived constructor: pre-allocate */ int dsz = cl->tsizeof(); Pexpr ce = new expr(IVAL,(Pexpr)dsz,0); ce = new expr(ELIST,ce,0); p = new expr(G_CALL,new_fct,ce); p->fct_name = new_fct; } Pcall c = (Pcall)e1; c->e1 = new ref(REF,p,(Pname)c->e1); /* c->set_fct_name(ctor);*/ c->simpl(); *this = *Pexpr(c); return; } } else if (cl_obj_vec) { Pclass cl = (Pclass)cl_obj_vec->tp; ctor = cl->has_ictor(); if (ctor == 0) { if (cl->has_ctor()) error("new %s[], no default constructor",cl->string); cl_obj_vec = 0; } } xxx: switch (tt->base) { case TYPE: tt = Pbase(tt)->b_name->tp; goto xxx; default: esz = tt->tsizeof(); break; case VEC: { Pvec v = (Pvec)tt; if (v->size) sz *= v->size; else if (v->dim) var_expr = (var_expr) ? new expr(MUL,var_expr,v->dim) : v->dim; else { sz = SZ_WPTR; break; } tt = v->typ; goto xxx; } } if (cl_obj_vec) { // _vec_new(0,no_of_elements,element_size,ctor) Pfct f = Pfct(cl_obj_vec->tp); // null constructor? Pblock b = f->body; if (f->f_inline && b->empty) goto skip2; const_expr = new expr(IVAL,(Pexpr)sz,0); Pexpr noe = (var_expr) ? (sz!=1) ? new expr(MUL,const_expr,var_expr) : var_expr : const_expr; const_expr = new expr(IVAL,(Pexpr)esz,0); base = CALL; arg = new expr(ELIST,ctor,0); /*ctor->take_addr();*/ ctor->lval(ADDROF); arg = new expr(ELIST,const_expr,arg); arg = new expr(ELIST,noe,arg); e2 = new expr(ELIST,zero,arg); e1 = vec_new_fct; fct_name = vec_new_fct; break; } skip2:; /* call _new(element_size*no_of_elements) */ sz *= esz; const_expr = new expr(IVAL,(Pexpr)sz,0); arg = (var_expr) ? (sz!=1) ? new expr(MUL,const_expr,var_expr) :var_expr : const_expr;//error('d',"new: (%t)_new(...)",tp); base = CAST; tp2 = tp; e1 = new expr(G_CALL,new_fct,new expr(ELIST,arg,0)); e1->fct_name = new_fct; simpl(); break; } case CAST: e1->simpl(); break; case REF: e1->simpl(); break; case DOT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -