//===--- Expr.cpp - Expression Constant Evaluator -------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the Expr constant evaluator. // //===----------------------------------------------------------------------===// #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" using namespace clang; static bool CalcFakeICEVal(const Expr* Expr, llvm::APSInt& Result, ASTContext& Context) { // Calculate the value of an expression that has a calculatable // value, but isn't an ICE. Currently, this only supports // a very narrow set of extensions, but it can be expanded if needed. if (const ParenExpr *PE = dyn_cast(Expr)) return CalcFakeICEVal(PE->getSubExpr(), Result, Context); if (const CastExpr *CE = dyn_cast(Expr)) { QualType CETy = CE->getType(); if ((CETy->isIntegralType() && !CETy->isBooleanType()) || CETy->isPointerType()) { if (CalcFakeICEVal(CE->getSubExpr(), Result, Context)) { Result.extOrTrunc(Context.getTypeSize(CETy)); // FIXME: This assumes pointers are signed. Result.setIsSigned(CETy->isSignedIntegerType() || CETy->isPointerType()); return true; } } } if (Expr->getType()->isIntegralType()) return Expr->isIntegerConstantExpr(Result, Context); return false; } bool Expr::tryEvaluate(APValue& Result, ASTContext &Ctx) const { llvm::APSInt sInt(1); if (CalcFakeICEVal(this, sInt, Ctx)) { Result = APValue(sInt); return true; } return false; }