aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-10-16 03:51:50 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-10-16 03:51:50 +0000
commit5db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afb (patch)
tree15a37364326fcef126fcbf59b036bce17e39e0ed /lib/AST/ExprConstant.cpp
parent3b0db908ebd07eaa26bc90deba5e826de00fe515 (diff)
Teach tryEvaluate that fabs, copysign, and unary +/- are constants for
floats. - With testcase, which also has some other things GCC folds but we don't commented out in it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57624 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index cc2b4e6735..5bc4170e70 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -586,6 +586,7 @@ public:
bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
bool VisitCallExpr(const CallExpr *E);
+ bool VisitUnaryOperator(const UnaryOperator *E);
bool VisitBinaryOperator(const BinaryOperator *E);
bool VisitFloatingLiteral(const FloatingLiteral *E);
};
@@ -625,14 +626,48 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
}
}
return false;
+
+ case Builtin::BI__builtin_fabs:
+ case Builtin::BI__builtin_fabsf:
+ case Builtin::BI__builtin_fabsl:
+ if (!EvaluateFloat(E->getArg(0), Result, Info))
+ return false;
+
+ if (Result.isNegative())
+ Result.changeSign();
+ return true;
+
+ case Builtin::BI__builtin_copysign:
+ case Builtin::BI__builtin_copysignf:
+ case Builtin::BI__builtin_copysignl: {
+ APFloat RHS(0.);
+ if (!EvaluateFloat(E->getArg(0), Result, Info) ||
+ !EvaluateFloat(E->getArg(1), RHS, Info))
+ return false;
+ Result.copySign(RHS);
+ return true;
+ }
}
}
+bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
+ if (!EvaluateFloat(E->getSubExpr(), Result, Info))
+ return false;
+
+ switch (E->getOpcode()) {
+ default: return false;
+ case UnaryOperator::Plus:
+ return true;
+ case UnaryOperator::Minus:
+ Result.changeSign();
+ return true;
+ }
+}
bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
// FIXME: Diagnostics? I really don't understand how the warnings
// and errors are supposed to work.
- APFloat LHS(0.0), RHS(0.0);
+ APFloat RHS(0.0);
if (!EvaluateFloat(E->getLHS(), Result, Info))
return false;
if (!EvaluateFloat(E->getRHS(), RHS, Info))