This is the final step/commit for implementing exlicit implicit casts. Unlike the

previous two checkins, which involved lot's of tedious refactoring, this checkin is nice and clean:-)

- Hacked UsualUnaryConversions, UsualArithmeticConversions, and DefaultFunctionArrayConversion
to create the AST node (using a helper function promoteExprToType).
- Added a setType method to Expr.
- Changed Expr::isIntegerConstantExpr to allow for the new node.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39866 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steve Naroff 2007-07-15 02:02:06 +00:00
Родитель c3f8937483
Коммит fa2eaabd30
3 изменённых файлов: 45 добавлений и 22 удалений

Просмотреть файл

@ -278,6 +278,9 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
default: default:
if (Loc) *Loc = getLocStart(); if (Loc) *Loc = getLocStart();
return false; return false;
case ImplicitCastExprClass:
return cast<ImplicitCastExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Loc, isEvaluated);
case ParenExprClass: case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()-> return cast<ParenExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Loc, isEvaluated); isIntegerConstantExpr(Result, Loc, isEvaluated);

Просмотреть файл

@ -567,14 +567,25 @@ Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result); return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result);
} }
QualType Sema::DefaultFunctionArrayConversion(Expr *&expr) { // promoteExprToType - a helper function to ensure we create exactly one
QualType t = expr->getType(); // ImplicitCastExpr. As a convenience (to the caller), we return the type.
static QualType promoteExprToType(Expr *&expr, QualType type) {
if (ImplicitCastExpr *impCast = dyn_cast<ImplicitCastExpr>(expr))
impCast->setType(type);
else
expr = new ImplicitCastExpr(type, expr);
return type;
}
/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
QualType Sema::DefaultFunctionArrayConversion(Expr *&e) {
QualType t = e->getType();
assert(!t.isNull() && "DefaultFunctionArrayConversion - missing type"); assert(!t.isNull() && "DefaultFunctionArrayConversion - missing type");
if (t->isFunctionType()) // C99 6.3.2.1p4 if (t->isFunctionType())
return Context.getPointerType(t); return promoteExprToType(e, Context.getPointerType(t));
if (const ArrayType *ary = dyn_cast<ArrayType>(t.getCanonicalType())) if (const ArrayType *ary = dyn_cast<ArrayType>(t.getCanonicalType()))
return Context.getPointerType(ary->getElementType()); // C99 6.3.2.1p3 return promoteExprToType(e, Context.getPointerType(ary->getElementType()));
return t; return t;
} }
@ -587,10 +598,8 @@ QualType Sema::UsualUnaryConversions(Expr *&expr) {
QualType t = expr->getType(); QualType t = expr->getType();
assert(!t.isNull() && "UsualUnaryConversions - missing type"); assert(!t.isNull() && "UsualUnaryConversions - missing type");
if (t->isPromotableIntegerType()) { // C99 6.3.1.1p2 if (t->isPromotableIntegerType()) // C99 6.3.1.1p2
// expr = new ImplicitCastExpr(Context.IntTy, expr); return promoteExprToType(expr, Context.IntTy);
return Context.IntTy;
}
return DefaultFunctionArrayConversion(expr); return DefaultFunctionArrayConversion(expr);
} }
@ -619,26 +628,36 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
// Handle complex types first (C99 6.3.1.8p1). // Handle complex types first (C99 6.3.1.8p1).
if (lhs->isComplexType() || rhs->isComplexType()) { if (lhs->isComplexType() || rhs->isComplexType()) {
// if we have an integer operand, the result is the complex type. // if we have an integer operand, the result is the complex type.
if (rhs->isIntegerType()) if (rhs->isIntegerType()) // convert the rhs to the lhs complex type.
return lhs; return promoteExprToType(rhsExpr, lhs);
if (lhs->isIntegerType())
return rhs;
return Context.maxComplexType(lhs, rhs); if (lhs->isIntegerType()) // convert the lhs to the rhs complex type.
return promoteExprToType(lhsExpr, rhs);
// Two complex types. Convert the smaller operand to the bigger result.
if (Context.maxComplexType(lhs, rhs) == lhs) // convert the rhs
return promoteExprToType(rhsExpr, lhs);
return promoteExprToType(lhsExpr, rhs); // convert the lhs
} }
// Now handle "real" floating types (i.e. float, double, long double). // Now handle "real" floating types (i.e. float, double, long double).
if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) { if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
// if we have an integer operand, the result is the real floating type. // if we have an integer operand, the result is the real floating type.
if (rhs->isIntegerType()) if (rhs->isIntegerType()) // convert the rhs to the lhs floating point type.
return lhs; return promoteExprToType(rhsExpr, lhs);
if (lhs->isIntegerType())
return rhs;
// we have two real floating types, float/complex combos were handled above. if (lhs->isIntegerType()) // convert the lhs to the rhs floating point type.
return Context.maxFloatingType(lhs, rhs); return promoteExprToType(lhsExpr, rhs);
// We have two real floating types, float/complex combos were handled above.
// Convert the smaller operand to the bigger result.
if (Context.maxFloatingType(lhs, rhs) == lhs) // convert the rhs
return promoteExprToType(rhsExpr, lhs);
return promoteExprToType(lhsExpr, rhs); // convert the lhs
} }
return Context.maxIntegerType(lhs, rhs); // Finally, we have two differing integer types.
if (Context.maxIntegerType(lhs, rhs) == lhs) // convert the rhs
return promoteExprToType(rhsExpr, lhs);
return promoteExprToType(lhsExpr, rhs); // convert the lhs
} }
// CheckPointerTypesForAssignment - This is a very tricky routine (despite // CheckPointerTypesForAssignment - This is a very tricky routine (despite

Просмотреть файл

@ -34,6 +34,7 @@ protected:
~Expr() {} ~Expr() {}
public: public:
QualType getType() const { return TR; } QualType getType() const { return TR; }
void setType(QualType t) { TR = t; }
/// SourceLocation tokens are not useful in isolation - they are low level /// SourceLocation tokens are not useful in isolation - they are low level
/// value objects created/interpreted by SourceManager. We assume AST /// value objects created/interpreted by SourceManager. We assume AST