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

📄 expr.c

📁 LCC4.2 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 + -