47 #include "llvm/Support/raw_ostream.h" 51 #define DEBUG_TYPE "exprconstant" 53 using namespace clang;
61 struct CallStackFrame;
74 for (
auto *Redecl = cast<ValueDecl>(D->getMostRecentDecl()); Redecl;
75 Redecl = cast_or_null<ValueDecl>(Redecl->getPreviousDecl())) {
88 dyn_cast<MaterializeTemporaryExpr>(Base)) {
91 const Expr *Temp = MTE->GetTemporaryExpr();
96 if (!Adjustments.empty())
115 return dyn_cast<
FieldDecl>(getAsBaseOrMember(E).getPointer());
120 return dyn_cast<
CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
125 return getAsBaseOrMember(E).getInt();
129 static const AllocSizeAttr *getAllocSizeAttr(
const CallExpr *CE) {
131 return Callee ? Callee->
getAttr<AllocSizeAttr>() :
nullptr;
138 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
146 if (
const auto *EC = dyn_cast<ExprWithCleanups>(E))
149 if (
const auto *Cast = dyn_cast<CastExpr>(E))
152 if (
const auto *CE = dyn_cast<CallExpr>(E))
153 return getAllocSizeAttr(CE) ? CE :
nullptr;
167 static const uint64_t AssumedSizeForUnsizedArray =
178 bool &FirstEntryIsUnsizedArray) {
181 assert(!isBaseAnAllocSizeCall(Base) &&
182 "Unsized arrays shouldn't appear here");
183 unsigned MostDerivedLength = 0;
184 Type = getType(Base);
186 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
190 MostDerivedLength = I + 1;
193 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
194 ArraySize = CAT->getSize().getZExtValue();
196 assert(I == 0 &&
"unexpected unsized array designator");
197 FirstEntryIsUnsizedArray =
true;
198 ArraySize = AssumedSizeForUnsizedArray;
204 MostDerivedLength = I + 1;
206 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
207 Type = FD->getType();
209 MostDerivedLength = I + 1;
217 return MostDerivedLength;
222 CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
223 CSK_This, CSK_Real, CSK_Imag
227 struct SubobjectDesignator {
231 unsigned Invalid : 1;
234 unsigned IsOnePastTheEnd : 1;
237 unsigned FirstEntryIsAnUnsizedArray : 1;
240 unsigned MostDerivedIsArrayElement : 1;
244 unsigned MostDerivedPathLength : 28;
253 uint64_t MostDerivedArraySize;
263 SubobjectDesignator() : Invalid(
true) {}
265 explicit SubobjectDesignator(
QualType T)
266 : Invalid(
false), IsOnePastTheEnd(
false),
267 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
268 MostDerivedPathLength(0), MostDerivedArraySize(0),
269 MostDerivedType(T) {}
273 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
274 MostDerivedPathLength(0), MostDerivedArraySize(0) {
275 assert(V.
isLValue() &&
"Non-LValue used to make an LValue designator?");
279 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
281 bool IsArray =
false;
282 bool FirstIsUnsizedArray =
false;
283 MostDerivedPathLength = findMostDerivedSubobject(
285 MostDerivedType, IsArray, FirstIsUnsizedArray);
286 MostDerivedIsArrayElement = IsArray;
287 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
299 bool isMostDerivedAnUnsizedArray()
const {
300 assert(!Invalid &&
"Calling this makes no sense on invalid designators");
301 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
306 uint64_t getMostDerivedArraySize()
const {
307 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
308 return MostDerivedArraySize;
312 bool isOnePastTheEnd()
const {
316 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
317 Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
323 bool isValidSubobject()
const {
326 return !isOnePastTheEnd();
335 Entry.ArrayIndex = 0;
336 Entries.push_back(Entry);
340 MostDerivedIsArrayElement =
true;
341 MostDerivedArraySize = CAT->
getSize().getZExtValue();
342 MostDerivedPathLength = Entries.size();
346 void addUnsizedArrayUnchecked(
QualType ElemTy) {
348 Entry.ArrayIndex = 0;
349 Entries.push_back(Entry);
351 MostDerivedType = ElemTy;
352 MostDerivedIsArrayElement =
true;
356 MostDerivedArraySize = AssumedSizeForUnsizedArray;
357 MostDerivedPathLength = Entries.size();
361 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
364 Entry.BaseOrMember = Value.getOpaqueValue();
365 Entries.push_back(Entry);
368 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
369 MostDerivedType = FD->getType();
370 MostDerivedIsArrayElement =
false;
371 MostDerivedArraySize = 0;
372 MostDerivedPathLength = Entries.size();
376 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
378 Entry.ArrayIndex = Imag;
379 Entries.push_back(Entry);
383 MostDerivedType = EltTy;
384 MostDerivedIsArrayElement =
true;
385 MostDerivedArraySize = 2;
386 MostDerivedPathLength = Entries.size();
388 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
389 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
392 void adjustIndex(EvalInfo &Info,
const Expr *E, APSInt N) {
393 if (Invalid || !N)
return;
394 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
395 if (isMostDerivedAnUnsizedArray()) {
396 diagnoseUnsizedArrayPointerArithmetic(Info, E);
400 Entries.back().ArrayIndex += TruncatedN;
407 bool IsArray = MostDerivedPathLength == Entries.size() &&
408 MostDerivedIsArrayElement;
409 uint64_t ArrayIndex =
410 IsArray ? Entries.back().ArrayIndex : (uint64_t)IsOnePastTheEnd;
412 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
414 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
417 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
418 (llvm::APInt&)N += ArrayIndex;
419 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
420 diagnosePointerArithmetic(Info, E, N);
425 ArrayIndex += TruncatedN;
426 assert(ArrayIndex <= ArraySize &&
427 "bounds check succeeded for out-of-bounds index");
430 Entries.back().ArrayIndex = ArrayIndex;
432 IsOnePastTheEnd = (ArrayIndex != 0);
437 struct CallStackFrame {
441 CallStackFrame *Caller;
455 typedef std::pair<const void *, unsigned> MapKeyTy;
456 typedef std::map<MapKeyTy, APValue>
MapTy;
468 unsigned CurTempVersion = TempVersionStack.back();
470 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
472 void pushTempVersion() {
473 TempVersionStack.push_back(++CurTempVersion);
476 void popTempVersion() {
477 TempVersionStack.pop_back();
488 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
497 APValue *getTemporary(
const void *Key,
unsigned Version) {
498 MapKeyTy KV(Key, Version);
499 auto LB = Temporaries.lower_bound(KV);
500 if (LB != Temporaries.end() && LB->first == KV)
504 assert((LB == Temporaries.end() || LB->first.first != Key) &&
505 (LB == Temporaries.begin() || std::prev(LB)->first.first != Key) &&
506 "Element with key 'Key' found in map");
511 APValue *getCurrentTemporary(
const void *Key) {
512 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
513 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
514 return &std::prev(UB)->second;
519 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
520 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
521 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
522 return std::prev(UB)->first.second;
530 class ThisOverrideRAII {
532 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
533 : Frame(Frame), OldThis(Frame.This) {
535 Frame.This = NewThis;
537 ~ThisOverrideRAII() {
538 Frame.This = OldThis;
541 CallStackFrame &Frame;
542 const LValue *OldThis;
547 class OptionalDiagnostic {
561 OptionalDiagnostic &
operator<<(
const APSInt &I) {
565 *Diag << StringRef(Buffer.data(), Buffer.size());
570 OptionalDiagnostic &
operator<<(
const APFloat &F) {
579 llvm::APFloat::semanticsPrecision(F.getSemantics());
580 precision = (precision * 59 + 195) / 196;
582 F.toString(Buffer, precision);
583 *Diag << StringRef(Buffer.data(), Buffer.size());
591 llvm::PointerIntPair<APValue*, 1, bool>
Value;
594 Cleanup(
APValue *Val,
bool IsLifetimeExtended)
595 :
Value(Val, IsLifetimeExtended) {}
597 bool isLifetimeExtended()
const {
return Value.getInt(); }
599 *Value.getPointer() =
APValue();
624 CallStackFrame *CurrentCall;
627 unsigned CallStackDepth;
630 unsigned NextCallIndex;
639 CallStackFrame BottomFrame;
655 typedef std::pair<APValue::LValueBase, std::pair<unsigned, unsigned>>
662 struct EvaluatingConstructorRAII {
664 EvaluatingObject Object;
666 EvaluatingConstructorRAII(EvalInfo &EI, EvaluatingObject Object)
667 : EI(EI), Object(Object) {
668 DidInsert = EI.EvaluatingConstructors.insert(Object).second;
670 ~EvaluatingConstructorRAII() {
671 if (DidInsert) EI.EvaluatingConstructors.erase(Object);
677 return EvaluatingConstructors.count(
678 EvaluatingObject(Decl, {CallIndex, Version}));
683 uint64_t ArrayInitIndex = -1;
687 bool HasActiveDiagnostic;
691 bool HasFoldFailureDiagnostic;
694 bool IsSpeculativelyEvaluating;
696 enum EvaluationMode {
699 EM_ConstantExpression,
705 EM_PotentialConstantExpression,
714 EM_EvaluateForOverflow,
718 EM_IgnoreSideEffects,
725 EM_ConstantExpressionUnevaluated,
734 EM_PotentialConstantExpressionUnevaluated,
751 bool checkingPotentialConstantExpression()
const {
752 return EvalMode == EM_PotentialConstantExpression ||
753 EvalMode == EM_PotentialConstantExpressionUnevaluated;
759 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
762 : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(
nullptr),
763 CallStackDepth(0), NextCallIndex(1),
764 StepsLeft(getLangOpts().ConstexprStepLimit),
766 EvaluatingDecl((
const ValueDecl *)
nullptr),
767 EvaluatingDeclValue(
nullptr), HasActiveDiagnostic(
false),
768 HasFoldFailureDiagnostic(
false), IsSpeculativelyEvaluating(
false),
772 EvaluatingDecl = Base;
773 EvaluatingDeclValue = &
Value;
774 EvaluatingConstructors.insert({Base, {0, 0}});
782 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
784 if (NextCallIndex == 0) {
786 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
789 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
791 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
792 << getLangOpts().ConstexprCallDepth;
796 CallStackFrame *getCallFrame(
unsigned CallIndex) {
797 assert(CallIndex &&
"no call index in getCallFrame");
800 CallStackFrame *Frame = CurrentCall;
801 while (Frame->Index > CallIndex)
802 Frame = Frame->Caller;
803 return (Frame->Index == CallIndex) ? Frame :
nullptr;
806 bool nextStep(
const Stmt *S) {
808 FFDiag(S->
getLocStart(), diag::note_constexpr_step_limit_exceeded);
819 EvalStatus.
Diag->push_back(std::make_pair(Loc, PD));
820 return EvalStatus.
Diag->back().second;
824 void addCallStack(
unsigned Limit);
828 unsigned ExtraNotes,
bool IsCCEDiag) {
830 if (EvalStatus.
Diag) {
837 if (!EvalStatus.
Diag->empty()) {
839 case EM_ConstantFold:
840 case EM_IgnoreSideEffects:
841 case EM_EvaluateForOverflow:
842 if (!HasFoldFailureDiagnostic)
846 case EM_ConstantExpression:
847 case EM_PotentialConstantExpression:
848 case EM_ConstantExpressionUnevaluated:
849 case EM_PotentialConstantExpressionUnevaluated:
851 HasActiveDiagnostic =
false;
852 return OptionalDiagnostic();
856 unsigned CallStackNotes = CallStackDepth - 1;
859 CallStackNotes =
std::min(CallStackNotes, Limit + 1);
860 if (checkingPotentialConstantExpression())
863 HasActiveDiagnostic =
true;
864 HasFoldFailureDiagnostic = !IsCCEDiag;
865 EvalStatus.
Diag->clear();
866 EvalStatus.
Diag->reserve(1 + ExtraNotes + CallStackNotes);
867 addDiag(Loc, DiagId);
868 if (!checkingPotentialConstantExpression())
870 return OptionalDiagnostic(&(*EvalStatus.
Diag)[0].second);
872 HasActiveDiagnostic =
false;
873 return OptionalDiagnostic();
879 diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr,
880 unsigned ExtraNotes = 0) {
881 return Diag(Loc, DiagId, ExtraNotes,
false);
885 = diag::note_invalid_subexpr_in_const_expr,
886 unsigned ExtraNotes = 0) {
889 HasActiveDiagnostic =
false;
890 return OptionalDiagnostic();
899 = diag::note_invalid_subexpr_in_const_expr,
900 unsigned ExtraNotes = 0) {
903 if (!EvalStatus.
Diag || !EvalStatus.
Diag->empty()) {
904 HasActiveDiagnostic =
false;
905 return OptionalDiagnostic();
907 return Diag(Loc, DiagId, ExtraNotes,
true);
910 = diag::note_invalid_subexpr_in_const_expr,
911 unsigned ExtraNotes = 0) {
912 return CCEDiag(E->
getExprLoc(), DiagId, ExtraNotes);
916 if (!HasActiveDiagnostic)
917 return OptionalDiagnostic();
918 return OptionalDiagnostic(&addDiag(Loc, DiagId));
923 if (HasActiveDiagnostic) {
924 EvalStatus.
Diag->insert(EvalStatus.
Diag->end(),
925 Diags.begin(), Diags.end());
931 bool keepEvaluatingAfterSideEffect() {
933 case EM_PotentialConstantExpression:
934 case EM_PotentialConstantExpressionUnevaluated:
935 case EM_EvaluateForOverflow:
936 case EM_IgnoreSideEffects:
939 case EM_ConstantExpression:
940 case EM_ConstantExpressionUnevaluated:
941 case EM_ConstantFold:
945 llvm_unreachable(
"Missed EvalMode case");
950 bool noteSideEffect() {
952 return keepEvaluatingAfterSideEffect();
956 bool keepEvaluatingAfterUndefinedBehavior() {
958 case EM_EvaluateForOverflow:
959 case EM_IgnoreSideEffects:
960 case EM_ConstantFold:
964 case EM_PotentialConstantExpression:
965 case EM_PotentialConstantExpressionUnevaluated:
966 case EM_ConstantExpression:
967 case EM_ConstantExpressionUnevaluated:
970 llvm_unreachable(
"Missed EvalMode case");
976 bool noteUndefinedBehavior() {
978 return keepEvaluatingAfterUndefinedBehavior();
983 bool keepEvaluatingAfterFailure() {
988 case EM_PotentialConstantExpression:
989 case EM_PotentialConstantExpressionUnevaluated:
990 case EM_EvaluateForOverflow:
993 case EM_ConstantExpression:
994 case EM_ConstantExpressionUnevaluated:
995 case EM_ConstantFold:
996 case EM_IgnoreSideEffects:
1000 llvm_unreachable(
"Missed EvalMode case");
1013 LLVM_NODISCARD
bool noteFailure() {
1021 bool KeepGoing = keepEvaluatingAfterFailure();
1026 class ArrayInitLoopIndex {
1028 uint64_t OuterIndex;
1031 ArrayInitLoopIndex(EvalInfo &Info)
1032 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1033 Info.ArrayInitIndex = 0;
1035 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1037 operator uint64_t&() {
return Info.ArrayInitIndex; }
1042 struct FoldConstant {
1045 bool HadNoPriorDiags;
1046 EvalInfo::EvaluationMode OldMode;
1048 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1051 HadNoPriorDiags(Info.EvalStatus.Diag &&
1052 Info.EvalStatus.Diag->empty() &&
1053 !Info.EvalStatus.HasSideEffects),
1054 OldMode(Info.EvalMode) {
1056 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
1057 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
1058 Info.EvalMode = EvalInfo::EM_ConstantFold;
1060 void keepDiagnostics() { Enabled =
false; }
1062 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1063 !Info.EvalStatus.HasSideEffects)
1064 Info.EvalStatus.Diag->clear();
1065 Info.EvalMode = OldMode;
1071 struct FoldOffsetRAII {
1073 EvalInfo::EvaluationMode OldMode;
1074 explicit FoldOffsetRAII(EvalInfo &Info)
1075 : Info(Info), OldMode(Info.EvalMode) {
1076 if (!Info.checkingPotentialConstantExpression())
1077 Info.EvalMode = EvalInfo::EM_OffsetFold;
1080 ~FoldOffsetRAII() { Info.EvalMode = OldMode; }
1085 class SpeculativeEvaluationRAII {
1086 EvalInfo *Info =
nullptr;
1088 bool OldIsSpeculativelyEvaluating;
1090 void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
1092 OldStatus = Other.OldStatus;
1093 OldIsSpeculativelyEvaluating = Other.OldIsSpeculativelyEvaluating;
1094 Other.Info =
nullptr;
1097 void maybeRestoreState() {
1101 Info->EvalStatus = OldStatus;
1102 Info->IsSpeculativelyEvaluating = OldIsSpeculativelyEvaluating;
1106 SpeculativeEvaluationRAII() =
default;
1108 SpeculativeEvaluationRAII(
1110 : Info(&Info), OldStatus(Info.EvalStatus),
1111 OldIsSpeculativelyEvaluating(Info.IsSpeculativelyEvaluating) {
1112 Info.EvalStatus.Diag = NewDiag;
1113 Info.IsSpeculativelyEvaluating =
true;
1116 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &Other) =
delete;
1117 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&Other) {
1118 moveFromAndCancel(std::move(Other));
1121 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&Other) {
1122 maybeRestoreState();
1123 moveFromAndCancel(std::move(Other));
1127 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1132 template<
bool IsFullExpression>
1135 unsigned OldStackSize;
1137 ScopeRAII(EvalInfo &Info)
1138 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1141 Info.CurrentCall->pushTempVersion();
1147 Info.CurrentCall->popTempVersion();
1150 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
1151 unsigned NewEnd = OldStackSize;
1152 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
1154 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
1157 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
1161 Info.CleanupStack[I].endLifetime();
1164 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
1165 Info.CleanupStack.end());
1168 typedef ScopeRAII<false> BlockScopeRAII;
1169 typedef ScopeRAII<true> FullExpressionRAII;
1172 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1176 if (isOnePastTheEnd()) {
1177 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1188 void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1190 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1195 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1200 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1201 Info.CCEDiag(E, diag::note_constexpr_array_index)
1203 <<
static_cast<unsigned>(getMostDerivedArraySize());
1205 Info.CCEDiag(E, diag::note_constexpr_array_index)
1210 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
1213 : Info(Info), Caller(Info.CurrentCall), Callee(Callee), This(This),
1214 Arguments(Arguments), CallLoc(CallLoc), Index(Info.NextCallIndex++) {
1215 Info.CurrentCall =
this;
1216 ++Info.CallStackDepth;
1219 CallStackFrame::~CallStackFrame() {
1220 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1221 --Info.CallStackDepth;
1222 Info.CurrentCall = Caller;
1226 bool IsLifetimeExtended) {
1227 unsigned Version = Info.CurrentCall->getTempVersion();
1229 assert(Result.
isUninit() &&
"temporary created multiple times");
1230 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
1234 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
1236 void EvalInfo::addCallStack(
unsigned Limit) {
1238 unsigned ActiveCalls = CallStackDepth - 1;
1239 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
1240 if (Limit && Limit < ActiveCalls) {
1241 SkipStart = Limit / 2 + Limit % 2;
1242 SkipEnd = ActiveCalls - Limit / 2;
1246 unsigned CallIdx = 0;
1247 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
1248 Frame = Frame->Caller, ++CallIdx) {
1250 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
1251 if (CallIdx == SkipStart) {
1253 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
1254 << unsigned(ActiveCalls - Limit);
1261 if (
auto *CD = dyn_cast_or_null<CXXConstructorDecl>(Frame->Callee)) {
1262 if (CD->isInheritingConstructor()) {
1263 addDiag(Frame->CallLoc, diag::note_constexpr_inherited_ctor_call_here)
1270 llvm::raw_svector_ostream Out(Buffer);
1272 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
1277 struct ComplexValue {
1282 APSInt IntReal, IntImag;
1283 APFloat FloatReal, FloatImag;
1285 ComplexValue() : FloatReal(APFloat::Bogus()), FloatImag(APFloat::Bogus()) {}
1287 void makeComplexFloat() { IsInt =
false; }
1288 bool isComplexFloat()
const {
return !IsInt; }
1289 APFloat &getComplexFloatReal() {
return FloatReal; }
1290 APFloat &getComplexFloatImag() {
return FloatImag; }
1292 void makeComplexInt() { IsInt =
true; }
1293 bool isComplexInt()
const {
return IsInt; }
1294 APSInt &getComplexIntReal() {
return IntReal; }
1295 APSInt &getComplexIntImag() {
return IntImag; }
1298 if (isComplexFloat())
1299 v =
APValue(FloatReal, FloatImag);
1301 v =
APValue(IntReal, IntImag);
1303 void setFrom(
const APValue &v) {
1322 bool InvalidBase : 1;
1327 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1328 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1329 bool isNullPointer()
const {
return IsNullPtr;}
1331 unsigned getLValueCallIndex()
const {
return Base.
getCallIndex(); }
1332 unsigned getLValueVersion()
const {
return Base.
getVersion(); }
1334 void moveInto(
APValue &V)
const {
1335 if (Designator.Invalid)
1338 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1339 V =
APValue(Base, Offset, Designator.Entries,
1340 Designator.IsOnePastTheEnd, IsNullPtr);
1344 assert(V.
isLValue() &&
"Setting LValue from a non-LValue?");
1347 InvalidBase =
false;
1348 Designator = SubobjectDesignator(Ctx, V);
1356 const auto *E = B.get<
const Expr *>();
1357 assert((isa<MemberExpr>(E) || tryUnwrapAllocSizeCall(E)) &&
1358 "Unexpected type of invalid base");
1364 InvalidBase = BInvalid;
1365 Designator = SubobjectDesignator(getType(B));
1369 void setNull(
QualType PointerTy, uint64_t TargetVal) {
1370 Base = (
Expr *)
nullptr;
1372 InvalidBase =
false;
1383 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1385 if (Designator.Invalid)
1388 Info.CCEDiag(E, diag::note_constexpr_null_subobject)
1390 Designator.setInvalid();
1399 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
1400 Designator.checkSubobject(Info, E, CSK);
1403 void addDecl(EvalInfo &Info,
const Expr *E,
1404 const Decl *D,
bool Virtual =
false) {
1405 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
1406 Designator.addDeclUnchecked(D, Virtual);
1408 void addUnsizedArray(EvalInfo &Info,
const Expr *E,
QualType ElemTy) {
1409 if (!Designator.Entries.empty()) {
1410 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1411 Designator.setInvalid();
1414 if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
1415 assert(getType(Base)->isPointerType() || getType(Base)->isArrayType());
1416 Designator.FirstEntryIsAnUnsizedArray =
true;
1417 Designator.addUnsizedArrayUnchecked(ElemTy);
1421 if (checkSubobject(Info, E, CSK_ArrayToPointer))
1422 Designator.addArrayUnchecked(CAT);
1424 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
1425 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
1426 Designator.addComplexUnchecked(EltTy, Imag);
1428 void clearIsNullPointer() {
1431 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1432 const APSInt &Index,
CharUnits ElementSize) {
1443 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1446 if (checkNullPointer(Info, E, CSK_ArrayIndex))
1447 Designator.adjustIndex(Info, E, Index);
1448 clearIsNullPointer();
1453 clearIsNullPointer();
1460 DeclAndIsDerivedMember(Decl,
false), Path() {}
1465 return DeclAndIsDerivedMember.getPointer();
1468 bool isDerivedMember()
const {
1469 return DeclAndIsDerivedMember.getInt();
1473 return cast<CXXRecordDecl>(
1474 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1477 void moveInto(
APValue &V)
const {
1478 V =
APValue(getDecl(), isDerivedMember(), Path);
1480 void setFrom(
const APValue &V) {
1486 Path.insert(Path.end(), P.begin(), P.end());
1492 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1500 assert(!Path.empty());
1502 if (Path.size() >= 2)
1503 Expected = Path[Path.size() - 2];
1505 Expected = getContainingRecord();
1522 if (!isDerivedMember()) {
1523 Path.push_back(Derived);
1526 if (!castBack(Derived))
1529 DeclAndIsDerivedMember.setInt(
false);
1537 DeclAndIsDerivedMember.setInt(
true);
1538 if (isDerivedMember()) {
1539 Path.push_back(Base);
1542 return castBack(Base);
1547 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1548 if (!LHS.getDecl() || !RHS.getDecl())
1549 return !LHS.getDecl() && !RHS.getDecl();
1550 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1552 return LHS.Path == RHS.Path;
1558 const LValue &This,
const Expr *E,
1559 bool AllowNonLiteralTypes =
false);
1561 bool InvalidBaseOK =
false);
1563 bool InvalidBaseOK =
false);
1581 template <
class KeyTy>
1583 LValue &LV, CallStackFrame &Frame) {
1584 LV.set({Key, Frame.Info.CurrentCall->Index,
1585 Frame.Info.CurrentCall->getTempVersion()});
1586 return Frame.createTemporary(Key, IsLifetimeExtended);
1592 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1593 Int = Int.extend(Int.getBitWidth() + 1);
1594 Int.setIsSigned(
true);
1601 unsigned ArgIndex = 0;
1602 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1603 !isa<CXXConstructorDecl>(Frame->Callee) &&
1604 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1607 Out << *Frame->Callee <<
'(';
1609 if (Frame->This && IsMemberCall) {
1611 Frame->This->moveInto(Val);
1613 Frame->This->Designator.MostDerivedType);
1615 Out <<
"->" << *Frame->Callee <<
'(';
1616 IsMemberCall =
false;
1620 E = Frame->Callee->param_end(); I != E; ++I, ++ArgIndex) {
1621 if (ArgIndex > (
unsigned)IsMemberCall)
1625 const APValue &Arg = Frame->Arguments[ArgIndex];
1628 if (ArgIndex == 0 && IsMemberCall)
1629 Out <<
"->" << *Frame->Callee <<
'(';
1642 return Info.noteSideEffect();
1649 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1650 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1659 if (!B)
return true;
1663 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1664 return VD->hasGlobalStorage();
1666 return isa<FunctionDecl>(D);
1670 switch (E->getStmtClass()) {
1673 case Expr::CompoundLiteralExprClass: {
1677 case Expr::MaterializeTemporaryExprClass:
1680 return cast<MaterializeTemporaryExpr>(E)->getStorageDuration() ==
SD_Static;
1682 case Expr::StringLiteralClass:
1683 case Expr::PredefinedExprClass:
1684 case Expr::ObjCStringLiteralClass:
1685 case Expr::ObjCEncodeExprClass:
1686 case Expr::CXXTypeidExprClass:
1687 case Expr::CXXUuidofExprClass:
1689 case Expr::CallExprClass:
1692 case Expr::AddrLabelExprClass:
1696 case Expr::BlockExprClass:
1697 return !cast<BlockExpr>(E)->getBlockDecl()->hasCaptures();
1698 case Expr::ImplicitValueInitExprClass:
1710 assert(Base &&
"no location for a null lvalue");
1713 Info.Note(VD->
getLocation(), diag::note_declared_at);
1716 diag::note_constexpr_temporary_here);
1728 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1734 if (Info.getLangOpts().CPlusPlus11) {
1736 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
1737 << IsReferenceType << !Designator.Entries.empty()
1746 assert((Info.checkingPotentialConstantExpression() ||
1747 LVal.getLValueCallIndex() == 0) &&
1748 "have call index for global lvalue");
1751 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1753 if (Var->getTLSKind())
1760 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1772 FD->hasAttr<DLLImportAttr>())
1779 if (!IsReferenceType)
1790 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1792 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
1793 << !Designator.Entries.empty() << !!VD << VD;
1808 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(Member);
1812 !FD->hasAttr<DLLImportAttr>();
1818 const LValue *This =
nullptr) {
1835 if (This && Info.EvaluatingDecl == This->getLValueBase())
1839 if (Info.getLangOpts().CPlusPlus11)
1840 Info.FFDiag(E, diag::note_constexpr_nonliteral)
1843 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
1855 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
1863 Type = AT->getValueType();
1887 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
1888 unsigned BaseIndex = 0;
1896 for (
const auto *I : RD->
fields()) {
1897 if (I->isUnnamedBitfield())
1909 LVal.setFrom(Info.Ctx, Value);
1921 return LVal.Base.dyn_cast<
const ValueDecl*>();
1925 if (Value.getLValueCallIndex())
1927 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1928 return E && !isa<MaterializeTemporaryExpr>(E);
1933 return Decl && Decl->
isWeak();
1938 if (Decl && isa<VarDecl>(Decl)) {
1959 return !Decl || !Decl->
isWeak();
1967 Result = Val.
getInt().getBoolValue();
1993 llvm_unreachable(
"unknown APValue kind");
1998 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2005 template<
typename T>
2007 const T &SrcValue,
QualType DestType) {
2008 Info.CCEDiag(E, diag::note_constexpr_overflow)
2009 << SrcValue << DestType;
2010 return Info.noteUndefinedBehavior();
2014 QualType SrcType,
const APFloat &Value,
2015 QualType DestType, APSInt &Result) {
2016 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2020 Result = APSInt(DestWidth, !DestSigned);
2022 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
2023 & APFloat::opInvalidOp)
2033 if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
2034 APFloat::rmNearestTiesToEven, &ignored)
2035 & APFloat::opOverflow)
2042 const APSInt &Value) {
2043 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2044 APSInt Result =
Value;
2047 Result = Result.extOrTrunc(DestWidth);
2053 QualType SrcType,
const APSInt &Value,
2054 QualType DestType, APFloat &Result) {
2055 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2056 if (Result.convertFromAPInt(Value, Value.isSigned(),
2057 APFloat::rmNearestTiesToEven)
2058 & APFloat::opOverflow)
2065 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2067 if (!Value.
isInt()) {
2071 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
2076 APSInt &Int = Value.
getInt();
2077 unsigned OldBitWidth = Int.getBitWidth();
2079 if (NewBitWidth < OldBitWidth)
2080 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2094 Res = SVal.
getFloat().bitcastToAPInt();
2099 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
2101 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
2102 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
2103 Res = llvm::APInt::getNullValue(VecSize);
2106 llvm::APInt EltAsInt;
2110 EltAsInt = Elt.
getFloat().bitcastToAPInt();
2114 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2117 unsigned BaseEltSize = EltAsInt.getBitWidth();
2119 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
2121 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
2127 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2134 template<
typename Operation>
2136 const APSInt &LHS,
const APSInt &RHS,
2137 unsigned BitWidth, Operation Op,
2139 if (LHS.isUnsigned()) {
2140 Result = Op(LHS, RHS);
2144 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2145 Result = Value.trunc(LHS.getBitWidth());
2146 if (Result.extend(BitWidth) !=
Value) {
2147 if (Info.checkingForOverflow())
2148 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2149 diag::warn_integer_constant_overflow)
2150 << Result.toString(10) << E->
getType();
2167 std::multiplies<APSInt>(), Result);
2170 std::plus<APSInt>(), Result);
2173 std::minus<APSInt>(), Result);
2174 case BO_And: Result = LHS & RHS;
return true;
2175 case BO_Xor: Result = LHS ^ RHS;
return true;
2176 case BO_Or: Result = LHS | RHS;
return true;
2180 Info.FFDiag(E, diag::note_expr_divide_by_zero);
2183 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2186 if (RHS.isNegative() && RHS.isAllOnesValue() &&
2187 LHS.isSigned() && LHS.isMinSignedValue())
2188 return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),
2192 if (Info.getLangOpts().OpenCL)
2194 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2195 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2197 else if (RHS.isSigned() && RHS.isNegative()) {
2200 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2207 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2209 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2210 << RHS << E->
getType() << LHS.getBitWidth();
2211 }
else if (LHS.isSigned()) {
2214 if (LHS.isNegative())
2215 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2216 else if (LHS.countLeadingZeros() < SA)
2217 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2223 if (Info.getLangOpts().OpenCL)
2225 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
2226 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2228 else if (RHS.isSigned() && RHS.isNegative()) {
2231 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2238 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2240 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2241 << RHS << E->
getType() << LHS.getBitWidth();
2246 case BO_LT: Result = LHS < RHS;
return true;
2247 case BO_GT: Result = LHS > RHS;
return true;
2248 case BO_LE: Result = LHS <= RHS;
return true;
2249 case BO_GE: Result = LHS >= RHS;
return true;
2250 case BO_EQ: Result = LHS == RHS;
return true;
2251 case BO_NE: Result = LHS != RHS;
return true;
2253 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2260 const APFloat &RHS) {
2266 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
2269 LHS.add(RHS, APFloat::rmNearestTiesToEven);
2272 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
2275 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
2279 if (LHS.isInfinity() || LHS.isNaN()) {
2280 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2281 return Info.noteUndefinedBehavior();
2290 unsigned TruncatedElements) {
2291 SubobjectDesignator &D = Result.Designator;
2294 if (TruncatedElements == D.Entries.size())
2296 assert(TruncatedElements >= D.MostDerivedPathLength &&
2297 "not casting to a derived class");
2298 if (!Result.checkSubobject(Info, E, CSK_Derived))
2303 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
2307 if (isVirtualBaseClass(D.Entries[I]))
2313 D.Entries.resize(TruncatedElements);
2323 RL = &Info.Ctx.getASTRecordLayout(Derived);
2326 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
2327 Obj.addDecl(Info, E, Base,
false);
2339 SubobjectDesignator &D = Obj.Designator;
2344 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
2350 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
2352 Obj.addDecl(Info, E, BaseDecl,
true);
2360 PathI != PathE; ++PathI) {
2364 Type = (*PathI)->getType();
2376 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
2380 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
2381 LVal.addDecl(Info, E, FD);
2389 for (
const auto *
C : IFD->
chain())
2417 Size = Info.Ctx.getTypeSizeInChars(Type);
2429 APSInt Adjustment) {
2434 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
2440 int64_t Adjustment) {
2442 APSInt::get(Adjustment));
2457 LVal.Offset += SizeOfComponent;
2459 LVal.addComplex(Info, E, EltTy, Imag);
2476 const VarDecl *VD, CallStackFrame *Frame,
2477 APValue *&Result,
const LValue *LVal) {
2481 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
2484 if (Info.checkingPotentialConstantExpression())
2486 if (!Frame || !Frame->Arguments) {
2487 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2490 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
2496 Result = LVal ? Frame->getTemporary(VD, LVal->getLValueVersion())
2497 : Frame->getCurrentTemporary(VD);
2505 "missing value for local variable");
2506 if (Info.checkingPotentialConstantExpression())
2510 diag::note_unimplemented_constexpr_lambda_feature_ast)
2511 <<
"captures not currently allowed";
2522 if (!Info.checkingPotentialConstantExpression())
2523 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2529 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
2530 Result = Info.EvaluatingDeclValue;
2537 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2545 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant,
2546 Notes.size() + 1) << VD;
2547 Info.Note(VD->
getLocation(), diag::note_declared_at);
2548 Info.addNotes(Notes);
2551 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2552 Notes.size() + 1) << VD;
2553 Info.Note(VD->
getLocation(), diag::note_declared_at);
2554 Info.addNotes(Notes);
2573 E = Derived->
bases_end(); I != E; ++I, ++Index) {
2574 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2578 llvm_unreachable(
"base class missing from derived class's bases list");
2585 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
2587 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
2588 assert(Index <= Str.size() &&
"Index too large");
2589 return APSInt::getUnsigned(Str.c_str()[Index]);
2592 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2593 Lit = PE->getFunctionName();
2596 Info.Ctx.getAsConstantArrayType(S->
getType());
2597 assert(CAT &&
"string literal isn't an array");
2598 QualType CharType = CAT->getElementType();
2599 assert(CharType->
isIntegerType() &&
"unexpected character type");
2603 if (Index < S->getLength())
2613 Info.Ctx.getAsConstantArrayType(S->
getType());
2614 assert(CAT &&
"string literal isn't an array");
2615 QualType CharType = CAT->getElementType();
2616 assert(CharType->
isIntegerType() &&
"unexpected character type");
2618 unsigned Elts = CAT->getSize().getZExtValue();
2634 assert(Index < Size);
2638 unsigned NewElts =
std::max(Index+1, OldElts * 2);
2643 for (
unsigned I = 0; I != OldElts; ++I)
2645 for (
unsigned I = OldElts; I != NewElts; ++I)
2649 Array.
swap(NewValue);
2664 for (
auto *Field : RD->
fields())
2668 for (
auto &BaseSpec : RD->
bases())
2686 for (
auto *Field : RD->
fields()) {
2691 if (Field->isMutable() &&
2693 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2694 Info.Note(Field->getLocation(), diag::note_declared_at);
2702 for (
auto &BaseSpec : RD->
bases())
2721 struct CompleteObject {
2726 bool LifetimeStartedInEvaluation;
2728 CompleteObject() :
Value(
nullptr) {}
2730 bool LifetimeStartedInEvaluation)
2731 :
Value(Value), Type(Type),
2732 LifetimeStartedInEvaluation(LifetimeStartedInEvaluation) {
2733 assert(Value &&
"missing value for complete object");
2736 explicit operator bool()
const {
return Value; }
2741 template<
typename Sub
objectHandler>
2742 typename SubobjectHandler::result_type
2744 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2747 return handler.failed();
2748 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
2749 if (Info.getLangOpts().CPlusPlus11)
2750 Info.FFDiag(E, Sub.isOnePastTheEnd()
2751 ? diag::note_constexpr_access_past_end
2752 : diag::note_constexpr_access_unsized_array)
2753 << handler.AccessKind;
2756 return handler.failed();
2762 const bool MayReadMutableMembers =
2763 Obj.LifetimeStartedInEvaluation && Info.getLangOpts().CPlusPlus14;
2766 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
2768 if (!Info.checkingPotentialConstantExpression())
2769 Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind;
2770 return handler.failed();
2780 return handler.failed();
2782 if (!handler.found(*O, ObjType))
2786 if (handler.AccessKind !=
AK_Read &&
2794 LastField =
nullptr;
2798 assert(CAT &&
"vla in literal type?");
2799 uint64_t Index = Sub.Entries[I].ArrayIndex;
2800 if (CAT->
getSize().ule(Index)) {
2803 if (Info.getLangOpts().CPlusPlus11)
2804 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2805 << handler.AccessKind;
2808 return handler.failed();
2816 assert(I == N - 1 &&
"extracting subobject of character?");
2818 if (handler.AccessKind !=
AK_Read)
2822 return handler.foundString(*O, ObjType, Index);
2827 else if (handler.AccessKind !=
AK_Read) {
2834 uint64_t Index = Sub.Entries[I].ArrayIndex;
2836 if (Info.getLangOpts().CPlusPlus11)
2837 Info.FFDiag(E, diag::note_constexpr_access_past_end)
2838 << handler.AccessKind;
2841 return handler.failed();
2846 if (WasConstQualified)
2849 assert(I == N - 1 &&
"extracting subobject of scalar?");
2858 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
2862 if (Field->isMutable() && handler.AccessKind ==
AK_Read &&
2863 !MayReadMutableMembers) {
2864 Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1)
2866 Info.Note(Field->getLocation(), diag::note_declared_at);
2867 return handler.failed();
2876 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
2877 << handler.AccessKind << Field << !UnionField << UnionField;
2878 return handler.failed();
2885 ObjType = Field->getType();
2886 if (WasConstQualified && !Field->isMutable())
2890 if (Info.getLangOpts().CPlusPlus) {
2892 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
2893 << handler.AccessKind << 2 << Field;
2894 Info.Note(Field->getLocation(), diag::note_declared_at);
2896 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2898 return handler.failed();
2909 ObjType = Info.Ctx.getRecordType(Base);
2910 if (WasConstQualified)
2917 struct ExtractSubobjectHandler {
2923 typedef bool result_type;
2924 bool failed() {
return false; }
2929 bool found(APSInt &Value,
QualType SubobjType) {
2933 bool found(APFloat &Value,
QualType SubobjType) {
2937 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2949 const CompleteObject &Obj,
2950 const SubobjectDesignator &Sub,
2952 ExtractSubobjectHandler Handler = { Info, Result };
2957 struct ModifySubobjectHandler {
2962 typedef bool result_type;
2968 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
2974 bool failed() {
return false; }
2976 if (!checkConst(SubobjType))
2979 Subobj.
swap(NewVal);
2982 bool found(APSInt &Value,
QualType SubobjType) {
2983 if (!checkConst(SubobjType))
2985 if (!NewVal.
isInt()) {
2993 bool found(APFloat &Value,
QualType SubobjType) {
2994 if (!checkConst(SubobjType))
2999 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3000 llvm_unreachable(
"shouldn't encounter string elements with ExpandArrays");
3009 const CompleteObject &Obj,
3010 const SubobjectDesignator &Sub,
3012 ModifySubobjectHandler Handler = { Info, NewVal, E };
3019 const SubobjectDesignator &A,
3020 const SubobjectDesignator &B,
3021 bool &WasArrayIndex) {
3022 unsigned I = 0, N =
std::min(A.Entries.size(), B.Entries.size());
3023 for (; I != N; ++I) {
3027 if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
3028 WasArrayIndex =
true;
3036 if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
3037 WasArrayIndex =
false;
3040 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
3042 ObjType = FD->getType();
3048 WasArrayIndex =
false;
3055 const SubobjectDesignator &A,
3056 const SubobjectDesignator &B) {
3057 if (A.Entries.size() != B.Entries.size())
3060 bool IsArray = A.MostDerivedIsArrayElement;
3061 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
3070 return CommonLength >= A.Entries.size() - IsArray;
3078 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
3079 return CompleteObject();
3082 CallStackFrame *Frame =
nullptr;
3083 if (LVal.getLValueCallIndex()) {
3084 Frame = Info.getCallFrame(LVal.getLValueCallIndex());
3086 Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1)
3087 << AK << LVal.Base.is<
const ValueDecl*>();
3089 return CompleteObject();
3098 if (Info.getLangOpts().CPlusPlus)
3099 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
3103 return CompleteObject();
3108 QualType BaseType = getType(LVal.Base);
3109 bool LifetimeStartedInEvaluation = Frame;
3126 return CompleteObject();
3131 if (Info.getLangOpts().CPlusPlus) {
3132 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3134 Info.Note(VD->getLocation(), diag::note_declared_at);
3138 return CompleteObject();
3144 if (Info.getLangOpts().CPlusPlus14 &&
3145 VD == Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()) {
3151 Info.FFDiag(E, diag::note_constexpr_modify_global);
3152 return CompleteObject();
3158 (Info.getLangOpts().OpenCL &&
3160 if (Info.getLangOpts().CPlusPlus) {
3161 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
3162 Info.Note(VD->
getLocation(), diag::note_declared_at);
3166 return CompleteObject();
3172 if (Info.getLangOpts().CPlusPlus11) {
3173 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3174 Info.Note(VD->
getLocation(), diag::note_declared_at);
3179 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr) << VD;
3183 if (Info.checkingPotentialConstantExpression() &&
3187 }
else if (Info.getLangOpts().CPlusPlus11) {
3188 Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
3189 Info.Note(VD->
getLocation(), diag::note_declared_at);
3193 return CompleteObject();
3198 return CompleteObject();
3200 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3204 dyn_cast<MaterializeTemporaryExpr>(Base)) {
3205 assert(MTE->getStorageDuration() ==
SD_Static &&
3206 "should have a frame for a non-global materialized temporary");
3223 const ValueDecl *ED = MTE->getExtendingDecl();
3226 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
3227 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
3228 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
3229 return CompleteObject();
3232 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
3233 assert(BaseVal &&
"got reference to unevaluated temporary");
3234 LifetimeStartedInEvaluation =
true;
3237 return CompleteObject();
3240 BaseVal = Frame->getTemporary(Base, LVal.Base.getVersion());
3241 assert(BaseVal &&
"missing value for temporary");
3246 if (Info.getLangOpts().CPlusPlus) {
3247 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
3249 Info.Note(Base->
getExprLoc(), diag::note_constexpr_temporary_here);
3253 return CompleteObject();
3260 if (Info.isEvaluatingConstructor(LVal.getLValueBase(),
3261 LVal.getLValueCallIndex(),
3262 LVal.getLValueVersion())) {
3263 BaseType = Info.Ctx.getCanonicalType(BaseType);
3265 LifetimeStartedInEvaluation =
true;
3273 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
3274 Info.EvalStatus.HasSideEffects) ||
3275 (AK !=
AK_Read && Info.IsSpeculativelyEvaluating))
3276 return CompleteObject();
3278 return CompleteObject(BaseVal, BaseType, LifetimeStartedInEvaluation);
3294 const LValue &LVal,
APValue &RVal) {
3295 if (LVal.Designator.Invalid)
3299 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
3310 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
3312 CompleteObject LitObj(&Lit, Base->
getType(),
false);
3314 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
3319 CompleteObject StrObj(&Str, Base->
getType(),
false);
3331 if (LVal.Designator.Invalid)
3334 if (!Info.getLangOpts().CPlusPlus14) {
3344 struct CompoundAssignSubobjectHandler {
3353 typedef bool result_type;
3358 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3364 bool failed() {
return false; }
3368 return found(Subobj.
getInt(), SubobjType);
3370 return found(Subobj.
getFloat(), SubobjType);
3377 return foundPointer(Subobj, SubobjType);
3384 bool found(APSInt &Value,
QualType SubobjType) {
3385 if (!checkConst(SubobjType))
3402 bool found(APFloat &Value,
QualType SubobjType) {
3403 return checkConst(SubobjType) &&
3410 if (!checkConst(SubobjType))
3418 (Opcode != BO_Add && Opcode != BO_Sub)) {
3424 if (Opcode == BO_Sub)
3428 LVal.setFrom(Info.Ctx, Subobj);
3431 LVal.moveInto(Subobj);
3434 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3435 llvm_unreachable(
"shouldn't encounter string elements here");
3444 EvalInfo &Info,
const Expr *E,
3447 if (LVal.Designator.Invalid)
3450 if (!Info.getLangOpts().CPlusPlus14) {
3456 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
3458 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3462 struct IncDecSubobjectHandler {
3468 typedef bool result_type;
3473 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
3479 bool failed() {
return false; }
3490 return found(Subobj.
getInt(), SubobjType);
3492 return found(Subobj.
getFloat(), SubobjType);
3502 return foundPointer(Subobj, SubobjType);
3509 bool found(APSInt &Value,
QualType SubobjType) {
3510 if (!checkConst(SubobjType))
3520 if (Old) *Old =
APValue(Value);
3532 bool WasNegative = Value.isNegative();
3536 if (!WasNegative && Value.isNegative() && E->
canOverflow()) {
3537 APSInt ActualValue(Value,
true);
3543 if (WasNegative && !Value.isNegative() && E->
canOverflow()) {
3544 unsigned BitWidth = Value.getBitWidth();
3545 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
3546 ActualValue.setBit(BitWidth);
3552 bool found(APFloat &Value,
QualType SubobjType) {
3553 if (!checkConst(SubobjType))
3556 if (Old) *Old =
APValue(Value);
3558 APFloat One(Value.getSemantics(), 1);
3560 Value.add(One, APFloat::rmNearestTiesToEven);
3562 Value.subtract(One, APFloat::rmNearestTiesToEven);
3566 if (!checkConst(SubobjType))
3578 LVal.setFrom(Info.Ctx, Subobj);
3582 LVal.moveInto(Subobj);
3585 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3586 llvm_unreachable(
"shouldn't encounter string elements here");
3594 if (LVal.Designator.Invalid)
3597 if (!Info.getLangOpts().CPlusPlus14) {
3604 IncDecSubobjectHandler Handler = {Info, cast<UnaryOperator>(E), AK, Old};
3605 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3620 Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3639 bool IncludeMember =
true) {
3646 if (!MemPtr.getDecl()) {
3652 if (MemPtr.isDerivedMember()) {
3656 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3657 LV.Designator.Entries.size()) {
3661 unsigned PathLengthToMember =
3662 LV.Designator.Entries.size() - MemPtr.Path.size();
3663 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
3665 LV.Designator.Entries[PathLengthToMember + I]);
3675 PathLengthToMember))
3677 }
else if (!MemPtr.Path.empty()) {
3679 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3680 MemPtr.Path.size() + IncludeMember);
3686 assert(RD &&
"member pointer access on non-class-type expression");
3688 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
3696 MemPtr.getContainingRecord()))
3701 if (IncludeMember) {
3702 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3706 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3710 llvm_unreachable(
"can't construct reference to bound member function");
3714 return MemPtr.getDecl();
3720 bool IncludeMember =
true) {
3724 if (Info.noteFailure()) {
3732 BO->
getRHS(), IncludeMember);
3739 SubobjectDesignator &D = Result.Designator;
3740 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
3748 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
3749 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3750 << D.MostDerivedType << TargetQT;
3756 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
3759 if (NewEntriesSize == D.MostDerivedPathLength)
3760 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
3762 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
3764 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3765 << D.MostDerivedType << TargetQT;
3800 Info.FFDiag(VD->
getLocStart(), diag::note_constexpr_uninitialized)
3822 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
3826 for (
auto *BD : DD->bindings())
3827 if (
auto *VD = BD->getHoldingVar())
3836 const Expr *Cond,
bool &Result) {
3837 FullExpressionRAII
Scope(Info);
3853 struct TempVersionRAII {
3854 CallStackFrame &Frame;
3856 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
3857 Frame.pushTempVersion();
3860 ~TempVersionRAII() {
3861 Frame.popTempVersion();
3875 BlockScopeRAII
Scope(Info);
3878 return ESR_Succeeded;
3881 return ESR_Continue;
3884 case ESR_CaseNotFound:
3887 llvm_unreachable(
"Invalid EvalStmtResult!");
3893 BlockScopeRAII
Scope(Info);
3898 FullExpressionRAII Scope(Info);
3901 if (ESR != ESR_Succeeded)
3916 if (isa<DefaultStmt>(SC)) {
3921 const CaseStmt *CS = cast<CaseStmt>(SC);
3925 if (LHS <= Value && Value <= RHS) {
3932 return ESR_Succeeded;
3937 return ESR_Succeeded;
3943 case ESR_CaseNotFound:
3946 Info.FFDiag(Found->
getLocStart(), diag::note_constexpr_stmt_expr_unsupported);
3949 llvm_unreachable(
"Invalid EvalStmtResult!");
3955 if (!Info.nextStep(S))
3966 case Stmt::CompoundStmtClass:
3970 case Stmt::LabelStmtClass:
3971 case Stmt::AttributedStmtClass:
3972 case Stmt::DoStmtClass:
3975 case Stmt::CaseStmtClass:
3976 case Stmt::DefaultStmtClass:
3981 case Stmt::IfStmtClass: {
3984 const IfStmt *IS = cast<IfStmt>(S);
3988 BlockScopeRAII
Scope(Info);
3991 if (ESR != ESR_CaseNotFound || !IS->
getElse())
3996 case Stmt::WhileStmtClass: {
3999 if (ESR != ESR_Continue)
4004 case Stmt::ForStmtClass: {
4005 const ForStmt *FS = cast<ForStmt>(S);
4008 if (ESR != ESR_Continue)
4011 FullExpressionRAII IncScope(Info);
4018 case Stmt::DeclStmtClass:
4022 return ESR_CaseNotFound;
4028 if (
const Expr *E = dyn_cast<Expr>(S)) {
4031 FullExpressionRAII
Scope(Info);
4034 return ESR_Succeeded;
4040 case Stmt::NullStmtClass:
4041 return ESR_Succeeded;
4043 case Stmt::DeclStmtClass: {
4044 const DeclStmt *DS = cast<DeclStmt>(S);
4045 for (
const auto *DclIt : DS->
decls()) {
4049 FullExpressionRAII
Scope(Info);
4053 return ESR_Succeeded;
4056 case Stmt::ReturnStmtClass: {
4057 const Expr *RetExpr = cast<ReturnStmt>(S)->getRetValue();
4058 FullExpressionRAII
Scope(Info);
4061 ? EvaluateInPlace(Result.Value, Info, *Result.Slot, RetExpr)
4062 : Evaluate(Result.Value, Info, RetExpr)))
4064 return ESR_Returned;
4067 case Stmt::CompoundStmtClass: {
4068 BlockScopeRAII
Scope(Info);
4071 for (
const auto *BI : CS->
body()) {
4073 if (ESR == ESR_Succeeded)
4075 else if (ESR != ESR_CaseNotFound)
4078 return Case ? ESR_CaseNotFound : ESR_Succeeded;
4081 case Stmt::IfStmtClass: {
4082 const IfStmt *IS = cast<IfStmt>(S);
4085 BlockScopeRAII
Scope(Info);
4088 if (ESR != ESR_Succeeded)
4097 if (ESR != ESR_Succeeded)
4100 return ESR_Succeeded;
4103 case Stmt::WhileStmtClass: {
4104 const WhileStmt *WS = cast<WhileStmt>(S);
4106 BlockScopeRAII
Scope(Info);
4115 if (ESR != ESR_Continue)
4118 return ESR_Succeeded;
4121 case Stmt::DoStmtClass: {
4122 const DoStmt *DS = cast<DoStmt>(S);
4126 if (ESR != ESR_Continue)
4130 FullExpressionRAII CondScope(Info);
4134 return ESR_Succeeded;
4137 case Stmt::ForStmtClass: {
4138 const ForStmt *FS = cast<ForStmt>(S);
4139 BlockScopeRAII
Scope(Info);
4142 if (ESR != ESR_Succeeded)
4146 BlockScopeRAII Scope(Info);
4147 bool Continue =
true;
4155 if (ESR != ESR_Continue)
4159 FullExpressionRAII IncScope(Info);
4164 return ESR_Succeeded;
4167 case Stmt::CXXForRangeStmtClass: {
4169 BlockScopeRAII
Scope(Info);
4173 if (ESR != ESR_Succeeded)
4178 if (ESR != ESR_Succeeded)
4181 if (ESR != ESR_Succeeded)
4187 bool Continue =
true;
4188 FullExpressionRAII CondExpr(Info);
4196 BlockScopeRAII InnerScope(Info);
4198 if (ESR != ESR_Succeeded)
4203 if (ESR != ESR_Continue)
4211 return ESR_Succeeded;
4214 case Stmt::SwitchStmtClass:
4217 case Stmt::ContinueStmtClass:
4218 return ESR_Continue;
4220 case Stmt::BreakStmtClass:
4223 case Stmt::LabelStmtClass:
4224 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
4226 case Stmt::AttributedStmtClass:
4229 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
4232 case Stmt::CaseStmtClass:
4233 case Stmt::DefaultStmtClass:
4234 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
4244 bool IsValueInitialization) {
4251 if (!CD->
isConstexpr() && !IsValueInitialization) {
4252 if (Info.getLangOpts().CPlusPlus11) {
4255 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
4257 Info.Note(CD->
getLocation(), diag::note_declared_at);
4259 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
4273 if (Info.checkingPotentialConstantExpression() && !Definition &&
4287 if (Info.getLangOpts().CPlusPlus11) {
4288 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
4293 if (CD && CD->isInheritingConstructor()) {
4295 if (!Inherited->isConstexpr())
4296 DiagDecl = CD = Inherited;
4302 if (CD && CD->isInheritingConstructor())
4303 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
4304 << CD->getInheritedConstructor().getConstructor()->getParent();
4306 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
4308 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
4310 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
4320 for (
auto *FD : RD->
fields()) {
4321 if (FD->isUnnamedBitfield())
4325 for (
auto &Base : RD->
bases())
4326 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
4338 bool Success =
true;
4341 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
4344 if (!Info.noteFailure())
4356 EvalInfo &Info,
APValue &Result,
4357 const LValue *ResultSlot) {
4358 ArgVector ArgValues(Args.size());
4362 if (!Info.CheckCallLimit(CallLoc))
4365 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
4374 if (MD && MD->isDefaulted() &&
4375 (MD->getParent()->isUnion() ||
4376 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
4378 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
4380 RHS.setFrom(Info.Ctx, ArgValues[0]);
4388 This->moveInto(Result);
4397 if (!Info.checkingPotentialConstantExpression())
4398 MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields,
4399 Frame.LambdaThisCaptureField);
4404 if (ESR == ESR_Succeeded) {
4407 Info.FFDiag(Callee->
getLocEnd(), diag::note_constexpr_no_return);
4409 return ESR == ESR_Returned;
4416 EvalInfo &Info,
APValue &Result) {
4418 if (!Info.CheckCallLimit(CallLoc))
4423 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
4427 EvalInfo::EvaluatingConstructorRAII EvalObj(
4428 Info, {This.getLValueBase(),
4429 {This.getLValueCallIndex(), This.getLValueVersion()}});
4430 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
4441 FullExpressionRAII InitScope(Info);
4460 RHS.setFrom(Info.Ctx, ArgValues[0]);
4475 BlockScopeRAII LifetimeExtendedScope(Info);
4477 bool Success =
true;
4478 unsigned BasesSeen = 0;
4482 for (
const auto *I : Definition->
inits()) {
4483 LValue Subobject = This;
4484 LValue SubobjectParent = This;
4489 if (I->isBaseInitializer()) {
4490 QualType BaseType(I->getBaseClass(), 0);
4494 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
4495 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
4496 "base class initializers not in expected order");
4500 BaseType->getAsCXXRecordDecl(), &Layout))
4503 }
else if ((FD = I->getMember())) {
4515 auto IndirectFieldChain = IFD->chain();
4516 for (
auto *
C : IndirectFieldChain) {
4517 FD = cast<FieldDecl>(
C);
4534 if (
C == IndirectFieldChain.back())
4535 SubobjectParent = Subobject;
4544 llvm_unreachable(
"unknown base initializer kind");
4550 const Expr *Init = I->getInit();
4551 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
4552 isa<CXXDefaultInitExpr>(Init));
4553 FullExpressionRAII InitScope(Info);
4559 if (!Info.noteFailure())
4572 EvalInfo &Info,
APValue &Result) {
4573 ArgVector ArgValues(Args.size());
4586 template <
class Derived>
4587 class ExprEvaluatorBase
4590 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
4591 bool DerivedSuccess(
const APValue &V,
const Expr *E) {
4592 return getDerived().Success(V, E);
4594 bool DerivedZeroInitialization(
const Expr *E) {
4595 return getDerived().ZeroInitialization(E);
4601 template<
typename ConditionalOperator>
4603 assert(Info.checkingPotentialConstantExpression());
4608 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4615 SpeculativeEvaluationRAII Speculate(Info, &Diag);
4622 Error(E, diag::note_constexpr_conditional_never_const);
4626 template<
typename ConditionalOperator>
4630 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
4631 CheckPotentialConstantConditional(E);
4634 if (Info.noteFailure()) {
4642 return StmtVisitorTy::Visit(EvalExpr);
4648 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
4651 return Info.CCEDiag(E, D);
4654 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
4657 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
4659 EvalInfo &getEvalInfo() {
return Info; }
4668 return Error(E, diag::note_invalid_subexpr_in_const_expr);
4671 bool VisitStmt(
const Stmt *) {
4672 llvm_unreachable(
"Expression evaluator should not be called on stmts");
4674 bool VisitExpr(
const Expr *E) {
4679 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4681 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4683 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4691 TempVersionRAII RAII(*Info.CurrentCall);
4692 return StmtVisitorTy::Visit(E->
getExpr());
4695 TempVersionRAII RAII(*Info.CurrentCall);
4699 return StmtVisitorTy::Visit(E->
getExpr());
4704 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4707 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
4708 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4711 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
4712 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4721 VisitIgnoredValue(E->
getLHS());
4722 return StmtVisitorTy::Visit(E->
getRHS());
4732 return DerivedSuccess(Result, E);
4744 return HandleConditionalOperator(E);
4748 bool IsBcpCall =
false;
4755 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
4760 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
4763 FoldConstant Fold(Info, IsBcpCall);
4764 if (!HandleConditionalOperator(E)) {
4765 Fold.keepDiagnostics();
4773 if (
APValue *Value = Info.CurrentCall->getCurrentTemporary(E))
4774 return DerivedSuccess(*Value, E);
4780 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
4783 return StmtVisitorTy::Visit(Source);
4786 bool VisitCallExpr(
const CallExpr *E) {
4788 if (!handleCallExpr(E, Result,
nullptr))
4790 return DerivedSuccess(Result, E);
4794 const LValue *ResultSlot) {
4799 LValue *This =
nullptr, ThisVal;
4801 bool HasQualifier =
false;
4806 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
4810 Member = ME->getMemberDecl();
4812 HasQualifier = ME->hasQualifier();
4813 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
4816 if (!Member)
return false;
4819 return Error(Callee);
4823 return Error(Callee);
4829 if (!Call.getLValueOffset().isZero())
4830 return Error(Callee);
4831 FD = dyn_cast_or_null<FunctionDecl>(
4832 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
4834 return Error(Callee);
4837 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
4855 Args = Args.slice(1);
4864 "Number of captures must be zero for conversion to function-ptr");
4875 "A generic lambda's static-invoker function must be a " 4876 "template specialization");
4879 LambdaCallOp->getDescribedFunctionTemplate();
4880 void *InsertPos =
nullptr;
4883 assert(CorrespondingCallOpSpecialization &&
4884 "We must always have a function call operator specialization " 4885 "that corresponds to our static invoker specialization");
4886 FD = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
4895 if (This && !This->checkSubobject(Info, E, CSK_This))
4900 if (This && !HasQualifier &&
4901 isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
4902 return Error(E, diag::note_constexpr_virtual_call);
4920 return DerivedZeroInitialization(E);
4922 return StmtVisitorTy::Visit(E->
getInit(0));
4926 return DerivedZeroInitialization(E);
4929 return DerivedZeroInitialization(E);
4932 return DerivedZeroInitialization(E);
4937 assert(!E->
isArrow() &&
"missing call to bound member function?");
4946 if (!FD)
return Error(E);
4951 CompleteObject Obj(&Val, BaseTy,
true);
4953 Designator.addDeclUnchecked(FD);
4957 DerivedSuccess(Result, E);
4960 bool VisitCastExpr(
const CastExpr *E) {
4965 case CK_AtomicToNonAtomic: {
4972 return DerivedSuccess(AtomicVal, E);
4976 case CK_UserDefinedConversion:
4977 return StmtVisitorTy::Visit(E->
getSubExpr());
4979 case CK_LValueToRValue: {
4988 return DerivedSuccess(RVal, E);
4996 return VisitUnaryPostIncDec(UO);
4999 return VisitUnaryPostIncDec(UO);
5002 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5012 return DerivedSuccess(RVal, UO);
5015 bool VisitStmtExpr(
const StmtExpr *E) {
5018 if (Info.checkingForOverflow())
5021 BlockScopeRAII
Scope(Info);
5030 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
5032 Info.FFDiag((*BI)->getLocStart(),
5033 diag::note_constexpr_stmt_expr_unsupported);
5036 return this->Visit(FinalExpr);
5040 StmtResult Result = { ReturnValue,
nullptr };
5042 if (ESR != ESR_Succeeded) {
5046 if (ESR != ESR_Failed)
5047 Info.FFDiag((*BI)->getLocStart(),
5048 diag::note_constexpr_stmt_expr_unsupported);
5053 llvm_unreachable(
"Return from function from the loop above.");
5057 void VisitIgnoredValue(
const Expr *E) {
5062 void VisitIgnoredBaseExpression(
const Expr *E) {
5065 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
5067 VisitIgnoredValue(E);
5077 template<
class Derived>
5078 class LValueExprEvaluatorBase
5079 :
public ExprEvaluatorBase<Derived> {
5083 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
5084 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
5091 bool evaluatePointer(
const Expr *E, LValue &Result) {
5096 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK)
5097 : ExprEvaluatorBaseTy(Info),
Result(Result),
5098 InvalidBaseOK(InvalidBaseOK) {}
5101 Result.setFrom(this->Info.Ctx, V);
5117 EvalOK = this->Visit(E->
getBase());
5123 Result.setInvalid(E);
5130 FD->
getParent()->getCanonicalDecl() &&
"record / field mismatch");
5138 return this->
Error(E);
5145 return Success(RefValue, E);
5153 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
5161 bool VisitCastExpr(
const CastExpr *E) {
5164 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5166 case CK_DerivedToBase:
5167 case CK_UncheckedDerivedToBase:
5212 class LValueExprEvaluator
5213 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
5215 LValueExprEvaluator(EvalInfo &Info, LValue &Result,
bool InvalidBaseOK) :
5216 LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
5218 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
5222 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
5226 bool VisitStringLiteral(
const StringLiteral *E) {
return Success(E); }
5227 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
5235 return VisitUnaryPreIncDec(UO);
5238 return VisitUnaryPreIncDec(UO);
5243 bool VisitCastExpr(
const CastExpr *E) {
5246 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
5248 case CK_LValueBitCast:
5249 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5252 Result.Designator.setInvalid();
5255 case CK_BaseToDerived:
5270 bool InvalidBaseOK) {
5273 return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
5276 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
5280 return VisitVarDecl(E, VD);
5282 return Visit(BD->getBinding());
5287 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
5294 isa<DeclRefExpr>(E) &&
5295 cast<DeclRefExpr>(E)->refersToEnclosingVariableOrCapture()) {
5300 if (Info.checkingPotentialConstantExpression())
5303 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
5305 Result = *Info.CurrentCall->This;
5312 if (FD->getType()->isReferenceType()) {
5317 Result.setFrom(Info.Ctx, RVal);
5322 CallStackFrame *Frame =
nullptr;
5330 if (Info.CurrentCall->Callee &&
5332 Frame = Info.CurrentCall;
5338 Result.set({VD, Frame->Index,
5339 Info.CurrentCall->getCurrentTemporaryVersion(VD)});
5349 if (!Info.checkingPotentialConstantExpression())
5350 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
5353 return Success(*V, E);
5356 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
5362 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
5365 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
5374 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
5393 for (
unsigned I = Adjustments.size(); I != 0; ) {
5395 switch (Adjustments[I].
Kind) {
5400 Type = Adjustments[I].DerivedToBase.BasePath->getType();
5406 Type = Adjustments[I].Field->getType();
5411 Adjustments[I].Ptr.RHS))
5413 Type = Adjustments[I].Ptr.MPT->getPointeeType();
5423 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
5424 "lvalue compound literal in c++?");
5430 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
5434 Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic)
5440 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
5444 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
5447 VisitIgnoredBaseExpression(E->
getBase());
5448 return VisitVarDecl(E, VD);
5453 if (MD->isStatic()) {
5454 VisitIgnoredBaseExpression(E->
getBase());
5460 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
5468 bool Success =
true;
5470 if (!Info.noteFailure())
5483 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
5487 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
5496 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
5498 "lvalue __imag__ on scalar?");
5505 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
5506 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5517 bool LValueExprEvaluator::VisitCompoundAssignOperator(
5519 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5525 if (!this->Visit(CAO->
getLHS())) {
5526 if (Info.noteFailure())
5540 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
5541 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
5546 if (!this->Visit(E->
getLHS())) {
5547 if (Info.noteFailure())
5571 llvm::APInt &Result) {
5572 const AllocSizeAttr *AllocSize = getAllocSizeAttr(Call);
5574 assert(AllocSize && AllocSize->getElemSizeParam().isValid());
5575 unsigned SizeArgNo = AllocSize->getElemSizeParam().getASTIndex();
5580 auto EvaluateAsSizeT = [&](
const Expr *E, APSInt &Into) {
5583 if (Into.isNegative() || !Into.isIntN(BitsInSizeT))
5585 Into = Into.zextOrSelf(BitsInSizeT);
5590 if (!EvaluateAsSizeT(Call->
getArg(SizeArgNo), SizeOfElem))
5593 if (!AllocSize->getNumElemsParam().isValid()) {
5594 Result = std::move(SizeOfElem);
5598 APSInt NumberOfElems;
5599 unsigned NumArgNo = AllocSize->getNumElemsParam().getASTIndex();
5600 if (!EvaluateAsSizeT(Call->
getArg(NumArgNo), NumberOfElems))
5604 llvm::APInt BytesAvailable = SizeOfElem.umul_ov(NumberOfElems, Overflow);
5608 Result = std::move(BytesAvailable);
5616 llvm::APInt &Result) {
5617 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
5618 "Can't get the size of a non alloc_size function");
5619 const auto *Base = LVal.getLValueBase().get<
const Expr *>();
5620 const CallExpr *CE = tryUnwrapAllocSizeCall(Base);
5648 if (!tryUnwrapAllocSizeCall(E))
5653 Result.setInvalid(E);
5656 Result.addUnsizedArray(Info, E, Pointee);
5661 class PointerExprEvaluator
5662 :
public ExprEvaluatorBase<PointerExprEvaluator> {
5666 bool Success(
const Expr *E) {
5671 bool evaluateLValue(
const Expr *E, LValue &Result) {
5675 bool evaluatePointer(
const Expr *E, LValue &Result) {
5679 bool visitNonBuiltinCallExpr(
const CallExpr *E);
5682 PointerExprEvaluator(EvalInfo &info, LValue &Result,
bool InvalidBaseOK)
5683 : ExprEvaluatorBaseTy(info),
Result(Result),
5684 InvalidBaseOK(InvalidBaseOK) {}
5687 Result.setFrom(Info.Ctx, V);
5690 bool ZeroInitialization(
const Expr *E) {
5691 auto TargetVal = Info.Ctx.getTargetNullPointerValue(E->
getType());
5692 Result.setNull(E->
getType(), TargetVal);
5697 bool VisitCastExpr(
const CastExpr* E);
5700 {
return Success(E); }
5702 if (Info.noteFailure())
5707 {
return Success(E); }
5708 bool VisitCallExpr(
const CallExpr *E);
5709 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
5710 bool VisitBlockExpr(
const BlockExpr *E) {
5717 if (Info.checkingPotentialConstantExpression())
5719 if (!Info.CurrentCall->This) {
5720 if (Info.getLangOpts().CPlusPlus11)
5721 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
5726 Result = *Info.CurrentCall->This;
5735 Info.CurrentCall->LambdaThisCaptureField))
5738 if (Info.CurrentCall->LambdaThisCaptureField->getType()
5739 ->isPointerType()) {
5745 Result.setFrom(Info.Ctx, RVal);
5756 bool InvalidBaseOK) {
5758 return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
5761 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
5764 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
5769 std::swap(PExp, IExp);
5771 bool EvalPtrOK = evaluatePointer(PExp, Result);
5772 if (!EvalPtrOK && !Info.noteFailure())
5786 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5790 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5798 case CK_CPointerToObjCPointerCast:
5799 case CK_BlockPointerToObjCPointerCast:
5800 case CK_AnyPointerToBlockPointerCast:
5801 case CK_AddressSpaceConversion:
5802 if (!Visit(SubExpr))
5812 Result.Designator.setInvalid();
5814 CCEDiag(E, diag::note_constexpr_invalid_cast)
5817 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5819 if (E->
getCastKind() == CK_AddressSpaceConversion && Result.IsNullPtr)
5820 ZeroInitialization(E);
5823 case CK_DerivedToBase:
5824 case CK_UncheckedDerivedToBase:
5827 if (!Result.Base && Result.Offset.isZero())
5833 castAs<PointerType>()->getPointeeType(),
5836 case CK_BaseToDerived:
5839 if (!Result.Base && Result.Offset.isZero())
5843 case CK_NullToPointer:
5845 return ZeroInitialization(E);
5847 case CK_IntegralToPointer: {
5848 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
5854 if (Value.
isInt()) {
5855 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
5856 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
5857 Result.Base = (
Expr*)
nullptr;
5858 Result.InvalidBase =
false;
5860 Result.Designator.setInvalid();
5861 Result.IsNullPtr =
false;
5865 Result.setFrom(Info.Ctx, Value);
5870 case CK_ArrayToPointerDecay: {
5872 if (!evaluateLValue(SubExpr, Result))
5881 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
5882 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
5883 Result.addArray(Info, E, CAT);
5889 case CK_FunctionToPointerDecay:
5890 return evaluateLValue(SubExpr, Result);
5892 case CK_LValueToRValue: {
5901 return InvalidBaseOK &&
5903 return Success(RVal, E);
5907 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5920 return Info.Ctx.toCharUnitsFromBits(
5921 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
5933 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
5934 return Info.Ctx.getDeclAlign(DRE->getDecl(),
5937 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
5938 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
5945 bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
5946 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
5949 if (!(InvalidBaseOK && getAllocSizeAttr(E)))
5952 Result.setInvalid(E);
5954 Result.addUnsizedArray(Info, E, PointeeTy);
5958 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
5963 return VisitBuiltinCallExpr(E, BuiltinOp);
5965 return visitNonBuiltinCallExpr(E);
5968 bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
5969 unsigned BuiltinOp) {
5970 switch (BuiltinOp) {
5971 case Builtin::BI__builtin_addressof:
5973 case Builtin::BI__builtin_assume_aligned: {
5980 LValue OffsetResult(Result);
5991 int64_t AdditionalOffset = -Offset.getZExtValue();
5996 if (OffsetResult.Base) {
5999 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
6000 BaseAlignment = Info.Ctx.getDeclAlign(VD);
6006 if (BaseAlignment < Align) {
6007 Result.Designator.setInvalid();
6010 diag::note_constexpr_baa_insufficient_alignment) << 0
6018 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
6019 Result.Designator.setInvalid();
6023 diag::note_constexpr_baa_insufficient_alignment) << 1
6025 diag::note_constexpr_baa_value_insufficient_alignment))
6026 << (int)OffsetResult.Offset.getQuantity()
6034 case Builtin::BIstrchr:
6035 case Builtin::BIwcschr:
6036 case Builtin::BImemchr:
6037 case Builtin::BIwmemchr:
6038 if (Info.getLangOpts().CPlusPlus11)
6039 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
6041 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
6043 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
6045 case Builtin::BI__builtin_strchr:
6046 case Builtin::BI__builtin_wcschr:
6047 case Builtin::BI__builtin_memchr:
6048 case Builtin::BI__builtin_char_memchr:
6049 case Builtin::BI__builtin_wmemchr: {
6050 if (!Visit(E->
getArg(0)))
6055 uint64_t MaxLength = uint64_t(-1);
6056 if (BuiltinOp != Builtin::BIstrchr &&
6057 BuiltinOp != Builtin::BIwcschr &&
6058 BuiltinOp != Builtin::BI__builtin_strchr &&
6059 BuiltinOp != Builtin::BI__builtin_wcschr) {
6063 MaxLength = N.getExtValue();
6070 uint64_t DesiredVal;
6071 bool StopAtNull =
false;
6072 switch (BuiltinOp) {
6073 case Builtin::BIstrchr:
6074 case Builtin::BI__builtin_strchr:
6081 return ZeroInitialization(E);
6084 case Builtin::BImemchr:
6085 case Builtin::BI__builtin_memchr:
6086 case Builtin::BI__builtin_char_memchr:
6090 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
6093 case Builtin::BIwcschr:
6094 case Builtin::BI__builtin_wcschr:
6097 case Builtin::BIwmemchr:
6098 case Builtin::BI__builtin_wmemchr:
6100 DesiredVal = Desired.getZExtValue();
6104 for (; MaxLength; --MaxLength) {
6109 if (Char.
getInt().getZExtValue() == DesiredVal)
6111 if (StopAtNull && !Char.
getInt())
6117 return ZeroInitialization(E);
6121 return visitNonBuiltinCallExpr(E);
6130 class MemberPointerExprEvaluator
6131 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
6135 Result = MemberPtr(D);
6140 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
6141 : ExprEvaluatorBaseTy(Info),
Result(Result) {}
6147 bool ZeroInitialization(
const Expr *E) {
6148 return Success((
const ValueDecl*)
nullptr);
6151 bool VisitCastExpr(
const CastExpr *E);
6159 return MemberPointerExprEvaluator(Info, Result).Visit(E);
6162 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6165 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6167 case CK_NullToMemberPointer:
6169 return ZeroInitialization(E);
6171 case CK_BaseToDerivedMemberPointer: {
6179 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
6181 PathI != PathE; ++PathI) {
6182 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
6183 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
6184 if (!Result.castToDerived(Derived))
6193 case CK_DerivedToBaseMemberPointer:
6197 PathE = E->
path_end(); PathI != PathE; ++PathI) {
6198 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
6199 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
6200 if (!Result.castToBase(Base))
6207 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
6210 return Success(cast<DeclRefExpr>(E->
getSubExpr())->getDecl());
6218 class RecordExprEvaluator
6219 :
public ExprEvaluatorBase<RecordExprEvaluator> {
6224 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
6225 : ExprEvaluatorBaseTy(info), This(This),
Result(Result) {}
6231 bool ZeroInitialization(
const Expr *E) {
6232 return ZeroInitialization(E, E->
getType());
6236 bool VisitCallExpr(
const CallExpr *E) {
6237 return handleCallExpr(E, Result, &This);
6239 bool VisitCastExpr(
const CastExpr *E);
6242 return VisitCXXConstructExpr(E, E->
getType());
6262 const LValue &This,
APValue &Result) {
6263 assert(!RD->
isUnion() &&
"Expected non-union class type");
6274 End = CD->bases_end(); I !=
End; ++I, ++Index) {
6275 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
6276 LValue Subobject = This;
6280 Result.getStructBase(Index)))
6285 for (
const auto *I : RD->
fields()) {
6287 if (I->getType()->isReferenceType())
6290 LValue Subobject = This;
6296 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
6303 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E,
QualType T) {
6315 LValue Subobject = This;
6320 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
6323 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
6324 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
6331 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6334 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6336 case CK_ConstructorConversion:
6339 case CK_DerivedToBase:
6340 case CK_UncheckedDerivedToBase: {
6348 APValue *Value = &DerivedObject;
6351 PathE = E->
path_end(); PathI != PathE; ++PathI) {
6352 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
6353 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
6363 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6385 LValue Subobject = This;
6390 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
6391 isa<CXXDefaultInitExpr>(InitExpr));
6393 return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, InitExpr);
6397 if (Result.isUninit())
6400 unsigned ElementNo = 0;
6401 bool Success =
true;
6405 for (
const auto &Base : CXXRD->bases()) {
6406 assert(ElementNo < E->getNumInits() &&
"missing init for base class");
6409 LValue Subobject = This;
6413 APValue &FieldVal = Result.getStructBase(ElementNo);
6415 if (!Info.noteFailure())
6424 for (
const auto *Field : RD->
fields()) {
6427 if (Field->isUnnamedBitfield())
6430 LValue Subobject = This;
6437 Subobject, Field, &Layout))
6443 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
6446 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
6447 isa<CXXDefaultInitExpr>(Init));
6449 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
6452 FieldVal, Field))) {
6453 if (!Info.noteFailure())
6472 if (!Result.isUninit())
6483 return ZeroInitialization(E, T);
6487 auto Body = FD->
getBody(Definition);
6495 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
6496 return Visit(ME->GetTemporaryExpr());
6498 if (ZeroInit && !ZeroInitialization(E, T))
6503 cast<CXXConstructorDecl>(Definition), Info,
6507 bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
6509 if (!Info.CurrentCall) {
6510 assert(Info.checkingPotentialConstantExpression());
6519 auto Body = FD->
getBody(Definition);
6525 cast<CXXConstructorDecl>(Definition), Info,
6529 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
6539 Array.addArray(Info, E, ArrayType);
6548 if (!Field->getType()->isPointerType() ||
6549 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
6555 Array.moveInto(Result.getStructField(0));
6560 if (Field->getType()->isPointerType() &&
6561 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
6566 ArrayType->
getSize().getZExtValue()))
6568 Array.moveInto(Result.getStructField(1));
6569 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
6571 Result.getStructField(1) =
APValue(APSInt(ArrayType->
getSize()));
6581 bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
6585 if (Info.checkingPotentialConstantExpression())
return true;
6587 const size_t NumFields =
6592 "The number of lambda capture initializers should equal the number of " 6593 "fields within the closure type");
6600 bool Success =
true;
6601 for (
const auto *Field : ClosureClass->
fields()) {
6604 Expr *
const CurFieldInit = *CaptureInitIt++;
6611 APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
6613 if (!Info.keepEvaluatingAfterFailure())
6623 APValue &Result, EvalInfo &Info) {
6625 "can't evaluate expression as a record rvalue");
6626 return RecordExprEvaluator(Info, This, Result).Visit(E);
6637 class TemporaryExprEvaluator
6638 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
6640 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
6641 LValueExprEvaluatorBaseTy(Info, Result,
false) {}
6644 bool VisitConstructExpr(
const Expr *E) {
6649 bool VisitCastExpr(
const CastExpr *E) {
6652 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
6654 case CK_ConstructorConversion:
6659 return VisitConstructExpr(E);
6662 return VisitConstructExpr(E);
6664 bool VisitCallExpr(
const CallExpr *E) {
6665 return VisitConstructExpr(E);
6668 return VisitConstructExpr(E);
6671 return VisitConstructExpr(E);
6679 return TemporaryExprEvaluator(Info, Result).Visit(E);
6687 class VectorExprEvaluator
6688 :
public ExprEvaluatorBase<VectorExprEvaluator> {
6692 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
6693 : ExprEvaluatorBaseTy(info),
Result(Result) {}
6698 Result =
APValue(V.data(), V.size());
6706 bool ZeroInitialization(
const Expr *E);
6710 bool VisitCastExpr(
const CastExpr* E);
6721 return VectorExprEvaluator(Info, Result).Visit(E);
6724 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
6732 case CK_VectorSplat: {
6738 Val =
APValue(std::move(IntResult));
6740 APFloat FloatResult(0.0);
6743 Val =
APValue(std::move(FloatResult));
6750 return Success(Elts, E);
6754 llvm::APInt SValInt;
6759 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
6760 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
6763 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
6764 unsigned FloatEltSize = EltSize;
6765 if (&Sem == &APFloat::x87DoubleExtended())
6767 for (
unsigned i = 0; i < NElts; i++) {
6770 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
6772 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
6773 Elts.push_back(
APValue(APFloat(Sem, Elt)));
6776 for (
unsigned i = 0; i < NElts; i++) {
6779 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
6781 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
6787 return Success(Elts, E);
6790 return ExprEvaluatorBaseTy::VisitCastExpr(E);
6795 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6807 unsigned CountInits = 0, CountElts = 0;
6808 while (CountElts < NumElements) {
6810 if (CountInits < NumInits
6816 for (
unsigned j = 0; j < vlen; j++)
6820 llvm::APSInt sInt(32);
6821 if (CountInits < NumInits) {
6825 sInt = Info.Ctx.MakeIntValue(0, EltTy);
6826 Elements.push_back(
APValue(sInt));
6829 llvm::APFloat f(0.0);
6830 if (CountInits < NumInits) {
6834 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
6835 Elements.push_back(
APValue(f));
6840 return Success(Elements, E);
6844 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
6848 if (EltTy->isIntegerType())
6849 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
6852 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
6855 return Success(Elements, E);
6858 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
6860 return ZeroInitialization(E);
6868 class ArrayExprEvaluator
6869 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
6874 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
6875 : ExprEvaluatorBaseTy(Info), This(This),
Result(Result) {}
6879 "expected array or string literal");
6884 bool ZeroInitialization(
const Expr *E) {
6886 Info.Ctx.getAsConstantArrayType(E->
getType());
6891 CAT->
getSize().getZExtValue());
6895 LValue Subobject = This;
6896 Subobject.addArray(Info, E, CAT);
6901 bool VisitCallExpr(
const CallExpr *E) {
6902 return handleCallExpr(E, Result, &This);
6908 const LValue &Subobject,
6914 APValue &Result, EvalInfo &Info) {
6916 return ArrayExprEvaluator(Info, This, Result).Visit(E);
6923 if (isa<ImplicitValueInitExpr>(FillerExpr))
6925 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
6926 for (
unsigned I = 0, E = ILE->getNumInits(); I != E; ++I) {
6935 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
6948 return Success(Val, E);
6951 bool Success =
true;
6953 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
6954 "zero-initialized array shouldn't have any initialized elts");
6956 if (Result.isArray() && Result.hasArrayFiller())
6957 Filler = Result.getArrayFiller();
6960 unsigned NumElts = CAT->
getSize().getZExtValue();
6966 NumEltsToInit = NumElts;
6968 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: " 6969 << NumEltsToInit <<
".\n");
6976 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
6977 Result.getArrayInitializedElt(I) = Filler;
6978 if (Result.hasArrayFiller())
6979 Result.getArrayFiller() = Filler;
6982 LValue Subobject = This;
6983 Subobject.addArray(Info, E, CAT);
6984 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
6988 Info, Subobject, Init) ||
6991 if (!Info.noteFailure())
6997 if (!Result.hasArrayFiller())
7002 assert(FillerExpr &&
"no array filler for incomplete init list");
7004 FillerExpr) && Success;
7015 uint64_t Elements = CAT->getSize().getZExtValue();
7018 LValue Subobject = This;
7019 Subobject.addArray(Info, E, CAT);
7021 bool Success =
true;
7022 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
7026 CAT->getElementType(), 1)) {
7027 if (!Info.noteFailure())
7036 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
7037 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
7041 const LValue &Subobject,
7044 bool HadZeroInit = !Value->
isUninit();
7047 unsigned N = CAT->getSize().getZExtValue();
7057 for (
unsigned I = 0; I != N; ++I)
7061 LValue ArrayElt = Subobject;
7062 ArrayElt.addArray(Info, E, CAT);
7063 for (
unsigned I = 0; I != N; ++I)
7065 CAT->getElementType()) ||
7067 CAT->getElementType(), 1))
7076 return RecordExprEvaluator(Info, Subobject, *Value)
7077 .VisitCXXConstructExpr(E, Type);
7089 class IntExprEvaluator
7090 :
public ExprEvaluatorBase<IntExprEvaluator> {
7093 IntExprEvaluator(EvalInfo &info,
APValue &result)
7094 : ExprEvaluatorBaseTy(info),
Result(result) {}
7096 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
7098 "Invalid evaluation result.");
7100 "Invalid evaluation result.");
7101 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7102 "Invalid evaluation result.");
7106 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
7107 return Success(SI, E, Result);
7110 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
7112 "Invalid evaluation result.");
7113 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7114 "Invalid evaluation result.");
7116 Result.
getInt().setIsUnsigned(
7120 bool Success(
const llvm::APInt &I,
const Expr *E) {
7121 return Success(I, E, Result);
7124 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
7126 "Invalid evaluation result.");
7130 bool Success(uint64_t Value,
const Expr *E) {
7131 return Success(Value, E, Result);
7143 return Success(V.
getInt(), E);
7146 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
7159 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
7161 if (CheckReferencedDecl(E, E->
getDecl()))
7164 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
7168 VisitIgnoredBaseExpression(E->
getBase());
7172 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
7175 bool VisitCallExpr(
const CallExpr *E);
7176 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
7181 bool VisitCastExpr(
const CastExpr* E);
7193 if (Info.ArrayInitIndex == uint64_t(-1)) {
7199 return Success(Info.ArrayInitIndex, E);
7204 return ZeroInitialization(E);
7228 class FixedPointExprEvaluator
7229 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
7233 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
7234 : ExprEvaluatorBaseTy(info),
Result(result) {}
7236 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
7239 "Invalid evaluation result.");
7240 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7241 "Invalid evaluation result.");
7245 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
7246 return Success(SI, E, Result);
7249 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
7251 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
7252 "Invalid evaluation result.");
7257 bool Success(
const llvm::APInt &I,
const Expr *E) {
7258 return Success(I, E, Result);
7261 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
7266 bool Success(uint64_t Value,
const Expr *E) {
7267 return Success(Value, E, Result);
7279 return Success(V.
getInt(), E);
7282 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
7307 return IntExprEvaluator(Info, Result).Visit(E);
7317 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
7327 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
7331 bool SameSign = (ECD->getInitVal().isSigned()
7333 bool SameWidth = (ECD->getInitVal().getBitWidth()
7334 == Info.Ctx.getIntWidth(E->
getType()));
7335 if (SameSign && SameWidth)
7336 return Success(ECD->getInitVal(), E);
7340 llvm::APSInt Val = ECD->getInitVal();
7342 Val.setIsSigned(!ECD->getInitVal().isSigned());
7344 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
7345 return Success(Val, E);
7390 switch (CanTy->getTypeClass()) {
7391 #define TYPE(ID, BASE) 7392 #define DEPENDENT_TYPE(ID, BASE) case Type::ID: 7393 #define NON_CANONICAL_TYPE(ID, BASE) case Type::ID: 7394 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID: 7395 #include "clang/AST/TypeNodes.def" 7397 case Type::DeducedTemplateSpecialization:
7398 llvm_unreachable(
"unexpected non-canonical or dependent type");
7402 #define BUILTIN_TYPE(ID, SINGLETON_ID) 7403 #define SIGNED_TYPE(ID, SINGLETON_ID) \ 7404 case BuiltinType::ID: return GCCTypeClass::Integer; 7405 #define FLOATING_TYPE(ID, SINGLETON_ID) \ 7406 case BuiltinType::ID: return GCCTypeClass::RealFloat; 7407 #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \ 7408 case BuiltinType::ID: break; 7409 #include "clang/AST/BuiltinTypes.def" 7410 case BuiltinType::Void:
7413 case BuiltinType::Bool:
7416 case BuiltinType::Char_U:
7417 case BuiltinType::UChar:
7418 case BuiltinType::WChar_U:
7419 case BuiltinType::Char8:
7420 case BuiltinType::Char16:
7421 case BuiltinType::Char32:
7422 case BuiltinType::UShort:
7423 case BuiltinType::UInt:
7424 case BuiltinType::ULong:
7425 case BuiltinType::ULongLong:
7426 case BuiltinType::UInt128:
7429 case BuiltinType::UShortAccum:
7430 case BuiltinType::UAccum:
7431 case BuiltinType::ULongAccum:
7432 case BuiltinType::UShortFract:
7433 case BuiltinType::UFract:
7434 case BuiltinType::ULongFract:
7435 case BuiltinType::SatUShortAccum:
7436 case BuiltinType::SatUAccum:
7437 case BuiltinType::SatULongAccum:
7438 case BuiltinType::SatUShortFract:
7439 case BuiltinType::SatUFract:
7440 case BuiltinType::SatULongFract:
7443 case BuiltinType::NullPtr:
7445 case BuiltinType::ObjCId:
7446 case BuiltinType::ObjCClass:
7447 case BuiltinType::ObjCSel:
7448 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 7449 case BuiltinType::Id: 7450 #include "clang/Basic/OpenCLImageTypes.def" 7451 case BuiltinType::OCLSampler:
7452 case BuiltinType::OCLEvent:
7453 case BuiltinType::OCLClkEvent:
7454 case BuiltinType::OCLQueue:
7455 case BuiltinType::OCLReserveID:
7458 case BuiltinType::Dependent:
7459 llvm_unreachable(
"unexpected dependent type");
7461 llvm_unreachable(
"unexpected placeholder type");
7467 case Type::ConstantArray:
7468 case Type::VariableArray:
7469 case Type::IncompleteArray:
7470 case Type::FunctionNoProto:
7471 case Type::FunctionProto:
7474 case Type::MemberPointer:
7475 return CanTy->isMemberDataPointerType()
7491 case Type::BlockPointer:
7493 case Type::ExtVector:
7494 case Type::ObjCObject:
7495 case Type::ObjCInterface:
7496 case Type::ObjCObjectPointer:
7502 case Type::LValueReference:
7503 case Type::RValueReference:
7504 llvm_unreachable(
"invalid type for expression");
7507 llvm_unreachable(
"unexpected type class");
7530 template<
typename LValue>
7532 const Expr *E = LV.getLValueBase().template dyn_cast<
const Expr*>();
7533 return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
7569 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
7584 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
7586 }
else if (
const Expr *E = B.
get<
const Expr*>()) {
7587 if (isa<CompoundLiteralExpr>(E))
7604 auto *Cast = dyn_cast<
CastExpr>(NoParens);
7605 if (Cast ==
nullptr)
7612 CastKind != CK_AddressSpaceConversion)
7615 auto *SubExpr = Cast->getSubExpr();
7616 if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isRValue())
7637 assert(!LVal.Designator.Invalid);
7639 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD,
bool &Invalid) {
7642 if (Invalid || Parent->
isUnion())
7648 auto &Base = LVal.getLValueBase();
7649 if (
auto *ME = dyn_cast_or_null<MemberExpr>(Base.
dyn_cast<
const Expr *>())) {
7650 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
7652 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
7654 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
7655 for (
auto *FD : IFD->chain()) {
7657 if (!IsLastOrInvalidFieldDecl(cast<FieldDecl>(FD), Invalid))
7665 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
7675 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
7676 const auto &Entry = LVal.Designator.Entries[I];
7682 const auto *CAT = cast<ConstantArrayType>(Ctx.
getAsArrayType(BaseType));
7683 uint64_t Index = Entry.ArrayIndex;
7684 if (Index + 1 != CAT->getSize())
7686 BaseType = CAT->getElementType();
7689 uint64_t Index = Entry.ArrayIndex;
7693 }
else if (
auto *FD = getAsField(Entry)) {
7695 if (!IsLastOrInvalidFieldDecl(FD, Invalid))
7699 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
7711 if (LVal.Designator.Invalid)
7714 if (!LVal.Designator.Entries.empty())
7715 return LVal.Designator.isMostDerivedAnUnsizedArray();
7717 if (!LVal.InvalidBase)
7722 const auto *E = LVal.Base.dyn_cast<
const Expr *>();
7723 return !E || !isa<MemberExpr>(E);
7729 const SubobjectDesignator &
Designator = LVal.Designator;
7741 return LVal.InvalidBase &&
7742 Designator.Entries.size() == Designator.MostDerivedPathLength &&
7743 Designator.MostDerivedIsArrayElement &&
7752 if (Int.ugt(CharUnitsMax))
7765 unsigned Type,
const LValue &LVal,
7778 if (!(Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
7780 if (Type == 3 && !DetermineForCompleteObject)
7783 llvm::APInt APEndOffset;
7784 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
7788 if (LVal.InvalidBase)
7792 return CheckedHandleSizeof(BaseTy, EndOffset);
7796 const SubobjectDesignator &
Designator = LVal.Designator;
7808 llvm::APInt APEndOffset;
7809 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
7821 if (!CheckedHandleSizeof(Designator.MostDerivedType, BytesPerElem))
7827 int64_t ElemsRemaining;
7828 if (Designator.MostDerivedIsArrayElement &&
7829 Designator.Entries.size() == Designator.MostDerivedPathLength) {
7830 uint64_t ArraySize = Designator.getMostDerivedArraySize();
7831 uint64_t ArrayIndex = Designator.Entries.back().ArrayIndex;
7832 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
7834 ElemsRemaining = Designator.isOnePastTheEnd() ? 0 : 1;
7837 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
7847 EvalInfo &Info, uint64_t &Size) {
7854 SpeculativeEvaluationRAII SpeculativeEval(Info);
7855 FoldOffsetRAII Fold(Info);
7863 LVal.setFrom(Info.Ctx, RVal);
7871 if (LVal.getLValueOffset().isNegative()) {
7882 if (EndOffset <= LVal.getLValueOffset())
7885 Size = (EndOffset - LVal.getLValueOffset()).getQuantity();
7889 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
7891 return VisitBuiltinCallExpr(E, BuiltinOp);
7893 return ExprEvaluatorBaseTy::VisitCallExpr(E);
7896 bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
7897 unsigned BuiltinOp) {
7900 return ExprEvaluatorBaseTy::VisitCallExpr(E);
7902 case Builtin::BI__builtin_object_size: {
7906 assert(Type <= 3 &&
"unexpected type");
7910 return Success(Size, E);
7913 return Success((Type & 2) ? 0 : -1, E);
7917 switch (Info.EvalMode) {
7918 case EvalInfo::EM_ConstantExpression:
7919 case EvalInfo::EM_PotentialConstantExpression:
7920 case EvalInfo::EM_ConstantFold:
7921 case EvalInfo::EM_EvaluateForOverflow:
7922 case EvalInfo::EM_IgnoreSideEffects:
7923 case EvalInfo::EM_OffsetFold:
7926 case EvalInfo::EM_ConstantExpressionUnevaluated:
7927 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
7929 return Success((Type & 2) ? 0 : -1, E);
7932 llvm_unreachable(
"unexpected EvalMode");
7935 case Builtin::BI__builtin_bswap16:
7936 case Builtin::BI__builtin_bswap32:
7937 case Builtin::BI__builtin_bswap64: {
7942 return Success(Val.byteSwap(), E);
7945 case Builtin::BI__builtin_classify_type:
7952 case Builtin::BI__builtin_clz:
7953 case Builtin::BI__builtin_clzl:
7954 case Builtin::BI__builtin_clzll:
7955 case Builtin::BI__builtin_clzs: {
7962 return Success(Val.countLeadingZeros(), E);
7965 case Builtin::BI__builtin_constant_p:
7968 case Builtin::BI__builtin_ctz:
7969 case Builtin::BI__builtin_ctzl:
7970 case Builtin::BI__builtin_ctzll:
7971 case Builtin::BI__builtin_ctzs: {
7978 return Success(Val.countTrailingZeros(), E);
7981 case Builtin::BI__builtin_eh_return_data_regno: {
7983 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
7984 return Success(Operand, E);
7987 case Builtin::BI__builtin_expect:
7988 return Visit(E->
getArg(0));
7990 case Builtin::BI__builtin_ffs:
7991 case Builtin::BI__builtin_ffsl:
7992 case Builtin::BI__builtin_ffsll: {
7997 unsigned N = Val.countTrailingZeros();
7998 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
8001 case Builtin::BI__builtin_fpclassify: {
8006 switch (Val.getCategory()) {
8007 case APFloat::fcNaN: Arg = 0;
break;
8008 case APFloat::fcInfinity: Arg = 1;
break;
8009 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
8010 case APFloat::fcZero: Arg = 4;
break;
8012 return Visit(E->
getArg(Arg));
8015 case Builtin::BI__builtin_isinf_sign: {
8018 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
8021 case Builtin::BI__builtin_isinf: {
8024 Success(Val.isInfinity() ? 1 : 0, E);
8027 case Builtin::BI__builtin_isfinite: {
8030 Success(Val.isFinite() ? 1 : 0, E);
8033 case Builtin::BI__builtin_isnan: {
8036 Success(Val.isNaN() ? 1 : 0, E);
8039 case Builtin::BI__builtin_isnormal: {
8042 Success(Val.isNormal() ? 1 : 0, E);
8045 case Builtin::BI__builtin_parity:
8046 case Builtin::BI__builtin_parityl:
8047 case Builtin::BI__builtin_parityll: {
8052 return Success(Val.countPopulation() % 2, E);
8055 case Builtin::BI__builtin_popcount:
8056 case Builtin::BI__builtin_popcountl:
8057 case Builtin::BI__builtin_popcountll: {
8062 return Success(Val.countPopulation(), E);
8065 case Builtin::BIstrlen:
8066 case Builtin::BIwcslen:
8068 if (Info.getLangOpts().CPlusPlus11)
8069 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
8071 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
8073 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
8075 case Builtin::BI__builtin_strlen:
8076 case Builtin::BI__builtin_wcslen: {
8086 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
8087 String.getLValueBase().dyn_cast<
const Expr *>())) {
8090 StringRef Str = S->getBytes();
8091 int64_t Off = String.Offset.getQuantity();
8092 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
8093 S->getCharByteWidth() == 1 &&
8095 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
8096 Str = Str.substr(Off);
8098 StringRef::size_type Pos = Str.find(0);
8099 if (Pos != StringRef::npos)
8100 Str = Str.substr(0, Pos);
8102 return Success(Str.size(), E);
8109 for (uint64_t Strlen = 0; ; ++Strlen) {
8115 return Success(Strlen, E);
8121 case Builtin::BIstrcmp:
8122 case Builtin::BIwcscmp:
8123 case Builtin::BIstrncmp:
8124 case Builtin::BIwcsncmp:
8125 case Builtin::BImemcmp:
8126 case Builtin::BIwmemcmp:
8128 if (Info.getLangOpts().CPlusPlus11)
8129 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
8131 << (std::string(
"'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) +
"'");
8133 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
8135 case Builtin::BI__builtin_strcmp:
8136 case Builtin::BI__builtin_wcscmp:
8137 case Builtin::BI__builtin_strncmp:
8138 case Builtin::BI__builtin_wcsncmp:
8139 case Builtin::BI__builtin_memcmp:
8140 case Builtin::BI__builtin_wmemcmp: {
8141 LValue String1, String2;
8148 uint64_t MaxLength = uint64_t(-1);
8149 if (BuiltinOp != Builtin::BIstrcmp &&
8150 BuiltinOp != Builtin::BIwcscmp &&
8151 BuiltinOp != Builtin::BI__builtin_strcmp &&
8152 BuiltinOp != Builtin::BI__builtin_wcscmp) {
8156 MaxLength = N.getExtValue();
8158 bool StopAtNull = (BuiltinOp != Builtin::BImemcmp &&
8159 BuiltinOp != Builtin::BIwmemcmp &&
8160 BuiltinOp != Builtin::BI__builtin_memcmp &&
8161 BuiltinOp != Builtin::BI__builtin_wmemcmp);
8162 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
8163 BuiltinOp == Builtin::BIwcsncmp ||
8164 BuiltinOp == Builtin::BIwmemcmp ||
8165 BuiltinOp == Builtin::BI__builtin_wcscmp ||
8166 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
8167 BuiltinOp == Builtin::BI__builtin_wmemcmp;
8168 for (; MaxLength; --MaxLength) {
8176 return Success(Char1.
getInt() < Char2.
getInt() ? -1 : 1, E);
8178 return Success(Char1.
getInt().ult(Char2.
getInt()) ? -1 : 1, E);
8180 if (StopAtNull && !Char1.
getInt())
8181 return Success(0, E);
8182 assert(!(StopAtNull && !Char2.
getInt()));
8188 return Success(0, E);
8191 case Builtin::BI__atomic_always_lock_free:
8192 case Builtin::BI__atomic_is_lock_free:
8193 case Builtin::BI__c11_atomic_is_lock_free: {
8211 unsigned InlineWidthBits =
8212 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
8213 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
8214 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
8220 return Success(1, E);
8223 castAs<PointerType>()->getPointeeType();
8225 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
8227 return Success(1, E);
8232 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
8233 Success(0, E) :
Error(E);
8235 case Builtin::BIomp_is_initial_device:
8237 return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
8238 case Builtin::BI__builtin_add_overflow:
8239 case Builtin::BI__builtin_sub_overflow:
8240 case Builtin::BI__builtin_mul_overflow:
8241 case Builtin::BI__builtin_sadd_overflow:
8242 case Builtin::BI__builtin_uadd_overflow:
8243 case Builtin::BI__builtin_uaddl_overflow:
8244 case Builtin::BI__builtin_uaddll_overflow:
8245 case Builtin::BI__builtin_usub_overflow:
8246 case Builtin::BI__builtin_usubl_overflow:
8247 case Builtin::BI__builtin_usubll_overflow:
8248 case Builtin::BI__builtin_umul_overflow:
8249 case Builtin::BI__builtin_umull_overflow:
8250 case Builtin::BI__builtin_umulll_overflow:
8251 case Builtin::BI__builtin_saddl_overflow:
8252 case Builtin::BI__builtin_saddll_overflow:
8253 case Builtin::BI__builtin_ssub_overflow:
8254 case Builtin::BI__builtin_ssubl_overflow:
8255 case Builtin::BI__builtin_ssubll_overflow:
8256 case Builtin::BI__builtin_smul_overflow:
8257 case Builtin::BI__builtin_smull_overflow:
8258 case Builtin::BI__builtin_smulll_overflow: {
8259 LValue ResultLValue;
8269 bool DidOverflow =
false;
8272 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
8273 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
8274 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
8275 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
8277 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
8279 uint64_t LHSSize = LHS.getBitWidth();
8280 uint64_t RHSSize = RHS.getBitWidth();
8281 uint64_t ResultSize = Info.Ctx.getTypeSize(ResultType);
8288 if (IsSigned && !AllSigned)
8291 LHS = APSInt(IsSigned ? LHS.sextOrSelf(MaxBits) : LHS.zextOrSelf(MaxBits),
8293 RHS = APSInt(IsSigned ? RHS.sextOrSelf(MaxBits) : RHS.zextOrSelf(MaxBits),
8295 Result = APSInt(MaxBits, !IsSigned);
8299 switch (BuiltinOp) {
8301 llvm_unreachable(
"Invalid value for BuiltinOp");
8302 case Builtin::BI__builtin_add_overflow:
8303 case Builtin::BI__builtin_sadd_overflow:
8304 case Builtin::BI__builtin_saddl_overflow:
8305 case Builtin::BI__builtin_saddll_overflow:
8306 case Builtin::BI__builtin_uadd_overflow:
8307 case Builtin::BI__builtin_uaddl_overflow:
8308 case Builtin::BI__builtin_uaddll_overflow:
8309 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
8310 : LHS.uadd_ov(RHS, DidOverflow);
8312 case Builtin::BI__builtin_sub_overflow:
8313 case Builtin::BI__builtin_ssub_overflow:
8314 case Builtin::BI__builtin_ssubl_overflow:
8315 case Builtin::BI__builtin_ssubll_overflow:
8316 case Builtin::BI__builtin_usub_overflow:
8317 case Builtin::BI__builtin_usubl_overflow:
8318 case Builtin::BI__builtin_usubll_overflow:
8319 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
8320 : LHS.usub_ov(RHS, DidOverflow);
8322 case Builtin::BI__builtin_mul_overflow:
8323 case Builtin::BI__builtin_smul_overflow:
8324 case Builtin::BI__builtin_smull_overflow:
8325 case Builtin::BI__builtin_smulll_overflow:
8326 case Builtin::BI__builtin_umul_overflow:
8327 case Builtin::BI__builtin_umull_overflow:
8328 case Builtin::BI__builtin_umulll_overflow:
8329 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
8330 : LHS.umul_ov(RHS, DidOverflow);
8336 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
8337 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
8338 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
8344 APSInt Temp = Result.extOrTrunc(Info.Ctx.getTypeSize(ResultType));
8347 if (!APSInt::isSameValue(Temp, Result))
8355 return Success(DidOverflow, E);
8361 if (!A.getLValueBase())
8362 return !B.getLValueBase();
8363 if (!B.getLValueBase())
8366 if (A.getLValueBase().getOpaqueValue() !=
8367 B.getLValueBase().getOpaqueValue()) {
8377 (A.getLValueCallIndex() == B.getLValueCallIndex() &&
8378 A.getLValueVersion() == B.getLValueVersion());
8387 if (!LV.getLValueBase())
8392 if (!LV.getLValueDesignator().Invalid &&
8393 !LV.getLValueDesignator().isOnePastTheEnd())
8398 QualType Ty = getType(LV.getLValueBase());
8405 return LV.getLValueOffset() == Size;
8415 class DataRecursiveIntBinOpEvaluator {
8420 EvalResult() : Failed(
false) { }
8422 void swap(EvalResult &RHS) {
8424 Failed = RHS.Failed;
8431 EvalResult LHSResult;
8432 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
8435 Job(Job &&) =
default;
8437 void startSpeculativeEval(EvalInfo &Info) {
8438 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
8442 SpeculativeEvaluationRAII SpecEvalRAII;
8447 IntExprEvaluator &IntEval;
8452 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
8453 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
8468 EvalResult PrevResult;
8469 while (!Queue.empty())
8470 process(PrevResult);
8472 if (PrevResult.Failed)
return false;
8474 FinalResult.
swap(PrevResult.Val);
8479 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
8480 return IntEval.Success(Value, E, Result);
8482 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
8483 return IntEval.Success(Value, E, Result);
8486 return IntEval.Error(E);
8489 return IntEval.Error(E, D);
8493 return Info.CCEDiag(E, D);
8497 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
8498 bool &SuppressRHSDiags);
8500 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
8503 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
8504 Result.Failed = !
Evaluate(Result.Val, Info, E);
8509 void process(EvalResult &Result);
8511 void enqueue(
const Expr *E) {
8513 Queue.resize(Queue.size()+1);
8515 Queue.back().Kind = Job::AnyExprKind;
8521 bool DataRecursiveIntBinOpEvaluator::
8522 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
8523 bool &SuppressRHSDiags) {
8526 if (LHSResult.Failed)
8527 return Info.noteSideEffect();
8536 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
8537 Success(LHSAsBool, E, LHSResult.Val);
8541 LHSResult.Failed =
true;
8545 if (!Info.noteSideEffect())
8551 SuppressRHSDiags =
true;
8560 if (LHSResult.Failed && !Info.noteFailure())
8571 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
8574 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
8576 : Offset64 + Index64);
8579 bool DataRecursiveIntBinOpEvaluator::
8580 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
8583 if (RHSResult.Failed)
8585 Result = RHSResult.Val;
8590 bool lhsResult, rhsResult;
8597 return Success(lhsResult || rhsResult, E, Result);
8599 return Success(lhsResult && rhsResult, E, Result);
8605 if (rhsResult == (E->
getOpcode() == BO_LOr))
8606 return Success(rhsResult, E, Result);
8616 if (LHSResult.Failed || RHSResult.Failed)
8619 const APValue &LHSVal = LHSResult.Val;
8620 const APValue &RHSVal = RHSResult.Val;
8644 if (!LHSExpr || !RHSExpr)
8648 if (!LHSAddrExpr || !RHSAddrExpr)
8652 RHSAddrExpr->getLabel()->getDeclContext())
8654 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
8670 return Success(Value, E, Result);
8673 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
8674 Job &job = Queue.back();
8677 case Job::AnyExprKind: {
8678 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
8679 if (shouldEnqueue(Bop)) {
8680 job.Kind = Job::BinOpKind;
8681 enqueue(Bop->getLHS());
8686 EvaluateExpr(job.E, Result);
8691 case Job::BinOpKind: {
8693 bool SuppressRHSDiags =
false;
8694 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
8698 if (SuppressRHSDiags)
8699 job.startSpeculativeEval(Info);
8700 job.LHSResult.swap(Result);
8701 job.Kind = Job::BinOpVisitedLHSKind;
8706 case Job::BinOpVisitedLHSKind: {
8710 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
8716 llvm_unreachable(
"Invalid Job::Kind!");
8722 class DelayedNoteFailureRAII {
8727 DelayedNoteFailureRAII(EvalInfo &Info,
bool NoteFailure =
true)
8728 : Info(Info), NoteFailure(NoteFailure) {}
8729 ~DelayedNoteFailureRAII() {
8731 bool ContinueAfterFailure = Info.noteFailure();
8732 (void)ContinueAfterFailure;
8733 assert(ContinueAfterFailure &&
8734 "Shouldn't have kept evaluating on failure.");
8740 template <
class SuccessCB,
class AfterCB>
8743 SuccessCB &&Success, AfterCB &&DoAfter) {
8747 "unsupported binary expression evaluation");
8749 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
8758 Info.Ctx.CompCategories.getInfoForType(E->
getType());
8770 if (!LHSOK && !Info.noteFailure())
8782 ComplexValue LHS, RHS;
8791 LHS.makeComplexFloat();
8792 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
8797 if (!LHSOK && !Info.noteFailure())
8803 RHS.makeComplexFloat();
8804 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
8808 if (LHS.isComplexFloat()) {
8809 APFloat::cmpResult CR_r =
8810 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
8811 APFloat::cmpResult CR_i =
8812 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
8813 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
8816 assert(IsEquality &&
"invalid complex comparison");
8817 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
8818 LHS.getComplexIntImag() == RHS.getComplexIntImag();
8825 APFloat RHS(0.0), LHS(0.0);
8828 if (!LHSOK && !Info.noteFailure())
8835 auto GetCmpRes = [&]() {
8836 switch (LHS.compare(RHS)) {
8837 case APFloat::cmpEqual:
8839 case APFloat::cmpLessThan:
8841 case APFloat::cmpGreaterThan:
8843 case APFloat::cmpUnordered:
8846 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
8848 return Success(GetCmpRes(), E);
8852 LValue LHSValue, RHSValue;
8855 if (!LHSOK && !Info.noteFailure())
8871 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
8872 (!RHSValue.Base && !RHSValue.Offset.isZero()))
8879 LHSValue.Base && RHSValue.Base)
8887 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
8889 (RHSValue.Base && RHSValue.Offset.isZero() &&
8900 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
8901 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
8903 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
8904 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
8914 Info.CCEDiag(E, diag::note_constexpr_void_comparison);
8924 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
8927 getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
8934 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
8935 Mismatch < RHSDesignator.Entries.size()) {
8936 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
8937 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
8939 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
8941 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
8942 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
8945 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
8946 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
8951 diag::note_constexpr_pointer_comparison_differing_access)
8959 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
8962 assert(PtrSize <= 64 &&
"Unexpected pointer width");
8963 uint64_t Mask = ~0ULL >> (64 - PtrSize);
8970 if (!LHSValue.Base.isNull() && IsRelational) {
8971 QualType BaseTy = getType(LHSValue.Base);
8974 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
8976 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
8980 if (CompareLHS < CompareRHS)
8982 if (CompareLHS > CompareRHS)
8988 assert(IsEquality &&
"unexpected member pointer operation");
8991 MemberPtr LHSValue, RHSValue;
8994 if (!LHSOK && !Info.noteFailure())
9003 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
9004 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
9010 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
9011 if (MD->isVirtual())
9012 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
9013 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
9014 if (MD->isVirtual())
9015 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
9021 bool Equal = LHSValue == RHSValue;
9027 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
9046 Info.Ctx.CompCategories.getInfoForType(E->
getType());
9057 return ExprEvaluatorBaseTy::VisitBinCmp(E);
9061 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9067 DelayedNoteFailureRAII MaybeNoteFailureLater(Info, E->
isAssignmentOp());
9068 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
9069 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
9073 "DataRecursiveIntBinOpEvaluator should have handled integral types");
9087 llvm_unreachable(
"unsupported binary operator");
9090 return Success(IsEqual == (Op == BO_EQ), E);
9091 case BO_LT:
return Success(IsLess, E);
9092 case BO_GT:
return Success(IsGreater, E);
9093 case BO_LE:
return Success(IsEqual || IsLess, E);
9094 case BO_GE:
return Success(IsEqual || IsGreater, E);
9098 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9107 LValue LHSValue, RHSValue;
9110 if (!LHSOK && !Info.noteFailure())
9120 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
9122 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr *>();
9123 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr *>();
9124 if (!LHSExpr || !RHSExpr)
9128 if (!LHSAddrExpr || !RHSAddrExpr)
9132 RHSAddrExpr->getLabel()->getDeclContext())
9134 return Success(
APValue(LHSAddrExpr, RHSAddrExpr), E);
9136 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
9137 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
9139 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
9140 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
9146 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
9149 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
9161 if (ElementSize.
isZero()) {
9162 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
9175 APSInt LHS(llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
9176 APSInt RHS(llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
9177 APSInt ElemSize(llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
9179 APSInt TrueResult = (LHS - RHS) / ElemSize;
9180 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
9182 if (Result.extend(65) != TrueResult &&
9185 return Success(Result, E);
9188 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9193 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
9214 return Success(n, E);
9216 return Success(1, E);
9229 return Success(Sizeof, E);
9234 Info.Ctx.toCharUnitsFromBits(
9240 llvm_unreachable(
"unknown expr/type trait");
9243 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
9249 for (
unsigned i = 0; i != n; ++i) {
9257 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
9261 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
9262 Result += IdxResult.getSExtValue() * ElementSize;
9275 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
9282 llvm_unreachable(
"dependent __builtin_offsetof");
9298 CurrentType = BaseSpec->
getType();
9309 return Success(Result, OOE);
9312 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9328 if (!Result.isInt())
return Error(E);
9329 const APSInt &Value = Result.getInt();
9330 if (Value.isSigned() && Value.isMinSignedValue() && E->
canOverflow() &&
9334 return Success(-Value, E);
9339 if (!Result.isInt())
return Error(E);
9340 return Success(~Result.getInt(), E);
9346 return Success(!bres, E);
9353 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9359 case CK_BaseToDerived:
9360 case CK_DerivedToBase:
9361 case CK_UncheckedDerivedToBase:
9364 case CK_ArrayToPointerDecay:
9365 case CK_FunctionToPointerDecay:
9366 case CK_NullToPointer:
9367 case CK_NullToMemberPointer:
9368 case CK_BaseToDerivedMemberPointer:
9369 case CK_DerivedToBaseMemberPointer:
9370 case CK_ReinterpretMemberPointer:
9371 case CK_ConstructorConversion:
9372 case CK_IntegralToPointer:
9374 case CK_VectorSplat:
9375 case CK_IntegralToFloating:
9376 case CK_FloatingCast:
9377 case CK_CPointerToObjCPointerCast:
9378 case CK_BlockPointerToObjCPointerCast:
9379 case CK_AnyPointerToBlockPointerCast:
9380 case CK_ObjCObjectLValueCast:
9381 case CK_FloatingRealToComplex:
9382 case CK_FloatingComplexToReal:
9383 case CK_FloatingComplexCast:
9384 case CK_FloatingComplexToIntegralComplex:
9385 case CK_IntegralRealToComplex:
9386 case CK_IntegralComplexCast:
9387 case CK_IntegralComplexToFloatingComplex:
9388 case CK_BuiltinFnToFnPtr:
9389 case CK_ZeroToOCLEvent:
9390 case CK_ZeroToOCLQueue:
9391 case CK_NonAtomicToAtomic:
9392 case CK_AddressSpaceConversion:
9393 case CK_IntToOCLSampler:
9394 llvm_unreachable(
"invalid cast kind for integral value");
9398 case CK_LValueBitCast:
9399 case CK_ARCProduceObject:
9400 case CK_ARCConsumeObject:
9401 case CK_ARCReclaimReturnedObject:
9402 case CK_ARCExtendBlockObject:
9403 case CK_CopyAndAutoreleaseBlockObject:
9406 case CK_UserDefinedConversion:
9407 case CK_LValueToRValue:
9408 case CK_AtomicToNonAtomic:
9410 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9412 case CK_MemberPointerToBoolean:
9413 case CK_PointerToBoolean:
9414 case CK_IntegralToBoolean:
9415 case CK_FloatingToBoolean:
9416 case CK_BooleanToSignedIntegral:
9417 case CK_FloatingComplexToBoolean:
9418 case CK_IntegralComplexToBoolean: {
9422 uint64_t IntResult = BoolResult;
9423 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
9424 IntResult = (uint64_t)-1;
9425 return Success(IntResult, E);
9428 case CK_IntegralCast: {
9429 if (!Visit(SubExpr))
9432 if (!Result.isInt()) {
9438 if (Result.isAddrLabelDiff())
9439 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
9441 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
9445 Result.getInt()), E);
9448 case CK_PointerToIntegral: {
9449 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
9455 if (LV.getLValueBase()) {
9460 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
9463 LV.Designator.setInvalid();
9464 LV.moveInto(Result);
9469 if (LV.isNullPointer())
9470 V = Info.Ctx.getTargetNullPointerValue(SrcType);
9472 V = LV.getLValueOffset().getQuantity();
9474 APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType);
9478 case CK_IntegralComplexToReal: {
9482 return Success(C.getComplexIntReal(), E);
9485 case CK_FloatingToIntegral: {
9493 return Success(Value, E);
9497 llvm_unreachable(
"unknown cast resulting in integral value");
9500 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9505 if (!LV.isComplexInt())
9507 return Success(LV.getComplexIntReal(), E);
9513 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9518 if (!LV.isComplexInt())
9520 return Success(LV.getComplexIntImag(), E);
9524 return Success(0, E);
9527 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
9531 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
9535 bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9545 if (!Result.isInt())
return Error(E);
9546 const APSInt &Value = Result.getInt();
9547 if (Value.isSigned() && Value.isMinSignedValue() && E->
canOverflow()) {
9550 Info.Ctx.getTypeInfo(E->
getType()).Width,
9552 Info.CCEDiag(E, diag::note_constexpr_overflow) << S << E->
getType();
9553 if (Info.noteUndefinedBehavior())
return false;
9555 return Success(-Value, E);
9561 return Success(!bres, E);
9571 class FloatExprEvaluator
9572 :
public ExprEvaluatorBase<FloatExprEvaluator> {
9575 FloatExprEvaluator(EvalInfo &info, APFloat &result)
9576 : ExprEvaluatorBaseTy(info),
Result(result) {}
9583 bool ZeroInitialization(
const Expr *E) {
9584 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
9588 bool VisitCallExpr(
const CallExpr *E);
9593 bool VisitCastExpr(
const CastExpr *E);
9604 return FloatExprEvaluator(Info, Result).Visit(E);
9611 llvm::APFloat &Result) {
9613 if (!S)
return false;
9621 fill = llvm::APInt(32, 0);
9622 else if (S->
getString().getAsInteger(0, fill))
9627 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
9629 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
9637 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
9639 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
9645 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9648 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9650 case Builtin::BI__builtin_huge_val:
9651 case Builtin::BI__builtin_huge_valf:
9652 case Builtin::BI__builtin_huge_vall:
9653 case Builtin::BI__builtin_huge_valf128:
9654 case Builtin::BI__builtin_inf:
9655 case Builtin::BI__builtin_inff:
9656 case Builtin::BI__builtin_infl:
9657 case Builtin::BI__builtin_inff128: {
9658 const llvm::fltSemantics &Sem =
9659 Info.Ctx.getFloatTypeSemantics(E->
getType());
9660 Result = llvm::APFloat::getInf(Sem);
9664 case Builtin::BI__builtin_nans:
9665 case Builtin::BI__builtin_nansf:
9666 case Builtin::BI__builtin_nansl:
9667 case Builtin::BI__builtin_nansf128:
9673 case Builtin::BI__builtin_nan:
9674 case Builtin::BI__builtin_nanf:
9675 case Builtin::BI__builtin_nanl:
9676 case Builtin::BI__builtin_nanf128:
9684 case Builtin::BI__builtin_fabs:
9685 case Builtin::BI__builtin_fabsf:
9686 case Builtin::BI__builtin_fabsl:
9687 case Builtin::BI__builtin_fabsf128:
9691 if (Result.isNegative())
9692 Result.changeSign();
9699 case Builtin::BI__builtin_copysign:
9700 case Builtin::BI__builtin_copysignf:
9701 case Builtin::BI__builtin_copysignl:
9702 case Builtin::BI__builtin_copysignf128: {
9707 Result.copySign(RHS);
9713 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9718 Result = CV.FloatReal;
9725 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9730 Result = CV.FloatImag;
9735 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
9736 Result = llvm::APFloat::getZero(Sem);
9740 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
9742 default:
return Error(E);
9748 Result.changeSign();
9753 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
9755 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9759 if (!LHSOK && !Info.noteFailure())
9765 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
9770 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9775 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9777 case CK_IntegralToFloating: {
9784 case CK_FloatingCast: {
9785 if (!Visit(SubExpr))
9791 case CK_FloatingComplexToReal: {
9795 Result = V.getComplexFloatReal();
9806 class ComplexExprEvaluator
9807 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
9811 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
9812 : ExprEvaluatorBaseTy(info),
Result(Result) {}
9819 bool ZeroInitialization(
const Expr *E);
9826 bool VisitCastExpr(
const CastExpr *E);
9836 return ComplexExprEvaluator(Info, Result).Visit(E);
9839 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
9842 Result.makeComplexFloat();
9843 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
9844 Result.FloatReal = Zero;
9845 Result.FloatImag = Zero;
9847 Result.makeComplexInt();
9848 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
9849 Result.IntReal = Zero;
9850 Result.IntImag = Zero;
9855 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
9859 Result.makeComplexFloat();
9860 APFloat &Imag = Result.FloatImag;
9864 Result.FloatReal = APFloat(Imag.getSemantics());
9868 "Unexpected imaginary literal.");
9870 Result.makeComplexInt();
9871 APSInt &Imag = Result.IntImag;
9875 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
9880 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
9884 case CK_BaseToDerived:
9885 case CK_DerivedToBase:
9886 case CK_UncheckedDerivedToBase:
9889 case CK_ArrayToPointerDecay:
9890 case CK_FunctionToPointerDecay:
9891 case CK_NullToPointer:
9892 case CK_NullToMemberPointer:
9893 case CK_BaseToDerivedMemberPointer:
9894 case CK_DerivedToBaseMemberPointer:
9895 case CK_MemberPointerToBoolean:
9896 case CK_ReinterpretMemberPointer:
9897 case CK_ConstructorConversion:
9898 case CK_IntegralToPointer:
9899 case CK_PointerToIntegral:
9900 case CK_PointerToBoolean:
9902 case CK_VectorSplat:
9903 case CK_IntegralCast:
9904 case CK_BooleanToSignedIntegral:
9905 case CK_IntegralToBoolean:
9906 case CK_IntegralToFloating:
9907 case CK_FloatingToIntegral:
9908 case CK_FloatingToBoolean:
9909 case CK_FloatingCast:
9910 case CK_CPointerToObjCPointerCast:
9911 case CK_BlockPointerToObjCPointerCast:
9912 case CK_AnyPointerToBlockPointerCast:
9913 case CK_ObjCObjectLValueCast:
9914 case CK_FloatingComplexToReal:
9915 case CK_FloatingComplexToBoolean:
9916 case CK_IntegralComplexToReal:
9917 case CK_IntegralComplexToBoolean:
9918 case CK_ARCProduceObject:
9919 case CK_ARCConsumeObject:
9920 case CK_ARCReclaimReturnedObject:
9921 case CK_ARCExtendBlockObject:
9922 case CK_CopyAndAutoreleaseBlockObject:
9923 case CK_BuiltinFnToFnPtr:
9924 case CK_ZeroToOCLEvent:
9925 case CK_ZeroToOCLQueue:
9926 case CK_NonAtomicToAtomic:
9927 case CK_AddressSpaceConversion:
9928 case CK_IntToOCLSampler:
9929 llvm_unreachable(
"invalid cast kind for complex value");
9931 case CK_LValueToRValue:
9932 case CK_AtomicToNonAtomic:
9934 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9937 case CK_LValueBitCast:
9938 case CK_UserDefinedConversion:
9941 case CK_FloatingRealToComplex: {
9942 APFloat &Real = Result.FloatReal;
9946 Result.makeComplexFloat();
9947 Result.FloatImag = APFloat(Real.getSemantics());
9951 case CK_FloatingComplexCast: {
9963 case CK_FloatingComplexToIntegralComplex: {
9970 Result.makeComplexInt();
9972 To, Result.IntReal) &&
9974 To, Result.IntImag);
9977 case CK_IntegralRealToComplex: {
9978 APSInt &Real = Result.IntReal;
9982 Result.makeComplexInt();
9983 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
9987 case CK_IntegralComplexCast: {
10000 case CK_IntegralComplexToFloatingComplex: {
10007 Result.makeComplexFloat();
10009 To, Result.FloatReal) &&
10011 To, Result.FloatImag);
10015 llvm_unreachable(
"unknown cast resulting in complex value");
10018 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10020 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10024 bool LHSReal =
false, RHSReal =
false;
10029 APFloat &Real = Result.FloatReal;
10032 Result.makeComplexFloat();
10033 Result.FloatImag = APFloat(Real.getSemantics());
10036 LHSOK = Visit(E->
getLHS());
10038 if (!LHSOK && !Info.noteFailure())
10044 APFloat &Real = RHS.FloatReal;
10047 RHS.makeComplexFloat();
10048 RHS.FloatImag = APFloat(Real.getSemantics());
10052 assert(!(LHSReal && RHSReal) &&
10053 "Cannot have both operands of a complex operation be real.");
10055 default:
return Error(E);
10057 if (Result.isComplexFloat()) {
10058 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
10059 APFloat::rmNearestTiesToEven);
10061 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
10063 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
10064 APFloat::rmNearestTiesToEven);
10066 Result.getComplexIntReal() += RHS.getComplexIntReal();
10067 Result.getComplexIntImag() += RHS.getComplexIntImag();
10071 if (Result.isComplexFloat()) {
10072 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
10073 APFloat::rmNearestTiesToEven);
10075 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
10076 Result.getComplexFloatImag().changeSign();
10077 }
else if (!RHSReal) {
10078 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
10079 APFloat::rmNearestTiesToEven);
10082 Result.getComplexIntReal() -= RHS.getComplexIntReal();
10083 Result.getComplexIntImag() -= RHS.getComplexIntImag();
10087 if (Result.isComplexFloat()) {
10092 ComplexValue LHS =
Result;
10093 APFloat &A = LHS.getComplexFloatReal();
10094 APFloat &B = LHS.getComplexFloatImag();
10095 APFloat &
C = RHS.getComplexFloatReal();
10096 APFloat &D = RHS.getComplexFloatImag();
10097 APFloat &ResR = Result.getComplexFloatReal();
10098 APFloat &ResI = Result.getComplexFloatImag();
10100 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
10103 }
else if (RHSReal) {
10109 APFloat AC = A *
C;
10110 APFloat BD = B * D;
10111 APFloat AD = A * D;
10112 APFloat BC = B *
C;
10115 if (ResR.isNaN() && ResI.isNaN()) {
10116 bool Recalc =
false;
10117 if (A.isInfinity() || B.isInfinity()) {
10118 A = APFloat::copySign(
10119 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
10120 B = APFloat::copySign(
10121 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
10123 C = APFloat::copySign(APFloat(C.getSemantics()), C);
10125 D = APFloat::copySign(APFloat(D.getSemantics()), D);
10128 if (C.isInfinity() || D.isInfinity()) {
10129 C = APFloat::copySign(
10130 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
10131 D = APFloat::copySign(
10132 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
10134 A = APFloat::copySign(APFloat(A.getSemantics()), A);
10136 B = APFloat::copySign(APFloat(B.getSemantics()), B);
10139 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
10140 AD.isInfinity() || BC.isInfinity())) {
10142 A = APFloat::copySign(APFloat(A.getSemantics()), A);
10144 B = APFloat::copySign(APFloat(B.getSemantics()), B);
10146 C = APFloat::copySign(APFloat(C.getSemantics()), C);
10148 D = APFloat::copySign(APFloat(D.getSemantics()), D);
10152 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
10153 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
10158 ComplexValue LHS =
Result;
10159 Result.getComplexIntReal() =
10160 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
10161 LHS.getComplexIntImag() * RHS.getComplexIntImag());
10162 Result.getComplexIntImag() =
10163 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
10164 LHS.getComplexIntImag() * RHS.getComplexIntReal());
10168 if (Result.isComplexFloat()) {
10173 ComplexValue LHS =
Result;
10174 APFloat &A = LHS.getComplexFloatReal();
10175 APFloat &B = LHS.getComplexFloatImag();
10176 APFloat &
C = RHS.getComplexFloatReal();
10177 APFloat &D = RHS.getComplexFloatImag();
10178 APFloat &ResR = Result.getComplexFloatReal();
10179 APFloat &ResI = Result.getComplexFloatImag();
10186 B = APFloat::getZero(A.getSemantics());
10189 APFloat MaxCD = maxnum(
abs(C),
abs(D));
10190 if (MaxCD.isFinite()) {
10191 DenomLogB =
ilogb(MaxCD);
10192 C =
scalbn(C, -DenomLogB, APFloat::rmNearestTiesToEven);
10193 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
10195 APFloat Denom = C * C + D * D;
10196 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB,
10197 APFloat::rmNearestTiesToEven);
10198 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB,
10199 APFloat::rmNearestTiesToEven);
10200 if (ResR.isNaN() && ResI.isNaN()) {
10201 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
10202 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
10203 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
10204 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
10206 A = APFloat::copySign(
10207 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
10208 B = APFloat::copySign(
10209 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
10210 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
10211 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
10212 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
10213 C = APFloat::copySign(
10214 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
10215 D = APFloat::copySign(
10216 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
10217 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
10218 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
10223 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
10224 return Error(E, diag::note_expr_divide_by_zero);
10226 ComplexValue LHS =
Result;
10227 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
10228 RHS.getComplexIntImag() * RHS.getComplexIntImag();
10229 Result.getComplexIntReal() =
10230 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
10231 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
10232 Result.getComplexIntImag() =
10233 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
10234 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
10242 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
10256 if (Result.isComplexFloat()) {
10257 Result.getComplexFloatReal().changeSign();
10258 Result.getComplexFloatImag().changeSign();
10261 Result.getComplexIntReal() = -Result.getComplexIntReal();
10262 Result.getComplexIntImag() = -Result.getComplexIntImag();
10266 if (Result.isComplexFloat())
10267 Result.getComplexFloatImag().changeSign();
10269 Result.getComplexIntImag() = -Result.getComplexIntImag();
10274 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
10277 Result.makeComplexFloat();
10283 Result.makeComplexInt();
10291 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
10300 class AtomicExprEvaluator :
10301 public ExprEvaluatorBase<AtomicExprEvaluator> {
10302 const LValue *This;
10305 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &Result)
10306 : ExprEvaluatorBaseTy(Info), This(This),
Result(Result) {}
10313 bool ZeroInitialization(
const Expr *E) {
10322 bool VisitCastExpr(
const CastExpr *E) {
10325 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10326 case CK_NonAtomicToAtomic:
10337 return AtomicExprEvaluator(Info, This, Result).Visit(E);
10346 class VoidExprEvaluator
10347 :
public ExprEvaluatorBase<VoidExprEvaluator> {
10349 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
10351 bool Success(
const APValue &V,
const Expr *e) {
return true; }
10353 bool ZeroInitialization(
const Expr *E) {
return true; }
10355 bool VisitCastExpr(
const CastExpr *E) {
10358 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10365 bool VisitCallExpr(
const CallExpr *E) {
10368 return ExprEvaluatorBaseTy::VisitCallExpr(E);
10369 case Builtin::BI__assume:
10370 case Builtin::BI__builtin_assume:
10380 return VoidExprEvaluator(Info).Visit(E);
10395 LV.moveInto(Result);
10400 if (!IntExprEvaluator(Info, Result).Visit(E))
10406 LV.moveInto(Result);
10408 llvm::APFloat F(0.0);
10416 C.moveInto(Result);
10418 if (!FixedPointExprEvaluator(Info, Result).Visit(E))
return false;
10423 P.moveInto(Result);
10438 if (!Info.getLangOpts().CPlusPlus11)
10439 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
10454 }
else if (Info.getLangOpts().CPlusPlus11) {
10455 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
10458 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
10469 const Expr *E,
bool AllowNonLiteralTypes) {
10508 LV.setFrom(Info.Ctx, Result);
10523 L->getType()->isUnsignedIntegerType()));
10557 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
10576 if (!getType()->isIntegralOrEnumerationType())
10584 Result = ExprResult.Val.getInt();
10590 if (!getType()->isRealFloatingType())
10598 Result = ExprResult.Val.getFloat();
10603 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
10612 LV.moveInto(Result.Val);
10618 EvalInfo::EvaluationMode EM = EvalInfo::EM_ConstantExpression;
10619 EvalInfo Info(Ctx, Result, EM);
10620 if (!::
Evaluate(Result.Val, Info,
this))
10632 if (isRValue() && (getType()->isArrayType() || getType()->
isRecordType()) &&
10637 EStatus.
Diag = &Notes;
10639 EvalInfo InitInfo(Ctx, EStatus, VD->
isConstexpr()
10640 ? EvalInfo::EM_ConstantExpression
10641 : EvalInfo::EM_ConstantFold);
10642 InitInfo.setEvaluatingDecl(VD, Value);
10679 EvalResult.Diag =
Diag;
10682 assert(Result &&
"Could not evaluate expression");
10683 assert(EvalResult.Val.isInt() &&
"Expression did not evaluate to integer");
10685 return EvalResult.Val.getInt();
10692 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
10698 assert(Val.isLValue());
10726 IK_ICEIfUnevaluated,
10742 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
10754 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
10759 #define ABSTRACT_STMT(Node) 10760 #define STMT(Node, Base) case Expr::Node##Class: 10761 #define EXPR(Node, Base) 10762 #include "clang/AST/StmtNodes.inc" 10763 case Expr::PredefinedExprClass:
10764 case Expr::FloatingLiteralClass:
10765 case Expr::ImaginaryLiteralClass:
10766 case Expr::StringLiteralClass:
10767 case Expr::ArraySubscriptExprClass:
10768 case Expr::OMPArraySectionExprClass:
10769 case Expr::MemberExprClass:
10770 case Expr::CompoundAssignOperatorClass:
10771 case Expr::CompoundLiteralExprClass:
10772 case Expr::ExtVectorElementExprClass:
10773 case Expr::DesignatedInitExprClass:
10774 case Expr::ArrayInitLoopExprClass:
10775 case Expr::ArrayInitIndexExprClass:
10776 case Expr::NoInitExprClass:
10777 case Expr::DesignatedInitUpdateExprClass:
10778 case Expr::ImplicitValueInitExprClass:
10779 case Expr::ParenListExprClass:
10780 case Expr::VAArgExprClass:
10781 case Expr::AddrLabelExprClass:
10782 case Expr::StmtExprClass:
10783 case Expr::CXXMemberCallExprClass:
10784 case Expr::CUDAKernelCallExprClass:
10785 case Expr::CXXDynamicCastExprClass:
10786 case Expr::CXXTypeidExprClass:
10787 case Expr::CXXUuidofExprClass:
10788 case Expr::MSPropertyRefExprClass:
10789 case Expr::MSPropertySubscriptExprClass:
10790 case Expr::CXXNullPtrLiteralExprClass:
10791 case Expr::UserDefinedLiteralClass:
10792 case Expr::CXXThisExprClass:
10793 case Expr::CXXThrowExprClass:
10794 case Expr::CXXNewExprClass:
10795 case Expr::CXXDeleteExprClass:
10796 case Expr::CXXPseudoDestructorExprClass:
10797 case Expr::UnresolvedLookupExprClass:
10798 case Expr::TypoExprClass:
10799 case Expr::DependentScopeDeclRefExprClass:
10800 case Expr::CXXConstructExprClass:
10801 case Expr::CXXInheritedCtorInitExprClass:
10802 case Expr::CXXStdInitializerListExprClass:
10803 case Expr::CXXBindTemporaryExprClass:
10804 case Expr::ExprWithCleanupsClass:
10805 case Expr::CXXTemporaryObjectExprClass:
10806 case Expr::CXXUnresolvedConstructExprClass:
10807 case Expr::CXXDependentScopeMemberExprClass:
10808 case Expr::UnresolvedMemberExprClass:
10809 case Expr::ObjCStringLiteralClass:
10810 case Expr::ObjCBoxedExprClass:
10811 case Expr::ObjCArrayLiteralClass:
10812 case Expr::ObjCDictionaryLiteralClass:
10813 case Expr::ObjCEncodeExprClass:
10814 case Expr::ObjCMessageExprClass:
10815 case Expr::ObjCSelectorExprClass:
10816 case Expr::ObjCProtocolExprClass:
10817 case Expr::ObjCIvarRefExprClass:
10818 case Expr::ObjCPropertyRefExprClass:
10819 case Expr::ObjCSubscriptRefExprClass:
10820 case Expr::ObjCIsaExprClass:
10821 case Expr::ObjCAvailabilityCheckExprClass:
10822 case Expr::ShuffleVectorExprClass:
10823 case Expr::ConvertVectorExprClass:
10824 case Expr::BlockExprClass:
10826 case Expr::OpaqueValueExprClass:
10827 case Expr::PackExpansionExprClass:
10828 case Expr::SubstNonTypeTemplateParmPackExprClass:
10829 case Expr::FunctionParmPackExprClass:
10830 case Expr::AsTypeExprClass:
10831 case Expr::ObjCIndirectCopyRestoreExprClass:
10832 case Expr::MaterializeTemporaryExprClass:
10833 case Expr::PseudoObjectExprClass:
10834 case Expr::AtomicExprClass:
10835 case Expr::LambdaExprClass:
10836 case Expr::CXXFoldExprClass:
10837 case Expr::CoawaitExprClass:
10838 case Expr::DependentCoawaitExprClass:
10839 case Expr::CoyieldExprClass:
10842 case Expr::InitListExprClass: {
10848 if (cast<InitListExpr>(E)->getNumInits() == 1)
10849 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
10853 case Expr::SizeOfPackExprClass:
10854 case Expr::GNUNullExprClass:
10858 case Expr::SubstNonTypeTemplateParmExprClass:
10860 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
10862 case Expr::ParenExprClass:
10863 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
10864 case Expr::GenericSelectionExprClass:
10865 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
10866 case Expr::IntegerLiteralClass:
10867 case Expr::FixedPointLiteralClass:
10868 case Expr::CharacterLiteralClass:
10869 case Expr::ObjCBoolLiteralExprClass:
10870 case Expr::CXXBoolLiteralExprClass:
10871 case Expr::CXXScalarValueInitExprClass:
10872 case Expr::TypeTraitExprClass:
10873 case Expr::ArrayTypeTraitExprClass:
10874 case Expr::ExpressionTraitExprClass:
10875 case Expr::CXXNoexceptExprClass:
10877 case Expr::CallExprClass:
10878 case Expr::CXXOperatorCallExprClass: {
10882 const CallExpr *CE = cast<CallExpr>(E);
10887 case Expr::DeclRefExprClass: {
10888 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
10890 const ValueDecl *D = cast<DeclRefExpr>(E)->getDecl();
10896 if (isa<ParmVarDecl>(D))
10897 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
10902 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
10903 if (!Dcl->getType()->isIntegralOrEnumerationType())
10904 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
10912 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
10917 case Expr::UnaryOperatorClass: {
10944 case Expr::OffsetOfExprClass: {
10953 case Expr::UnaryExprOrTypeTraitExprClass: {
10960 case Expr::BinaryOperatorClass: {
11005 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
11008 return ICEDiag(IK_ICEIfUnevaluated, E->
getLocStart());
11009 if (REval.isSigned() && REval.isAllOnesValue()) {
11011 if (LEval.isMinSignedValue())
11012 return ICEDiag(IK_ICEIfUnevaluated, E->
getLocStart());
11020 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
11021 return ICEDiag(IK_ICEIfUnevaluated, E->
getLocStart());
11027 return Worst(LHSResult, RHSResult);
11033 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
11043 return Worst(LHSResult, RHSResult);
11048 case Expr::ImplicitCastExprClass:
11049 case Expr::CStyleCastExprClass:
11050 case Expr::CXXFunctionalCastExprClass:
11051 case Expr::CXXStaticCastExprClass:
11052 case Expr::CXXReinterpretCastExprClass:
11053 case Expr::CXXConstCastExprClass:
11054 case Expr::ObjCBridgedCastExprClass: {
11055 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
11056 if (isa<ExplicitCastExpr>(E)) {
11061 APSInt IgnoredVal(DestWidth, !DestSigned);
11066 if (FL->getValue().convertToInteger(IgnoredVal,
11067 llvm::APFloat::rmTowardZero,
11068 &Ignored) & APFloat::opInvalidOp)
11073 switch (cast<CastExpr>(E)->getCastKind()) {
11074 case CK_LValueToRValue:
11075 case CK_AtomicToNonAtomic:
11076 case CK_NonAtomicToAtomic:
11078 case CK_IntegralToBoolean:
11079 case CK_IntegralCast:
11085 case Expr::BinaryConditionalOperatorClass: {
11088 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
11090 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
11091 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
11092 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
11094 return FalseResult;
11096 case Expr::ConditionalOperatorClass: {
11104 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
11107 if (CondResult.Kind == IK_NotICE)
11113 if (TrueResult.Kind == IK_NotICE)
11115 if (FalseResult.Kind == IK_NotICE)
11116 return FalseResult;
11117 if (CondResult.Kind == IK_ICEIfUnevaluated)
11119 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
11125 return FalseResult;
11128 case Expr::CXXDefaultArgExprClass:
11129 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
11130 case Expr::CXXDefaultInitExprClass:
11131 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
11132 case Expr::ChooseExprClass: {
11133 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
11137 llvm_unreachable(
"Invalid StmtClass!");
11143 llvm::APSInt *Value,
11154 if (!Result.
isInt()) {
11159 if (Value) *Value = Result.
getInt();
11169 if (D.Kind != IK_ICE) {
11170 if (Loc) *Loc = D.Loc;
11181 if (!isIntegerConstantExpr(Ctx, Loc))
11187 if (!EvaluateAsInt(Value, Ctx, SE_AllowSideEffects))
11188 llvm_unreachable(
"ICE cannot be evaluated!");
11193 return CheckICE(
this, Ctx).Kind == IK_ICE;
11205 Status.Diag = &Diags;
11206 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
11211 if (!Diags.empty()) {
11212 IsConstExpr =
false;
11213 if (Loc) *Loc = Diags[0].first;
11214 }
else if (!IsConstExpr) {
11216 if (Loc) *Loc = getExprLoc();
11219 return IsConstExpr;
11225 const Expr *This)
const {
11227 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
11230 const LValue *ThisPtr =
nullptr;
11234 assert(MD &&
"Don't provide `this` for non-methods.");
11235 assert(!MD->isStatic() &&
"Don't provide `this` for static methods.");
11238 ThisPtr = &ThisVal;
11239 if (Info.EvalStatus.HasSideEffects)
11243 ArgVector ArgValues(Args.size());
11246 if ((*I)->isValueDependent() ||
11247 !
Evaluate(ArgValues[I - Args.begin()], Info, *I))
11249 ArgValues[I - Args.begin()] =
APValue();
11250 if (Info.EvalStatus.HasSideEffects)
11255 CallStackFrame Frame(Info, Callee->
getLocation(), Callee, ThisPtr,
11257 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
11270 Status.
Diag = &Diags;
11273 EvalInfo::EM_PotentialConstantExpression);
11282 This.set({&VIE, Info.CurrentCall->Index});
11290 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
11295 Args, FD->
getBody(), Info, Scratch,
nullptr);
11298 return Diags.empty();
11306 Status.
Diag = &Diags;
11309 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
11313 ArgVector ArgValues(0);
11317 "Failed to set up arguments for potential constant evaluation");
11318 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
11322 return Diags.empty();
11326 unsigned Type)
const {
11327 if (!getType()->isPointerType())
11331 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
bool hasArrayFiller() const
Return true if this is an array initializer and its array "filler" has been set.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, llvm::Type *BaseLVType, CharUnits BaseLVAlignment, llvm::Value *Addr)
static bool HandleConstructorCall(const Expr *E, const LValue &This, APValue *ArgValues, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
Defines the clang::ASTContext interface.
const BlockDecl * getBlockDecl() const
The null pointer literal (C++11 [lex.nullptr])
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Represents a function declaration or definition.
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
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.
const Stmt * getElse() const
static bool IsGlobalLValue(APValue::LValueBase B)
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...
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
uint64_t getValue() const
bool isMemberPointerType() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
static Opcode getOpForCompoundAssignment(Opcode Opc)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
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 operator==(CanQual< T > x, CanQual< U > y)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
CompoundStmt * getSubStmt()
const Expr * getInit(unsigned Init) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
IfStmt - This represents an if/then/else.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
An instance of this object exists for each enum constant that is defined.
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...
bool isRealFloatingType() const
Floating point categories.
SourceLocation getLocStart() const LLVM_READONLY
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
void addConst()
Add the const type qualifier to this QualType.
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isRecordType() const
void FixedPointValueToString(SmallVectorImpl< char > &Str, const llvm::APSInt &Val, unsigned Scale, unsigned Radix)
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
Decl - This represents one declaration (or definition), e.g.
__DEVICE__ long long abs(long long __n)
llvm::APFloat getValue() const
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
ConstExprUsage
Indicates how the constant expression will be used.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic, and whose semantics are that of the sole contained initializer)?
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
ParenExpr - This represents a parethesized expression, e.g.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
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)
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
The base class of the type hierarchy.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
DiagnosticsEngine & getDiagnostics() const
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsConstNonVolatile(QualType T)
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.
Represents a call to a C++ constructor.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
bool isZero() const
isZero - Test whether the quantity equals zero.
const TargetInfo & getTargetInfo() 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...
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
llvm::DenseMap< Stmt *, Stmt * > MapTy
SourceLocation getLocEnd() const LLVM_READONLY
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to...
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...
Describes the capture of a variable or of this, or of a C++1y init-capture.
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
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.
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
const Expr * getResultExpr() const
The generic selection's result expression.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin...
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
QualType getElementType() const
const Expr * getSubExpr() const
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "while" statement, if any.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Expr * getIndexExpr(unsigned Idx)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
const CXXBaseSpecifier *const * path_const_iterator
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
This file provides some common utility functions for processing Lambda related AST Constructs...
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...
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
static void negateAsSigned(APSInt &Int)
Negate an APSInt in place, converting it to a signed form if necessary, and preserving its value (by ...
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.
QualType getReturnType() const
CompoundLiteralExpr - [C99 6.5.2.5].
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
APFloat & getComplexFloatReal()
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
const T * getAs() const
Member-template getAs<specific type>'.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type...
ArrayRef< LValuePathEntry > getLValuePath() const
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const CallExpr *Call, llvm::APInt &Result)
Attempts to compute the number of bytes available at the pointer returned by a function with the allo...
bool isInvalidDecl() const
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
bool isAddrLabelDiff() const
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Expr * getExprOperand() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
static bool isAssignmentOp(Opcode Opc)
Represents a parameter to a function.
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "switch" statement, if any.
The collection of all-type qualifiers we support.
bool isVariableArrayType() const
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
bool isLValueOnePastTheEnd() const
static bool HasSameBase(const LValue &A, const LValue &B)
const ValueDecl * getMemberPointerDecl() const
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Represents a struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
unsigned getVersion() const
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size)
Get the size of the given type in char units.
Expr * getFalseExpr() const
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
FieldDecl * getField() const
For a field offsetof node, returns the 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)
field_range fields() const
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
Represents a member of a struct/union/class.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
unsigned getCallIndex() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
bool isReferenceType() const
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
unsigned getArraySize() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
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 getCharByteWidth() const
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
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...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. ...
bool isBitField() const
Determines whether this field is a bitfield.
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.
unsigned getLength() const
static bool isEqualityOp(Opcode Opc)
static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, llvm::APInt &Res)
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isElidable() const
Whether this construction is elidable.
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...
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)...
CharUnits - This is an opaque type for sizes expressed in character units.
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.
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr *> Args, const Expr *This=nullptr) const
EvaluateWithSubstitution - Evaluate an expression as if from the context of a call to the given funct...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
ArrayRef< NamedDecl * > chain() const
path_iterator path_begin()
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 isRecordType(QualType T)
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, Expr::ConstExprUsage Usage=Expr::EvaluateForCodeGen)
Check that this core constant expression value is a valid value for a constant expression.
bool isComplexFloat() const
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
bool isComplexInt() const
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
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.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
field_iterator field_begin() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
base_class_iterator bases_begin()
Helper class for OffsetOfExpr.
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)
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
bool isEquality() const
True iff the comparison category is an equality comparison.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
APSInt & getComplexIntReal()
A binding in a decomposition declaration.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
A default argument (C++ [dcl.fct.default]).
static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
bool isUnsignedFixedPointType() const
Return true if this is a fixed point type that is unsigned according to ISO/IEC JTC1 SC22 WG14 N1169...
Represents the this expression in C++.
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
Get the initialization expression that will be used.
APValue & getVectorElt(unsigned I)
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
ConditionalOperator - The ?: ternary operator.
StringRef getString() const
static GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static CharUnits One()
One - Construct a CharUnits quantity of one.
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 }.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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 ...
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool hasLValuePath() const
QualType getComputationLHSType() const
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.
APValue & getArrayFiller()
Specifies that the expression should never be value-dependent.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, APValue *&Result, const LValue *LVal)
Try to evaluate the initializer for a variable declaration.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool HasUndefinedBehavior
Whether the evaluation hit undefined behavior.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getValue() const
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool hasArrayFiller() const
capture_const_iterator captures_end() const
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type...
QualType getElementType() const
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
Allow any unmodeled side effect.
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc, unsigned Type, const LValue &LVal, CharUnits &EndOffset)
Helper for tryEvaluateBuiltinObjectSize – Given an LValue, this will determine how many bytes exist ...
bool isDefaulted() const
Whether this function is defaulted per C++0x.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
static bool HandleConversionToBool(const APValue &Val, bool &Result)
void EvaluateForOverflow(const ASTContext &Ctx) const
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
unsigned getPackLength() const
Retrieve the length of the parameter pack.
const T * castAs() const
Member-template castAs<specific type>.
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
const Stmt * getThen() const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
unsigned getNumInits() const
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Expr * getSubExpr() const
Get the initializer to use for each array element.
const Expr * getCallee() const
bool isNullPtrType() const
field_iterator field_end() const
QualType getArgumentType() const
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, Expr::ConstExprUsage Usage)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
DeclContext * getDeclContext()
uint32_t getCodeUnit(size_t i) const
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
bool isAnyComplexType() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
TypeSourceInfo * getTypeSourceInfo() 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)
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
Defines the clang::TypeLoc interface and its subclasses.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
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.
Kind getKind() const
Determine what kind of offsetof node this is.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
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...
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.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
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?
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.
bool isNullPointer() const
Represents a reference to a non-type template parameter that has been substituted with a template arg...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
const OffsetOfNode & getComponent(unsigned Idx) const
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
APSInt & getComplexIntImag()
The result type of a method or function.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const Expr * getSubExpr() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Stmt *const * const_body_iterator
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).
const FieldDecl * getUnionField() const
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
DoStmt - This represents a 'do/while' stmt.
bool isSignedFixedPointType() const
Return true if this is a fixed point type that is signed according to ISO/IEC JTC1 SC22 WG14 N1169...
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
bool isVoidPointerType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
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.
RecordDecl * getDecl() const
static APValue & createTemporary(const KeyTy *Key, bool IsLifetimeExtended, LValue &LV, CallStackFrame &Frame)
A helper function to create a temporary and set an LValue.
APValue & getStructBase(unsigned i)
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
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)
APValue & getArrayInitializedElt(unsigned I)
A field in a dependent type, known only by its name.
QualType getCanonicalType() const
Represents a call to an inherited base class constructor from an inheriting constructor.
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
unsigned path_size() const
const LValueBase getLValueBase() const
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
bool isOrdered() const
True iff the comparison category is a relational comparison.
bool isGlobalLValue() const
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant...
Encodes a location in the source.
LangAS getAddressSpace() const
Return the address space of this type.
Expr * getSubExpr() const
CastKind getCastKind() const
const SwitchCase * getSwitchCaseList() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
APValue & getUnionValue()
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocStart() const LLVM_READONLY
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
QualType getElementType() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
static bool IsLiteralLValue(const LValue &Value)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
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.
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.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isMemberPointer() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
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 EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
UnaryExprOrTypeTrait getKind() const
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
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...
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
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 isVectorType() 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 isArgumentType() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
bool isMemberPointerToDerivedMember() const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const Expr * getInitializer() const
CompoundAssignOperator - For compound assignments (e.g.
CXXConstructorDecl * getConstructor() const
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.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "if" statement, if any.
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
Dataflow Directional Tag Classes.
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...
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
[C99 6.4.2.2] - A predefined identifier such as func.
EvalResult is a struct with detailed info about an evaluated expression.
static bool isZeroSized(const LValue &Value)
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
Represents a field injected from an anonymous union/struct into the parent scope. ...
AccessSpecifier getAccess() const
const Expr * getInit() const
A decomposition declaration.
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
StmtClass getStmtClass() const
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...
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
const Expr * getExpr() const
bool isBooleanType() const
unsigned getArrayInitializedElts() const
SourceLocation getLocStart() const LLVM_READONLY
A pointer to member type per C++ 8.3.3 - Pointers to members.
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...
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base, LValue &Result)
Attempts to evaluate the given LValueBase as the result of a call to a function with the alloc_size a...
body_iterator body_begin()
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isPtrMemOp() const
predicates to categorize the respective opcodes.
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).
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
const Stmt * getBody() const
llvm::APInt getValue() const
LabelDecl * getLabel() const
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
SwitchStmt - This represents a 'switch' stmt.
bool isStringLiteralInit() const
unsigned getIntWidth(QualType T) const
bool isIncompleteArrayType() const
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
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.
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6.7.5p3.
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, const ASTContext &Ctx) const
Evaluate an expression that is required to be a constant expression.
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 getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
ObjCEncodeExpr, used for @encode in Objective-C.
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T)
An implicit indirection through a C++ base class, when the field found is in a base class...
const llvm::APInt & getSize() const
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.
bool isAtomicType() const
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
bool isFunctionType() const
Expr * getReplacement() const
static bool isAdditiveOp(Opcode Opc)
Expr * getArg(unsigned Arg)
Return the specified argument.
Base for LValueReferenceType and RValueReferenceType.
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
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
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...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
DeclStmt * getRangeStmt()
static bool isIncrementOp(Opcode Op)
unsigned getConstexprBacktraceLimit() const
Retrieve the maximum number of constexpr evaluation notes to emit along with a given diagnostic...
static bool EvaluateArgs(ArrayRef< const Expr *> Args, ArgVector &ArgValues, EvalInfo &Info)
EvaluateArgs - Evaluate the arguments to a function call.
A use of a default initializer in a constructor or in aggregate initialization.
A template argument list.
const SwitchCase * getNextSwitchCase() const
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
ValueKind getKind() const
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 ...
ActionResult< Expr * > ExprResult
bool hasUnaligned() const
APFloat & getComplexFloatImag()
Represents a C++ struct/union/class.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
Expr * getTrueExpr() const
Represents a loop initializing the elements of an array.
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, uint64_t &Size)
Tries to evaluate the __builtin_object_size for E.
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...
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
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.
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
base_class_iterator bases_end()
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
unsigned kind
All of the diagnostics that can be emitted by the frontend.
This class is used for builtin types like 'int'.
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
bool isComplexIntegerType() const
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...
__DEVICE__ int max(int __a, int __b)
unsigned getNumElements() const
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
unsigned getNumComponents() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
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...
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression...
A reference to a declared variable, function, enum, etc.
Designator - A designator in a C99 designated initializer.
bool isPointerType() const
__DEVICE__ int min(int __a, int __b)
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 EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static void expandStringLiteral(EvalInfo &Info, const Expr *Lit, APValue &Result)
capture_const_iterator captures_begin() const
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
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()
unsigned getNumArgs() const
bool isFloatingType() const
const Expr * getCond() const
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).
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Automatic storage duration (most local variables).
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr...
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
DeclStmt * getBeginStmt()
const Expr * getCond() const
bool isFunctionPointerType() const
static bool isComparisonOp(Opcode Opc)
const LangOptions & getLangOpts() const
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.
Defines enum values for all the target-independent builtin functions.
Declaration of a template function.
Represents an implicitly-generated value initialization of an object of a given type.
static void describeCall(CallStackFrame *Frame, raw_ostream &Out)
Produce a string describing the given constexpr call.
SourceLocation getLocation() const
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.
QualType getType() const
Return the type wrapped by this type source info.
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor...
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the the correct result kind for this category.
CharUnits & getLValueOffset()
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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 getType() const
Retrieves the type of the base class.
unsigned getVectorLength() const