📄 dcl.c
字号:
// constructors for statics are executed in order static Pstmt itail = 0; if (st_ilist == 0) st_ilist = ist; else itail->s_list = ist; itail = ist; init = 0; } // if (sti) nn->n_initializer = n_initializer = init; const_save = const_old; tbl = otbl; } else if (init == 0) /* no initializer */ goto str; else if (cl->is_simple() && cl->csu!=UNION && cl->csu!=ANON) /* struct */ goto str; else if (init->base == ILIST) { // class or union error("cannotI%n withIrL",nn); } else { // bitwise copy ok? // possible to get here?//error('d',"not simple %n",this); init = init->typ(tbl); if (nn->tp->check(init->tp,ASSIGN)==0) goto str; else error("cannotI%n:C %s has privateMs but no constructor",nn,cl->string); } break; } case VEC: t = Pvec(t)->typ; vec_seen++; goto lll; case TYPE: if (init==0 && Pbase(t)->b_const) { switch (n_scope) { case ARG: case 0: case PUBLIC: break; default: if (n_sto != EXTERN) error("unId const%n",this); } } t = Pbase(t)->b_name->tp; goto lll; default: str://error('d',"str: %n",this); if (init == 0) { switch (n_scope) { case ARG: case 0: case PUBLIC: break; default: if (n_sto!=EXTERN && t->tconst()) error("unId const%n",this); } break; } const_save = const_save || n_scope==ARG || (t->tconst() && vec_const==0); nn->n_initializer = n_initializer = init = init->typ(tbl); if (const_save) PERM(init); nn->assign(); const_save = const_old; switch (init->base) { case ILIST: new_list(init); list_check(nn,nn->tp,0); if (next_elem()) error("IrL too long"); break; case STRING: if (nn->tp->base == VEC) { Pvec v = (Pvec)nn->tp; if (v->typ->base == CHAR) { /* error('w',"\"char[] = string\"");*/ int sz = v->size; int isz = Pvec(init->tp)->size; if (sz == 0) v->size = isz; else if (sz < isz) error("Ir too long (%d characters) for%n[%d]",isz,nn,sz); break; } } default: { Ptype nt = nn->tp; if (vec_seen) { error("badIr for vector%n",nn); break; } tlx: switch (nt->base) { case TYPE: nt = ((Pbase)nt)->b_name->tp; goto tlx; case INT: case CHAR: case SHORT: if (init->base==ICON && init->tp==long_type) error('w',"longIr constant for%k%n",nn->tp->base,nn); case LONG: if (Pbase(nt)->b_unsigned && init->base==UMINUS && init->e2->base==ICON) error('w',"negativeIr for unsigned%n",nn); if (Pbase(nt)->b_const) { int i; Neval = 0; i = init->eval(); if (Neval == 0) { DEL(init); nn->n_evaluated = n_evaluated = 1; nn->n_val = n_val = i; nn->n_initializer = n_initializer = 0; } } goto cvcv; case PTR: { Pfct ef = Pfct(Pptr(nt)->typ); if (ef->base == FCT) { Pfct f; Pname n = 0; switch (init->base) { case NAME: f = (Pfct)init->tp; n = Pname(init); switch (f->base) { case FCT: case OVERLOAD: init = new expr(G_ADDROF,0,init); init->tp = f; } goto ad; case DOT: case REF: f = (Pfct) init->mem->tp; switch (f->base) { case FCT: case OVERLOAD: n = Pname(init->mem); init = new expr(G_ADDROF,0,init); init = init->typ(tbl); } goto ad; case ADDROF: case G_ADDROF: f = (Pfct)init->e2->tp; ad: if (f->base == OVERLOAD) { Pgen g = (Pgen)f; n = g->find(ef); if (n == 0) { error("cannot deduceT for &overloaded %s()",g->string); } init->e2 = n; n_initializer = init; n->lval(ADDROF); goto stgg; } if (n) n->lval(ADDROF); } } } } cvcv: { Pname cn; int i; if ((cn=init->tp->is_cl_obj()) && (i=can_coerce(nt,init->tp)) && Ncoerce) { if (1 < i) error("%d possible conversions forIr",i);/*error('d',"dcl %t<-%t",nt,init->tp);*/ Pclass cl = (Pclass)cn->tp; Pref r = new ref(DOT,init,Ncoerce); Pexpr c = new expr(G_CALL,r,0); c->fct_name = Ncoerce; c->tp = nt; n_initializer = c; goto stgg; } } if (nt->check(init->tp,ASSIGN)) error("badIrT%t for%n (%tX)",init->tp,this,nn->tp); else { stgg: if (init && n_stclass== STATIC) { /* check if non-static variables are used */ /* INCOMPLETE */ switch (init->base) { case NAME: if (init->tp->tconst()==0) error("V%n used inIr for%n",init,nn); break; case DEREF: case DOT: case REF: case CALL: case G_CALL: error("%k inIr of static%n",init->base,nn); } } } } } /* switch */ } /* block */ } /* default */ } /* switch */ggg: PERM(nn); switch (n_scope) { case FCT: nn->n_initializer = n_initializer; break; default: {/* Pexpr ii = nn->n_initializer;*/ Ptype t = nn->tp; /* if (ii) PERM(ii);*/ px: PERM(t); switch (t->base) { case PTR: case RPTR: t = Pptr(t)->typ; goto px; case VEC: t = Pvec(t)->typ; goto px; case TYPE: t = Pbase(t)->b_name->tp; goto px; case FCT: t = Pfct(t)->returns; goto px; /* args? */ } } } Cdcl = odcl; return nn;}int inline_restr; /* report use of constructs that the inline expanded cannot handle here */void fct.dcl(Pname n){ int nmem = TBLSIZE; Pname a; Pname ll; Ptable ftbl; Pptr cct = 0; int const_old = const_save; int bit_old = bit_offset; int byte_old = byte_offset; int max_old = max_align; int stack_old = stack_size; if (base != FCT) error('i',"fct.dcl(%d)",base); if (body == 0) error('i',"fct.dcl(body=%d)",body); if (n==0 || n->base!=NAME) error('i',"fct.dcl(name=%d %d)",n,(n)?n->base:0); if (body->memtbl == 0) body->memtbl = new table(nmem+3,n->n_table,0); ftbl = body->memtbl; body->own_tbl = 1; ftbl->real_block = body; max_align = AL_FRAME; stack_size = byte_offset = SZ_BOTTOM; bit_offset = 0; cc->stack(); cc->nof = n; cc->ftbl = ftbl; switch (n->n_scope) { case 0: case PUBLIC: cc->not = n->n_table->t_name; cc->cot = (Pclass)cc->not->tp; cc->tot = cc->cot->this_type; if (f_this==0 || cc->tot==0) error('i',"fct.dcl(%n): f_this=%d cc->tot=%d",n,f_this,cc->tot); f_this->n_table = ftbl; /* fake for inline printout */ cc->c_this = f_this; } Pname ax; for (a=argtype, ll=0; a; a=ax) { ax = a->n_list; Pname nn = a->dcl(ftbl,ARG); nn->n_assigned_to = nn->n_used = nn->n_addr_taken = 0; nn->n_list = 0; switch (a->tp->base) { case CLASS: case ENUM: /* unlink types declared in arg list */ a->n_list = dcl_list; dcl_list = a; break; default: if (ll) ll->n_list = nn; else { argtype = nn; if (f_this) f_this->n_list = argtype; } ll = nn; delete a; } } /* handle initializers for base class and member classes this->f_init == list of names of classes to be initialized no name => base class => constructor call in f_init->n_initializer name "m" => member object => constructor call in m->n_initializer */ if (n->n_oper != CTOR) { if (f_init) error(0,"unXAL: not a constructor"); } else {//error('d',"%n:f_init %d %d",n,f_init,f_init?f_init->base:0); if (f_init) { // explicit initializers Pname bn = cc->cot->clbase; Ptable tbl = cc->cot->memtbl; Pexpr binit = 0; Pname nx; const_save = 1; for ( Pname nn=f_init; nn; nn=nx) { nx = nn->n_list; Pexpr i = nn->n_initializer; if (nn->string) { // class member initializer Pname m = tbl->look(nn->string, 0); if (m && m->n_table == tbl) nn->n_initializer = mem_init(m,i,ftbl); else { error("%n not inC%n",m,n); nn->n_initializer = 0; } } else if (bn) { // base class initializer binit = base_init(bn,i,ftbl); nn->n_initializer = 0; } else error( "unXAL: noBC" ); } // for const_save = const_old; b_init = binit; } if (b_init == 0) { // try default initialization of base class Pname bn = cc->cot->clbase; if (bn && Pclass(bn->tp)->has_ctor()) b_init = base_init(bn,0,ftbl); } } PERM(returns); if (returns->base != VOID) { Pname rv = new name("_result"); rv->tp = returns; ftbl->insert(rv,0); delete rv; } const_save = f_inline?1:0; inline_restr = 0; body->dcl(ftbl); if( f_inline && inline_restr && returns->base!=VOID) { f_inline = 0; error( 'w', "\"inline\" ignored, %n contains%s%s%s%s",n, (inline_restr & 8) ? " loop" : "", (inline_restr & 4) ? " switch" : "", (inline_restr & 2) ? " goto" : "", (inline_restr & 1) ? " label" : "" ); } const_save = const_old; if (f_inline) isf_list = new name_list(n,isf_list); defined |= DEFINED; frame_size = stack_size + SZ_TOP; frame_size = ((frame_size-1)/AL_FRAME)*AL_FRAME+AL_FRAME; bit_offset = bit_old; byte_offset = byte_old; max_align = max_old; stack_size = stack_old; cc->unstack();}Pexpr fct.base_init(Pname bn, Pexpr i, Ptable ftbl)/* have base class bn and expr list i return "( *(base*)this ) . ctor( i )" ctor call generated in expr.typ()*/{ Pclass bcl = (Pclass)bn->tp; Pname bnw = bcl->has_ctor();//error('d',"base_init%n %d i %d %d bcl %d %d",bn,bnw,i,i?i->base:0,bcl,bcl?bcl->base:0); if (bnw) { Ptype t = bnw->tp; Pfct f = Pfct((t->base==FCT) ? t : Pgen(t)->fct_list->f->tp); Ptype ty = f->f_this->tp; // this Pexpr th = new texpr(CAST,ty,f_this); // (base*)this Pexpr v = new texpr(VALUE,bcl,i); // ?.base(i) v->e2 = new expr(DEREF,th,0); // (*(base*)this).base(i) v = v->typ(ftbl); // *base(&*(base*)this,i)//error('d',"v %d %k",v,v->base); switch (v->base) { case DEREF: Pexpr vv = v; v = v->e1; // base(&*(base*)this,i) delete vv; break; case ASSIGN: // degenerate base(base&): *(base*)this=i th = new texpr(CAST,ty,f_this); v = new expr(CM,v,th); // (*(base*)this=i,(base*)this); v = v->typ(ftbl); break; default: error('i',"fct.base_init: unX%k",v->base); } return v; } else error(0,"unXAL: noBC constructor"); return 0;}Pexpr fct.mem_init(Pname member, Pexpr i, Ptable ftbl)/* return "member_ctor( m, i )"*/{//error('d',"mem_init(%n)",member); if (member->n_stclass == STATIC) error('s',"MIr for static%n",member); Pname cn = member->tp->is_cl_obj(); // first find the class name if (cn) { Pclass mcl = Pclass(cn->tp); // then find the classdef Pname ctor = mcl->has_ctor();//error('d',"cn%n ctor %d",cn,ctor); if (ctor) { // generate: this->member.cn::cn(args) Pref tn = new ref(REF,f_this,member); Pref ct = new ref(DOT,tn,ctor); Pexpr c = new expr(G_CALL,ct,i); return c->typ(ftbl); } else error("init of member %m with no ctor",member); } else if (cl_obj_vec) error('s', "init of Cmember vector with ctor"); else if (member->tp->tconst()) { TOK t = member->tp->set_const(0); switch (t) { case ANY: case VEC: case RPTR: error("MIr for%kM%n",member); return 0; } Pref tn = new ref(REF,f_this,member); Pexpr init = new expr(ASSIGN,tn,i); init = init->typ(ftbl); member->tp->set_const(1); return init; } else if (member->tp->is_ref()) { Pexpr init = i->typ(ftbl); init = ref_init(Pptr(member->tp),init,ftbl); member->assign(); return init; } else { Pref tn = new ref (REF,f_this,member); Pexpr init = new expr(ASSIGN,tn,i); return init->typ(ftbl); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -