📄 dcl.c
字号:
}bbb:/*fprintf(stderr,"bbb: bt %d %d\n",bt,bt->base); fflush(stderr);*/ Pname ln = tbl->look(bn->string,0);//error('d',"ln %d %d",ln,ln?ln->n_table==tbl:0); if (ln && ln->n_table==tbl) error('w',"%n redefined",ln); bn->where = nx->where; Pname bnn = tbl->insert(bn,CLASS); // copy for member lookup cl = (Pclass)bn->tp; /* CLASS *//*fprintf(stderr,"cl %d %d\n",cl,cl->base); fflush(stderr);*/ if (cl->defined&(DEFINED|SIMPLIFIED)) error("C%n defined twice",this); else { if (bn->n_scope == ARG) bn->n_scope = ARGT; cl->dcl(bn,tbl); // if (nest) { // int l1 = strlen(cl->string); // int l2 = strlen(nest->string); // char* s = new char[l1+l2+2]; // strcpy(s,nest->string); // s[l2] = '_'; // strcpy(s+l2+1,cl->string); // cl->string = s; // /* cl->memtbl->t_name->string = s;*/ // } } tp = cl; Cdcl = odcl; return bnn; } case ENUM: { Pname nx = ktbl->look(string,0); /* TNAME */ if (nx == 0) { nx = ktbl->look(string,HIDDEN); /* hidden TNAME */ } Pbase bt = (Pbase)nx->tp; /* EOBJ */ Pname bn = bt->b_name; Pname bnn = tbl->insert(bn,CLASS); Penum en = (Penum)bn->tp; /* ENUM */ if (en->defined&(DEFINED|SIMPLIFIED)) error("enum%n defined twice",this); else { if (bn->n_scope == ARG) bn->n_scope = ARGT; en->dcl(bn,tbl); } tp = en; Cdcl = odcl; return bnn; } case FCT: { Pfct f = (Pfct)tp; Pname class_name; Ptable etbl; int can_overload; int in_class_dcl = (int)cc->not; int just_made = 0;//error('d',"fct%n",this); if (f->f_inline) n_sto = STATIC; if (f->argtype) { Pname a; int oo = const_save; const_save = 1; for (a=f->argtype; a; a=a->n_list) { Pexpr init; if (init = a->n_initializer) { // default argument//or('d',"init %k",init->base);Pname cln;if (cln = a->tp->is_cl_obj()) {//error('d',"a%n cln%n init %k",a,cln,init->base); if (init->base==VALUE) { switch (init->tp2->base) { case CLASS: if (Pclass(init->tp2)!=Pclass(cln->tp)) goto inin2; break; default: Pname n2 = init->tp2->is_cl_obj(); if (n2==0 || Pclass(n2->tp)!=Pclass(cln->tp)) goto inin2; } init->e2 = a; init = init->typ(tbl); init->simpl(); init->permanent = 2; a->n_initializer = init; error('s',"constructor as defaultA"); } else { inin2://error('d',"inin2: %k %s",init->base,init->base==NAME?init->string:""); if (init->base == ILIST) error('s',"list as AIr"); Pexpr i = init->typ(tbl); init = class_init(a,a->tp,i,tbl); if (i!=init && init->base==DEREF) error('s',"constructor needed forAIr"); init->simpl(); init->permanent = 2; a->n_initializer = init; }}else if (a->tp->is_ref()) {//error('d',"%n is ref",a); init = init->typ(tbl); int tcount = stcount; init = ref_init(Pptr(a->tp),init,tbl); if (tcount != stcount) error('s',"needs temporaryV to evaluateAIr"); init->simpl(); init->permanent = 2; a->n_initializer = init;//error('d',"ok");}else { int i = 0; init = init->typ(tbl); if (a->tp->check(init->tp,ARG)==0 || (i=can_coerce(a->tp,init->tp))) { if (1 < i) error("%d possible conversions for defaultA",i); if (Ncoerce) { Pname cn = init->tp->is_cl_obj(); Pclass cl = (Pclass)cn->tp; Pref r = new ref(DOT,init,Ncoerce); init = new expr(G_CALL,r,0); init->fct_name = Ncoerce; init->tp = a->tp; } init->simpl(); init->permanent = 2; a->n_initializer = init; Neval = 0; int i = init->eval(); if (Neval == 0) { a->n_evaluated = 1; a->n_val = i; } } else { error("badIrT%t forA%n",init->tp,a); DEL(init); a->n_initializer = 0; } }} flatten1: switch (a->tp->base) { case TYPE: a->tp = Pbase(a->tp)->b_name->tp; goto flatten1; case CHAR: case SHORT: /* error('w',"A ofT%k (becomes int)",a->tp->base); */ a->tp = int_type; break; case FLOAT: /* error('w',"A ofT float (becomes double)"); */ a->tp = double_type; break; } } const_save = oo; } tp->dcl(tbl); /* must be done before the type check */ if (n_qualifier) { /* qualified name: c.f() checked above */ if (in_class_dcl) { error("unXQN%n",this); Cdcl = odcl; return 0; } class_name = Pbase(n_qualifier->tp)->b_name; etbl = Pclass(class_name->tp)->memtbl; } else { class_name = cc->not; /* beware of local function declarations in member functions */ if (class_name && tbl!=cc->cot->memtbl) { class_name = 0; in_class_dcl = 0; } if (n_oper) check_oper(class_name); etbl = tbl; } if (etbl==0 || etbl->base!=TABLE) error('i',"N.dcl: etbl=%d",etbl); switch (n_oper) { case NEW: case DELETE: switch (scope) { case 0: case PUBLIC: error("%nMF",this); } case 0: can_overload = in_class_dcl; break; case CTOR: if (f->f_virtual) { error("virtual constructor"); f->f_virtual = 0; } case DTOR: if (fct_void) n_scope = PUBLIC; can_overload = in_class_dcl; break; case TYPE: can_overload = 0; break; case ASSIGN://error('d',"assign %n",class_name); if (class_name && f->nargs==1) { Ptype t = f->argtype->tp; Pname an = t->is_cl_obj(); // X::operator=(X) ? if (an==0 && t->is_ref()) { // X::operator=(X&) ? t = Pptr(t)->typ; rx1: switch (t->base) { case TYPE: t = Pbase(t)->b_name->tp; goto rx1; case COBJ: an = Pbase(t)->b_name; } } if (an && an==class_name) Pclass(an->tp)->bit_ass = 0;//error('d',"%n ==> %d",an,Pclass(class_name)->bit_ass); } else if (f->nargs == 2) { Ptype t = f->argtype->tp; Pname an1; if (t->is_ref()) { // operator=(X&,?) ? t = Pptr(t)->typ; rx2: switch (t->base) { case TYPE: t = Pbase(t)->b_name->tp; goto rx2; case COBJ: an1 = Pbase(t)->b_name; } } t = f->argtype->n_list->tp; Pname an2 = t->is_cl_obj(); // operator=(X&,X) ? if (an2==0 && t->is_ref()) { // operator=(X&,X&) ? t = Pptr(t)->typ; rx3: switch (t->base) { case TYPE: t = Pbase(t)->b_name->tp; goto rx3; case COBJ: an2 = Pbase(t)->b_name; } } if (an1 && an1==an2) Pclass(an1->tp)->bit_ass = 0; } default: can_overload = 1; /* all operators are overloaded */ } switch (scope) { case FCT: case ARG: { Pname nx = gtbl->insert(this,0); n_table = 0; n_tbl_list = 0; if (Nold && tp->check(nx->tp,0)) error('w',"%n has been declared both as%t and as%t",this,nx->tp,tp); /* no break */ } default: nn = etbl->insert(this,0); nn->assign(); n_table = etbl; break; } if (Nold) { Pfct nf = (Pfct)nn->tp;/*error('d',"%n: tp%t nf%t",nn,tp,nf);*/ if (nf->base==ANY || f->base==ANY) ; else if (nf->base == OVERLOAD) { Pgen g = (Pgen) nf; nn = g->add(this,0); string = nn->string; if (Nold == 0) { if (f->body) { if (n_qualifier) { error(0,"badAL for overloaded %n::%s()",n_qualifier,g->string); Cdcl = odcl; return 0; } // else if (f->f_inline==0 && n_oper==0) // error('w',"overloaded %n defined without being previously declared",nn); } goto thth; } else { if (f->body==0 && friend_in_class==0) error('w',"overloaded%n redeclared",nn); } nf = (Pfct)nn->tp; if (f->body && nf->body) { error("two definitions of overloaded%n",nn); Cdcl = odcl; return 0; } if (f->body) goto bdbd; goto stst; } else if (nf->base != FCT) { error("%n declared both as%t and asF",this,nf); f->body = 0; } else if (can_overload) { if (nf->check(f,OVERLOAD) || vrp_equiv) { if (f->body && n_qualifier) { error("badAT for%n",nn); Cdcl = odcl; return 0; } Pgen g = new gen(string); Pname n1 = g->add(nn,in_class_dcl); Pname n2 = g->add(this,0);/*error('d',"n1%n n2%n\n",n1,n2);*/ nn->tp = (Ptype)g; nn->string = g->string; nn = n2; goto thth; } if (in_class_dcl) { error("two declarations of%n",this); f->body = 0; Cdcl = odcl; return 0; } if (nf->body && f->body) { error("two definitions of%n",this); f->body = 0; Cdcl = odcl; return 0; } if (f->body) goto bdbd; goto stst; } else if (nf->check(f,0)) { switch (n_oper) { case CTOR: case DTOR: f->s_returns = nf->s_returns; } error("%nT mismatch:%t and%t",this,nf,f); f->body = 0; } else if (nf->body && f->body) { error("two definitions of%n",this); f->body = 0; } else if (f->body) { Pname a1, a2; bdbd: if (f->nargs_known && nf->nargs_known) for (a1=f->argtype, a2=nf->argtype; a1; a1=a1->n_list, a2=a2->n_list) { int i1 = a1->n_initializer || a1->n_evaluated; int i2 = a2->n_initializer || a2->n_evaluated;//error('d',"bdbd: i %d %d eval %d %d val %d %d",i1,i2,a1->n_evaluated,a2->n_evaluated,a1->n_val,a2->n_val); if (i1) { if (i2 && ( a1->n_evaluated==0 || a2->n_evaluated==0 || a1->n_val!=a2->n_val) ) error("twoIrs for%nA%n",nn,a1); } else if (i2) { a1->n_initializer = a2->n_initializer; a1->n_evaluated = a2->n_evaluated; a1->n_val = a2->n_val; } } f->f_virtual = nf->f_virtual; f->f_this = nf->f_this;/*fprintf(stderr,"bdbd %s: f %d inl %d nf %d inl %d\n",string,f,f->f_inline,nf,nf->f_inline);*/ nn->tp = f; if (f->f_inline) { if (nf->f_inline==0 && nn->n_used) error("%n called before defined as inline",nn); nf->f_inline = 1; nn->n_sto = STATIC; } else if (nf->f_inline) { /*error("%n defined as inline but not declared as inline",this);*/ f->f_inline = 1; } goto stst2; } else { /* two declarations */ Pname a1, a2; f->f_this = nf->f_this; stst: if (f->nargs_known && nf->nargs_known) for (a1=f->argtype, a2=nf->argtype; a1; a1=a1->n_list, a2=a2->n_list) { int i1 = a1->n_initializer || a1->n_evaluated; int i2 = a2->n_initializer || a2->n_evaluated;//error('d',"stst %d %d",i1,i2); if (i1) { if (i2) { if (a1->n_evaluated==0 || a2->n_evaluated==0 || a1->n_val!=a2->n_val) error("twoIrs for%nA%n",nn,a1); } else if (class_name) error("defaultA for%n",nn); } else if (i2) { a1->n_initializer = a2->n_initializer; a1->n_evaluated = a2->n_evaluated; a1->n_val = a2->n_val; } } stst2: if (f->f_inline) n_sto = STATIC; if (n_sto && nn->n_scope!=n_sto && friend_in_class==0 && f->f_inline==0){ // allow re-def to "static"if (n_sto == STATIC) nn->n_sto = STATIC; else error("%n both%k and%k",this,n_sto,nn->n_scope); } n_scope = nn->n_scope; // first specifier wins n_sto = nn->n_sto; } /* Pfct(nn->tp)->nargs_known = nf->nargs_known; */ } else { /* new function: make f_this for member functions */ if (tbl==gtbl && n_oper) { // overload operator Pgen g = new gen(string); Pname n1 = g->add(nn,1);//error('d',"overload %n -> %s",this,n1->string); nn->tp = Ptype(g); nn->string = g->string; string = n1->string; nn = n1; } thth: just_made = 1; if (f->f_inline) nn->n_sto = STATIC; else if (class_name==0 && n_sto==0 && f->body==0) // ``explicitly'' extern nn->n_sto = EXTERN;/*fprintf(stderr,"thth %s: f %d nn->tp %d inl %d\n",string,f,nn->tp,f->f_inline);*/ if (class_name && etbl!=gtbl) { /* beware of implicit declatation */ Pname cn = nn->n_table->t_name; Pname tt = new name("this"); tt->n_scope = ARG; tt->n_sto = REGISTER; tt->tp = Pclass(class_name->tp)->this_type; PERM(tt); Pfct(nn->tp)->f_this = f->f_this = tt; tt->n_list = f->argtype; } if (f->f_virtual) { switch (nn->n_scope) { default: error("nonC virtual%n",this); break; case 0: case PUBLIC: cc->cot->virt_count = 1; Pfct(nn->tp)->f_virtual = 1; break; } } } /* an operator must take at least one class object or reference to class object argument */ switch (n_oper) { case CTOR: if (f->nargs == 1) { /* check for X(X) and X(X&) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -