ExprConstant.cpp revision fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7d
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. 4587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstruct EvalInfo { 464ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Ctx; 471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4854da0496616cb898596cfd5fae1f824098bd8435Anders Carlsson /// EvalResult - Contains information about the evaluation. 4954da0496616cb898596cfd5fae1f824098bd8435Anders Carlsson Expr::EvalResult &EvalResult; 50f0c1e4b679e15c26bffb5892e35985bf3c52f77aAnders Carlsson 514ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad EvalInfo(const ASTContext &ctx, Expr::EvalResult& evalresult) 5242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall : Ctx(ctx), EvalResult(evalresult) {} 5387eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner}; 5487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 55f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCallnamespace { 56f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall struct ComplexValue { 57f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall private: 58f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool IsInt; 59f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 60f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall public: 61f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APSInt IntReal, IntImag; 62f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APFloat FloatReal, FloatImag; 63f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 64f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {} 65f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 66f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall void makeComplexFloat() { IsInt = false; } 67f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool isComplexFloat() const { return !IsInt; } 68f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APFloat &getComplexFloatReal() { return FloatReal; } 69f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APFloat &getComplexFloatImag() { return FloatImag; } 70f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 71f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall void makeComplexInt() { IsInt = true; } 72f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool isComplexInt() const { return IsInt; } 73f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APSInt &getComplexIntReal() { return IntReal; } 74f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall APSInt &getComplexIntImag() { return IntImag; } 75f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall 76f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall void moveInto(APValue &v) { 77f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall if (isComplexFloat()) 78f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall v = APValue(FloatReal, FloatImag); 79f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall else 80f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall v = APValue(IntReal, IntImag); 81f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall } 82f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall }; 83efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 84efdb83e26f9a1fd2566afe54461216cd84814d42John McCall struct LValue { 85efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Expr *Base; 86efdb83e26f9a1fd2566afe54461216cd84814d42John McCall CharUnits Offset; 87efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 88efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Expr *getLValueBase() { return Base; } 89efdb83e26f9a1fd2566afe54461216cd84814d42John McCall CharUnits getLValueOffset() { return Offset; } 90efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 91efdb83e26f9a1fd2566afe54461216cd84814d42John McCall void moveInto(APValue &v) { 92efdb83e26f9a1fd2566afe54461216cd84814d42John McCall v = APValue(Base, Offset); 93efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 94efdb83e26f9a1fd2566afe54461216cd84814d42John McCall }; 95f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall} 9687eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner 97efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info); 98efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info); 9987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattnerstatic bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info); 100d9becd1846e2c72bf6ad283faa1b048f33dd3afeChris Lattnerstatic bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, 101d9becd1846e2c72bf6ad283faa1b048f33dd3afeChris Lattner EvalInfo &Info); 102d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info); 103f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCallstatic bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info); 104f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 105f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 1064efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman// Misc utilities 1074efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 1084efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 109e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnarastatic bool IsGlobalLValue(const Expr* E) { 11042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!E) return true; 11142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 11242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 11342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (isa<FunctionDecl>(DRE->getDecl())) 11442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return true; 11542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) 11642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return VD->hasGlobalStorage(); 11742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 11842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall } 11942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 12042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(E)) 12142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return CLE->isFileScope(); 12242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 12342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return true; 12442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall} 12542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 126efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvalPointerValueAsBool(LValue& Value, bool& Result) { 127efdb83e26f9a1fd2566afe54461216cd84814d42John McCall const Expr* Base = Value.Base; 128a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 1293554283157190e67918fad4221a5e6faf9317362John McCall // A null base expression indicates a null pointer. These are always 1303554283157190e67918fad4221a5e6faf9317362John McCall // evaluatable, and they are false unless the offset is zero. 1313554283157190e67918fad4221a5e6faf9317362John McCall if (!Base) { 1323554283157190e67918fad4221a5e6faf9317362John McCall Result = !Value.Offset.isZero(); 1333554283157190e67918fad4221a5e6faf9317362John McCall return true; 1343554283157190e67918fad4221a5e6faf9317362John McCall } 1353554283157190e67918fad4221a5e6faf9317362John McCall 13642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall // Require the base expression to be a global l-value. 137e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara if (!IsGlobalLValue(Base)) return false; 13842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 1393554283157190e67918fad4221a5e6faf9317362John McCall // We have a non-null base expression. These are generally known to 1403554283157190e67918fad4221a5e6faf9317362John McCall // be true, but if it'a decl-ref to a weak symbol it can be null at 1413554283157190e67918fad4221a5e6faf9317362John McCall // runtime. 1423554283157190e67918fad4221a5e6faf9317362John McCall Result = true; 143a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 1443554283157190e67918fad4221a5e6faf9317362John McCall const DeclRefExpr* DeclRef = dyn_cast<DeclRefExpr>(Base); 145a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola if (!DeclRef) 146a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola return true; 147a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 1483554283157190e67918fad4221a5e6faf9317362John McCall // If it's a weak symbol, it isn't constant-evaluable. 149a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola const ValueDecl* Decl = DeclRef->getDecl(); 150a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola if (Decl->hasAttr<WeakAttr>() || 151a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola Decl->hasAttr<WeakRefAttr>() || 152a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola Decl->hasAttr<WeakImportAttr>()) 153a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola return false; 154a7d3c04fcfe9d4af2f7758f46aef26b1a8f8ac09Rafael Espindola 1555bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return true; 1565bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman} 1575bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman 158cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCallstatic bool HandleConversionToBool(const Expr* E, bool& Result, 159cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall EvalInfo &Info) { 1602ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (E->getType()->isIntegralOrEnumerationType()) { 1614efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APSInt IntResult; 1624efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluateInteger(E, IntResult, Info)) 1634efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 1644efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = IntResult != 0; 1654efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 1664efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } else if (E->getType()->isRealFloatingType()) { 1674efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APFloat FloatResult(0.0); 1684efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluateFloat(E, FloatResult, Info)) 1694efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 1704efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = !FloatResult.isZero(); 1714efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 172a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman } else if (E->getType()->hasPointerRepresentation()) { 173efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue PointerResult; 1744efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!EvaluatePointer(E, PointerResult, Info)) 1754efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 1765bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return EvalPointerValueAsBool(PointerResult, Result); 177a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman } else if (E->getType()->isAnyComplexType()) { 178f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue ComplexResult; 179a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman if (!EvaluateComplex(E, ComplexResult, Info)) 180a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman return false; 181a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman if (ComplexResult.isComplexFloat()) { 182a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman Result = !ComplexResult.getComplexFloatReal().isZero() || 183a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman !ComplexResult.getComplexFloatImag().isZero(); 184a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman } else { 185a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman Result = ComplexResult.getComplexIntReal().getBoolValue() || 186a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman ComplexResult.getComplexIntImag().getBoolValue(); 187a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman } 188a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman return true; 1894efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 1904efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1914efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 1924efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 1934efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType, 1954ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APFloat &Value, const ASTContext &Ctx) { 196a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar unsigned DestWidth = Ctx.getIntWidth(DestType); 197a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // Determine whether we are converting to unsigned or signed. 198a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar bool DestSigned = DestType->isSignedIntegerType(); 1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 200a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // FIXME: Warning for overflow. 201a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar uint64_t Space[4]; 202a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar bool ignored; 203a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar (void)Value.convertToInteger(Space, DestWidth, DestSigned, 204a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar llvm::APFloat::rmTowardZero, &ignored); 205a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned); 206a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 207a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType, 2094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APFloat &Value, const ASTContext &Ctx) { 210a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar bool ignored; 211a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat Result = Value; 2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result.convert(Ctx.getFloatTypeSemantics(DestType), 213a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat::rmNearestTiesToEven, &ignored); 214a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return Result; 215a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 216a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APSInt HandleIntToIntCast(QualType DestType, QualType SrcType, 2184ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APSInt &Value, const ASTContext &Ctx) { 219a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar unsigned DestWidth = Ctx.getIntWidth(DestType); 220a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APSInt Result = Value; 221a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // Figure out if this is a truncate, extend or noop cast. 222a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar // If the input is signed, do a sign extend, noop, or truncate. 2239f71a8f4c7a182a5236da9e747d57cc1d1bd24c2Jay Foad Result = Result.extOrTrunc(DestWidth); 224a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result.setIsUnsigned(DestType->isUnsignedIntegerType()); 225a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return Result; 226a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 227a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType, 2294ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad APSInt &Value, const ASTContext &Ctx) { 230a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 231a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1); 232a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result.convertFromAPInt(Value, Value.isSigned(), 233a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar APFloat::rmNearestTiesToEven); 234a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar return Result; 235a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar} 236a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 237c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stumpnamespace { 238770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass HasSideEffect 239c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump : public StmtVisitor<HasSideEffect, bool> { 240c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump EvalInfo &Info; 241c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stumppublic: 242c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 243c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump HasSideEffect(EvalInfo &info) : Info(info) {} 244c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 245c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump // Unhandled nodes conservatively default to having side effects. 246c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitStmt(Stmt *S) { 247c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return true; 248c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump } 249c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 250c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 251c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitDeclRefExpr(DeclRefExpr *E) { 252df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified()) 253c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return true; 254c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return false; 255c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump } 256c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump // We don't want to evaluate BlockExprs multiple times, as they generate 257c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump // a ton of code. 258c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitBlockExpr(BlockExpr *E) { return true; } 259c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitPredefinedExpr(PredefinedExpr *E) { return false; } 260c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E) 261c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump { return Visit(E->getInitializer()); } 262c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitMemberExpr(MemberExpr *E) { return Visit(E->getBase()); } 263c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitIntegerLiteral(IntegerLiteral *E) { return false; } 264c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitFloatingLiteral(FloatingLiteral *E) { return false; } 265c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitStringLiteral(StringLiteral *E) { return false; } 266c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitCharacterLiteral(CharacterLiteral *E) { return false; } 267c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return false; } 268c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) 269980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump { return Visit(E->getLHS()) || Visit(E->getRHS()); } 270c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitChooseExpr(ChooseExpr *E) 271c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump { return Visit(E->getChosenSubExpr(Info.Ctx)); } 272c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); } 273c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitBinAssign(BinaryOperator *E) { return true; } 2743f0147e161df4725ff15fbb731f4f727afcc229fMike Stump bool VisitCompoundAssignOperator(BinaryOperator *E) { return true; } 275980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump bool VisitBinaryOperator(BinaryOperator *E) 276980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump { return Visit(E->getLHS()) || Visit(E->getRHS()); } 277c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitUnaryPreInc(UnaryOperator *E) { return true; } 278c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitUnaryPostInc(UnaryOperator *E) { return true; } 279c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitUnaryPreDec(UnaryOperator *E) { return true; } 280c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitUnaryPostDec(UnaryOperator *E) { return true; } 281c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitUnaryDeref(UnaryOperator *E) { 282df317bf71653eeb235da8337b1e8e790f9653aa4Mike Stump if (Info.Ctx.getCanonicalType(E->getType()).isVolatileQualified()) 283c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump return true; 284980ca220848d27ef55ef4c2d37423461a8ed0da3Mike Stump return Visit(E->getSubExpr()); 285c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump } 286c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump bool VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); } 287363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner 288363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner // Has side effects if any element does. 289363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner bool VisitInitListExpr(InitListExpr *E) { 290363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner for (unsigned i = 0, e = E->getNumInits(); i != e; ++i) 291363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner if (Visit(E->getInit(i))) return true; 292363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner return false; 293363ff23cfddb51abe4ee4212a6dd3c9b534fcc8bChris Lattner } 294ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor 295ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor bool VisitSizeOfPackExpr(SizeOfPackExpr *) { return false; } 296c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump}; 297c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 298c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump} // end anonymous namespace 299c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 3004efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 3014efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman// LValue Evaluation 3024efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 3034efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmannamespace { 304770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass LValueExprEvaluator 305efdb83e26f9a1fd2566afe54461216cd84814d42John McCall : public StmtVisitor<LValueExprEvaluator, bool> { 3064efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman EvalInfo &Info; 307efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue &Result; 308efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 309efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool Success(Expr *E) { 310efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = E; 311efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = CharUnits::Zero(); 312efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 313efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 3144efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanpublic: 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 316efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValueExprEvaluator(EvalInfo &info, LValue &Result) : 317efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Info(info), Result(Result) {} 3184efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 319efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitStmt(Stmt *S) { 320efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 3214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 3228ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 323efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 324efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitDeclRefExpr(DeclRefExpr *E); 325efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitPredefinedExpr(PredefinedExpr *E) { return Success(E); } 326efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); 327efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitMemberExpr(MemberExpr *E); 328efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitStringLiteral(StringLiteral *E) { return Success(E); } 329efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return Success(E); } 330efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitArraySubscriptExpr(ArraySubscriptExpr *E); 331efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitUnaryDeref(UnaryOperator *E); 332efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitUnaryExtension(const UnaryOperator *E) 333ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman { return Visit(E->getSubExpr()); } 334efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitChooseExpr(const ChooseExpr *E) 335ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman { return Visit(E->getChosenSubExpr(Info.Ctx)); } 33626bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson 337efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitCastExpr(CastExpr *E) { 33826bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson switch (E->getCastKind()) { 33926bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson default: 340efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 34126bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson 3422de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_NoOp: 34326bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson return Visit(E->getSubExpr()); 34426bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson } 34526bc220377705292a0519a71d3ea3aef68fcfec6Anders Carlsson } 346ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman // FIXME: Missing: __real__, __imag__ 3474efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman}; 3484efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} // end anonymous namespace 3494efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 350efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluateLValue(const Expr* E, LValue& Result, EvalInfo &Info) { 351efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return LValueExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 3524efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 3534efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 354efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool LValueExprEvaluator::VisitDeclRefExpr(DeclRefExpr *E) { 35550c39ea4858265f3f5f42a0c624557ce2281936bEli Friedman if (isa<FunctionDecl>(E->getDecl())) { 356efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 35750c39ea4858265f3f5f42a0c624557ce2281936bEli Friedman } else if (VarDecl* VD = dyn_cast<VarDecl>(E->getDecl())) { 35850c39ea4858265f3f5f42a0c624557ce2281936bEli Friedman if (!VD->getType()->isReferenceType()) 359efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 360761c94e3bffef0fcb8b4bbf202fd5ee73db134f3Chandler Carruth // Reference parameters can refer to anything even if they have an 361761c94e3bffef0fcb8b4bbf202fd5ee73db134f3Chandler Carruth // "initializer" in the form of a default argument. 362761c94e3bffef0fcb8b4bbf202fd5ee73db134f3Chandler Carruth if (isa<ParmVarDecl>(VD)) 363761c94e3bffef0fcb8b4bbf202fd5ee73db134f3Chandler Carruth return false; 364d933a0198f3ccce9c73bf2951625315b911d37bfEli Friedman // FIXME: Check whether VD might be overridden! 36531310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl if (const Expr *Init = VD->getAnyInitializer()) 366cf3293eaeb3853d12cff47e648bbe835004e929fDouglas Gregor return Visit(const_cast<Expr *>(Init)); 36750c39ea4858265f3f5f42a0c624557ce2281936bEli Friedman } 36850c39ea4858265f3f5f42a0c624557ce2281936bEli Friedman 369efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 37035873c49adad211ff466e34342a52665742794f5Anders Carlsson} 37135873c49adad211ff466e34342a52665742794f5Anders Carlsson 372efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 373efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 3744efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 3754efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 376efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) { 3774efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman QualType Ty; 3784efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (E->isArrow()) { 379efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluatePointer(E->getBase(), Result, Info)) 380efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 3816217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType(); 3824efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } else { 383efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!Visit(E->getBase())) 384efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 3854efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Ty = E->getBase()->getType(); 3864efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 3874efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 3886217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek RecordDecl *RD = Ty->getAs<RecordType>()->getDecl(); 3894efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 39086f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor 39186f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 39286f194083504938df72135b5b66bf0c5cafd9498Douglas Gregor if (!FD) // FIXME: deal with other kinds of member expressions 393efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 3942be586108bb401019647791feca19ea03fd477ceEli Friedman 3952be586108bb401019647791feca19ea03fd477ceEli Friedman if (FD->getType()->isReferenceType()) 396efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 3972be586108bb401019647791feca19ea03fd477ceEli Friedman 3984efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman // FIXME: This is linear time. 39944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor unsigned i = 0; 40017945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis for (RecordDecl::field_iterator Field = RD->field_begin(), 40117945a0f64fe03ff6ec0c2146005a87636e3ac12Argyrios Kyrtzidis FieldEnd = RD->field_end(); 40244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor Field != FieldEnd; (void)++Field, ++i) { 40344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor if (*Field == FD) 4044efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman break; 4054efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 4064efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 407fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Result.Offset += Info.Ctx.toCharUnitsFromBits(RL.getFieldOffset(i)); 408efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 4094efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 4104efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 411efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool LValueExprEvaluator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { 4123068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluatePointer(E->getBase(), Result, Info)) 413efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4153068d117951a8df54bae9db039b56201ab10962bAnders Carlsson APSInt Index; 4163068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluateInteger(E->getIdx(), Index, Info)) 417efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 4183068d117951a8df54bae9db039b56201ab10962bAnders Carlsson 419199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(E->getType()); 420efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset += Index.getSExtValue() * ElementSize; 421efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 4223068d117951a8df54bae9db039b56201ab10962bAnders Carlsson} 4234efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 424efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool LValueExprEvaluator::VisitUnaryDeref(UnaryOperator *E) { 425efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return EvaluatePointer(E->getSubExpr(), Result, Info); 426e8761c8fe2ee6b628104a0885f49fd3c21c08a4fEli Friedman} 427e8761c8fe2ee6b628104a0885f49fd3c21c08a4fEli Friedman 4284efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman//===----------------------------------------------------------------------===// 429f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Pointer Evaluation 430f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 431f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 432c754aa62643e66ab967ca32ae8b0b3fc419bba25Anders Carlssonnamespace { 433770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass PointerExprEvaluator 434efdb83e26f9a1fd2566afe54461216cd84814d42John McCall : public StmtVisitor<PointerExprEvaluator, bool> { 43587eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo &Info; 436efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue &Result; 437efdb83e26f9a1fd2566afe54461216cd84814d42John McCall 438efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool Success(Expr *E) { 439efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = E; 440efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = CharUnits::Zero(); 441efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 442efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 4432bad1687fe6f00e10767a691a33b070b151902b6Anders Carlssonpublic: 4441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 445efdb83e26f9a1fd2566afe54461216cd84814d42John McCall PointerExprEvaluator(EvalInfo &info, LValue &Result) 446efdb83e26f9a1fd2566afe54461216cd84814d42John McCall : Info(info), Result(Result) {} 447f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 448efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitStmt(Stmt *S) { 449efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 4502bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 4512bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 452efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 4532bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 454efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitBinaryOperator(const BinaryOperator *E); 455efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitCastExpr(CastExpr* E); 456efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitUnaryExtension(const UnaryOperator *E) 4572217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman { return Visit(E->getSubExpr()); } 458efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitUnaryAddrOf(const UnaryOperator *E); 459efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitObjCStringLiteral(ObjCStringLiteral *E) 460efdb83e26f9a1fd2566afe54461216cd84814d42John McCall { return Success(E); } 461efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitAddrLabelExpr(AddrLabelExpr *E) 462efdb83e26f9a1fd2566afe54461216cd84814d42John McCall { return Success(E); } 463efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitCallExpr(CallExpr *E); 464efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitBlockExpr(BlockExpr *E) { 465b83d287bc7f47d36fb0751a481e2ef9308b37252Mike Stump if (!E->hasBlockDeclRefExprs()) 466efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 467efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 468b83d287bc7f47d36fb0751a481e2ef9308b37252Mike Stump } 469efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) 470efdb83e26f9a1fd2566afe54461216cd84814d42John McCall { return Success((Expr*)0); } 471efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitConditionalOperator(ConditionalOperator *E); 472efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitChooseExpr(ChooseExpr *E) 4736e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl { return Visit(E->getChosenSubExpr(Info.Ctx)); } 474efdb83e26f9a1fd2566afe54461216cd84814d42John McCall bool VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) 475efdb83e26f9a1fd2566afe54461216cd84814d42John McCall { return Success((Expr*)0); } 476ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman // FIXME: Missing: @protocol, @selector 4772bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson}; 478f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 4792bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 480efdb83e26f9a1fd2566afe54461216cd84814d42John McCallstatic bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) { 4817db7acbbb84b82d0522266a50ebabc3a52a9e5d1John McCall assert(E->getType()->hasPointerRepresentation()); 482efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return PointerExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 483f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 484650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 485efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 4862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() != BO_Add && 4872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall E->getOpcode() != BO_Sub) 488efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 490650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *PExp = E->getLHS(); 491650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson const Expr *IExp = E->getRHS(); 492650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson if (IExp->getType()->isPointerType()) 493f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner std::swap(PExp, IExp); 4941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 495efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluatePointer(PExp, Result, Info)) 496efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 498efdb83e26f9a1fd2566afe54461216cd84814d42John McCall llvm::APSInt Offset; 499efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateInteger(IExp, Offset, Info)) 500efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 501efdb83e26f9a1fd2566afe54461216cd84814d42John McCall int64_t AdditionalOffset 502efdb83e26f9a1fd2566afe54461216cd84814d42John McCall = Offset.isSigned() ? Offset.getSExtValue() 503efdb83e26f9a1fd2566afe54461216cd84814d42John McCall : static_cast<int64_t>(Offset.getZExtValue()); 504650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 505e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar // Compute the new offset in the appropriate width. 506e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar 507e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar QualType PointeeType = 508e0cdb4edd8f265d0fd22d178d03c597dd201cda2Daniel Dunbar PExp->getType()->getAs<PointerType>()->getPointeeType(); 509efdb83e26f9a1fd2566afe54461216cd84814d42John McCall CharUnits SizeOfPointee; 5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5114d4c50dd8b4db191c38782414665fb7608315a36Anders Carlsson // Explicitly handle GNU void* and function pointer arithmetic extensions. 5124d4c50dd8b4db191c38782414665fb7608315a36Anders Carlsson if (PointeeType->isVoidType() || PointeeType->isFunctionType()) 513efdb83e26f9a1fd2566afe54461216cd84814d42John McCall SizeOfPointee = CharUnits::One(); 5144d4c50dd8b4db191c38782414665fb7608315a36Anders Carlsson else 515efdb83e26f9a1fd2566afe54461216cd84814d42John McCall SizeOfPointee = Info.Ctx.getTypeSizeInChars(PointeeType); 5164efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 5172de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Add) 518efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset += AdditionalOffset * SizeOfPointee; 519650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson else 520efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset -= AdditionalOffset * SizeOfPointee; 5214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 522efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 523650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson} 5244efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 525efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { 526efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return EvaluateLValue(E->getSubExpr(), Result, Info); 5274efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 5281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 529650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 530efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitCastExpr(CastExpr* E) { 53109a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman Expr* SubExpr = E->getSubExpr(); 532650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 53309a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman switch (E->getCastKind()) { 53409a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman default: 53509a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman break; 53609a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman 5372de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_NoOp: 5382de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_BitCast: 5392de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_LValueBitCast: 5402de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_AnyPointerToObjCPointerCast: 5412de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_AnyPointerToBlockPointerCast: 54209a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman return Visit(SubExpr); 54309a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman 5445c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson case CK_DerivedToBase: 5455c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson case CK_UncheckedDerivedToBase: { 5465c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson LValue BaseLV; 5475c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson if (!EvaluatePointer(E->getSubExpr(), BaseLV, Info)) 5485c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson return false; 5495c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 5505c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // Now figure out the necessary offset to add to the baseLV to get from 5515c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // the derived class to the base class. 5525c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson uint64_t Offset = 0; 5535c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 5545c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson QualType Ty = E->getSubExpr()->getType(); 5555c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const CXXRecordDecl *DerivedDecl = 5565c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson Ty->getAs<PointerType>()->getPointeeType()->getAsCXXRecordDecl(); 5575c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 5585c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson for (CastExpr::path_const_iterator PathI = E->path_begin(), 5595c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson PathE = E->path_end(); PathI != PathE; ++PathI) { 5605c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const CXXBaseSpecifier *Base = *PathI; 5615c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 5625c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // FIXME: If the base is virtual, we'd need to determine the type of the 5635c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson // most derived class and we don't support that right now. 5645c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson if (Base->isVirtual()) 5655c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson return false; 5665c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 5675c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const CXXRecordDecl *BaseDecl = Base->getType()->getAsCXXRecordDecl(); 5685c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl); 5695c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 570a14f5979572aa25c03d24750ee4724d2031d4edeAnders Carlsson Offset += Layout.getBaseClassOffsetInBits(BaseDecl); 5715c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson DerivedDecl = BaseDecl; 5725c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson } 5735c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 5745c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson Result.Base = BaseLV.getLValueBase(); 5755c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson Result.Offset = BaseLV.getLValueOffset() + 576fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Info.Ctx.toCharUnitsFromBits(Offset); 5775c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson return true; 5785c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson } 5795c5a764fcd256df6f6cfbce5cdd2a2dfb2c45e95Anders Carlsson 580404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall case CK_NullToPointer: { 581404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall Result.Base = 0; 582404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall Result.Offset = CharUnits::Zero(); 583404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall return true; 584404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall } 585404cd1669c3ba138a9ae0a619bd689cce5aae271John McCall 5862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_IntegralToPointer: { 587efdb83e26f9a1fd2566afe54461216cd84814d42John McCall APValue Value; 588efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateIntegerOrLValue(SubExpr, Value, Info)) 58909a8a0e6ec1252cad52666e9dbb21002b9c80f38Eli Friedman break; 59069ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar 591efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (Value.isInt()) { 5929f71a8f4c7a182a5236da9e747d57cc1d1bd24c2Jay Foad Value.getInt() = Value.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); 593efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = 0; 594efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = CharUnits::fromQuantity(Value.getInt().getZExtValue()); 595efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 596efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else { 597efdb83e26f9a1fd2566afe54461216cd84814d42John McCall // Cast is of an lvalue, no need to change value. 598efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Base = Value.getLValueBase(); 599efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Result.Offset = Value.getLValueOffset(); 600efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 601650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 602650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson } 6032de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_ArrayToPointerDecay: 6042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case CK_FunctionToPointerDecay: 605efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return EvaluateLValue(SubExpr, Result, Info); 6064efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 6074efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 608efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 610650c92fdcc27a950a8a848ecab6a74e6f5e80788Anders Carlsson 611efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitCallExpr(CallExpr *E) { 6121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (E->isBuiltinCall(Info.Ctx) == 6130d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall Builtin::BI__builtin___CFStringMakeConstantString || 6140d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall E->isBuiltinCall(Info.Ctx) == 6150d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall Builtin::BI__builtin___NSStringMakeConstantString) 616efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Success(E); 617efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 6183941b18b8e441c8c466efecd557de60b9a32d10bEli Friedman} 6193941b18b8e441c8c466efecd557de60b9a32d10bEli Friedman 620efdb83e26f9a1fd2566afe54461216cd84814d42John McCallbool PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { 6214efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool BoolResult; 6224efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!HandleConversionToBool(E->getCond(), BoolResult, Info)) 623efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 6244efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 6254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr(); 626efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return Visit(EvalExpr); 6274efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 628f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 629f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 63059b5da6d853b4368b984700315adf7b37de05764Nate Begeman// Vector Evaluation 63159b5da6d853b4368b984700315adf7b37de05764Nate Begeman//===----------------------------------------------------------------------===// 63259b5da6d853b4368b984700315adf7b37de05764Nate Begeman 63359b5da6d853b4368b984700315adf7b37de05764Nate Begemannamespace { 634770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramer class VectorExprEvaluator 63559b5da6d853b4368b984700315adf7b37de05764Nate Begeman : public StmtVisitor<VectorExprEvaluator, APValue> { 63659b5da6d853b4368b984700315adf7b37de05764Nate Begeman EvalInfo &Info; 63791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue GetZeroVector(QualType VecType); 63859b5da6d853b4368b984700315adf7b37de05764Nate Begeman public: 6391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64059b5da6d853b4368b984700315adf7b37de05764Nate Begeman VectorExprEvaluator(EvalInfo &info) : Info(info) {} 6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64259b5da6d853b4368b984700315adf7b37de05764Nate Begeman APValue VisitStmt(Stmt *S) { 64359b5da6d853b4368b984700315adf7b37de05764Nate Begeman return APValue(); 64459b5da6d853b4368b984700315adf7b37de05764Nate Begeman } 6451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 64691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitParenExpr(ParenExpr *E) 64791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman { return Visit(E->getSubExpr()); } 64891110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitUnaryExtension(const UnaryOperator *E) 64991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman { return Visit(E->getSubExpr()); } 65091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitUnaryPlus(const UnaryOperator *E) 65191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman { return Visit(E->getSubExpr()); } 65291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitUnaryReal(const UnaryOperator *E) 65391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman { return Visit(E->getSubExpr()); } 65491110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) 65591110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman { return GetZeroVector(E->getType()); } 65659b5da6d853b4368b984700315adf7b37de05764Nate Begeman APValue VisitCastExpr(const CastExpr* E); 65759b5da6d853b4368b984700315adf7b37de05764Nate Begeman APValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); 65859b5da6d853b4368b984700315adf7b37de05764Nate Begeman APValue VisitInitListExpr(const InitListExpr *E); 65991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitConditionalOperator(const ConditionalOperator *E); 660ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman APValue VisitChooseExpr(const ChooseExpr *E) 661ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman { return Visit(E->getChosenSubExpr(Info.Ctx)); } 66291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue VisitUnaryImag(const UnaryOperator *E); 66391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // FIXME: Missing: unary -, unary ~, binary add/sub/mul/div, 6642217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman // binary comparisons, binary and/or/xor, 66591110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // shufflevector, ExtVectorElementExpr 66691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // (Note that these require implementing conversions 66791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman // between vector types.) 66859b5da6d853b4368b984700315adf7b37de05764Nate Begeman }; 66959b5da6d853b4368b984700315adf7b37de05764Nate Begeman} // end anonymous namespace 67059b5da6d853b4368b984700315adf7b37de05764Nate Begeman 67159b5da6d853b4368b984700315adf7b37de05764Nate Begemanstatic bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { 67259b5da6d853b4368b984700315adf7b37de05764Nate Begeman if (!E->getType()->isVectorType()) 67359b5da6d853b4368b984700315adf7b37de05764Nate Begeman return false; 67459b5da6d853b4368b984700315adf7b37de05764Nate Begeman Result = VectorExprEvaluator(Info).Visit(const_cast<Expr*>(E)); 67559b5da6d853b4368b984700315adf7b37de05764Nate Begeman return !Result.isUninit(); 67659b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 67759b5da6d853b4368b984700315adf7b37de05764Nate Begeman 67859b5da6d853b4368b984700315adf7b37de05764Nate BegemanAPValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) { 679183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const VectorType *VTy = E->getType()->getAs<VectorType>(); 680c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman QualType EltTy = VTy->getElementType(); 681c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman unsigned NElts = VTy->getNumElements(); 682c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman unsigned EltWidth = Info.Ctx.getTypeSize(EltTy); 6831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68459b5da6d853b4368b984700315adf7b37de05764Nate Begeman const Expr* SE = E->getSubExpr(); 685e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman QualType SETy = SE->getType(); 686e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman APValue Result = APValue(); 68759b5da6d853b4368b984700315adf7b37de05764Nate Begeman 688e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman // Check for vector->vector bitcast and scalar->vector splat. 689e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman if (SETy->isVectorType()) { 69059b5da6d853b4368b984700315adf7b37de05764Nate Begeman return this->Visit(const_cast<Expr*>(SE)); 691e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman } else if (SETy->isIntegerType()) { 692e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman APSInt IntResult; 693d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar if (!EvaluateInteger(SE, IntResult, Info)) 694d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar return APValue(); 695d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar Result = APValue(IntResult); 696e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman } else if (SETy->isRealFloatingType()) { 697e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman APFloat F(0.0); 698d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar if (!EvaluateFloat(SE, F, Info)) 699d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar return APValue(); 700d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar Result = APValue(F); 701d906dc7605b2d6352e16c27a5d3fb5f1a1b44ac8Daniel Dunbar } else 702c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman return APValue(); 70359b5da6d853b4368b984700315adf7b37de05764Nate Begeman 704c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // For casts of a scalar to ExtVector, convert the scalar to the element type 705c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // and splat it to all elements. 706c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman if (E->getType()->isExtVectorType()) { 707c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman if (EltTy->isIntegerType() && Result.isInt()) 708c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(), 709c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Info.Ctx)); 710c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman else if (EltTy->isIntegerType()) 711c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(), 712c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Info.Ctx)); 713c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman else if (EltTy->isRealFloatingType() && Result.isInt()) 714c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(), 715c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Info.Ctx)); 716c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman else if (EltTy->isRealFloatingType()) 717c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(), 718c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Info.Ctx)); 719c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman else 720c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman return APValue(); 721c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman 722c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // Splat and create vector APValue. 723c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman llvm::SmallVector<APValue, 4> Elts(NElts, Result); 724c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman return APValue(&Elts[0], Elts.size()); 725e8c9e9218f215ec6089f12b076c7b9d310fd5194Nate Begeman } 726c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman 727c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // For casts of a scalar to regular gcc-style vector type, bitcast the scalar 728c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // to the vector. To construct the APValue vector initializer, bitcast the 729c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // initializing value to an APInt, and shift out the bits pertaining to each 730c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman // element. 731c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman APSInt Init; 732c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt(); 7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 734c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman llvm::SmallVector<APValue, 4> Elts; 735c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman for (unsigned i = 0; i != NElts; ++i) { 7369f71a8f4c7a182a5236da9e747d57cc1d1bd24c2Jay Foad APSInt Tmp = Init.extOrTrunc(EltWidth); 7371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 738c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman if (EltTy->isIntegerType()) 739c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Elts.push_back(APValue(Tmp)); 740c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman else if (EltTy->isRealFloatingType()) 741c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Elts.push_back(APValue(APFloat(Tmp))); 742c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman else 743c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman return APValue(); 744c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman 745c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman Init >>= EltWidth; 746c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman } 747c0b8b19bd8056d6b5d831623a0825cce150f4507Nate Begeman return APValue(&Elts[0], Elts.size()); 74859b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 74959b5da6d853b4368b984700315adf7b37de05764Nate Begeman 7501eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAPValue 75159b5da6d853b4368b984700315adf7b37de05764Nate BegemanVectorExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { 75259b5da6d853b4368b984700315adf7b37de05764Nate Begeman return this->Visit(const_cast<Expr*>(E->getInitializer())); 75359b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 75459b5da6d853b4368b984700315adf7b37de05764Nate Begeman 7551eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAPValue 75659b5da6d853b4368b984700315adf7b37de05764Nate BegemanVectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { 757183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const VectorType *VT = E->getType()->getAs<VectorType>(); 75859b5da6d853b4368b984700315adf7b37de05764Nate Begeman unsigned NumInits = E->getNumInits(); 75991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman unsigned NumElements = VT->getNumElements(); 7601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 76159b5da6d853b4368b984700315adf7b37de05764Nate Begeman QualType EltTy = VT->getElementType(); 76259b5da6d853b4368b984700315adf7b37de05764Nate Begeman llvm::SmallVector<APValue, 4> Elements; 76359b5da6d853b4368b984700315adf7b37de05764Nate Begeman 764a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall // If a vector is initialized with a single element, that value 765a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall // becomes every element of the vector, not just the first. 766a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall // This is the behavior described in the IBM AltiVec documentation. 767a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (NumInits == 1) { 768a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall APValue InitValue; 76959b5da6d853b4368b984700315adf7b37de05764Nate Begeman if (EltTy->isIntegerType()) { 77059b5da6d853b4368b984700315adf7b37de05764Nate Begeman llvm::APSInt sInt(32); 771a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateInteger(E->getInit(0), sInt, Info)) 772a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall return APValue(); 773a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall InitValue = APValue(sInt); 77459b5da6d853b4368b984700315adf7b37de05764Nate Begeman } else { 77559b5da6d853b4368b984700315adf7b37de05764Nate Begeman llvm::APFloat f(0.0); 776a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateFloat(E->getInit(0), f, Info)) 777a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall return APValue(); 778a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall InitValue = APValue(f); 779a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 780a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall for (unsigned i = 0; i < NumElements; i++) { 781a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall Elements.push_back(InitValue); 782a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 783a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } else { 784a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall for (unsigned i = 0; i < NumElements; i++) { 785a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (EltTy->isIntegerType()) { 786a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall llvm::APSInt sInt(32); 787a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (i < NumInits) { 788a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateInteger(E->getInit(i), sInt, Info)) 789a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall return APValue(); 790a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } else { 791a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall sInt = Info.Ctx.MakeIntValue(0, EltTy); 792a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 793a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall Elements.push_back(APValue(sInt)); 79491110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman } else { 795a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall llvm::APFloat f(0.0); 796a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (i < NumInits) { 797a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall if (!EvaluateFloat(E->getInit(i), f, Info)) 798a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall return APValue(); 799a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } else { 800a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)); 801a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall } 802a7d6c221558fa8117aa1d1fd41cf0046c5c9fadeJohn McCall Elements.push_back(APValue(f)); 80391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman } 80459b5da6d853b4368b984700315adf7b37de05764Nate Begeman } 80559b5da6d853b4368b984700315adf7b37de05764Nate Begeman } 80659b5da6d853b4368b984700315adf7b37de05764Nate Begeman return APValue(&Elements[0], Elements.size()); 80759b5da6d853b4368b984700315adf7b37de05764Nate Begeman} 80859b5da6d853b4368b984700315adf7b37de05764Nate Begeman 8091eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpAPValue 81091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli FriedmanVectorExprEvaluator::GetZeroVector(QualType T) { 811183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall const VectorType *VT = T->getAs<VectorType>(); 81291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman QualType EltTy = VT->getElementType(); 81391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue ZeroElement; 81491110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman if (EltTy->isIntegerType()) 81591110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman ZeroElement = APValue(Info.Ctx.MakeIntValue(0, EltTy)); 81691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman else 81791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman ZeroElement = 81891110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy))); 81991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 82091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman llvm::SmallVector<APValue, 4> Elements(VT->getNumElements(), ZeroElement); 82191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman return APValue(&Elements[0], Elements.size()); 82291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman} 82391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 82491110ee24e3475e0a3a38938c7b98439b5cf0b0eEli FriedmanAPValue VectorExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { 82591110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman bool BoolResult; 82691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman if (!HandleConversionToBool(E->getCond(), BoolResult, Info)) 82791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman return APValue(); 82891110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 82991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman Expr* EvalExpr = BoolResult ? E->getTrueExpr() : E->getFalseExpr(); 83091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 83191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman APValue Result; 83291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman if (EvaluateVector(EvalExpr, Result, Info)) 83391110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman return Result; 83491110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman return APValue(); 83591110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman} 83691110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 83791110ee24e3475e0a3a38938c7b98439b5cf0b0eEli FriedmanAPValue VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { 83891110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman if (!E->getSubExpr()->isEvaluatable(Info.Ctx)) 83991110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman Info.EvalResult.HasSideEffects = true; 84091110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman return GetZeroVector(E->getType()); 84191110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman} 84291110ee24e3475e0a3a38938c7b98439b5cf0b0eEli Friedman 84359b5da6d853b4368b984700315adf7b37de05764Nate Begeman//===----------------------------------------------------------------------===// 844f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner// Integer Evaluation 845f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 846f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 847f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnernamespace { 848770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass IntExprEvaluator 849b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner : public StmtVisitor<IntExprEvaluator, bool> { 85087eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner EvalInfo &Info; 85130c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar APValue &Result; 852f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattnerpublic: 85330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar IntExprEvaluator(EvalInfo &info, APValue &result) 85487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner : Info(info), Result(result) {} 855f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 8563f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar bool Success(const llvm::APSInt &SI, const Expr *E) { 8572ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType() && 8582ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor "Invalid evaluation result."); 85930c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar assert(SI.isSigned() == E->getType()->isSignedIntegerType() && 8603f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar "Invalid evaluation result."); 86130c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) && 8623f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar "Invalid evaluation result."); 86330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = APValue(SI); 8643f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar return true; 8653f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar } 8663f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar 867131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar bool Success(const llvm::APInt &I, const Expr *E) { 8682ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType() && 8692ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor "Invalid evaluation result."); 87030c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) && 8713f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar "Invalid evaluation result."); 87230c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = APValue(APSInt(I)); 87330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result.getInt().setIsUnsigned(E->getType()->isUnsignedIntegerType()); 874131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return true; 875131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 876131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar 877131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar bool Success(uint64_t Value, const Expr *E) { 8782ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType() && 8792ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor "Invalid evaluation result."); 88030c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType())); 881131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return true; 882131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 883131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar 88482206e267ce6cc709797127616f64672d255b310Anders Carlsson bool Error(SourceLocation L, diag::kind D, const Expr *E) { 88532fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner // Take the first error. 88654da0496616cb898596cfd5fae1f824098bd8435Anders Carlsson if (Info.EvalResult.Diag == 0) { 88754da0496616cb898596cfd5fae1f824098bd8435Anders Carlsson Info.EvalResult.DiagLoc = L; 88854da0496616cb898596cfd5fae1f824098bd8435Anders Carlsson Info.EvalResult.Diag = D; 88982206e267ce6cc709797127616f64672d255b310Anders Carlsson Info.EvalResult.DiagExpr = E; 89032fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 89154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner return false; 8927a76778e218da57a3b10c80066a0a938f28987b6Chris Lattner } 8931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 894f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 895f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner // Visitor Methods 896f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner //===--------------------------------------------------------------------===// 8971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 89832fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner bool VisitStmt(Stmt *) { 89932fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner assert(0 && "This should be called on integers, stmts are not integers"); 90032fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner return false; 90132fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner } 9021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 90332fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner bool VisitExpr(Expr *E) { 9040e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 905f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner } 9061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 907b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 908f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 9094c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitIntegerLiteral(const IntegerLiteral *E) { 910131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getValue(), E); 9114c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 9124c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner bool VisitCharacterLiteral(const CharacterLiteral *E) { 913131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getValue(), E); 9144c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner } 915043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman 916043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman bool CheckReferencedDecl(const Expr *E, const Decl *D); 917043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman bool VisitDeclRefExpr(const DeclRefExpr *E) { 918043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman return CheckReferencedDecl(E, E->getDecl()); 919043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman } 920043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman bool VisitMemberExpr(const MemberExpr *E) { 921043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman if (CheckReferencedDecl(E, E->getMemberDecl())) { 922043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman // Conservatively assume a MemberExpr will have side-effects 923043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman Info.EvalResult.HasSideEffects = true; 924043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman return true; 925043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman } 926043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman return false; 927043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman } 928043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman 929c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman bool VisitCallExpr(CallExpr *E); 930b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitBinaryOperator(const BinaryOperator *E); 9318ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor bool VisitOffsetOfExpr(const OffsetOfExpr *E); 932b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner bool VisitUnaryOperator(const UnaryOperator *E); 933ca7c2eaca35edac066ab7cec15f7ecebbb3731d8Nuno Lopes bool VisitConditionalOperator(const ConditionalOperator *E); 934f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 935a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar bool VisitCastExpr(CastExpr* E); 9360518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E); 9370518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 9383068d117951a8df54bae9db039b56201ab10962bAnders Carlsson bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { 939131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getValue(), E); 9403068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 9411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9423f70456b8adb0405ef2a47d51f9fc2d5937ae8aeAnders Carlsson bool VisitGNUNullExpr(const GNUNullExpr *E) { 943131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(0, E); 9443f70456b8adb0405ef2a47d51f9fc2d5937ae8aeAnders Carlsson } 9451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 946ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregor bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) { 947131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(0, E); 9483068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 9493068d117951a8df54bae9db039b56201ab10962bAnders Carlsson 950664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { 951664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman return Success(0, E); 952664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman } 953664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman 95464b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) { 9550dfd848fa4c9664852ba8c929a8bd3fce93ddca2Sebastian Redl return Success(E->getValue(), E); 95664b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl } 95764b45f7e0d3167f040841ac2920aead7f080730dSebastian Redl 9586ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet bool VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) { 9596ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet return Success(E->getValue(), E); 9606ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet } 9616ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet 962ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman bool VisitChooseExpr(const ChooseExpr *E) { 963ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman return Visit(E->getChosenSubExpr(Info.Ctx)); 964ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman } 965ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman 966722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman bool VisitUnaryReal(const UnaryOperator *E); 967664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman bool VisitUnaryImag(const UnaryOperator *E); 968664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman 969295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E); 970ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor bool VisitSizeOfPackExpr(const SizeOfPackExpr *E); 971ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor 972fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattnerprivate: 9738b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck CharUnits GetAlignOfExpr(const Expr *E); 9748b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck CharUnits GetAlignOfType(QualType T); 97542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall static QualType GetObjectType(const Expr *E); 97642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall bool TryEvaluateBuiltinObjectSize(CallExpr *E); 977664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman // FIXME: Missing: array subscript of vector, member of vector 978f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner}; 979f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} // end anonymous namespace 980f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 98169ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbarstatic bool EvaluateIntegerOrLValue(const Expr* E, APValue &Result, EvalInfo &Info) { 9822ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType()); 98369ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 98469ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar} 98569ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar 98669ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbarstatic bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) { 9872ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor assert(E->getType()->isIntegralOrEnumerationType()); 9887db7acbbb84b82d0522266a50ebabc3a52a9e5d1John McCall 98930c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar APValue Val; 99069ab26a8623141f35e86817cfc6e0fbe7639a40fDaniel Dunbar if (!EvaluateIntegerOrLValue(E, Val, Info) || !Val.isInt()) 99130c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return false; 99230c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result = Val.getInt(); 99330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return true; 994f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner} 995f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 996043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedmanbool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { 9974c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Enums are integer constant exprs. 99829a7f3342c3c6dd15d914c61ae22246c36d51ce7Eli Friedman if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) 99929a7f3342c3c6dd15d914c61ae22246c36d51ce7Eli Friedman return Success(ECD->getInitVal(), E); 1000b2bc62bd35129f09d0746ef6a5ef4dc392b6d6e1Sebastian Redl 1001b2bc62bd35129f09d0746ef6a5ef4dc392b6d6e1Sebastian Redl // In C++, const, non-volatile integers initialized with ICEs are ICEs. 1002e1646da3bb0fe97b372e5fe8cefc537b22048fc4Eli Friedman // In C, they can also be folded, although they are not ICEs. 1003cf3293eaeb3853d12cff47e648bbe835004e929fDouglas Gregor if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers() 1004cf3293eaeb3853d12cff47e648bbe835004e929fDouglas Gregor == Qualifiers::Const) { 1005f6b6025a4e26bb0295a57e0efece73253038f278Anders Carlsson 1006f6b6025a4e26bb0295a57e0efece73253038f278Anders Carlsson if (isa<ParmVarDecl>(D)) 1007f6b6025a4e26bb0295a57e0efece73253038f278Anders Carlsson return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1008f6b6025a4e26bb0295a57e0efece73253038f278Anders Carlsson 1009043097507f99b1156bfd8bad41e7d5166ae4b9b6Eli Friedman if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { 101031310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl if (const Expr *Init = VD->getAnyInitializer()) { 1011c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman if (APValue *V = VD->getEvaluatedValue()) { 1012c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman if (V->isInt()) 1013c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman return Success(V->getInt(), E); 1014c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1015c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman } 1016c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman 1017c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman if (VD->isEvaluatingValue()) 1018c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1019c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman 1020c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman VD->setEvaluatingValue(); 1021c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman 1022a7dedf7004e8ac3f947d6817370b2778fa648c2bEli Friedman Expr::EvalResult EResult; 1023a7dedf7004e8ac3f947d6817370b2778fa648c2bEli Friedman if (Init->Evaluate(EResult, Info.Ctx) && !EResult.HasSideEffects && 1024a7dedf7004e8ac3f947d6817370b2778fa648c2bEli Friedman EResult.Val.isInt()) { 102578d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor // Cache the evaluated value in the variable declaration. 1026a7dedf7004e8ac3f947d6817370b2778fa648c2bEli Friedman Result = EResult.Val; 1027c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman VD->setEvaluatedValue(Result); 102878d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor return true; 102978d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor } 103078d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor 1031c013118155077cf8bdaef743c5dbce760114eed3Eli Friedman VD->setEvaluatedValue(APValue()); 103278d1583d0b36b7d6d8d10234cdc19ab94adf765aDouglas Gregor } 1033b2bc62bd35129f09d0746ef6a5ef4dc392b6d6e1Sebastian Redl } 1034b2bc62bd35129f09d0746ef6a5ef4dc392b6d6e1Sebastian Redl } 1035b2bc62bd35129f09d0746ef6a5ef4dc392b6d6e1Sebastian Redl 10364c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // Otherwise, random variable references are not constants. 10370e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 10384c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 10394c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner 1040a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner/// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way 1041a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner/// as GCC. 1042a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattnerstatic int EvaluateBuiltinClassifyType(const CallExpr *E) { 1043a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // The following enum mimics the values returned by GCC. 10447c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl // FIXME: Does GCC differ between lvalue and rvalue references here? 1045a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner enum gcc_type_class { 1046a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner no_type_class = -1, 1047a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner void_type_class, integer_type_class, char_type_class, 1048a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner enumeral_type_class, boolean_type_class, 1049a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner pointer_type_class, reference_type_class, offset_type_class, 1050a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner real_type_class, complex_type_class, 1051a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner function_type_class, method_type_class, 1052a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner record_type_class, union_type_class, 1053a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner array_type_class, string_type_class, 1054a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner lang_type_class 1055a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner }; 10561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // If no argument was supplied, default to "no_type_class". This isn't 1058a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner // ideal, however it is what gcc does. 1059a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner if (E->getNumArgs() == 0) 1060a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return no_type_class; 10611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1062a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner QualType ArgTy = E->getArg(0)->getType(); 1063a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner if (ArgTy->isVoidType()) 1064a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return void_type_class; 1065a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isEnumeralType()) 1066a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return enumeral_type_class; 1067a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isBooleanType()) 1068a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return boolean_type_class; 1069a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isCharType()) 1070a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return string_type_class; // gcc doesn't appear to use char_type_class 1071a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isIntegerType()) 1072a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return integer_type_class; 1073a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isPointerType()) 1074a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return pointer_type_class; 1075a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isReferenceType()) 1076a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return reference_type_class; 1077a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isRealType()) 1078a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return real_type_class; 1079a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isComplexType()) 1080a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return complex_type_class; 1081a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isFunctionType()) 1082a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return function_type_class; 1083fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor else if (ArgTy->isStructureOrClassType()) 1084a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return record_type_class; 1085a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isUnionType()) 1086a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return union_type_class; 1087a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isArrayType()) 1088a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return array_type_class; 1089a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else if (ArgTy->isUnionType()) 1090a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return union_type_class; 1091a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner else // FIXME: offset_type_class, method_type_class, & lang_type_class? 1092a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner assert(0 && "CallExpr::isBuiltinClassifyType(): unimplemented type"); 1093a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner return -1; 1094a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner} 1095a4d55d89c8076b402bb168e3edeef0c2cd2a78c3Chris Lattner 109642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// Retrieves the "underlying object type" of the given expression, 109742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// as used by __builtin_object_size. 109842c8f87eb60958170c46767273bf93e6c96125bfJohn McCallQualType IntExprEvaluator::GetObjectType(const Expr *E) { 109942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 110042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) 110142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return VD->getType(); 110242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall } else if (isa<CompoundLiteralExpr>(E)) { 110342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return E->getType(); 110442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall } 110542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 110642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return QualType(); 110742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall} 110842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 110942c8f87eb60958170c46767273bf93e6c96125bfJohn McCallbool IntExprEvaluator::TryEvaluateBuiltinObjectSize(CallExpr *E) { 111042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall // TODO: Perhaps we should let LLVM lower this? 111142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall LValue Base; 111242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!EvaluatePointer(E->getArg(0), Base, Info)) 111342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 111442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 111542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall // If we can prove the base is null, lower to zero now. 111642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall const Expr *LVBase = Base.getLValueBase(); 111742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!LVBase) return Success(0, E); 111842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 111942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall QualType T = GetObjectType(LVBase); 112042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (T.isNull() || 112142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall T->isIncompleteType() || 11221357869bc5983cdfbc986db1f3d18265bb34cb0eEli Friedman T->isFunctionType() || 112342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall T->isVariablyModifiedType() || 112442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall T->isDependentType()) 112542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 112642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 112742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall CharUnits Size = Info.Ctx.getTypeSizeInChars(T); 112842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall CharUnits Offset = Base.getLValueOffset(); 112942c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 113042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (!Offset.isNegative() && Offset <= Size) 113142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall Size -= Offset; 113242c8f87eb60958170c46767273bf93e6c96125bfJohn McCall else 113342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall Size = CharUnits::Zero(); 113442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return Success(Size.getQuantity(), E); 113542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall} 113642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall 1137c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedmanbool IntExprEvaluator::VisitCallExpr(CallExpr *E) { 11383c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor switch (E->isBuiltinCall(Info.Ctx)) { 1139019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner default: 11400e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 114164eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 114264eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump case Builtin::BI__builtin_object_size: { 114342c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (TryEvaluateBuiltinObjectSize(E)) 114442c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return true; 114564eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 1146b2aaf51ed73a4774322a39a0dd59d0fe7e3258c0Eric Christopher // If evaluating the argument has side-effects we can't determine 1147b2aaf51ed73a4774322a39a0dd59d0fe7e3258c0Eric Christopher // the size of the object and lower it to unknown now. 1148393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian if (E->getArg(0)->HasSideEffects(Info.Ctx)) { 11493f27b384801de26ce7efaa395699b42719372f24Benjamin Kramer if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1) 1150cf184655319cf7a5b811067cff9d26a5741fd161Chris Lattner return Success(-1ULL, E); 115164eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump return Success(0, E); 115264eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump } 1153c4c9045dabfc0f0d37dea1b3eb2992654d5b2db1Mike Stump 115464eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 115564eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump } 115664eda9e50b593f935c95bd1edc98c4bfda03f601Mike Stump 1157019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_classify_type: 1158131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(EvaluateBuiltinClassifyType(E), E); 11591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11604bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson case Builtin::BI__builtin_constant_p: 1161019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner // __builtin_constant_p always has one operand: it returns true if that 1162019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner // operand can be folded, false otherwise. 1163131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(E->getArg(0)->isEvaluatable(Info.Ctx), E); 116421fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner 116521fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner case Builtin::BI__builtin_eh_return_data_regno: { 116621fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner int Operand = E->getArg(0)->EvaluateAsInt(Info.Ctx).getZExtValue(); 116721fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner Operand = Info.Ctx.Target.getEHDataRegisterNumber(Operand); 116821fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner return Success(Operand, E); 116921fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner } 1170c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman 1171c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman case Builtin::BI__builtin_expect: 1172c4a2638b5ef3e2d35d872614ceb655a7a22c58beEli Friedman return Visit(E->getArg(0)); 11735726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor 11745726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor case Builtin::BIstrlen: 11755726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor case Builtin::BI__builtin_strlen: 11765726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // As an extension, we support strlen() and __builtin_strlen() as constant 11775726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // expressions when the argument is a string literal. 11785726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor if (StringLiteral *S 11795726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor = dyn_cast<StringLiteral>(E->getArg(0)->IgnoreParenImpCasts())) { 11805726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // The string literal may have embedded null characters. Find the first 11815726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor // one and truncate there. 11825726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor llvm::StringRef Str = S->getString(); 11835726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor llvm::StringRef::size_type Pos = Str.find(0); 11845726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor if (Pos != llvm::StringRef::npos) 11855726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor Str = Str.substr(0, Pos); 11865726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor 11875726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor return Success(Str.size(), E); 11885726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor } 11895726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor 11905726d405e71f11feaaf0c8f518abe26e909537a4Douglas Gregor return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E); 1191019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 11924c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner} 1193f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 1194b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 11952de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Comma) { 1196027f62ec1860f4ab0c91bd863b238938880b8102Anders Carlsson if (!Visit(E->getRHS())) 1197027f62ec1860f4ab0c91bd863b238938880b8102Anders Carlsson return false; 11984fdfb0965b396f2778091f7e6c051d17ff9791baAnders Carlsson 119933ef1456a19779fb15c51aea362bd9c7cb4087f3Eli Friedman // If we can't evaluate the LHS, it might have side effects; 120033ef1456a19779fb15c51aea362bd9c7cb4087f3Eli Friedman // conservatively mark it. 120133ef1456a19779fb15c51aea362bd9c7cb4087f3Eli Friedman if (!E->getLHS()->isEvaluatable(Info.Ctx)) 120233ef1456a19779fb15c51aea362bd9c7cb4087f3Eli Friedman Info.EvalResult.HasSideEffects = true; 1203c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner 1204027f62ec1860f4ab0c91bd863b238938880b8102Anders Carlsson return true; 1205a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1206a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1207a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (E->isLogicalOp()) { 1208a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // These need to be handled specially because the operands aren't 1209a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // necessarily integral 1210fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson bool lhsResult, rhsResult; 12111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1212fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson if (HandleConversionToBool(E->getLHS(), lhsResult, Info)) { 121351fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson // We were able to evaluate the LHS, see if we can get away with not 121451fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson // evaluating the RHS: 0 && X -> 0, 1 || X -> 1 12152de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (lhsResult == (E->getOpcode() == BO_LOr)) 12163f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar return Success(lhsResult, E); 1217a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1218fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) { 12192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_LOr) 1220131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(lhsResult || rhsResult, E); 12214bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson else 1222131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(lhsResult && rhsResult, E); 12234bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } 12244bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } else { 1225fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson if (HandleConversionToBool(E->getRHS(), rhsResult, Info)) { 12264bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson // We can't evaluate the LHS; however, sometimes the result 12274bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson // is determined by the RHS: X && 0 -> 0, X || 1 -> 1. 12282de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (rhsResult == (E->getOpcode() == BO_LOr) || 12292de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall !rhsResult == (E->getOpcode() == BO_LAnd)) { 1230131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar // Since we weren't able to evaluate the left hand side, it 1231fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson // must have had side effects. 1232fcb4d09531abbf2a5cf398c2f946fb3bc2875f64Anders Carlsson Info.EvalResult.HasSideEffects = true; 1233131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar 1234131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(rhsResult, E); 12354bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } 12364bbc0e05a714d4ee4918a92a4a7049dd6ef33ad0Anders Carlsson } 1237a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1238a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1239a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 1240c8cc9ccc7b87a7ed1749b074f6b670bcec49abc1Chris Lattner } 124154176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner 1242286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson QualType LHSTy = E->getLHS()->getType(); 1243286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson QualType RHSTy = E->getRHS()->getType(); 12444087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 12454087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (LHSTy->isAnyComplexType()) { 12464087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar assert(RHSTy->isAnyComplexType() && "Invalid comparison"); 1247f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LHS, RHS; 12484087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 12494087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (!EvaluateComplex(E->getLHS(), LHS, Info)) 12504087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar return false; 12514087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 12524087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (!EvaluateComplex(E->getRHS(), RHS, Info)) 12534087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar return false; 12544087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 12554087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar if (LHS.isComplexFloat()) { 12561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump APFloat::cmpResult CR_r = 12574087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal()); 12581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump APFloat::cmpResult CR_i = 12594087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag()); 12604087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar 12612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_EQ) 1262131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success((CR_r == APFloat::cmpEqual && 1263131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar CR_i == APFloat::cmpEqual), E); 1264131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar else { 12652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall assert(E->getOpcode() == BO_NE && 1266131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar "Invalid complex comparison."); 12671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Success(((CR_r == APFloat::cmpGreaterThan || 1268fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_r == APFloat::cmpLessThan || 1269fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_r == APFloat::cmpUnordered) || 12701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (CR_i == APFloat::cmpGreaterThan || 1271fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_i == APFloat::cmpLessThan || 1272fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang CR_i == APFloat::cmpUnordered)), E); 1273131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 12744087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar } else { 12752de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_EQ) 1276131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() && 1277131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar LHS.getComplexIntImag() == RHS.getComplexIntImag()), E); 1278131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar else { 12792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall assert(E->getOpcode() == BO_NE && 1280131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar "Invalid compex comparison."); 1281131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() || 1282131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar LHS.getComplexIntImag() != RHS.getComplexIntImag()), E); 1283131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar } 12844087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar } 12854087e24f73d05d96ac2d259679751d054d3ddfbcDaniel Dunbar } 12861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1287286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson if (LHSTy->isRealFloatingType() && 1288286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson RHSTy->isRealFloatingType()) { 1289286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson APFloat RHS(0.0), LHS(0.0); 12901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1291286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson if (!EvaluateFloat(E->getRHS(), RHS, Info)) 1292286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson return false; 12931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1294286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson if (!EvaluateFloat(E->getLHS(), LHS, Info)) 1295286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson return false; 12961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1297286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson APFloat::cmpResult CR = LHS.compare(RHS); 1298529569e68d10b0fd3750fd2124faf742249b846bAnders Carlsson 1299286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson switch (E->getOpcode()) { 1300286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson default: 1301286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson assert(0 && "Invalid binary operator!"); 13022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LT: 1303131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpLessThan, E); 13042de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GT: 1305131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpGreaterThan, E); 13062de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LE: 1307131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E); 13082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GE: 13091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual, 1310131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar E); 13112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_EQ: 1312131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(CR == APFloat::cmpEqual, E); 13132de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_NE: 13141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Success(CR == APFloat::cmpGreaterThan 1315fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang || CR == APFloat::cmpLessThan 1316fc39dc4c7886723310419b1869cf651ca55b7af4Mon P Wang || CR == APFloat::cmpUnordered, E); 1317286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson } 1318286f85e791dda3634fee7f6c67f0ed92296c028fAnders Carlsson } 13191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1320ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman if (LHSTy->isPointerType() && RHSTy->isPointerType()) { 13212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Sub || E->isEqualityOp()) { 1322efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LHSValue; 13233068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluatePointer(E->getLHS(), LHSValue, Info)) 13243068d117951a8df54bae9db039b56201ab10962bAnders Carlsson return false; 1325a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 1326efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue RHSValue; 13273068d117951a8df54bae9db039b56201ab10962bAnders Carlsson if (!EvaluatePointer(E->getRHS(), RHSValue, Info)) 13283068d117951a8df54bae9db039b56201ab10962bAnders Carlsson return false; 1329a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 13305bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman // Reject any bases from the normal codepath; we special-case comparisons 13315bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman // to null. 13325bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (LHSValue.getLValueBase()) { 13335bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!E->isEqualityOp()) 13345bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 1335a73058324197b7bdfd19307965954f626e26199dKen Dyck if (RHSValue.getLValueBase() || !RHSValue.getLValueOffset().isZero()) 13365bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 13375bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman bool bres; 13385bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!EvalPointerValueAsBool(LHSValue, bres)) 13395bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 13402de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall return Success(bres ^ (E->getOpcode() == BO_EQ), E); 13415bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman } else if (RHSValue.getLValueBase()) { 13425bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!E->isEqualityOp()) 13435bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 1344a73058324197b7bdfd19307965954f626e26199dKen Dyck if (LHSValue.getLValueBase() || !LHSValue.getLValueOffset().isZero()) 13455bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 13465bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman bool bres; 13475bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman if (!EvalPointerValueAsBool(RHSValue, bres)) 13485bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman return false; 13492de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall return Success(bres ^ (E->getOpcode() == BO_EQ), E); 13505bc86103767c2abcbfdd6518e0ccbbbb6aa59e0fEli Friedman } 1351a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 13522de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Sub) { 13534992bdde387c5f033bb450a716eaabc0fda52688Chris Lattner QualType Type = E->getLHS()->getType(); 13544992bdde387c5f033bb450a716eaabc0fda52688Chris Lattner QualType ElementType = Type->getAs<PointerType>()->getPointeeType(); 13553068d117951a8df54bae9db039b56201ab10962bAnders Carlsson 1356a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits ElementSize = CharUnits::One(); 1357ce1bca73aef9bbf6359ab8420278203dda81a054Eli Friedman if (!ElementType->isVoidType() && !ElementType->isFunctionType()) 1358a73058324197b7bdfd19307965954f626e26199dKen Dyck ElementSize = Info.Ctx.getTypeSizeInChars(ElementType); 1359a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 1360a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits Diff = LHSValue.getLValueOffset() - 1361a73058324197b7bdfd19307965954f626e26199dKen Dyck RHSValue.getLValueOffset(); 1362a73058324197b7bdfd19307965954f626e26199dKen Dyck return Success(Diff / ElementSize, E); 1363ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman } 1364ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman bool Result; 13652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_EQ) { 1366ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman Result = LHSValue.getLValueOffset() == RHSValue.getLValueOffset(); 1367267c0ab1b9a15768f3f15abbfc40ce344751c78bEli Friedman } else { 1368ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman Result = LHSValue.getLValueOffset() != RHSValue.getLValueOffset(); 1369ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman } 1370ad02d7debd03ff275ac8ea27891a4ecccdb78068Eli Friedman return Success(Result, E); 13713068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 13723068d117951a8df54bae9db039b56201ab10962bAnders Carlsson } 13732ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!LHSTy->isIntegralOrEnumerationType() || 13742ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor !RHSTy->isIntegralOrEnumerationType()) { 1375a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // We can't continue from here for non-integral types, and they 1376a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // could potentially confuse the following operations. 1377a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 1378a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1379a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 1380a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // The LHS of a constant expr is always evaluated and needed. 138130c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar if (!Visit(E->getLHS())) 1382a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; // error in subexpression. 1383d9f4bcda18bfbf79341edd9d381d4b6a3cffe655Eli Friedman 138442edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman APValue RHSVal; 138542edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman if (!EvaluateIntegerOrLValue(E->getRHS(), RHSVal, Info)) 138630c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return false; 138742edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 138842edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman // Handle cases like (unsigned long)&a + 4. 138942edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman if (E->isAdditiveOp() && Result.isLValue() && RHSVal.isInt()) { 1390a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits Offset = Result.getLValueOffset(); 1391a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits AdditionalOffset = CharUnits::fromQuantity( 1392a73058324197b7bdfd19307965954f626e26199dKen Dyck RHSVal.getInt().getZExtValue()); 13932de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Add) 1394a73058324197b7bdfd19307965954f626e26199dKen Dyck Offset += AdditionalOffset; 139542edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman else 1396a73058324197b7bdfd19307965954f626e26199dKen Dyck Offset -= AdditionalOffset; 1397a73058324197b7bdfd19307965954f626e26199dKen Dyck Result = APValue(Result.getLValueBase(), Offset); 139842edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman return true; 139942edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman } 140042edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 140142edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman // Handle cases like 4 + (unsigned long)&a 14022de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Add && 140342edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman RHSVal.isLValue() && Result.isInt()) { 1404a73058324197b7bdfd19307965954f626e26199dKen Dyck CharUnits Offset = RHSVal.getLValueOffset(); 1405a73058324197b7bdfd19307965954f626e26199dKen Dyck Offset += CharUnits::fromQuantity(Result.getInt().getZExtValue()); 1406a73058324197b7bdfd19307965954f626e26199dKen Dyck Result = APValue(RHSVal.getLValueBase(), Offset); 140742edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman return true; 140842edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman } 140942edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 141042edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman // All the following cases expect both operands to be an integer 141142edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman if (!Result.isInt() || !RHSVal.isInt()) 1412b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 1413a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 141442edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman APSInt& RHS = RHSVal.getInt(); 141542edd0d32a729d2735a6fb152ba6bf349bf0a169Eli Friedman 1416a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson switch (E->getOpcode()) { 141732fea9d18cc3658a1b01df5ca6f2ac302625c61dChris Lattner default: 14180e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E); 14192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: return Success(Result.getInt() * RHS, E); 14202de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: return Success(Result.getInt() + RHS, E); 14212de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: return Success(Result.getInt() - RHS, E); 14222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_And: return Success(Result.getInt() & RHS, E); 14232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Xor: return Success(Result.getInt() ^ RHS, E); 14242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Or: return Success(Result.getInt() | RHS, E); 14252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Div: 142654176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 14270e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E); 142830c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return Success(Result.getInt() / RHS, E); 14292de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Rem: 143054176fdb044312b4b77c3da6682d3575b3728d30Chris Lattner if (RHS == 0) 14310e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_expr_divide_by_zero, E); 143230c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return Success(Result.getInt() % RHS, E); 14332de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shl: { 1434091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall // During constant-folding, a negative shift is an opposite shift. 1435091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall if (RHS.isSigned() && RHS.isNegative()) { 1436091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall RHS = -RHS; 1437091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall goto shift_right; 1438091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall } 1439091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall 1440091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall shift_left: 1441091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall unsigned SA 1442091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall = (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1); 144330c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return Success(Result.getInt() << SA, E); 14443f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar } 14452de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shr: { 1446091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall // During constant-folding, a negative shift is an opposite shift. 1447091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall if (RHS.isSigned() && RHS.isNegative()) { 1448091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall RHS = -RHS; 1449091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall goto shift_left; 1450091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall } 1451091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall 1452091f23f1d6d4bcffd6641cda72a6831e08c02ea7John McCall shift_right: 14531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned SA = 145430c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar (unsigned) RHS.getLimitedValue(Result.getInt().getBitWidth()-1); 145530c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return Success(Result.getInt() >> SA, E); 14563f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar } 14571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14582de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LT: return Success(Result.getInt() < RHS, E); 14592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GT: return Success(Result.getInt() > RHS, E); 14602de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LE: return Success(Result.getInt() <= RHS, E); 14612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GE: return Success(Result.getInt() >= RHS, E); 14622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_EQ: return Success(Result.getInt() == RHS, E); 14632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_NE: return Success(Result.getInt() != RHS, E); 1464b11e77836dd0867955c5abf32baf1c3e6c7f81e1Eli Friedman } 1465a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 1466a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 1467ca7c2eaca35edac066ab7cec15f7ecebbb3731d8Nuno Lopesbool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { 1468a25bd55e63b9ab26ca69390533356aaae7f1a40eNuno Lopes bool Cond; 1469a25bd55e63b9ab26ca69390533356aaae7f1a40eNuno Lopes if (!HandleConversionToBool(E->getCond(), Cond, Info)) 1470ca7c2eaca35edac066ab7cec15f7ecebbb3731d8Nuno Lopes return false; 1471ca7c2eaca35edac066ab7cec15f7ecebbb3731d8Nuno Lopes 1472a25bd55e63b9ab26ca69390533356aaae7f1a40eNuno Lopes return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr()); 1473ca7c2eaca35edac066ab7cec15f7ecebbb3731d8Nuno Lopes} 1474ca7c2eaca35edac066ab7cec15f7ecebbb3731d8Nuno Lopes 14758b752f10c394b140f9ef89e049cbad1a7676fc25Ken DyckCharUnits IntExprEvaluator::GetAlignOfType(QualType T) { 14765d484e8cf710207010720589d89602233de61d01Sebastian Redl // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, 14775d484e8cf710207010720589d89602233de61d01Sebastian Redl // the result is the size of the referenced type." 14785d484e8cf710207010720589d89602233de61d01Sebastian Redl // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the 14795d484e8cf710207010720589d89602233de61d01Sebastian Redl // result shall be the alignment of the referenced type." 14805d484e8cf710207010720589d89602233de61d01Sebastian Redl if (const ReferenceType *Ref = T->getAs<ReferenceType>()) 14815d484e8cf710207010720589d89602233de61d01Sebastian Redl T = Ref->getPointeeType(); 14825d484e8cf710207010720589d89602233de61d01Sebastian Redl 14832be586108bb401019647791feca19ea03fd477ceEli Friedman // __alignof is defined to return the preferred alignment. 1484fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck return Info.Ctx.toCharUnitsFromBits( 1485fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Info.Ctx.getPreferredTypeAlign(T.getTypePtr())); 1486e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner} 1487e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner 14888b752f10c394b140f9ef89e049cbad1a7676fc25Ken DyckCharUnits IntExprEvaluator::GetAlignOfExpr(const Expr *E) { 1489af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner E = E->IgnoreParens(); 1490af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner 1491af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner // alignof decl is always accepted, even if it doesn't make sense: we default 14921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // to 1 in those cases. 1493af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) 14948b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck return Info.Ctx.getDeclAlign(DRE->getDecl(), 14958b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck /*RefAsPointee*/true); 1496a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 1497af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) 14988b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck return Info.Ctx.getDeclAlign(ME->getMemberDecl(), 14998b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck /*RefAsPointee*/true); 1500af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner 1501e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner return GetAlignOfType(E->getType()); 1502e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner} 1503e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner 1504e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner 15050518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl/// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the 15060518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl/// expression's type. 15070518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redlbool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { 1508e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner // Handle alignof separately. 1509e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner if (!E->isSizeOf()) { 1510e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner if (E->isArgumentType()) 15118b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck return Success(GetAlignOfType(E->getArgumentType()).getQuantity(), E); 1512e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner else 15138b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck return Success(GetAlignOfExpr(E->getArgumentExpr()).getQuantity(), E); 1514e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner } 1515a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 15160518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl QualType SrcTy = E->getTypeOfArgument(); 15175d484e8cf710207010720589d89602233de61d01Sebastian Redl // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, 15185d484e8cf710207010720589d89602233de61d01Sebastian Redl // the result is the size of the referenced type." 15195d484e8cf710207010720589d89602233de61d01Sebastian Redl // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the 15205d484e8cf710207010720589d89602233de61d01Sebastian Redl // result shall be the alignment of the referenced type." 15215d484e8cf710207010720589d89602233de61d01Sebastian Redl if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>()) 15225d484e8cf710207010720589d89602233de61d01Sebastian Redl SrcTy = Ref->getPointeeType(); 15230518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl 1524131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc 1525131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar // extension. 1526131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar if (SrcTy->isVoidType() || SrcTy->isFunctionType()) 1527131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(1, E); 1528a1f47c447a919c6a05c63801cb6a52c4c288e2ccEli Friedman 1529fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. 1530e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner if (!SrcTy->isConstantSizeType()) 1531fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner return false; 1532f2da9dfef96dc11b7b5effb1d02cb427b2d71599Eli Friedman 1533e9feb475d72ba50dc29cec62a8c47cae721065ebChris Lattner // Get information about the size. 1534199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck return Success(Info.Ctx.getTypeSizeInChars(SrcTy).getQuantity(), E); 1535fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner} 1536fcee0019b76f9f368f2b3d6d4048a98232593f29Chris Lattner 15378ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregorbool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *E) { 15388ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CharUnits Result; 15398ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor unsigned n = E->getNumComponents(); 15408ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor OffsetOfExpr* OOE = const_cast<OffsetOfExpr*>(E); 15418ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (n == 0) 15428ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 15438ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor QualType CurrentType = E->getTypeSourceInfo()->getType(); 15448ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor for (unsigned i = 0; i != n; ++i) { 15458ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor OffsetOfExpr::OffsetOfNode ON = OOE->getComponent(i); 15468ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor switch (ON.getKind()) { 15478ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case OffsetOfExpr::OffsetOfNode::Array: { 15488ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor Expr *Idx = OOE->getIndexExpr(ON.getArrayExprIndex()); 15498ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor APSInt IdxResult; 15508ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (!EvaluateInteger(Idx, IdxResult, Info)) 15518ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 15528ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType); 15538ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (!AT) 15548ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 15558ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CurrentType = AT->getElementType(); 15568ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType); 15578ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor Result += IdxResult.getSExtValue() * ElementSize; 15588ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 15598ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 15608ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 15618ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case OffsetOfExpr::OffsetOfNode::Field: { 15628ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor FieldDecl *MemberDecl = ON.getField(); 15638ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor const RecordType *RT = CurrentType->getAs<RecordType>(); 15648ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (!RT) 15658ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return false; 15668ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor RecordDecl *RD = RT->getDecl(); 15678ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 15688ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor unsigned i = 0; 15698ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor // FIXME: It would be nice if we didn't have to loop here! 15708ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor for (RecordDecl::field_iterator Field = RD->field_begin(), 15718ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor FieldEnd = RD->field_end(); 15728ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor Field != FieldEnd; (void)++Field, ++i) { 15738ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (*Field == MemberDecl) 15748ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 15758ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 1576cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor assert(i < RL.getFieldCount() && "offsetof field in wrong type"); 1577fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Result += Info.Ctx.toCharUnitsFromBits(RL.getFieldOffset(i)); 15788ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor CurrentType = MemberDecl->getType().getNonReferenceType(); 15798ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor break; 15808ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 15818ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 15828ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor case OffsetOfExpr::OffsetOfNode::Identifier: 15838ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor llvm_unreachable("dependent __builtin_offsetof"); 1584cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 1585cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 1586cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor case OffsetOfExpr::OffsetOfNode::Base: { 1587cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor CXXBaseSpecifier *BaseSpec = ON.getBase(); 1588cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor if (BaseSpec->isVirtual()) 1589cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 1590cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 1591cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor // Find the layout of the class whose base we are looking into. 1592cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor const RecordType *RT = CurrentType->getAs<RecordType>(); 1593cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor if (!RT) 1594cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 1595cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor RecordDecl *RD = RT->getDecl(); 1596cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD); 1597cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 1598cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor // Find the base class itself. 1599cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor CurrentType = BaseSpec->getType(); 1600cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor const RecordType *BaseRT = CurrentType->getAs<RecordType>(); 1601cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor if (!BaseRT) 1602cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor return false; 1603cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor 1604cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor // Add the offset to the base. 1605fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck Result += Info.Ctx.toCharUnitsFromBits( 1606fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck RL.getBaseClassOffsetInBits( 1607fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck cast<CXXRecordDecl>(BaseRT->getDecl()))); 1608cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor break; 1609cc8a5d5f90bbbbcb46f342117b851b7e07ec34f1Douglas Gregor } 16108ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 16118ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 16128ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor return Success(Result.getQuantity(), E); 16138ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor} 16148ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 1615b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattnerbool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 16162de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == UO_LNot) { 1617a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman // LNot's operand isn't necessarily an integer, so we handle it specially. 1618a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman bool bres; 1619a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman if (!HandleConversionToBool(E->getSubExpr(), bres, Info)) 1620a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman return false; 1621131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(!bres, E); 1622a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman } 1623a6afa768aa7bd3102a2807aa720917e4a1771e4eEli Friedman 16244fff4819a913c65ae23cfd389bc47c61919e4e1fDaniel Dunbar // Only handle integral operations... 16252ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!E->getSubExpr()->getType()->isIntegralOrEnumerationType()) 16264fff4819a913c65ae23cfd389bc47c61919e4e1fDaniel Dunbar return false; 16274fff4819a913c65ae23cfd389bc47c61919e4e1fDaniel Dunbar 162887eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner // Get the operand value into 'Result'. 162987eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!Visit(E->getSubExpr())) 163075a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner return false; 1631a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson 163275a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner switch (E->getOpcode()) { 16334c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner default: 163475a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // Address, indirect, pre/post inc/dec, etc are not valid constant exprs. 163575a4881047deeb3a300ff9293dc6ba8570048bb5Chris Lattner // See C99 6.6p3. 16360e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getOperatorLoc(), diag::note_invalid_subexpr_in_ice, E); 16372de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Extension: 16384c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // FIXME: Should extension allow i-c-e extension expressions in its scope? 16394c4867e140327fa3b56306fa03c64c8e6a7c95efChris Lattner // If so, we could clear the diagnostic ID. 16403f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar return true; 16412de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Plus: 16421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // The result is always just the subexpr. 16433f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar return true; 16442de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Minus: 164530c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar if (!Result.isInt()) return false; 164630c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return Success(-Result.getInt(), E); 16472de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Not: 164830c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar if (!Result.isInt()) return false; 164930c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar return Success(~Result.getInt(), E); 165006a3675627e3b3c47b49c689c8e404a33144194aAnders Carlsson } 1651a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 16521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1653732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// HandleCast - This is used to evaluate implicit or explicit casts where the 1654732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner/// result type is integer. 1655a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbarbool IntExprEvaluator::VisitCastExpr(CastExpr *E) { 165682206e267ce6cc709797127616f64672d255b310Anders Carlsson Expr *SubExpr = E->getSubExpr(); 165782206e267ce6cc709797127616f64672d255b310Anders Carlsson QualType DestType = E->getType(); 1658b92dac8bc2f6f73919825f9af693a8a7e89ae1d4Daniel Dunbar QualType SrcType = SubExpr->getType(); 165982206e267ce6cc709797127616f64672d255b310Anders Carlsson 16604efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (DestType->isBooleanType()) { 16614efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool BoolResult; 16624efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!HandleConversionToBool(SubExpr, BoolResult, Info)) 16634efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 1664131eb438d8c216b2e2a4f8fa8158ea88b787dc14Daniel Dunbar return Success(BoolResult, E); 16654efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 16664efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1667a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson // Handle simple integer->integer casts. 16682ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (SrcType->isIntegralOrEnumerationType()) { 1669732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner if (!Visit(SubExpr)) 1670b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 1671a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar 1672be26570e3faa009bdcefedfaf04473e518940520Eli Friedman if (!Result.isInt()) { 1673be26570e3faa009bdcefedfaf04473e518940520Eli Friedman // Only allow casts of lvalues if they are lossless. 1674be26570e3faa009bdcefedfaf04473e518940520Eli Friedman return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType); 1675be26570e3faa009bdcefedfaf04473e518940520Eli Friedman } 167630c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar 1677dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return Success(HandleIntToIntCast(DestType, SrcType, 167830c37f4d2ee5811e85f692c22fb67d74ddc88079Daniel Dunbar Result.getInt(), Info.Ctx), E); 1679732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner } 16801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1681732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner // FIXME: Clean this up! 1682b92dac8bc2f6f73919825f9af693a8a7e89ae1d4Daniel Dunbar if (SrcType->isPointerType()) { 1683efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 168487eae5ecf94e38baa20d9a327b8f73f8bdc72436Chris Lattner if (!EvaluatePointer(SubExpr, LV, Info)) 1685b542afe02d317411d53b3541946f9f2a8f509a11Chris Lattner return false; 16864efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1687dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar if (LV.getLValueBase()) { 1688dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar // Only allow based lvalue casts if they are lossless. 1689dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType)) 1690dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return false; 1691dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar 1692efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LV.moveInto(Result); 1693dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return true; 1694dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar } 16954efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1696a73058324197b7bdfd19307965954f626e26199dKen Dyck APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(), 1697a73058324197b7bdfd19307965954f626e26199dKen Dyck SrcType); 1698dd2116462ae311043986ae8b7fba27e68c1b2e66Daniel Dunbar return Success(HandleIntToIntCast(DestType, SrcType, AsInt, Info.Ctx), E); 16992bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson } 17004efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 1701be26570e3faa009bdcefedfaf04473e518940520Eli Friedman if (SrcType->isArrayType() || SrcType->isFunctionType()) { 1702be26570e3faa009bdcefedfaf04473e518940520Eli Friedman // This handles double-conversion cases, where there's both 1703be26570e3faa009bdcefedfaf04473e518940520Eli Friedman // an l-value promotion and an implicit conversion to int. 1704efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 1705be26570e3faa009bdcefedfaf04473e518940520Eli Friedman if (!EvaluateLValue(SubExpr, LV, Info)) 1706be26570e3faa009bdcefedfaf04473e518940520Eli Friedman return false; 1707be26570e3faa009bdcefedfaf04473e518940520Eli Friedman 1708be26570e3faa009bdcefedfaf04473e518940520Eli Friedman if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(Info.Ctx.VoidPtrTy)) 1709be26570e3faa009bdcefedfaf04473e518940520Eli Friedman return false; 1710be26570e3faa009bdcefedfaf04473e518940520Eli Friedman 1711efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LV.moveInto(Result); 1712be26570e3faa009bdcefedfaf04473e518940520Eli Friedman return true; 1713be26570e3faa009bdcefedfaf04473e518940520Eli Friedman } 1714be26570e3faa009bdcefedfaf04473e518940520Eli Friedman 17151725f683432715e5afe34d476024bd6f16eac3fcEli Friedman if (SrcType->isAnyComplexType()) { 1716f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue C; 17171725f683432715e5afe34d476024bd6f16eac3fcEli Friedman if (!EvaluateComplex(SubExpr, C, Info)) 17181725f683432715e5afe34d476024bd6f16eac3fcEli Friedman return false; 17191725f683432715e5afe34d476024bd6f16eac3fcEli Friedman if (C.isComplexFloat()) 17201725f683432715e5afe34d476024bd6f16eac3fcEli Friedman return Success(HandleFloatToIntCast(DestType, SrcType, 17211725f683432715e5afe34d476024bd6f16eac3fcEli Friedman C.getComplexFloatReal(), Info.Ctx), 17221725f683432715e5afe34d476024bd6f16eac3fcEli Friedman E); 17231725f683432715e5afe34d476024bd6f16eac3fcEli Friedman else 17241725f683432715e5afe34d476024bd6f16eac3fcEli Friedman return Success(HandleIntToIntCast(DestType, SrcType, 17251725f683432715e5afe34d476024bd6f16eac3fcEli Friedman C.getComplexIntReal(), Info.Ctx), E); 17261725f683432715e5afe34d476024bd6f16eac3fcEli Friedman } 17272217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman // FIXME: Handle vectors 17282217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman 1729b92dac8bc2f6f73919825f9af693a8a7e89ae1d4Daniel Dunbar if (!SrcType->isRealFloatingType()) 17300e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); 1731732b2236ae4a4f11e7642677cebbd169c07ea877Chris Lattner 1732d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat F(0.0); 1733d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(SubExpr, F, Info)) 17340e8acbbba71ec6acd5dceb4fcbce63e463e1b755Anders Carlsson return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); 17351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1736b92dac8bc2f6f73919825f9af693a8a7e89ae1d4Daniel Dunbar return Success(HandleFloatToIntCast(DestType, SrcType, F, Info.Ctx), E); 1737a25ae3d68d84d2b89907f998df6a396549589da5Anders Carlsson} 17382bad1687fe6f00e10767a691a33b070b151902b6Anders Carlsson 1739722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedmanbool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { 1740722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (E->getSubExpr()->getType()->isAnyComplexType()) { 1741f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LV; 1742722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt()) 1743722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); 1744722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Success(LV.getComplexIntReal(), E); 1745722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman } 1746722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman 1747722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Visit(E->getSubExpr()); 1748722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman} 1749722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman 1750664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedmanbool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { 1751722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (E->getSubExpr()->getType()->isComplexIntegerType()) { 1752f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LV; 1753722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt()) 1754722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E); 1755722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman return Success(LV.getComplexIntImag(), E); 1756722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman } 1757722c717cd833e410ca6e7976d78baea16995e0c4Eli Friedman 1758664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman if (!E->getSubExpr()->isEvaluatable(Info.Ctx)) 1759664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman Info.EvalResult.HasSideEffects = true; 1760664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman return Success(0, E); 1761664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman} 1762664a104ba0b8f47b8908ec6af694d9646adba1fcEli Friedman 1763ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregorbool IntExprEvaluator::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { 1764ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor return Success(E->getPackLength(), E); 1765ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor} 1766ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor 1767295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redlbool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { 1768295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl return Success(E->getValue(), E); 1769295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl} 1770295995c9c3196416372c9cd35d9cedb6da37bd3dSebastian Redl 1771f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 1772d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman// Float Evaluation 1773d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 1774d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 1775d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmannamespace { 1776770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass FloatExprEvaluator 1777d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman : public StmtVisitor<FloatExprEvaluator, bool> { 1778d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman EvalInfo &Info; 1779d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman APFloat &Result; 1780d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanpublic: 1781d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman FloatExprEvaluator(EvalInfo &info, APFloat &result) 1782d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman : Info(info), Result(result) {} 1783d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 1784d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitStmt(Stmt *S) { 1785d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 1786d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 1787d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 1788d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 1789019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner bool VisitCallExpr(const CallExpr *E); 1790d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 17915db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar bool VisitUnaryOperator(const UnaryOperator *E); 1792d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitBinaryOperator(const BinaryOperator *E); 1793d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman bool VisitFloatingLiteral(const FloatingLiteral *E); 17944efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman bool VisitCastExpr(CastExpr *E); 1795ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregor bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); 179667f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman bool VisitConditionalOperator(ConditionalOperator *E); 17972217c87bdc5ab357046a5453bdb06f469c41024eEli Friedman 1798ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman bool VisitChooseExpr(const ChooseExpr *E) 1799ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman { return Visit(E->getChosenSubExpr(Info.Ctx)); } 1800ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman bool VisitUnaryExtension(const UnaryOperator *E) 1801ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman { return Visit(E->getSubExpr()); } 1802abd3a857ace59100305790545d1baae5877b8945John McCall bool VisitUnaryReal(const UnaryOperator *E); 1803abd3a857ace59100305790545d1baae5877b8945John McCall bool VisitUnaryImag(const UnaryOperator *E); 1804ba98d6bb414861965a1f22628494ea046785ecd4Eli Friedman 1805189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall bool VisitDeclRefExpr(const DeclRefExpr *E); 1806189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1807abd3a857ace59100305790545d1baae5877b8945John McCall // FIXME: Missing: array subscript of vector, member of vector, 1808abd3a857ace59100305790545d1baae5877b8945John McCall // ImplicitValueInitExpr 1809d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman}; 1810d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} // end anonymous namespace 1811d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 1812d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanstatic bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) { 18137db7acbbb84b82d0522266a50ebabc3a52a9e5d1John McCall assert(E->getType()->isRealFloatingType()); 1814d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return FloatExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 1815d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 1816d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 18174ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadstatic bool TryEvaluateBuiltinNaN(const ASTContext &Context, 1818db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall QualType ResultTy, 1819db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall const Expr *Arg, 1820db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall bool SNaN, 1821db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall llvm::APFloat &Result) { 1822db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts()); 1823db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall if (!S) return false; 1824db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 1825db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy); 1826db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 1827db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall llvm::APInt fill; 1828db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 1829db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall // Treat empty strings as if they were zero. 1830db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall if (S->getString().empty()) 1831db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall fill = llvm::APInt(32, 0); 1832db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall else if (S->getString().getAsInteger(0, fill)) 1833db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return false; 1834db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 1835db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall if (SNaN) 1836db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall Result = llvm::APFloat::getSNaN(Sem, false, &fill); 1837db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall else 1838db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall Result = llvm::APFloat::getQNaN(Sem, false, &fill); 1839db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return true; 1840db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall} 1841db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 1842019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattnerbool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { 18433c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor switch (E->isBuiltinCall(Info.Ctx)) { 184434a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner default: return false; 1845019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_val: 1846019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_valf: 1847019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_huge_vall: 1848019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_inf: 1849019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner case Builtin::BI__builtin_inff: 18507cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar case Builtin::BI__builtin_infl: { 18517cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar const llvm::fltSemantics &Sem = 18527cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar Info.Ctx.getFloatTypeSemantics(E->getType()); 185334a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner Result = llvm::APFloat::getInf(Sem); 185434a74ab81600a40c6324fd76adb724b803dfaf91Chris Lattner return true; 18557cbed03c00e246682e5292785d01e1c120ce54bdDaniel Dunbar } 18561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1857db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall case Builtin::BI__builtin_nans: 1858db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall case Builtin::BI__builtin_nansf: 1859db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall case Builtin::BI__builtin_nansl: 1860db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0), 1861db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall true, Result); 1862db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall 18639e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nan: 18649e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nanf: 18659e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner case Builtin::BI__builtin_nanl: 18664572baba9d18c275968ac113fd73b0e3c77cccb8Mike Stump // If this is __builtin_nan() turn this into a nan, otherwise we 18679e62171a25e3a08fb5c49fb370f83faf5ae786f5Chris Lattner // can't constant fold it. 1868db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall return TryEvaluateBuiltinNaN(Info.Ctx, E->getType(), E->getArg(0), 1869db7b72a82a6834680ccf1eeb51dc57e6d935c655John McCall false, Result); 18705db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 18715db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabs: 18725db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabsf: 18735db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_fabsl: 18745db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getArg(0), Result, Info)) 18755db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 18761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18775db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (Result.isNegative()) 18785db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.changeSign(); 18795db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 18805db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 18811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_copysign: 18821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Builtin::BI__builtin_copysignf: 18835db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar case Builtin::BI__builtin_copysignl: { 18845db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar APFloat RHS(0.); 18855db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getArg(0), Result, Info) || 18865db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar !EvaluateFloat(E->getArg(1), RHS, Info)) 18875db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 18885db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.copySign(RHS); 18895db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 18905db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar } 1891019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner } 1892019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner} 1893019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 1894189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCallbool FloatExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { 1895189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall const Decl *D = E->getDecl(); 1896189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (!isa<VarDecl>(D) || isa<ParmVarDecl>(D)) return false; 1897189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall const VarDecl *VD = cast<VarDecl>(D); 1898189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1899189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall // Require the qualifiers to be const and not volatile. 1900189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall CanQualType T = Info.Ctx.getCanonicalType(E->getType()); 1901189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (!T.isConstQualified() || T.isVolatileQualified()) 1902189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall return false; 1903189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1904189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall const Expr *Init = VD->getAnyInitializer(); 1905189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (!Init) return false; 1906189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1907189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (APValue *V = VD->getEvaluatedValue()) { 1908189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (V->isFloat()) { 1909189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall Result = V->getFloat(); 1910189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall return true; 1911189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall } 1912189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall return false; 1913189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall } 1914189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1915189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (VD->isEvaluatingValue()) 1916189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall return false; 1917189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1918189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall VD->setEvaluatingValue(); 1919189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1920189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall Expr::EvalResult InitResult; 1921189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall if (Init->Evaluate(InitResult, Info.Ctx) && !InitResult.HasSideEffects && 1922189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall InitResult.Val.isFloat()) { 1923189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall // Cache the evaluated value in the variable declaration. 1924189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall Result = InitResult.Val.getFloat(); 1925189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall VD->setEvaluatedValue(InitResult.Val); 1926189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall return true; 1927189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall } 1928189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1929189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall VD->setEvaluatedValue(APValue()); 1930189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall return false; 1931189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall} 1932189d6ef40eff11b83b2cda941d5ed89a5cef09b2John McCall 1933abd3a857ace59100305790545d1baae5877b8945John McCallbool FloatExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { 193443efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (E->getSubExpr()->getType()->isAnyComplexType()) { 193543efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman ComplexValue CV; 193643efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (!EvaluateComplex(E->getSubExpr(), CV, Info)) 193743efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return false; 193843efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Result = CV.FloatReal; 193943efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return true; 194043efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman } 194143efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman 194243efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return Visit(E->getSubExpr()); 1943abd3a857ace59100305790545d1baae5877b8945John McCall} 1944abd3a857ace59100305790545d1baae5877b8945John McCall 1945abd3a857ace59100305790545d1baae5877b8945John McCallbool FloatExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { 194643efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (E->getSubExpr()->getType()->isAnyComplexType()) { 194743efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman ComplexValue CV; 194843efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (!EvaluateComplex(E->getSubExpr(), CV, Info)) 194943efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return false; 195043efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Result = CV.FloatImag; 195143efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman return true; 195243efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman } 195343efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman 195443efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman if (!E->getSubExpr()->isEvaluatable(Info.Ctx)) 195543efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Info.EvalResult.HasSideEffects = true; 195643efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->getType()); 195743efa31fe601bb7c3f132f02246dc3c903d9f361Eli Friedman Result = llvm::APFloat::getZero(Sem); 1958abd3a857ace59100305790545d1baae5877b8945John McCall return true; 1959abd3a857ace59100305790545d1baae5877b8945John McCall} 1960abd3a857ace59100305790545d1baae5877b8945John McCall 19615db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbarbool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 19622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == UO_Deref) 1963a468d34bed16861f25aff6c8354f4e75d3358c1aNuno Lopes return false; 1964a468d34bed16861f25aff6c8354f4e75d3358c1aNuno Lopes 19655db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar if (!EvaluateFloat(E->getSubExpr(), Result, Info)) 19665db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return false; 19675db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar 19685db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar switch (E->getOpcode()) { 19695db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar default: return false; 19702de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Plus: 19715db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 19722de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Minus: 19735db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar Result.changeSign(); 19745db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar return true; 19755db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar } 19765db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar} 1977019f4e858e78587f2241ff1a76c747d7bcd7578cChris Lattner 1978d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 19792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (E->getOpcode() == BO_Comma) { 19807f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman if (!EvaluateFloat(E->getRHS(), Result, Info)) 19817f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman return false; 19827f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman 19837f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman // If we can't evaluate the LHS, it might have side effects; 19847f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman // conservatively mark it. 19857f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman if (!E->getLHS()->isEvaluatable(Info.Ctx)) 19867f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman Info.EvalResult.HasSideEffects = true; 19877f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman 19887f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman return true; 19897f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman } 19907f92f0362ef2cf218bc19bb83e1a97dd254b5527Eli Friedman 199196e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson // We can't evaluate pointer-to-member operations. 199296e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson if (E->isPtrMemOp()) 199396e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson return false; 199496e93660124c8028a4c3bcc038ab0cdd18cd7ab2Anders Carlsson 1995d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // FIXME: Diagnostics? I really don't understand how the warnings 1996d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman // and errors are supposed to work. 19975db4b3f3ed9f769d5b02c1d1ccc52bfd71fb9afbDaniel Dunbar APFloat RHS(0.0); 1998d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getLHS(), Result, Info)) 1999d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 2000d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman if (!EvaluateFloat(E->getRHS(), RHS, Info)) 2001d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return false; 2002d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2003d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman switch (E->getOpcode()) { 2004d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman default: return false; 20052de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: 2006d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.multiply(RHS, APFloat::rmNearestTiesToEven); 2007d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 20082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: 2009d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.add(RHS, APFloat::rmNearestTiesToEven); 2010d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 20112de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: 2012d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.subtract(RHS, APFloat::rmNearestTiesToEven); 2013d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 20142de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Div: 2015d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result.divide(RHS, APFloat::rmNearestTiesToEven); 2016d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 2017d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman } 2018d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 2019d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 2020d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedmanbool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { 2021d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman Result = E->getValue(); 2022d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman return true; 2023d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman} 2024d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman 20254efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedmanbool FloatExprEvaluator::VisitCastExpr(CastExpr *E) { 20264efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Expr* SubExpr = E->getSubExpr(); 20271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20282ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (SubExpr->getType()->isIntegralOrEnumerationType()) { 20294efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman APSInt IntResult; 20303f7d995390009fede92b333a040da80e1ce90997Daniel Dunbar if (!EvaluateInteger(SubExpr, IntResult, Info)) 20314efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 20321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(), 2033a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar IntResult, Info.Ctx); 20344efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 20354efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 20364efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (SubExpr->getType()->isRealFloatingType()) { 20374efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman if (!Visit(SubExpr)) 20384efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 2039a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(), 2040a2cfd34952204c9a160fe1a5da5ba2f231df891dDaniel Dunbar Result, Info.Ctx); 20414efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 20424efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman } 2043f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall 2044f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall if (E->getCastKind() == CK_FloatingComplexToReal) { 2045f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall ComplexValue V; 2046f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall if (!EvaluateComplex(SubExpr, V, Info)) 2047f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall return false; 2048f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall Result = V.getComplexFloatReal(); 2049f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall return true; 2050f3ea8cfe6b1c2ef0702efe130561e9e66708d799John McCall } 20514efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 20524efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return false; 20534efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 20544efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 2055ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregorbool FloatExprEvaluator::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 20564efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType())); 20574efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman return true; 20584efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman} 20594efaa276bc0ce8f7baf6138ead11915f3e3e58d9Eli Friedman 206067f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedmanbool FloatExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { 206167f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman bool Cond; 206267f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman if (!HandleConversionToBool(E->getCond(), Cond, Info)) 206367f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman return false; 206467f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman 206567f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr()); 206667f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman} 206767f85fcdab64f36233a7211f963ed1cccffcbfb8Eli Friedman 2068d8bfe7f25a695ca947effbccdf9ecbe3e018e221Eli Friedman//===----------------------------------------------------------------------===// 2069a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar// Complex Evaluation (for float and integer) 20709ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson//===----------------------------------------------------------------------===// 20719ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 20729ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlssonnamespace { 2073770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramerclass ComplexExprEvaluator 2074f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall : public StmtVisitor<ComplexExprEvaluator, bool> { 20759ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson EvalInfo &Info; 2076f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue &Result; 20771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20789ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlssonpublic: 2079f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result) 2080f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall : Info(info), Result(Result) {} 20811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20829ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson //===--------------------------------------------------------------------===// 20839ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson // Visitor Methods 20849ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson //===--------------------------------------------------------------------===// 20859ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 2086f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool VisitStmt(Stmt *S) { 2087f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return false; 20889ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson } 20891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2090f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); } 20919ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 2092b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman bool VisitImaginaryLiteral(ImaginaryLiteral *E); 2093a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar 2094b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman bool VisitCastExpr(CastExpr *E); 2095b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2096b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman bool VisitBinaryOperator(const BinaryOperator *E); 209796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara bool VisitUnaryOperator(const UnaryOperator *E); 209896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara bool VisitConditionalOperator(const ConditionalOperator *E); 2099b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman bool VisitChooseExpr(const ChooseExpr *E) 2100b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman { return Visit(E->getChosenSubExpr(Info.Ctx)); } 2101b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman bool VisitUnaryExtension(const UnaryOperator *E) 2102b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman { return Visit(E->getSubExpr()); } 210396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // FIXME Missing: ImplicitValueInitExpr 2104b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman}; 2105b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman} // end anonymous namespace 21061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2107b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedmanstatic bool EvaluateComplex(const Expr *E, ComplexValue &Result, 2108b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman EvalInfo &Info) { 2109b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman assert(E->getType()->isAnyComplexType()); 2110b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return ComplexExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E)); 2111b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman} 2112b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2113b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedmanbool ComplexExprEvaluator::VisitImaginaryLiteral(ImaginaryLiteral *E) { 2114b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Expr* SubExpr = E->getSubExpr(); 2115b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2116b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman if (SubExpr->getType()->isRealFloatingType()) { 2117b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.makeComplexFloat(); 2118b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APFloat &Imag = Result.FloatImag; 2119b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman if (!EvaluateFloat(SubExpr, Imag, Info)) 2120b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2121b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2122b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.FloatReal = APFloat(Imag.getSemantics()); 2123b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return true; 2124b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman } else { 2125b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman assert(SubExpr->getType()->isIntegerType() && 2126b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman "Unexpected imaginary literal."); 2127b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2128b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.makeComplexInt(); 2129b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APSInt &Imag = Result.IntImag; 2130b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman if (!EvaluateInteger(SubExpr, Imag, Info)) 2131b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2132b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2133b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned()); 2134b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return true; 2135b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman } 2136b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman} 2137b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 2138b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedmanbool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) { 2139b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 21408786da77984e81d48e0e1b2bd339809b1efc19f3John McCall switch (E->getCastKind()) { 21418786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_BitCast: 21428786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_LValueBitCast: 21438786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_BaseToDerived: 21448786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_DerivedToBase: 21458786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_UncheckedDerivedToBase: 21468786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_Dynamic: 21478786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ToUnion: 21488786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ArrayToPointerDecay: 21498786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FunctionToPointerDecay: 21508786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_NullToPointer: 21518786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_NullToMemberPointer: 21528786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_BaseToDerivedMemberPointer: 21538786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_DerivedToBaseMemberPointer: 21548786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_MemberPointerToBoolean: 21558786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ConstructorConversion: 21568786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralToPointer: 21578786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_PointerToIntegral: 21588786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_PointerToBoolean: 21598786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ToVoid: 21608786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_VectorSplat: 21618786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralCast: 21628786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralToBoolean: 21638786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralToFloating: 21648786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingToIntegral: 21658786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingToBoolean: 21668786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingCast: 21678786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_AnyPointerToObjCPointerCast: 21688786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_AnyPointerToBlockPointerCast: 21698786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_ObjCObjectLValueCast: 21708786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexToReal: 21718786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexToBoolean: 21728786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexToReal: 21738786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexToBoolean: 21748786da77984e81d48e0e1b2bd339809b1efc19f3John McCall llvm_unreachable("invalid cast kind for complex value"); 21758786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 21768786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_LValueToRValue: 21778786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_NoOp: 21788786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return Visit(E->getSubExpr()); 21792bb5d00fcf71a7b4d478d478be778fff0494aff6John McCall 21808786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_Dependent: 21818786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_GetObjCProperty: 21828786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_UserDefinedConversion: 21838786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 21848786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 21858786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingRealToComplex: { 2186b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APFloat &Real = Result.FloatReal; 21878786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!EvaluateFloat(E->getSubExpr(), Real, Info)) 2188b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2189b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman 21908786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexFloat(); 21918786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatImag = APFloat(Real.getSemantics()); 21928786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 21938786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 21948786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 21958786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexCast: { 21968786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 21978786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 21988786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 21998786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 22008786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 22018786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 22028786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22038786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatReal 22048786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = HandleFloatToFloatCast(To, From, Result.FloatReal, Info.Ctx); 22058786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatImag 22068786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = HandleFloatToFloatCast(To, From, Result.FloatImag, Info.Ctx); 22078786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 22088786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 22098786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22108786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_FloatingComplexToIntegralComplex: { 22118786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 22128786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 22138786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22148786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 22158786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 22168786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 22178786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexInt(); 22188786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntReal = HandleFloatToIntCast(To, From, Result.FloatReal, Info.Ctx); 22198786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntImag = HandleFloatToIntCast(To, From, Result.FloatImag, Info.Ctx); 22208786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 22218786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 22228786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22238786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralRealToComplex: { 2224b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman APSInt &Real = Result.IntReal; 22258786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!EvaluateInteger(E->getSubExpr(), Real, Info)) 2226b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 22279ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 22288786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexInt(); 22298786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned()); 22308786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 22318786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 22328786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22338786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexCast: { 22348786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 2235b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 2236ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson 22378786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 22388786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 22398786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 22401725f683432715e5afe34d476024bd6f16eac3fcEli Friedman 22418786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntReal = HandleIntToIntCast(To, From, Result.IntReal, Info.Ctx); 22428786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.IntImag = HandleIntToIntCast(To, From, Result.IntImag, Info.Ctx); 22438786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 22448786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 22458786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22468786da77984e81d48e0e1b2bd339809b1efc19f3John McCall case CK_IntegralComplexToFloatingComplex: { 22478786da77984e81d48e0e1b2bd339809b1efc19f3John McCall if (!Visit(E->getSubExpr())) 22488786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return false; 22498786da77984e81d48e0e1b2bd339809b1efc19f3John McCall 22508786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType To = E->getType()->getAs<ComplexType>()->getElementType(); 22518786da77984e81d48e0e1b2bd339809b1efc19f3John McCall QualType From 22528786da77984e81d48e0e1b2bd339809b1efc19f3John McCall = E->getSubExpr()->getType()->getAs<ComplexType>()->getElementType(); 22538786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.makeComplexFloat(); 22548786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatReal = HandleIntToFloatCast(To, From, Result.IntReal, Info.Ctx); 22558786da77984e81d48e0e1b2bd339809b1efc19f3John McCall Result.FloatImag = HandleIntToFloatCast(To, From, Result.IntImag, Info.Ctx); 22568786da77984e81d48e0e1b2bd339809b1efc19f3John McCall return true; 22578786da77984e81d48e0e1b2bd339809b1efc19f3John McCall } 2258ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson } 22591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 22608786da77984e81d48e0e1b2bd339809b1efc19f3John McCall llvm_unreachable("unknown cast resulting in complex value"); 2261b2dc7f59fe4c762cba73badc3bbc6f356fcd7b5bEli Friedman return false; 22629ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson} 22639ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson 2264f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCallbool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { 226596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (E->getOpcode() == BO_Comma) { 226696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (!Visit(E->getRHS())) 226796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 226896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 226996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // If we can't evaluate the LHS, it might have side effects; 227096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // conservatively mark it. 227196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (!E->getLHS()->isEvaluatable(Info.Ctx)) 227296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Info.EvalResult.HasSideEffects = true; 227396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 227496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 227596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 2276f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall if (!Visit(E->getLHS())) 2277f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return false; 22781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2279f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue RHS; 2280a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar if (!EvaluateComplex(E->getRHS(), RHS, Info)) 2281f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return false; 2282a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar 22833f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar assert(Result.isComplexFloat() == RHS.isComplexFloat() && 22843f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar "Invalid operands to binary operator."); 2285ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson switch (E->getOpcode()) { 2286f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall default: return false; 22872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: 2288a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar if (Result.isComplexFloat()) { 2289a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatReal().add(RHS.getComplexFloatReal(), 2290a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2291a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatImag().add(RHS.getComplexFloatImag(), 2292a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2293a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } else { 2294a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntReal() += RHS.getComplexIntReal(); 2295a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntImag() += RHS.getComplexIntImag(); 2296a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } 22973f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar break; 22982de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: 2299a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar if (Result.isComplexFloat()) { 2300a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(), 2301a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2302a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(), 2303a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar APFloat::rmNearestTiesToEven); 2304a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } else { 2305a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntReal() -= RHS.getComplexIntReal(); 2306a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar Result.getComplexIntImag() -= RHS.getComplexIntImag(); 2307a5fd07bbc5e4bae542c06643da3fbfe4967a9379Daniel Dunbar } 23083f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar break; 23092de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: 23103f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar if (Result.isComplexFloat()) { 2311f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LHS = Result; 23123f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &LHS_r = LHS.getComplexFloatReal(); 23133f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &LHS_i = LHS.getComplexFloatImag(); 23143f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &RHS_r = RHS.getComplexFloatReal(); 23153f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat &RHS_i = RHS.getComplexFloatImag(); 23161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 23173f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar APFloat Tmp = LHS_r; 23183f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven); 23193f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatReal() = Tmp; 23203f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp = LHS_i; 23213f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 23223f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven); 23233f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar 23243f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp = LHS_r; 23253f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 23263f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatImag() = Tmp; 23273f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp = LHS_i; 23283f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven); 23293f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven); 23303f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar } else { 2331f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall ComplexValue LHS = Result; 23321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result.getComplexIntReal() = 23333f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar (LHS.getComplexIntReal() * RHS.getComplexIntReal() - 23343f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar LHS.getComplexIntImag() * RHS.getComplexIntImag()); 23351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Result.getComplexIntImag() = 23363f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar (LHS.getComplexIntReal() * RHS.getComplexIntImag() + 23373f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar LHS.getComplexIntImag() * RHS.getComplexIntReal()); 23383f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar } 23393f2798757c9ee353e207e18115e2e966432a4beeDaniel Dunbar break; 234096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case BO_Div: 234196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (Result.isComplexFloat()) { 234296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara ComplexValue LHS = Result; 234396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &LHS_r = LHS.getComplexFloatReal(); 234496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &LHS_i = LHS.getComplexFloatImag(); 234596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &RHS_r = RHS.getComplexFloatReal(); 234696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &RHS_i = RHS.getComplexFloatImag(); 234796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &Res_r = Result.getComplexFloatReal(); 234896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat &Res_i = Result.getComplexFloatImag(); 234996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 235096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat Den = RHS_r; 235196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Den.multiply(RHS_r, APFloat::rmNearestTiesToEven); 235296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APFloat Tmp = RHS_i; 235396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 235496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Den.add(Tmp, APFloat::rmNearestTiesToEven); 235596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 235696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r = LHS_r; 235796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r.multiply(RHS_r, APFloat::rmNearestTiesToEven); 235896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp = LHS_i; 235996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 236096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r.add(Tmp, APFloat::rmNearestTiesToEven); 236196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_r.divide(Den, APFloat::rmNearestTiesToEven); 236296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 236396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i = LHS_i; 236496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i.multiply(RHS_r, APFloat::rmNearestTiesToEven); 236596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp = LHS_r; 236696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); 236796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i.subtract(Tmp, APFloat::rmNearestTiesToEven); 236896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Res_i.divide(Den, APFloat::rmNearestTiesToEven); 236996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } else { 237096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0) { 237196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // FIXME: what about diagnostics? 237296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 237396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 237496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara ComplexValue LHS = Result; 237596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() + 237696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara RHS.getComplexIntImag() * RHS.getComplexIntImag(); 237796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntReal() = 237896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara (LHS.getComplexIntReal() * RHS.getComplexIntReal() + 237996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den; 238096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntImag() = 238196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara (LHS.getComplexIntImag() * RHS.getComplexIntReal() - 238296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den; 238396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 238496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara break; 2385ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson } 2386ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson 2387f4cf1a18d09d57b757b3cb47eab36c1457091ef7John McCall return true; 2388ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson} 2389ccc3fce5697e33f005990f9795e1c7cb8b4559ecAnders Carlsson 239096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnarabool ComplexExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { 239196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // Get the operand value into 'Result'. 239296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (!Visit(E->getSubExpr())) 239396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 239496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 239596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara switch (E->getOpcode()) { 239696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara default: 239796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // FIXME: what about diagnostics? 239896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 239996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Extension: 240096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 240196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Plus: 240296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara // The result is always just the subexpr. 240396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 240496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Minus: 240596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (Result.isComplexFloat()) { 240696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexFloatReal().changeSign(); 240796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexFloatImag().changeSign(); 240896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 240996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara else { 241096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntReal() = -Result.getComplexIntReal(); 241196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntImag() = -Result.getComplexIntImag(); 241296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 241396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 241496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara case UO_Not: 241596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (Result.isComplexFloat()) 241696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexFloatImag().changeSign(); 241796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara else 241896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara Result.getComplexIntImag() = -Result.getComplexIntImag(); 241996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return true; 242096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara } 242196fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara} 242296fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 242396fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnarabool ComplexExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { 242496fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara bool Cond; 242596fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara if (!HandleConversionToBool(E->getCond(), Cond, Info)) 242696fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return false; 242796fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 242896fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr()); 242996fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara} 243096fc8e4086df323c49f17cac594db1d2f066a2e9Abramo Bagnara 24319ad16aebc0e840a5e7d425da72eb6cbe25e4b58cAnders Carlsson//===----------------------------------------------------------------------===// 24326ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner// Top level Expr::Evaluate method. 2433f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner//===----------------------------------------------------------------------===// 2434f5eeb055ecbadbc25c83df0867cdada2c2559dcfChris Lattner 243542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// Evaluate - Return true if this is a constant which we can fold using 243642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// any crazy technique (that has nothing to do with language standards) that 243742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// we want to. If this function returns true, it returns the folded constant 243842c8f87eb60958170c46767273bf93e6c96125bfJohn McCall/// in Result. 24394ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::Evaluate(EvalResult &Result, const ASTContext &Ctx) const { 244042c8f87eb60958170c46767273bf93e6c96125bfJohn McCall const Expr *E = this; 244142c8f87eb60958170c46767273bf93e6c96125bfJohn McCall EvalInfo Info(Ctx, Result); 2442efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (E->getType()->isVectorType()) { 2443efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateVector(E, Info.EvalResult.Val, Info)) 244459b5da6d853b4368b984700315adf7b37de05764Nate Begeman return false; 2445efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->isIntegerType()) { 2446efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!IntExprEvaluator(Info, Info.EvalResult.Val).Visit(const_cast<Expr*>(E))) 24476dde0d5dc09f45f4d9508c964703e36fef1a0198Anders Carlsson return false; 24480f2b692bb10be35fdc60d0a72a847bdd73124670John McCall if (Result.Val.isLValue() && !IsGlobalLValue(Result.Val.getLValueBase())) 24490f2b692bb10be35fdc60d0a72a847bdd73124670John McCall return false; 2450efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->hasPointerRepresentation()) { 2451efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 2452efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluatePointer(E, LV, Info)) 24536dde0d5dc09f45f4d9508c964703e36fef1a0198Anders Carlsson return false; 2454e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara if (!IsGlobalLValue(LV.Base)) 245542c8f87eb60958170c46767273bf93e6c96125bfJohn McCall return false; 2456efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LV.moveInto(Info.EvalResult.Val); 2457efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->isRealFloatingType()) { 2458efdb83e26f9a1fd2566afe54461216cd84814d42John McCall llvm::APFloat F(0.0); 2459efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateFloat(E, F, Info)) 24606dde0d5dc09f45f4d9508c964703e36fef1a0198Anders Carlsson return false; 24611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2462efdb83e26f9a1fd2566afe54461216cd84814d42John McCall Info.EvalResult.Val = APValue(F); 2463efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } else if (E->getType()->isAnyComplexType()) { 2464efdb83e26f9a1fd2566afe54461216cd84814d42John McCall ComplexValue C; 2465efdb83e26f9a1fd2566afe54461216cd84814d42John McCall if (!EvaluateComplex(E, C, Info)) 2466660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump return false; 2467efdb83e26f9a1fd2566afe54461216cd84814d42John McCall C.moveInto(Info.EvalResult.Val); 2468660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump } else 2469660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump return false; 2470660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump 2471660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump return true; 2472660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump} 2473660e6f79a138a30a437c02142f23e7ef4eb21b2eMike Stump 24744ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::EvaluateAsBooleanCondition(bool &Result, 24754ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Ctx) const { 2476cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall EvalResult Scratch; 2477cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall EvalInfo Info(Ctx, Scratch); 2478cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall 2479cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall return HandleConversionToBool(this, Result, Info); 2480cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall} 2481cd7a445c6b46c5585580dfb652300c8483c0cb6bJohn McCall 24824ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const { 24831b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlsson EvalInfo Info(Ctx, Result); 24841b78276a75a5a0f496a82429c1ff9604d622a76dAnders Carlsson 2485efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LValue LV; 248642c8f87eb60958170c46767273bf93e6c96125bfJohn McCall if (EvaluateLValue(this, LV, Info) && 248742c8f87eb60958170c46767273bf93e6c96125bfJohn McCall !Result.HasSideEffects && 2488e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara IsGlobalLValue(LV.Base)) { 2489e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara LV.moveInto(Result.Val); 2490e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara return true; 2491e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara } 2492e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara return false; 2493e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara} 2494e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 24954ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::EvaluateAsAnyLValue(EvalResult &Result, 24964ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Ctx) const { 2497e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara EvalInfo Info(Ctx, Result); 2498e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 2499e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara LValue LV; 2500e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara if (EvaluateLValue(this, LV, Info)) { 2501efdb83e26f9a1fd2566afe54461216cd84814d42John McCall LV.moveInto(Result.Val); 2502efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return true; 2503efdb83e26f9a1fd2566afe54461216cd84814d42John McCall } 2504efdb83e26f9a1fd2566afe54461216cd84814d42John McCall return false; 2505b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman} 2506b2f295c8050fb8c141bf2cf38eed0a56e99d0092Eli Friedman 25076ee7aa154e8bbb21a21254293410b944f78b0bfeChris Lattner/// isEvaluatable - Call Evaluate to see if this expression can be constant 250845b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner/// folded, but discard the result. 25094ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::isEvaluatable(const ASTContext &Ctx) const { 25104fdfb0965b396f2778091f7e6c051d17ff9791baAnders Carlsson EvalResult Result; 25114fdfb0965b396f2778091f7e6c051d17ff9791baAnders Carlsson return Evaluate(Result, Ctx) && !Result.HasSideEffects; 251245b6b9d080ac56917337d73d8f1cd6374b27b05dChris Lattner} 251351fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson 25144ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadbool Expr::HasSideEffects(const ASTContext &Ctx) const { 2515393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian Expr::EvalResult Result; 2516393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian EvalInfo Info(Ctx, Result); 2517393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian return HasSideEffect(Info).Visit(const_cast<Expr*>(this)); 2518393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian} 2519393c247fe025ccb5f914e37e948192ea86faef8cFariborz Jahanian 25204ba2a17694148e16eaa8d3917f657ffcd3667be4Jay FoadAPSInt Expr::EvaluateAsInt(const ASTContext &Ctx) const { 25211c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson EvalResult EvalResult; 25221c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson bool Result = Evaluate(EvalResult, Ctx); 2523c6ed729f669044f5072a49d79041f455d971ece3Jeffrey Yasskin (void)Result; 252451fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson assert(Result && "Could not evaluate expression"); 25251c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson assert(EvalResult.Val.isInt() && "Expression did not evaluate to integer"); 252651fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson 25271c0cfd4599e816cfd7a8f348286bf0ad79652ffcAnders Carlsson return EvalResult.Val.getInt(); 252851fe996231b1d7199f76e4005ff4c943d5deeecdAnders Carlsson} 2529d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2530e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara bool Expr::EvalResult::isGlobalLValue() const { 2531e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara assert(Val.isLValue()); 2532e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara return IsGlobalLValue(Val.getLValueBase()); 2533e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara } 2534e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 2535e17a6436b429e4b18a5e157061fb13bbc677b3b0Abramo Bagnara 2536d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// isIntegerConstantExpr - this recursive routine will test if an expression is 2537d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// an integer constant expression. 2538d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2539d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// FIXME: Pass up a reason why! Invalid operation in i-c-e, division by zero, 2540d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// comma, etc 2541d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// 2542d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// FIXME: Handle offsetof. Two things to do: Handle GCC's __builtin_offsetof 2543d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// to support gcc 4.0+ and handle the idiom GCC recognizes with a null pointer 2544d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall/// cast+dereference. 2545d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2546d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// CheckICE - This function does the fundamental ICE checking: the returned 2547d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// ICEDiag contains a Val of 0, 1, or 2, and a possibly null SourceLocation. 2548d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// Note that to reduce code duplication, this helper does no evaluation 2549d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// itself; the caller checks whether the expression is evaluatable, and 2550d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// in the rare cases where CheckICE actually cares about the evaluated 2551d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// value, it calls into Evalute. 2552d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 2553d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// Meanings of Val: 2554d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 0: This expression is an ICE if it can be evaluated by Evaluate. 2555d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 1: This expression is not an ICE, but if it isn't evaluated, it's 2556d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// a legal subexpression for an ICE. This return value is used to handle 2557d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// the comma operator in C99 mode. 2558d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall// 2: This expression is not an ICE, and is not a legal subexpression for one. 2559d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 25603c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmannamespace { 25613c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 2562d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallstruct ICEDiag { 2563d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall unsigned Val; 2564d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall SourceLocation Loc; 2565d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2566d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall public: 2567d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag(unsigned v, SourceLocation l) : Val(v), Loc(l) {} 2568d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag() : Val(0) {} 2569d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall}; 2570d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 25713c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman} 25723c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohman 25733c46e8db99196179b30e7ac5c20c4efd5f3926d7Dan Gohmanstatic ICEDiag NoDiag() { return ICEDiag(); } 2574d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2575d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallstatic ICEDiag CheckEvalInICE(const Expr* E, ASTContext &Ctx) { 2576d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Expr::EvalResult EVResult; 2577d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects || 2578d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall !EVResult.Val.isInt()) { 2579d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2580d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2581d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2582d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall} 2583d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2584d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallstatic ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { 2585d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall assert(!E->isValueDependent() && "Should not see value dependent exprs!"); 25862ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (!E->getType()->isIntegralOrEnumerationType()) { 2587d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2588d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2589d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2590d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall switch (E->getStmtClass()) { 2591d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall#define STMT(Node, Base) case Expr::Node##Class: 2592d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall#define EXPR(Node, Base) 2593d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall#include "clang/AST/StmtNodes.inc" 2594d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::PredefinedExprClass: 2595d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::FloatingLiteralClass: 2596d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ImaginaryLiteralClass: 2597d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::StringLiteralClass: 2598d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ArraySubscriptExprClass: 2599d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::MemberExprClass: 2600d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CompoundAssignOperatorClass: 2601d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CompoundLiteralExprClass: 2602d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ExtVectorElementExprClass: 2603d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::InitListExprClass: 2604d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::DesignatedInitExprClass: 2605d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ImplicitValueInitExprClass: 2606d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ParenListExprClass: 2607d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::VAArgExprClass: 2608d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::AddrLabelExprClass: 2609d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::StmtExprClass: 2610d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXMemberCallExprClass: 2611d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDynamicCastExprClass: 2612d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXTypeidExprClass: 26139be88403e965cc49af76c9d33d818781d44b333eFrancois Pichet case Expr::CXXUuidofExprClass: 2614d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXNullPtrLiteralExprClass: 2615d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXThisExprClass: 2616d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXThrowExprClass: 2617d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXNewExprClass: 2618d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDeleteExprClass: 2619d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXPseudoDestructorExprClass: 2620d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnresolvedLookupExprClass: 2621d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::DependentScopeDeclRefExprClass: 2622d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXConstructExprClass: 2623d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXBindTemporaryExprClass: 26244765fa05b5652fcc4356371c2f481d0ea9a1b007John McCall case Expr::ExprWithCleanupsClass: 2625d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXTemporaryObjectExprClass: 2626d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXUnresolvedConstructExprClass: 2627d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDependentScopeMemberExprClass: 2628d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnresolvedMemberExprClass: 2629d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCStringLiteralClass: 2630d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCEncodeExprClass: 2631d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCMessageExprClass: 2632d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCSelectorExprClass: 2633d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCProtocolExprClass: 2634d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCIvarRefExprClass: 2635d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCPropertyRefExprClass: 2636d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ObjCIsaExprClass: 2637d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ShuffleVectorExprClass: 2638d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::BlockExprClass: 2639d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::BlockDeclRefExprClass: 2640d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::NoStmtClass: 26417cd7d1ad33fdf49eef83942e8855fe20d95aa1b9John McCall case Expr::OpaqueValueExprClass: 2642be230c36e32142cbdcdbe9c97511d097beeecbabDouglas Gregor case Expr::PackExpansionExprClass: 2643c7793c73ba8a343de3f2552d984851985a46f159Douglas Gregor case Expr::SubstNonTypeTemplateParmPackExprClass: 2644d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2645d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2646ee8aff06f6a96214731de17b2cb6df407c6c1820Douglas Gregor case Expr::SizeOfPackExprClass: 2647d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::GNUNullExprClass: 2648d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // GCC considers the GNU __null value to be an integral constant expression. 2649d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2650d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2651d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ParenExprClass: 2652d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx); 2653d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::IntegerLiteralClass: 2654d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CharacterLiteralClass: 2655d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXBoolLiteralExprClass: 2656ed8abf18329df67b0abcbb3a10458bd8c1d2a595Douglas Gregor case Expr::CXXScalarValueInitExprClass: 2657d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnaryTypeTraitExprClass: 26586ad6f2848d7652ab2991286eb48be440d3493b28Francois Pichet case Expr::BinaryTypeTraitExprClass: 26592e156225a29407a50dd19041aa5750171ad44ea3Sebastian Redl case Expr::CXXNoexceptExprClass: 2660d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2661d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CallExprClass: 26626cf750298d3621d8a10a6dd07fcee8e274b9d94dSean Hunt case Expr::CXXOperatorCallExprClass: { 2663d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const CallExpr *CE = cast<CallExpr>(E); 2664d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CE->isBuiltinCall(Ctx)) 2665d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckEvalInICE(E, Ctx); 2666d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2667d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2668d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::DeclRefExprClass: 2669d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl())) 2670d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2671d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Ctx.getLangOptions().CPlusPlus && 2672d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall E->getType().getCVRQualifiers() == Qualifiers::Const) { 2673d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl(); 2674d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2675d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Parameter variables are never constants. Without this check, 2676d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // getAnyInitializer() can find a default argument, which leads 2677d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // to chaos. 2678d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (isa<ParmVarDecl>(D)) 2679d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 2680d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2681d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // C++ 7.1.5.1p2 2682d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // A variable of non-volatile const-qualified integral or enumeration 2683d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // type initialized by an ICE can be used in ICEs. 2684d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) { 2685d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Qualifiers Quals = Ctx.getCanonicalType(Dcl->getType()).getQualifiers(); 2686d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Quals.hasVolatile() || !Quals.hasConst()) 2687d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 2688d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2689d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Look for a declaration of this variable that has an initializer. 2690d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const VarDecl *ID = 0; 2691d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const Expr *Init = Dcl->getAnyInitializer(ID); 2692d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Init) { 2693d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (ID->isInitKnownICE()) { 2694d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // We have already checked whether this subexpression is an 2695d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // integral constant expression. 2696d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (ID->isInitICE()) 2697d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2698d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall else 2699d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 2700d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2701d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2702d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // It's an ICE whether or not the definition we found is 2703d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // out-of-line. See DR 721 and the discussion in Clang PR 2704d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // 6206 for details. 2705d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2706d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Dcl->isCheckingICE()) { 2707d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation()); 2708d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2709d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2710d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Dcl->setCheckingICE(); 2711d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag Result = CheckICE(Init, Ctx); 2712d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Cache the result of the ICE test. 2713d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Dcl->setInitKnownICE(Result.Val == 0); 2714d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return Result; 2715d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2716d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2717d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2718d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2719d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::UnaryOperatorClass: { 2720d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const UnaryOperator *Exp = cast<UnaryOperator>(E); 2721d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall switch (Exp->getOpcode()) { 27222de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PostInc: 27232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PostDec: 27242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PreInc: 27252de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_PreDec: 27262de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_AddrOf: 27272de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Deref: 2728d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 27292de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Extension: 27302de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_LNot: 27312de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Plus: 27322de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Minus: 27332de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Not: 27342de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Real: 27352de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case UO_Imag: 2736d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(Exp->getSubExpr(), Ctx); 2737d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2738d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2739d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // OffsetOf falls through here. 2740d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2741d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::OffsetOfExprClass: { 2742d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Note that per C99, offsetof must be an ICE. And AFAIK, using 2743d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Evaluate matches the proposed gcc behavior for cases like 2744d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // "offsetof(struct s{int x[4];}, x[!.0])". This doesn't affect 2745d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // compliance: we should warn earlier for offsetof expressions with 2746d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // array subscripts that aren't ICEs, and if the array subscripts 2747d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // are ICEs, the value of the offsetof must be an integer constant. 2748d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckEvalInICE(E, Ctx); 2749d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2750d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::SizeOfAlignOfExprClass: { 2751d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const SizeOfAlignOfExpr *Exp = cast<SizeOfAlignOfExpr>(E); 2752d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Exp->isSizeOf() && Exp->getTypeOfArgument()->isVariableArrayType()) 2753d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2754d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2755d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2756d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::BinaryOperatorClass: { 2757d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const BinaryOperator *Exp = cast<BinaryOperator>(E); 2758d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall switch (Exp->getOpcode()) { 27592de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_PtrMemD: 27602de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_PtrMemI: 27612de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Assign: 27622de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_MulAssign: 27632de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_DivAssign: 27642de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_RemAssign: 27652de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_AddAssign: 27662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_SubAssign: 27672de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_ShlAssign: 27682de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_ShrAssign: 27692de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_AndAssign: 27702de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_XorAssign: 27712de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_OrAssign: 2772d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2773d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 27742de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Mul: 27752de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Div: 27762de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Rem: 27772de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Add: 27782de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Sub: 27792de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shl: 27802de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Shr: 27812de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LT: 27822de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GT: 27832de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LE: 27842de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_GE: 27852de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_EQ: 27862de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_NE: 27872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_And: 27882de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Xor: 27892de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Or: 27902de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_Comma: { 2791d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); 2792d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); 27932de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (Exp->getOpcode() == BO_Div || 27942de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall Exp->getOpcode() == BO_Rem) { 2795d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Evaluate gives an error for undefined Div/Rem, so make sure 2796d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // we don't evaluate one. 2797d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val != 2 && RHSResult.Val != 2) { 2798d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall llvm::APSInt REval = Exp->getRHS()->EvaluateAsInt(Ctx); 2799d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (REval == 0) 2800d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(1, E->getLocStart()); 2801d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (REval.isSigned() && REval.isAllOnesValue()) { 2802d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall llvm::APSInt LEval = Exp->getLHS()->EvaluateAsInt(Ctx); 2803d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LEval.isMinSignedValue()) 2804d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(1, E->getLocStart()); 2805d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2806d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2807d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 28082de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (Exp->getOpcode() == BO_Comma) { 2809d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Ctx.getLangOptions().C99) { 2810d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // C99 6.6p3 introduces a strange edge case: comma can be in an ICE 2811d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // if it isn't evaluated. 2812d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val == 0 && RHSResult.Val == 0) 2813d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(1, E->getLocStart()); 2814d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } else { 2815d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // In both C89 and C++, commas in ICEs are illegal. 2816d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2817d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2818d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2819d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val >= RHSResult.Val) 2820d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return LHSResult; 2821d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return RHSResult; 2822d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 28232de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LAnd: 28242de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall case BO_LOr: { 2825d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); 2826d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); 2827d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val == 0 && RHSResult.Val == 1) { 2828d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Rare case where the RHS has a comma "side-effect"; we need 2829d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // to actually check the condition to see whether the side 2830d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // with the comma is evaluated. 28312de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if ((Exp->getOpcode() == BO_LAnd) != 2832d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall (Exp->getLHS()->EvaluateAsInt(Ctx) == 0)) 2833d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return RHSResult; 2834d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2835d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2836d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2837d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (LHSResult.Val >= RHSResult.Val) 2838d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return LHSResult; 2839d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return RHSResult; 2840d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2841d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2842d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2843d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ImplicitCastExprClass: 2844d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CStyleCastExprClass: 2845d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXFunctionalCastExprClass: 2846d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXStaticCastExprClass: 2847d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXReinterpretCastExprClass: 2848d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXConstCastExprClass: { 2849d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr(); 28502ade35e2cfd554e49d35a52047cea98a82787af9Douglas Gregor if (SubExpr->getType()->isIntegralOrEnumerationType()) 2851d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(SubExpr, Ctx); 2852d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (isa<FloatingLiteral>(SubExpr->IgnoreParens())) 2853d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2854d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2855d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2856d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ConditionalOperatorClass: { 2857d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall const ConditionalOperator *Exp = cast<ConditionalOperator>(E); 2858d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // If the condition (ignoring parens) is a __builtin_constant_p call, 2859d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // then only the true side is actually considered in an integer constant 2860d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // expression, and it is fully evaluated. This is an important GNU 2861d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // extension. See GCC PR38377 for discussion. 2862d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (const CallExpr *CallCE 2863d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall = dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts())) 2864d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CallCE->isBuiltinCall(Ctx) == Builtin::BI__builtin_constant_p) { 2865d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Expr::EvalResult EVResult; 2866d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (!E->Evaluate(EVResult, Ctx) || EVResult.HasSideEffects || 2867d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall !EVResult.Val.isInt()) { 2868d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2869d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2870d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2871d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2872d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx); 2873d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag TrueResult = CheckICE(Exp->getTrueExpr(), Ctx); 2874d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); 2875d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CondResult.Val == 2) 2876d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CondResult; 2877d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (TrueResult.Val == 2) 2878d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return TrueResult; 2879d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (FalseResult.Val == 2) 2880d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return FalseResult; 2881d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (CondResult.Val == 1) 2882d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CondResult; 2883d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (TrueResult.Val == 0 && FalseResult.Val == 0) 2884d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return NoDiag(); 2885d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Rare case where the diagnostics depend on which side is evaluated 2886d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Note that if we get here, CondResult is 0, and at least one of 2887d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // TrueResult and FalseResult is non-zero. 2888d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Exp->getCond()->EvaluateAsInt(Ctx) == 0) { 2889d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return FalseResult; 2890d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2891d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return TrueResult; 2892d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2893d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::CXXDefaultArgExprClass: 2894d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx); 2895d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall case Expr::ChooseExprClass: { 2896d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(Ctx), Ctx); 2897d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2898d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2899d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2900d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall // Silence a GCC warning 2901d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return ICEDiag(2, E->getLocStart()); 2902d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall} 2903d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall 2904d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCallbool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, 2905d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall SourceLocation *Loc, bool isEvaluated) const { 2906d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall ICEDiag d = CheckICE(this, Ctx); 2907d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (d.Val != 0) { 2908d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (Loc) *Loc = d.Loc; 2909d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return false; 2910d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall } 2911d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall EvalResult EvalResult; 2912d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall if (!Evaluate(EvalResult, Ctx)) 2913d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall llvm_unreachable("ICE cannot be evaluated!"); 2914d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall assert(!EvalResult.HasSideEffects && "ICE with side effects!"); 2915d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall assert(EvalResult.Val.isInt() && "ICE that isn't integer!"); 2916d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall Result = EvalResult.Val.getInt(); 2917d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall return true; 2918d905f5ad540c415d1a21b4f8b7bd715bfb7bb920John McCall} 2919