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

📄 enode.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "c.h"

static Tree addtree ARGS((int, Tree, Tree));
static Tree andtree ARGS((int, Tree, Tree));
static Tree cmptree ARGS((int, Tree, Tree));
static int compatible ARGS((Type, Type));
static int isnullptr ARGS((Tree e));
static Tree multree ARGS((int, Tree, Tree));
static Tree subtree ARGS((int, Tree, Tree));
#define isvoidptr(ty) \
	(isptr(ty) && unqual(ty->type) == voidtype)

Tree (*optree[]) ARGS((int, Tree, Tree)) = {
#define xx(a,b,c,d,e,f,g) e,
#define yy(a,b,c,d,e,f,g) e,
#include "token.h"
};

void typewarning(int op,Tree l,Tree r);

Tree call(Tree f,Type fty,Coordinate src)
{
	int n = 0;
	Tree args = NULL, r = NULL;
	Type *proto, rty = unqual(freturn(fty));
	Symbol t3 = NULL;
	Tree result;
	Type functionCallType;
	int isIntrinsic=0,nestedCall,intrinsicArgsTableIdx=0;
	Tree intrinsicArgsTable[10];

	if (fty->u.f.oldstyle)
		proto = NULL;
	else
		proto = fty->u.f.proto;
	if (f->u.sym) {
		if (f->Flags) {
			isIntrinsic = IsIntrinsic(f->u.sym->name);
		}
		f->u.sym->x.callused++;
		if (!strcmp(f->u.sym->name,"alloca"))
			hasAllocA = 1;
	}
	if (hascall(f))
		r = f;
	if (isstruct(rty))
		{
			t3 = temporary(AUTO, unqual(rty), level);
			if (rty->size == 0)
				error(StrTab[279], rty);// <illegal use of incomplete type `%t'\n>
		}
	if (t != ')')
		for (;;) {
			Tree q = pointer(expr1(0));
			if (proto && *proto && *proto != voidtype)
				{
					Type aty;
					q = value(q);
					aty = assign(*proto, q);
					if (aty)
						q = cast(q, aty);
					else
						error(StrTab[280], n + 1, funcname(f),// <type error in argument %d to %s; found `%t' expected `%t'\n>

							q->type, *proto);
					if ((isint(q->type) || isenum(q->type))
					&& q->type->size != inttype->size)
						q = cast(q, promote(q->type));
					++proto;
				}
			else
				{
					if (!fty->u.f.oldstyle && *proto == NULL)
						error(StrTab[281], funcname(f));// <too many arguments to %s\n>
					q = value(q);
					if (q->type == floattype)
						q = cast(q, doubletype);
					else if (isarray(q->type) || q->type->size == 0)
						error(StrTab[282], n + 1, funcname(f), q->type);// <type error in argument %d to %s; `%t' is illegal\n>

					else
						q = cast(q, promote(q->type));
				}
			if (!IR->wants_argb && isstruct(q->type))
				if (iscallb(q))
					q = addrof(q);
				else {
					Symbol t1 = temporary(AUTO, unqual(q->type), level);
					q = asgn(t1, q);
					q = tree(RIGHT, ptr(t1->type),
						root(q), lvalue(idtree(t1)));
				}
			if (q->type->size == 0)
				q->type = inttype;
			nestedCall = 0;
			if (hascall(q)) {
				FunctionInfo.NestedCalls = 1;
				r = r ? tree(RIGHT, voidtype, r, q) : q;
				nestedCall = 1;
			}
			args = tree(ARG + widen(q->type), q->type, q, args);
			if (isIntrinsic) {
				args->intrinsicArg=isIntrinsic;
				args->nestedCall = nestedCall;
				assert(intrinsicArgsTableIdx < 10);
				intrinsicArgsTable[intrinsicArgsTableIdx++] = args;
			}
			n++;
			if (Aflag >= 2 && n == 32)
				warning(StrTab[283],// <more than 31 arguments in a call to %s\n>
					funcname(f));
			if (t != ',')
				break;
			t = gettok();
		}
	expect(')');
	if (proto && *proto && *proto != voidtype)
		error(StrTab[284],// <insufficient number of arguments to %s\n>
			funcname(f));
	if (r)
		args = tree(RIGHT, voidtype, r, args);
	if (events.calls)
		apply(events.calls, &src, &f);
	result = calltree(f, rty, args, t3);
	functionCallType = f->type;
	if (functionCallType->op == POINTER)
		functionCallType = functionCallType->type;
	if (functionCallType->u.f.isStdCall) {
		result->Flags = 1;
	}
	if (f->Flags) {
		if (f->u.sym && f->u.sym->name && IsIntrinsic(f->u.sym->name)) {
			int i;

			nestedCall = 0;
			for (i=0; i<intrinsicArgsTableIdx;i++) {
				if (intrinsicArgsTable[i]->nestedCall) {
					nestedCall = 1;
					break;
				}
			}
			for (i=0; i<intrinsicArgsTableIdx;i++) {
				intrinsicArgsTable[i]->nestedCall = nestedCall;
			}

			result->intrinsic=isIntrinsic;
			result->nestedCall = nestedCall;
		}
		result->Flags = 1;
	}
	if (xref) {
		if (f->u.sym && f->u.sym->name && !isIntrinsic)
			FunctionInfo.CalledFunctionsList = append(f->u.sym,FunctionInfo.CalledFunctionsList);
	}
	return(result);
}
Tree calltree(Tree f,Type ty,Tree args,Symbol t3)
{
	Tree p;

	if (args)
		f = tree(RIGHT, f->type, args, f);
	if (isstruct(ty))
#ifndef NDEBUG
		assert(t3),
#endif
		p = tree(RIGHT, ty,
			tree(CALL+B, ty, f, addrof(idtree(t3))),
			idtree(t3));
	else {
		Type rty = ty;
		if (isenum(ty))
			rty = unqual(ty)->type;
		else if (isptr(ty))
			rty = unsignedtype;
		p = tree(CALL + widen(rty), promote(rty), f, NULL);
		if (isptr(ty) || p->type->size > ty->size)
			p = cast(p, ty);
	}
	return p;
}
int iscallb(Tree e)
{
	return e->op == RIGHT && e->kids[0] && e->kids[1]
		&& e->kids[0]->op == CALL+B
		&& e->kids[1]->op == INDIR+B
		&& isaddrop(e->kids[1]->kids[0]->op)
		&& e->kids[1]->kids[0]->u.sym->temporary;
}

