ExprConstant.cpp revision d0dcceae2a8ca0e37b5dd471a704de8583d49c95
1b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner//===--- ExprConstant.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" 16199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h" 1719cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson#include "clang/AST/RecordLayout.h" 180fe52e1bcaa69ba127f1bda036f057fec1f478deSeo Sanghyeon#include "clang/AST/StmtVisitor.h" 198ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor#include "clang/AST/TypeLoc.h" 20500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/AST/ASTDiagnostic.h" 218ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor#include "clang/AST/Expr.h" 221b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner#include "clang/Basic/Builtins.h" 2306a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson#include "clang/Basic/TargetInfo.h" 247462b39a9bccaf4392687831036713f09f9c0681Mike Stump#include "llvm/ADT/SmallString.h" 254572baba9d18c275968ac113fd73b0e3c77cccb8Mike Stump#include <cstring> 264572baba9d18c275968ac113fd73b0e3c77cccb8Mike Stump 27c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlssonusing namespace clang; 28f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerusing llvm::APSInt; 29d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanusing llvm::APFloat; 30c44eec6dd29ee9415cbd38a35deff4c8b67abb6aAnders Carlsson 3187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// EvalInfo - This is a private struct used by the evaluator to capture 3287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// information about a subexpression as it is folded. It retains information 3387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// about the AST context, but also maintains information about the folded 3487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// expression. 3587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// 3687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// If an expression could be evaluated, it is still possible it is not a C 3787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// "integer constant expression" or constant expression. If not, this struct 3887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// captures information about how and why not. 3987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// 4087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// One bit of information passed *into* the request for constant folding 4187eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// indicates whether the subexpression is "evaluated" or not according to C 4287eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// rules. For example, the RHS of (0 && foo()) is not evaluated. We can 4387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// evaluate the expression regardless of what the RHS is, but C only allows 4487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner/// certain things in certain situations. 45c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramernamespace { 46d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith struct CallStackFrame; 47d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 48c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer struct EvalInfo { 49c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer const ASTContext &Ctx; 501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 511e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith /// EvalStatus - Contains information about the evaluation. 521e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith Expr::EvalStatus &EvalStatus; 53f0c1e4b679e15c26bffb5892e35985bf3c52f77aAnders Carlsson 54d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// CurrentCall - The top of the constexpr call stack. 55d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const CallStackFrame *CurrentCall; 56d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 57d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// NumCalls - The number of calls we've evaluated so far. 58d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith unsigned NumCalls; 59d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 60d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// CallStackDepth - The number of calls in the call stack right now. 61d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith unsigned CallStackDepth; 62d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 63c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer typedef llvm::DenseMap<const OpaqueValueExpr*, APValue> MapTy; 64c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer MapTy OpaqueValues; 65c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer const APValue *getOpaqueValue(const OpaqueValueExpr *e) const { 66c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer MapTy::const_iterator i = OpaqueValues.find(e); 67c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer if (i == OpaqueValues.end()) return 0; 68c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer return &i->second; 69c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer } 7056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 711e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith EvalInfo(const ASTContext &C, Expr::EvalStatus &S) 72d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith : Ctx(C), EvalStatus(S), CurrentCall(0), NumCalls(0), CallStackDepth(0) {} 73f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith 74f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith const LangOptions &getLangOpts() { return Ctx.getLangOptions(); } 75c54061a679d8db4169438b2f97f81e3f443c6a25Benjamin Kramer }; 7687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 77d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// A stack frame in the constexpr call stack. 78d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith struct CallStackFrame { 79d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith EvalInfo &Info; 80d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 81d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// Parent - The caller of this stack frame. 82d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const CallStackFrame *Caller; 83d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 84d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// ParmBindings - Parameter bindings for this function call, indexed by 85d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// parameters' function scope indices. 86d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const APValue *Arguments; 87d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 88d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// CallIndex - The index of the current call. This is used to match lvalues 89d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// referring to parameters up with the corresponding stack frame, and to 90d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// detect when the parameter is no longer in scope. 91d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith unsigned CallIndex; 92d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 93d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith CallStackFrame(EvalInfo &Info, const APValue *Arguments) 94d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith : Info(Info), Caller(Info.CurrentCall), Arguments(Arguments), 95d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith CallIndex(Info.NumCalls++) { 96d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith Info.CurrentCall = this; 97d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith ++Info.CallStackDepth; 98d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 99d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith ~CallStackFrame() { 100d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith assert(Info.CurrentCall == this && "calls retired out of order"); 101d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith --Info.CallStackDepth; 102d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith Info.CurrentCall = Caller; 103d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 104d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith }; 105d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 106f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall struct ComplexValue { 107f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall private: 108f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool IsInt; 109f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 110f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall public: 111f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APSInt IntReal, IntImag; 112f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APFloat FloatReal, FloatImag; 113f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 114f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {} 115f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 116f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall void makeComplexFloat() { IsInt = false; } 117f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool isComplexFloat() const { return !IsInt; } 118f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APFloat &getComplexFloatReal() { return FloatReal; } 119f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APFloat &getComplexFloatImag() { return FloatImag; } 120f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 121f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall void makeComplexInt() { IsInt = true; } 122f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool isComplexInt() const { return IsInt; } 123f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APSInt &getComplexIntReal() { return IntReal; } 124f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APSInt &getComplexIntImag() { return IntImag; } 125f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 12656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall void moveInto(APValue &v) const { 127f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall if (isComplexFloat()) 128f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall v = APValue(FloatReal, FloatImag); 129f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall else 130f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall v = APValue(IntReal, IntImag); 131f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall } 13256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall void setFrom(const APValue &v) { 13356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall assert(v.isComplexFloat() || v.isComplexInt()); 13456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (v.isComplexFloat()) { 13556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall makeComplexFloat(); 13656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall FloatReal = v.getComplexFloatReal(); 13756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall FloatImag = v.getComplexFloatImag(); 13856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } else { 13956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall makeComplexInt(); 14056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall IntReal = v.getComplexIntReal(); 14156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall IntImag = v.getComplexIntImag(); 14256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 14356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 144f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall }; 145efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 146efdb83e26f9a1fd2566afe54461216cd84814d42John McCall struct LValue { 1478cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr *Base; 148efdb83e26f9a1fd2566afe54461216cd84814d42John McCall CharUnits Offset; 149efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 1508cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr *getLValueBase() { return Base; } 151efdb83e26f9a1fd2566afe54461216cd84814d42John McCall CharUnits getLValueOffset() { return Offset; } 152efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 15356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall void moveInto(APValue &v) const { 154efdb83e26f9a1fd2566afe54461216cd84814d42John McCall v = APValue(Base, Offset); 155efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 15656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall void setFrom(const APValue &v) { 15756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall assert(v.isLValue()); 15856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall Base = v.getLValueBase(); 15956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall Offset = v.getLValueOffset(); 16056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 161efdb83e26f9a1fd2566afe54461216cd84814d42John McCall }; 162f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall} 16387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 1641e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smithstatic bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E); 165efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info); 166efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info); 16787eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info); 168d9becd1846e2c72bf6ad283faa1b048f33dd3afeChris Lattnerstatic bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, 169d9becd1846e2c72bf6ad283faa1b048f33dd3afeChris Lattner EvalInfo &Info); 170d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info); 171f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCallstatic bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info); 172f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 173f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 1744efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman// Misc utilities 1754efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 1764efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 177e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnarastatic bool IsGlobalLValue(const Expr* E) { 17842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!E) return true; 17942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 18042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 18142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (isa<FunctionDecl>(DRE->getDecl())) 18242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return true; 18342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) 18442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return VD->hasGlobalStorage(); 18542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 18642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall } 18742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 18842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(E)) 18942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return CLE->isFileScope(); 19042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 191c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (isa<MemberExpr>(E)) 192c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 193c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 19442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return true; 19542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall} 19642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 197c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smithstatic bool EvalPointerValueAsBool(const LValue &Value, bool &Result) { 198efdb83e26f9a1fd2566afe54461216cd84814d42John McCall const Expr* Base = Value.Base; 199a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 2003554283157190e67918fad4221a5e6faf9317362John McCall // A null base expression indicates a null pointer. These are always 2013554283157190e67918fad4221a5e6faf9317362John McCall // evaluatable, and they are false unless the offset is zero. 2023554283157190e67918fad4221a5e6faf9317362John McCall if (!Base) { 2033554283157190e67918fad4221a5e6faf9317362John McCall Result = !Value.Offset.isZero(); 2043554283157190e67918fad4221a5e6faf9317362John McCall return true; 2053554283157190e67918fad4221a5e6faf9317362John McCall } 2063554283157190e67918fad4221a5e6faf9317362John McCall 20742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall // Require the base expression to be a global l-value. 208e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara if (!IsGlobalLValue(Base)) return false; 20942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 2103554283157190e67918fad4221a5e6faf9317362John McCall // We have a non-null base expression. These are generally known to 2113554283157190e67918fad4221a5e6faf9317362John McCall // be true, but if it'a decl-ref to a weak symbol it can be null at 2123554283157190e67918fad4221a5e6faf9317362John McCall // runtime. 2133554283157190e67918fad4221a5e6faf9317362John McCall Result = true; 214a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 2153554283157190e67918fad4221a5e6faf9317362John McCall const DeclRefExpr* DeclRef = dyn_cast<DeclRefExpr>(Base); 216a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola if (!DeclRef) 217a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola return true; 218a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 2193554283157190e67918fad4221a5e6faf9317362John McCall // If it's a weak symbol, it isn't constant-evaluable. 220a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola const ValueDecl* Decl = DeclRef->getDecl(); 221a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola if (Decl->hasAttr<WeakAttr>() || 222a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola Decl->hasAttr<WeakRefAttr>() || 2230a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor Decl->isWeakImported()) 224a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola return false; 225a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 2265bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return true; 2275bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman} 2285bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman 229c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smithstatic bool HandleConversionToBool(const APValue &Val, bool &Result) { 230c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith switch (Val.getKind()) { 231c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::Uninitialized: 232c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 233c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::Int: 234c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Result = Val.getInt().getBoolValue(); 23541bf4f38348561a0f12c10d34f1673cd19a6eb04Richard Smith return true; 236c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::Float: 237c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Result = !Val.getFloat().isZero(); 238a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman return true; 239c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::ComplexInt: 240c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Result = Val.getComplexIntReal().getBoolValue() || 241c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Val.getComplexIntImag().getBoolValue(); 242c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return true; 243c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::ComplexFloat: 244c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Result = !Val.getComplexFloatReal().isZero() || 245c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith !Val.getComplexFloatImag().isZero(); 246436c8898cd1c93c5bacd3fcc4ac586bc5cd77062Richard Smith return true; 247c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::LValue: 248c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith { 249c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith LValue PointerResult; 250c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith PointerResult.setFrom(Val); 251c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return EvalPointerValueAsBool(PointerResult, Result); 252c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 253c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case APValue::Vector: 254c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 2554efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 2564efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 257c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith llvm_unreachable("unknown APValue kind"); 258c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith} 259c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 260c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smithstatic bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, 261c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith EvalInfo &Info) { 262c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(E->isRValue() && "missing lvalue-to-rvalue conv in bool condition"); 263c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APValue Val; 264c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Evaluate(Val, Info, E)) 265c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 266c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return HandleConversionToBool(Val, Result); 2674efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 2684efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType, 2704ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APFloat &Value, const ASTContext &Ctx) { 271a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar unsigned DestWidth = Ctx.getIntWidth(DestType); 272a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // Determine whether we are converting to unsigned or signed. 273575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor bool DestSigned = DestType->isSignedIntegerOrEnumerationType(); 2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 275a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // FIXME: Warning for overflow. 2763e1ef7849845a9e7bf79156bbb8a2c26d77a1d2eJeffrey Yasskin APSInt Result(DestWidth, !DestSigned); 277a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar bool ignored; 2783e1ef7849845a9e7bf79156bbb8a2c26d77a1d2eJeffrey Yasskin (void)Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored); 2793e1ef7849845a9e7bf79156bbb8a2c26d77a1d2eJeffrey Yasskin return Result; 280a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 281a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType, 2834ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APFloat &Value, const ASTContext &Ctx) { 284a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar bool ignored; 285a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat Result = Value; 2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result.convert(Ctx.getFloatTypeSemantics(DestType), 287a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat::rmNearestTiesToEven, &ignored); 288a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return Result; 289a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 290a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APSInt HandleIntToIntCast(QualType DestType, QualType SrcType, 2924ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APSInt &Value, const ASTContext &Ctx) { 293a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar unsigned DestWidth = Ctx.getIntWidth(DestType); 294a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APSInt Result = Value; 295a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // Figure out if this is a truncate, extend or noop cast. 296a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // If the input is signed, do a sign extend, noop, or truncate. 2979f71a8f4c7a182a5236da9e747d57cc1d1bd24c2Jay Foad Result = Result.extOrTrunc(DestWidth); 298575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor Result.setIsUnsigned(DestType->isUnsignedIntegerOrEnumerationType()); 299a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return Result; 300a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 301a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 3021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType, 3034ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APSInt &Value, const ASTContext &Ctx) { 304a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 305a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1); 306a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result.convertFromAPInt(Value, Value.isSigned(), 307a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat::rmNearestTiesToEven); 308a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return Result; 309a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 310a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 31103f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith/// Try to evaluate the initializer for a variable declaration. 312d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smithstatic const APValue *EvaluateVarDeclInit(EvalInfo &Info, const VarDecl *VD) { 313d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // If this is a parameter to an active constexpr function call, perform 314d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // argument substitution. 315d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) { 316d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // FIXME This assumes that all parameters must be parameters of the current 317d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // call. Add the CallIndex to the LValue representation and use that to 318d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // check. 319d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (Info.CurrentCall) 320d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return &Info.CurrentCall->Arguments[PVD->getFunctionScopeIndex()]; 32103f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith return 0; 322d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 32303f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 32403f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith const Expr *Init = VD->getAnyInitializer(); 32503f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith if (!Init) 32603f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith return 0; 32703f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 32803f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith if (APValue *V = VD->getEvaluatedValue()) 32903f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith return V; 33003f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 33103f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith if (VD->isEvaluatingValue()) 33203f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith return 0; 33303f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 33403f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith VD->setEvaluatingValue(); 33503f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 33603f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith Expr::EvalResult EResult; 337c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith EvalInfo InitInfo(Info.Ctx, EResult); 338c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: The caller will need to know whether the value was a constant 339c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // expression. If not, we should propagate up a diagnostic. 340c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (Evaluate(EResult.Val, InitInfo, Init)) 34103f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith VD->setEvaluatedValue(EResult.Val); 34203f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith else 34303f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith VD->setEvaluatedValue(APValue()); 34403f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 34503f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith return VD->getEvaluatedValue(); 34603f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith} 34703f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 348c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smithstatic bool IsConstNonVolatile(QualType T) { 34903f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith Qualifiers Quals = T.getQualifiers(); 35003f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith return Quals.hasConst() && !Quals.hasVolatile(); 35103f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith} 35203f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith 353c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smithbool HandleLValueToRValueConversion(EvalInfo &Info, QualType Type, 354c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith const LValue &LVal, APValue &RVal) { 355c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith const Expr *Base = LVal.Base; 356c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 357c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Indirection through a null pointer deserves a diagnostic. 358c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Base) 359c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 360c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 361c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Support accessing subobjects of objects of literal types. A simple 362c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // byte offset is insufficient for C++11 semantics: we need to know how the 363c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // reference was formed (which union member was named, for instance). 364c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Support subobjects of StringLiteral and PredefinedExpr. 365c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!LVal.Offset.isZero()) 366c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 367c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 368c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith const Decl *D = 0; 369c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 370c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { 371c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // If the lvalue has been cast to some other type, don't try to read it. 372c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Could simulate a bitcast here. 373c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Info.Ctx.hasSameUnqualifiedType(Type, DRE->getType())) 374c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 375c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith D = DRE->getDecl(); 376c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 377c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 378c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Static data members accessed via a MemberExpr are represented as 379c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // that MemberExpr. We should use the Decl directly instead. 380c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base)) { 381c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Info.Ctx.hasSameUnqualifiedType(Type, ME->getType())) 382c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 383c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith D = ME->getMemberDecl(); 384c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(!isa<FieldDecl>(D) && "shouldn't see fields here"); 385c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 386c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 387c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (D) { 388c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // In C++98, const, non-volatile integers initialized with ICEs are ICEs. 389c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // In C++11, constexpr, non-volatile variables initialized with constant 390d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // expressions are constant expressions too. Inside constexpr functions, 391d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // parameters are constant expressions even if they're non-const. 392c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // In C, such things can also be folded, although they are not ICEs. 393c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // 394c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Allow folding any const variable of literal type initialized with 395c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // a constant expression. For now, we only allow variables with integral and 396c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // floating types to be folded. 397d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // FIXME: volatile-qualified ParmVarDecls need special handling. A literal 398d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // interpretation of C++11 suggests that volatile parameters are OK if 399d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // they're never read (there's no prohibition against constructing volatile 400d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // objects in constant expressions), but lvalue-to-rvalue conversions on 401d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // them are not permitted. 402c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith const VarDecl *VD = dyn_cast<VarDecl>(D); 403d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (!VD || !(IsConstNonVolatile(VD->getType()) || isa<ParmVarDecl>(VD)) || 404d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith !(Type->isIntegralOrEnumerationType() || Type->isRealFloatingType())) 405c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 406c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 407d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const APValue *V = EvaluateVarDeclInit(Info, VD); 408c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!V || V->isUninit()) 409c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 410c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 411d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (isa<ParmVarDecl>(VD) || !VD->getAnyInitializer()->isLValue()) { 412c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith RVal = *V; 413c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return true; 414c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 415c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 416c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // The declaration was initialized by an lvalue, with no lvalue-to-rvalue 417c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // conversion. This happens when the declaration and the lvalue should be 418c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // considered synonymous, for instance when initializing an array of char 419c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // from a string literal. Continue as if the initializer lvalue was the 420c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // value we were originally given. 421c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Base = V->getLValueBase(); 422c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!V->getLValueOffset().isZero()) 423c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 424c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 425c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 426c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: C++11: Support MaterializeTemporaryExpr in LValueExprEvaluator and 427c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // here. 428c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 429c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the 430c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // initializer until now for such expressions. Such an expression can't be 431c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // an ICE in C, so this only matters for fold. 432c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(Base)) { 433c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(!Info.getLangOpts().CPlusPlus && "lvalue compound literal in c++?"); 434c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Evaluate(RVal, Info, CLE->getInitializer()); 435c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 436c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 437c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 438c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith} 439c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 440c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stumpnamespace { 441d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smithenum EvalStmtResult { 442d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// Evaluation failed. 443d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith ESR_Failed, 444d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// Hit a 'return' statement. 445d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith ESR_Returned, 446d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith /// Evaluation succeeded. 447d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith ESR_Succeeded 448d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith}; 449d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith} 450d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 451d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith// Evaluate a statement. 452d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smithstatic EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info, 453d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const Stmt *S) { 454d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith switch (S->getStmtClass()) { 455d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith default: 456d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return ESR_Failed; 457d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 458d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith case Stmt::NullStmtClass: 459d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith case Stmt::DeclStmtClass: 460d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return ESR_Succeeded; 461d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 462d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith case Stmt::ReturnStmtClass: 463d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (Evaluate(Result, Info, cast<ReturnStmt>(S)->getRetValue())) 464d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return ESR_Returned; 465d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return ESR_Failed; 466d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 467d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith case Stmt::CompoundStmtClass: { 468d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const CompoundStmt *CS = cast<CompoundStmt>(S); 469d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith for (CompoundStmt::const_body_iterator BI = CS->body_begin(), 470d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith BE = CS->body_end(); BI != BE; ++BI) { 471d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith EvalStmtResult ESR = EvaluateStmt(Result, Info, *BI); 472d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (ESR != ESR_Succeeded) 473d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return ESR; 474d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 475d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return ESR_Succeeded; 476d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 477d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 478d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith} 479d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 480d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith/// Evaluate a function call. 481d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smithstatic bool HandleFunctionCall(ArrayRef<const Expr*> Args, const Stmt *Body, 482d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith EvalInfo &Info, APValue &Result) { 483d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // FIXME: Implement a proper call limit, along with a command-line flag. 484d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (Info.NumCalls >= 1000000 || Info.CallStackDepth >= 512) 485d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return false; 486d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 487d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith SmallVector<APValue, 16> ArgValues(Args.size()); 488d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // FIXME: Deal with default arguments and 'this'. 489d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end(); 490d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith I != E; ++I) 491d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) 492d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return false; 493d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 494d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith CallStackFrame Frame(Info, ArgValues.data()); 495d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return EvaluateStmt(Result, Info, Body) == ESR_Returned; 496d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith} 497d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 498d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smithnamespace { 499770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass HasSideEffect 5008cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ConstStmtVisitor<HasSideEffect, bool> { 5011e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith const ASTContext &Ctx; 502c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stumppublic: 503c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 5041e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith HasSideEffect(const ASTContext &C) : Ctx(C) {} 505c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 506c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump // Unhandled nodes conservatively default to having side effects. 5078cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitStmt(const Stmt *S) { 508c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return true; 509c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump } 510c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 5118cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitParenExpr(const ParenExpr *E) { return Visit(E->getSubExpr()); } 5128cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitGenericSelectionExpr(const GenericSelectionExpr *E) { 513f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne return Visit(E->getResultExpr()); 514f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne } 5158cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitDeclRefExpr(const DeclRefExpr *E) { 5161e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (Ctx.getCanonicalType(E->getType()).isVolatileQualified()) 517c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return true; 518c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return false; 519c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump } 520f85e193739c953358c865005855253af4f68a497John McCall bool VisitObjCIvarRefExpr(const ObjCIvarRefExpr *E) { 5211e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (Ctx.getCanonicalType(E->getType()).isVolatileQualified()) 522f85e193739c953358c865005855253af4f68a497John McCall return true; 523f85e193739c953358c865005855253af4f68a497John McCall return false; 524f85e193739c953358c865005855253af4f68a497John McCall } 525f85e193739c953358c865005855253af4f68a497John McCall bool VisitBlockDeclRefExpr (const BlockDeclRefExpr *E) { 5261e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (Ctx.getCanonicalType(E->getType()).isVolatileQualified()) 527f85e193739c953358c865005855253af4f68a497John McCall return true; 528f85e193739c953358c865005855253af4f68a497John McCall return false; 529f85e193739c953358c865005855253af4f68a497John McCall } 530f85e193739c953358c865005855253af4f68a497John McCall 531c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump // We don't want to evaluate BlockExprs multiple times, as they generate 532c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump // a ton of code. 5338cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitBlockExpr(const BlockExpr *E) { return true; } 5348cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitPredefinedExpr(const PredefinedExpr *E) { return false; } 5358cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) 536c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump { return Visit(E->getInitializer()); } 5378cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitMemberExpr(const MemberExpr *E) { return Visit(E->getBase()); } 5388cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitIntegerLiteral(const IntegerLiteral *E) { return false; } 5398cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitFloatingLiteral(const FloatingLiteral *E) { return false; } 5408cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitStringLiteral(const StringLiteral *E) { return false; } 5418cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCharacterLiteral(const CharacterLiteral *E) { return false; } 5428cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E) 543f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne { return false; } 5448cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E) 545980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump { return Visit(E->getLHS()) || Visit(E->getRHS()); } 5468cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitChooseExpr(const ChooseExpr *E) 5471e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith { return Visit(E->getChosenSubExpr(Ctx)); } 5488cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCastExpr(const CastExpr *E) { return Visit(E->getSubExpr()); } 5498cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitBinAssign(const BinaryOperator *E) { return true; } 5508cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCompoundAssignOperator(const BinaryOperator *E) { return true; } 5518cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitBinaryOperator(const BinaryOperator *E) 552980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump { return Visit(E->getLHS()) || Visit(E->getRHS()); } 5538cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryPreInc(const UnaryOperator *E) { return true; } 5548cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryPostInc(const UnaryOperator *E) { return true; } 5558cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryPreDec(const UnaryOperator *E) { return true; } 5568cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryPostDec(const UnaryOperator *E) { return true; } 5578cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryDeref(const UnaryOperator *E) { 5581e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (Ctx.getCanonicalType(E->getType()).isVolatileQualified()) 559c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return true; 560980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump return Visit(E->getSubExpr()); 561c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump } 5628cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryOperator(const UnaryOperator *E) { return Visit(E->getSubExpr()); } 563363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner 564363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner // Has side effects if any element does. 5658cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitInitListExpr(const InitListExpr *E) { 566363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner for (unsigned i = 0, e = E->getNumInits(); i != e; ++i) 567363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner if (Visit(E->getInit(i))) return true; 5688cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne if (const Expr *filler = E->getArrayFiller()) 5694423ac0282acb8ba801eb05b38712438dc0c1e3eArgyrios Kyrtzidis return Visit(filler); 570363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner return false; 571363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner } 572ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor 5738cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitSizeOfPackExpr(const SizeOfPackExpr *) { return false; } 574c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump}; 575c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 57656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallclass OpaqueValueEvaluation { 57756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall EvalInfo &info; 57856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall OpaqueValueExpr *opaqueValue; 57956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 58056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallpublic: 58156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall OpaqueValueEvaluation(EvalInfo &info, OpaqueValueExpr *opaqueValue, 58256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall Expr *value) 58356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall : info(info), opaqueValue(opaqueValue) { 58456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 58556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall // If evaluation fails, fail immediately. 5861e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (!Evaluate(info.OpaqueValues[opaqueValue], info, value)) { 58756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall this->opaqueValue = 0; 58856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall return; 58956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 59056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 59156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 59256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall bool hasError() const { return opaqueValue == 0; } 59356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 59456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall ~OpaqueValueEvaluation() { 5951e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith // FIXME: This will not work for recursive constexpr functions using opaque 5961e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith // values. Restore the former value. 59756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (opaqueValue) info.OpaqueValues.erase(opaqueValue); 59856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 59956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall}; 60056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 601c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump} // end anonymous namespace 602c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 6034efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 6048cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne// Generic Evaluation 6058cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne//===----------------------------------------------------------------------===// 6068cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournenamespace { 6078cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6088cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournetemplate <class Derived, typename RetTy=void> 6098cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourneclass ExprEvaluatorBase 6108cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ConstStmtVisitor<Derived, RetTy> { 6118cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourneprivate: 6128cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy DerivedSuccess(const APValue &V, const Expr *E) { 6138cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return static_cast<Derived*>(this)->Success(V, E); 6148cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 6158cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy DerivedError(const Expr *E) { 6168cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return static_cast<Derived*>(this)->Error(E); 6178cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 618f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith RetTy DerivedValueInitialization(const Expr *E) { 619f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return static_cast<Derived*>(this)->ValueInitialization(E); 620f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 6218cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6228cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourneprotected: 6238cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne EvalInfo &Info; 6248cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne typedef ConstStmtVisitor<Derived, RetTy> StmtVisitorTy; 6258cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne typedef ExprEvaluatorBase ExprEvaluatorBaseTy; 6268cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 627f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith RetTy ValueInitialization(const Expr *E) { return DerivedError(E); } 628f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith 6298cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournepublic: 6308cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {} 6318cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6328cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitStmt(const Stmt *) { 633b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Expression evaluator should not be called on stmts"); 6348cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 6358cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitExpr(const Expr *E) { 6368cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return DerivedError(E); 6378cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 6388cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6398cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitParenExpr(const ParenExpr *E) 6408cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne { return StmtVisitorTy::Visit(E->getSubExpr()); } 6418cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitUnaryExtension(const UnaryOperator *E) 6428cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne { return StmtVisitorTy::Visit(E->getSubExpr()); } 6438cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitUnaryPlus(const UnaryOperator *E) 6448cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne { return StmtVisitorTy::Visit(E->getSubExpr()); } 6458cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitChooseExpr(const ChooseExpr *E) 6468cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne { return StmtVisitorTy::Visit(E->getChosenSubExpr(Info.Ctx)); } 6478cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitGenericSelectionExpr(const GenericSelectionExpr *E) 6488cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne { return StmtVisitorTy::Visit(E->getResultExpr()); } 64991a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall RetTy VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) 65091a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall { return StmtVisitorTy::Visit(E->getReplacement()); } 6518cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6528cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) { 6538cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne OpaqueValueEvaluation opaque(Info, E->getOpaqueValue(), E->getCommon()); 6548cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne if (opaque.hasError()) 6558cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return DerivedError(E); 6568cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6578cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool cond; 658c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateAsBooleanCondition(E->getCond(), cond, Info)) 6598cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return DerivedError(E); 6608cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6618cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return StmtVisitorTy::Visit(cond ? E->getTrueExpr() : E->getFalseExpr()); 6628cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 6638cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6648cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitConditionalOperator(const ConditionalOperator *E) { 6658cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool BoolResult; 666c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateAsBooleanCondition(E->getCond(), BoolResult, Info)) 6678cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return DerivedError(E); 6688cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 669c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Expr *EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr(); 6708cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return StmtVisitorTy::Visit(EvalExpr); 6718cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 6728cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 6738cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne RetTy VisitOpaqueValueExpr(const OpaqueValueExpr *E) { 6748cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const APValue *value = Info.getOpaqueValue(E); 6758cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne if (!value) 6768cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return (E->getSourceExpr() ? StmtVisitorTy::Visit(E->getSourceExpr()) 6778cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : DerivedError(E)); 6788cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return DerivedSuccess(*value, E); 6798cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 680f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith 681d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith RetTy VisitCallExpr(const CallExpr *E) { 682d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const Expr *Callee = E->getCallee(); 683d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith QualType CalleeType = Callee->getType(); 684d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 685d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // FIXME: Handle the case where Callee is a (parenthesized) MemberExpr for a 686d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // non-static member function. 687d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) 688d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedError(E); 689d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 690d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (!CalleeType->isFunctionType() && !CalleeType->isFunctionPointerType()) 691d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedError(E); 692d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 693d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith APValue Call; 694d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (!Evaluate(Call, Info, Callee) || !Call.isLValue() || 695d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith !Call.getLValueBase() || !Call.getLValueOffset().isZero()) 696d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedError(Callee); 697d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 698d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const FunctionDecl *FD = 0; 699d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Call.getLValueBase())) 700d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith FD = dyn_cast<FunctionDecl>(DRE->getDecl()); 701d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith else if (const MemberExpr *ME = dyn_cast<MemberExpr>(Call.getLValueBase())) 702d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith FD = dyn_cast<FunctionDecl>(ME->getMemberDecl()); 703d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (!FD) 704d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedError(Callee); 705d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 706d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // Don't call function pointers which have been cast to some other type. 707d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (!Info.Ctx.hasSameType(CalleeType->getPointeeType(), FD->getType())) 708d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedError(E); 709d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 710d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const FunctionDecl *Definition; 711d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith Stmt *Body = FD->getBody(Definition); 712d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith APValue Result; 713d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith llvm::ArrayRef<const Expr*> Args(E->getArgs(), E->getNumArgs()); 714d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 715d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (Body && Definition->isConstexpr() && !Definition->isInvalidDecl() && 716d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith HandleFunctionCall(Args, Body, Info, Result)) 717d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedSuccess(Result, E); 718d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 719d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return DerivedError(E); 720d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 721d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 722c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith RetTy VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { 723c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return StmtVisitorTy::Visit(E->getInitializer()); 724c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 725f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith RetTy VisitInitListExpr(const InitListExpr *E) { 726f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith if (Info.getLangOpts().CPlusPlus0x) { 727f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith if (E->getNumInits() == 0) 728f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return DerivedValueInitialization(E); 729f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith if (E->getNumInits() == 1) 730f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return StmtVisitorTy::Visit(E->getInit(0)); 731f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 732f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return DerivedError(E); 733f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 734f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith RetTy VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { 735f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return DerivedValueInitialization(E); 736f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 737f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith RetTy VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) { 738f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return DerivedValueInitialization(E); 739f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 740f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith 741c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith RetTy VisitCastExpr(const CastExpr *E) { 742c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith switch (E->getCastKind()) { 743c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith default: 744c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith break; 745c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 746c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case CK_NoOp: 747c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return StmtVisitorTy::Visit(E->getSubExpr()); 748c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 749c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case CK_LValueToRValue: { 750c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith LValue LVal; 751c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (EvaluateLValue(E->getSubExpr(), LVal, Info)) { 752c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APValue RVal; 753c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (HandleLValueToRValueConversion(Info, E->getType(), LVal, RVal)) 754c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return DerivedSuccess(RVal, E); 755c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 756c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith break; 757c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 758c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 759c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 760c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return DerivedError(E); 761c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 762c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 7638327fad71da34492d82c532f42a58cb4baff81a3Richard Smith /// Visit a value which is evaluated, but whose value is ignored. 7648327fad71da34492d82c532f42a58cb4baff81a3Richard Smith void VisitIgnoredValue(const Expr *E) { 7658327fad71da34492d82c532f42a58cb4baff81a3Richard Smith APValue Scratch; 7668327fad71da34492d82c532f42a58cb4baff81a3Richard Smith if (!Evaluate(Scratch, Info, E)) 7678327fad71da34492d82c532f42a58cb4baff81a3Richard Smith Info.EvalStatus.HasSideEffects = true; 7688327fad71da34492d82c532f42a58cb4baff81a3Richard Smith } 7698cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne}; 7708cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 7718cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne} 7728cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 7738cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne//===----------------------------------------------------------------------===// 7744efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman// LValue Evaluation 775c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// 776c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// This is used for evaluating lvalues (in C and C++), xvalues (in C++11), 777c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// function designators (in C), decl references to void objects (in C), and 778c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// temporaries (if building with -Wno-address-of-temporary). 779c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// 780c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// LValue evaluation produces values comprising a base expression of one of the 781c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// following types: 782c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * DeclRefExpr 783c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * MemberExpr for a static member 784c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * CompoundLiteralExpr in C 785c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * StringLiteral 786c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * PredefinedExpr 787c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * ObjCEncodeExpr 788c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * AddrLabelExpr 789c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * BlockExpr 790c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// * CallExpr for a MakeStringConstant builtin 791c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// plus an offset in bytes. 7924efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 7934efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmannamespace { 794770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass LValueExprEvaluator 7958cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ExprEvaluatorBase<LValueExprEvaluator, bool> { 796efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue &Result; 7970124839d7fb3d846795190ba2ccf3951f27784feChandler Carruth const Decl *PrevDecl; 798efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 7998cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const Expr *E) { 800efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = E; 801efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = CharUnits::Zero(); 802efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 803efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 8044efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanpublic: 8051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 806efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValueExprEvaluator(EvalInfo &info, LValue &Result) : 8070124839d7fb3d846795190ba2ccf3951f27784feChandler Carruth ExprEvaluatorBaseTy(info), Result(Result), PrevDecl(0) {} 8084efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 8098cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const APValue &V, const Expr *E) { 8108cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne Result.setFrom(V); 8118cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return true; 8128cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 8138cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Error(const Expr *E) { 814efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 8154efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 8168ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 817c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith bool VisitVarDecl(const Expr *E, const VarDecl *VD); 818c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 8198cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitDeclRefExpr(const DeclRefExpr *E); 8208cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitPredefinedExpr(const PredefinedExpr *E) { return Success(E); } 8218cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); 8228cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitMemberExpr(const MemberExpr *E); 8238cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitStringLiteral(const StringLiteral *E) { return Success(E); } 8248cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); } 8258cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E); 8268cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitUnaryDeref(const UnaryOperator *E); 8278cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 8288cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCastExpr(const CastExpr *E) { 82926bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson switch (E->getCastKind()) { 83026bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson default: 831c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return ExprEvaluatorBaseTy::VisitCastExpr(E); 83226bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson 833db924224b51b153f24fbe492102d4edebcbbb7f4Eli Friedman case CK_LValueBitCast: 83426bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson return Visit(E->getSubExpr()); 835db924224b51b153f24fbe492102d4edebcbbb7f4Eli Friedman 836c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Support CK_DerivedToBase and CK_UncheckedDerivedToBase. 837c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // Reuse PointerExprEvaluator::VisitCastExpr for these. 83826bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson } 83926bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson } 840cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl 841ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman // FIXME: Missing: __real__, __imag__ 8428cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 8434efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman}; 8444efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} // end anonymous namespace 8454efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 846c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// Evaluate an expression as an lvalue. This can be legitimately called on 847c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// expressions which are not glvalues, in a few cases: 848c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// * function designators in C, 849c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// * "extern void" objects, 850c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// * temporaries, if building with -Wno-address-of-temporary. 851efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluateLValue(const Expr* E, LValue& Result, EvalInfo &Info) { 852c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert((E->isGLValue() || E->getType()->isFunctionType() || 853c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith E->getType()->isVoidType() || isa<CXXTemporaryObjectExpr>(E)) && 854c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith "can't evaluate expression as an lvalue"); 8558cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return LValueExprEvaluator(Info, Result).Visit(E); 8564efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 8574efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 8588cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { 859c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (isa<FunctionDecl>(E->getDecl())) 860efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 861c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (const VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) 862c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return VisitVarDecl(E, VD); 863c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Error(E); 864c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith} 865436c8898cd1c93c5bacd3fcc4ac586bc5cd77062Richard Smith 866c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smithbool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { 867c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!VD->getType()->isReferenceType()) 868c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(E); 86950c39ea4858265f3f5f42a0c624557ce2281936bEli Friedman 870d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith const APValue *V = EvaluateVarDeclInit(Info, VD); 871c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (V && !V->isUninit()) 872c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(*V, E); 873c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 874c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Error(E); 87535873c49adad211ff466e34342a52665742794f5Anders Carlsson} 87635873c49adad211ff466e34342a52665742794f5Anders Carlsson 8778cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool 8788cad3046be06ea73ff8892d947697a21d7a440d3Peter CollingbourneLValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { 879c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(!Info.getLangOpts().CPlusPlus && "lvalue compound literal in c++?"); 880c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // Defer visiting the literal until the lvalue-to-rvalue conversion. We can 881c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // only see this when folding in C, so there's no standard to follow here. 882efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 8834efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 8844efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 8858cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) { 886c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // Handle static data members. 887c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) { 888c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith VisitIgnoredValue(E->getBase()); 889c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return VisitVarDecl(E, VD); 890c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 891c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 892d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith // Handle static member functions. 893d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getMemberDecl())) { 894d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith if (MD->isStatic()) { 895d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith VisitIgnoredValue(E->getBase()); 896d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith return Success(E); 897d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 898d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith } 899d0dcceae2a8ca0e37b5dd471a704de8583d49c95Richard Smith 9004efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman QualType Ty; 9014efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->isArrow()) { 902efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluatePointer(E->getBase(), Result, Info)) 903efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 9046217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType(); 9054efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } else { 906efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!Visit(E->getBase())) 907efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 9084efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Ty = E->getBase()->getType(); 9094efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 9104efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 9118cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl(); 9124efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 91386f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor 9148cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 91586f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor if (!FD) // FIXME: deal with other kinds of member expressions 916efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 9172be586108bb401019647791feca19ea03fd477ceEli Friedman 9182be586108bb401019647791feca19ea03fd477ceEli Friedman if (FD->getType()->isReferenceType()) 919efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 9202be586108bb401019647791feca19ea03fd477ceEli Friedman 92182905749d5c8d8b4edec11de754a73349cb96603Eli Friedman unsigned i = FD->getFieldIndex(); 922fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Result.Offset += Info.Ctx.toCharUnitsFromBits(RL.getFieldOffset(i)); 923efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 9244efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 9254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 9268cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { 927c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: Deal with vectors as array subscript bases. 928c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (E->getBase()->getType()->isVectorType()) 929c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 930c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 9313068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluatePointer(E->getBase(), Result, Info)) 932efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 9331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9343068d117951a8df54bae9db039b56201ab10962bAnders Carlsson APSInt Index; 9353068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluateInteger(E->getIdx(), Index, Info)) 936efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 9373068d117951a8df54bae9db039b56201ab10962bAnders Carlsson 938199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType()); 939efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset += Index.getSExtValue() * ElementSize; 940efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 9413068d117951a8df54bae9db039b56201ab10962bAnders Carlsson} 9424efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 9438cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) { 944efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return EvaluatePointer(E->getSubExpr(), Result, Info); 945e8761c8fe2ee6b628104a0885f49fd3c21c08a4fEli Friedman} 946e8761c8fe2ee6b628104a0885f49fd3c21c08a4fEli Friedman 9474efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 948f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Pointer Evaluation 949f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 950f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 951c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlssonnamespace { 952770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass PointerExprEvaluator 9538cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ExprEvaluatorBase<PointerExprEvaluator, bool> { 954efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue &Result; 955efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 9568cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const Expr *E) { 957efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = E; 958efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = CharUnits::Zero(); 959efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 960efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 9612bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonpublic: 9621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 963efdb83e26f9a1fd2566afe54461216cd84814d42John McCall PointerExprEvaluator(EvalInfo &info, LValue &Result) 9648cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : ExprEvaluatorBaseTy(info), Result(Result) {} 965f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 9668cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const APValue &V, const Expr *E) { 9678cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne Result.setFrom(V); 9688cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return true; 9692bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 9708cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Error(const Stmt *S) { 9718cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return false; 972f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne } 973f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith bool ValueInitialization(const Expr *E) { 974f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return Success((Expr*)0); 975f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 9762bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 977efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitBinaryOperator(const BinaryOperator *E); 9788cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCastExpr(const CastExpr* E); 979efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitUnaryAddrOf(const UnaryOperator *E); 9808cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitObjCStringLiteral(const ObjCStringLiteral *E) 981efdb83e26f9a1fd2566afe54461216cd84814d42John McCall { return Success(E); } 9828cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitAddrLabelExpr(const AddrLabelExpr *E) 983efdb83e26f9a1fd2566afe54461216cd84814d42John McCall { return Success(E); } 9848cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCallExpr(const CallExpr *E); 9858cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitBlockExpr(const BlockExpr *E) { 986469a1eb996e1cb0be54f9b210f836afbddcbb2ccJohn McCall if (!E->getBlockDecl()->hasCaptures()) 987efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 988efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 989b83d287bc7f47d36fb0751a481e2ef9308b37252Mike Stump } 9908cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) 991f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith { return ValueInitialization(E); } 99256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 993ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman // FIXME: Missing: @protocol, @selector 9942bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson}; 995f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 9962bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 997efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) { 998c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(E->isRValue() && E->getType()->hasPointerRepresentation()); 9998cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return PointerExprEvaluator(Info, Result).Visit(E); 1000f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 1001650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 1002efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 10032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() != BO_Add && 10042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall E->getOpcode() != BO_Sub) 1005efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1007650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *PExp = E->getLHS(); 1008650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *IExp = E->getRHS(); 1009650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (IExp->getType()->isPointerType()) 1010f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner std::swap(PExp, IExp); 10111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1012efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluatePointer(PExp, Result, Info)) 1013efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1015efdb83e26f9a1fd2566afe54461216cd84814d42John McCall llvm::APSInt Offset; 1016efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateInteger(IExp, Offset, Info)) 1017efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 1018efdb83e26f9a1fd2566afe54461216cd84814d42John McCall int64_t AdditionalOffset 1019efdb83e26f9a1fd2566afe54461216cd84814d42John McCall = Offset.isSigned() ? Offset.getSExtValue() 1020efdb83e26f9a1fd2566afe54461216cd84814d42John McCall : static_cast<int64_t>(Offset.getZExtValue()); 1021650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 1022e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar // Compute the new offset in the appropriate width. 1023e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar 1024e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar QualType PointeeType = 1025e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar PExp->getType()->getAs<PointerType>()->getPointeeType(); 1026efdb83e26f9a1fd2566afe54461216cd84814d42John McCall CharUnits SizeOfPointee; 10271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10284d4c50dd8b4db191c38782414665fb7608315a36Anders Carlsson // Explicitly handle GNU void* and function pointer arithmetic extensions. 10294d4c50dd8b4db191c38782414665fb7608315a36Anders Carlsson if (PointeeType->isVoidType() || PointeeType->isFunctionType()) 1030efdb83e26f9a1fd2566afe54461216cd84814d42John McCall SizeOfPointee = CharUnits::One(); 10314d4c50dd8b4db191c38782414665fb7608315a36Anders Carlsson else 1032efdb83e26f9a1fd2566afe54461216cd84814d42John McCall SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType); 10334efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 10342de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Add) 1035efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset += AdditionalOffset * SizeOfPointee; 1036650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson else 1037efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset -= AdditionalOffset * SizeOfPointee; 10384efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1039efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 1040650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 10414efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1042efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { 1043efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return EvaluateLValue(E->getSubExpr(), Result, Info); 10444efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 10451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1046650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 10478cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { 10488cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr* SubExpr = E->getSubExpr(); 1049650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 105009a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman switch (E->getCastKind()) { 105109a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman default: 105209a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman break; 105309a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman 10542de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_BitCast: 10551d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_CPointerToObjCPointerCast: 10561d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_BlockPointerToObjCPointerCast: 10572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_AnyPointerToBlockPointerCast: 105809a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman return Visit(SubExpr); 105909a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman 10605c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson case CK_DerivedToBase: 10615c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson case CK_UncheckedDerivedToBase: { 10625c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson LValue BaseLV; 10635c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson if (!EvaluatePointer(E->getSubExpr(), BaseLV, Info)) 10645c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson return false; 10655c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10665c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // Now figure out the necessary offset to add to the baseLV to get from 10675c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // the derived class to the base class. 10687c7f820d70c925b29290a8563b59615816a827fcKen Dyck CharUnits Offset = CharUnits::Zero(); 10695c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10705c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson QualType Ty = E->getSubExpr()->getType(); 10715c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const CXXRecordDecl *DerivedDecl = 10725c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson Ty->getAs<PointerType>()->getPointeeType()->getAsCXXRecordDecl(); 10735c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10745c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson for (CastExpr::path_const_iterator PathI = E->path_begin(), 10755c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson PathE = E->path_end(); PathI != PathE; ++PathI) { 10765c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const CXXBaseSpecifier *Base = *PathI; 10775c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10785c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // FIXME: If the base is virtual, we'd need to determine the type of the 10795c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // most derived class and we don't support that right now. 10805c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson if (Base->isVirtual()) 10815c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson return false; 10825c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10835c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const CXXRecordDecl *BaseDecl = Base->getType()->getAsCXXRecordDecl(); 10845c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl); 10855c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10867c7f820d70c925b29290a8563b59615816a827fcKen Dyck Offset += Layout.getBaseClassOffset(BaseDecl); 10875c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson DerivedDecl = BaseDecl; 10885c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson } 10895c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 10905c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson Result.Base = BaseLV.getLValueBase(); 10917c7f820d70c925b29290a8563b59615816a827fcKen Dyck Result.Offset = BaseLV.getLValueOffset() + Offset; 10925c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson return true; 10935c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson } 10945c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 1095404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall case CK_NullToPointer: { 1096404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall Result.Base = 0; 1097404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall Result.Offset = CharUnits::Zero(); 1098404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall return true; 1099404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall } 1100404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall 11012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_IntegralToPointer: { 1102efdb83e26f9a1fd2566afe54461216cd84814d42John McCall APValue Value; 1103efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateIntegerOrLValue(SubExpr, Value, Info)) 110409a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman break; 110569ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar 1106efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (Value.isInt()) { 11079f71a8f4c7a182a5236da9e747d57cc1d1bd24c2Jay Foad Value.getInt() = Value.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); 1108efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = 0; 1109efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = CharUnits::fromQuantity(Value.getInt().getZExtValue()); 1110efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 1111efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else { 1112efdb83e26f9a1fd2566afe54461216cd84814d42John McCall // Cast is of an lvalue, no need to change value. 1113efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = Value.getLValueBase(); 1114efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = Value.getLValueOffset(); 1115efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 1116650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 1117650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 11182de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_ArrayToPointerDecay: 11192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_FunctionToPointerDecay: 1120efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return EvaluateLValue(SubExpr, Result, Info); 11214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 11224efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1123c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return ExprEvaluatorBaseTy::VisitCastExpr(E); 11241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 1125650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 11268cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { 11271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (E->isBuiltinCall(Info.Ctx) == 11280d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall Builtin::BI__builtin___CFStringMakeConstantString || 11290d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall E->isBuiltinCall(Info.Ctx) == 11300d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall Builtin::BI__builtin___NSStringMakeConstantString) 1131efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 113256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 11338cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return ExprEvaluatorBaseTy::VisitCallExpr(E); 11344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 1135f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1136f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 113759b5da6d853b4368b984700315adf7b37de05764Nate Begeman// Vector Evaluation 113859b5da6d853b4368b984700315adf7b37de05764Nate Begeman//===----------------------------------------------------------------------===// 113959b5da6d853b4368b984700315adf7b37de05764Nate Begeman 114059b5da6d853b4368b984700315adf7b37de05764Nate Begemannamespace { 1141770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramer class VectorExprEvaluator 114207fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith : public ExprEvaluatorBase<VectorExprEvaluator, bool> { 114307fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith APValue &Result; 114459b5da6d853b4368b984700315adf7b37de05764Nate Begeman public: 11451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 114607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith VectorExprEvaluator(EvalInfo &info, APValue &Result) 114707fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith : ExprEvaluatorBaseTy(info), Result(Result) {} 11481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 114907fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool Success(const ArrayRef<APValue> &V, const Expr *E) { 115007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith assert(V.size() == E->getType()->castAs<VectorType>()->getNumElements()); 115107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith // FIXME: remove this APValue copy. 115207fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith Result = APValue(V.data(), V.size()); 115307fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return true; 115407fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith } 115507fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool Success(const APValue &V, const Expr *E) { 115607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith Result = V; 115707fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return true; 115807fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith } 115907fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool Error(const Expr *E) { return false; } 116007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool ValueInitialization(const Expr *E); 11611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 116207fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool VisitUnaryReal(const UnaryOperator *E) 116391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman { return Visit(E->getSubExpr()); } 116407fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool VisitCastExpr(const CastExpr* E); 116507fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool VisitInitListExpr(const InitListExpr *E); 116607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith bool VisitUnaryImag(const UnaryOperator *E); 116791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div, 11682217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman // binary comparisons, binary and/or/xor, 116991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // shufflevector, ExtVectorElementExpr 117091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // (Note that these require implementing conversions 117191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // between vector types.) 117259b5da6d853b4368b984700315adf7b37de05764Nate Begeman }; 117359b5da6d853b4368b984700315adf7b37de05764Nate Begeman} // end anonymous namespace 117459b5da6d853b4368b984700315adf7b37de05764Nate Begeman 117559b5da6d853b4368b984700315adf7b37de05764Nate Begemanstatic bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { 1176c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(E->isRValue() && E->getType()->isVectorType() &&"not a vector rvalue"); 117707fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return VectorExprEvaluator(Info, Result).Visit(E); 117859b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 117959b5da6d853b4368b984700315adf7b37de05764Nate Begeman 118007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smithbool VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { 118107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith const VectorType *VTy = E->getType()->castAs<VectorType>(); 1182c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman QualType EltTy = VTy->getElementType(); 1183c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman unsigned NElts = VTy->getNumElements(); 1184c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman unsigned EltWidth = Info.Ctx.getTypeSize(EltTy); 11851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 118659b5da6d853b4368b984700315adf7b37de05764Nate Begeman const Expr* SE = E->getSubExpr(); 1187e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman QualType SETy = SE->getType(); 118859b5da6d853b4368b984700315adf7b37de05764Nate Begeman 118946a523285928aa07bf14803178dc04616ac85994Eli Friedman switch (E->getCastKind()) { 119046a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_VectorSplat: { 119107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith APValue Val = APValue(); 119246a523285928aa07bf14803178dc04616ac85994Eli Friedman if (SETy->isIntegerType()) { 119346a523285928aa07bf14803178dc04616ac85994Eli Friedman APSInt IntResult; 119446a523285928aa07bf14803178dc04616ac85994Eli Friedman if (!EvaluateInteger(SE, IntResult, Info)) 119507fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 119607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith Val = APValue(IntResult); 119746a523285928aa07bf14803178dc04616ac85994Eli Friedman } else if (SETy->isRealFloatingType()) { 119846a523285928aa07bf14803178dc04616ac85994Eli Friedman APFloat F(0.0); 119946a523285928aa07bf14803178dc04616ac85994Eli Friedman if (!EvaluateFloat(SE, F, Info)) 120007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 120107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith Val = APValue(F); 120246a523285928aa07bf14803178dc04616ac85994Eli Friedman } else { 120307fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 120446a523285928aa07bf14803178dc04616ac85994Eli Friedman } 1205c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman 1206c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // Splat and create vector APValue. 120707fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith SmallVector<APValue, 4> Elts(NElts, Val); 120807fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Success(Elts, E); 1209e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman } 121046a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_BitCast: { 121107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith // FIXME: this is wrong for any cast other than a no-op cast. 121246a523285928aa07bf14803178dc04616ac85994Eli Friedman if (SETy->isVectorType()) 12138cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return Visit(SE); 1214c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman 121546a523285928aa07bf14803178dc04616ac85994Eli Friedman if (!SETy->isIntegerType()) 121607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 12171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 121846a523285928aa07bf14803178dc04616ac85994Eli Friedman APSInt Init; 121946a523285928aa07bf14803178dc04616ac85994Eli Friedman if (!EvaluateInteger(SE, Init, Info)) 122007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 1221c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman 122246a523285928aa07bf14803178dc04616ac85994Eli Friedman assert((EltTy->isIntegerType() || EltTy->isRealFloatingType()) && 122346a523285928aa07bf14803178dc04616ac85994Eli Friedman "Vectors must be composed of ints or floats"); 122446a523285928aa07bf14803178dc04616ac85994Eli Friedman 12255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<APValue, 4> Elts; 122646a523285928aa07bf14803178dc04616ac85994Eli Friedman for (unsigned i = 0; i != NElts; ++i) { 122746a523285928aa07bf14803178dc04616ac85994Eli Friedman APSInt Tmp = Init.extOrTrunc(EltWidth); 122846a523285928aa07bf14803178dc04616ac85994Eli Friedman 122946a523285928aa07bf14803178dc04616ac85994Eli Friedman if (EltTy->isIntegerType()) 123046a523285928aa07bf14803178dc04616ac85994Eli Friedman Elts.push_back(APValue(Tmp)); 123146a523285928aa07bf14803178dc04616ac85994Eli Friedman else 123246a523285928aa07bf14803178dc04616ac85994Eli Friedman Elts.push_back(APValue(APFloat(Tmp))); 123346a523285928aa07bf14803178dc04616ac85994Eli Friedman 123446a523285928aa07bf14803178dc04616ac85994Eli Friedman Init >>= EltWidth; 123546a523285928aa07bf14803178dc04616ac85994Eli Friedman } 123607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Success(Elts, E); 123746a523285928aa07bf14803178dc04616ac85994Eli Friedman } 123846a523285928aa07bf14803178dc04616ac85994Eli Friedman default: 1239c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return ExprEvaluatorBaseTy::VisitCastExpr(E); 1240c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman } 124159b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 124259b5da6d853b4368b984700315adf7b37de05764Nate Begeman 124307fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smithbool 124459b5da6d853b4368b984700315adf7b37de05764Nate BegemanVectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { 124507fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith const VectorType *VT = E->getType()->castAs<VectorType>(); 124659b5da6d853b4368b984700315adf7b37de05764Nate Begeman unsigned NumInits = E->getNumInits(); 124791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman unsigned NumElements = VT->getNumElements(); 12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 124959b5da6d853b4368b984700315adf7b37de05764Nate Begeman QualType EltTy = VT->getElementType(); 12505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<APValue, 4> Elements; 125159b5da6d853b4368b984700315adf7b37de05764Nate Begeman 1252a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall // If a vector is initialized with a single element, that value 1253a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall // becomes every element of the vector, not just the first. 1254a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall // This is the behavior described in the IBM AltiVec documentation. 1255a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (NumInits == 1) { 125607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith 125707fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith // Handle the case where the vector is initialized by another 1258b92ae0e31126e5630d7022f2d6abe7eed2e17746Tanya Lattner // vector (OpenCL 6.1.6). 1259b92ae0e31126e5630d7022f2d6abe7eed2e17746Tanya Lattner if (E->getInit(0)->getType()->isVectorType()) 126007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Visit(E->getInit(0)); 126107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith 1262a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall APValue InitValue; 126359b5da6d853b4368b984700315adf7b37de05764Nate Begeman if (EltTy->isIntegerType()) { 126459b5da6d853b4368b984700315adf7b37de05764Nate Begeman llvm::APSInt sInt(32); 1265a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateInteger(E->getInit(0), sInt, Info)) 126607fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 1267a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall InitValue = APValue(sInt); 126859b5da6d853b4368b984700315adf7b37de05764Nate Begeman } else { 126959b5da6d853b4368b984700315adf7b37de05764Nate Begeman llvm::APFloat f(0.0); 1270a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateFloat(E->getInit(0), f, Info)) 127107fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 1272a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall InitValue = APValue(f); 1273a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 1274a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall for (unsigned i = 0; i < NumElements; i++) { 1275a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall Elements.push_back(InitValue); 1276a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 1277a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } else { 1278a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall for (unsigned i = 0; i < NumElements; i++) { 1279a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (EltTy->isIntegerType()) { 1280a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall llvm::APSInt sInt(32); 1281a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (i < NumInits) { 1282a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateInteger(E->getInit(i), sInt, Info)) 128307fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 1284a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } else { 1285a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall sInt = Info.Ctx.MakeIntValue(0, EltTy); 1286a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 1287a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall Elements.push_back(APValue(sInt)); 128891110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman } else { 1289a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall llvm::APFloat f(0.0); 1290a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (i < NumInits) { 1291a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateFloat(E->getInit(i), f, Info)) 129207fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Error(E); 1293a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } else { 1294a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)); 1295a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 1296a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall Elements.push_back(APValue(f)); 129791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman } 129859b5da6d853b4368b984700315adf7b37de05764Nate Begeman } 129959b5da6d853b4368b984700315adf7b37de05764Nate Begeman } 130007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Success(Elements, E); 130159b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 130259b5da6d853b4368b984700315adf7b37de05764Nate Begeman 130307fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smithbool 130407fc657e3077531805b0e2dbf8f8964d48daa38bRichard SmithVectorExprEvaluator::ValueInitialization(const Expr *E) { 130507fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith const VectorType *VT = E->getType()->getAs<VectorType>(); 130691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman QualType EltTy = VT->getElementType(); 130791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue ZeroElement; 130891110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman if (EltTy->isIntegerType()) 130991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy)); 131091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman else 131191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman ZeroElement = 131291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy))); 131391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 13145f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement); 131507fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return Success(Elements, E); 131691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman} 131791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 131807fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smithbool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { 13198327fad71da34492d82c532f42a58cb4baff81a3Richard Smith VisitIgnoredValue(E->getSubExpr()); 132007fc657e3077531805b0e2dbf8f8964d48daa38bRichard Smith return ValueInitialization(E); 132191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman} 132291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 132359b5da6d853b4368b984700315adf7b37de05764Nate Begeman//===----------------------------------------------------------------------===// 1324f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Integer Evaluation 1325c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// 1326c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// As a GNU extension, we support casting pointers to sufficiently-wide integer 1327c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// types and back in constant folding. Integer values are thus represented 1328c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith// either as an integer-valued APValue, or as an lvalue-valued APValue. 1329f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 1330f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1331f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnernamespace { 1332770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass IntExprEvaluator 13338cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ExprEvaluatorBase<IntExprEvaluator, bool> { 133430c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar APValue &Result; 1335f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerpublic: 133630c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar IntExprEvaluator(EvalInfo &info, APValue &result) 13378cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : ExprEvaluatorBaseTy(info), Result(result) {} 1338f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1339973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara bool Success(const llvm::APSInt &SI, const Expr *E) { 1340973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara assert(E->getType()->isIntegralOrEnumerationType() && 13412ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor "Invalid evaluation result."); 1342973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara assert(SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() && 13433f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar "Invalid evaluation result."); 1344973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) && 13453f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar "Invalid evaluation result."); 134630c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = APValue(SI); 13473f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar return true; 13483f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar } 13493f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar 1350131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar bool Success(const llvm::APInt &I, const Expr *E) { 13512ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType() && 13522ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor "Invalid evaluation result."); 135330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) && 13543f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar "Invalid evaluation result."); 135530c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = APValue(APSInt(I)); 1356575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor Result.getInt().setIsUnsigned( 1357575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor E->getType()->isUnsignedIntegerOrEnumerationType()); 1358131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return true; 1359131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 1360131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar 1361131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar bool Success(uint64_t Value, const Expr *E) { 13622ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType() && 13632ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor "Invalid evaluation result."); 136430c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType())); 1365131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return true; 1366131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 1367131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar 13684f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck bool Success(CharUnits Size, const Expr *E) { 13694f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck return Success(Size.getQuantity(), E); 13704f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck } 13714f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck 13724f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck 137382206e267ce6cc709797127616f64672d255b310Anders Carlsson bool Error(SourceLocation L, diag::kind D, const Expr *E) { 137432fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner // Take the first error. 13751e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (Info.EvalStatus.Diag == 0) { 13761e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith Info.EvalStatus.DiagLoc = L; 13771e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith Info.EvalStatus.Diag = D; 13781e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith Info.EvalStatus.DiagExpr = E; 137932fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 138054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return false; 13817a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner } 13821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13838cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const APValue &V, const Expr *E) { 13848cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return Success(V.getInt(), E); 138532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 13868cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Error(const Expr *E) { 13870e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1388f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 13891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1390f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith bool ValueInitialization(const Expr *E) { return Success(0, E); } 1391f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith 13928cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne //===--------------------------------------------------------------------===// 13938cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne // Visitor Methods 13948cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne //===--------------------------------------------------------------------===// 1395f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 13964c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitIntegerLiteral(const IntegerLiteral *E) { 1397131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getValue(), E); 13984c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 13994c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitCharacterLiteral(const CharacterLiteral *E) { 1400131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getValue(), E); 14014c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 1402043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman 1403043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman bool CheckReferencedDecl(const Expr *E, const Decl *D); 1404043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman bool VisitDeclRefExpr(const DeclRefExpr *E) { 14058cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne if (CheckReferencedDecl(E, E->getDecl())) 14068cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return true; 14078cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 14088cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return ExprEvaluatorBaseTy::VisitDeclRefExpr(E); 1409043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman } 1410043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman bool VisitMemberExpr(const MemberExpr *E) { 1411043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman if (CheckReferencedDecl(E, E->getMemberDecl())) { 1412c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith VisitIgnoredValue(E->getBase()); 1413043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman return true; 1414043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman } 14158cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 14168cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return ExprEvaluatorBaseTy::VisitMemberExpr(E); 1417043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman } 1418043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman 14198cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCallExpr(const CallExpr *E); 1420b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitBinaryOperator(const BinaryOperator *E); 14218ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor bool VisitOffsetOfExpr(const OffsetOfExpr *E); 1422b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitUnaryOperator(const UnaryOperator *E); 1423f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 14248cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCastExpr(const CastExpr* E); 1425f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); 14260518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 14273068d117951a8df54bae9db039b56201ab10962bAnders Carlsson bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { 1428131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getValue(), E); 14293068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 14301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1431f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith // Note, GNU defines __null as an integer, not a pointer. 14323f70456b8adb0405ef2a47d51f9fc2d5937ae8aeAnders Carlsson bool VisitGNUNullExpr(const GNUNullExpr *E) { 1433f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return ValueInitialization(E); 1434664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman } 1435664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman 143664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) { 14370dfd848fa4c9664852ba8c929a8bd3fce93ddca2Sebastian Redl return Success(E->getValue(), E); 143864b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl } 143964b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 14406ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet bool VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) { 14416ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return Success(E->getValue(), E); 14426ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 14436ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 144421ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) { 144521ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley return Success(E->getValue(), E); 144621ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley } 144721ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley 1448552622067dc45013d240f73952fece703f5e63bdJohn Wiegley bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E) { 1449552622067dc45013d240f73952fece703f5e63bdJohn Wiegley return Success(E->getValue(), E); 1450552622067dc45013d240f73952fece703f5e63bdJohn Wiegley } 1451552622067dc45013d240f73952fece703f5e63bdJohn Wiegley 1452722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman bool VisitUnaryReal(const UnaryOperator *E); 1453664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman bool VisitUnaryImag(const UnaryOperator *E); 1454664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman 1455295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E); 1456ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor bool VisitSizeOfPackExpr(const SizeOfPackExpr *E); 1457cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl 1458fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattnerprivate: 14598b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck CharUnits GetAlignOfExpr(const Expr *E); 14608b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck CharUnits GetAlignOfType(QualType T); 146142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall static QualType GetObjectType(const Expr *E); 14628cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool TryEvaluateBuiltinObjectSize(const CallExpr *E); 1463664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman // FIXME: Missing: array subscript of vector, member of vector 1464f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner}; 1465f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 1466f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1467c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and 1468c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// produce either the integer value or a pointer. 1469c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// 1470c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// GCC has a heinous extension which folds casts between pointer types and 1471c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// pointer-sized integral types. We support this by allowing the evaluation of 1472c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// an integer rvalue to produce a pointer (represented as an lvalue) instead. 1473c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// Some simple arithmetic on such values is supported (they are treated much 1474c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// like char*). 147569ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbarstatic bool EvaluateIntegerOrLValue(const Expr* E, APValue &Result, EvalInfo &Info) { 1476c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(E->isRValue() && E->getType()->isIntegralOrEnumerationType()); 14778cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return IntExprEvaluator(Info, Result).Visit(E); 147869ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar} 147969ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar 148069ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbarstatic bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) { 148130c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar APValue Val; 148269ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt()) 148330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return false; 148430c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = Val.getInt(); 148530c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return true; 1486f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 1487f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1488043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedmanbool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { 14894c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Enums are integer constant exprs. 1490bfbdcd861a4364bfc21a9e5047bdbd56812d6693Abramo Bagnara if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) { 1491973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara // Check for signedness/width mismatches between E type and ECD value. 1492973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara bool SameSign = (ECD->getInitVal().isSigned() 1493973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara == E->getType()->isSignedIntegerOrEnumerationType()); 1494973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara bool SameWidth = (ECD->getInitVal().getBitWidth() 1495973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara == Info.Ctx.getIntWidth(E->getType())); 1496973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara if (SameSign && SameWidth) 1497973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara return Success(ECD->getInitVal(), E); 1498973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara else { 1499973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara // Get rid of mismatch (otherwise Success assertions will fail) 1500973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara // by computing a new value matching the type of E. 1501973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara llvm::APSInt Val = ECD->getInitVal(); 1502973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara if (!SameSign) 1503973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara Val.setIsSigned(!ECD->getInitVal().isSigned()); 1504973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara if (!SameWidth) 1505973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->getType())); 1506973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara return Success(Val, E); 1507973c4fc0b0a88f9cea273b16f2082788a6e57d74Abramo Bagnara } 1508bfbdcd861a4364bfc21a9e5047bdbd56812d6693Abramo Bagnara } 15098cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return false; 15104c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 15114c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 1512a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way 1513a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner/// as GCC. 1514a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattnerstatic int EvaluateBuiltinClassifyType(const CallExpr *E) { 1515a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // The following enum mimics the values returned by GCC. 15167c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl // FIXME: Does GCC differ between lvalue and rvalue references here? 1517a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner enum gcc_type_class { 1518a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner no_type_class = -1, 1519a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner void_type_class, integer_type_class, char_type_class, 1520a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner enumeral_type_class, boolean_type_class, 1521a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner pointer_type_class, reference_type_class, offset_type_class, 1522a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner real_type_class, complex_type_class, 1523a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner function_type_class, method_type_class, 1524a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner record_type_class, union_type_class, 1525a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner array_type_class, string_type_class, 1526a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner lang_type_class 1527a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner }; 15281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // If no argument was supplied, default to "no_type_class". This isn't 1530a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // ideal, however it is what gcc does. 1531a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner if (E->getNumArgs() == 0) 1532a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return no_type_class; 15331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1534a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner QualType ArgTy = E->getArg(0)->getType(); 1535a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner if (ArgTy->isVoidType()) 1536a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return void_type_class; 1537a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isEnumeralType()) 1538a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return enumeral_type_class; 1539a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isBooleanType()) 1540a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return boolean_type_class; 1541a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isCharType()) 1542a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return string_type_class; // gcc doesn't appear to use char_type_class 1543a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isIntegerType()) 1544a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return integer_type_class; 1545a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isPointerType()) 1546a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return pointer_type_class; 1547a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isReferenceType()) 1548a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return reference_type_class; 1549a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isRealType()) 1550a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return real_type_class; 1551a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isComplexType()) 1552a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return complex_type_class; 1553a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isFunctionType()) 1554a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return function_type_class; 1555fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor else if (ArgTy->isStructureOrClassType()) 1556a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return record_type_class; 1557a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isUnionType()) 1558a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return union_type_class; 1559a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isArrayType()) 1560a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return array_type_class; 1561a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isUnionType()) 1562a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return union_type_class; 1563a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else // FIXME: offset_type_class, method_type_class, & lang_type_class? 1564b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("CallExpr::isBuiltinClassifyType(): unimplemented type"); 1565a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return -1; 1566a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner} 1567a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner 156842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// Retrieves the "underlying object type" of the given expression, 156942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// as used by __builtin_object_size. 157042c8f87eb60958170c46767273bf93e6c96125bfJohn McCallQualType IntExprEvaluator::GetObjectType(const Expr *E) { 157142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 157242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) 157342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return VD->getType(); 157442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall } else if (isa<CompoundLiteralExpr>(E)) { 157542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return E->getType(); 157642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall } 157742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 157842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return QualType(); 157942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall} 158042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 15818cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E) { 158242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall // TODO: Perhaps we should let LLVM lower this? 158342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall LValue Base; 158442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!EvaluatePointer(E->getArg(0), Base, Info)) 158542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 158642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 158742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall // If we can prove the base is null, lower to zero now. 158842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall const Expr *LVBase = Base.getLValueBase(); 158942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!LVBase) return Success(0, E); 159042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 159142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall QualType T = GetObjectType(LVBase); 159242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (T.isNull() || 159342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall T->isIncompleteType() || 15941357869bc5983cdfbc986db1f3d18265bb34cb0eEli Friedman T->isFunctionType() || 159542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall T->isVariablyModifiedType() || 159642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall T->isDependentType()) 159742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 159842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 159942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall CharUnits Size = Info.Ctx.getTypeSizeInChars(T); 160042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall CharUnits Offset = Base.getLValueOffset(); 160142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 160242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!Offset.isNegative() && Offset <= Size) 160342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall Size -= Offset; 160442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall else 160542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall Size = CharUnits::Zero(); 16064f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck return Success(Size, E); 160742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall} 160842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 16098cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { 16103c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor switch (E->isBuiltinCall(Info.Ctx)) { 1611019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner default: 16128cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return ExprEvaluatorBaseTy::VisitCallExpr(E); 161364eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 161464eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump case Builtin::BI__builtin_object_size: { 161542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (TryEvaluateBuiltinObjectSize(E)) 161642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return true; 161764eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 1618b2aaf51ed73a4774322a39a0dd59d0fe7e3258c0Eric Christopher // If evaluating the argument has side-effects we can't determine 1619b2aaf51ed73a4774322a39a0dd59d0fe7e3258c0Eric Christopher // the size of the object and lower it to unknown now. 1620393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian if (E->getArg(0)->HasSideEffects(Info.Ctx)) { 1621a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue() <= 1) 1622cf184655319cf7a5b811067cff9d26a5741fd161Chris Lattner return Success(-1ULL, E); 162364eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump return Success(0, E); 162464eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump } 1625c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 162664eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 162764eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump } 162864eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 1629019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_classify_type: 1630131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(EvaluateBuiltinClassifyType(E), E); 16311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 16324bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson case Builtin::BI__builtin_constant_p: 1633019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner // __builtin_constant_p always has one operand: it returns true if that 1634019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner // operand can be folded, false otherwise. 1635131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E); 163621fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner 163721fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner case Builtin::BI__builtin_eh_return_data_regno: { 1638a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith int Operand = E->getArg(0)->EvaluateKnownConstInt(Info.Ctx).getZExtValue(); 1639bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand); 164021fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner return Success(Operand, E); 164121fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner } 1642c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman 1643c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman case Builtin::BI__builtin_expect: 1644c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman return Visit(E->getArg(0)); 16455726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor 16465726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor case Builtin::BIstrlen: 16475726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor case Builtin::BI__builtin_strlen: 16485726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // As an extension, we support strlen() and __builtin_strlen() as constant 16495726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // expressions when the argument is a string literal. 16508cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne if (const StringLiteral *S 16515726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor = dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenImpCasts())) { 16525726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // The string literal may have embedded null characters. Find the first 16535726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // one and truncate there. 16545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Str = S->getString(); 16555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef::size_type Pos = Str.find(0); 16565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (Pos != StringRef::npos) 16575726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor Str = Str.substr(0, Pos); 16585726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor 16595726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor return Success(Str.size(), E); 16605726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor } 16615726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor 16625726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1663454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman 1664454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman case Builtin::BI__atomic_is_lock_free: { 1665454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman APSInt SizeVal; 1666454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman if (!EvaluateInteger(E->getArg(0), SizeVal, Info)) 1667454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman return false; 1668454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman 1669454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // For __atomic_is_lock_free(sizeof(_Atomic(T))), if the size is a power 1670454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // of two less than the maximum inline atomic width, we know it is 1671454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // lock-free. If the size isn't a power of two, or greater than the 1672454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // maximum alignment where we promote atomics, we know it is not lock-free 1673454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // (at least not in the sense of atomic_is_lock_free). Otherwise, 1674454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // the answer can only be determined at runtime; for example, 16-byte 1675454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // atomics have lock-free implementations on some, but not all, 1676454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // x86-64 processors. 1677454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman 1678454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // Check power-of-two. 1679454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue()); 1680454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman if (!Size.isPowerOfTwo()) 1681454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman#if 0 1682454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // FIXME: Suppress this folding until the ABI for the promotion width 1683454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // settles. 1684454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman return Success(0, E); 1685454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman#else 1686454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1687454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman#endif 1688454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman 1689454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman#if 0 1690454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // Check against promotion width. 1691454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // FIXME: Suppress this folding until the ABI for the promotion width 1692454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // settles. 1693454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman unsigned PromoteWidthBits = 1694454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman Info.Ctx.getTargetInfo().getMaxAtomicPromoteWidth(); 1695454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman if (Size > Info.Ctx.toCharUnitsFromBits(PromoteWidthBits)) 1696454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman return Success(0, E); 1697454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman#endif 1698454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman 1699454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman // Check against inlining width. 1700454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman unsigned InlineWidthBits = 1701454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth(); 1702454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) 1703454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman return Success(1, E); 1704454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman 1705454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1706454b57ac42c9ce0bed9b7a99c2ed5a18fbcd286bEli Friedman } 1707019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 17084c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 1709f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1710b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 1711c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (E->isAssignmentOp()) 1712c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E); 1713c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 17142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Comma) { 17158327fad71da34492d82c532f42a58cb4baff81a3Richard Smith VisitIgnoredValue(E->getLHS()); 17168327fad71da34492d82c532f42a58cb4baff81a3Richard Smith return Visit(E->getRHS()); 1717a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1718a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1719a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (E->isLogicalOp()) { 1720a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // These need to be handled specially because the operands aren't 1721a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // necessarily integral 1722fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson bool lhsResult, rhsResult; 17231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1724c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (EvaluateAsBooleanCondition(E->getLHS(), lhsResult, Info)) { 172551fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson // We were able to evaluate the LHS, see if we can get away with not 172651fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson // evaluating the RHS: 0 && X -> 0, 1 || X -> 1 17272de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (lhsResult == (E->getOpcode() == BO_LOr)) 17283f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar return Success(lhsResult, E); 1729a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1730c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) { 17312de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_LOr) 1732131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(lhsResult || rhsResult, E); 17334bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson else 1734131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(lhsResult && rhsResult, E); 17354bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } 17364bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } else { 1737c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) { 17384bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson // We can't evaluate the LHS; however, sometimes the result 17394bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson // is determined by the RHS: X && 0 -> 0, X || 1 -> 1. 17402de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (rhsResult == (E->getOpcode() == BO_LOr) || 17412de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall !rhsResult == (E->getOpcode() == BO_LAnd)) { 1742131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar // Since we weren't able to evaluate the left hand side, it 1743fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson // must have had side effects. 17441e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith Info.EvalStatus.HasSideEffects = true; 1745131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar 1746131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(rhsResult, E); 17474bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } 17484bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } 1749a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1750a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1751a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 1752c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner } 175354176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 1754286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson QualType LHSTy = E->getLHS()->getType(); 1755286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson QualType RHSTy = E->getRHS()->getType(); 17564087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 17574087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (LHSTy->isAnyComplexType()) { 17584087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar assert(RHSTy->isAnyComplexType() && "Invalid comparison"); 1759f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LHS, RHS; 17604087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 17614087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (!EvaluateComplex(E->getLHS(), LHS, Info)) 17624087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar return false; 17634087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 17644087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (!EvaluateComplex(E->getRHS(), RHS, Info)) 17654087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar return false; 17664087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 17674087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (LHS.isComplexFloat()) { 17681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump APFloat::cmpResult CR_r = 17694087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal()); 17701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump APFloat::cmpResult CR_i = 17714087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag()); 17724087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 17732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_EQ) 1774131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success((CR_r == APFloat::cmpEqual && 1775131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar CR_i == APFloat::cmpEqual), E); 1776131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar else { 17772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall assert(E->getOpcode() == BO_NE && 1778131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar "Invalid complex comparison."); 17791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Success(((CR_r == APFloat::cmpGreaterThan || 1780fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_r == APFloat::cmpLessThan || 1781fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_r == APFloat::cmpUnordered) || 17821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (CR_i == APFloat::cmpGreaterThan || 1783fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_i == APFloat::cmpLessThan || 1784fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_i == APFloat::cmpUnordered)), E); 1785131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 17864087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar } else { 17872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_EQ) 1788131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() && 1789131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar LHS.getComplexIntImag() == RHS.getComplexIntImag()), E); 1790131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar else { 17912de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall assert(E->getOpcode() == BO_NE && 1792131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar "Invalid compex comparison."); 1793131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() || 1794131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar LHS.getComplexIntImag() != RHS.getComplexIntImag()), E); 1795131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 17964087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar } 17974087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar } 17981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1799286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson if (LHSTy->isRealFloatingType() && 1800286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson RHSTy->isRealFloatingType()) { 1801286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson APFloat RHS(0.0), LHS(0.0); 18021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1803286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson if (!EvaluateFloat(E->getRHS(), RHS, Info)) 1804286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson return false; 18051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1806286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson if (!EvaluateFloat(E->getLHS(), LHS, Info)) 1807286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson return false; 18081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1809286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson APFloat::cmpResult CR = LHS.compare(RHS); 1810529569e68d10b0fd3750fd2124faf742249b846bAnders Carlsson 1811286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson switch (E->getOpcode()) { 1812286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson default: 1813b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid binary operator!"); 18142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LT: 1815131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpLessThan, E); 18162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GT: 1817131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpGreaterThan, E); 18182de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LE: 1819131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E); 18202de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GE: 18211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual, 1822131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar E); 18232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_EQ: 1824131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpEqual, E); 18252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_NE: 18261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Success(CR == APFloat::cmpGreaterThan 1827fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang || CR == APFloat::cmpLessThan 1828fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang || CR == APFloat::cmpUnordered, E); 1829286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson } 1830286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson } 18311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1832ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman if (LHSTy->isPointerType() && RHSTy->isPointerType()) { 18332de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Sub || E->isEqualityOp()) { 1834efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LHSValue; 18353068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluatePointer(E->getLHS(), LHSValue, Info)) 18363068d117951a8df54bae9db039b56201ab10962bAnders Carlsson return false; 1837a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 1838efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue RHSValue; 18393068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluatePointer(E->getRHS(), RHSValue, Info)) 18403068d117951a8df54bae9db039b56201ab10962bAnders Carlsson return false; 1841a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 18425bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman // Reject any bases from the normal codepath; we special-case comparisons 18435bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman // to null. 18445bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (LHSValue.getLValueBase()) { 18455bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!E->isEqualityOp()) 18465bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 1847a73058324197b7bdfd19307965954f626e26199dKen Dyck if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero()) 18485bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 18495bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman bool bres; 18505bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!EvalPointerValueAsBool(LHSValue, bres)) 18515bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 18522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall return Success(bres ^ (E->getOpcode() == BO_EQ), E); 18535bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman } else if (RHSValue.getLValueBase()) { 18545bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!E->isEqualityOp()) 18555bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 1856a73058324197b7bdfd19307965954f626e26199dKen Dyck if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero()) 18575bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 18585bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman bool bres; 18595bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!EvalPointerValueAsBool(RHSValue, bres)) 18605bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 18612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall return Success(bres ^ (E->getOpcode() == BO_EQ), E); 18625bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman } 1863a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 18642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Sub) { 18654992bdde387c5f033bb450a716eaabc0fda52688Chris Lattner QualType Type = E->getLHS()->getType(); 18664992bdde387c5f033bb450a716eaabc0fda52688Chris Lattner QualType ElementType = Type->getAs<PointerType>()->getPointeeType(); 18673068d117951a8df54bae9db039b56201ab10962bAnders Carlsson 1868a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits ElementSize = CharUnits::One(); 1869ce1bca73aef9bbf6359ab8420278203dda81a054Eli Friedman if (!ElementType->isVoidType() && !ElementType->isFunctionType()) 1870a73058324197b7bdfd19307965954f626e26199dKen Dyck ElementSize = Info.Ctx.getTypeSizeInChars(ElementType); 1871a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 1872a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits Diff = LHSValue.getLValueOffset() - 1873a73058324197b7bdfd19307965954f626e26199dKen Dyck RHSValue.getLValueOffset(); 1874a73058324197b7bdfd19307965954f626e26199dKen Dyck return Success(Diff / ElementSize, E); 1875ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman } 1876ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman bool Result; 18772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_EQ) { 1878ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset(); 1879267c0ab1b9a15768f3f15abbfc40ce344751c78bEli Friedman } else { 1880ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset(); 1881ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman } 1882ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman return Success(Result, E); 18833068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 18843068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 18852ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!LHSTy->isIntegralOrEnumerationType() || 18862ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor !RHSTy->isIntegralOrEnumerationType()) { 1887a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // We can't continue from here for non-integral types, and they 1888a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // could potentially confuse the following operations. 1889a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 1890a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1891a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1892a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // The LHS of a constant expr is always evaluated and needed. 1893c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APValue LHSVal; 1894c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateIntegerOrLValue(E->getLHS(), LHSVal, Info)) 1895a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; // error in subexpression. 1896d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman 1897c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Visit(E->getRHS())) 189830c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return false; 1899c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APValue &RHSVal = Result; 190042edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 190142edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman // Handle cases like (unsigned long)&a + 4. 1902c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (E->isAdditiveOp() && LHSVal.isLValue() && RHSVal.isInt()) { 1903c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith CharUnits Offset = LHSVal.getLValueOffset(); 1904a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits AdditionalOffset = CharUnits::fromQuantity( 1905a73058324197b7bdfd19307965954f626e26199dKen Dyck RHSVal.getInt().getZExtValue()); 19062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Add) 1907a73058324197b7bdfd19307965954f626e26199dKen Dyck Offset += AdditionalOffset; 190842edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman else 1909a73058324197b7bdfd19307965954f626e26199dKen Dyck Offset -= AdditionalOffset; 1910c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Result = APValue(LHSVal.getLValueBase(), Offset); 191142edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman return true; 191242edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman } 191342edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 191442edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman // Handle cases like 4 + (unsigned long)&a 19152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Add && 1916c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith RHSVal.isLValue() && LHSVal.isInt()) { 1917a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits Offset = RHSVal.getLValueOffset(); 1918c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Offset += CharUnits::fromQuantity(LHSVal.getInt().getZExtValue()); 1919a73058324197b7bdfd19307965954f626e26199dKen Dyck Result = APValue(RHSVal.getLValueBase(), Offset); 192042edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman return true; 192142edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman } 192242edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 192342edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman // All the following cases expect both operands to be an integer 1924c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!LHSVal.isInt() || !RHSVal.isInt()) 1925b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 1926a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1927c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APSInt &LHS = LHSVal.getInt(); 1928c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APSInt &RHS = RHSVal.getInt(); 192942edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 1930a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson switch (E->getOpcode()) { 193132fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner default: 19320e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E); 1933c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_Mul: return Success(LHS * RHS, E); 1934c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_Add: return Success(LHS + RHS, E); 1935c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_Sub: return Success(LHS - RHS, E); 1936c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_And: return Success(LHS & RHS, E); 1937c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_Xor: return Success(LHS ^ RHS, E); 1938c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_Or: return Success(LHS | RHS, E); 19392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Div: 194054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 19410e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E); 1942c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(LHS / RHS, E); 19432de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Rem: 194454176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 19450e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E); 1946c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(LHS % RHS, E); 19472de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shl: { 1948091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall // During constant-folding, a negative shift is an opposite shift. 1949091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall if (RHS.isSigned() && RHS.isNegative()) { 1950091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall RHS = -RHS; 1951091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall goto shift_right; 1952091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall } 1953091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall 1954091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall shift_left: 1955091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall unsigned SA 1956c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1); 1957c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(LHS << SA, E); 19583f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar } 19592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shr: { 1960091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall // During constant-folding, a negative shift is an opposite shift. 1961091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall if (RHS.isSigned() && RHS.isNegative()) { 1962091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall RHS = -RHS; 1963091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall goto shift_left; 1964091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall } 1965091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall 1966091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall shift_right: 19671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned SA = 1968c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1); 1969c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(LHS >> SA, E); 19703f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar } 19711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1972c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_LT: return Success(LHS < RHS, E); 1973c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_GT: return Success(LHS > RHS, E); 1974c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_LE: return Success(LHS <= RHS, E); 1975c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_GE: return Success(LHS >= RHS, E); 1976c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_EQ: return Success(LHS == RHS, E); 1977c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith case BO_NE: return Success(LHS != RHS, E); 1978b11e77836dd0867955c5abf32baf1c3e6c7f81e1Eli Friedman } 1979a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 1980a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 19818b752f10c394b140f9ef89e049cbad1a7676fc25Ken DyckCharUnits IntExprEvaluator::GetAlignOfType(QualType T) { 19825d484e8cf710207010720589d89602233de61d01Sebastian Redl // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, 19835d484e8cf710207010720589d89602233de61d01Sebastian Redl // the result is the size of the referenced type." 19845d484e8cf710207010720589d89602233de61d01Sebastian Redl // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the 19855d484e8cf710207010720589d89602233de61d01Sebastian Redl // result shall be the alignment of the referenced type." 19865d484e8cf710207010720589d89602233de61d01Sebastian Redl if (const ReferenceType *Ref = T->getAs<ReferenceType>()) 19875d484e8cf710207010720589d89602233de61d01Sebastian Redl T = Ref->getPointeeType(); 19889f1210c3280104417a4ad30f0a00825ac8fa718aChad Rosier 19899f1210c3280104417a4ad30f0a00825ac8fa718aChad Rosier // __alignof is defined to return the preferred alignment. 19909f1210c3280104417a4ad30f0a00825ac8fa718aChad Rosier return Info.Ctx.toCharUnitsFromBits( 19919f1210c3280104417a4ad30f0a00825ac8fa718aChad Rosier Info.Ctx.getPreferredTypeAlign(T.getTypePtr())); 1992e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner} 1993e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner 19948b752f10c394b140f9ef89e049cbad1a7676fc25Ken DyckCharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) { 1995af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner E = E->IgnoreParens(); 1996af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner 1997af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner // alignof decl is always accepted, even if it doesn't make sense: we default 19981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // to 1 in those cases. 1999af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 20008b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck return Info.Ctx.getDeclAlign(DRE->getDecl(), 20018b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck /*RefAsPointee*/true); 2002a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 2003af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) 20048b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck return Info.Ctx.getDeclAlign(ME->getMemberDecl(), 20058b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck /*RefAsPointee*/true); 2006af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner 2007e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner return GetAlignOfType(E->getType()); 2008e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner} 2009e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner 2010e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner 2011f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne/// VisitUnaryExprOrTypeTraitExpr - Evaluate a sizeof, alignof or vec_step with 2012f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne/// a result as the expression's type. 2013f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbournebool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr( 2014f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne const UnaryExprOrTypeTraitExpr *E) { 2015f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne switch(E->getKind()) { 2016f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case UETT_AlignOf: { 2017e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner if (E->isArgumentType()) 20184f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck return Success(GetAlignOfType(E->getArgumentType()), E); 2019e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner else 20204f3bc8f7aa90b72832b03bee9201c98f4bb6b4d1Ken Dyck return Success(GetAlignOfExpr(E->getArgumentExpr()), E); 2021e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner } 2022a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 2023f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case UETT_VecStep: { 2024f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne QualType Ty = E->getTypeOfArgument(); 20250518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 2026f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if (Ty->isVectorType()) { 2027f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne unsigned n = Ty->getAs<VectorType>()->getNumElements(); 2028a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 2029f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // The vec_step built-in functions that take a 3-component 2030f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // vector return 4. (OpenCL 1.1 spec 6.11.12) 2031f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if (n == 3) 2032f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne n = 4; 2033f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne 2034f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return Success(n, E); 2035f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne } else 2036f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return Success(1, E); 2037f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne } 2038f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne 2039f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case UETT_SizeOf: { 2040f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne QualType SrcTy = E->getTypeOfArgument(); 2041f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, 2042f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // the result is the size of the referenced type." 2043f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the 2044f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // result shall be the alignment of the referenced type." 2045f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>()) 2046f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne SrcTy = Ref->getPointeeType(); 2047f2da9dfef96dc11b7b5effb1d02cb427b2d71599Eli Friedman 2048f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc 2049f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // extension. 2050f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if (SrcTy->isVoidType() || SrcTy->isFunctionType()) 2051f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return Success(1, E); 2052f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne 2053f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. 2054f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if (!SrcTy->isConstantSizeType()) 2055f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return false; 2056f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne 2057f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne // Get information about the size. 2058f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return Success(Info.Ctx.getTypeSizeInChars(SrcTy), E); 2059f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne } 2060f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne } 2061f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne 2062f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne llvm_unreachable("unknown expr/type trait"); 2063f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne return false; 2064fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner} 2065fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 20668cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { 20678ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CharUnits Result; 20688cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne unsigned n = OOE->getNumComponents(); 20698ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (n == 0) 20708ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 20718cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne QualType CurrentType = OOE->getTypeSourceInfo()->getType(); 20728ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor for (unsigned i = 0; i != n; ++i) { 20738ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor OffsetOfExpr::OffsetOfNode ON = OOE->getComponent(i); 20748ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor switch (ON.getKind()) { 20758ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case OffsetOfExpr::OffsetOfNode::Array: { 20768cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr *Idx = OOE->getIndexExpr(ON.getArrayExprIndex()); 20778ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor APSInt IdxResult; 20788ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (!EvaluateInteger(Idx, IdxResult, Info)) 20798ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 20808ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType); 20818ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (!AT) 20828ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 20838ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CurrentType = AT->getElementType(); 20848ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType); 20858ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor Result += IdxResult.getSExtValue() * ElementSize; 20868ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 20878ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 20888ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 20898ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case OffsetOfExpr::OffsetOfNode::Field: { 20908ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor FieldDecl *MemberDecl = ON.getField(); 20918ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor const RecordType *RT = CurrentType->getAs<RecordType>(); 20928ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (!RT) 20938ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 20948ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor RecordDecl *RD = RT->getDecl(); 20958ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 2096ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall unsigned i = MemberDecl->getFieldIndex(); 2097cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor assert(i < RL.getFieldCount() && "offsetof field in wrong type"); 2098fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Result += Info.Ctx.toCharUnitsFromBits(RL.getFieldOffset(i)); 20998ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CurrentType = MemberDecl->getType().getNonReferenceType(); 21008ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 21018ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 21028ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 21038ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case OffsetOfExpr::OffsetOfNode::Identifier: 21048ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor llvm_unreachable("dependent __builtin_offsetof"); 2105cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 2106cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 2107cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor case OffsetOfExpr::OffsetOfNode::Base: { 2108cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor CXXBaseSpecifier *BaseSpec = ON.getBase(); 2109cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor if (BaseSpec->isVirtual()) 2110cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 2111cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 2112cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor // Find the layout of the class whose base we are looking into. 2113cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor const RecordType *RT = CurrentType->getAs<RecordType>(); 2114cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor if (!RT) 2115cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 2116cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor RecordDecl *RD = RT->getDecl(); 2117cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 2118cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 2119cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor // Find the base class itself. 2120cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor CurrentType = BaseSpec->getType(); 2121cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor const RecordType *BaseRT = CurrentType->getAs<RecordType>(); 2122cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor if (!BaseRT) 2123cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 2124cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 2125cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor // Add the offset to the base. 21267c7f820d70c925b29290a8563b59615816a827fcKen Dyck Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl())); 2127cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor break; 2128cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor } 21298ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 21308ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 21318cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return Success(Result, OOE); 21328ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor} 21338ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 2134b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 21352de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == UO_LNot) { 2136a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // LNot's operand isn't necessarily an integer, so we handle it specially. 2137a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman bool bres; 2138c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateAsBooleanCondition(E->getSubExpr(), bres, Info)) 2139a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 2140131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(!bres, E); 2141a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 2142a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 21434fff4819a913c65ae23cfd389bc47c61919e4e1fDaniel Dunbar // Only handle integral operations... 21442ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!E->getSubExpr()->getType()->isIntegralOrEnumerationType()) 21454fff4819a913c65ae23cfd389bc47c61919e4e1fDaniel Dunbar return false; 21464fff4819a913c65ae23cfd389bc47c61919e4e1fDaniel Dunbar 2147c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // Get the operand value. 2148c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith APValue Val; 2149c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Evaluate(Val, Info, E->getSubExpr())) 215075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner return false; 2151a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 215275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner switch (E->getOpcode()) { 21534c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner default: 215475a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // Address, indirect, pre/post inc/dec, etc are not valid constant exprs. 215575a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // See C99 6.6p3. 21560e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E); 21572de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Extension: 21584c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // FIXME: Should extension allow i-c-e extension expressions in its scope? 21594c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // If so, we could clear the diagnostic ID. 2160c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(Val, E); 21612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Plus: 2162c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // The result is just the value. 2163c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(Val, E); 21642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Minus: 2165c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Val.isInt()) return false; 2166c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(-Val.getInt(), E); 21672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Not: 2168c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Val.isInt()) return false; 2169c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Success(~Val.getInt(), E); 217006a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 2171a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 21721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2173732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// HandleCast - This is used to evaluate implicit or explicit casts where the 2174732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// result type is integer. 21758cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { 21768cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr *SubExpr = E->getSubExpr(); 217782206e267ce6cc709797127616f64672d255b310Anders Carlsson QualType DestType = E->getType(); 2178b92dac8bc2f6f73919825f9af693a8a7e89ae1d4Daniel Dunbar QualType SrcType = SubExpr->getType(); 217982206e267ce6cc709797127616f64672d255b310Anders Carlsson 218046a523285928aa07bf14803178dc04616ac85994Eli Friedman switch (E->getCastKind()) { 218146a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_BaseToDerived: 218246a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_DerivedToBase: 218346a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_UncheckedDerivedToBase: 218446a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_Dynamic: 218546a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_ToUnion: 218646a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_ArrayToPointerDecay: 218746a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FunctionToPointerDecay: 218846a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_NullToPointer: 218946a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_NullToMemberPointer: 219046a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_BaseToDerivedMemberPointer: 219146a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_DerivedToBaseMemberPointer: 219246a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_ConstructorConversion: 219346a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralToPointer: 219446a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_ToVoid: 219546a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_VectorSplat: 219646a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralToFloating: 219746a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingCast: 21981d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_CPointerToObjCPointerCast: 21991d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_BlockPointerToObjCPointerCast: 220046a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_AnyPointerToBlockPointerCast: 220146a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_ObjCObjectLValueCast: 220246a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingRealToComplex: 220346a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingComplexToReal: 220446a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingComplexCast: 220546a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingComplexToIntegralComplex: 220646a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralRealToComplex: 220746a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralComplexCast: 220846a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralComplexToFloatingComplex: 220946a523285928aa07bf14803178dc04616ac85994Eli Friedman llvm_unreachable("invalid cast kind for integral value"); 221046a523285928aa07bf14803178dc04616ac85994Eli Friedman 2211e50c297f92914ca996deb8b597624193273b62e4Eli Friedman case CK_BitCast: 221246a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_Dependent: 221346a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_GetObjCProperty: 221446a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_LValueBitCast: 221546a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_UserDefinedConversion: 221633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCProduceObject: 221733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCConsumeObject: 221833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCReclaimReturnedObject: 221933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCExtendBlockObject: 222046a523285928aa07bf14803178dc04616ac85994Eli Friedman return false; 222146a523285928aa07bf14803178dc04616ac85994Eli Friedman 222246a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_LValueToRValue: 222346a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_NoOp: 2224c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return ExprEvaluatorBaseTy::VisitCastExpr(E); 222546a523285928aa07bf14803178dc04616ac85994Eli Friedman 222646a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_MemberPointerToBoolean: 222746a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_PointerToBoolean: 222846a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralToBoolean: 222946a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingToBoolean: 223046a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingComplexToBoolean: 223146a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralComplexToBoolean: { 22324efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool BoolResult; 2233c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateAsBooleanCondition(SubExpr, BoolResult, Info)) 22344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 2235131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(BoolResult, E); 22364efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 22374efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 223846a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralCast: { 2239732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (!Visit(SubExpr)) 2240b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 2241a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 2242be26570e3faa009bdcefedfaf04473e518940520Eli Friedman if (!Result.isInt()) { 2243be26570e3faa009bdcefedfaf04473e518940520Eli Friedman // Only allow casts of lvalues if they are lossless. 2244be26570e3faa009bdcefedfaf04473e518940520Eli Friedman return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType); 2245be26570e3faa009bdcefedfaf04473e518940520Eli Friedman } 224630c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar 2247dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return Success(HandleIntToIntCast(DestType, SrcType, 224830c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result.getInt(), Info.Ctx), E); 2249732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner } 22501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 225146a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_PointerToIntegral: { 2252efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 225387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluatePointer(SubExpr, LV, Info)) 2254b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 22554efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2256dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar if (LV.getLValueBase()) { 2257dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar // Only allow based lvalue casts if they are lossless. 2258dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType)) 2259dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return false; 2260dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar 2261efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LV.moveInto(Result); 2262dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return true; 2263dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar } 22644efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2265a73058324197b7bdfd19307965954f626e26199dKen Dyck APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), 2266a73058324197b7bdfd19307965954f626e26199dKen Dyck SrcType); 2267dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E); 22682bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 22694efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 227046a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_IntegralComplexToReal: { 2271f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue C; 22721725f683432715e5afe34d476024bd6f16eac3fcEli Friedman if (!EvaluateComplex(SubExpr, C, Info)) 22731725f683432715e5afe34d476024bd6f16eac3fcEli Friedman return false; 227446a523285928aa07bf14803178dc04616ac85994Eli Friedman return Success(C.getComplexIntReal(), E); 22751725f683432715e5afe34d476024bd6f16eac3fcEli Friedman } 22762217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman 227746a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_FloatingToIntegral: { 227846a523285928aa07bf14803178dc04616ac85994Eli Friedman APFloat F(0.0); 227946a523285928aa07bf14803178dc04616ac85994Eli Friedman if (!EvaluateFloat(SubExpr, F, Info)) 228046a523285928aa07bf14803178dc04616ac85994Eli Friedman return false; 2281732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 228246a523285928aa07bf14803178dc04616ac85994Eli Friedman return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E); 228346a523285928aa07bf14803178dc04616ac85994Eli Friedman } 228446a523285928aa07bf14803178dc04616ac85994Eli Friedman } 22851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 228646a523285928aa07bf14803178dc04616ac85994Eli Friedman llvm_unreachable("unknown cast resulting in integral value"); 228746a523285928aa07bf14803178dc04616ac85994Eli Friedman return false; 2288a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 22892bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 2290722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedmanbool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { 2291722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (E->getSubExpr()->getType()->isAnyComplexType()) { 2292f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LV; 2293722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt()) 2294722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); 2295722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Success(LV.getComplexIntReal(), E); 2296722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman } 2297722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman 2298722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Visit(E->getSubExpr()); 2299722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman} 2300722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman 2301664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedmanbool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { 2302722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (E->getSubExpr()->getType()->isComplexIntegerType()) { 2303f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LV; 2304722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt()) 2305722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); 2306722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Success(LV.getComplexIntImag(), E); 2307722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman } 2308722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman 23098327fad71da34492d82c532f42a58cb4baff81a3Richard Smith VisitIgnoredValue(E->getSubExpr()); 2310664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman return Success(0, E); 2311664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman} 2312664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman 2313ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregorbool IntExprEvaluator::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { 2314ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor return Success(E->getPackLength(), E); 2315ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor} 2316ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor 2317295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redlbool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { 2318295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl return Success(E->getValue(), E); 2319295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl} 2320295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl 2321f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 2322d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman// Float Evaluation 2323d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 2324d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2325d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmannamespace { 2326770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass FloatExprEvaluator 23278cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ExprEvaluatorBase<FloatExprEvaluator, bool> { 2328d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat &Result; 2329d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanpublic: 2330d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman FloatExprEvaluator(EvalInfo &info, APFloat &result) 23318cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : ExprEvaluatorBaseTy(info), Result(result) {} 2332d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 23338cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const APValue &V, const Expr *e) { 23348cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne Result = V.getFloat(); 23358cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return true; 23368cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 23378cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Error(const Stmt *S) { 2338d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 2339d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 2340d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2341f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith bool ValueInitialization(const Expr *E) { 2342f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType())); 2343f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith return true; 2344f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith } 2345f10d9171ac24380ca94c71847a9270a05b791cefRichard Smith 2346019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner bool VisitCallExpr(const CallExpr *E); 2347d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 23485db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar bool VisitUnaryOperator(const UnaryOperator *E); 2349d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitBinaryOperator(const BinaryOperator *E); 2350d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitFloatingLiteral(const FloatingLiteral *E); 23518cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCastExpr(const CastExpr *E); 23522217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman 2353abd3a857ace59100305790545d1baae5877b8945John McCall bool VisitUnaryReal(const UnaryOperator *E); 2354abd3a857ace59100305790545d1baae5877b8945John McCall bool VisitUnaryImag(const UnaryOperator *E); 2355ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman 2356abd3a857ace59100305790545d1baae5877b8945John McCall // FIXME: Missing: array subscript of vector, member of vector, 2357abd3a857ace59100305790545d1baae5877b8945John McCall // ImplicitValueInitExpr 2358d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman}; 2359d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} // end anonymous namespace 2360d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2361d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) { 2362c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(E->isRValue() && E->getType()->isRealFloatingType()); 23638cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return FloatExprEvaluator(Info, Result).Visit(E); 2364d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 2365d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 23664ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadstatic bool TryEvaluateBuiltinNaN(const ASTContext &Context, 2367db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall QualType ResultTy, 2368db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall const Expr *Arg, 2369db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall bool SNaN, 2370db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall llvm::APFloat &Result) { 2371db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts()); 2372db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall if (!S) return false; 2373db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 2374db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy); 2375db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 2376db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall llvm::APInt fill; 2377db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 2378db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall // Treat empty strings as if they were zero. 2379db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall if (S->getString().empty()) 2380db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall fill = llvm::APInt(32, 0); 2381db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall else if (S->getString().getAsInteger(0, fill)) 2382db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return false; 2383db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 2384db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall if (SNaN) 2385db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall Result = llvm::APFloat::getSNaN(Sem, false, &fill); 2386db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall else 2387db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall Result = llvm::APFloat::getQNaN(Sem, false, &fill); 2388db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return true; 2389db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall} 2390db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 2391019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattnerbool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { 23923c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor switch (E->isBuiltinCall(Info.Ctx)) { 23938cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne default: 23948cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return ExprEvaluatorBaseTy::VisitCallExpr(E); 23958cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne 2396019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_val: 2397019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_valf: 2398019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_vall: 2399019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_inf: 2400019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_inff: 24017cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar case Builtin::BI__builtin_infl: { 24027cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar const llvm::fltSemantics &Sem = 24037cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar Info.Ctx.getFloatTypeSemantics(E->getType()); 240434a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner Result = llvm::APFloat::getInf(Sem); 240534a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner return true; 24067cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar } 24071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2408db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall case Builtin::BI__builtin_nans: 2409db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall case Builtin::BI__builtin_nansf: 2410db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall case Builtin::BI__builtin_nansl: 2411db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0), 2412db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall true, Result); 2413db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 24149e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nan: 24159e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nanf: 24169e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nanl: 24174572baba9d18c275968ac113fd73b0e3c77cccb8Mike Stump // If this is __builtin_nan() turn this into a nan, otherwise we 24189e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner // can't constant fold it. 2419db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0), 2420db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall false, Result); 24215db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 24225db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabs: 24235db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabsf: 24245db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabsl: 24255db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getArg(0), Result, Info)) 24265db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 24271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24285db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (Result.isNegative()) 24295db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.changeSign(); 24305db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 24315db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 24321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_copysign: 24331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_copysignf: 24345db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_copysignl: { 24355db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar APFloat RHS(0.); 24365db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getArg(0), Result, Info) || 24375db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar !EvaluateFloat(E->getArg(1), RHS, Info)) 24385db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 24395db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.copySign(RHS); 24405db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 24415db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar } 2442019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 2443019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner} 2444019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 2445abd3a857ace59100305790545d1baae5877b8945John McCallbool FloatExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { 244643efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (E->getSubExpr()->getType()->isAnyComplexType()) { 244743efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman ComplexValue CV; 244843efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (!EvaluateComplex(E->getSubExpr(), CV, Info)) 244943efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return false; 245043efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Result = CV.FloatReal; 245143efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return true; 245243efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman } 245343efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman 245443efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return Visit(E->getSubExpr()); 2455abd3a857ace59100305790545d1baae5877b8945John McCall} 2456abd3a857ace59100305790545d1baae5877b8945John McCall 2457abd3a857ace59100305790545d1baae5877b8945John McCallbool FloatExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { 245843efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (E->getSubExpr()->getType()->isAnyComplexType()) { 245943efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman ComplexValue CV; 246043efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (!EvaluateComplex(E->getSubExpr(), CV, Info)) 246143efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return false; 246243efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Result = CV.FloatImag; 246343efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return true; 246443efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman } 246543efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman 24668327fad71da34492d82c532f42a58cb4baff81a3Richard Smith VisitIgnoredValue(E->getSubExpr()); 246743efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->getType()); 246843efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Result = llvm::APFloat::getZero(Sem); 2469abd3a857ace59100305790545d1baae5877b8945John McCall return true; 2470abd3a857ace59100305790545d1baae5877b8945John McCall} 2471abd3a857ace59100305790545d1baae5877b8945John McCall 24725db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbarbool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 24732de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == UO_Deref) 2474a468d34bed16861f25aff6c8354f4e75d3358c1aNuno Lopes return false; 2475a468d34bed16861f25aff6c8354f4e75d3358c1aNuno Lopes 24765db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getSubExpr(), Result, Info)) 24775db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 24785db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 24795db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar switch (E->getOpcode()) { 24805db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar default: return false; 24812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Plus: 24825db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 24832de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Minus: 24845db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.changeSign(); 24855db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 24865db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar } 24875db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar} 2488019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 2489d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 24902de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Comma) { 24918327fad71da34492d82c532f42a58cb4baff81a3Richard Smith VisitIgnoredValue(E->getLHS()); 24928327fad71da34492d82c532f42a58cb4baff81a3Richard Smith return Visit(E->getRHS()); 24937f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman } 24947f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman 249596e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson // We can't evaluate pointer-to-member operations. 249696e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson if (E->isPtrMemOp()) 249796e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson return false; 249896e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson 2499d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // FIXME: Diagnostics? I really don't understand how the warnings 2500d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // and errors are supposed to work. 25015db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar APFloat RHS(0.0); 2502d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getLHS(), Result, Info)) 2503d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 2504d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getRHS(), RHS, Info)) 2505d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 2506d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2507d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman switch (E->getOpcode()) { 2508d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman default: return false; 25092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: 2510d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.multiply(RHS, APFloat::rmNearestTiesToEven); 2511d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 25122de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: 2513d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.add(RHS, APFloat::rmNearestTiesToEven); 2514d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 25152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: 2516d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.subtract(RHS, APFloat::rmNearestTiesToEven); 2517d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 25182de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Div: 2519d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.divide(RHS, APFloat::rmNearestTiesToEven); 2520d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 2521d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 2522d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 2523d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2524d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { 2525d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = E->getValue(); 2526d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 2527d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 2528d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 25298cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool FloatExprEvaluator::VisitCastExpr(const CastExpr *E) { 25308cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr* SubExpr = E->getSubExpr(); 25311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25322a523eec6a31955be876625819b89e8dc5def707Eli Friedman switch (E->getCastKind()) { 25332a523eec6a31955be876625819b89e8dc5def707Eli Friedman default: 2534c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return ExprEvaluatorBaseTy::VisitCastExpr(E); 25352a523eec6a31955be876625819b89e8dc5def707Eli Friedman 25362a523eec6a31955be876625819b89e8dc5def707Eli Friedman case CK_IntegralToFloating: { 25374efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APSInt IntResult; 25383f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar if (!EvaluateInteger(SubExpr, IntResult, Info)) 25394efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 25401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(), 2541a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar IntResult, Info.Ctx); 25424efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 25434efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 25442a523eec6a31955be876625819b89e8dc5def707Eli Friedman 25452a523eec6a31955be876625819b89e8dc5def707Eli Friedman case CK_FloatingCast: { 25464efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!Visit(SubExpr)) 25474efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 2548a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(), 2549a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result, Info.Ctx); 25504efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 25514efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 2552f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall 25532a523eec6a31955be876625819b89e8dc5def707Eli Friedman case CK_FloatingComplexToReal: { 2554f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall ComplexValue V; 2555f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall if (!EvaluateComplex(SubExpr, V, Info)) 2556f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall return false; 2557f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall Result = V.getComplexFloatReal(); 2558f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall return true; 2559f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall } 25602a523eec6a31955be876625819b89e8dc5def707Eli Friedman } 25614efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 25624efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 25634efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 25644efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2565d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 2566a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar// Complex Evaluation (for float and integer) 25679ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson//===----------------------------------------------------------------------===// 25689ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 25699ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlssonnamespace { 2570770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass ComplexExprEvaluator 25718cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : public ExprEvaluatorBase<ComplexExprEvaluator, bool> { 2572f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue &Result; 25731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25749ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlssonpublic: 2575f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result) 25768cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne : ExprEvaluatorBaseTy(info), Result(Result) {} 25771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25788cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Success(const APValue &V, const Expr *e) { 25798cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne Result.setFrom(V); 25808cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return true; 25818cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne } 25828cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool Error(const Expr *E) { 2583f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return false; 25849ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson } 25851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 25868cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne //===--------------------------------------------------------------------===// 25878cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne // Visitor Methods 25888cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne //===--------------------------------------------------------------------===// 25899ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 25908cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitImaginaryLiteral(const ImaginaryLiteral *E); 2591a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar 25928cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne bool VisitCastExpr(const CastExpr *E); 2593b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2594b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman bool VisitBinaryOperator(const BinaryOperator *E); 259596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara bool VisitUnaryOperator(const UnaryOperator *E); 2596cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl // FIXME Missing: ImplicitValueInitExpr, InitListExpr 2597b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman}; 2598b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman} // end anonymous namespace 25991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2600b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedmanstatic bool EvaluateComplex(const Expr *E, ComplexValue &Result, 2601b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman EvalInfo &Info) { 2602c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith assert(E->isRValue() && E->getType()->isAnyComplexType()); 26038cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne return ComplexExprEvaluator(Info, Result).Visit(E); 2604b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman} 2605b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 26068cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool ComplexExprEvaluator::VisitImaginaryLiteral(const ImaginaryLiteral *E) { 26078cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbourne const Expr* SubExpr = E->getSubExpr(); 2608b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2609b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman if (SubExpr->getType()->isRealFloatingType()) { 2610b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.makeComplexFloat(); 2611b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APFloat &Imag = Result.FloatImag; 2612b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman if (!EvaluateFloat(SubExpr, Imag, Info)) 2613b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2614b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2615b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.FloatReal = APFloat(Imag.getSemantics()); 2616b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return true; 2617b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman } else { 2618b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman assert(SubExpr->getType()->isIntegerType() && 2619b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman "Unexpected imaginary literal."); 2620b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2621b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.makeComplexInt(); 2622b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APSInt &Imag = Result.IntImag; 2623b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman if (!EvaluateInteger(SubExpr, Imag, Info)) 2624b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2625b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2626b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned()); 2627b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return true; 2628b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman } 2629b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman} 2630b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 26318cad3046be06ea73ff8892d947697a21d7a440d3Peter Collingbournebool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { 2632b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 26338786da77984e81d48e0e1b2bd339809b1efc19f3John McCall switch (E->getCastKind()) { 26348786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_BitCast: 26358786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_BaseToDerived: 26368786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_DerivedToBase: 26378786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_UncheckedDerivedToBase: 26388786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_Dynamic: 26398786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ToUnion: 26408786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ArrayToPointerDecay: 26418786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FunctionToPointerDecay: 26428786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_NullToPointer: 26438786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_NullToMemberPointer: 26448786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_BaseToDerivedMemberPointer: 26458786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_DerivedToBaseMemberPointer: 26468786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_MemberPointerToBoolean: 26478786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ConstructorConversion: 26488786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralToPointer: 26498786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_PointerToIntegral: 26508786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_PointerToBoolean: 26518786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ToVoid: 26528786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_VectorSplat: 26538786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralCast: 26548786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralToBoolean: 26558786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralToFloating: 26568786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingToIntegral: 26578786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingToBoolean: 26588786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingCast: 26591d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_CPointerToObjCPointerCast: 26601d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall case CK_BlockPointerToObjCPointerCast: 26618786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_AnyPointerToBlockPointerCast: 26628786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ObjCObjectLValueCast: 26638786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexToReal: 26648786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexToBoolean: 26658786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexToReal: 26668786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexToBoolean: 266733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCProduceObject: 266833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCConsumeObject: 266933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCReclaimReturnedObject: 267033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall case CK_ARCExtendBlockObject: 26718786da77984e81d48e0e1b2bd339809b1efc19f3John McCall llvm_unreachable("invalid cast kind for complex value"); 26728786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 26738786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_LValueToRValue: 26748786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_NoOp: 2675c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return ExprEvaluatorBaseTy::VisitCastExpr(E); 26762bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall 26778786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_Dependent: 26788786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_GetObjCProperty: 267946a523285928aa07bf14803178dc04616ac85994Eli Friedman case CK_LValueBitCast: 26808786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_UserDefinedConversion: 26818786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 26828786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 26838786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingRealToComplex: { 2684b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APFloat &Real = Result.FloatReal; 26858786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!EvaluateFloat(E->getSubExpr(), Real, Info)) 2686b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2687b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 26888786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexFloat(); 26898786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatImag = APFloat(Real.getSemantics()); 26908786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 26918786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 26928786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 26938786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexCast: { 26948786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 26958786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 26968786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 26978786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 26988786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 26998786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 27008786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27018786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatReal 27028786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = HandleFloatToFloatCast(To, From, Result.FloatReal, Info.Ctx); 27038786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatImag 27048786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = HandleFloatToFloatCast(To, From, Result.FloatImag, Info.Ctx); 27058786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 27068786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 27078786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27088786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexToIntegralComplex: { 27098786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 27108786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 27118786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27128786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 27138786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 27148786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 27158786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexInt(); 27168786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntReal = HandleFloatToIntCast(To, From, Result.FloatReal, Info.Ctx); 27178786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntImag = HandleFloatToIntCast(To, From, Result.FloatImag, Info.Ctx); 27188786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 27198786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 27208786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27218786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralRealToComplex: { 2722b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APSInt &Real = Result.IntReal; 27238786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!EvaluateInteger(E->getSubExpr(), Real, Info)) 2724b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 27259ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 27268786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexInt(); 27278786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned()); 27288786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 27298786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 27308786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27318786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexCast: { 27328786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 2733b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2734ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson 27358786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 27368786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 27378786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 27381725f683432715e5afe34d476024bd6f16eac3fcEli Friedman 27398786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntReal = HandleIntToIntCast(To, From, Result.IntReal, Info.Ctx); 27408786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntImag = HandleIntToIntCast(To, From, Result.IntImag, Info.Ctx); 27418786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 27428786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 27438786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27448786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexToFloatingComplex: { 27458786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 27468786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 27478786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 27488786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 27498786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 27508786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 27518786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexFloat(); 27528786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatReal = HandleIntToFloatCast(To, From, Result.IntReal, Info.Ctx); 27538786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatImag = HandleIntToFloatCast(To, From, Result.IntImag, Info.Ctx); 27548786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 27558786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 2756ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson } 27571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 27588786da77984e81d48e0e1b2bd339809b1efc19f3John McCall llvm_unreachable("unknown cast resulting in complex value"); 2759b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 27609ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson} 27619ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 2762f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCallbool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 276396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (E->getOpcode() == BO_Comma) { 27648327fad71da34492d82c532f42a58cb4baff81a3Richard Smith VisitIgnoredValue(E->getLHS()); 27658327fad71da34492d82c532f42a58cb4baff81a3Richard Smith return Visit(E->getRHS()); 276696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 2767f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall if (!Visit(E->getLHS())) 2768f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return false; 27691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2770f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue RHS; 2771a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar if (!EvaluateComplex(E->getRHS(), RHS, Info)) 2772f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return false; 2773a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar 27743f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar assert(Result.isComplexFloat() == RHS.isComplexFloat() && 27753f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar "Invalid operands to binary operator."); 2776ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson switch (E->getOpcode()) { 2777f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall default: return false; 27782de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: 2779a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar if (Result.isComplexFloat()) { 2780a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatReal().add(RHS.getComplexFloatReal(), 2781a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2782a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatImag().add(RHS.getComplexFloatImag(), 2783a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2784a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } else { 2785a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntReal() += RHS.getComplexIntReal(); 2786a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntImag() += RHS.getComplexIntImag(); 2787a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } 27883f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar break; 27892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: 2790a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar if (Result.isComplexFloat()) { 2791a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(), 2792a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2793a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(), 2794a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2795a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } else { 2796a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntReal() -= RHS.getComplexIntReal(); 2797a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntImag() -= RHS.getComplexIntImag(); 2798a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } 27993f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar break; 28002de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: 28013f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar if (Result.isComplexFloat()) { 2802f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LHS = Result; 28033f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &LHS_r = LHS.getComplexFloatReal(); 28043f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &LHS_i = LHS.getComplexFloatImag(); 28053f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &RHS_r = RHS.getComplexFloatReal(); 28063f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &RHS_i = RHS.getComplexFloatImag(); 28071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 28083f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat Tmp = LHS_r; 28093f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven); 28103f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatReal() = Tmp; 28113f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp = LHS_i; 28123f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 28133f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven); 28143f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar 28153f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp = LHS_r; 28163f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 28173f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatImag() = Tmp; 28183f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp = LHS_i; 28193f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven); 28203f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven); 28213f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar } else { 2822f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LHS = Result; 28231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result.getComplexIntReal() = 28243f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar (LHS.getComplexIntReal() * RHS.getComplexIntReal() - 28253f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar LHS.getComplexIntImag() * RHS.getComplexIntImag()); 28261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result.getComplexIntImag() = 28273f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar (LHS.getComplexIntReal() * RHS.getComplexIntImag() + 28283f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar LHS.getComplexIntImag() * RHS.getComplexIntReal()); 28293f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar } 28303f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar break; 283196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case BO_Div: 283296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (Result.isComplexFloat()) { 283396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara ComplexValue LHS = Result; 283496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &LHS_r = LHS.getComplexFloatReal(); 283596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &LHS_i = LHS.getComplexFloatImag(); 283696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &RHS_r = RHS.getComplexFloatReal(); 283796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &RHS_i = RHS.getComplexFloatImag(); 283896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &Res_r = Result.getComplexFloatReal(); 283996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &Res_i = Result.getComplexFloatImag(); 284096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 284196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat Den = RHS_r; 284296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Den.multiply(RHS_r, APFloat::rmNearestTiesToEven); 284396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat Tmp = RHS_i; 284496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 284596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Den.add(Tmp, APFloat::rmNearestTiesToEven); 284696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 284796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r = LHS_r; 284896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r.multiply(RHS_r, APFloat::rmNearestTiesToEven); 284996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp = LHS_i; 285096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 285196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r.add(Tmp, APFloat::rmNearestTiesToEven); 285296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r.divide(Den, APFloat::rmNearestTiesToEven); 285396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 285496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i = LHS_i; 285596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i.multiply(RHS_r, APFloat::rmNearestTiesToEven); 285696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp = LHS_r; 285796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 285896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i.subtract(Tmp, APFloat::rmNearestTiesToEven); 285996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i.divide(Den, APFloat::rmNearestTiesToEven); 286096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } else { 286196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0) { 286296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // FIXME: what about diagnostics? 286396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 286496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 286596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara ComplexValue LHS = Result; 286696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() + 286796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara RHS.getComplexIntImag() * RHS.getComplexIntImag(); 286896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntReal() = 286996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara (LHS.getComplexIntReal() * RHS.getComplexIntReal() + 287096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den; 287196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntImag() = 287296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara (LHS.getComplexIntImag() * RHS.getComplexIntReal() - 287396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den; 287496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 287596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara break; 2876ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson } 2877ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson 2878f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return true; 2879ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson} 2880ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson 288196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnarabool ComplexExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 288296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // Get the operand value into 'Result'. 288396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (!Visit(E->getSubExpr())) 288496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 288596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 288696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara switch (E->getOpcode()) { 288796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara default: 288896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // FIXME: what about diagnostics? 288996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 289096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Extension: 289196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 289296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Plus: 289396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // The result is always just the subexpr. 289496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 289596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Minus: 289696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (Result.isComplexFloat()) { 289796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexFloatReal().changeSign(); 289896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexFloatImag().changeSign(); 289996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 290096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara else { 290196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntReal() = -Result.getComplexIntReal(); 290296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntImag() = -Result.getComplexIntImag(); 290396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 290496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 290596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Not: 290696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (Result.isComplexFloat()) 290796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexFloatImag().changeSign(); 290896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara else 290996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntImag() = -Result.getComplexIntImag(); 291096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 291196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 291296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara} 291396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 29149ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson//===----------------------------------------------------------------------===// 29156ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner// Top level Expr::Evaluate method. 2916f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 2917f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 29181e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smithstatic bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { 2919c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // In C, function designators are not lvalues, but we evaluate them as if they 2920c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // are. 2921c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (E->isGLValue() || E->getType()->isFunctionType()) { 2922c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith LValue LV; 2923c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateLValue(E, LV, Info)) 2924c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 2925c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith LV.moveInto(Result); 2926c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } else if (E->getType()->isVectorType()) { 29271e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (!EvaluateVector(E, Result, Info)) 292859b5da6d853b4368b984700315adf7b37de05764Nate Begeman return false; 2929575a1c9dc8dc5b4977194993e289f9eda7295c39Douglas Gregor } else if (E->getType()->isIntegralOrEnumerationType()) { 29301e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith if (!IntExprEvaluator(Info, Result).Visit(E)) 29316dde0d5dc09f45f4d9508c964703e36fef1a0198Anders Carlsson return false; 2932efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->hasPointerRepresentation()) { 2933efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 2934efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluatePointer(E, LV, Info)) 29356dde0d5dc09f45f4d9508c964703e36fef1a0198Anders Carlsson return false; 29361e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith LV.moveInto(Result); 2937efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->isRealFloatingType()) { 2938efdb83e26f9a1fd2566afe54461216cd84814d42John McCall llvm::APFloat F(0.0); 2939efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateFloat(E, F, Info)) 29406dde0d5dc09f45f4d9508c964703e36fef1a0198Anders Carlsson return false; 29411e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith Result = APValue(F); 2942efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->isAnyComplexType()) { 2943efdb83e26f9a1fd2566afe54461216cd84814d42John McCall ComplexValue C; 2944efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateComplex(E, C, Info)) 2945660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump return false; 29461e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith C.moveInto(Result); 2947660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump } else 2948660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump return false; 2949660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump 2950660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump return true; 2951660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump} 2952660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump 2953c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 295456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall/// Evaluate - Return true if this is a constant which we can fold using 295556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall/// any crazy technique (that has nothing to do with language standards) that 295656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall/// we want to. If this function returns true, it returns the folded constant 2957c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion 2958c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith/// will be applied to the result. 295956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallbool Expr::Evaluate(EvalResult &Result, const ASTContext &Ctx) const { 296056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall EvalInfo Info(Ctx, Result); 2961c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 2962c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!::Evaluate(Result.Val, Info, this)) 2963c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 2964c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 2965c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (isGLValue()) { 2966c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith LValue LV; 2967c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith LV.setFrom(Result.Val); 2968c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return HandleLValueToRValueConversion(Info, getType(), LV, Result.Val); 2969c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 2970c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith 2971c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // FIXME: We don't allow expressions to fold to pointers or references to 2972c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith // locals. Code which calls Evaluate() isn't ready for that yet. 2973c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return !Result.Val.isLValue() || IsGlobalLValue(Result.Val.getLValueBase()); 297456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall} 297556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall 29764ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::EvaluateAsBooleanCondition(bool &Result, 29774ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Ctx) const { 2978c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith EvalResult Scratch; 2979c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return Evaluate(Scratch, Ctx) && HandleConversionToBool(Scratch.Val, Result); 2980cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall} 2981cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall 2982a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smithbool Expr::EvaluateAsInt(APSInt &Result, const ASTContext &Ctx) const { 2983c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith EvalResult ExprResult; 2984c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!Evaluate(ExprResult, Ctx) || ExprResult.HasSideEffects || 2985c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith !ExprResult.Val.isInt()) { 2986c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return false; 2987c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith } 2988c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith Result = ExprResult.Val.getInt(); 2989c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith return true; 2990a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith} 2991a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith 29924ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const { 29931b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlsson EvalInfo Info(Ctx, Result); 29941b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlsson 2995efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 2996c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (EvaluateLValue(this, LV, Info) && !Result.HasSideEffects && 2997e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara IsGlobalLValue(LV.Base)) { 2998e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara LV.moveInto(Result.Val); 2999e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara return true; 3000e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara } 3001e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara return false; 3002e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara} 3003e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 30044ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::EvaluateAsAnyLValue(EvalResult &Result, 30054ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Ctx) const { 3006e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara EvalInfo Info(Ctx, Result); 3007e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 3008e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara LValue LV; 3009e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara if (EvaluateLValue(this, LV, Info)) { 3010efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LV.moveInto(Result.Val); 3011efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 3012efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 3013efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 3014b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman} 3015b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman 30166ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner/// isEvaluatable - Call Evaluate to see if this expression can be constant 301745b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner/// folded, but discard the result. 30184ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::isEvaluatable(const ASTContext &Ctx) const { 30194fdfb0965b396f2778091f7e6c051d17ff9791baAnders Carlsson EvalResult Result; 30204fdfb0965b396f2778091f7e6c051d17ff9791baAnders Carlsson return Evaluate(Result, Ctx) && !Result.HasSideEffects; 302145b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner} 302251fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson 30234ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::HasSideEffects(const ASTContext &Ctx) const { 30241e12c59e8f9bb76c23628c4e0d0a1dfced0b1fa0Richard Smith return HasSideEffect(Ctx).Visit(this); 3025393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian} 3026393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian 3027a6b8b2c09610b8bc4330e948ece8b940c2386406Richard SmithAPSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx) const { 30281c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson EvalResult EvalResult; 30291c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson bool Result = Evaluate(EvalResult, Ctx); 3030c6ed729f669044f5072a49d79041f455d971ece3Jeffrey Yasskin (void)Result; 303151fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson assert(Result && "Could not evaluate expression"); 30321c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); 303351fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson 30341c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson return EvalResult.Val.getInt(); 303551fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson} 3036d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3037e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara bool Expr::EvalResult::isGlobalLValue() const { 3038e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara assert(Val.isLValue()); 3039e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara return IsGlobalLValue(Val.getLValueBase()); 3040e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara } 3041e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 3042e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 3043d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// isIntegerConstantExpr - this recursive routine will test if an expression is 3044d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// an integer constant expression. 3045d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3046d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero, 3047d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// comma, etc 3048d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// 3049d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// FIXME: Handle offsetof. Two things to do: Handle GCC's __builtin_offsetof 3050d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// to support gcc 4.0+ and handle the idiom GCC recognizes with a null pointer 3051d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// cast+dereference. 3052d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3053d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// CheckICE - This function does the fundamental ICE checking: the returned 3054d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// ICEDiag contains a Val of 0, 1, or 2, and a possibly null SourceLocation. 3055d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// Note that to reduce code duplication, this helper does no evaluation 3056d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// itself; the caller checks whether the expression is evaluatable, and 3057d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// in the rare cases where CheckICE actually cares about the evaluated 3058d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// value, it calls into Evalute. 3059d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 3060d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// Meanings of Val: 3061d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 0: This expression is an ICE if it can be evaluated by Evaluate. 3062d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 1: This expression is not an ICE, but if it isn't evaluated, it's 3063d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// a legal subexpression for an ICE. This return value is used to handle 3064d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// the comma operator in C99 mode. 3065d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 2: This expression is not an ICE, and is not a legal subexpression for one. 3066d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 30673c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace { 30683c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 3069d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallstruct ICEDiag { 3070d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall unsigned Val; 3071d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall SourceLocation Loc; 3072d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3073d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall public: 3074d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag(unsigned v, SourceLocation l) : Val(v), Loc(l) {} 3075d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag() : Val(0) {} 3076d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall}; 3077d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 30783c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman} 30793c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 30803c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmanstatic ICEDiag NoDiag() { return ICEDiag(); } 3081d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3082d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallstatic ICEDiag CheckEvalInICE(const Expr* E, ASTContext &Ctx) { 3083d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Expr::EvalResult EVResult; 3084d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects || 3085d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall !EVResult.Val.isInt()) { 3086d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3087d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3088d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3089d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall} 3090d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3091d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallstatic ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { 3092d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall assert(!E->isValueDependent() && "Should not see value dependent exprs!"); 30932ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!E->getType()->isIntegralOrEnumerationType()) { 3094d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3095d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3096d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3097d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall switch (E->getStmtClass()) { 309863c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall#define ABSTRACT_STMT(Node) 3099d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall#define STMT(Node, Base) case Expr::Node##Class: 3100d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall#define EXPR(Node, Base) 3101d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall#include "clang/AST/StmtNodes.inc" 3102d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::PredefinedExprClass: 3103d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::FloatingLiteralClass: 3104d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ImaginaryLiteralClass: 3105d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::StringLiteralClass: 3106d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ArraySubscriptExprClass: 3107d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::MemberExprClass: 3108d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CompoundAssignOperatorClass: 3109d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CompoundLiteralExprClass: 3110d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ExtVectorElementExprClass: 3111d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::DesignatedInitExprClass: 3112d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ImplicitValueInitExprClass: 3113d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ParenListExprClass: 3114d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::VAArgExprClass: 3115d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::AddrLabelExprClass: 3116d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::StmtExprClass: 3117d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXMemberCallExprClass: 3118e08ce650a2b02410eddd1f60a4aa6b3d4be71e73Peter Collingbourne case Expr::CUDAKernelCallExprClass: 3119d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDynamicCastExprClass: 3120d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXTypeidExprClass: 31219be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet case Expr::CXXUuidofExprClass: 3122d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXNullPtrLiteralExprClass: 3123d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXThisExprClass: 3124d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXThrowExprClass: 3125d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXNewExprClass: 3126d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDeleteExprClass: 3127d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXPseudoDestructorExprClass: 3128d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnresolvedLookupExprClass: 3129d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::DependentScopeDeclRefExprClass: 3130d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXConstructExprClass: 3131d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXBindTemporaryExprClass: 31324765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall case Expr::ExprWithCleanupsClass: 3133d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXTemporaryObjectExprClass: 3134d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXUnresolvedConstructExprClass: 3135d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDependentScopeMemberExprClass: 3136d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnresolvedMemberExprClass: 3137d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCStringLiteralClass: 3138d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCEncodeExprClass: 3139d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCMessageExprClass: 3140d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCSelectorExprClass: 3141d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCProtocolExprClass: 3142d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCIvarRefExprClass: 3143d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCPropertyRefExprClass: 3144d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCIsaExprClass: 3145d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ShuffleVectorExprClass: 3146d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::BlockExprClass: 3147d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::BlockDeclRefExprClass: 3148d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::NoStmtClass: 31497cd7d1ad33fdf49eef83942e8855fe20d95aa1b9John McCall case Expr::OpaqueValueExprClass: 3150be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor case Expr::PackExpansionExprClass: 3151c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor case Expr::SubstNonTypeTemplateParmPackExprClass: 315261eee0ca33b29e102f11bab77c8b74cc00e2392bTanya Lattner case Expr::AsTypeExprClass: 3153f85e193739c953358c865005855253af4f68a497John McCall case Expr::ObjCIndirectCopyRestoreExprClass: 315403e80030515c800d1ab44125b9052dfffd1bd04cDouglas Gregor case Expr::MaterializeTemporaryExprClass: 3155276b061970939293f1abaf694bd3ef05b2cbda79Eli Friedman case Expr::AtomicExprClass: 3156d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3157d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3158cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl case Expr::InitListExprClass: 3159cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl if (Ctx.getLangOptions().CPlusPlus0x) { 3160cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl const InitListExpr *ILE = cast<InitListExpr>(E); 3161cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl if (ILE->getNumInits() == 0) 3162cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl return NoDiag(); 3163cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl if (ILE->getNumInits() == 1) 3164cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl return CheckICE(ILE->getInit(0), Ctx); 3165cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl // Fall through for more than 1 expression. 3166cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl } 3167cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl return ICEDiag(2, E->getLocStart()); 3168cea8d966f826554f0679595e9371e314e8dbc1cfSebastian Redl 3169ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor case Expr::SizeOfPackExprClass: 3170d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::GNUNullExprClass: 3171d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // GCC considers the GNU __null value to be an integral constant expression. 3172d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3173d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 317491a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall case Expr::SubstNonTypeTemplateParmExprClass: 317591a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall return 317691a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx); 317791a5755ad73c5dc1dfb167e448fdd74e75a6df56John McCall 3178d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ParenExprClass: 3179d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx); 3180f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne case Expr::GenericSelectionExprClass: 3181f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx); 3182d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::IntegerLiteralClass: 3183d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CharacterLiteralClass: 3184d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXBoolLiteralExprClass: 3185ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregor case Expr::CXXScalarValueInitExprClass: 3186d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnaryTypeTraitExprClass: 31876ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet case Expr::BinaryTypeTraitExprClass: 318821ff2e516b0e0bc8c1dbf965cb3d44bac3c64330John Wiegley case Expr::ArrayTypeTraitExprClass: 3189552622067dc45013d240f73952fece703f5e63bdJohn Wiegley case Expr::ExpressionTraitExprClass: 31902e156225a29407a50dd19041aa5750171ad44ea3Sebastian Redl case Expr::CXXNoexceptExprClass: 3191d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3192d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CallExprClass: 31936cf750298d3621d8a10a6dd07fcee8e274b9d94dSean Hunt case Expr::CXXOperatorCallExprClass: { 319405830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // C99 6.6/3 allows function calls within unevaluated subexpressions of 319505830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // constant expressions, but they can never be ICEs because an ICE cannot 319605830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // contain an operand of (pointer to) function type. 3197d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const CallExpr *CE = cast<CallExpr>(E); 3198d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CE->isBuiltinCall(Ctx)) 3199d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckEvalInICE(E, Ctx); 3200d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3201d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3202d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::DeclRefExprClass: 3203d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl())) 3204d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 320503f96110bc2c2c773e06a42982b17a03dd2e5379Richard Smith if (Ctx.getLangOptions().CPlusPlus && IsConstNonVolatile(E->getType())) { 3206d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl(); 3207d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3208d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Parameter variables are never constants. Without this check, 3209d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // getAnyInitializer() can find a default argument, which leads 3210d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // to chaos. 3211d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (isa<ParmVarDecl>(D)) 3212d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 3213d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3214d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // C++ 7.1.5.1p2 3215d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // A variable of non-volatile const-qualified integral or enumeration 3216d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // type initialized by an ICE can be used in ICEs. 3217d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) { 3218d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Look for a declaration of this variable that has an initializer. 3219d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const VarDecl *ID = 0; 3220d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const Expr *Init = Dcl->getAnyInitializer(ID); 3221d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Init) { 3222d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (ID->isInitKnownICE()) { 3223d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // We have already checked whether this subexpression is an 3224d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // integral constant expression. 3225d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (ID->isInitICE()) 3226d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3227d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall else 3228d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 3229d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3230d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3231d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // It's an ICE whether or not the definition we found is 3232d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // out-of-line. See DR 721 and the discussion in Clang PR 3233d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // 6206 for details. 3234d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3235d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Dcl->isCheckingICE()) { 3236d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 3237d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3238d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3239d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Dcl->setCheckingICE(); 3240d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag Result = CheckICE(Init, Ctx); 3241d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Cache the result of the ICE test. 3242d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Dcl->setInitKnownICE(Result.Val == 0); 3243d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return Result; 3244d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3245d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3246d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3247d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3248d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnaryOperatorClass: { 3249d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const UnaryOperator *Exp = cast<UnaryOperator>(E); 3250d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall switch (Exp->getOpcode()) { 32512de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PostInc: 32522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PostDec: 32532de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PreInc: 32542de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PreDec: 32552de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_AddrOf: 32562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Deref: 325705830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // C99 6.6/3 allows increment and decrement within unevaluated 325805830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // subexpressions of constant expressions, but they can never be ICEs 325905830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // because an ICE cannot contain an lvalue operand. 3260d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 32612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Extension: 32622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_LNot: 32632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Plus: 32642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Minus: 32652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Not: 32662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Real: 32672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Imag: 3268d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(Exp->getSubExpr(), Ctx); 3269d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3270d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3271d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // OffsetOf falls through here. 3272d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3273d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::OffsetOfExprClass: { 3274d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Note that per C99, offsetof must be an ICE. And AFAIK, using 3275d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Evaluate matches the proposed gcc behavior for cases like 327605830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // "offsetof(struct s{int x[4];}, x[1.0])". This doesn't affect 3277d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // compliance: we should warn earlier for offsetof expressions with 3278d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // array subscripts that aren't ICEs, and if the array subscripts 3279d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // are ICEs, the value of the offsetof must be an integer constant. 3280d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckEvalInICE(E, Ctx); 3281d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3282f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne case Expr::UnaryExprOrTypeTraitExprClass: { 3283f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne const UnaryExprOrTypeTraitExpr *Exp = cast<UnaryExprOrTypeTraitExpr>(E); 3284f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne if ((Exp->getKind() == UETT_SizeOf) && 3285f4e3cfbe8abd124be6341ef5d714819b4fbd9082Peter Collingbourne Exp->getTypeOfArgument()->isVariableArrayType()) 3286d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3287d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3288d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3289d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::BinaryOperatorClass: { 3290d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const BinaryOperator *Exp = cast<BinaryOperator>(E); 3291d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall switch (Exp->getOpcode()) { 32922de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_PtrMemD: 32932de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_PtrMemI: 32942de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Assign: 32952de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_MulAssign: 32962de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_DivAssign: 32972de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_RemAssign: 32982de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_AddAssign: 32992de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_SubAssign: 33002de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_ShlAssign: 33012de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_ShrAssign: 33022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_AndAssign: 33032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_XorAssign: 33042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_OrAssign: 330505830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // C99 6.6/3 allows assignments within unevaluated subexpressions of 330605830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // constant expressions, but they can never be ICEs because an ICE cannot 330705830143fa8c70b8bc46c96b93018455d8a2ca92Richard Smith // contain an lvalue operand. 3308d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3309d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 33102de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: 33112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Div: 33122de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Rem: 33132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: 33142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: 33152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shl: 33162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shr: 33172de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LT: 33182de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GT: 33192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LE: 33202de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GE: 33212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_EQ: 33222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_NE: 33232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_And: 33242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Xor: 33252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Or: 33262de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Comma: { 3327d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); 3328d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); 33292de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (Exp->getOpcode() == BO_Div || 33302de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall Exp->getOpcode() == BO_Rem) { 3331d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Evaluate gives an error for undefined Div/Rem, so make sure 3332d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // we don't evaluate one. 33333b332ab132fa85c83833d74d400f6e126f52fbd2John McCall if (LHSResult.Val == 0 && RHSResult.Val == 0) { 3334a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt REval = Exp->getRHS()->EvaluateKnownConstInt(Ctx); 3335d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (REval == 0) 3336d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(1, E->getLocStart()); 3337d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (REval.isSigned() && REval.isAllOnesValue()) { 3338a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith llvm::APSInt LEval = Exp->getLHS()->EvaluateKnownConstInt(Ctx); 3339d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LEval.isMinSignedValue()) 3340d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(1, E->getLocStart()); 3341d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3342d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3343d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 33442de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (Exp->getOpcode() == BO_Comma) { 3345d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Ctx.getLangOptions().C99) { 3346d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // C99 6.6p3 introduces a strange edge case: comma can be in an ICE 3347d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // if it isn't evaluated. 3348d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val == 0 && RHSResult.Val == 0) 3349d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(1, E->getLocStart()); 3350d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } else { 3351d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // In both C89 and C++, commas in ICEs are illegal. 3352d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3353d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3354d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3355d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val >= RHSResult.Val) 3356d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return LHSResult; 3357d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return RHSResult; 3358d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 33592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LAnd: 33602de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LOr: { 3361d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); 336263fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor 336363fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // C++0x [expr.const]p2: 336463fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // [...] subexpressions of logical AND (5.14), logical OR 336563fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // (5.15), and condi- tional (5.16) operations that are not 336663fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // evaluated are not considered. 336763fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor if (Ctx.getLangOptions().CPlusPlus0x && LHSResult.Val == 0) { 336863fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor if (Exp->getOpcode() == BO_LAnd && 3369a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Exp->getLHS()->EvaluateKnownConstInt(Ctx) == 0) 337063fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor return LHSResult; 337163fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor 337263fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor if (Exp->getOpcode() == BO_LOr && 3373a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Exp->getLHS()->EvaluateKnownConstInt(Ctx) != 0) 337463fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor return LHSResult; 337563fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor } 337663fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor 3377d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); 3378d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val == 0 && RHSResult.Val == 1) { 3379d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Rare case where the RHS has a comma "side-effect"; we need 3380d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // to actually check the condition to see whether the side 3381d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // with the comma is evaluated. 33822de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if ((Exp->getOpcode() == BO_LAnd) != 3383a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith (Exp->getLHS()->EvaluateKnownConstInt(Ctx) == 0)) 3384d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return RHSResult; 3385d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3386d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3387d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3388d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val >= RHSResult.Val) 3389d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return LHSResult; 3390d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return RHSResult; 3391d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3392d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3393d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3394d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ImplicitCastExprClass: 3395d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CStyleCastExprClass: 3396d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXFunctionalCastExprClass: 3397d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXStaticCastExprClass: 3398d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXReinterpretCastExprClass: 339932cb47174304bc7ec11478b9497c4e10f48273d9Richard Smith case Expr::CXXConstCastExprClass: 3400f85e193739c953358c865005855253af4f68a497John McCall case Expr::ObjCBridgedCastExprClass: { 3401d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr(); 340298326ede499696f85d9f7bc1fbc7a628fc22f1ecRichard Smith if (isa<ExplicitCastExpr>(E) && 340332cb47174304bc7ec11478b9497c4e10f48273d9Richard Smith isa<FloatingLiteral>(SubExpr->IgnoreParenImpCasts())) 340432cb47174304bc7ec11478b9497c4e10f48273d9Richard Smith return NoDiag(); 3405eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman switch (cast<CastExpr>(E)->getCastKind()) { 3406eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman case CK_LValueToRValue: 3407eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman case CK_NoOp: 3408eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman case CK_IntegralToBoolean: 3409eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman case CK_IntegralCast: 3410d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(SubExpr, Ctx); 3411eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman default: 3412eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman return ICEDiag(2, E->getLocStart()); 3413eea0e817c609c662f3fef61bb257fddf1ae8f7b7Eli Friedman } 3414d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 341556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall case Expr::BinaryConditionalOperatorClass: { 341656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall const BinaryConditionalOperator *Exp = cast<BinaryConditionalOperator>(E); 341756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall ICEDiag CommonResult = CheckICE(Exp->getCommon(), Ctx); 341856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (CommonResult.Val == 2) return CommonResult; 341956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); 342056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (FalseResult.Val == 2) return FalseResult; 342156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (CommonResult.Val == 1) return CommonResult; 342256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall if (FalseResult.Val == 1 && 3423a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith Exp->getCommon()->EvaluateKnownConstInt(Ctx) == 0) return NoDiag(); 342456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall return FalseResult; 342556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall } 3426d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ConditionalOperatorClass: { 3427d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const ConditionalOperator *Exp = cast<ConditionalOperator>(E); 3428d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // If the condition (ignoring parens) is a __builtin_constant_p call, 3429d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // then only the true side is actually considered in an integer constant 3430d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // expression, and it is fully evaluated. This is an important GNU 3431d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // extension. See GCC PR38377 for discussion. 3432d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (const CallExpr *CallCE 3433d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall = dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts())) 3434d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) { 3435d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Expr::EvalResult EVResult; 3436d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects || 3437d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall !EVResult.Val.isInt()) { 3438d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3439d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3440d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3441d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3442d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx); 3443d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CondResult.Val == 2) 3444d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CondResult; 344563fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor 344663fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // C++0x [expr.const]p2: 344763fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // subexpressions of [...] conditional (5.16) operations that 344863fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor // are not evaluated are not considered 344963fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor bool TrueBranch = Ctx.getLangOptions().CPlusPlus0x 3450a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith ? Exp->getCond()->EvaluateKnownConstInt(Ctx) != 0 345163fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor : false; 345263fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor ICEDiag TrueResult = NoDiag(); 345363fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor if (!Ctx.getLangOptions().CPlusPlus0x || TrueBranch) 345463fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor TrueResult = CheckICE(Exp->getTrueExpr(), Ctx); 345563fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor ICEDiag FalseResult = NoDiag(); 345663fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor if (!Ctx.getLangOptions().CPlusPlus0x || !TrueBranch) 345763fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); 345863fe6814f339df30b8463b39995947cbdf920e48Douglas Gregor 3459d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (TrueResult.Val == 2) 3460d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return TrueResult; 3461d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (FalseResult.Val == 2) 3462d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return FalseResult; 3463d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CondResult.Val == 1) 3464d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CondResult; 3465d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (TrueResult.Val == 0 && FalseResult.Val == 0) 3466d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 3467d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Rare case where the diagnostics depend on which side is evaluated 3468d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Note that if we get here, CondResult is 0, and at least one of 3469d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // TrueResult and FalseResult is non-zero. 3470a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith if (Exp->getCond()->EvaluateKnownConstInt(Ctx) == 0) { 3471d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return FalseResult; 3472d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3473d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return TrueResult; 3474d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3475d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDefaultArgExprClass: 3476d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx); 3477d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ChooseExprClass: { 3478d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(Ctx), Ctx); 3479d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3480d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3481d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3482d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Silence a GCC warning 3483d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 3484d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall} 3485d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 3486d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallbool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, 3487d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall SourceLocation *Loc, bool isEvaluated) const { 3488d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag d = CheckICE(this, Ctx); 3489d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (d.Val != 0) { 3490d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Loc) *Loc = d.Loc; 3491d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return false; 3492d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 3493c49bd11f96c2378969822f1f1b814ffa8f2bfee4Richard Smith if (!EvaluateAsInt(Result, Ctx)) 3494d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall llvm_unreachable("ICE cannot be evaluated!"); 3495d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return true; 3496d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall} 3497