📄 dcl.c
字号:
Ptype t = f->argtype->tp; clll: switch (t->base) { case TYPE: t = Pbase(t)->b_name->tp; goto clll; case RPTR: /* X(X&) ? */ t = Pptr(t)->typ; cxll: switch (t->base) { case TYPE: t = Pbase(t)->b_name->tp; goto cxll; case COBJ: if (class_name == Pbase(t)->b_name) Pclass(class_name->tp)->itor = nn; } break; case COBJ: /* X(X) ? */ if (class_name == Pbase(t)->b_name) error("impossible constructor: %s(%s)",class_name->string,class_name->string); } } break; case TYPE:/*error('d',"just_made %d %n",just_made,this);*/ if (just_made) { nn->n_list = Pclass(class_name->tp)->conv; Pclass(class_name->tp)->conv = nn; } break; case DTOR: case NEW: case DELETE: case CALL: case 0: break; default: if (f->nargs_known != 1) { error("ATs must be fully specified for%n",nn); } else if (class_name == 0) { Pname a; switch (f->nargs) { case 1: case 2: for (a=f->argtype; a; a=a->n_list) { Ptype tx = a->tp; if (tx->base == RPTR) tx = ((Pptr)tx)->typ; if (tx->is_cl_obj()) goto cok; } error("%n must take at least oneCTA",nn); break; default: error("%n must take 1 or 2As",nn); } } else { switch (f->nargs) { case 0: case 1: break; default: error("%n must take 0 or 1As",nn); } } cok:; } /* the body cannot be checked until the name has been checked and entered into its table */ if (f->body) f->dcl(nn); break; } case FIELD: { Pbase fld = (Pbase)tp; switch (n_stclass) { case 0: case PUBLIC: break; default: error("%k field",n_stclass); n_stclass = 0; } if (cc->not==0 || cc->cot->csu==UNION) { error(cc->not?"field in union":"field not inC"); PERM(tp); Cdcl = odcl; return this; } if (string) { nn = tbl->insert(this,0); n_table = nn->n_table; if (Nold) error("twoDs of field%n",this); } tp->dcl(tbl); // adjust alignment int a = (F_SENSITIVE) ? Pbase(tp)->b_fieldtype->align() : SZ_WORD; if (max_align < a) max_align = a; if (fld->b_bits == 0) { // force word alignment int b; if (bit_offset) fld->b_bits = BI_IN_WORD - bit_offset; else if (b = byte_offset%SZ_WORD) fld->b_bits = b * BI_IN_BYTE; if (max_align < SZ_WORD) max_align = SZ_WORD; } else if (bit_offset == 0) { // take care of part of word int b = byte_offset%SZ_WORD; if (b) { byte_offset -= b; bit_offset = b*BI_IN_BYTE; } }//error('d',"byteoff %d bitoff %d bits %d",byte_offset,bit_offset,fld->b_bits); int x = (bit_offset += fld->b_bits); if (BI_IN_WORD < x) { fld->b_offset = 0; byte_offset += SZ_WORD; bit_offset = fld->b_bits; } else { fld->b_offset = bit_offset; if (BI_IN_WORD == x) { bit_offset = 0; byte_offset += SZ_WORD; } else bit_offset = x; } n_offset = byte_offset; break; } case COBJ: { Pclass cl = Pclass(Pbase(tp)->b_name->tp);/*fprintf(stderr,"COBJ %d %s -> (%d %d)\n",tp,Pbase(tp)->b_name->string,cl,cl->base); fflush(stderr);*/ if (cl->csu == ANON) { /* export member names to enclosing scope */ Pname nn; int i; int uindex; Ptable mtbl = cl->memtbl; char* p = cl->string; if (tbl == gtbl) error('s',"global anonymous union"); while (*p++ != 'C'); /* UGH!!! */ uindex = str_to_int(p); for ( nn=mtbl->get_mem(i=1); nn; nn=mtbl->get_mem(++i) ) { Ptable tb = nn->n_table; nn->n_table = 0; Pname n = tbl->insert(nn,0); n->n_union = uindex; nn->n_table = tb; } } goto cde; } case VEC: case PTR: case RPTR: tp->dcl(tbl); default: cde: nn = tbl->insert(this,0); n_table = nn->n_table;//error('d',"Nold %d tbl %d nn %d%n tp%t gtbl %d",Nold,tbl,nn,nn,nn->tp,gtbl); if (Nold) { if (nn->tp->base == ANY) goto zzz; if (tp->check(nn->tp,0)) { error("twoDs of%n;Ts:%t and%t",this,nn->tp,tp); Cdcl = odcl; return 0; } if (n_sto && n_sto!=nn->n_scope) error("%n both%k and not%k",this,n_sto,n_sto); else if (nn->n_scope==STATIC && n_scope==EXTERN) error("%n both static and extern",this); else if (nn->n_sto==STATIC && n_sto==STATIC ) error("static%n declared twice",this); else { // n_sto = nn->n_sto; first scope specifier wins n_scope = nn->n_scope; switch (scope) { case FCT: error("twoDs of%n",this); Cdcl = odcl; return 0; case ARG: error("two arguments%n",this); Cdcl = odcl; return 0; case 0: case PUBLIC: error("twoDs ofM%n",this); Cdcl = odcl; return 0; case EXTERN: if (fct_void==0 && n_sto==0 && nn->n_sto==0) { error("two definitions of%n",this); Cdcl = odcl; return 0; } } } n_scope = nn->n_scope;/* n_val */ if (n_initializer) { if (nn->n_initializer || nn->n_val) error("twoIrs for%n",this); nn->n_initializer = n_initializer; } } else { // check for the ambiguous plain "int a;" /* if (n_initializer==0 && n_sto==0 && scope==EXTERN) { error('w',"%n does not have storageC or initializer",this); } */ } zzz: if (base != TNAME) { Ptype t = nn->tp;//fprintf(stderr,"tp %d %d nn->tp %d %d\n",tp,tp->base,nn->tp,nn->tp?nn->tp->base:0); fflush(stderr); if (t->base == TYPE) { Ptype tt = Pbase(t)->b_name->tp; if (tt->base == FCT) nn->tp = t = tt; } switch (nn->n_stclass) { default: switch (t->base) { case FCT: case OVERLOAD: break; default: { int x = t->align(); int y = t->tsizeof(); if (max_align < x) max_align = x; while (0 < bit_offset) { byte_offset++; bit_offset -= BI_IN_BYTE; } bit_offset = 0; if (byte_offset && 1<x) byte_offset = ((byte_offset-1)/x)*x+x; nn->n_offset = byte_offset; byte_offset += y; } } break; case STATIC: switch (t->base) { case FCT: case OVERLOAD: break; default: t->tsizeof(); // check that size is known } break; } } { Ptype t = nn->tp; int const_old = const_save; bit vec_seen = 0; Pexpr init = n_initializer; if (init) { switch (n_scope) { case 0: case PUBLIC: if (n_stclass != STATIC) error("Ir forM%n",this); break; } } /* if (n_scope == EXTERN) break; */ lll: switch (t->base) { case RPTR: if (init) { if (nn->n_scope == ARG) break; init = init->typ(tbl); if (n_sto==STATIC && init->lval(0)==0) error("Ir for static reference%n not an lvalue",this); else {// int tcount = stcount; nn->n_initializer = n_initializer = ref_init(Pptr(t),init,tbl);// if (tcount != stcount) error('s',"needs temporaryV for evaluation of AIr"); } nn->assign(); } else { switch (nn->n_scope) { default: if (n_sto == EXTERN) break; error("unId reference%n",this); case ARG: break; case PUBLIC: case 0: if (n_sto == STATIC) error("a staticM%n cannot be a reference",this); break; } } break; case COBJ: { Pname cn = Pbase(t)->b_name; Pclass cl = (Pclass)cn->tp; Pname ctor = cl->has_ctor(); Pname dtor = cl->has_dtor();//error('d',"c/dtor %n %d %d",cn,ctor,dtor); if (dtor) { Pstmt dls; switch ( nn->n_scope ) { case EXTERN: if (n_sto==EXTERN) break; case STATIC: { Ptable otbl = tbl; // to collect temporaries generated // in static destructors where we // can find them again (in std_tbl) if (std_tbl == 0) std_tbl = new table(8,gtbl,0); tbl = std_tbl; if (vec_seen) { /* _vec_delete(vec,noe,sz,dtor,0); */ int esz = cl->tsizeof(); Pexpr noe = new expr(IVAL, (Pexpr)(nn->tp->tsizeof()/esz),0); Pexpr sz = new expr(IVAL,(Pexpr)esz,0); Pexpr arg = new expr(ELIST,dtor,zero); dtor->lval(ADDROF); arg = new expr(ELIST,sz,arg); arg = new expr(ELIST,noe,arg); arg = new expr(ELIST,nn,arg); arg = new call(vec_del_fct,arg); arg->base = G_CALL; arg->fct_name = vec_del_fct; arg->tp = any_type; // avoid another type check dls = new estmt(SM,nn->where,arg,0); } else { /* nn->cl.~cl(0); */ Pref r = new ref(DOT,nn,dtor); Pexpr ee = new expr(ELIST,zero,0); Pcall dl = new call(r,ee); dls = new estmt(SM,nn->where,dl,0); dl->base = G_CALL; dl->fct_name = dtor; dl->tp = any_type; // avoid another check } // destructors for statics are executed in reverse order if (st_dlist) dls->s_list = st_dlist; st_dlist = dls; tbl = otbl; } } } if (ctor) { Pexpr oo = nn; for (int vi=vec_seen; vi; vi--) oo = oo->contents(); int sti = 0;//error('d',"ctor init=%d n_scope=%d",init,nn->n_scope); switch (nn->n_scope) { case EXTERN: if (init==0 && n_sto==EXTERN) goto ggg; case STATIC: sti = 1; if (tbl != gtbl) {// prohibited only to avoid having to handle local variables in the// constructors argument list error('s',"local static%n of class with constructor",this); } default: if (vec_seen && init) { error("Ir forCO%n\[\]",this); n_initializer = init = 0; } break; case ARG://error('d',"init %d",init);/* if (init) { // check default arguments init = new texpr(VALUE,cl,0); init->e2 = oo; nn->n_initializer = n_initializer = init = init->typ(tbl); }*/ case PUBLIC: case 0: goto ggg; } const_save = 1; nn->assign();//error('d',"init %d %n tbl %d",init,nn,tbl); Ptable otbl = tbl; if (sti) { // to collect temporaries generated // in static initializers where we // can find them again (in sti_tbl) if (sti_tbl == 0) sti_tbl = new table(8,gtbl,0); tbl = sti_tbl; if (n_sto == EXTERN) nn->n_sto = n_sto = 0; }//error('d',"init %d %d vec_seen %d",init,init?init->base:0,vec_seen); if (init) { if (init->base==VALUE) {//error('d',"value %d",init->tp2->base); switch (init->tp2->base) { case CLASS: if (Pclass(init->tp2)!=cl) goto inin; break; default: Pname n2 = init->tp2->is_cl_obj(); if (n2==0 || Pclass(n2->tp)!=cl) goto inin; } init->e2 = oo; init = init->typ(tbl); } else { inin://error('d',"inin:"); init = init->typ(tbl); init = class_init(nn,nn->tp,init,tbl); } } else { init = new texpr(VALUE,cl,0); init->e2 = oo; init = init->typ(tbl); } Pname c; if (vec_seen) { c = cl->has_ictor(); if (c == 0) error("vector ofC%n that do not have a constructor taking noAs",cn); else if (Pfct(c->tp)->nargs) error('s',"defaultAs for constructor for vector ofC%n",cn); } if (sti) { if (vec_seen) { // _vec_new(vec,noe,sz,ctor); int esz = cl->tsizeof(); Pexpr noe = new expr(IVAL,(Pexpr)(nn->tp->tsizeof()/esz),0); Pexpr sz = new expr(IVAL,(Pexpr)esz,0); Pexpr arg = new expr(ELIST,c,0); c->lval(ADDROF); arg = new expr(ELIST,sz,arg); arg = new expr(ELIST,noe,arg); arg = new expr(ELIST,nn,arg); init = new call(vec_new_fct,arg); init->base = G_CALL; init->fct_name = vec_new_fct; init->tp = any_type; } else {//error('d',"init%n: %k",nn,init->base); switch (init->base) { case DEREF: // *constructor? if (init->e1->base == G_CALL) { Pname fn = init->e1->fct_name; if (fn==0 || fn->n_oper!=CTOR) goto as; init = init->e1; break; } goto as; case ASSIGN: if (init->e1 == nn) break; // simple assignment as: default: init = new expr(ASSIGN,nn,init); } } Pstmt ist = new estmt(SM,nn->where,init,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -