diff options
author | Chris Lattner <sabre@nondot.org> | 2008-10-06 05:28:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-10-06 05:28:25 +0000 |
commit | 019f4e858e78587f2241ff1a76c747d7bcd7578c (patch) | |
tree | 547758f5452c62ccf094e935363664059273a220 /lib/AST/ExprConstant.cpp | |
parent | cb888967400a03504c88acedd5248d6778a82f46 (diff) |
Add a comment that describes tryEvaluate. Make tryEvaluate fold
__builtin_constant_p properly, and add some scaffolding for
FloatExprEvaluator to eventually handle huge_val and inf.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57152 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index e987617811..45724d318c 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -245,14 +245,25 @@ bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { return Error(E->getLocStart(), diag::err_expr_not_constant); } - bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); - // __builtin_type_compatible_p is a constant. - if (E->isBuiltinClassifyType(Result)) - return true; - return Error(E->getLocStart(), diag::err_expr_not_constant); + switch (E->isBuiltinCall()) { + default: + return Error(E->getLocStart(), diag::err_expr_not_constant); + case Builtin::BI__builtin_classify_type: + // __builtin_type_compatible_p is a constant. Return its value. + E->isBuiltinClassifyType(Result); + return true; + + case Builtin::BI__builtin_constant_p: { + // __builtin_constant_p always has one operand: it returns true if that + // operand can be folded, false otherwise. + APValue Res; + Result = E->getArg(0)->tryEvaluate(Res, Info.Ctx); + return true; + } + } } bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { @@ -520,6 +531,7 @@ public: } bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + bool VisitCallExpr(const CallExpr *E); bool VisitBinaryOperator(const BinaryOperator *E); bool VisitFloatingLiteral(const FloatingLiteral *E); @@ -530,6 +542,22 @@ static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) { return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); } +bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { + //Result.zextOrTrunc(getIntTypeSizeInBits(E->getType())); + + switch (E->isBuiltinCall()) { + case Builtin::BI__builtin_huge_val: + case Builtin::BI__builtin_huge_valf: + case Builtin::BI__builtin_huge_vall: + case Builtin::BI__builtin_inf: + case Builtin::BI__builtin_inff: + case Builtin::BI__builtin_infl: + // FIXME: Implement me. + default: return false; + } +} + + bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // FIXME: Diagnostics? I really don't understand how the warnings // and errors are supposed to work. @@ -568,6 +596,10 @@ bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { // Top level TryEvaluate. //===----------------------------------------------------------------------===// +/// tryEvaluate - Return true if this is a constant which we can fold using +/// any crazy technique (that has nothing to do with language standards) that +/// we want to. If this function returns true, it returns the folded constant +/// in Result. bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const { EvalInfo Info(Ctx); if (getType()->isIntegerType()) { |