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

📄 enode.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (isenum(lty) && rty == inttype
		||  isenum(rty) && lty == inttype) {
			if (Aflag >= 1)
				warning(StrTab[288],// <assignment between `%t' and `%t' is compiler-dependent\n>
					xty, yty);
			return xty;
		}
	}
	/* Any pointer can be assigned to any other This is a laxist
	point of view... jn */
	if (isptr(xty) && isptr(yty)) {
		Type t1,t2;
		t1 = unqual(xty->type);
		t2 = unqual(yty->type);
		if (t1 != t2 && !eqtype(t1,t2,1)) {
			if ((t1 != signedchar && t1 != unsignedchar) &&
				(t2 != signedchar && t2 != unsignedchar))
				warning(StrTab[289],xty,yty);// <assignment of %t to %t\n>
		}
		return xty;
	}
	return NULL;
}
Tree asgntree(int op,Tree l,Tree r)
{
	Type aty, ty;

	r = pointer(r);
	ty = assign(l->type, r);
	if (ty)
		r = cast(r, ty);
	else {
		if (isptr(l->type) && isptr(r->type)) {
			typewarning(ASGN,l,r);
		}
		else
		typeerror(ASGN, l, r);
		if (r->type == voidtype)
			r = retype(r, inttype);
		ty = r->type;
	}
	if (l->op != FIELD)
		l = lvalue(l);
	aty = l->type;
	if (isptr(aty))
		aty = unqual(aty)->type;
	if ( isconst(aty)
	||  isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)
		if (isaddrop(l->op)
		&& !l->u.sym->computed && !l->u.sym->generated)
			error(StrTab[290],// <assignment to const identifier `%s'\n>
				l->u.sym->name);
		else
			error(StrTab[291]);// <assignment to const location\n>
	if (l->op == FIELD) {
		int n = 8*l->u.field->type->size - fieldsize(l->u.field);
		if (n > 0 && isunsigned(l->u.field->type))
			r = bittree(BAND, r,
				consttree(fieldmask(l->u.field), unsignedtype));
		else if (n > 0) {
			if (r->op == CNST+I)
				r = consttree(r->u.v.i<<n, inttype);
			else
				r = shtree(LSH, r, consttree(n, inttype));
			r = shtree(RSH, r, consttree(n, inttype));
		}
	}
	if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
		return tree(RIGHT, ty,
			tree(CALL+B, ty, r->kids[0]->kids[0], l),
			idtree(l->u.sym));
	return tree(op + (isunsigned(ty) ? I : ttob(ty)),
		ty, l, r);
}
Tree condtree(Tree e,Tree l,Tree r)
{
	Symbol t1;
	Type ty, xty = l->type, yty = r->type;
	Tree p;

	if (isarith(xty) && isarith(yty))
		ty = binary(xty, yty);
	else if (eqtype(xty, yty, 1))
		ty = unqual(xty);
	else if (isptr(xty)   && isnullptr(r))
		ty = xty;
	else if (isnullptr(l) && isptr(yty))
		ty = yty;
	else if (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
	||       isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
		ty = voidptype;
	else if ((isptr(xty) && isptr(yty)
		&& eqtype(unqual(xty->type), unqual(yty->type), 1)))
		ty = xty;
	else {
		typeerror(COND, l, r);
		return consttree(0, inttype);
	}
	if (isptr(ty)) {
		ty = unqual(unqual(ty)->type);
		if (isptr(xty) && isconst(unqual(xty)->type)
		||  isptr(yty) && isconst(unqual(yty)->type))
			ty = qual(CONST, ty);
		if (isptr(xty) && isvolatile(unqual(xty)->type)
		||  isptr(yty) && isvolatile(unqual(yty)->type))
			ty = qual(VOLATILE, ty);
		ty = ptr(ty);
	}
	if (e->op == CNST+D || e->op == CNST+F) {
		e = cast(e, doubletype);
		return retype(e->u.v.d != 0.0 ? l : r, ty);
	}
	if (generic(e->op) == CNST) {
		e = cast(e, unsignedtype);
		return retype(e->u.v.u ? l : r, ty);
	}
	if (ty != voidtype && ty->size > 0) {
		/*
		Here was asked for a REGISTER temporary. This could lead to
		that register never being freed. I changed it to AUTO instead
		*/
		t1 = temporary(REGISTER, unqual(ty), level);
		l = asgn(t1, l);
		r = asgn(t1, r);
	} else
		t1 = NULL;
	p = tree(COND, ty, cond(e),
		tree(RIGHT, ty, root(l), root(r)));
	p->u.sym = t1;
	return p;
}
/* addrof - address of p */
Tree addrof(Tree p)
{
	Tree q = p;

	for (;;)
		switch (generic(q->op)) {
		case RIGHT:
			assert(q->kids[0] || q->kids[1]);
			q = q->kids[1] ? q->kids[1] : q->kids[0];
			continue;
		case ASGN:
			q = q->kids[1];
			continue;
		case COND: {
			Symbol t1 = q->u.sym;
			q->u.sym = 0;
			q = idtree(t1);
			/* fall thru */
			}
		case INDIR:
			if (p == q)
				return q->kids[0];
			q = q->kids[0];
			return tree(RIGHT, q->type, root(p), q);
		default:
			error(StrTab[292]);// <addressable object required\n>
			return value(p);
		}
}

/* andtree - construct tree for l [&& ||] r */
static Tree andtree(int op,Tree l,Tree r)
{
	if (!isscalar(l->type) || !isscalar(r->type))
		typeerror(op, l, r);
	return simplify(op, inttype, cond(l), cond(r));
}

/* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
Tree asgn(Symbol p,Tree e)
{
	if (isarray(p->type))
		e = tree(ASGN+B, p->type, idtree(p),
			tree(INDIR+B, e->type, e, NULL));
	else {
		Type ty = p->type;
		p->type = unqual(p->type);
		if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
			p->type->u.sym->u.s.cfields = 0;
			e = asgntree(ASGN, idtree(p), e);
			p->type->u.sym->u.s.cfields = 1;
		} else
			e = asgntree(ASGN, idtree(p), e);
		p->type = ty;
	}
	return e;
}

/* bittree - construct tree for l [& | ^ %] r */
Tree bittree(int op,Tree l,Tree r)
{
	Type ty = inttype;

	if (l->type == longlongtype || l->type == ulonglongtype) {
		ty = ulonglongtype;
		op = generic(op)+L;
		r = cast(r,longlongtype);
	}
	if ((isint(l->type) && isint(r->type)) ||
		((l->type == longlongtype || l->type == ulonglongtype)
			&& isint(r->type)) ||
		(l->type == longlongtype && r->type == longlongtype) ||
		(l->type == ulonglongtype && r->type == ulonglongtype) ||
		(l->type == longlongtype && r->type == ulonglongtype) ||
		(l->type == ulonglongtype && r->type == longlongtype) ||
		(isint(l->type) && (r->type == longlongtype ||
					r->type == ulonglongtype))) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);
		if (op != MOD && (l->type != ulonglongtype && l->type != longlongtype)) {
			l = cast(l, unsignedtype);
			r = cast(r, unsignedtype);
		}
	} else
		typeerror(op, l, r);
	if (op == MOD)
		return simplify(op, ty, l, r);
	else if (l->type == ulonglongtype || l->type == longlongtype)
		return cast(simplify(op, ulonglongtype, l, r), ty);
	return cast(simplify(op, unsignedtype, l, r), ty);
}

