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 unsigned IsOnePastTheEnd : 1;
166 unsigned 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;
481 bool IsSpeculativelyEvaluating;
483 enum EvaluationMode {
486 EM_ConstantExpression,
492 EM_PotentialConstantExpression,
501 EM_EvaluateForOverflow,
505 EM_IgnoreSideEffects,
512 EM_ConstantExpressionUnevaluated,
521 EM_PotentialConstantExpressionUnevaluated,
530 bool checkingPotentialConstantExpression()
const {
531 return EvalMode == EM_PotentialConstantExpression ||
532 EvalMode == EM_PotentialConstantExpressionUnevaluated;
538 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
541 : Ctx(const_cast<
ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
542 CallStackDepth(0), NextCallIndex(1),
543 StepsLeft(getLangOpts().ConstexprStepLimit),
545 EvaluatingDecl((const
ValueDecl *)nullptr),
546 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
547 HasFoldFailureDiagnostic(
false), IsSpeculativelyEvaluating(
false),
551 EvaluatingDecl = Base;
552 EvaluatingDeclValue = &
Value;
560 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
562 if (NextCallIndex == 0) {
564 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
567 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
569 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
570 << getLangOpts().ConstexprCallDepth;
574 CallStackFrame *getCallFrame(
unsigned CallIndex) {
575 assert(CallIndex &&
"no call index in getCallFrame");
578 CallStackFrame *Frame = CurrentCall;
579 while (Frame->Index > CallIndex)
580 Frame = Frame->Caller;
581 return (Frame->Index == CallIndex) ? Frame :
nullptr;
584 bool nextStep(
const Stmt *
S) {
586 FFDiag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded);
597 EvalStatus.Diag->push_back(std::make_pair(Loc, PD));
598 return EvalStatus.Diag->back().second;
602 void addCallStack(
unsigned Limit);
606 unsigned ExtraNotes,
bool IsCCEDiag) {
608 if (EvalStatus.Diag) {
615 if (!EvalStatus.Diag->empty()) {
617 case EM_ConstantFold:
618 case EM_IgnoreSideEffects:
619 case EM_EvaluateForOverflow:
620 if (!HasFoldFailureDiagnostic)
623 case EM_ConstantExpression:
624 case EM_PotentialConstantExpression:
625 case EM_ConstantExpressionUnevaluated:
626 case EM_PotentialConstantExpressionUnevaluated:
627 case EM_DesignatorFold:
628 HasActiveDiagnostic =
false;
629 return OptionalDiagnostic();
633 unsigned CallStackNotes = CallStackDepth - 1;
636 CallStackNotes =
std::min(CallStackNotes, Limit + 1);
637 if (checkingPotentialConstantExpression())
640 HasActiveDiagnostic =
true;
641 HasFoldFailureDiagnostic = !IsCCEDiag;
642 EvalStatus.Diag->clear();
643 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
644 addDiag(Loc, DiagId);
645 if (!checkingPotentialConstantExpression())
647 return OptionalDiagnostic(&(*EvalStatus.Diag)[0].second);
649 HasActiveDiagnostic =
false;
650 return OptionalDiagnostic();
656 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
657 unsigned ExtraNotes = 0) {
658 return Diag(Loc, DiagId, ExtraNotes,
false);
662 = diag::note_invalid_subexpr_in_const_expr,
663 unsigned ExtraNotes = 0) {
666 HasActiveDiagnostic =
false;
667 return OptionalDiagnostic();
676 = diag::note_invalid_subexpr_in_const_expr,
677 unsigned ExtraNotes = 0) {
680 if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) {
681 HasActiveDiagnostic =
false;
682 return OptionalDiagnostic();
684 return Diag(Loc, DiagId, ExtraNotes,
true);
687 = diag::note_invalid_subexpr_in_const_expr,
688 unsigned ExtraNotes = 0) {
689 return CCEDiag(E->
getExprLoc(), DiagId, ExtraNotes);
693 if (!HasActiveDiagnostic)
694 return OptionalDiagnostic();
695 return OptionalDiagnostic(&addDiag(Loc, DiagId));
700 if (HasActiveDiagnostic) {
701 EvalStatus.Diag->insert(EvalStatus.Diag->end(),
702 Diags.begin(), Diags.end());
708 bool keepEvaluatingAfterSideEffect() {
710 case EM_PotentialConstantExpression:
711 case EM_PotentialConstantExpressionUnevaluated:
712 case EM_EvaluateForOverflow:
713 case EM_IgnoreSideEffects:
716 case EM_ConstantExpression:
717 case EM_ConstantExpressionUnevaluated:
718 case EM_ConstantFold:
719 case EM_DesignatorFold:
722 llvm_unreachable(
"Missed EvalMode case");
727 bool noteSideEffect() {
728 EvalStatus.HasSideEffects =
true;
729 return keepEvaluatingAfterSideEffect();
733 bool keepEvaluatingAfterUndefinedBehavior() {
735 case EM_EvaluateForOverflow:
736 case EM_IgnoreSideEffects:
737 case EM_ConstantFold:
738 case EM_DesignatorFold:
741 case EM_PotentialConstantExpression:
742 case EM_PotentialConstantExpressionUnevaluated:
743 case EM_ConstantExpression:
744 case EM_ConstantExpressionUnevaluated:
747 llvm_unreachable(
"Missed EvalMode case");
753 bool noteUndefinedBehavior() {
754 EvalStatus.HasUndefinedBehavior =
true;
755 return keepEvaluatingAfterUndefinedBehavior();
760 bool keepEvaluatingAfterFailure() {
765 case EM_PotentialConstantExpression:
766 case EM_PotentialConstantExpressionUnevaluated:
767 case EM_EvaluateForOverflow:
770 case EM_ConstantExpression:
771 case EM_ConstantExpressionUnevaluated:
772 case EM_ConstantFold:
773 case EM_IgnoreSideEffects:
774 case EM_DesignatorFold:
777 llvm_unreachable(
"Missed EvalMode case");
790 LLVM_ATTRIBUTE_UNUSED_RESULT
bool noteFailure() {
798 bool KeepGoing = keepEvaluatingAfterFailure();
799 EvalStatus.HasSideEffects |= KeepGoing;
803 bool allowInvalidBaseExpr()
const {
804 return EvalMode == EM_DesignatorFold;
809 struct FoldConstant {
812 bool HadNoPriorDiags;
813 EvalInfo::EvaluationMode OldMode;
815 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
818 HadNoPriorDiags(Info.EvalStatus.
Diag &&
819 Info.EvalStatus.
Diag->empty() &&
820 !Info.EvalStatus.HasSideEffects),
821 OldMode(Info.EvalMode) {
823 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
824 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
825 Info.EvalMode = EvalInfo::EM_ConstantFold;
827 void keepDiagnostics() { Enabled =
false; }
829 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
830 !Info.EvalStatus.HasSideEffects)
831 Info.EvalStatus.Diag->clear();
832 Info.EvalMode = OldMode;
838 struct FoldOffsetRAII {
840 EvalInfo::EvaluationMode OldMode;
841 explicit FoldOffsetRAII(EvalInfo &Info,
bool Subobject)
842 : Info(Info), OldMode(Info.EvalMode) {
843 if (!Info.checkingPotentialConstantExpression())
844 Info.EvalMode = Subobject ? EvalInfo::EM_DesignatorFold
845 : EvalInfo::EM_ConstantFold;
848 ~FoldOffsetRAII() { Info.EvalMode = OldMode; }
853 class SpeculativeEvaluationRAII {
856 llvm::PointerIntPair<EvalInfo *, 1, bool> InfoAndOldSpecEval;
859 void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
860 InfoAndOldSpecEval = Other.InfoAndOldSpecEval;
862 Other.InfoAndOldSpecEval.setPointer(
nullptr);
865 void maybeRestoreState() {
866 EvalInfo *Info = InfoAndOldSpecEval.getPointer();
870 Info->EvalStatus = Old;
871 Info->IsSpeculativelyEvaluating = InfoAndOldSpecEval.getInt();
875 SpeculativeEvaluationRAII() =
default;
877 SpeculativeEvaluationRAII(
879 : InfoAndOldSpecEval(&Info, Info.IsSpeculativelyEvaluating),
880 Old(Info.EvalStatus) {
881 Info.EvalStatus.Diag = NewDiag;
882 Info.IsSpeculativelyEvaluating =
true;
885 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &Other) =
delete;
886 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) {
887 moveFromAndCancel(std::move(Other));
890 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) {
892 moveFromAndCancel(std::move(Other));
896 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
901 template<
bool IsFullExpression>
904 unsigned OldStackSize;
906 ScopeRAII(EvalInfo &Info)
907 : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
914 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
915 unsigned NewEnd = OldStackSize;
916 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
918 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
921 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
925 Info.CleanupStack[
I].endLifetime();
928 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
929 Info.CleanupStack.end());
932 typedef ScopeRAII<false> BlockScopeRAII;
933 typedef ScopeRAII<true> FullExpressionRAII;
936 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
940 if (isOnePastTheEnd()) {
941 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
949 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
950 const Expr *E, uint64_t N) {
951 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
952 Info.CCEDiag(E, diag::note_constexpr_array_index)
953 <<
static_cast<int>(N) << 0
954 << static_cast<unsigned>(MostDerivedArraySize);
956 Info.CCEDiag(E, diag::note_constexpr_array_index)
957 <<
static_cast<int>(N) << 1;
961 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
964 : Info(Info), Caller(Info.CurrentCall), CallLoc(CallLoc), Callee(Callee),
965 Index(Info.NextCallIndex++), This(This), Arguments(Arguments) {
966 Info.CurrentCall =
this;
967 ++Info.CallStackDepth;
970 CallStackFrame::~CallStackFrame() {
971 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
972 --Info.CallStackDepth;
973 Info.CurrentCall = Caller;
976 APValue &CallStackFrame::createTemporary(
const void *Key,
977 bool IsLifetimeExtended) {
979 assert(Result.
isUninit() &&
"temporary created multiple times");
980 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
984 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
986 void EvalInfo::addCallStack(
unsigned Limit) {
988 unsigned ActiveCalls = CallStackDepth - 1;
989 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
990 if (Limit && Limit < ActiveCalls) {
991 SkipStart = Limit / 2 + Limit % 2;
992 SkipEnd = ActiveCalls - Limit / 2;
996 unsigned CallIdx = 0;
997 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
998 Frame = Frame->Caller, ++CallIdx) {
1000 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
1001 if (CallIdx == SkipStart) {
1003 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
1011 if (
auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) {
1012 if (CD->isInheritingConstructor()) {
1013 addDiag(Frame->CallLoc, diag::note_constexpr_inherited_ctor_call_here)
1020 llvm::raw_svector_ostream Out(Buffer);
1022 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
1027 struct ComplexValue {
1032 APSInt IntReal, IntImag;
1033 APFloat FloatReal, FloatImag;
1035 ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {}
1037 void makeComplexFloat() { IsInt =
false; }
1038 bool isComplexFloat()
const {
return !IsInt; }
1039 APFloat &getComplexFloatReal() {
return FloatReal; }
1040 APFloat &getComplexFloatImag() {
return FloatImag; }
1042 void makeComplexInt() { IsInt =
true; }
1043 bool isComplexInt()
const {
return IsInt; }
1044 APSInt &getComplexIntReal() {
return IntReal; }
1045 APSInt &getComplexIntImag() {
return IntImag; }
1047 void moveInto(
APValue &v)
const {
1048 if (isComplexFloat())
1049 v =
APValue(FloatReal, FloatImag);
1051 v =
APValue(IntReal, IntImag);
1053 void setFrom(
const APValue &v) {
1070 unsigned InvalidBase : 1;
1071 unsigned CallIndex : 31;
1077 unsigned getLValueCallIndex()
const {
return CallIndex; }
1078 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1079 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1081 void moveInto(
APValue &V)
const {
1092 InvalidBase =
false;
1099 Offset = CharUnits::Zero();
1100 InvalidBase = BInvalid;
1102 Designator = SubobjectDesignator(getType(B));
1111 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1116 Info.CCEDiag(E, diag::note_constexpr_null_subobject)
1127 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
1131 void addDecl(EvalInfo &Info,
const Expr *E,
1132 const Decl *D,
bool Virtual =
false) {
1133 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
1137 if (checkSubobject(Info, E, CSK_ArrayToPointer))
1140 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1141 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1144 void adjustIndex(EvalInfo &Info,
const Expr *E, uint64_t N) {
1145 if (N && checkNullPointer(Info, E, CSK_ArrayIndex))
1153 DeclAndIsDerivedMember(Decl,
false), Path() {}
1158 return DeclAndIsDerivedMember.getPointer();
1161 bool isDerivedMember()
const {
1162 return DeclAndIsDerivedMember.getInt();
1166 return cast<CXXRecordDecl>(
1167 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1170 void moveInto(
APValue &V)
const {
1171 V =
APValue(getDecl(), isDerivedMember(), Path);
1173 void setFrom(
const APValue &V) {
1179 Path.insert(Path.end(), P.begin(), P.end());
1185 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1193 assert(!Path.empty());
1195 if (Path.size() >= 2)
1196 Expected = Path[Path.size() - 2];
1198 Expected = getContainingRecord();
1215 if (!isDerivedMember()) {
1216 Path.push_back(Derived);
1219 if (!castBack(Derived))
1222 DeclAndIsDerivedMember.setInt(
false);
1230 DeclAndIsDerivedMember.setInt(
true);
1231 if (isDerivedMember()) {
1232 Path.push_back(Base);
1235 return castBack(Base);
1240 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1241 if (!LHS.getDecl() || !RHS.getDecl())
1242 return !LHS.getDecl() && !RHS.getDecl();
1243 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1245 return LHS.Path == RHS.Path;
1251 const LValue &This,
const Expr *E,
1252 bool AllowNonLiteralTypes =
false);
1272 unsigned ArgIndex = 0;
1273 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1274 !isa<CXXConstructorDecl>(Frame->Callee) &&
1275 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1278 Out << *Frame->Callee <<
'(';
1280 if (Frame->This && IsMemberCall) {
1282 Frame->This->moveInto(Val);
1284 Frame->This->Designator.MostDerivedType);
1286 Out <<
"->" << *Frame->Callee <<
'(';
1287 IsMemberCall =
false;
1291 E = Frame->Callee->param_end(); I !=
E; ++
I, ++ArgIndex) {
1292 if (ArgIndex > (
unsigned)IsMemberCall)
1296 const APValue &Arg = Frame->Arguments[ArgIndex];
1299 if (ArgIndex == 0 && IsMemberCall)
1300 Out <<
"->" << *Frame->Callee <<
'(';
1313 return Info.noteSideEffect();
1320 return Value.isSigned() ? Value.getSExtValue()
1321 :
static_cast<int64_t
>(Value.getZExtValue());
1327 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1328 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1337 if (!B)
return true;
1341 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1342 return VD->hasGlobalStorage();
1344 return isa<FunctionDecl>(D);
1347 const Expr *E = B.get<
const Expr*>();
1348 switch (E->getStmtClass()) {
1351 case Expr::CompoundLiteralExprClass: {
1355 case Expr::MaterializeTemporaryExprClass:
1358 return cast<MaterializeTemporaryExpr>(
E)->getStorageDuration() ==
SD_Static;
1360 case Expr::StringLiteralClass:
1361 case Expr::PredefinedExprClass:
1362 case Expr::ObjCStringLiteralClass:
1363 case Expr::ObjCEncodeExprClass:
1364 case Expr::CXXTypeidExprClass:
1365 case Expr::CXXUuidofExprClass:
1367 case Expr::CallExprClass:
1370 case Expr::AddrLabelExprClass:
1374 case Expr::BlockExprClass:
1375 return !cast<BlockExpr>(
E)->getBlockDecl()->hasCaptures();
1376 case Expr::ImplicitValueInitExprClass:
1388 assert(Base &&
"no location for a null lvalue");
1391 Info.Note(VD->getLocation(), diag::note_declared_at);
1394 diag::note_constexpr_temporary_here);
1401 QualType Type,
const LValue &LVal) {
1405 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1411 if (Info.getLangOpts().CPlusPlus11) {
1413 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
1414 << IsReferenceType << !Designator.Entries.empty()
1423 assert((Info.checkingPotentialConstantExpression() ||
1424 LVal.getLValueCallIndex() == 0) &&
1425 "have call index for global lvalue");
1428 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1430 if (Var->getTLSKind())
1434 if (Var->hasAttr<DLLImportAttr>())
1437 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1448 if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
1455 if (!IsReferenceType)
1466 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1468 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
1469 << !Designator.Entries.empty() << !!VD << VD;
1479 const LValue *This =
nullptr) {
1486 if (Info.getLangOpts().CPlusPlus14 && This &&
1487 Info.EvaluatingDecl == This->getLValueBase())
1491 if (Info.getLangOpts().CPlusPlus11)
1492 Info.FFDiag(E, diag::note_constexpr_nonliteral)
1495 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1505 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
1513 Type = AT->getValueType();
1537 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
1538 unsigned BaseIndex = 0;
1540 End = CD->bases_end(); I !=
End; ++
I, ++BaseIndex) {
1546 for (
const auto *I : RD->
fields()) {
1555 LVal.setFrom(Info.Ctx, Value);
1564 return LVal.Base.dyn_cast<
const ValueDecl*>();
1568 if (Value.CallIndex)
1570 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1571 return E && !isa<MaterializeTemporaryExpr>(
E);
1576 return Decl && Decl->
isWeak();
1581 if (Decl && isa<VarDecl>(Decl)) {
1585 Decl->getASTContext().getTypeSize(Ty) == 0;
1602 return !Decl || !Decl->
isWeak();
1610 Result = Val.
getInt().getBoolValue();
1612 case APValue::Float:
1615 case APValue::ComplexInt:
1619 case APValue::ComplexFloat:
1623 case APValue::LValue:
1625 case APValue::MemberPointer:
1628 case APValue::Vector:
1629 case APValue::Array:
1630 case APValue::Struct:
1631 case APValue::Union:
1632 case APValue::AddrLabelDiff:
1636 llvm_unreachable(
"unknown APValue kind");
1641 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
1648 template<
typename T>
1650 const T &SrcValue,
QualType DestType) {
1651 Info.CCEDiag(E, diag::note_constexpr_overflow)
1652 << SrcValue << DestType;
1653 return Info.noteUndefinedBehavior();
1657 QualType SrcType,
const APFloat &Value,
1658 QualType DestType, APSInt &Result) {
1659 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1663 Result = APSInt(DestWidth, !DestSigned);
1665 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
1666 & APFloat::opInvalidOp)
1674 APFloat Value = Result;
1676 if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
1677 APFloat::rmNearestTiesToEven, &ignored)
1678 & APFloat::opOverflow)
1685 const APSInt &Value) {
1686 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1687 APSInt Result =
Value;
1690 Result = Result.extOrTrunc(DestWidth);
1696 QualType SrcType,
const APSInt &Value,
1697 QualType DestType, APFloat &Result) {
1698 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
1699 if (Result.convertFromAPInt(Value, Value.isSigned(),
1700 APFloat::rmNearestTiesToEven)
1701 & APFloat::opOverflow)
1708 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
1710 if (!Value.
isInt()) {
1714 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
1719 APSInt &Int = Value.
getInt();
1720 unsigned OldBitWidth = Int.getBitWidth();
1722 if (NewBitWidth < OldBitWidth)
1723 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
1737 Res = SVal.
getFloat().bitcastToAPInt();
1742 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
1744 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
1745 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
1746 Res = llvm::APInt::getNullValue(VecSize);
1749 llvm::APInt EltAsInt;
1753 EltAsInt = Elt.
getFloat().bitcastToAPInt();
1757 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1760 unsigned BaseEltSize = EltAsInt.getBitWidth();
1762 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
1764 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
1770 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1777 template<
typename Operation>
1779 const APSInt &LHS,
const APSInt &RHS,
1780 unsigned BitWidth, Operation Op,
1782 if (LHS.isUnsigned()) {
1783 Result = Op(LHS, RHS);
1787 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
1788 Result = Value.trunc(LHS.getBitWidth());
1789 if (Result.extend(BitWidth) !=
Value) {
1790 if (Info.checkingForOverflow())
1791 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
1792 diag::warn_integer_constant_overflow)
1793 << Result.toString(10) << E->
getType();
1810 std::multiplies<APSInt>(), Result);
1813 std::plus<APSInt>(), Result);
1816 std::minus<APSInt>(), Result);
1817 case BO_And: Result = LHS & RHS;
return true;
1818 case BO_Xor: Result = LHS ^ RHS;
return true;
1819 case BO_Or: Result = LHS | RHS;
return true;
1823 Info.FFDiag(E, diag::note_expr_divide_by_zero);
1826 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
1829 if (RHS.isNegative() && RHS.isAllOnesValue() &&
1830 LHS.isSigned() && LHS.isMinSignedValue())
1831 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
1835 if (Info.getLangOpts().OpenCL)
1837 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
1838 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
1840 else if (RHS.isSigned() && RHS.isNegative()) {
1843 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
1850 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
1852 Info.CCEDiag(E, diag::note_constexpr_large_shift)
1853 << RHS << E->
getType() << LHS.getBitWidth();
1854 }
else if (LHS.isSigned()) {
1857 if (LHS.isNegative())
1858 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
1859 else if (LHS.countLeadingZeros() < SA)
1860 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
1866 if (Info.getLangOpts().OpenCL)
1868 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
1869 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
1871 else if (RHS.isSigned() && RHS.isNegative()) {
1874 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
1881 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
1883 Info.CCEDiag(E, diag::note_constexpr_large_shift)
1884 << RHS << E->
getType() << LHS.getBitWidth();
1889 case BO_LT: Result = LHS < RHS;
return true;
1890 case BO_GT: Result = LHS > RHS;
return true;
1891 case BO_LE: Result = LHS <= RHS;
return true;
1892 case BO_GE: Result = LHS >= RHS;
return true;
1893 case BO_EQ: Result = LHS == RHS;
return true;
1894 case BO_NE: Result = LHS != RHS;
return true;
1901 const APFloat &RHS) {
1907 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
1910 LHS.add(RHS, APFloat::rmNearestTiesToEven);
1913 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
1916 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
1920 if (LHS.isInfinity() || LHS.isNaN()) {
1921 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
1922 return Info.noteUndefinedBehavior();
1931 unsigned TruncatedElements) {
1932 SubobjectDesignator &D = Result.Designator;
1935 if (TruncatedElements == D.Entries.size())
1937 assert(TruncatedElements >= D.MostDerivedPathLength &&
1938 "not casting to a derived class");
1939 if (!Result.checkSubobject(Info, E, CSK_Derived))
1944 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++
I) {
1945 if (RD->isInvalidDecl())
return false;
1948 if (isVirtualBaseClass(D.Entries[I]))
1954 D.Entries.resize(TruncatedElements);
1963 if (Derived->isInvalidDecl())
return false;
1964 RL = &Info.Ctx.getASTRecordLayout(Derived);
1967 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
1968 Obj.addDecl(Info, E, Base,
false);
1980 SubobjectDesignator &D = Obj.Designator;
1985 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
1990 if (DerivedDecl->isInvalidDecl())
return false;
1991 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
1993 Obj.addDecl(Info, E, BaseDecl,
true);
2001 PathI != PathE; ++PathI) {
2005 Type = (*PathI)->getType();
2016 if (FD->
getParent()->isInvalidDecl())
return false;
2017 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
2021 LVal.Offset += Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I));
2022 LVal.addDecl(Info, E, FD);
2030 for (
const auto *
C : IFD->
chain())
2042 Size = CharUnits::One();
2058 Size = Info.Ctx.getTypeSizeInChars(Type);
2070 int64_t Adjustment) {
2076 LVal.Offset += Adjustment * SizeOfPointee;
2077 LVal.adjustIndex(Info, E, Adjustment);
2093 LVal.Offset += SizeOfComponent;
2095 LVal.addComplex(Info, E, EltTy, Imag);
2108 const VarDecl *VD, CallStackFrame *Frame,
2112 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2115 if (Info.checkingPotentialConstantExpression())
2117 if (!Frame || !Frame->Arguments) {
2118 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2121 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2127 Result = Frame->getTemporary(VD);
2128 assert(Result &&
"missing value for local variable");
2137 if (!Info.checkingPotentialConstantExpression())
2138 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2144 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2145 Result = Info.EvaluatingDeclValue;
2152 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2160 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant,
2161 Notes.size() + 1) << VD;
2162 Info.Note(VD->getLocation(), diag::note_declared_at);
2163 Info.addNotes(Notes);
2166 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2167 Notes.size() + 1) << VD;
2168 Info.Note(VD->getLocation(), diag::note_declared_at);
2169 Info.addNotes(Notes);
2189 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2193 llvm_unreachable(
"base class missing from derived class's bases list");
2200 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2201 Lit = PE->getFunctionName();
2204 Info.Ctx.getAsConstantArrayType(S->
getType());
2205 assert(CAT &&
"string literal isn't an array");
2206 QualType CharType = CAT->getElementType();
2207 assert(CharType->
isIntegerType() &&
"unexpected character type");
2211 if (Index < S->getLength())
2221 Info.Ctx.getAsConstantArrayType(S->
getType());
2222 assert(CAT &&
"string literal isn't an array");
2223 QualType CharType = CAT->getElementType();
2224 assert(CharType->
isIntegerType() &&
"unexpected character type");
2226 unsigned Elts = CAT->getSize().getZExtValue();
2242 assert(Index < Size);
2246 unsigned NewElts =
std::max(Index+1, OldElts * 2);
2251 for (
unsigned I = 0; I != OldElts; ++
I)
2253 for (
unsigned I = OldElts; I != NewElts; ++
I)
2257 Array.
swap(NewValue);
2272 for (
auto *Field : RD->
fields())
2276 for (
auto &BaseSpec : RD->
bases())
2294 for (
auto *Field : RD->
fields()) {
2299 if (Field->isMutable() &&
2301 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2302 Info.Note(Field->getLocation(), diag::note_declared_at);
2310 for (
auto &BaseSpec : RD->
bases())
2329 struct CompleteObject {
2335 CompleteObject() :
Value(
nullptr) {}
2337 :
Value(Value), Type(Type) {
2338 assert(Value &&
"missing value for complete object");
2341 explicit operator bool()
const {
return Value; }
2346 template<
typename Sub
objectHandler>
2347 typename SubobjectHandler::result_type
2349 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2352 return handler.failed();
2353 if (Sub.isOnePastTheEnd()) {
2354 if (Info.getLangOpts().CPlusPlus11)
2355 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2356 << handler.AccessKind;
2359 return handler.failed();
2367 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++
I) {
2369 if (!Info.checkingPotentialConstantExpression())
2370 Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind;
2371 return handler.failed();
2381 return handler.failed();
2383 if (!handler.found(*O, ObjType))
2387 if (handler.AccessKind !=
AK_Read &&
2395 LastField =
nullptr;
2399 assert(CAT &&
"vla in literal type?");
2400 uint64_t Index = Sub.Entries[
I].ArrayIndex;
2401 if (CAT->
getSize().ule(Index)) {
2404 if (Info.getLangOpts().CPlusPlus11)
2405 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2406 << handler.AccessKind;
2409 return handler.failed();
2417 assert(I == N - 1 &&
"extracting subobject of character?");
2419 if (handler.AccessKind !=
AK_Read)
2423 return handler.foundString(*O, ObjType, Index);
2428 else if (handler.AccessKind !=
AK_Read) {
2435 uint64_t Index = Sub.Entries[
I].ArrayIndex;
2437 if (Info.getLangOpts().CPlusPlus11)
2438 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2439 << handler.AccessKind;
2442 return handler.failed();
2447 if (WasConstQualified)
2450 assert(I == N - 1 &&
"extracting subobject of scalar?");
2459 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
2460 if (Field->isMutable() && handler.AccessKind ==
AK_Read) {
2461 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1)
2463 Info.Note(Field->getLocation(), diag::note_declared_at);
2464 return handler.failed();
2473 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
2474 << handler.AccessKind << Field << !UnionField << UnionField;
2475 return handler.failed();
2482 ObjType = Field->getType();
2483 if (WasConstQualified && !Field->isMutable())
2487 if (Info.getLangOpts().CPlusPlus) {
2489 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2490 << handler.AccessKind << 2 << Field;
2491 Info.Note(Field->getLocation(), diag::note_declared_at);
2493 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2495 return handler.failed();
2506 ObjType = Info.Ctx.getRecordType(Base);
2507 if (WasConstQualified)
2514 struct ExtractSubobjectHandler {
2520 typedef bool result_type;
2521 bool failed() {
return false; }
2526 bool found(APSInt &Value,
QualType SubobjType) {
2530 bool found(APFloat &Value,
QualType SubobjType) {
2534 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2546 const CompleteObject &Obj,
2547 const SubobjectDesignator &Sub,
2549 ExtractSubobjectHandler Handler = { Info, Result };
2554 struct ModifySubobjectHandler {
2559 typedef bool result_type;
2565 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
2571 bool failed() {
return false; }
2573 if (!checkConst(SubobjType))
2576 Subobj.
swap(NewVal);
2579 bool found(APSInt &Value,
QualType SubobjType) {
2580 if (!checkConst(SubobjType))
2582 if (!NewVal.isInt()) {
2587 Value = NewVal.getInt();
2590 bool found(APFloat &Value,
QualType SubobjType) {
2591 if (!checkConst(SubobjType))
2593 Value = NewVal.getFloat();
2596 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2597 llvm_unreachable(
"shouldn't encounter string elements with ExpandArrays");
2606 const CompleteObject &Obj,
2607 const SubobjectDesignator &Sub,
2609 ModifySubobjectHandler Handler = { Info, NewVal, E };
2616 const SubobjectDesignator &A,
2617 const SubobjectDesignator &B,
2618 bool &WasArrayIndex) {
2619 unsigned I = 0, N =
std::min(A.Entries.size(), B.Entries.size());
2620 for (; I != N; ++
I) {
2624 if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
2625 WasArrayIndex =
true;
2633 if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
2634 WasArrayIndex =
false;
2637 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
2639 ObjType = FD->getType();
2645 WasArrayIndex =
false;
2652 const SubobjectDesignator &A,
2653 const SubobjectDesignator &B) {
2654 if (A.Entries.size() != B.Entries.size())
2657 bool IsArray = A.MostDerivedIsArrayElement;
2658 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
2667 return CommonLength >= A.Entries.size() - IsArray;
2675 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
2676 return CompleteObject();
2679 CallStackFrame *Frame =
nullptr;
2680 if (LVal.CallIndex) {
2681 Frame = Info.getCallFrame(LVal.CallIndex);
2683 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
2684 << AK << LVal.Base.is<
const ValueDecl*>();
2686 return CompleteObject();
2695 if (Info.getLangOpts().CPlusPlus)
2696 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
2700 return CompleteObject();
2705 QualType BaseType = getType(LVal.Base);
2720 if (!VD || VD->isInvalidDecl()) {
2722 return CompleteObject();
2727 if (Info.getLangOpts().CPlusPlus) {
2728 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2730 Info.Note(VD->getLocation(), diag::note_declared_at);
2734 return CompleteObject();
2740 if (Info.getLangOpts().CPlusPlus14 &&
2741 VD == Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()) {
2747 Info.FFDiag(E, diag::note_constexpr_modify_global);
2748 return CompleteObject();
2754 (Info.getLangOpts().OpenCL &&
2756 if (Info.getLangOpts().CPlusPlus) {
2757 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
2758 Info.Note(VD->getLocation(), diag::note_declared_at);
2762 return CompleteObject();
2768 if (Info.getLangOpts().CPlusPlus11) {
2769 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
2770 Info.Note(VD->getLocation(), diag::note_declared_at);
2776 if (Info.checkingPotentialConstantExpression() &&
2780 }
else if (Info.getLangOpts().CPlusPlus11) {
2781 Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
2782 Info.Note(VD->getLocation(), diag::note_declared_at);
2786 return CompleteObject();
2791 return CompleteObject();
2793 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
2797 dyn_cast<MaterializeTemporaryExpr>(Base)) {
2798 assert(MTE->getStorageDuration() ==
SD_Static &&
2799 "should have a frame for a non-global materialized temporary");
2816 const ValueDecl *ED = MTE->getExtendingDecl();
2819 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
2820 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
2821 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
2822 return CompleteObject();
2825 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
2826 assert(BaseVal &&
"got reference to unevaluated temporary");
2829 return CompleteObject();
2832 BaseVal = Frame->getTemporary(Base);
2833 assert(BaseVal &&
"missing value for temporary");
2838 if (Info.getLangOpts().CPlusPlus) {
2839 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2841 Info.Note(Base->
getExprLoc(), diag::note_constexpr_temporary_here);
2845 return CompleteObject();
2853 if (LVal.getLValueBase() == Info.EvaluatingDecl) {
2854 BaseType = Info.Ctx.getCanonicalType(BaseType);
2863 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
2864 Info.EvalStatus.HasSideEffects) ||
2865 (AK !=
AK_Read && Info.IsSpeculativelyEvaluating))
2866 return CompleteObject();
2868 return CompleteObject(BaseVal, BaseType);
2884 const LValue &LVal,
APValue &RVal) {
2885 if (LVal.Designator.Invalid)
2889 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
2895 assert(!Info.getLangOpts().CPlusPlus &&
"lvalue compound literal in c++?");
2901 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
2903 CompleteObject LitObj(&Lit, Base->
getType());
2905 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
2910 CompleteObject StrObj(&Str, Base->
getType());
2922 if (LVal.Designator.Invalid)
2925 if (!Info.getLangOpts().CPlusPlus14) {
2940 struct CompoundAssignSubobjectHandler {
2949 typedef bool result_type;
2954 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
2960 bool failed() {
return false; }
2964 return found(Subobj.
getInt(), SubobjType);
2965 case APValue::Float:
2966 return found(Subobj.
getFloat(), SubobjType);
2967 case APValue::ComplexInt:
2968 case APValue::ComplexFloat:
2972 case APValue::LValue:
2973 return foundPointer(Subobj, SubobjType);
2980 bool found(APSInt &Value,
QualType SubobjType) {
2981 if (!checkConst(SubobjType))
2998 bool found(APFloat &Value,
QualType SubobjType) {
2999 return checkConst(SubobjType) &&
3006 if (!checkConst(SubobjType))
3013 if (PointeeType.
isNull() || !RHS.isInt() ||
3014 (Opcode != BO_Add && Opcode != BO_Sub)) {
3020 if (Opcode == BO_Sub)
3024 LVal.setFrom(Info.Ctx, Subobj);
3027 LVal.moveInto(Subobj);
3030 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3031 llvm_unreachable(
"shouldn't encounter string elements here");
3040 EvalInfo &Info,
const Expr *E,
3043 if (LVal.Designator.Invalid)
3046 if (!Info.getLangOpts().CPlusPlus14) {
3052 CompoundAssignSubobjectHandler Handler = { Info,
E, PromotedLValType, Opcode,
3054 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3058 struct IncDecSubobjectHandler {
3064 typedef bool result_type;
3069 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3075 bool failed() {
return false; }
3086 return found(Subobj.
getInt(), SubobjType);
3087 case APValue::Float:
3088 return found(Subobj.
getFloat(), SubobjType);
3089 case APValue::ComplexInt:
3093 case APValue::ComplexFloat:
3097 case APValue::LValue:
3098 return foundPointer(Subobj, SubobjType);
3105 bool found(APSInt &Value,
QualType SubobjType) {
3106 if (!checkConst(SubobjType))
3116 if (Old) *Old =
APValue(Value);
3128 bool WasNegative = Value.isNegative();
3132 if (!WasNegative && Value.isNegative() &&
3134 APSInt ActualValue(Value,
true);
3140 if (WasNegative && !Value.isNegative() &&
3142 unsigned BitWidth = Value.getBitWidth();
3143 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
3144 ActualValue.setBit(BitWidth);
3150 bool found(APFloat &Value,
QualType SubobjType) {
3151 if (!checkConst(SubobjType))
3154 if (Old) *Old =
APValue(Value);
3156 APFloat One(Value.getSemantics(), 1);
3158 Value.add(One, APFloat::rmNearestTiesToEven);
3160 Value.subtract(One, APFloat::rmNearestTiesToEven);
3164 if (!checkConst(SubobjType))
3176 LVal.setFrom(Info.Ctx, Subobj);
3180 LVal.moveInto(Subobj);
3183 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3184 llvm_unreachable(
"shouldn't encounter string elements here");
3192 if (LVal.Designator.Invalid)
3195 if (!Info.getLangOpts().CPlusPlus14) {
3202 IncDecSubobjectHandler Handler = { Info,
E, AK, Old };
3203 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3218 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3237 bool IncludeMember =
true) {
3244 if (!MemPtr.getDecl()) {
3250 if (MemPtr.isDerivedMember()) {
3254 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3255 LV.Designator.Entries.size()) {
3259 unsigned PathLengthToMember =
3260 LV.Designator.Entries.size() - MemPtr.Path.size();
3261 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++
I) {
3263 LV.Designator.Entries[PathLengthToMember + I]);
3273 PathLengthToMember))
3275 }
else if (!MemPtr.Path.empty()) {
3277 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3278 MemPtr.Path.size() + IncludeMember);
3284 assert(RD &&
"member pointer access on non-class-type expression");
3286 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++
I) {
3294 MemPtr.getContainingRecord()))
3299 if (IncludeMember) {
3300 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3304 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3308 llvm_unreachable(
"can't construct reference to bound member function");
3312 return MemPtr.getDecl();
3318 bool IncludeMember =
true) {
3322 if (Info.noteFailure()) {
3330 BO->
getRHS(), IncludeMember);
3337 SubobjectDesignator &D = Result.Designator;
3338 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
3346 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
3347 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3348 << D.MostDerivedType << TargetQT;
3354 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
3357 if (NewEntriesSize == D.MostDerivedPathLength)
3358 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
3360 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
3362 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3363 << D.MostDerivedType << TargetQT;
3389 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3391 if (!VD->hasLocalStorage())
3395 Result.set(VD, Info.CurrentCall->Index);
3396 APValue &Val = Info.CurrentCall->createTemporary(VD,
true);
3398 const Expr *InitE = VD->getInit();
3400 Info.FFDiag(D->getLocStart(), diag::note_constexpr_uninitialized)
3401 <<
false << VD->getType();
3422 const Expr *Cond,
bool &Result) {
3423 FullExpressionRAII
Scope(Info);
3448 BlockScopeRAII
Scope(Info);
3451 return ESR_Succeeded;
3454 return ESR_Continue;
3457 case ESR_CaseNotFound:
3460 llvm_unreachable(
"Invalid EvalStmtResult!");
3466 BlockScopeRAII
Scope(Info);
3471 FullExpressionRAII Scope(Info);
3474 if (ESR != ESR_Succeeded)
3489 if (isa<DefaultStmt>(SC)) {
3494 const CaseStmt *CS = cast<CaseStmt>(SC);
3498 if (LHS <= Value && Value <= RHS) {
3505 return ESR_Succeeded;
3510 return ESR_Succeeded;
3516 case ESR_CaseNotFound:
3519 Info.FFDiag(Found->
getLocStart(), diag::note_constexpr_stmt_expr_unsupported);
3522 llvm_unreachable(
"Invalid EvalStmtResult!");
3528 if (!Info.nextStep(S))
3538 switch (S->getStmtClass()) {
3539 case Stmt::CompoundStmtClass:
3543 case Stmt::LabelStmtClass:
3544 case Stmt::AttributedStmtClass:
3545 case Stmt::DoStmtClass:
3548 case Stmt::CaseStmtClass:
3549 case Stmt::DefaultStmtClass:
3554 case Stmt::IfStmtClass: {
3557 const IfStmt *IS = cast<IfStmt>(
S);
3561 BlockScopeRAII
Scope(Info);
3564 if (ESR != ESR_CaseNotFound || !IS->
getElse())
3569 case Stmt::WhileStmtClass: {
3572 if (ESR != ESR_Continue)
3577 case Stmt::ForStmtClass: {
3578 const ForStmt *FS = cast<ForStmt>(
S);
3581 if (ESR != ESR_Continue)
3584 FullExpressionRAII IncScope(Info);
3591 case Stmt::DeclStmtClass:
3595 return ESR_CaseNotFound;
3599 switch (S->getStmtClass()) {
3601 if (
const Expr *E = dyn_cast<Expr>(S)) {
3604 FullExpressionRAII
Scope(Info);
3607 return ESR_Succeeded;
3610 Info.FFDiag(S->getLocStart());
3613 case Stmt::NullStmtClass:
3614 return ESR_Succeeded;
3616 case Stmt::DeclStmtClass: {
3618 for (
const auto *DclIt : DS->
decls()) {
3622 FullExpressionRAII
Scope(Info);
3626 return ESR_Succeeded;
3629 case Stmt::ReturnStmtClass: {
3630 const Expr *RetExpr = cast<ReturnStmt>(
S)->getRetValue();
3631 FullExpressionRAII
Scope(Info);
3635 :
Evaluate(Result.Value, Info, RetExpr)))
3637 return ESR_Returned;
3640 case Stmt::CompoundStmtClass: {
3641 BlockScopeRAII
Scope(Info);
3644 for (
const auto *BI : CS->
body()) {
3646 if (ESR == ESR_Succeeded)
3648 else if (ESR != ESR_CaseNotFound)
3651 return Case ? ESR_CaseNotFound : ESR_Succeeded;
3654 case Stmt::IfStmtClass: {
3655 const IfStmt *IS = cast<IfStmt>(
S);
3658 BlockScopeRAII
Scope(Info);
3661 if (ESR != ESR_Succeeded)
3670 if (ESR != ESR_Succeeded)
3673 return ESR_Succeeded;
3676 case Stmt::WhileStmtClass: {
3679 BlockScopeRAII
Scope(Info);
3688 if (ESR != ESR_Continue)
3691 return ESR_Succeeded;
3694 case Stmt::DoStmtClass: {
3695 const DoStmt *DS = cast<DoStmt>(
S);
3699 if (ESR != ESR_Continue)
3703 FullExpressionRAII CondScope(Info);
3707 return ESR_Succeeded;
3710 case Stmt::ForStmtClass: {
3711 const ForStmt *FS = cast<ForStmt>(
S);
3712 BlockScopeRAII
Scope(Info);
3715 if (ESR != ESR_Succeeded)
3719 BlockScopeRAII Scope(Info);
3720 bool Continue =
true;
3728 if (ESR != ESR_Continue)
3732 FullExpressionRAII IncScope(Info);
3737 return ESR_Succeeded;
3740 case Stmt::CXXForRangeStmtClass: {
3742 BlockScopeRAII
Scope(Info);
3746 if (ESR != ESR_Succeeded)
3751 if (ESR != ESR_Succeeded)
3754 if (ESR != ESR_Succeeded)
3760 bool Continue =
true;
3761 FullExpressionRAII CondExpr(Info);
3769 BlockScopeRAII InnerScope(Info);
3771 if (ESR != ESR_Succeeded)
3776 if (ESR != ESR_Continue)
3784 return ESR_Succeeded;
3787 case Stmt::SwitchStmtClass:
3790 case Stmt::ContinueStmtClass:
3791 return ESR_Continue;
3793 case Stmt::BreakStmtClass:
3796 case Stmt::LabelStmtClass:
3797 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
3799 case Stmt::AttributedStmtClass:
3802 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
3805 case Stmt::CaseStmtClass:
3806 case Stmt::DefaultStmtClass:
3807 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
3817 bool IsValueInitialization) {
3824 if (!CD->
isConstexpr() && !IsValueInitialization) {
3825 if (Info.getLangOpts().CPlusPlus11) {
3828 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
3830 Info.Note(CD->getLocation(), diag::note_declared_at);
3832 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
3846 if (Info.checkingPotentialConstantExpression() && !Definition &&
3852 if (Declaration->isInvalidDecl())
3857 !Definition->isInvalidDecl() && Body)
3860 if (Info.getLangOpts().CPlusPlus11) {
3861 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
3866 if (CD && CD->isInheritingConstructor()) {
3868 if (!Inherited->isConstexpr())
3869 DiagDecl = CD = Inherited;
3875 if (CD && CD->isInheritingConstructor())
3876 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
3877 << CD->getInheritedConstructor().getConstructor()->getParent();
3879 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
3881 Info.Note(DiagDecl->getLocation(), diag::note_declared_at);
3883 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
3893 for (
auto *FD : RD->
fields()) {
3894 if (FD->isUnnamedBitfield())
3898 for (
auto &Base : RD->
bases())
3899 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
3911 bool Success =
true;
3914 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *
I)) {
3917 if (!Info.noteFailure())
3929 EvalInfo &Info,
APValue &Result,
3930 const LValue *ResultSlot) {
3931 ArgVector ArgValues(Args.size());
3935 if (!Info.CheckCallLimit(CallLoc))
3938 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
3947 if (MD && MD->isDefaulted() &&
3948 (MD->getParent()->isUnion() ||
3949 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
3951 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
3953 RHS.setFrom(Info.Ctx, ArgValues[0]);
3961 This->moveInto(Result);
3967 if (ESR == ESR_Succeeded) {
3970 Info.FFDiag(Callee->getLocEnd(), diag::note_constexpr_no_return);
3972 return ESR == ESR_Returned;
3979 EvalInfo &Info,
APValue &Result) {
3981 if (!Info.CheckCallLimit(CallLoc))
3986 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
3990 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
4001 FullExpressionRAII InitScope(Info);
4020 RHS.setFrom(Info.Ctx, ArgValues[0]);
4031 if (RD->isInvalidDecl())
return false;
4035 BlockScopeRAII LifetimeExtendedScope(Info);
4037 bool Success =
true;
4038 unsigned BasesSeen = 0;
4042 for (
const auto *I : Definition->
inits()) {
4043 LValue Subobject = This;
4048 if (I->isBaseInitializer()) {
4049 QualType BaseType(I->getBaseClass(), 0);
4053 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
4054 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
4055 "base class initializers not in expected order");
4059 BaseType->getAsCXXRecordDecl(), &Layout))
4062 }
else if ((FD = I->getMember())) {
4074 for (
auto *
C : IFD->chain()) {
4075 FD = cast<FieldDecl>(
C);
4098 llvm_unreachable(
"unknown base initializer kind");
4101 FullExpressionRAII InitScope(Info);
4107 if (!Info.noteFailure())
4120 EvalInfo &Info,
APValue &Result) {
4121 ArgVector ArgValues(Args.size());
4134 template <
class Derived>
4135 class ExprEvaluatorBase
4138 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
4139 bool DerivedSuccess(
const APValue &V,
const Expr *E) {
4140 return getDerived().Success(V, E);
4142 bool DerivedZeroInitialization(
const Expr *E) {
4143 return getDerived().ZeroInitialization(E);
4149 template<
typename ConditionalOperator>
4151 assert(Info.checkingPotentialConstantExpression());
4156 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4163 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4170 Error(E, diag::note_constexpr_conditional_never_const);
4174 template<
typename ConditionalOperator>
4178 if (Info.checkingPotentialConstantExpression() && Info.noteFailure())
4179 CheckPotentialConstantConditional(E);
4184 return StmtVisitorTy::Visit(EvalExpr);
4190 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
4193 return Info.CCEDiag(E, D);
4196 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
4199 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
4201 EvalInfo &getEvalInfo() {
return Info; }
4210 return Error(E, diag::note_invalid_subexpr_in_const_expr);
4213 bool VisitStmt(
const Stmt *) {
4214 llvm_unreachable(
"Expression evaluator should not be called on stmts");
4216 bool VisitExpr(
const Expr *E) {
4221 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4223 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4225 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4233 {
return StmtVisitorTy::Visit(E->
getExpr()); }
4238 return StmtVisitorTy::Visit(E->
getExpr());
4243 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4246 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
4247 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4250 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
4251 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4260 VisitIgnoredValue(E->
getLHS());
4261 return StmtVisitorTy::Visit(E->
getRHS());
4271 return DerivedSuccess(Result, E);
4283 return HandleConditionalOperator(E);
4287 bool IsBcpCall =
false;
4294 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
4299 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
4302 FoldConstant Fold(Info, IsBcpCall);
4303 if (!HandleConditionalOperator(E)) {
4304 Fold.keepDiagnostics();
4312 if (
APValue *Value = Info.CurrentCall->getTemporary(E))
4313 return DerivedSuccess(*Value, E);
4319 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
4322 return StmtVisitorTy::Visit(Source);
4325 bool VisitCallExpr(
const CallExpr *E) {
4327 if (!handleCallExpr(E, Result,
nullptr))
4329 return DerivedSuccess(Result, E);
4333 const LValue *ResultSlot) {
4338 LValue *This =
nullptr, ThisVal;
4340 bool HasQualifier =
false;
4345 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
4349 Member = ME->getMemberDecl();
4351 HasQualifier = ME->hasQualifier();
4352 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
4355 if (!Member)
return false;
4358 return Error(Callee);
4362 return Error(Callee);
4368 if (!Call.getLValueOffset().isZero())
4369 return Error(Callee);
4370 FD = dyn_cast_or_null<FunctionDecl>(
4371 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
4373 return Error(Callee);
4388 Args = Args.slice(1);
4397 if (This && !This->checkSubobject(Info, E, CSK_This))
4402 if (This && !HasQualifier &&
4403 isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
4404 return Error(E, diag::note_constexpr_virtual_call);
4422 return DerivedZeroInitialization(E);
4424 return StmtVisitorTy::Visit(E->
getInit(0));
4428 return DerivedZeroInitialization(E);
4431 return DerivedZeroInitialization(E);
4434 return DerivedZeroInitialization(E);
4439 assert(!E->
isArrow() &&
"missing call to bound member function?");
4448 if (!FD)
return Error(E);
4453 CompleteObject Obj(&Val, BaseTy);
4459 DerivedSuccess(Result, E);
4462 bool VisitCastExpr(
const CastExpr *E) {
4467 case CK_AtomicToNonAtomic: {
4471 return DerivedSuccess(AtomicVal, E);
4475 case CK_UserDefinedConversion:
4476 return StmtVisitorTy::Visit(E->
getSubExpr());
4478 case CK_LValueToRValue: {
4487 return DerivedSuccess(RVal, E);
4495 return VisitUnaryPostIncDec(UO);
4498 return VisitUnaryPostIncDec(UO);
4501 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4511 return DerivedSuccess(RVal, UO);
4514 bool VisitStmtExpr(
const StmtExpr *E) {
4517 if (Info.checkingForOverflow())
4520 BlockScopeRAII
Scope(Info);
4529 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
4531 Info.FFDiag((*BI)->getLocStart(),
4532 diag::note_constexpr_stmt_expr_unsupported);
4535 return this->
Visit(FinalExpr);
4539 StmtResult Result = { ReturnValue,
nullptr };
4541 if (ESR != ESR_Succeeded) {
4545 if (ESR != ESR_Failed)
4546 Info.FFDiag((*BI)->getLocStart(),
4547 diag::note_constexpr_stmt_expr_unsupported);
4552 llvm_unreachable(
"Return from function from the loop above.");
4556 void VisitIgnoredValue(
const Expr *E) {
4561 void VisitIgnoredBaseExpression(
const Expr *E) {
4564 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
4566 VisitIgnoredValue(E);
4576 template<
class Derived>
4577 class LValueExprEvaluatorBase
4578 :
public ExprEvaluatorBase<Derived> {
4581 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
4582 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
4590 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
4591 ExprEvaluatorBaseTy(Info), Result(Result) {}
4594 Result.setFrom(this->Info.Ctx, V);
4610 EvalOK = this->Visit(E->
getBase());
4614 if (!this->Info.allowInvalidBaseExpr())
4616 Result.setInvalid(E);
4631 return this->
Error(E);
4646 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
4654 bool VisitCastExpr(
const CastExpr *E) {
4657 return ExprEvaluatorBaseTy::VisitCastExpr(E);
4659 case CK_DerivedToBase:
4660 case CK_UncheckedDerivedToBase:
4705 class LValueExprEvaluator
4706 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
4708 LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
4709 LValueExprEvaluatorBaseTy(Info, Result) {}
4711 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
4728 return VisitUnaryPreIncDec(UO);
4731 return VisitUnaryPreIncDec(UO);
4736 bool VisitCastExpr(
const CastExpr *E) {
4739 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
4741 case CK_LValueBitCast:
4742 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
4745 Result.Designator.setInvalid();
4748 case CK_BaseToDerived:
4765 return LValueExprEvaluator(Info, Result).Visit(E);
4768 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
4772 return VisitVarDecl(E, VD);
4776 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
4777 CallStackFrame *Frame =
nullptr;
4779 Frame = Info.CurrentCall;
4783 Result.set(VD, Frame->Index);
4793 if (!Info.checkingPotentialConstantExpression())
4794 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
4800 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
4806 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
4809 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++
I)
4818 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
4822 Value = &Info.CurrentCall->
4824 Result.set(E, Info.CurrentCall->Index);
4838 for (
unsigned I = Adjustments.size(); I != 0; ) {
4840 switch (Adjustments[I].
Kind) {
4841 case SubobjectAdjustment::DerivedToBaseAdjustment:
4845 Type = Adjustments[
I].DerivedToBase.BasePath->getType();
4848 case SubobjectAdjustment::FieldAdjustment:
4851 Type = Adjustments[
I].Field->getType();
4854 case SubobjectAdjustment::MemberPointerAdjustment:
4856 Adjustments[I].Ptr.RHS))
4858 Type = Adjustments[
I].Ptr.MPT->getPointeeType();
4868 assert(!Info.getLangOpts().CPlusPlus &&
"lvalue compound literal in c++?");
4874 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
4878 Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
4884 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
4888 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
4891 VisitIgnoredBaseExpression(E->
getBase());
4892 return VisitVarDecl(E, VD);
4897 if (MD->isStatic()) {
4898 VisitIgnoredBaseExpression(E->
getBase());
4904 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
4923 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
4927 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
4936 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
4938 "lvalue __imag__ on scalar?");
4945 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
4946 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4957 bool LValueExprEvaluator::VisitCompoundAssignOperator(
4959 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4965 if (!this->Visit(CAO->
getLHS())) {
4966 if (Info.noteFailure())
4980 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
4981 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4986 if (!this->Visit(E->
getLHS())) {
4987 if (Info.noteFailure())
5004 class PointerExprEvaluator
5005 :
public ExprEvaluatorBase<PointerExprEvaluator> {
5014 PointerExprEvaluator(EvalInfo &info, LValue &Result)
5015 : ExprEvaluatorBaseTy(info), Result(Result) {}
5018 Result.setFrom(Info.Ctx, V);
5021 bool ZeroInitialization(
const Expr *E) {
5026 bool VisitCastExpr(
const CastExpr* E);
5034 bool VisitCallExpr(
const CallExpr *E);
5035 bool VisitBlockExpr(
const BlockExpr *E) {
5042 if (Info.checkingPotentialConstantExpression())
5044 if (!Info.CurrentCall->This) {
5045 if (Info.getLangOpts().CPlusPlus11)
5046 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
5051 Result = *Info.CurrentCall->This;
5061 return PointerExprEvaluator(Info, Result).Visit(E);
5064 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
5067 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
5072 std::swap(PExp, IExp);
5075 if (!EvalPtrOK && !Info.noteFailure())
5084 AdditionalOffset = -AdditionalOffset;
5091 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5095 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr* E) {
5103 case CK_CPointerToObjCPointerCast:
5104 case CK_BlockPointerToObjCPointerCast:
5105 case CK_AnyPointerToBlockPointerCast:
5106 case CK_AddressSpaceConversion:
5107 if (!Visit(SubExpr))
5113 Result.Designator.setInvalid();
5115 CCEDiag(E, diag::note_constexpr_invalid_cast)
5118 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5122 case CK_DerivedToBase:
5123 case CK_UncheckedDerivedToBase:
5126 if (!Result.Base && Result.Offset.isZero())
5132 castAs<PointerType>()->getPointeeType(),
5135 case CK_BaseToDerived:
5138 if (!Result.Base && Result.Offset.isZero())
5142 case CK_NullToPointer:
5144 return ZeroInitialization(E);
5146 case CK_IntegralToPointer: {
5147 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5153 if (Value.
isInt()) {
5154 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
5155 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
5156 Result.Base = (
Expr*)
nullptr;
5157 Result.InvalidBase =
false;
5158 Result.Offset = CharUnits::fromQuantity(N);
5159 Result.CallIndex = 0;
5160 Result.Designator.setInvalid();
5164 Result.setFrom(Info.Ctx, Value);
5168 case CK_ArrayToPointerDecay:
5173 Result.set(SubExpr, Info.CurrentCall->Index);
5174 if (!
EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr,
false),
5175 Info, Result, SubExpr))
5180 = Info.Ctx.getAsConstantArrayType(SubExpr->
getType()))
5181 Result.addArray(Info, E, CAT);
5183 Result.Designator.setInvalid();
5186 case CK_FunctionToPointerDecay:
5190 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5201 return Info.Ctx.toCharUnitsFromBits(
5202 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
5214 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
5215 return Info.Ctx.getDeclAlign(DRE->getDecl(),
5218 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
5219 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
5225 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
5230 case Builtin::BI__builtin_addressof:
5232 case Builtin::BI__builtin_assume_aligned: {
5239 LValue OffsetResult(Result);
5251 OffsetResult.Offset += CharUnits::fromQuantity(AdditionalOffset);
5255 if (OffsetResult.Base) {
5258 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
5259 BaseAlignment = Info.Ctx.getDeclAlign(VD);
5265 if (BaseAlignment < Align) {
5266 Result.Designator.setInvalid();
5270 diag::note_constexpr_baa_insufficient_alignment) << 0
5271 << (
int) BaseAlignment.getQuantity()
5278 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
5279 Result.Designator.setInvalid();
5280 APSInt
Offset(64,
false);
5281 Offset = OffsetResult.Offset.getQuantity();
5283 if (OffsetResult.Base)
5285 diag::note_constexpr_baa_insufficient_alignment) << 1
5289 diag::note_constexpr_baa_value_insufficient_alignment)
5298 return ExprEvaluatorBaseTy::VisitCallExpr(E);
5307 class MemberPointerExprEvaluator
5308 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
5312 Result = MemberPtr(D);
5317 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
5318 : ExprEvaluatorBaseTy(Info), Result(Result) {}
5324 bool ZeroInitialization(
const Expr *E) {
5328 bool VisitCastExpr(
const CastExpr *E);
5336 return MemberPointerExprEvaluator(Info, Result).Visit(E);
5339 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5342 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5344 case CK_NullToMemberPointer:
5346 return ZeroInitialization(E);
5348 case CK_BaseToDerivedMemberPointer: {
5356 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
5358 PathI != PathE; ++PathI) {
5359 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5360 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
5361 if (!Result.castToDerived(Derived))
5370 case CK_DerivedToBaseMemberPointer:
5374 PathE = E->
path_end(); PathI != PathE; ++PathI) {
5375 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5376 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
5377 if (!Result.castToBase(Base))
5384 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5395 class RecordExprEvaluator
5396 :
public ExprEvaluatorBase<RecordExprEvaluator> {
5401 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
5402 : ExprEvaluatorBaseTy(info), This(This), Result(Result) {}
5408 bool ZeroInitialization(
const Expr *E) {
5409 return ZeroInitialization(E, E->
getType());
5413 bool VisitCallExpr(
const CallExpr *E) {
5414 return handleCallExpr(E, Result, &This);
5416 bool VisitCastExpr(
const CastExpr *E);
5419 return VisitCXXConstructExpr(E, E->
getType());
5436 const LValue &This,
APValue &Result) {
5437 assert(!RD->
isUnion() &&
"Expected non-union class type");
5442 if (RD->isInvalidDecl())
return false;
5448 End = CD->bases_end(); I !=
End; ++
I, ++Index) {
5449 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
5450 LValue Subobject = This;
5454 Result.getStructBase(Index)))
5459 for (
const auto *I : RD->
fields()) {
5461 if (I->getType()->isReferenceType())
5464 LValue Subobject = This;
5470 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
5477 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
5479 if (RD->isInvalidDecl())
return false;
5489 LValue Subobject = This;
5494 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
5497 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
5498 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
5505 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5508 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5510 case CK_ConstructorConversion:
5513 case CK_DerivedToBase:
5514 case CK_UncheckedDerivedToBase: {
5522 APValue *Value = &DerivedObject;
5525 PathE = E->
path_end(); PathI != PathE; ++PathI) {
5526 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
5527 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
5537 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5539 if (RD->isInvalidDecl())
return false;
5556 LValue Subobject = This;
5561 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
5562 isa<CXXDefaultInitExpr>(InitExpr));
5564 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
5568 if (Result.isUninit())
5571 unsigned ElementNo = 0;
5576 for (
const auto &Base : CXXRD->bases()) {
5577 assert(ElementNo < E->getNumInits() &&
"missing init for base class");
5580 LValue Subobject = This;
5584 APValue &FieldVal = Result.getStructBase(ElementNo);
5586 if (!Info.noteFailure())
5595 for (
const auto *Field : RD->
fields()) {
5601 LValue Subobject = This;
5608 Subobject, Field, &Layout))
5614 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
5617 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
5618 isa<CXXDefaultInitExpr>(Init));
5620 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
5623 FieldVal, Field))) {
5624 if (!Info.noteFailure())
5638 if (FD->isInvalidDecl() || FD->
getParent()->isInvalidDecl())
return false;
5643 if (!Result.isUninit())
5654 return ZeroInitialization(E, T);
5658 auto Body = FD->
getBody(Definition);
5666 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
5667 return Visit(ME->GetTemporaryExpr());
5669 if (ZeroInit && !ZeroInitialization(E, T))
5674 cast<CXXConstructorDecl>(Definition), Info,
5678 bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
5680 if (!Info.CurrentCall) {
5681 assert(Info.checkingPotentialConstantExpression());
5686 if (FD->isInvalidDecl() || FD->
getParent()->isInvalidDecl())
5690 auto Body = FD->
getBody(Definition);
5696 cast<CXXConstructorDecl>(Definition), Info,
5700 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
5710 Array.addArray(Info, E, ArrayType);
5719 if (!Field->getType()->isPointerType() ||
5720 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
5726 Array.moveInto(Result.getStructField(0));
5731 if (Field->getType()->isPointerType() &&
5732 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
5737 ArrayType->
getSize().getZExtValue()))
5739 Array.moveInto(Result.getStructField(1));
5740 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
5742 Result.getStructField(1) =
APValue(APSInt(ArrayType->
getSize()));
5753 APValue &Result, EvalInfo &Info) {
5755 "can't evaluate expression as a record rvalue");
5756 return RecordExprEvaluator(Info, This, Result).Visit(E);
5767 class TemporaryExprEvaluator
5768 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
5770 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
5771 LValueExprEvaluatorBaseTy(Info, Result) {}
5774 bool VisitConstructExpr(
const Expr *E) {
5775 Result.set(E, Info.CurrentCall->Index);
5780 bool VisitCastExpr(
const CastExpr *E) {
5783 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
5785 case CK_ConstructorConversion:
5790 return VisitConstructExpr(E);
5793 return VisitConstructExpr(E);
5795 bool VisitCallExpr(
const CallExpr *E) {
5796 return VisitConstructExpr(E);
5799 return VisitConstructExpr(E);
5807 return TemporaryExprEvaluator(Info, Result).Visit(E);
5815 class VectorExprEvaluator
5816 :
public ExprEvaluatorBase<VectorExprEvaluator> {
5820 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
5821 : ExprEvaluatorBaseTy(info), Result(Result) {}
5826 Result =
APValue(V.data(), V.size());
5834 bool ZeroInitialization(
const Expr *E);
5838 bool VisitCastExpr(
const CastExpr* E);
5849 return VectorExprEvaluator(Info, Result).Visit(E);
5852 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5860 case CK_VectorSplat: {
5866 Val =
APValue(std::move(IntResult));
5868 APFloat FloatResult(0.0);
5871 Val =
APValue(std::move(FloatResult));
5878 return Success(Elts, E);
5882 llvm::APInt SValInt;
5887 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
5888 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
5891 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
5892 unsigned FloatEltSize = EltSize;
5893 if (&Sem == &APFloat::x87DoubleExtended)
5895 for (
unsigned i = 0; i < NElts; i++) {
5898 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
5900 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
5901 Elts.push_back(
APValue(APFloat(Sem, Elt)));
5904 for (
unsigned i = 0; i < NElts; i++) {
5907 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
5909 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
5915 return Success(Elts, E);
5918 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5923 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5935 unsigned CountInits = 0, CountElts = 0;
5936 while (CountElts < NumElements) {
5938 if (CountInits < NumInits
5944 for (
unsigned j = 0; j < vlen; j++)
5948 llvm::APSInt sInt(32);
5949 if (CountInits < NumInits) {
5953 sInt = Info.Ctx.MakeIntValue(0, EltTy);
5954 Elements.push_back(
APValue(sInt));
5957 llvm::APFloat f(0.0);
5958 if (CountInits < NumInits) {
5962 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
5963 Elements.push_back(
APValue(f));
5968 return Success(Elements, E);
5972 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
5976 if (EltTy->isIntegerType())
5977 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
5980 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
5983 return Success(Elements, E);
5986 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
5988 return ZeroInitialization(E);
5996 class ArrayExprEvaluator
5997 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
6002 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
6003 : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
6007 "expected array or string literal");
6012 bool ZeroInitialization(
const Expr *E) {
6014 Info.Ctx.getAsConstantArrayType(E->
getType());
6019 CAT->
getSize().getZExtValue());
6020 if (!Result.hasArrayFiller())
return true;
6023 LValue Subobject = This;
6024 Subobject.addArray(Info, E, CAT);
6026 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
6029 bool VisitCallExpr(
const CallExpr *E) {
6030 return handleCallExpr(E, Result, &This);
6035 const LValue &Subobject,
6041 APValue &Result, EvalInfo &Info) {
6043 return ArrayExprEvaluator(Info, This, Result).Visit(E);
6046 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6059 return Success(Val, E);
6062 bool Success =
true;
6064 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
6065 "zero-initialized array shouldn't have any initialized elts");
6067 if (Result.isArray() && Result.hasArrayFiller())
6071 unsigned NumElts = CAT->
getSize().getZExtValue();
6076 if (NumEltsToInit != NumElts && !isa<ImplicitValueInitExpr>(FillerExpr))
6077 NumEltsToInit = NumElts;
6084 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I !=
E; ++
I)
6085 Result.getArrayInitializedElt(I) = Filler;
6086 if (Result.hasArrayFiller())
6090 LValue Subobject = This;
6091 Subobject.addArray(Info, E, CAT);
6092 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
6096 Info, Subobject, Init) ||
6099 if (!Info.noteFailure())
6105 if (!Result.hasArrayFiller())
6110 assert(FillerExpr &&
"no array filler for incomplete init list");
6112 FillerExpr) && Success;
6115 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
6116 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
6120 const LValue &Subobject,
6123 bool HadZeroInit = !Value->
isUninit();
6126 unsigned N = CAT->
getSize().getZExtValue();
6136 for (
unsigned I = 0; I != N; ++
I)
6140 LValue ArrayElt = Subobject;
6141 ArrayElt.addArray(Info, E, CAT);
6142 for (
unsigned I = 0; I != N; ++
I)
6155 return RecordExprEvaluator(Info, Subobject, *Value)
6156 .VisitCXXConstructExpr(E, Type);
6168 class IntExprEvaluator
6169 :
public ExprEvaluatorBase<IntExprEvaluator> {
6172 IntExprEvaluator(EvalInfo &info,
APValue &result)
6173 : ExprEvaluatorBaseTy(info), Result(result) {}
6175 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
6177 "Invalid evaluation result.");
6179 "Invalid evaluation result.");
6180 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
6181 "Invalid evaluation result.");
6185 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
6186 return Success(SI, E, Result);
6189 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
6191 "Invalid evaluation result.");
6192 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
6193 "Invalid evaluation result.");
6195 Result.
getInt().setIsUnsigned(
6199 bool Success(
const llvm::APInt &I,
const Expr *E) {
6200 return Success(I, E, Result);
6203 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
6205 "Invalid evaluation result.");
6209 bool Success(uint64_t Value,
const Expr *E) {
6210 return Success(Value, E, Result);
6222 return Success(V.
getInt(),
E);
6225 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
6238 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
6240 if (CheckReferencedDecl(E, E->
getDecl()))
6243 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
6247 VisitIgnoredBaseExpression(E->
getBase());
6251 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
6254 bool VisitCallExpr(
const CallExpr *E);
6259 bool VisitCastExpr(
const CastExpr* E);
6272 return ZeroInitialization(E);
6294 bool TryEvaluateBuiltinObjectSize(
const CallExpr *E,
unsigned Type);
6310 return IntExprEvaluator(Info, Result).Visit(E);
6320 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
6330 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
6334 bool SameSign = (ECD->getInitVal().isSigned()
6336 bool SameWidth = (ECD->getInitVal().getBitWidth()
6337 == Info.Ctx.getIntWidth(E->
getType()));
6338 if (SameSign && SameWidth)
6339 return Success(ECD->getInitVal(),
E);
6343 llvm::APSInt Val = ECD->getInitVal();
6345 Val.setIsSigned(!ECD->getInitVal().isSigned());
6347 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
6348 return Success(Val, E);
6360 enum gcc_type_class {
6362 void_type_class, integer_type_class, char_type_class,
6363 enumeral_type_class, boolean_type_class,
6364 pointer_type_class, reference_type_class, offset_type_class,
6365 real_type_class, complex_type_class,
6366 function_type_class, method_type_class,
6367 record_type_class, union_type_class,
6368 array_type_class, string_type_class,
6375 return no_type_class;
6381 #define TYPE(ID, BASE)
6382 #define DEPENDENT_TYPE(ID, BASE) case Type::ID:
6383 #define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
6384 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
6385 #include "clang/AST/TypeNodes.def"
6386 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6390 #define BUILTIN_TYPE(ID, SINGLETON_ID)
6391 #define SIGNED_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: return integer_type_class;
6392 #define FLOATING_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: return real_type_class;
6393 #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: break;
6394 #include "clang/AST/BuiltinTypes.def"
6395 case BuiltinType::Void:
6396 return void_type_class;
6398 case BuiltinType::Bool:
6399 return boolean_type_class;
6401 case BuiltinType::Char_U:
6402 case BuiltinType::UChar:
6403 case BuiltinType::UShort:
6404 case BuiltinType::UInt:
6405 case BuiltinType::ULong:
6406 case BuiltinType::ULongLong:
6407 case BuiltinType::UInt128:
6408 return integer_type_class;
6410 case BuiltinType::NullPtr:
6411 return pointer_type_class;
6413 case BuiltinType::WChar_U:
6414 case BuiltinType::Char16:
6415 case BuiltinType::Char32:
6416 case BuiltinType::ObjCId:
6417 case BuiltinType::ObjCClass:
6418 case BuiltinType::ObjCSel:
6419 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
6420 case BuiltinType::Id:
6421 #include "clang/Basic/OpenCLImageTypes.def"
6422 case BuiltinType::OCLSampler:
6423 case BuiltinType::OCLEvent:
6424 case BuiltinType::OCLClkEvent:
6425 case BuiltinType::OCLQueue:
6426 case BuiltinType::OCLNDRange:
6427 case BuiltinType::OCLReserveID:
6428 case BuiltinType::Dependent:
6429 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6433 return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class;
6437 return pointer_type_class;
6440 case Type::MemberPointer:
6442 return offset_type_class;
6447 return method_type_class;
6451 return complex_type_class;
6453 case Type::FunctionNoProto:
6454 case Type::FunctionProto:
6455 return LangOpts.CPlusPlus ? function_type_class : pointer_type_class;
6459 switch (RT->getDecl()->getTagKind()) {
6463 return record_type_class;
6466 return LangOpts.CPlusPlus ? enumeral_type_class : integer_type_class;
6469 return union_type_class;
6472 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6474 case Type::ConstantArray:
6475 case Type::VariableArray:
6476 case Type::IncompleteArray:
6477 return LangOpts.CPlusPlus ? array_type_class : pointer_type_class;
6479 case Type::BlockPointer:
6480 case Type::LValueReference:
6481 case Type::RValueReference:
6483 case Type::ExtVector:
6485 case Type::ObjCObject:
6486 case Type::ObjCInterface:
6487 case Type::ObjCObjectPointer:
6490 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6493 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6501 template<
typename LValue>
6503 const Expr *E = LV.getLValueBase().template dyn_cast<
const Expr*>();
6504 return E && isa<StringLiteral>(
E) && LV.getLValueOffset().isZero();
6531 if (V.
getKind() == APValue::Int)
6533 if (V.
getKind() == APValue::LValue)
6540 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
6555 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
6557 }
else if (
const Expr *E = B.get<
const Expr*>()) {
6558 if (isa<CompoundLiteralExpr>(E))
6575 auto *Cast = dyn_cast<
CastExpr>(NoParens);
6576 if (Cast ==
nullptr)
6583 CastKind != CK_AddressSpaceConversion)
6586 auto *SubExpr = Cast->getSubExpr();
6607 assert(!LVal.Designator.Invalid);
6609 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &Invalid) {
6611 Invalid = Parent->isInvalidDecl();
6612 if (Invalid || Parent->
isUnion())
6618 auto &Base = LVal.getLValueBase();
6619 if (
auto *ME = dyn_cast_or_null<MemberExpr>(Base.dyn_cast<
const Expr *>())) {
6620 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
6622 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
6624 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
6625 for (
auto *FD : IFD->chain()) {
6627 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
6634 for (
int I = 0, E = LVal.Designator.Entries.size(); I !=
E; ++
I) {
6640 auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
6641 uint64_t Index = LVal.Designator.Entries[
I].ArrayIndex;
6642 if (Index + 1 != CAT->
getSize())
6647 uint64_t Index = LVal.Designator.Entries[
I].ArrayIndex;
6651 }
else if (
auto *FD = getAsField(LVal.Designator.Entries[I])) {
6653 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
6657 assert(getAsBaseClass(LVal.Designator.Entries[I]) !=
nullptr &&
6658 "Expecting cast to a base class");
6667 if (LVal.Designator.Invalid || !LVal.Designator.Entries.empty())
6670 if (!LVal.InvalidBase)
6673 auto *E = LVal.Base.dyn_cast<
const Expr *>();
6675 assert(E !=
nullptr && isa<MemberExpr>(E));
6685 EvalInfo &Info, uint64_t &Size,
6686 bool *WasError =
nullptr) {
6687 if (WasError !=
nullptr)
6691 if (WasError !=
nullptr)
6696 auto Success = [&](uint64_t
S,
const Expr *
E) {
6707 SpeculativeEvaluationRAII SpeculativeEval(Info);
6708 FoldOffsetRAII Fold(Info, Type & 1);
6716 Base.setFrom(Info.Ctx, RVal);
6721 CharUnits BaseOffset = Base.getLValueOffset();
6725 return Success(0, E);
6742 if (Base.InvalidBase && !SubobjectOnly)
6752 if (!SubobjectOnly || (End.Designator.Invalid && Type == 1)) {
6755 End.Designator.setInvalid();
6757 End.Designator = SubobjectDesignator(T);
6758 End.Offset = CharUnits::Zero();
6765 if (End.Designator.Invalid)
6771 int64_t AmountToAdd = 1;
6772 if (End.Designator.MostDerivedIsArrayElement &&
6773 End.Designator.Entries.size() == End.Designator.MostDerivedPathLength) {
6775 AmountToAdd = End.Designator.MostDerivedArraySize -
6776 End.Designator.Entries.back().ArrayIndex;
6777 }
else if (End.Designator.isOnePastTheEnd()) {
6782 QualType PointeeType = End.Designator.MostDerivedType;
6783 assert(!PointeeType.
isNull());
6791 auto EndOffset = End.getLValueOffset();
6803 if (End.InvalidBase && SubobjectOnly && Type == 1 &&
6804 End.Designator.Entries.size() == End.Designator.MostDerivedPathLength &&
6805 End.Designator.MostDerivedIsArrayElement &&
6806 End.Designator.MostDerivedArraySize < 2 &&
6810 if (BaseOffset > EndOffset)
6811 return Success(0, E);
6813 return Success((EndOffset - BaseOffset).getQuantity(), E);
6816 bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(
const CallExpr *E,
6821 return Success(Size, E);
6827 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
6830 return ExprEvaluatorBaseTy::VisitCallExpr(E);
6832 case Builtin::BI__builtin_object_size: {
6836 assert(Type <= 3 &&
"unexpected type");
6838 if (TryEvaluateBuiltinObjectSize(E, Type))
6842 return Success((Type & 2) ? 0 : -1,
E);
6846 switch (Info.EvalMode) {
6847 case EvalInfo::EM_ConstantExpression:
6848 case EvalInfo::EM_PotentialConstantExpression:
6849 case EvalInfo::EM_ConstantFold:
6850 case EvalInfo::EM_EvaluateForOverflow:
6851 case EvalInfo::EM_IgnoreSideEffects:
6852 case EvalInfo::EM_DesignatorFold:
6855 case EvalInfo::EM_ConstantExpressionUnevaluated:
6856 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
6858 return Success((Type & 2) ? 0 : -1, E);
6862 case Builtin::BI__builtin_bswap16:
6863 case Builtin::BI__builtin_bswap32:
6864 case Builtin::BI__builtin_bswap64: {
6869 return Success(Val.byteSwap(),
E);
6872 case Builtin::BI__builtin_classify_type:
6879 case Builtin::BI__builtin_clz:
6880 case Builtin::BI__builtin_clzl:
6881 case Builtin::BI__builtin_clzll:
6882 case Builtin::BI__builtin_clzs: {
6889 return Success(Val.countLeadingZeros(),
E);
6892 case Builtin::BI__builtin_constant_p:
6895 case Builtin::BI__builtin_ctz:
6896 case Builtin::BI__builtin_ctzl:
6897 case Builtin::BI__builtin_ctzll:
6898 case Builtin::BI__builtin_ctzs: {
6905 return Success(Val.countTrailingZeros(),
E);
6908 case Builtin::BI__builtin_eh_return_data_regno: {
6910 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
6911 return Success(Operand, E);
6914 case Builtin::BI__builtin_expect:
6915 return Visit(E->
getArg(0));
6917 case Builtin::BI__builtin_ffs:
6918 case Builtin::BI__builtin_ffsl:
6919 case Builtin::BI__builtin_ffsll: {
6924 unsigned N = Val.countTrailingZeros();
6925 return Success(N == Val.getBitWidth() ? 0 : N + 1,
E);
6928 case Builtin::BI__builtin_fpclassify: {
6933 switch (Val.getCategory()) {
6934 case APFloat::fcNaN: Arg = 0;
break;
6935 case APFloat::fcInfinity: Arg = 1;
break;
6936 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
6937 case APFloat::fcZero: Arg = 4;
break;
6939 return Visit(E->
getArg(Arg));
6942 case Builtin::BI__builtin_isinf_sign: {
6945 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
6948 case Builtin::BI__builtin_isinf: {
6951 Success(Val.isInfinity() ? 1 : 0,
E);
6954 case Builtin::BI__builtin_isfinite: {
6957 Success(Val.isFinite() ? 1 : 0,
E);
6960 case Builtin::BI__builtin_isnan: {
6963 Success(Val.isNaN() ? 1 : 0,
E);
6966 case Builtin::BI__builtin_isnormal: {
6969 Success(Val.isNormal() ? 1 : 0,
E);
6972 case Builtin::BI__builtin_parity:
6973 case Builtin::BI__builtin_parityl:
6974 case Builtin::BI__builtin_parityll: {
6979 return Success(Val.countPopulation() % 2,
E);
6982 case Builtin::BI__builtin_popcount:
6983 case Builtin::BI__builtin_popcountl:
6984 case Builtin::BI__builtin_popcountll: {
6989 return Success(Val.countPopulation(),
E);
6992 case Builtin::BIstrlen:
6994 if (Info.getLangOpts().CPlusPlus11)
6995 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
6996 << 0 << 0 <<
"'strlen'";
6998 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
7000 case Builtin::BI__builtin_strlen: {
7008 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
7009 String.getLValueBase().dyn_cast<
const Expr *>())) {
7012 StringRef Str = S->getBytes();
7013 int64_t Off = String.Offset.getQuantity();
7014 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
7015 S->getCharByteWidth() == 1) {
7016 Str = Str.substr(Off);
7018 StringRef::size_type Pos = Str.find(0);
7019 if (Pos != StringRef::npos)
7020 Str = Str.substr(0, Pos);
7022 return Success(Str.size(),
E);
7030 for (uint64_t Strlen = 0; ; ++Strlen) {
7036 return Success(Strlen, E);
7042 case Builtin::BI__atomic_always_lock_free:
7043 case Builtin::BI__atomic_is_lock_free:
7044 case Builtin::BI__c11_atomic_is_lock_free: {
7059 CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
7062 unsigned InlineWidthBits =
7063 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
7064 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
7065 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
7066 Size == CharUnits::One() ||
7068 Expr::NPC_NeverValueDependent))
7071 return Success(1, E);
7074 castAs<PointerType>()->getPointeeType();
7076 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
7078 return Success(1, E);
7083 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
7084 Success(0, E) :
Error(E);
7090 if (!A.getLValueBase())
7091 return !B.getLValueBase();
7092 if (!B.getLValueBase())
7095 if (A.getLValueBase().getOpaqueValue() !=
7096 B.getLValueBase().getOpaqueValue()) {
7101 if (!BDecl || ADecl->getCanonicalDecl() != BDecl->getCanonicalDecl())
7106 A.getLValueCallIndex() == B.getLValueCallIndex();
7115 if (!LV.getLValueBase())
7120 if (!LV.getLValueDesignator().Invalid &&
7121 !LV.getLValueDesignator().isOnePastTheEnd())
7126 QualType Ty = getType(LV.getLValueBase());
7133 return LV.getLValueOffset() == Size;
7143 class DataRecursiveIntBinOpEvaluator {
7148 EvalResult() : Failed(false) { }
7150 void swap(EvalResult &RHS) {
7152 Failed = RHS.Failed;
7159 EvalResult LHSResult;
7160 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
7164 : E(J.E), LHSResult(J.LHSResult), Kind(J.Kind),
7165 SpecEvalRAII(std::move(J.SpecEvalRAII)) {}
7167 void startSpeculativeEval(EvalInfo &Info) {
7168 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
7172 SpeculativeEvaluationRAII SpecEvalRAII;
7177 IntExprEvaluator &IntEval;
7182 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
7183 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
7200 EvalResult PrevResult;
7201 while (!Queue.empty())
7202 process(PrevResult);
7204 if (PrevResult.Failed)
return false;
7206 FinalResult.swap(PrevResult.Val);
7211 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
7212 return IntEval.Success(Value, E, Result);
7214 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
7215 return IntEval.Success(Value, E, Result);
7218 return IntEval.Error(E);
7221 return IntEval.Error(E, D);
7225 return Info.CCEDiag(E, D);
7229 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
7230 bool &SuppressRHSDiags);
7232 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
7235 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
7236 Result.Failed = !
Evaluate(Result.Val, Info, E);
7241 void process(EvalResult &Result);
7243 void enqueue(
const Expr *E) {
7245 Queue.resize(Queue.size()+1);
7247 Queue.back().Kind = Job::AnyExprKind;
7253 bool DataRecursiveIntBinOpEvaluator::
7254 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
7255 bool &SuppressRHSDiags) {
7258 if (LHSResult.Failed)
7259 return Info.noteSideEffect();
7268 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
7269 Success(LHSAsBool, E, LHSResult.Val);
7273 LHSResult.Failed =
true;
7277 if (!Info.noteSideEffect())
7283 SuppressRHSDiags =
true;
7292 if (LHSResult.Failed && !Info.noteFailure())
7298 bool DataRecursiveIntBinOpEvaluator::
7299 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
7302 if (RHSResult.Failed)
7304 Result = RHSResult.Val;
7309 bool lhsResult, rhsResult;
7316 return Success(lhsResult || rhsResult, E, Result);
7318 return Success(lhsResult && rhsResult, E, Result);
7324 if (rhsResult == (E->
getOpcode() == BO_LOr))
7325 return Success(rhsResult, E, Result);
7335 if (LHSResult.Failed || RHSResult.Failed)
7338 const APValue &LHSVal = LHSResult.Val;
7339 const APValue &RHSVal = RHSResult.Val;
7345 CharUnits::fromQuantity(RHSVal.
getInt().getZExtValue());
7358 CharUnits::fromQuantity(LHSVal.
getInt().getZExtValue());
7369 if (!LHSExpr || !RHSExpr)
7373 if (!LHSAddrExpr || !RHSAddrExpr)
7376 if (LHSAddrExpr->
getLabel()->getDeclContext() !=
7377 RHSAddrExpr->getLabel()->getDeclContext())
7379 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
7395 return Success(Value, E, Result);
7398 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
7399 Job &job = Queue.back();
7402 case Job::AnyExprKind: {
7403 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
7404 if (shouldEnqueue(Bop)) {
7405 job.Kind = Job::BinOpKind;
7406 enqueue(Bop->getLHS());
7411 EvaluateExpr(job.E, Result);
7416 case Job::BinOpKind: {
7418 bool SuppressRHSDiags =
false;
7419 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
7423 if (SuppressRHSDiags)
7424 job.startSpeculativeEval(Info);
7425 job.LHSResult.swap(Result);
7426 job.Kind = Job::BinOpVisitedLHSKind;
7431 case Job::BinOpVisitedLHSKind: {
7435 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
7441 llvm_unreachable(
"Invalid Job::Kind!");
7447 class DelayedNoteFailureRAII {
7452 DelayedNoteFailureRAII(EvalInfo &Info,
bool NoteFailure =
true)
7453 : Info(Info), NoteFailure(NoteFailure) {}
7454 ~DelayedNoteFailureRAII() {
7456 bool ContinueAfterFailure = Info.noteFailure();
7457 (void)ContinueAfterFailure;
7458 assert(ContinueAfterFailure &&
7459 "Shouldn't have kept evaluating on failure.");
7465 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
7471 DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->
isAssignmentOp());
7472 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
7473 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
7479 ComplexValue LHS, RHS;
7488 LHS.makeComplexFloat();
7489 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
7494 if (!LHSOK && !Info.noteFailure())
7500 RHS.makeComplexFloat();
7501 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
7505 if (LHS.isComplexFloat()) {
7506 APFloat::cmpResult CR_r =
7507 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
7508 APFloat::cmpResult CR_i =
7509 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
7512 return Success((CR_r == APFloat::cmpEqual &&
7513 CR_i == APFloat::cmpEqual),
E);
7516 "Invalid complex comparison.");
7517 return Success(((CR_r == APFloat::cmpGreaterThan ||
7518 CR_r == APFloat::cmpLessThan ||
7519 CR_r == APFloat::cmpUnordered) ||
7520 (CR_i == APFloat::cmpGreaterThan ||
7521 CR_i == APFloat::cmpLessThan ||
7522 CR_i == APFloat::cmpUnordered)), E);
7526 return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
7527 LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
7530 "Invalid compex comparison.");
7531 return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
7532 LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
7539 APFloat RHS(0.0), LHS(0.0);
7542 if (!LHSOK && !Info.noteFailure())
7548 APFloat::cmpResult CR = LHS.compare(RHS);
7552 llvm_unreachable(
"Invalid binary operator!");
7554 return Success(CR == APFloat::cmpLessThan, E);
7556 return Success(CR == APFloat::cmpGreaterThan, E);
7558 return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
7560 return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
7563 return Success(CR == APFloat::cmpEqual, E);
7565 return Success(CR == APFloat::cmpGreaterThan
7566 || CR == APFloat::cmpLessThan
7567 || CR == APFloat::cmpUnordered, E);
7573 LValue LHSValue, RHSValue;
7576 if (!LHSOK && !Info.noteFailure())
7587 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
7589 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr*>();
7590 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr*>();
7591 if (!LHSExpr || !RHSExpr)
7595 if (!LHSAddrExpr || !RHSAddrExpr)
7598 if (LHSAddrExpr->
getLabel()->getDeclContext() !=
7599 RHSAddrExpr->getLabel()->getDeclContext())
7601 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
7610 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
7611 (!RHSValue.Base && !RHSValue.Offset.isZero()))
7618 LHSValue.Base && RHSValue.Base)
7626 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
7628 (RHSValue.Base && RHSValue.Offset.isZero() &&
7643 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
7644 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
7646 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
7647 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
7654 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
7656 LHSDesignator, RHSDesignator))
7657 CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
7669 if (ElementSize.
isZero()) {
7670 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
7684 llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
7686 llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
7688 llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
false);
7689 APSInt TrueResult = (LHS - RHS) / ElemSize;
7690 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
7692 if (Result.extend(65) != TrueResult &&
7695 return Success(Result, E);
7707 CCEDiag(E, diag::note_constexpr_void_comparison);
7717 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
7722 RHSDesignator, WasArrayIndex);
7729 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
7730 Mismatch < RHSDesignator.Entries.size()) {
7731 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
7732 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
7734 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
7736 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
7737 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
7740 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
7741 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
7744 LF->getAccess() != RF->getAccess())
7745 CCEDiag(E, diag::note_constexpr_pointer_comparison_differing_access)
7746 << LF << LF->getAccess() << RF << RF->getAccess()
7753 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
7756 assert(PtrSize <= 64 &&
"Unexpected pointer width");
7757 uint64_t Mask = ~0ULL >> (64 - PtrSize);
7765 QualType BaseTy = getType(LHSValue.Base);
7768 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
7770 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
7775 default: llvm_unreachable(
"missing comparison operator");
7776 case BO_LT:
return Success(CompareLHS < CompareRHS, E);
7777 case BO_GT:
return Success(CompareLHS > CompareRHS, E);
7778 case BO_LE:
return Success(CompareLHS <= CompareRHS, E);
7779 case BO_GE:
return Success(CompareLHS >= CompareRHS, E);
7780 case BO_EQ:
return Success(CompareLHS == CompareRHS, E);
7781 case BO_NE:
return Success(CompareLHS != CompareRHS, E);
7787 assert(E->
isEqualityOp() &&
"unexpected member pointer operation");
7790 MemberPtr LHSValue, RHSValue;
7793 if (!LHSOK && !Info.noteFailure())
7802 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
7803 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
7804 return Success(E->
getOpcode() == BO_EQ ? Equal : !Equal,
E);
7809 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
7810 if (MD->isVirtual())
7811 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
7812 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
7813 if (MD->isVirtual())
7814 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
7820 bool Equal = LHSValue == RHSValue;
7821 return Success(E->
getOpcode() == BO_EQ ? Equal : !Equal,
E);
7826 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
7831 return Success(Opcode == BO_EQ || Opcode == BO_LE || Opcode == BO_GE, E);
7836 "DataRecursiveIntBinOpEvaluator should have handled integral types");
7838 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7843 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
7864 return Success(n, E);
7866 return Success(1, E);
7879 return Success(Sizeof, E);
7884 Info.Ctx.toCharUnitsFromBits(
7890 llvm_unreachable(
"unknown expr/type trait");
7893 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
7899 for (
unsigned i = 0; i != n; ++i) {
7902 case OffsetOfNode::Array: {
7907 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
7911 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
7912 Result += IdxResult.getSExtValue() * ElementSize;
7916 case OffsetOfNode::Field: {
7922 if (RD->isInvalidDecl())
return false;
7925 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
7931 case OffsetOfNode::Identifier:
7932 llvm_unreachable(
"dependent __builtin_offsetof");
7934 case OffsetOfNode::Base: {
7944 if (RD->isInvalidDecl())
return false;
7948 CurrentType = BaseSpec->
getType();
7959 return Success(Result, OOE);
7962 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
7978 if (!Result.isInt())
return Error(E);
7979 const APSInt &Value = Result.getInt();
7980 if (Value.isSigned() && Value.isMinSignedValue() &&
7984 return Success(-Value, E);
7989 if (!Result.isInt())
return Error(E);
7990 return Success(~Result.getInt(),
E);
7996 return Success(!bres, E);
8003 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8009 case CK_BaseToDerived:
8010 case CK_DerivedToBase:
8011 case CK_UncheckedDerivedToBase:
8014 case CK_ArrayToPointerDecay:
8015 case CK_FunctionToPointerDecay:
8016 case CK_NullToPointer:
8017 case CK_NullToMemberPointer:
8018 case CK_BaseToDerivedMemberPointer:
8019 case CK_DerivedToBaseMemberPointer:
8020 case CK_ReinterpretMemberPointer:
8021 case CK_ConstructorConversion:
8022 case CK_IntegralToPointer:
8024 case CK_VectorSplat:
8025 case CK_IntegralToFloating:
8026 case CK_FloatingCast:
8027 case CK_CPointerToObjCPointerCast:
8028 case CK_BlockPointerToObjCPointerCast:
8029 case CK_AnyPointerToBlockPointerCast:
8030 case CK_ObjCObjectLValueCast:
8031 case CK_FloatingRealToComplex:
8032 case CK_FloatingComplexToReal:
8033 case CK_FloatingComplexCast:
8034 case CK_FloatingComplexToIntegralComplex:
8035 case CK_IntegralRealToComplex:
8036 case CK_IntegralComplexCast:
8037 case CK_IntegralComplexToFloatingComplex:
8038 case CK_BuiltinFnToFnPtr:
8039 case CK_ZeroToOCLEvent:
8040 case CK_NonAtomicToAtomic:
8041 case CK_AddressSpaceConversion:
8042 llvm_unreachable(
"invalid cast kind for integral value");
8046 case CK_LValueBitCast:
8047 case CK_ARCProduceObject:
8048 case CK_ARCConsumeObject:
8049 case CK_ARCReclaimReturnedObject:
8050 case CK_ARCExtendBlockObject:
8051 case CK_CopyAndAutoreleaseBlockObject:
8054 case CK_UserDefinedConversion:
8055 case CK_LValueToRValue:
8056 case CK_AtomicToNonAtomic:
8058 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8060 case CK_MemberPointerToBoolean:
8061 case CK_PointerToBoolean:
8062 case CK_IntegralToBoolean:
8063 case CK_FloatingToBoolean:
8064 case CK_BooleanToSignedIntegral:
8065 case CK_FloatingComplexToBoolean:
8066 case CK_IntegralComplexToBoolean: {
8070 uint64_t IntResult = BoolResult;
8071 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
8072 IntResult = (uint64_t)-1;
8073 return Success(IntResult, E);
8076 case CK_IntegralCast: {
8077 if (!Visit(SubExpr))
8080 if (!Result.isInt()) {
8086 if (Result.isAddrLabelDiff())
8087 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
8089 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
8093 Result.getInt()), E);
8096 case CK_PointerToIntegral: {
8097 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
8103 if (LV.getLValueBase()) {
8108 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
8111 LV.Designator.setInvalid();
8112 LV.moveInto(Result);
8116 APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(),
8121 case CK_IntegralComplexToReal: {
8125 return Success(C.getComplexIntReal(),
E);
8128 case CK_FloatingToIntegral: {
8136 return Success(Value, E);
8140 llvm_unreachable(
"unknown cast resulting in integral value");
8143 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
8148 if (!LV.isComplexInt())
8150 return Success(LV.getComplexIntReal(),
E);
8156 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8161 if (!LV.isComplexInt())
8163 return Success(LV.getComplexIntImag(),
E);
8167 return Success(0, E);
8170 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
8174 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
8183 class FloatExprEvaluator
8184 :
public ExprEvaluatorBase<FloatExprEvaluator> {
8187 FloatExprEvaluator(EvalInfo &info, APFloat &result)
8188 : ExprEvaluatorBaseTy(info), Result(result) {}
8195 bool ZeroInitialization(
const Expr *E) {
8196 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
8200 bool VisitCallExpr(
const CallExpr *E);
8205 bool VisitCastExpr(
const CastExpr *E);
8216 return FloatExprEvaluator(Info, Result).Visit(E);
8223 llvm::APFloat &Result) {
8225 if (!S)
return false;
8233 fill = llvm::APInt(32, 0);
8234 else if (S->
getString().getAsInteger(0, fill))
8239 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
8241 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
8249 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
8251 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
8257 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
8260 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8262 case Builtin::BI__builtin_huge_val:
8263 case Builtin::BI__builtin_huge_valf:
8264 case Builtin::BI__builtin_huge_vall:
8265 case Builtin::BI__builtin_inf:
8266 case Builtin::BI__builtin_inff:
8267 case Builtin::BI__builtin_infl: {
8268 const llvm::fltSemantics &Sem =
8269 Info.Ctx.getFloatTypeSemantics(E->
getType());
8270 Result = llvm::APFloat::getInf(Sem);
8274 case Builtin::BI__builtin_nans:
8275 case Builtin::BI__builtin_nansf:
8276 case Builtin::BI__builtin_nansl:
8282 case Builtin::BI__builtin_nan:
8283 case Builtin::BI__builtin_nanf:
8284 case Builtin::BI__builtin_nanl:
8292 case Builtin::BI__builtin_fabs:
8293 case Builtin::BI__builtin_fabsf:
8294 case Builtin::BI__builtin_fabsl:
8298 if (Result.isNegative())
8299 Result.changeSign();
8306 case Builtin::BI__builtin_copysign:
8307 case Builtin::BI__builtin_copysignf:
8308 case Builtin::BI__builtin_copysignl: {
8313 Result.copySign(RHS);
8319 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
8324 Result = CV.FloatReal;
8331 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
8336 Result = CV.FloatImag;
8341 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
8342 Result = llvm::APFloat::getZero(Sem);
8346 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
8348 default:
return Error(E);
8354 Result.changeSign();
8359 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
8361 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8365 if (!LHSOK && !Info.noteFailure())
8371 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
8376 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8381 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8383 case CK_IntegralToFloating: {
8390 case CK_FloatingCast: {
8391 if (!Visit(SubExpr))
8397 case CK_FloatingComplexToReal: {
8401 Result = V.getComplexFloatReal();
8412 class ComplexExprEvaluator
8413 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
8414 ComplexValue &Result;
8417 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
8418 : ExprEvaluatorBaseTy(info), Result(Result) {}
8425 bool ZeroInitialization(
const Expr *E);
8432 bool VisitCastExpr(
const CastExpr *E);
8442 return ComplexExprEvaluator(Info, Result).Visit(E);
8445 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
8448 Result.makeComplexFloat();
8449 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
8450 Result.FloatReal = Zero;
8451 Result.FloatImag = Zero;
8453 Result.makeComplexInt();
8454 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
8455 Result.IntReal = Zero;
8456 Result.IntImag = Zero;
8461 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
8465 Result.makeComplexFloat();
8466 APFloat &Imag = Result.FloatImag;
8470 Result.FloatReal = APFloat(Imag.getSemantics());
8474 "Unexpected imaginary literal.");
8476 Result.makeComplexInt();
8477 APSInt &Imag = Result.IntImag;
8481 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
8486 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
8490 case CK_BaseToDerived:
8491 case CK_DerivedToBase:
8492 case CK_UncheckedDerivedToBase:
8495 case CK_ArrayToPointerDecay:
8496 case CK_FunctionToPointerDecay:
8497 case CK_NullToPointer:
8498 case CK_NullToMemberPointer:
8499 case CK_BaseToDerivedMemberPointer:
8500 case CK_DerivedToBaseMemberPointer:
8501 case CK_MemberPointerToBoolean:
8502 case CK_ReinterpretMemberPointer:
8503 case CK_ConstructorConversion:
8504 case CK_IntegralToPointer:
8505 case CK_PointerToIntegral:
8506 case CK_PointerToBoolean:
8508 case CK_VectorSplat:
8509 case CK_IntegralCast:
8510 case CK_BooleanToSignedIntegral:
8511 case CK_IntegralToBoolean:
8512 case CK_IntegralToFloating:
8513 case CK_FloatingToIntegral:
8514 case CK_FloatingToBoolean:
8515 case CK_FloatingCast:
8516 case CK_CPointerToObjCPointerCast:
8517 case CK_BlockPointerToObjCPointerCast:
8518 case CK_AnyPointerToBlockPointerCast:
8519 case CK_ObjCObjectLValueCast:
8520 case CK_FloatingComplexToReal:
8521 case CK_FloatingComplexToBoolean:
8522 case CK_IntegralComplexToReal:
8523 case CK_IntegralComplexToBoolean:
8524 case CK_ARCProduceObject:
8525 case CK_ARCConsumeObject:
8526 case CK_ARCReclaimReturnedObject:
8527 case CK_ARCExtendBlockObject:
8528 case CK_CopyAndAutoreleaseBlockObject:
8529 case CK_BuiltinFnToFnPtr:
8530 case CK_ZeroToOCLEvent:
8531 case CK_NonAtomicToAtomic:
8532 case CK_AddressSpaceConversion:
8533 llvm_unreachable(
"invalid cast kind for complex value");
8535 case CK_LValueToRValue:
8536 case CK_AtomicToNonAtomic:
8538 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8541 case CK_LValueBitCast:
8542 case CK_UserDefinedConversion:
8545 case CK_FloatingRealToComplex: {
8546 APFloat &Real = Result.FloatReal;
8550 Result.makeComplexFloat();
8551 Result.FloatImag = APFloat(Real.getSemantics());
8555 case CK_FloatingComplexCast: {
8567 case CK_FloatingComplexToIntegralComplex: {
8574 Result.makeComplexInt();
8576 To, Result.IntReal) &&
8578 To, Result.IntImag);
8581 case CK_IntegralRealToComplex: {
8582 APSInt &Real = Result.IntReal;
8586 Result.makeComplexInt();
8587 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
8591 case CK_IntegralComplexCast: {
8604 case CK_IntegralComplexToFloatingComplex: {
8611 Result.makeComplexFloat();
8613 To, Result.FloatReal) &&
8615 To, Result.FloatImag);
8619 llvm_unreachable(
"unknown cast resulting in complex value");
8622 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
8624 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
8628 bool LHSReal =
false, RHSReal =
false;
8633 APFloat &Real = Result.FloatReal;
8636 Result.makeComplexFloat();
8637 Result.FloatImag = APFloat(Real.getSemantics());
8640 LHSOK = Visit(E->
getLHS());
8642 if (!LHSOK && !Info.noteFailure())
8648 APFloat &Real = RHS.FloatReal;
8651 RHS.makeComplexFloat();
8652 RHS.FloatImag = APFloat(Real.getSemantics());
8656 assert(!(LHSReal && RHSReal) &&
8657 "Cannot have both operands of a complex operation be real.");
8659 default:
return Error(E);
8661 if (Result.isComplexFloat()) {
8662 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
8663 APFloat::rmNearestTiesToEven);
8665 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
8667 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
8668 APFloat::rmNearestTiesToEven);
8670 Result.getComplexIntReal() += RHS.getComplexIntReal();
8671 Result.getComplexIntImag() += RHS.getComplexIntImag();
8675 if (Result.isComplexFloat()) {
8676 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
8677 APFloat::rmNearestTiesToEven);
8679 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
8680 Result.getComplexFloatImag().changeSign();
8681 }
else if (!RHSReal) {
8682 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
8683 APFloat::rmNearestTiesToEven);
8686 Result.getComplexIntReal() -= RHS.getComplexIntReal();
8687 Result.getComplexIntImag() -= RHS.getComplexIntImag();
8691 if (Result.isComplexFloat()) {
8696 ComplexValue LHS = Result;
8697 APFloat &A = LHS.getComplexFloatReal();
8698 APFloat &B = LHS.getComplexFloatImag();
8699 APFloat &C = RHS.getComplexFloatReal();
8700 APFloat &D = RHS.getComplexFloatImag();
8701 APFloat &ResR = Result.getComplexFloatReal();
8702 APFloat &ResI = Result.getComplexFloatImag();
8704 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
8707 }
else if (RHSReal) {
8719 if (ResR.isNaN() && ResI.isNaN()) {
8720 bool Recalc =
false;
8721 if (A.isInfinity() || B.isInfinity()) {
8722 A = APFloat::copySign(
8723 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
8724 B = APFloat::copySign(
8725 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
8727 C = APFloat::copySign(APFloat(C.getSemantics()), C);
8729 D = APFloat::copySign(APFloat(D.getSemantics()), D);
8732 if (C.isInfinity() || D.isInfinity()) {
8733 C = APFloat::copySign(
8734 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
8735 D = APFloat::copySign(
8736 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
8738 A = APFloat::copySign(APFloat(A.getSemantics()), A);
8740 B = APFloat::copySign(APFloat(B.getSemantics()), B);
8743 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
8744 AD.isInfinity() || BC.isInfinity())) {
8746 A = APFloat::copySign(APFloat(A.getSemantics()), A);
8748 B = APFloat::copySign(APFloat(B.getSemantics()), B);
8750 C = APFloat::copySign(APFloat(C.getSemantics()), C);
8752 D = APFloat::copySign(APFloat(D.getSemantics()), D);
8756 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
8757 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
8762 ComplexValue LHS = Result;
8763 Result.getComplexIntReal() =
8764 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
8765 LHS.getComplexIntImag() * RHS.getComplexIntImag());
8766 Result.getComplexIntImag() =
8767 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
8768 LHS.getComplexIntImag() * RHS.getComplexIntReal());
8772 if (Result.isComplexFloat()) {
8777 ComplexValue LHS = Result;
8778 APFloat &A = LHS.getComplexFloatReal();
8779 APFloat &B = LHS.getComplexFloatImag();
8780 APFloat &C = RHS.getComplexFloatReal();
8781 APFloat &D = RHS.getComplexFloatImag();
8782 APFloat &ResR = Result.getComplexFloatReal();
8783 APFloat &ResI = Result.getComplexFloatImag();
8790 B = APFloat::getZero(A.getSemantics());
8793 APFloat MaxCD = maxnum(
abs(C),
abs(D));
8794 if (MaxCD.isFinite()) {
8795 DenomLogB =
ilogb(MaxCD);
8796 C =
scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
8797 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
8799 APFloat Denom = C * C + D * D;
8800 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB,
8801 APFloat::rmNearestTiesToEven);
8802 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB,
8803 APFloat::rmNearestTiesToEven);
8804 if (ResR.isNaN() && ResI.isNaN()) {
8805 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
8806 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
8807 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
8808 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
8810 A = APFloat::copySign(
8811 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
8812 B = APFloat::copySign(
8813 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
8814 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
8815 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
8816 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
8817 C = APFloat::copySign(
8818 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
8819 D = APFloat::copySign(
8820 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
8821 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
8822 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
8827 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
8828 return Error(E, diag::note_expr_divide_by_zero);
8830 ComplexValue LHS = Result;
8831 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
8832 RHS.getComplexIntImag() * RHS.getComplexIntImag();
8833 Result.getComplexIntReal() =
8834 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
8835 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
8836 Result.getComplexIntImag() =
8837 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
8838 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
8846 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
8860 if (Result.isComplexFloat()) {
8861 Result.getComplexFloatReal().changeSign();
8862 Result.getComplexFloatImag().changeSign();
8865 Result.getComplexIntReal() = -Result.getComplexIntReal();
8866 Result.getComplexIntImag() = -Result.getComplexIntImag();
8870 if (Result.isComplexFloat())
8871 Result.getComplexFloatImag().changeSign();
8873 Result.getComplexIntImag() = -Result.getComplexIntImag();
8878 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
8881 Result.makeComplexFloat();
8887 Result.makeComplexInt();
8895 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
8904 class AtomicExprEvaluator :
8905 public ExprEvaluatorBase<AtomicExprEvaluator> {
8908 AtomicExprEvaluator(EvalInfo &Info,
APValue &Result)
8909 : ExprEvaluatorBaseTy(Info), Result(Result) {}
8916 bool ZeroInitialization(
const Expr *E) {
8919 return Evaluate(Result, Info, &VIE);
8922 bool VisitCastExpr(
const CastExpr *E) {
8925 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8926 case CK_NonAtomicToAtomic:
8935 return AtomicExprEvaluator(Info, Result).Visit(E);
8944 class VoidExprEvaluator
8945 :
public ExprEvaluatorBase<VoidExprEvaluator> {
8947 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
8949 bool Success(
const APValue &V,
const Expr *e) {
return true; }
8951 bool VisitCastExpr(
const CastExpr *E) {
8954 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8961 bool VisitCallExpr(
const CallExpr *E) {
8964 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8965 case Builtin::BI__assume:
8966 case Builtin::BI__builtin_assume:
8976 return VoidExprEvaluator(Info).Visit(E);
8991 LV.moveInto(Result);
8996 if (!IntExprEvaluator(Info, Result).Visit(E))
9002 LV.moveInto(Result);
9004 llvm::APFloat F(0.0);
9021 LV.set(E, Info.CurrentCall->Index);
9022 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
9028 LV.set(E, Info.CurrentCall->Index);
9029 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
9034 if (!Info.getLangOpts().CPlusPlus11)
9035 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
9042 }
else if (Info.getLangOpts().CPlusPlus11) {
9043 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
9046 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
9057 const Expr *E,
bool AllowNonLiteralTypes) {
9090 LV.setFrom(Info.Ctx, Result);
9105 L->getType()->isUnsignedIntegerType()));
9139 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
9158 if (!
getType()->isIntegralOrEnumerationType())
9166 Result = ExprResult.Val.getInt();
9172 if (!
getType()->isRealFloatingType())
9180 Result = ExprResult.Val.getFloat();
9185 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
9193 LV.moveInto(Result.Val);
9207 EStatus.
Diag = &Notes;
9210 ? EvalInfo::EM_ConstantExpression
9211 : EvalInfo::EM_ConstantFold);
9212 InitInfo.setEvaluatingDecl(VD, Value);
9249 EvalResult.Diag =
Diag;
9252 assert(Result &&
"Could not evaluate expression");
9253 assert(EvalResult.Val.isInt() &&
"Expression did not evaluate to integer");
9255 return EvalResult.Val.getInt();
9262 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
9268 assert(Val.isLValue());
9296 IK_ICEIfUnevaluated,
9312 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
9318 return ICEDiag(IK_NotICE, E->getLocStart());
9326 return ICEDiag(IK_NotICE, E->getLocStart());
9328 switch (E->getStmtClass()) {
9329 #define ABSTRACT_STMT(Node)
9330 #define STMT(Node, Base) case Expr::Node##Class:
9331 #define EXPR(Node, Base)
9332 #include "clang/AST/StmtNodes.inc"
9333 case Expr::PredefinedExprClass:
9334 case Expr::FloatingLiteralClass:
9335 case Expr::ImaginaryLiteralClass:
9336 case Expr::StringLiteralClass:
9337 case Expr::ArraySubscriptExprClass:
9338 case Expr::OMPArraySectionExprClass:
9339 case Expr::MemberExprClass:
9340 case Expr::CompoundAssignOperatorClass:
9341 case Expr::CompoundLiteralExprClass:
9342 case Expr::ExtVectorElementExprClass:
9343 case Expr::DesignatedInitExprClass:
9344 case Expr::NoInitExprClass:
9345 case Expr::DesignatedInitUpdateExprClass:
9346 case Expr::ImplicitValueInitExprClass:
9347 case Expr::ParenListExprClass:
9348 case Expr::VAArgExprClass:
9349 case Expr::AddrLabelExprClass:
9350 case Expr::StmtExprClass:
9351 case Expr::CXXMemberCallExprClass:
9352 case Expr::CUDAKernelCallExprClass:
9353 case Expr::CXXDynamicCastExprClass:
9354 case Expr::CXXTypeidExprClass:
9355 case Expr::CXXUuidofExprClass:
9356 case Expr::MSPropertyRefExprClass:
9357 case Expr::MSPropertySubscriptExprClass:
9358 case Expr::CXXNullPtrLiteralExprClass:
9359 case Expr::UserDefinedLiteralClass:
9360 case Expr::CXXThisExprClass:
9361 case Expr::CXXThrowExprClass:
9362 case Expr::CXXNewExprClass:
9363 case Expr::CXXDeleteExprClass:
9364 case Expr::CXXPseudoDestructorExprClass:
9365 case Expr::UnresolvedLookupExprClass:
9366 case Expr::TypoExprClass:
9367 case Expr::DependentScopeDeclRefExprClass:
9368 case Expr::CXXConstructExprClass:
9369 case Expr::CXXInheritedCtorInitExprClass:
9370 case Expr::CXXStdInitializerListExprClass:
9371 case Expr::CXXBindTemporaryExprClass:
9372 case Expr::ExprWithCleanupsClass:
9373 case Expr::CXXTemporaryObjectExprClass:
9374 case Expr::CXXUnresolvedConstructExprClass:
9375 case Expr::CXXDependentScopeMemberExprClass:
9376 case Expr::UnresolvedMemberExprClass:
9377 case Expr::ObjCStringLiteralClass:
9378 case Expr::ObjCBoxedExprClass:
9379 case Expr::ObjCArrayLiteralClass:
9380 case Expr::ObjCDictionaryLiteralClass:
9381 case Expr::ObjCEncodeExprClass:
9382 case Expr::ObjCMessageExprClass:
9383 case Expr::ObjCSelectorExprClass:
9384 case Expr::ObjCProtocolExprClass:
9385 case Expr::ObjCIvarRefExprClass:
9386 case Expr::ObjCPropertyRefExprClass:
9387 case Expr::ObjCSubscriptRefExprClass:
9388 case Expr::ObjCIsaExprClass:
9389 case Expr::ObjCAvailabilityCheckExprClass:
9390 case Expr::ShuffleVectorExprClass:
9391 case Expr::ConvertVectorExprClass:
9392 case Expr::BlockExprClass:
9393 case Expr::NoStmtClass:
9394 case Expr::OpaqueValueExprClass:
9395 case Expr::PackExpansionExprClass:
9396 case Expr::SubstNonTypeTemplateParmPackExprClass:
9397 case Expr::FunctionParmPackExprClass:
9398 case Expr::AsTypeExprClass:
9399 case Expr::ObjCIndirectCopyRestoreExprClass:
9400 case Expr::MaterializeTemporaryExprClass:
9401 case Expr::PseudoObjectExprClass:
9402 case Expr::AtomicExprClass:
9403 case Expr::LambdaExprClass:
9404 case Expr::CXXFoldExprClass:
9405 case Expr::CoawaitExprClass:
9406 case Expr::CoyieldExprClass:
9407 return ICEDiag(IK_NotICE, E->getLocStart());
9409 case Expr::InitListExprClass: {
9415 if (cast<InitListExpr>(E)->getNumInits() == 1)
9416 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
9417 return ICEDiag(IK_NotICE, E->getLocStart());
9420 case Expr::SizeOfPackExprClass:
9421 case Expr::GNUNullExprClass:
9425 case Expr::SubstNonTypeTemplateParmExprClass:
9427 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
9429 case Expr::ParenExprClass:
9430 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
9431 case Expr::GenericSelectionExprClass:
9432 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
9433 case Expr::IntegerLiteralClass:
9434 case Expr::CharacterLiteralClass:
9435 case Expr::ObjCBoolLiteralExprClass:
9436 case Expr::CXXBoolLiteralExprClass:
9437 case Expr::CXXScalarValueInitExprClass:
9438 case Expr::TypeTraitExprClass:
9439 case Expr::ArrayTypeTraitExprClass:
9440 case Expr::ExpressionTraitExprClass:
9441 case Expr::CXXNoexceptExprClass:
9443 case Expr::CallExprClass:
9444 case Expr::CXXOperatorCallExprClass: {
9451 return ICEDiag(IK_NotICE, E->getLocStart());
9453 case Expr::DeclRefExprClass: {
9454 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
9462 if (isa<ParmVarDecl>(D))
9463 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
9468 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
9469 if (!Dcl->getType()->isIntegralOrEnumerationType())
9470 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
9478 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
9481 return ICEDiag(IK_NotICE, E->getLocStart());
9483 case Expr::UnaryOperatorClass: {
9496 return ICEDiag(IK_NotICE, E->getLocStart());
9509 case Expr::OffsetOfExprClass: {
9518 case Expr::UnaryExprOrTypeTraitExprClass: {
9522 return ICEDiag(IK_NotICE, E->getLocStart());
9525 case Expr::BinaryOperatorClass: {
9544 return ICEDiag(IK_NotICE, E->getLocStart());
9569 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
9572 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
9573 if (REval.isSigned() && REval.isAllOnesValue()) {
9575 if (LEval.isMinSignedValue())
9576 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
9584 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
9585 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
9588 return ICEDiag(IK_NotICE, E->getLocStart());
9591 return Worst(LHSResult, RHSResult);
9597 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
9607 return Worst(LHSResult, RHSResult);
9611 case Expr::ImplicitCastExprClass:
9612 case Expr::CStyleCastExprClass:
9613 case Expr::CXXFunctionalCastExprClass:
9614 case Expr::CXXStaticCastExprClass:
9615 case Expr::CXXReinterpretCastExprClass:
9616 case Expr::CXXConstCastExprClass:
9617 case Expr::ObjCBridgedCastExprClass: {
9618 const Expr *SubExpr = cast<CastExpr>(
E)->getSubExpr();
9619 if (isa<ExplicitCastExpr>(E)) {
9624 APSInt IgnoredVal(DestWidth, !DestSigned);
9629 if (FL->getValue().convertToInteger(IgnoredVal,
9630 llvm::APFloat::rmTowardZero,
9631 &Ignored) & APFloat::opInvalidOp)
9632 return ICEDiag(IK_NotICE, E->getLocStart());
9636 switch (cast<CastExpr>(E)->getCastKind()) {
9637 case CK_LValueToRValue:
9638 case CK_AtomicToNonAtomic:
9639 case CK_NonAtomicToAtomic:
9641 case CK_IntegralToBoolean:
9642 case CK_IntegralCast:
9645 return ICEDiag(IK_NotICE, E->getLocStart());
9648 case Expr::BinaryConditionalOperatorClass: {
9651 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
9653 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
9654 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
9655 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
9659 case Expr::ConditionalOperatorClass: {
9667 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
9670 if (CondResult.Kind == IK_NotICE)
9676 if (TrueResult.Kind == IK_NotICE)
9678 if (FalseResult.Kind == IK_NotICE)
9680 if (CondResult.Kind == IK_ICEIfUnevaluated)
9682 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
9691 case Expr::CXXDefaultArgExprClass:
9692 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
9693 case Expr::CXXDefaultInitExprClass:
9694 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
9695 case Expr::ChooseExprClass: {
9696 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
9700 llvm_unreachable(
"Invalid StmtClass!");
9706 llvm::APSInt *Value,
9717 if (!Result.
isInt()) {
9722 if (Value) *Value = Result.
getInt();
9732 if (D.Kind != IK_ICE) {
9733 if (Loc) *Loc = D.Loc;
9751 llvm_unreachable(
"ICE cannot be evaluated!");
9756 return CheckICE(
this, Ctx).Kind == IK_ICE;
9768 Status.Diag = &Diags;
9769 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
9774 if (!Diags.empty()) {
9775 IsConstExpr =
false;
9776 if (Loc) *Loc = Diags[0].first;
9777 }
else if (!IsConstExpr) {
9789 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
9791 ArgVector ArgValues(Args.size());
9794 if ((*I)->isValueDependent() ||
9795 !
Evaluate(ArgValues[I - Args.begin()], Info, *
I))
9797 ArgValues[I - Args.begin()] =
APValue();
9798 if (Info.EvalStatus.HasSideEffects)
9803 CallStackFrame Frame(Info, Callee->getLocation(), Callee,
nullptr,
9805 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
9818 Status.
Diag = &Diags;
9820 EvalInfo Info(FD->getASTContext(), Status,
9821 EvalInfo::EM_PotentialConstantExpression);
9830 This.set(&VIE, Info.CurrentCall->Index);
9838 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
9843 Args, FD->
getBody(), Info, Scratch,
nullptr);
9846 return Diags.empty();
9854 Status.
Diag = &Diags;
9856 EvalInfo Info(FD->getASTContext(), Status,
9857 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
9861 ArgVector ArgValues(0);
9865 "Failed to set up arguments for potential constant evaluation");
9866 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
9870 return Diags.empty();
9874 unsigned Type)
const {
9875 if (!
getType()->isPointerType())
9879 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
unsigned getNumElements() const
unsigned getAddressSpace() const
Return the address space of this type.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
static bool HandleConstructorCall(const Expr *E, const LValue &This, APValue *ArgValues, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
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...
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
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.
__DEVICE__ long long abs(long long __n)
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)
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.
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...
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.
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...
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
const llvm::APInt & getSize() const
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...
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...
field_iterator field_begin() const
The "__interface" keyword.
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
bool isMemberDataPointerType() const
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.
return(__x >> __y)|(__x<< (32-__y))
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 ...
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
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
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...
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr...
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...
unsigned getLValueCallIndex() const
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression as an lvalue.
static bool isRelationalOp(Opcode Opc)
static bool IsWeakLValue(const LValue &Value)
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...
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.
static int EvaluateBuiltinClassifyType(const CallExpr *E, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
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
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...
TypeClass getTypeClass() const
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.
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)
CXXConstructorDecl * getConstructor() const
bool isAddrLabelDiff() const
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
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.
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...
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, LValue BaseLV, llvm::Value *Addr)
const Expr * getExpr() const
Get the initialization expression that will be used.
bool HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool isFunctionPointerType() const
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...
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
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.
Allow any unmodeled side effect.
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
ArrayRef< NamedDecl * > chain() const
bool isComplexFloat() const
bool isAtomicType() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
bool isVariableArrayType() const
const ParmVarDecl * getParamDecl(unsigned i) const
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)
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
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
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
PartialDiagnostic::StorageAllocator & getDiagAllocator()
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
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
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.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
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...
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition, const Stmt *Body)
CheckConstexprFunction - Check that a function can be called in a constant expression.
APValue & getStructBase(unsigned i)
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
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.
Represents a call to an inherited base class constructor from an inheriting constructor.
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
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.
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
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.
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.
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)
bool isMemberFunctionPointerType() const
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)
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 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.
bool isZero() const
isZero - Test whether the quantity equals zero.
static bool isZeroSized(const LValue &Value)
const Stmt * getBody() const
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
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
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.
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.
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.
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...
QualType getCanonicalType() const
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)
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
static bool isAdditiveOp(Opcode Opc)
Expr * getArg(unsigned Arg)
Return the specified argument.
Base for LValueReferenceType and RValueReferenceType.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
ActionResult< Stmt * > StmtResult
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.
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...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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.
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...
This class is used for builtin types like 'int'.
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
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.
A reference to a declared variable, function, enum, etc.
Designator - A designator in a C99 designated initializer.
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.
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...
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
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.
DeclStmt * getBeginStmt()
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.
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