58#include "llvm/ADT/APFixedPoint.h"
59#include "llvm/ADT/Sequence.h"
60#include "llvm/ADT/SmallBitVector.h"
61#include "llvm/ADT/StringExtras.h"
62#include "llvm/Support/Casting.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/SaveAndRestore.h"
65#include "llvm/Support/SipHash.h"
66#include "llvm/Support/TimeProfiler.h"
67#include "llvm/Support/raw_ostream.h"
73#define DEBUG_TYPE "exprconstant"
76using llvm::APFixedPoint;
80using llvm::FixedPointSemantics;
87 using SourceLocExprScopeGuard =
122 static const CallExpr *tryUnwrapAllocSizeCall(
const Expr *E) {
130 if (
const auto *FE = dyn_cast<FullExpr>(E))
133 if (
const auto *Cast = dyn_cast<CastExpr>(E))
134 E = Cast->getSubExpr()->IgnoreParens();
136 if (
const auto *CE = dyn_cast<CallExpr>(E))
137 return CE->getCalleeAllocSizeAttr() ? CE :
nullptr;
144 const auto *E =
Base.dyn_cast<
const Expr *>();
145 return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
153 case ConstantExprKind::Normal:
154 case ConstantExprKind::ClassTemplateArgument:
155 case ConstantExprKind::ImmediateInvocation:
160 case ConstantExprKind::NonClassTemplateArgument:
163 llvm_unreachable(
"unknown ConstantExprKind");
168 case ConstantExprKind::Normal:
169 case ConstantExprKind::ImmediateInvocation:
172 case ConstantExprKind::ClassTemplateArgument:
173 case ConstantExprKind::NonClassTemplateArgument:
176 llvm_unreachable(
"unknown ConstantExprKind");
182 static const uint64_t AssumedSizeForUnsizedArray =
183 std::numeric_limits<uint64_t>::max() / 2;
193 bool &FirstEntryIsUnsizedArray) {
196 assert(!isBaseAnAllocSizeCall(
Base) &&
197 "Unsized arrays shouldn't appear here");
198 unsigned MostDerivedLength = 0;
203 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
207 MostDerivedLength = I + 1;
210 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
211 ArraySize = CAT->getZExtSize();
213 assert(I == 0 &&
"unexpected unsized array designator");
214 FirstEntryIsUnsizedArray =
true;
215 ArraySize = AssumedSizeForUnsizedArray;
221 MostDerivedLength = I + 1;
224 Type = VT->getElementType();
225 ArraySize = VT->getNumElements();
226 MostDerivedLength = I + 1;
228 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
229 Type = FD->getType();
231 MostDerivedLength = I + 1;
239 return MostDerivedLength;
243 struct SubobjectDesignator {
247 LLVM_PREFERRED_TYPE(
bool)
251 LLVM_PREFERRED_TYPE(
bool)
252 unsigned IsOnePastTheEnd : 1;
255 LLVM_PREFERRED_TYPE(
bool)
256 unsigned FirstEntryIsAnUnsizedArray : 1;
259 LLVM_PREFERRED_TYPE(
bool)
260 unsigned MostDerivedIsArrayElement : 1;
264 unsigned MostDerivedPathLength : 28;
273 uint64_t MostDerivedArraySize;
282 SubobjectDesignator() :
Invalid(
true) {}
284 explicit SubobjectDesignator(
QualType T)
285 :
Invalid(
false), IsOnePastTheEnd(
false),
286 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
287 MostDerivedPathLength(0), MostDerivedArraySize(0),
291 :
Invalid(!
V.isLValue() || !
V.hasLValuePath()), IsOnePastTheEnd(
false),
292 FirstEntryIsAnUnsizedArray(
false), MostDerivedIsArrayElement(
false),
293 MostDerivedPathLength(0), MostDerivedArraySize(0) {
294 assert(
V.isLValue() &&
"Non-LValue used to make an LValue designator?");
296 IsOnePastTheEnd =
V.isLValueOnePastTheEnd();
297 llvm::append_range(Entries,
V.getLValuePath());
298 if (
V.getLValueBase()) {
299 bool IsArray =
false;
300 bool FirstIsUnsizedArray =
false;
301 MostDerivedPathLength = findMostDerivedSubobject(
302 Ctx,
V.getLValueBase(),
V.getLValuePath(), MostDerivedArraySize,
303 MostDerivedType, IsArray, FirstIsUnsizedArray);
304 MostDerivedIsArrayElement = IsArray;
305 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
311 unsigned NewLength) {
315 assert(
Base &&
"cannot truncate path for null pointer");
316 assert(NewLength <= Entries.size() &&
"not a truncation");
318 if (NewLength == Entries.size())
320 Entries.resize(NewLength);
322 bool IsArray =
false;
323 bool FirstIsUnsizedArray =
false;
324 MostDerivedPathLength = findMostDerivedSubobject(
325 Ctx,
Base, Entries, MostDerivedArraySize, MostDerivedType, IsArray,
326 FirstIsUnsizedArray);
327 MostDerivedIsArrayElement = IsArray;
328 FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
338 bool isMostDerivedAnUnsizedArray()
const {
339 assert(!
Invalid &&
"Calling this makes no sense on invalid designators");
340 return Entries.size() == 1 && FirstEntryIsAnUnsizedArray;
345 uint64_t getMostDerivedArraySize()
const {
346 assert(!isMostDerivedAnUnsizedArray() &&
"Unsized array has no size");
347 return MostDerivedArraySize;
351 bool isOnePastTheEnd()
const {
355 if (!isMostDerivedAnUnsizedArray() && MostDerivedIsArrayElement &&
356 Entries[MostDerivedPathLength - 1].getAsArrayIndex() ==
357 MostDerivedArraySize)
365 std::pair<uint64_t, uint64_t> validIndexAdjustments() {
366 if (
Invalid || isMostDerivedAnUnsizedArray())
372 bool IsArray = MostDerivedPathLength == Entries.size() &&
373 MostDerivedIsArrayElement;
374 uint64_t ArrayIndex = IsArray ? Entries.back().getAsArrayIndex()
375 : (uint64_t)IsOnePastTheEnd;
377 IsArray ? getMostDerivedArraySize() : (uint64_t)1;
378 return {ArrayIndex, ArraySize - ArrayIndex};
382 bool isValidSubobject()
const {
385 return !isOnePastTheEnd();
393 assert(!
Invalid &&
"invalid designator has no subobject type");
394 return MostDerivedPathLength == Entries.size()
405 MostDerivedIsArrayElement =
true;
407 MostDerivedPathLength = Entries.size();
411 void addUnsizedArrayUnchecked(
QualType ElemTy) {
414 MostDerivedType = ElemTy;
415 MostDerivedIsArrayElement =
true;
419 MostDerivedArraySize = AssumedSizeForUnsizedArray;
420 MostDerivedPathLength = Entries.size();
424 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
428 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
429 MostDerivedType = FD->getType();
430 MostDerivedIsArrayElement =
false;
431 MostDerivedArraySize = 0;
432 MostDerivedPathLength = Entries.size();
436 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
441 MostDerivedType = EltTy;
442 MostDerivedIsArrayElement =
true;
443 MostDerivedArraySize = 2;
444 MostDerivedPathLength = Entries.size();
447 void addVectorElementUnchecked(
QualType EltTy, uint64_t Size,
450 MostDerivedType = EltTy;
451 MostDerivedPathLength = Entries.size();
452 MostDerivedArraySize = 0;
453 MostDerivedIsArrayElement =
false;
456 void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E);
457 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
460 void adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
const LValue &LV);
464 enum class ScopeKind {
472 CallRef() : OrigCallee(), CallIndex(0), Version() {}
473 CallRef(
const FunctionDecl *Callee,
unsigned CallIndex,
unsigned Version)
474 : OrigCallee(Callee), CallIndex(CallIndex), Version(Version) {}
476 explicit operator bool()
const {
return OrigCallee; }
502 CallStackFrame *Caller;
524 typedef std::pair<const void *, unsigned> MapKeyTy;
525 typedef std::map<MapKeyTy, APValue>
MapTy;
537 unsigned CurTempVersion = TempVersionStack.back();
539 unsigned getTempVersion()
const {
return TempVersionStack.back(); }
541 void pushTempVersion() {
542 TempVersionStack.push_back(++CurTempVersion);
545 void popTempVersion() {
546 TempVersionStack.pop_back();
550 return {Callee, Index, ++CurTempVersion};
561 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
562 FieldDecl *LambdaThisCaptureField =
nullptr;
564 CallStackFrame(EvalInfo &Info,
SourceRange CallRange,
570 APValue *getTemporary(
const void *Key,
unsigned Version) {
571 MapKeyTy KV(Key, Version);
572 auto LB = Temporaries.lower_bound(KV);
573 if (LB != Temporaries.end() && LB->first == KV)
579 APValue *getCurrentTemporary(
const void *Key) {
580 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
581 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
582 return &std::prev(UB)->second;
587 unsigned getCurrentTemporaryVersion(
const void *Key)
const {
588 auto UB = Temporaries.upper_bound(MapKeyTy(Key,
UINT_MAX));
589 if (UB != Temporaries.begin() && std::prev(UB)->first.first == Key)
590 return std::prev(UB)->first.second;
598 template<
typename KeyT>
600 ScopeKind
Scope, LValue &LV);
605 void describe(llvm::raw_ostream &OS)
const override;
607 Frame *getCaller()
const override {
return Caller; }
608 SourceRange getCallRange()
const override {
return CallRange; }
611 bool isStdFunction()
const {
612 for (
const DeclContext *DC = Callee; DC; DC = DC->getParent())
613 if (DC->isStdNamespace())
620 bool CanEvalMSConstexpr =
false;
628 class ThisOverrideRAII {
630 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
631 : Frame(Frame), OldThis(Frame.This) {
633 Frame.This = NewThis;
635 ~ThisOverrideRAII() {
636 Frame.This = OldThis;
639 CallStackFrame &Frame;
640 const LValue *OldThis;
645 class ExprTimeTraceScope {
647 ExprTimeTraceScope(
const Expr *E,
const ASTContext &Ctx, StringRef Name)
648 : TimeScope(Name, [E, &Ctx] {
653 llvm::TimeTraceScope TimeScope;
658 struct MSConstexprContextRAII {
659 CallStackFrame &Frame;
661 explicit MSConstexprContextRAII(CallStackFrame &Frame,
bool Value)
662 : Frame(Frame), OldValue(Frame.CanEvalMSConstexpr) {
663 Frame.CanEvalMSConstexpr =
Value;
666 ~MSConstexprContextRAII() { Frame.CanEvalMSConstexpr = OldValue; }
679 llvm::PointerIntPair<APValue*, 2, ScopeKind> Value;
680 APValue::LValueBase Base;
684 Cleanup(
APValue *Val, APValue::LValueBase Base, QualType T,
686 : Value(Val, Scope), Base(Base), T(T) {}
690 bool isDestroyedAtEndOf(ScopeKind K)
const {
691 return (
int)Value.getInt() >= (
int)K;
693 bool endLifetime(EvalInfo &Info,
bool RunDestructors) {
694 if (RunDestructors) {
696 if (
const ValueDecl *VD = Base.dyn_cast<
const ValueDecl*>())
697 Loc = VD->getLocation();
698 else if (
const Expr *E = Base.dyn_cast<
const Expr*>())
699 Loc = E->getExprLoc();
702 *Value.getPointer() =
APValue();
706 bool hasSideEffect() {
707 return T.isDestructedType();
712 struct ObjectUnderConstruction {
713 APValue::LValueBase Base;
714 ArrayRef<APValue::LValuePathEntry> Path;
715 friend bool operator==(
const ObjectUnderConstruction &LHS,
716 const ObjectUnderConstruction &RHS) {
717 return LHS.Base == RHS.Base && LHS.Path == RHS.Path;
719 friend llvm::hash_code
hash_value(
const ObjectUnderConstruction &Obj) {
720 return llvm::hash_combine(Obj.Base, Obj.Path);
723 enum class ConstructionPhase {
734template<>
struct DenseMapInfo<ObjectUnderConstruction> {
735 using Base = DenseMapInfo<APValue::LValueBase>;
739 static bool isEqual(
const ObjectUnderConstruction &LHS,
740 const ObjectUnderConstruction &RHS) {
754 const Expr *AllocExpr =
nullptr;
765 if (
auto *NE = dyn_cast<CXXNewExpr>(AllocExpr))
766 return NE->isArray() ? ArrayNew : New;
772 struct DynAllocOrder {
773 bool operator()(DynamicAllocLValue L, DynamicAllocLValue R)
const {
795 CallStackFrame *CurrentCall;
798 unsigned CallStackDepth;
801 unsigned NextCallIndex;
810 bool EnableNewConstInterp;
814 CallStackFrame BottomFrame;
818 llvm::SmallVector<Cleanup, 16> CleanupStack;
822 APValue::LValueBase EvaluatingDecl;
824 enum class EvaluatingDeclKind {
831 EvaluatingDeclKind IsEvaluatingDecl = EvaluatingDeclKind::None;
840 SmallVector<const Stmt *> BreakContinueStack;
843 llvm::DenseMap<ObjectUnderConstruction, ConstructionPhase>
844 ObjectsUnderConstruction;
849 std::map<DynamicAllocLValue, DynAlloc, DynAllocOrder> HeapAllocs;
852 unsigned NumHeapAllocs = 0;
854 struct EvaluatingConstructorRAII {
856 ObjectUnderConstruction Object;
858 EvaluatingConstructorRAII(EvalInfo &EI, ObjectUnderConstruction Object,
860 : EI(EI), Object(Object) {
862 EI.ObjectsUnderConstruction
863 .insert({Object, HasBases ? ConstructionPhase::Bases
864 : ConstructionPhase::AfterBases})
867 void finishedConstructingBases() {
868 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterBases;
870 void finishedConstructingFields() {
871 EI.ObjectsUnderConstruction[Object] = ConstructionPhase::AfterFields;
873 ~EvaluatingConstructorRAII() {
874 if (DidInsert) EI.ObjectsUnderConstruction.erase(Object);
878 struct EvaluatingDestructorRAII {
880 ObjectUnderConstruction Object;
882 EvaluatingDestructorRAII(EvalInfo &EI, ObjectUnderConstruction Object)
883 : EI(EI), Object(Object) {
884 DidInsert = EI.ObjectsUnderConstruction
885 .insert({Object, ConstructionPhase::Destroying})
888 void startedDestroyingBases() {
889 EI.ObjectsUnderConstruction[Object] =
890 ConstructionPhase::DestroyingBases;
892 ~EvaluatingDestructorRAII() {
894 EI.ObjectsUnderConstruction.erase(Object);
899 isEvaluatingCtorDtor(APValue::LValueBase Base,
900 ArrayRef<APValue::LValuePathEntry> Path) {
901 return ObjectsUnderConstruction.lookup({
Base, Path});
906 unsigned SpeculativeEvaluationDepth = 0;
912 EvalInfo(
const ASTContext &
C, Expr::EvalStatus &S,
EvaluationMode Mode)
913 : State(const_cast<ASTContext &>(
C), S), CurrentCall(
nullptr),
914 CallStackDepth(0), NextCallIndex(1),
915 StepsLeft(
C.getLangOpts().ConstexprStepLimit),
916 EnableNewConstInterp(
C.getLangOpts().EnableNewConstInterp),
917 BottomFrame(*this, SourceLocation(),
nullptr,
920 EvaluatingDecl((const ValueDecl *)
nullptr),
929 void setEvaluatingDecl(APValue::LValueBase Base,
APValue &
Value,
930 EvaluatingDeclKind EDK = EvaluatingDeclKind::Ctor) {
931 EvaluatingDecl =
Base;
932 IsEvaluatingDecl = EDK;
933 EvaluatingDeclValue = &
Value;
936 bool CheckCallLimit(SourceLocation Loc) {
939 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
941 if (NextCallIndex == 0) {
943 FFDiag(Loc, diag::note_constexpr_call_limit_exceeded);
946 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
948 FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded)
949 << getLangOpts().ConstexprCallDepth;
954 uint64_t ElemCount,
bool Diag) {
960 ElemCount >
uint64_t(std::numeric_limits<unsigned>::max())) {
962 FFDiag(Loc, diag::note_constexpr_new_too_large) << ElemCount;
971 uint64_t Limit = getLangOpts().ConstexprStepLimit;
972 if (Limit != 0 && ElemCount > Limit) {
974 FFDiag(Loc, diag::note_constexpr_new_exceeds_limits)
975 << ElemCount << Limit;
981 std::pair<CallStackFrame *, unsigned>
982 getCallFrameAndDepth(
unsigned CallIndex) {
983 assert(CallIndex &&
"no call index in getCallFrameAndDepth");
986 unsigned Depth = CallStackDepth;
987 CallStackFrame *Frame = CurrentCall;
988 while (Frame->Index > CallIndex) {
989 Frame = Frame->Caller;
992 if (Frame->Index == CallIndex)
993 return {Frame, Depth};
997 bool nextStep(
const Stmt *S) {
998 if (getLangOpts().ConstexprStepLimit == 0)
1002 FFDiag(S->
getBeginLoc(), diag::note_constexpr_step_limit_exceeded);
1009 APValue *createHeapAlloc(
const Expr *E, QualType T, LValue &LV);
1011 std::optional<DynAlloc *> lookupDynamicAlloc(DynamicAllocLValue DA) {
1012 std::optional<DynAlloc *>
Result;
1013 auto It = HeapAllocs.find(DA);
1014 if (It != HeapAllocs.end())
1020 APValue *getParamSlot(CallRef
Call,
const ParmVarDecl *PVD) {
1021 CallStackFrame *Frame = getCallFrameAndDepth(
Call.CallIndex).first;
1022 return Frame ? Frame->getTemporary(
Call.getOrigParam(PVD),
Call.Version)
1027 struct StdAllocatorCaller {
1028 unsigned FrameIndex;
1031 explicit operator bool()
const {
return FrameIndex != 0; };
1034 StdAllocatorCaller getStdAllocatorCaller(StringRef FnName)
const {
1035 for (
const CallStackFrame *
Call = CurrentCall;
Call->Caller !=
nullptr;
1037 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
Call->Callee);
1040 const IdentifierInfo *FnII = MD->getIdentifier();
1041 if (!FnII || !FnII->
isStr(FnName))
1045 dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1049 const IdentifierInfo *ClassII = CTSD->getIdentifier();
1050 const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
1051 if (CTSD->isInStdNamespace() && ClassII &&
1052 ClassII->
isStr(
"allocator") && TAL.
size() >= 1 &&
1054 return {
Call->Index, TAL[0].getAsType(),
Call->CallExpr};
1060 void performLifetimeExtension() {
1062 llvm::erase_if(CleanupStack, [](Cleanup &
C) {
1063 return !
C.isDestroyedAtEndOf(ScopeKind::FullExpression);
1070 bool discardCleanups() {
1071 for (Cleanup &
C : CleanupStack) {
1072 if (
C.hasSideEffect() && !noteSideEffect()) {
1073 CleanupStack.clear();
1077 CleanupStack.clear();
1082 const interp::Frame *getCurrentFrame()
override {
return CurrentCall; }
1084 unsigned getCallStackDepth()
override {
return CallStackDepth; }
1085 bool stepsLeft()
const override {
return StepsLeft > 0; }
1098 [[nodiscard]]
bool noteFailure() {
1106 bool KeepGoing = keepEvaluatingAfterFailure();
1107 EvalStatus.HasSideEffects |= KeepGoing;
1111 class ArrayInitLoopIndex {
1116 ArrayInitLoopIndex(EvalInfo &Info)
1117 : Info(Info), OuterIndex(Info.ArrayInitIndex) {
1118 Info.ArrayInitIndex = 0;
1120 ~ArrayInitLoopIndex() { Info.ArrayInitIndex = OuterIndex; }
1122 operator uint64_t&() {
return Info.ArrayInitIndex; }
1127 struct FoldConstant {
1130 bool HadNoPriorDiags;
1133 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
1136 HadNoPriorDiags(Info.EvalStatus.
Diag &&
1137 Info.EvalStatus.
Diag->empty() &&
1138 !Info.EvalStatus.HasSideEffects),
1139 OldMode(Info.EvalMode) {
1141 Info.EvalMode = EvaluationMode::ConstantFold;
1143 void keepDiagnostics() { Enabled =
false; }
1145 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
1146 !Info.EvalStatus.HasSideEffects) {
1147 Info.EvalStatus.Diag->clear();
1148 Info.EvalStatus.DiagEmitted =
false;
1150 Info.EvalMode = OldMode;
1156 struct IgnoreSideEffectsRAII {
1159 explicit IgnoreSideEffectsRAII(EvalInfo &Info)
1160 : Info(Info), OldMode(Info.EvalMode) {
1161 Info.EvalMode = EvaluationMode::IgnoreSideEffects;
1164 ~IgnoreSideEffectsRAII() { Info.EvalMode = OldMode; }
1169 class SpeculativeEvaluationRAII {
1170 EvalInfo *Info =
nullptr;
1171 Expr::EvalStatus OldStatus;
1172 unsigned OldSpeculativeEvaluationDepth = 0;
1174 void moveFromAndCancel(SpeculativeEvaluationRAII &&
Other) {
1176 OldStatus =
Other.OldStatus;
1177 OldSpeculativeEvaluationDepth =
Other.OldSpeculativeEvaluationDepth;
1178 Other.Info =
nullptr;
1181 void maybeRestoreState() {
1185 Info->EvalStatus = OldStatus;
1186 Info->SpeculativeEvaluationDepth = OldSpeculativeEvaluationDepth;
1190 SpeculativeEvaluationRAII() =
default;
1192 SpeculativeEvaluationRAII(
1193 EvalInfo &Info, SmallVectorImpl<PartialDiagnosticAt> *NewDiag =
nullptr)
1194 : Info(&Info), OldStatus(Info.EvalStatus),
1195 OldSpeculativeEvaluationDepth(Info.SpeculativeEvaluationDepth) {
1196 Info.EvalStatus.Diag = NewDiag;
1197 Info.SpeculativeEvaluationDepth = Info.CallStackDepth + 1;
1200 SpeculativeEvaluationRAII(
const SpeculativeEvaluationRAII &
Other) =
delete;
1201 SpeculativeEvaluationRAII(SpeculativeEvaluationRAII &&
Other) {
1202 moveFromAndCancel(std::move(
Other));
1205 SpeculativeEvaluationRAII &operator=(SpeculativeEvaluationRAII &&
Other) {
1206 maybeRestoreState();
1207 moveFromAndCancel(std::move(
Other));
1211 ~SpeculativeEvaluationRAII() { maybeRestoreState(); }
1216 template<ScopeKind Kind>
1219 unsigned OldStackSize;
1221 ScopeRAII(EvalInfo &Info)
1222 : Info(Info), OldStackSize(Info.CleanupStack.size()) {
1225 Info.CurrentCall->pushTempVersion();
1227 bool destroy(
bool RunDestructors =
true) {
1228 bool OK =
cleanup(Info, RunDestructors, OldStackSize);
1229 OldStackSize = std::numeric_limits<unsigned>::max();
1233 if (OldStackSize != std::numeric_limits<unsigned>::max())
1237 Info.CurrentCall->popTempVersion();
1240 static bool cleanup(EvalInfo &Info,
bool RunDestructors,
1241 unsigned OldStackSize) {
1242 assert(OldStackSize <= Info.CleanupStack.size() &&
1243 "running cleanups out of order?");
1248 for (
unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
1249 if (Info.CleanupStack[I - 1].isDestroyedAtEndOf(Kind)) {
1250 if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) {
1258 auto NewEnd = Info.CleanupStack.begin() + OldStackSize;
1259 if (Kind != ScopeKind::Block)
1261 std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &
C) {
1262 return C.isDestroyedAtEndOf(Kind);
1264 Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
1268 typedef ScopeRAII<ScopeKind::Block> BlockScopeRAII;
1269 typedef ScopeRAII<ScopeKind::FullExpression> FullExpressionRAII;
1270 typedef ScopeRAII<ScopeKind::Call> CallScopeRAII;
1273bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
1277 if (isOnePastTheEnd()) {
1278 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
1289void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
1291 Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
1296void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
1301 if (MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement)
1302 Info.CCEDiag(E, diag::note_constexpr_array_index)
1304 <<
static_cast<unsigned>(getMostDerivedArraySize());
1306 Info.CCEDiag(E, diag::note_constexpr_array_index)
1311CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
1312 const FunctionDecl *Callee,
const LValue *This,
1313 const Expr *CallExpr, CallRef Call)
1315 CallExpr(CallExpr),
Arguments(Call), CallRange(CallRange),
1316 Index(Info.NextCallIndex++) {
1317 Info.CurrentCall =
this;
1318 ++Info.CallStackDepth;
1321CallStackFrame::~CallStackFrame() {
1322 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
1323 --Info.CallStackDepth;
1324 Info.CurrentCall = Caller;
1349 llvm_unreachable(
"unknown access kind");
1386 llvm_unreachable(
"unknown access kind");
1390 struct ComplexValue {
1398 ComplexValue() : FloatReal(
APFloat::Bogus()), FloatImag(
APFloat::Bogus()) {}
1400 void makeComplexFloat() { IsInt =
false; }
1401 bool isComplexFloat()
const {
return !IsInt; }
1402 APFloat &getComplexFloatReal() {
return FloatReal; }
1403 APFloat &getComplexFloatImag() {
return FloatImag; }
1405 void makeComplexInt() { IsInt =
true; }
1406 bool isComplexInt()
const {
return IsInt; }
1407 APSInt &getComplexIntReal() {
return IntReal; }
1408 APSInt &getComplexIntImag() {
return IntImag; }
1410 void moveInto(
APValue &v)
const {
1411 if (isComplexFloat())
1412 v =
APValue(FloatReal, FloatImag);
1414 v =
APValue(IntReal, IntImag);
1416 void setFrom(
const APValue &v) {
1431 APValue::LValueBase
Base;
1433 SubobjectDesignator Designator;
1435 bool InvalidBase : 1;
1437 bool AllowConstexprUnknown =
false;
1439 const APValue::LValueBase getLValueBase()
const {
return Base; }
1440 bool allowConstexprUnknown()
const {
return AllowConstexprUnknown; }
1441 CharUnits &getLValueOffset() {
return Offset; }
1442 const CharUnits &getLValueOffset()
const {
return Offset; }
1443 SubobjectDesignator &getLValueDesignator() {
return Designator; }
1444 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
1445 bool isNullPointer()
const {
return IsNullPtr;}
1447 unsigned getLValueCallIndex()
const {
return Base.getCallIndex(); }
1448 unsigned getLValueVersion()
const {
return Base.getVersion(); }
1451 if (Designator.Invalid)
1452 V =
APValue(Base, Offset, APValue::NoLValuePath(), IsNullPtr);
1454 assert(!InvalidBase &&
"APValues can't handle invalid LValue bases");
1455 V =
APValue(Base, Offset, Designator.Entries,
1456 Designator.IsOnePastTheEnd, IsNullPtr);
1458 if (AllowConstexprUnknown)
1459 V.setConstexprUnknown();
1461 void setFrom(
const ASTContext &Ctx,
const APValue &
V) {
1462 assert(
V.isLValue() &&
"Setting LValue from a non-LValue?");
1463 Base =
V.getLValueBase();
1464 Offset =
V.getLValueOffset();
1465 InvalidBase =
false;
1466 Designator = SubobjectDesignator(Ctx,
V);
1467 IsNullPtr =
V.isNullPointer();
1468 AllowConstexprUnknown =
V.allowConstexprUnknown();
1471 void set(APValue::LValueBase B,
bool BInvalid =
false) {
1475 const auto *E = B.
get<
const Expr *>();
1477 "Unexpected type of invalid base");
1483 InvalidBase = BInvalid;
1484 Designator = SubobjectDesignator(
getType(B));
1486 AllowConstexprUnknown =
false;
1489 void setNull(ASTContext &Ctx, QualType PointerTy) {
1490 Base = (
const ValueDecl *)
nullptr;
1493 InvalidBase =
false;
1496 AllowConstexprUnknown =
false;
1499 void setInvalid(APValue::LValueBase B,
unsigned I = 0) {
1503 std::string
toString(ASTContext &Ctx, QualType T)
const {
1505 moveInto(Printable);
1512 template <
typename GenDiagType>
1513 bool checkNullPointerDiagnosingWith(
const GenDiagType &GenDiag) {
1514 if (Designator.Invalid)
1518 Designator.setInvalid();
1525 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
1527 return checkNullPointerDiagnosingWith([&Info, E, CSK] {
1528 Info.CCEDiag(E, diag::note_constexpr_null_subobject) << CSK;
1532 bool checkNullPointerForFoldAccess(EvalInfo &Info,
const Expr *E,
1534 return checkNullPointerDiagnosingWith([&Info, E, AK] {
1535 if (AK == AccessKinds::AK_Dereference)
1536 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
1538 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
1546 Designator.checkSubobject(Info, E, CSK);
1549 void addDecl(EvalInfo &Info,
const Expr *E,
1550 const Decl *D,
bool Virtual =
false) {
1552 Designator.addDeclUnchecked(D,
Virtual);
1554 void addUnsizedArray(EvalInfo &Info,
const Expr *E, QualType ElemTy) {
1555 if (!Designator.Entries.empty()) {
1556 Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
1557 Designator.setInvalid();
1561 assert(!Base ||
getType(Base).getNonReferenceType()->isPointerType() ||
1562 getType(Base).getNonReferenceType()->isArrayType());
1563 Designator.FirstEntryIsAnUnsizedArray =
true;
1564 Designator.addUnsizedArrayUnchecked(ElemTy);
1567 void addArray(EvalInfo &Info,
const Expr *E,
const ConstantArrayType *CAT) {
1569 Designator.addArrayUnchecked(CAT);
1571 void addComplex(EvalInfo &Info,
const Expr *E, QualType EltTy,
bool Imag) {
1573 Designator.addComplexUnchecked(EltTy, Imag);
1575 void addVectorElement(EvalInfo &Info,
const Expr *E, QualType EltTy,
1576 uint64_t Size, uint64_t Idx) {
1578 Designator.addVectorElementUnchecked(EltTy, Size, Idx);
1580 void clearIsNullPointer() {
1583 void adjustOffsetAndIndex(EvalInfo &Info,
const Expr *E,
1584 const APSInt &Index, CharUnits ElementSize) {
1595 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
1599 Designator.adjustIndex(Info, E, Index, *
this);
1600 clearIsNullPointer();
1602 void adjustOffset(CharUnits N) {
1605 clearIsNullPointer();
1611 explicit MemberPtr(
const ValueDecl *Decl)
1612 : DeclAndIsDerivedMember(
Decl,
false) {}
1616 const ValueDecl *getDecl()
const {
1617 return DeclAndIsDerivedMember.getPointer();
1620 bool isDerivedMember()
const {
1621 return DeclAndIsDerivedMember.getInt();
1624 const CXXRecordDecl *getContainingRecord()
const {
1626 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1630 V =
APValue(getDecl(), isDerivedMember(), Path);
1633 assert(
V.isMemberPointer());
1634 DeclAndIsDerivedMember.setPointer(
V.getMemberPointerDecl());
1635 DeclAndIsDerivedMember.setInt(
V.isMemberPointerToDerivedMember());
1637 llvm::append_range(Path,
V.getMemberPointerPath());
1643 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1646 SmallVector<const CXXRecordDecl*, 4> Path;
1650 bool castBack(
const CXXRecordDecl *
Class) {
1651 assert(!Path.empty());
1652 const CXXRecordDecl *Expected;
1653 if (Path.size() >= 2)
1654 Expected = Path[Path.size() - 2];
1656 Expected = getContainingRecord();
1670 bool castToDerived(
const CXXRecordDecl *Derived) {
1673 if (!isDerivedMember()) {
1674 Path.push_back(Derived);
1677 if (!castBack(Derived))
1680 DeclAndIsDerivedMember.setInt(
false);
1688 DeclAndIsDerivedMember.setInt(
true);
1689 if (isDerivedMember()) {
1690 Path.push_back(Base);
1693 return castBack(Base);
1698 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1699 if (!LHS.getDecl() || !RHS.getDecl())
1700 return !LHS.getDecl() && !RHS.getDecl();
1701 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1703 return LHS.Path == RHS.Path;
1707void SubobjectDesignator::adjustIndex(EvalInfo &Info,
const Expr *E,
APSInt N,
1711 uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
1712 if (isMostDerivedAnUnsizedArray()) {
1713 diagnoseUnsizedArrayPointerArithmetic(Info, E);
1718 PathEntry::ArrayIndex(Entries.back().getAsArrayIndex() + TruncatedN);
1726 MostDerivedPathLength == Entries.size() && MostDerivedIsArrayElement;
1728 IsArray ? Entries.back().getAsArrayIndex() : (
uint64_t)IsOnePastTheEnd;
1731 if (N < -(int64_t)ArrayIndex || N > ArraySize - ArrayIndex) {
1732 if (!Info.checkingPotentialConstantExpression() ||
1733 !LV.AllowConstexprUnknown) {
1736 N = N.extend(std::max<unsigned>(N.getBitWidth() + 1, 65));
1737 (llvm::APInt &)N += ArrayIndex;
1738 assert(N.ugt(ArraySize) &&
"bounds check failed for in-bounds index");
1739 diagnosePointerArithmetic(Info, E, N);
1745 ArrayIndex += TruncatedN;
1746 assert(ArrayIndex <= ArraySize &&
1747 "bounds check succeeded for out-of-bounds index");
1750 Entries.back() = PathEntry::ArrayIndex(ArrayIndex);
1752 IsOnePastTheEnd = (ArrayIndex != 0);
1757 const LValue &This,
const Expr *E,
1758 bool AllowNonLiteralTypes =
false);
1760 bool InvalidBaseOK =
false);
1762 bool InvalidBaseOK =
false);
1770static bool EvaluateComplex(
const Expr *E, ComplexValue &Res, EvalInfo &Info);
1775static std::optional<uint64_t>
1777 std::string *StringResult =
nullptr);
1794 if (Int.isUnsigned() || Int.isMinSignedValue()) {
1795 Int = Int.extend(Int.getBitWidth() + 1);
1796 Int.setIsSigned(
true);
1801template<
typename KeyT>
1802APValue &CallStackFrame::createTemporary(
const KeyT *Key, QualType T,
1803 ScopeKind Scope, LValue &LV) {
1804 unsigned Version = getTempVersion();
1805 APValue::LValueBase
Base(Key, Index, Version);
1807 return createLocal(Base, Key, T, Scope);
1811APValue &CallStackFrame::createParam(CallRef Args,
const ParmVarDecl *PVD,
1813 assert(Args.CallIndex == Index &&
"creating parameter in wrong frame");
1814 APValue::LValueBase
Base(PVD, Index, Args.Version);
1819 return createLocal(Base, PVD, PVD->
getType(), ScopeKind::Call);
1822APValue &CallStackFrame::createLocal(APValue::LValueBase Base,
const void *Key,
1823 QualType T, ScopeKind Scope) {
1824 assert(
Base.getCallIndex() == Index &&
"lvalue for wrong frame");
1825 unsigned Version =
Base.getVersion();
1827 assert(
Result.isAbsent() &&
"local created multiple times");
1833 if (Index <= Info.SpeculativeEvaluationDepth) {
1835 Info.noteSideEffect();
1837 Info.CleanupStack.push_back(Cleanup(&
Result, Base, T, Scope));
1842APValue *EvalInfo::createHeapAlloc(
const Expr *E, QualType T, LValue &LV) {
1844 FFDiag(E, diag::note_constexpr_heap_alloc_limit_exceeded);
1848 DynamicAllocLValue DA(NumHeapAllocs++);
1850 auto Result = HeapAllocs.emplace(std::piecewise_construct,
1851 std::forward_as_tuple(DA), std::tuple<>());
1852 assert(
Result.second &&
"reused a heap alloc index?");
1853 Result.first->second.AllocExpr = E;
1854 return &
Result.first->second.Value;
1858void CallStackFrame::describe(raw_ostream &Out)
const {
1859 bool IsMemberCall =
false;
1860 bool ExplicitInstanceParam =
false;
1861 clang::PrintingPolicy PrintingPolicy = Info.Ctx.getPrintingPolicy();
1864 if (
const auto *MD = dyn_cast<CXXMethodDecl>(Callee)) {
1866 ExplicitInstanceParam = MD->isExplicitObjectMemberFunction();
1870 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1873 if (This && IsMemberCall) {
1874 if (
const auto *MCE = dyn_cast_if_present<CXXMemberCallExpr>(CallExpr)) {
1875 const Expr *
Object = MCE->getImplicitObjectArgument();
1876 Object->printPretty(Out,
nullptr, PrintingPolicy,
1878 if (
Object->getType()->isPointerType())
1882 }
else if (
const auto *OCE =
1883 dyn_cast_if_present<CXXOperatorCallExpr>(CallExpr)) {
1884 OCE->getArg(0)->printPretty(Out,
nullptr, PrintingPolicy,
1889 This->moveInto(Val);
1892 Info.Ctx.getLValueReferenceType(
This->Designator.MostDerivedType));
1895 Callee->getNameForDiagnostic(Out, PrintingPolicy,
1901 llvm::ListSeparator
Comma;
1902 for (
const ParmVarDecl *Param :
1903 Callee->parameters().slice(ExplicitInstanceParam)) {
1905 const APValue *
V = Info.getParamSlot(Arguments, Param);
1907 V->printPretty(Out, Info.Ctx, Param->getType());
1923 return Info.noteSideEffect();
1930 return (
Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1931 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||
1932 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||
1933 Builtin == Builtin::BI__builtin_function_start);
1937 const auto *BaseExpr =
1938 llvm::dyn_cast_if_present<CallExpr>(LVal.Base.
dyn_cast<
const Expr *>());
1953 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1954 return VD->hasGlobalStorage();
1970 case Expr::CompoundLiteralExprClass: {
1974 case Expr::MaterializeTemporaryExprClass:
1979 case Expr::StringLiteralClass:
1980 case Expr::PredefinedExprClass:
1981 case Expr::ObjCStringLiteralClass:
1982 case Expr::ObjCEncodeExprClass:
1984 case Expr::ObjCBoxedExprClass:
1985 case Expr::ObjCArrayLiteralClass:
1986 case Expr::ObjCDictionaryLiteralClass:
1988 case Expr::CallExprClass:
1991 case Expr::AddrLabelExprClass:
1995 case Expr::BlockExprClass:
1999 case Expr::SourceLocExprClass:
2001 case Expr::ImplicitValueInitExprClass:
2026 const auto *BaseExpr = LVal.Base.
dyn_cast<
const Expr *>();
2031 if (
const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) {
2032 Info.Ctx.getObjCEncodingForType(EE->getEncodedType(),
2040 const auto *Lit = dyn_cast<StringLiteral>(BaseExpr);
2041 if (
const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr))
2042 Lit = PE->getFunctionName();
2047 AsString.
Bytes = Lit->getBytes();
2048 AsString.
CharWidth = Lit->getCharByteWidth();
2068 const LValue &RHS) {
2077 CharUnits Offset = RHS.Offset - LHS.Offset;
2078 if (Offset.isNegative()) {
2079 if (LHSString.
Bytes.size() < (
size_t)-Offset.getQuantity())
2081 LHSString.
Bytes = LHSString.
Bytes.drop_front(-Offset.getQuantity());
2083 if (RHSString.
Bytes.size() < (
size_t)Offset.getQuantity())
2085 RHSString.
Bytes = RHSString.
Bytes.drop_front(Offset.getQuantity());
2088 bool LHSIsLonger = LHSString.
Bytes.size() > RHSString.
Bytes.size();
2089 StringRef Longer = LHSIsLonger ? LHSString.
Bytes : RHSString.
Bytes;
2090 StringRef Shorter = LHSIsLonger ? RHSString.
Bytes : LHSString.
Bytes;
2091 int ShorterCharWidth = (LHSIsLonger ? RHSString : LHSString).CharWidth;
2096 for (
int NullByte : llvm::seq(ShorterCharWidth)) {
2097 if (Shorter.size() + NullByte >= Longer.size())
2099 if (Longer[Shorter.size() + NullByte])
2105 return Shorter == Longer.take_front(Shorter.size());
2115 if (isa_and_nonnull<VarDecl>(
Decl)) {
2125 if (!A.getLValueBase())
2126 return !B.getLValueBase();
2127 if (!B.getLValueBase())
2130 if (A.getLValueBase().getOpaqueValue() !=
2131 B.getLValueBase().getOpaqueValue())
2134 return A.getLValueCallIndex() == B.getLValueCallIndex() &&
2135 A.getLValueVersion() == B.getLValueVersion();
2139 assert(
Base &&
"no location for a null lvalue");
2145 if (
auto *PVD = dyn_cast_or_null<ParmVarDecl>(VD)) {
2147 for (CallStackFrame *F = Info.CurrentCall; F; F = F->Caller) {
2148 if (F->Arguments.CallIndex ==
Base.getCallIndex() &&
2149 F->Arguments.Version ==
Base.getVersion() && F->Callee &&
2150 Idx < F->Callee->getNumParams()) {
2151 VD = F->Callee->getParamDecl(Idx);
2158 Info.Note(VD->
getLocation(), diag::note_declared_at);
2160 Info.Note(E->
getExprLoc(), diag::note_constexpr_temporary_here);
2163 if (std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA))
2164 Info.Note((*Alloc)->AllocExpr->getExprLoc(),
2165 diag::note_constexpr_dynamic_alloc_here);
2198 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
2206 if (isTemplateArgument(Kind)) {
2207 int InvalidBaseKind = -1;
2210 InvalidBaseKind = 0;
2211 else if (isa_and_nonnull<StringLiteral>(BaseE))
2212 InvalidBaseKind = 1;
2213 else if (isa_and_nonnull<MaterializeTemporaryExpr>(BaseE) ||
2214 isa_and_nonnull<LifetimeExtendedTemporaryDecl>(BaseVD))
2215 InvalidBaseKind = 2;
2216 else if (
auto *PE = dyn_cast_or_null<PredefinedExpr>(BaseE)) {
2217 InvalidBaseKind = 3;
2218 Ident = PE->getIdentKindName();
2221 if (InvalidBaseKind != -1) {
2222 Info.FFDiag(Loc, diag::note_constexpr_invalid_template_arg)
2223 << IsReferenceType << !
Designator.Entries.empty() << InvalidBaseKind
2229 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(BaseVD);
2230 FD && FD->isImmediateFunction()) {
2231 Info.FFDiag(Loc, diag::note_consteval_address_accessible)
2233 Info.Note(FD->getLocation(), diag::note_declared_at);
2241 if (Info.getLangOpts().CPlusPlus11) {
2242 Info.FFDiag(Loc, diag::note_constexpr_non_global, 1)
2243 << IsReferenceType << !
Designator.Entries.empty() << !!BaseVD
2245 auto *VarD = dyn_cast_or_null<VarDecl>(BaseVD);
2246 if (VarD && VarD->isConstexpr()) {
2252 Info.Note(VarD->getLocation(), diag::note_constexpr_not_static)
2264 assert((Info.checkingPotentialConstantExpression() ||
2265 LVal.getLValueCallIndex() == 0) &&
2266 "have call index for global lvalue");
2268 if (LVal.allowConstexprUnknown()) {
2270 Info.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << BaseVD;
2279 Info.FFDiag(Loc, diag::note_constexpr_dynamic_alloc)
2280 << IsReferenceType << !
Designator.Entries.empty();
2286 if (
const VarDecl *Var = dyn_cast<const VarDecl>(BaseVD)) {
2288 if (Var->getTLSKind())
2296 if (!isForManglingOnly(Kind) && Var->hasAttr<DLLImportAttr>() &&
2297 !Var->isStaticLocal())
2302 if (Info.getLangOpts().CUDA && Info.getLangOpts().CUDAIsDevice &&
2303 Info.Ctx.CUDAConstantEvalCtx.NoWrongSidedVars) {
2304 if ((!Var->hasAttr<CUDADeviceAttr>() &&
2305 !Var->hasAttr<CUDAConstantAttr>() &&
2306 !Var->getType()->isCUDADeviceBuiltinSurfaceType() &&
2307 !Var->getType()->isCUDADeviceBuiltinTextureType()) ||
2308 Var->hasAttr<HIPManagedAttr>())
2312 if (
const auto *FD = dyn_cast<const FunctionDecl>(BaseVD)) {
2323 if (Info.getLangOpts().CPlusPlus && !isForManglingOnly(Kind) &&
2324 FD->hasAttr<DLLImportAttr>())
2328 }
else if (
const auto *MTE =
2329 dyn_cast_or_null<MaterializeTemporaryExpr>(BaseE)) {
2330 if (CheckedTemps.insert(MTE).second) {
2333 Info.FFDiag(MTE->getExprLoc(),
2334 diag::note_constexpr_unsupported_temporary_nontrivial_dtor)
2339 APValue *
V = MTE->getOrCreateValue(
false);
2340 assert(
V &&
"evasluation result refers to uninitialised temporary");
2342 Info, MTE->getExprLoc(), TempType, *
V, Kind,
2343 nullptr, CheckedTemps))
2350 if (!IsReferenceType)
2362 Info.FFDiag(Loc, diag::note_constexpr_past_end, 1)
2363 << !
Designator.Entries.empty() << !!BaseVD << BaseVD;
2378 const auto *FD = dyn_cast_or_null<CXXMethodDecl>(
Member);
2381 if (FD->isImmediateFunction()) {
2382 Info.FFDiag(Loc, diag::note_consteval_address_accessible) << 0;
2383 Info.Note(FD->getLocation(), diag::note_declared_at);
2386 return isForManglingOnly(Kind) || FD->isVirtual() ||
2387 !FD->hasAttr<DLLImportAttr>();
2393 const LValue *
This =
nullptr) {
2395 if (Info.getLangOpts().CPlusPlus23)
2414 if (
This && Info.EvaluatingDecl ==
This->getLValueBase())
2418 if (Info.getLangOpts().CPlusPlus11)
2419 Info.FFDiag(E, diag::note_constexpr_nonliteral)
2422 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
2433 if (SubobjectDecl) {
2434 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2435 << 1 << SubobjectDecl;
2437 diag::note_constexpr_subobject_declared_here);
2439 Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized)
2448 Type = AT->getValueType();
2453 if (
Value.isArray()) {
2455 for (
unsigned I = 0, N =
Value.getArrayInitializedElts(); I != N; ++I) {
2457 Value.getArrayInitializedElt(I), Kind,
2458 SubobjectDecl, CheckedTemps))
2461 if (!
Value.hasArrayFiller())
2464 Value.getArrayFiller(), Kind, SubobjectDecl,
2467 if (
Value.isUnion() &&
Value.getUnionField()) {
2470 Value.getUnionValue(), Kind,
Value.getUnionField(), CheckedTemps);
2472 if (
Value.isStruct()) {
2474 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
2475 unsigned BaseIndex = 0;
2477 const APValue &BaseValue =
Value.getStructBase(BaseIndex);
2480 Info.FFDiag(TypeBeginLoc, diag::note_constexpr_uninitialized_base)
2481 << BS.getType() <<
SourceRange(TypeBeginLoc, BS.getEndLoc());
2491 for (
const auto *I : RD->fields()) {
2492 if (I->isUnnamedBitField())
2496 Value.getStructField(I->getFieldIndex()), Kind,
2502 if (
Value.isLValue() &&
2505 LVal.setFrom(Info.Ctx,
Value);
2510 if (
Value.isMemberPointer() &&
2531 nullptr, CheckedTemps);
2541 ConstantExprKind::Normal,
nullptr, CheckedTemps);
2547 if (!Info.HeapAllocs.empty()) {
2551 Info.CCEDiag(Info.HeapAllocs.begin()->second.AllocExpr,
2552 diag::note_constexpr_memory_leak)
2553 <<
unsigned(Info.HeapAllocs.size() - 1);
2561 if (!
Value.getLValueBase()) {
2614 llvm_unreachable(
"unknown APValue kind");
2620 assert(E->
isPRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
2629 const T &SrcValue,
QualType DestType) {
2630 Info.CCEDiag(E, diag::note_constexpr_overflow) << SrcValue << DestType;
2631 if (
const auto *OBT = DestType->
getAs<OverflowBehaviorType>();
2632 OBT && OBT->isTrapKind()) {
2635 return Info.noteUndefinedBehavior();
2641 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2647 if (
Value.convertToInteger(
Result, llvm::APFloat::rmTowardZero, &ignored)
2648 & APFloat::opInvalidOp)
2659 llvm::RoundingMode RM =
2661 if (RM == llvm::RoundingMode::Dynamic)
2662 RM = llvm::RoundingMode::NearestTiesToEven;
2668 APFloat::opStatus St) {
2671 if (Info.InConstantContext)
2675 if ((St & APFloat::opInexact) &&
2679 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
2683 if ((St != APFloat::opOK) &&
2686 FPO.getAllowFEnvAccess())) {
2687 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
2691 if ((St & APFloat::opStatus::opInvalidOp) &&
2712 "HandleFloatToFloatCast has been checked with only CastExpr, "
2713 "CompoundAssignOperator and ConvertVectorExpr. Please either validate "
2714 "the new expression or address the root cause of this usage.");
2716 APFloat::opStatus St;
2719 St =
Result.convert(Info.Ctx.getFloatTypeSemantics(DestType), RM, &ignored);
2726 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
2740 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
2742 APFloat::opStatus St =
Result.convertFromAPInt(
Value,
Value.isSigned(), RM);
2748 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
2750 if (!
Value.isInt()) {
2754 assert(
Value.isLValue() &&
"integral value neither int nor lvalue?");
2760 unsigned OldBitWidth = Int.getBitWidth();
2762 if (NewBitWidth < OldBitWidth)
2763 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
2770template<
typename Operation>
2773 unsigned BitWidth, Operation Op,
2775 if (LHS.isUnsigned()) {
2780 APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
2783 if (Info.checkingForUndefinedBehavior())
2784 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
2785 diag::warn_integer_constant_overflow)
2798 bool HandleOverflowResult =
true;
2805 std::multiplies<APSInt>(),
Result);
2808 std::plus<APSInt>(),
Result);
2811 std::minus<APSInt>(),
Result);
2812 case BO_And:
Result = LHS & RHS;
return true;
2813 case BO_Xor:
Result = LHS ^ RHS;
return true;
2814 case BO_Or:
Result = LHS | RHS;
return true;
2818 Info.FFDiag(E, diag::note_expr_divide_by_zero)
2824 if (RHS.isNegative() && RHS.isAllOnes() && LHS.isSigned() &&
2825 LHS.isMinSignedValue())
2827 Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->
getType());
2828 Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);
2829 return HandleOverflowResult;
2831 if (Info.getLangOpts().OpenCL)
2833 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2834 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2836 else if (RHS.isSigned() && RHS.isNegative()) {
2839 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2840 if (!Info.noteUndefinedBehavior())
2848 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2850 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2851 << RHS << E->
getType() << LHS.getBitWidth();
2852 if (!Info.noteUndefinedBehavior())
2854 }
else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
2859 if (LHS.isNegative()) {
2860 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
2861 if (!Info.noteUndefinedBehavior())
2863 }
else if (LHS.countl_zero() < SA) {
2864 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
2865 if (!Info.noteUndefinedBehavior())
2873 if (Info.getLangOpts().OpenCL)
2875 RHS &=
APSInt(llvm::APInt(RHS.getBitWidth(),
2876 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
2878 else if (RHS.isSigned() && RHS.isNegative()) {
2881 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
2882 if (!Info.noteUndefinedBehavior())
2890 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
2892 Info.CCEDiag(E, diag::note_constexpr_large_shift)
2893 << RHS << E->
getType() << LHS.getBitWidth();
2894 if (!Info.noteUndefinedBehavior())
2902 case BO_LT:
Result = LHS < RHS;
return true;
2903 case BO_GT:
Result = LHS > RHS;
return true;
2904 case BO_LE:
Result = LHS <= RHS;
return true;
2905 case BO_GE:
Result = LHS >= RHS;
return true;
2906 case BO_EQ:
Result = LHS == RHS;
return true;
2907 case BO_NE:
Result = LHS != RHS;
return true;
2909 llvm_unreachable(
"BO_Cmp should be handled elsewhere");
2916 const APFloat &RHS) {
2918 APFloat::opStatus St;
2924 St = LHS.multiply(RHS, RM);
2927 St = LHS.add(RHS, RM);
2930 St = LHS.subtract(RHS, RM);
2936 Info.CCEDiag(E, diag::note_expr_divide_by_zero);
2937 St = LHS.divide(RHS, RM);
2946 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
2947 return Info.noteUndefinedBehavior();
2955 const APInt &RHSValue, APInt &
Result) {
2956 bool LHS = (LHSValue != 0);
2957 bool RHS = (RHSValue != 0);
2959 if (Opcode == BO_LAnd)
2967 const APFloat &RHSValue, APInt &
Result) {
2968 bool LHS = !LHSValue.isZero();
2969 bool RHS = !RHSValue.isZero();
2971 if (Opcode == BO_LAnd)
2990template <
typename APTy>
2993 const APTy &RHSValue, APInt &
Result) {
2996 llvm_unreachable(
"unsupported binary operator");
2998 Result = (LHSValue == RHSValue);
3001 Result = (LHSValue != RHSValue);
3004 Result = (LHSValue < RHSValue);
3007 Result = (LHSValue > RHSValue);
3010 Result = (LHSValue <= RHSValue);
3013 Result = (LHSValue >= RHSValue);
3042 assert(Opcode != BO_PtrMemD && Opcode != BO_PtrMemI &&
3043 "Operation not supported on vector types");
3047 QualType EltTy = VT->getElementType();
3054 "A vector result that isn't a vector OR uncalculated LValue");
3060 RHSValue.
getVectorLength() == NumElements &&
"Different vector sizes");
3064 for (
unsigned EltNum = 0; EltNum < NumElements; ++EltNum) {
3069 APSInt EltResult{Info.Ctx.getIntWidth(EltTy),
3079 RHSElt.
getInt(), EltResult);
3085 ResultElements.emplace_back(EltResult);
3090 "Mismatched LHS/RHS/Result Type");
3091 APFloat LHSFloat = LHSElt.
getFloat();
3099 ResultElements.emplace_back(LHSFloat);
3103 LHSValue =
APValue(ResultElements.data(), ResultElements.size());
3111 unsigned TruncatedElements) {
3112 SubobjectDesignator &D =
Result.Designator;
3115 if (TruncatedElements == D.Entries.size())
3117 assert(TruncatedElements >= D.MostDerivedPathLength &&
3118 "not casting to a derived class");
3124 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
3128 if (isVirtualBaseClass(D.Entries[I]))
3134 D.Entries.resize(TruncatedElements);
3144 RL = &Info.Ctx.getASTRecordLayout(Derived);
3147 Obj.addDecl(Info, E,
Base,
false);
3148 Obj.getLValueOffset() += RL->getBaseClassOffset(
Base);
3157 if (!
Base->isVirtual())
3160 SubobjectDesignator &D = Obj.Designator;
3175 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
3176 Obj.addDecl(Info, E, BaseDecl,
true);
3185 PathI != PathE; ++PathI) {
3189 Type = (*PathI)->getType();
3201 llvm_unreachable(
"Class must be derived from the passed in base class!");
3216 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
3220 LVal.addDecl(Info, E, FD);
3221 LVal.adjustOffset(Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I)));
3229 for (
const auto *
C : IFD->
chain())
3263 Size = Info.Ctx.getTypeSizeInChars(
Type);
3265 Size = Info.Ctx.getTypeInfoDataSizeInChars(
Type).Width;
3282 LVal.adjustOffsetAndIndex(Info, E, Adjustment, SizeOfPointee);
3288 int64_t Adjustment) {
3290 APSInt::get(Adjustment));
3305 LVal.Offset += SizeOfComponent;
3307 LVal.addComplex(Info, E, EltTy, Imag);
3313 uint64_t Size, uint64_t Idx) {
3318 LVal.Offset += SizeOfElement * Idx;
3320 LVal.addVectorElement(Info, E, EltTy, Size, Idx);
3334 const VarDecl *VD, CallStackFrame *Frame,
3338 bool AllowConstexprUnknown =
3343 auto CheckUninitReference = [&](
bool IsLocalVariable) {
3355 if (!AllowConstexprUnknown || IsLocalVariable) {
3356 if (!Info.checkingPotentialConstantExpression())
3357 Info.FFDiag(E, diag::note_constexpr_use_uninit_reference);
3367 Result = Frame->getTemporary(VD, Version);
3369 return CheckUninitReference(
true);
3378 "missing value for local variable");
3379 if (Info.checkingPotentialConstantExpression())
3383 "A variable in a frame should either be a local or a parameter");
3389 if (Info.EvaluatingDecl ==
Base) {
3390 Result = Info.EvaluatingDeclValue;
3391 return CheckUninitReference(
false);
3399 if (AllowConstexprUnknown) {
3406 if (!Info.checkingPotentialConstantExpression() ||
3407 !Info.CurrentCall->Callee ||
3409 if (Info.getLangOpts().CPlusPlus11) {
3410 Info.FFDiag(E, diag::note_constexpr_function_param_value_unknown)
3431 if (!
Init && !AllowConstexprUnknown) {
3434 if (!Info.checkingPotentialConstantExpression()) {
3435 Info.FFDiag(E, diag::note_constexpr_var_init_unknown, 1)
3446 if (
Init &&
Init->isValueDependent()) {
3453 if (!Info.checkingPotentialConstantExpression()) {
3454 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
3455 ? diag::note_constexpr_ltor_non_constexpr
3456 : diag::note_constexpr_ltor_non_integral, 1)
3470 Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3486 !AllowConstexprUnknown) ||
3487 ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) &&
3490 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD;
3500 Info.FFDiag(E, diag::note_constexpr_var_init_weak) << VD;
3507 if (!
Result && !AllowConstexprUnknown)
3510 return CheckUninitReference(
false);
3520 E = Derived->
bases_end(); I != E; ++I, ++Index) {
3521 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
Base)
3525 llvm_unreachable(
"base class missing from derived class's bases list");
3532 "SourceLocExpr should have already been converted to a StringLiteral");
3535 if (
const auto *ObjCEnc = dyn_cast<ObjCEncodeExpr>(Lit)) {
3537 Info.Ctx.getObjCEncodingForType(ObjCEnc->getEncodedType(), Str);
3538 assert(Index <= Str.size() &&
"Index too large");
3539 return APSInt::getUnsigned(Str.c_str()[Index]);
3542 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
3543 Lit = PE->getFunctionName();
3546 Info.Ctx.getAsConstantArrayType(S->
getType());
3547 assert(CAT &&
"string literal isn't an array");
3549 assert(CharType->
isIntegerType() &&
"unexpected character type");
3552 if (Index < S->getLength())
3565 AllocType.isNull() ? S->
getType() : AllocType);
3566 assert(CAT &&
"string literal isn't an array");
3568 assert(CharType->
isIntegerType() &&
"unexpected character type");
3575 if (
Result.hasArrayFiller())
3577 for (
unsigned I = 0, N =
Result.getArrayInitializedElts(); I != N; ++I) {
3585 unsigned Size =
Array.getArraySize();
3586 assert(Index < Size);
3589 unsigned OldElts =
Array.getArrayInitializedElts();
3590 unsigned NewElts = std::max(Index+1, OldElts * 2);
3591 NewElts = std::min(Size, std::max(NewElts, 8u));
3595 for (
unsigned I = 0; I != OldElts; ++I)
3597 for (
unsigned I = OldElts; I != NewElts; ++I)
3601 Array.swap(NewValue);
3608 Vec =
APValue(Elts.data(), Elts.size());
3618 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3629 for (
auto *Field : RD->
fields())
3630 if (!Field->isUnnamedBitField() &&
3634 for (
auto &BaseSpec : RD->
bases())
3645 CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
3652 for (
auto *Field : RD->
fields()) {
3657 if (Field->isMutable() &&
3659 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1) << AK << Field;
3660 Info.Note(Field->getLocation(), diag::note_declared_at);
3668 for (
auto &BaseSpec : RD->
bases())
3678 bool MutableSubobject =
false) {
3683 switch (Info.IsEvaluatingDecl) {
3684 case EvalInfo::EvaluatingDeclKind::None:
3687 case EvalInfo::EvaluatingDeclKind::Ctor:
3689 if (Info.EvaluatingDecl ==
Base)
3694 if (
auto *BaseE =
Base.dyn_cast<
const Expr *>())
3695 if (
auto *BaseMTE = dyn_cast<MaterializeTemporaryExpr>(BaseE))
3696 return Info.EvaluatingDecl == BaseMTE->getExtendingDecl();
3699 case EvalInfo::EvaluatingDeclKind::Dtor:
3704 if (MutableSubobject ||
Base != Info.EvaluatingDecl)
3710 return T.isConstQualified() || T->isReferenceType();
3713 llvm_unreachable(
"unknown evaluating decl kind");
3718 return Info.CheckArraySize(
3738 uint64_t IntResult = BoolResult;
3741 : Info.Ctx.getIntTypeForBitwidth(64,
false);
3742 Result =
APValue(Info.Ctx.MakeIntValue(IntResult, IntType));
3747 Info.Ctx.getIntTypeForBitwidth(64,
false),
3750 Result = std::move(Result2);
3758 DestTy,
Result.getFloat());
3764 uint64_t IntResult = BoolResult;
3783 uint64_t IntResult = BoolResult;
3790 DestTy,
Result.getInt());
3794 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3807 {&
Result, ResultType, 0}};
3810 while (!WorkList.empty() && ElI < Elements.size()) {
3811 auto [Res,
Type, BitWidth] = WorkList.pop_back_val();
3827 APSInt &Int = Res->getInt();
3828 unsigned OldBitWidth = Int.getBitWidth();
3829 unsigned NewBitWidth = BitWidth;
3830 if (NewBitWidth < OldBitWidth)
3831 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
3840 for (
unsigned I = 0; I < NumEl; ++I) {
3846 *Res =
APValue(Vals.data(), NumEl);
3855 for (int64_t I = Size - 1; I > -1; --I)
3856 WorkList.emplace_back(&Res->getArrayInitializedElt(I), ElTy, 0u);
3862 unsigned NumBases = 0;
3863 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
3864 NumBases = CXXRD->getNumBases();
3871 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3872 if (CXXRD->getNumBases() > 0) {
3873 assert(CXXRD->getNumBases() == 1);
3875 ReverseList.emplace_back(&Res->getStructBase(0), BS.
getType(), 0u);
3882 if (FD->isUnnamedBitField())
3884 if (FD->isBitField()) {
3885 FDBW = FD->getBitWidthValue();
3888 ReverseList.emplace_back(&Res->getStructField(FD->getFieldIndex()),
3889 FD->getType(), FDBW);
3892 std::reverse(ReverseList.begin(), ReverseList.end());
3893 llvm::append_range(WorkList, ReverseList);
3896 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
3909 assert((Elements.size() == SrcTypes.size()) &&
3910 (Elements.size() == DestTypes.size()));
3912 for (
unsigned I = 0, ESz = Elements.size(); I < ESz; ++I) {
3913 APValue Original = Elements[I];
3917 if (!
handleScalarCast(Info, FPO, E, SourceTy, DestTy, Original, Results[I]))
3928 while (!WorkList.empty()) {
3951 for (uint64_t I = 0; I < ArrSize; ++I) {
3952 WorkList.push_back(ElTy);
3960 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3961 if (CXXRD->getNumBases() > 0) {
3962 assert(CXXRD->getNumBases() == 1);
3964 WorkList.push_back(BS.
getType());
3970 if (FD->isUnnamedBitField())
3972 WorkList.push_back(FD->getType());
3989 "Not a valid HLSLAggregateSplatCast.");
4009 unsigned Populated = 0;
4010 while (!WorkList.empty() && Populated < Size) {
4011 auto [Work,
Type] = WorkList.pop_back_val();
4013 if (Work.isFloat() || Work.isInt()) {
4014 Elements.push_back(Work);
4015 Types.push_back(
Type);
4019 if (Work.isVector()) {
4022 for (
unsigned I = 0; I < Work.getVectorLength() && Populated < Size;
4024 Elements.push_back(Work.getVectorElt(I));
4025 Types.push_back(ElTy);
4030 if (Work.isMatrix()) {
4033 QualType ElTy = MT->getElementType();
4035 for (
unsigned Row = 0; Row < Work.getMatrixNumRows() && Populated < Size;
4037 for (
unsigned Col = 0;
4038 Col < Work.getMatrixNumColumns() && Populated < Size; Col++) {
4039 Elements.push_back(Work.getMatrixElt(Row, Col));
4040 Types.push_back(ElTy);
4046 if (Work.isArray()) {
4050 for (int64_t I = Work.getArraySize() - 1; I > -1; --I) {
4051 WorkList.emplace_back(Work.getArrayInitializedElt(I), ElTy);
4056 if (Work.isStruct()) {
4064 if (FD->isUnnamedBitField())
4066 ReverseList.emplace_back(Work.getStructField(FD->getFieldIndex()),
4070 std::reverse(ReverseList.begin(), ReverseList.end());
4071 llvm::append_range(WorkList, ReverseList);
4074 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
4075 if (CXXRD->getNumBases() > 0) {
4076 assert(CXXRD->getNumBases() == 1);
4081 if (!
Base.isStruct())
4089 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4098struct CompleteObject {
4100 APValue::LValueBase
Base;
4110 bool mayAccessMutableMembers(EvalInfo &Info,
AccessKinds AK)
const {
4121 if (!Info.getLangOpts().CPlusPlus14 &&
4122 AK != AccessKinds::AK_IsWithinLifetime)
4127 explicit operator bool()
const {
return !
Type.isNull(); }
4132 bool IsMutable =
false) {
4146template <
typename Sub
objectHandler>
4147static typename SubobjectHandler::result_type
4149 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
4152 return handler.failed();
4153 if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
4154 if (Info.getLangOpts().CPlusPlus11)
4155 Info.FFDiag(E, Sub.isOnePastTheEnd()
4156 ? diag::note_constexpr_access_past_end
4157 : diag::note_constexpr_access_unsized_array)
4158 << handler.AccessKind;
4161 return handler.failed();
4167 const FieldDecl *VolatileField =
nullptr;
4170 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
4181 if (!Info.checkingPotentialConstantExpression()) {
4182 Info.FFDiag(E, diag::note_constexpr_access_uninit)
4187 return handler.failed();
4195 Info.isEvaluatingCtorDtor(
4196 Obj.Base,
ArrayRef(Sub.Entries.begin(), Sub.Entries.begin() + I)) !=
4197 ConstructionPhase::None) {
4198 ObjType = Info.Ctx.getCanonicalType(ObjType);
4207 if (Info.getLangOpts().CPlusPlus) {
4211 if (VolatileField) {
4214 Decl = VolatileField;
4217 Loc = VD->getLocation();
4224 Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1)
4225 << handler.AccessKind << DiagKind <<
Decl;
4226 Info.Note(Loc, diag::note_constexpr_volatile_here) << DiagKind;
4228 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
4230 return handler.failed();
4238 !Obj.mayAccessMutableMembers(Info, handler.AccessKind) &&
4240 return handler.failed();
4244 if (!handler.found(*O, ObjType, Obj.Base))
4256 LastField =
nullptr;
4259 const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
4261 "vla in literal type?");
4262 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4263 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4264 CAT && CAT->
getSize().ule(Index)) {
4267 if (Info.getLangOpts().CPlusPlus11)
4268 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4269 << handler.AccessKind;
4272 return handler.failed();
4279 else if (!
isRead(handler.AccessKind)) {
4280 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
4282 return handler.failed();
4290 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4292 if (Info.getLangOpts().CPlusPlus11)
4293 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4294 << handler.AccessKind;
4297 return handler.failed();
4303 assert(I == N - 1 &&
"extracting subobject of scalar?");
4313 uint64_t Index = Sub.Entries[I].getAsArrayIndex();
4314 unsigned NumElements = VT->getNumElements();
4315 if (Index == NumElements) {
4316 if (Info.getLangOpts().CPlusPlus11)
4317 Info.FFDiag(E, diag::note_constexpr_access_past_end)
4318 << handler.AccessKind;
4321 return handler.failed();
4324 if (Index > NumElements) {
4325 Info.CCEDiag(E, diag::note_constexpr_array_index)
4326 << Index << 0 << NumElements;
4327 return handler.failed();
4330 ObjType = VT->getElementType();
4331 assert(I == N - 1 &&
"extracting subobject of scalar?");
4334 if (
isRead(handler.AccessKind)) {
4336 return handler.failed();
4340 assert(O->
isVector() &&
"unexpected object during vector element access");
4341 return handler.found(O->
getVectorElt(Index), ObjType, Obj.Base);
4342 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
4343 if (Field->isMutable() &&
4344 !Obj.mayAccessMutableMembers(Info, handler.AccessKind)) {
4345 Info.FFDiag(E, diag::note_constexpr_access_mutable, 1)
4346 << handler.AccessKind << Field;
4347 Info.Note(Field->getLocation(), diag::note_declared_at);
4348 return handler.failed();
4357 if (I == N - 1 && handler.AccessKind ==
AK_Construct) {
4368 Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member)
4369 << handler.AccessKind << Field << !UnionField << UnionField;
4370 return handler.failed();
4379 if (Field->getType().isVolatileQualified())
4380 VolatileField = Field;
4393struct ExtractSubobjectHandler {
4399 typedef bool result_type;
4400 bool failed() {
return false; }
4401 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4411 bool found(APFloat &
Value, QualType SubobjType) {
4420 const CompleteObject &Obj,
4424 ExtractSubobjectHandler Handler = {Info, E,
Result, AK};
4429struct ModifySubobjectHandler {
4434 typedef bool result_type;
4437 bool checkConst(QualType QT) {
4440 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4446 bool failed() {
return false; }
4447 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4448 if (!checkConst(SubobjType))
4451 Subobj.
swap(NewVal);
4455 if (!checkConst(SubobjType))
4457 if (!NewVal.
isInt()) {
4465 bool found(APFloat &
Value, QualType SubobjType) {
4466 if (!checkConst(SubobjType))
4474const AccessKinds ModifySubobjectHandler::AccessKind;
4478 const CompleteObject &Obj,
4479 const SubobjectDesignator &Sub,
4481 ModifySubobjectHandler Handler = { Info, NewVal, E };
4488 const SubobjectDesignator &A,
4489 const SubobjectDesignator &B,
4490 bool &WasArrayIndex) {
4491 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
4492 for (; I != N; ++I) {
4496 if (A.Entries[I].getAsArrayIndex() != B.Entries[I].getAsArrayIndex()) {
4497 WasArrayIndex =
true;
4505 if (A.Entries[I].getAsBaseOrMember() !=
4506 B.Entries[I].getAsBaseOrMember()) {
4507 WasArrayIndex =
false;
4510 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
4512 ObjType = FD->getType();
4518 WasArrayIndex =
false;
4525 const SubobjectDesignator &A,
4526 const SubobjectDesignator &B) {
4527 if (A.Entries.size() != B.Entries.size())
4530 bool IsArray = A.MostDerivedIsArrayElement;
4531 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
4540 return CommonLength >= A.Entries.size() - IsArray;
4547 if (LVal.InvalidBase) {
4549 return CompleteObject();
4554 Info.FFDiag(E, diag::note_constexpr_dereferencing_null);
4556 Info.FFDiag(E, diag::note_constexpr_access_null) << AK;
4557 return CompleteObject();
4560 CallStackFrame *Frame =
nullptr;
4562 if (LVal.getLValueCallIndex()) {
4563 std::tie(Frame, Depth) =
4564 Info.getCallFrameAndDepth(LVal.getLValueCallIndex());
4566 Info.FFDiag(E, diag::note_constexpr_access_uninit, 1)
4569 return CompleteObject();
4580 if (Info.getLangOpts().CPlusPlus)
4581 Info.FFDiag(E, diag::note_constexpr_access_volatile_type)
4585 return CompleteObject();
4592 if (Info.getLangOpts().CPlusPlus14 && LVal.Base == Info.EvaluatingDecl &&
4596 BaseVal = Info.EvaluatingDeclValue;
4599 if (
auto *GD = dyn_cast<MSGuidDecl>(D)) {
4602 Info.FFDiag(E, diag::note_constexpr_modify_global);
4603 return CompleteObject();
4607 Info.FFDiag(E, diag::note_constexpr_unsupported_layout)
4609 return CompleteObject();
4611 return CompleteObject(LVal.Base, &
V, GD->getType());
4615 if (
auto *GCD = dyn_cast<UnnamedGlobalConstantDecl>(D)) {
4617 Info.FFDiag(E, diag::note_constexpr_modify_global);
4618 return CompleteObject();
4620 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&GCD->getValue()),
4625 if (
auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
4627 Info.FFDiag(E, diag::note_constexpr_modify_global);
4628 return CompleteObject();
4630 return CompleteObject(LVal.Base,
const_cast<APValue *
>(&TPO->getValue()),
4641 const VarDecl *VD = dyn_cast<VarDecl>(D);
4648 return CompleteObject();
4651 bool IsConstant = BaseType.isConstant(Info.Ctx);
4652 bool ConstexprVar =
false;
4653 if (
const auto *VD = dyn_cast_if_present<VarDecl>(
4665 }
else if (Info.getLangOpts().CPlusPlus14 &&
4672 Info.FFDiag(E, diag::note_constexpr_modify_global);
4673 return CompleteObject();
4676 }
else if (Info.getLangOpts().C23 && ConstexprVar) {
4678 return CompleteObject();
4679 }
else if (BaseType->isIntegralOrEnumerationType()) {
4682 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4683 if (Info.getLangOpts().CPlusPlus) {
4684 Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
4685 Info.Note(VD->
getLocation(), diag::note_declared_at);
4689 return CompleteObject();
4691 }
else if (!IsAccess) {
4692 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4693 }
else if ((IsConstant || BaseType->isReferenceType()) &&
4694 Info.checkingPotentialConstantExpression() &&
4695 BaseType->isLiteralType(Info.Ctx) && !VD->
hasDefinition()) {
4697 }
else if (IsConstant) {
4701 if (Info.getLangOpts().CPlusPlus) {
4702 Info.CCEDiag(E, Info.getLangOpts().CPlusPlus11
4703 ? diag::note_constexpr_ltor_non_constexpr
4704 : diag::note_constexpr_ltor_non_integral, 1)
4706 Info.Note(VD->
getLocation(), diag::note_declared_at);
4712 if (Info.getLangOpts().CPlusPlus) {
4713 Info.FFDiag(E, Info.getLangOpts().CPlusPlus11
4714 ? diag::note_constexpr_ltor_non_constexpr
4715 : diag::note_constexpr_ltor_non_integral, 1)
4717 Info.Note(VD->
getLocation(), diag::note_declared_at);
4721 return CompleteObject();
4730 return CompleteObject();
4735 if (!Info.checkingPotentialConstantExpression()) {
4736 Info.FFDiag(E, diag::note_constexpr_access_unknown_variable, 1)
4738 Info.Note(VD->getLocation(), diag::note_declared_at);
4740 return CompleteObject();
4743 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
4745 Info.FFDiag(E, diag::note_constexpr_access_deleted_object) << AK;
4746 return CompleteObject();
4748 return CompleteObject(LVal.Base, &(*Alloc)->Value,
4758 dyn_cast_or_null<MaterializeTemporaryExpr>(
Base)) {
4759 assert(MTE->getStorageDuration() ==
SD_Static &&
4760 "should have a frame for a non-global materialized temporary");
4787 if (!MTE->isUsableInConstantExpressions(Info.Ctx) &&
4790 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4791 Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
4792 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
4793 return CompleteObject();
4796 BaseVal = MTE->getOrCreateValue(
false);
4797 assert(BaseVal &&
"got reference to unevaluated temporary");
4799 dyn_cast_or_null<CompoundLiteralExpr>(
Base)) {
4815 !CLETy.isConstant(Info.Ctx)) {
4817 Info.Note(CLE->getExprLoc(), diag::note_declared_at);
4818 return CompleteObject();
4821 BaseVal = &CLE->getStaticValue();
4824 return CompleteObject(LVal.getLValueBase(),
nullptr, BaseType);
4827 Info.FFDiag(E, diag::note_constexpr_access_unreadable_object)
4830 Info.Ctx.getLValueReferenceType(LValType));
4832 return CompleteObject();
4836 assert(BaseVal &&
"missing value for temporary");
4847 unsigned VisibleDepth = Depth;
4848 if (llvm::isa_and_nonnull<ParmVarDecl>(
4851 if ((Frame && Info.getLangOpts().CPlusPlus14 &&
4852 Info.EvalStatus.HasSideEffects) ||
4853 (
isModification(AK) && VisibleDepth < Info.SpeculativeEvaluationDepth))
4854 return CompleteObject();
4856 return CompleteObject(LVal.getLValueBase(), BaseVal, BaseType);
4875 const LValue &LVal,
APValue &RVal,
4876 bool WantObjectRepresentation =
false) {
4877 if (LVal.Designator.Invalid)
4886 if (
Base && !LVal.getLValueCallIndex() && !
Type.isVolatileQualified()) {
4890 assert(LVal.Designator.Entries.size() <= 1 &&
4891 "Can only read characters from string literals");
4892 if (LVal.Designator.Entries.empty()) {
4899 if (LVal.Designator.isOnePastTheEnd()) {
4900 if (Info.getLangOpts().CPlusPlus11)
4901 Info.FFDiag(Conv, diag::note_constexpr_access_past_end) << AK;
4906 uint64_t CharIndex = LVal.Designator.Entries[0].getAsArrayIndex();
4913 return Obj &&
extractSubobject(Info, Conv, Obj, LVal.Designator, RVal, AK);
4927 LVal.setFrom(Info.Ctx, Val);
4943 if (LVal.Designator.Invalid)
4946 if (!Info.getLangOpts().CPlusPlus14) {
4956struct CompoundAssignSubobjectHandler {
4958 const CompoundAssignOperator *E;
4959 QualType PromotedLHSType;
4965 typedef bool result_type;
4967 bool checkConst(QualType QT) {
4970 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
4976 bool failed() {
return false; }
4977 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
4980 return found(Subobj.
getInt(), SubobjType);
4982 return found(Subobj.
getFloat(), SubobjType);
4989 return foundPointer(Subobj, SubobjType);
4991 return foundVector(Subobj, SubobjType);
4993 Info.FFDiag(E, diag::note_constexpr_access_uninit)
5005 bool foundVector(
APValue &
Value, QualType SubobjType) {
5006 if (!checkConst(SubobjType))
5017 if (!checkConst(SubobjType))
5036 Info.Ctx.getLangOpts());
5039 PromotedLHSType, FValue) &&
5048 bool found(APFloat &
Value, QualType SubobjType) {
5049 return checkConst(SubobjType) &&
5055 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5056 if (!checkConst(SubobjType))
5059 QualType PointeeType;
5060 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5064 (Opcode != BO_Add && Opcode != BO_Sub)) {
5070 if (Opcode == BO_Sub)
5074 LVal.setFrom(Info.Ctx, Subobj);
5077 LVal.moveInto(Subobj);
5083const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
5088 const LValue &LVal,
QualType LValType,
5092 if (LVal.Designator.Invalid)
5095 if (!Info.getLangOpts().CPlusPlus14) {
5101 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
5103 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5107struct IncDecSubobjectHandler {
5109 const UnaryOperator *E;
5113 typedef bool result_type;
5115 bool checkConst(QualType QT) {
5118 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
5124 bool failed() {
return false; }
5125 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
5135 return found(Subobj.
getInt(), SubobjType);
5137 return found(Subobj.
getFloat(), SubobjType);
5140 SubobjType->
castAs<ComplexType>()->getElementType()
5144 SubobjType->
castAs<ComplexType>()->getElementType()
5147 return foundPointer(Subobj, SubobjType);
5155 if (!checkConst(SubobjType))
5177 bool WasNegative =
Value.isNegative();
5191 unsigned BitWidth =
Value.getBitWidth();
5192 APSInt ActualValue(
Value.sext(BitWidth + 1),
false);
5193 ActualValue.setBit(BitWidth);
5199 bool found(APFloat &
Value, QualType SubobjType) {
5200 if (!checkConst(SubobjType))
5207 APFloat::opStatus St;
5209 St =
Value.add(One, RM);
5211 St =
Value.subtract(One, RM);
5214 bool foundPointer(
APValue &Subobj, QualType SubobjType) {
5215 if (!checkConst(SubobjType))
5218 QualType PointeeType;
5219 if (
const PointerType *PT = SubobjType->
getAs<PointerType>())
5227 LVal.setFrom(Info.Ctx, Subobj);
5231 LVal.moveInto(Subobj);
5240 if (LVal.Designator.Invalid)
5243 if (!Info.getLangOpts().CPlusPlus14) {
5251 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
5257 if (
Object->getType()->isPointerType() &&
Object->isPRValue())
5263 if (
Object->getType()->isLiteralType(Info.Ctx))
5266 if (
Object->getType()->isRecordType() &&
Object->isPRValue())
5269 Info.FFDiag(
Object, diag::note_constexpr_nonliteral) <<
Object->getType();
5288 bool IncludeMember =
true) {
5295 if (!MemPtr.getDecl()) {
5301 if (MemPtr.isDerivedMember()) {
5308 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
5309 LV.Designator.Entries.size()) {
5313 unsigned PathLengthToMember =
5314 LV.Designator.Entries.size() - MemPtr.Path.size();
5315 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
5317 LV.Designator.Entries[PathLengthToMember + I]);
5334 (PathLengthToMember > LV.Designator.MostDerivedPathLength)
5335 ? getAsBaseClass(LV.Designator.Entries[PathLengthToMember - 1])
5337 const CXXRecordDecl *LastMPDecl = MemPtr.getContainingRecord();
5345 PathLengthToMember))
5347 }
else if (!MemPtr.Path.empty()) {
5349 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
5350 MemPtr.Path.size() + IncludeMember);
5356 assert(RD &&
"member pointer access on non-class-type expression");
5358 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
5366 MemPtr.getContainingRecord()))
5371 if (IncludeMember) {
5372 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
5376 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
5380 llvm_unreachable(
"can't construct reference to bound member function");
5384 return MemPtr.getDecl();
5390 bool IncludeMember =
true) {
5394 if (Info.noteFailure()) {
5402 BO->
getRHS(), IncludeMember);
5409 SubobjectDesignator &D =
Result.Designator;
5417 auto InvalidCast = [&]() {
5418 if (!Info.checkingPotentialConstantExpression() ||
5419 !
Result.AllowConstexprUnknown) {
5420 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
5421 << D.MostDerivedType << TargetQT;
5427 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size())
5428 return InvalidCast();
5432 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
5435 if (NewEntriesSize == D.MostDerivedPathLength)
5438 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
5440 return InvalidCast();
5455 if (
auto *RD = T->getAsCXXRecordDecl()) {
5456 if (RD->isInvalidDecl()) {
5460 if (RD->isUnion()) {
5469 End = RD->bases_end();
5470 I != End; ++I, ++Index)
5474 for (
const auto *I : RD->fields()) {
5475 if (I->isUnnamedBitField())
5478 I->getType(),
Result.getStructField(I->getFieldIndex()));
5484 dyn_cast_or_null<ConstantArrayType>(T->getAsArrayTypeUnsafe())) {
5486 if (
Result.hasArrayFiller())
5498enum EvalStmtResult {
5527 if (!
Result.Designator.Invalid &&
Result.Designator.isOnePastTheEnd()) {
5545 APValue &Val = Info.CurrentCall->createTemporary(VD, VD->
getType(),
5546 ScopeKind::Block,
Result);
5551 return Info.noteSideEffect();
5572 const DecompositionDecl *DD);
5575 bool EvaluateConditionDecl =
false) {
5577 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
5581 EvaluateConditionDecl && DD)
5591 if (
auto *VD = BD->getHoldingVar())
5599 if (
auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
5608 if (Info.noteSideEffect())
5610 assert(E->
containsErrors() &&
"valid value-dependent expression should never "
5611 "reach invalid code path.");
5618 if (
Cond->isValueDependent())
5620 FullExpressionRAII
Scope(Info);
5627 return Scope.destroy();
5640struct TempVersionRAII {
5641 CallStackFrame &Frame;
5643 TempVersionRAII(CallStackFrame &Frame) : Frame(Frame) {
5644 Frame.pushTempVersion();
5647 ~TempVersionRAII() {
5648 Frame.popTempVersion();
5656 const SwitchCase *SC =
nullptr);
5662 const Stmt *LoopOrSwitch,
5664 EvalStmtResult &ESR) {
5668 if (!IsSwitch && ESR == ESR_Succeeded) {
5673 if (ESR != ESR_Break && ESR != ESR_Continue)
5677 bool CanBreakOrContinue = !IsSwitch || ESR == ESR_Break;
5678 const Stmt *StackTop = Info.BreakContinueStack.back();
5679 if (CanBreakOrContinue && (StackTop ==
nullptr || StackTop == LoopOrSwitch)) {
5680 Info.BreakContinueStack.pop_back();
5681 if (ESR == ESR_Break)
5682 ESR = ESR_Succeeded;
5687 for (BlockScopeRAII *S : Scopes) {
5688 if (!S->destroy()) {
5700 BlockScopeRAII
Scope(Info);
5703 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5712 BlockScopeRAII
Scope(Info);
5719 if (ESR != ESR_Succeeded) {
5720 if (ESR != ESR_Failed && !
Scope.destroy())
5726 FullExpressionRAII CondScope(Info);
5741 if (!CondScope.destroy())
5762 if (LHSValue <=
Value &&
Value <= RHSValue) {
5769 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
5773 if (ESR != ESR_Failed && ESR != ESR_CaseNotFound && !
Scope.destroy())
5780 llvm_unreachable(
"Should have been converted to Succeeded");
5786 case ESR_CaseNotFound:
5789 Info.FFDiag(
Found->getBeginLoc(),
5790 diag::note_constexpr_stmt_expr_unsupported);
5793 llvm_unreachable(
"Invalid EvalStmtResult!");
5803 Info.CCEDiag(VD->
getLocation(), diag::note_constexpr_static_local)
5813 if (!Info.nextStep(S))
5820 case Stmt::CompoundStmtClass:
5824 case Stmt::LabelStmtClass:
5825 case Stmt::AttributedStmtClass:
5826 case Stmt::DoStmtClass:
5829 case Stmt::CaseStmtClass:
5830 case Stmt::DefaultStmtClass:
5835 case Stmt::IfStmtClass: {
5842 BlockScopeRAII
Scope(Info);
5848 if (ESR != ESR_CaseNotFound) {
5849 assert(ESR != ESR_Succeeded);
5860 if (ESR == ESR_Failed)
5862 if (ESR != ESR_CaseNotFound)
5863 return Scope.destroy() ? ESR : ESR_Failed;
5865 return ESR_CaseNotFound;
5868 if (ESR == ESR_Failed)
5870 if (ESR != ESR_CaseNotFound)
5871 return Scope.destroy() ? ESR : ESR_Failed;
5872 return ESR_CaseNotFound;
5875 case Stmt::WhileStmtClass: {
5876 EvalStmtResult ESR =
5880 if (ESR != ESR_Continue)
5885 case Stmt::ForStmtClass: {
5887 BlockScopeRAII
Scope(Info);
5893 if (ESR != ESR_CaseNotFound) {
5894 assert(ESR != ESR_Succeeded);
5899 EvalStmtResult ESR =
5903 if (ESR != ESR_Continue)
5905 if (
const auto *Inc = FS->
getInc()) {
5906 if (Inc->isValueDependent()) {
5910 FullExpressionRAII IncScope(Info);
5918 case Stmt::DeclStmtClass: {
5922 for (
const auto *D : DS->
decls()) {
5923 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
5926 if (VD->hasLocalStorage() && !VD->getInit())
5934 return ESR_CaseNotFound;
5938 return ESR_CaseNotFound;
5944 if (
const Expr *E = dyn_cast<Expr>(S)) {
5953 FullExpressionRAII
Scope(Info);
5957 return ESR_Succeeded;
5963 case Stmt::NullStmtClass:
5964 return ESR_Succeeded;
5966 case Stmt::DeclStmtClass: {
5968 for (
const auto *D : DS->
decls()) {
5969 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
5973 if (
const auto *ESD = dyn_cast<CXXExpansionStmtDecl>(D)) {
5974 assert(ESD->getInstantiations() &&
"not expanded?");
5979 FullExpressionRAII
Scope(Info);
5981 !Info.noteFailure())
5983 if (!
Scope.destroy())
5986 return ESR_Succeeded;
5989 case Stmt::ReturnStmtClass: {
5991 FullExpressionRAII
Scope(Info);
6002 return Scope.destroy() ? ESR_Returned : ESR_Failed;
6005 case Stmt::CompoundStmtClass: {
6006 BlockScopeRAII
Scope(Info);
6009 for (
const auto *BI : CS->
body()) {
6011 if (ESR == ESR_Succeeded)
6013 else if (ESR != ESR_CaseNotFound) {
6014 if (ESR != ESR_Failed && !
Scope.destroy())
6020 return ESR_CaseNotFound;
6021 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6024 case Stmt::IfStmtClass: {
6028 BlockScopeRAII
Scope(Info);
6031 if (ESR != ESR_Succeeded) {
6032 if (ESR != ESR_Failed && !
Scope.destroy())
6042 if (!Info.InConstantContext)
6050 if (ESR != ESR_Succeeded) {
6051 if (ESR != ESR_Failed && !
Scope.destroy())
6056 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6059 case Stmt::WhileStmtClass: {
6062 BlockScopeRAII
Scope(Info);
6074 if (ESR != ESR_Continue) {
6075 if (ESR != ESR_Failed && !
Scope.destroy())
6079 if (!
Scope.destroy())
6082 return ESR_Succeeded;
6085 case Stmt::DoStmtClass: {
6092 if (ESR != ESR_Continue)
6101 FullExpressionRAII CondScope(Info);
6103 !CondScope.destroy())
6106 return ESR_Succeeded;
6109 case Stmt::ForStmtClass: {
6111 BlockScopeRAII ForScope(Info);
6114 if (ESR != ESR_Succeeded) {
6115 if (ESR != ESR_Failed && !ForScope.destroy())
6121 BlockScopeRAII IterScope(Info);
6122 bool Continue =
true;
6128 if (!IterScope.destroy())
6136 if (ESR != ESR_Continue) {
6137 if (ESR != ESR_Failed && (!IterScope.destroy() || !ForScope.destroy()))
6142 if (
const auto *Inc = FS->
getInc()) {
6143 if (Inc->isValueDependent()) {
6147 FullExpressionRAII IncScope(Info);
6153 if (!IterScope.destroy())
6156 return ForScope.destroy() ? ESR_Succeeded : ESR_Failed;
6159 case Stmt::CXXForRangeStmtClass: {
6161 BlockScopeRAII
Scope(Info);
6166 if (ESR != ESR_Succeeded) {
6167 if (ESR != ESR_Failed && !
Scope.destroy())
6175 if (ESR != ESR_Succeeded) {
6176 if (ESR != ESR_Failed && !
Scope.destroy())
6188 if (ESR != ESR_Succeeded) {
6189 if (ESR != ESR_Failed && !
Scope.destroy())
6194 if (ESR != ESR_Succeeded) {
6195 if (ESR != ESR_Failed && !
Scope.destroy())
6208 bool Continue =
true;
6209 FullExpressionRAII CondExpr(Info);
6217 BlockScopeRAII InnerScope(Info);
6219 if (ESR != ESR_Succeeded) {
6220 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6229 if (ESR != ESR_Continue) {
6230 if (ESR != ESR_Failed && (!InnerScope.destroy() || !
Scope.destroy()))
6243 if (!InnerScope.destroy())
6247 return Scope.destroy() ? ESR_Succeeded : ESR_Failed;
6250 case Stmt::CXXExpansionStmtInstantiationClass: {
6251 BlockScopeRAII
Scope(Info);
6253 for (
const Stmt *PreambleStmt : Expansion->getPreambleStmts()) {
6255 if (ESR != ESR_Succeeded) {
6256 if (ESR != ESR_Failed && !
Scope.destroy())
6264 EvalStmtResult ESR = ESR_Succeeded;
6265 for (
const Stmt *Instantiation : Expansion->getInstantiations()) {
6267 if (ESR == ESR_Failed ||
6270 if (ESR != ESR_Continue) {
6272 assert(ESR == ESR_Succeeded || ESR == ESR_Returned);
6278 if (ESR == ESR_Continue)
6279 ESR = ESR_Succeeded;
6281 return Scope.destroy() ? ESR : ESR_Failed;
6284 case Stmt::SwitchStmtClass:
6287 case Stmt::ContinueStmtClass:
6288 case Stmt::BreakStmtClass: {
6290 Info.BreakContinueStack.push_back(B->getNamedLoopOrSwitch());
6294 case Stmt::LabelStmtClass:
6297 case Stmt::AttributedStmtClass: {
6299 const auto *SS = AS->getSubStmt();
6300 MSConstexprContextRAII ConstexprContext(
6304 auto LO = Info.Ctx.getLangOpts();
6305 if (LO.CXXAssumptions && !LO.MSVCCompat) {
6306 for (
auto *
Attr : AS->getAttrs()) {
6307 auto *AA = dyn_cast<CXXAssumeAttr>(
Attr);
6311 auto *Assumption = AA->getAssumption();
6312 if (Assumption->isValueDependent())
6315 if (Assumption->HasSideEffects(Info.Ctx))
6322 Info.CCEDiag(Assumption->getExprLoc(),
6323 diag::note_constexpr_assumption_failed);
6332 case Stmt::CaseStmtClass:
6333 case Stmt::DefaultStmtClass:
6335 case Stmt::CXXTryStmtClass:
6347 bool IsValueInitialization) {
6354 if (!CD->
isConstexpr() && !IsValueInitialization) {
6355 if (Info.getLangOpts().CPlusPlus11) {
6358 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
6360 Info.Note(CD->
getLocation(), diag::note_declared_at);
6362 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
6376 if (Info.checkingPotentialConstantExpression() && !
Definition &&
6384 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6393 Info.CCEDiag(CallLoc, diag::note_constexpr_virtual_call);
6396 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6402 (
Definition->isConstexpr() || (Info.CurrentCall->CanEvalMSConstexpr &&
6412 StringRef Name = DiagDecl->
getName();
6414 Name ==
"__assert_rtn" || Name ==
"__assert_fail" || Name ==
"_wassert";
6416 Info.FFDiag(CallLoc, diag::note_constexpr_assert_failed);
6421 if (Info.getLangOpts().CPlusPlus11) {
6424 auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl);
6425 if (CD && CD->isInheritingConstructor()) {
6426 auto *Inherited = CD->getInheritedConstructor().getConstructor();
6427 if (!Inherited->isConstexpr())
6428 DiagDecl = CD = Inherited;
6434 if (CD && CD->isInheritingConstructor())
6435 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1)
6436 << CD->getInheritedConstructor().getConstructor()->getParent();
6438 Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1)
6440 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
6442 Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
6448struct CheckDynamicTypeHandler {
6450 typedef bool result_type;
6451 bool failed() {
return false; }
6452 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6455 bool found(
APSInt &
Value, QualType SubobjType) {
return true; }
6456 bool found(APFloat &
Value, QualType SubobjType) {
return true; }
6464 if (
This.Designator.Invalid)
6476 if (
This.Designator.isOnePastTheEnd() ||
6477 This.Designator.isMostDerivedAnUnsizedArray()) {
6478 Info.FFDiag(E,
This.Designator.isOnePastTheEnd()
6479 ? diag::note_constexpr_access_past_end
6480 : diag::note_constexpr_access_unsized_array)
6483 }
else if (Polymorphic) {
6486 if (!Info.checkingPotentialConstantExpression() ||
6487 !
This.AllowConstexprUnknown) {
6491 Info.Ctx.getLValueReferenceType(
This.Designator.getType(Info.Ctx));
6492 Info.FFDiag(E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
6500 CheckDynamicTypeHandler Handler{AK};
6523 unsigned PathLength) {
6524 assert(PathLength >=
Designator.MostDerivedPathLength && PathLength <=
6525 Designator.Entries.size() &&
"invalid path length");
6526 return (PathLength ==
Designator.MostDerivedPathLength)
6527 ?
Designator.MostDerivedType->getAsCXXRecordDecl()
6528 : getAsBaseClass(
Designator.Entries[PathLength - 1]);
6541 return std::nullopt;
6543 if (
This.Designator.Invalid)
6544 return std::nullopt;
6553 This.Designator.MostDerivedType->getAsCXXRecordDecl();
6554 if (!Class || Class->getNumVBases()) {
6556 return std::nullopt;
6564 for (
unsigned PathLength =
This.Designator.MostDerivedPathLength;
6565 PathLength <= Path.size(); ++PathLength) {
6566 switch (Info.isEvaluatingCtorDtor(
This.getLValueBase(),
6567 Path.slice(0, PathLength))) {
6568 case ConstructionPhase::Bases:
6569 case ConstructionPhase::DestroyingBases:
6574 case ConstructionPhase::None:
6575 case ConstructionPhase::AfterBases:
6576 case ConstructionPhase::AfterFields:
6577 case ConstructionPhase::Destroying:
6589 return std::nullopt;
6607 unsigned PathLength = DynType->PathLength;
6608 for (; PathLength <=
This.Designator.Entries.size(); ++PathLength) {
6611 Found->getCorrespondingMethodDeclaredInClass(Class,
false);
6621 if (Callee->isPureVirtual()) {
6622 Info.FFDiag(E, diag::note_constexpr_pure_virtual_call, 1) << Callee;
6623 Info.Note(Callee->getLocation(), diag::note_declared_at);
6629 if (!Info.Ctx.hasSameUnqualifiedType(Callee->getReturnType(),
6630 Found->getReturnType())) {
6631 CovariantAdjustmentPath.push_back(Callee->getReturnType());
6632 for (
unsigned CovariantPathLength = PathLength + 1;
6633 CovariantPathLength !=
This.Designator.Entries.size();
6634 ++CovariantPathLength) {
6638 Found->getCorrespondingMethodDeclaredInClass(NextClass,
false);
6639 if (
Next && !Info.Ctx.hasSameUnqualifiedType(
6640 Next->getReturnType(), CovariantAdjustmentPath.back()))
6641 CovariantAdjustmentPath.push_back(
Next->getReturnType());
6643 if (!Info.Ctx.hasSameUnqualifiedType(
Found->getReturnType(),
6644 CovariantAdjustmentPath.back()))
6645 CovariantAdjustmentPath.push_back(
Found->getReturnType());
6661 assert(
Result.isLValue() &&
6662 "unexpected kind of APValue for covariant return");
6663 if (
Result.isNullPointer())
6667 LVal.setFrom(Info.Ctx,
Result);
6669 const CXXRecordDecl *OldClass = Path[0]->getPointeeCXXRecordDecl();
6670 for (
unsigned I = 1; I != Path.size(); ++I) {
6671 const CXXRecordDecl *NewClass = Path[I]->getPointeeCXXRecordDecl();
6672 assert(OldClass && NewClass &&
"unexpected kind of covariant return");
6673 if (OldClass != NewClass &&
6676 OldClass = NewClass;
6688 auto *BaseClass = BaseSpec.getType()->getAsCXXRecordDecl();
6690 return BaseSpec.getAccessSpecifier() ==
AS_public;
6692 llvm_unreachable(
"Base is not a direct base of Derived");
6702 SubobjectDesignator &D = Ptr.Designator;
6708 if (Ptr.isNullPointer() && !E->
isGLValue())
6714 std::optional<DynamicType> DynType =
6726 assert(
C &&
"dynamic_cast target is not void pointer nor class");
6734 Ptr.setNull(Info.Ctx, E->
getType());
6741 DynType->Type->isDerivedFrom(
C)))
6743 else if (!Paths || Paths->begin() == Paths->end())
6745 else if (Paths->isAmbiguous(CQT))
6748 assert(Paths->front().Access !=
AS_public &&
"why did the cast fail?");
6751 Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
6752 << DiagKind << Ptr.Designator.getType(Info.Ctx)
6753 << Info.Ctx.getCanonicalTagType(DynType->Type)
6761 for (
int PathLength = Ptr.Designator.Entries.size();
6762 PathLength >= (
int)DynType->PathLength; --PathLength) {
6767 if (PathLength > (
int)DynType->PathLength &&
6770 return RuntimeCheckFailed(
nullptr);
6777 if (DynType->Type->isDerivedFrom(
C, Paths) && !Paths.
isAmbiguous(CQT) &&
6790 return RuntimeCheckFailed(&Paths);
6794struct StartLifetimeOfUnionMemberHandler {
6796 const Expr *LHSExpr;
6797 const FieldDecl *
Field;
6799 bool Failed =
false;
6802 typedef bool result_type;
6803 bool failed() {
return Failed; }
6804 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
6819 }
else if (DuringInit) {
6823 Info.FFDiag(LHSExpr,
6824 diag::note_constexpr_union_member_change_during_init);
6833 llvm_unreachable(
"wrong value kind for union object");
6835 bool found(APFloat &
Value, QualType SubobjType) {
6836 llvm_unreachable(
"wrong value kind for union object");
6841const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
6848 const Expr *LHSExpr,
6849 const LValue &LHS) {
6850 if (LHS.InvalidBase || LHS.Designator.Invalid)
6856 unsigned PathLength = LHS.Designator.Entries.size();
6857 for (
const Expr *E = LHSExpr; E !=
nullptr;) {
6859 if (
auto *ME = dyn_cast<MemberExpr>(E)) {
6860 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
6863 if (!FD || FD->getType()->isReferenceType())
6867 if (FD->getParent()->isUnion()) {
6872 FD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6873 if (!RD || RD->hasTrivialDefaultConstructor())
6874 UnionPathLengths.push_back({PathLength - 1, FD});
6880 LHS.Designator.Entries[PathLength]
6881 .getAsBaseOrMember().getPointer()));
6885 }
else if (
auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
6887 auto *
Base = ASE->getBase()->IgnoreImplicit();
6888 if (!
Base->getType()->isArrayType())
6894 }
else if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
6897 if (ICE->getCastKind() == CK_NoOp)
6899 if (ICE->getCastKind() != CK_DerivedToBase &&
6900 ICE->getCastKind() != CK_UncheckedDerivedToBase)
6904 if (Elt->isVirtual()) {
6913 LHS.Designator.Entries[PathLength]
6914 .getAsBaseOrMember().getPointer()));
6924 if (UnionPathLengths.empty())
6929 CompleteObject Obj =
6933 for (std::pair<unsigned, const FieldDecl *> LengthAndField :
6934 llvm::reverse(UnionPathLengths)) {
6936 SubobjectDesignator D = LHS.Designator;
6937 D.truncate(Info.Ctx, LHS.Base, LengthAndField.first);
6939 bool DuringInit = Info.isEvaluatingCtorDtor(LHS.Base, D.Entries) ==
6940 ConstructionPhase::AfterBases;
6941 StartLifetimeOfUnionMemberHandler StartLifetime{
6942 Info, LHSExpr, LengthAndField.second, DuringInit};
6951 CallRef
Call, EvalInfo &Info,
bool NonNull =
false,
6952 APValue **EvaluatedArg =
nullptr) {
6959 APValue &
V = PVD ? Info.CurrentCall->createParam(
Call, PVD, LV)
6960 : Info.CurrentCall->createTemporary(Arg, Arg->
getType(),
6961 ScopeKind::Call, LV);
6967 if (
NonNull &&
V.isLValue() &&
V.isNullPointer()) {
6968 Info.CCEDiag(Arg, diag::note_non_null_attribute_failed);
6981 bool RightToLeft =
false,
6982 LValue *ObjectArg =
nullptr) {
6984 llvm::SmallBitVector ForbiddenNullArgs;
6985 if (Callee->hasAttr<NonNullAttr>()) {
6986 ForbiddenNullArgs.resize(Args.size());
6987 for (
const auto *
Attr : Callee->specific_attrs<NonNullAttr>()) {
6988 if (!
Attr->args_size()) {
6989 ForbiddenNullArgs.set();
6992 for (
auto Idx :
Attr->args()) {
6993 unsigned ASTIdx = Idx.getASTIndex();
6994 if (ASTIdx >= Args.size())
6996 ForbiddenNullArgs[ASTIdx] =
true;
7000 for (
unsigned I = 0; I < Args.size(); I++) {
7001 unsigned Idx = RightToLeft ? Args.size() - I - 1 : I;
7003 Idx < Callee->getNumParams() ? Callee->getParamDecl(Idx) :
nullptr;
7004 bool NonNull = !ForbiddenNullArgs.empty() && ForbiddenNullArgs[Idx];
7009 if (!Info.noteFailure())
7014 ObjectArg->setFrom(Info.Ctx, *That);
7023 bool CopyObjectRepresentation) {
7025 CallStackFrame *Frame = Info.CurrentCall;
7026 APValue *RefValue = Info.getParamSlot(Frame->Arguments, Param);
7034 RefLValue.setFrom(Info.Ctx, *RefValue);
7037 CopyObjectRepresentation);
7043 const LValue *ObjectArg,
const Expr *E,
7045 const Stmt *Body, EvalInfo &Info,
7047 if (!Info.CheckCallLimit(CallLoc))
7060 auto IsTrivialMemoryOperation = [&](
const CXXMethodDecl *MD) {
7070 if (IsTrivialMemoryOperation(MD)) {
7083 ObjectArg->moveInto(
Result);
7092 if (!Info.checkingPotentialConstantExpression())
7094 Frame.LambdaThisCaptureField);
7097 StmtResult Ret = {
Result, ResultSlot};
7099 if (ESR == ESR_Succeeded) {
7100 if (Callee->getReturnType()->isVoidType())
7102 Info.FFDiag(Callee->getEndLoc(), diag::note_constexpr_no_return);
7104 return ESR == ESR_Returned;
7113 if (!Info.CheckCallLimit(CallLoc))
7118 Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD;
7122 EvalInfo::EvaluatingConstructorRAII EvalObj(
7124 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
7131 StmtResult Ret = {RetVal,
nullptr};
7136 if ((*I)->getInit()->isValueDependent()) {
7140 FullExpressionRAII InitScope(Info);
7142 !InitScope.destroy())
7165 if (!
Result.hasValue()) {
7178 BlockScopeRAII LifetimeExtendedScope(Info);
7181 unsigned BasesSeen = 0;
7186 auto SkipToField = [&](
FieldDecl *FD,
bool Indirect) {
7191 assert(Indirect &&
"fields out of order?");
7197 assert(FieldIt != RD->
field_end() &&
"missing field?");
7198 if (!FieldIt->isUnnamedBitField())
7201 Result.getStructField(FieldIt->getFieldIndex()));
7206 LValue Subobject =
This;
7207 LValue SubobjectParent =
This;
7212 if (I->isBaseInitializer()) {
7213 QualType BaseType(I->getBaseClass(), 0);
7217 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
7218 assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->
getType(), BaseType) &&
7219 "base class initializers not in expected order");
7223 BaseType->getAsCXXRecordDecl(), &Layout))
7226 }
else if ((FD = I->getMember())) {
7233 SkipToField(FD,
false);
7239 auto IndirectFieldChain = IFD->chain();
7240 for (
auto *
C : IndirectFieldChain) {
7249 (
Value->isUnion() &&
7262 if (
C == IndirectFieldChain.back())
7263 SubobjectParent = Subobject;
7269 if (
C == IndirectFieldChain.front() && !RD->
isUnion())
7270 SkipToField(FD,
true);
7275 llvm_unreachable(
"unknown base initializer kind");
7282 if (
Init->isValueDependent()) {
7286 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &SubobjectParent,
7288 FullExpressionRAII InitScope(Info);
7294 if (!Info.noteFailure())
7303 if (!Info.noteFailure())
7311 if (I->isBaseInitializer() && BasesSeen == RD->
getNumBases())
7312 EvalObj.finishedConstructingBases();
7317 for (; FieldIt != RD->
field_end(); ++FieldIt) {
7318 if (!FieldIt->isUnnamedBitField())
7321 Result.getStructField(FieldIt->getFieldIndex()));
7325 EvalObj.finishedConstructingFields();
7329 LifetimeExtendedScope.destroy();
7336 CallScopeRAII CallScope(Info);
7342 CallScope.destroy();
7352 if (
Value.isAbsent() && !T->isNullPtrType()) {
7354 This.moveInto(Printable);
7356 diag::note_constexpr_destroy_out_of_lifetime)
7357 << Printable.
getAsString(Info.Ctx, Info.Ctx.getLValueReferenceType(T));
7373 LValue ElemLV =
This;
7374 ElemLV.addArray(Info, &LocE, CAT);
7381 if (Size && Size >
Value.getArrayInitializedElts())
7386 for (Size =
Value.getArraySize(); Size != 0; --Size) {
7387 APValue &Elem =
Value.getArrayInitializedElt(Size - 1);
7400 if (T.isDestructedType()) {
7402 diag::note_constexpr_unsupported_destruction)
7412 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_virtual_base) << RD;
7437 if (!Info.CheckCallLimit(CallRange.
getBegin()))
7446 CallStackFrame Frame(Info, CallRange,
Definition, &
This,
nullptr,
7451 EvalInfo::EvaluatingDestructorRAII EvalObj(
7453 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries});
7454 if (!EvalObj.DidInsert) {
7461 Info.FFDiag(CallRange.
getBegin(), diag::note_constexpr_double_destroy);
7468 StmtResult Ret = {RetVal,
nullptr};
7481 for (
const FieldDecl *FD : llvm::reverse(Fields)) {
7482 if (FD->isUnnamedBitField())
7485 LValue Subobject =
This;
7489 APValue *SubobjectValue = &
Value.getStructField(FD->getFieldIndex());
7496 EvalObj.startedDestroyingBases();
7503 LValue Subobject =
This;
7505 BaseType->getAsCXXRecordDecl(), &Layout))
7508 APValue *SubobjectValue = &
Value.getStructBase(BasesLeft);
7513 assert(BasesLeft == 0 &&
"NumBases was wrong?");
7521struct DestroyObjectHandler {
7527 typedef bool result_type;
7528 bool failed() {
return false; }
7529 bool found(
APValue &Subobj, QualType SubobjType, APValue::LValueBase Base) {
7534 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7537 bool found(APFloat &
Value, QualType SubobjType) {
7538 Info.FFDiag(E, diag::note_constexpr_destroy_complex_elem);
7559 if (Info.EvalStatus.HasSideEffects)
7570 if (Info.checkingPotentialConstantExpression() ||
7571 Info.SpeculativeEvaluationDepth)
7575 auto Caller = Info.getStdAllocatorCaller(
"allocate");
7577 Info.FFDiag(E->
getExprLoc(), Info.getLangOpts().CPlusPlus20
7578 ? diag::note_constexpr_new_untyped
7579 : diag::note_constexpr_new);
7583 QualType ElemType = Caller.ElemType;
7586 diag::note_constexpr_new_not_complete_object_type)
7594 bool IsNothrow =
false;
7595 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I) {
7603 APInt Size, Remainder;
7604 APInt ElemSizeAP(ByteSize.getBitWidth(), ElemSize.
getQuantity());
7605 APInt::udivrem(ByteSize, ElemSizeAP, Size, Remainder);
7606 if (Remainder != 0) {
7608 Info.FFDiag(E->
getExprLoc(), diag::note_constexpr_operator_new_bad_size)
7609 << ByteSize <<
APSInt(ElemSizeAP,
true) << ElemType;
7613 if (!Info.CheckArraySize(E->
getBeginLoc(), ByteSize.getActiveBits(),
7614 Size.getZExtValue(), !IsNothrow)) {
7622 QualType AllocType = Info.Ctx.getConstantArrayType(
7624 APValue *Val = Info.createHeapAlloc(Caller.Call, AllocType,
Result);
7633 return DD->isVirtual();
7640 return DD->isVirtual() ? DD->getOperatorDelete() :
nullptr;
7651 DynAlloc::Kind DeallocKind) {
7652 auto PointerAsString = [&] {
7653 return Pointer.toString(Info.Ctx, Info.Ctx.VoidPtrTy);
7658 Info.FFDiag(E, diag::note_constexpr_delete_not_heap_alloc)
7659 << PointerAsString();
7662 return std::nullopt;
7665 std::optional<DynAlloc *> Alloc = Info.lookupDynamicAlloc(DA);
7667 Info.FFDiag(E, diag::note_constexpr_double_delete);
7668 return std::nullopt;
7671 if (DeallocKind != (*Alloc)->getKind()) {
7673 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
7674 << DeallocKind << (*Alloc)->getKind() << AllocType;
7676 return std::nullopt;
7679 bool Subobject =
false;
7680 if (DeallocKind == DynAlloc::New) {
7681 Subobject =
Pointer.Designator.MostDerivedPathLength != 0 ||
7682 Pointer.Designator.isOnePastTheEnd();
7684 Subobject =
Pointer.Designator.Entries.size() != 1 ||
7685 Pointer.Designator.Entries[0].getAsArrayIndex() != 0;
7688 Info.FFDiag(E, diag::note_constexpr_delete_subobject)
7689 << PointerAsString() <<
Pointer.Designator.isOnePastTheEnd();
7690 return std::nullopt;
7698 if (Info.checkingPotentialConstantExpression() ||
7699 Info.SpeculativeEvaluationDepth)
7703 if (!Info.getStdAllocatorCaller(
"deallocate")) {
7711 for (
unsigned I = 1, N = E->
getNumArgs(); I != N; ++I)
7714 if (
Pointer.Designator.Invalid)
7719 if (
Pointer.isNullPointer()) {
7720 Info.CCEDiag(E->
getExprLoc(), diag::note_constexpr_deallocate_null);
7736class BitCastBuffer {
7742 SmallVector<std::optional<unsigned char>, 32> Bytes;
7744 static_assert(std::numeric_limits<unsigned char>::digits >= 8,
7745 "Need at least 8 bit unsigned char");
7747 bool TargetIsLittleEndian;
7750 BitCastBuffer(CharUnits Width,
bool TargetIsLittleEndian)
7751 : Bytes(Width.getQuantity()),
7752 TargetIsLittleEndian(TargetIsLittleEndian) {}
7754 [[nodiscard]]
bool readObject(CharUnits Offset, CharUnits Width,
7755 SmallVectorImpl<unsigned char> &Output)
const {
7756 for (CharUnits I = Offset, E = Offset + Width; I != E; ++I) {
7759 if (!Bytes[I.getQuantity()])
7761 Output.push_back(*Bytes[I.getQuantity()]);
7763 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7764 std::reverse(Output.begin(), Output.end());
7768 void writeObject(CharUnits Offset, SmallVectorImpl<unsigned char> &Input) {
7769 if (llvm::sys::IsLittleEndianHost != TargetIsLittleEndian)
7770 std::reverse(Input.begin(), Input.end());
7773 for (
unsigned char Byte : Input) {
7774 assert(!Bytes[Offset.
getQuantity() + Index] &&
"overwriting a byte?");
7780 size_t size() {
return Bytes.size(); }
7785class APValueToBufferConverter {
7787 BitCastBuffer Buffer;
7790 APValueToBufferConverter(EvalInfo &Info, CharUnits ObjectWidth,
7793 Buffer(ObjectWidth, Info.Ctx.getTargetInfo().isLittleEndian()),
7796 bool visit(
const APValue &Val, QualType Ty) {
7801 bool visit(
const APValue &Val, QualType Ty, CharUnits Offset) {
7802 assert((
size_t)Offset.
getQuantity() <= Buffer.size());
7815 return visitInt(Val.
getInt(), Ty, Offset);
7817 return visitFloat(Val.
getFloat(), Ty, Offset);
7819 return visitArray(Val, Ty, Offset);
7821 return visitRecord(Val, Ty, Offset);
7823 return visitVector(Val, Ty, Offset);
7827 return visitComplex(Val, Ty, Offset);
7837 diag::note_constexpr_bit_cast_unsupported_type)
7842 llvm_unreachable(
"Unhandled APValue::ValueKind");
7845 bool visitRecord(
const APValue &Val, QualType Ty, CharUnits Offset) {
7847 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
7850 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
7851 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
7852 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
7857 if (!
Base.isStruct())
7860 if (!visitRecord(Base, BS.
getType(),
7867 unsigned FieldIdx = 0;
7868 for (FieldDecl *FD : RD->
fields()) {
7869 if (FD->isBitField()) {
7871 diag::note_constexpr_bit_cast_unsupported_bitfield);
7877 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0 &&
7878 "only bit-fields can have sub-char alignment");
7879 CharUnits FieldOffset =
7880 Info.Ctx.toCharUnitsFromBits(FieldOffsetBits) + Offset;
7881 QualType FieldTy = FD->getType();
7890 bool visitArray(
const APValue &Val, QualType Ty, CharUnits Offset) {
7896 CharUnits ElemWidth = Info.Ctx.getTypeSizeInChars(CAT->
getElementType());
7900 for (
unsigned I = 0; I != NumInitializedElts; ++I) {
7902 if (!visit(SubObj, CAT->
getElementType(), Offset + I * ElemWidth))
7909 for (
unsigned I = NumInitializedElts; I != ArraySize; ++I) {
7910 if (!visit(Filler, CAT->
getElementType(), Offset + I * ElemWidth))
7918 bool visitComplex(
const APValue &Val, QualType Ty, CharUnits Offset) {
7919 const ComplexType *ComplexTy = Ty->
castAs<ComplexType>();
7921 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7926 Offset + (0 * EltSizeChars)))
7929 Offset + (1 * EltSizeChars)))
7933 Offset + (0 * EltSizeChars)))
7936 Offset + (1 * EltSizeChars)))
7943 bool visitVector(
const APValue &Val, QualType Ty, CharUnits Offset) {
7944 const VectorType *VTy = Ty->
castAs<VectorType>();
7957 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
7959 llvm::APInt Res = llvm::APInt::getZero(NElts);
7960 for (
unsigned I = 0; I < NElts; ++I) {
7962 assert(EltAsInt.isUnsigned() && EltAsInt.getBitWidth() == 1 &&
7963 "bool vector element must be 1-bit unsigned integer!");
7965 Res.insertBits(EltAsInt, BigEndian ? (NElts - I - 1) : I);
7968 SmallVector<uint8_t, 8> Bytes(NElts / 8);
7969 llvm::StoreIntToMemory(Res, &*Bytes.begin(), NElts / 8);
7970 Buffer.writeObject(Offset, Bytes);
7974 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
7975 for (
unsigned I = 0; I < NElts; ++I) {
7976 if (!visit(Val.
getVectorElt(I), EltTy, Offset + I * EltSizeChars))
7984 bool visitInt(
const APSInt &Val, QualType Ty, CharUnits Offset) {
7985 APSInt AdjustedVal = Val;
7986 unsigned Width = AdjustedVal.getBitWidth();
7988 Width = Info.Ctx.getTypeSize(Ty);
7989 AdjustedVal = AdjustedVal.extend(Width);
7992 SmallVector<uint8_t, 8> Bytes(Width / 8);
7993 llvm::StoreIntToMemory(AdjustedVal, &*Bytes.begin(), Width / 8);
7994 Buffer.writeObject(Offset, Bytes);
7998 bool visitFloat(
const APFloat &Val, QualType Ty, CharUnits Offset) {
7999 APSInt AsInt(Val.bitcastToAPInt());
8000 return visitInt(AsInt, Ty, Offset);
8004 static std::optional<BitCastBuffer>
8006 CharUnits DstSize = Info.Ctx.getTypeSizeInChars(BCE->
getType());
8007 APValueToBufferConverter Converter(Info, DstSize, BCE);
8009 return std::nullopt;
8010 return Converter.Buffer;
8015class BufferToAPValueConverter {
8017 const BitCastBuffer &Buffer;
8020 BufferToAPValueConverter(EvalInfo &Info,
const BitCastBuffer &Buffer,
8022 : Info(Info), Buffer(Buffer), BCE(BCE) {}
8027 std::nullopt_t unsupportedType(QualType Ty) {
8029 diag::note_constexpr_bit_cast_unsupported_type)
8031 return std::nullopt;
8034 std::nullopt_t unrepresentableValue(QualType Ty,
const APSInt &Val) {
8036 diag::note_constexpr_bit_cast_unrepresentable_value)
8038 return std::nullopt;
8041 std::optional<APValue> visit(
const BuiltinType *T, CharUnits Offset,
8042 const EnumType *EnumSugar =
nullptr) {
8044 uint64_t NullValue = Info.Ctx.getTargetNullPointerValue(QualType(T, 0));
8045 return APValue((Expr *)
nullptr,
8047 APValue::NoLValuePath{},
true);
8050 CharUnits
SizeOf = Info.Ctx.getTypeSizeInChars(T);
8056 const llvm::fltSemantics &Semantics =
8057 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8058 unsigned NumBits = llvm::APFloatBase::getSizeInBits(Semantics);
8059 assert(NumBits % 8 == 0);
8065 SmallVector<uint8_t, 8> Bytes;
8066 if (!Buffer.readObject(Offset,
SizeOf, Bytes)) {
8069 bool IsStdByte = EnumSugar && EnumSugar->isStdByteType();
8073 if (!IsStdByte && !IsUChar) {
8074 QualType DisplayType(EnumSugar ? (
const Type *)EnumSugar : T, 0);
8076 diag::note_constexpr_bit_cast_indet_dest)
8077 << DisplayType << Info.Ctx.getLangOpts().CharIsSigned;
8078 return std::nullopt;
8084 APSInt Val(
SizeOf.getQuantity() * Info.Ctx.getCharWidth(),
true);
8085 llvm::LoadIntFromMemory(Val, &*Bytes.begin(), Bytes.size());
8090 unsigned IntWidth = Info.Ctx.getIntWidth(QualType(T, 0));
8091 if (IntWidth != Val.getBitWidth()) {
8092 APSInt Truncated = Val.trunc(IntWidth);
8093 if (Truncated.extend(Val.getBitWidth()) != Val)
8094 return unrepresentableValue(QualType(T, 0), Val);
8102 const llvm::fltSemantics &Semantics =
8103 Info.Ctx.getFloatTypeSemantics(QualType(T, 0));
8107 return unsupportedType(QualType(T, 0));
8110 std::optional<APValue> visit(
const RecordType *RTy, CharUnits Offset) {
8111 const RecordDecl *RD = RTy->getAsRecordDecl();
8113 return std::nullopt;
8114 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
8116 unsigned NumBases = 0;
8117 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
8118 NumBases = CXXRD->getNumBases();
8123 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
8124 for (
size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
8125 const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
8128 std::optional<APValue> SubObj = visitType(
8131 return std::nullopt;
8132 ResultVal.getStructBase(I) = *SubObj;
8137 unsigned FieldIdx = 0;
8138 for (FieldDecl *FD : RD->
fields()) {
8141 if (FD->isBitField()) {
8143 diag::note_constexpr_bit_cast_unsupported_bitfield);
8144 return std::nullopt;
8148 assert(FieldOffsetBits % Info.Ctx.getCharWidth() == 0);
8150 CharUnits FieldOffset =
8153 QualType FieldTy = FD->getType();
8154 std::optional<APValue> SubObj = visitType(FieldTy, FieldOffset);
8156 return std::nullopt;
8157 ResultVal.getStructField(FieldIdx) = *SubObj;
8164 std::optional<APValue> visit(
const EnumType *Ty, CharUnits Offset) {
8165 QualType RepresentationType =
8166 Ty->getDecl()->getDefinitionOrSelf()->getIntegerType();
8167 assert(!RepresentationType.
isNull() &&
8168 "enum forward decl should be caught by Sema");
8169 const auto *AsBuiltin =
8173 return visit(AsBuiltin, Offset, Ty);
8176 std::optional<APValue> visit(
const ConstantArrayType *Ty, CharUnits Offset) {
8178 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->
getElementType());
8180 APValue ArrayValue(APValue::UninitArray(), Size, Size);
8181 for (
size_t I = 0; I !=
Size; ++I) {
8182 std::optional<APValue> ElementValue =
8185 return std::nullopt;
8186 ArrayValue.getArrayInitializedElt(I) = std::move(*ElementValue);
8192 std::optional<APValue> visit(
const ComplexType *Ty, CharUnits Offset) {
8194 CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(ElementType);
8197 std::optional<APValue> Values[2];
8198 for (
unsigned I = 0; I != 2; ++I) {
8199 Values[I] = visitType(Ty->
getElementType(), Offset + I * ElementWidth);
8201 return std::nullopt;
8205 return APValue(Values[0]->getInt(), Values[1]->getInt());
8206 return APValue(Values[0]->getFloat(), Values[1]->getFloat());
8209 std::optional<APValue> visit(
const VectorType *VTy, CharUnits Offset) {
8215 SmallVector<APValue, 4> Elts;
8216 Elts.reserve(NElts);
8226 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
8228 SmallVector<uint8_t, 8> Bytes;
8229 Bytes.reserve(NElts / 8);
8231 return std::nullopt;
8233 APSInt SValInt(NElts,
true);
8234 llvm::LoadIntFromMemory(SValInt, &*Bytes.begin(), Bytes.size());
8236 for (
unsigned I = 0; I < NElts; ++I) {
8238 SValInt.extractBits(1, (BigEndian ? NElts - I - 1 : I) * EltSize);
8245 CharUnits EltSizeChars = Info.Ctx.getTypeSizeInChars(EltTy);
8246 for (
unsigned I = 0; I < NElts; ++I) {
8247 std::optional<APValue> EltValue =
8248 visitType(EltTy, Offset + I * EltSizeChars);
8250 return std::nullopt;
8251 Elts.push_back(std::move(*EltValue));
8255 return APValue(Elts.data(), Elts.size());
8258 std::optional<APValue> visit(
const Type *Ty, CharUnits Offset) {
8259 return unsupportedType(QualType(Ty, 0));
8262 std::optional<APValue> visitType(QualType Ty, CharUnits Offset) {
8266#define TYPE(Class, Base) \
8268 return visit(cast<Class##Type>(Can.getTypePtr()), Offset);
8269#define ABSTRACT_TYPE(Class, Base)
8270#define NON_CANONICAL_TYPE(Class, Base) \
8272 llvm_unreachable("non-canonical type should be impossible!");
8273#define DEPENDENT_TYPE(Class, Base) \
8276 "dependent types aren't supported in the constant evaluator!");
8277#define NON_CANONICAL_UNLESS_DEPENDENT(Class, Base) \
8279 llvm_unreachable("either dependent or not canonical!");
8280#include "clang/AST/TypeNodes.inc"
8282 llvm_unreachable(
"Unhandled Type::TypeClass");
8287 static std::optional<APValue> convert(EvalInfo &Info, BitCastBuffer &Buffer,
8289 BufferToAPValueConverter Converter(Info, Buffer, BCE);
8294static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
8295 QualType Ty, EvalInfo *Info,
8296 const ASTContext &Ctx,
8297 bool CheckingDest) {
8300 auto diag = [&](
int Reason) {
8302 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_type)
8303 << CheckingDest << (Reason == 4) << Reason;
8306 auto note = [&](
int Construct, QualType NoteTy, SourceLocation NoteLoc) {
8308 Info->Note(NoteLoc, diag::note_constexpr_bit_cast_invalid_subtype)
8309 << NoteTy << Construct << Ty;
8323 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(
Record)) {
8324 for (CXXBaseSpecifier &BS : CXXRD->bases())
8325 if (!checkBitCastConstexprEligibilityType(Loc, BS.
getType(), Info, Ctx,
8329 for (FieldDecl *FD :
Record->fields()) {
8330 if (FD->getType()->isReferenceType())
8332 if (!checkBitCastConstexprEligibilityType(Loc, FD->getType(), Info, Ctx,
8334 return note(0, FD->getType(), FD->getBeginLoc());
8340 Info, Ctx, CheckingDest))
8343 if (
const auto *VTy = Ty->
getAs<VectorType>()) {
8355 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector)
8356 << QualType(VTy, 0) << EltSize << NElts << Ctx.
getCharWidth();
8366 Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type)
8375static bool checkBitCastConstexprEligibility(EvalInfo *Info,
8376 const ASTContext &Ctx,
8378 bool DestOK = checkBitCastConstexprEligibilityType(
8380 bool SourceOK = DestOK && checkBitCastConstexprEligibilityType(
8386static bool handleRValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8389 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8390 "no host or target supports non 8-bit chars");
8392 if (!checkBitCastConstexprEligibility(&Info, Info.Ctx, BCE))
8396 std::optional<BitCastBuffer> Buffer =
8397 APValueToBufferConverter::convert(Info, SourceRValue, BCE);
8402 std::optional<APValue> MaybeDestValue =
8403 BufferToAPValueConverter::convert(Info, *Buffer, BCE);
8404 if (!MaybeDestValue)
8407 DestValue = std::move(*MaybeDestValue);
8411static bool handleLValueToRValueBitCast(EvalInfo &Info,
APValue &DestValue,
8414 assert(
CHAR_BIT == 8 && Info.Ctx.getTargetInfo().getCharWidth() == 8 &&
8415 "no host or target supports non 8-bit chars");
8417 "LValueToRValueBitcast requires an lvalue operand!");
8419 LValue SourceLValue;
8421 SourceLValue.setFrom(Info.Ctx, SourceValue);
8424 SourceRValue,
true))
8427 return handleRValueToRValueBitCast(Info, DestValue, SourceRValue, BCE);
8430template <
class Derived>
8431class ExprEvaluatorBase
8432 :
public ConstStmtVisitor<Derived, bool> {
8434 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8435 bool DerivedSuccess(
const APValue &
V,
const Expr *E) {
8436 return getDerived().Success(
V, E);
8438 bool DerivedZeroInitialization(
const Expr *E) {
8439 return getDerived().ZeroInitialization(E);
8445 template<
typename ConditionalOperator>
8446 void CheckPotentialConstantConditional(
const ConditionalOperator *E) {
8447 assert(Info.checkingPotentialConstantExpression());
8450 SmallVector<PartialDiagnosticAt, 8>
Diag;
8452 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8459 SpeculativeEvaluationRAII Speculate(Info, &
Diag);
8461 Info.EvalStatus.DiagEmitted =
false;
8467 Error(E, diag::note_constexpr_conditional_never_const);
8471 template<
typename ConditionalOperator>
8472 bool HandleConditionalOperator(
const ConditionalOperator *E) {
8475 if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
8476 CheckPotentialConstantConditional(E);
8479 if (Info.noteFailure()) {
8487 return StmtVisitorTy::Visit(EvalExpr);
8492 typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
8493 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
8495 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
8496 return Info.CCEDiag(E, D);
8499 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
8501 bool IsConstantEvaluatedBuiltinCall(
const CallExpr *E) {
8503 return BuiltinOp != 0 &&
8504 Info.Ctx.BuiltinInfo.isConstantEvaluated(BuiltinOp);
8508 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
8510 EvalInfo &getEvalInfo() {
return Info; }
8518 bool Error(
const Expr *E) {
8519 return Error(E, diag::note_invalid_subexpr_in_const_expr);
8522 bool VisitStmt(
const Stmt *) {
8523 llvm_unreachable(
"Expression evaluator should not be called on stmts");
8525 bool VisitExpr(
const Expr *E) {
8529 bool VisitEmbedExpr(
const EmbedExpr *E) {
8530 const auto It = E->
begin();
8531 return StmtVisitorTy::Visit(*It);
8534 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
8537 bool VisitConstantExpr(
const ConstantExpr *E) {
8541 return StmtVisitorTy::Visit(E->
getSubExpr());
8544 bool VisitParenExpr(
const ParenExpr *E)
8545 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8546 bool VisitUnaryExtension(
const UnaryOperator *E)
8547 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8548 bool VisitUnaryPlus(
const UnaryOperator *E)
8549 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
8550 bool VisitChooseExpr(
const ChooseExpr *E)
8552 bool VisitGenericSelectionExpr(
const GenericSelectionExpr *E)
8554 bool VisitSubstNonTypeTemplateParmExpr(
const SubstNonTypeTemplateParmExpr *E)
8556 bool VisitCXXDefaultArgExpr(
const CXXDefaultArgExpr *E) {
8557 TempVersionRAII RAII(*Info.CurrentCall);
8558 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8559 return StmtVisitorTy::Visit(E->
getExpr());
8561 bool VisitCXXDefaultInitExpr(
const CXXDefaultInitExpr *E) {
8562 TempVersionRAII RAII(*Info.CurrentCall);
8566 SourceLocExprScopeGuard Guard(E, Info.CurrentCall->CurSourceLocExprScope);
8567 return StmtVisitorTy::Visit(E->
getExpr());
8570 bool VisitExprWithCleanups(
const ExprWithCleanups *E) {
8571 FullExpressionRAII Scope(Info);
8572 return StmtVisitorTy::Visit(E->
getSubExpr()) && Scope.destroy();
8577 bool VisitCXXBindTemporaryExpr(
const CXXBindTemporaryExpr *E) {
8578 return StmtVisitorTy::Visit(E->
getSubExpr());
8581 bool VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
8582 CCEDiag(E, diag::note_constexpr_invalid_cast)
8583 << diag::ConstexprInvalidCastKind::Reinterpret;
8584 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8586 bool VisitCXXDynamicCastExpr(
const CXXDynamicCastExpr *E) {
8587 if (!Info.Ctx.getLangOpts().CPlusPlus20)
8588 CCEDiag(E, diag::note_constexpr_invalid_cast)
8589 << diag::ConstexprInvalidCastKind::Dynamic;
8590 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8592 bool VisitBuiltinBitCastExpr(
const BuiltinBitCastExpr *E) {
8593 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
8596 bool VisitBinaryOperator(
const BinaryOperator *E) {
8602 VisitIgnoredValue(E->
getLHS());
8603 return StmtVisitorTy::Visit(E->
getRHS());
8613 return DerivedSuccess(
Result, E);
8618 bool VisitCXXRewrittenBinaryOperator(
const CXXRewrittenBinaryOperator *E) {
8622 bool VisitBinaryConditionalOperator(
const BinaryConditionalOperator *E) {
8626 if (!
Evaluate(Info.CurrentCall->createTemporary(
8629 ScopeKind::FullExpression, CommonLV),
8633 return HandleConditionalOperator(E);
8636 bool VisitConditionalOperator(
const ConditionalOperator *E) {
8637 bool IsBcpCall =
false;
8642 if (
const CallExpr *CallCE =
8644 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
8651 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
8654 FoldConstant Fold(Info, IsBcpCall);
8655 if (!HandleConditionalOperator(E)) {
8656 Fold.keepDiagnostics();
8663 bool VisitOpaqueValueExpr(
const OpaqueValueExpr *E) {
8664 if (
APValue *
Value = Info.CurrentCall->getCurrentTemporary(E);
8666 return DerivedSuccess(*
Value, E);
8672 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
8675 return StmtVisitorTy::Visit(Source);
8678 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *E) {
8679 for (
const Expr *SemE : E->
semantics()) {
8680 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SemE)) {
8689 if (OVE->isUnique())
8693 if (!
Evaluate(Info.CurrentCall->createTemporary(
8694 OVE, getStorageType(Info.Ctx, OVE),
8695 ScopeKind::FullExpression, LV),
8696 Info, OVE->getSourceExpr()))
8699 if (!StmtVisitorTy::Visit(SemE))
8709 bool VisitCallExpr(
const CallExpr *E) {
8711 if (!handleCallExpr(E,
Result,
nullptr))
8713 return DerivedSuccess(
Result, E);
8717 const LValue *ResultSlot) {
8718 CallScopeRAII CallScope(Info);
8721 QualType CalleeType =
Callee->getType();
8723 const FunctionDecl *FD =
nullptr;
8724 LValue *
This =
nullptr, ObjectArg;
8726 bool HasQualifier =
false;
8732 const CXXMethodDecl *
Member =
nullptr;
8733 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
8737 Member = dyn_cast<CXXMethodDecl>(ME->getMemberDecl());
8739 return Error(Callee);
8741 HasQualifier = ME->hasQualifier();
8742 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
8744 const ValueDecl *D =
8748 Member = dyn_cast<CXXMethodDecl>(D);
8750 return Error(Callee);
8752 }
else if (
const auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(Callee)) {
8753 if (!Info.getLangOpts().CPlusPlus20)
8754 Info.CCEDiag(PDE, diag::note_constexpr_pseudo_destructor);
8758 return Error(Callee);
8765 if (!CalleeLV.getLValueOffset().isZero())
8766 return Error(Callee);
8767 if (CalleeLV.isNullPointer()) {
8768 Info.FFDiag(Callee, diag::note_constexpr_null_callee)
8769 <<
const_cast<Expr *
>(
Callee);
8772 FD = dyn_cast_or_null<FunctionDecl>(
8773 CalleeLV.getLValueBase().dyn_cast<
const ValueDecl *>());
8775 return Error(Callee);
8778 if (!Info.Ctx.hasSameFunctionTypeIgnoringExceptionSpec(
8785 auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
8786 if (OCE && OCE->isAssignmentOp()) {
8787 assert(Args.size() == 2 &&
"wrong number of arguments in assignment");
8788 Call = Info.CurrentCall->createCall(FD);
8789 bool HasThis =
false;
8790 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
8791 HasThis = MD->isImplicitObjectMemberFunction();
8799 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
8819 if (Info.getLangOpts().CPlusPlus20 && OCE &&
8820 OCE->getOperator() == OO_Equal && MD->
isTrivial() &&
8824 Args = Args.slice(1);
8830 const CXXRecordDecl *ClosureClass = MD->
getParent();
8832 ClosureClass->
captures().empty() &&
8833 "Number of captures must be zero for conversion to function-ptr");
8835 const CXXMethodDecl *LambdaCallOp =
8844 "A generic lambda's static-invoker function must be a "
8845 "template specialization");
8847 FunctionTemplateDecl *CallOpTemplate =
8849 void *InsertPos =
nullptr;
8850 FunctionDecl *CorrespondingCallOpSpecialization =
8852 assert(CorrespondingCallOpSpecialization &&
8853 "We must always have a function call operator specialization "
8854 "that corresponds to our static invoker specialization");
8856 FD = CorrespondingCallOpSpecialization;
8865 return CallScope.destroy();
8875 Call = Info.CurrentCall->createCall(FD);
8881 SmallVector<QualType, 4> CovariantAdjustmentPath;
8883 auto *NamedMember = dyn_cast<CXXMethodDecl>(FD);
8884 if (NamedMember && NamedMember->isVirtual() && !HasQualifier) {
8887 CovariantAdjustmentPath);
8890 }
else if (NamedMember && NamedMember->isImplicitObjectMemberFunction()) {
8900 if (
auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
8901 assert(This &&
"no 'this' pointer for destructor call");
8903 Info.Ctx.getCanonicalTagType(DD->getParent())) &&
8904 CallScope.destroy();
8921 if (!CovariantAdjustmentPath.empty() &&
8923 CovariantAdjustmentPath))
8926 return CallScope.destroy();
8929 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
8932 bool VisitInitListExpr(
const InitListExpr *E) {
8934 return DerivedZeroInitialization(E);
8936 return StmtVisitorTy::Visit(E->
getInit(0));
8939 bool VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
8940 return DerivedZeroInitialization(E);
8942 bool VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
8943 return DerivedZeroInitialization(E);
8945 bool VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
8946 return DerivedZeroInitialization(E);
8950 bool VisitMemberExpr(
const MemberExpr *E) {
8951 assert(!Info.Ctx.getLangOpts().CPlusPlus11 &&
8952 "missing temporary materialization conversion");
8953 assert(!E->
isArrow() &&
"missing call to bound member function?");
8961 const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl());
8962 if (!FD)
return Error(E);
8966 "record / field mismatch");
8971 CompleteObject Obj(APValue::LValueBase(), &Val, BaseTy);
8972 SubobjectDesignator Designator(BaseTy);
8973 Designator.addDeclUnchecked(FD);
8977 DerivedSuccess(
Result, E);
8980 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) {
8986 SmallVector<uint32_t, 4> Indices;
8988 if (Indices.size() == 1) {
8990 return DerivedSuccess(Val.
getVectorElt(Indices[0]), E);
8993 SmallVector<APValue, 4> Elts;
8994 for (
unsigned I = 0; I < Indices.size(); ++I) {
8997 APValue VecResult(Elts.data(), Indices.size());
8998 return DerivedSuccess(VecResult, E);
9005 bool VisitCastExpr(
const CastExpr *E) {
9010 case CK_AtomicToNonAtomic: {
9017 return DerivedSuccess(AtomicVal, E);
9021 case CK_UserDefinedConversion:
9022 return StmtVisitorTy::Visit(E->
getSubExpr());
9024 case CK_HLSLArrayRValue: {
9030 return DerivedSuccess(Val, E);
9041 return DerivedSuccess(RVal, E);
9043 case CK_LValueToRValue: {
9052 return DerivedSuccess(RVal, E);
9054 case CK_LValueToRValueBitCast: {
9055 APValue DestValue, SourceValue;
9058 if (!handleLValueToRValueBitCast(Info, DestValue, SourceValue, E))
9060 return DerivedSuccess(DestValue, E);
9063 case CK_AddressSpaceConversion: {
9067 return DerivedSuccess(
Value, E);
9074 bool VisitUnaryPostInc(
const UnaryOperator *UO) {
9075 return VisitUnaryPostIncDec(UO);
9077 bool VisitUnaryPostDec(
const UnaryOperator *UO) {
9078 return VisitUnaryPostIncDec(UO);
9080 bool VisitUnaryPostIncDec(
const UnaryOperator *UO) {
9081 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9091 return DerivedSuccess(RVal, UO);
9094 bool VisitStmtExpr(
const StmtExpr *E) {
9097 llvm::SaveAndRestore NotCheckingForUB(Info.CheckingForUndefinedBehavior,
9104 BlockScopeRAII Scope(Info);
9109 const Expr *FinalExpr = dyn_cast<Expr>(*BI);
9111 Info.FFDiag((*BI)->getBeginLoc(),
9112 diag::note_constexpr_stmt_expr_unsupported);
9115 return this->Visit(FinalExpr) && Scope.destroy();
9121 if (ESR != ESR_Succeeded) {
9125 if (ESR != ESR_Failed)
9126 Info.FFDiag((*BI)->getBeginLoc(),
9127 diag::note_constexpr_stmt_expr_unsupported);
9132 llvm_unreachable(
"Return from function from the loop above.");
9135 bool VisitPackIndexingExpr(
const PackIndexingExpr *E) {
9140 void VisitIgnoredValue(
const Expr *E) {
9145 void VisitIgnoredBaseExpression(
const Expr *E) {
9148 if (Info.getLangOpts().MSVCCompat && !E->
HasSideEffects(Info.Ctx))
9150 VisitIgnoredValue(E);
9160template<
class Derived>
9161class LValueExprEvaluatorBase
9162 :
public ExprEvaluatorBase<Derived> {
9166 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
9167 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
9169 bool Success(APValue::LValueBase B) {
9174 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9179 LValueExprEvaluatorBase(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK)
9181 InvalidBaseOK(InvalidBaseOK) {}
9184 Result.setFrom(this->Info.Ctx,
V);
9188 bool VisitMemberExpr(
const MemberExpr *E) {
9200 EvalOK = this->Visit(E->
getBase());
9211 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(E->
getMemberDecl())) {
9214 "record / field mismatch");
9218 }
else if (
const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(MD)) {
9222 return this->
Error(E);
9234 bool VisitBinaryOperator(
const BinaryOperator *E) {
9237 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
9245 bool VisitCastExpr(
const CastExpr *E) {
9248 return ExprEvaluatorBaseTy::VisitCastExpr(E);
9250 case CK_DerivedToBase:
9251 case CK_UncheckedDerivedToBase:
9298class LValueExprEvaluator
9299 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
9301 LValueExprEvaluator(EvalInfo &Info, LValue &
Result,
bool InvalidBaseOK) :
9302 LValueExprEvaluatorBaseTy(Info,
Result, InvalidBaseOK) {}
9304 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
9305 bool VisitUnaryPreIncDec(
const UnaryOperator *UO);
9307 bool VisitCallExpr(
const CallExpr *E);
9308 bool VisitDeclRefExpr(
const DeclRefExpr *E);
9309 bool VisitPredefinedExpr(
const PredefinedExpr *E) {
return Success(E); }
9310 bool VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E);
9311 bool VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E);
9312 bool VisitMemberExpr(
const MemberExpr *E);
9313 bool VisitStringLiteral(
const StringLiteral *E) {
9315 APValue::LValueBase(E, 0, Info.Ctx.getNextStringLiteralVersion()));
9317 bool VisitObjCEncodeExpr(
const ObjCEncodeExpr *E) {
return Success(E); }
9318 bool VisitCXXTypeidExpr(
const CXXTypeidExpr *E);
9319 bool VisitCXXUuidofExpr(
const CXXUuidofExpr *E);
9320 bool VisitArraySubscriptExpr(
const ArraySubscriptExpr *E);
9321 bool VisitExtVectorElementExpr(
const ExtVectorElementExpr *E);
9322 bool VisitUnaryDeref(
const UnaryOperator *E);
9323 bool VisitUnaryReal(
const UnaryOperator *E);
9324 bool VisitUnaryImag(
const UnaryOperator *E);
9325 bool VisitUnaryPreInc(
const UnaryOperator *UO) {
9326 return VisitUnaryPreIncDec(UO);
9328 bool VisitUnaryPreDec(
const UnaryOperator *UO) {
9329 return VisitUnaryPreIncDec(UO);
9331 bool VisitBinAssign(
const BinaryOperator *BO);
9332 bool VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO);
9334 bool VisitCastExpr(
const CastExpr *E) {
9337 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
9339 case CK_LValueBitCast:
9340 this->CCEDiag(E, diag::note_constexpr_invalid_cast)
9341 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
9345 Result.Designator.setInvalid();
9348 case CK_BaseToDerived:
9365 bool LValueToRValueConversion) {
9369 assert(Info.CurrentCall->This ==
nullptr &&
9370 "This should not be set for a static call operator");
9378 if (
Self->getType()->isReferenceType()) {
9379 APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments,
Self);
9381 Result.setFrom(Info.Ctx, *RefValue);
9383 const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(
Self);
9384 CallStackFrame *Frame =
9385 Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
9387 unsigned Version = Info.CurrentCall->Arguments.Version;
9388 Result.set({VD, Frame->Index, Version});
9391 Result = *Info.CurrentCall->This;
9401 if (LValueToRValueConversion) {
9405 Result.setFrom(Info.Ctx, RVal);
9416 bool InvalidBaseOK) {
9420 return LValueExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
9423bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
9424 const ValueDecl *D = E->
getDecl();
9436 if (Info.checkingPotentialConstantExpression())
9439 if (
auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(D)) {
9446 if (
isa<FunctionDecl, MSGuidDecl, TemplateParamObjectDecl,
9447 UnnamedGlobalConstantDecl>(D))
9449 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
9450 return VisitVarDecl(E, VD);
9451 if (
const BindingDecl *BD = dyn_cast<BindingDecl>(D))
9452 return Visit(BD->getBinding());
9456bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
9457 CallStackFrame *Frame =
nullptr;
9458 unsigned Version = 0;
9466 CallStackFrame *CurrFrame = Info.CurrentCall;
9471 if (
auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
9472 if (CurrFrame->Arguments) {
9473 VD = CurrFrame->Arguments.getOrigParam(PVD);
9475 Info.getCallFrameAndDepth(CurrFrame->Arguments.CallIndex).first;
9476 Version = CurrFrame->Arguments.Version;
9480 Version = CurrFrame->getCurrentTemporaryVersion(VD);
9487 Result.set({VD, Frame->Index, Version});
9493 if (!Info.getLangOpts().CPlusPlus11) {
9494 Info.CCEDiag(E, diag::note_constexpr_ltor_non_integral, 1)
9496 Info.Note(VD->
getLocation(), diag::note_declared_at);
9505 Result.AllowConstexprUnknown =
true;
9512bool LValueExprEvaluator::VisitCallExpr(
const CallExpr *E) {
9513 if (!IsConstantEvaluatedBuiltinCall(E))
9514 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9519 case Builtin::BIas_const:
9520 case Builtin::BIforward:
9521 case Builtin::BIforward_like:
9522 case Builtin::BImove:
9523 case Builtin::BImove_if_noexcept:
9525 return Visit(E->
getArg(0));
9529 return ExprEvaluatorBaseTy::VisitCallExpr(E);
9532bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
9533 const MaterializeTemporaryExpr *E) {
9541 for (
const Expr *E : CommaLHSs)
9550 if (Info.EvalMode == EvaluationMode::ConstantFold)
9557 Value = &Info.CurrentCall->createTemporary(
9573 for (
unsigned I = Adjustments.size(); I != 0; ) {
9575 switch (Adjustments[I].Kind) {
9580 Type = Adjustments[I].DerivedToBase.BasePath->getType();
9586 Type = Adjustments[I].Field->getType();
9591 Adjustments[I].Ptr.RHS))
9593 Type = Adjustments[I].Ptr.MPT->getPointeeType();
9602LValueExprEvaluator::VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
9603 assert((!Info.getLangOpts().CPlusPlus || E->
isFileScope()) &&
9604 "lvalue compound literal in c++?");
9616 assert(!Info.getLangOpts().CPlusPlus);
9618 ScopeKind::Block,
Result);
9630bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
9631 TypeInfoLValue TypeInfo;
9639 if (!Info.Ctx.getLangOpts().CPlusPlus20) {
9640 Info.CCEDiag(E, diag::note_constexpr_typeid_polymorphic)
9648 std::optional<DynamicType> DynType =
9653 TypeInfo = TypeInfoLValue(
9654 Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
9660bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
9664bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
9666 if (
const VarDecl *VD = dyn_cast<VarDecl>(E->
getMemberDecl())) {
9667 VisitIgnoredBaseExpression(E->
getBase());
9668 return VisitVarDecl(E, VD);
9672 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->
getMemberDecl())) {
9673 if (MD->isStatic()) {
9674 VisitIgnoredBaseExpression(E->
getBase());
9680 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
9683bool LValueExprEvaluator::VisitExtVectorElementExpr(
9684 const ExtVectorElementExpr *E) {
9689 if (!Info.noteFailure())
9697 if (Indices.size() > 1)
9701 Result.setFrom(Info.Ctx, Val);
9705 const auto *VT = BaseType->
castAs<VectorType>();
9707 VT->getNumElements(), Indices[0]);
9713bool LValueExprEvaluator::VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
9723 if (!Info.noteFailure())
9729 if (!Info.noteFailure())
9735 Result.setFrom(Info.Ctx, Val);
9737 VT->getNumElements(), Index.getZExtValue());
9745 for (
const Expr *SubExpr : {E->
getLHS(), E->
getRHS()}) {
9746 if (SubExpr == E->
getBase() ? !evaluatePointer(SubExpr,
Result)
9748 if (!Info.noteFailure())
9758bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
9769 Info.noteUndefinedBehavior();
9772bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
9781bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
9783 "lvalue __imag__ on scalar?");
9790bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
9791 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9802bool LValueExprEvaluator::VisitCompoundAssignOperator(
9803 const CompoundAssignOperator *CAO) {
9804 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9812 if (!Info.noteFailure())
9827bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
9828 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
9836 if (!Info.noteFailure())
9844 if (Info.getLangOpts().CPlusPlus20 &&
9861 assert(isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
9862 "Can't get the size of a non alloc_size function");
9863 const auto *
Base = LVal.getLValueBase().get<
const Expr *>();
9865 std::optional<llvm::APInt> Size =
9866 CE->evaluateBytesReturnedByAllocSizeCall(Ctx);
9870 Result = std::move(*Size);
9889 dyn_cast_or_null<VarDecl>(
Base.dyn_cast<
const ValueDecl *>());
9894 if (!
Init ||
Init->getType().isNull())
9897 const Expr *E =
Init->IgnoreParens();
9898 if (!tryUnwrapAllocSizeCall(E))
9906 Result.addUnsizedArray(Info, E, Pointee);
9911class PointerExprEvaluator
9912 :
public ExprEvaluatorBase<PointerExprEvaluator> {
9921 bool evaluateLValue(
const Expr *E, LValue &
Result) {
9925 bool evaluatePointer(
const Expr *E, LValue &
Result) {
9929 bool visitNonBuiltinCallExpr(
const CallExpr *E);
9932 PointerExprEvaluator(EvalInfo &info, LValue &
Result,
bool InvalidBaseOK)
9934 InvalidBaseOK(InvalidBaseOK) {}
9940 bool ZeroInitialization(
const Expr *E) {
9945 bool VisitBinaryOperator(
const BinaryOperator *E);
9946 bool VisitCastExpr(
const CastExpr* E);
9947 bool VisitUnaryAddrOf(
const UnaryOperator *E);
9948 bool VisitObjCStringLiteral(
const ObjCStringLiteral *E)
9950 bool VisitObjCBoxedExpr(
const ObjCBoxedExpr *E) {
9953 if (Info.noteFailure())
9957 bool VisitObjCArrayLiteral(
const ObjCArrayLiteral *E) {
9960 bool VisitObjCDictionaryLiteral(
const ObjCDictionaryLiteral *E) {
9963 bool VisitAddrLabelExpr(
const AddrLabelExpr *E)
9965 bool VisitCallExpr(
const CallExpr *E);
9966 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
9967 bool VisitBlockExpr(
const BlockExpr *E) {
9972 bool VisitCXXThisExpr(
const CXXThisExpr *E) {
9973 auto DiagnoseInvalidUseOfThis = [&] {
9974 if (Info.getLangOpts().CPlusPlus11)
9975 Info.FFDiag(E, diag::note_constexpr_this) << E->
isImplicit();
9981 if (Info.checkingPotentialConstantExpression())
9984 bool IsExplicitLambda =
9986 if (!IsExplicitLambda) {
9987 if (!Info.CurrentCall->This) {
9988 DiagnoseInvalidUseOfThis();
9992 Result = *Info.CurrentCall->This;
10000 if (!Info.CurrentCall->LambdaThisCaptureField) {
10001 if (IsExplicitLambda && !Info.CurrentCall->This) {
10002 DiagnoseInvalidUseOfThis();
10011 Info, E,
Result, MD, Info.CurrentCall->LambdaThisCaptureField,
10017 bool VisitCXXNewExpr(
const CXXNewExpr *E);
10019 bool VisitSourceLocExpr(
const SourceLocExpr *E) {
10020 assert(!E->
isIntType() &&
"SourceLocExpr isn't a pointer type?");
10022 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
10023 Result.setFrom(Info.Ctx, LValResult);
10027 bool VisitEmbedExpr(
const EmbedExpr *E) {
10028 llvm::report_fatal_error(
"Not yet implemented for ExprConstant.cpp");
10032 bool VisitSYCLUniqueStableNameExpr(
const SYCLUniqueStableNameExpr *E) {
10033 std::string ResultStr = E->
ComputeName(Info.Ctx);
10035 QualType CharTy = Info.Ctx.CharTy.withConst();
10036 APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
10037 ResultStr.size() + 1);
10038 QualType ArrayTy = Info.Ctx.getConstantArrayType(
10039 CharTy, Size,
nullptr, ArraySizeModifier::Normal, 0);
10041 StringLiteral *SL =
10042 StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
10045 evaluateLValue(SL,
Result);
10055 bool InvalidBaseOK) {
10058 return PointerExprEvaluator(Info,
Result, InvalidBaseOK).Visit(E);
10061bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
10064 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
10066 const Expr *PExp = E->
getLHS();
10067 const Expr *IExp = E->
getRHS();
10069 std::swap(PExp, IExp);
10071 bool EvalPtrOK = evaluatePointer(PExp,
Result);
10072 if (!EvalPtrOK && !Info.noteFailure())
10075 llvm::APSInt Offset;
10086bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
10094 if (!Info.getLangOpts().CPlusPlus) {
10096 if (
const auto *Deref = dyn_cast<UnaryOperator>(Sub);
10097 Deref && Deref->getOpcode() == UO_Deref)
10098 return evaluatePointer(Deref->getSubExpr(),
Result);
10108 if (!FnII || !FnII->
isStr(
"current"))
10111 const auto *RD = dyn_cast<RecordDecl>(FD->
getParent());
10119bool PointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
10126 case CK_CPointerToObjCPointerCast:
10127 case CK_BlockPointerToObjCPointerCast:
10128 case CK_AnyPointerToBlockPointerCast:
10129 case CK_AddressSpaceConversion:
10130 if (!Visit(SubExpr))
10136 CCEDiag(E, diag::note_constexpr_invalid_cast)
10137 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10138 << Info.Ctx.getLangOpts().CPlusPlus;
10139 Result.Designator.setInvalid();
10147 bool HasValidResult = !
Result.InvalidBase && !
Result.Designator.Invalid &&
10149 bool VoidPtrCastMaybeOK =
10152 Info.Ctx.hasSimilarType(
Result.Designator.getType(Info.Ctx),
10161 if (VoidPtrCastMaybeOK &&
10162 (Info.getStdAllocatorCaller(
"allocate") ||
10164 Info.getLangOpts().CPlusPlus26)) {
10168 Info.getLangOpts().CPlusPlus) {
10169 if (HasValidResult)
10170 CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
10171 << SubExpr->
getType() << Info.getLangOpts().CPlusPlus26
10172 <<
Result.Designator.getType(Info.Ctx).getCanonicalType()
10175 CCEDiag(E, diag::note_constexpr_invalid_cast)
10176 << diag::ConstexprInvalidCastKind::CastFrom
10179 CCEDiag(E, diag::note_constexpr_invalid_cast)
10180 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10181 << Info.Ctx.getLangOpts().CPlusPlus;
10182 Result.Designator.setInvalid();
10186 ZeroInitialization(E);
10189 case CK_DerivedToBase:
10190 case CK_UncheckedDerivedToBase:
10202 case CK_BaseToDerived:
10214 case CK_NullToPointer:
10216 return ZeroInitialization(E);
10218 case CK_IntegralToPointer: {
10219 CCEDiag(E, diag::note_constexpr_invalid_cast)
10220 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
10221 << Info.Ctx.getLangOpts().CPlusPlus;
10227 if (
Value.isInt()) {
10228 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
10229 uint64_t N =
Value.getInt().extOrTrunc(Size).getZExtValue();
10230 if (N == Info.Ctx.getTargetNullPointerValue(E->
getType())) {
10233 Result.Base = (Expr *)
nullptr;
10234 Result.InvalidBase =
false;
10236 Result.Designator.setInvalid();
10237 Result.IsNullPtr =
false;
10245 if (!
Value.isLValue())
10254 case CK_ArrayToPointerDecay: {
10256 if (!evaluateLValue(SubExpr,
Result))
10260 SubExpr, SubExpr->
getType(), ScopeKind::FullExpression,
Result);
10265 auto *AT = Info.Ctx.getAsArrayType(SubExpr->
getType());
10266 if (
auto *CAT = dyn_cast<ConstantArrayType>(AT))
10267 Result.addArray(Info, E, CAT);
10269 Result.addUnsizedArray(Info, E, AT->getElementType());
10273 case CK_FunctionToPointerDecay:
10274 return evaluateLValue(SubExpr,
Result);
10276 case CK_LValueToRValue: {
10285 return InvalidBaseOK &&
10291 return ExprEvaluatorBaseTy::VisitCastExpr(E);
10299 T = T.getNonReferenceType();
10301 if (T.getQualifiers().hasUnaligned())
10304 const bool AlignOfReturnsPreferred =
10310 if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
10313 else if (ExprKind == UETT_AlignOf)
10316 llvm_unreachable(
"GetAlignOfType on a non-alignment ExprKind");
10331 unsigned BuiltinOp) {
10355 switch (OwningTarget->
getTriple().getArch()) {
10356 case llvm::Triple::x86:
10357 case llvm::Triple::x86_64:
10379 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
10383 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
10392 return Info.Ctx.getDeclAlign(VD);
10393 if (
const auto *E =
Value.Base.dyn_cast<
const Expr *>())
10401 EvalInfo &Info,
APSInt &Alignment) {
10404 if (Alignment < 0 || !Alignment.isPowerOf2()) {
10405 Info.FFDiag(E, diag::note_constexpr_invalid_alignment) << Alignment;
10408 unsigned SrcWidth = Info.Ctx.getIntWidth(ForType);
10409 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
10410 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
10411 Info.FFDiag(E, diag::note_constexpr_alignment_too_big)
10412 << MaxValue << ForType << Alignment;
10418 APSInt(Alignment.zextOrTrunc(SrcWidth),
true);
10419 assert(APSInt::compareValues(Alignment, ExtAlignment) == 0 &&
10420 "Alignment should not be changed by ext/trunc");
10421 Alignment = ExtAlignment;
10422 assert(Alignment.getBitWidth() == SrcWidth);
10427bool PointerExprEvaluator::visitNonBuiltinCallExpr(
const CallExpr *E) {
10428 if (ExprEvaluatorBaseTy::VisitCallExpr(E))
10436 Result.addUnsizedArray(Info, E, PointeeTy);
10440bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
10441 if (!IsConstantEvaluatedBuiltinCall(E))
10442 return visitNonBuiltinCallExpr(E);
10449 return T->isCharType() || T->isChar8Type();
10452bool PointerExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
10453 unsigned BuiltinOp) {
10457 switch (BuiltinOp) {
10458 case Builtin::BIaddressof:
10459 case Builtin::BI__addressof:
10460 case Builtin::BI__builtin_addressof:
10462 case Builtin::BI__builtin_assume_aligned: {
10469 LValue OffsetResult(
Result);
10481 int64_t AdditionalOffset = -Offset.getZExtValue();
10486 if (OffsetResult.Base) {
10489 if (BaseAlignment < Align) {
10490 Result.Designator.setInvalid();
10491 CCEDiag(E->
getArg(0), diag::note_constexpr_baa_insufficient_alignment)
10498 if (OffsetResult.Offset.alignTo(Align) != OffsetResult.Offset) {
10499 Result.Designator.setInvalid();
10503 diag::note_constexpr_baa_insufficient_alignment)
10506 diag::note_constexpr_baa_value_insufficient_alignment))
10507 << OffsetResult.Offset.getQuantity() << Align.
getQuantity();
10513 case Builtin::BI__builtin_align_up:
10514 case Builtin::BI__builtin_align_down: {
10534 assert(Alignment.getBitWidth() <= 64 &&
10535 "Cannot handle > 64-bit address-space");
10536 uint64_t Alignment64 = Alignment.getZExtValue();
10538 BuiltinOp == Builtin::BI__builtin_align_down
10539 ? llvm::alignDown(
Result.Offset.getQuantity(), Alignment64)
10540 : llvm::alignTo(
Result.Offset.getQuantity(), Alignment64));
10546 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_adjust)
10550 case Builtin::BI__builtin_operator_new:
10552 case Builtin::BI__builtin_launder:
10554 case Builtin::BIstrchr:
10555 case Builtin::BIwcschr:
10556 case Builtin::BImemchr:
10557 case Builtin::BIwmemchr:
10558 if (Info.getLangOpts().CPlusPlus11)
10559 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10561 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10563 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10565 case Builtin::BI__builtin_strchr:
10566 case Builtin::BI__builtin_wcschr:
10567 case Builtin::BI__builtin_memchr:
10568 case Builtin::BI__builtin_char_memchr:
10569 case Builtin::BI__builtin_wmemchr: {
10570 if (!Visit(E->
getArg(0)))
10576 if (BuiltinOp != Builtin::BIstrchr &&
10577 BuiltinOp != Builtin::BIwcschr &&
10578 BuiltinOp != Builtin::BI__builtin_strchr &&
10579 BuiltinOp != Builtin::BI__builtin_wcschr) {
10583 MaxLength = N.getZExtValue();
10586 if (MaxLength == 0u)
10587 return ZeroInitialization(E);
10588 if (!
Result.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
10589 Result.Designator.Invalid)
10591 QualType CharTy =
Result.Designator.getType(Info.Ctx);
10592 bool IsRawByte = BuiltinOp == Builtin::BImemchr ||
10593 BuiltinOp == Builtin::BI__builtin_memchr;
10594 assert(IsRawByte ||
10595 Info.Ctx.hasSameUnqualifiedType(
10599 Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy;
10605 Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
10606 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy;
10612 bool StopAtNull =
false;
10613 switch (BuiltinOp) {
10614 case Builtin::BIstrchr:
10615 case Builtin::BI__builtin_strchr:
10622 return ZeroInitialization(E);
10625 case Builtin::BImemchr:
10626 case Builtin::BI__builtin_memchr:
10627 case Builtin::BI__builtin_char_memchr:
10631 DesiredVal = Desired.trunc(Info.Ctx.getCharWidth()).getZExtValue();
10634 case Builtin::BIwcschr:
10635 case Builtin::BI__builtin_wcschr:
10638 case Builtin::BIwmemchr:
10639 case Builtin::BI__builtin_wmemchr:
10641 DesiredVal = Desired.getZExtValue();
10645 for (; MaxLength; --MaxLength) {
10650 if (Char.
getInt().getZExtValue() == DesiredVal)
10652 if (StopAtNull && !Char.
getInt())
10658 return ZeroInitialization(E);
10661 case Builtin::BImemcpy:
10662 case Builtin::BImemmove:
10663 case Builtin::BIwmemcpy:
10664 case Builtin::BIwmemmove:
10665 if (Info.getLangOpts().CPlusPlus11)
10666 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
10668 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
10670 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
10672 case Builtin::BI__builtin_memcpy:
10673 case Builtin::BI__builtin_memmove:
10674 case Builtin::BI__builtin_wmemcpy:
10675 case Builtin::BI__builtin_wmemmove: {
10676 bool WChar = BuiltinOp == Builtin::BIwmemcpy ||
10677 BuiltinOp == Builtin::BIwmemmove ||
10678 BuiltinOp == Builtin::BI__builtin_wmemcpy ||
10679 BuiltinOp == Builtin::BI__builtin_wmemmove;
10680 bool Move = BuiltinOp == Builtin::BImemmove ||
10681 BuiltinOp == Builtin::BIwmemmove ||
10682 BuiltinOp == Builtin::BI__builtin_memmove ||
10683 BuiltinOp == Builtin::BI__builtin_wmemmove;
10686 if (!Visit(E->
getArg(0)))
10697 assert(!N.isSigned() &&
"memcpy and friends take an unsigned size");
10707 if (!Src.Base || !Dest.Base) {
10709 (!Src.Base ? Src : Dest).moveInto(Val);
10710 Info.FFDiag(E, diag::note_constexpr_memcpy_null)
10711 <<
Move << WChar << !!Src.Base
10715 if (Src.Designator.Invalid || Dest.Designator.Invalid)
10721 QualType T = Dest.Designator.getType(Info.Ctx);
10722 QualType SrcT = Src.Designator.getType(Info.Ctx);
10723 if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) {
10725 Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) <<
Move << SrcT << T;
10729 Info.FFDiag(E, diag::note_constexpr_memcpy_incomplete_type) <<
Move << T;
10733 Info.FFDiag(E, diag::note_constexpr_memcpy_nontrivial) <<
Move << T;
10738 uint64_t TSize = Info.Ctx.getTypeSizeInChars(T).getQuantity();
10743 llvm::APInt OrigN = N;
10744 llvm::APInt::udivrem(OrigN, TSize, N, Remainder);
10746 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10747 <<
Move << WChar << 0 << T <<
toString(OrigN, 10,
false)
10748 << (unsigned)TSize;
10756 uint64_t RemainingSrcSize = Src.Designator.validIndexAdjustments().second;
10757 uint64_t RemainingDestSize = Dest.Designator.validIndexAdjustments().second;
10758 if (N.ugt(RemainingSrcSize) || N.ugt(RemainingDestSize)) {
10759 Info.FFDiag(E, diag::note_constexpr_memcpy_unsupported)
10760 <<
Move << WChar << (N.ugt(RemainingSrcSize) ? 1 : 2) << T
10764 uint64_t NElems = N.getZExtValue();
10770 uint64_t SrcOffset = Src.getLValueOffset().getQuantity();
10771 uint64_t DestOffset = Dest.getLValueOffset().getQuantity();
10772 if (DestOffset >= SrcOffset && DestOffset - SrcOffset < NBytes) {
10775 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10783 }
else if (!Move && SrcOffset >= DestOffset &&
10784 SrcOffset - DestOffset < NBytes) {
10786 Info.FFDiag(E, diag::note_constexpr_memcpy_overlap) << WChar;
10815 QualType AllocType);
10818 const CXXConstructExpr *CCE,
10819 QualType AllocType);
10821bool PointerExprEvaluator::VisitCXXNewExpr(
const CXXNewExpr *E) {
10822 if (!Info.getLangOpts().CPlusPlus20)
10823 Info.CCEDiag(E, diag::note_constexpr_new);
10826 if (Info.SpeculativeEvaluationDepth)
10831 QualType TargetType = AllocType;
10833 bool IsNothrow =
false;
10834 bool IsPlacement =
false;
10852 }
else if (OperatorNew->isReservedGlobalPlacementOperator()) {
10853 if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 ||
10854 (Info.CurrentCall->CanEvalMSConstexpr &&
10855 OperatorNew->hasAttr<MSConstexprAttr>())) {
10858 if (
Result.Designator.Invalid)
10861 IsPlacement =
true;
10863 Info.FFDiag(E, diag::note_constexpr_new_placement)
10868 Info.FFDiag(E, diag::note_constexpr_new_placement)
10871 }
else if (!OperatorNew
10872 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
10873 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
10879 const InitListExpr *ResizedArrayILE =
nullptr;
10880 const CXXConstructExpr *ResizedArrayCCE =
nullptr;
10881 bool ValueInit =
false;
10883 if (std::optional<const Expr *> ArraySize = E->
getArraySize()) {
10884 const Expr *Stripped = *ArraySize;
10885 for (;
auto *ICE = dyn_cast<ImplicitCastExpr>(Stripped);
10886 Stripped = ICE->getSubExpr())
10887 if (ICE->getCastKind() != CK_NoOp &&
10888 ICE->getCastKind() != CK_IntegralCast)
10901 return ZeroInitialization(E);
10903 Info.FFDiag(*ArraySize, diag::note_constexpr_new_negative)
10904 <<
ArrayBound << (*ArraySize)->getSourceRange();
10910 if (!Info.CheckArraySize(ArraySize.value()->getExprLoc(),
10915 return ZeroInitialization(E);
10927 }
else if (
auto *CCE = dyn_cast<CXXConstructExpr>(
Init)) {
10928 ResizedArrayCCE = CCE;
10930 auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType());
10931 assert(CAT &&
"unexpected type for array initializer");
10935 llvm::APInt InitBound = CAT->
getSize().zext(Bits);
10936 llvm::APInt AllocBound =
ArrayBound.zext(Bits);
10937 if (InitBound.ugt(AllocBound)) {
10939 return ZeroInitialization(E);
10941 Info.FFDiag(*ArraySize, diag::note_constexpr_new_too_small)
10942 <<
toString(AllocBound, 10,
false)
10944 << (*ArraySize)->getSourceRange();
10950 if (InitBound != AllocBound)
10954 AllocType = Info.Ctx.getConstantArrayType(AllocType,
ArrayBound,
nullptr,
10955 ArraySizeModifier::Normal, 0);
10965 "array allocation with non-array new");
10971 struct FindObjectHandler {
10974 QualType AllocType;
10978 typedef bool result_type;
10979 bool failed() {
return false; }
10980 bool checkConst(QualType QT) {
10982 Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT;
10987 bool found(
APValue &Subobj, QualType SubobjType,
10988 APValue::LValueBase Base) {
10989 if (!checkConst(SubobjType))
10993 if (!Info.Ctx.hasSimilarType(SubobjType, AllocType)) {
10994 Info.FFDiag(E, diag::note_constexpr_placement_new_wrong_type)
10995 << SubobjType << AllocType;
11002 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11005 bool found(APFloat &
Value, QualType SubobjType) {
11006 Info.FFDiag(E, diag::note_constexpr_construct_complex_elem);
11009 } Handler = {Info, E, AllocType, AK,
nullptr};
11012 Result.Designator.MostDerivedIsArrayElement &&
11013 Result.Designator.Entries.back().getAsArrayIndex() == 0) {
11018 QualType AllocElementType =
11019 Info.Ctx.getAsArrayType(AllocType)->getElementType();
11020 if (Info.Ctx.hasSimilarType(AllocElementType,
11021 Result.Designator.MostDerivedType)) {
11023 Result.Designator.MostDerivedPathLength - 1);
11031 Val = Handler.Value;
11040 Val = Info.createHeapAlloc(E, AllocType,
Result);
11046 ImplicitValueInitExpr VIE(AllocType);
11049 }
else if (ResizedArrayILE) {
11053 }
else if (ResizedArrayCCE) {
11076class MemberPointerExprEvaluator
11077 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
11080 bool Success(
const ValueDecl *D) {
11086 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &
Result)
11093 bool ZeroInitialization(
const Expr *E) {
11094 return Success((
const ValueDecl*)
nullptr);
11097 bool VisitCastExpr(
const CastExpr *E);
11098 bool VisitUnaryAddrOf(
const UnaryOperator *E);
11106 return MemberPointerExprEvaluator(Info,
Result).Visit(E);
11109bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11112 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11114 case CK_NullToMemberPointer:
11116 return ZeroInitialization(E);
11118 case CK_BaseToDerivedMemberPointer: {
11126 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
11128 PathI != PathE; ++PathI) {
11129 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11130 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
11131 if (!
Result.castToDerived(Derived))
11135 ->
castAs<MemberPointerType>()
11136 ->getMostRecentCXXRecordDecl()))
11141 case CK_DerivedToBaseMemberPointer:
11145 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11146 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
11147 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11148 if (!
Result.castToBase(Base))
11155bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
11166 class RecordExprEvaluator
11167 :
public ExprEvaluatorBase<RecordExprEvaluator> {
11168 const LValue &
This;
11172 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &
Result)
11179 bool ZeroInitialization(
const Expr *E) {
11180 return ZeroInitialization(E, E->
getType());
11182 bool ZeroInitialization(
const Expr *E, QualType T);
11184 bool VisitCallExpr(
const CallExpr *E) {
11185 return handleCallExpr(E,
Result, &This);
11187 bool VisitCastExpr(
const CastExpr *E);
11188 bool VisitInitListExpr(
const InitListExpr *E);
11189 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11190 return VisitCXXConstructExpr(E, E->
getType());
11193 bool VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E);
11194 bool VisitCXXConstructExpr(
const CXXConstructExpr *E, QualType T);
11195 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E);
11196 bool VisitBinCmp(
const BinaryOperator *E);
11197 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
11198 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
11199 ArrayRef<Expr *> Args);
11200 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
11214 assert(!RD->
isUnion() &&
"Expected non-union class type");
11223 unsigned Index = 0;
11225 End = CD->
bases_end(); I != End; ++I, ++Index) {
11227 LValue Subobject =
This;
11231 Result.getStructBase(Index)))
11236 for (
const auto *I : RD->
fields()) {
11238 if (I->isUnnamedBitField() || I->getType()->isReferenceType())
11241 LValue Subobject =
This;
11247 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
11254bool RecordExprEvaluator::ZeroInitialization(
const Expr *E, QualType T) {
11261 while (I != RD->
field_end() && (*I)->isUnnamedBitField())
11268 LValue Subobject =
This;
11272 ImplicitValueInitExpr VIE(I->getType());
11277 Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD;
11284bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11287 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11289 case CK_ConstructorConversion:
11292 case CK_DerivedToBase:
11293 case CK_UncheckedDerivedToBase: {
11304 PathE = E->
path_end(); PathI != PathE; ++PathI) {
11305 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
11306 const CXXRecordDecl *
Base = (*PathI)->getType()->getAsCXXRecordDecl();
11313 case CK_HLSLAggregateSplatCast: {
11333 case CK_HLSLElementwiseCast: {
11351 LValue Subobject =
This;
11358 if (
Field->isBitField()) {
11368bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11371 return VisitCXXParenListOrInitListExpr(E, E->
inits());
11374bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
11378 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
11379 auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
11381 EvalInfo::EvaluatingConstructorRAII EvalObj(
11383 ObjectUnderConstruction{
This.getLValueBase(),
This.Designator.Entries},
11384 CXXRD && CXXRD->getNumBases());
11387 const FieldDecl *
Field;
11388 if (
auto *ILE = dyn_cast<InitListExpr>(ExprToVisit)) {
11389 Field = ILE->getInitializedFieldInUnion();
11390 }
else if (
auto *PLIE = dyn_cast<CXXParenListInitExpr>(ExprToVisit)) {
11391 Field = PLIE->getInitializedFieldInUnion();
11394 "Expression is neither an init list nor a C++ paren list");
11406 ImplicitValueInitExpr VIE(
Field->getType());
11407 const Expr *InitExpr = Args.empty() ? &VIE : Args[0];
11409 LValue Subobject =
This;
11414 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11418 if (
Field->isBitField())
11428 Result =
APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
11430 unsigned ElementNo = 0;
11434 if (CXXRD && CXXRD->getNumBases()) {
11435 for (
const auto &Base : CXXRD->bases()) {
11436 assert(ElementNo < Args.size() &&
"missing init for base class");
11437 const Expr *
Init = Args[ElementNo];
11439 LValue Subobject =
This;
11445 if (!Info.noteFailure())
11452 EvalObj.finishedConstructingBases();
11456 for (
const auto *Field : RD->
fields()) {
11459 if (
Field->isUnnamedBitField())
11462 LValue Subobject =
This;
11464 bool HaveInit = ElementNo < Args.size();
11469 Subobject, Field, &Layout))
11474 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy :
Field->getType());
11475 const Expr *
Init = HaveInit ? Args[ElementNo++] : &VIE;
11482 if (
Field->getType()->isIncompleteArrayType()) {
11483 if (
auto *CAT = Info.Ctx.getAsConstantArrayType(
Init->getType())) {
11487 Info.FFDiag(
Init, diag::note_constexpr_unsupported_flexible_array);
11494 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
11498 if (
Field->getType()->isReferenceType()) {
11502 if (!Info.noteFailure())
11507 (
Field->isBitField() &&
11509 if (!Info.noteFailure())
11515 EvalObj.finishedConstructingFields();
11520bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
11530 return ZeroInitialization(E, T);
11548 const Expr *SrcObj = E->
getArg(0);
11550 assert(Info.Ctx.hasSameUnqualifiedType(E->
getType(), SrcObj->
getType()));
11551 if (
const MaterializeTemporaryExpr *ME =
11552 dyn_cast<MaterializeTemporaryExpr>(SrcObj))
11553 return Visit(ME->getSubExpr());
11556 if (ZeroInit && !ZeroInitialization(E, T))
11565bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
11566 const CXXInheritedCtorInitExpr *E) {
11567 if (!Info.CurrentCall) {
11568 assert(Info.checkingPotentialConstantExpression());
11587bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
11588 const CXXStdInitializerListExpr *E) {
11589 const ConstantArrayType *ArrayType =
11596 assert(ArrayType &&
"unexpected type for array initializer");
11599 Array.addArray(Info, E, ArrayType);
11607 assert(Field !=
Record->field_end() &&
11608 Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11610 "Expected std::initializer_list first field to be const E *");
11612 assert(Field !=
Record->field_end() &&
11613 "Expected std::initializer_list to have two fields");
11615 if (Info.Ctx.hasSameType(
Field->getType(), Info.Ctx.getSizeType())) {
11620 assert(Info.Ctx.hasSameType(
Field->getType()->getPointeeType(),
11622 "Expected std::initializer_list second field to be const E *");
11630 assert(++Field ==
Record->field_end() &&
11631 "Expected std::initializer_list to only have two fields");
11636bool RecordExprEvaluator::VisitLambdaExpr(
const LambdaExpr *E) {
11641 const size_t NumFields = ClosureClass->
getNumFields();
11645 "The number of lambda capture initializers should equal the number of "
11646 "fields within the closure type");
11653 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(ClosureClass);
11654 for (
const auto *Field : ClosureClass->
fields()) {
11657 Expr *
const CurFieldInit = *CaptureInitIt++;
11664 LValue Subobject =
This;
11671 if (!Info.keepEvaluatingAfterFailure())
11679bool RecordExprEvaluator::VisitDesignatedInitUpdateExpr(
11680 const DesignatedInitUpdateExpr *E) {
11690 "can't evaluate expression as a record rvalue");
11691 return RecordExprEvaluator(Info,
This,
Result).Visit(E);
11702class TemporaryExprEvaluator
11703 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
11705 TemporaryExprEvaluator(EvalInfo &Info, LValue &
Result) :
11706 LValueExprEvaluatorBaseTy(Info,
Result,
false) {}
11709 bool VisitConstructExpr(
const Expr *E) {
11715 bool VisitCastExpr(
const CastExpr *E) {
11718 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
11720 case CK_ConstructorConversion:
11724 bool VisitInitListExpr(
const InitListExpr *E) {
11725 return VisitConstructExpr(E);
11727 bool VisitCXXConstructExpr(
const CXXConstructExpr *E) {
11728 return VisitConstructExpr(E);
11730 bool VisitCallExpr(
const CallExpr *E) {
11731 return VisitConstructExpr(E);
11733 bool VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) {
11734 return VisitConstructExpr(E);
11737 return VisitConstructExpr(E);
11746 return TemporaryExprEvaluator(Info,
Result).Visit(E);
11754 class VectorExprEvaluator
11755 :
public ExprEvaluatorBase<VectorExprEvaluator> {
11762 bool Success(ArrayRef<APValue>
V,
const Expr *E) {
11763 assert(
V.size() == E->
getType()->
castAs<VectorType>()->getNumElements());
11769 assert(
V.isVector());
11773 bool ZeroInitialization(
const Expr *E);
11775 bool VisitUnaryReal(
const UnaryOperator *E)
11777 bool VisitCastExpr(
const CastExpr* E);
11778 bool VisitInitListExpr(
const InitListExpr *E);
11779 bool VisitUnaryImag(
const UnaryOperator *E);
11780 bool VisitBinaryOperator(
const BinaryOperator *E);
11781 bool VisitUnaryOperator(
const UnaryOperator *E);
11782 bool VisitCallExpr(
const CallExpr *E);
11783 bool VisitConvertVectorExpr(
const ConvertVectorExpr *E);
11784 bool VisitShuffleVectorExpr(
const ShuffleVectorExpr *E);
11793 "not a vector prvalue");
11794 return VectorExprEvaluator(Info,
Result).Visit(E);
11798 assert(Val.
isVector() &&
"expected vector APValue");
11802 llvm::APInt
Result(NumElts, 0);
11804 for (
unsigned I = 0; I < NumElts; ++I) {
11806 assert(Elt.
isInt() &&
"expected integer element in bool vector");
11808 if (Elt.
getInt().getBoolValue())
11815bool VectorExprEvaluator::VisitCastExpr(
const CastExpr *E) {
11816 const VectorType *VTy = E->
getType()->
castAs<VectorType>();
11820 QualType SETy = SE->
getType();
11823 case CK_VectorSplat: {
11829 Val =
APValue(std::move(IntResult));
11834 Val =
APValue(std::move(FloatResult));
11851 Info.FFDiag(E, diag::note_constexpr_invalid_cast)
11852 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
11853 << Info.Ctx.getLangOpts().CPlusPlus;
11857 if (!handleRValueToRValueBitCast(Info,
Result, SVal, E))
11862 case CK_HLSLVectorTruncation: {
11867 for (
unsigned I = 0; I < NElts; I++)
11871 case CK_HLSLMatrixTruncation: {
11877 for (
unsigned Row = 0;
11879 for (
unsigned Col = 0;
11884 case CK_HLSLAggregateSplatCast: {
11901 case CK_HLSLElementwiseCast: {
11914 return Success(ResultEls, E);
11916 case CK_IntegralToFloating:
11917 case CK_FloatingToIntegral:
11918 case CK_IntegralCast:
11919 case CK_FloatingCast:
11920 case CK_FloatingToBoolean:
11921 case CK_IntegralToBoolean: {
11923 assert(SETy->
isVectorType() &&
"expected vector source type");
11929 QualType SrcEltTy = SETy->
castAs<VectorType>()->getElementType();
11934 for (
unsigned I = 0; I < NElts; ++I) {
11939 return Success(ResultEls, E);
11942 return ExprEvaluatorBaseTy::VisitCastExpr(E);
11947VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
11964 unsigned CountInits = 0, CountElts = 0;
11965 while (CountElts < NumElements) {
11967 if (CountInits < NumInits
11973 for (
unsigned j = 0; j < vlen; j++)
11977 llvm::APSInt sInt(32);
11978 if (CountInits < NumInits) {
11982 sInt = Info.Ctx.MakeIntValue(0, EltTy);
11983 Elements.push_back(
APValue(sInt));
11986 llvm::APFloat f(0.0);
11987 if (CountInits < NumInits) {
11991 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
11992 Elements.push_back(
APValue(f));
12001VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
12005 if (EltTy->isIntegerType())
12006 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
12009 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
12015bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
12017 return ZeroInitialization(E);
12020bool VectorExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
12022 assert(Op != BO_PtrMemD && Op != BO_PtrMemI && Op != BO_Cmp &&
12023 "Operation not supported on vector types");
12025 if (Op == BO_Comma)
12026 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
12028 Expr *LHS = E->
getLHS();
12029 Expr *RHS = E->
getRHS();
12032 "Must both be vector types");
12035 assert(LHS->
getType()->
castAs<VectorType>()->getNumElements() ==
12039 "All operands must be the same size.");
12043 bool LHSOK =
Evaluate(LHSValue, Info, LHS);
12044 if (!LHSOK && !Info.noteFailure())
12046 if (!
Evaluate(RHSValue, Info, RHS) || !LHSOK)
12068 "Vector can only be int or float type");
12076 "Vector operator ~ can only be int");
12077 Elt.
getInt().flipAllBits();
12087 "Vector can only be int or float type");
12093 EltResult.setAllBits();
12095 EltResult.clearAllBits();
12101 return std::nullopt;
12105bool VectorExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
12111 const QualType ResultEltTy = VD->getElementType();
12115 if (!
Evaluate(SubExprValue, Info, SubExpr))
12128 "Vector length doesn't match type?");
12131 for (
unsigned EltNum = 0; EltNum < VD->getNumElements(); ++EltNum) {
12133 Info.Ctx, ResultEltTy, Op, SubExprValue.
getVectorElt(EltNum));
12136 ResultElements.push_back(*Elt);
12138 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12149 DestTy,
Result.getFloat());
12165 DestTy,
Result.getInt());
12169 Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast)
12170 << SourceTy << DestTy;
12175 llvm::function_ref<APInt(
const APSInt &)> PackFn) {
12184 assert(LHSVecLen != 0 && LHSVecLen == RHSVecLen &&
12185 "pack builtin LHSVecLen must equal to RHSVecLen");
12188 const unsigned SrcBits = Info.Ctx.getIntWidth(VT0->
getElementType());
12194 const unsigned SrcPerLane = 128 / SrcBits;
12195 const unsigned Lanes = LHSVecLen * SrcBits / 128;
12198 Out.reserve(LHSVecLen + RHSVecLen);
12200 for (
unsigned Lane = 0; Lane != Lanes; ++Lane) {
12201 unsigned base = Lane * SrcPerLane;
12202 for (
unsigned I = 0; I != SrcPerLane; ++I)
12205 for (
unsigned I = 0; I != SrcPerLane; ++I)
12216 llvm::function_ref<std::pair<unsigned, int>(
unsigned,
unsigned)>
12223 unsigned ShuffleMask = 0;
12225 bool IsVectorMask =
false;
12226 bool IsSingleOperand = (
Call->getNumArgs() == 2);
12228 if (IsSingleOperand) {
12231 IsVectorMask =
true;
12240 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12250 IsVectorMask =
true;
12259 ShuffleMask =
static_cast<unsigned>(MaskImm.getZExtValue());
12270 ResultElements.reserve(NumElts);
12272 for (
unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
12273 if (IsVectorMask) {
12274 ShuffleMask =
static_cast<unsigned>(
12275 MaskVector.getVectorElt(DstIdx).getInt().getZExtValue());
12277 auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask);
12283 ResultElements.push_back(
12284 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy))));
12290 ResultElements.push_back(
APValue());
12293 const APValue &Src = (SrcVecIdx == 0) ? A : B;
12298 Out =
APValue(ResultElements.data(), ResultElements.size());
12304 if (OrigVal.isInfinity()) {
12305 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 0;
12308 if (OrigVal.isNaN()) {
12309 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << 1;
12313 APFloat Val = OrigVal;
12314 bool LosesInfo =
false;
12315 APFloat::opStatus Status = Val.convert(
12316 APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &LosesInfo);
12318 if (LosesInfo || Val.isDenormal()) {
12319 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic_strict);
12323 if (Status != APFloat::opOK) {
12324 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
12333 llvm::function_ref<APInt(
const APInt &, uint64_t)> ShiftOp,
12334 llvm::function_ref<APInt(
const APInt &,
unsigned)> OverflowOp) {
12341 assert(
Call->getNumArgs() == 2);
12345 Call->getArg(1)->getType()->isVectorType());
12348 unsigned DestEltWidth = Source.getVectorElt(0).getInt().getBitWidth();
12349 unsigned DestLen = Source.getVectorLength();
12352 unsigned NumBitsInQWord = 64;
12353 unsigned NumCountElts = NumBitsInQWord / CountEltWidth;
12355 Result.reserve(DestLen);
12357 uint64_t CountLQWord = 0;
12358 for (
unsigned EltIdx = 0; EltIdx != NumCountElts; ++EltIdx) {
12360 CountLQWord |= (Elt << (EltIdx * CountEltWidth));
12363 for (
unsigned EltIdx = 0; EltIdx != DestLen; ++EltIdx) {
12364 APInt Elt = Source.getVectorElt(EltIdx).getInt();
12365 if (CountLQWord < DestEltWidth) {
12367 APValue(
APSInt(ShiftOp(Elt, CountLQWord), IsDestUnsigned)));
12370 APValue(
APSInt(OverflowOp(Elt, DestEltWidth), IsDestUnsigned)));
12378 std::optional<APSInt> RoundingMode,
12380 APSInt DefaultMode(APInt(32, 4),
true);
12381 if (RoundingMode.value_or(DefaultMode) != 4)
12382 return std::nullopt;
12383 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
12384 B.isInfinity() || B.isDenormal())
12385 return std::nullopt;
12386 if (A.isZero() && B.isZero())
12388 return IsMin ? llvm::minimum(A, B) : llvm::maximum(A, B);
12391bool VectorExprEvaluator::VisitCallExpr(
const CallExpr *E) {
12392 if (!IsConstantEvaluatedBuiltinCall(E))
12393 return ExprEvaluatorBaseTy::VisitCallExpr(E);
12397 auto EvaluateBinOpExpr =
12399 APValue SourceLHS, SourceRHS;
12405 QualType DestEltTy = DestTy->getElementType();
12406 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12409 ResultElements.reserve(SourceLen);
12411 if (SourceRHS.
isInt()) {
12413 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12415 ResultElements.push_back(
12419 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12422 ResultElements.push_back(
12429 auto EvaluateFpBinOpExpr =
12430 [&](llvm::function_ref<std::optional<APFloat>(
12431 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12433 bool IsScalar =
false) {
12443 std::optional<APSInt> RoundingMode;
12448 RoundingMode = Imm;
12453 ResultElements.reserve(NumElems);
12455 for (
unsigned EltNum = 0; EltNum < NumElems; ++EltNum) {
12456 if (IsScalar && EltNum > 0) {
12462 std::optional<APFloat>
Result =
Fn(EltA, EltB, RoundingMode);
12470 auto EvaluateScalarFpRoundMaskBinOp =
12471 [&](llvm::function_ref<std::optional<APFloat>(
12472 const APFloat &,
const APFloat &, std::optional<APSInt>)>
12476 APSInt MaskVal, Rounding;
12487 ResultElements.reserve(NumElems);
12489 if (MaskVal.getZExtValue() & 1) {
12492 std::optional<APFloat>
Result =
Fn(EltA, EltB, Rounding);
12500 for (
unsigned I = 1; I < NumElems; ++I)
12506 auto EvalSelectScalar = [&](
unsigned Len) ->
bool {
12514 bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
12518 for (
unsigned I = 1; I < Len; ++I)
12520 APValue V(Res.data(), Res.size());
12524 auto EvalVectorDotProduct = [&](
bool IsSaturating) ->
bool {
12525 APValue Source, OperandA, OperandB;
12534 unsigned ElemsPerLane = NumOperandElems / NumSrcElems;
12539 Result.reserve(NumSrcElems);
12540 for (
unsigned I = 0; I != NumSrcElems; ++I) {
12542 DotProduct = DotProduct.extend(64);
12543 for (
unsigned J = 0; J != ElemsPerLane; ++J) {
12550 DotProduct += OpA * OpB;
12552 if (IsSaturating) {
12553 DotProduct =
APSInt(DotProduct.truncSSat(32),
false);
12555 DotProduct =
APSInt(DotProduct.trunc(32),
false);
12563 switch (BuiltinOp) {
12566 case Builtin::BI__builtin_elementwise_popcount:
12567 case Builtin::BI__builtin_elementwise_bitreverse: {
12572 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12575 ResultElements.reserve(SourceLen);
12577 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12579 switch (BuiltinOp) {
12580 case Builtin::BI__builtin_elementwise_popcount:
12581 ResultElements.push_back(
APValue(
12582 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), Elt.popcount()),
12585 case Builtin::BI__builtin_elementwise_bitreverse:
12586 ResultElements.push_back(
12593 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12595 case Builtin::BI__builtin_elementwise_abs: {
12600 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12603 ResultElements.reserve(SourceLen);
12605 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
12610 CurrentEle.getInt().
abs(),
12611 DestEltTy->isUnsignedIntegerOrEnumerationType()));
12612 ResultElements.push_back(Val);
12615 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12618 case Builtin::BI__builtin_elementwise_add_sat:
12619 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12620 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
12623 case Builtin::BI__builtin_elementwise_sub_sat:
12624 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12625 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
12628 case X86::BI__builtin_ia32_extract128i256:
12629 case X86::BI__builtin_ia32_vextractf128_pd256:
12630 case X86::BI__builtin_ia32_vextractf128_ps256:
12631 case X86::BI__builtin_ia32_vextractf128_si256: {
12632 APValue SourceVec, SourceImm;
12641 unsigned RetLen = RetVT->getNumElements();
12642 unsigned Idx = SourceImm.
getInt().getZExtValue() & 1;
12645 ResultElements.reserve(RetLen);
12647 for (
unsigned I = 0; I < RetLen; I++)
12648 ResultElements.push_back(SourceVec.
getVectorElt(Idx * RetLen + I));
12653 case clang::X86::BI__builtin_ia32_cvtmask2b128:
12654 case clang::X86::BI__builtin_ia32_cvtmask2b256:
12655 case clang::X86::BI__builtin_ia32_cvtmask2b512:
12656 case clang::X86::BI__builtin_ia32_cvtmask2w128:
12657 case clang::X86::BI__builtin_ia32_cvtmask2w256:
12658 case clang::X86::BI__builtin_ia32_cvtmask2w512:
12659 case clang::X86::BI__builtin_ia32_cvtmask2d128:
12660 case clang::X86::BI__builtin_ia32_cvtmask2d256:
12661 case clang::X86::BI__builtin_ia32_cvtmask2d512:
12662 case clang::X86::BI__builtin_ia32_cvtmask2q128:
12663 case clang::X86::BI__builtin_ia32_cvtmask2q256:
12664 case clang::X86::BI__builtin_ia32_cvtmask2q512: {
12670 QualType VecTy = E->
getType();
12671 const VectorType *VT = VecTy->
castAs<VectorType>();
12674 unsigned ElemWidth = Info.Ctx.getTypeSize(ElemTy);
12677 for (
unsigned I = 0; I != VectorLen; ++I) {
12678 bool BitSet = Mask[I];
12679 APSInt ElemVal(ElemWidth,
false);
12681 ElemVal.setAllBits();
12683 Elems.push_back(
APValue(ElemVal));
12688 case X86::BI__builtin_ia32_extracti32x4_256_mask:
12689 case X86::BI__builtin_ia32_extractf32x4_256_mask:
12690 case X86::BI__builtin_ia32_extracti32x4_mask:
12691 case X86::BI__builtin_ia32_extractf32x4_mask:
12692 case X86::BI__builtin_ia32_extracti32x8_mask:
12693 case X86::BI__builtin_ia32_extractf32x8_mask:
12694 case X86::BI__builtin_ia32_extracti64x2_256_mask:
12695 case X86::BI__builtin_ia32_extractf64x2_256_mask:
12696 case X86::BI__builtin_ia32_extracti64x2_512_mask:
12697 case X86::BI__builtin_ia32_extractf64x2_512_mask:
12698 case X86::BI__builtin_ia32_extracti64x4_mask:
12699 case X86::BI__builtin_ia32_extractf64x4_mask: {
12710 unsigned RetLen = RetVT->getNumElements();
12715 unsigned Lanes = SrcLen / RetLen;
12716 unsigned Lane =
static_cast<unsigned>(Imm.getZExtValue() % Lanes);
12717 unsigned Base = Lane * RetLen;
12720 ResultElements.reserve(RetLen);
12721 for (
unsigned I = 0; I < RetLen; ++I) {
12723 ResultElements.push_back(SourceVec.
getVectorElt(Base + I));
12727 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12730 case clang::X86::BI__builtin_ia32_pavgb128:
12731 case clang::X86::BI__builtin_ia32_pavgw128:
12732 case clang::X86::BI__builtin_ia32_pavgb256:
12733 case clang::X86::BI__builtin_ia32_pavgw256:
12734 case clang::X86::BI__builtin_ia32_pavgb512:
12735 case clang::X86::BI__builtin_ia32_pavgw512:
12736 return EvaluateBinOpExpr(llvm::APIntOps::avgCeilU);
12738 case clang::X86::BI__builtin_ia32_pmulhrsw128:
12739 case clang::X86::BI__builtin_ia32_pmulhrsw256:
12740 case clang::X86::BI__builtin_ia32_pmulhrsw512:
12741 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
12742 return (llvm::APIntOps::mulsExtended(LHS, RHS).ashr(14) + 1)
12743 .extractBits(16, 1);
12746 case clang::X86::BI__builtin_ia32_psadbw128:
12747 case clang::X86::BI__builtin_ia32_psadbw256:
12748 case clang::X86::BI__builtin_ia32_psadbw512: {
12749 APValue SourceLHS, SourceRHS;
12757 assert((SourceLen % 8) == 0);
12760 QualType DestEltTy = DestTy->getElementType();
12761 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12763 ResultElements.reserve(SourceLen / 8);
12765 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 8) {
12767 for (
unsigned I = 0; I != 8; ++I) {
12770 Sum += llvm::APIntOps::abdu(LHS, RHS).zext(64);
12772 ResultElements.push_back(
APValue(
APSInt(Sum, DestUnsigned)));
12775 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12778 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12779 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12780 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12781 case clang::X86::BI__builtin_ia32_pmaddwd128:
12782 case clang::X86::BI__builtin_ia32_pmaddwd256:
12783 case clang::X86::BI__builtin_ia32_pmaddwd512: {
12784 APValue SourceLHS, SourceRHS;
12790 QualType DestEltTy = DestTy->getElementType();
12792 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12794 ResultElements.reserve(SourceLen / 2);
12796 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
12801 unsigned BitWidth = 2 * LoLHS.getBitWidth();
12803 switch (BuiltinOp) {
12804 case clang::X86::BI__builtin_ia32_pmaddubsw128:
12805 case clang::X86::BI__builtin_ia32_pmaddubsw256:
12806 case clang::X86::BI__builtin_ia32_pmaddubsw512:
12807 ResultElements.push_back(
APValue(
12808 APSInt((LoLHS.zext(BitWidth) * LoRHS.sext(BitWidth))
12809 .sadd_sat((HiLHS.zext(BitWidth) * HiRHS.sext(BitWidth))),
12812 case clang::X86::BI__builtin_ia32_pmaddwd128:
12813 case clang::X86::BI__builtin_ia32_pmaddwd256:
12814 case clang::X86::BI__builtin_ia32_pmaddwd512:
12815 ResultElements.push_back(
12816 APValue(
APSInt((LoLHS.sext(BitWidth) * LoRHS.sext(BitWidth)) +
12817 (HiLHS.sext(BitWidth) * HiRHS.sext(BitWidth)),
12823 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12826 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v16hi:
12827 case clang::X86::BI__builtin_ia32_bmacor16x16x16_v32hi:
12828 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi:
12829 case clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi: {
12840 APValue SourceA, SourceB, SourceC;
12847 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v16hi ||
12849 clang::X86::BI__builtin_ia32_bmacxor16x16x16_v32hi;
12852 assert(SourceLen % 16 == 0 &&
"BMM operates on 256-bit lanes of 16 x i16");
12854 QualType DestEltTy = DestTy->getElementType();
12855 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12858 for (
unsigned Lane = 0; Lane != SourceLen; Lane += 16) {
12859 for (
unsigned I = 0; I != 16; ++I) {
12864 for (
unsigned J = 0; J != 16; ++J) {
12868 unsigned Bit = (Dst >> J) & 1u;
12869 for (
unsigned K = 0; K != 16; ++K) {
12873 unsigned Product = ((A >> K) & 1u) & ((B >> J) & 1u);
12874 Bit = IsXor ? (Bit ^ Product) : (Bit | Product);
12878 ResultElements[Lane + I] =
12882 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12885 case clang::X86::BI__builtin_ia32_dbpsadbw128:
12886 case clang::X86::BI__builtin_ia32_dbpsadbw256:
12887 case clang::X86::BI__builtin_ia32_dbpsadbw512: {
12888 APValue SourceA, SourceB, SourceImm;
12895 constexpr unsigned LaneSize = 16;
12896 unsigned Imm = SourceImm.
getInt().getZExtValue();
12899 QualType DestEltTy = DestTy->getElementType();
12900 bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
12902 ResultElements.reserve(SourceLen / 2);
12908 for (
unsigned I = 0; I < SourceLen; I += LaneSize) {
12909 for (
unsigned J = 0; J < 4; ++J) {
12910 unsigned Part = (Imm >> (2 * J)) & 3;
12911 for (
unsigned K = 0; K < 4; ++K) {
12912 Shuffled[I + 4 * J + K] =
static_cast<uint8_t>(
12913 SourceB.
getVectorElt(I + 4 * Part + K).getInt().getZExtValue());
12921 unsigned Size = SourceLen / 2;
12922 for (
unsigned I = 0; I <
Size; I += 4) {
12923 unsigned Sad[4] = {0, 0, 0, 0};
12924 for (
unsigned J = 0; J < 4; ++J) {
12926 SourceA.
getVectorElt(2 * I + J).getInt().getZExtValue());
12928 SourceA.
getVectorElt(2 * I + J + 4).getInt().getZExtValue());
12929 uint8_t B0 = Shuffled[2 * I + J];
12930 uint8_t B1 = Shuffled[2 * I + J + 1];
12931 uint8_t B2 = Shuffled[2 * I + J + 2];
12932 uint8_t B3 = Shuffled[2 * I + J + 3];
12933 Sad[0] += (A1 > B0) ? (A1 - B0) : (B0 - A1);
12934 Sad[1] += (A1 > B1) ? (A1 - B1) : (B1 - A1);
12935 Sad[2] += (A2 > B2) ? (A2 - B2) : (B2 - A2);
12936 Sad[3] += (A2 > B3) ? (A2 - B3) : (B3 - A2);
12938 for (
unsigned R = 0;
R < 4; ++
R)
12939 ResultElements.push_back(
12943 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12946 case clang::X86::BI__builtin_ia32_mpsadbw128:
12947 case clang::X86::BI__builtin_ia32_mpsadbw256: {
12955 constexpr unsigned LaneSize = 16;
12956 assert((SourceLen == LaneSize || SourceLen == 2 * LaneSize) &&
12957 "MPSADBW operates on 128-bit or 256-bit vectors");
12958 unsigned NumLanes = SourceLen / LaneSize;
12959 unsigned Imm = SourceImm.getZExtValue();
12961 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
12964 ResultElements.reserve(SourceLen / 2);
12966 for (
unsigned Lane = 0; Lane != NumLanes; ++Lane) {
12967 unsigned Ctrl = (Imm >> (3 * Lane)) & 0x7;
12968 unsigned AOff = ((Ctrl >> 2) & 1) * 4;
12969 unsigned BOff = (Ctrl & 3) * 4;
12970 for (
unsigned J = 0; J != 8; ++J) {
12972 for (
unsigned K = 0; K != 4; ++K) {
12981 Sad += (A > B) ? (A - B) : (B - A);
12986 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
12989 case clang::X86::BI__builtin_ia32_pmulhuw128:
12990 case clang::X86::BI__builtin_ia32_pmulhuw256:
12991 case clang::X86::BI__builtin_ia32_pmulhuw512:
12992 return EvaluateBinOpExpr(llvm::APIntOps::mulhu);
12994 case clang::X86::BI__builtin_ia32_pmulhw128:
12995 case clang::X86::BI__builtin_ia32_pmulhw256:
12996 case clang::X86::BI__builtin_ia32_pmulhw512:
12997 return EvaluateBinOpExpr(llvm::APIntOps::mulhs);
12999 case clang::X86::BI__builtin_ia32_psllv2di:
13000 case clang::X86::BI__builtin_ia32_psllv4di:
13001 case clang::X86::BI__builtin_ia32_psllv4si:
13002 case clang::X86::BI__builtin_ia32_psllv8di:
13003 case clang::X86::BI__builtin_ia32_psllv8hi:
13004 case clang::X86::BI__builtin_ia32_psllv8si:
13005 case clang::X86::BI__builtin_ia32_psllv16hi:
13006 case clang::X86::BI__builtin_ia32_psllv16si:
13007 case clang::X86::BI__builtin_ia32_psllv32hi:
13008 case clang::X86::BI__builtin_ia32_psllwi128:
13009 case clang::X86::BI__builtin_ia32_pslldi128:
13010 case clang::X86::BI__builtin_ia32_psllqi128:
13011 case clang::X86::BI__builtin_ia32_psllwi256:
13012 case clang::X86::BI__builtin_ia32_pslldi256:
13013 case clang::X86::BI__builtin_ia32_psllqi256:
13014 case clang::X86::BI__builtin_ia32_psllwi512:
13015 case clang::X86::BI__builtin_ia32_pslldi512:
13016 case clang::X86::BI__builtin_ia32_psllqi512:
13017 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13018 if (RHS.uge(LHS.getBitWidth())) {
13019 return APInt::getZero(LHS.getBitWidth());
13021 return LHS.shl(RHS.getZExtValue());
13024 case clang::X86::BI__builtin_ia32_psrav4si:
13025 case clang::X86::BI__builtin_ia32_psrav8di:
13026 case clang::X86::BI__builtin_ia32_psrav8hi:
13027 case clang::X86::BI__builtin_ia32_psrav8si:
13028 case clang::X86::BI__builtin_ia32_psrav16hi:
13029 case clang::X86::BI__builtin_ia32_psrav16si:
13030 case clang::X86::BI__builtin_ia32_psrav32hi:
13031 case clang::X86::BI__builtin_ia32_psravq128:
13032 case clang::X86::BI__builtin_ia32_psravq256:
13033 case clang::X86::BI__builtin_ia32_psrawi128:
13034 case clang::X86::BI__builtin_ia32_psradi128:
13035 case clang::X86::BI__builtin_ia32_psraqi128:
13036 case clang::X86::BI__builtin_ia32_psrawi256:
13037 case clang::X86::BI__builtin_ia32_psradi256:
13038 case clang::X86::BI__builtin_ia32_psraqi256:
13039 case clang::X86::BI__builtin_ia32_psrawi512:
13040 case clang::X86::BI__builtin_ia32_psradi512:
13041 case clang::X86::BI__builtin_ia32_psraqi512:
13042 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13043 if (RHS.uge(LHS.getBitWidth())) {
13044 return LHS.ashr(LHS.getBitWidth() - 1);
13046 return LHS.ashr(RHS.getZExtValue());
13049 case clang::X86::BI__builtin_ia32_psrlv2di:
13050 case clang::X86::BI__builtin_ia32_psrlv4di:
13051 case clang::X86::BI__builtin_ia32_psrlv4si:
13052 case clang::X86::BI__builtin_ia32_psrlv8di:
13053 case clang::X86::BI__builtin_ia32_psrlv8hi:
13054 case clang::X86::BI__builtin_ia32_psrlv8si:
13055 case clang::X86::BI__builtin_ia32_psrlv16hi:
13056 case clang::X86::BI__builtin_ia32_psrlv16si:
13057 case clang::X86::BI__builtin_ia32_psrlv32hi:
13058 case clang::X86::BI__builtin_ia32_psrlwi128:
13059 case clang::X86::BI__builtin_ia32_psrldi128:
13060 case clang::X86::BI__builtin_ia32_psrlqi128:
13061 case clang::X86::BI__builtin_ia32_psrlwi256:
13062 case clang::X86::BI__builtin_ia32_psrldi256:
13063 case clang::X86::BI__builtin_ia32_psrlqi256:
13064 case clang::X86::BI__builtin_ia32_psrlwi512:
13065 case clang::X86::BI__builtin_ia32_psrldi512:
13066 case clang::X86::BI__builtin_ia32_psrlqi512:
13067 return EvaluateBinOpExpr([](
const APSInt &LHS,
const APSInt &RHS) {
13068 if (RHS.uge(LHS.getBitWidth())) {
13069 return APInt::getZero(LHS.getBitWidth());
13071 return LHS.lshr(RHS.getZExtValue());
13073 case X86::BI__builtin_ia32_packsswb128:
13074 case X86::BI__builtin_ia32_packsswb256:
13075 case X86::BI__builtin_ia32_packsswb512:
13076 case X86::BI__builtin_ia32_packssdw128:
13077 case X86::BI__builtin_ia32_packssdw256:
13078 case X86::BI__builtin_ia32_packssdw512:
13080 return APSInt(Src).truncSSat(Src.getBitWidth() / 2);
13082 case X86::BI__builtin_ia32_packusdw128:
13083 case X86::BI__builtin_ia32_packusdw256:
13084 case X86::BI__builtin_ia32_packusdw512:
13085 case X86::BI__builtin_ia32_packuswb128:
13086 case X86::BI__builtin_ia32_packuswb256:
13087 case X86::BI__builtin_ia32_packuswb512:
13089 return APSInt(Src).truncSSatU(Src.getBitWidth() / 2);
13091 case clang::X86::BI__builtin_ia32_selectss_128:
13092 return EvalSelectScalar(4);
13093 case clang::X86::BI__builtin_ia32_selectsd_128:
13094 return EvalSelectScalar(2);
13095 case clang::X86::BI__builtin_ia32_selectsh_128:
13096 case clang::X86::BI__builtin_ia32_selectsbf_128:
13097 return EvalSelectScalar(8);
13098 case clang::X86::BI__builtin_ia32_pmuldq128:
13099 case clang::X86::BI__builtin_ia32_pmuldq256:
13100 case clang::X86::BI__builtin_ia32_pmuldq512:
13101 case clang::X86::BI__builtin_ia32_pmuludq128:
13102 case clang::X86::BI__builtin_ia32_pmuludq256:
13103 case clang::X86::BI__builtin_ia32_pmuludq512: {
13104 APValue SourceLHS, SourceRHS;
13111 ResultElements.reserve(SourceLen / 2);
13113 for (
unsigned EltNum = 0; EltNum < SourceLen; EltNum += 2) {
13117 switch (BuiltinOp) {
13118 case clang::X86::BI__builtin_ia32_pmuludq128:
13119 case clang::X86::BI__builtin_ia32_pmuludq256:
13120 case clang::X86::BI__builtin_ia32_pmuludq512:
13121 ResultElements.push_back(
13122 APValue(
APSInt(llvm::APIntOps::muluExtended(LHS, RHS),
true)));
13124 case clang::X86::BI__builtin_ia32_pmuldq128:
13125 case clang::X86::BI__builtin_ia32_pmuldq256:
13126 case clang::X86::BI__builtin_ia32_pmuldq512:
13127 ResultElements.push_back(
13128 APValue(
APSInt(llvm::APIntOps::mulsExtended(LHS, RHS),
false)));
13133 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13136 case X86::BI__builtin_ia32_vpmadd52luq128:
13137 case X86::BI__builtin_ia32_vpmadd52luq256:
13138 case X86::BI__builtin_ia32_vpmadd52luq512: {
13147 ResultElements.reserve(ALen);
13149 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13152 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13153 APSInt ResElt(AElt + (BElt * CElt).zext(64),
false);
13154 ResultElements.push_back(
APValue(ResElt));
13157 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13159 case X86::BI__builtin_ia32_vpmadd52huq128:
13160 case X86::BI__builtin_ia32_vpmadd52huq256:
13161 case X86::BI__builtin_ia32_vpmadd52huq512: {
13170 ResultElements.reserve(ALen);
13172 for (
unsigned EltNum = 0; EltNum < ALen; EltNum += 1) {
13175 APInt CElt =
C.getVectorElt(EltNum).getInt().trunc(52);
13176 APSInt ResElt(AElt + llvm::APIntOps::mulhu(BElt, CElt).zext(64),
false);
13177 ResultElements.push_back(
APValue(ResElt));
13180 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13183 case clang::X86::BI__builtin_ia32_vprotbi:
13184 case clang::X86::BI__builtin_ia32_vprotdi:
13185 case clang::X86::BI__builtin_ia32_vprotqi:
13186 case clang::X86::BI__builtin_ia32_vprotwi:
13187 case clang::X86::BI__builtin_ia32_prold128:
13188 case clang::X86::BI__builtin_ia32_prold256:
13189 case clang::X86::BI__builtin_ia32_prold512:
13190 case clang::X86::BI__builtin_ia32_prolq128:
13191 case clang::X86::BI__builtin_ia32_prolq256:
13192 case clang::X86::BI__builtin_ia32_prolq512:
13193 return EvaluateBinOpExpr(
13194 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
13196 case clang::X86::BI__builtin_ia32_prord128:
13197 case clang::X86::BI__builtin_ia32_prord256:
13198 case clang::X86::BI__builtin_ia32_prord512:
13199 case clang::X86::BI__builtin_ia32_prorq128:
13200 case clang::X86::BI__builtin_ia32_prorq256:
13201 case clang::X86::BI__builtin_ia32_prorq512:
13202 return EvaluateBinOpExpr(
13203 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
13205 case Builtin::BI__builtin_elementwise_max:
13206 case Builtin::BI__builtin_elementwise_min: {
13207 APValue SourceLHS, SourceRHS;
13212 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13219 ResultElements.reserve(SourceLen);
13221 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13224 switch (BuiltinOp) {
13225 case Builtin::BI__builtin_elementwise_max:
13226 ResultElements.push_back(
13230 case Builtin::BI__builtin_elementwise_min:
13231 ResultElements.push_back(
13238 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13240 case X86::BI__builtin_ia32_vpshldd128:
13241 case X86::BI__builtin_ia32_vpshldd256:
13242 case X86::BI__builtin_ia32_vpshldd512:
13243 case X86::BI__builtin_ia32_vpshldq128:
13244 case X86::BI__builtin_ia32_vpshldq256:
13245 case X86::BI__builtin_ia32_vpshldq512:
13246 case X86::BI__builtin_ia32_vpshldw128:
13247 case X86::BI__builtin_ia32_vpshldw256:
13248 case X86::BI__builtin_ia32_vpshldw512: {
13249 APValue SourceHi, SourceLo, SourceAmt;
13255 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13258 ResultElements.reserve(SourceLen);
13261 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13264 APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
13265 ResultElements.push_back(
13269 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13271 case X86::BI__builtin_ia32_vpshrdd128:
13272 case X86::BI__builtin_ia32_vpshrdd256:
13273 case X86::BI__builtin_ia32_vpshrdd512:
13274 case X86::BI__builtin_ia32_vpshrdq128:
13275 case X86::BI__builtin_ia32_vpshrdq256:
13276 case X86::BI__builtin_ia32_vpshrdq512:
13277 case X86::BI__builtin_ia32_vpshrdw128:
13278 case X86::BI__builtin_ia32_vpshrdw256:
13279 case X86::BI__builtin_ia32_vpshrdw512: {
13281 APValue SourceHi, SourceLo, SourceAmt;
13287 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
13290 ResultElements.reserve(SourceLen);
13293 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13296 APInt R = llvm::APIntOps::fshr(Hi, Lo, Amt);
13297 ResultElements.push_back(
13301 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13303 case X86::BI__builtin_ia32_compressdf128_mask:
13304 case X86::BI__builtin_ia32_compressdf256_mask:
13305 case X86::BI__builtin_ia32_compressdf512_mask:
13306 case X86::BI__builtin_ia32_compressdi128_mask:
13307 case X86::BI__builtin_ia32_compressdi256_mask:
13308 case X86::BI__builtin_ia32_compressdi512_mask:
13309 case X86::BI__builtin_ia32_compresshi128_mask:
13310 case X86::BI__builtin_ia32_compresshi256_mask:
13311 case X86::BI__builtin_ia32_compresshi512_mask:
13312 case X86::BI__builtin_ia32_compressqi128_mask:
13313 case X86::BI__builtin_ia32_compressqi256_mask:
13314 case X86::BI__builtin_ia32_compressqi512_mask:
13315 case X86::BI__builtin_ia32_compresssf128_mask:
13316 case X86::BI__builtin_ia32_compresssf256_mask:
13317 case X86::BI__builtin_ia32_compresssf512_mask:
13318 case X86::BI__builtin_ia32_compresssi128_mask:
13319 case X86::BI__builtin_ia32_compresssi256_mask:
13320 case X86::BI__builtin_ia32_compresssi512_mask: {
13331 ResultElements.reserve(NumElts);
13333 for (
unsigned I = 0; I != NumElts; ++I) {
13337 for (
unsigned I = ResultElements.size(); I != NumElts; ++I) {
13341 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13343 case X86::BI__builtin_ia32_expanddf128_mask:
13344 case X86::BI__builtin_ia32_expanddf256_mask:
13345 case X86::BI__builtin_ia32_expanddf512_mask:
13346 case X86::BI__builtin_ia32_expanddi128_mask:
13347 case X86::BI__builtin_ia32_expanddi256_mask:
13348 case X86::BI__builtin_ia32_expanddi512_mask:
13349 case X86::BI__builtin_ia32_expandhi128_mask:
13350 case X86::BI__builtin_ia32_expandhi256_mask:
13351 case X86::BI__builtin_ia32_expandhi512_mask:
13352 case X86::BI__builtin_ia32_expandqi128_mask:
13353 case X86::BI__builtin_ia32_expandqi256_mask:
13354 case X86::BI__builtin_ia32_expandqi512_mask:
13355 case X86::BI__builtin_ia32_expandsf128_mask:
13356 case X86::BI__builtin_ia32_expandsf256_mask:
13357 case X86::BI__builtin_ia32_expandsf512_mask:
13358 case X86::BI__builtin_ia32_expandsi128_mask:
13359 case X86::BI__builtin_ia32_expandsi256_mask:
13360 case X86::BI__builtin_ia32_expandsi512_mask: {
13371 ResultElements.reserve(NumElts);
13373 unsigned SourceIdx = 0;
13374 for (
unsigned I = 0; I != NumElts; ++I) {
13376 ResultElements.push_back(Source.
getVectorElt(SourceIdx++));
13380 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13382 case X86::BI__builtin_ia32_vpconflictsi_128:
13383 case X86::BI__builtin_ia32_vpconflictsi_256:
13384 case X86::BI__builtin_ia32_vpconflictsi_512:
13385 case X86::BI__builtin_ia32_vpconflictdi_128:
13386 case X86::BI__builtin_ia32_vpconflictdi_256:
13387 case X86::BI__builtin_ia32_vpconflictdi_512: {
13395 ResultElements.reserve(SourceLen);
13398 bool DestUnsigned =
13399 VecT->getElementType()->isUnsignedIntegerOrEnumerationType();
13401 for (
unsigned I = 0; I != SourceLen; ++I) {
13404 APInt ConflictMask(EltI.
getInt().getBitWidth(), 0);
13405 for (
unsigned J = 0; J != I; ++J) {
13407 ConflictMask.setBitVal(J, EltI.
getInt() == EltJ.
getInt());
13409 ResultElements.push_back(
APValue(
APSInt(ConflictMask, DestUnsigned)));
13411 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13413 case X86::BI__builtin_ia32_blendpd:
13414 case X86::BI__builtin_ia32_blendpd256:
13415 case X86::BI__builtin_ia32_blendps:
13416 case X86::BI__builtin_ia32_blendps256:
13417 case X86::BI__builtin_ia32_pblendw128:
13418 case X86::BI__builtin_ia32_pblendw256:
13419 case X86::BI__builtin_ia32_pblendd128:
13420 case X86::BI__builtin_ia32_pblendd256: {
13421 APValue SourceF, SourceT, SourceC;
13430 ResultElements.reserve(SourceLen);
13431 for (
unsigned EltNum = 0; EltNum != SourceLen; ++EltNum) {
13434 ResultElements.push_back(
C[EltNum % 8] ? T : F);
13437 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13440 case X86::BI__builtin_ia32_psignb128:
13441 case X86::BI__builtin_ia32_psignb256:
13442 case X86::BI__builtin_ia32_psignw128:
13443 case X86::BI__builtin_ia32_psignw256:
13444 case X86::BI__builtin_ia32_psignd128:
13445 case X86::BI__builtin_ia32_psignd256:
13446 return EvaluateBinOpExpr([](
const APInt &AElem,
const APInt &BElem) {
13447 if (BElem.isZero())
13448 return APInt::getZero(AElem.getBitWidth());
13449 if (BElem.isNegative())
13454 case X86::BI__builtin_ia32_blendvpd:
13455 case X86::BI__builtin_ia32_blendvpd256:
13456 case X86::BI__builtin_ia32_blendvps:
13457 case X86::BI__builtin_ia32_blendvps256:
13458 case X86::BI__builtin_ia32_pblendvb128:
13459 case X86::BI__builtin_ia32_pblendvb256: {
13461 APValue SourceF, SourceT, SourceC;
13469 ResultElements.reserve(SourceLen);
13471 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13475 APInt M =
C.isInt() ? (
APInt)
C.getInt() :
C.getFloat().bitcastToAPInt();
13476 ResultElements.push_back(M.isNegative() ? T : F);
13479 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13481 case X86::BI__builtin_ia32_selectb_128:
13482 case X86::BI__builtin_ia32_selectb_256:
13483 case X86::BI__builtin_ia32_selectb_512:
13484 case X86::BI__builtin_ia32_selectw_128:
13485 case X86::BI__builtin_ia32_selectw_256:
13486 case X86::BI__builtin_ia32_selectw_512:
13487 case X86::BI__builtin_ia32_selectd_128:
13488 case X86::BI__builtin_ia32_selectd_256:
13489 case X86::BI__builtin_ia32_selectd_512:
13490 case X86::BI__builtin_ia32_selectq_128:
13491 case X86::BI__builtin_ia32_selectq_256:
13492 case X86::BI__builtin_ia32_selectq_512:
13493 case X86::BI__builtin_ia32_selectph_128:
13494 case X86::BI__builtin_ia32_selectph_256:
13495 case X86::BI__builtin_ia32_selectph_512:
13496 case X86::BI__builtin_ia32_selectpbf_128:
13497 case X86::BI__builtin_ia32_selectpbf_256:
13498 case X86::BI__builtin_ia32_selectpbf_512:
13499 case X86::BI__builtin_ia32_selectps_128:
13500 case X86::BI__builtin_ia32_selectps_256:
13501 case X86::BI__builtin_ia32_selectps_512:
13502 case X86::BI__builtin_ia32_selectpd_128:
13503 case X86::BI__builtin_ia32_selectpd_256:
13504 case X86::BI__builtin_ia32_selectpd_512: {
13506 APValue SourceMask, SourceLHS, SourceRHS;
13515 ResultElements.reserve(SourceLen);
13517 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
13520 ResultElements.push_back(Mask[EltNum] ? LHS : RHS);
13523 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
13526 case X86::BI__builtin_ia32_cvtsd2ss: {
13539 Elements.push_back(ResultVal);
13542 for (
unsigned I = 1; I < NumEltsA; ++I) {
13548 case X86::BI__builtin_ia32_cvtsd2ss_round_mask: {
13549 APValue VecA, VecB, VecSrc, MaskValue;
13557 unsigned Mask = MaskValue.
getInt().getZExtValue();
13565 Elements.push_back(ResultVal);
13571 for (
unsigned I = 1; I < NumEltsA; ++I) {
13577 case X86::BI__builtin_ia32_cvtpd2ps:
13578 case X86::BI__builtin_ia32_cvtpd2ps256:
13579 case X86::BI__builtin_ia32_cvtpd2ps_mask:
13580 case X86::BI__builtin_ia32_cvtpd2ps512_mask: {
13582 const auto BuiltinID = BuiltinOp;
13583 bool IsMasked = (BuiltinID == X86::BI__builtin_ia32_cvtpd2ps_mask ||
13584 BuiltinID == X86::BI__builtin_ia32_cvtpd2ps512_mask);
13591 unsigned Mask = 0xFFFFFFFF;
13592 bool NeedsMerge =
false;
13597 Mask = MaskValue.
getInt().getZExtValue();
13598 auto NumEltsResult = E->
getType()->
getAs<VectorType>()->getNumElements();
13599 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13600 if (!((Mask >> I) & 1)) {
13611 unsigned NumEltsResult =
13615 for (
unsigned I = 0; I < NumEltsResult; ++I) {
13616 if (IsMasked && !((Mask >> I) & 1)) {
13624 if (I >= NumEltsInput) {
13625 Elements.push_back(
APValue(APFloat::getZero(APFloat::IEEEsingle())));
13634 Elements.push_back(ResultVal);
13639 case X86::BI__builtin_ia32_shufps:
13640 case X86::BI__builtin_ia32_shufps256:
13641 case X86::BI__builtin_ia32_shufps512: {
13645 [](
unsigned DstIdx,
13646 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13647 constexpr unsigned LaneBits = 128u;
13648 unsigned NumElemPerLane = LaneBits / 32;
13649 unsigned NumSelectableElems = NumElemPerLane / 2;
13650 unsigned BitsPerElem = 2;
13651 unsigned IndexMask = (1u << BitsPerElem) - 1;
13652 unsigned MaskBits = 8;
13653 unsigned Lane = DstIdx / NumElemPerLane;
13654 unsigned ElemInLane = DstIdx % NumElemPerLane;
13655 unsigned LaneOffset = Lane * NumElemPerLane;
13656 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13657 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13658 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13659 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13664 case X86::BI__builtin_ia32_shufpd:
13665 case X86::BI__builtin_ia32_shufpd256:
13666 case X86::BI__builtin_ia32_shufpd512: {
13670 [](
unsigned DstIdx,
13671 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13672 constexpr unsigned LaneBits = 128u;
13673 unsigned NumElemPerLane = LaneBits / 64;
13674 unsigned NumSelectableElems = NumElemPerLane / 2;
13675 unsigned BitsPerElem = 1;
13676 unsigned IndexMask = (1u << BitsPerElem) - 1;
13677 unsigned MaskBits = 8;
13678 unsigned Lane = DstIdx / NumElemPerLane;
13679 unsigned ElemInLane = DstIdx % NumElemPerLane;
13680 unsigned LaneOffset = Lane * NumElemPerLane;
13681 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13682 unsigned SrcIdx = (ElemInLane < NumSelectableElems) ? 0 : 1;
13683 unsigned Index = (ShuffleMask >> BitIndex) & IndexMask;
13684 return {SrcIdx,
static_cast<int>(LaneOffset + Index)};
13689 case X86::BI__builtin_ia32_insertps128: {
13693 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13695 if ((Mask & (1 << DstIdx)) != 0) {
13700 unsigned SrcElem = (Mask >> 6) & 0x3;
13701 unsigned DstElem = (Mask >> 4) & 0x3;
13702 if (DstIdx == DstElem) {
13704 return {1,
static_cast<int>(SrcElem)};
13707 return {0,
static_cast<int>(DstIdx)};
13713 case X86::BI__builtin_ia32_pshufb128:
13714 case X86::BI__builtin_ia32_pshufb256:
13715 case X86::BI__builtin_ia32_pshufb512: {
13719 [](
unsigned DstIdx,
13720 unsigned ShuffleMask) -> std::pair<unsigned, int> {
13723 return std::make_pair(0, -1);
13725 unsigned LaneBase = (DstIdx / 16) * 16;
13726 unsigned SrcOffset = Ctlb & 0x0F;
13727 unsigned SrcIdx = LaneBase + SrcOffset;
13728 return std::make_pair(0,
static_cast<int>(SrcIdx));
13734 case X86::BI__builtin_ia32_pshuflw:
13735 case X86::BI__builtin_ia32_pshuflw256:
13736 case X86::BI__builtin_ia32_pshuflw512: {
13740 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13741 constexpr unsigned LaneBits = 128u;
13742 constexpr unsigned ElemBits = 16u;
13743 constexpr unsigned LaneElts = LaneBits / ElemBits;
13744 constexpr unsigned HalfSize = 4;
13745 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13746 unsigned LaneIdx = DstIdx % LaneElts;
13747 if (LaneIdx < HalfSize) {
13748 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13749 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13751 return std::make_pair(0,
static_cast<int>(DstIdx));
13757 case X86::BI__builtin_ia32_pshufhw:
13758 case X86::BI__builtin_ia32_pshufhw256:
13759 case X86::BI__builtin_ia32_pshufhw512: {
13763 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13764 constexpr unsigned LaneBits = 128u;
13765 constexpr unsigned ElemBits = 16u;
13766 constexpr unsigned LaneElts = LaneBits / ElemBits;
13767 constexpr unsigned HalfSize = 4;
13768 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13769 unsigned LaneIdx = DstIdx % LaneElts;
13770 if (LaneIdx >= HalfSize) {
13771 unsigned Rel = LaneIdx - HalfSize;
13772 unsigned Sel = (Mask >> (2 * Rel)) & 0x3;
13773 return std::make_pair(
13774 0,
static_cast<int>(LaneBase + HalfSize + Sel));
13776 return std::make_pair(0,
static_cast<int>(DstIdx));
13782 case X86::BI__builtin_ia32_pshufd:
13783 case X86::BI__builtin_ia32_pshufd256:
13784 case X86::BI__builtin_ia32_pshufd512:
13785 case X86::BI__builtin_ia32_vpermilps:
13786 case X86::BI__builtin_ia32_vpermilps256:
13787 case X86::BI__builtin_ia32_vpermilps512: {
13791 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13792 constexpr unsigned LaneBits = 128u;
13793 constexpr unsigned ElemBits = 32u;
13794 constexpr unsigned LaneElts = LaneBits / ElemBits;
13795 unsigned LaneBase = (DstIdx / LaneElts) * LaneElts;
13796 unsigned LaneIdx = DstIdx % LaneElts;
13797 unsigned Sel = (Mask >> (2 * LaneIdx)) & 0x3;
13798 return std::make_pair(0,
static_cast<int>(LaneBase + Sel));
13804 case X86::BI__builtin_ia32_vpermilvarpd:
13805 case X86::BI__builtin_ia32_vpermilvarpd256:
13806 case X86::BI__builtin_ia32_vpermilvarpd512: {
13810 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13811 unsigned NumElemPerLane = 2;
13812 unsigned Lane = DstIdx / NumElemPerLane;
13813 unsigned Offset = Mask & 0b10 ? 1 : 0;
13814 return std::make_pair(
13815 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13821 case X86::BI__builtin_ia32_vpermilpd:
13822 case X86::BI__builtin_ia32_vpermilpd256:
13823 case X86::BI__builtin_ia32_vpermilpd512: {
13826 unsigned NumElemPerLane = 2;
13827 unsigned BitsPerElem = 1;
13828 unsigned MaskBits = 8;
13829 unsigned IndexMask = 0x1;
13830 unsigned Lane = DstIdx / NumElemPerLane;
13831 unsigned LaneOffset = Lane * NumElemPerLane;
13832 unsigned BitIndex = (DstIdx * BitsPerElem) % MaskBits;
13833 unsigned Index = (Control >> BitIndex) & IndexMask;
13834 return std::make_pair(0,
static_cast<int>(LaneOffset + Index));
13840 case X86::BI__builtin_ia32_permdf256:
13841 case X86::BI__builtin_ia32_permdi256: {
13846 unsigned Index = (Control >> (2 * DstIdx)) & 0x3;
13847 return std::make_pair(0,
static_cast<int>(Index));
13853 case X86::BI__builtin_ia32_vpermilvarps:
13854 case X86::BI__builtin_ia32_vpermilvarps256:
13855 case X86::BI__builtin_ia32_vpermilvarps512: {
13859 [](
unsigned DstIdx,
unsigned Mask) -> std::pair<unsigned, int> {
13860 unsigned NumElemPerLane = 4;
13861 unsigned Lane = DstIdx / NumElemPerLane;
13862 unsigned Offset = Mask & 0b11;
13863 return std::make_pair(
13864 0,
static_cast<int>(Lane * NumElemPerLane + Offset));
13870 case X86::BI__builtin_ia32_vpmultishiftqb128:
13871 case X86::BI__builtin_ia32_vpmultishiftqb256:
13872 case X86::BI__builtin_ia32_vpmultishiftqb512: {
13880 unsigned NumBytesInQWord = 8;
13881 unsigned NumBitsInByte = 8;
13883 unsigned NumQWords = NumBytes / NumBytesInQWord;
13885 Result.reserve(NumBytes);
13887 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
13888 APInt BQWord(64, 0);
13889 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13890 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13892 BQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
13895 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
13896 unsigned Idx = QWordId * NumBytesInQWord + ByteIdx;
13900 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
13901 Byte.setBitVal(BitIdx, BQWord[(Ctrl + BitIdx) & 0x3F]);
13909 case X86::BI__builtin_ia32_phminposuw128: {
13916 unsigned ElemBitWidth = Info.Ctx.getTypeSize(ElemQT);
13918 APInt MinIndex(ElemBitWidth, 0);
13920 for (
unsigned I = 1; I != SourceLen; ++I) {
13922 if (MinVal.ugt(Val)) {
13931 ->isUnsignedIntegerOrEnumerationType();
13934 Result.reserve(SourceLen);
13936 Result.emplace_back(
APSInt(MinIndex, ResultUnsigned));
13937 for (
unsigned I = 0; I != SourceLen - 2; ++I) {
13943 case X86::BI__builtin_ia32_psraq128:
13944 case X86::BI__builtin_ia32_psraq256:
13945 case X86::BI__builtin_ia32_psraq512:
13946 case X86::BI__builtin_ia32_psrad128:
13947 case X86::BI__builtin_ia32_psrad256:
13948 case X86::BI__builtin_ia32_psrad512:
13949 case X86::BI__builtin_ia32_psraw128:
13950 case X86::BI__builtin_ia32_psraw256:
13951 case X86::BI__builtin_ia32_psraw512: {
13955 [](
const APInt &Elt, uint64_t Count) {
return Elt.ashr(Count); },
13956 [](
const APInt &Elt,
unsigned Width) {
13957 return Elt.ashr(Width - 1);
13963 case X86::BI__builtin_ia32_psllq128:
13964 case X86::BI__builtin_ia32_psllq256:
13965 case X86::BI__builtin_ia32_psllq512:
13966 case X86::BI__builtin_ia32_pslld128:
13967 case X86::BI__builtin_ia32_pslld256:
13968 case X86::BI__builtin_ia32_pslld512:
13969 case X86::BI__builtin_ia32_psllw128:
13970 case X86::BI__builtin_ia32_psllw256:
13971 case X86::BI__builtin_ia32_psllw512: {
13975 [](
const APInt &Elt, uint64_t Count) {
return Elt.shl(Count); },
13976 [](
const APInt &Elt,
unsigned Width) {
13977 return APInt::getZero(Width);
13983 case X86::BI__builtin_ia32_psrlq128:
13984 case X86::BI__builtin_ia32_psrlq256:
13985 case X86::BI__builtin_ia32_psrlq512:
13986 case X86::BI__builtin_ia32_psrld128:
13987 case X86::BI__builtin_ia32_psrld256:
13988 case X86::BI__builtin_ia32_psrld512:
13989 case X86::BI__builtin_ia32_psrlw128:
13990 case X86::BI__builtin_ia32_psrlw256:
13991 case X86::BI__builtin_ia32_psrlw512: {
13995 [](
const APInt &Elt, uint64_t Count) {
return Elt.lshr(Count); },
13996 [](
const APInt &Elt,
unsigned Width) {
13997 return APInt::getZero(Width);
14003 case X86::BI__builtin_ia32_pternlogd128_mask:
14004 case X86::BI__builtin_ia32_pternlogd256_mask:
14005 case X86::BI__builtin_ia32_pternlogd512_mask:
14006 case X86::BI__builtin_ia32_pternlogq128_mask:
14007 case X86::BI__builtin_ia32_pternlogq256_mask:
14008 case X86::BI__builtin_ia32_pternlogq512_mask: {
14009 APValue AValue, BValue, CValue, ImmValue, UValue;
14017 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14023 ResultElements.reserve(ResultLen);
14025 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14031 unsigned BitWidth = ALane.getBitWidth();
14032 APInt ResLane(BitWidth, 0);
14034 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14035 unsigned ABit = ALane[Bit];
14036 unsigned BBit = BLane[Bit];
14037 unsigned CBit = CLane[Bit];
14039 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14040 ResLane.setBitVal(Bit, Imm[Idx]);
14042 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14044 ResultElements.push_back(
APValue(
APSInt(ALane, DestUnsigned)));
14047 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14049 case X86::BI__builtin_ia32_pternlogd128_maskz:
14050 case X86::BI__builtin_ia32_pternlogd256_maskz:
14051 case X86::BI__builtin_ia32_pternlogd512_maskz:
14052 case X86::BI__builtin_ia32_pternlogq128_maskz:
14053 case X86::BI__builtin_ia32_pternlogq256_maskz:
14054 case X86::BI__builtin_ia32_pternlogq512_maskz: {
14055 APValue AValue, BValue, CValue, ImmValue, UValue;
14063 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14069 ResultElements.reserve(ResultLen);
14071 for (
unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
14076 unsigned BitWidth = ALane.getBitWidth();
14077 APInt ResLane(BitWidth, 0);
14080 for (
unsigned Bit = 0; Bit < BitWidth; ++Bit) {
14081 unsigned ABit = ALane[Bit];
14082 unsigned BBit = BLane[Bit];
14083 unsigned CBit = CLane[Bit];
14085 unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
14086 ResLane.setBitVal(Bit, Imm[Idx]);
14089 ResultElements.push_back(
APValue(
APSInt(ResLane, DestUnsigned)));
14091 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14094 case Builtin::BI__builtin_elementwise_clzg:
14095 case Builtin::BI__builtin_elementwise_ctzg: {
14097 std::optional<APValue> Fallback;
14104 Fallback = FallbackTmp;
14107 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14110 ResultElements.reserve(SourceLen);
14112 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14117 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
14119 Builtin::BI__builtin_elementwise_ctzg);
14122 ResultElements.push_back(Fallback->getVectorElt(EltNum));
14125 switch (BuiltinOp) {
14126 case Builtin::BI__builtin_elementwise_clzg:
14127 ResultElements.push_back(
APValue(
14128 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
14131 case Builtin::BI__builtin_elementwise_ctzg:
14132 ResultElements.push_back(
APValue(
14133 APSInt(
APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
14139 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14142 case Builtin::BI__builtin_elementwise_fma: {
14143 APValue SourceX, SourceY, SourceZ;
14151 ResultElements.reserve(SourceLen);
14153 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14158 (void)
Result.fusedMultiplyAdd(Y, Z, RM);
14161 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14164 case clang::X86::BI__builtin_ia32_phaddw128:
14165 case clang::X86::BI__builtin_ia32_phaddw256:
14166 case clang::X86::BI__builtin_ia32_phaddd128:
14167 case clang::X86::BI__builtin_ia32_phaddd256:
14168 case clang::X86::BI__builtin_ia32_phaddsw128:
14169 case clang::X86::BI__builtin_ia32_phaddsw256:
14171 case clang::X86::BI__builtin_ia32_phsubw128:
14172 case clang::X86::BI__builtin_ia32_phsubw256:
14173 case clang::X86::BI__builtin_ia32_phsubd128:
14174 case clang::X86::BI__builtin_ia32_phsubd256:
14175 case clang::X86::BI__builtin_ia32_phsubsw128:
14176 case clang::X86::BI__builtin_ia32_phsubsw256: {
14177 APValue SourceLHS, SourceRHS;
14181 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14185 unsigned EltBits = Info.Ctx.getIntWidth(DestEltTy);
14186 unsigned EltsPerLane = 128 / EltBits;
14188 ResultElements.reserve(NumElts);
14190 for (
unsigned LaneStart = 0; LaneStart != NumElts;
14191 LaneStart += EltsPerLane) {
14192 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14195 switch (BuiltinOp) {
14196 case clang::X86::BI__builtin_ia32_phaddw128:
14197 case clang::X86::BI__builtin_ia32_phaddw256:
14198 case clang::X86::BI__builtin_ia32_phaddd128:
14199 case clang::X86::BI__builtin_ia32_phaddd256: {
14200 APSInt Res(LHSA + LHSB, DestUnsigned);
14201 ResultElements.push_back(
APValue(Res));
14204 case clang::X86::BI__builtin_ia32_phaddsw128:
14205 case clang::X86::BI__builtin_ia32_phaddsw256: {
14206 APSInt Res(LHSA.sadd_sat(LHSB));
14207 ResultElements.push_back(
APValue(Res));
14210 case clang::X86::BI__builtin_ia32_phsubw128:
14211 case clang::X86::BI__builtin_ia32_phsubw256:
14212 case clang::X86::BI__builtin_ia32_phsubd128:
14213 case clang::X86::BI__builtin_ia32_phsubd256: {
14214 APSInt Res(LHSA - LHSB, DestUnsigned);
14215 ResultElements.push_back(
APValue(Res));
14218 case clang::X86::BI__builtin_ia32_phsubsw128:
14219 case clang::X86::BI__builtin_ia32_phsubsw256: {
14220 APSInt Res(LHSA.ssub_sat(LHSB));
14221 ResultElements.push_back(
APValue(Res));
14226 for (
unsigned I = 0; I != EltsPerLane; I += 2) {
14229 switch (BuiltinOp) {
14230 case clang::X86::BI__builtin_ia32_phaddw128:
14231 case clang::X86::BI__builtin_ia32_phaddw256:
14232 case clang::X86::BI__builtin_ia32_phaddd128:
14233 case clang::X86::BI__builtin_ia32_phaddd256: {
14234 APSInt Res(RHSA + RHSB, DestUnsigned);
14235 ResultElements.push_back(
APValue(Res));
14238 case clang::X86::BI__builtin_ia32_phaddsw128:
14239 case clang::X86::BI__builtin_ia32_phaddsw256: {
14240 APSInt Res(RHSA.sadd_sat(RHSB));
14241 ResultElements.push_back(
APValue(Res));
14244 case clang::X86::BI__builtin_ia32_phsubw128:
14245 case clang::X86::BI__builtin_ia32_phsubw256:
14246 case clang::X86::BI__builtin_ia32_phsubd128:
14247 case clang::X86::BI__builtin_ia32_phsubd256: {
14248 APSInt Res(RHSA - RHSB, DestUnsigned);
14249 ResultElements.push_back(
APValue(Res));
14252 case clang::X86::BI__builtin_ia32_phsubsw128:
14253 case clang::X86::BI__builtin_ia32_phsubsw256: {
14254 APSInt Res(RHSA.ssub_sat(RHSB));
14255 ResultElements.push_back(
APValue(Res));
14261 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14263 case clang::X86::BI__builtin_ia32_haddpd:
14264 case clang::X86::BI__builtin_ia32_haddps:
14265 case clang::X86::BI__builtin_ia32_haddps256:
14266 case clang::X86::BI__builtin_ia32_haddpd256:
14267 case clang::X86::BI__builtin_ia32_hsubpd:
14268 case clang::X86::BI__builtin_ia32_hsubps:
14269 case clang::X86::BI__builtin_ia32_hsubps256:
14270 case clang::X86::BI__builtin_ia32_hsubpd256: {
14271 APValue SourceLHS, SourceRHS;
14277 ResultElements.reserve(NumElts);
14279 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14280 unsigned EltBits = Info.Ctx.getTypeSize(DestEltTy);
14281 unsigned NumLanes = NumElts * EltBits / 128;
14282 unsigned NumElemsPerLane = NumElts / NumLanes;
14283 unsigned HalfElemsPerLane = NumElemsPerLane / 2;
14285 for (
unsigned L = 0; L != NumElts; L += NumElemsPerLane) {
14286 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14289 switch (BuiltinOp) {
14290 case clang::X86::BI__builtin_ia32_haddpd:
14291 case clang::X86::BI__builtin_ia32_haddps:
14292 case clang::X86::BI__builtin_ia32_haddps256:
14293 case clang::X86::BI__builtin_ia32_haddpd256:
14294 LHSA.add(LHSB, RM);
14296 case clang::X86::BI__builtin_ia32_hsubpd:
14297 case clang::X86::BI__builtin_ia32_hsubps:
14298 case clang::X86::BI__builtin_ia32_hsubps256:
14299 case clang::X86::BI__builtin_ia32_hsubpd256:
14300 LHSA.subtract(LHSB, RM);
14303 ResultElements.push_back(
APValue(LHSA));
14305 for (
unsigned I = 0; I != HalfElemsPerLane; ++I) {
14308 switch (BuiltinOp) {
14309 case clang::X86::BI__builtin_ia32_haddpd:
14310 case clang::X86::BI__builtin_ia32_haddps:
14311 case clang::X86::BI__builtin_ia32_haddps256:
14312 case clang::X86::BI__builtin_ia32_haddpd256:
14313 RHSA.add(RHSB, RM);
14315 case clang::X86::BI__builtin_ia32_hsubpd:
14316 case clang::X86::BI__builtin_ia32_hsubps:
14317 case clang::X86::BI__builtin_ia32_hsubps256:
14318 case clang::X86::BI__builtin_ia32_hsubpd256:
14319 RHSA.subtract(RHSB, RM);
14322 ResultElements.push_back(
APValue(RHSA));
14325 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14327 case clang::X86::BI__builtin_ia32_addsubpd:
14328 case clang::X86::BI__builtin_ia32_addsubps:
14329 case clang::X86::BI__builtin_ia32_addsubpd256:
14330 case clang::X86::BI__builtin_ia32_addsubps256: {
14333 APValue SourceLHS, SourceRHS;
14339 ResultElements.reserve(NumElems);
14342 for (
unsigned I = 0; I != NumElems; ++I) {
14347 LHS.subtract(RHS, RM);
14352 ResultElements.push_back(
APValue(LHS));
14354 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14356 case clang::X86::BI__builtin_ia32_pclmulqdq128:
14357 case clang::X86::BI__builtin_ia32_pclmulqdq256:
14358 case clang::X86::BI__builtin_ia32_pclmulqdq512: {
14362 APValue SourceLHS, SourceRHS;
14372 bool SelectUpperA = (Imm8 & 0x01) != 0;
14373 bool SelectUpperB = (Imm8 & 0x10) != 0;
14377 ResultElements.reserve(NumElems);
14378 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14382 for (
unsigned Lane = 0; Lane < NumElems; Lane += 2) {
14391 APInt A = SelectUpperA ? A1 : A0;
14392 APInt B = SelectUpperB ? B1 : B0;
14395 APInt A128 = A.zext(128);
14396 APInt B128 = B.zext(128);
14399 APInt Result = llvm::APIntOps::clmul(A128, B128);
14402 APSInt ResultLow(
Result.extractBits(64, 0), DestUnsigned);
14403 APSInt ResultHigh(
Result.extractBits(64, 64), DestUnsigned);
14405 ResultElements.push_back(
APValue(ResultLow));
14406 ResultElements.push_back(
APValue(ResultHigh));
14409 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14411 case Builtin::BI__builtin_elementwise_clmul:
14412 return EvaluateBinOpExpr(llvm::APIntOps::clmul);
14413 case Builtin::BI__builtin_elementwise_pext:
14414 return EvaluateBinOpExpr(llvm::APIntOps::pext);
14415 case Builtin::BI__builtin_elementwise_pdep:
14416 return EvaluateBinOpExpr(llvm::APIntOps::pdep);
14417 case Builtin::BI__builtin_elementwise_fshl:
14418 case Builtin::BI__builtin_elementwise_fshr: {
14419 APValue SourceHi, SourceLo, SourceShift;
14425 QualType DestEltTy = E->
getType()->
castAs<VectorType>()->getElementType();
14431 ResultElements.reserve(SourceLen);
14432 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
14436 switch (BuiltinOp) {
14437 case Builtin::BI__builtin_elementwise_fshl:
14438 ResultElements.push_back(
APValue(
14439 APSInt(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned())));
14441 case Builtin::BI__builtin_elementwise_fshr:
14442 ResultElements.push_back(
APValue(
14443 APSInt(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned())));
14448 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14451 case X86::BI__builtin_ia32_shuf_f32x4_256:
14452 case X86::BI__builtin_ia32_shuf_i32x4_256:
14453 case X86::BI__builtin_ia32_shuf_f64x2_256:
14454 case X86::BI__builtin_ia32_shuf_i64x2_256:
14455 case X86::BI__builtin_ia32_shuf_f32x4:
14456 case X86::BI__builtin_ia32_shuf_i32x4:
14457 case X86::BI__builtin_ia32_shuf_f64x2:
14458 case X86::BI__builtin_ia32_shuf_i64x2: {
14472 unsigned ElemBits = Info.Ctx.getTypeSize(ElemQT);
14473 unsigned LaneBits = 128u;
14474 unsigned NumLanes = (NumElems * ElemBits) / LaneBits;
14475 unsigned NumElemsPerLane = LaneBits / ElemBits;
14479 ResultElements.reserve(DstLen);
14484 [NumLanes, NumElemsPerLane](
unsigned DstIdx,
unsigned ShuffleMask)
14485 -> std::pair<unsigned, int> {
14487 unsigned BitsPerElem = NumLanes / 2;
14488 unsigned IndexMask = (1u << BitsPerElem) - 1;
14489 unsigned Lane = DstIdx / NumElemsPerLane;
14490 unsigned SrcIdx = (Lane < NumLanes / 2) ? 0 : 1;
14491 unsigned BitIdx = BitsPerElem * Lane;
14492 unsigned SrcLaneIdx = (ShuffleMask >> BitIdx) & IndexMask;
14493 unsigned ElemInLane = DstIdx % NumElemsPerLane;
14494 unsigned IdxToPick = SrcLaneIdx * NumElemsPerLane + ElemInLane;
14495 return {SrcIdx, IdxToPick};
14501 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14502 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14503 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi:
14504 case X86::BI__builtin_ia32_vgf2p8affineqb_v16qi:
14505 case X86::BI__builtin_ia32_vgf2p8affineqb_v32qi:
14506 case X86::BI__builtin_ia32_vgf2p8affineqb_v64qi: {
14518 bool IsInverse =
false;
14519 switch (BuiltinOp) {
14520 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v16qi:
14521 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v32qi:
14522 case X86::BI__builtin_ia32_vgf2p8affineinvqb_v64qi: {
14527 unsigned NumBitsInByte = 8;
14528 unsigned NumBytesInQWord = 8;
14529 unsigned NumBitsInQWord = 64;
14531 unsigned NumQWords = NumBytes / NumBytesInQWord;
14533 Result.reserve(NumBytes);
14536 for (
unsigned QWordIdx = 0; QWordIdx != NumQWords; ++QWordIdx) {
14538 APInt XQWord(NumBitsInQWord, 0);
14539 APInt AQWord(NumBitsInQWord, 0);
14540 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14541 unsigned Idx = QWordIdx * NumBytesInQWord + ByteIdx;
14542 APInt XByte =
X.getVectorElt(Idx).getInt();
14544 XQWord.insertBits(XByte, ByteIdx * NumBitsInByte);
14545 AQWord.insertBits(AByte, ByteIdx * NumBitsInByte);
14548 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
14550 XQWord.lshr(ByteIdx * NumBitsInByte).getLoBits(8).getZExtValue();
14559 case X86::BI__builtin_ia32_vgf2p8mulb_v16qi:
14560 case X86::BI__builtin_ia32_vgf2p8mulb_v32qi:
14561 case X86::BI__builtin_ia32_vgf2p8mulb_v64qi: {
14572 Result.reserve(NumBytes);
14574 for (
unsigned ByteIdx = 0; ByteIdx != NumBytes; ++ByteIdx) {
14584 case X86::BI__builtin_ia32_insertf32x4_256:
14585 case X86::BI__builtin_ia32_inserti32x4_256:
14586 case X86::BI__builtin_ia32_insertf64x2_256:
14587 case X86::BI__builtin_ia32_inserti64x2_256:
14588 case X86::BI__builtin_ia32_insertf32x4:
14589 case X86::BI__builtin_ia32_inserti32x4:
14590 case X86::BI__builtin_ia32_insertf64x2_512:
14591 case X86::BI__builtin_ia32_inserti64x2_512:
14592 case X86::BI__builtin_ia32_insertf32x8:
14593 case X86::BI__builtin_ia32_inserti32x8:
14594 case X86::BI__builtin_ia32_insertf64x4:
14595 case X86::BI__builtin_ia32_inserti64x4:
14596 case X86::BI__builtin_ia32_vinsertf128_ps256:
14597 case X86::BI__builtin_ia32_vinsertf128_pd256:
14598 case X86::BI__builtin_ia32_vinsertf128_si256:
14599 case X86::BI__builtin_ia32_insert128i256: {
14600 APValue SourceDst, SourceSub;
14612 assert(SubLen != 0 && DstLen != 0 && (DstLen % SubLen) == 0);
14613 unsigned NumLanes = DstLen / SubLen;
14614 unsigned LaneIdx = (Imm.getZExtValue() % NumLanes) * SubLen;
14617 ResultElements.reserve(DstLen);
14619 for (
unsigned EltNum = 0; EltNum < DstLen; ++EltNum) {
14620 if (EltNum >= LaneIdx && EltNum < LaneIdx + SubLen)
14621 ResultElements.push_back(SourceSub.
getVectorElt(EltNum - LaneIdx));
14623 ResultElements.push_back(SourceDst.
getVectorElt(EltNum));
14626 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
14629 case clang::X86::BI__builtin_ia32_vec_set_v4hi:
14630 case clang::X86::BI__builtin_ia32_vec_set_v16qi:
14631 case clang::X86::BI__builtin_ia32_vec_set_v8hi:
14632 case clang::X86::BI__builtin_ia32_vec_set_v4si:
14633 case clang::X86::BI__builtin_ia32_vec_set_v2di:
14634 case clang::X86::BI__builtin_ia32_vec_set_v32qi:
14635 case clang::X86::BI__builtin_ia32_vec_set_v16hi:
14636 case clang::X86::BI__builtin_ia32_vec_set_v8si:
14637 case clang::X86::BI__builtin_ia32_vec_set_v4di: {
14645 QualType ElemTy = E->
getType()->
castAs<VectorType>()->getElementType();
14646 unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
14648 Scalar.setIsUnsigned(ElemUnsigned);
14654 static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
14657 Elems.reserve(NumElems);
14658 for (
unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
14659 Elems.push_back(ElemNum == Index ? ElemAV : VecVal.
getVectorElt(ElemNum));
14664 case X86::BI__builtin_ia32_pslldqi128_byteshift:
14665 case X86::BI__builtin_ia32_pslldqi256_byteshift:
14666 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
14670 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14671 unsigned LaneBase = (DstIdx / 16) * 16;
14672 unsigned LaneIdx = DstIdx % 16;
14673 if (LaneIdx < Shift)
14674 return std::make_pair(0, -1);
14676 return std::make_pair(
14677 0,
static_cast<int>(LaneBase + LaneIdx - Shift));
14683 case X86::BI__builtin_ia32_psrldqi128_byteshift:
14684 case X86::BI__builtin_ia32_psrldqi256_byteshift:
14685 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
14689 [](
unsigned DstIdx,
unsigned Shift) -> std::pair<unsigned, int> {
14690 unsigned LaneBase = (DstIdx / 16) * 16;
14691 unsigned LaneIdx = DstIdx % 16;
14692 if (LaneIdx + Shift < 16)
14693 return std::make_pair(
14694 0,
static_cast<int>(LaneBase + LaneIdx + Shift));
14696 return std::make_pair(0, -1);
14702 case X86::BI__builtin_ia32_palignr128:
14703 case X86::BI__builtin_ia32_palignr256:
14704 case X86::BI__builtin_ia32_palignr512: {
14708 unsigned VecIdx = 1;
14711 int Lane = DstIdx / 16;
14712 int Offset = DstIdx % 16;
14715 unsigned ShiftedIdx = Offset + (
Shift & 0xFF);
14716 if (ShiftedIdx < 16) {
14717 ElemIdx = ShiftedIdx + (Lane * 16);
14718 }
else if (ShiftedIdx < 32) {
14720 ElemIdx = (ShiftedIdx - 16) + (Lane * 16);
14723 return std::pair<unsigned, int>{VecIdx, ElemIdx};
14728 case X86::BI__builtin_ia32_alignd128:
14729 case X86::BI__builtin_ia32_alignd256:
14730 case X86::BI__builtin_ia32_alignd512:
14731 case X86::BI__builtin_ia32_alignq128:
14732 case X86::BI__builtin_ia32_alignq256:
14733 case X86::BI__builtin_ia32_alignq512: {
14735 unsigned NumElems = E->
getType()->
castAs<VectorType>()->getNumElements();
14737 [NumElems](
unsigned DstIdx,
unsigned Shift) {
14738 unsigned Imm =
Shift & 0xFF;
14739 unsigned EffectiveShift = Imm & (NumElems - 1);
14740 unsigned SourcePos = DstIdx + EffectiveShift;
14741 unsigned VecIdx = SourcePos < NumElems ? 1 : 0;
14742 unsigned ElemIdx = SourcePos & (NumElems - 1);
14744 return std::pair<unsigned, int>{
14745 VecIdx,
static_cast<int>(ElemIdx)};
14750 case X86::BI__builtin_ia32_permvarsi256:
14751 case X86::BI__builtin_ia32_permvarsf256:
14752 case X86::BI__builtin_ia32_permvardf512:
14753 case X86::BI__builtin_ia32_permvardi512:
14754 case X86::BI__builtin_ia32_permvarhi128: {
14757 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14758 int Offset = ShuffleMask & 0x7;
14759 return std::pair<unsigned, int>{0, Offset};
14764 case X86::BI__builtin_ia32_permvarqi128:
14765 case X86::BI__builtin_ia32_permvarhi256:
14766 case X86::BI__builtin_ia32_permvarsi512:
14767 case X86::BI__builtin_ia32_permvarsf512: {
14770 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14771 int Offset = ShuffleMask & 0xF;
14772 return std::pair<unsigned, int>{0, Offset};
14777 case X86::BI__builtin_ia32_permvardi256:
14778 case X86::BI__builtin_ia32_permvardf256: {
14781 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14782 int Offset = ShuffleMask & 0x3;
14783 return std::pair<unsigned, int>{0, Offset};
14788 case X86::BI__builtin_ia32_permvarqi256:
14789 case X86::BI__builtin_ia32_permvarhi512: {
14792 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14793 int Offset = ShuffleMask & 0x1F;
14794 return std::pair<unsigned, int>{0, Offset};
14799 case X86::BI__builtin_ia32_permvarqi512: {
14802 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14803 int Offset = ShuffleMask & 0x3F;
14804 return std::pair<unsigned, int>{0, Offset};
14809 case X86::BI__builtin_ia32_vpermi2varq128:
14810 case X86::BI__builtin_ia32_vpermi2varpd128: {
14813 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14814 int Offset = ShuffleMask & 0x1;
14815 unsigned SrcIdx = (ShuffleMask >> 1) & 0x1;
14816 return std::pair<unsigned, int>{SrcIdx, Offset};
14821 case X86::BI__builtin_ia32_vpermi2vard128:
14822 case X86::BI__builtin_ia32_vpermi2varps128:
14823 case X86::BI__builtin_ia32_vpermi2varq256:
14824 case X86::BI__builtin_ia32_vpermi2varpd256: {
14827 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14828 int Offset = ShuffleMask & 0x3;
14829 unsigned SrcIdx = (ShuffleMask >> 2) & 0x1;
14830 return std::pair<unsigned, int>{SrcIdx, Offset};
14835 case X86::BI__builtin_ia32_vpermi2varhi128:
14836 case X86::BI__builtin_ia32_vpermi2vard256:
14837 case X86::BI__builtin_ia32_vpermi2varps256:
14838 case X86::BI__builtin_ia32_vpermi2varq512:
14839 case X86::BI__builtin_ia32_vpermi2varpd512: {
14842 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14843 int Offset = ShuffleMask & 0x7;
14844 unsigned SrcIdx = (ShuffleMask >> 3) & 0x1;
14845 return std::pair<unsigned, int>{SrcIdx, Offset};
14850 case X86::BI__builtin_ia32_vpermi2varqi128:
14851 case X86::BI__builtin_ia32_vpermi2varhi256:
14852 case X86::BI__builtin_ia32_vpermi2vard512:
14853 case X86::BI__builtin_ia32_vpermi2varps512: {
14856 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14857 int Offset = ShuffleMask & 0xF;
14858 unsigned SrcIdx = (ShuffleMask >> 4) & 0x1;
14859 return std::pair<unsigned, int>{SrcIdx, Offset};
14864 case X86::BI__builtin_ia32_vpermi2varqi256:
14865 case X86::BI__builtin_ia32_vpermi2varhi512: {
14868 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14869 int Offset = ShuffleMask & 0x1F;
14870 unsigned SrcIdx = (ShuffleMask >> 5) & 0x1;
14871 return std::pair<unsigned, int>{SrcIdx, Offset};
14876 case X86::BI__builtin_ia32_vpermi2varqi512: {
14879 [](
unsigned DstIdx,
unsigned ShuffleMask) {
14880 int Offset = ShuffleMask & 0x3F;
14881 unsigned SrcIdx = (ShuffleMask >> 6) & 0x1;
14882 return std::pair<unsigned, int>{SrcIdx, Offset};
14888 case clang::X86::BI__builtin_ia32_minps:
14889 case clang::X86::BI__builtin_ia32_minpd:
14890 case clang::X86::BI__builtin_ia32_minps256:
14891 case clang::X86::BI__builtin_ia32_minpd256:
14892 case clang::X86::BI__builtin_ia32_minps512:
14893 case clang::X86::BI__builtin_ia32_minpd512:
14894 case clang::X86::BI__builtin_ia32_minph128:
14895 case clang::X86::BI__builtin_ia32_minph256:
14896 case clang::X86::BI__builtin_ia32_minph512:
14897 return EvaluateFpBinOpExpr(
14898 [](
const APFloat &A,
const APFloat &B,
14899 std::optional<APSInt>) -> std::optional<APFloat> {
14900 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14901 B.isInfinity() || B.isDenormal())
14902 return std::nullopt;
14903 if (A.isZero() && B.isZero())
14905 return llvm::minimum(A, B);
14908 case clang::X86::BI__builtin_ia32_minss:
14909 case clang::X86::BI__builtin_ia32_minsd:
14910 return EvaluateFpBinOpExpr(
14911 [](
const APFloat &A,
const APFloat &B,
14912 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14917 case clang::X86::BI__builtin_ia32_minsd_round_mask:
14918 case clang::X86::BI__builtin_ia32_minss_round_mask:
14919 case clang::X86::BI__builtin_ia32_minsh_round_mask:
14920 case clang::X86::BI__builtin_ia32_maxsd_round_mask:
14921 case clang::X86::BI__builtin_ia32_maxss_round_mask:
14922 case clang::X86::BI__builtin_ia32_maxsh_round_mask: {
14923 bool IsMin = BuiltinOp == clang::X86::BI__builtin_ia32_minsd_round_mask ||
14924 BuiltinOp == clang::X86::BI__builtin_ia32_minss_round_mask ||
14925 BuiltinOp == clang::X86::BI__builtin_ia32_minsh_round_mask;
14926 return EvaluateScalarFpRoundMaskBinOp(
14927 [IsMin](
const APFloat &A,
const APFloat &B,
14928 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14933 case clang::X86::BI__builtin_ia32_maxps:
14934 case clang::X86::BI__builtin_ia32_maxpd:
14935 case clang::X86::BI__builtin_ia32_maxps256:
14936 case clang::X86::BI__builtin_ia32_maxpd256:
14937 case clang::X86::BI__builtin_ia32_maxps512:
14938 case clang::X86::BI__builtin_ia32_maxpd512:
14939 case clang::X86::BI__builtin_ia32_maxph128:
14940 case clang::X86::BI__builtin_ia32_maxph256:
14941 case clang::X86::BI__builtin_ia32_maxph512:
14942 return EvaluateFpBinOpExpr(
14943 [](
const APFloat &A,
const APFloat &B,
14944 std::optional<APSInt>) -> std::optional<APFloat> {
14945 if (A.isNaN() || A.isInfinity() || A.isDenormal() || B.isNaN() ||
14946 B.isInfinity() || B.isDenormal())
14947 return std::nullopt;
14948 if (A.isZero() && B.isZero())
14950 return llvm::maximum(A, B);
14953 case clang::X86::BI__builtin_ia32_maxss:
14954 case clang::X86::BI__builtin_ia32_maxsd:
14955 return EvaluateFpBinOpExpr(
14956 [](
const APFloat &A,
const APFloat &B,
14957 std::optional<APSInt> RoundingMode) -> std::optional<APFloat> {
14962 case clang::X86::BI__builtin_ia32_vcvtps2ph:
14963 case clang::X86::BI__builtin_ia32_vcvtps2ph256: {
14973 unsigned SrcNumElems = SrcVTy->getNumElements();
14975 unsigned DstNumElems = DstVTy->getNumElements();
14976 QualType DstElemTy = DstVTy->getElementType();
14978 const llvm::fltSemantics &HalfSem =
14979 Info.Ctx.getFloatTypeSemantics(Info.Ctx.HalfTy);
14981 int ImmVal = Imm.getZExtValue();
14982 bool UseMXCSR = (ImmVal & 4) != 0;
14983 bool IsFPConstrained =
14986 llvm::RoundingMode RM;
14988 switch (ImmVal & 3) {
14990 RM = llvm::RoundingMode::NearestTiesToEven;
14993 RM = llvm::RoundingMode::TowardNegative;
14996 RM = llvm::RoundingMode::TowardPositive;
14999 RM = llvm::RoundingMode::TowardZero;
15002 llvm_unreachable(
"Invalid immediate rounding mode");
15005 RM = llvm::RoundingMode::NearestTiesToEven;
15009 ResultElements.reserve(DstNumElems);
15011 for (
unsigned I = 0; I < SrcNumElems; ++I) {
15015 APFloat::opStatus St = SrcVal.convert(HalfSem, RM, &LostInfo);
15017 if (UseMXCSR && IsFPConstrained && St != APFloat::opOK) {
15018 Info.FFDiag(E, diag::note_constexpr_dynamic_rounding);
15022 APSInt DstInt(SrcVal.bitcastToAPInt(),
15024 ResultElements.push_back(
APValue(DstInt));
15027 if (DstNumElems > SrcNumElems) {
15028 APSInt Zero = Info.Ctx.MakeIntValue(0, DstElemTy);
15029 for (
unsigned I = SrcNumElems; I < DstNumElems; ++I) {
15034 return Success(ResultElements, E);
15036 case X86::BI__builtin_ia32_vperm2f128_pd256:
15037 case X86::BI__builtin_ia32_vperm2f128_ps256:
15038 case X86::BI__builtin_ia32_vperm2f128_si256:
15039 case X86::BI__builtin_ia32_permti256: {
15040 unsigned NumElements =
15042 unsigned PreservedBitsCnt = NumElements >> 2;
15046 [PreservedBitsCnt](
unsigned DstIdx,
unsigned ShuffleMask) {
15047 unsigned ControlBitsCnt = DstIdx >> PreservedBitsCnt << 2;
15048 unsigned ControlBits = ShuffleMask >> ControlBitsCnt;
15050 if (ControlBits & 0b1000)
15051 return std::make_pair(0u, -1);
15053 unsigned SrcVecIdx = (ControlBits & 0b10) >> 1;
15054 unsigned PreservedBitsMask = (1 << PreservedBitsCnt) - 1;
15055 int SrcIdx = ((ControlBits & 0b1) << PreservedBitsCnt) |
15056 (DstIdx & PreservedBitsMask);
15057 return std::make_pair(SrcVecIdx, SrcIdx);
15062 case X86::BI__builtin_ia32_vpdpwssd128:
15063 case X86::BI__builtin_ia32_vpdpwssd256:
15064 case X86::BI__builtin_ia32_vpdpwssd512:
15065 case X86::BI__builtin_ia32_vpdpbusd128:
15066 case X86::BI__builtin_ia32_vpdpbusd256:
15067 case X86::BI__builtin_ia32_vpdpbusd512:
15068 return EvalVectorDotProduct(
false);
15069 case X86::BI__builtin_ia32_vpdpwssds128:
15070 case X86::BI__builtin_ia32_vpdpwssds256:
15071 case X86::BI__builtin_ia32_vpdpwssds512:
15072 case X86::BI__builtin_ia32_vpdpbusds128:
15073 case X86::BI__builtin_ia32_vpdpbusds256:
15074 case X86::BI__builtin_ia32_vpdpbusds512:
15075 return EvalVectorDotProduct(
true);
15079bool VectorExprEvaluator::VisitConvertVectorExpr(
const ConvertVectorExpr *E) {
15085 QualType DestTy = E->
getType()->
castAs<VectorType>()->getElementType();
15086 QualType SourceTy = SourceVecType->
castAs<VectorType>()->getElementType();
15092 ResultElements.reserve(SourceLen);
15093 for (
unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
15098 ResultElements.push_back(std::move(Elt));
15101 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15106 APValue const &VecVal2,
unsigned EltNum,
15108 unsigned const TotalElementsInInputVector1 = VecVal1.
getVectorLength();
15109 unsigned const TotalElementsInInputVector2 = VecVal2.
getVectorLength();
15112 int64_t
index = IndexVal.getExtValue();
15119 E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr)
15125 index >= TotalElementsInInputVector1 + TotalElementsInInputVector2)
15126 llvm_unreachable(
"Out of bounds shuffle index");
15128 if (
index >= TotalElementsInInputVector1)
15135bool VectorExprEvaluator::VisitShuffleVectorExpr(
const ShuffleVectorExpr *E) {
15140 const Expr *Vec1 = E->
getExpr(0);
15144 const Expr *Vec2 = E->
getExpr(1);
15148 VectorType
const *DestVecTy = E->
getType()->
castAs<VectorType>();
15154 ResultElements.reserve(TotalElementsInOutputVector);
15155 for (
unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) {
15159 ResultElements.push_back(std::move(Elt));
15162 return Success(
APValue(ResultElements.data(), ResultElements.size()), E);
15170class MatrixExprEvaluator :
public ExprEvaluatorBase<MatrixExprEvaluator> {
15177 bool Success(ArrayRef<APValue> M,
const Expr *E) {
15179 assert(M.size() == CMTy->getNumElementsFlattened());
15181 Result =
APValue(M.data(), CMTy->getNumRows(), CMTy->getNumColumns());
15185 assert(M.
isMatrix() &&
"expected matrix");
15190 bool VisitCastExpr(
const CastExpr *E);
15191 bool VisitInitListExpr(
const InitListExpr *E);
15197 "not a matrix prvalue");
15198 return MatrixExprEvaluator(Info,
Result).Visit(E);
15201bool MatrixExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15202 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15203 unsigned NumRows = MT->getNumRows();
15204 unsigned NumCols = MT->getNumColumns();
15205 unsigned NElts = NumRows * NumCols;
15206 QualType EltTy = MT->getElementType();
15210 case CK_HLSLAggregateSplatCast: {
15225 case CK_HLSLElementwiseCast: {
15238 return Success(ResultEls, E);
15241 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15245bool MatrixExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
15246 const auto *MT = E->
getType()->
castAs<ConstantMatrixType>();
15247 QualType EltTy = MT->getElementType();
15249 assert(E->
getNumInits() == MT->getNumElementsFlattened() &&
15250 "Expected number of elements in initializer list to match the number "
15251 "of matrix elements");
15254 Elements.reserve(MT->getNumElementsFlattened());
15259 for (
unsigned I = 0, N = MT->getNumElementsFlattened(); I < N; ++I) {
15260 if (EltTy->isIntegerType()) {
15261 llvm::APSInt IntVal;
15264 Elements.push_back(
APValue(IntVal));
15266 llvm::APFloat FloatVal(0.0);
15269 Elements.push_back(
APValue(FloatVal));
15281 class ArrayExprEvaluator
15282 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
15283 const LValue &
This;
15287 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &
Result)
15291 assert(
V.isArray() &&
"expected array");
15296 bool ZeroInitialization(
const Expr *E) {
15297 const ConstantArrayType *CAT =
15298 Info.Ctx.getAsConstantArrayType(E->
getType());
15312 if (!
Result.hasArrayFiller())
15316 LValue Subobject =
This;
15317 Subobject.addArray(Info, E, CAT);
15322 bool VisitCallExpr(
const CallExpr *E) {
15323 return handleCallExpr(E,
Result, &This);
15325 bool VisitCastExpr(
const CastExpr *E);
15326 bool VisitInitListExpr(
const InitListExpr *E,
15327 QualType AllocType = QualType());
15328 bool VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E);
15329 bool VisitCXXConstructExpr(
const CXXConstructExpr *E);
15330 bool VisitCXXConstructExpr(
const CXXConstructExpr *E,
15331 const LValue &Subobject,
15333 bool VisitStringLiteral(
const StringLiteral *E,
15334 QualType AllocType = QualType()) {
15338 bool VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E);
15339 bool VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit,
15340 ArrayRef<Expr *> Args,
15341 const Expr *ArrayFiller,
15342 QualType AllocType = QualType());
15343 bool VisitDesignatedInitUpdateExpr(
const DesignatedInitUpdateExpr *E);
15351 "not an array prvalue");
15352 return ArrayExprEvaluator(Info,
This,
Result).Visit(E);
15360 "not an array prvalue");
15361 return ArrayExprEvaluator(Info,
This,
Result)
15362 .VisitInitListExpr(ILE, AllocType);
15371 "not an array prvalue");
15372 return ArrayExprEvaluator(Info,
This,
Result)
15373 .VisitCXXConstructExpr(CCE,
This, &
Result, AllocType);
15382 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(FillerExpr)) {
15383 for (
unsigned I = 0, E = ILE->
getNumInits(); I != E; ++I) {
15388 if (ILE->hasArrayFiller() &&
15397bool ArrayExprEvaluator::VisitCastExpr(
const CastExpr *E) {
15402 return ExprEvaluatorBaseTy::VisitCastExpr(E);
15403 case CK_HLSLAggregateSplatCast: {
15423 case CK_HLSLElementwiseCast: {
15440bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E,
15441 QualType AllocType) {
15442 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15455 return VisitStringLiteral(SL, AllocType);
15460 "transparent array list initialization is not string literal init?");
15466bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
15468 QualType AllocType) {
15469 const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
15474 unsigned NumEltsToInit = Args.size();
15479 if (NumEltsToInit != NumElts &&
15481 NumEltsToInit = NumElts;
15484 for (
auto *
Init : Args) {
15485 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts()))
15486 NumEltsToInit += EmbedS->getDataElementCount() - 1;
15489 if (NumEltsToInit > NumElts)
15490 NumEltsToInit = NumElts;
15494 if (
Result.hasValue() && NumEltsToInit <
Result.getArrayInitializedElts())
15495 NumEltsToInit =
Result.getArrayInitializedElts();
15498 LLVM_DEBUG(llvm::dbgs() <<
"The number of elements to initialize: "
15499 << NumEltsToInit <<
".\n");
15501 if (!
Result.hasValue()) {
15502 Result =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15503 }
else if (
Result.getArrayInitializedElts() != NumEltsToInit) {
15514 APValue NewResult =
APValue(APValue::UninitArray(), NumEltsToInit, NumElts);
15516 unsigned NumOldElts =
Result.getArrayInitializedElts();
15517 for (
unsigned I = 0; I < NumOldElts; ++I) {
15519 std::move(
Result.getArrayInitializedElt(I));
15522 for (
unsigned I =
Result.getArrayInitializedElts(); I < NumEltsToInit; ++I)
15526 Result = std::move(NewResult);
15529 LValue Subobject =
This;
15530 Subobject.addArray(Info, ExprToVisit, CAT);
15531 auto Eval = [&](
const Expr *
Init,
unsigned ArrayIndex) {
15532 if (
Init->isValueDependent())
15541 Subobject,
Init) ||
15544 if (!Info.noteFailure())
15550 unsigned ArrayIndex = 0;
15553 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
15554 const Expr *
Init = Index < Args.size() ? Args[Index] : ArrayFiller;
15555 if (ArrayIndex >= NumEltsToInit)
15557 if (
auto *EmbedS = dyn_cast<EmbedExpr>(
Init->IgnoreParenImpCasts())) {
15558 StringLiteral *SL = EmbedS->getDataStringLiteral();
15559 for (
unsigned I = EmbedS->getStartingElementPos(),
15560 N = EmbedS->getDataElementCount();
15561 I != EmbedS->getStartingElementPos() + N; ++I) {
15567 const FPOptions FPO =
15568 Init->getFPFeaturesInEffect(Info.Ctx.getLangOpts());
15573 Result.getArrayInitializedElt(ArrayIndex) =
APValue(FValue);
15578 if (!Eval(
Init, ArrayIndex))
15584 if (!
Result.hasArrayFiller())
15589 assert(ArrayFiller &&
"no array filler for incomplete init list");
15595bool ArrayExprEvaluator::VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *E) {
15598 !
Evaluate(Info.CurrentCall->createTemporary(
15601 ScopeKind::FullExpression, CommonLV),
15608 Result =
APValue(APValue::UninitArray(), Elements, Elements);
15610 LValue Subobject =
This;
15611 Subobject.addArray(Info, E, CAT);
15614 for (EvalInfo::ArrayInitLoopIndex Index(Info); Index != Elements; ++Index) {
15623 FullExpressionRAII Scope(Info);
15629 if (!Info.noteFailure())
15641bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
15642 return VisitCXXConstructExpr(E, This, &
Result, E->
getType());
15645bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E,
15646 const LValue &Subobject,
15649 bool HadZeroInit =
Value->hasValue();
15651 if (
const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(
Type)) {
15656 HadZeroInit &&
Value->hasArrayFiller() ?
Value->getArrayFiller()
15659 *
Value =
APValue(APValue::UninitArray(), 0, FinalSize);
15660 if (FinalSize == 0)
15666 LValue ArrayElt = Subobject;
15667 ArrayElt.addArray(Info, E, CAT);
15673 for (
const unsigned N : {1u, FinalSize}) {
15674 unsigned OldElts =
Value->getArrayInitializedElts();
15679 APValue NewValue(APValue::UninitArray(), N, FinalSize);
15680 for (
unsigned I = 0; I < OldElts; ++I)
15681 NewValue.getArrayInitializedElt(I).swap(
15682 Value->getArrayInitializedElt(I));
15683 Value->swap(NewValue);
15686 for (
unsigned I = OldElts; I < N; ++I)
15687 Value->getArrayInitializedElt(I) = Filler;
15689 if (HasTrivialConstructor && N == FinalSize && FinalSize != 1) {
15692 APValue &FirstResult =
Value->getArrayInitializedElt(0);
15693 for (
unsigned I = OldElts; I < FinalSize; ++I)
15694 Value->getArrayInitializedElt(I) = FirstResult;
15696 for (
unsigned I = OldElts; I < N; ++I) {
15697 if (!VisitCXXConstructExpr(E, ArrayElt,
15698 &
Value->getArrayInitializedElt(I),
15705 if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
15706 !Info.keepEvaluatingAfterFailure())
15715 if (!
Type->isRecordType())
15718 return RecordExprEvaluator(Info, Subobject, *
Value)
15719 .VisitCXXConstructExpr(E,
Type);
15722bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
15723 const CXXParenListInitExpr *E) {
15725 "Expression result is not a constant array type");
15727 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs(),
15731bool ArrayExprEvaluator::VisitDesignatedInitUpdateExpr(
15732 const DesignatedInitUpdateExpr *E) {
15747class IntExprEvaluator
15748 :
public ExprEvaluatorBase<IntExprEvaluator> {
15751 IntExprEvaluator(EvalInfo &info,
APValue &result)
15752 : ExprEvaluatorBaseTy(info),
Result(result) {}
15756 "Invalid evaluation result.");
15758 "Invalid evaluation result.");
15759 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15760 "Invalid evaluation result.");
15764 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
15770 "Invalid evaluation result.");
15771 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15772 "Invalid evaluation result.");
15774 Result.getInt().setIsUnsigned(
15778 bool Success(
const llvm::APInt &I,
const Expr *E) {
15784 "Invalid evaluation result.");
15792 bool Success(CharUnits Size,
const Expr *E) {
15799 if (
V.isLValue() ||
V.isAddrLabelDiff() ||
V.isIndeterminate() ||
15800 V.allowConstexprUnknown()) {
15807 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
15809 friend std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &,
15816 bool VisitIntegerLiteral(
const IntegerLiteral *E) {
15819 bool VisitCharacterLiteral(
const CharacterLiteral *E) {
15823 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
15824 bool VisitDeclRefExpr(
const DeclRefExpr *E) {
15825 if (CheckReferencedDecl(E, E->
getDecl()))
15828 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
15830 bool VisitMemberExpr(
const MemberExpr *E) {
15832 VisitIgnoredBaseExpression(E->
getBase());
15836 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
15839 bool VisitCallExpr(
const CallExpr *E);
15840 bool VisitBuiltinCallExpr(
const CallExpr *E,
unsigned BuiltinOp);
15841 bool VisitBinaryOperator(
const BinaryOperator *E);
15842 bool VisitOffsetOfExpr(
const OffsetOfExpr *E);
15843 bool VisitUnaryOperator(
const UnaryOperator *E);
15845 bool VisitCastExpr(
const CastExpr* E);
15846 bool VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
15848 bool VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
15852 bool VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
15856 bool VisitArrayInitIndexExpr(
const ArrayInitIndexExpr *E) {
15857 if (Info.ArrayInitIndex ==
uint64_t(-1)) {
15863 return Success(Info.ArrayInitIndex, E);
15867 bool VisitGNUNullExpr(
const GNUNullExpr *E) {
15868 return ZeroInitialization(E);
15871 bool VisitTypeTraitExpr(
const TypeTraitExpr *E) {
15880 bool VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
15884 bool VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
15888 bool VisitOpenACCAsteriskSizeExpr(
const OpenACCAsteriskSizeExpr *E) {
15895 bool VisitUnaryReal(
const UnaryOperator *E);
15896 bool VisitUnaryImag(
const UnaryOperator *E);
15898 bool VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E);
15899 bool VisitSizeOfPackExpr(
const SizeOfPackExpr *E);
15900 bool VisitSourceLocExpr(
const SourceLocExpr *E);
15901 bool VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E);
15906class FixedPointExprEvaluator
15907 :
public ExprEvaluatorBase<FixedPointExprEvaluator> {
15911 FixedPointExprEvaluator(EvalInfo &info,
APValue &result)
15912 : ExprEvaluatorBaseTy(info),
Result(result) {}
15914 bool Success(
const llvm::APInt &I,
const Expr *E) {
15916 APFixedPoint(I, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15921 APFixedPoint(
Value, Info.Ctx.getFixedPointSemantics(E->
getType())), E);
15925 return Success(
V.getFixedPoint(), E);
15928 bool Success(
const APFixedPoint &
V,
const Expr *E) {
15930 assert(
V.getWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
15931 "Invalid evaluation result.");
15936 bool ZeroInitialization(
const Expr *E) {
15944 bool VisitFixedPointLiteral(
const FixedPointLiteral *E) {
15948 bool VisitCastExpr(
const CastExpr *E);
15949 bool VisitUnaryOperator(
const UnaryOperator *E);
15950 bool VisitBinaryOperator(
const BinaryOperator *E);
15966 return IntExprEvaluator(Info,
Result).Visit(E);
15974 if (!Val.
isInt()) {
15977 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
15984bool IntExprEvaluator::VisitSourceLocExpr(
const SourceLocExpr *E) {
15986 Info.Ctx, Info.CurrentCall->CurSourceLocExprScope.
getDefaultExpr());
15995 if (!FixedPointExprEvaluator(Info, Val).Visit(E))
16010 auto FXSema = Info.Ctx.getFixedPointSemantics(E->
getType());
16014 Result = APFixedPoint(Val, FXSema);
16025bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
16027 if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
16029 bool SameSign = (ECD->getInitVal().isSigned()
16031 bool SameWidth = (ECD->getInitVal().
getBitWidth()
16032 == Info.Ctx.getIntWidth(E->
getType()));
16033 if (SameSign && SameWidth)
16034 return Success(ECD->getInitVal(), E);
16038 llvm::APSInt Val = ECD->getInitVal();
16040 Val.setIsSigned(!ECD->getInitVal().isSigned());
16042 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
16053 assert(!T->isDependentType() &&
"unexpected dependent type");
16058#define TYPE(ID, BASE)
16059#define DEPENDENT_TYPE(ID, BASE) case Type::ID:
16060#define NON_CANONICAL_TYPE(ID, BASE) case Type::ID:
16061#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(ID, BASE) case Type::ID:
16062#include "clang/AST/TypeNodes.inc"
16064 case Type::DeducedTemplateSpecialization:
16065 llvm_unreachable(
"unexpected non-canonical or dependent type");
16067 case Type::Builtin:
16069#define BUILTIN_TYPE(ID, SINGLETON_ID)
16070#define SIGNED_TYPE(ID, SINGLETON_ID) \
16071 case BuiltinType::ID: return GCCTypeClass::Integer;
16072#define FLOATING_TYPE(ID, SINGLETON_ID) \
16073 case BuiltinType::ID: return GCCTypeClass::RealFloat;
16074#define PLACEHOLDER_TYPE(ID, SINGLETON_ID) \
16075 case BuiltinType::ID: break;
16076#include "clang/AST/BuiltinTypes.def"
16077 case BuiltinType::Void:
16080 case BuiltinType::Bool:
16083 case BuiltinType::Char_U:
16084 case BuiltinType::UChar:
16085 case BuiltinType::WChar_U:
16086 case BuiltinType::Char8:
16087 case BuiltinType::Char16:
16088 case BuiltinType::Char32:
16089 case BuiltinType::UShort:
16090 case BuiltinType::UInt:
16091 case BuiltinType::ULong:
16092 case BuiltinType::ULongLong:
16093 case BuiltinType::UInt128:
16096 case BuiltinType::UShortAccum:
16097 case BuiltinType::UAccum:
16098 case BuiltinType::ULongAccum:
16099 case BuiltinType::UShortFract:
16100 case BuiltinType::UFract:
16101 case BuiltinType::ULongFract:
16102 case BuiltinType::SatUShortAccum:
16103 case BuiltinType::SatUAccum:
16104 case BuiltinType::SatULongAccum:
16105 case BuiltinType::SatUShortFract:
16106 case BuiltinType::SatUFract:
16107 case BuiltinType::SatULongFract:
16110 case BuiltinType::NullPtr:
16112 case BuiltinType::ObjCId:
16113 case BuiltinType::ObjCClass:
16114 case BuiltinType::ObjCSel:
16115#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
16116 case BuiltinType::Id:
16117#include "clang/Basic/OpenCLImageTypes.def"
16118#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
16119 case BuiltinType::Id:
16120#include "clang/Basic/OpenCLExtensionTypes.def"
16121 case BuiltinType::OCLSampler:
16122 case BuiltinType::OCLEvent:
16123 case BuiltinType::OCLClkEvent:
16124 case BuiltinType::OCLQueue:
16125 case BuiltinType::OCLReserveID:
16126#define SVE_TYPE(Name, Id, SingletonId) \
16127 case BuiltinType::Id:
16128#include "clang/Basic/AArch64ACLETypes.def"
16129#define PPC_VECTOR_TYPE(Name, Id, Size) \
16130 case BuiltinType::Id:
16131#include "clang/Basic/PPCTypes.def"
16132#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16133#include "clang/Basic/RISCVVTypes.def"
16134#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16135#include "clang/Basic/WebAssemblyReferenceTypes.def"
16136#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
16137#include "clang/Basic/AMDGPUTypes.def"
16138#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
16139#include "clang/Basic/HLSLIntangibleTypes.def"
16142 case BuiltinType::Dependent:
16143 llvm_unreachable(
"unexpected dependent type");
16145 llvm_unreachable(
"unexpected placeholder type");
16150 case Type::Pointer:
16151 case Type::ConstantArray:
16152 case Type::VariableArray:
16153 case Type::IncompleteArray:
16154 case Type::FunctionNoProto:
16155 case Type::FunctionProto:
16156 case Type::ArrayParameter:
16159 case Type::MemberPointer:
16164 case Type::Complex:
16177 case Type::ExtVector:
16180 case Type::BlockPointer:
16181 case Type::ConstantMatrix:
16182 case Type::ObjCObject:
16183 case Type::ObjCInterface:
16184 case Type::ObjCObjectPointer:
16186 case Type::HLSLAttributedResource:
16187 case Type::HLSLInlineSpirv:
16188 case Type::OverflowBehavior:
16196 case Type::LValueReference:
16197 case Type::RValueReference:
16198 llvm_unreachable(
"invalid type for expression");
16201 llvm_unreachable(
"unexpected type class");
16226 if (
Base.isNull()) {
16229 }
else if (
const Expr *E =
Base.dyn_cast<
const Expr *>()) {
16248 SpeculativeEvaluationRAII SpeculativeEval(Info);
16253 FoldConstant Fold(Info,
true);
16271 if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
16272 ArgType->isAnyComplexType() || ArgType->isPointerType() ||
16273 ArgType->isNullPtrType()) {
16276 Fold.keepDiagnostics();
16285 return V.hasValue();
16296 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
16320 const auto *Cast = dyn_cast<CastExpr>(NoParens);
16321 if (Cast ==
nullptr)
16326 auto CastKind = Cast->getCastKind();
16328 CastKind != CK_AddressSpaceConversion)
16331 const auto *SubExpr = Cast->getSubExpr();
16353 assert(!LVal.Designator.Invalid);
16355 auto IsLastOrInvalidFieldDecl = [&Ctx](
const FieldDecl *FD) {
16363 auto &
Base = LVal.getLValueBase();
16364 if (
auto *ME = dyn_cast_or_null<MemberExpr>(
Base.dyn_cast<
const Expr *>())) {
16365 if (
auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
16366 if (!IsLastOrInvalidFieldDecl(FD))
16368 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(ME->getMemberDecl())) {
16369 for (
auto *FD : IFD->chain()) {
16378 if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
16382 if (BaseType->isIncompleteArrayType())
16388 for (
unsigned E = LVal.Designator.Entries.size(); I != E; ++I) {
16389 const auto &Entry = LVal.Designator.Entries[I];
16390 if (BaseType->isArrayType()) {
16396 uint64_t Index = Entry.getAsArrayIndex();
16400 }
else if (BaseType->isAnyComplexType()) {
16401 const auto *CT = BaseType->castAs<
ComplexType>();
16402 uint64_t Index = Entry.getAsArrayIndex();
16405 BaseType = CT->getElementType();
16406 }
else if (
auto *FD = getAsField(Entry)) {
16407 if (!IsLastOrInvalidFieldDecl(FD))
16411 assert(getAsBaseClass(Entry) &&
"Expecting cast to a base class");
16423 if (LVal.Designator.Invalid)
16426 if (!LVal.Designator.Entries.empty())
16427 return LVal.Designator.isMostDerivedAnUnsizedArray();
16429 if (!LVal.InvalidBase)
16441 const SubobjectDesignator &
Designator = LVal.Designator;
16453 auto isFlexibleArrayMember = [&] {
16455 FAMKind StrictFlexArraysLevel =
16458 if (
Designator.isMostDerivedAnUnsizedArray())
16461 if (StrictFlexArraysLevel == FAMKind::Default)
16464 if (
Designator.getMostDerivedArraySize() == 0 &&
16465 StrictFlexArraysLevel != FAMKind::IncompleteOnly)
16468 if (
Designator.getMostDerivedArraySize() == 1 &&
16469 StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
16475 return LVal.InvalidBase &&
16477 Designator.MostDerivedIsArrayElement && isFlexibleArrayMember() &&
16485 auto CharUnitsMax = std::numeric_limits<CharUnits::QuantityType>::max();
16486 if (Int.ugt(CharUnitsMax))
16496 if (!T.isNull() && T->isStructureType() &&
16497 T->castAsRecordDecl()->hasFlexibleArrayMember())
16498 if (
const auto *
V = LV.getLValueBase().dyn_cast<
const ValueDecl *>())
16499 if (
const auto *VD = dyn_cast<VarDecl>(
V))
16511 unsigned Type,
const LValue &LVal,
16530 if (!(
Type & 1) || LVal.Designator.Invalid || DetermineForCompleteObject) {
16532 if (
Type == 3 && !DetermineForCompleteObject)
16535 llvm::APInt APEndOffset;
16536 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16540 if (LVal.InvalidBase)
16544 const bool Ret = CheckedHandleSizeof(BaseTy, EndOffset);
16550 const SubobjectDesignator &
Designator = LVal.Designator;
16562 llvm::APInt APEndOffset;
16563 if (isBaseAnAllocSizeCall(LVal.getLValueBase()) &&
16575 if (!CheckedHandleSizeof(
Designator.MostDerivedType, BytesPerElem))
16581 int64_t ElemsRemaining;
16584 uint64_t ArraySize =
Designator.getMostDerivedArraySize();
16585 uint64_t ArrayIndex =
Designator.Entries.back().getAsArrayIndex();
16586 ElemsRemaining = ArraySize <= ArrayIndex ? 0 : ArraySize - ArrayIndex;
16588 ElemsRemaining =
Designator.isOnePastTheEnd() ? 0 : 1;
16591 EndOffset = LVal.getLValueOffset() + BytesPerElem * ElemsRemaining;
16605static std::optional<uint64_t>
16607 bool IsDynamic =
false) {
16615 SpeculativeEvaluationRAII SpeculativeEval(Info);
16616 IgnoreSideEffectsRAII Fold(Info);
16623 return std::nullopt;
16624 LVal.setFrom(Info.Ctx, RVal);
16627 return std::nullopt;
16632 if (LVal.getLValueOffset().isNegative())
16647 const auto *FD = ME ? dyn_cast<FieldDecl>(ME->getMemberDecl()) :
nullptr;
16649 return std::nullopt;
16654 return std::nullopt;
16658 if (EndOffset <= LVal.getLValueOffset())
16660 return (EndOffset - LVal.getLValueOffset()).
getQuantity();
16663bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
16664 if (!IsConstantEvaluatedBuiltinCall(E))
16665 return ExprEvaluatorBaseTy::VisitCallExpr(E);
16682 Info.FFDiag(E->
getArg(0));
16688 assert(SrcInt.getBitWidth() >= Alignment.getBitWidth() &&
16689 "Bit widths must be the same");
16696bool IntExprEvaluator::VisitBuiltinCallExpr(
const CallExpr *E,
16697 unsigned BuiltinOp) {
16698 auto EvalTestOp = [&](llvm::function_ref<
bool(
const APInt &,
const APInt &)>
16700 APValue SourceLHS, SourceRHS;
16708 unsigned LaneWidth = Info.Ctx.getTypeSize(ElemQT);
16710 APInt AWide(LaneWidth * SourceLen, 0);
16711 APInt BWide(LaneWidth * SourceLen, 0);
16713 for (
unsigned I = 0; I != SourceLen; ++I) {
16716 if (ElemQT->isIntegerType()) {
16719 }
else if (ElemQT->isFloatingType()) {
16727 AWide.insertBits(ALane, I * LaneWidth);
16728 BWide.insertBits(BLane, I * LaneWidth);
16733 auto HandleMaskBinOp =
16746 auto HandleCRC32 = [&](
unsigned DataBytes) ->
bool {
16752 uint64_t CRCVal = CRC.getZExtValue();
16756 static const uint32_t CRC32C_POLY = 0x82F63B78;
16760 for (
unsigned I = 0; I != DataBytes; ++I) {
16761 uint8_t Byte =
static_cast<uint8_t>((DataVal >> (I * 8)) & 0xFF);
16763 for (
int J = 0; J != 8; ++J) {
16771 switch (BuiltinOp) {
16775 case X86::BI__builtin_ia32_crc32qi:
16776 return HandleCRC32(1);
16777 case X86::BI__builtin_ia32_crc32hi:
16778 return HandleCRC32(2);
16779 case X86::BI__builtin_ia32_crc32si:
16780 return HandleCRC32(4);
16781 case X86::BI__builtin_ia32_crc32di:
16782 return HandleCRC32(8);
16784 case Builtin::BI__builtin_dynamic_object_size:
16785 case Builtin::BI__builtin_object_size: {
16789 assert(
Type <= 3 &&
"unexpected type");
16791 bool IsDynamic = BuiltinOp == Builtin::BI__builtin_dynamic_object_size;
16792 if (std::optional<uint64_t> Size =
16801 switch (Info.EvalMode) {
16802 case EvaluationMode::ConstantExpression:
16803 case EvaluationMode::ConstantFold:
16804 case EvaluationMode::IgnoreSideEffects:
16807 case EvaluationMode::ConstantExpressionUnevaluated:
16812 llvm_unreachable(
"unexpected EvalMode");
16815 case Builtin::BI__builtin_os_log_format_buffer_size: {
16816 analyze_os_log::OSLogBufferLayout Layout;
16821 case Builtin::BI__builtin_is_aligned: {
16829 Ptr.setFrom(Info.Ctx, Src);
16835 assert(Alignment.isPowerOf2());
16848 Info.FFDiag(E->
getArg(0), diag::note_constexpr_alignment_compute)
16852 assert(Src.
isInt());
16853 return Success((Src.
getInt() & (Alignment - 1)) == 0 ? 1 : 0, E);
16855 case Builtin::BI__builtin_align_up: {
16863 APSInt((Src.
getInt() + (Alignment - 1)) & ~(Alignment - 1),
16864 Src.
getInt().isUnsigned());
16865 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16866 return Success(AlignedVal, E);
16868 case Builtin::BI__builtin_align_down: {
16877 assert(AlignedVal.getBitWidth() == Src.
getInt().getBitWidth());
16878 return Success(AlignedVal, E);
16881 case Builtin::BI__builtin_bitreverseg:
16882 case Builtin::BI__builtin_bitreverse8:
16883 case Builtin::BI__builtin_bitreverse16:
16884 case Builtin::BI__builtin_bitreverse32:
16885 case Builtin::BI__builtin_bitreverse64:
16886 case Builtin::BI__builtin_elementwise_bitreverse: {
16891 return Success(Val.reverseBits(), E);
16893 case Builtin::BI__builtin_bswapg:
16894 case Builtin::BI__builtin_bswap16:
16895 case Builtin::BI__builtin_bswap32:
16896 case Builtin::BI__builtin_bswap64:
16897 case Builtin::BIstdc_memreverse8u8:
16898 case Builtin::BIstdc_memreverse8u16:
16899 case Builtin::BIstdc_memreverse8u32:
16900 case Builtin::BIstdc_memreverse8u64: {
16904 if (Val.getBitWidth() == 8 || Val.getBitWidth() == 1)
16907 return Success(Val.byteSwap(), E);
16910 case Builtin::BI__builtin_classify_type:
16913 case Builtin::BI__builtin_clrsb:
16914 case Builtin::BI__builtin_clrsbl:
16915 case Builtin::BI__builtin_clrsbll: {
16920 return Success(Val.getBitWidth() - Val.getSignificantBits(), E);
16923 case Builtin::BI__builtin_clz:
16924 case Builtin::BI__builtin_clzl:
16925 case Builtin::BI__builtin_clzll:
16926 case Builtin::BI__builtin_clzs:
16927 case Builtin::BI__builtin_clzg:
16928 case Builtin::BI__builtin_elementwise_clzg:
16929 case Builtin::BI__lzcnt16:
16930 case Builtin::BI__lzcnt:
16931 case Builtin::BI__lzcnt64: {
16942 std::optional<APSInt> Fallback;
16943 if ((BuiltinOp == Builtin::BI__builtin_clzg ||
16944 BuiltinOp == Builtin::BI__builtin_elementwise_clzg) &&
16949 Fallback = FallbackTemp;
16954 return Success(*Fallback, E);
16959 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
16960 BuiltinOp != Builtin::BI__lzcnt &&
16961 BuiltinOp != Builtin::BI__lzcnt64;
16963 if (BuiltinOp == Builtin::BI__builtin_elementwise_clzg) {
16964 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
16968 if (ZeroIsUndefined)
16972 return Success(Val.countl_zero(), E);
16975 case Builtin::BI__builtin_constant_p: {
16976 const Expr *Arg = E->
getArg(0);
16985 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
16989 case Builtin::BI__noop:
16993 case Builtin::BI__builtin_is_constant_evaluated: {
16994 const auto *
Callee = Info.CurrentCall->getCallee();
16995 if (Info.InConstantContext && !Info.CheckingPotentialConstantExpression &&
16996 (Info.CallStackDepth == 1 ||
16997 (Info.CallStackDepth == 2 &&
Callee->isInStdNamespace() &&
16998 Callee->getIdentifier() &&
16999 Callee->getIdentifier()->isStr(
"is_constant_evaluated")))) {
17001 if (Info.EvalStatus.Diag)
17002 Info.report((Info.CallStackDepth == 1)
17004 : Info.CurrentCall->getCallRange().getBegin(),
17005 diag::warn_is_constant_evaluated_always_true_constexpr)
17006 << (Info.CallStackDepth == 1 ?
"__builtin_is_constant_evaluated"
17007 :
"std::is_constant_evaluated");
17010 return Success(Info.InConstantContext, E);
17013 case Builtin::BI__builtin_is_within_lifetime:
17014 if (
auto result = EvaluateBuiltinIsWithinLifetime(*
this, E))
17018 case Builtin::BI__builtin_ctz:
17019 case Builtin::BI__builtin_ctzl:
17020 case Builtin::BI__builtin_ctzll:
17021 case Builtin::BI__builtin_ctzs:
17022 case Builtin::BI__builtin_ctzg:
17023 case Builtin::BI__builtin_elementwise_ctzg: {
17034 std::optional<APSInt> Fallback;
17035 if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
17036 BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) &&
17041 Fallback = FallbackTemp;
17046 return Success(*Fallback, E);
17048 if (BuiltinOp == Builtin::BI__builtin_elementwise_ctzg) {
17049 Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
17055 return Success(Val.countr_zero(), E);
17058 case Builtin::BI__builtin_eh_return_data_regno: {
17060 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
17064 case Builtin::BI__builtin_elementwise_abs: {
17069 return Success(Val.abs(), E);
17072 case Builtin::BI__builtin_expect:
17073 case Builtin::BI__builtin_expect_with_probability:
17074 return Visit(E->
getArg(0));
17076 case Builtin::BI__builtin_ptrauth_string_discriminator: {
17083 case Builtin::BI__builtin_infer_alloc_token: {
17089 E, diag::note_constexpr_infer_alloc_token_type_inference_failed);
17092 return Error(E, diag::note_constexpr_infer_alloc_token_no_metadata);
17094 Info.getLangOpts().AllocTokenMode.value_or(llvm::DefaultAllocTokenMode);
17095 uint64_t BitWidth = Info.Ctx.getTypeSize(Info.Ctx.getSizeType());
17096 auto MaxTokensOpt = Info.getLangOpts().AllocTokenMax;
17098 MaxTokensOpt.value_or(0) ? *MaxTokensOpt : (~0ULL >> (64 - BitWidth));
17099 auto MaybeToken = llvm::getAllocToken(Mode, *ATMD, MaxTokens);
17101 return Error(E, diag::note_constexpr_infer_alloc_token_stateful_mode);
17102 return Success(llvm::APInt(BitWidth, *MaybeToken), E);
17105 case Builtin::BI__builtin_ffs:
17106 case Builtin::BI__builtin_ffsl:
17107 case Builtin::BI__builtin_ffsll: {
17112 unsigned N = Val.countr_zero();
17113 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
17116 case Builtin::BI__builtin_fpclassify: {
17121 switch (Val.getCategory()) {
17122 case APFloat::fcNaN: Arg = 0;
break;
17123 case APFloat::fcInfinity: Arg = 1;
break;
17124 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
17125 case APFloat::fcZero: Arg = 4;
break;
17127 return Visit(E->
getArg(Arg));
17130 case Builtin::BI__builtin_isinf_sign: {
17133 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
17136 case Builtin::BI__builtin_isinf: {
17139 Success(Val.isInfinity() ? 1 : 0, E);
17142 case Builtin::BI__builtin_isfinite: {
17145 Success(Val.isFinite() ? 1 : 0, E);
17148 case Builtin::BI__builtin_isnan: {
17151 Success(Val.isNaN() ? 1 : 0, E);
17154 case Builtin::BI__builtin_isnormal: {
17157 Success(Val.isNormal() ? 1 : 0, E);
17160 case Builtin::BI__builtin_issubnormal: {
17163 Success(Val.isDenormal() ? 1 : 0, E);
17166 case Builtin::BI__builtin_iszero: {
17169 Success(Val.isZero() ? 1 : 0, E);
17172 case Builtin::BI__builtin_signbit:
17173 case Builtin::BI__builtin_signbitf:
17174 case Builtin::BI__builtin_signbitl: {
17177 Success(Val.isNegative() ? 1 : 0, E);
17180 case Builtin::BI__builtin_isgreater:
17181 case Builtin::BI__builtin_isgreaterequal:
17182 case Builtin::BI__builtin_isless:
17183 case Builtin::BI__builtin_islessequal:
17184 case Builtin::BI__builtin_islessgreater:
17185 case Builtin::BI__builtin_isunordered: {
17194 switch (BuiltinOp) {
17195 case Builtin::BI__builtin_isgreater:
17197 case Builtin::BI__builtin_isgreaterequal:
17199 case Builtin::BI__builtin_isless:
17201 case Builtin::BI__builtin_islessequal:
17203 case Builtin::BI__builtin_islessgreater: {
17204 APFloat::cmpResult cmp = LHS.compare(RHS);
17205 return cmp == APFloat::cmpResult::cmpLessThan ||
17206 cmp == APFloat::cmpResult::cmpGreaterThan;
17208 case Builtin::BI__builtin_isunordered:
17209 return LHS.compare(RHS) == APFloat::cmpResult::cmpUnordered;
17211 llvm_unreachable(
"Unexpected builtin ID: Should be a floating "
17212 "point comparison function");
17220 case Builtin::BI__builtin_issignaling: {
17223 Success(Val.isSignaling() ? 1 : 0, E);
17226 case Builtin::BI__builtin_isfpclass: {
17230 unsigned Test =
static_cast<llvm::FPClassTest
>(MaskVal.getZExtValue());
17233 Success((Val.classify() & Test) ? 1 : 0, E);
17236 case Builtin::BI__builtin_parity:
17237 case Builtin::BI__builtin_parityl:
17238 case Builtin::BI__builtin_parityll: {
17243 return Success(Val.popcount() % 2, E);
17246 case Builtin::BI__builtin_abs:
17247 case Builtin::BI__builtin_labs:
17248 case Builtin::BI__builtin_llabs: {
17252 if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
17255 if (Val.isNegative())
17260 case Builtin::BI__builtin_popcount:
17261 case Builtin::BI__builtin_popcountl:
17262 case Builtin::BI__builtin_popcountll:
17263 case Builtin::BI__builtin_popcountg:
17264 case Builtin::BI__builtin_elementwise_popcount:
17265 case Builtin::BI__popcnt16:
17266 case Builtin::BI__popcnt:
17267 case Builtin::BI__popcnt64: {
17278 return Success(Val.popcount(), E);
17281 case Builtin::BI__builtin_rotateleft8:
17282 case Builtin::BI__builtin_rotateleft16:
17283 case Builtin::BI__builtin_rotateleft32:
17284 case Builtin::BI__builtin_rotateleft64:
17285 case Builtin::BI__builtin_rotateright8:
17286 case Builtin::BI__builtin_rotateright16:
17287 case Builtin::BI__builtin_rotateright32:
17288 case Builtin::BI__builtin_rotateright64:
17289 case Builtin::BI__builtin_stdc_rotate_left:
17290 case Builtin::BI__builtin_stdc_rotate_right:
17291 case Builtin::BIstdc_rotate_left_uc:
17292 case Builtin::BIstdc_rotate_left_us:
17293 case Builtin::BIstdc_rotate_left_ui:
17294 case Builtin::BIstdc_rotate_left_ul:
17295 case Builtin::BIstdc_rotate_left_ull:
17296 case Builtin::BIstdc_rotate_right_uc:
17297 case Builtin::BIstdc_rotate_right_us:
17298 case Builtin::BIstdc_rotate_right_ui:
17299 case Builtin::BIstdc_rotate_right_ul:
17300 case Builtin::BIstdc_rotate_right_ull:
17301 case Builtin::BI_rotl8:
17302 case Builtin::BI_rotl16:
17303 case Builtin::BI_rotl:
17304 case Builtin::BI_lrotl:
17305 case Builtin::BI_rotl64:
17306 case Builtin::BI_rotr8:
17307 case Builtin::BI_rotr16:
17308 case Builtin::BI_rotr:
17309 case Builtin::BI_lrotr:
17310 case Builtin::BI_rotr64: {
17318 switch (BuiltinOp) {
17319 case Builtin::BI__builtin_rotateright8:
17320 case Builtin::BI__builtin_rotateright16:
17321 case Builtin::BI__builtin_rotateright32:
17322 case Builtin::BI__builtin_rotateright64:
17323 case Builtin::BI__builtin_stdc_rotate_right:
17324 case Builtin::BIstdc_rotate_right_uc:
17325 case Builtin::BIstdc_rotate_right_us:
17326 case Builtin::BIstdc_rotate_right_ui:
17327 case Builtin::BIstdc_rotate_right_ul:
17328 case Builtin::BIstdc_rotate_right_ull:
17329 case Builtin::BI_rotr8:
17330 case Builtin::BI_rotr16:
17331 case Builtin::BI_rotr:
17332 case Builtin::BI_lrotr:
17333 case Builtin::BI_rotr64:
17342 case Builtin::BIstdc_leading_zeros_uc:
17343 case Builtin::BIstdc_leading_zeros_us:
17344 case Builtin::BIstdc_leading_zeros_ui:
17345 case Builtin::BIstdc_leading_zeros_ul:
17346 case Builtin::BIstdc_leading_zeros_ull:
17347 case Builtin::BIstdc_leading_ones_uc:
17348 case Builtin::BIstdc_leading_ones_us:
17349 case Builtin::BIstdc_leading_ones_ui:
17350 case Builtin::BIstdc_leading_ones_ul:
17351 case Builtin::BIstdc_leading_ones_ull:
17352 case Builtin::BIstdc_trailing_zeros_uc:
17353 case Builtin::BIstdc_trailing_zeros_us:
17354 case Builtin::BIstdc_trailing_zeros_ui:
17355 case Builtin::BIstdc_trailing_zeros_ul:
17356 case Builtin::BIstdc_trailing_zeros_ull:
17357 case Builtin::BIstdc_trailing_ones_uc:
17358 case Builtin::BIstdc_trailing_ones_us:
17359 case Builtin::BIstdc_trailing_ones_ui:
17360 case Builtin::BIstdc_trailing_ones_ul:
17361 case Builtin::BIstdc_trailing_ones_ull:
17362 case Builtin::BIstdc_first_leading_zero_uc:
17363 case Builtin::BIstdc_first_leading_zero_us:
17364 case Builtin::BIstdc_first_leading_zero_ui:
17365 case Builtin::BIstdc_first_leading_zero_ul:
17366 case Builtin::BIstdc_first_leading_zero_ull:
17367 case Builtin::BIstdc_first_leading_one_uc:
17368 case Builtin::BIstdc_first_leading_one_us:
17369 case Builtin::BIstdc_first_leading_one_ui:
17370 case Builtin::BIstdc_first_leading_one_ul:
17371 case Builtin::BIstdc_first_leading_one_ull:
17372 case Builtin::BIstdc_first_trailing_zero_uc:
17373 case Builtin::BIstdc_first_trailing_zero_us:
17374 case Builtin::BIstdc_first_trailing_zero_ui:
17375 case Builtin::BIstdc_first_trailing_zero_ul:
17376 case Builtin::BIstdc_first_trailing_zero_ull:
17377 case Builtin::BIstdc_first_trailing_one_uc:
17378 case Builtin::BIstdc_first_trailing_one_us:
17379 case Builtin::BIstdc_first_trailing_one_ui:
17380 case Builtin::BIstdc_first_trailing_one_ul:
17381 case Builtin::BIstdc_first_trailing_one_ull:
17382 case Builtin::BIstdc_count_zeros_uc:
17383 case Builtin::BIstdc_count_zeros_us:
17384 case Builtin::BIstdc_count_zeros_ui:
17385 case Builtin::BIstdc_count_zeros_ul:
17386 case Builtin::BIstdc_count_zeros_ull:
17387 case Builtin::BIstdc_count_ones_uc:
17388 case Builtin::BIstdc_count_ones_us:
17389 case Builtin::BIstdc_count_ones_ui:
17390 case Builtin::BIstdc_count_ones_ul:
17391 case Builtin::BIstdc_count_ones_ull:
17392 case Builtin::BIstdc_has_single_bit_uc:
17393 case Builtin::BIstdc_has_single_bit_us:
17394 case Builtin::BIstdc_has_single_bit_ui:
17395 case Builtin::BIstdc_has_single_bit_ul:
17396 case Builtin::BIstdc_has_single_bit_ull:
17397 case Builtin::BIstdc_bit_width_uc:
17398 case Builtin::BIstdc_bit_width_us:
17399 case Builtin::BIstdc_bit_width_ui:
17400 case Builtin::BIstdc_bit_width_ul:
17401 case Builtin::BIstdc_bit_width_ull:
17402 case Builtin::BIstdc_bit_floor_uc:
17403 case Builtin::BIstdc_bit_floor_us:
17404 case Builtin::BIstdc_bit_floor_ui:
17405 case Builtin::BIstdc_bit_floor_ul:
17406 case Builtin::BIstdc_bit_floor_ull:
17407 case Builtin::BIstdc_bit_ceil_uc:
17408 case Builtin::BIstdc_bit_ceil_us:
17409 case Builtin::BIstdc_bit_ceil_ui:
17410 case Builtin::BIstdc_bit_ceil_ul:
17411 case Builtin::BIstdc_bit_ceil_ull:
17412 case Builtin::BI__builtin_stdc_leading_zeros:
17413 case Builtin::BI__builtin_stdc_leading_ones:
17414 case Builtin::BI__builtin_stdc_trailing_zeros:
17415 case Builtin::BI__builtin_stdc_trailing_ones:
17416 case Builtin::BI__builtin_stdc_first_leading_zero:
17417 case Builtin::BI__builtin_stdc_first_leading_one:
17418 case Builtin::BI__builtin_stdc_first_trailing_zero:
17419 case Builtin::BI__builtin_stdc_first_trailing_one:
17420 case Builtin::BI__builtin_stdc_count_zeros:
17421 case Builtin::BI__builtin_stdc_count_ones:
17422 case Builtin::BI__builtin_stdc_has_single_bit:
17423 case Builtin::BI__builtin_stdc_bit_width:
17424 case Builtin::BI__builtin_stdc_bit_floor:
17425 case Builtin::BI__builtin_stdc_bit_ceil: {
17430 unsigned BitWidth = Val.getBitWidth();
17431 const unsigned ResBitWidth = Info.Ctx.getIntWidth(E->
getType());
17433 switch (BuiltinOp) {
17434 case Builtin::BIstdc_leading_zeros_uc:
17435 case Builtin::BIstdc_leading_zeros_us:
17436 case Builtin::BIstdc_leading_zeros_ui:
17437 case Builtin::BIstdc_leading_zeros_ul:
17438 case Builtin::BIstdc_leading_zeros_ull:
17439 case Builtin::BI__builtin_stdc_leading_zeros:
17440 return Success(
APInt(ResBitWidth, Val.countl_zero()), E);
17441 case Builtin::BIstdc_leading_ones_uc:
17442 case Builtin::BIstdc_leading_ones_us:
17443 case Builtin::BIstdc_leading_ones_ui:
17444 case Builtin::BIstdc_leading_ones_ul:
17445 case Builtin::BIstdc_leading_ones_ull:
17446 case Builtin::BI__builtin_stdc_leading_ones:
17447 return Success(
APInt(ResBitWidth, Val.countl_one()), E);
17448 case Builtin::BIstdc_trailing_zeros_uc:
17449 case Builtin::BIstdc_trailing_zeros_us:
17450 case Builtin::BIstdc_trailing_zeros_ui:
17451 case Builtin::BIstdc_trailing_zeros_ul:
17452 case Builtin::BIstdc_trailing_zeros_ull:
17453 case Builtin::BI__builtin_stdc_trailing_zeros:
17454 return Success(
APInt(ResBitWidth, Val.countr_zero()), E);
17455 case Builtin::BIstdc_trailing_ones_uc:
17456 case Builtin::BIstdc_trailing_ones_us:
17457 case Builtin::BIstdc_trailing_ones_ui:
17458 case Builtin::BIstdc_trailing_ones_ul:
17459 case Builtin::BIstdc_trailing_ones_ull:
17460 case Builtin::BI__builtin_stdc_trailing_ones:
17461 return Success(
APInt(ResBitWidth, Val.countr_one()), E);
17462 case Builtin::BIstdc_first_leading_zero_uc:
17463 case Builtin::BIstdc_first_leading_zero_us:
17464 case Builtin::BIstdc_first_leading_zero_ui:
17465 case Builtin::BIstdc_first_leading_zero_ul:
17466 case Builtin::BIstdc_first_leading_zero_ull:
17467 case Builtin::BI__builtin_stdc_first_leading_zero:
17469 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countl_one() + 1), E);
17470 case Builtin::BIstdc_first_leading_one_uc:
17471 case Builtin::BIstdc_first_leading_one_us:
17472 case Builtin::BIstdc_first_leading_one_ui:
17473 case Builtin::BIstdc_first_leading_one_ul:
17474 case Builtin::BIstdc_first_leading_one_ull:
17475 case Builtin::BI__builtin_stdc_first_leading_one:
17477 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countl_zero() + 1), E);
17478 case Builtin::BIstdc_first_trailing_zero_uc:
17479 case Builtin::BIstdc_first_trailing_zero_us:
17480 case Builtin::BIstdc_first_trailing_zero_ui:
17481 case Builtin::BIstdc_first_trailing_zero_ul:
17482 case Builtin::BIstdc_first_trailing_zero_ull:
17483 case Builtin::BI__builtin_stdc_first_trailing_zero:
17485 APInt(ResBitWidth, Val.isAllOnes() ? 0 : Val.countr_one() + 1), E);
17486 case Builtin::BIstdc_first_trailing_one_uc:
17487 case Builtin::BIstdc_first_trailing_one_us:
17488 case Builtin::BIstdc_first_trailing_one_ui:
17489 case Builtin::BIstdc_first_trailing_one_ul:
17490 case Builtin::BIstdc_first_trailing_one_ull:
17491 case Builtin::BI__builtin_stdc_first_trailing_one:
17493 APInt(ResBitWidth, Val.isZero() ? 0 : Val.countr_zero() + 1), E);
17494 case Builtin::BIstdc_count_zeros_uc:
17495 case Builtin::BIstdc_count_zeros_us:
17496 case Builtin::BIstdc_count_zeros_ui:
17497 case Builtin::BIstdc_count_zeros_ul:
17498 case Builtin::BIstdc_count_zeros_ull:
17499 case Builtin::BI__builtin_stdc_count_zeros: {
17500 APInt Cnt(ResBitWidth, BitWidth - Val.popcount());
17503 case Builtin::BIstdc_count_ones_uc:
17504 case Builtin::BIstdc_count_ones_us:
17505 case Builtin::BIstdc_count_ones_ui:
17506 case Builtin::BIstdc_count_ones_ul:
17507 case Builtin::BIstdc_count_ones_ull:
17508 case Builtin::BI__builtin_stdc_count_ones: {
17509 APInt Cnt(ResBitWidth, Val.popcount());
17512 case Builtin::BIstdc_has_single_bit_uc:
17513 case Builtin::BIstdc_has_single_bit_us:
17514 case Builtin::BIstdc_has_single_bit_ui:
17515 case Builtin::BIstdc_has_single_bit_ul:
17516 case Builtin::BIstdc_has_single_bit_ull:
17517 case Builtin::BI__builtin_stdc_has_single_bit: {
17518 APInt Res(ResBitWidth, Val.popcount() == 1 ? 1 : 0);
17521 case Builtin::BIstdc_bit_width_uc:
17522 case Builtin::BIstdc_bit_width_us:
17523 case Builtin::BIstdc_bit_width_ui:
17524 case Builtin::BIstdc_bit_width_ul:
17525 case Builtin::BIstdc_bit_width_ull:
17526 case Builtin::BI__builtin_stdc_bit_width:
17527 return Success(
APInt(ResBitWidth, BitWidth - Val.countl_zero()), E);
17528 case Builtin::BIstdc_bit_floor_uc:
17529 case Builtin::BIstdc_bit_floor_us:
17530 case Builtin::BIstdc_bit_floor_ui:
17531 case Builtin::BIstdc_bit_floor_ul:
17532 case Builtin::BIstdc_bit_floor_ull:
17533 case Builtin::BI__builtin_stdc_bit_floor: {
17536 unsigned Exp = BitWidth - Val.countl_zero() - 1;
17538 APSInt(APInt::getOneBitSet(BitWidth, Exp),
true), E);
17540 case Builtin::BIstdc_bit_ceil_uc:
17541 case Builtin::BIstdc_bit_ceil_us:
17542 case Builtin::BIstdc_bit_ceil_ui:
17543 case Builtin::BIstdc_bit_ceil_ul:
17544 case Builtin::BIstdc_bit_ceil_ull:
17545 case Builtin::BI__builtin_stdc_bit_ceil: {
17548 APInt ValMinusOne = Val - 1;
17549 unsigned LZ = ValMinusOne.countl_zero();
17553 APInt Result = APInt::getOneBitSet(BitWidth, BitWidth - LZ);
17557 llvm_unreachable(
"Unknown stdc builtin");
17561 case Builtin::BI__builtin_elementwise_add_sat: {
17567 APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
17570 case Builtin::BI__builtin_elementwise_sub_sat: {
17576 APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
17579 case Builtin::BI__builtin_elementwise_max: {
17588 case Builtin::BI__builtin_elementwise_min: {
17597 case Builtin::BI__builtin_elementwise_clmul: {
17606 case Builtin::BI__builtin_elementwise_fshl:
17607 case Builtin::BI__builtin_elementwise_fshr: {
17614 switch (BuiltinOp) {
17615 case Builtin::BI__builtin_elementwise_fshl: {
17616 APSInt Result(llvm::APIntOps::fshl(Hi, Lo, Shift), Hi.isUnsigned());
17619 case Builtin::BI__builtin_elementwise_fshr: {
17620 APSInt Result(llvm::APIntOps::fshr(Hi, Lo, Shift), Hi.isUnsigned());
17624 llvm_unreachable(
"Fully covered switch above");
17626 case Builtin::BIstrlen:
17627 case Builtin::BIwcslen:
17629 if (Info.getLangOpts().CPlusPlus11)
17630 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17632 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17634 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17636 case Builtin::BI__builtin_strlen:
17637 case Builtin::BI__builtin_wcslen: {
17640 if (std::optional<uint64_t> StrLen =
17646 case Builtin::BIstrcmp:
17647 case Builtin::BIwcscmp:
17648 case Builtin::BIstrncmp:
17649 case Builtin::BIwcsncmp:
17650 case Builtin::BImemcmp:
17651 case Builtin::BIbcmp:
17652 case Builtin::BIwmemcmp:
17654 if (Info.getLangOpts().CPlusPlus11)
17655 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
17657 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp);
17659 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
17661 case Builtin::BI__builtin_strcmp:
17662 case Builtin::BI__builtin_wcscmp:
17663 case Builtin::BI__builtin_strncmp:
17664 case Builtin::BI__builtin_wcsncmp:
17665 case Builtin::BI__builtin_memcmp:
17666 case Builtin::BI__builtin_bcmp:
17667 case Builtin::BI__builtin_wmemcmp: {
17668 LValue String1, String2;
17674 if (BuiltinOp != Builtin::BIstrcmp &&
17675 BuiltinOp != Builtin::BIwcscmp &&
17676 BuiltinOp != Builtin::BI__builtin_strcmp &&
17677 BuiltinOp != Builtin::BI__builtin_wcscmp) {
17681 MaxLength = N.getZExtValue();
17685 if (MaxLength == 0u)
17688 if (!String1.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17689 !String2.checkNullPointerForFoldAccess(Info, E,
AK_Read) ||
17690 String1.Designator.Invalid || String2.Designator.Invalid)
17693 QualType CharTy1 = String1.Designator.getType(Info.Ctx);
17694 QualType CharTy2 = String2.Designator.getType(Info.Ctx);
17696 bool IsRawByte = BuiltinOp == Builtin::BImemcmp ||
17697 BuiltinOp == Builtin::BIbcmp ||
17698 BuiltinOp == Builtin::BI__builtin_memcmp ||
17699 BuiltinOp == Builtin::BI__builtin_bcmp;
17701 assert(IsRawByte ||
17702 (Info.Ctx.hasSameUnqualifiedType(
17704 Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2)));
17711 Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
17712 << Info.Ctx.BuiltinInfo.getQuotedName(BuiltinOp) << CharTy1
17717 const auto &ReadCurElems = [&](
APValue &Char1,
APValue &Char2) {
17720 Char1.
isInt() && Char2.isInt();
17722 const auto &AdvanceElems = [&] {
17728 (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp &&
17729 BuiltinOp != Builtin::BIwmemcmp &&
17730 BuiltinOp != Builtin::BI__builtin_memcmp &&
17731 BuiltinOp != Builtin::BI__builtin_bcmp &&
17732 BuiltinOp != Builtin::BI__builtin_wmemcmp);
17733 bool IsWide = BuiltinOp == Builtin::BIwcscmp ||
17734 BuiltinOp == Builtin::BIwcsncmp ||
17735 BuiltinOp == Builtin::BIwmemcmp ||
17736 BuiltinOp == Builtin::BI__builtin_wcscmp ||
17737 BuiltinOp == Builtin::BI__builtin_wcsncmp ||
17738 BuiltinOp == Builtin::BI__builtin_wmemcmp;
17740 for (; MaxLength; --MaxLength) {
17742 if (!ReadCurElems(Char1, Char2))
17750 if (StopAtNull && !Char1.
getInt())
17752 assert(!(StopAtNull && !Char2.
getInt()));
17753 if (!AdvanceElems())
17760 case Builtin::BI__atomic_always_lock_free:
17761 case Builtin::BI__atomic_is_lock_free:
17762 case Builtin::BI__c11_atomic_is_lock_free: {
17778 if (
Size.isPowerOfTwo()) {
17780 unsigned InlineWidthBits =
17781 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
17782 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
17783 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
17789 const Expr *PtrArg = E->
getArg(1);
17795 IntResult.isAligned(
Size.getAsAlign()))
17799 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
17802 if (ICE->getCastKind() == CK_BitCast)
17803 PtrArg = ICE->getSubExpr();
17806 if (
auto PtrTy = PtrArg->
getType()->
getAs<PointerType>()) {
17809 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
17817 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
17820 case Builtin::BI__builtin_addcb:
17821 case Builtin::BI__builtin_addcs:
17822 case Builtin::BI__builtin_addc:
17823 case Builtin::BI__builtin_addcl:
17824 case Builtin::BI__builtin_addcll:
17825 case Builtin::BI__builtin_subcb:
17826 case Builtin::BI__builtin_subcs:
17827 case Builtin::BI__builtin_subc:
17828 case Builtin::BI__builtin_subcl:
17829 case Builtin::BI__builtin_subcll: {
17830 LValue CarryOutLValue;
17842 bool FirstOverflowed =
false;
17843 bool SecondOverflowed =
false;
17844 switch (BuiltinOp) {
17846 llvm_unreachable(
"Invalid value for BuiltinOp");
17847 case Builtin::BI__builtin_addcb:
17848 case Builtin::BI__builtin_addcs:
17849 case Builtin::BI__builtin_addc:
17850 case Builtin::BI__builtin_addcl:
17851 case Builtin::BI__builtin_addcll:
17853 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
17855 case Builtin::BI__builtin_subcb:
17856 case Builtin::BI__builtin_subcs:
17857 case Builtin::BI__builtin_subc:
17858 case Builtin::BI__builtin_subcl:
17859 case Builtin::BI__builtin_subcll:
17861 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
17867 CarryOut = (
uint64_t)(FirstOverflowed | SecondOverflowed);
17873 case Builtin::BI__builtin_add_overflow:
17874 case Builtin::BI__builtin_sub_overflow:
17875 case Builtin::BI__builtin_mul_overflow:
17876 case Builtin::BI__builtin_sadd_overflow:
17877 case Builtin::BI__builtin_uadd_overflow:
17878 case Builtin::BI__builtin_uaddl_overflow:
17879 case Builtin::BI__builtin_uaddll_overflow:
17880 case Builtin::BI__builtin_usub_overflow:
17881 case Builtin::BI__builtin_usubl_overflow:
17882 case Builtin::BI__builtin_usubll_overflow:
17883 case Builtin::BI__builtin_umul_overflow:
17884 case Builtin::BI__builtin_umull_overflow:
17885 case Builtin::BI__builtin_umulll_overflow:
17886 case Builtin::BI__builtin_saddl_overflow:
17887 case Builtin::BI__builtin_saddll_overflow:
17888 case Builtin::BI__builtin_ssub_overflow:
17889 case Builtin::BI__builtin_ssubl_overflow:
17890 case Builtin::BI__builtin_ssubll_overflow:
17891 case Builtin::BI__builtin_smul_overflow:
17892 case Builtin::BI__builtin_smull_overflow:
17893 case Builtin::BI__builtin_smulll_overflow: {
17894 LValue ResultLValue;
17904 bool DidOverflow =
false;
17907 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17908 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17909 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17910 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
17912 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
17914 uint64_t LHSSize = LHS.getBitWidth();
17915 uint64_t RHSSize = RHS.getBitWidth();
17916 uint64_t ResultSize = Info.Ctx.getIntWidth(ResultType);
17917 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
17923 if (IsSigned && !AllSigned)
17926 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
17927 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
17932 switch (BuiltinOp) {
17934 llvm_unreachable(
"Invalid value for BuiltinOp");
17935 case Builtin::BI__builtin_add_overflow:
17936 case Builtin::BI__builtin_sadd_overflow:
17937 case Builtin::BI__builtin_saddl_overflow:
17938 case Builtin::BI__builtin_saddll_overflow:
17939 case Builtin::BI__builtin_uadd_overflow:
17940 case Builtin::BI__builtin_uaddl_overflow:
17941 case Builtin::BI__builtin_uaddll_overflow:
17942 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, DidOverflow)
17943 : LHS.uadd_ov(RHS, DidOverflow);
17945 case Builtin::BI__builtin_sub_overflow:
17946 case Builtin::BI__builtin_ssub_overflow:
17947 case Builtin::BI__builtin_ssubl_overflow:
17948 case Builtin::BI__builtin_ssubll_overflow:
17949 case Builtin::BI__builtin_usub_overflow:
17950 case Builtin::BI__builtin_usubl_overflow:
17951 case Builtin::BI__builtin_usubll_overflow:
17952 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, DidOverflow)
17953 : LHS.usub_ov(RHS, DidOverflow);
17955 case Builtin::BI__builtin_mul_overflow:
17956 case Builtin::BI__builtin_smul_overflow:
17957 case Builtin::BI__builtin_smull_overflow:
17958 case Builtin::BI__builtin_smulll_overflow:
17959 case Builtin::BI__builtin_umul_overflow:
17960 case Builtin::BI__builtin_umull_overflow:
17961 case Builtin::BI__builtin_umulll_overflow:
17962 Result = LHS.isSigned() ? LHS.smul_ov(RHS, DidOverflow)
17963 : LHS.umul_ov(RHS, DidOverflow);
17972 APSInt Temp =
Result.extOrTrunc(Info.Ctx.getIntWidth(ResultType));
17977 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
17978 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
17979 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
17980 if (!APSInt::isSameValue(Temp,
Result))
17981 DidOverflow =
true;
17988 return Success(DidOverflow, E);
17991 case Builtin::BI__builtin_reduce_add:
17992 case Builtin::BI__builtin_reduce_mul:
17993 case Builtin::BI__builtin_reduce_and:
17994 case Builtin::BI__builtin_reduce_or:
17995 case Builtin::BI__builtin_reduce_xor:
17996 case Builtin::BI__builtin_reduce_min:
17997 case Builtin::BI__builtin_reduce_max: {
18004 for (
unsigned EltNum = 1; EltNum < SourceLen; ++EltNum) {
18005 switch (BuiltinOp) {
18008 case Builtin::BI__builtin_reduce_add: {
18011 Reduced.getBitWidth() + 1, std::plus<APSInt>(), Reduced))
18015 case Builtin::BI__builtin_reduce_mul: {
18018 Reduced.getBitWidth() * 2, std::multiplies<APSInt>(), Reduced))
18022 case Builtin::BI__builtin_reduce_and: {
18026 case Builtin::BI__builtin_reduce_or: {
18030 case Builtin::BI__builtin_reduce_xor: {
18034 case Builtin::BI__builtin_reduce_min: {
18038 case Builtin::BI__builtin_reduce_max: {
18048 case clang::X86::BI__builtin_ia32_addcarryx_u32:
18049 case clang::X86::BI__builtin_ia32_addcarryx_u64:
18050 case clang::X86::BI__builtin_ia32_subborrow_u32:
18051 case clang::X86::BI__builtin_ia32_subborrow_u64: {
18052 LValue ResultLValue;
18053 APSInt CarryIn, LHS, RHS;
18061 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
18062 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
18064 unsigned BitWidth = LHS.getBitWidth();
18065 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
18068 ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
18069 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
18071 APInt Result = ExResult.extractBits(BitWidth, 0);
18072 uint64_t CarryOut = ExResult.extractBitsAsZExtValue(1, BitWidth);
18080 case clang::X86::BI__builtin_ia32_movmskps:
18081 case clang::X86::BI__builtin_ia32_movmskpd:
18082 case clang::X86::BI__builtin_ia32_pmovmskb128:
18083 case clang::X86::BI__builtin_ia32_pmovmskb256:
18084 case clang::X86::BI__builtin_ia32_movmskps256:
18085 case clang::X86::BI__builtin_ia32_movmskpd256: {
18092 unsigned ResultLen = Info.Ctx.getTypeSize(
18096 for (
unsigned I = 0; I != SourceLen; ++I) {
18098 if (ElemQT->isIntegerType()) {
18100 }
else if (ElemQT->isRealFloatingType()) {
18105 Result.setBitVal(I, Elem.isNegative());
18110 case clang::X86::BI__builtin_ia32_bextr_u32:
18111 case clang::X86::BI__builtin_ia32_bextr_u64:
18112 case clang::X86::BI__builtin_ia32_bextri_u32:
18113 case clang::X86::BI__builtin_ia32_bextri_u64: {
18119 unsigned BitWidth = Val.getBitWidth();
18121 uint64_t Length = Idx.extractBitsAsZExtValue(8, 8);
18122 Length = Length > BitWidth ? BitWidth : Length;
18125 if (Length == 0 || Shift >= BitWidth)
18129 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
18133 case clang::X86::BI__builtin_ia32_bzhi_si:
18134 case clang::X86::BI__builtin_ia32_bzhi_di: {
18140 unsigned BitWidth = Val.getBitWidth();
18141 unsigned Index = Idx.extractBitsAsZExtValue(8, 0);
18142 if (Index < BitWidth)
18143 Val.clearHighBits(BitWidth - Index);
18147 case clang::X86::BI__builtin_ia32_ktestcqi:
18148 case clang::X86::BI__builtin_ia32_ktestchi:
18149 case clang::X86::BI__builtin_ia32_ktestcsi:
18150 case clang::X86::BI__builtin_ia32_ktestcdi: {
18156 return Success((~A & B) == 0, E);
18159 case clang::X86::BI__builtin_ia32_ktestzqi:
18160 case clang::X86::BI__builtin_ia32_ktestzhi:
18161 case clang::X86::BI__builtin_ia32_ktestzsi:
18162 case clang::X86::BI__builtin_ia32_ktestzdi: {
18168 return Success((A & B) == 0, E);
18171 case clang::X86::BI__builtin_ia32_kortestcqi:
18172 case clang::X86::BI__builtin_ia32_kortestchi:
18173 case clang::X86::BI__builtin_ia32_kortestcsi:
18174 case clang::X86::BI__builtin_ia32_kortestcdi: {
18180 return Success(~(A | B) == 0, E);
18183 case clang::X86::BI__builtin_ia32_kortestzqi:
18184 case clang::X86::BI__builtin_ia32_kortestzhi:
18185 case clang::X86::BI__builtin_ia32_kortestzsi:
18186 case clang::X86::BI__builtin_ia32_kortestzdi: {
18192 return Success((A | B) == 0, E);
18195 case clang::X86::BI__builtin_ia32_kunpckhi:
18196 case clang::X86::BI__builtin_ia32_kunpckdi:
18197 case clang::X86::BI__builtin_ia32_kunpcksi: {
18205 unsigned BW = A.getBitWidth();
18206 APSInt Result(A.trunc(BW / 2).concat(B.trunc(BW / 2)), A.isUnsigned());
18210 case clang::X86::BI__builtin_ia32_lzcnt_u16:
18211 case clang::X86::BI__builtin_ia32_lzcnt_u32:
18212 case clang::X86::BI__builtin_ia32_lzcnt_u64: {
18216 return Success(Val.countLeadingZeros(), E);
18219 case clang::X86::BI__builtin_ia32_tzcnt_u16:
18220 case clang::X86::BI__builtin_ia32_tzcnt_u32:
18221 case clang::X86::BI__builtin_ia32_tzcnt_u64: {
18225 return Success(Val.countTrailingZeros(), E);
18228 case clang::X86::BI__builtin_ia32_pdep_si:
18229 case clang::X86::BI__builtin_ia32_pdep_di:
18230 case Builtin::BI__builtin_elementwise_pdep: {
18235 return Success(llvm::APIntOps::pdep(Val, Msk), E);
18238 case clang::X86::BI__builtin_ia32_pext_si:
18239 case clang::X86::BI__builtin_ia32_pext_di:
18240 case Builtin::BI__builtin_elementwise_pext: {
18245 return Success(llvm::APIntOps::pext(Val, Msk), E);
18247 case X86::BI__builtin_ia32_ptestz128:
18248 case X86::BI__builtin_ia32_ptestz256:
18249 case X86::BI__builtin_ia32_vtestzps:
18250 case X86::BI__builtin_ia32_vtestzps256:
18251 case X86::BI__builtin_ia32_vtestzpd:
18252 case X86::BI__builtin_ia32_vtestzpd256: {
18254 [](
const APInt &A,
const APInt &B) {
return (A & B) == 0; });
18256 case X86::BI__builtin_ia32_ptestc128:
18257 case X86::BI__builtin_ia32_ptestc256:
18258 case X86::BI__builtin_ia32_vtestcps:
18259 case X86::BI__builtin_ia32_vtestcps256:
18260 case X86::BI__builtin_ia32_vtestcpd:
18261 case X86::BI__builtin_ia32_vtestcpd256: {
18263 [](
const APInt &A,
const APInt &B) {
return (~A & B) == 0; });
18265 case X86::BI__builtin_ia32_ptestnzc128:
18266 case X86::BI__builtin_ia32_ptestnzc256:
18267 case X86::BI__builtin_ia32_vtestnzcps:
18268 case X86::BI__builtin_ia32_vtestnzcps256:
18269 case X86::BI__builtin_ia32_vtestnzcpd:
18270 case X86::BI__builtin_ia32_vtestnzcpd256: {
18271 return EvalTestOp([](
const APInt &A,
const APInt &B) {
18272 return ((A & B) != 0) && ((~A & B) != 0);
18275 case X86::BI__builtin_ia32_kandqi:
18276 case X86::BI__builtin_ia32_kandhi:
18277 case X86::BI__builtin_ia32_kandsi:
18278 case X86::BI__builtin_ia32_kanddi: {
18279 return HandleMaskBinOp(
18280 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS & RHS; });
18283 case X86::BI__builtin_ia32_kandnqi:
18284 case X86::BI__builtin_ia32_kandnhi:
18285 case X86::BI__builtin_ia32_kandnsi:
18286 case X86::BI__builtin_ia32_kandndi: {
18287 return HandleMaskBinOp(
18288 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~LHS & RHS; });
18291 case X86::BI__builtin_ia32_korqi:
18292 case X86::BI__builtin_ia32_korhi:
18293 case X86::BI__builtin_ia32_korsi:
18294 case X86::BI__builtin_ia32_kordi: {
18295 return HandleMaskBinOp(
18296 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS | RHS; });
18299 case X86::BI__builtin_ia32_kxnorqi:
18300 case X86::BI__builtin_ia32_kxnorhi:
18301 case X86::BI__builtin_ia32_kxnorsi:
18302 case X86::BI__builtin_ia32_kxnordi: {
18303 return HandleMaskBinOp(
18304 [](
const APSInt &LHS,
const APSInt &RHS) {
return ~(LHS ^ RHS); });
18307 case X86::BI__builtin_ia32_kxorqi:
18308 case X86::BI__builtin_ia32_kxorhi:
18309 case X86::BI__builtin_ia32_kxorsi:
18310 case X86::BI__builtin_ia32_kxordi: {
18311 return HandleMaskBinOp(
18312 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS ^ RHS; });
18315 case X86::BI__builtin_ia32_knotqi:
18316 case X86::BI__builtin_ia32_knothi:
18317 case X86::BI__builtin_ia32_knotsi:
18318 case X86::BI__builtin_ia32_knotdi: {
18326 case X86::BI__builtin_ia32_kaddqi:
18327 case X86::BI__builtin_ia32_kaddhi:
18328 case X86::BI__builtin_ia32_kaddsi:
18329 case X86::BI__builtin_ia32_kadddi: {
18330 return HandleMaskBinOp(
18331 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS + RHS; });
18334 case X86::BI__builtin_ia32_kmovb:
18335 case X86::BI__builtin_ia32_kmovw:
18336 case X86::BI__builtin_ia32_kmovd:
18337 case X86::BI__builtin_ia32_kmovq: {
18344 case X86::BI__builtin_ia32_kshiftliqi:
18345 case X86::BI__builtin_ia32_kshiftlihi:
18346 case X86::BI__builtin_ia32_kshiftlisi:
18347 case X86::BI__builtin_ia32_kshiftlidi: {
18348 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18349 unsigned Amt = RHS.getZExtValue() & 0xFF;
18350 if (Amt >= LHS.getBitWidth())
18351 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18352 return APSInt(LHS.shl(Amt), LHS.isUnsigned());
18356 case X86::BI__builtin_ia32_kshiftriqi:
18357 case X86::BI__builtin_ia32_kshiftrihi:
18358 case X86::BI__builtin_ia32_kshiftrisi:
18359 case X86::BI__builtin_ia32_kshiftridi: {
18360 return HandleMaskBinOp([](
const APSInt &LHS,
const APSInt &RHS) {
18361 unsigned Amt = RHS.getZExtValue() & 0xFF;
18362 if (Amt >= LHS.getBitWidth())
18363 return APSInt(APInt::getZero(LHS.getBitWidth()), LHS.isUnsigned());
18364 return APSInt(LHS.lshr(Amt), LHS.isUnsigned());
18368 case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
18369 case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
18370 case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
18371 case clang::X86::BI__builtin_ia32_vec_ext_v4si:
18372 case clang::X86::BI__builtin_ia32_vec_ext_v2di:
18373 case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
18374 case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
18375 case clang::X86::BI__builtin_ia32_vec_ext_v8si:
18376 case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
18383 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
18387 case clang::X86::BI__builtin_ia32_cvtb2mask128:
18388 case clang::X86::BI__builtin_ia32_cvtb2mask256:
18389 case clang::X86::BI__builtin_ia32_cvtb2mask512:
18390 case clang::X86::BI__builtin_ia32_cvtw2mask128:
18391 case clang::X86::BI__builtin_ia32_cvtw2mask256:
18392 case clang::X86::BI__builtin_ia32_cvtw2mask512:
18393 case clang::X86::BI__builtin_ia32_cvtd2mask128:
18394 case clang::X86::BI__builtin_ia32_cvtd2mask256:
18395 case clang::X86::BI__builtin_ia32_cvtd2mask512:
18396 case clang::X86::BI__builtin_ia32_cvtq2mask128:
18397 case clang::X86::BI__builtin_ia32_cvtq2mask256:
18398 case clang::X86::BI__builtin_ia32_cvtq2mask512: {
18405 unsigned RetWidth = Info.Ctx.getIntWidth(E->
getType());
18406 llvm::APInt Bits(RetWidth, 0);
18408 for (
unsigned ElemNum = 0; ElemNum != VectorLen; ++ElemNum) {
18410 unsigned MSB = A[A.getBitWidth() - 1];
18411 Bits.setBitVal(ElemNum, MSB);
18414 APSInt RetMask(Bits,
true);
18418 case clang::X86::BI__builtin_ia32_cmpb128_mask:
18419 case clang::X86::BI__builtin_ia32_cmpw128_mask:
18420 case clang::X86::BI__builtin_ia32_cmpd128_mask:
18421 case clang::X86::BI__builtin_ia32_cmpq128_mask:
18422 case clang::X86::BI__builtin_ia32_cmpb256_mask:
18423 case clang::X86::BI__builtin_ia32_cmpw256_mask:
18424 case clang::X86::BI__builtin_ia32_cmpd256_mask:
18425 case clang::X86::BI__builtin_ia32_cmpq256_mask:
18426 case clang::X86::BI__builtin_ia32_cmpb512_mask:
18427 case clang::X86::BI__builtin_ia32_cmpw512_mask:
18428 case clang::X86::BI__builtin_ia32_cmpd512_mask:
18429 case clang::X86::BI__builtin_ia32_cmpq512_mask:
18430 case clang::X86::BI__builtin_ia32_ucmpb128_mask:
18431 case clang::X86::BI__builtin_ia32_ucmpw128_mask:
18432 case clang::X86::BI__builtin_ia32_ucmpd128_mask:
18433 case clang::X86::BI__builtin_ia32_ucmpq128_mask:
18434 case clang::X86::BI__builtin_ia32_ucmpb256_mask:
18435 case clang::X86::BI__builtin_ia32_ucmpw256_mask:
18436 case clang::X86::BI__builtin_ia32_ucmpd256_mask:
18437 case clang::X86::BI__builtin_ia32_ucmpq256_mask:
18438 case clang::X86::BI__builtin_ia32_ucmpb512_mask:
18439 case clang::X86::BI__builtin_ia32_ucmpw512_mask:
18440 case clang::X86::BI__builtin_ia32_ucmpd512_mask:
18441 case clang::X86::BI__builtin_ia32_ucmpq512_mask: {
18445 (BuiltinOp >= clang::X86::BI__builtin_ia32_ucmpb128_mask &&
18446 BuiltinOp <= clang::X86::BI__builtin_ia32_ucmpw512_mask);
18459 unsigned RetWidth = Mask.getBitWidth();
18461 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18463 for (
unsigned ElemNum = 0; ElemNum < VectorLen; ++ElemNum) {
18468 switch (
Opcode.getExtValue() & 0x7) {
18473 Result = IsUnsigned ? A.ult(B) : A.slt(B);
18476 Result = IsUnsigned ? A.ule(B) : A.sle(B);
18485 Result = IsUnsigned ? A.uge(B) : A.sge(B);
18488 Result = IsUnsigned ? A.ugt(B) : A.sgt(B);
18495 RetMask.setBitVal(ElemNum, Mask[ElemNum] &&
Result);
18500 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
18501 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
18502 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
18515 unsigned NumBytesInQWord = 8;
18516 unsigned NumBitsInByte = 8;
18518 unsigned NumQWords = NumBytes / NumBytesInQWord;
18519 unsigned RetWidth = ZeroMask.getBitWidth();
18520 APSInt RetMask(llvm::APInt(RetWidth, 0),
true);
18522 for (
unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
18523 APInt SourceQWord(64, 0);
18524 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18528 SourceQWord.insertBits(
APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
18531 for (
unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
18532 unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
18535 if (ZeroMask[SelIdx]) {
18536 RetMask.setBitVal(SelIdx, SourceQWord[M]);
18548 const LValue &LV) {
18551 if (!LV.getLValueBase())
18556 if (!LV.getLValueDesignator().Invalid &&
18557 !LV.getLValueDesignator().isOnePastTheEnd())
18567 if (LV.getLValueDesignator().Invalid)
18573 return LV.getLValueOffset() == Size;
18583class DataRecursiveIntBinOpEvaluator {
18584 struct EvalResult {
18586 bool Failed =
false;
18588 EvalResult() =
default;
18590 void swap(EvalResult &RHS) {
18592 Failed = RHS.Failed;
18593 RHS.Failed =
false;
18599 EvalResult LHSResult;
18600 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
18603 Job(Job &&) =
default;
18605 void startSpeculativeEval(EvalInfo &Info) {
18606 SpecEvalRAII = SpeculativeEvaluationRAII(Info);
18610 SpeculativeEvaluationRAII SpecEvalRAII;
18613 SmallVector<Job, 16> Queue;
18615 IntExprEvaluator &IntEval;
18620 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &
Result)
18621 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(
Result) { }
18627 static bool shouldEnqueue(
const BinaryOperator *E) {
18634 bool Traverse(
const BinaryOperator *E) {
18636 EvalResult PrevResult;
18637 while (!Queue.empty())
18638 process(PrevResult);
18640 if (PrevResult.Failed)
return false;
18642 FinalResult.
swap(PrevResult.Val);
18653 bool Error(
const Expr *E) {
18654 return IntEval.Error(E);
18657 return IntEval.Error(E, D);
18660 OptionalDiagnostic CCEDiag(
const Expr *E,
diag::kind D) {
18661 return Info.CCEDiag(E, D);
18665 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18666 bool &SuppressRHSDiags);
18668 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18671 void EvaluateExpr(
const Expr *E, EvalResult &
Result) {
18677 void process(EvalResult &
Result);
18679 void enqueue(
const Expr *E) {
18681 Queue.resize(Queue.size()+1);
18682 Queue.back().E = E;
18683 Queue.back().Kind = Job::AnyExprKind;
18689bool DataRecursiveIntBinOpEvaluator::
18690 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
18691 bool &SuppressRHSDiags) {
18694 if (LHSResult.Failed)
18695 return Info.noteSideEffect();
18704 if (LHSAsBool == (E->
getOpcode() == BO_LOr)) {
18705 Success(LHSAsBool, E, LHSResult.Val);
18709 LHSResult.Failed =
true;
18713 if (!Info.noteSideEffect())
18719 SuppressRHSDiags =
true;
18728 if (LHSResult.Failed && !Info.noteFailure())
18739 assert(!LVal.
hasLValuePath() &&
"have designator for integer lvalue");
18741 uint64_t Offset64 = Offset.getQuantity();
18742 uint64_t Index64 = Index.extOrTrunc(64).getZExtValue();
18744 : Offset64 + Index64);
18747bool DataRecursiveIntBinOpEvaluator::
18748 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
18751 if (RHSResult.Failed)
18758 bool lhsResult, rhsResult;
18773 if (rhsResult == (E->
getOpcode() == BO_LOr))
18784 if (LHSResult.Failed || RHSResult.Failed)
18787 const APValue &LHSVal = LHSResult.Val;
18788 const APValue &RHSVal = RHSResult.Val;
18812 if (!LHSExpr || !RHSExpr)
18814 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
18815 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
18816 if (!LHSAddrExpr || !RHSAddrExpr)
18841void DataRecursiveIntBinOpEvaluator::process(EvalResult &
Result) {
18842 Job &job = Queue.back();
18844 switch (job.Kind) {
18845 case Job::AnyExprKind: {
18846 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
18847 if (shouldEnqueue(Bop)) {
18848 job.Kind = Job::BinOpKind;
18849 enqueue(Bop->getLHS());
18854 EvaluateExpr(job.E,
Result);
18859 case Job::BinOpKind: {
18861 bool SuppressRHSDiags =
false;
18862 if (!VisitBinOpLHSOnly(
Result, Bop, SuppressRHSDiags)) {
18866 if (SuppressRHSDiags)
18867 job.startSpeculativeEval(Info);
18868 job.LHSResult.swap(
Result);
18869 job.Kind = Job::BinOpVisitedLHSKind;
18874 case Job::BinOpVisitedLHSKind: {
18878 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop,
Result.Val);
18884 llvm_unreachable(
"Invalid Job::Kind!");
18888enum class CmpResult {
18897template <
class SuccessCB,
class AfterCB>
18900 SuccessCB &&
Success, AfterCB &&DoAfter) {
18905 "unsupported binary expression evaluation");
18907 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
18921 if (!LHSOK && !Info.noteFailure())
18926 return Success(CmpResult::Less, E);
18928 return Success(CmpResult::Greater, E);
18929 return Success(CmpResult::Equal, E);
18933 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHSTy));
18934 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHSTy));
18937 if (!LHSOK && !Info.noteFailure())
18942 return Success(CmpResult::Less, E);
18944 return Success(CmpResult::Greater, E);
18945 return Success(CmpResult::Equal, E);
18949 ComplexValue LHS, RHS;
18958 LHS.makeComplexFloat();
18959 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
18964 if (!LHSOK && !Info.noteFailure())
18970 RHS.makeComplexFloat();
18971 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
18975 if (LHS.isComplexFloat()) {
18976 APFloat::cmpResult CR_r =
18977 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
18978 APFloat::cmpResult CR_i =
18979 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
18980 bool IsEqual = CR_r == APFloat::cmpEqual && CR_i == APFloat::cmpEqual;
18981 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18983 assert(IsEquality &&
"invalid complex comparison");
18984 bool IsEqual = LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
18985 LHS.getComplexIntImag() == RHS.getComplexIntImag();
18986 return Success(IsEqual ? CmpResult::Equal : CmpResult::Unequal, E);
18992 APFloat RHS(0.0), LHS(0.0);
18995 if (!LHSOK && !Info.noteFailure())
19002 llvm::APFloatBase::cmpResult APFloatCmpResult = LHS.compare(RHS);
19003 if (!Info.InConstantContext &&
19004 APFloatCmpResult == APFloat::cmpUnordered &&
19007 Info.FFDiag(E, diag::note_constexpr_float_arithmetic_strict);
19010 auto GetCmpRes = [&]() {
19011 switch (APFloatCmpResult) {
19012 case APFloat::cmpEqual:
19013 return CmpResult::Equal;
19014 case APFloat::cmpLessThan:
19015 return CmpResult::Less;
19016 case APFloat::cmpGreaterThan:
19017 return CmpResult::Greater;
19018 case APFloat::cmpUnordered:
19019 return CmpResult::Unordered;
19021 llvm_unreachable(
"Unrecognised APFloat::cmpResult enum");
19023 return Success(GetCmpRes(), E);
19027 LValue LHSValue, RHSValue;
19030 if (!LHSOK && !Info.noteFailure())
19041 if (Info.checkingPotentialConstantExpression() &&
19042 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19044 auto DiagComparison = [&] (
unsigned DiagID,
bool Reversed =
false) {
19045 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19046 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19047 Info.FFDiag(E, DiagID)
19054 return DiagComparison(
19055 diag::note_constexpr_pointer_comparison_unspecified);
19061 if ((!LHSValue.Base && !LHSValue.Offset.
isZero()) ||
19062 (!RHSValue.Base && !RHSValue.Offset.
isZero()))
19063 return DiagComparison(diag::note_constexpr_pointer_constant_comparison,
19077 return DiagComparison(diag::note_constexpr_literal_comparison);
19079 return DiagComparison(diag::note_constexpr_opaque_call_comparison,
19084 return DiagComparison(diag::note_constexpr_pointer_weak_comparison,
19088 if (LHSValue.Base && LHSValue.Offset.
isZero() &&
19090 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19092 if (RHSValue.Base && RHSValue.Offset.
isZero() &&
19094 return DiagComparison(diag::note_constexpr_pointer_comparison_past_end,
19100 return DiagComparison(
19101 diag::note_constexpr_pointer_comparison_zero_sized);
19102 if (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown)
19103 return DiagComparison(
19104 diag::note_constexpr_pointer_comparison_unspecified);
19106 return Success(CmpResult::Unequal, E);
19109 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19110 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19112 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19113 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19123 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
19124 bool WasArrayIndex;
19127 :
getType(LHSValue.Base).getNonReferenceType(),
19128 LHSDesignator, RHSDesignator, WasArrayIndex);
19135 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
19136 Mismatch < RHSDesignator.Entries.size()) {
19137 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
19138 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
19140 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
19142 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19143 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
19146 Info.CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
19147 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
19152 diag::note_constexpr_pointer_comparison_differing_access)
19160 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
19163 assert(PtrSize <= 64 &&
"Unexpected pointer width");
19164 uint64_t Mask = ~0ULL >> (64 - PtrSize);
19165 CompareLHS &= Mask;
19166 CompareRHS &= Mask;
19171 if (!LHSValue.Base.
isNull() && IsRelational) {
19175 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
19176 uint64_t OffsetLimit = Size.getQuantity();
19177 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
19181 if (CompareLHS < CompareRHS)
19182 return Success(CmpResult::Less, E);
19183 if (CompareLHS > CompareRHS)
19184 return Success(CmpResult::Greater, E);
19185 return Success(CmpResult::Equal, E);
19189 assert(IsEquality &&
"unexpected member pointer operation");
19192 MemberPtr LHSValue, RHSValue;
19195 if (!LHSOK && !Info.noteFailure())
19203 if (LHSValue.getDecl() && LHSValue.getDecl()->isWeak()) {
19204 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19205 << LHSValue.getDecl();
19208 if (RHSValue.getDecl() && RHSValue.getDecl()->isWeak()) {
19209 Info.FFDiag(E, diag::note_constexpr_mem_pointer_weak_comparison)
19210 << RHSValue.getDecl();
19217 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
19218 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
19219 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19224 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
19225 if (MD->isVirtual())
19226 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19227 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
19228 if (MD->isVirtual())
19229 Info.CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
19235 bool Equal = LHSValue == RHSValue;
19236 return Success(
Equal ? CmpResult::Equal : CmpResult::Unequal, E);
19241 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
19249 return Success(CmpResult::Equal, E);
19255bool RecordExprEvaluator::VisitBinCmp(
const BinaryOperator *E) {
19259 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19262 case CmpResult::Unequal:
19263 llvm_unreachable(
"should never produce Unequal for three-way comparison");
19264 case CmpResult::Less:
19265 CCR = ComparisonCategoryResult::Less;
19267 case CmpResult::Equal:
19268 CCR = ComparisonCategoryResult::Equal;
19270 case CmpResult::Greater:
19271 CCR = ComparisonCategoryResult::Greater;
19273 case CmpResult::Unordered:
19274 CCR = ComparisonCategoryResult::Unordered;
19279 const ComparisonCategoryInfo &CmpInfo =
19280 Info.Ctx.CompCategories.getInfoForType(E->
getType());
19288 ConstantExprKind::Normal);
19291 return ExprEvaluatorBaseTy::VisitBinCmp(E);
19295bool RecordExprEvaluator::VisitCXXParenListInitExpr(
19296 const CXXParenListInitExpr *E) {
19297 return VisitCXXParenListOrInitListExpr(E, E->
getInitExprs());
19300bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
19305 if (!Info.noteFailure())
19309 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
19310 return DataRecursiveIntBinOpEvaluator(*
this,
Result).Traverse(E);
19314 "DataRecursiveIntBinOpEvaluator should have handled integral types");
19319 auto OnSuccess = [&](CmpResult CR,
const BinaryOperator *E) {
19320 assert((CR != CmpResult::Unequal || E->
isEqualityOp()) &&
19321 "should only produce Unequal for equality comparisons");
19322 bool IsEqual = CR == CmpResult::Equal,
19323 IsLess = CR == CmpResult::Less,
19324 IsGreater = CR == CmpResult::Greater;
19328 llvm_unreachable(
"unsupported binary operator");
19331 return Success(IsEqual == (Op == BO_EQ), E);
19335 return Success(IsGreater, E);
19337 return Success(IsEqual || IsLess, E);
19339 return Success(IsEqual || IsGreater, E);
19343 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19352 LValue LHSValue, RHSValue;
19355 if (!LHSOK && !Info.noteFailure())
19364 if (Info.checkingPotentialConstantExpression() &&
19365 (LHSValue.AllowConstexprUnknown || RHSValue.AllowConstexprUnknown))
19368 const Expr *LHSExpr = LHSValue.Base.
dyn_cast<
const Expr *>();
19369 const Expr *RHSExpr = RHSValue.Base.
dyn_cast<
const Expr *>();
19371 auto DiagArith = [&](
unsigned DiagID) {
19372 std::string LHS = LHSValue.toString(Info.Ctx, E->
getLHS()->
getType());
19373 std::string RHS = RHSValue.toString(Info.Ctx, E->
getRHS()->
getType());
19374 Info.FFDiag(E, DiagID) << LHS << RHS;
19375 if (LHSExpr && LHSExpr == RHSExpr)
19377 diag::note_constexpr_repeated_literal_eval)
19382 if (!LHSExpr || !RHSExpr)
19383 return DiagArith(diag::note_constexpr_pointer_arith_unspecified);
19386 return DiagArith(diag::note_constexpr_literal_arith);
19388 const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
19389 const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
19390 if (!LHSAddrExpr || !RHSAddrExpr)
19398 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
19399 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
19401 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
19402 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
19408 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
19411 Info.CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
19416 CharUnits ElementSize;
19423 if (ElementSize.
isZero()) {
19424 Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size)
19441 APSInt TrueResult = (LHS - RHS) / ElemSize;
19444 if (
Result.extend(65) != TrueResult &&
19450 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
19455bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
19456 const UnaryExprOrTypeTraitExpr *E) {
19458 case UETT_PreferredAlignOf:
19459 case UETT_AlignOf: {
19468 case UETT_PtrAuthTypeDiscriminator: {
19474 case UETT_VecStep: {
19478 unsigned n = Ty->
castAs<VectorType>()->getNumElements();
19490 case UETT_DataSizeOf:
19491 case UETT_SizeOf: {
19495 if (
const ReferenceType *Ref = SrcTy->
getAs<ReferenceType>())
19506 case UETT_OpenMPRequiredSimdAlign:
19509 Info.Ctx.toCharUnitsFromBits(
19513 case UETT_VectorElements: {
19517 if (
const auto *VT = Ty->
getAs<VectorType>())
19521 if (Info.InConstantContext)
19522 Info.CCEDiag(E, diag::note_constexpr_non_const_vectorelements)
19527 case UETT_CountOf: {
19533 if (
const auto *CAT =
19543 const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
19545 if (VAT->getElementType()->isArrayType()) {
19548 if (!VAT->getSizeExpr()) {
19553 std::optional<APSInt> Res =
19554 VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
19559 static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
19560 Res->getZExtValue()};
19572 llvm_unreachable(
"unknown expr/type trait");
19575bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
19576 Info.Ctx.recordOffsetOfEvaluation(OOE);
19582 for (
unsigned i = 0; i != n; ++i) {
19590 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
19594 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
19597 if (IdxResult.isNegative() || IdxResult.getActiveBits() > 63)
19599 int64_t IdxVal = IdxResult.getExtValue();
19602 ElemSize > std::numeric_limits<int64_t>::max() / IdxVal)
19603 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19604 int64_t Offset = IdxVal * ElemSize;
19605 if (
Result.getQuantity() > std::numeric_limits<int64_t>::max() - Offset)
19606 return Error(OOE, diag::note_constexpr_offsetof_overflow);
19612 FieldDecl *MemberDecl = ON.
getField();
19617 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19619 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
19626 llvm_unreachable(
"dependent __builtin_offsetof");
19629 CXXBaseSpecifier *BaseSpec = ON.
getBase();
19638 const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
19641 CurrentType = BaseSpec->
getType();
19655bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19675 if (Info.checkingForUndefinedBehavior())
19676 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
19677 diag::warn_integer_constant_overflow)
19705bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
19707 QualType DestType = E->
getType();
19708 QualType SrcType = SubExpr->
getType();
19711 case CK_BaseToDerived:
19712 case CK_DerivedToBase:
19713 case CK_UncheckedDerivedToBase:
19716 case CK_ArrayToPointerDecay:
19717 case CK_FunctionToPointerDecay:
19718 case CK_NullToPointer:
19719 case CK_NullToMemberPointer:
19720 case CK_BaseToDerivedMemberPointer:
19721 case CK_DerivedToBaseMemberPointer:
19722 case CK_ReinterpretMemberPointer:
19723 case CK_ConstructorConversion:
19724 case CK_IntegralToPointer:
19726 case CK_VectorSplat:
19727 case CK_IntegralToFloating:
19728 case CK_FloatingCast:
19729 case CK_CPointerToObjCPointerCast:
19730 case CK_BlockPointerToObjCPointerCast:
19731 case CK_AnyPointerToBlockPointerCast:
19732 case CK_ObjCObjectLValueCast:
19733 case CK_FloatingRealToComplex:
19734 case CK_FloatingComplexToReal:
19735 case CK_FloatingComplexCast:
19736 case CK_FloatingComplexToIntegralComplex:
19737 case CK_IntegralRealToComplex:
19738 case CK_IntegralComplexCast:
19739 case CK_IntegralComplexToFloatingComplex:
19740 case CK_BuiltinFnToFnPtr:
19741 case CK_ZeroToOCLOpaqueType:
19742 case CK_NonAtomicToAtomic:
19743 case CK_AddressSpaceConversion:
19744 case CK_IntToOCLSampler:
19745 case CK_FloatingToFixedPoint:
19746 case CK_FixedPointToFloating:
19747 case CK_FixedPointCast:
19748 case CK_IntegralToFixedPoint:
19749 case CK_MatrixCast:
19750 case CK_HLSLAggregateSplatCast:
19751 llvm_unreachable(
"invalid cast kind for integral value");
19755 case CK_LValueBitCast:
19756 case CK_ARCProduceObject:
19757 case CK_ARCConsumeObject:
19758 case CK_ARCReclaimReturnedObject:
19759 case CK_ARCExtendBlockObject:
19760 case CK_CopyAndAutoreleaseBlockObject:
19763 case CK_UserDefinedConversion:
19764 case CK_LValueToRValue:
19765 case CK_AtomicToNonAtomic:
19767 case CK_LValueToRValueBitCast:
19768 case CK_HLSLArrayRValue:
19769 return ExprEvaluatorBaseTy::VisitCastExpr(E);
19771 case CK_MemberPointerToBoolean:
19772 case CK_PointerToBoolean:
19773 case CK_IntegralToBoolean:
19774 case CK_FloatingToBoolean:
19775 case CK_BooleanToSignedIntegral:
19776 case CK_FloatingComplexToBoolean:
19777 case CK_IntegralComplexToBoolean: {
19782 if (BoolResult && E->
getCastKind() == CK_BooleanToSignedIntegral)
19784 return Success(IntResult, E);
19787 case CK_FixedPointToIntegral: {
19788 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SrcType));
19792 llvm::APSInt
Result = Src.convertToInt(
19793 Info.Ctx.getIntWidth(DestType),
19800 case CK_FixedPointToBoolean: {
19803 if (!
Evaluate(Val, Info, SubExpr))
19808 case CK_IntegralCast: {
19809 if (!Visit(SubExpr))
19819 if (
Result.isAddrLabelDiff()) {
19820 unsigned DestBits = Info.Ctx.getTypeSize(DestType);
19821 return DestBits >= 32 && DestBits <= Info.Ctx.getTypeSize(SrcType);
19824 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
19827 if (Info.Ctx.getLangOpts().CPlusPlus && DestType->
isEnumeralType()) {
19839 if (!ED->isFixed()) {
19843 ED->getValueRange(
Max,
Min);
19846 if (ED->getNumNegativeBits() &&
19847 (
Max.slt(
Result.getInt().getSExtValue()) ||
19848 Min.sgt(
Result.getInt().getSExtValue())))
19849 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19850 << llvm::toString(
Result.getInt(), 10) <<
Min.getSExtValue()
19851 <<
Max.getSExtValue() << ED;
19852 else if (!ED->getNumNegativeBits() &&
19853 Max.ult(
Result.getInt().getZExtValue()))
19854 Info.CCEDiag(E, diag::note_constexpr_unscoped_enum_out_of_range)
19855 << llvm::toString(
Result.getInt(), 10) <<
Min.getZExtValue()
19856 <<
Max.getZExtValue() << ED;
19864 case CK_PointerToIntegral: {
19865 CCEDiag(E, diag::note_constexpr_invalid_cast)
19866 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
19873 if (LV.getLValueBase()) {
19878 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
19881 LV.Designator.setInvalid();
19889 if (!
V.toIntegralConstant(AsInt, SrcType, Info.Ctx))
19890 llvm_unreachable(
"Can't cast this!");
19895 case CK_IntegralComplexToReal: {
19899 return Success(
C.getComplexIntReal(), E);
19902 case CK_FloatingToIntegral: {
19912 case CK_HLSLVectorTruncation: {
19918 case CK_HLSLMatrixTruncation: {
19924 case CK_HLSLElementwiseCast: {
19937 return Success(ResultVal, E);
19941 llvm_unreachable(
"unknown cast resulting in integral value");
19944bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
19949 if (!LV.isComplexInt())
19951 return Success(LV.getComplexIntReal(), E);
19957bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
19962 if (!LV.isComplexInt())
19964 return Success(LV.getComplexIntImag(), E);
19971bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
19975bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
19979bool IntExprEvaluator::VisitConceptSpecializationExpr(
19980 const ConceptSpecializationExpr *E) {
19984bool IntExprEvaluator::VisitRequiresExpr(
const RequiresExpr *E) {
19988bool FixedPointExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
19998 if (!
Result.isFixedPoint())
20001 APFixedPoint Negated =
Result.getFixedPoint().negate(&Overflowed);
20015bool FixedPointExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20017 QualType DestType = E->
getType();
20019 "Expected destination type to be a fixed point type");
20020 auto DestFXSema = Info.Ctx.getFixedPointSemantics(DestType);
20023 case CK_FixedPointCast: {
20024 APFixedPoint Src(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20028 APFixedPoint
Result = Src.convert(DestFXSema, &Overflowed);
20030 if (Info.checkingForUndefinedBehavior())
20031 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20032 diag::warn_fixedpoint_constant_overflow)
20039 case CK_IntegralToFixedPoint: {
20045 APFixedPoint IntResult = APFixedPoint::getFromIntValue(
20046 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20049 if (Info.checkingForUndefinedBehavior())
20050 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20051 diag::warn_fixedpoint_constant_overflow)
20052 << IntResult.toString() << E->
getType();
20057 return Success(IntResult, E);
20059 case CK_FloatingToFixedPoint: {
20065 APFixedPoint
Result = APFixedPoint::getFromFloatValue(
20066 Src, Info.Ctx.getFixedPointSemantics(DestType), &Overflowed);
20069 if (Info.checkingForUndefinedBehavior())
20070 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20071 diag::warn_fixedpoint_constant_overflow)
20080 case CK_LValueToRValue:
20081 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20087bool FixedPointExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20089 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20091 const Expr *LHS = E->
getLHS();
20092 const Expr *RHS = E->
getRHS();
20094 Info.Ctx.getFixedPointSemantics(E->
getType());
20096 APFixedPoint LHSFX(Info.Ctx.getFixedPointSemantics(LHS->
getType()));
20099 APFixedPoint RHSFX(Info.Ctx.getFixedPointSemantics(RHS->
getType()));
20103 bool OpOverflow =
false, ConversionOverflow =
false;
20104 APFixedPoint
Result(LHSFX.getSemantics());
20107 Result = LHSFX.add(RHSFX, &OpOverflow)
20108 .convert(ResultFXSema, &ConversionOverflow);
20112 Result = LHSFX.sub(RHSFX, &OpOverflow)
20113 .convert(ResultFXSema, &ConversionOverflow);
20117 Result = LHSFX.mul(RHSFX, &OpOverflow)
20118 .convert(ResultFXSema, &ConversionOverflow);
20122 if (RHSFX.getValue() == 0) {
20123 Info.FFDiag(E, diag::note_expr_divide_by_zero);
20126 Result = LHSFX.div(RHSFX, &OpOverflow)
20127 .convert(ResultFXSema, &ConversionOverflow);
20133 llvm::APSInt RHSVal = RHSFX.getValue();
20136 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding();
20137 unsigned Amt = RHSVal.getLimitedValue(ShiftBW - 1);
20141 if (RHSVal.isNegative())
20142 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHSVal;
20143 else if (Amt != RHSVal)
20144 Info.CCEDiag(E, diag::note_constexpr_large_shift)
20145 << RHSVal << E->
getType() << ShiftBW;
20148 Result = LHSFX.shl(Amt, &OpOverflow);
20150 Result = LHSFX.shr(Amt, &OpOverflow);
20156 if (OpOverflow || ConversionOverflow) {
20157 if (Info.checkingForUndefinedBehavior())
20158 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
20159 diag::warn_fixedpoint_constant_overflow)
20172class FloatExprEvaluator
20173 :
public ExprEvaluatorBase<FloatExprEvaluator> {
20176 FloatExprEvaluator(EvalInfo &info, APFloat &result)
20177 : ExprEvaluatorBaseTy(info),
Result(result) {}
20184 bool ZeroInitialization(
const Expr *E) {
20185 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20189 bool VisitCallExpr(
const CallExpr *E);
20191 bool VisitUnaryOperator(
const UnaryOperator *E);
20192 bool VisitBinaryOperator(
const BinaryOperator *E);
20193 bool VisitFloatingLiteral(
const FloatingLiteral *E);
20194 bool VisitCastExpr(
const CastExpr *E);
20196 bool VisitUnaryReal(
const UnaryOperator *E);
20197 bool VisitUnaryImag(
const UnaryOperator *E);
20206 return FloatExprEvaluator(Info,
Result).Visit(E);
20213 llvm::APFloat &
Result) {
20215 if (!S)
return false;
20217 const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
20223 fill = llvm::APInt(32, 0);
20224 else if (S->
getString().getAsInteger(0, fill))
20227 if (Context.getTargetInfo().isNan2008()) {
20229 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20231 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20239 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
20241 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
20247bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
20248 if (!IsConstantEvaluatedBuiltinCall(E))
20249 return ExprEvaluatorBaseTy::VisitCallExpr(E);
20253 switch (BuiltinOp) {
20257 case Builtin::BI__builtin_huge_val:
20258 case Builtin::BI__builtin_huge_valf:
20259 case Builtin::BI__builtin_huge_vall:
20260 case Builtin::BI__builtin_huge_valf16:
20261 case Builtin::BI__builtin_huge_valf128:
20262 case Builtin::BI__builtin_inf:
20263 case Builtin::BI__builtin_inff:
20264 case Builtin::BI__builtin_infl:
20265 case Builtin::BI__builtin_inff16:
20266 case Builtin::BI__builtin_inff128: {
20267 const llvm::fltSemantics &Sem =
20268 Info.Ctx.getFloatTypeSemantics(E->
getType());
20269 Result = llvm::APFloat::getInf(Sem);
20273 case Builtin::BI__builtin_nans:
20274 case Builtin::BI__builtin_nansf:
20275 case Builtin::BI__builtin_nansl:
20276 case Builtin::BI__builtin_nansf16:
20277 case Builtin::BI__builtin_nansf128:
20283 case Builtin::BI__builtin_nan:
20284 case Builtin::BI__builtin_nanf:
20285 case Builtin::BI__builtin_nanl:
20286 case Builtin::BI__builtin_nanf16:
20287 case Builtin::BI__builtin_nanf128:
20295 case Builtin::BI__builtin_elementwise_abs:
20296 case Builtin::BI__builtin_fabs:
20297 case Builtin::BI__builtin_fabsf:
20298 case Builtin::BI__builtin_fabsl:
20299 case Builtin::BI__builtin_fabsf128:
20308 if (
Result.isNegative())
20312 case Builtin::BI__arithmetic_fence:
20319 case Builtin::BI__builtin_copysign:
20320 case Builtin::BI__builtin_copysignf:
20321 case Builtin::BI__builtin_copysignl:
20322 case Builtin::BI__builtin_copysignf128: {
20331 case Builtin::BI__builtin_fmax:
20332 case Builtin::BI__builtin_fmaxf:
20333 case Builtin::BI__builtin_fmaxl:
20334 case Builtin::BI__builtin_fmaxf16:
20335 case Builtin::BI__builtin_fmaxf128: {
20344 case Builtin::BI__builtin_fmin:
20345 case Builtin::BI__builtin_fminf:
20346 case Builtin::BI__builtin_fminl:
20347 case Builtin::BI__builtin_fminf16:
20348 case Builtin::BI__builtin_fminf128: {
20357 case Builtin::BI__builtin_fmaximum_num:
20358 case Builtin::BI__builtin_fmaximum_numf:
20359 case Builtin::BI__builtin_fmaximum_numl:
20360 case Builtin::BI__builtin_fmaximum_numf16:
20361 case Builtin::BI__builtin_fmaximum_numf128: {
20370 case Builtin::BI__builtin_fminimum_num:
20371 case Builtin::BI__builtin_fminimum_numf:
20372 case Builtin::BI__builtin_fminimum_numl:
20373 case Builtin::BI__builtin_fminimum_numf16:
20374 case Builtin::BI__builtin_fminimum_numf128: {
20383 case Builtin::BI__builtin_elementwise_fma: {
20388 APFloat SourceY(0.), SourceZ(0.);
20394 (void)
Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
20398 case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
20405 unsigned Idx =
static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
20411bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
20423bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
20433 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
20434 Result = llvm::APFloat::getZero(Sem);
20438bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
20440 default:
return Error(E);
20454bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
20456 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
20460 if (!LHSOK && !Info.noteFailure())
20466bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
20471bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20476 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20478 case CK_HLSLAggregateSplatCast:
20479 llvm_unreachable(
"invalid cast kind for floating value");
20481 case CK_IntegralToFloating: {
20484 Info.Ctx.getLangOpts());
20490 case CK_FixedPointToFloating: {
20491 APFixedPoint FixResult(Info.Ctx.getFixedPointSemantics(SubExpr->
getType()));
20495 FixResult.convertToFloat(Info.Ctx.getFloatTypeSemantics(E->
getType()));
20499 case CK_FloatingCast: {
20500 if (!Visit(SubExpr))
20506 case CK_FloatingComplexToReal: {
20510 Result =
V.getComplexFloatReal();
20513 case CK_HLSLVectorTruncation: {
20519 case CK_HLSLMatrixTruncation: {
20525 case CK_HLSLElementwiseCast: {
20540 return Success(ResultVal, E);
20550class ComplexExprEvaluator
20551 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
20555 ComplexExprEvaluator(EvalInfo &info, ComplexValue &
Result)
20563 bool ZeroInitialization(
const Expr *E);
20569 bool VisitImaginaryLiteral(
const ImaginaryLiteral *E);
20570 bool VisitCastExpr(
const CastExpr *E);
20571 bool VisitBinaryOperator(
const BinaryOperator *E);
20572 bool VisitUnaryOperator(
const UnaryOperator *E);
20573 bool VisitInitListExpr(
const InitListExpr *E);
20574 bool VisitCallExpr(
const CallExpr *E);
20582 return ComplexExprEvaluator(Info,
Result).Visit(E);
20585bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
20586 QualType ElemTy = E->
getType()->
castAs<ComplexType>()->getElementType();
20588 Result.makeComplexFloat();
20589 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
20593 Result.makeComplexInt();
20594 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
20601bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
20605 Result.makeComplexFloat();
20614 "Unexpected imaginary literal.");
20616 Result.makeComplexInt();
20621 Result.IntReal =
APSInt(Imag.getBitWidth(), !Imag.isSigned());
20626bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
20630 case CK_BaseToDerived:
20631 case CK_DerivedToBase:
20632 case CK_UncheckedDerivedToBase:
20635 case CK_ArrayToPointerDecay:
20636 case CK_FunctionToPointerDecay:
20637 case CK_NullToPointer:
20638 case CK_NullToMemberPointer:
20639 case CK_BaseToDerivedMemberPointer:
20640 case CK_DerivedToBaseMemberPointer:
20641 case CK_MemberPointerToBoolean:
20642 case CK_ReinterpretMemberPointer:
20643 case CK_ConstructorConversion:
20644 case CK_IntegralToPointer:
20645 case CK_PointerToIntegral:
20646 case CK_PointerToBoolean:
20648 case CK_VectorSplat:
20649 case CK_IntegralCast:
20650 case CK_BooleanToSignedIntegral:
20651 case CK_IntegralToBoolean:
20652 case CK_IntegralToFloating:
20653 case CK_FloatingToIntegral:
20654 case CK_FloatingToBoolean:
20655 case CK_FloatingCast:
20656 case CK_CPointerToObjCPointerCast:
20657 case CK_BlockPointerToObjCPointerCast:
20658 case CK_AnyPointerToBlockPointerCast:
20659 case CK_ObjCObjectLValueCast:
20660 case CK_FloatingComplexToReal:
20661 case CK_FloatingComplexToBoolean:
20662 case CK_IntegralComplexToReal:
20663 case CK_IntegralComplexToBoolean:
20664 case CK_ARCProduceObject:
20665 case CK_ARCConsumeObject:
20666 case CK_ARCReclaimReturnedObject:
20667 case CK_ARCExtendBlockObject:
20668 case CK_CopyAndAutoreleaseBlockObject:
20669 case CK_BuiltinFnToFnPtr:
20670 case CK_ZeroToOCLOpaqueType:
20671 case CK_NonAtomicToAtomic:
20672 case CK_AddressSpaceConversion:
20673 case CK_IntToOCLSampler:
20674 case CK_FloatingToFixedPoint:
20675 case CK_FixedPointToFloating:
20676 case CK_FixedPointCast:
20677 case CK_FixedPointToBoolean:
20678 case CK_FixedPointToIntegral:
20679 case CK_IntegralToFixedPoint:
20680 case CK_MatrixCast:
20681 case CK_HLSLVectorTruncation:
20682 case CK_HLSLMatrixTruncation:
20683 case CK_HLSLElementwiseCast:
20684 case CK_HLSLAggregateSplatCast:
20685 llvm_unreachable(
"invalid cast kind for complex value");
20687 case CK_LValueToRValue:
20688 case CK_AtomicToNonAtomic:
20690 case CK_LValueToRValueBitCast:
20691 case CK_HLSLArrayRValue:
20692 return ExprEvaluatorBaseTy::VisitCastExpr(E);
20695 case CK_LValueBitCast:
20696 case CK_UserDefinedConversion:
20699 case CK_FloatingRealToComplex: {
20704 Result.makeComplexFloat();
20709 case CK_FloatingComplexCast: {
20713 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20721 case CK_FloatingComplexToIntegralComplex: {
20725 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20728 Result.makeComplexInt();
20735 case CK_IntegralRealToComplex: {
20740 Result.makeComplexInt();
20741 Result.IntImag =
APSInt(Real.getBitWidth(), !Real.isSigned());
20745 case CK_IntegralComplexCast: {
20749 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20758 case CK_IntegralComplexToFloatingComplex: {
20763 Info.Ctx.getLangOpts());
20764 QualType To = E->
getType()->
castAs<ComplexType>()->getElementType();
20767 Result.makeComplexFloat();
20769 To,
Result.FloatReal) &&
20775 llvm_unreachable(
"unknown cast resulting in complex value");
20781 0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1, 0xe8, 0x4f, 0x29, 0xc0,
20782 0xb0, 0xe1, 0xe5, 0xc7, 0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
20783 0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2, 0x3a, 0x6e, 0x5a, 0xf1,
20784 0x55, 0x4d, 0xa8, 0xc9, 0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
20785 0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42, 0xf2, 0x35, 0x20, 0x6f,
20786 0x77, 0xbb, 0x59, 0x19, 0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
20787 0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09, 0xed, 0x5c, 0x05, 0xca,
20788 0x4c, 0x24, 0x87, 0xbf, 0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
20789 0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43, 0xf4, 0x47, 0x91, 0xdf,
20790 0x33, 0x93, 0x21, 0x3b, 0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
20791 0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82, 0x83, 0x7e, 0x7f, 0x80,
20792 0x96, 0x73, 0xbe, 0x56, 0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
20793 0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72, 0x2a, 0x14, 0x9f, 0x88,
20794 0xf9, 0xdc, 0x89, 0x9a, 0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
20795 0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62, 0x0c, 0xe0, 0x1f, 0xef,
20796 0x11, 0x75, 0x78, 0x71, 0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
20797 0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f, 0xa9, 0x27, 0x53, 0x04,
20798 0x1b, 0xfc, 0xac, 0xe6, 0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
20799 0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b, 0xb1, 0x0d, 0xd6, 0xeb,
20800 0xc6, 0x0e, 0xcf, 0xad, 0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
20801 0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c, 0xdd, 0x9c, 0x7d, 0xa0,
20802 0xcd, 0x1a, 0x41, 0x1c};
20804 return GFInv[Byte];
20809 unsigned NumBitsInByte = 8;
20812 for (
uint32_t BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20814 AQword.lshr((7 -
static_cast<int32_t>(BitIdx)) * NumBitsInByte)
20821 Product = AByte & XByte;
20826 for (
unsigned PBitIdx = 0; PBitIdx != NumBitsInByte; ++PBitIdx) {
20827 Parity = Parity ^ ((Product >> PBitIdx) & 0x1);
20830 uint8_t Temp = Imm[BitIdx] ? 1 : 0;
20831 RetByte |= (Temp ^ Parity) << BitIdx;
20841 unsigned NumBitsInByte = 8;
20842 for (
unsigned BitIdx = 0; BitIdx != NumBitsInByte; ++BitIdx) {
20843 if ((BByte >> BitIdx) & 0x1) {
20844 TWord = TWord ^ (AByte << BitIdx);
20852 for (
int32_t BitIdx = 14; BitIdx > 7; --BitIdx) {
20853 if ((TWord >> BitIdx) & 0x1) {
20854 TWord = TWord ^ (0x11B << (BitIdx - 8));
20857 return (TWord & 0xFF);
20861 APFloat &ResR, APFloat &ResI) {
20867 APFloat AC = A *
C;
20868 APFloat BD = B * D;
20869 APFloat AD = A * D;
20870 APFloat BC = B *
C;
20873 if (ResR.isNaN() && ResI.isNaN()) {
20874 bool Recalc =
false;
20875 if (A.isInfinity() || B.isInfinity()) {
20876 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20878 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20881 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20883 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20886 if (
C.isInfinity() || D.isInfinity()) {
20887 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20889 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20892 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20894 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20897 if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
20898 BC.isInfinity())) {
20900 A = APFloat::copySign(APFloat(A.getSemantics()), A);
20902 B = APFloat::copySign(APFloat(B.getSemantics()), B);
20904 C = APFloat::copySign(APFloat(
C.getSemantics()),
C);
20906 D = APFloat::copySign(APFloat(D.getSemantics()), D);
20910 ResR = APFloat::getInf(A.getSemantics()) * (A *
C - B * D);
20911 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B *
C);
20917 APFloat &ResR, APFloat &ResI) {
20924 APFloat MaxCD = maxnum(
abs(
C),
abs(D));
20925 if (MaxCD.isFinite()) {
20926 DenomLogB =
ilogb(MaxCD);
20927 C =
scalbn(
C, -DenomLogB, APFloat::rmNearestTiesToEven);
20928 D =
scalbn(D, -DenomLogB, APFloat::rmNearestTiesToEven);
20930 APFloat Denom =
C *
C + D * D;
20932 scalbn((A *
C + B * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20934 scalbn((B *
C - A * D) / Denom, -DenomLogB, APFloat::rmNearestTiesToEven);
20935 if (ResR.isNaN() && ResI.isNaN()) {
20936 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
20937 ResR = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * A;
20938 ResI = APFloat::getInf(ResR.getSemantics(),
C.isNegative()) * B;
20939 }
else if ((A.isInfinity() || B.isInfinity()) &&
C.isFinite() &&
20941 A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
20943 B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
20945 ResR = APFloat::getInf(ResR.getSemantics()) * (A *
C + B * D);
20946 ResI = APFloat::getInf(ResI.getSemantics()) * (B *
C - A * D);
20947 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
20948 C = APFloat::copySign(APFloat(
C.getSemantics(),
C.isInfinity() ? 1 : 0),
20950 D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
20952 ResR = APFloat::getZero(ResR.getSemantics()) * (A *
C + B * D);
20953 ResI = APFloat::getZero(ResI.getSemantics()) * (B *
C - A * D);
20960 APSInt NormAmt = Amount;
20961 unsigned BitWidth =
Value.getBitWidth();
20962 unsigned AmtBitWidth = NormAmt.getBitWidth();
20963 if (BitWidth == 1) {
20965 NormAmt =
APSInt(APInt(AmtBitWidth, 0), NormAmt.isUnsigned());
20966 }
else if (BitWidth == 2) {
20971 APSInt(APInt(AmtBitWidth, NormAmt[0] ? 1 : 0), NormAmt.isUnsigned());
20974 if (AmtBitWidth > BitWidth) {
20975 Divisor = llvm::APInt(AmtBitWidth, BitWidth);
20977 Divisor = llvm::APInt(BitWidth, BitWidth);
20978 if (AmtBitWidth < BitWidth) {
20979 NormAmt = NormAmt.extend(BitWidth);
20984 if (NormAmt.isSigned()) {
20985 NormAmt =
APSInt(NormAmt.srem(Divisor),
false);
20986 if (NormAmt.isNegative()) {
20987 APSInt SignedDivisor(Divisor,
false);
20988 NormAmt += SignedDivisor;
20991 NormAmt =
APSInt(NormAmt.urem(Divisor),
true);
20998bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
21000 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
21004 bool LHSReal =
false, RHSReal =
false;
21012 Result.makeComplexFloat();
21016 LHSOK = Visit(E->
getLHS());
21018 if (!LHSOK && !Info.noteFailure())
21024 APFloat &Real = RHS.FloatReal;
21027 RHS.makeComplexFloat();
21028 RHS.FloatImag =
APFloat(Real.getSemantics());
21032 assert(!(LHSReal && RHSReal) &&
21033 "Cannot have both operands of a complex operation be real.");
21035 default:
return Error(E);
21037 if (
Result.isComplexFloat()) {
21038 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
21039 APFloat::rmNearestTiesToEven);
21041 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21043 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
21044 APFloat::rmNearestTiesToEven);
21046 Result.getComplexIntReal() += RHS.getComplexIntReal();
21047 Result.getComplexIntImag() += RHS.getComplexIntImag();
21051 if (
Result.isComplexFloat()) {
21052 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
21053 APFloat::rmNearestTiesToEven);
21055 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
21056 Result.getComplexFloatImag().changeSign();
21057 }
else if (!RHSReal) {
21058 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
21059 APFloat::rmNearestTiesToEven);
21062 Result.getComplexIntReal() -= RHS.getComplexIntReal();
21063 Result.getComplexIntImag() -= RHS.getComplexIntImag();
21067 if (
Result.isComplexFloat()) {
21072 ComplexValue LHS =
Result;
21073 APFloat &A = LHS.getComplexFloatReal();
21074 APFloat &B = LHS.getComplexFloatImag();
21075 APFloat &
C = RHS.getComplexFloatReal();
21076 APFloat &D = RHS.getComplexFloatImag();
21080 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
21088 }
else if (RHSReal) {
21100 ComplexValue LHS =
Result;
21101 Result.getComplexIntReal() =
21102 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
21103 LHS.getComplexIntImag() * RHS.getComplexIntImag());
21104 Result.getComplexIntImag() =
21105 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
21106 LHS.getComplexIntImag() * RHS.getComplexIntReal());
21110 if (
Result.isComplexFloat()) {
21115 ComplexValue LHS =
Result;
21116 APFloat &A = LHS.getComplexFloatReal();
21117 APFloat &B = LHS.getComplexFloatImag();
21118 APFloat &
C = RHS.getComplexFloatReal();
21119 APFloat &D = RHS.getComplexFloatImag();
21133 B = APFloat::getZero(A.getSemantics());
21138 ComplexValue LHS =
Result;
21139 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
21140 RHS.getComplexIntImag() * RHS.getComplexIntImag();
21142 return Error(E, diag::note_expr_divide_by_zero);
21144 Result.getComplexIntReal() =
21145 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
21146 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
21147 Result.getComplexIntImag() =
21148 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
21149 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
21157bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
21171 if (
Result.isComplexFloat()) {
21172 Result.getComplexFloatReal().changeSign();
21173 Result.getComplexFloatImag().changeSign();
21176 Result.getComplexIntReal() = -
Result.getComplexIntReal();
21177 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21181 if (
Result.isComplexFloat())
21182 Result.getComplexFloatImag().changeSign();
21184 Result.getComplexIntImag() = -
Result.getComplexIntImag();
21189bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
21192 Result.makeComplexFloat();
21198 Result.makeComplexInt();
21206 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
21209bool ComplexExprEvaluator::VisitCallExpr(
const CallExpr *E) {
21210 if (!IsConstantEvaluatedBuiltinCall(E))
21211 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21214 case Builtin::BI__builtin_complex:
21215 Result.makeComplexFloat();
21233class AtomicExprEvaluator :
21234 public ExprEvaluatorBase<AtomicExprEvaluator> {
21235 const LValue *
This;
21238 AtomicExprEvaluator(EvalInfo &Info,
const LValue *This,
APValue &
Result)
21246 bool ZeroInitialization(
const Expr *E) {
21247 ImplicitValueInitExpr VIE(
21255 bool VisitCastExpr(
const CastExpr *E) {
21258 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21259 case CK_NullToPointer:
21261 return ZeroInitialization(E);
21262 case CK_NonAtomicToAtomic:
21274 return AtomicExprEvaluator(Info,
This,
Result).Visit(E);
21283class VoidExprEvaluator
21284 :
public ExprEvaluatorBase<VoidExprEvaluator> {
21286 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
21290 bool ZeroInitialization(
const Expr *E) {
return true; }
21292 bool VisitCastExpr(
const CastExpr *E) {
21295 return ExprEvaluatorBaseTy::VisitCastExpr(E);
21302 bool VisitCallExpr(
const CallExpr *E) {
21303 if (!IsConstantEvaluatedBuiltinCall(E))
21304 return ExprEvaluatorBaseTy::VisitCallExpr(E);
21307 case Builtin::BI__assume:
21308 case Builtin::BI__builtin_assume:
21312 case Builtin::BI__builtin_operator_delete:
21320 bool VisitCXXDeleteExpr(
const CXXDeleteExpr *E);
21324bool VoidExprEvaluator::VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
21326 if (Info.SpeculativeEvaluationDepth)
21330 if (!OperatorDelete
21331 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21332 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21342 if (
Pointer.Designator.Invalid)
21346 if (
Pointer.isNullPointer()) {
21350 if (!Info.getLangOpts().CPlusPlus20)
21351 Info.CCEDiag(E, diag::note_constexpr_new);
21359 QualType AllocType =
Pointer.Base.getDynamicAllocType();
21365 Info.FFDiag(E, diag::note_constexpr_delete_base_nonvirt_dtor)
21374 if (VirtualDelete &&
21376 ->isUsableAsGlobalAllocationFunctionInConstantEvaluation()) {
21377 Info.FFDiag(E, diag::note_constexpr_new_non_replaceable)
21384 (*Alloc)->Value, AllocType))
21387 if (!Info.HeapAllocs.erase(
Pointer.Base.dyn_cast<DynamicAllocLValue>())) {
21392 Info.FFDiag(E, diag::note_constexpr_double_delete);
21402 return VoidExprEvaluator(Info).Visit(E);
21414 if (E->
isGLValue() || T->isFunctionType()) {
21419 }
else if (T->isVectorType()) {
21422 }
else if (T->isConstantMatrixType()) {
21425 }
else if (T->isIntegralOrEnumerationType()) {
21426 if (!IntExprEvaluator(Info,
Result).Visit(E))
21428 }
else if (T->hasPointerRepresentation()) {
21433 }
else if (T->isRealFloatingType()) {
21434 llvm::APFloat F(0.0);
21438 }
else if (T->isAnyComplexType()) {
21443 }
else if (T->isFixedPointType()) {
21444 if (!FixedPointExprEvaluator(Info,
Result).Visit(E))
return false;
21445 }
else if (T->isMemberPointerType()) {
21451 }
else if (T->isArrayType()) {
21454 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21458 }
else if (T->isRecordType()) {
21461 Info.CurrentCall->createTemporary(E, T, ScopeKind::FullExpression, LV);
21465 }
else if (T->isVoidType()) {
21466 if (!Info.getLangOpts().CPlusPlus11)
21467 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
21471 }
else if (T->isAtomicType()) {
21476 E, Unqual, ScopeKind::FullExpression, LV);
21484 }
else if (Info.getLangOpts().CPlusPlus11) {
21485 Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->
getType();
21488 Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr);
21499 const Expr *E,
bool AllowNonLiteralTypes) {
21515 if (T->isArrayType())
21517 else if (T->isRecordType())
21519 else if (T->isAtomicType()) {
21541 if (Info.EnableNewConstInterp) {
21542 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E,
Result))
21545 ConstantExprKind::Normal);
21554 LV.setFrom(Info.Ctx,
Result);
21561 ConstantExprKind::Normal) &&
21569 if (
const auto *L = dyn_cast<IntegerLiteral>(Exp)) {
21571 APValue(
APSInt(L->getValue(), L->getType()->isUnsignedIntegerType()));
21576 if (
const auto *L = dyn_cast<CXXBoolLiteralExpr>(Exp)) {
21582 if (
const auto *FL = dyn_cast<FloatingLiteral>(Exp)) {
21588 if (
const auto *L = dyn_cast<CharacterLiteral>(Exp)) {
21594 if (
const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
21595 if (CE->hasAPValueResult()) {
21596 APValue APV = CE->getAPValueResult();
21598 Result = std::move(APV);
21674 bool InConstantContext)
const {
21676 "Expression evaluator can't be called on a dependent expression.");
21677 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsRValue");
21679 Info.InConstantContext = InConstantContext;
21680 return ::EvaluateAsRValue(
this,
Result, Ctx, Info);
21684 bool InConstantContext)
const {
21686 "Expression evaluator can't be called on a dependent expression.");
21687 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsBooleanCondition");
21695 bool InConstantContext)
const {
21697 "Expression evaluator can't be called on a dependent expression.");
21698 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsInt");
21700 Info.InConstantContext = InConstantContext;
21701 return ::EvaluateAsInt(
this,
Result, Ctx, AllowSideEffects, Info);
21706 bool InConstantContext)
const {
21708 "Expression evaluator can't be called on a dependent expression.");
21709 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFixedPoint");
21711 Info.InConstantContext = InConstantContext;
21712 return ::EvaluateAsFixedPoint(
this,
Result, Ctx, AllowSideEffects, Info);
21717 bool InConstantContext)
const {
21719 "Expression evaluator can't be called on a dependent expression.");
21721 if (!
getType()->isRealFloatingType())
21724 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsFloat");
21736 bool InConstantContext)
const {
21738 "Expression evaluator can't be called on a dependent expression.");
21740 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsLValue");
21742 Info.InConstantContext = InConstantContext;
21746 if (Info.EnableNewConstInterp) {
21747 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val,
21748 ConstantExprKind::Normal))
21751 LV.setFrom(Ctx,
Result.Val);
21754 ConstantExprKind::Normal, CheckedTemps);
21757 if (!
EvaluateLValue(
this, LV, Info) || !Info.discardCleanups() ||
21758 Result.HasSideEffects ||
21761 ConstantExprKind::Normal, CheckedTemps))
21764 LV.moveInto(
Result.Val);
21771 bool IsConstantDestruction) {
21772 EvalInfo Info(Ctx, EStatus,
21775 Info.setEvaluatingDecl(
Base, DestroyedValue,
21776 EvalInfo::EvaluatingDeclKind::Dtor);
21777 Info.InConstantContext = IsConstantDestruction;
21786 if (!Info.discardCleanups())
21787 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21795 "Expression evaluator can't be called on a dependent expression.");
21801 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateAsConstantExpr");
21803 EvalInfo Info(Ctx,
Result, EM);
21804 Info.InConstantContext =
true;
21806 if (Info.EnableNewConstInterp) {
21807 if (!Info.Ctx.getInterpContext().evaluate(Info,
this,
Result.Val, Kind))
21810 getStorageType(Ctx,
this),
Result.Val, Kind);
21815 if (Kind == ConstantExprKind::ClassTemplateArgument)
21831 FullExpressionRAII
Scope(Info);
21836 if (!Info.discardCleanups())
21837 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21847 if (Kind == ConstantExprKind::ClassTemplateArgument &&
21850 Result.HasSideEffects)) {
21861 bool IsConstantInitialization)
const {
21863 "Expression evaluator can't be called on a dependent expression.");
21864 assert(VD &&
"Need a valid VarDecl");
21866 llvm::TimeTraceScope TimeScope(
"EvaluateAsInitializer", [&] {
21868 llvm::raw_string_ostream OS(Name);
21873 EvalInfo Info(Ctx, EStatus,
21874 (IsConstantInitialization &&
21878 Info.setEvaluatingDecl(VD, EStatus.
Val);
21879 Info.InConstantContext = IsConstantInitialization;
21884 if (Info.EnableNewConstInterp) {
21886 if (!InterpCtx.evaluateAsInitializer(Info, VD,
this, EStatus.
Val))
21890 ConstantExprKind::Normal);
21905 FullExpressionRAII
Scope(Info);
21914 Info.performLifetimeExtension();
21916 if (!Info.discardCleanups())
21917 llvm_unreachable(
"Unhandled cleanup; missing full expression marker?");
21921 ConstantExprKind::Normal) &&
21941 EStatus.
Diag = &Notes;
21958 EvalInfo Info(Ctx, EStatus,
21961 Info.InConstantContext = IsConstantDestruction;
21963 std::move(DestroyedValue)))
21970 getLocation(), EStatus, IsConstantDestruction) ||
21982 "Expression evaluator can't be called on a dependent expression.");
21991 "Expression evaluator can't be called on a dependent expression.");
21993 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstInt");
21996 Info.InConstantContext =
true;
22000 assert(
Result &&
"Could not evaluate expression");
22001 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22003 return EVResult.Val.getInt();
22009 "Expression evaluator can't be called on a dependent expression.");
22011 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateKnownConstIntCheckOverflow");
22013 EVResult.Diag =
Diag;
22015 Info.InConstantContext =
true;
22016 Info.CheckingForUndefinedBehavior =
true;
22020 assert(
Result &&
"Could not evaluate expression");
22021 assert(EVResult.Val.isInt() &&
"Expression did not evaluate to integer");
22023 return EVResult.Val.getInt();
22028 "Expression evaluator can't be called on a dependent expression.");
22030 ExprTimeTraceScope TimeScope(
this, Ctx,
"EvaluateForOverflow");
22035 Info.CheckingForUndefinedBehavior =
true;
22041 assert(
Val.isLValue());
22067 IK_ICEIfUnevaluated,
22083static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
22090 Info.InConstantContext =
true;
22099 assert(!E->
isValueDependent() &&
"Should not see value dependent exprs!");
22104#define ABSTRACT_STMT(Node)
22105#define STMT(Node, Base) case Expr::Node##Class:
22106#define EXPR(Node, Base)
22107#include "clang/AST/StmtNodes.inc"
22108 case Expr::PredefinedExprClass:
22109 case Expr::FloatingLiteralClass:
22110 case Expr::ImaginaryLiteralClass:
22111 case Expr::StringLiteralClass:
22112 case Expr::ArraySubscriptExprClass:
22113 case Expr::MatrixSingleSubscriptExprClass:
22114 case Expr::MatrixSubscriptExprClass:
22115 case Expr::ArraySectionExprClass:
22116 case Expr::OMPArrayShapingExprClass:
22117 case Expr::OMPIteratorExprClass:
22118 case Expr::CompoundAssignOperatorClass:
22119 case Expr::CompoundLiteralExprClass:
22120 case Expr::ExtVectorElementExprClass:
22121 case Expr::MatrixElementExprClass:
22122 case Expr::DesignatedInitExprClass:
22123 case Expr::ArrayInitLoopExprClass:
22124 case Expr::ArrayInitIndexExprClass:
22125 case Expr::NoInitExprClass:
22126 case Expr::DesignatedInitUpdateExprClass:
22127 case Expr::ImplicitValueInitExprClass:
22128 case Expr::ParenListExprClass:
22129 case Expr::VAArgExprClass:
22130 case Expr::AddrLabelExprClass:
22131 case Expr::StmtExprClass:
22132 case Expr::CXXMemberCallExprClass:
22133 case Expr::CUDAKernelCallExprClass:
22134 case Expr::CXXAddrspaceCastExprClass:
22135 case Expr::CXXDynamicCastExprClass:
22136 case Expr::CXXTypeidExprClass:
22137 case Expr::CXXUuidofExprClass:
22138 case Expr::MSPropertyRefExprClass:
22139 case Expr::MSPropertySubscriptExprClass:
22140 case Expr::CXXNullPtrLiteralExprClass:
22141 case Expr::UserDefinedLiteralClass:
22142 case Expr::CXXThisExprClass:
22143 case Expr::CXXThrowExprClass:
22144 case Expr::CXXNewExprClass:
22145 case Expr::CXXDeleteExprClass:
22146 case Expr::CXXPseudoDestructorExprClass:
22147 case Expr::UnresolvedLookupExprClass:
22148 case Expr::RecoveryExprClass:
22149 case Expr::DependentScopeDeclRefExprClass:
22150 case Expr::CXXConstructExprClass:
22151 case Expr::CXXInheritedCtorInitExprClass:
22152 case Expr::CXXStdInitializerListExprClass:
22153 case Expr::CXXBindTemporaryExprClass:
22154 case Expr::ExprWithCleanupsClass:
22155 case Expr::CXXTemporaryObjectExprClass:
22156 case Expr::CXXUnresolvedConstructExprClass:
22157 case Expr::CXXDependentScopeMemberExprClass:
22158 case Expr::UnresolvedMemberExprClass:
22159 case Expr::ObjCStringLiteralClass:
22160 case Expr::ObjCBoxedExprClass:
22161 case Expr::ObjCArrayLiteralClass:
22162 case Expr::ObjCDictionaryLiteralClass:
22163 case Expr::ObjCEncodeExprClass:
22164 case Expr::ObjCMessageExprClass:
22165 case Expr::ObjCSelectorExprClass:
22166 case Expr::ObjCProtocolExprClass:
22167 case Expr::ObjCIvarRefExprClass:
22168 case Expr::ObjCPropertyRefExprClass:
22169 case Expr::ObjCSubscriptRefExprClass:
22170 case Expr::ObjCIsaExprClass:
22171 case Expr::ObjCAvailabilityCheckExprClass:
22172 case Expr::ShuffleVectorExprClass:
22173 case Expr::ConvertVectorExprClass:
22174 case Expr::BlockExprClass:
22176 case Expr::OpaqueValueExprClass:
22177 case Expr::PackExpansionExprClass:
22178 case Expr::SubstNonTypeTemplateParmPackExprClass:
22179 case Expr::FunctionParmPackExprClass:
22180 case Expr::AsTypeExprClass:
22181 case Expr::ObjCIndirectCopyRestoreExprClass:
22182 case Expr::MaterializeTemporaryExprClass:
22183 case Expr::PseudoObjectExprClass:
22184 case Expr::AtomicExprClass:
22185 case Expr::LambdaExprClass:
22186 case Expr::CXXFoldExprClass:
22187 case Expr::CoawaitExprClass:
22188 case Expr::DependentCoawaitExprClass:
22189 case Expr::CoyieldExprClass:
22190 case Expr::SYCLUniqueStableNameExprClass:
22191 case Expr::CXXParenListInitExprClass:
22192 case Expr::HLSLOutArgExprClass:
22193 case Expr::CXXExpansionSelectExprClass:
22196 case Expr::MemberExprClass: {
22199 while (
const auto *M = dyn_cast<MemberExpr>(ME)) {
22202 ME = M->getBase()->IgnoreParenImpCasts();
22204 const auto *DRE = dyn_cast<DeclRefExpr>(ME);
22206 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
22214 case Expr::InitListExprClass: {
22225 case Expr::SizeOfPackExprClass:
22226 case Expr::GNUNullExprClass:
22227 case Expr::SourceLocExprClass:
22228 case Expr::EmbedExprClass:
22229 case Expr::OpenACCAsteriskSizeExprClass:
22232 case Expr::PackIndexingExprClass:
22235 case Expr::SubstNonTypeTemplateParmExprClass:
22239 case Expr::ConstantExprClass:
22242 case Expr::ParenExprClass:
22244 case Expr::GenericSelectionExprClass:
22246 case Expr::IntegerLiteralClass:
22247 case Expr::FixedPointLiteralClass:
22248 case Expr::CharacterLiteralClass:
22249 case Expr::ObjCBoolLiteralExprClass:
22250 case Expr::CXXBoolLiteralExprClass:
22251 case Expr::CXXScalarValueInitExprClass:
22252 case Expr::TypeTraitExprClass:
22253 case Expr::ConceptSpecializationExprClass:
22254 case Expr::RequiresExprClass:
22255 case Expr::ArrayTypeTraitExprClass:
22256 case Expr::ExpressionTraitExprClass:
22257 case Expr::CXXNoexceptExprClass:
22258 case Expr::CXXReflectExprClass:
22260 case Expr::CallExprClass:
22261 case Expr::CXXOperatorCallExprClass: {
22270 case Expr::CXXRewrittenBinaryOperatorClass:
22273 case Expr::DeclRefExprClass: {
22287 const VarDecl *VD = dyn_cast<VarDecl>(D);
22294 case Expr::UnaryOperatorClass: {
22317 llvm_unreachable(
"invalid unary operator class");
22319 case Expr::OffsetOfExprClass: {
22328 case Expr::UnaryExprOrTypeTraitExprClass: {
22330 if ((Exp->
getKind() == UETT_SizeOf) &&
22333 if (Exp->
getKind() == UETT_CountOf) {
22340 if (VAT->getElementType()->isArrayType())
22352 case Expr::BinaryOperatorClass: {
22397 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
22400 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22401 if (REval.isSigned() && REval.isAllOnes()) {
22403 if (LEval.isMinSignedValue())
22404 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22412 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
22413 return ICEDiag(IK_ICEIfUnevaluated, E->
getBeginLoc());
22419 return Worst(LHSResult, RHSResult);
22425 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
22435 return Worst(LHSResult, RHSResult);
22438 llvm_unreachable(
"invalid binary operator kind");
22440 case Expr::ImplicitCastExprClass:
22441 case Expr::CStyleCastExprClass:
22442 case Expr::CXXFunctionalCastExprClass:
22443 case Expr::CXXStaticCastExprClass:
22444 case Expr::CXXReinterpretCastExprClass:
22445 case Expr::CXXConstCastExprClass:
22446 case Expr::ObjCBridgedCastExprClass: {
22453 APSInt IgnoredVal(DestWidth, !DestSigned);
22458 if (FL->getValue().convertToInteger(IgnoredVal,
22459 llvm::APFloat::rmTowardZero,
22460 &Ignored) & APFloat::opInvalidOp)
22466 case CK_LValueToRValue:
22467 case CK_AtomicToNonAtomic:
22468 case CK_NonAtomicToAtomic:
22470 case CK_IntegralToBoolean:
22471 case CK_IntegralCast:
22477 case Expr::BinaryConditionalOperatorClass: {
22480 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
22482 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
22483 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
22484 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
22486 return FalseResult;
22488 case Expr::ConditionalOperatorClass: {
22496 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
22499 if (CondResult.Kind == IK_NotICE)
22505 if (TrueResult.Kind == IK_NotICE)
22507 if (FalseResult.Kind == IK_NotICE)
22508 return FalseResult;
22509 if (CondResult.Kind == IK_ICEIfUnevaluated)
22511 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
22517 return FalseResult;
22520 case Expr::CXXDefaultArgExprClass:
22522 case Expr::CXXDefaultInitExprClass:
22524 case Expr::ChooseExprClass: {
22527 case Expr::BuiltinBitCastExprClass: {
22528 if (!checkBitCastConstexprEligibility(
nullptr, Ctx,
cast<CastExpr>(E)))
22534 llvm_unreachable(
"Invalid StmtClass!");
22540 llvm::APSInt *
Value) {
22557 "Expression evaluator can't be called on a dependent expression.");
22559 ExprTimeTraceScope TimeScope(
this, Ctx,
"isIntegerConstantExpr");
22565 if (D.Kind != IK_ICE)
22570std::optional<llvm::APSInt>
22574 return std::nullopt;
22581 return std::nullopt;
22585 return std::nullopt;
22594 Info.InConstantContext =
true;
22597 llvm_unreachable(
"ICE cannot be evaluated!");
22604 "Expression evaluator can't be called on a dependent expression.");
22606 return CheckICE(
this, Ctx).Kind == IK_ICE;
22611 "Expression evaluator can't be called on a dependent expression.");
22621 *
Result = std::move(Scratch);
22633 Info.discardCleanups() && !Status.HasSideEffects;
22635 return IsConstExpr && !Status.DiagEmitted;
22643 "Expression evaluator can't be called on a dependent expression.");
22645 llvm::TimeTraceScope TimeScope(
"EvaluateWithSubstitution", [&] {
22647 llvm::raw_string_ostream OS(Name);
22655 Info.InConstantContext =
true;
22657 if (Info.EnableNewConstInterp) {
22658 if (std::optional<bool> BoolResult =
22659 Info.Ctx.getInterpContext().evaluateWithSubstitution(
22660 Info, Callee, Args,
This,
this)) {
22668 const LValue *ThisPtr =
nullptr;
22671 auto *MD = dyn_cast<CXXMethodDecl>(Callee);
22672 assert(MD &&
"Don't provide `this` for non-methods.");
22673 assert(MD->isImplicitObjectMemberFunction() &&
22674 "Don't provide `this` for methods without an implicit object.");
22676 if (!
This->isValueDependent() &&
22678 !Info.EvalStatus.HasSideEffects)
22679 ThisPtr = &ThisVal;
22683 Info.EvalStatus.HasSideEffects =
false;
22686 CallRef
Call = Info.CurrentCall->createCall(Callee);
22689 unsigned Idx = I - Args.begin();
22690 if (Idx >= Callee->getNumParams())
22692 const ParmVarDecl *PVD = Callee->getParamDecl(Idx);
22693 if ((*I)->isValueDependent() ||
22695 Info.EvalStatus.HasSideEffects) {
22697 if (
APValue *Slot = Info.getParamSlot(
Call, PVD))
22703 Info.EvalStatus.HasSideEffects =
false;
22708 Info.discardCleanups();
22709 Info.EvalStatus.HasSideEffects =
false;
22712 CallStackFrame Frame(Info, Callee->getLocation(), Callee, ThisPtr,
This,
22715 FullExpressionRAII
Scope(Info);
22717 !Info.EvalStatus.HasSideEffects;
22729 llvm::TimeTraceScope TimeScope(
"isPotentialConstantExpr", [&] {
22731 llvm::raw_string_ostream OS(Name);
22738 Status.
Diag = &Diags;
22742 Info.InConstantContext =
true;
22743 Info.CheckingPotentialConstantExpression =
true;
22746 if (Info.EnableNewConstInterp) {
22747 Info.Ctx.getInterpContext().isPotentialConstantExpr(Info, FD);
22748 return Diags.empty();
22759 This.set({&VIE, Info.CurrentCall->Index});
22767 Info.setEvaluatingDecl(
This.getLValueBase(), Scratch);
22773 &VIE, Args, CallRef(), FD->
getBody(), Info, Scratch,
22777 return Diags.empty();
22785 "Expression evaluator can't be called on a dependent expression.");
22788 Status.
Diag = &Diags;
22792 Info.InConstantContext =
true;
22793 Info.CheckingPotentialConstantExpression =
true;
22795 if (Info.EnableNewConstInterp) {
22796 Info.Ctx.getInterpContext().isPotentialConstantExprUnevaluated(Info, E, FD);
22797 return Diags.empty();
22802 nullptr, CallRef());
22806 return Diags.empty();
22810 unsigned Type)
const {
22811 if (!
getType()->isPointerType())
22812 return std::nullopt;
22816 if (Info.EnableNewConstInterp)
22817 return Info.Ctx.getInterpContext().tryEvaluateObjectSize(Info,
this,
Type);
22821static std::optional<uint64_t>
22823 std::string *StringResult) {
22825 return std::nullopt;
22830 return std::nullopt;
22835 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
22836 String.getLValueBase().dyn_cast<
const Expr *>())) {
22839 if (
Off >= 0 && (uint64_t)
Off <= (uint64_t)Str.size() &&
22842 Info.Ctx.hasSameUnqualifiedType(CharTy, Info.Ctx.CharTy)) {
22843 Str = Str.substr(
Off);
22845 StringRef::size_type Pos = Str.find(0);
22846 if (Pos != StringRef::npos)
22847 Str = Str.substr(0, Pos);
22850 *StringResult = Str;
22858 for (uint64_t Strlen = 0; ; ++Strlen) {
22862 return std::nullopt;
22865 else if (StringResult)
22866 StringResult->push_back(Char.
getInt().getExtValue());
22868 return std::nullopt;
22875 std::string StringResult;
22877 if (Info.EnableNewConstInterp) {
22878 if (!Info.Ctx.getInterpContext().evaluateString(Info,
this, StringResult))
22879 return std::nullopt;
22880 return StringResult;
22884 return StringResult;
22885 return std::nullopt;
22888template <
typename T>
22890 const Expr *SizeExpression,
22891 const Expr *PtrExpression,
22895 Info.InConstantContext =
true;
22897 if (Info.EnableNewConstInterp)
22898 return Info.Ctx.getInterpContext().evaluateCharRange(Info, SizeExpression,
22902 FullExpressionRAII
Scope(Info);
22907 uint64_t Size = SizeValue.getZExtValue();
22910 if constexpr (std::is_same_v<APValue, T>)
22913 if (Size <
Result.max_size())
22920 for (uint64_t I = 0; I < Size; ++I) {
22926 if constexpr (std::is_same_v<APValue, T>) {
22927 Result.getArrayInitializedElt(I) = std::move(Char);
22931 assert(
C.getBitWidth() <= 8 &&
22932 "string element not representable in char");
22934 Result.push_back(
static_cast<char>(
C.getExtValue()));
22945 const Expr *SizeExpression,
22949 PtrExpression, Ctx, Status);
22953 const Expr *SizeExpression,
22957 PtrExpression, Ctx, Status);
22964 if (Info.EnableNewConstInterp)
22965 return Info.Ctx.getInterpContext().evaluateStrlen(Info,
this);
22970struct IsWithinLifetimeHandler {
22973 using result_type = std::optional<bool>;
22974 std::optional<bool> failed() {
return std::nullopt; }
22975 template <
typename T>
22976 std::optional<bool> found(T &Subobj,
QualType SubobjType,
22980 template <
typename T>
22981 std::optional<bool> found(T &Subobj, QualType SubobjType) {
22986std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
22987 const CallExpr *E) {
22988 EvalInfo &Info = IEE.Info;
22993 if (!Info.InConstantContext)
22994 return std::nullopt;
22996 const Expr *Arg = E->
getArg(0);
22998 return std::nullopt;
23001 return std::nullopt;
23003 if (Val.allowConstexprUnknown())
23007 bool CalledFromStd =
false;
23008 const auto *
Callee = Info.CurrentCall->getCallee();
23009 if (Callee &&
Callee->isInStdNamespace()) {
23010 const IdentifierInfo *Identifier =
Callee->getIdentifier();
23011 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
23013 Info.CCEDiag(CalledFromStd ? Info.CurrentCall->getCallRange().getBegin()
23015 diag::err_invalid_is_within_lifetime)
23016 << (CalledFromStd ?
"std::is_within_lifetime"
23017 :
"__builtin_is_within_lifetime")
23019 return std::nullopt;
23029 if (Val.isNullPointer() || Val.getLValueBase().isNull())
23031 QualType T = Val.getLValueBase().getType();
23033 "Pointers to functions should have been typed as function pointers "
23034 "which would have been rejected earlier");
23037 if (Val.getLValueDesignator().isOnePastTheEnd())
23039 assert(Val.getLValueDesignator().isValidSubobject() &&
23040 "Unchecked case for valid subobject");
23044 CompleteObject CO =
23048 if (Info.EvaluatingDeclValue && CO.Value == Info.EvaluatingDeclValue)
23053 IsWithinLifetimeHandler handler{Info};
23054 return findSubobject(Info, E, CO, Val.getLValueDesignator(), handler);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, Address OriginalBaseAddress, llvm::Value *Addr)
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
@ PointerToMemberFunction
static bool isRead(AccessKinds AK)
static bool EvaluateCharRangeAsStringImpl(const Expr *, T &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, Expr::EvalResult &Status)
static bool isValidIndeterminateAccess(AccessKinds AK)
Is this kind of access valid on an indeterminate object value?
static unsigned elementwiseSize(EvalInfo &Info, QualType BaseTy)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result, Expr::SideEffectsKind SEK)
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
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...
static const CXXMethodDecl * HandleVirtualDispatch(EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found, llvm::SmallVectorImpl< QualType > &CovariantAdjustmentPath)
Perform virtual dispatch.
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD)
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK, EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind, const FieldDecl *SubobjectDecl, CheckedTemporaries &CheckedTemps)
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 bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, llvm::function_ref< APInt(const APSInt &)> PackFn)
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size, SizeOfType SOT=SizeOfType::SizeOf)
Get the size of the given type in char units.
static bool HandleConstructorCall(const Expr *E, const LValue &This, CallRef Call, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
static bool hlslElementwiseCastHelper(EvalInfo &Info, const Expr *E, QualType DestTy, SmallVectorImpl< APValue > &SrcVals, SmallVectorImpl< QualType > &SrcTypes)
static bool ShouldPropagateBreakContinue(EvalInfo &Info, const Stmt *LoopOrSwitch, ArrayRef< BlockScopeRAII * > Scopes, EvalStmtResult &ESR)
Helper to implement named break/continue.
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 EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
CheckTrivialDefaultConstructor - Check whether a constructor is a trivial default constructor.
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
static const Expr * ignorePointerCastsAndParens(const Expr *E)
A more selective version of E->IgnoreParenCasts for tryEvaluateBuiltinObjectSize. This ignores some c...
static bool isAnyAccess(AccessKinds AK)
static bool EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, SuccessCB &&Success, AfterCB &&DoAfter)
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. C++11 [dcl.init]p5: To zero-initial...
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
std::optional< APFloat > EvalScalarMinMaxFp(const APFloat &A, const APFloat &B, std::optional< APSInt > RoundingMode, bool IsMin)
static bool CheckMemoryLeaks(EvalInfo &Info)
Enforce C++2a [expr.const]/4.17, which disallows new-expressions unless "the allocated storage is dea...
static bool handleScalarCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val)
static bool flattenAPValue(EvalInfo &Info, const Expr *E, APValue Value, QualType BaseTy, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &Types, unsigned Size)
static bool hlslAggSplatHelper(EvalInfo &Info, const Expr *E, APValue &SrcVal, QualType &SrcTy)
static bool isBaseClassPublic(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
Determine whether Base, which is known to be a direct base class of Derived, is a public base class.
static bool hasVirtualDestructor(QualType T)
static bool HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value)
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
unsigned ConvertBuiltinIDToX86BuiltinID(const ASTContext &Ctx, unsigned BuiltinOp)
Convert a builtin ID to the canonical x86 builtin ID the constant evaluators dispatch on in their x86...
static bool ConvertDoubleToFloatStrict(EvalInfo &Info, const Expr *E, APFloat OrigVal, APValue &Result)
static ICEDiag Worst(ICEDiag A, ICEDiag B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, unsigned Version, APValue *&Result)
Try to evaluate the initializer for a variable declaration.
static bool handleDefaultInitValue(QualType T, APValue &Result)
Get the value to use for a default-initialized object of type T.
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, uint64_t Size, uint64_t Idx)
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal, ConstantExprKind Kind, CheckedTemporaries &CheckedTemps)
Check that this reference or pointer core constant expression is a valid value for an address or refe...
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,...
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, QualType ElemType, APValue const &VecVal1, APValue const &VecVal2, unsigned EltNum, APValue &Result)
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, const Expr *E, QualType SourceTy, QualType DestTy, APValue const &Original, APValue &Result)
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
HandleMemberPointerAccess - Evaluate a member access operation and build an lvalue referring to the r...
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
HandleBaseToDerivedCast - Apply the given base-to-derived cast operation on the provided lvalue,...
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
static bool IsOpaqueConstantCall(const CallExpr *E)
Should this call expression be treated as forming an opaque constant?
static bool CheckMemberPointerConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Member pointers are constant expressions unless they point to a non-virtual dllimport member function...
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal, bool WantObjectRepresentation=false)
Perform an lvalue-to-rvalue conversion on the given glvalue.
static bool handleElementwiseCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &SrcTypes, SmallVectorImpl< QualType > &DestTypes, SmallVectorImpl< APValue > &Results)
static bool refersToCompleteObject(const LValue &LVal)
Tests to see if the LValue has a user-specified designator (that isn't necessarily valid)....
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 EvaluateDecompositionDeclInit(EvalInfo &Info, const DecompositionDecl *DD)
static bool IsWeakLValue(const LValue &Value)
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This, APValue &Result, const CXXConstructExpr *CCE, QualType AllocType)
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
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.
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...
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
Evaluate an expression to see if it had side-effects, and discard its result.
static bool constructAggregate(EvalInfo &Info, const FPOptions FPO, const Expr *E, APValue &Result, QualType ResultType, SmallVectorImpl< APValue > &Elements, SmallVectorImpl< QualType > &ElTypes)
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T, const LValue &LV, CharUnits &Size)
If we're evaluating the object size of an instance of a struct that contains a flexible array member,...
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< std::pair< unsigned, int >(unsigned, unsigned)> GetSourceIndex)
static QualType getSubobjectType(QualType ObjType, QualType SubobjType, bool IsMutable=false)
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate an integer or fixed point expression into an APResult.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, const FPOptions FPO, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
static const CXXRecordDecl * getBaseClassType(SubobjectDesignator &Designator, unsigned PathLength)
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result, const CXXRecordDecl *DerivedRD, const CXXRecordDecl *BaseRD)
Cast an lvalue referring to a derived class to a known base subobject.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static void expandVector(APValue &Vec, unsigned NumElements)
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
static bool handleCompareOpForVector(const APValue &LHSValue, BinaryOperatorKind Opcode, const APValue &RHSValue, APInt &Result)
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr)
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
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...
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CheckEvaluationResultKind
static bool isZeroSized(const LValue &Value)
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value)
Evaluate an expression as a C++11 integral constant expression.
static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T, UnaryExprOrTypeTrait ExprKind)
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info, APValue &Val, APSInt &Alignment)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, APSInt Adjustment)
Update a pointer value to model pointer arithmetic.
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result, AccessKinds AK=AK_Read)
Extract the designated sub-object of an rvalue.
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...
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index, bool IsSub)
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD)
static std::optional< uint64_t > EvaluateBuiltinStrLen(const Expr *E, EvalInfo &Info, std::string *StringResult=nullptr)
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param, const Expr *E, APValue &Result, bool CopyObjectRepresentation)
Perform a trivial copy from Param, which is the parameter of a copy or move constructor or assignment...
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, APFloat::opStatus St)
Check if the given evaluation result is allowed for constant evaluation.
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV)
EvaluateBuiltinConstantPForLValue - Determine the result of __builtin_constant_p when applied to the ...
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg)
EvaluateBuiltinConstantP - Evaluate __builtin_constant_p as similarly to GCC as we can manage.
static bool checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E, const LValue &This, const CXXMethodDecl *NamedMember)
Check that the pointee of the 'this' pointer in a member function call is either within its lifetime ...
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value, ConstantExprKind Kind)
Check that this core constant expression value is a valid value for a constant expression.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static std::optional< DynamicType > ComputeDynamicType(EvalInfo &Info, const Expr *E, LValue &This, AccessKinds AK)
Determine the dynamic type of an object.
static bool EvaluateDecl(EvalInfo &Info, const Decl *D, bool EvaluateConditionDecl=false)
static void expandArray(APValue &Array, unsigned Index)
static bool handleLogicalOpForVector(const APInt &LHSValue, BinaryOperatorKind Opcode, const APInt &RHSValue, APInt &Result)
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...
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.
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.
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result, EvalInfo &Info)
Evaluate only a fixed point expression into an APResult.
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, BinaryOperatorKind Opcode, APValue &LHSValue, const APValue &RHSValue)
static bool EvaluateMatrix(const Expr *E, APValue &Result, EvalInfo &Info)
static const FunctionDecl * getVirtualOperatorDelete(QualType T)
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 bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc={})
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. In some cases, the in-place evaluati...
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
static std::optional< DynAlloc * > CheckDeleteKind(EvalInfo &Info, const Expr *E, const LValue &Pointer, DynAlloc::Kind DeallocKind)
Check that the given object is a suitable pointer to a heap allocation that still exists and is of th...
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info, bool InvalidBaseOK=false)
Evaluate an expression as an lvalue. This can be legitimately called on expressions which are not glv...
static bool FastEvaluateAsRValue(const Expr *Exp, APValue &Result, const ASTContext &Ctx, bool &IsConst)
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E, APValue &Result, ArrayRef< QualType > Path)
Perform the adjustment from a value returned by a virtual function to a value of the statically expec...
static bool evalShiftWithCount(EvalInfo &Info, const CallExpr *Call, APValue &Out, llvm::function_ref< APInt(const APInt &, uint64_t)> ShiftOp, llvm::function_ref< APInt(const APInt &, unsigned)> OverflowOp)
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, APValue &Result, QualType AllocType=QualType())
static bool EvaluateArgs(ArrayRef< const Expr * > Args, CallRef Call, EvalInfo &Info, const FunctionDecl *Callee, bool RightToLeft=false, LValue *ObjectArg=nullptr)
Evaluate the arguments to a function call.
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result, EvalInfo &Info)
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx, const LValue &LVal, llvm::APInt &Result)
Convenience function. LVal's base must be a call to an alloc_size function.
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
static bool EvaluateInitForDeclOfReferenceType(EvalInfo &Info, const ValueDecl *D, const Expr *Init, LValue &Result, APValue &Val)
Evaluates the initializer of a reference.
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This, AccessKinds AK, bool Polymorphic)
Check that we can access the notional vptr of an object / determine its dynamic type.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
static bool getAlignmentArgument(const Expr *E, QualType ForType, EvalInfo &Info, APSInt &Alignment)
Evaluate the value of the alignment argument to __builtin_align_{up,down}, __builtin_is_aligned and _...
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
static 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 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 f...
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int, CharUnits &Result)
Converts the given APInt to CharUnits, assuming the APInt is unsigned. Fails if the conversion would ...
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg, CallRef Call, EvalInfo &Info, bool NonNull=false, APValue **EvaluatedArg=nullptr)
llvm::SmallPtrSet< const MaterializeTemporaryExpr *, 8 > CheckedTemporaries
Materialized temporaries that we've already checked to determine if they're initializsed by a constan...
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info)
static bool MaybeEvaluateDeferredVarDeclInit(EvalInfo &Info, const VarDecl *VD)
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, const APSInt &Value)
static std::optional< APValue > handleVectorUnaryOperator(ASTContext &Ctx, QualType ResultTy, UnaryOperatorKind Op, APValue Elt)
static bool lifetimeStartedInEvaluation(EvalInfo &Info, APValue::LValueBase Base, bool MutableSubobject=false)
static bool isOneByteCharacterType(QualType T)
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result, const CXXMethodDecl *MD, const FieldDecl *FD, bool LValueToRValueConversion)
Get an lvalue to a field of a lambda's closure type.
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult, const ASTContext &Ctx, Expr::SideEffectsKind AllowSideEffects, EvalInfo &Info)
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...
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK, QualType T)
Diagnose an attempt to read from any unreadable field within the specified type, which might be a cla...
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
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.
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base, APValue DestroyedValue, QualType Type, SourceLocation Loc, Expr::EvalStatus &EStatus, bool IsConstantDestruction)
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This, APValue &Result, const InitListExpr *ILE, QualType AllocType)
static bool HasSameBase(const LValue &A, const LValue &B)
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD)
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
static bool IsGlobalLValue(APValue::LValueBase B)
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E)
Get rounding mode to use in evaluation of the specified expression.
static QualType getObjectType(APValue::LValueBase B)
Retrieves the "underlying object type" of the given expression, as used by __builtin_object_size.
static bool handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode, const APTy &RHSValue, APInt &Result)
static std::optional< uint64_t > tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type, EvalInfo &Info, bool IsDynamic=false)
Tries to evaluate the __builtin_object_size for E. If successful, returns true and stores the result ...
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD)
Determine whether a type would actually be read by an lvalue-to-rvalue conversion.
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 HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *ObjectArg, const Expr *E, ArrayRef< const Expr * > Args, CallRef Call, const Stmt *Body, EvalInfo &Info, APValue &Result, const LValue *ResultSlot)
Evaluate a function call.
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 ...
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, LValueBaseString &AsString)
static bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and produce either the intege...
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E, LValue &Ptr)
Apply the given dynamic cast operation on the provided lvalue.
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E, LValue &Result)
Perform a call to 'operator new' or to ‘__builtin_operator_new’.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr, const LValue &LHS)
Handle a builtin simple-assignment or a call to a trivial assignment operator whose left-hand side mi...
uint8_t GFNIMul(uint8_t AByte, uint8_t BByte)
static bool isFormalAccess(AccessKinds AK)
Is this an access per the C++ definition?
static bool handleCompoundAssignment(EvalInfo &Info, const CompoundAssignOperator *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
static bool HandleDestruction(EvalInfo &Info, const Expr *E, const LValue &This, QualType ThisType)
Perform a destructor or pseudo-destructor call on the given object, which might in general not be a c...
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, const LValue &This, APValue &Value, QualType T)
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, const LValue &LHS, const LValue &RHS)
uint8_t GFNIMultiplicativeInverse(uint8_t Byte)
uint8_t GFNIAffine(uint8_t XByte, const APInt &AQword, const APSInt &Imm, bool Inverse)
APSInt NormalizeRotateAmount(const APSInt &Value, const APSInt &Amount)
Result
Implement __builtin_bit_cast and related operations.
static bool isModification(AccessKinds AK)
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.
llvm::MachO::Record Record
Implements a partial diagnostic which may not be emitted.
llvm::DenseMap< Stmt *, Stmt * > MapTy
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Expr * getExpr()
Get 'expr' part of the associated expression/statement.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ long long abs(long long __n)
a trap message and trap category.
llvm::APInt getValue() const
unsigned getVersion() const
QualType getDynamicAllocType() const
QualType getTypeInfoType() const
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
BaseOrMemberType getAsBaseOrMember() const
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool hasArrayFiller() const
const LValueBase getLValueBase() const
APValue & getArrayInitializedElt(unsigned I)
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
APValue & getStructField(unsigned i)
unsigned getMatrixNumColumns() const
const FieldDecl * getUnionField() const
APSInt & getComplexIntImag()
bool isComplexInt() const
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
A FieldDecl or CXXRecordDecl, along with a flag indicating whether we mean a virtual or non-virtual b...
ValueKind getKind() const
unsigned getArrayInitializedElts() const
static APValue IndeterminateValue()
APFixedPoint & getFixedPoint()
bool hasLValuePath() const
const ValueDecl * getMemberPointerDecl() const
APValue & getUnionValue()
CharUnits & getLValueOffset()
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
APValue & getArrayFiller()
unsigned getVectorLength() const
void setUnion(const FieldDecl *Field, const APValue &Value)
bool isIndeterminate() const
unsigned getMatrixNumRows() const
unsigned getArraySize() const
bool allowConstexprUnknown() const
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
bool isFixedPoint() const
APValue & getMatrixElt(unsigned Idx)
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
@ None
There is no such object (it's outside its lifetime).
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
APValue & getStructBase(unsigned i)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
unsigned getPreferredTypeAlign(QualType T) const
Return the "preferred" alignment of the specified type T for the current target, in bits.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const TargetInfo * getAuxTargetInfo() const
interp::Context & getInterpContext() const
Returns the clang bytecode interpreter context.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
LabelDecl * getLabel() const
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
uint64_t getValue() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
static bool isRelationalOp(Opcode Opc)
static bool isComparisonOp(Opcode Opc)
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
static bool isPtrMemOp(Opcode Opc)
predicates to categorize the respective opcodes.
static bool isAssignmentOp(Opcode Opc)
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isEqualityOp(Opcode Opc)
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const BlockDecl * getBlockDecl() const
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Expr * getExpr()
Get the initialization expression that will be used.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getLoopVarStmt()
DeclStmt * getRangeStmt()
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will call.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
QualType getFunctionObjectParameterReferenceType() const
Return the type of the object pointed by this.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isLambdaStaticInvoker() const
Determine whether this is a lambda closure type's static member function that is used for the result ...
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
Expr * getPlacementArg(unsigned I)
unsigned getNumPlacementArgs() const
SourceRange getSourceRange() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
base_class_iterator bases_end()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
capture_const_range captures() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
const AllocSizeAttr * getCalleeAllocSizeAttr() const
Try to get the alloc_size attribute of the callee. May return null.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CaseStmt - Represent a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
unsigned path_size() const
CastKind getCastKind() const
const FieldDecl * getTargetUnionField() const
const CXXBaseSpecifier *const * path_const_iterator
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operation.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPowerOfTwo() const
isPowerOfTwo - Test whether the quantity is a power of two.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const
Converts the specified result kind into the correct result kind for this category.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
CompoundLiteralExpr - [C99 6.5.2.5].
bool hasStaticStorage() const
APValue & getOrCreateStaticValue(ASTContext &Ctx) const
const Expr * getInitializer() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Stmt *const * const_body_iterator
body_iterator body_begin()
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
ConditionalOperator - The ?
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Represents the canonical version of C arrays with a specified constant size.
unsigned getSizeBitWidth() const
Return the bit width of the size type.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
bool isZeroSize() const
Return true if the size is zero.
const Expr * getSizeExpr() const
Return a pointer to the size expression.
llvm::APInt getSize() const
Return the constant array size as an APInt.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
Represents the current source location and context used to determine the value of the source location...
const Expr * getDefaultExpr() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
bool isAnyOperatorNew() const
A decomposition declaration.
auto flat_bindings() const
InitListExpr * getUpdater() const
Designator - A designator in a C99 designated initializer.
DoStmt - This represents a 'do/while' stmt.
Symbolic representation of a dynamic allocation.
static unsigned getMaxIndex()
const Expr * getBase() const
ChildElementIter< false > begin()
ExplicitCastExpr - An explicit cast written in the source code.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
This represents one expression.
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 EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExprUnevaluated - Return true if this expression might be usable in a constant exp...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_AllowUndefinedBehavior
Allow UB that we can give a value, but not arbitrary unmodeled side effects.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr) const
isCXX11ConstantExpr - Return true if this expression is a constant expression in C++11.
bool EvaluateCharRangeAsString(std::string &Result, const Expr *SizeExpression, const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const
llvm::APSInt EvaluateKnownConstIntCheckOverflow(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool EvaluateAsInitializer(const ASTContext &Ctx, const VarDecl *VD, EvalResult &Result, bool IsConstantInitializer) const
EvaluateAsInitializer - Evaluate an expression as if it were the initializer of the given declaration...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
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 EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
isCXX98IntegralConstantExpr - Return true if this expression is an integral constant expression in C+...
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...
void EvaluateForOverflow(const ASTContext &Ctx) const
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
bool isFPConstrained() const
LangOptions::FPExceptionModeKind getExceptionMode() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
const Expr * getSubExpr() const
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool hasCXXExplicitFunctionObjectParameter() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isUsableAsGlobalAllocationFunctionInConstantEvaluation(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions described in i...
bool isDefaulted() const
Whether this function is defaulted.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
Expr * getResultExpr()
Return the result expression of this controlling expression.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IfStmt - This represents an if/then/else.
bool isNonNegatedConsteval() const
VarDecl * getConditionVariable()
Retrieve the variable declared in this "if" statement, if any.
const Expr * getSubExpr() const
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
StrictFlexArraysLevelKind
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isCompatibleWith(ClangABI Version) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
bool isExpressibleAsConstantInitializer() const
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
Represents a parameter to a function.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
bool isExplicitObjectParameter() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
StringLiteral * getFunctionName()
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
void addVolatile()
Add the volatile type qualifier to this QualType.
bool isConstQualified() const
Determine whether this type is const-qualified.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool isWrapType() const
Returns true if it is a OverflowBehaviorType of Wrap kind.
Represents a struct/union/class.
unsigned getNumFields() const
Returns the number of fields (non-static data members) in this record.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
bool isSatisfied() const
Whether or not the requires clause is satisfied.
SourceLocation getLocation() const
std::string ComputeName(ASTContext &Context) const
Scope - A scope is a transient data structure that is used while parsing the program.
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
std::string printToString(const SourceManager &SM) const
CompoundStmt * getSubStmt()
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Expr * getReplacement() const
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "switch" statement, if any.
SwitchCase * getSwitchCaseList()
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
The base class of the type hierarchy.
bool isBooleanType() const
bool isFunctionReferenceType() const
bool isMFloat8Type() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isCountAttributedType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isExtVectorBoolType() const
bool isMemberDataPointerType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool isMemberPointerType() const
bool isAtomicType() const
bool isComplexIntegerType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * castAsCanonical() const
Return this type's canonical type cast to the specified type.
bool isAnyPointerType() const
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
bool hasPointerRepresentation() const
Whether this type is represented natively as a pointer.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
QualType getArgumentType() const
SourceLocation getBeginLoc() const LLVM_READONLY
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
static bool isIncrementOp(Opcode Op)
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
bool hasICEInitializer(const ASTContext &Context) const
Determine whether the initializer of this variable is an integer constant expression.
bool isInitCapture() const
Whether this variable is the implicit variable for a lambda init-capture.
const APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or nullptr if the value is not yet...
CharUnits getFlexibleArrayInitChars(const ASTContext &Ctx) const
If hasFlexibleArrayInit is true, compute the number of additional bytes necessary to store those elem...
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value might be usable in a constant expression, according to the re...
EvaluatedStmt * ensureEvaluatedStmt() const
Convert the initializer for this declaration to the elaborated EvaluatedStmt form,...
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
const APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Expr * getSizeExpr() const
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
VarDecl * getConditionVariable()
Retrieve the variable declared in this "while" statement, if any.
bool evaluateDestruction(State &Parent, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
Base class for stack frames, shared between VM and walker.
Interface for the VM to interact with the AST walker's context.
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static const FunctionDecl * getCallee(const CXXConstructExpr &D)
uint32_t Literal
Literals are represented as positive integers.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
bool Sub(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
llvm::FixedPointSemantics FixedPointSemantics
bool This(InterpState &S, CodePtr OpPC)
bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const Expr * findStructFieldAccess(const Expr *E, const Expr **OutArrayIndex=nullptr, QualType *OutArrayElementTy=nullptr)
Walk E through parens, implicit casts, unary &/*, array subscripts and comma operators to find the he...
bool hasSpecificAttr(const Container &container)
@ NonNull
Values of this type can never be null.
@ Success
Annotation was successful.
Expr::ConstantExprKind ConstantExprKind
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
CheckSubobjectKind
The order of this enum is important for diagnostics.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
@ AK_ReadObjectRepresentation
@ Off
Never emit colors regardless of the output stream.
@ Type
The name was classified as a type.
CastKind
CastKind - The kind of operation required for a conversion.
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ ArrayBound
Array bound in array declarator or new-expression.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
ActionResult< Stmt * > StmtResult
Diagnostic wrappers for TextAPI types for error reporting.
hash_code hash_value(const clang::dependencies::ModuleID &ID)
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
unsigned PathLength
The corresponding path length in the lvalue.
const CXXRecordDecl * Type
The dynamic class type of the object.
std::string ObjCEncodeStorage
Represents an element in a path from a derived class to a base class.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool isGlobalLValue() const
Return true if the evaluated lvalue expression is global.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
bool HasSideEffects
Whether the evaluated expression has side effects.
unsigned SuppressLambdaBody
Whether to suppress printing the body of a lambda.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
DenseMapInfo< APValue::LValueBase > Base
static unsigned getHashValue(const ObjectUnderConstruction &Object)
static bool isEqual(const ObjectUnderConstruction &LHS, const ObjectUnderConstruction &RHS)