static Tree addtree(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 if (isptr(l->type) && isint(r->type))
		return addtree(ADD, r, l);
	else if (isptr(l->type) && r->type == longlongtype) {
		r = cast(r,inttype);
		return addtree(ADD, r, l);
	}
	else if (  isptr(r->type) && isint(l->type)
	&& !isfunc(r->type->type))
		{
			int n;
			ty = unqual(r->type);
			n = unqual(ty->type)->size;
			if (n == 0)
				error(StrTab[285], ty->type);// <unknown size for type `%t'\n>
			l = cast(l, promote(l->type));
			if (n > 1)
				l = multree(MUL, consttree(n, inttype), l);
			if (YYcheck && !isaddrop(r->op))		/* omit */
				return nullcall(ty, YYcheck, r, l);	/* omit */
			return simplify(ADD+P, ty, l, r);
		}

	else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}

Tree consttree(unsigned n,Type ty)
{
	Tree p;

	if (isarray(ty))
		ty = atop(ty);
	p = tree(CNST + ttob(ty), ty, NULL, NULL);
	p->u.v.u = n;
	return p;
}
static Tree cmptree(int op,Tree l,Tree r)
{
	Type ty;

	if (isarith(l->type) && isarith(r->type)) {
		if (l->type->size != r->type->size &&
			(r->op == CNSTI || r->op == CNSTU)) {
			if (optype(l->op) == C &&
				r->u.v.i > 255) {
				warning(StrTab[286],r->u.v.i);// <overflow in char comparison with constant %d\n>
			}
			else if (optype(l->op) == S &&
				r->u.v.i > 65535) {
				warning(StrTab[287],r->u.v.i);// <overflow in short comparison with constant %d\n>
			}

		}
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);
	} else if (compatible(l->type, r->type)) {
		ty = unsignedtype;
		l = cast(l, ty);
		r = cast(r, ty);
	} else {
		ty = unsignedtype;
		typeerror(op, l, r);
	}
	return simplify(op + ttob(ty), inttype, l, r);
}
static int compatible(Type ty1,Type ty2)
{
	return isptr(ty1) && !isfunc(ty1->type)
		&& isptr(ty2) && !isfunc(ty2->type)
		&& eqtype(unqual(ty1->type), unqual(ty2->type), 0);
}
static int isnullptr(Tree e)
{
	return (isint(e->type) && generic(e->op) == CNST
			&& cast(e, unsignedtype)->u.v.u == 0)
		|| (isvoidptr(e->type) && e->op == CNST+P
			&& e->u.v.p == NULL);
}
Tree eqtree(int op,Tree l,Tree r)
{
	Type xty = l->type, yty = r->type;

	if (isptr(xty) && isnullptr(r)
	||  isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
	||  (isptr(xty) && isptr(yty)
		&& eqtype(unqual(xty->type), unqual(yty->type), 1))) {
		Type ty = unsignedtype;
		l = cast(l, ty);
		r = cast(r, ty);
		return simplify(op + U, inttype, l, r);
	}
	if (isptr(yty) && isnullptr(l)
	||  isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
		return eqtree(op, r, l);
	return cmptree(op, l, r);
}

Type assign(Type xty,Tree e)
{
	Type yty = unqual(e->type);

	xty = unqual(xty);
	if (isenum(xty))
		xty = xty->type;
	if (xty->size == 0 || yty->size == 0)
		return NULL;
	if ( isarith(xty) && isarith(yty)
	||  isstruct(xty) && xty == yty)
		return xty;
	if (isstruct(xty) && isstruct(yty) && extends(yty, xty))
		return xty;
	if (isptr(xty) && isstruct(xty->type)
	&&  isptr(yty) && isstruct(yty->type)
	&&  extends(yty->type, xty->type))
		return xty;
	if (isptr(xty) && isnullptr(e))
		return xty;
	if ((isvoidptr(xty) && isptr(yty)
	|| isptr(xty)     && isvoidptr(yty))
	&& (  (isconst(xty->type)    || !isconst(yty->type))
	&& (isvolatile(xty->type) || !isvolatile(yty->type))))
		return xty;

	if ((isptr(xty) && isptr(yty)
		&& eqtype(unqual(xty->type), unqual(yty->type), 1))
	&&  (  (isconst(xty->type)    || !isconst(yty->type))
		&& (isvolatile(xty->type) || !isvolatile(yty->type))))
		return xty;
	if (isptr(xty) && isptr(yty)
	&& (  (isconst(xty->type)    || !isconst(yty->type))
	&& (isvolatile(xty->type) || !isvolatile(yty->type)))) {
		Type lty = unqual(xty->type), rty = unqual(yty->type);

⌨️ 快捷键说明

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