/* multree - construct tree for l [* /] r */
static Tree multree(int op,Tree l,Tree r)
{
	Type ty = inttype;

	if (isarith(l->type) && isarith(r->type)) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);
	} else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}

/* shtree - construct tree for l [>> <<] r */
Tree shtree(int op,Tree l,Tree r)
{
	Type ty = inttype;

	if (isint(l->type) && isint(r->type)) {
		ty = promote(l->type);
		l = cast(l, ty);
		r = cast(r, inttype);
	}
	else if ((l->type == ulonglongtype || l->type == longlongtype)
		&& ((r->type == ulonglongtype || r->type == longlongtype) ||
		isint(r->type)))
		return simplify((op == LSH)?LSHL:RSHL,l->type,l,r);
	else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}

/* subtree - construct tree for l - r */
static Tree subtree(int op,Tree l,Tree r)
{
	int n;
	Type ty = inttype;

	if (isarith(l->type) && isarith(r->type)) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);
	} else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
		ty = unqual(l->type);
		n = ty->type->size;
		if (n == 0)
			error(StrTab[293], ty->type);// <unknown size for type `%t'\n>
		r = cast(r, promote(r->type));
		if (n > 1)
			r = multree(MUL, consttree(n, inttype), r);
		return simplify(SUB+P, ty, l, r);
	} else if (compatible(l->type, r->type)) {
		ty = unqual(l->type);
		n = ty->type->size;
		if (n == 0)
			error(StrTab[294], ty->type);// <unknown size for type `%t'\n>
		l = simplify(SUB+U, unsignedtype, cast(l, unsignedtype),
			cast(r, unsignedtype));
		return simplify(DIV+I, inttype, cast(l, inttype), consttree(n, inttype));
	} else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}
	static struct { int op; char *name; } ops[] = {
		ASGN, "=",	INDIR, "*",	NEG,  "-",
		ADD,  "+",	SUB,   "-",	LSH,  "<<",
		MOD,  "%",	RSH,   ">>",	BAND, "&",
		BCOM, "~",	BOR,   "|",	BXOR, "^",
		DIV,  "/",	MUL,   "*",	EQ,   "==",
		GE,   ">=",	GT,    ">",	LE,   "<=",
		LT,   "<",	NE,    "!=",	AND,  "&&",
		NOT,  "!",	OR,    "||",	COND, "?:",
		0, 0
	};

/* typeerror - issue "operands of op have illegal types `l' and `r'" */
void typeerror(int op,Tree l,Tree r) {
	int i;

	op = generic(op);
	for (i = 0; ops[i].op; i++)
		if (op == ops[i].op)
			break;
	assert(ops[i].name);
	if (r)
		error(StrTab[295],// <operands of %s have illegal types `%t' and `%t'\n>
			ops[i].name, l->type, r->type);
	else
		error(StrTab[296], ops[i].name,// <operand of unary %s has illegal type `%t'\n>
			l->type);
}
/* typewarning - issue "operands of op have different types `l' and `r'" */
void typewarning(int op,Tree l,Tree r) {
	int i;

	op = generic(op);
	for (i = 0; ops[i].op; i++)
		if (op == ops[i].op)
			break;
	assert(ops[i].name);
	assert(r);
	warning(StrTab[297],// <operands of %s have different types `%t' and `%t'\n>
			ops[i].name, l->type, r->type);
}

⌨️ 快捷键说明

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