зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
c3f8937483
Коммит
fa2eaabd30
|
@ -278,6 +278,9 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc,
|
|||
default:
|
||||
if (Loc) *Loc = getLocStart();
|
||||
return false;
|
||||
case ImplicitCastExprClass:
|
||||
return cast<ImplicitCastExpr>(this)->getSubExpr()->
|
||||
isIntegerConstantExpr(Result, Loc, isEvaluated);
|
||||
case ParenExprClass:
|
||||
return cast<ParenExpr>(this)->getSubExpr()->
|
||||
isIntegerConstantExpr(Result, Loc, isEvaluated);
|
||||
|
|
|
@ -567,14 +567,25 @@ Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
|
|||
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result);
|
||||
}
|
||||
|
||||
QualType Sema::DefaultFunctionArrayConversion(Expr *&expr) {
|
||||
QualType t = expr->getType();
|
||||
// promoteExprToType - a helper function to ensure we create exactly one
|
||||
// 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");
|
||||
|
||||
if (t->isFunctionType()) // C99 6.3.2.1p4
|
||||
return Context.getPointerType(t);
|
||||
if (t->isFunctionType())
|
||||
return promoteExprToType(e, Context.getPointerType(t));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -587,10 +598,8 @@ QualType Sema::UsualUnaryConversions(Expr *&expr) {
|
|||
QualType t = expr->getType();
|
||||
assert(!t.isNull() && "UsualUnaryConversions - missing type");
|
||||
|
||||
if (t->isPromotableIntegerType()) { // C99 6.3.1.1p2
|
||||
// expr = new ImplicitCastExpr(Context.IntTy, expr);
|
||||
return Context.IntTy;
|
||||
}
|
||||
if (t->isPromotableIntegerType()) // C99 6.3.1.1p2
|
||||
return promoteExprToType(expr, Context.IntTy);
|
||||
return DefaultFunctionArrayConversion(expr);
|
||||
}
|
||||
|
||||
|
@ -619,26 +628,36 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
|
|||
// Handle complex types first (C99 6.3.1.8p1).
|
||||
if (lhs->isComplexType() || rhs->isComplexType()) {
|
||||
// if we have an integer operand, the result is the complex type.
|
||||
if (rhs->isIntegerType())
|
||||
return lhs;
|
||||
if (lhs->isIntegerType())
|
||||
return rhs;
|
||||
if (rhs->isIntegerType()) // convert the rhs to the lhs complex type.
|
||||
return promoteExprToType(rhsExpr, lhs);
|
||||
|
||||
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).
|
||||
if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
|
||||
// if we have an integer operand, the result is the real floating type.
|
||||
if (rhs->isIntegerType())
|
||||
return lhs;
|
||||
if (lhs->isIntegerType())
|
||||
return rhs;
|
||||
if (rhs->isIntegerType()) // convert the rhs to the lhs floating point type.
|
||||
return promoteExprToType(rhsExpr, lhs);
|
||||
|
||||
// we have two real floating types, float/complex combos were handled above.
|
||||
return Context.maxFloatingType(lhs, rhs);
|
||||
if (lhs->isIntegerType()) // convert the lhs to the rhs floating point type.
|
||||
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
|
||||
|
|
|
@ -34,6 +34,7 @@ protected:
|
|||
~Expr() {}
|
||||
public:
|
||||
QualType getType() const { return TR; }
|
||||
void setType(QualType t) { TR = t; }
|
||||
|
||||
/// SourceLocation tokens are not useful in isolation - they are low level
|
||||
/// value objects created/interpreted by SourceManager. We assume AST
|
||||
|
|
Загрузка…
Ссылка в новой задаче