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

📄 simpl.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
		e1->simpl();		if (e1->base == CM) {	/* &( , name). => ( ... , &name)-> */			Pexpr ex = e1;			cfr:			switch (ex->e2->base) {			case NAME:				base = REF;				ex->e2 = ex->e2->address();				break;			case CM:				ex = ex->e2;				goto cfr;			}		}		break;	case ASSIGN:	{	Pfct f = (Pfct)curr_fct->tp;		Pexpr th = f->f_this;		if (e1) e1->simpl();		if (e2) e2->simpl();		if (th && th==e1) {			if (curr_fct->n_oper == CTOR) {				if (init_list) {					/* this=e2 => (this=e2,init_list) */					base = CM;					e1 = new expr(ASSIGN,e1,e2);					e2 = init_list;				}			}		}		break;	}	}		if (tp && tp->base==INT) {		Neval = 0;		int i = eval();		if (Neval == 0) {			base = IVAL;			e1 = (Pexpr)i;		}	}}void call.simpl()/*	fix member function calls:		p->f(x) becomes f(p,x)		o.f(x)  becomes f(&o,x)	or if f is virtual:		p->f(x) becomes ( *p->_vptr[ type_of(p).index(f)-1 ] )(p,x)	replace calls to inline functions by the expanded code*/{	Pname fn = fct_name;	Pfct f = (fn) ? (Pfct)fn->tp : 0;	if (fn == 0) e1->simpl();	if (f) {		switch(f->base) {		case ANY:			return;		case FCT:			break;		case OVERLOAD:		{	Pgen g = (Pgen)f;			fct_name = fn = g->fct_list->f;			f = (Pfct)fn->tp;		}		}	}	if (f && curr_expr==this) {	/* check for class object returning fct */		Pname cln = f->returns->is_cl_obj();		if (cln && Pclass(cln->tp)->has_dtor()) error('s',"%n returned by%n is not used (%n has destructor)",cln,fn,cln);	}//error('d',"simpl call%n e1: %d%k",fn,e1,e1->base);	switch (e1->base) {	case DOT:	case REF:	{	Pref r = (Pref)e1;		Pexpr a1 = r->e1;//error('d',"simpl fn %s f %d fv %d",fn?fn->string:"?",f,f?f->f_virtual:0);		if (f && f->f_virtual) {			Pexpr a11 = 0;			switch(a1->base) {	// see if temporary might be needed			case NAME:				a11 = a1;				break;			case ADDROF:			case G_ADDROF:				if (a1->e2->base == NAME) a11 = a1;				break;			}			if (e1->base == DOT) {				if (a11) a11 = a11->address();				a1 = a1->address();			}						if (a11 == 0) {				/* temporary (maybe) needed				   e->f() => (t=e,t->f(t))				*/				char* s = make_name('K');				Pname n = new name(s);				n->tp = a1->tp;				n = n->dcl(scope,ARG); /* no init! */				n->n_scope = FCT;				n->assign();				a11 = n;				a1 = new expr(ASSIGN,n,a1);				a1->tp = n->tp;				a1->simpl();				Pcall cc = new call(0,0);				*cc = *this;				base = CM;				e1 = a1;				e2 = cc;				this = cc;			}			e2 = new expr(ELIST,a11,e2);			int index = f->f_virtual;			Pexpr ie = (1<index) ? new expr(IVAL,(Pexpr)(index-1),0) : 0;			Pname vp = fn->n_table->look("_vptr",0);			Pexpr vptr = new ref(REF,a11,vp);	/* p->vptr */			Pexpr ee = new expr(DEREF,vptr,ie);	/* p->vptr[i] */			Ptype pft = new ptr(PTR,f);			ee = new texpr(CAST,pft,ee);		/* (T)p->vptr[i] */			ee->tp = (Ptype)f->f_this;		/* encode argtype */			e1 = new expr(DEREF,ee,0);		/* *(T)p->vptr[i] */								/* e1->tp must be 0, means "argtype encoded" */			fct_name = 0;			fn = 0;			e2->simpl();			return;				/* (*(T)p->vptr[i])(e2) */		}		else {//error('d',"a1 %k%k%n",a1->base,e1->base,r->mem);			if (e1->base == DOT) a1 = a1->address();			e2 = new expr(ELIST,a1,e2);			e1 = r->mem;		}	}	}//error('d',"ex1 %d %d %d",fn,f->f_inline,debug);	e2->simpl();//error('d',"ex2 %d %d %d",fn,f->f_inline,debug);	if (e1->base==NAME && e1->tp->base==FCT) {		/* reconstitute fn destroyed to suppress "virtual" */		fct_name = fn = (Pname)e1;		f = (Pfct)fn->tp;	}//error('d',"ex3 %d %d %d",fn,f->f_inline,debug);	if (fn && f->f_inline && debug==0) {//error('d',"expand%n",fn);		Pexpr ee = f->expand(fn,scope,e2);//error('d',"expanded %d %d",fn,ee);		if (ee) *Pexpr(this) = *ee;	}}Pexpr curr_expr;	/* to protect against an inline being expanded twice			   in a simple expression keep track of expressions			   being simplified			*/Pstmt stmt.simpl()/*	return a pointer to the last statement in the list, or 0*/{	if (this == 0) error('i',"0->stmt.simpl()");/*error('d',"stmt.simpl %d%k e %d%k s %d%k sl %d%k\n",this,base,e,e?e->base:0,s,s?s->base:0,s_list,s_list?s_list->base:0); fflush(stderr);*/	curr_expr = e;	switch (base) {	default:		error('i',"stmt.simpl(%k)",base);	case ASM:		break;	case BREAK:	case CONTINUE:		if (block_del_list) {		/*	break		=>	{ _dtor()s; break; }			continue	=>	{ _dtor()s; continue; }		*/			Pstmt bs = new stmt(base,where,0);			Pstmt dl = block_del_list->copy();			base = BLOCK;			s = new pair(where,dl,bs);			break;		}		break;	case DEFAULT:		s->simpl();		break;	case SM:		if (e) e->simpl();		break;	case RETURN:	{	/*	return x;	=>				{ _ret_var = x; _dtor()s;  return _ret_var; }			return ctor(x);	=>				{ ctor(&_result,x); _dtor()s;  return _ret_var; }			return;		=>				{ _dtor()s; return; } OR (in constructors)				{ _dtor()s; return _this; }		*/		no_of_returns++;		if (not_inl) {			Pstmt as;			if (e && e!=dummy) {				Pexpr ee;				if (e->base==G_CALL				&& e->fct_name				&& e->fct_name->n_oper==CTOR				&& e->e1->base==DOT ) {					Pref r = (Pref)e->e1;					r->e1 = ret_var;					ee = e;				}				else {					ee = new expr(ASSIGN,ret_var,e);				}				ee->simpl();				as = new estmt(SM,where,ee,0);			}			else				as = 0;			base = BLOCK;			s = 0;			d = 0;			own_tbl = (memtbl) ? 1 : 0;			Pblock(this)->simpl();			Pstmt dl = (del_list) ? del_list->copy() : 0;			if (s) dl = (dl) ? new pair(where,s,dl) : s;							Pstmt rs = new estmt(RETURN,where,(ret_var)?(Pexpr)ret_var:0,0);			if (as) {				if (dl) as = new pair(where,as,dl);				s = new pair(where,as,rs);			}			else {				if (curr_fct->n_oper == CTOR) {					rs->e = Pfct(curr_fct->tp)->f_this;				}				s = (dl) ? new pair(where,dl,rs) : rs;			}		}		else {			if (e->base == VALUE) error('s',"inlineF returns constructor");			e->simpl();		}		break;	}	case WHILE:	case DO:		e->simpl();		s->simpl();		break;	case SWITCH:		e->simpl();		s->simpl();		switch (s->base) {		case DEFAULT:		case LABEL:		case CASE:			break;		case BLOCK:			if (s->s)			switch (s->s->base) {			case BREAK:	/* to cope with the "break; case" macro */			case CASE:			case LABEL:			case DEFAULT:				break;			default:				goto df;			}			break;		default:		df:			error('w',&s->where,"statement not reached: case label missing");		}		break;	case CASE:		e->simpl();		s->simpl();		break;	case LABEL:		if (del_list) error('s',"label in block with destructors");		s->simpl();		break;	case GOTO:		/* If the goto is going to a different (effective) scope,		 * then it is necessary to activate all relevant destructors		 * on the way out of nested scopes, and issue errors if there		 * are any constructors on the way into the target. */		/* Only bother if the goto and label have different effective		 * scopes. (If mem table of goto == mem table of label, then		 * they're in the same scope for all practical purposes. */		{		Pname n = scope->look( d->string, LABEL );		if (n == 0) error('i',&where,"label%n missing",d);		if( n->n_realscope != scope ) {			/* Find the root of the smallest subtree containing			 * the path of the goto.  This algorithm is quadratic			 * only if the goto is to an inner or unrelated scope. */			Ptable r = 0;			for(Ptable q=n->n_realscope; q!=gtbl; q=q->next) {				for( Ptable p = scope; p != gtbl; p = p->next ) {					if( p==q ) {						r = p; /* found root of subtree! */						goto xyzzy;					}				}			}xyzzy:			if( r==0 ) error( 'i',&where,"finding root of subtree" );			/* At this point, r = root of subtree, n->n_realscope			 * = mem table of label, and scope = mem table of goto. */			/* Climb the tree from the label mem table to the table			 * preceding the root of the subtree, looking for			 * initializers and ctors.  If the mem table "belongs"			 * to an unsimplified block(s), the n_initializer field			 * indicates presence of initializer, otherwise initializer			 * information is recorded in the init_stat field of			 * mem table. */			for( Ptable p=n->n_realscope; p!=r; p=p->next )				if( p->init_stat == 2 ) {					error(&where,"goto%n pastD withIr",d);					goto plugh; /* avoid multiple error msgs */				}				else if( p->init_stat == 0 ) {					int i;					for(Pname nn=p->get_mem(i=1);nn;nn=p->get_mem(++i))						if(nn->n_initializer||nn->n_evaluated){							error(&nn->where,"goto%n pastId%n",d,nn);							goto plugh;						}				}plugh:			/* Proceed in a similar manner from the point of the goto,			 * generating the code to activate dtors before the goto. */			/* There is a bug in this code.  If there are class objects			 * of the same name and type in (of course) different mem			 * tables on the path to the root of the subtree from the			 * goto, then the innermost object's dtor will be activated			 * more than once. */			{			Pstmt dd = 0, ddt;			for( Ptable p=scope; p!=r; p=p->next ) {				int i;				for(Pname n=p->get_mem(i=1);n;n=p->get_mem(++i)) {		Pname cln;		if (n->tp == 0) continue; /* label */		if ( cln=n->tp->is_cl_obj() ) {			Pclass cl = (Pclass)cln->tp;			Pname d = cl->has_dtor();			if (d) {	/* n->cl.delete(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;			}		}		else if (cl_obj_vec) {	/* never "new x" is a pointer */			Pclass cl = (Pclass)cl_obj_vec->tp;			Pname c = cl->has_ictor();			Pname d = cl->has_dtor();			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);				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;			}		}				} /* end mem table scan */			} /* end dtor loop */			/* "activate" the list of dtors obtained. */			if( dd ) {				dd->simpl();				Pstmt bs = new stmt( base, where, 0 );				*bs = *this;				base = PAIR;				s = dd;				s2 = bs;			}			}		} /* end special case for non-local goto */		}		break;	case IF:		e->simpl();		s->simpl();		if (else_stmt) else_stmt->simpl();		break;	case FOR:		/* "for (s;e;e2) s2; => s; while(e) {s2;e3}" */		if (for_init) {			for_init->simpl();			if (for_init->base==SM && for_init->e->tp==void_type)				error('s',"call of inline voidF in for-expression");		}		if (e) e->simpl();		if (e2) {			curr_expr = e2;			e2->simpl(); 			if (e2->base==ICALL && e2->tp==void_type)				error('s',"call of inline voidF in for-expression");		}		s->simpl();		break;	case BLOCK:		Pblock(this)->simpl();		break;	case PAIR:		break;	}	/*if (s) s->simpl();*/	if (base!=BLOCK && memtbl) {		int i;		Pstmt t1 = (s_list) ? s_list->simpl() : 0;		Pstmt ss = 0;		Pname cln;		for (Pname tn = memtbl->get_mem(i=1); tn; tn=memtbl->get_mem(++i)) {/*fprintf(stderr,"tmp %s tbl %d\n",tn->string,memtbl);*/			if ( cln=tn->tp->is_cl_obj() ) {				Pclass cl = (Pclass)cln->tp;				Pname d = cl->has_dtor();				if (d) {	/* n->cl.delete(0); */					Pref r = new ref(DOT,tn,d);					Pexpr ee = new expr(ELIST,zero,0);					Pcall dl = new call(r,ee);					Pstmt dls = new estmt(SM,tn->where,dl,0);					dl->base = G_CALL;					dl->fct_name = d;					dls->s_list = ss;					ss = dls;/*error('d',"%d (tbl=%d): %n.%n %d->%d",this,memtbl,tn,d,ss,ss->s_list);*/ 				}			}		}		if (ss) {			Pstmt t2 = ss->simpl();			switch (base) {			case IF:				Pstmt es = ss->copy();				if (else_stmt) {					for (Pstmt t=es; t->s_list; t=t->s_list);					t->s_list = else_stmt;				}				else_stmt = es;				t2->s_list = s;				s = ss;				break;			case RETURN:			case WHILE:			case FOR:			case DO:			case SWITCH:				error('s',"E in%kS needs temporary ofC%n with destructor",base,cln);				break;			default:				if (t1) {					t2->s_list = s_list;					s_list = ss;					return t1;				}				s_list = ss;				return t2;			}		}		return (t1) ? t1 : this;	}	return (s_list) ? s_list->simpl() : this;}Pstmt stmt.copy()// now handles dtors in the expression of an IF stmt// not general!{	Pstmt ns = new stmt(0,curloc,0);	*ns = *this;	if (s) ns->s = s->copy();	if (s_list) ns->s_list = s_list->copy();	switch (base) {	case PAIR:		ns->s2 = s2->copy();		break;	}	return ns;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -