示例#1
0
static AstExpression CheckEqualityOP(AstExpression expr)
{
	Type ty1, ty2;

	expr->ty = T(INT);
	ty1 = expr->kids[0]->ty;
	ty2 = expr->kids[1]->ty;
	if (BothArithType(ty1, ty2))
	{
		PERFORM_ARITH_CONVERSION(expr);
		expr->ty = T(INT);
		return FoldConstant(expr);
	}

	if (IsCompatiblePtr(ty1, ty2) ||
		NotFunctionPtr(ty1) && IsVoidPtr(ty2) ||
		NotFunctionPtr(ty2) && IsVoidPtr(ty1) ||
		IsPtrType(ty1) && IsNullConstant(expr->kids[1]) ||
		IsPtrType(ty2) && IsNullConstant(expr->kids[0]))
	{
		return expr;
	}

	REPORT_OP_ERROR;
}
示例#2
0
static AstExpression CheckConditionalExpression(AstExpression expr)
{
	int qual;
	Type ty1, ty2;

	expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);

	if (! IsScalarType(expr->kids[0]->ty))
	{
		Error(&expr->coord, "The first expression shall be scalar type.");
	}
	expr->kids[1]->kids[0] = Adjust(CheckExpression(expr->kids[1]->kids[0]), 1);
	expr->kids[1]->kids[1] = Adjust(CheckExpression(expr->kids[1]->kids[1]), 1);

	ty1 = expr->kids[1]->kids[0]->ty;
	ty2 = expr->kids[1]->kids[1]->ty;
	if (BothArithType(ty1, ty2))
	{
		expr->ty = CommonRealType(ty1, ty2);
		expr->kids[1]->kids[0] = Cast(expr->ty, expr->kids[1]->kids[0]);
		expr->kids[1]->kids[1] = Cast(expr->ty, expr->kids[1]->kids[1]);

		return FoldConstant(expr);
	}
	else if (IsRecordType(ty1) && ty1 == ty2)
	{
		expr->ty = ty1;
	}
	else if (ty1->categ == VOID && ty2->categ == VOID)
	{
		expr->ty = T(VOID);
	}
	else if (IsCompatiblePtr(ty1, ty2))
	{
		qual = ty1->bty->qual | ty2->bty->qual;
		expr->ty  = PointerTo(Qualify(qual, CompositeType(Unqual(ty1->bty), Unqual(ty2->bty))));
	}
	else if (IsPtrType(ty1) && IsNullConstant(expr->kids[1]->kids[1]))
	{
		expr->ty = ty1;
	}
	else if (IsPtrType(ty2) && IsNullConstant(expr->kids[1]->kids[0]))
	{
		expr->ty = ty2;
	}
	else if (NotFunctionPtr(ty1) && IsVoidPtr(ty2) ||
	         NotFunctionPtr(ty2) && IsVoidPtr(ty1))
	{
		qual = ty1->bty->qual | ty2->bty->qual;
		expr->ty = PointerTo(Qualify(qual, T(VOID)));
	}
	else
	{
		Error(&expr->coord, "invalid operand for ? operator.");
		expr->ty = T(INT);
	}

	return expr;
}
示例#3
0
static AstExpression CheckFunctionCall(AstExpression expr)
{
	AstExpression arg;
	Type ty;
	AstNode *tail;
	int argNo, argFull;

	if (expr->kids[0]->op == OP_ID && LookupID(expr->kids[0]->val.p) == NULL)
	{
		expr->kids[0]->ty = DefaultFunctionType;
		expr->kids[0]->val.p = AddFunction(expr->kids[0]->val.p, DefaultFunctionType, TK_EXTERN);
	}
	else
	{
		expr->kids[0] = CheckExpression(expr->kids[0]);
	}
	expr->kids[0] = Adjust(expr->kids[0], 1);
	ty = expr->kids[0]->ty;

	if (! (IsPtrType(ty) && IsFunctionType(ty->bty)))
	{
		Error(&expr->coord, "The left operand must be function or function pointer");
	    ty = DefaultFunctionType;
	}
	else
	{
		ty = ty->bty;
	}

	tail = (AstNode *)&expr->kids[1];
	arg = expr->kids[1];
	argNo = 1;
	argFull = 0;
	while (arg != NULL && ! argFull)
	{
		*tail = (AstNode)CheckArgument((FunctionType)ty, arg, argNo, &argFull);
		tail = &(*tail)->next;
		arg = (AstExpression)arg->next;
		argNo++;
	}
	*tail = NULL;

	if (arg != NULL)
	{
		while (arg != NULL)
		{
			CheckExpression(arg);
			arg = (AstExpression)arg->next;
		}
		Error(&expr->coord, "Too many arguments");
	}
	else if (argNo < LEN(((FunctionType)ty)->sig->params))
	{
		Error(&expr->coord, "Too few arguments");
	}
	expr->ty = ty->bty;

	return expr;
}
示例#4
0
/**
 * Check if the initializer expression is address constant.
 * e.g. 
 * int a;
 * int b = &a;
 */
static AstExpression CheckAddressConstant(AstExpression expr)
{
	AstExpression addr;
	AstExpression p;
	int offset = 0;

	if (! IsPtrType(expr->ty))
		return NULL;

	if (expr->op == OP_ADD || expr->op == OP_SUB)
	{
		addr = CheckAddressConstant(expr->kids[0]);
		if (addr == NULL || expr->kids[1]->op != OP_CONST)
			return NULL;
		
		expr->kids[0] = addr->kids[0];
		expr->kids[1]->val.i[0] += (expr->op == OP_ADD ? 1 : -1) * addr->kids[1]->val.i[0];

		return expr;
	}

	if (expr->op == OP_ADDRESS)
		addr = expr->kids[0];
	else
		addr = expr;

	while (addr->op == OP_INDEX || addr->op == OP_MEMBER)
	{
		if (addr->op == OP_INDEX)
		{
			if (addr->kids[1]->op != OP_CONST)
				return NULL;

			offset += addr->kids[1]->val.i[0] * addr->ty->size;
		}
		else
		{
			Field fld = addr->val.p;

			offset += fld->offset;
		}
		addr = addr->kids[0];
	}

	if (addr->op != OP_ID || (expr->op != OP_ADDRESS && ! addr->isarray && ! addr->isfunc))
		return NULL;


	((Symbol)addr->val.p)->ref++;

	CREATE_AST_NODE(p, Expression);
	p->op = OP_ADD;
	p->ty = expr->ty;
	p->kids[0] = addr;
	p->kids[1] = Constant(addr->coord, T(INT), p->val);

	return p;
}
示例#5
0
int CanAssign(Type lty, AstExpression expr)
{
	Type rty = expr->ty;

	lty = Unqual(lty);
	rty = Unqual(rty);
	if (lty == rty)
	{
		return 1;
	}
	if (BothArithType(lty, rty))
	{
		return 1;
	}
	if (IsCompatiblePtr(lty, rty) && ((lty->bty->qual & rty->bty->qual) == rty->bty->qual))
	{
		return 1;
	}
	if ((NotFunctionPtr(lty) && IsVoidPtr(rty) || NotFunctionPtr(rty) && IsVoidPtr(lty))&& 
		((lty->bty->qual & rty->bty->qual) == rty->bty->qual))
	{
		return 1;
	}
	if (IsPtrType(lty) && IsNullConstant(expr))
	{
		return 1;
	}

	if (IsPtrType(lty) && IsPtrType(rty))
	{
		//Warning(&expr->coord, "assignment from incompatible pointer type");
		return 1;
	}

	if ((IsPtrType(lty) && IsIntegType(rty) || IsPtrType(rty) && IsIntegType(lty))&&
		(lty->size == rty->size))
	{
		Warning(&expr->coord, "conversion between pointer and integer without a cast");
		return 1;
	}

	return 0;
}
示例#6
0
/* 添加常量到符号表中 */
Symbol AddConstant (Type ty, union value val) 
{
    unsigned h = (unsigned)val.i[0] & SYM_HASH_MASK;
    Symbol p;

    /* 去掉修饰符 */
    ty = Unqual (ty);
    if (IsIntegType (ty)) {
        ty = T (INT);
    } else if (IsPtrType (ty)) {
        ty = T (POINTER);
    } else if (LONGDOUBLE == ty->categ) {
        ty = T (DOUBLE);
    }

    /* 如果已经添加直接返回 */
    for (p = Constants.buckets[h]; p; p = p->link) {
        if (p->ty == ty && p->val.i[0] == val.i[0] && p->val.i[1] == val.i[1]) 
            return p;
    }

    /* 将常量添加到符号表中 */
    CALLOC (p);
    p->kind = SK_Constant;
    switch (ty->categ) {
        case INT:
            p->name = FormatName ("%d", val.i[0]); break;
        case POINTER:
            p->name = (val.i[0] ? FormatName ("0x%x", val.i[0]) : "0"); break;
        case FLOAT:
            /* %g可以省略浮点多余的0 */
            p->name = FormatName ("%g", val.f); break;
        case DOUBLE:
            p->name = FormatName ("%g", val.d); break;
        default:
            assert (0);
    }
    p->ty       = ty;
    p->sclass   = TK_STATIC;
    p->val      = val;

    p->link = Constants.buckets[h];
    Constants.buckets[h] = p;
    if (FLOAT == ty->categ || DOUBLE == ty->categ) {
        
        *FloatTail = p;
        FloatTail = &p->next;
    }
    return p;
}
示例#7
0
static AstExpression CheckMemberAccess(AstExpression expr)
{
	Type ty;
	Field fld;

	expr->kids[0] = CheckExpression(expr->kids[0]);
	if (expr->op == OP_MEMBER)
	{
		expr->kids[0] = Adjust(expr->kids[0], 0);
		ty = expr->kids[0]->ty;
		if (! IsRecordType(ty))
		{
			REPORT_OP_ERROR;
		}
		expr->lvalue = expr->kids[0]->lvalue;
	}
	else
	{
		expr->kids[0] = Adjust(expr->kids[0], 1);
		ty = expr->kids[0]->ty;
		if (! (IsPtrType(ty) && IsRecordType(ty->bty)))
		{
			REPORT_OP_ERROR;
		}
		ty = ty->bty;
		expr->lvalue = 1;
	}
	
	fld = LookupField(Unqual(ty), expr->val.p);
	if (fld == NULL)
	{
		Error(&expr->coord, "struct or union member %s doesn't exsist", expr->val.p);
		expr->ty = T(INT);
		return expr;
	}
	expr->ty = Qualify(ty->qual, fld->ty);
	expr->val.p = fld;
	expr->bitfld = fld->bits != 0;
	return expr;
}
示例#8
0
static AstExpression CheckUnaryExpression(AstExpression expr)
{
	Type ty;

	switch (expr->op)
	{
	case OP_PREINC:
	case OP_PREDEC:
		return TransformIncrement(expr);

	case OP_ADDRESS:
		expr->kids[0] = CheckExpression(expr->kids[0]);
		ty = expr->kids[0]->ty;
		if (expr->kids[0]->op == OP_DEREF)
		{
			expr->kids[0]->kids[0]->lvalue = 0;
			return expr->kids[0]->kids[0];
		}
		else if (expr->kids[0]->op == OP_INDEX)
		{
			expr->kids[0]->op = OP_ADD;
			expr->kids[0]->ty = PointerTo(ty);
			expr->kids[0]->lvalue = 0;
			return expr->kids[0];
		}
		else if (IsFunctionType(ty) || 
			     (expr->kids[0]->lvalue && ! expr->kids[0]->bitfld && ! expr->kids[0]->inreg))
		{
			expr->ty = PointerTo(ty);
			return expr;
		}
		break;

	case OP_DEREF:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		ty = expr->kids[0]->ty;
		if (expr->kids[0]->op == OP_ADDRESS)
		{
			expr->kids[0]->kids[0]->ty = ty->bty;
			return expr->kids[0]->kids[0];
		}
		else if (expr->kids[0]->op == OP_ADD && expr->kids[0]->kids[0]->isarray)
		{
			expr->kids[0]->op = OP_INDEX;
			expr->kids[0]->ty = ty->bty;
			expr->kids[0]->lvalue = 1;
			return expr->kids[0];
		}
		if (IsPtrType(ty))
		{
			expr->ty = ty->bty;
			if (IsFunctionType(expr->ty))
			{
				return expr->kids[0];
			}
			expr->lvalue = 1;
			return expr;
		}
		break;

	case OP_POS:
	case OP_NEG:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		if (IsArithType(expr->kids[0]->ty))
		{
			expr->kids[0] = DoIntegerPromotion(expr->kids[0]);
			expr->ty = expr->kids[0]->ty;
			return expr->op == OP_POS ? expr->kids[0] : FoldConstant(expr);
		}
		break;

	case OP_COMP:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		if (IsIntegType(expr->kids[0]->ty))
		{
			expr->kids[0] = DoIntegerPromotion(expr->kids[0]);
			expr->ty = expr->kids[0]->ty;
			return FoldConstant(expr);
		}
		break;

	case OP_NOT:
		expr->kids[0] = Adjust(CheckExpression(expr->kids[0]), 1);
		if (IsScalarType(expr->kids[0]->ty))
		{
			expr->ty = T(INT);
			return FoldConstant(expr);
		}
		break;

	case OP_SIZEOF:
		if (expr->kids[0]->kind == NK_Expression)
		{
			expr->kids[0] = CheckExpression(expr->kids[0]);
			if (expr->kids[0]->bitfld)
				goto err;
			ty = expr->kids[0]->ty;
		}
		else
		{
			ty = CheckTypeName((AstTypeName)expr->kids[0]);
		}
		if (IsFunctionType(ty) || ty->size == 0)
			goto err;

		expr->ty = T(UINT);
		expr->op = OP_CONST;
		expr->val.i[0] = ty->size;
		return expr;

	case OP_CAST:
		return CheckTypeCast(expr);

	default:
		assert(0);
	}

err:
	REPORT_OP_ERROR;

}