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

📄 expr.c

📁 c语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
	case ID:   if (tsym == NULL)		   	{				Symbol p = install(token, &identifiers, level, PERM);				p->src = src;				if (getchr() == '(') {					Symbol q = lookup(token, externals);					p->type = func(inttype, NULL, 1);					p->sclass = EXTERN;					if (Aflag >= 1)						warning("missing prototype\n");					if (q && !eqtype(q->type, p->type, 1))						warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);					if (q == NULL) {						q = install(p->name, &externals, GLOBAL, PERM);						q->type = p->type;						q->sclass = EXTERN;						q->src = src;						(*IR->defsymbol)(q);					}					p->u.alias = q;				} else {					error("undeclared identifier `%s'\n", p->name);					p->sclass = AUTO;					p->type = inttype;					if (p->scope == GLOBAL)						(*IR->defsymbol)(p);					else						addlocal(p);				}				t = gettok();				if (xref)					use(p, src);				return idtree(p);			}		   if (xref)		   	use(tsym, src);		   if (tsym->sclass == ENUM)		   	p = consttree(tsym->u.value, inttype);		   else {		   	if (tsym->sclass == TYPEDEF)		   		error("illegal use of type name `%s'\n", tsym->name);		   	p = idtree(tsym);		   } break;	case FIRSTARG:		if (level > PARAM && cfunc && cfunc->u.f.callee[0])			p = idtree(cfunc->u.f.callee[0]);		else {			error("illegal use of `%k'\n", FIRSTARG);			p = cnsttree(inttype, 0L);		}		break;	default:		error("illegal expression\n");			p = cnsttree(inttype, 0L);	}	t = gettok();	return p;}Tree idtree(Symbol p) {	int op;	Tree e;	Type ty = p->type ? unqual(p->type) : voidptype;	if (p->scope == GLOBAL || p->sclass == STATIC)		op = ADDRG;	else if (p->scope == PARAM) {		op = ADDRF;		if (isstruct(p->type) && !IR->wants_argb)			{				e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL);				e->u.sym = p;				return rvalue(rvalue(e));			}	} else if (p->sclass == EXTERN) {		assert(p->u.alias);		p = p->u.alias;		op = ADDRG;	} else		op = ADDRL;	p->ref += refinc;	if (isarray(ty))		e = tree(mkop(op,voidptype), p->type,      NULL, NULL);	else if (isfunc(ty))		e = tree(mkop(op,funcptype), p->type,      NULL, NULL);	else		e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL);	e->u.sym = p;	if (isptr(e->type))		e = rvalue(e);	return e;}Tree rvalue(Tree p) {	Type ty = deref(p->type);	ty = unqual(ty);	return tree(mkop(INDIR,ty), ty, p, NULL);}Tree lvalue(Tree p) {	if (generic(p->op) != INDIR) {		error("lvalue required\n");		return value(p);	} else if (unqual(p->type) == voidtype)		warning("`%t' used as an lvalue\n", p->type);	return p->kids[0];}Tree retype(Tree p, Type ty) {	Tree q;	if (p->type == ty)		return p;	q = tree(p->op, ty, p->kids[0], p->kids[1]);	q->node = p->node;	q->u = p->u;	return q;}Tree rightkid(Tree p) {	while (p && p->op == RIGHT)		if (p->kids[1])			p = p->kids[1];		else if (p->kids[0])			p = p->kids[0];		else			assert(0);	assert(p);	return p;}int hascall(Tree p) {	if (p == 0)		return 0;	if (generic(p->op) == CALL || (IR->mulops_calls &&	  (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I	|| p->op == DIV+U || p->op == MOD+U || p->op == MUL+U)))		return 1;	return hascall(p->kids[0]) || hascall(p->kids[1]);}Type binary(Type xty, Type yty) {#define xx(t) if (xty == t || yty == t) return t	xx(longdouble);	xx(doubletype);	xx(floattype);	xx(unsignedlonglong);	xx(longlong);	xx(unsignedlong);	if (xty == longtype     && yty == unsignedtype	||  xty == unsignedtype && yty == longtype)		if (longtype->size > unsignedtype->size)			return longtype;		else			return unsignedlong;	xx(longtype);	xx(unsignedtype);	return inttype;#undef xx}Tree pointer(Tree p) {	if (isarray(p->type))		/* assert(p->op != RIGHT || p->u.sym == NULL), */		p = retype(p, atop(p->type));	else if (isfunc(p->type))		p = retype(p, ptr(p->type));	return p;}Tree cond(Tree p) {	int op = generic(rightkid(p)->op);	if (op == AND || op == OR || op == NOT	||  op == EQ  || op == NE	||  op == LE  || op == LT || op == GE || op == GT)		return p;	p = pointer(p);	return (*optree[NEQ])(NE, p, consttree(0, inttype));}Tree cast(Tree p, Type type) {	Type src, dst;	p = value(p);	if (p->type == type)		return p;	dst = unqual(type);	src = unqual(p->type);	if (src->op != dst->op || src->size != dst->size) {		switch (src->op) {		case INT:			if (src->size < inttype->size)				p = simplify(CVI, inttype, p, NULL);			break;		case UNSIGNED:			if (src->size < inttype->size)				p = simplify(CVU, inttype, p, NULL);			else if (src->size < unsignedtype->size)				p = simplify(CVU, unsignedtype, p, NULL);			break;		case ENUM:			p = retype(p, inttype);			break;		case POINTER:			if (isint(dst) && src->size > dst->size)				warning("conversion from `%t' to `%t' is undefined\n", p->type, type);			p = simplify(CVP, super(src), p, NULL);			break;		case FLOAT:			break;		default: assert(0);		}		{			src = unqual(p->type);			dst = super(dst);			if (src->op != dst->op)				switch (src->op) {				case INT:					p = simplify(CVI, dst, p, NULL);					break;				case UNSIGNED:					if (isfloat(dst)) {						Type ssrc = signedint(src);						Tree two = cnsttree(longdouble, (long double)2.0);						p = (*optree['+'])(ADD,							(*optree['*'])(MUL,								two,								simplify(CVU, ssrc,									simplify(RSH, src,										p, consttree(1, inttype)), NULL)),							simplify(CVU, ssrc,								simplify(BAND, src,									p, consttree(1, unsignedtype)), NULL));					} else						p = simplify(CVU, dst, p, NULL);					break;				case FLOAT:					if (isunsigned(dst)) {						Type sdst = signedint(dst);						Tree c = cast(cnsttree(longdouble, (long double)sdst->u.sym->u.limits.max.i + 1), src);						p = condtree(							simplify(GE, src, p, c),							(*optree['+'])(ADD,								cast(cast(simplify(SUB, src, p, c), sdst), dst),								cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)),							simplify(CVF, sdst, p, NULL));					} else						p = simplify(CVF, dst, p, NULL);					break;				default: assert(0);				}			dst = unqual(type);		}	}	src = unqual(p->type);	switch (src->op) {	case INT:		if (src->op != dst->op || src->size != dst->size)			p = simplify(CVI, dst, p, NULL);		break;	case UNSIGNED:		if (src->op != dst->op || src->size != dst->size)			p = simplify(CVU, dst, p, NULL);		break;	case FLOAT:		if (src->op != dst->op || src->size != dst->size)			p = simplify(CVF, dst, p, NULL);		break;	case POINTER:		if (src->op != dst->op)			p = simplify(CVP, dst, p, NULL);		else {			if (isfunc(src->type) && !isfunc(dst->type)			|| !isfunc(src->type) &&  isfunc(dst->type))				warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type);			if (src->size != dst->size)				p = simplify(CVP, dst, p, NULL);		}		break;	default: assert(0);	}	return retype(p, type);}Tree field(Tree p, const char *name) {	Field q;	Type ty1, ty = p->type;	if (isptr(ty))		ty = deref(ty);	ty1 = ty;	ty = unqual(ty);	if ((q = fieldref(name, ty)) != NULL) {		if (isarray(q->type)) {			ty = q->type->type;			if (isconst(ty1) && !isconst(ty))				ty = qual(CONST, ty);			if (isvolatile(ty1) && !isvolatile(ty))				ty = qual(VOLATILE, ty);			ty = array(ty, q->type->size/ty->size, q->type->align);		} else {			ty = q->type;			if (isconst(ty1) && !isconst(ty))				ty = qual(CONST, ty);			if (isvolatile(ty1) && !isvolatile(ty))				ty = qual(VOLATILE, ty);			ty = ptr(ty);		}		if (YYcheck && !isaddrop(p->op) && q->offset > 0)	/* omit */			p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype));	/* omit */		else					/* omit */		p = simplify(ADD+P, ty, p, consttree(q->offset, signedptr));		if (q->lsb) {			p = tree(FIELD, ty->type, rvalue(p), NULL);			p->u.field = q;		} else if (!isarray(q->type))			p = rvalue(p);	} else {		error("unknown field `%s' of `%t'\n", name, ty);		p = rvalue(retype(p, ptr(inttype)));	}	return p;}/* funcname - return name of function f or a function' */char *funcname(Tree f) {	if (isaddrop(f->op))		return stringf("`%s'", f->u.sym->name);	return "a function";}static Tree nullcheck(Tree p) {	if (!needconst && YYnull && isptr(p->type)) {		p = value(p);		if (strcmp(YYnull->name, "_YYnull") == 0) {			Symbol t1 = temporary(REGISTER, voidptype);			p = tree(RIGHT, p->type,				tree(OR, voidtype,					cond(asgn(t1, cast(p, voidptype))),					vcall(YYnull, voidtype,	(file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno)		, NULL)),				idtree(t1));		}		else			p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L));	}	return p;}Tree nullcall(Type pty, Symbol f, Tree p, Tree e) {	Type ty;	if (isarray(pty))		return retype(nullcall(atop(pty), f, p, e), pty);	ty = unqual(unqual(p->type)->type);	return vcall(f, pty,		p, e,		cnsttree(inttype, (long)ty->size),		cnsttree(inttype, (long)ty->align),		(file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno)		, NULL);}

⌨️ 快捷键说明

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