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

📄 dcl2.c

📁 c 语言编译器 源代码- c compiler
💻 C
📖 第 1 页 / 共 3 页
字号:
				Pname ctor = cl->has_ctor();				Pname dtor = cl->has_dtor();				if (ctor) {					if (m->n_stclass==STATIC) {						error('s',"staticM%n ofC%n with constructor",m,cn);						statc = m;					}					else if (un)						error("M%n ofC%n with constructor in union",m,cn);					else if (ct) {						if (statc) error('s',"staticM%n ofC%t with constructor",statc,statc->tp);						make_ctor = 1;						ct = 0;					}				}				if (dtor) {					if (m->n_stclass==STATIC) {						error('s',"staticM%n ofC%n with destructor",m,cn);						statd = m;					}					else if (un)						error("M%n ofC%n with destructor in union",m,cn);					else if (dt) {						if (statd) error('s',"staticM%n ofC%t with constructor",statd,statd->tp);						make_dtor = 1;						dt = 0;					}				}			}		}	}}	if (make_ctor) {		Pname ct = has_ctor();		if (ct==0 || ct->n_table!=memtbl) {			// make a constructor for the class: x::x() {}			// a base class's constructor is not good enough			if (ct && has_ictor()==0) error("%k %s needs a constructor",csu,string);			Pname n = new name(string);			Pfct f = new fct(defa_type,0,1);			n->tp = f;			n->n_oper = TNAME;			Pname m = n->dcl(memtbl,PUBLIC);			Pfct(m->tp)->body = new block(curloc,0,0);		}	}	if (make_dtor && has_dtor()==0) {		// make a destructor for the class: x::x() {}		Pname n = new name(string);		Pfct f = new fct(defa_type,0,1);		n->tp = f;		n->n_oper = DTOR;		Pname m = n->dcl(memtbl,PUBLIC);		Pfct(m->tp)->body = new block(curloc,0,0);	}	defined |= DEFINED;	for (p=memtbl->get_mem(i=1); p; p=memtbl->get_mem(++i)) {	/* define members defined inline *///error('d',"member %n",p);		switch (p->tp->base) {		case FCT:		{	Pfct f = (Pfct)p->tp;			if (f->body) {				f->f_inline = 1;				p->n_sto = STATIC;				f->dcl(p);			}			break;		}		case OVERLOAD:		{	Pgen g = (Pgen)p->tp;			Plist gl;			for (gl=g->fct_list; gl; gl=gl->l) {				Pname n = gl->f;				Pfct f = (Pfct)n->tp;				if (f->body) {					f->f_inline = 1;					n->n_sto = STATIC;					f->dcl(n);				}			}		}		}	}	Plist fl;			/* define friends defined inline */	for (fl=friend_list; fl; fl=fl->l) {		Pname p = fl->f;		switch (p->tp->base) {		case FCT:		{	Pfct f = (Pfct)p->tp;			if (f->body			&&  (f->defined&(DEFINED|SIMPLIFIED)) == 0) {				f->f_inline = 1;				p->n_sto = STATIC;				f->dcl(p);			}			break;		}		case OVERLOAD:		{	Pgen g = (Pgen)p->tp;			Plist gl;			for (gl=g->fct_list; gl; gl=gl->l) {				Pname n = gl->f;				Pfct f = (Pfct)n->tp;				if (f->body				&&  (f->defined&(DEFINED|SIMPLIFIED)) == 0) {					f->f_inline = 1;					n->n_sto = STATIC;					f->dcl(n);				}			}		}		}	}	byte_offset = byte_old;	bit_offset = bit_old;	max_align = max_old;	cc->unstack();}void enumdef.dcl(Pname, Ptable tbl){#define FIRST_ENUM 0	int nmem = mem->no_of_names();	Pname p;	Pname ns = 0;	Pname nl;	int enum_old = enum_count;	no_of_enumerators = nmem;	enum_count = FIRST_ENUM;	if (this == 0) error('i',"0->enumdef.dcl(%d)",tbl);	for(p=mem, mem=0; p; p=p->n_list) {		Pname nn;		if (p->n_initializer) {			Pexpr i = p->n_initializer->typ(tbl);			Neval = 0;			enum_count = i->eval();			if (Neval) error("%s",Neval);			DEL(i);			p->n_initializer = 0;		}		p->n_evaluated = 1;		p->n_val = enum_count++; 		nn = tbl->insert(p,0); /* ??? */		if (Nold) {			if (nn->n_stclass == ENUM)				error( (p->n_val!=nn->n_val)?0:'w',"enumerator%n declared twice",nn);			else				error("incompatibleDs of%n",nn);		}		else {			nn->n_stclass = ENUM; // no store will be allocated			if (ns)				nl->n_list = nn;			else				ns = nn;			nl = nn;		}		delete p;	}	mem = ns;	enum_count = enum_old;	defined |= DEFINED;}Pstmt curr_loop;Pstmt curr_switch;Pblock curr_block;void stmt.reached(){	register Pstmt ss = s_list;	if (ss == 0) return;	switch (ss->base) {	case LABEL:	case CASE:	case DEFAULT:		break;	default:		error('w',"statement not reached");		/* delete unreacheable code */		for (; ss; ss=ss->s_list) {			switch (ss->base) {			case LABEL:			case CASE:			case DEFAULT:	/* reachable */				s_list = ss;				return;			case IF:			case DO:			case WHILE:			case SWITCH:			case FOR:			case BLOCK:	/* may hide a label */				s_list = ss;				return;			}		}		s_list = 0;	}}bit arg_err_suppress;Pexpr check_cond(Pexpr e, TOK b, Ptable tbl){//error('d',"check_cond(%k %k) tbl %d",e->base,b,tbl);	Pname cn;	if (cn = e->tp->is_cl_obj()) {			Pclass cl = (Pclass)cn->tp;		int i = 0;		Pname found = 0;		for (Pname on = cl->conv; on; on=on->n_list) {			Pfct f = (Pfct)on->tp;			Ptype t = f->returns;		xx:			switch (t->base) {			case TYPE:				t = Pbase(t)->b_name->tp;				goto xx;			case CHAR:			case SHORT:			case INT:			case LONG:			case EOBJ:			case FLOAT:			case DOUBLE:			case PTR:				i++;				found = on;			}		}		switch (i) {		case 0:			error("%nO in%kE",cn,b);			return e;		case 1:		{//error('d',"cond%t<-%t:%n",Pfct(found->tp)->returns,e->tp,found);			Pclass cl = (Pclass)cn->tp;			Pref r = new ref(DOT,e,found);			r->tp = found->tp;			Pexpr c = new expr(G_CALL,r,0);			c->fct_name = found;		//	c->tp = Pfct(found->tp)->returns;			return c->typ(tbl);		}		default:			error("%d possible conversions for%nO in%kE",i,cn,b);			return e;		}			}	e->tp->num_ptr(b);	return e;}void stmt.dcl()/*	typecheck statement "this" in scope "curr_block->tbl"*/{	Pstmt ss;	Pname n;	Pname nn;	Pstmt ostmt = Cstmt;	for (ss=this; ss; ss=ss->s_list) {		Pstmt old_loop, old_switch;		Cstmt = ss;		Ptable tbl = curr_block->memtbl;/*error('d',"ss %d%k tbl %d e %d%k s %d%k sl %d%k", ss, ss->base, tbl, ss->e, (ss->e)?ss->e->base:0, ss->s, (ss->s)?ss->s->base:0, ss->s_list, (ss->s_list)?ss->s_list->base:0);*/		switch (ss->base) {		case BREAK:			if (curr_loop==0 && curr_switch==0)				error("%k not in loop or switch",BREAK);			ss->reached();			break;		case CONTINUE:			if (curr_loop == 0) error("%k not in loop",CONTINUE);			ss->reached();			break;		case DEFAULT:			if (curr_switch == 0) {				error("default not in switch");				break;			}			if (curr_switch->has_default) error("two defaults in switch");			curr_switch->has_default = ss;			ss->s->s_list = ss->s_list;			ss->s_list = 0;			ss->s->dcl();			break;		case SM:			switch (ss->e->base) {			case DUMMY:				ss->e = 0;				break;					// check for unused results					// don't check operators that are likely					// to be overloaded to represent "actions":					// ! ~ < <= > >= << >>			case EQ:			case NE:			case PLUS:			case MINUS:			case REF:			case DOT:			case MUL:			case DIV:			case ADDROF:			case AND:			case OR:			case ER:			case DEREF:			case ANDAND:			case OROR:			case NAME:				if (ss->e->tp) break;	// avoid looking at generated code				ss->e = ss->e->typ(tbl);				if (ss->e->tp->base != VOID) error('w',"result of%kE not used",ss->e->base);				break;			default:				ss->e = ss->e->typ(tbl);			}		//	ss->e = (ss->e != dummy) ? ss->e->typ(tbl) : 0;			break;		case RETURN:		{	Pname fn = cc->nof;			Ptype rt = Pfct(fn->tp)->returns;			Pexpr v = ss->e;			if (v != dummy) {				if (rt->base == VOID) {					error('w',"unX return value");					/*refuse to return the value:*/					ss->e = dummy;				}				else {					v = v->typ(tbl);				lx://error('d',"return %t",rt);					switch (rt->base) {					case TYPE:						rt = Pbase(rt)->b_name->tp;						goto lx;					case RPTR:						ss->e = ref_init(Pptr(rt),v,tbl);						if (v->lval(0)==0						&& v->tp->tconst()==0)							error('w',"reference to non-lvalue returned");						else if (v->base==NAME						&& Pname(v)->n_scope==FCT)							error('w',"reference to local variable returned");																					break;					case COBJ:					{	Pname rv = tbl->look("_result",0);						ss->e = class_init(rv,rt,v,tbl);//error('d',"ss->e %t %d",ss->e->tp,ss->e->base);						break;					}					case ANY:						break;					case INT:					case CHAR:					case LONG:					case SHORT:						if (Pbase(rt)->b_unsigned						&& v->base==UMINUS						&& v->e2->base==ICON)							error('w',"negative retured fromF returning unsigned");					default:		{	Pname cn;			int i;			if ((cn=v->tp->is_cl_obj())			&& (i=can_coerce(rt,v->tp))			&& Ncoerce) {				if (1 < i) error("%d possible conversions for return value",i);				Pclass cl = (Pclass)cn->tp;				Pref r = new ref(DOT,v,Ncoerce);				Pexpr c = new expr(G_CALL,r,0);				c->fct_name = Ncoerce;				c->tp = rt;				ss->e = c;				break;			}		}						ss->e = v;						if (rt->check(v->tp,ASSIGN))							error("bad return valueT for%n:%t (%tX)",fn,v->tp,rt);					}				}			}			else {				if (rt->base != VOID) error('w',"return valueX");			}			ss->reached();			break;		}		case DO:	/* in DO the stmt is before the test */					inline_restr |= 8;			old_loop = curr_loop;			curr_loop = ss;			if (ss->s->base == DCL) error('s',"D as onlyS in do-loop");			ss->s->dcl();		/*	tbl = curr_block->memtbl;*/			ss->e = ss->e->typ(tbl);			ss->e = check_cond(ss->e,DO,tbl);			curr_loop = old_loop;			break;		case WHILE:			inline_restr |= 8;			old_loop = curr_loop;			curr_loop = ss;			ss->e = ss->e->typ(tbl);			/*ss->e->tp->num_ptr(ss->base);*/			ss->e = check_cond(ss->e,WHILE,tbl);			if (ss->s->base == DCL) error('s',"D as onlyS in while-loop");			ss->s->dcl();			curr_loop = old_loop;			break;		case SWITCH:		{	int ne = 0;			inline_restr |= 4;			old_switch = curr_switch;			curr_switch = ss;			ss->e = ss->e->typ(tbl);		/*	ss->e->tp->num_ptr(SWITCH);*/			ss->e = check_cond(ss->e,SWITCH,tbl);			{	Ptype tt = ss->e->tp;			sii:				switch (tt->base) {				case TYPE:					tt = ((Pbase)tt)->b_name->tp; goto sii;				case EOBJ:					ne = Penum(Pbase(tt)->b_name->tp)->no_of_enumerators;				case ZTYPE:				case ANY:				case CHAR:				case SHORT:				case INT:				case LONG:				case FIELD:					break;				default:					error('s',"%t switchE",ss->e->tp);				}			}			ss->s->dcl();			if (ne) {	/* see if the number of cases is "close to"					   but not equal to the number of enumerators					*/				int i = 0;				Pstmt cs;				for (cs=ss->case_list; cs; cs=cs->case_list) i++;				if (i && i!=ne) {					if (ne < i) {				ee:		error('w',"switch (%t) with %d cases (%d enumerators)",ss->e->tp,i,ne);					}					else {						switch (ne-i) {						case 1: if (3<ne) goto ee;						case 2: if (7<ne) goto ee;						case 3: if (23<ne) goto ee;						case 4: if (60<ne) goto ee;						case 5: if (99<ne) goto ee;						}					}				}			}			curr_switch = old_switch;			break;		}		case CASE:			if (curr_switch == 0) {				error("case not in switch");				break;			}			ss->e = ss->e->typ(tbl);			ss->e->tp->num_ptr(CASE);			{	Ptype tt = ss->e->tp;			iii:				switch (tt->base) {				case TYPE:					tt = Pbase(tt)->b_name->tp; goto iii;				case ZTYPE:				case ANY:				case CHAR:				case SHORT:				case INT:				case LONG:					break;				default:					error('s',"%t caseE",ss->e->tp);				}			}			if (1) {				Neval = 0;				int i = ss->e->eval();				if (Neval == 0) {					Pstmt cs;					for (cs=curr_switch->case_list; cs; cs=cs->case_list) {						if (cs->case_value == i) error("case %d used twice in switch",i);					}					ss->case_value = i;					ss->case_list = curr_switch->case_list;					curr_switch->case_list = ss;				}				else					error("bad case label: %s",Neval);			}			if (ss->s->s_list) error('i',"case%k",ss->s->s_list->base);			ss->s->s_list = ss->s_list;			ss->s_list = 0;			ss->s->dcl();			break;		case GOTO:			inline_restr |= 2;			ss->reached();		case LABEL:			/* Insert label in function mem table;			   labels have function scope.			*/			n = ss->d;			nn = cc->ftbl->insert(n,LABEL);			/* Set a ptr to the mem table corresponding to the scope			   in which the label actually occurred.  This allows the			   processing of goto's in the presence of ctors and dtors			*/			if(ss->base == LABEL) {				nn->n_realscope = curr_block->memtbl;				inline_restr |= 1;			}			if (Nold) {				if (ss->base == LABEL) {					if (nn->n_initializer) error("twoDs of label%n",n);					nn->n_initializer = (Pexpr)1;				}				if (n != nn) ss->d = nn;			}			else {				if (ss->base == LABEL) nn->n_initializer = (Pexpr)1;				nn->where = ss->where;			}			if (ss->base == GOTO)				nn->use();			else {				if (ss->s->s_list) error('i',"label%k",ss->s->s_list->base);				ss->s->s_list = ss->s_list;				ss->s_list = 0;				nn->assign();			}			if (ss->s) ss->s->dcl();			break;		case IF:		{	Pexpr ee = ss->e->typ(tbl);			if (ee->base == ASSIGN) {				Neval = 0;				(void)ee->e2->eval();				if (Neval == 0)					error('w',"constant assignment in condition");			}			ss->e = ee = check_cond(ee,IF,tbl);//error('d',"if (%t)",ee->tp);			switch (ee->tp->base) {			case INT:			case ZTYPE:

⌨️ 快捷键说明

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