46 #include "llvm/ADT/SmallString.h"
47 #include "llvm/Support/raw_ostream.h"
51 using namespace clang;
59 struct CallStackFrame;
72 dyn_cast<MaterializeTemporaryExpr>(Base)) {
75 const Expr *Temp = MTE->GetTemporaryExpr();
99 return dyn_cast<
FieldDecl>(getAsBaseOrMember(E).getPointer());
104 return dyn_cast<
CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
109 return getAsBaseOrMember(E).getInt();
119 unsigned MostDerivedLength = 0;
121 for (
unsigned I = 0, N = Path.size();
I != N; ++
I) {
126 ArraySize = CAT->
getSize().getZExtValue();
127 MostDerivedLength =
I + 1;
129 }
else if (Type->isAnyComplexType()) {
133 MostDerivedLength =
I + 1;
135 }
else if (
const FieldDecl *FD = getAsField(Path[
I])) {
136 Type = FD->getType();
138 MostDerivedLength = I + 1;
146 return MostDerivedLength;
151 CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
152 CSK_This, CSK_Real, CSK_Imag
156 struct SubobjectDesignator {
163 bool IsOnePastTheEnd : 1;
166 bool MostDerivedIsArrayElement : 1;
170 unsigned MostDerivedPathLength : 29;
176 uint64_t MostDerivedArraySize;
188 explicit SubobjectDesignator(
QualType T)
190 MostDerivedIsArrayElement(
false), MostDerivedPathLength(0),
191 MostDerivedArraySize(0), MostDerivedType(T) {}
194 :
Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(
false),
195 MostDerivedIsArrayElement(
false), MostDerivedPathLength(0),
196 MostDerivedArraySize(0) {
200 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
202 bool IsArray =
false;
203 MostDerivedPathLength =
206 MostDerivedType, IsArray);
207 MostDerivedIsArrayElement = IsArray;
218 bool isOnePastTheEnd()
const {
222 if (MostDerivedIsArrayElement &&
223 Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
229 bool isValidSubobject()
const {
232 return !isOnePastTheEnd();
241 Entry.ArrayIndex = 0;
242 Entries.push_back(Entry);
246 MostDerivedIsArrayElement =
true;
247 MostDerivedArraySize = CAT->
getSize().getZExtValue();
248 MostDerivedPathLength = Entries.size();
252 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
255 Entry.BaseOrMember = Value.getOpaqueValue();
256 Entries.push_back(Entry);
259 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
260 MostDerivedType = FD->getType();
261 MostDerivedIsArrayElement =
false;
262 MostDerivedArraySize = 0;
263 MostDerivedPathLength = Entries.size();
267 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
269 Entry.ArrayIndex = Imag;
270 Entries.push_back(Entry);
274 MostDerivedType = EltTy;
275 MostDerivedIsArrayElement =
true;
276 MostDerivedArraySize = 2;
277 MostDerivedPathLength = Entries.size();
279 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E, uint64_t N);
281 void adjustIndex(EvalInfo &Info,
const Expr *E, uint64_t N) {
283 if (MostDerivedPathLength == Entries.size() &&
284 MostDerivedIsArrayElement) {
285 Entries.back().ArrayIndex += N;
286 if (Entries.back().ArrayIndex > MostDerivedArraySize) {
287 diagnosePointerArithmetic(Info, E, Entries.back().ArrayIndex);
295 if (IsOnePastTheEnd && N == (uint64_t)-1)
296 IsOnePastTheEnd =
false;
297 else if (!IsOnePastTheEnd && N == 1)
298 IsOnePastTheEnd =
true;
300 diagnosePointerArithmetic(Info, E, uint64_t(IsOnePastTheEnd) + N);
307 struct CallStackFrame {
311 CallStackFrame *Caller;
331 typedef std::map<const void*, APValue>
MapTy;
332 typedef MapTy::const_iterator temp_iterator;
341 APValue *getTemporary(
const void *Key) {
343 return I == Temporaries.end() ?
nullptr : &I->second;
345 APValue &createTemporary(
const void *Key,
bool IsLifetimeExtended);
349 class ThisOverrideRAII {
351 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
352 : Frame(Frame), OldThis(Frame.This) {
354 Frame.This = NewThis;
356 ~ThisOverrideRAII() {
357 Frame.This = OldThis;
360 CallStackFrame &Frame;
361 const LValue *OldThis;
366 class OptionalDiagnostic {
380 OptionalDiagnostic &
operator<<(
const APSInt &I) {
384 *
Diag << StringRef(Buffer.data(), Buffer.size());
389 OptionalDiagnostic &
operator<<(
const APFloat &F) {
398 llvm::APFloat::semanticsPrecision(F.getSemantics());
399 precision = (precision * 59 + 195) / 196;
401 F.toString(Buffer, precision);
402 *
Diag << StringRef(Buffer.data(), Buffer.size());
410 llvm::PointerIntPair<APValue*, 1, bool>
Value;
413 Cleanup(
APValue *Val,
bool IsLifetimeExtended)
414 : Value(Val, IsLifetimeExtended) {}
416 bool isLifetimeExtended()
const {
return Value.getInt(); }
418 *Value.getPointer() =
APValue();
443 CallStackFrame *CurrentCall;
446 unsigned CallStackDepth;
449 unsigned NextCallIndex;
458 CallStackFrame BottomFrame;
474 bool HasActiveDiagnostic;
478 bool HasFoldFailureDiagnostic;
480 enum EvaluationMode {
483 EM_ConstantExpression,
489 EM_PotentialConstantExpression,
498 EM_EvaluateForOverflow,
502 EM_IgnoreSideEffects,
509 EM_ConstantExpressionUnevaluated,
518 EM_PotentialConstantExpressionUnevaluated,
527 bool checkingPotentialConstantExpression()
const {
528 return EvalMode == EM_PotentialConstantExpression ||
529 EvalMode == EM_PotentialConstantExpressionUnevaluated;
535 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
538 : Ctx(const_cast<
ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
539 CallStackDepth(0), NextCallIndex(1),
540 StepsLeft(getLangOpts().ConstexprStepLimit),
542 EvaluatingDecl((const
ValueDecl *)nullptr),
543 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
544 HasFoldFailureDiagnostic(
false), EvalMode(Mode) {}
547 EvaluatingDecl = Base;
548 EvaluatingDeclValue = &
Value;
556 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
558 if (NextCallIndex == 0) {
560 Diag(Loc, diag::note_constexpr_call_limit_exceeded);
563 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
565 Diag(Loc, diag::note_constexpr_depth_limit_exceeded)
566 << getLangOpts().ConstexprCallDepth;
570 CallStackFrame *getCallFrame(
unsigned CallIndex) {
571 assert(CallIndex &&
"no call index in getCallFrame");
574 CallStackFrame *Frame = CurrentCall;
575 while (Frame->Index > CallIndex)
576 Frame = Frame->Caller;
577 return (Frame->Index == CallIndex) ? Frame :
nullptr;
580 bool nextStep(
const Stmt *
S) {
582 Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded);
593 EvalStatus.Diag->push_back(std::make_pair(Loc, PD));
594 return EvalStatus.Diag->back().second;
598 void addCallStack(
unsigned Limit);
603 = diag::note_invalid_subexpr_in_const_expr,
604 unsigned ExtraNotes = 0,
bool IsCCEDiag =
false) {
605 if (EvalStatus.Diag) {
612 if (!EvalStatus.Diag->empty()) {
614 case EM_ConstantFold:
615 case EM_IgnoreSideEffects:
616 case EM_EvaluateForOverflow:
617 if (!HasFoldFailureDiagnostic)
620 case EM_ConstantExpression:
621 case EM_PotentialConstantExpression:
622 case EM_ConstantExpressionUnevaluated:
623 case EM_PotentialConstantExpressionUnevaluated:
624 case EM_DesignatorFold:
625 HasActiveDiagnostic =
false;
626 return OptionalDiagnostic();
630 unsigned CallStackNotes = CallStackDepth - 1;
633 CallStackNotes = std::min(CallStackNotes, Limit + 1);
634 if (checkingPotentialConstantExpression())
637 HasActiveDiagnostic =
true;
638 HasFoldFailureDiagnostic = !IsCCEDiag;
639 EvalStatus.Diag->clear();
640 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
641 addDiag(Loc, DiagId);
642 if (!checkingPotentialConstantExpression())
644 return OptionalDiagnostic(&(*EvalStatus.Diag)[0].second);
646 HasActiveDiagnostic =
false;
647 return OptionalDiagnostic();
651 = diag::note_invalid_subexpr_in_const_expr,
652 unsigned ExtraNotes = 0,
bool IsCCEDiag =
false) {
655 HasActiveDiagnostic =
false;
656 return OptionalDiagnostic();
664 template<
typename LocArg>
665 OptionalDiagnostic CCEDiag(LocArg Loc,
diag::kind DiagId
666 = diag::note_invalid_subexpr_in_const_expr,
667 unsigned ExtraNotes = 0) {
670 if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) {
671 HasActiveDiagnostic =
false;
672 return OptionalDiagnostic();
674 return Diag(Loc, DiagId, ExtraNotes,
true);
679 if (!HasActiveDiagnostic)
680 return OptionalDiagnostic();
681 return OptionalDiagnostic(&addDiag(Loc, DiagId));
686 if (HasActiveDiagnostic) {
687 EvalStatus.Diag->insert(EvalStatus.Diag->end(),
688 Diags.begin(), Diags.end());
694 bool keepEvaluatingAfterSideEffect() {
696 case EM_PotentialConstantExpression:
697 case EM_PotentialConstantExpressionUnevaluated:
698 case EM_EvaluateForOverflow:
699 case EM_IgnoreSideEffects:
702 case EM_ConstantExpression:
703 case EM_ConstantExpressionUnevaluated:
704 case EM_ConstantFold:
705 case EM_DesignatorFold:
708 llvm_unreachable(
"Missed EvalMode case");
713 bool noteSideEffect() {
714 EvalStatus.HasSideEffects =
true;
715 return keepEvaluatingAfterSideEffect();
719 bool keepEvaluatingAfterUndefinedBehavior() {
721 case EM_EvaluateForOverflow:
722 case EM_IgnoreSideEffects:
723 case EM_ConstantFold:
724 case EM_DesignatorFold:
727 case EM_PotentialConstantExpression:
728 case EM_PotentialConstantExpressionUnevaluated:
729 case EM_ConstantExpression:
730 case EM_ConstantExpressionUnevaluated:
733 llvm_unreachable(
"Missed EvalMode case");
739 bool noteUndefinedBehavior() {
740 EvalStatus.HasUndefinedBehavior =
true;
741 return keepEvaluatingAfterUndefinedBehavior();
746 bool keepEvaluatingAfterFailure() {
751 case EM_PotentialConstantExpression:
752 case EM_PotentialConstantExpressionUnevaluated:
753 case EM_EvaluateForOverflow:
756 case EM_ConstantExpression:
757 case EM_ConstantExpressionUnevaluated:
758 case EM_ConstantFold:
759 case EM_IgnoreSideEffects:
760 case EM_DesignatorFold:
763 llvm_unreachable(
"Missed EvalMode case");
766 bool allowInvalidBaseExpr()
const {
767 return EvalMode == EM_DesignatorFold;
772 struct FoldConstant {
775 bool HadNoPriorDiags;
776 EvalInfo::EvaluationMode OldMode;
778 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
781 HadNoPriorDiags(Info.EvalStatus.
Diag &&
782 Info.EvalStatus.
Diag->empty() &&
783 !Info.EvalStatus.HasSideEffects),
784 OldMode(Info.EvalMode) {
786 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
787 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
788 Info.EvalMode = EvalInfo::EM_ConstantFold;
790 void keepDiagnostics() { Enabled =
false; }
792 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
793 !Info.EvalStatus.HasSideEffects)
794 Info.EvalStatus.Diag->clear();
795 Info.EvalMode = OldMode;
801 struct FoldOffsetRAII {
803 EvalInfo::EvaluationMode OldMode;
804 explicit FoldOffsetRAII(EvalInfo &Info,
bool Subobject)
805 : Info(Info), OldMode(Info.EvalMode) {
806 if (!Info.checkingPotentialConstantExpression())
807 Info.EvalMode = Subobject ? EvalInfo::EM_DesignatorFold
808 : EvalInfo::EM_ConstantFold;
811 ~FoldOffsetRAII() { Info.EvalMode = OldMode; }
816 class SpeculativeEvaluationRAII {
821 SpeculativeEvaluationRAII(EvalInfo &Info,
823 : Info(Info), Old(Info.EvalStatus) {
824 Info.EvalStatus.Diag = NewDiag;
827 Info.EvalStatus.HasSideEffects =
true;
829 ~SpeculativeEvaluationRAII() {
830 Info.EvalStatus = Old;
836 template<
bool IsFullExpression>
839 unsigned OldStackSize;
841 ScopeRAII(EvalInfo &Info)
842 : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
846 cleanup(Info, OldStackSize);
849 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
850 unsigned NewEnd = OldStackSize;
851 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
853 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
856 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
860 Info.CleanupStack[
I].endLifetime();
863 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
864 Info.CleanupStack.end());
867 typedef ScopeRAII<false> BlockScopeRAII;
868 typedef ScopeRAII<true> FullExpressionRAII;
871 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
875 if (isOnePastTheEnd()) {
876 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
884 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
885 const Expr *E, uint64_t N) {
886 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
887 Info.CCEDiag(E, diag::note_constexpr_array_index)
888 <<
static_cast<int>(N) << 0
889 << static_cast<unsigned>(MostDerivedArraySize);
891 Info.CCEDiag(E, diag::note_constexpr_array_index)
892 <<
static_cast<int>(N) << 1;
896 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
899 : Info(Info), Caller(Info.CurrentCall), CallLoc(CallLoc), Callee(Callee),
900 Index(Info.NextCallIndex++), This(This), Arguments(Arguments) {
901 Info.CurrentCall =
this;
902 ++Info.CallStackDepth;
905 CallStackFrame::~CallStackFrame() {
906 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
907 --Info.CallStackDepth;
908 Info.CurrentCall = Caller;
911 APValue &CallStackFrame::createTemporary(
const void *Key,
912 bool IsLifetimeExtended) {
914 assert(Result.
isUninit() &&
"temporary created multiple times");
915 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
919 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
921 void EvalInfo::addCallStack(
unsigned Limit) {
923 unsigned ActiveCalls = CallStackDepth - 1;
924 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
925 if (Limit && Limit < ActiveCalls) {
926 SkipStart = Limit / 2 + Limit % 2;
927 SkipEnd = ActiveCalls - Limit / 2;
931 unsigned CallIdx = 0;
932 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
933 Frame = Frame->Caller, ++CallIdx) {
935 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
936 if (CallIdx == SkipStart) {
938 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
945 llvm::raw_svector_ostream Out(Buffer);
947 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
952 struct ComplexValue {
957 APSInt IntReal, IntImag;
958 APFloat FloatReal, FloatImag;
960 ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {}
962 void makeComplexFloat() { IsInt =
false; }
963 bool isComplexFloat()
const {
return !IsInt; }
964 APFloat &getComplexFloatReal() {
return FloatReal; }
965 APFloat &getComplexFloatImag() {
return FloatImag; }
967 void makeComplexInt() { IsInt =
true; }
968 bool isComplexInt()
const {
return IsInt; }
969 APSInt &getComplexIntReal() {
return IntReal; }
970 APSInt &getComplexIntImag() {
return IntImag; }
972 void moveInto(
APValue &v)
const {
973 if (isComplexFloat())
974 v =
APValue(FloatReal, FloatImag);
978 void setFrom(
const APValue &v) {
995 bool InvalidBase : 1;
996 unsigned CallIndex : 31;
1002 unsigned getLValueCallIndex()
const {
return CallIndex; }
1003 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1004 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1006 void moveInto(
APValue &V)
const {
1017 InvalidBase =
false;
1024 Offset = CharUnits::Zero();
1025 InvalidBase = BInvalid;
1027 Designator = SubobjectDesignator(getType(B));
1036 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1041 Info.CCEDiag(E, diag::note_constexpr_null_subobject)
1052 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
1056 void addDecl(EvalInfo &Info,
const Expr *E,
1057 const Decl *D,
bool Virtual =
false) {
1058 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
1062 if (checkSubobject(Info, E, CSK_ArrayToPointer))
1065 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1066 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1069 void adjustIndex(EvalInfo &Info,
const Expr *E, uint64_t N) {
1070 if (N && checkNullPointer(Info, E, CSK_ArrayIndex))
1078 DeclAndIsDerivedMember(Decl,
false), Path() {}
1083 return DeclAndIsDerivedMember.getPointer();
1086 bool isDerivedMember()
const {
1087 return DeclAndIsDerivedMember.getInt();
1091 return cast<CXXRecordDecl>(
1092 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1095 void moveInto(
APValue &V)
const {
1096 V =
APValue(getDecl(), isDerivedMember(), Path);
1098 void setFrom(
const APValue &V) {
1104 Path.insert(Path.end(), P.begin(), P.end());
1110 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1118 assert(!Path.empty());
1120 if (Path.size() >= 2)
1121 Expected = Path[Path.size() - 2];
1123 Expected = getContainingRecord();
1140 if (!isDerivedMember()) {
1141 Path.push_back(Derived);
1144 if (!castBack(Derived))
1147 DeclAndIsDerivedMember.setInt(
false);
1155 DeclAndIsDerivedMember.setInt(
true);
1156 if (isDerivedMember()) {
1157 Path.push_back(Base);
1160 return castBack(Base);
1165 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1166 if (!LHS.getDecl() || !RHS.getDecl())
1167 return !LHS.getDecl() && !RHS.getDecl();
1168 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1170 return LHS.Path == RHS.Path;
1176 const LValue &This,
const Expr *E,
1177 bool AllowNonLiteralTypes =
false);
1197 unsigned ArgIndex = 0;
1198 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1199 !isa<CXXConstructorDecl>(Frame->Callee) &&
1200 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1203 Out << *Frame->Callee <<
'(';
1205 if (Frame->This && IsMemberCall) {
1207 Frame->This->moveInto(Val);
1209 Frame->This->Designator.MostDerivedType);
1211 Out <<
"->" << *Frame->Callee <<
'(';
1212 IsMemberCall =
false;
1216 E = Frame->Callee->param_end(); I !=
E; ++
I, ++ArgIndex) {
1217 if (ArgIndex > (
unsigned)IsMemberCall)
1221 const APValue &Arg = Frame->Arguments[ArgIndex];
1224 if (ArgIndex == 0 && IsMemberCall)
1225 Out <<
"->" << *Frame->Callee <<
'(';
1238 return Info.noteSideEffect();
1245 return Value.isSigned() ? Value.getSExtValue()
1246 :
static_cast<int64_t
>(Value.getZExtValue());
1252 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1253 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1262 if (!B)
return true;
1266 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1267 return VD->hasGlobalStorage();
1269 return isa<FunctionDecl>(D);
1272 const Expr *E = B.get<
const Expr*>();
1273 switch (E->getStmtClass()) {
1276 case Expr::CompoundLiteralExprClass: {
1280 case Expr::MaterializeTemporaryExprClass:
1283 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
1285 case Expr::StringLiteralClass:
1286 case Expr::PredefinedExprClass:
1287 case Expr::ObjCStringLiteralClass:
1288 case Expr::ObjCEncodeExprClass:
1289 case Expr::CXXTypeidExprClass:
1290 case Expr::CXXUuidofExprClass:
1292 case Expr::CallExprClass:
1295 case Expr::AddrLabelExprClass:
1299 case Expr::BlockExprClass:
1300 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
1301 case Expr::ImplicitValueInitExprClass:
1313 assert(Base &&
"no location for a null lvalue");
1316 Info.Note(VD->
getLocation(), diag::note_declared_at);
1319 diag::note_constexpr_temporary_here);
1326 QualType Type,
const LValue &LVal) {
1330 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1336 if (Info.getLangOpts().CPlusPlus11) {
1338 Info.Diag(Loc, diag::note_constexpr_non_global, 1)
1339 << IsReferenceType << !Designator.Entries.empty()
1348 assert((Info.checkingPotentialConstantExpression() ||
1349 LVal.getLValueCallIndex() == 0) &&
1350 "have call index for global lvalue");
1353 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1355 if (Var->getTLSKind())
1359 if (Var->hasAttr<DLLImportAttr>())
1362 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1373 if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
1380 if (!IsReferenceType)
1391 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1393 Info.Diag(Loc, diag::note_constexpr_past_end, 1)
1394 << !Designator.Entries.empty() << !!VD << VD;
1404 const LValue *This =
nullptr) {
1411 if (Info.getLangOpts().CPlusPlus14 && This &&
1412 Info.EvaluatingDecl == This->getLValueBase())
1416 if (Info.getLangOpts().CPlusPlus11)
1417 Info.Diag(E, diag::note_constexpr_nonliteral)
1420 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1430 Info.Diag(DiagLoc, diag::note_constexpr_uninitialized)
1438 Type = AT->getValueType();
1462 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
1463 unsigned BaseIndex = 0;
1465 End = CD->bases_end(); I !=
End; ++
I, ++BaseIndex) {
1471 for (
const auto *I : RD->
fields()) {
1480 LVal.setFrom(Info.Ctx, Value);
1489 return LVal.Base.dyn_cast<
const ValueDecl*>();
1493 if (Value.CallIndex)
1495 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1496 return E && !isa<MaterializeTemporaryExpr>(
E);
1501 return Decl && Decl->
isWeak();
1506 if (Decl && isa<VarDecl>(Decl)) {
1527 return !Decl || !Decl->
isWeak();
1535 Result = Val.
getInt().getBoolValue();
1537 case APValue::Float:
1540 case APValue::ComplexInt:
1544 case APValue::ComplexFloat:
1548 case APValue::LValue:
1550 case APValue::MemberPointer:
1553 case APValue::Vector:
1554 case APValue::Array:
1555 case APValue::Struct:
1556 case APValue::Union:
1557 case APValue::AddrLabelDiff:
1561 llvm_unreachable(
"unknown APValue kind");
1566 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
1573 template<
typename T>
1575 const T &SrcValue,
QualType DestType) {
1576 Info.CCEDiag(E, diag::note_constexpr_overflow)
1577 << SrcValue << DestType;
1578 return Info.noteUndefinedBehavior();
1582 QualType SrcType,
const APFloat &Value,
1583 QualType DestType, APSInt &Result) {
1584 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1588 Result = APSInt(DestWidth, !DestSigned);
1590 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
1591 & APFloat::opInvalidOp)
1599 APFloat Value = Result;
1601 if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
1602 APFloat::rmNearestTiesToEven, &ignored)
1603 & APFloat::opOverflow)
1610 const APSInt &Value) {
1611 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1612 APSInt Result =
Value;
1615 Result = Result.extOrTrunc(DestWidth);
1621 QualType SrcType,
const APSInt &Value,
1622 QualType DestType, APFloat &Result) {
1623 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
1624 if (Result.convertFromAPInt(Value, Value.isSigned(),
1625 APFloat::rmNearestTiesToEven)
1626 & APFloat::opOverflow)
1633 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
1635 if (!Value.
isInt()) {
1639 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
1644 APSInt &Int = Value.
getInt();
1645 unsigned OldBitWidth = Int.getBitWidth();
1647 if (NewBitWidth < OldBitWidth)
1648 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
1662 Res = SVal.
getFloat().bitcastToAPInt();
1667 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
1669 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
1670 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
1671 Res = llvm::APInt::getNullValue(VecSize);
1674 llvm::APInt EltAsInt;
1678 EltAsInt = Elt.
getFloat().bitcastToAPInt();
1682 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1685 unsigned BaseEltSize = EltAsInt.getBitWidth();
1687 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
1689 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
1695 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1702 template<
typename Operation>
1704 const APSInt &LHS,
const APSInt &RHS,
1705 unsigned BitWidth, Operation Op,
1707 if (LHS.isUnsigned()) {
1708 Result = Op(LHS, RHS);
1712 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
1713 Result = Value.trunc(LHS.getBitWidth());
1714 if (Result.extend(BitWidth) !=
Value) {
1715 if (Info.checkingForOverflow())
1716 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
1717 diag::warn_integer_constant_overflow)
1718 << Result.toString(10) << E->
getType();
1735 std::multiplies<APSInt>(), Result);
1738 std::plus<APSInt>(), Result);
1741 std::minus<APSInt>(), Result);
1742 case BO_And: Result = LHS & RHS;
return true;
1743 case BO_Xor: Result = LHS ^ RHS;
return true;
1744 case BO_Or: Result = LHS | RHS;
return true;
1748 Info.Diag(E, diag::note_expr_divide_by_zero);
1751 Result = (Opcode ==
BO_Rem ? LHS % RHS : LHS / RHS);
1754 if (RHS.isNegative() && RHS.isAllOnesValue() &&
1755 LHS.isSigned() && LHS.isMinSignedValue())
1756 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
1760 if (Info.getLangOpts().OpenCL)
1762 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
1763 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
1765 else if (RHS.isSigned() && RHS.isNegative()) {
1768 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
1775 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
1777 Info.CCEDiag(E, diag::note_constexpr_large_shift)
1778 << RHS << E->
getType() << LHS.getBitWidth();
1779 }
else if (LHS.isSigned()) {
1782 if (LHS.isNegative())
1783 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
1784 else if (LHS.countLeadingZeros() < SA)
1785 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
1791 if (Info.getLangOpts().OpenCL)
1793 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
1794 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
1796 else if (RHS.isSigned() && RHS.isNegative()) {
1799 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
1806 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
1808 Info.CCEDiag(E, diag::note_constexpr_large_shift)
1809 << RHS << E->
getType() << LHS.getBitWidth();
1814 case BO_LT: Result = LHS < RHS;
return true;
1815 case BO_GT: Result = LHS > RHS;
return true;
1816 case BO_LE: Result = LHS <= RHS;
return true;
1817 case BO_GE: Result = LHS >= RHS;
return true;
1818 case BO_EQ: Result = LHS == RHS;
return true;
1819 case BO_NE: Result = LHS != RHS;
return true;
1826 const APFloat &RHS) {
1832 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
1835 LHS.add(RHS, APFloat::rmNearestTiesToEven);
1838 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
1841 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
1845 if (LHS.isInfinity() || LHS.isNaN()) {
1846 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
1847 return Info.noteUndefinedBehavior();
1856 unsigned TruncatedElements) {
1857 SubobjectDesignator &D = Result.Designator;
1860 if (TruncatedElements == D.Entries.size())
1862 assert(TruncatedElements >= D.MostDerivedPathLength &&
1863 "not casting to a derived class");
1864 if (!Result.checkSubobject(Info, E, CSK_Derived))
1869 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++
I) {
1873 if (isVirtualBaseClass(D.Entries[I]))
1879 D.Entries.resize(TruncatedElements);
1889 RL = &Info.Ctx.getASTRecordLayout(Derived);
1892 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
1893 Obj.addDecl(Info, E, Base,
false);
1905 SubobjectDesignator &D = Obj.Designator;
1910 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
1916 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
1918 Obj.addDecl(Info, E, BaseDecl,
true);
1926 PathI != PathE; ++PathI) {
1930 Type = (*PathI)->getType();
1942 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
1946 LVal.Offset += Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I));
1947 LVal.addDecl(Info, E, FD);
1955 for (
const auto *
C : IFD->
chain())
1967 Size = CharUnits::One();
1978 Size = Info.Ctx.getTypeSizeInChars(Type);
1990 int64_t Adjustment) {
1996 LVal.Offset += Adjustment * SizeOfPointee;
1997 LVal.adjustIndex(Info, E, Adjustment);
2013 LVal.Offset += SizeOfComponent;
2015 LVal.addComplex(Info, E, EltTy, Imag);
2028 const VarDecl *VD, CallStackFrame *Frame,
2032 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2035 if (Info.checkingPotentialConstantExpression())
2037 if (!Frame || !Frame->Arguments) {
2038 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
2041 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2047 Result = Frame->getTemporary(VD);
2048 assert(Result &&
"missing value for local variable");
2057 if (!Info.checkingPotentialConstantExpression())
2058 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
2064 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2065 Result = Info.EvaluatingDeclValue;
2072 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
2080 Info.Diag(E, diag::note_constexpr_var_init_non_constant,
2081 Notes.size() + 1) << VD;
2082 Info.Note(VD->
getLocation(), diag::note_declared_at);
2083 Info.addNotes(Notes);
2086 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2087 Notes.size() + 1) << VD;
2088 Info.Note(VD->
getLocation(), diag::note_declared_at);
2089 Info.addNotes(Notes);
2109 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2113 llvm_unreachable(
"base class missing from derived class's bases list");
2120 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2121 Lit = PE->getFunctionName();
2124 Info.Ctx.getAsConstantArrayType(S->
getType());
2125 assert(CAT &&
"string literal isn't an array");
2126 QualType CharType = CAT->getElementType();
2127 assert(CharType->
isIntegerType() &&
"unexpected character type");
2131 if (Index < S->getLength())
2141 Info.Ctx.getAsConstantArrayType(S->
getType());
2142 assert(CAT &&
"string literal isn't an array");
2143 QualType CharType = CAT->getElementType();
2144 assert(CharType->
isIntegerType() &&
"unexpected character type");
2146 unsigned Elts = CAT->getSize().getZExtValue();
2162 assert(Index < Size);
2166 unsigned NewElts = std::max(Index+1, OldElts * 2);
2167 NewElts = std::min(Size, std::max(NewElts, 8u));
2171 for (
unsigned I = 0; I != OldElts; ++
I)
2173 for (
unsigned I = OldElts; I != NewElts; ++
I)
2177 Array.
swap(NewValue);
2192 for (
auto *Field : RD->
fields())
2196 for (
auto &BaseSpec : RD->
bases())
2214 for (
auto *Field : RD->
fields()) {
2219 if (Field->isMutable() &&
2221 Info.Diag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2222 Info.Note(Field->getLocation(), diag::note_declared_at);
2230 for (
auto &BaseSpec : RD->
bases())
2249 struct CompleteObject {
2255 CompleteObject() :
Value(
nullptr) {}
2257 :
Value(Value), Type(Type) {
2258 assert(Value &&
"missing value for complete object");
2261 explicit operator bool()
const {
return Value; }
2266 template<
typename Sub
objectHandler>
2267 typename SubobjectHandler::result_type
2269 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2272 return handler.failed();
2273 if (Sub.isOnePastTheEnd()) {
2274 if (Info.getLangOpts().CPlusPlus11)
2275 Info.Diag(E, diag::note_constexpr_access_past_end)
2276 << handler.AccessKind;
2279 return handler.failed();
2287 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++
I) {
2289 if (!Info.checkingPotentialConstantExpression())
2290 Info.Diag(E, diag::note_constexpr_access_uninit) << handler.AccessKind;
2291 return handler.failed();
2301 return handler.failed();
2303 if (!handler.found(*O, ObjType))
2307 if (handler.AccessKind !=
AK_Read &&
2315 LastField =
nullptr;
2319 assert(CAT &&
"vla in literal type?");
2320 uint64_t Index = Sub.Entries[
I].ArrayIndex;
2321 if (CAT->
getSize().ule(Index)) {
2324 if (Info.getLangOpts().CPlusPlus11)
2325 Info.Diag(E, diag::note_constexpr_access_past_end)
2326 << handler.AccessKind;
2329 return handler.failed();
2337 assert(I == N - 1 &&
"extracting subobject of character?");
2339 if (handler.AccessKind !=
AK_Read)
2343 return handler.foundString(*O, ObjType, Index);
2348 else if (handler.AccessKind !=
AK_Read) {
2355 uint64_t Index = Sub.Entries[
I].ArrayIndex;
2357 if (Info.getLangOpts().CPlusPlus11)
2358 Info.Diag(E, diag::note_constexpr_access_past_end)
2359 << handler.AccessKind;
2362 return handler.failed();
2367 if (WasConstQualified)
2370 assert(I == N - 1 &&
"extracting subobject of scalar?");
2379 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
2380 if (Field->isMutable() && handler.AccessKind ==
AK_Read) {
2381 Info.Diag(E, diag::note_constexpr_ltor_mutable, 1)
2383 Info.Note(Field->getLocation(), diag::note_declared_at);
2384 return handler.failed();
2393 Info.Diag(E, diag::note_constexpr_access_inactive_union_member)
2394 << handler.AccessKind << Field << !UnionField << UnionField;
2395 return handler.failed();
2402 ObjType = Field->getType();
2403 if (WasConstQualified && !Field->isMutable())
2407 if (Info.getLangOpts().CPlusPlus) {
2409 Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1)
2410 << handler.AccessKind << 2 << Field;
2411 Info.Note(Field->getLocation(), diag::note_declared_at);
2413 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
2415 return handler.failed();
2426 ObjType = Info.Ctx.getRecordType(Base);
2427 if (WasConstQualified)
2434 struct ExtractSubobjectHandler {
2440 typedef bool result_type;
2441 bool failed() {
return false; }
2446 bool found(APSInt &Value,
QualType SubobjType) {
2450 bool found(APFloat &Value,
QualType SubobjType) {
2454 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2466 const CompleteObject &Obj,
2467 const SubobjectDesignator &Sub,
2469 ExtractSubobjectHandler Handler = { Info, Result };
2474 struct ModifySubobjectHandler {
2479 typedef bool result_type;
2485 Info.Diag(E, diag::note_constexpr_modify_const_type) << QT;
2491 bool failed() {
return false; }
2493 if (!checkConst(SubobjType))
2496 Subobj.
swap(NewVal);
2499 bool found(APSInt &Value,
QualType SubobjType) {
2500 if (!checkConst(SubobjType))
2502 if (!NewVal.isInt()) {
2507 Value = NewVal.getInt();
2510 bool found(APFloat &Value,
QualType SubobjType) {
2511 if (!checkConst(SubobjType))
2513 Value = NewVal.getFloat();
2516 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2517 llvm_unreachable(
"shouldn't encounter string elements with ExpandArrays");
2526 const CompleteObject &Obj,
2527 const SubobjectDesignator &Sub,
2529 ModifySubobjectHandler Handler = { Info, NewVal, E };
2536 const SubobjectDesignator &A,
2537 const SubobjectDesignator &B,
2538 bool &WasArrayIndex) {
2539 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
2540 for (; I != N; ++
I) {
2544 if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
2545 WasArrayIndex =
true;
2553 if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
2554 WasArrayIndex =
false;
2557 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
2559 ObjType = FD->getType();
2565 WasArrayIndex =
false;
2572 const SubobjectDesignator &A,
2573 const SubobjectDesignator &B) {
2574 if (A.Entries.size() != B.Entries.size())
2577 bool IsArray = A.MostDerivedIsArrayElement;
2578 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
2587 return CommonLength >= A.Entries.size() - IsArray;
2595 Info.Diag(E, diag::note_constexpr_access_null) << AK;
2596 return CompleteObject();
2599 CallStackFrame *Frame =
nullptr;
2600 if (LVal.CallIndex) {
2601 Frame = Info.getCallFrame(LVal.CallIndex);
2603 Info.Diag(E, diag::note_constexpr_lifetime_ended, 1)
2604 << AK << LVal.Base.is<
const ValueDecl*>();
2606 return CompleteObject();
2615 if (Info.getLangOpts().CPlusPlus)
2616 Info.Diag(E, diag::note_constexpr_access_volatile_type)
2620 return CompleteObject();
2625 QualType BaseType = getType(LVal.Base);
2642 return CompleteObject();
2647 if (Info.getLangOpts().CPlusPlus) {
2648 Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1)
2650 Info.Note(VD->getLocation(), diag::note_declared_at);
2654 return CompleteObject();
2660 if (Info.getLangOpts().CPlusPlus14 &&
2661 VD == Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()) {
2667 Info.Diag(E, diag::note_constexpr_modify_global);
2668 return CompleteObject();
2673 if (Info.getLangOpts().CPlusPlus) {
2674 Info.Diag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
2675 Info.Note(VD->
getLocation(), diag::note_declared_at);
2679 return CompleteObject();
2685 if (Info.getLangOpts().CPlusPlus11) {
2686 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
2687 Info.Note(VD->
getLocation(), diag::note_declared_at);
2693 if (Info.getLangOpts().CPlusPlus11) {
2694 Info.Diag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
2695 Info.Note(VD->
getLocation(), diag::note_declared_at);
2699 return CompleteObject();
2704 return CompleteObject();
2706 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
2710 dyn_cast<MaterializeTemporaryExpr>(Base)) {
2711 assert(MTE->getStorageDuration() ==
SD_Static &&
2712 "should have a frame for a non-global materialized temporary");
2729 const ValueDecl *ED = MTE->getExtendingDecl();
2732 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
2733 Info.Diag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
2734 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
2735 return CompleteObject();
2738 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
2739 assert(BaseVal &&
"got reference to unevaluated temporary");
2742 return CompleteObject();
2745 BaseVal = Frame->getTemporary(Base);
2746 assert(BaseVal &&
"missing value for temporary");
2751 if (Info.getLangOpts().CPlusPlus) {
2752 Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1)
2754 Info.Note(Base->
getExprLoc(), diag::note_constexpr_temporary_here);
2758 return CompleteObject();
2766 if (LVal.getLValueBase() == Info.EvaluatingDecl) {
2767 BaseType = Info.Ctx.getCanonicalType(BaseType);
2776 if (Frame && Info.getLangOpts().CPlusPlus14 &&
2777 (Info.EvalStatus.HasSideEffects || Info.keepEvaluatingAfterFailure()))
2778 return CompleteObject();
2780 return CompleteObject(BaseVal, BaseType);
2796 const LValue &LVal,
APValue &RVal) {
2797 if (LVal.Designator.Invalid)
2801 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
2807 assert(!Info.getLangOpts().CPlusPlus &&
"lvalue compound literal in c++?");
2813 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
2815 CompleteObject LitObj(&Lit, Base->
getType());
2817 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
2822 CompleteObject StrObj(&Str, Base->
getType());
2834 if (LVal.Designator.Invalid)
2837 if (!Info.getLangOpts().CPlusPlus14) {
2852 struct CompoundAssignSubobjectHandler {
2861 typedef bool result_type;
2866 Info.Diag(E, diag::note_constexpr_modify_const_type) << QT;
2872 bool failed() {
return false; }
2876 return found(Subobj.
getInt(), SubobjType);
2877 case APValue::Float:
2878 return found(Subobj.
getFloat(), SubobjType);
2879 case APValue::ComplexInt:
2880 case APValue::ComplexFloat:
2884 case APValue::LValue:
2885 return foundPointer(Subobj, SubobjType);
2892 bool found(APSInt &Value,
QualType SubobjType) {
2893 if (!checkConst(SubobjType))
2910 bool found(APFloat &Value,
QualType SubobjType) {
2911 return checkConst(SubobjType) &&
2918 if (!checkConst(SubobjType))
2925 if (PointeeType.
isNull() || !RHS.isInt() ||
2936 LVal.setFrom(Info.Ctx, Subobj);
2939 LVal.moveInto(Subobj);
2942 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2943 llvm_unreachable(
"shouldn't encounter string elements here");
2952 EvalInfo &Info,
const Expr *E,
2955 if (LVal.Designator.Invalid)
2958 if (!Info.getLangOpts().CPlusPlus14) {
2964 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
2966 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
2970 struct IncDecSubobjectHandler {
2976 typedef bool result_type;
2981 Info.Diag(E, diag::note_constexpr_modify_const_type) << QT;
2987 bool failed() {
return false; }
2998 return found(Subobj.
getInt(), SubobjType);
2999 case APValue::Float:
3000 return found(Subobj.
getFloat(), SubobjType);
3001 case APValue::ComplexInt:
3005 case APValue::ComplexFloat:
3009 case APValue::LValue:
3010 return foundPointer(Subobj, SubobjType);
3017 bool found(APSInt &Value,
QualType SubobjType) {
3018 if (!checkConst(SubobjType))
3028 if (Old) *Old =
APValue(Value);
3040 bool WasNegative = Value.isNegative();
3044 if (!WasNegative && Value.isNegative() &&
3046 APSInt ActualValue(Value,
true);
3052 if (WasNegative && !Value.isNegative() &&
3054 unsigned BitWidth = Value.getBitWidth();
3055 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
3056 ActualValue.setBit(BitWidth);
3062 bool found(APFloat &Value,
QualType SubobjType) {
3063 if (!checkConst(SubobjType))
3066 if (Old) *Old =
APValue(Value);
3068 APFloat One(Value.getSemantics(), 1);
3070 Value.add(One, APFloat::rmNearestTiesToEven);
3072 Value.subtract(One, APFloat::rmNearestTiesToEven);
3076 if (!checkConst(SubobjType))
3088 LVal.setFrom(Info.Ctx, Subobj);
3092 LVal.moveInto(Subobj);
3095 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3096 llvm_unreachable(
"shouldn't encounter string elements here");
3104 if (LVal.Designator.Invalid)
3107 if (!Info.getLangOpts().CPlusPlus14) {
3114 IncDecSubobjectHandler Handler = { Info,
E, AK, Old };
3115 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3130 Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3149 bool IncludeMember =
true) {
3156 if (!MemPtr.getDecl()) {
3162 if (MemPtr.isDerivedMember()) {
3166 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3167 LV.Designator.Entries.size()) {
3171 unsigned PathLengthToMember =
3172 LV.Designator.Entries.size() - MemPtr.Path.size();
3173 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++
I) {
3175 LV.Designator.Entries[PathLengthToMember + I]);
3185 PathLengthToMember))
3187 }
else if (!MemPtr.Path.empty()) {
3189 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3190 MemPtr.Path.size() + IncludeMember);
3196 assert(RD &&
"member pointer access on non-class-type expression");
3198 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++
I) {
3206 MemPtr.getContainingRecord()))
3211 if (IncludeMember) {
3212 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3216 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3220 llvm_unreachable(
"can't construct reference to bound member function");
3224 return MemPtr.getDecl();
3230 bool IncludeMember =
true) {
3234 if (Info.keepEvaluatingAfterFailure()) {
3242 BO->
getRHS(), IncludeMember);
3249 SubobjectDesignator &D = Result.Designator;
3250 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
3258 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
3259 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3260 << D.MostDerivedType << TargetQT;
3266 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
3269 if (NewEntriesSize == D.MostDerivedPathLength)
3270 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
3272 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
3274 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3275 << D.MostDerivedType << TargetQT;
3301 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3303 if (!VD->hasLocalStorage())
3307 Result.set(VD, Info.CurrentCall->Index);
3308 APValue &Val = Info.CurrentCall->createTemporary(VD,
true);
3310 const Expr *InitE = VD->getInit();
3312 Info.Diag(D->
getLocStart(), diag::note_constexpr_uninitialized)
3313 <<
false << VD->getType();
3334 const Expr *Cond,
bool &Result) {
3335 FullExpressionRAII
Scope(Info);
3358 BlockScopeRAII
Scope(Info);
3361 return ESR_Succeeded;
3364 return ESR_Continue;
3367 case ESR_CaseNotFound:
3370 llvm_unreachable(
"Invalid EvalStmtResult!");
3376 BlockScopeRAII
Scope(Info);
3381 FullExpressionRAII Scope(Info);
3394 if (isa<DefaultStmt>(SC)) {
3399 const CaseStmt *CS = cast<CaseStmt>(SC);
3403 if (LHS <= Value && Value <= RHS) {
3410 return ESR_Succeeded;
3415 return ESR_Succeeded;
3421 case ESR_CaseNotFound:
3424 Info.Diag(Found->
getLocStart(), diag::note_constexpr_stmt_expr_unsupported);
3427 llvm_unreachable(
"Invalid EvalStmtResult!");
3433 if (!Info.nextStep(S))
3443 switch (S->getStmtClass()) {
3444 case Stmt::CompoundStmtClass:
3448 case Stmt::LabelStmtClass:
3449 case Stmt::AttributedStmtClass:
3450 case Stmt::DoStmtClass:
3453 case Stmt::CaseStmtClass:
3454 case Stmt::DefaultStmtClass:
3459 case Stmt::IfStmtClass: {
3462 const IfStmt *IS = cast<IfStmt>(
S);
3466 BlockScopeRAII
Scope(Info);
3469 if (ESR != ESR_CaseNotFound || !IS->
getElse())
3474 case Stmt::WhileStmtClass: {
3477 if (ESR != ESR_Continue)
3482 case Stmt::ForStmtClass: {
3483 const ForStmt *FS = cast<ForStmt>(
S);
3486 if (ESR != ESR_Continue)
3489 FullExpressionRAII IncScope(Info);
3496 case Stmt::DeclStmtClass:
3500 return ESR_CaseNotFound;
3504 switch (S->getStmtClass()) {
3506 if (
const Expr *E = dyn_cast<Expr>(S)) {
3509 FullExpressionRAII
Scope(Info);
3512 return ESR_Succeeded;
3515 Info.Diag(S->getLocStart());
3518 case Stmt::NullStmtClass:
3519 return ESR_Succeeded;
3521 case Stmt::DeclStmtClass: {
3523 for (
const auto *DclIt : DS->
decls()) {
3527 FullExpressionRAII
Scope(Info);
3528 if (!
EvaluateDecl(Info, DclIt) && !Info.keepEvaluatingAfterFailure())
3531 return ESR_Succeeded;
3534 case Stmt::ReturnStmtClass: {
3535 const Expr *RetExpr = cast<ReturnStmt>(
S)->getRetValue();
3536 FullExpressionRAII
Scope(Info);
3542 return ESR_Returned;
3545 case Stmt::CompoundStmtClass: {
3546 BlockScopeRAII
Scope(Info);
3549 for (
const auto *BI : CS->
body()) {
3551 if (ESR == ESR_Succeeded)
3553 else if (ESR != ESR_CaseNotFound)
3556 return Case ? ESR_CaseNotFound : ESR_Succeeded;
3559 case Stmt::IfStmtClass: {
3560 const IfStmt *IS = cast<IfStmt>(
S);
3563 BlockScopeRAII
Scope(Info);
3570 if (ESR != ESR_Succeeded)
3573 return ESR_Succeeded;
3576 case Stmt::WhileStmtClass: {
3579 BlockScopeRAII
Scope(Info);
3588 if (ESR != ESR_Continue)
3591 return ESR_Succeeded;
3594 case Stmt::DoStmtClass: {
3595 const DoStmt *DS = cast<DoStmt>(
S);
3599 if (ESR != ESR_Continue)
3603 FullExpressionRAII CondScope(Info);
3607 return ESR_Succeeded;
3610 case Stmt::ForStmtClass: {
3611 const ForStmt *FS = cast<ForStmt>(
S);
3612 BlockScopeRAII
Scope(Info);
3615 if (ESR != ESR_Succeeded)
3619 BlockScopeRAII Scope(Info);
3620 bool Continue =
true;
3628 if (ESR != ESR_Continue)
3632 FullExpressionRAII IncScope(Info);
3637 return ESR_Succeeded;
3640 case Stmt::CXXForRangeStmtClass: {
3642 BlockScopeRAII
Scope(Info);
3646 if (ESR != ESR_Succeeded)
3651 if (ESR != ESR_Succeeded)
3657 bool Continue =
true;
3658 FullExpressionRAII CondExpr(Info);
3666 BlockScopeRAII InnerScope(Info);
3668 if (ESR != ESR_Succeeded)
3673 if (ESR != ESR_Continue)
3681 return ESR_Succeeded;
3684 case Stmt::SwitchStmtClass:
3687 case Stmt::ContinueStmtClass:
3688 return ESR_Continue;
3690 case Stmt::BreakStmtClass:
3693 case Stmt::LabelStmtClass:
3694 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
3696 case Stmt::AttributedStmtClass:
3699 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
3702 case Stmt::CaseStmtClass:
3703 case Stmt::DefaultStmtClass:
3704 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
3714 bool IsValueInitialization) {
3721 if (!CD->
isConstexpr() && !IsValueInitialization) {
3722 if (Info.getLangOpts().CPlusPlus11) {
3725 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
3727 Info.Note(CD->
getLocation(), diag::note_declared_at);
3729 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
3742 if (Info.checkingPotentialConstantExpression() && !Definition &&
3755 if (Info.getLangOpts().CPlusPlus11) {
3756 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
3759 Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1)
3760 << DiagDecl->
isConstexpr() << isa<CXXConstructorDecl>(DiagDecl)
3762 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
3764 Info.Diag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
3774 for (
auto *FD : RD->
fields()) {
3775 if (FD->isUnnamedBitfield())
3779 for (
auto &Base : RD->
bases())
3780 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
3792 bool Success =
true;
3795 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *
I)) {
3798 if (!Info.keepEvaluatingAfterFailure())
3810 EvalInfo &Info,
APValue &Result,
3811 const LValue *ResultSlot) {
3812 ArgVector ArgValues(Args.size());
3816 if (!Info.CheckCallLimit(CallLoc))
3819 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
3828 if (MD && MD->isDefaulted() &&
3829 (MD->getParent()->isUnion() ||
3830 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
3832 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
3834 RHS.setFrom(Info.Ctx, ArgValues[0]);
3842 This->moveInto(Result);
3848 if (ESR == ESR_Succeeded) {
3851 Info.Diag(Callee->
getLocEnd(), diag::note_constexpr_no_return);
3853 return ESR == ESR_Returned;
3860 EvalInfo &Info,
APValue &Result) {
3861 ArgVector ArgValues(Args.size());
3865 if (!Info.CheckCallLimit(CallLoc))
3870 Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD;
3874 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data());
3885 FullExpressionRAII InitScope(Info);
3904 RHS.setFrom(Info.Ctx, ArgValues[0]);
3918 BlockScopeRAII LifetimeExtendedScope(Info);
3920 bool Success =
true;
3921 unsigned BasesSeen = 0;
3925 for (
const auto *I : Definition->
inits()) {
3926 LValue Subobject = This;
3931 if (I->isBaseInitializer()) {
3932 QualType BaseType(I->getBaseClass(), 0);
3936 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
3937 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
3938 "base class initializers not in expected order");
3942 BaseType->getAsCXXRecordDecl(), &Layout))
3945 }
else if ((FD = I->getMember())) {
3957 for (
auto *
C : IFD->chain()) {
3958 FD = cast<FieldDecl>(
C);
3971 std::distance(CD->field_begin(), CD->field_end()));
3981 llvm_unreachable(
"unknown base initializer kind");
3984 FullExpressionRAII InitScope(Info);
3990 if (!Info.keepEvaluatingAfterFailure())
4005 template <
class Derived>
4006 class ExprEvaluatorBase
4009 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
4010 bool DerivedSuccess(
const APValue &V,
const Expr *E) {
4011 return getDerived().Success(V, E);
4013 bool DerivedZeroInitialization(
const Expr *E) {
4014 return getDerived().ZeroInitialization(E);
4020 template<
typename ConditionalOperator>
4022 assert(Info.checkingPotentialConstantExpression());
4027 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4039 Error(E, diag::note_constexpr_conditional_never_const);
4043 template<
typename ConditionalOperator>
4047 if (Info.checkingPotentialConstantExpression())
4048 CheckPotentialConstantConditional(E);
4053 return StmtVisitorTy::Visit(EvalExpr);
4059 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
4062 return Info.CCEDiag(E, D);
4065 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
4068 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
4070 EvalInfo &getEvalInfo() {
return Info; }
4079 return Error(E, diag::note_invalid_subexpr_in_const_expr);
4082 bool VisitStmt(
const Stmt *) {
4083 llvm_unreachable(
"Expression evaluator should not be called on stmts");
4085 bool VisitExpr(
const Expr *E) {
4090 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4092 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4094 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4102 {
return StmtVisitorTy::Visit(E->
getExpr()); }
4107 return StmtVisitorTy::Visit(E->
getExpr());
4112 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4115 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
4116 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4119 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
4120 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4129 VisitIgnoredValue(E->
getLHS());
4130 return StmtVisitorTy::Visit(E->
getRHS());
4140 return DerivedSuccess(Result, E);
4152 return HandleConditionalOperator(E);
4156 bool IsBcpCall =
false;
4163 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
4168 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
4171 FoldConstant Fold(Info, IsBcpCall);
4172 if (!HandleConditionalOperator(E)) {
4173 Fold.keepDiagnostics();
4181 if (
APValue *Value = Info.CurrentCall->getTemporary(E))
4182 return DerivedSuccess(*Value, E);
4188 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
4191 return StmtVisitorTy::Visit(Source);
4194 bool VisitCallExpr(
const CallExpr *E) {
4196 if (!handleCallExpr(E, Result,
nullptr))
4198 return DerivedSuccess(Result, E);
4202 const LValue *ResultSlot) {
4207 LValue *This =
nullptr, ThisVal;
4209 bool HasQualifier =
false;
4214 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
4218 Member = ME->getMemberDecl();
4220 HasQualifier = ME->hasQualifier();
4221 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
4224 if (!Member)
return false;
4227 return Error(Callee);
4231 return Error(Callee);
4237 if (!Call.getLValueOffset().isZero())
4238 return Error(Callee);
4239 FD = dyn_cast_or_null<FunctionDecl>(
4240 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
4242 return Error(Callee);
4257 Args = Args.slice(1);
4266 if (This && !This->checkSubobject(Info, E, CSK_This))
4271 if (This && !HasQualifier &&
4272 isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
4273 return Error(E, diag::note_constexpr_virtual_call);
4291 return DerivedZeroInitialization(E);
4293 return StmtVisitorTy::Visit(E->
getInit(0));
4297 return DerivedZeroInitialization(E);
4300 return DerivedZeroInitialization(E);
4303 return DerivedZeroInitialization(E);
4308 assert(!E->
isArrow() &&
"missing call to bound member function?");
4317 if (!FD)
return Error(E);
4322 CompleteObject Obj(&Val, BaseTy);
4328 DerivedSuccess(Result, E);
4331 bool VisitCastExpr(
const CastExpr *E) {
4340 return DerivedSuccess(AtomicVal, E);
4345 return StmtVisitorTy::Visit(E->
getSubExpr());
4356 return DerivedSuccess(RVal, E);
4364 return VisitUnaryPostIncDec(UO);
4367 return VisitUnaryPostIncDec(UO);
4370 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4380 return DerivedSuccess(RVal, UO);
4383 bool VisitStmtExpr(
const StmtExpr *E) {
4386 if (Info.checkingForOverflow())
4389 BlockScopeRAII
Scope(Info);
4398 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
4400 Info.Diag((*BI)->getLocStart(),
4401 diag::note_constexpr_stmt_expr_unsupported);
4404 return this->
Visit(FinalExpr);
4408 StmtResult Result = { ReturnValue,
nullptr };
4410 if (ESR != ESR_Succeeded) {
4414 if (ESR != ESR_Failed)
4415 Info.Diag((*BI)->getLocStart(),
4416 diag::note_constexpr_stmt_expr_unsupported);
4421 llvm_unreachable(
"Return from function from the loop above.");
4425 void VisitIgnoredValue(
const Expr *E) {
4436 template<
class Derived>
4437 class LValueExprEvaluatorBase
4438 :
public ExprEvaluatorBase<Derived> {
4441 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
4442 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
4450 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
4451 ExprEvaluatorBaseTy(Info), Result(Result) {}
4454 Result.setFrom(this->Info.Ctx, V);
4470 EvalOK = this->Visit(E->
getBase());
4474 if (!this->Info.allowInvalidBaseExpr())
4476 Result.setInvalid(E);
4491 return this->
Error(E);
4506 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
4514 bool VisitCastExpr(
const CastExpr *E) {
4517 return ExprEvaluatorBaseTy::VisitCastExpr(E);
4565 class LValueExprEvaluator
4566 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
4568 LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
4569 LValueExprEvaluatorBaseTy(Info, Result) {}
4571 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
4588 return VisitUnaryPreIncDec(UO);
4591 return VisitUnaryPreIncDec(UO);
4596 bool VisitCastExpr(
const CastExpr *E) {
4599 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
4602 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
4605 Result.Designator.setInvalid();
4625 return LValueExprEvaluator(Info, Result).Visit(E);
4628 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
4632 return VisitVarDecl(E, VD);
4636 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
4637 CallStackFrame *Frame =
nullptr;
4639 Frame = Info.CurrentCall;
4643 Result.set(VD, Frame->Index);
4653 if (!Info.checkingPotentialConstantExpression())
4654 Info.Diag(E, diag::note_constexpr_use_uninit_reference);
4660 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
4666 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
4669 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++
I)
4678 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
4682 Value = &Info.CurrentCall->
4684 Result.set(E, Info.CurrentCall->Index);
4698 for (
unsigned I = Adjustments.size(); I != 0; ) {
4700 switch (Adjustments[I].
Kind) {
4701 case SubobjectAdjustment::DerivedToBaseAdjustment:
4705 Type = Adjustments[
I].DerivedToBase.BasePath->getType();
4708 case SubobjectAdjustment::FieldAdjustment:
4711 Type = Adjustments[
I].Field->getType();
4714 case SubobjectAdjustment::MemberPointerAdjustment:
4716 Adjustments[I].Ptr.RHS))
4718 Type = Adjustments[
I].Ptr.MPT->getPointeeType();
4728 assert(!Info.getLangOpts().CPlusPlus &&
"lvalue compound literal in c++?");
4734 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
4738 Info.Diag(E, diag::note_constexpr_typeid_polymorphic)
4744 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
4748 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
4751 VisitIgnoredValue(E->
getBase());
4752 return VisitVarDecl(E, VD);
4757 if (MD->isStatic()) {
4758 VisitIgnoredValue(E->
getBase());
4764 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
4783 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
4787 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
4796 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
4798 "lvalue __imag__ on scalar?");
4805 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
4806 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4817 bool LValueExprEvaluator::VisitCompoundAssignOperator(
4819 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4825 if (!this->Visit(CAO->
getLHS())) {
4826 if (Info.keepEvaluatingAfterFailure())
4840 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
4841 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4846 if (!this->Visit(E->
getLHS())) {
4847 if (Info.keepEvaluatingAfterFailure())
4864 class PointerExprEvaluator
4865 :
public ExprEvaluatorBase<PointerExprEvaluator> {
4874 PointerExprEvaluator(EvalInfo &info, LValue &Result)
4875 : ExprEvaluatorBaseTy(info), Result(Result) {}
4878 Result.setFrom(Info.Ctx, V);
4881 bool ZeroInitialization(
const Expr *E) {
4886 bool VisitCastExpr(
const CastExpr* E);
4894 bool VisitCallExpr(
const CallExpr *E);
4895 bool VisitBlockExpr(
const BlockExpr *E) {
4902 if (Info.checkingPotentialConstantExpression())
4904 if (!Info.CurrentCall->This) {
4905 if (Info.getLangOpts().CPlusPlus11)
4906 Info.Diag(E, diag::note_constexpr_this) << E->
isImplicit();
4911 Result = *Info.CurrentCall->This;
4921 return PointerExprEvaluator(Info, Result).Visit(E);
4924 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
4927 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
4932 std::swap(PExp, IExp);
4935 if (!EvalPtrOK && !Info.keepEvaluatingAfterFailure())
4944 AdditionalOffset = -AdditionalOffset;
4951 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
4955 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr* E) {
4967 if (!Visit(SubExpr))
4973 Result.Designator.setInvalid();
4975 CCEDiag(E, diag::note_constexpr_invalid_cast)
4978 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
4986 if (!Result.Base && Result.Offset.isZero())
4992 castAs<PointerType>()->getPointeeType(),
4998 if (!Result.Base && Result.Offset.isZero())
5004 return ZeroInitialization(E);
5007 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5013 if (Value.
isInt()) {
5014 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
5015 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
5016 Result.Base = (
Expr*)
nullptr;
5017 Result.InvalidBase =
false;
5018 Result.Offset = CharUnits::fromQuantity(N);
5019 Result.CallIndex = 0;
5020 Result.Designator.setInvalid();
5024 Result.setFrom(Info.Ctx, Value);
5033 Result.set(SubExpr, Info.CurrentCall->Index);
5034 if (!
EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr,
false),
5035 Info, Result, SubExpr))
5040 = Info.Ctx.getAsConstantArrayType(SubExpr->
getType()))
5041 Result.addArray(Info, E, CAT);
5043 Result.Designator.setInvalid();
5050 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5061 return Info.Ctx.toCharUnitsFromBits(
5062 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
5074 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
5075 return Info.Ctx.getDeclAlign(DRE->getDecl(),
5078 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
5079 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
5085 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
5090 case Builtin::BI__builtin_addressof:
5092 case Builtin::BI__builtin_assume_aligned: {
5099 LValue OffsetResult(Result);
5111 OffsetResult.Offset += CharUnits::fromQuantity(AdditionalOffset);
5115 if (OffsetResult.Base) {
5118 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
5119 BaseAlignment = Info.Ctx.getDeclAlign(VD);
5125 if (BaseAlignment < Align) {
5126 Result.Designator.setInvalid();
5130 diag::note_constexpr_baa_insufficient_alignment) << 0
5131 << (
int) BaseAlignment.getQuantity()
5138 if (OffsetResult.Offset.RoundUpToAlignment(Align) != OffsetResult.Offset) {
5139 Result.Designator.setInvalid();
5140 APSInt
Offset(64,
false);
5141 Offset = OffsetResult.Offset.getQuantity();
5143 if (OffsetResult.Base)
5145 diag::note_constexpr_baa_insufficient_alignment) << 1
5149 diag::note_constexpr_baa_value_insufficient_alignment)
5158 return ExprEvaluatorBaseTy::VisitCallExpr(E);
5167 class MemberPointerExprEvaluator
5168 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
5172 Result = MemberPtr(D);
5177 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
5178 : ExprEvaluatorBaseTy(Info), Result(Result) {}
5184 bool ZeroInitialization(
const Expr *E) {
5188 bool VisitCastExpr(
const CastExpr *E);
5196 return MemberPointerExprEvaluator(Info, Result).Visit(E);
5199 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5202 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5206 return ZeroInitialization(E);
5216 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
5218 PathI != PathE; ++PathI) {
5219 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5220 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
5221 if (!Result.castToDerived(Derived))
5234 PathE = E->
path_end(); PathI != PathE; ++PathI) {
5235 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5236 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
5237 if (!Result.castToBase(Base))
5244 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5255 class RecordExprEvaluator
5256 :
public ExprEvaluatorBase<RecordExprEvaluator> {
5261 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
5262 : ExprEvaluatorBaseTy(info), This(This), Result(Result) {}
5268 bool ZeroInitialization(
const Expr *E);
5270 bool VisitCallExpr(
const CallExpr *E) {
5271 return handleCallExpr(E, Result, &This);
5273 bool VisitCastExpr(
const CastExpr *E);
5289 const LValue &This,
APValue &Result) {
5290 assert(!RD->
isUnion() &&
"Expected non-union class type");
5301 End = CD->bases_end(); I !=
End; ++
I, ++Index) {
5302 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
5303 LValue Subobject = This;
5307 Result.getStructBase(Index)))
5312 for (
const auto *I : RD->
fields()) {
5314 if (I->getType()->isReferenceType())
5317 LValue Subobject = This;
5323 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
5330 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E) {
5342 LValue Subobject = This;
5350 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
5351 Info.Diag(E, diag::note_constexpr_virtual_base) << RD;
5358 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5361 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5375 APValue *Value = &DerivedObject;
5378 PathE = E->
path_end(); PathI != PathE; ++PathI) {
5379 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
5380 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
5390 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5409 LValue Subobject = This;
5414 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
5415 isa<CXXDefaultInitExpr>(InitExpr));
5420 assert((!isa<CXXRecordDecl>(RD) || !cast<CXXRecordDecl>(RD)->getNumBases()) &&
5421 "initializer list for class with base classes");
5424 unsigned ElementNo = 0;
5426 for (
const auto *Field : RD->
fields()) {
5432 LValue Subobject = This;
5439 Subobject, Field, &Layout))
5445 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
5448 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
5449 isa<CXXDefaultInitExpr>(Init));
5454 FieldVal, Field))) {
5455 if (!Info.keepEvaluatingAfterFailure())
5464 bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
5482 return ZeroInitialization(E);
5494 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
5495 return Visit(ME->GetTemporaryExpr());
5497 if (ZeroInit && !ZeroInitialization(E))
5502 cast<CXXConstructorDecl>(Definition), Info,
5506 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
5516 Array.addArray(Info, E, ArrayType);
5525 if (!Field->getType()->isPointerType() ||
5526 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
5537 if (Field->getType()->isPointerType() &&
5538 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
5543 ArrayType->
getSize().getZExtValue()))
5546 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
5559 APValue &Result, EvalInfo &Info) {
5561 "can't evaluate expression as a record rvalue");
5562 return RecordExprEvaluator(Info, This, Result).Visit(E);
5573 class TemporaryExprEvaluator
5574 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
5576 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
5577 LValueExprEvaluatorBaseTy(Info, Result) {}
5580 bool VisitConstructExpr(
const Expr *E) {
5581 Result.set(E, Info.CurrentCall->Index);
5586 bool VisitCastExpr(
const CastExpr *E) {
5589 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
5596 return VisitConstructExpr(E);
5599 return VisitConstructExpr(E);
5601 bool VisitCallExpr(
const CallExpr *E) {
5602 return VisitConstructExpr(E);
5605 return VisitConstructExpr(E);
5613 return TemporaryExprEvaluator(Info, Result).Visit(E);
5621 class VectorExprEvaluator
5622 :
public ExprEvaluatorBase<VectorExprEvaluator> {
5626 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
5627 : ExprEvaluatorBaseTy(info), Result(Result) {}
5632 Result =
APValue(V.data(), V.size());
5640 bool ZeroInitialization(
const Expr *E);
5644 bool VisitCastExpr(
const CastExpr* E);
5655 return VectorExprEvaluator(Info, Result).Visit(E);
5658 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5672 Val =
APValue(std::move(IntResult));
5674 APFloat FloatResult(0.0);
5677 Val =
APValue(std::move(FloatResult));
5684 return Success(Elts, E);
5688 llvm::APInt SValInt;
5693 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
5694 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
5697 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
5698 unsigned FloatEltSize = EltSize;
5699 if (&Sem == &APFloat::x87DoubleExtended)
5701 for (
unsigned i = 0; i < NElts; i++) {
5704 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
5706 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
5707 Elts.push_back(
APValue(APFloat(Sem, Elt)));
5710 for (
unsigned i = 0; i < NElts; i++) {
5713 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
5715 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
5721 return Success(Elts, E);
5724 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5729 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5741 unsigned CountInits = 0, CountElts = 0;
5742 while (CountElts < NumElements) {
5744 if (CountInits < NumInits
5750 for (
unsigned j = 0; j < vlen; j++)
5754 llvm::APSInt sInt(32);
5755 if (CountInits < NumInits) {
5759 sInt = Info.Ctx.MakeIntValue(0, EltTy);
5760 Elements.push_back(
APValue(sInt));
5763 llvm::APFloat f(0.0);
5764 if (CountInits < NumInits) {
5768 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
5769 Elements.push_back(
APValue(f));
5774 return Success(Elements, E);
5778 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
5782 if (EltTy->isIntegerType())
5783 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
5786 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
5789 return Success(Elements, E);
5792 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
5794 return ZeroInitialization(E);
5802 class ArrayExprEvaluator
5803 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
5808 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
5809 : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
5813 "expected array or string literal");
5818 bool ZeroInitialization(
const Expr *E) {
5820 Info.Ctx.getAsConstantArrayType(E->
getType());
5825 CAT->
getSize().getZExtValue());
5826 if (!Result.hasArrayFiller())
return true;
5829 LValue Subobject = This;
5830 Subobject.addArray(Info, E, CAT);
5832 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
5835 bool VisitCallExpr(
const CallExpr *E) {
5836 return handleCallExpr(E, Result, &This);
5841 const LValue &Subobject,
5847 APValue &Result, EvalInfo &Info) {
5849 return ArrayExprEvaluator(Info, This, Result).Visit(E);
5852 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5865 return Success(Val, E);
5868 bool Success =
true;
5870 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
5871 "zero-initialized array shouldn't have any initialized elts");
5873 if (Result.isArray() && Result.hasArrayFiller())
5877 unsigned NumElts = CAT->
getSize().getZExtValue();
5882 if (NumEltsToInit != NumElts && !isa<ImplicitValueInitExpr>(FillerExpr))
5883 NumEltsToInit = NumElts;
5890 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I !=
E; ++
I)
5891 Result.getArrayInitializedElt(I) = Filler;
5892 if (Result.hasArrayFiller())
5896 LValue Subobject = This;
5897 Subobject.addArray(Info, E, CAT);
5898 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
5902 Info, Subobject, Init) ||
5905 if (!Info.keepEvaluatingAfterFailure())
5911 if (!Result.hasArrayFiller())
5916 assert(FillerExpr &&
"no array filler for incomplete init list");
5918 FillerExpr) && Success;
5921 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
5922 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
5926 const LValue &Subobject,
5929 bool HadZeroInit = !Value->
isUninit();
5932 unsigned N = CAT->
getSize().getZExtValue();
5942 for (
unsigned I = 0; I != N; ++
I)
5946 LValue ArrayElt = Subobject;
5947 ArrayElt.addArray(Info, E, CAT);
5948 for (
unsigned I = 0; I != N; ++
I)
5979 if (ZeroInit && !HadZeroInit) {
5987 cast<CXXConstructorDecl>(Definition),
6000 class IntExprEvaluator
6001 :
public ExprEvaluatorBase<IntExprEvaluator> {
6004 IntExprEvaluator(EvalInfo &info,
APValue &result)
6005 : ExprEvaluatorBaseTy(info), Result(result) {}
6007 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
6009 "Invalid evaluation result.");
6011 "Invalid evaluation result.");
6012 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
6013 "Invalid evaluation result.");
6017 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
6018 return Success(SI, E, Result);
6021 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
6023 "Invalid evaluation result.");
6024 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
6025 "Invalid evaluation result.");
6027 Result.
getInt().setIsUnsigned(
6031 bool Success(
const llvm::APInt &I,
const Expr *E) {
6032 return Success(I, E, Result);
6035 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
6037 "Invalid evaluation result.");
6041 bool Success(uint64_t Value,
const Expr *E) {
6042 return Success(Value, E, Result);
6054 return Success(V.
getInt(),
E);
6057 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
6070 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
6072 if (CheckReferencedDecl(E, E->
getDecl()))
6075 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
6079 VisitIgnoredValue(E->
getBase());
6083 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
6086 bool VisitCallExpr(
const CallExpr *E);
6091 bool VisitCastExpr(
const CastExpr* E);
6104 return ZeroInitialization(E);
6126 bool TryEvaluateBuiltinObjectSize(
const CallExpr *E,
unsigned Type);
6142 return IntExprEvaluator(Info, Result).Visit(E);
6152 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
6162 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
6166 bool SameSign = (ECD->getInitVal().isSigned()
6168 bool SameWidth = (ECD->getInitVal().getBitWidth()
6169 == Info.Ctx.getIntWidth(E->
getType()));
6170 if (SameSign && SameWidth)
6171 return Success(ECD->getInitVal(),
E);
6175 llvm::APSInt Val = ECD->getInitVal();
6177 Val.setIsSigned(!ECD->getInitVal().isSigned());
6179 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
6180 return Success(Val, E);
6191 enum gcc_type_class {
6193 void_type_class, integer_type_class, char_type_class,
6194 enumeral_type_class, boolean_type_class,
6195 pointer_type_class, reference_type_class, offset_type_class,
6196 real_type_class, complex_type_class,
6197 function_type_class, method_type_class,
6198 record_type_class, union_type_class,
6199 array_type_class, string_type_class,
6206 return no_type_class;
6210 return void_type_class;
6212 return enumeral_type_class;
6214 return boolean_type_class;
6216 return string_type_class;
6218 return integer_type_class;
6220 return pointer_type_class;
6222 return reference_type_class;
6224 return real_type_class;
6226 return complex_type_class;
6228 return function_type_class;
6230 return record_type_class;
6232 return union_type_class;
6234 return array_type_class;
6236 return union_type_class;
6238 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6246 template<
typename LValue>
6248 const Expr *E = LV.getLValueBase().template dyn_cast<
const Expr*>();
6249 return E && isa<StringLiteral>(
E) && LV.getLValueOffset().isZero();
6276 if (V.
getKind() == APValue::Int)
6278 if (V.
getKind() == APValue::LValue)
6285 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
6300 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
6302 }
else if (
const Expr *E = B.get<
const Expr*>()) {
6303 if (isa<CompoundLiteralExpr>(E))
6320 auto *Cast = dyn_cast<
CastExpr>(NoParens);
6321 if (Cast ==
nullptr)
6331 auto *SubExpr = Cast->getSubExpr();
6350 assert(!LVal.Designator.Invalid);
6352 auto IsLastFieldDecl = [&Ctx](
const FieldDecl *FD) {
6359 auto &Base = LVal.getLValueBase();
6360 if (
auto *ME = dyn_cast_or_null<MemberExpr>(Base.dyn_cast<
const Expr *>())) {
6361 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
6362 if (!IsLastFieldDecl(FD))
6364 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
6365 for (
auto *FD : IFD->chain())
6366 if (!IsLastFieldDecl(cast<FieldDecl>(FD)))
6372 for (
int I = 0, E = LVal.Designator.Entries.size(); I !=
E; ++
I) {
6378 auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
6379 uint64_t Index = LVal.Designator.Entries[
I].ArrayIndex;
6380 if (Index + 1 != CAT->
getSize())
6385 uint64_t Index = LVal.Designator.Entries[
I].ArrayIndex;
6389 }
else if (
auto *FD = getAsField(LVal.Designator.Entries[I])) {
6390 if (!IsLastFieldDecl(FD))
6394 assert(getAsBaseClass(LVal.Designator.Entries[I]) !=
nullptr &&
6395 "Expecting cast to a base class");
6404 if (LVal.Designator.Invalid || !LVal.Designator.Entries.empty())
6407 if (!LVal.InvalidBase)
6410 auto *E = LVal.Base.dyn_cast<
const Expr *>();
6412 assert(E !=
nullptr && isa<MemberExpr>(E));
6422 EvalInfo &Info, uint64_t &Size,
6423 bool *WasError =
nullptr) {
6424 if (WasError !=
nullptr)
6428 if (WasError !=
nullptr)
6433 auto Success = [&](uint64_t
S,
const Expr *
E) {
6444 SpeculativeEvaluationRAII SpeculativeEval(Info);
6445 FoldOffsetRAII Fold(Info, Type & 1);
6453 Base.setFrom(Info.Ctx, RVal);
6458 CharUnits BaseOffset = Base.getLValueOffset();
6462 return Success(0, E);
6479 if (Base.InvalidBase && !SubobjectOnly)
6489 if (!SubobjectOnly || (End.Designator.Invalid && Type == 1)) {
6492 End.Designator.setInvalid();
6494 End.Designator = SubobjectDesignator(T);
6495 End.Offset = CharUnits::Zero();
6502 if (End.Designator.Invalid)
6508 int64_t AmountToAdd = 1;
6509 if (End.Designator.MostDerivedIsArrayElement &&
6510 End.Designator.Entries.size() == End.Designator.MostDerivedPathLength) {
6512 AmountToAdd = End.Designator.MostDerivedArraySize -
6513 End.Designator.Entries.back().ArrayIndex;
6514 }
else if (End.Designator.isOnePastTheEnd()) {
6519 QualType PointeeType = End.Designator.MostDerivedType;
6520 assert(!PointeeType.
isNull());
6528 auto EndOffset = End.getLValueOffset();
6540 if (End.InvalidBase && SubobjectOnly && Type == 1 &&
6541 End.Designator.Entries.size() == End.Designator.MostDerivedPathLength &&
6542 End.Designator.MostDerivedIsArrayElement &&
6543 End.Designator.MostDerivedArraySize < 2 &&
6547 if (BaseOffset > EndOffset)
6548 return Success(0, E);
6550 return Success((EndOffset - BaseOffset).getQuantity(), E);
6553 bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(
const CallExpr *E,
6558 return Success(Size, E);
6564 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
6567 return ExprEvaluatorBaseTy::VisitCallExpr(E);
6569 case Builtin::BI__builtin_object_size: {
6573 assert(Type <= 3 &&
"unexpected type");
6575 if (TryEvaluateBuiltinObjectSize(E, Type))
6579 return Success((Type & 2) ? 0 : -1,
E);
6583 switch (Info.EvalMode) {
6584 case EvalInfo::EM_ConstantExpression:
6585 case EvalInfo::EM_PotentialConstantExpression:
6586 case EvalInfo::EM_ConstantFold:
6587 case EvalInfo::EM_EvaluateForOverflow:
6588 case EvalInfo::EM_IgnoreSideEffects:
6589 case EvalInfo::EM_DesignatorFold:
6592 case EvalInfo::EM_ConstantExpressionUnevaluated:
6593 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
6595 return Success((Type & 2) ? 0 : -1, E);
6599 case Builtin::BI__builtin_bswap16:
6600 case Builtin::BI__builtin_bswap32:
6601 case Builtin::BI__builtin_bswap64: {
6606 return Success(Val.byteSwap(),
E);
6609 case Builtin::BI__builtin_classify_type:
6616 case Builtin::BI__builtin_clz:
6617 case Builtin::BI__builtin_clzl:
6618 case Builtin::BI__builtin_clzll:
6619 case Builtin::BI__builtin_clzs: {
6626 return Success(Val.countLeadingZeros(),
E);
6629 case Builtin::BI__builtin_constant_p:
6632 case Builtin::BI__builtin_ctz:
6633 case Builtin::BI__builtin_ctzl:
6634 case Builtin::BI__builtin_ctzll:
6635 case Builtin::BI__builtin_ctzs: {
6642 return Success(Val.countTrailingZeros(),
E);
6645 case Builtin::BI__builtin_eh_return_data_regno: {
6647 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
6648 return Success(Operand, E);
6651 case Builtin::BI__builtin_expect:
6652 return Visit(E->
getArg(0));
6654 case Builtin::BI__builtin_ffs:
6655 case Builtin::BI__builtin_ffsl:
6656 case Builtin::BI__builtin_ffsll: {
6661 unsigned N = Val.countTrailingZeros();
6662 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
6665 case Builtin::BI__builtin_fpclassify: {
6670 switch (Val.getCategory()) {
6671 case APFloat::fcNaN: Arg = 0;
break;
6672 case APFloat::fcInfinity: Arg = 1;
break;
6673 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
6674 case APFloat::fcZero: Arg = 4;
break;
6676 return Visit(E->
getArg(Arg));
6679 case Builtin::BI__builtin_isinf_sign: {
6682 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
6685 case Builtin::BI__builtin_isinf: {
6688 Success(Val.isInfinity() ? 1 : 0,
E);
6691 case Builtin::BI__builtin_isfinite: {
6694 Success(Val.isFinite() ? 1 : 0,
E);
6697 case Builtin::BI__builtin_isnan: {
6700 Success(Val.isNaN() ? 1 : 0,
E);
6703 case Builtin::BI__builtin_isnormal: {
6706 Success(Val.isNormal() ? 1 : 0,
E);
6709 case Builtin::BI__builtin_parity:
6710 case Builtin::BI__builtin_parityl:
6711 case Builtin::BI__builtin_parityll: {
6716 return Success(Val.countPopulation() % 2,
E);
6719 case Builtin::BI__builtin_popcount:
6720 case Builtin::BI__builtin_popcountl:
6721 case Builtin::BI__builtin_popcountll: {
6726 return Success(Val.countPopulation(),
E);
6729 case Builtin::BIstrlen:
6731 if (Info.getLangOpts().CPlusPlus11)
6732 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
6733 << 0 << 0 <<
"'strlen'";
6735 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
6737 case Builtin::BI__builtin_strlen: {
6745 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
6746 String.getLValueBase().dyn_cast<
const Expr *>())) {
6749 StringRef Str = S->getBytes();
6750 int64_t Off = String.Offset.getQuantity();
6751 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
6752 S->getCharByteWidth() == 1) {
6753 Str = Str.substr(Off);
6755 StringRef::size_type Pos = Str.find(0);
6756 if (Pos != StringRef::npos)
6757 Str = Str.substr(0, Pos);
6759 return Success(Str.size(),
E);
6767 for (uint64_t Strlen = 0; ; ++Strlen) {
6773 return Success(Strlen, E);
6779 case Builtin::BI__atomic_always_lock_free:
6780 case Builtin::BI__atomic_is_lock_free:
6781 case Builtin::BI__c11_atomic_is_lock_free: {
6796 CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
6799 unsigned InlineWidthBits =
6800 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
6801 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
6802 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
6803 Size == CharUnits::One() ||
6805 Expr::NPC_NeverValueDependent))
6808 return Success(1, E);
6811 castAs<PointerType>()->getPointeeType();
6813 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
6815 return Success(1, E);
6820 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
6821 Success(0, E) :
Error(E);
6827 if (!A.getLValueBase())
6828 return !B.getLValueBase();
6829 if (!B.getLValueBase())
6832 if (A.getLValueBase().getOpaqueValue() !=
6833 B.getLValueBase().getOpaqueValue()) {
6843 A.getLValueCallIndex() == B.getLValueCallIndex();
6852 if (!LV.getLValueBase())
6857 if (!LV.getLValueDesignator().Invalid &&
6858 !LV.getLValueDesignator().isOnePastTheEnd())
6863 QualType Ty = getType(LV.getLValueBase());
6870 return LV.getLValueOffset() == Size;
6880 class DataRecursiveIntBinOpEvaluator {
6885 EvalResult() : Failed(false) { }
6887 void swap(EvalResult &RHS) {
6889 Failed = RHS.Failed;
6896 EvalResult LHSResult;
6897 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
6901 : E(J.E), LHSResult(J.LHSResult), Kind(J.Kind),
6902 StoredInfo(J.StoredInfo), OldEvalStatus(J.OldEvalStatus) {
6903 J.StoredInfo =
nullptr;
6906 void startSpeculativeEval(EvalInfo &Info) {
6907 OldEvalStatus = Info.EvalStatus;
6908 Info.EvalStatus.Diag =
nullptr;
6913 StoredInfo->EvalStatus = OldEvalStatus;
6917 EvalInfo *StoredInfo =
nullptr;
6923 IntExprEvaluator &IntEval;
6928 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
6929 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
6944 EvalResult PrevResult;
6945 while (!Queue.empty())
6946 process(PrevResult);
6948 if (PrevResult.Failed)
return false;
6950 FinalResult.swap(PrevResult.Val);
6955 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
6956 return IntEval.Success(Value, E, Result);
6958 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
6959 return IntEval.Success(Value, E, Result);
6962 return IntEval.Error(E);
6965 return IntEval.Error(E, D);
6969 return Info.CCEDiag(E, D);
6973 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
6974 bool &SuppressRHSDiags);
6976 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
6979 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
6980 Result.Failed = !
Evaluate(Result.Val, Info, E);
6985 void process(EvalResult &Result);
6987 void enqueue(
const Expr *E) {
6989 Queue.resize(Queue.size()+1);
6991 Queue.back().Kind = Job::AnyExprKind;
6997 bool DataRecursiveIntBinOpEvaluator::
6998 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
6999 bool &SuppressRHSDiags) {
7002 if (LHSResult.Failed)
7003 return Info.noteSideEffect();
7013 Success(LHSAsBool, E, LHSResult.Val);
7017 LHSResult.Failed =
true;
7021 if (!Info.noteSideEffect())
7027 SuppressRHSDiags =
true;
7036 if (LHSResult.Failed && !Info.keepEvaluatingAfterFailure())
7042 bool DataRecursiveIntBinOpEvaluator::
7043 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
7046 if (RHSResult.Failed)
7048 Result = RHSResult.Val;
7053 bool lhsResult, rhsResult;
7060 return Success(lhsResult || rhsResult, E, Result);
7062 return Success(lhsResult && rhsResult, E, Result);
7069 return Success(rhsResult, E, Result);
7079 if (LHSResult.Failed || RHSResult.Failed)
7082 const APValue &LHSVal = LHSResult.Val;
7083 const APValue &RHSVal = RHSResult.Val;
7089 CharUnits::fromQuantity(RHSVal.
getInt().getZExtValue());
7102 CharUnits::fromQuantity(LHSVal.
getInt().getZExtValue());
7113 if (!LHSExpr || !RHSExpr)
7117 if (!LHSAddrExpr || !RHSAddrExpr)
7121 RHSAddrExpr->getLabel()->getDeclContext())
7123 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
7139 return Success(Value, E, Result);
7142 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
7143 Job &job = Queue.back();
7146 case Job::AnyExprKind: {
7147 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
7148 if (shouldEnqueue(Bop)) {
7149 job.Kind = Job::BinOpKind;
7150 enqueue(Bop->getLHS());
7155 EvaluateExpr(job.E, Result);
7160 case Job::BinOpKind: {
7162 bool SuppressRHSDiags =
false;
7163 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
7167 if (SuppressRHSDiags)
7168 job.startSpeculativeEval(Info);
7169 job.LHSResult.swap(Result);
7170 job.Kind = Job::BinOpVisitedLHSKind;
7175 case Job::BinOpVisitedLHSKind: {
7179 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
7185 llvm_unreachable(
"Invalid Job::Kind!");
7188 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
7192 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
7193 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
7199 ComplexValue LHS, RHS;
7208 LHS.makeComplexFloat();
7209 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
7214 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
7220 RHS.makeComplexFloat();
7221 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
7225 if (LHS.isComplexFloat()) {
7226 APFloat::cmpResult CR_r =
7227 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
7228 APFloat::cmpResult CR_i =
7229 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
7232 return Success((CR_r == APFloat::cmpEqual &&
7233 CR_i == APFloat::cmpEqual),
E);
7236 "Invalid complex comparison.");
7237 return Success(((CR_r == APFloat::cmpGreaterThan ||
7238 CR_r == APFloat::cmpLessThan ||
7239 CR_r == APFloat::cmpUnordered) ||
7240 (CR_i == APFloat::cmpGreaterThan ||
7241 CR_i == APFloat::cmpLessThan ||
7242 CR_i == APFloat::cmpUnordered)), E);
7246 return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
7247 LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
7250 "Invalid compex comparison.");
7251 return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
7252 LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
7259 APFloat RHS(0.0), LHS(0.0);
7262 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
7268 APFloat::cmpResult CR = LHS.compare(RHS);
7272 llvm_unreachable(
"Invalid binary operator!");
7274 return Success(CR == APFloat::cmpLessThan, E);
7276 return Success(CR == APFloat::cmpGreaterThan, E);
7278 return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
7280 return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
7283 return Success(CR == APFloat::cmpEqual, E);
7285 return Success(CR == APFloat::cmpGreaterThan
7286 || CR == APFloat::cmpLessThan
7287 || CR == APFloat::cmpUnordered, E);
7293 LValue LHSValue, RHSValue;
7296 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
7307 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
7309 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr*>();
7310 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr*>();
7311 if (!LHSExpr || !RHSExpr)
7315 if (!LHSAddrExpr || !RHSAddrExpr)
7319 RHSAddrExpr->getLabel()->getDeclContext())
7321 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
7330 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
7331 (!RHSValue.Base && !RHSValue.Offset.isZero()))
7338 LHSValue.Base && RHSValue.Base)
7346 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
7348 (RHSValue.Base && RHSValue.Offset.isZero() &&
7363 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
7364 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
7366 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
7367 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
7374 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
7376 LHSDesignator, RHSDesignator))
7377 CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
7389 if (ElementSize.
isZero()) {
7390 Info.Diag(E, diag::note_constexpr_pointer_subtraction_zero_size)
7404 llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
7406 llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
7408 llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
false);
7409 APSInt TrueResult = (LHS - RHS) / ElemSize;
7410 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
7412 if (Result.extend(65) != TrueResult &&
7415 return Success(Result, E);
7427 CCEDiag(E, diag::note_constexpr_void_comparison);
7437 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
7442 RHSDesignator, WasArrayIndex);
7449 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
7450 Mismatch < RHSDesignator.Entries.size()) {
7451 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
7452 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
7454 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
7456 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
7457 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
7460 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
7461 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
7465 CCEDiag(E, diag::note_constexpr_pointer_comparison_differing_access)
7473 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
7476 assert(PtrSize <= 64 &&
"Unexpected pointer width");
7477 uint64_t Mask = ~0ULL >> (64 - PtrSize);
7485 QualType BaseTy = getType(LHSValue.Base);
7488 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
7490 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
7495 default: llvm_unreachable(
"missing comparison operator");
7496 case BO_LT:
return Success(CompareLHS < CompareRHS, E);
7497 case BO_GT:
return Success(CompareLHS > CompareRHS, E);
7498 case BO_LE:
return Success(CompareLHS <= CompareRHS, E);
7499 case BO_GE:
return Success(CompareLHS >= CompareRHS, E);
7500 case BO_EQ:
return Success(CompareLHS == CompareRHS, E);
7501 case BO_NE:
return Success(CompareLHS != CompareRHS, E);
7507 assert(E->
isEqualityOp() &&
"unexpected member pointer operation");
7510 MemberPtr LHSValue, RHSValue;
7513 if (!LHSOK && Info.keepEvaluatingAfterFailure())
7522 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
7523 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
7529 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
7530 if (MD->isVirtual())
7531 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
7532 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
7533 if (MD->isVirtual())
7534 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
7540 bool Equal = LHSValue == RHSValue;
7546 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
7551 return Success(Opcode ==
BO_EQ || Opcode ==
BO_LE || Opcode ==
BO_GE, E);
7556 "DataRecursiveIntBinOpEvaluator should have handled integral types");
7558 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7563 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
7584 return Success(n, E);
7586 return Success(1, E);
7599 return Success(Sizeof, E);
7604 Info.Ctx.toCharUnitsFromBits(
7610 llvm_unreachable(
"unknown expr/type trait");
7613 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
7619 for (
unsigned i = 0; i != n; ++i) {
7622 case OffsetOfNode::Array: {
7627 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
7631 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
7632 Result += IdxResult.getSExtValue() * ElementSize;
7636 case OffsetOfNode::Field: {
7645 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
7651 case OffsetOfNode::Identifier:
7652 llvm_unreachable(
"dependent __builtin_offsetof");
7654 case OffsetOfNode::Base: {
7668 CurrentType = BaseSpec->
getType();
7679 return Success(Result, OOE);
7682 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
7698 if (!Result.isInt())
return Error(E);
7699 const APSInt &Value = Result.getInt();
7700 if (Value.isSigned() && Value.isMinSignedValue() &&
7704 return Success(-Value, E);
7709 if (!Result.isInt())
return Error(E);
7710 return Success(~Result.getInt(),
E);
7716 return Success(!bres, E);
7723 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7762 llvm_unreachable(
"invalid cast kind for integral value");
7778 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7790 uint64_t IntResult = BoolResult;
7792 IntResult = (uint64_t)-1;
7793 return Success(IntResult, E);
7797 if (!Visit(SubExpr))
7800 if (!Result.isInt()) {
7806 if (Result.isAddrLabelDiff())
7807 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
7809 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
7813 Result.getInt()), E);
7817 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
7823 if (LV.getLValueBase()) {
7828 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
7831 LV.Designator.setInvalid();
7832 LV.moveInto(Result);
7836 APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(),
7845 return Success(C.getComplexIntReal(),
E);
7856 return Success(Value, E);
7860 llvm_unreachable(
"unknown cast resulting in integral value");
7863 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
7868 if (!LV.isComplexInt())
7870 return Success(LV.getComplexIntReal(),
E);
7876 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
7881 if (!LV.isComplexInt())
7883 return Success(LV.getComplexIntImag(),
E);
7887 return Success(0, E);
7890 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
7894 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
7903 class FloatExprEvaluator
7904 :
public ExprEvaluatorBase<FloatExprEvaluator> {
7907 FloatExprEvaluator(EvalInfo &info, APFloat &result)
7908 : ExprEvaluatorBaseTy(info), Result(result) {}
7915 bool ZeroInitialization(
const Expr *E) {
7916 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
7920 bool VisitCallExpr(
const CallExpr *E);
7925 bool VisitCastExpr(
const CastExpr *E);
7936 return FloatExprEvaluator(Info, Result).Visit(E);
7943 llvm::APFloat &Result) {
7945 if (!S)
return false;
7953 fill = llvm::APInt(32, 0);
7954 else if (S->
getString().getAsInteger(0, fill))
7959 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
7961 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
7969 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
7971 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
7977 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
7980 return ExprEvaluatorBaseTy::VisitCallExpr(E);
7982 case Builtin::BI__builtin_huge_val:
7983 case Builtin::BI__builtin_huge_valf:
7984 case Builtin::BI__builtin_huge_vall:
7985 case Builtin::BI__builtin_inf:
7986 case Builtin::BI__builtin_inff:
7987 case Builtin::BI__builtin_infl: {
7988 const llvm::fltSemantics &Sem =
7989 Info.Ctx.getFloatTypeSemantics(E->
getType());
7990 Result = llvm::APFloat::getInf(Sem);
7994 case Builtin::BI__builtin_nans:
7995 case Builtin::BI__builtin_nansf:
7996 case Builtin::BI__builtin_nansl:
8002 case Builtin::BI__builtin_nan:
8003 case Builtin::BI__builtin_nanf:
8004 case Builtin::BI__builtin_nanl:
8012 case Builtin::BI__builtin_fabs:
8013 case Builtin::BI__builtin_fabsf:
8014 case Builtin::BI__builtin_fabsl:
8018 if (Result.isNegative())
8019 Result.changeSign();
8026 case Builtin::BI__builtin_copysign:
8027 case Builtin::BI__builtin_copysignf:
8028 case Builtin::BI__builtin_copysignl: {
8033 Result.copySign(RHS);
8039 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
8044 Result = CV.FloatReal;
8051 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8056 Result = CV.FloatImag;
8061 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
8062 Result = llvm::APFloat::getZero(Sem);
8066 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
8068 default:
return Error(E);
8074 Result.changeSign();
8079 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
8081 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8085 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
8091 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
8096 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8101 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8111 if (!Visit(SubExpr))
8121 Result = V.getComplexFloatReal();
8132 class ComplexExprEvaluator
8133 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
8134 ComplexValue &Result;
8137 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
8138 : ExprEvaluatorBaseTy(info), Result(Result) {}
8145 bool ZeroInitialization(
const Expr *E);
8152 bool VisitCastExpr(
const CastExpr *E);
8162 return ComplexExprEvaluator(Info, Result).Visit(E);
8165 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
8168 Result.makeComplexFloat();
8169 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
8170 Result.FloatReal = Zero;
8171 Result.FloatImag = Zero;
8173 Result.makeComplexInt();
8174 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
8175 Result.IntReal = Zero;
8176 Result.IntImag = Zero;
8181 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
8185 Result.makeComplexFloat();
8186 APFloat &Imag = Result.FloatImag;
8190 Result.FloatReal = APFloat(Imag.getSemantics());
8194 "Unexpected imaginary literal.");
8196 Result.makeComplexInt();
8197 APSInt &Imag = Result.IntImag;
8201 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
8206 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8253 llvm_unreachable(
"invalid cast kind for complex value");
8258 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8266 APFloat &Real = Result.FloatReal;
8270 Result.makeComplexFloat();
8271 Result.FloatImag = APFloat(Real.getSemantics());
8294 Result.makeComplexInt();
8296 To, Result.IntReal) &&
8298 To, Result.IntImag);
8302 APSInt &Real = Result.IntReal;
8306 Result.makeComplexInt();
8307 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
8331 Result.makeComplexFloat();
8333 To, Result.FloatReal) &&
8335 To, Result.FloatImag);
8339 llvm_unreachable(
"unknown cast resulting in complex value");
8342 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
8344 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8348 bool LHSReal =
false, RHSReal =
false;
8353 APFloat &Real = Result.FloatReal;
8356 Result.makeComplexFloat();
8357 Result.FloatImag = APFloat(Real.getSemantics());
8360 LHSOK = Visit(E->
getLHS());
8362 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
8368 APFloat &Real = RHS.FloatReal;
8371 RHS.makeComplexFloat();
8372 RHS.FloatImag = APFloat(Real.getSemantics());
8376 assert(!(LHSReal && RHSReal) &&
8377 "Cannot have both operands of a complex operation be real.");
8379 default:
return Error(E);
8381 if (Result.isComplexFloat()) {
8382 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
8383 APFloat::rmNearestTiesToEven);
8385 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
8387 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
8388 APFloat::rmNearestTiesToEven);
8390 Result.getComplexIntReal() += RHS.getComplexIntReal();
8391 Result.getComplexIntImag() += RHS.getComplexIntImag();
8395 if (Result.isComplexFloat()) {
8396 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
8397 APFloat::rmNearestTiesToEven);
8399 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
8400 Result.getComplexFloatImag().changeSign();
8401 }
else if (!RHSReal) {
8402 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
8403 APFloat::rmNearestTiesToEven);
8406 Result.getComplexIntReal() -= RHS.getComplexIntReal();
8407 Result.getComplexIntImag() -= RHS.getComplexIntImag();
8411 if (Result.isComplexFloat()) {
8416 ComplexValue LHS = Result;
8417 APFloat &A = LHS.getComplexFloatReal();
8418 APFloat &B = LHS.getComplexFloatImag();
8419 APFloat &C = RHS.getComplexFloatReal();
8420 APFloat &D = RHS.getComplexFloatImag();
8421 APFloat &ResR = Result.getComplexFloatReal();
8422 APFloat &ResI = Result.getComplexFloatImag();
8424 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
8427 }
else if (RHSReal) {
8439 if (ResR.isNaN() && ResI.isNaN()) {
8440 bool Recalc =
false;
8441 if (A.isInfinity() || B.isInfinity()) {
8442 A = APFloat::copySign(
8443 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
8444 B = APFloat::copySign(
8445 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
8447 C = APFloat::copySign(APFloat(C.getSemantics()), C);
8449 D = APFloat::copySign(APFloat(D.getSemantics()), D);
8452 if (C.isInfinity() || D.isInfinity()) {
8453 C = APFloat::copySign(
8454 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
8455 D = APFloat::copySign(
8456 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
8458 A = APFloat::copySign(APFloat(A.getSemantics()), A);
8460 B = APFloat::copySign(APFloat(B.getSemantics()), B);
8463 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
8464 AD.isInfinity() || BC.isInfinity())) {
8466 A = APFloat::copySign(APFloat(A.getSemantics()), A);
8468 B = APFloat::copySign(APFloat(B.getSemantics()), B);
8470 C = APFloat::copySign(APFloat(C.getSemantics()), C);
8472 D = APFloat::copySign(APFloat(D.getSemantics()), D);
8476 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
8477 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
8482 ComplexValue LHS = Result;
8483 Result.getComplexIntReal() =
8484 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
8485 LHS.getComplexIntImag() * RHS.getComplexIntImag());
8486 Result.getComplexIntImag() =
8487 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
8488 LHS.getComplexIntImag() * RHS.getComplexIntReal());
8492 if (Result.isComplexFloat()) {
8497 ComplexValue LHS = Result;
8498 APFloat &A = LHS.getComplexFloatReal();
8499 APFloat &B = LHS.getComplexFloatImag();
8500 APFloat &C = RHS.getComplexFloatReal();
8501 APFloat &D = RHS.getComplexFloatImag();
8502 APFloat &ResR = Result.getComplexFloatReal();
8503 APFloat &ResI = Result.getComplexFloatImag();
8510 B = APFloat::getZero(A.getSemantics());
8513 APFloat MaxCD = maxnum(abs(C), abs(D));
8514 if (MaxCD.isFinite()) {
8515 DenomLogB =
ilogb(MaxCD);
8516 C =
scalbn(C, -DenomLogB);
8517 D =
scalbn(D, -DenomLogB);
8519 APFloat Denom = C * C + D * D;
8520 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB);
8521 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB);
8522 if (ResR.isNaN() && ResI.isNaN()) {
8523 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
8524 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
8525 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
8526 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
8528 A = APFloat::copySign(
8529 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
8530 B = APFloat::copySign(
8531 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
8532 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
8533 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
8534 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
8535 C = APFloat::copySign(
8536 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
8537 D = APFloat::copySign(
8538 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
8539 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
8540 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
8545 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
8546 return Error(E, diag::note_expr_divide_by_zero);
8548 ComplexValue LHS = Result;
8549 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
8550 RHS.getComplexIntImag() * RHS.getComplexIntImag();
8551 Result.getComplexIntReal() =
8552 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
8553 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
8554 Result.getComplexIntImag() =
8555 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
8556 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
8564 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
8578 if (Result.isComplexFloat()) {
8579 Result.getComplexFloatReal().changeSign();
8580 Result.getComplexFloatImag().changeSign();
8583 Result.getComplexIntReal() = -Result.getComplexIntReal();
8584 Result.getComplexIntImag() = -Result.getComplexIntImag();
8588 if (Result.isComplexFloat())
8589 Result.getComplexFloatImag().changeSign();
8591 Result.getComplexIntImag() = -Result.getComplexIntImag();
8596 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
8599 Result.makeComplexFloat();
8605 Result.makeComplexInt();
8613 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
8622 class AtomicExprEvaluator :
8623 public ExprEvaluatorBase<AtomicExprEvaluator> {
8626 AtomicExprEvaluator(EvalInfo &Info,
APValue &Result)
8627 : ExprEvaluatorBaseTy(Info), Result(Result) {}
8634 bool ZeroInitialization(
const Expr *E) {
8637 return Evaluate(Result, Info, &VIE);
8640 bool VisitCastExpr(
const CastExpr *E) {
8643 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8653 return AtomicExprEvaluator(Info, Result).Visit(E);
8662 class VoidExprEvaluator
8663 :
public ExprEvaluatorBase<VoidExprEvaluator> {
8665 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
8667 bool Success(
const APValue &V,
const Expr *e) {
return true; }
8669 bool VisitCastExpr(
const CastExpr *E) {
8672 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8679 bool VisitCallExpr(
const CallExpr *E) {
8682 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8683 case Builtin::BI__assume:
8684 case Builtin::BI__builtin_assume:
8694 return VoidExprEvaluator(Info).Visit(E);
8709 LV.moveInto(Result);
8714 if (!IntExprEvaluator(Info, Result).Visit(E))
8720 LV.moveInto(Result);
8722 llvm::APFloat F(0.0);
8739 LV.set(E, Info.CurrentCall->Index);
8740 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
8746 LV.set(E, Info.CurrentCall->Index);
8747 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
8752 if (!Info.getLangOpts().CPlusPlus11)
8753 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
8760 }
else if (Info.getLangOpts().CPlusPlus11) {
8761 Info.Diag(E, diag::note_constexpr_nonliteral) << E->
getType();
8764 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
8775 const Expr *E,
bool AllowNonLiteralTypes) {
8808 LV.setFrom(Info.Ctx, Result);
8823 L->getType()->isUnsignedIntegerType()));
8857 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
8876 if (!
getType()->isIntegralOrEnumerationType())
8884 Result = ExprResult.Val.getInt();
8889 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
8897 LV.moveInto(Result.Val);
8911 EStatus.
Diag = &Notes;
8914 ? EvalInfo::EM_ConstantExpression
8915 : EvalInfo::EM_ConstantFold);
8916 InitInfo.setEvaluatingDecl(VD, Value);
8953 EvalResult.Diag =
Diag;
8956 assert(Result &&
"Could not evaluate expression");
8957 assert(EvalResult.Val.isInt() &&
"Expression did not evaluate to integer");
8959 return EvalResult.Val.getInt();
8966 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
8972 assert(Val.isLValue());
9000 IK_ICEIfUnevaluated,
9016 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
9022 return ICEDiag(IK_NotICE, E->getLocStart());
9030 return ICEDiag(IK_NotICE, E->getLocStart());
9032 switch (E->getStmtClass()) {
9033 #define ABSTRACT_STMT(Node)
9034 #define STMT(Node, Base) case Expr::Node##Class:
9035 #define EXPR(Node, Base)
9036 #include "clang/AST/StmtNodes.inc"
9037 case Expr::PredefinedExprClass:
9038 case Expr::FloatingLiteralClass:
9039 case Expr::ImaginaryLiteralClass:
9040 case Expr::StringLiteralClass:
9041 case Expr::ArraySubscriptExprClass:
9042 case Expr::OMPArraySectionExprClass:
9043 case Expr::MemberExprClass:
9044 case Expr::CompoundAssignOperatorClass:
9045 case Expr::CompoundLiteralExprClass:
9046 case Expr::ExtVectorElementExprClass:
9047 case Expr::DesignatedInitExprClass:
9048 case Expr::NoInitExprClass:
9049 case Expr::DesignatedInitUpdateExprClass:
9050 case Expr::ImplicitValueInitExprClass:
9051 case Expr::ParenListExprClass:
9052 case Expr::VAArgExprClass:
9053 case Expr::AddrLabelExprClass:
9054 case Expr::StmtExprClass:
9055 case Expr::CXXMemberCallExprClass:
9056 case Expr::CUDAKernelCallExprClass:
9057 case Expr::CXXDynamicCastExprClass:
9058 case Expr::CXXTypeidExprClass:
9059 case Expr::CXXUuidofExprClass:
9060 case Expr::MSPropertyRefExprClass:
9061 case Expr::MSPropertySubscriptExprClass:
9062 case Expr::CXXNullPtrLiteralExprClass:
9063 case Expr::UserDefinedLiteralClass:
9064 case Expr::CXXThisExprClass:
9065 case Expr::CXXThrowExprClass:
9066 case Expr::CXXNewExprClass:
9067 case Expr::CXXDeleteExprClass:
9068 case Expr::CXXPseudoDestructorExprClass:
9069 case Expr::UnresolvedLookupExprClass:
9070 case Expr::TypoExprClass:
9071 case Expr::DependentScopeDeclRefExprClass:
9072 case Expr::CXXConstructExprClass:
9073 case Expr::CXXStdInitializerListExprClass:
9074 case Expr::CXXBindTemporaryExprClass:
9075 case Expr::ExprWithCleanupsClass:
9076 case Expr::CXXTemporaryObjectExprClass:
9077 case Expr::CXXUnresolvedConstructExprClass:
9078 case Expr::CXXDependentScopeMemberExprClass:
9079 case Expr::UnresolvedMemberExprClass:
9080 case Expr::ObjCStringLiteralClass:
9081 case Expr::ObjCBoxedExprClass:
9082 case Expr::ObjCArrayLiteralClass:
9083 case Expr::ObjCDictionaryLiteralClass:
9084 case Expr::ObjCEncodeExprClass:
9085 case Expr::ObjCMessageExprClass:
9086 case Expr::ObjCSelectorExprClass:
9087 case Expr::ObjCProtocolExprClass:
9088 case Expr::ObjCIvarRefExprClass:
9089 case Expr::ObjCPropertyRefExprClass:
9090 case Expr::ObjCSubscriptRefExprClass:
9091 case Expr::ObjCIsaExprClass:
9092 case Expr::ShuffleVectorExprClass:
9093 case Expr::ConvertVectorExprClass:
9094 case Expr::BlockExprClass:
9095 case Expr::NoStmtClass:
9096 case Expr::OpaqueValueExprClass:
9097 case Expr::PackExpansionExprClass:
9098 case Expr::SubstNonTypeTemplateParmPackExprClass:
9099 case Expr::FunctionParmPackExprClass:
9100 case Expr::AsTypeExprClass:
9101 case Expr::ObjCIndirectCopyRestoreExprClass:
9102 case Expr::MaterializeTemporaryExprClass:
9103 case Expr::PseudoObjectExprClass:
9104 case Expr::AtomicExprClass:
9105 case Expr::LambdaExprClass:
9106 case Expr::CXXFoldExprClass:
9107 case Expr::CoawaitExprClass:
9108 case Expr::CoyieldExprClass:
9109 return ICEDiag(IK_NotICE, E->getLocStart());
9111 case Expr::InitListExprClass: {
9117 if (cast<InitListExpr>(E)->getNumInits() == 1)
9118 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
9119 return ICEDiag(IK_NotICE, E->getLocStart());
9122 case Expr::SizeOfPackExprClass:
9123 case Expr::GNUNullExprClass:
9127 case Expr::SubstNonTypeTemplateParmExprClass:
9129 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
9131 case Expr::ParenExprClass:
9132 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
9133 case Expr::GenericSelectionExprClass:
9134 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
9135 case Expr::IntegerLiteralClass:
9136 case Expr::CharacterLiteralClass:
9137 case Expr::ObjCBoolLiteralExprClass:
9138 case Expr::CXXBoolLiteralExprClass:
9139 case Expr::CXXScalarValueInitExprClass:
9140 case Expr::TypeTraitExprClass:
9141 case Expr::ArrayTypeTraitExprClass:
9142 case Expr::ExpressionTraitExprClass:
9143 case Expr::CXXNoexceptExprClass:
9145 case Expr::CallExprClass:
9146 case Expr::CXXOperatorCallExprClass: {
9153 return ICEDiag(IK_NotICE, E->getLocStart());
9155 case Expr::DeclRefExprClass: {
9156 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
9164 if (isa<ParmVarDecl>(D))
9165 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
9170 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
9171 if (!Dcl->getType()->isIntegralOrEnumerationType())
9172 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
9180 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
9183 return ICEDiag(IK_NotICE, E->getLocStart());
9185 case Expr::UnaryOperatorClass: {
9198 return ICEDiag(IK_NotICE, E->getLocStart());
9211 case Expr::OffsetOfExprClass: {
9220 case Expr::UnaryExprOrTypeTraitExprClass: {
9224 return ICEDiag(IK_NotICE, E->getLocStart());
9227 case Expr::BinaryOperatorClass: {
9246 return ICEDiag(IK_NotICE, E->getLocStart());
9271 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
9274 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
9275 if (REval.isSigned() && REval.isAllOnesValue()) {
9277 if (LEval.isMinSignedValue())
9278 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
9286 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
9287 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
9290 return ICEDiag(IK_NotICE, E->getLocStart());
9293 return Worst(LHSResult, RHSResult);
9299 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
9309 return Worst(LHSResult, RHSResult);
9313 case Expr::ImplicitCastExprClass:
9314 case Expr::CStyleCastExprClass:
9315 case Expr::CXXFunctionalCastExprClass:
9316 case Expr::CXXStaticCastExprClass:
9317 case Expr::CXXReinterpretCastExprClass:
9318 case Expr::CXXConstCastExprClass:
9319 case Expr::ObjCBridgedCastExprClass: {
9320 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
9321 if (isa<ExplicitCastExpr>(E)) {
9326 APSInt IgnoredVal(DestWidth, !DestSigned);
9331 if (FL->getValue().convertToInteger(IgnoredVal,
9332 llvm::APFloat::rmTowardZero,
9333 &Ignored) & APFloat::opInvalidOp)
9334 return ICEDiag(IK_NotICE, E->getLocStart());
9338 switch (cast<CastExpr>(E)->getCastKind()) {
9347 return ICEDiag(IK_NotICE, E->getLocStart());
9350 case Expr::BinaryConditionalOperatorClass: {
9353 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
9355 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
9356 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
9357 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
9361 case Expr::ConditionalOperatorClass: {
9369 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
9372 if (CondResult.Kind == IK_NotICE)
9378 if (TrueResult.Kind == IK_NotICE)
9380 if (FalseResult.Kind == IK_NotICE)
9382 if (CondResult.Kind == IK_ICEIfUnevaluated)
9384 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
9393 case Expr::CXXDefaultArgExprClass:
9394 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
9395 case Expr::CXXDefaultInitExprClass:
9396 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
9397 case Expr::ChooseExprClass: {
9398 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
9402 llvm_unreachable(
"Invalid StmtClass!");
9408 llvm::APSInt *Value,
9419 if (!Result.
isInt()) {
9424 if (Value) *Value = Result.
getInt();
9434 if (D.Kind != IK_ICE) {
9435 if (Loc) *Loc = D.Loc;
9453 llvm_unreachable(
"ICE cannot be evaluated!");
9458 return CheckICE(
this, Ctx).Kind == IK_ICE;
9470 Status.Diag = &Diags;
9471 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
9476 if (!Diags.empty()) {
9477 IsConstExpr =
false;
9478 if (Loc) *Loc = Diags[0].first;
9479 }
else if (!IsConstExpr) {
9491 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
9493 ArgVector ArgValues(Args.size());
9496 if ((*I)->isValueDependent() ||
9497 !
Evaluate(ArgValues[I - Args.begin()], Info, *
I))
9499 ArgValues[I - Args.begin()] =
APValue();
9500 if (Info.EvalStatus.HasSideEffects)
9505 CallStackFrame Frame(Info, Callee->
getLocation(), Callee,
nullptr,
9507 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
9520 Status.
Diag = &Diags;
9523 EvalInfo::EM_PotentialConstantExpression);
9532 This.set(&VIE, Info.CurrentCall->Index);
9542 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
9546 Args, FD->
getBody(), Info, Scratch,
nullptr);
9548 return Diags.empty();
9556 Status.
Diag = &Diags;
9559 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
9563 ArgVector ArgValues(0);
9567 "Failed to set up arguments for potential constant evaluation");
9568 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
9572 return Diags.empty();
9576 unsigned Type)
const {
9577 if (!
getType()->isPointerType())
9581 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
unsigned getNumElements() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
APValue & Value
The APValue that should be filled in with the returned value.
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
Defines the clang::ASTContext interface.
unsigned getNumInits() const
const SwitchCase * getNextSwitchCase() const
CastKind getCastKind() const
The null pointer literal (C++11 [lex.nullptr])
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
CK_LValueToRValue - A conversion which causes the extraction of an r-value from the operand gl-value...
Expr ** getArgs()
Retrieve the call arguments.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
bool isNullPtrType() const
const FieldDecl * getUnionField() const
ParmVarDecl *const * param_const_iterator
static bool IsGlobalLValue(APValue::LValueBase B)
PointerType - C99 6.7.5.1 - Pointer Declarators.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
A (possibly-)qualified type.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool isBitField() const
Determines whether this field is a bitfield.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
bool isMemberPointerType() const
QualType getType() const
Retrieves the type of the base class.
bool isElidable() const
Whether this construction is elidable.
bool operator==(CanQual< T > x, CanQual< U > y)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
CompoundStmt * getSubStmt()
bool isArgumentType() const
IfStmt - This represents an if/then/else.
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
unsigned getIntWidth(QualType T) const
SourceLocation getLocStart() const LLVM_READONLY
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
void addConst()
Add the const type qualifier to this QualType.
ActionResult< Expr * > ExprResult
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
TypeSourceInfo * getTypeSourceInfo() const
bool isRecordType() const
unsigned getPackLength() const
Retrieve the length of the parameter pack.
CK_ToUnion - The GCC cast-to-union extension.
Decl - This represents one declaration (or definition), e.g.
chain_range chain() const
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
bool isVoidPointerType() const
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
bool isEnumeralType() const
ParenExpr - This represents a parethesized expression, e.g.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result)
Extract the designated sub-object of an rvalue.
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
The base class of the type hierarchy.
bool isMemberPointer() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
CK_BaseToDerivedMemberPointer - Member pointer in base class to member pointer in derived class...
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static bool IsConstNonVolatile(QualType T)
std::unique_ptr< llvm::MemoryBuffer > Buffer
void * BaseOrMember
BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item in the path.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getResultExpr() const
The generic selection's result expression.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
bool hasLValuePath() const
Represents a call to a C++ constructor.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
CK_FloatingToIntegral - Floating point to integral.
bool isBooleanType() const
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue...
llvm::DenseMap< Stmt *, Stmt * > MapTy
const Stmt * getElse() const
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
SourceLocation getLocEnd() const LLVM_READONLY
[ARC] Consumes a retainable object pointer that has just been produced, e.g.
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
Represents a C++ constructor within a class.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
const llvm::APInt & getSize() const
CK_IntegralToFloating - Integral to floating point.
Expr * getIndexExpr(unsigned Idx)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
const CXXBaseSpecifier *const * path_const_iterator
VarDecl - An instance of this class is created to represent a variable declaration or definition...
CK_IntegralCast - A cast between integral types (other than to boolean).
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
EvaluateInPlace - Evaluate an expression in-place in an APValue.
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getCallee() const
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
APFloat & getComplexFloatReal()
bool hasCaptures() const
hasCaptures - True if this block (or its nested blocks) captures anything of local storage from its e...
AccessSpecifier getAccess() const
field_iterator field_begin() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CK_Dynamic - A C++ dynamic_cast.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
UnaryExprOrTypeTrait getKind() const
CK_Dependent - A conversion which cannot yet be analyzed because either the expression or target type...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
unsigned getValue() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
static bool isAssignmentOp(Opcode Opc)
ParmVarDecl - Represents a parameter to a function.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant...
unsigned path_size() const
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
The collection of all-type qualifiers we support.
static bool HasSameBase(const LValue &A, const LValue &B)
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
RecordDecl - Represents a struct/union/class.
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size)
Get the size of the given type in char units.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
bool isComplexInt() const
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Converts between different integral complex types.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isReferenceType() const
QualType getReturnType() const
bool isStructureOrClassType() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Converting between two Objective-C object types, which can occur when performing reference binding to...
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info)
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
CK_FloatingCast - Casting between floating types of different size.
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr...
[ARC] Causes a value of block type to be copied to the heap, if it is not already there...
CK_VectorSplat - A conversion from an arithmetic type to a vector of that element type...
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Perform zero-initialization on an object of non-union class type.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
CK_NullToPointer - Null pointer constant to pointer, ObjC pointer, or block pointer.
CK_PointerToIntegral - Pointer to integral.
CK_IntegralToPointer - Integral to pointer.
unsigned getLValueCallIndex() const
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression as an lvalue.
static bool isRelationalOp(Opcode Opc)
Converts a floating point complex to bool by comparing against 0+0i.
static bool IsWeakLValue(const LValue &Value)
A location where the result (returned value) of evaluating a statement should be stored.
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
Describes an C or C++ initializer list.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
CK_IntegralToBoolean - Integral to boolean.
uint32_t getCodeUnit(size_t i) const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for TryEvaluateBuiltinObjectSize. ...
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
ForStmt - This represents a 'for (init;cond;inc)' stmt.
static bool isEqualityOp(Opcode Opc)
const TargetInfo & getTargetInfo() const
static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, llvm::APInt &Res)
const LangOptions & getLangOpts() const
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a designator (that isn't necessarily valid).
unsigned getLength() const
CharUnits - This is an opaque type for sizes expressed in character units.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
APValue Val
Val - This is the value the expression can be folded to.
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal)
Perform an lvalue-to-rvalue conversion on the given glvalue.
const TemplateArgument & getArg(unsigned Idx) const
Retrieve a specific template argument as a type.
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
bool isDefaulted() const
Whether this function is defaulted per C++0x.
Expr * getExprOperand() const
path_iterator path_begin()
field_range fields() const
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue...
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, int64_t Adjustment)
Update a pointer value to model pointer arithmetic.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
static bool isRecordType(QualType T)
A builtin binary operation expression such as "x + y" or "x <= y".
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
RecordDecl * getDecl() const
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
ObjCStringLiteral, used for Objective-C string literals i.e.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
Scope - A scope is a transient data structure that is used while parsing the program.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
base_class_iterator bases_begin()
Helper class for OffsetOfExpr.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
Update an lvalue to refer to a component of a complex number.
static void expandArray(APValue &Array, unsigned Index)
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
APSInt & getComplexIntReal()
init_iterator init_begin()
Retrieve an iterator to the first initializer.
A default argument (C++ [dcl.fct.default]).
static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
bool isUnnamedBitfield() const
Determines whether this is an unnamed bitfield.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, SourceLocation *Loc=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
Represents the this expression in C++.
DiagnosticsEngine & getDiagnostics() const
field_iterator field_end() const
APValue & getVectorElt(unsigned I)
CK_AnyPointerToBlockPointerCast - Casting any non-block pointer to a block pointer.
bool isAddrLabelDiff() const
ConditionalOperator - The ?: ternary operator.
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type...
Expr * getFalseExpr() const
llvm::APInt getValue() const
static bool handleCompoundAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
CompoundStmt - This represents a group of statements like { stmt stmt }.
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
Causes a block literal to by copied to the heap and then autoreleased.
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
Find the position where two subobject designators diverge, or equivalently the length of the common i...
CastKind
CastKind - The kind of operation required for a conversion.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
APValue & getArrayFiller()
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
const Expr * getExpr() const
Get the initialization expression that will be used.
bool HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
CK_FunctionToPointerDecay - Function to pointer decay.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
Converts between different floating point complex types.
bool isRealFloatingType() const
Floating point categories.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
unsigned getArrayInitializedElts() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
CK_PointerToBoolean - Pointer to boolean conversion.
Allow any unmodeled side effect.
Converts an integral complex to an integral real of the source's element type by discarding the imagi...
CK_BitCast - A conversion which causes a bit pattern of one type to be reinterpreted as a bit pattern...
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
bool isAnyComplexType() const
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "while" statement, if any.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
bool isMemberPointerToDerivedMember() const
bool isComplexFloat() const
bool isAtomicType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
bool isVariableArrayType() const
DeclContext * getDeclContext()
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
bool isFloatingType() const
Represents an expression that computes the length of a parameter pack.
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
const LValue * Slot
The location containing the result, if any (used to support RVO).
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static int EvaluateBuiltinClassifyType(const CallExpr *E)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
Defines the clang::TypeLoc interface and its subclasses.
const SwitchCase * getSwitchCaseList() const
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
unsigned getConstexprBacktraceLimit() const
Retrieve the maximum number of constexpr evaluation notes to emit along with a given diagnostic...
static bool isOverflowingIntegerType(ASTContext &Ctx, QualType T)
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
static bool diagnoseUnreadableFields(EvalInfo &Info, const Expr *E, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
Expr * getSubExpr() const
PartialDiagnostic::StorageAllocator & getDiagAllocator()
CK_ConstructorConversion - Conversion by constructor.
APValue & getStructField(unsigned i)
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
Cast an lvalue referring to a base subobject to a derived class, by truncating the lvalue's path to t...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
static bool IsStringLiteralCall(const CallExpr *E)
Should this call expression be treated as a string literal?
unsigned getNumComponents() const
Converts from an integral complex to a floating complex.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Represents a GCC generic vector type.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
QualType getElementType() const
APSInt & getComplexIntImag()
QualType getComputationLHSType() const
static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This, ArrayRef< const Expr * > Args, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
bool isComplexIntegerType() const
The result type of a method or function.
static bool EvaluateArgs(ArrayRef< const Expr * > Args, ArgVector &ArgValues, EvalInfo &Info)
EvaluateArgs - Evaluate the arguments to a function call.
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
void EvaluateForOverflow(const ASTContext &Ctx) const
Expr * getTrueExpr() const
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op, APSInt &Result)
Perform the given integer operation, which is known to need at most BitWidth bits, and check for overflow in the original type (if that type was not an unsigned type).
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
const Expr * getAnyInitializer() const
getAnyInitializer - Get the initializer for this variable, no matter which declaration it is attached...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
CK_ArrayToPointerDecay - Array to pointer decay.
DoStmt - This represents a 'do/while' stmt.
bool isLValueOnePastTheEnd() const
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
APValue & getStructBase(unsigned i)
CK_CPointerToObjCPointerCast - Casting a C pointer kind to an Objective-C pointer.
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
SourceLocation getLocStart() const LLVM_READONLY
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
static ICEDiag Worst(ICEDiag A, ICEDiag B)
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const
EvaluateAsBooleanCondition - Return true if this is a constant which we we can fold and convert to a ...
APValue & getArrayInitializedElt(unsigned I)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
CK_UserDefinedConversion - Conversion using a user defined type conversion function.
Encodes a location in the source.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
const TemplateArgument * iterator
QualType getElementType() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this core constant expression value is a valid value for a constant expression.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
APValue & getUnionValue()
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6.7.5p3.
ASTContext & getASTContext() const LLVM_READONLY
CK_NullToMemberPointer - Null pointer constant to member pointer.
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
ValueKind getKind() const
const Expr * getCond() const
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
static bool IsLiteralLValue(const LValue &Value)
Represents a static or instance method of a struct/union/class.
static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
CK_ReinterpretMemberPointer - Reinterpret a member pointer as a different kind of member pointer...
CK_DerivedToBase - A conversion from a C++ class pointer to a base class pointer. ...
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
unsigned getCharByteWidth() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Converts from an integral real to an integral complex whose element type matches the source...
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal)
Checks to see if the given LValue's Designator is at the end of the LValue's record layout...
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "switch" statement, if any.
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
const T * castAs() const
Member-template castAs<specific type>.
bool isVectorType() const
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool isLogicalOp(Opcode Opc)
An expression trait intrinsic.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
uint64_t getValue() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E)
ObjCBoxedExpr - used for generalized expression boxing.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const BlockDecl * getBlockDecl() const
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
QualType getType() const
Return the type wrapped by this type source info.
bool isGlobalLValue() const
const OffsetOfNode & getComponent(unsigned Idx) const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isPtrMemOp() const
predicates to categorize the respective opcodes.
CompoundAssignOperator - For compound assignments (e.g.
Represents a C11 generic selection.
EvalStatus is a struct with detailed info about an evaluation in progress.
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
AddrLabelExpr - The GNU address of label extension, representing &&label.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
Converts a floating point complex to floating point real of the source's element type.
Expr * getReplacement() const
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "if" statement, if any.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
static const Type * getElementType(const Expr *BaseExpr)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Get the base index of the given base class within an APValue representing the given derived class...
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const Expr * getExpr() const
[C99 6.4.2.2] - A predefined identifier such as func.
EvalResult is a struct with detailed info about an evaluated expression.
Converts an integral complex to bool by comparing against 0+0i.
bool isZero() const
isZero - Test whether the quantity equals zero.
static bool isZeroSized(const LValue &Value)
return(x >> y)|(x<< (32-y))
const Stmt * getBody() const
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
bool isInvalidDecl() const
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
CK_BaseToDerived - A conversion from a C++ class pointer/reference to a derived class pointer/referen...
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
StringRef getString() const
CK_BlockPointerToObjCPointerCast - Casting a block pointer to an ObjC pointer.
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
static int64_t getExtValue(const APSInt &Value)
Sign- or zero-extend a value to 64 bits.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
A conversion of a floating point real to a floating point complex of the original type...
CK_MemberPointerToBoolean - Member pointer to boolean.
unsigned getNumArgs() const
body_iterator body_begin()
Stmt *const * const_body_iterator
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
llvm::APFloat getValue() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
[ARC] Reclaim a retainable object pointer object that may have been produced and autoreleased as part...
const Stmt * getThen() const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
SwitchStmt - This represents a 'switch' stmt.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
ArrayRef< LValuePathEntry > getLValuePath() const
bool HasSideEffects
Whether the evaluated expression has side effects.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
const T * getAs() const
Member-template getAs<specific type>'.
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
DeclStmt * getBeginEndStmt()
static bool hasFields(const CXXRecordDecl *RD)
Determine if a class has any fields that might need to be copied by a trivial copy or move operation...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
ObjCEncodeExpr, used for @encode in Objective-C.
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T)
[ARC] Produces a retainable object pointer so that it may be consumed, e.g.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
bool isFunctionType() const
CK_LValueBitCast - A conversion which reinterprets the address of an l-value as an l-value of a diffe...
Converts from T to _Atomic(T).
static bool isAdditiveOp(Opcode Opc)
Expr * getArg(unsigned Arg)
Return the specified argument.
Base for LValueReferenceType and RValueReferenceType.
CXXConstructorDecl * getConstructor() const
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Converts from a floating complex to an integral complex.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
const Expr * getSubExpr() const
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
SourceLocation getExprLoc() const LLVM_READONLY
LabelDecl * getLabel() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Represents a base class of a C++ class.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
Update LVal to refer to the given field, which must be a member of the type currently described by LV...
const Expr * getInitializer() const
unsigned getFieldIndex() const
getFieldIndex - Returns the index of this field within its record, as appropriate for passing to ASTR...
CK_UncheckedDerivedToBase - A conversion from a C++ class pointer/reference to a base class that can ...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
DeclStmt * getRangeStmt()
static bool isIncrementOp(Opcode Op)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
A use of a default initializer in a constructor or in aggregate initialization.
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition)
CheckConstexprFunction - Check that a function can be called in a constant expression.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static bool EvaluateBuiltinConstantPForLValue(const LValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
const Expr * getSubExpr() const
bool hasArrayFiller() const
Return true if this is an array initializer and its array "filler" has been set.
APFloat & getComplexFloatImag()
const LValueBase getLValueBase() const
Represents a C++ struct/union/class.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
static bool isReadByLvalueToRvalueConversion(QualType T)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, SourceLocation *Loc)
Evaluate an expression as a C++11 integral constant expression.
WhileStmt - This represents a 'while' stmt.
const Expr * getCond() const
base_class_iterator bases_end()
FieldDecl * getField() const
For a field offsetof node, returns the field.
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info)
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
Converts from _Atomic(T) to T.
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage...
bool isStringLiteralInit() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
CK_NoOp - A conversion which does not affect the type other than (possibly) adding qualifiers...
A reference to a declared variable, function, enum, etc.
Designator - A designator in a C99 designated initializer.
CK_DerivedToBaseMemberPointer - Member pointer in derived class to member pointer in base class...
QualType getElementType() const
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
Determine whether the given subobject designators refer to elements of the same array object...
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
const Expr * getInit(unsigned Init) const
static void expandStringLiteral(EvalInfo &Info, const Expr *Lit, APValue &Result)
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluted - Return true if this expression might be usable in a constant expr...
DeclStmt * getLoopVarStmt()
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
SourceLocation getLocation() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
A boolean literal, per ([C++ lex.bool] Boolean literals).
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size, bool *WasError=nullptr)
Tries to evaluate the __builtin_object_size for E.
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Automatic storage duration (most local variables).
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
unsigned getArraySize() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
CK_ToVoid - Cast to void, discarding the computed value.
static bool isComparisonOp(Opcode Opc)
Represents the canonical version of C arrays with a specified constant size.
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
unsigned getVectorLength() const
Defines enum values for all the target-independent builtin functions.
Represents an implicitly-generated value initialization of an object of a given type.
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *This, ArrayRef< const Expr * > Args, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
static void describeCall(CallStackFrame *Frame, raw_ostream &Out)
Produce a string describing the given constexpr call.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
Kind getKind() const
Determine what kind of offsetof node this is.
bool hasArrayFiller() const
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor...
const RecordDecl * getParent() const
getParent - Returns the parent of this field declaration, which is the struct in which this method is...
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
CharUnits & getLValueOffset()
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isPointerType() const
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
EvaluateAsRValue - Try to evaluate this expression, performing an implicit lvalue-to-rvalue cast if i...
QualType getArgumentType() const
CK_FloatingToBoolean - Floating point to boolean.