⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcl.c

📁 CFront1.0的源代码,第一代C++编译器的思想...
💻 C
📖 第 1 页 / 共 4 页
字号:
		}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 + -