diff options
author | Nate Begeman <natebegeman@mac.com> | 2009-01-18 03:20:47 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2009-01-18 03:20:47 +0000 |
commit | 59b5da6d853b4368b984700315adf7b37de05764 (patch) | |
tree | a87909833d6430bb5abcd31c866393a438fc67a8 /lib/AST/ExprConstant.cpp | |
parent | 77ecb3a28f21496ecfdbb3d5f5b66b0d2abf48c9 (diff) |
Support evaluation of vector constant expressions, and codegen of same.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62455 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index b5a234c508..f45bd787b5 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -318,6 +318,78 @@ APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { } //===----------------------------------------------------------------------===// +// Vector Evaluation +//===----------------------------------------------------------------------===// + +namespace { + class VISIBILITY_HIDDEN VectorExprEvaluator + : public StmtVisitor<VectorExprEvaluator, APValue> { + EvalInfo &Info; + public: + + VectorExprEvaluator(EvalInfo &info) : Info(info) {} + + APValue VisitStmt(Stmt *S) { + return APValue(); + } + + APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } + APValue VisitCastExpr(const CastExpr* E); + APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); + APValue VisitInitListExpr(const InitListExpr *E); + }; +} // end anonymous namespace + +static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { + if (!E->getType()->isVectorType()) + return false; + Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E)); + return !Result.isUninit(); +} + +APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { + const Expr* SE = E->getSubExpr(); + + // Check for vector->vector bitcast. + if (SE->getType()->isVectorType()) + return this->Visit(const_cast<Expr*>(SE)); + + return APValue(); +} + +APValue +VectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { + return this->Visit(const_cast<Expr*>(E->getInitializer())); +} + +APValue +VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { + const VectorType *VT = E->getType()->getAsVectorType(); + unsigned NumInits = E->getNumInits(); + + if (!VT || VT->getNumElements() != NumInits) + return APValue(); + + QualType EltTy = VT->getElementType(); + llvm::SmallVector<APValue, 4> Elements; + + for (unsigned i = 0; i < NumInits; i++) { + if (EltTy->isIntegerType()) { + llvm::APSInt sInt(32); + if (!EvaluateInteger(E->getInit(i), sInt, Info)) + return APValue(); + Elements.push_back(APValue(sInt)); + } else { + llvm::APFloat f(0.0); + if (!EvaluateFloat(E->getInit(i), f, Info)) + return APValue(); + Elements.push_back(APValue(f)); + } + } + return APValue(&Elements[0], Elements.size()); +} + +//===----------------------------------------------------------------------===// // Integer Evaluation //===----------------------------------------------------------------------===// @@ -1067,6 +1139,7 @@ bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) { Expr* SubExpr = E->getSubExpr(); + const llvm::fltSemantics& destSemantics = Info.Ctx.getFloatTypeSemantics(E->getType()); if (SubExpr->getType()->isIntegralType()) { @@ -1189,7 +1262,10 @@ APValue ComplexFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const { EvalInfo Info(Ctx, Result); - if (getType()->isIntegerType()) { + if (getType()->isVectorType()) { + if (!EvaluateVector(this, Result.Val, Info)) + return false; + } else if (getType()->isIntegerType()) { llvm::APSInt sInt(32); if (!EvaluateInteger(this, sInt, Info)) return false; |