diff options
author | Anders Carlsson <andersca@mac.com> | 2008-11-16 07:17:21 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-11-16 07:17:21 +0000 |
commit | 286f85e791dda3634fee7f6c67f0ed92296c028f (patch) | |
tree | 48190a5730db845627b63a531047b39c77e566b3 /lib/AST/ExprConstant.cpp | |
parent | cb529b542a6c473251d15fdd637b3230906ea1dc (diff) |
Add the ability to evaluate comparison operators with floating point numbers as operands.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 87ee465174..08236836a7 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -529,8 +529,51 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return false; } - if (!E->getLHS()->getType()->isIntegralType() || - !E->getRHS()->getType()->isIntegralType()) { + QualType LHSTy = E->getLHS()->getType(); + QualType RHSTy = E->getRHS()->getType(); + + if (LHSTy->isRealFloatingType() && + RHSTy->isRealFloatingType()) { + APFloat RHS(0.0), LHS(0.0); + + if (!EvaluateFloat(E->getRHS(), RHS, Info)) + return false; + + if (!EvaluateFloat(E->getLHS(), LHS, Info)) + return false; + + APFloat::cmpResult CR = LHS.compare(RHS); + + switch (E->getOpcode()) { + default: + assert(0 && "Invalid binary operator!"); + case BinaryOperator::LT: + Result = CR == APFloat::cmpLessThan; + break; + case BinaryOperator::GT: + Result = CR == APFloat::cmpGreaterThan; + break; + case BinaryOperator::LE: + Result = CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual; + break; + case BinaryOperator::GE: + Result = CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual; + break; + case BinaryOperator::EQ: + Result = CR == APFloat::cmpEqual; + break; + case BinaryOperator::NE: + Result = CR == APFloat::cmpGreaterThan || CR == APFloat::cmpLessThan; + break; + } + + Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); + Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); + return true; + } + + if (!LHSTy->isIntegralType() || + !RHSTy->isIntegralType()) { // We can't continue from here for non-integral types, and they // could potentially confuse the following operations. // FIXME: Deal with EQ and friends. |