ExprConstant.cpp revision f5eeb055ecbadbc25c83df0867cdada2c2559dcf
1c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson//===--- Expr.cpp - Expression Constant Evaluator -------------------------===// 2c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 3c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// The LLVM Compiler Infrastructure 4c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 5c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// This file is distributed under the University of Illinois Open Source 6c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// License. See LICENSE.TXT for details. 7c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 8c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson//===----------------------------------------------------------------------===// 9c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 10c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// This file implements the Expr constant evaluator. 11c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson// 12c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson//===----------------------------------------------------------------------===// 13c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 14c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#include "clang/AST/APValue.h" 15c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#include "clang/AST/ASTContext.h" 16c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson#include "clang/AST/Expr.h" 170fe52e1bcaa69ba127f1bda036f057fec1f478deSeo Sanghyeon#include "clang/AST/StmtVisitor.h" 1806a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson#include "clang/Basic/TargetInfo.h" 19c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#include "llvm/Support/Compiler.h" 20c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlssonusing namespace clang; 21f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerusing llvm::APSInt; 22c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 23c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#define USE_NEW_EVALUATOR 0 24c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 25f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerstatic bool CalcFakeICEVal(const Expr *Expr, 26f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner llvm::APSInt &Result, 27f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner ASTContext &Context) { 28c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson // Calculate the value of an expression that has a calculatable 29c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson // value, but isn't an ICE. Currently, this only supports 30c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson // a very narrow set of extensions, but it can be expanded if needed. 31c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson if (const ParenExpr *PE = dyn_cast<ParenExpr>(Expr)) 32c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return CalcFakeICEVal(PE->getSubExpr(), Result, Context); 33c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 34c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) { 35c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson QualType CETy = CE->getType(); 36c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson if ((CETy->isIntegralType() && !CETy->isBooleanType()) || 37c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson CETy->isPointerType()) { 38c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) { 39c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson Result.extOrTrunc(Context.getTypeSize(CETy)); 40c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson // FIXME: This assumes pointers are signed. 41c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson Result.setIsSigned(CETy->isSignedIntegerType() || 42c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson CETy->isPointerType()); 43c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return true; 44c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson } 45c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson } 46c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson } 47c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 48c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson if (Expr->getType()->isIntegralType()) 49c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return Expr->isIntegerConstantExpr(Result, Context); 50c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 51c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return false; 52c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson} 53c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 54f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerstatic bool EvaluatePointer(const Expr *E, APValue &Result, ASTContext &Ctx); 55f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerstatic bool EvaluateInteger(const Expr *E, APSInt &Result, ASTContext &Ctx); 56f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 57f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 58f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 59f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Pointer Evaluation 60f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 61f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 62c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlssonnamespace { 632bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonclass VISIBILITY_HIDDEN PointerExprEvaluator 642bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson : public StmtVisitor<PointerExprEvaluator, APValue> { 652bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson ASTContext &Ctx; 662bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonpublic: 672bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 68f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner PointerExprEvaluator(ASTContext &ctx) : Ctx(ctx) {} 69f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 702bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson APValue VisitStmt(Stmt *S) { 712bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson // FIXME: Remove this when we support more expressions. 72650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson printf("Unhandled pointer statement\n"); 732bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson S->dump(); 742bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson return APValue(); 752bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 762bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 772bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 782bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 79650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue VisitBinaryOperator(const BinaryOperator *E); 80650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue VisitCastExpr(const CastExpr* E); 812bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson}; 82f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 832bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 84f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerstatic bool EvaluatePointer(const Expr* E, APValue& Result, ASTContext &Ctx) { 85f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!E->getType()->isPointerType()) 86f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return false; 87f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner Result = PointerExprEvaluator(Ctx).Visit(const_cast<Expr*>(E)); 88f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return Result.isLValue(); 89f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 90650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 91f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris LattnerAPValue PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 92650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getOpcode() != BinaryOperator::Add && 93650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson E->getOpcode() != BinaryOperator::Sub) 94650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 95650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 96650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *PExp = E->getLHS(); 97650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *IExp = E->getRHS(); 98650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (IExp->getType()->isPointerType()) 99f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner std::swap(PExp, IExp); 100650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 101650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue ResultLValue; 102f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluatePointer(PExp, ResultLValue, Ctx)) 103650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 104f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 105650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt AdditionalOffset(32); 106f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluateInteger(IExp, AdditionalOffset, Ctx)) 107650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 108650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 109650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson uint64_t Offset = ResultLValue.getLValueOffset(); 110650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getOpcode() == BinaryOperator::Add) 111650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Offset += AdditionalOffset.getZExtValue(); 112650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson else 113650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Offset -= AdditionalOffset.getZExtValue(); 114650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 115650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(ResultLValue.getLValueBase(), Offset); 116650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 117650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 118650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 119650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders CarlssonAPValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) 120650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson{ 121650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr* SubExpr = E->getSubExpr(); 122650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 123650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // Check for pointer->pointer cast 124650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (SubExpr->getType()->isPointerType()) { 125650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson APValue Result; 126f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (EvaluatePointer(SubExpr, Result, Ctx)) 127650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return Result; 128f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return APValue(); 129650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 130650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 131650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (SubExpr->getType()->isArithmeticType()) { 132650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt Result(32); 133f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (EvaluateInteger(SubExpr, Result, Ctx)) { 134650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result.extOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType()))); 135650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(0, Result.getZExtValue()); 136650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 137650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 138650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 139650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson assert(0 && "Unhandled cast"); 140650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 141650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 142650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 143f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 144f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 145f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Integer Evaluation 146f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 147f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 148f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 149f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnernamespace { 150f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerclass VISIBILITY_HIDDEN IntExprEvaluator 151f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner : public StmtVisitor<IntExprEvaluator, APValue> { 152f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner ASTContext &Ctx; 153f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 154f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerpublic: 155f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner IntExprEvaluator(ASTContext &ctx) : Ctx(ctx) {} 156f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 157f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 158f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner // Visitor Methods 159f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 160f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitStmt(Stmt *S) { 161f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner // FIXME: Remove this when we support more expressions. 162f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner printf("unhandled int expression"); 163f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner S->dump(); 164f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return APValue(); 165f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 166f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 167f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 168f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 169f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitBinaryOperator(const BinaryOperator *E); 170f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitUnaryOperator(const UnaryOperator *E); 171f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 172f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue HandleCast(const Expr* SubExpr, QualType DestType); 173f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitCastExpr(const CastExpr* E) { 174f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return HandleCast(E->getSubExpr(), E->getType()); 175f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 176f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitImplicitCastExpr(const ImplicitCastExpr* E) { 177f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return HandleCast(E->getSubExpr(), E->getType()); 178f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 179f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E); 180f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 181f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue VisitIntegerLiteral(const IntegerLiteral *E) { 182f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner llvm::APSInt Result(Ctx.getTypeSize(E->getType())); 183f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 184f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner Result = E->getValue(); 185f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return APValue(Result); 186f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 187f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner}; 188f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 189f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 190f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerstatic bool EvaluateInteger(const Expr* E, APSInt &Result, ASTContext &Ctx) { 191f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner APValue Value = IntExprEvaluator(Ctx).Visit(const_cast<Expr*>(E)); 192f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!Value.isSInt()) 193f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return false; 194f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 195f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner Result = Value.getSInt(); 196f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner return true; 197f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 198f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 199f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 200a25ae3d68d84d2b89907f998df6a396549589da5Anders CarlssonAPValue IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 201a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // The LHS of a constant expr is always evaluated and needed. 202a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson llvm::APSInt Result(32); 203f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluateInteger(E->getLHS(), Result, Ctx)) 204a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 205a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 206a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson llvm::APSInt RHS(32); 207f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluateInteger(E->getRHS(), RHS, Ctx)) 208a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 209a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 210a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson switch (E->getOpcode()) { 211a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson default: 212a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 213a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Mul: 214a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result *= RHS; 215a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 216a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Div: 217a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (RHS == 0) 218a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 219a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result /= RHS; 220a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 221a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Rem: 222a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (RHS == 0) 22306a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson return APValue(); 224a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result %= RHS; 225a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 226a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Add: Result += RHS; break; 227a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Sub: Result -= RHS; break; 228a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Shl: 229a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result <<= 230a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1)); 231a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 232a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Shr: 233a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result >>= 234a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson static_cast<uint32_t>(RHS.getLimitedValue(Result.getBitWidth()-1)); 235a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson break; 236a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::LT: Result = Result < RHS; break; 237a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::GT: Result = Result > RHS; break; 238a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::LE: Result = Result <= RHS; break; 239a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::GE: Result = Result >= RHS; break; 240a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::EQ: Result = Result == RHS; break; 241a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::NE: Result = Result != RHS; break; 242a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::And: Result &= RHS; break; 243a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Xor: Result ^= RHS; break; 244a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Or: Result |= RHS; break; 24506a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 246a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case BinaryOperator::Comma: 247a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // C99 6.6p3: "shall not contain assignment, ..., or comma operators, 248a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // *except* when they are contained within a subexpression that is not 249a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // evaluated". Note that Assignment can never happen due to constraints 250a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // on the LHS subexpr, so we don't need to check it here. 251a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // FIXME: Need to come up with an efficient way to deal with the C99 252a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // rules on evaluation while still evaluating this. Maybe a 253a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // "evaluated comma" out parameter? 254a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 255a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } 256a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 257a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 258a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 259a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(Result); 260a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 261a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 262a25ae3d68d84d2b89907f998df6a396549589da5Anders CarlssonAPValue IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 263a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson llvm::APSInt Result(32); 264a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 265a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (E->isOffsetOfOp()) 266a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = E->evaluateOffsetOf(Ctx); 267a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson else if (E->isSizeOfAlignOfOp()) { 268a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Return the result in the right width. 269a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType()))); 270a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 271a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // sizeof(void) and __alignof__(void) = 1 as a gcc extension. 272a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (E->getSubExpr()->getType()->isVoidType()) 273a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = 1; 274a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 275a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. 276a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (!E->getSubExpr()->getType()->isConstantSizeType()) { 277a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // FIXME: Should we attempt to evaluate this? 278a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 279a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } 280a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 281a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Get information about the size or align. 282a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (E->getSubExpr()->getType()->isFunctionType()) { 283a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // GCC extension: sizeof(function) = 1. 284a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // FIXME: AlignOf shouldn't be unconditionally 4! 285a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = E->getOpcode() == UnaryOperator::AlignOf ? 4 : 1; 286a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } else { 287a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson unsigned CharSize = Ctx.Target.getCharWidth(); 288a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (E->getOpcode() == UnaryOperator::AlignOf) 289a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = Ctx.getTypeAlign(E->getSubExpr()->getType()) / CharSize; 290a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson else 291a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = Ctx.getTypeSize(E->getSubExpr()->getType()) / CharSize; 292a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } 293a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } else { 294a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Get the operand value. If this is sizeof/alignof, do not evalute the 295a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // operand. This affects C99 6.6p3. 296f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluateInteger(E->getSubExpr(), Result, Ctx)) 297a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 298a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 29906a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson switch (E->getOpcode()) { 300a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Address, indirect, pre/post inc/dec, etc are not valid constant exprs. 301a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // See C99 6.6p3. 30206a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson default: 30306a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson return APValue(); 304a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case UnaryOperator::Extension: 305a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson assert(0 && "Handle UnaryOperator::Extension"); 306a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 307a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case UnaryOperator::LNot: { 308a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson bool Val = Result == 0; 309a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson uint32_t typeSize = Ctx.getTypeSize(E->getType()); 310a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.zextOrTrunc(typeSize); 311a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = Val; 31206a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson break; 313a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } 314a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case UnaryOperator::Plus: 31506a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson break; 316a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case UnaryOperator::Minus: 317a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = -Result; 31806a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson break; 319a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson case UnaryOperator::Not: 320a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = ~Result; 32106a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson break; 32206a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 32306a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 32406a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 325a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 326a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(Result); 327a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 328a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 329a25ae3d68d84d2b89907f998df6a396549589da5Anders CarlssonAPValue IntExprEvaluator::HandleCast(const Expr* SubExpr, QualType DestType) { 330a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson llvm::APSInt Result(32); 33106a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 332a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson uint32_t DestWidth = static_cast<uint32_t>(Ctx.getTypeSize(DestType)); 33306a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson 334a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Handle simple integer->integer casts. 335a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (SubExpr->getType()->isIntegerType()) { 336f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluateInteger(SubExpr, Result, Ctx)) 337a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 3382bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 339a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Figure out if this is a truncate, extend or noop cast. 340a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // If the input is signed, do a sign extend, noop, or truncate. 341a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (DestType->isBooleanType()) { 342a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Conversion to bool compares against zero. 343a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result = Result != 0; 344a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.zextOrTrunc(DestWidth); 3452bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 346a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson else 347a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.extOrTrunc(DestWidth); 348a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } else if (SubExpr->getType()->isPointerType()) { 349a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson APValue LV; 350f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner if (!EvaluatePointer(SubExpr, LV, Ctx)) 351a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 352a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson if (LV.getLValueBase()) 353a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(); 3542bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 355559e56b3a201316ae0b7e7389879a8054f6a3a82Anders Carlsson Result.extOrTrunc(DestWidth); 356559e56b3a201316ae0b7e7389879a8054f6a3a82Anders Carlsson Result = LV.getLValueOffset(); 357a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson } else { 358a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson assert(0 && "Unhandled cast!"); 3592bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 3602bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 361a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 362a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson return APValue(Result); 363a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 3642bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 365f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris LattnerAPValue IntExprEvaluator:: 366f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner VisitSizeOfAlignOfTypeExpr(const SizeOfAlignOfTypeExpr *E) { 367650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson llvm::APSInt Result(32); 368650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 369650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // Return the result in the right width. 370650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(E->getType()))); 371650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 372650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // sizeof(void) and __alignof__(void) = 1 as a gcc extension. 373650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getArgumentType()->isVoidType()) { 374650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result = 1; 375650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 376650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(Result); 377650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 378650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 379650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // alignof always evaluates to a constant, sizeof does if arg is not VLA. 380650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->isSizeOf() && !E->getArgumentType()->isConstantSizeType()) 381650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(); 382650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 383650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // Get information about the size or align. 384650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->getArgumentType()->isFunctionType()) { 385650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson // GCC extension: sizeof(function) = 1. 386650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result = E->isSizeOf() ? 1 : 4; 387650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } else { 388650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson unsigned CharSize = Ctx.Target.getCharWidth(); 389650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (E->isSizeOf()) 390650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result = Ctx.getTypeSize(E->getArgumentType()) / CharSize; 391650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson else 392650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result = Ctx.getTypeAlign(E->getArgumentType()) / CharSize; 393650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 394650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 395650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson Result.setIsUnsigned(E->getType()->isUnsignedIntegerType()); 396650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson return APValue(Result); 397650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 398650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 399f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 400f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Top level TryEvaluate. 401f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 402f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 403f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerbool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const { 404c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson llvm::APSInt sInt(1); 405c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 406c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#if USE_NEW_EVALUATOR 40706a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson if (getType()->isIntegerType()) { 40806a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson if (IntExprEvaluator::Evaluate(this, sInt, Ctx)) { 40906a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson Result = APValue(sInt); 41006a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson return true; 41106a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 41206a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } else 413c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson return false; 414c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson 415c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#else 416c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson if (CalcFakeICEVal(this, sInt, Ctx)) { 417c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson Result = APValue(sInt); 418c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return true; 419c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson } 420c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlsson#endif 421c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 422c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson return false; 423c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson} 424