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

📄 simpl.c

📁 CFront1.0的源代码,第一代C++编译器的思想...
💻 C
📖 第 1 页 / 共 3 页
字号:
/* @(#) simpl.c 1.7 1/27/86 17:49:27 */ /*ident	"@(#)cfront:src/simpl.c	1.7" *//*******************************************************************	C++ source for cfront, the C++ compiler front-end	written in the computer science research center of Bell Labs	Copyright (c) 1984 AT&T, Inc. All Rights Reserved	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T, INC.simpl.c:	simplify the typechecked function	remove:		classes:				class fct-calls				operators				value constructors and destructors			new and delete operators (replace with function calls)			initializers		(turn them into statements)			constant expressions		(evaluate them)			inline functions		(expand the calls)			enums				(make const ints)			unreachable code		(delete it)	make implicit coersions explicit	in general you cannot simplify something twice*******************************************************************/#include "cfront.h"#include "size.h"#include <ctype.h>Pname new_fct;Pname del_fct;Pname vec_new_fct;Pname vec_del_fct;Pstmt del_list;Pstmt block_del_list;Pname ret_var;bit not_inl;	// is the current function an inline?Pname curr_fct;	// current functionPexpr init_list;Pexpr one;void simpl_init(){	Pname nw = new name(oper_name(NEW));	Pname dl = new name(oper_name(DELETE));	Pname vn = new name("_vec_new");	Pname vd = new name("_vec_delete");	new_fct = gtbl->insert(nw,0);	/* void* operator new(long); */	delete nw;	Pname a = new name;	a->tp = long_type;	new_fct->tp = new fct(Pvoid_type,a,1);	new_fct->n_scope = EXTERN;	PERM(new_fct);	PERM(new_fct->tp);	new_fct->use();	new_fct->dcl_print(0);	del_fct = gtbl->insert(dl,0);	/* void operator delete(void*); */	delete dl;	a = new name;	a->tp = Pvoid_type;	del_fct->tp = new fct(void_type,a,1);	del_fct->n_scope = EXTERN;	PERM(del_fct);	PERM(del_fct->tp);	del_fct->use();	del_fct->dcl_print(0);	a = new name;	a->tp = Pvoid_type;	Pname al = a;	a = new name;	a->tp = int_type;	a->n_list = al;	al = a;	a = new name;	a->tp = int_type;	a->n_list = al;	al = a;	a = new name;		a->tp = Pvoid_type;	a->n_list = al;	al = a;				/* (Pvoid, int, int, Pvoid) */	vec_new_fct = gtbl->insert(vn,0);	delete vn;	vec_new_fct->tp = new fct(Pvoid_type,al,1);	vec_new_fct->n_scope = EXTERN;	PERM(vec_new_fct);	PERM(vec_new_fct->tp);	vec_new_fct->use();	vec_new_fct->dcl_print(0);	a = new name;	a->tp = int_type;	al = a;	a = new name;	a->tp = Pvoid_type;	a->n_list = al;	al = a;	a = new name;	a->tp = int_type;	a->n_list = al;	al = a;	a = new name;	a->tp = int_type;	a->n_list = al;	al = a;	a = new name;		a->tp = Pvoid_type;	a->n_list = al;	al = a;				/* (Pvoid, int, int, Pvoid, int) */	vec_del_fct = gtbl->insert(vd,0);	delete vd;	vec_del_fct->tp = new fct(void_type,al,1);	vec_del_fct->n_scope = EXTERN;	PERM(vec_del_fct);	PERM(vec_del_fct->tp);	vec_del_fct->use();	vec_del_fct->dcl_print(0);	one = new expr(IVAL,(Pexpr)1,0);	one->tp = int_type;	PERM(one);}Ptable scope;		/* current scope for simpl() */Pname expand_fn;	/* name of function being expanded or 0 */Ptable expand_tbl;	/* scope for inline function variables */Pname classdef.has_oper(TOK op){	char* s = oper_name(op);	Pname n;	if (this == 0) error('i',"0->has_oper(%s)",s);	n = memtbl->lookc(s,0);	if (n == 0) return 0;	switch (n->n_scope) {	case 0:	case PUBLIC:	return n;	default:	return 0;	}}int no_of_returns;void name.simpl(){	if (base == PUBLIC) return;	if (tp == 0) error('i',"%n->name.simple(tp==0)",this);	switch (tp->base) {	case 0:		error('i',"%n->name.simpl(tp->base==0)",this);	case OVERLOAD:	{	Plist gl;		for (gl = Pgen(tp)->fct_list; gl; gl=gl->l) gl->f->simpl();		break;	}	case FCT:	{	Pfct f = (Pfct)tp;		Pname n;		Pname th = f->f_this;//error('d',"simpl%n tp=%t def=%d th=%d n_oper%k",this,tp,tp->defined,th,n_oper);		if (th) {			th->n_list = f->argtype;			if (n_oper == CTOR) f->s_returns = th->tp;		}		if (tp->defined & (SIMPLIFIED | ~DEFINED) ) return;	//	tp->defined |= SIMPLIFIED;		for (n=(th)?th:f->argtype; n; n=n->n_list) n->simpl();		if (f->body) {			Ptable oscope = scope;			scope = f->body->memtbl;			if (scope == 0) error('i',"%n memtbl missing",this);			curr_fct = this;			f->simpl();			if (f->f_inline && debug==0) {				if (MIA<=f->nargs) {					error('w',"too many arguments for inline%n (inline ignored)",this);					f->f_inline = 0;					scope = oscope;					break;				}				int i = 0;				for (n=(th)?th:f->argtype; n; n=n->n_list) {					n->base = ANAME;					n->n_val = i++;					if (n->n_table != scope) error('i',"%s %d %d\n",n->string,n->n_table,scope);				}				expand_tbl = (f->returns->base!=VOID || n_oper==CTOR) ? scope : 0;				expand_fn = this;				if (expand_tbl) {					// value returning: generate expression					Pexpr ee = (Pexpr)f->body->expand();					/* the body still holds the memtbl */					f->f_expr = (ee->base==CM) ? ee : new expr(CM,zero,ee);					/* print.c assumes expansion into comma expression */				}				else {	// not value return: can generate block					f->f_expr = 0;					f->body = (Pblock)f->body->expand();				}				expand_fn = 0;				expand_tbl = 0;			}			scope = oscope;		}		break;	}	case CLASS:		Pclass(tp)->simpl();		break;/*	case EOBJ:		tp->base = INT;		break;*/	default://error('d',"%n tp %t n_init %d",this,tp, n_initializer);		break;	}	if (n_initializer) n_initializer->simpl();	tp->defined |= SIMPLIFIED;}void fct.simpl()/*	call only for the function definition (body != 0)	simplify argument initializers, and base class initializer, if any	then simplify the body, if any	for constructor:call allocator if this==0 and this not assigned to			(auto and static objects call constructor with this!=0,			the new operator generates calls with this==0)			call base & member constructors	for destructor:	call deallocator (no effect if this==0)			case base & member destructors	for arguments  and function return values look for class objects	that must be passed by constructor "operator X(X&)".	Allocate temporaries for class object expressions, and see if	class object return values can be passed as pointers.	call constructor and destructor for local class variables.*/{	Pexpr th = f_this;	Ptable tbl = body->memtbl;	Pstmt ss = 0;	Pstmt tail;	Pname cln; 	Pclass cl;	Pstmt dtail = 0;	not_inl = debug || f_inline==0;	ret_var = tbl->look("_result",0);	if (ret_var && not_inl==0) /* "_result" not used in inlines */		ret_var->n_used = ret_var->n_assigned_to = ret_var->n_addr_taken = 0;	del_list = 0;	block_del_list = 0;	scope = tbl;	if (scope == 0) error('i',"fct.simpl()");	if (th) {		Pptr p = (Pptr)th->tp;		cln = Pbase(p->typ)->b_name;		cl = (Pclass)cln->tp;	}	if (curr_fct->n_oper == DTOR) {		/* initialize del_list */		Pexpr ee;		Pstmt es;		class ifstmt * ifs;		Pname bcln = cl->clbase;		Pclass bcl;		Pname d;		Pname fa = new name("_free");	/* fake argument for dtor */		fa->tp = int_type;		Pname free_arg = fa->dcl(body->memtbl,ARG);		delete fa;		f_this->n_list = free_arg;		Ptable tbl = cl->memtbl;		int i;		Pname m;		/* generate calls to destructors for all members of class cl */		for (m=tbl->get_mem(i=1); m; m=tbl->get_mem(++i) ) {			Ptype t = m->tp;			Pname cn;			Pclass cl;			Pname dtor;			if (m->n_stclass == STATIC) continue;			if (cn = t->is_cl_obj()) {				cl = (Pclass)cn->tp;				if (dtor = cl->has_dtor()) {					/*	dtor(this,0);	*/					Pexpr aa = new expr(ELIST,zero,0);					ee = new ref(REF,th,m);					ee = new ref(DOT,ee,dtor);					ee = new call(ee,aa);					ee->fct_name = dtor;					ee->base = G_CALL;					es = new estmt(SM,curloc,ee,0);					if (dtail)						dtail->s_list = es;					else						del_list = es;					dtail = es;					}			}			else if (cl_obj_vec) {				cl = Pclass(cl_obj_vec->tp);				if (dtor = cl->has_dtor()) {					int esz = cl->tsizeof();					Pexpr noe = new expr(IVAL,Pexpr(t->tsizeof()/esz),0);					Pexpr sz = new expr(IVAL,(Pexpr)esz,0);					Pexpr mm = new ref(REF,th,m);					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,mm,arg);					ee = new call(vec_del_fct,arg);					ee->base = G_CALL;								es = new estmt(SM,curloc,ee,0);					if (dtail)						dtail->s_list = es;					else						del_list = es;					dtail = es;				}			}		}		// delete base		if (bcln		&& (bcl=(Pclass)bcln->tp)		&& (d=bcl->has_dtor()) ) {	// base.dtor(this,_free);			Pexpr aa = new expr(ELIST,free_arg,0);			ee = new ref(REF,th,d);			ee = new call(ee,aa);			/*ee->fct_name = d; NO would suppress virtual */			ee->base = G_CALL;			es = new estmt(SM,curloc,ee,0);		}		else {				// if (_free) _delete(this);			Pexpr aa  = new expr(ELIST,th,0);			ee = new call(del_fct,aa);			ee->fct_name = del_fct;			ee->base = G_CALL;			es = new estmt(SM,curloc,ee,0);			es = new ifstmt(curloc,free_arg,es,0);		}		free_arg->use();		Pname(th)->use();		if (dtail)			dtail->s_list = es;		else			del_list = es;		ifs = new ifstmt(curloc,th,del_list,0);/*		ifs = new ifstmt(curloc,cc,es,0);		if (dtail)			dtail->s_list = ifs;		else			del_list = ifs;		dtail = ifs;*/		del_list = ifs;		if (del_list) del_list->simpl();	}int ass_count;	if (curr_fct->n_oper == CTOR) {		Pexpr ee;		Ptable tbl = cl->memtbl;		Pname m;		int i;		/*			generate: this=base::base(args)			this->b_init == base::base(args) or 0		*/		if (b_init) {//error('d',"b_init %k",b_init->base);			switch (b_init->base) {			case ASSIGN:			case CM:				break;			default:			{	Pcall cc = (Pcall)b_init;				Pname bn = cc->fct_name;				Pname tt = Pfct(bn->tp)->f_this;				ass_count = tt->n_assigned_to;				cc->simpl();				init_list = new expr(ASSIGN,th,cc);			}			}		}		else {			ass_count = 0;			init_list = 0;		}		if (cl->virt_count) {	/* generate: this->_vptr=virt_init; */			Pname vp = cl->memtbl->look("_vptr",0);			Pexpr vtbl = new text_expr(cl->string,"_vtbl");			ee = new ref(REF,th,vp);			ee = new expr(ASSIGN,ee,vtbl);			init_list =  (init_list) ? new expr(CM,init_list,ee) : ee;		}for (Pname nn = f_init; nn; nn=nn->n_list) {	if (nn->n_initializer == 0) continue;	Pname m = tbl->look(nn->string, 0);	if (m && m->n_table == tbl) m->n_initializer = nn->n_initializer;}		/* generate cl.new(args) for all members of cl */		for (m=tbl->get_mem(i=1); m; m=tbl->get_mem(++i) ) {			Ptype t = m->tp;			Pname cn;			Pclass cl;			Pname ctor;			switch (m->n_stclass) {			case STATIC:			case ENUM:				continue;			}			switch (t->base) {			case FCT:			case OVERLOAD:			case CLASS:			case ENUM:				continue;			}			if (m->base == PUBLIC) continue;			if (cn=t->is_cl_obj()) {		 		Pexpr ee = m->n_initializer;				m->n_initializer = 0;	// from fct must not persist until next fct				if (ee == 0) {		// try default					cl = (Pclass)cn->tp;					if (ctor = cl->has_ictor()) {						ee = new ref(REF,th,m);						ee = new ref(DOT,ee,ctor);						ee = new call(ee,0);						ee->fct_name = ctor;						ee->base = G_CALL;						ee = ee->typ(tbl);	// look for default arguments					} else if (cl->has_ctor()) {					   error("M%n needsIr (no default constructor forC %s)",m,cl->string);					}				}				if (ee) {					ee->simpl();					if (init_list)						init_list = new expr(CM,init_list,ee);					else						init_list = ee;				} 			}			else if (cl_obj_vec) {				cl = (Pclass)cl_obj_vec->tp;				if (ctor = cl->has_ictor()) {	/*  _new_vec(vec,noe,sz,ctor); */					int esz = cl->tsizeof();					Pexpr noe = new expr(IVAL,(Pexpr)(t->tsizeof()/esz),0);					Pexpr sz = new expr(IVAL,(Pexpr)esz,0);					Pexpr mm = new ref(REF,th,m);					Pexpr arg = new expr(ELIST,ctor,0);					/*ctor->take_addr();*/					ctor->lval(ADDROF);					arg = new expr(ELIST,sz,arg);					arg = new expr(ELIST,noe,arg);					arg = new expr(ELIST,mm,arg);					ee = new call(vec_new_fct,arg);					ee->fct_name = vec_new_fct;					ee->base = G_CALL;				/*	ee = ee->typ(tbl);	 look for default arguments */					ee->simpl();					if (init_list)						init_list = new expr(CM,								init_list,ee);					else						init_list = ee;				}				else if (cl->has_ctor()) {					error("M%n[] needsIr (no default constructor forC %s)",m,cl->string);				}			}			else if (m->n_initializer) {				// init of non-class mem				// set in fct.mem_init()				if (init_list)					init_list = new expr(CM,init_list,m->n_initializer);				else					init_list = m->n_initializer;				m->n_initializer = 0;	// from fct must not persist until next fct			}			else if (t->is_ref()) {				error("referenceM%n needsIr",m);			}			else if (t->tconst() && vec_const==0) {				error("constM%n needsIr",m);			}		} // for m	}	no_of_returns = 0;	tail = body->simpl();	if (body->s == 0) body->empty = 1;	// null function	if (returns->base != VOID) {	/* return must have been seen */		if (no_of_returns) {			switch (tail->base) {			case SM:				switch (tail->e->base) {				case ICALL:				case G_CALL:		/* not good enough */					goto dontknow;				};			default:/*fprintf(stderr,"t %d %d\n",tail->base,tail->e->base);*/				if (strcmp(curr_fct->string,"main"))						error('w',"maybe no value returned from%n",curr_fct);				if (del_list) goto zaq;				break;			case RETURN:			case IF:			case SWITCH:			case DO:			case FOR:			case LABEL:			case BLOCK:			case PAIR:

⌨️ 快捷键说明

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