46 #include "llvm/ADT/SmallString.h"
47 #include "llvm/Support/raw_ostream.h"
51 using namespace clang;
59 struct CallStackFrame;
72 dyn_cast<MaterializeTemporaryExpr>(Base)) {
75 const Expr *Temp = MTE->GetTemporaryExpr();
99 return dyn_cast<
FieldDecl>(getAsBaseOrMember(E).getPointer());
104 return dyn_cast<
CXXRecordDecl>(getAsBaseOrMember(E).getPointer());
109 return getAsBaseOrMember(E).getInt();
118 unsigned MostDerivedLength = 0;
120 for (
unsigned I = 0, N = Path.size(); I != N; ++I) {
125 ArraySize = CAT->
getSize().getZExtValue();
126 MostDerivedLength = I + 1;
127 }
else if (Type->isAnyComplexType()) {
131 MostDerivedLength = I + 1;
132 }
else if (
const FieldDecl *FD = getAsField(Path[I])) {
133 Type = FD->getType();
135 MostDerivedLength = I + 1;
141 return MostDerivedLength;
146 CSK_Base, CSK_Derived, CSK_Field, CSK_ArrayToPointer, CSK_ArrayIndex,
147 CSK_This, CSK_Real, CSK_Imag
151 struct SubobjectDesignator {
158 bool IsOnePastTheEnd : 1;
162 unsigned MostDerivedPathLength : 30;
166 uint64_t MostDerivedArraySize;
176 SubobjectDesignator() : Invalid(
true) {}
178 explicit SubobjectDesignator(
QualType T)
179 : Invalid(
false), IsOnePastTheEnd(
false), MostDerivedPathLength(0),
180 MostDerivedArraySize(0), MostDerivedType(T) {}
183 : Invalid(!V.isLValue() || !V.hasLValuePath()), IsOnePastTheEnd(
false),
184 MostDerivedPathLength(0), MostDerivedArraySize(0) {
188 Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
190 MostDerivedPathLength =
203 bool isOnePastTheEnd()
const {
207 if (MostDerivedArraySize &&
208 Entries[MostDerivedPathLength - 1].ArrayIndex == MostDerivedArraySize)
214 bool isValidSubobject()
const {
217 return !isOnePastTheEnd();
226 Entry.ArrayIndex = 0;
227 Entries.push_back(Entry);
231 MostDerivedArraySize = CAT->
getSize().getZExtValue();
232 MostDerivedPathLength = Entries.size();
236 void addDeclUnchecked(
const Decl *D,
bool Virtual =
false) {
239 Entry.BaseOrMember = Value.getOpaqueValue();
240 Entries.push_back(Entry);
243 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
244 MostDerivedType = FD->getType();
245 MostDerivedArraySize = 0;
246 MostDerivedPathLength = Entries.size();
250 void addComplexUnchecked(
QualType EltTy,
bool Imag) {
252 Entry.ArrayIndex = Imag;
253 Entries.push_back(Entry);
257 MostDerivedType = EltTy;
258 MostDerivedArraySize = 2;
259 MostDerivedPathLength = Entries.size();
261 void diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E, uint64_t N);
263 void adjustIndex(EvalInfo &Info,
const Expr *E, uint64_t N) {
265 if (MostDerivedPathLength == Entries.size() && MostDerivedArraySize) {
266 Entries.back().ArrayIndex += N;
267 if (Entries.back().ArrayIndex > MostDerivedArraySize) {
268 diagnosePointerArithmetic(Info, E, Entries.back().ArrayIndex);
276 if (IsOnePastTheEnd && N == (uint64_t)-1)
277 IsOnePastTheEnd =
false;
278 else if (!IsOnePastTheEnd && N == 1)
279 IsOnePastTheEnd =
true;
281 diagnosePointerArithmetic(Info, E, uint64_t(IsOnePastTheEnd) + N);
288 struct CallStackFrame {
292 CallStackFrame *Caller;
312 typedef std::map<const void*, APValue>
MapTy;
313 typedef MapTy::const_iterator temp_iterator;
322 APValue *getTemporary(
const void *Key) {
323 MapTy::iterator I = Temporaries.find(Key);
324 return I == Temporaries.end() ?
nullptr : &I->second;
326 APValue &createTemporary(
const void *Key,
bool IsLifetimeExtended);
330 class ThisOverrideRAII {
332 ThisOverrideRAII(CallStackFrame &Frame,
const LValue *NewThis,
bool Enable)
333 : Frame(Frame), OldThis(Frame.This) {
335 Frame.This = NewThis;
337 ~ThisOverrideRAII() {
338 Frame.This = OldThis;
341 CallStackFrame &Frame;
342 const LValue *OldThis;
347 class OptionalDiagnostic {
361 OptionalDiagnostic &
operator<<(
const APSInt &I) {
365 *
Diag << StringRef(Buffer.data(), Buffer.size());
370 OptionalDiagnostic &
operator<<(
const APFloat &F) {
379 llvm::APFloat::semanticsPrecision(F.getSemantics());
380 precision = (precision * 59 + 195) / 196;
382 F.toString(Buffer, precision);
383 *
Diag << StringRef(Buffer.data(), Buffer.size());
391 llvm::PointerIntPair<APValue*, 1, bool>
Value;
394 Cleanup(
APValue *Val,
bool IsLifetimeExtended)
395 : Value(Val, IsLifetimeExtended) {}
397 bool isLifetimeExtended()
const {
return Value.getInt(); }
399 *Value.getPointer() =
APValue();
424 CallStackFrame *CurrentCall;
427 unsigned CallStackDepth;
430 unsigned NextCallIndex;
439 CallStackFrame BottomFrame;
455 bool HasActiveDiagnostic;
457 enum EvaluationMode {
460 EM_ConstantExpression,
466 EM_PotentialConstantExpression,
475 EM_EvaluateForOverflow,
479 EM_IgnoreSideEffects,
486 EM_ConstantExpressionUnevaluated,
495 EM_PotentialConstantExpressionUnevaluated
500 bool checkingPotentialConstantExpression()
const {
501 return EvalMode == EM_PotentialConstantExpression ||
502 EvalMode == EM_PotentialConstantExpressionUnevaluated;
508 bool checkingForOverflow() {
return EvalMode == EM_EvaluateForOverflow; }
511 : Ctx(const_cast<
ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
512 CallStackDepth(0), NextCallIndex(1),
513 StepsLeft(getLangOpts().ConstexprStepLimit),
515 EvaluatingDecl((const
ValueDecl *)nullptr),
516 EvaluatingDeclValue(nullptr), HasActiveDiagnostic(
false),
520 EvaluatingDecl = Base;
521 EvaluatingDeclValue = &
Value;
529 if (checkingPotentialConstantExpression() && CallStackDepth > 1)
531 if (NextCallIndex == 0) {
533 Diag(Loc, diag::note_constexpr_call_limit_exceeded);
536 if (CallStackDepth <= getLangOpts().ConstexprCallDepth)
538 Diag(Loc, diag::note_constexpr_depth_limit_exceeded)
539 << getLangOpts().ConstexprCallDepth;
543 CallStackFrame *getCallFrame(
unsigned CallIndex) {
544 assert(CallIndex &&
"no call index in getCallFrame");
547 CallStackFrame *Frame = CurrentCall;
548 while (Frame->Index > CallIndex)
549 Frame = Frame->Caller;
550 return (Frame->Index == CallIndex) ? Frame :
nullptr;
553 bool nextStep(
const Stmt *
S) {
555 Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded);
566 EvalStatus.Diag->push_back(std::make_pair(Loc, PD));
567 return EvalStatus.Diag->back().second;
571 void addCallStack(
unsigned Limit);
576 = diag::note_invalid_subexpr_in_const_expr,
577 unsigned ExtraNotes = 0) {
578 if (EvalStatus.Diag) {
585 if (!EvalStatus.Diag->empty()) {
587 case EM_ConstantFold:
588 case EM_IgnoreSideEffects:
589 case EM_EvaluateForOverflow:
590 if (!EvalStatus.HasSideEffects)
594 case EM_ConstantExpression:
595 case EM_PotentialConstantExpression:
596 case EM_ConstantExpressionUnevaluated:
597 case EM_PotentialConstantExpressionUnevaluated:
598 HasActiveDiagnostic =
false;
599 return OptionalDiagnostic();
603 unsigned CallStackNotes = CallStackDepth - 1;
606 CallStackNotes = std::min(CallStackNotes, Limit + 1);
607 if (checkingPotentialConstantExpression())
610 HasActiveDiagnostic =
true;
611 EvalStatus.Diag->clear();
612 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
613 addDiag(Loc, DiagId);
614 if (!checkingPotentialConstantExpression())
616 return OptionalDiagnostic(&(*EvalStatus.Diag)[0].second);
618 HasActiveDiagnostic =
false;
619 return OptionalDiagnostic();
623 = diag::note_invalid_subexpr_in_const_expr,
624 unsigned ExtraNotes = 0) {
627 HasActiveDiagnostic =
false;
628 return OptionalDiagnostic();
636 template<
typename LocArg>
637 OptionalDiagnostic CCEDiag(LocArg Loc,
diag::kind DiagId
638 = diag::note_invalid_subexpr_in_const_expr,
639 unsigned ExtraNotes = 0) {
642 if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) {
643 HasActiveDiagnostic =
false;
644 return OptionalDiagnostic();
646 return Diag(Loc, DiagId, ExtraNotes);
651 if (!HasActiveDiagnostic)
652 return OptionalDiagnostic();
653 return OptionalDiagnostic(&addDiag(Loc, DiagId));
658 if (HasActiveDiagnostic) {
659 EvalStatus.Diag->insert(EvalStatus.Diag->end(),
660 Diags.begin(), Diags.end());
666 bool keepEvaluatingAfterSideEffect() {
668 case EM_PotentialConstantExpression:
669 case EM_PotentialConstantExpressionUnevaluated:
670 case EM_EvaluateForOverflow:
671 case EM_IgnoreSideEffects:
674 case EM_ConstantExpression:
675 case EM_ConstantExpressionUnevaluated:
676 case EM_ConstantFold:
679 llvm_unreachable(
"Missed EvalMode case");
684 bool noteSideEffect() {
685 EvalStatus.HasSideEffects =
true;
686 return keepEvaluatingAfterSideEffect();
691 bool keepEvaluatingAfterFailure() {
696 case EM_PotentialConstantExpression:
697 case EM_PotentialConstantExpressionUnevaluated:
698 case EM_EvaluateForOverflow:
701 case EM_ConstantExpression:
702 case EM_ConstantExpressionUnevaluated:
703 case EM_ConstantFold:
704 case EM_IgnoreSideEffects:
707 llvm_unreachable(
"Missed EvalMode case");
712 struct FoldConstant {
715 bool HadNoPriorDiags;
716 EvalInfo::EvaluationMode OldMode;
718 explicit FoldConstant(EvalInfo &Info,
bool Enabled)
721 HadNoPriorDiags(Info.EvalStatus.
Diag &&
722 Info.EvalStatus.
Diag->empty() &&
723 !Info.EvalStatus.HasSideEffects),
724 OldMode(Info.EvalMode) {
726 (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
727 Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
728 Info.EvalMode = EvalInfo::EM_ConstantFold;
730 void keepDiagnostics() { Enabled =
false; }
732 if (Enabled && HadNoPriorDiags && !Info.EvalStatus.Diag->empty() &&
733 !Info.EvalStatus.HasSideEffects)
734 Info.EvalStatus.Diag->clear();
735 Info.EvalMode = OldMode;
741 class SpeculativeEvaluationRAII {
746 SpeculativeEvaluationRAII(EvalInfo &Info,
748 : Info(Info), Old(Info.EvalStatus) {
749 Info.EvalStatus.Diag = NewDiag;
752 Info.EvalStatus.HasSideEffects =
true;
754 ~SpeculativeEvaluationRAII() {
755 Info.EvalStatus = Old;
761 template<
bool IsFullExpression>
764 unsigned OldStackSize;
766 ScopeRAII(EvalInfo &Info)
767 : Info(Info), OldStackSize(Info.CleanupStack.size()) {}
771 cleanup(Info, OldStackSize);
774 static void cleanup(EvalInfo &Info,
unsigned OldStackSize) {
775 unsigned NewEnd = OldStackSize;
776 for (
unsigned I = OldStackSize, N = Info.CleanupStack.size();
778 if (IsFullExpression && Info.CleanupStack[I].isLifetimeExtended()) {
781 std::swap(Info.CleanupStack[I], Info.CleanupStack[NewEnd]);
785 Info.CleanupStack[I].endLifetime();
788 Info.CleanupStack.erase(Info.CleanupStack.begin() + NewEnd,
789 Info.CleanupStack.end());
792 typedef ScopeRAII<false> BlockScopeRAII;
793 typedef ScopeRAII<true> FullExpressionRAII;
796 bool SubobjectDesignator::checkSubobject(EvalInfo &Info,
const Expr *E,
800 if (isOnePastTheEnd()) {
801 Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
809 void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
810 const Expr *E, uint64_t N) {
811 if (MostDerivedPathLength == Entries.size() && MostDerivedArraySize)
812 Info.CCEDiag(E, diag::note_constexpr_array_index)
813 <<
static_cast<int>(N) << 0
814 << static_cast<unsigned>(MostDerivedArraySize);
816 Info.CCEDiag(E, diag::note_constexpr_array_index)
817 <<
static_cast<int>(N) << 1;
821 CallStackFrame::CallStackFrame(EvalInfo &Info,
SourceLocation CallLoc,
824 : Info(Info), Caller(Info.CurrentCall), CallLoc(CallLoc), Callee(Callee),
825 Index(Info.NextCallIndex++), This(This), Arguments(Arguments) {
826 Info.CurrentCall =
this;
827 ++Info.CallStackDepth;
830 CallStackFrame::~CallStackFrame() {
831 assert(Info.CurrentCall ==
this &&
"calls retired out of order");
832 --Info.CallStackDepth;
833 Info.CurrentCall = Caller;
836 APValue &CallStackFrame::createTemporary(
const void *Key,
837 bool IsLifetimeExtended) {
839 assert(Result.
isUninit() &&
"temporary created multiple times");
840 Info.CleanupStack.push_back(Cleanup(&Result, IsLifetimeExtended));
844 static void describeCall(CallStackFrame *Frame, raw_ostream &Out);
846 void EvalInfo::addCallStack(
unsigned Limit) {
848 unsigned ActiveCalls = CallStackDepth - 1;
849 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
850 if (Limit && Limit < ActiveCalls) {
851 SkipStart = Limit / 2 + Limit % 2;
852 SkipEnd = ActiveCalls - Limit / 2;
856 unsigned CallIdx = 0;
857 for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
858 Frame = Frame->Caller, ++CallIdx) {
860 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
861 if (CallIdx == SkipStart) {
863 addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
870 llvm::raw_svector_ostream Out(Buffer);
872 addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
877 struct ComplexValue {
882 APSInt IntReal, IntImag;
883 APFloat FloatReal, FloatImag;
885 ComplexValue() : FloatReal(APFloat::Bogus), FloatImag(APFloat::Bogus) {}
887 void makeComplexFloat() { IsInt =
false; }
888 bool isComplexFloat()
const {
return !IsInt; }
889 APFloat &getComplexFloatReal() {
return FloatReal; }
890 APFloat &getComplexFloatImag() {
return FloatImag; }
892 void makeComplexInt() { IsInt =
true; }
893 bool isComplexInt()
const {
return IsInt; }
894 APSInt &getComplexIntReal() {
return IntReal; }
895 APSInt &getComplexIntImag() {
return IntImag; }
897 void moveInto(
APValue &v)
const {
898 if (isComplexFloat())
899 v =
APValue(FloatReal, FloatImag);
903 void setFrom(
const APValue &v) {
926 unsigned getLValueCallIndex()
const {
return CallIndex; }
927 SubobjectDesignator &getLValueDesignator() {
return Designator; }
928 const SubobjectDesignator &getLValueDesignator()
const {
return Designator;}
930 void moveInto(
APValue &V)
const {
947 Offset = CharUnits::Zero();
954 bool checkNullPointer(EvalInfo &Info,
const Expr *E,
959 Info.CCEDiag(E, diag::note_constexpr_null_subobject)
972 if (!Info.getLangOpts().CPlusPlus11)
974 return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
978 void addDecl(EvalInfo &Info,
const Expr *E,
979 const Decl *D,
bool Virtual =
false) {
980 if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
984 if (checkSubobject(Info, E, CSK_ArrayToPointer))
987 void addComplex(EvalInfo &Info,
const Expr *E,
QualType EltTy,
bool Imag) {
988 if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
991 void adjustIndex(EvalInfo &Info,
const Expr *E, uint64_t N) {
992 if (N && checkNullPointer(Info, E, CSK_ArrayIndex))
1000 DeclAndIsDerivedMember(Decl,
false), Path() {}
1005 return DeclAndIsDerivedMember.getPointer();
1008 bool isDerivedMember()
const {
1009 return DeclAndIsDerivedMember.getInt();
1013 return cast<CXXRecordDecl>(
1014 DeclAndIsDerivedMember.getPointer()->getDeclContext());
1017 void moveInto(
APValue &V)
const {
1018 V =
APValue(getDecl(), isDerivedMember(), Path);
1020 void setFrom(
const APValue &V) {
1026 Path.insert(Path.end(), P.begin(), P.end());
1032 llvm::PointerIntPair<const ValueDecl*, 1, bool> DeclAndIsDerivedMember;
1040 assert(!Path.empty());
1042 if (Path.size() >= 2)
1043 Expected = Path[Path.size() - 2];
1045 Expected = getContainingRecord();
1062 if (!isDerivedMember()) {
1063 Path.push_back(Derived);
1066 if (!castBack(Derived))
1069 DeclAndIsDerivedMember.setInt(
false);
1077 DeclAndIsDerivedMember.setInt(
true);
1078 if (isDerivedMember()) {
1079 Path.push_back(Base);
1082 return castBack(Base);
1087 static bool operator==(
const MemberPtr &LHS,
const MemberPtr &RHS) {
1088 if (!LHS.getDecl() || !RHS.getDecl())
1089 return !LHS.getDecl() && !RHS.getDecl();
1090 if (LHS.getDecl()->getCanonicalDecl() != RHS.getDecl()->getCanonicalDecl())
1092 return LHS.Path == RHS.Path;
1098 const LValue &This,
const Expr *E,
1099 bool AllowNonLiteralTypes =
false);
1118 unsigned ArgIndex = 0;
1119 bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
1120 !isa<CXXConstructorDecl>(Frame->Callee) &&
1121 cast<CXXMethodDecl>(Frame->Callee)->isInstance();
1124 Out << *Frame->Callee <<
'(';
1126 if (Frame->This && IsMemberCall) {
1128 Frame->This->moveInto(Val);
1130 Frame->This->Designator.MostDerivedType);
1132 Out <<
"->" << *Frame->Callee <<
'(';
1133 IsMemberCall =
false;
1137 E = Frame->Callee->param_end(); I != E; ++I, ++ArgIndex) {
1138 if (ArgIndex > (
unsigned)IsMemberCall)
1142 const APValue &Arg = Frame->Arguments[ArgIndex];
1145 if (ArgIndex == 0 && IsMemberCall)
1146 Out <<
"->" << *Frame->Callee <<
'(';
1159 return Info.noteSideEffect();
1166 return Value.isSigned() ? Value.getSExtValue()
1167 :
static_cast<int64_t
>(Value.getZExtValue());
1173 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
1174 Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
1183 if (!B)
return true;
1187 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
1188 return VD->hasGlobalStorage();
1190 return isa<FunctionDecl>(D);
1193 const Expr *E = B.get<
const Expr*>();
1194 switch (E->getStmtClass()) {
1197 case Expr::CompoundLiteralExprClass: {
1201 case Expr::MaterializeTemporaryExprClass:
1204 return cast<MaterializeTemporaryExpr>(E)->getStorageDuration() ==
SD_Static;
1206 case Expr::StringLiteralClass:
1207 case Expr::PredefinedExprClass:
1208 case Expr::ObjCStringLiteralClass:
1209 case Expr::ObjCEncodeExprClass:
1210 case Expr::CXXTypeidExprClass:
1211 case Expr::CXXUuidofExprClass:
1213 case Expr::CallExprClass:
1216 case Expr::AddrLabelExprClass:
1220 case Expr::BlockExprClass:
1221 return !cast<BlockExpr>(E)->getBlockDecl()->hasCaptures();
1222 case Expr::ImplicitValueInitExprClass:
1234 assert(Base &&
"no location for a null lvalue");
1237 Info.Note(VD->
getLocation(), diag::note_declared_at);
1240 diag::note_constexpr_temporary_here);
1247 QualType Type,
const LValue &LVal) {
1251 const SubobjectDesignator &
Designator = LVal.getLValueDesignator();
1257 if (Info.getLangOpts().CPlusPlus11) {
1259 Info.Diag(Loc, diag::note_constexpr_non_global, 1)
1260 << IsReferenceType << !Designator.Entries.empty()
1269 assert((Info.checkingPotentialConstantExpression() ||
1270 LVal.getLValueCallIndex() == 0) &&
1271 "have call index for global lvalue");
1274 if (
const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
1276 if (Var->getTLSKind())
1280 if (Var->hasAttr<DLLImportAttr>())
1283 if (
const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
1294 if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
1301 if (!IsReferenceType)
1312 if (!Designator.Invalid && Designator.isOnePastTheEnd()) {
1314 Info.Diag(Loc, diag::note_constexpr_past_end, 1)
1315 << !Designator.Entries.empty() << !!VD << VD;
1325 const LValue *This =
nullptr) {
1332 if (Info.getLangOpts().CPlusPlus14 && This &&
1333 Info.EvaluatingDecl == This->getLValueBase())
1337 if (Info.getLangOpts().CPlusPlus11)
1338 Info.Diag(E, diag::note_constexpr_nonliteral)
1341 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1351 Info.Diag(DiagLoc, diag::note_constexpr_uninitialized)
1359 Type = AT->getValueType();
1383 if (
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
1384 unsigned BaseIndex = 0;
1386 End = CD->bases_end(); I !=
End; ++I, ++BaseIndex) {
1392 for (
const auto *I : RD->
fields()) {
1401 LVal.setFrom(Info.Ctx, Value);
1410 return LVal.Base.dyn_cast<
const ValueDecl*>();
1414 if (Value.CallIndex)
1416 const Expr *E = Value.Base.dyn_cast<
const Expr*>();
1417 return E && !isa<MaterializeTemporaryExpr>(E);
1422 return Decl && Decl->
isWeak();
1427 if (Decl && isa<VarDecl>(Decl)) {
1448 return !Decl || !Decl->
isWeak();
1456 Result = Val.
getInt().getBoolValue();
1458 case APValue::Float:
1461 case APValue::ComplexInt:
1465 case APValue::ComplexFloat:
1469 case APValue::LValue:
1471 case APValue::MemberPointer:
1474 case APValue::Vector:
1475 case APValue::Array:
1476 case APValue::Struct:
1477 case APValue::Union:
1478 case APValue::AddrLabelDiff:
1482 llvm_unreachable(
"unknown APValue kind");
1487 assert(E->
isRValue() &&
"missing lvalue-to-rvalue conv in bool condition");
1494 template<
typename T>
1496 const T &SrcValue,
QualType DestType) {
1497 Info.CCEDiag(E, diag::note_constexpr_overflow)
1498 << SrcValue << DestType;
1502 QualType SrcType,
const APFloat &Value,
1503 QualType DestType, APSInt &Result) {
1504 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1508 Result = APSInt(DestWidth, !DestSigned);
1510 if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero, &ignored)
1511 & APFloat::opInvalidOp)
1519 APFloat Value = Result;
1521 if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),
1522 APFloat::rmNearestTiesToEven, &ignored)
1523 & APFloat::opOverflow)
1531 unsigned DestWidth = Info.Ctx.getIntWidth(DestType);
1532 APSInt Result =
Value;
1535 Result = Result.extOrTrunc(DestWidth);
1541 QualType SrcType,
const APSInt &Value,
1542 QualType DestType, APFloat &Result) {
1543 Result = APFloat(Info.Ctx.getFloatTypeSemantics(DestType), 1);
1544 if (Result.convertFromAPInt(Value, Value.isSigned(),
1545 APFloat::rmNearestTiesToEven)
1546 & APFloat::opOverflow)
1553 assert(FD->
isBitField() &&
"truncateBitfieldValue on non-bitfield");
1555 if (!Value.
isInt()) {
1559 assert(Value.
isLValue() &&
"integral value neither int nor lvalue?");
1564 APSInt &Int = Value.
getInt();
1565 unsigned OldBitWidth = Int.getBitWidth();
1567 if (NewBitWidth < OldBitWidth)
1568 Int = Int.trunc(NewBitWidth).extend(OldBitWidth);
1582 Res = SVal.
getFloat().bitcastToAPInt();
1587 unsigned VecSize = Info.Ctx.getTypeSize(VecTy);
1589 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
1590 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
1591 Res = llvm::APInt::getNullValue(VecSize);
1594 llvm::APInt EltAsInt;
1598 EltAsInt = Elt.
getFloat().bitcastToAPInt();
1602 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1605 unsigned BaseEltSize = EltAsInt.getBitWidth();
1607 Res |= EltAsInt.zextOrTrunc(VecSize).rotr(i*EltSize+BaseEltSize);
1609 Res |= EltAsInt.zextOrTrunc(VecSize).rotl(i*EltSize);
1615 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1622 template<
typename Operation>
1624 const APSInt &LHS,
const APSInt &RHS,
1625 unsigned BitWidth, Operation Op) {
1626 if (LHS.isUnsigned())
1627 return Op(LHS, RHS);
1629 APSInt
Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)),
false);
1630 APSInt Result = Value.trunc(LHS.getBitWidth());
1631 if (Result.extend(BitWidth) !=
Value) {
1632 if (Info.checkingForOverflow())
1633 Info.Ctx.getDiagnostics().Report(E->
getExprLoc(),
1634 diag::warn_integer_constant_overflow)
1635 << Result.toString(10) << E->
getType();
1652 std::multiplies<APSInt>());
1656 std::plus<APSInt>());
1660 std::minus<APSInt>());
1662 case BO_And: Result = LHS & RHS;
return true;
1663 case BO_Xor: Result = LHS ^ RHS;
return true;
1664 case BO_Or: Result = LHS | RHS;
return true;
1668 Info.Diag(E, diag::note_expr_divide_by_zero);
1672 if (RHS.isNegative() && RHS.isAllOnesValue() &&
1673 LHS.isSigned() && LHS.isMinSignedValue())
1675 Result = (Opcode ==
BO_Rem ? LHS % RHS : LHS / RHS);
1678 if (Info.getLangOpts().OpenCL)
1680 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
1681 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
1683 else if (RHS.isSigned() && RHS.isNegative()) {
1686 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
1693 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
1695 Info.CCEDiag(E, diag::note_constexpr_large_shift)
1696 << RHS << E->
getType() << LHS.getBitWidth();
1697 }
else if (LHS.isSigned()) {
1700 if (LHS.isNegative())
1701 Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
1702 else if (LHS.countLeadingZeros() < SA)
1703 Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
1709 if (Info.getLangOpts().OpenCL)
1711 RHS &= APSInt(llvm::APInt(RHS.getBitWidth(),
1712 static_cast<uint64_t
>(LHS.getBitWidth() - 1)),
1714 else if (RHS.isSigned() && RHS.isNegative()) {
1717 Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
1724 unsigned SA = (
unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
1726 Info.CCEDiag(E, diag::note_constexpr_large_shift)
1727 << RHS << E->
getType() << LHS.getBitWidth();
1732 case BO_LT: Result = LHS < RHS;
return true;
1733 case BO_GT: Result = LHS > RHS;
return true;
1734 case BO_LE: Result = LHS <= RHS;
return true;
1735 case BO_GE: Result = LHS >= RHS;
return true;
1736 case BO_EQ: Result = LHS == RHS;
return true;
1737 case BO_NE: Result = LHS != RHS;
return true;
1744 const APFloat &RHS) {
1750 LHS.multiply(RHS, APFloat::rmNearestTiesToEven);
1753 LHS.add(RHS, APFloat::rmNearestTiesToEven);
1756 LHS.subtract(RHS, APFloat::rmNearestTiesToEven);
1759 LHS.divide(RHS, APFloat::rmNearestTiesToEven);
1763 if (LHS.isInfinity() || LHS.isNaN())
1764 Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) << LHS.isNaN();
1772 unsigned TruncatedElements) {
1773 SubobjectDesignator &D = Result.Designator;
1776 if (TruncatedElements == D.Entries.size())
1778 assert(TruncatedElements >= D.MostDerivedPathLength &&
1779 "not casting to a derived class");
1780 if (!Result.checkSubobject(Info, E, CSK_Derived))
1785 for (
unsigned I = TruncatedElements, N = D.Entries.size(); I != N; ++I) {
1789 if (isVirtualBaseClass(D.Entries[I]))
1795 D.Entries.resize(TruncatedElements);
1805 RL = &Info.Ctx.getASTRecordLayout(Derived);
1808 Obj.getLValueOffset() += RL->getBaseClassOffset(Base);
1809 Obj.addDecl(Info, E, Base,
false);
1821 SubobjectDesignator &D = Obj.Designator;
1826 DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
1832 const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
1834 Obj.addDecl(Info, E, BaseDecl,
true);
1842 PathI != PathE; ++PathI) {
1846 Type = (*PathI)->getType();
1858 RL = &Info.Ctx.getASTRecordLayout(FD->
getParent());
1862 LVal.Offset += Info.Ctx.toCharUnitsFromBits(RL->getFieldOffset(I));
1863 LVal.addDecl(Info, E, FD);
1871 for (
const auto *
C : IFD->
chain())
1883 Size = CharUnits::One();
1894 Size = Info.Ctx.getTypeSizeInChars(Type);
1906 int64_t Adjustment) {
1912 LVal.Offset += Adjustment * SizeOfPointee;
1913 LVal.adjustIndex(Info, E, Adjustment);
1929 LVal.Offset += SizeOfComponent;
1931 LVal.addComplex(Info, E, EltTy, Imag);
1944 const VarDecl *VD, CallStackFrame *Frame,
1948 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD)) {
1951 if (Info.checkingPotentialConstantExpression())
1953 if (!Frame || !Frame->Arguments) {
1954 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1957 Result = &Frame->Arguments[PVD->getFunctionScopeIndex()];
1963 Result = Frame->getTemporary(VD);
1964 assert(Result &&
"missing value for local variable");
1973 if (!Info.checkingPotentialConstantExpression())
1974 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1980 if (Info.EvaluatingDecl.dyn_cast<
const ValueDecl*>() == VD) {
1981 Result = Info.EvaluatingDeclValue;
1988 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
1996 Info.Diag(E, diag::note_constexpr_var_init_non_constant,
1997 Notes.size() + 1) << VD;
1998 Info.Note(VD->
getLocation(), diag::note_declared_at);
1999 Info.addNotes(Notes);
2002 Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
2003 Notes.size() + 1) << VD;
2004 Info.Note(VD->
getLocation(), diag::note_declared_at);
2005 Info.addNotes(Notes);
2024 E = Derived->
bases_end(); I != E; ++I, ++Index) {
2025 if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == Base)
2029 llvm_unreachable(
"base class missing from derived class's bases list");
2036 if (
auto PE = dyn_cast<PredefinedExpr>(Lit))
2037 Lit = PE->getFunctionName();
2040 Info.Ctx.getAsConstantArrayType(S->
getType());
2041 assert(CAT &&
"string literal isn't an array");
2042 QualType CharType = CAT->getElementType();
2043 assert(CharType->
isIntegerType() &&
"unexpected character type");
2047 if (Index < S->getLength())
2057 Info.Ctx.getAsConstantArrayType(S->
getType());
2058 assert(CAT &&
"string literal isn't an array");
2059 QualType CharType = CAT->getElementType();
2060 assert(CharType->
isIntegerType() &&
"unexpected character type");
2062 unsigned Elts = CAT->getSize().getZExtValue();
2078 assert(Index < Size);
2082 unsigned NewElts = std::max(Index+1, OldElts * 2);
2083 NewElts = std::min(Size, std::max(NewElts, 8u));
2087 for (
unsigned I = 0; I != OldElts; ++I)
2089 for (
unsigned I = OldElts; I != NewElts; ++I)
2093 Array.
swap(NewValue);
2108 for (
auto *Field : RD->
fields())
2112 for (
auto &BaseSpec : RD->
bases())
2130 for (
auto *Field : RD->
fields()) {
2135 if (Field->isMutable() &&
2137 Info.Diag(E, diag::note_constexpr_ltor_mutable, 1) << Field;
2138 Info.Note(Field->getLocation(), diag::note_declared_at);
2146 for (
auto &BaseSpec : RD->
bases())
2172 : Value(Value), Type(Type) {
2173 assert(Value &&
"missing value for complete object");
2180 template<
typename Sub
objectHandler>
2181 typename SubobjectHandler::result_type
2183 const SubobjectDesignator &Sub, SubobjectHandler &handler) {
2186 return handler.failed();
2187 if (Sub.isOnePastTheEnd()) {
2188 if (Info.getLangOpts().CPlusPlus11)
2189 Info.Diag(E, diag::note_constexpr_access_past_end)
2190 << handler.AccessKind;
2193 return handler.failed();
2201 for (
unsigned I = 0, N = Sub.Entries.size(); ; ++I) {
2203 if (!Info.checkingPotentialConstantExpression())
2204 Info.Diag(E, diag::note_constexpr_access_uninit) << handler.AccessKind;
2205 return handler.failed();
2215 return handler.failed();
2217 if (!handler.found(*O, ObjType))
2221 if (handler.AccessKind !=
AK_Read &&
2229 LastField =
nullptr;
2233 assert(CAT &&
"vla in literal type?");
2234 uint64_t Index = Sub.Entries[I].ArrayIndex;
2235 if (CAT->
getSize().ule(Index)) {
2238 if (Info.getLangOpts().CPlusPlus11)
2239 Info.Diag(E, diag::note_constexpr_access_past_end)
2240 << handler.AccessKind;
2243 return handler.failed();
2251 assert(I == N - 1 &&
"extracting subobject of character?");
2253 if (handler.AccessKind !=
AK_Read)
2257 return handler.foundString(*O, ObjType, Index);
2262 else if (handler.AccessKind !=
AK_Read) {
2269 uint64_t Index = Sub.Entries[I].ArrayIndex;
2271 if (Info.getLangOpts().CPlusPlus11)
2272 Info.Diag(E, diag::note_constexpr_access_past_end)
2273 << handler.AccessKind;
2276 return handler.failed();
2281 if (WasConstQualified)
2284 assert(I == N - 1 &&
"extracting subobject of scalar?");
2293 }
else if (
const FieldDecl *Field = getAsField(Sub.Entries[I])) {
2294 if (Field->isMutable() && handler.AccessKind ==
AK_Read) {
2295 Info.Diag(E, diag::note_constexpr_ltor_mutable, 1)
2297 Info.Note(Field->getLocation(), diag::note_declared_at);
2298 return handler.failed();
2307 Info.Diag(E, diag::note_constexpr_access_inactive_union_member)
2308 << handler.AccessKind << Field << !UnionField << UnionField;
2309 return handler.failed();
2316 ObjType = Field->getType();
2317 if (WasConstQualified && !Field->isMutable())
2321 if (Info.getLangOpts().CPlusPlus) {
2323 Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1)
2324 << handler.AccessKind << 2 << Field;
2325 Info.Note(Field->getLocation(), diag::note_declared_at);
2327 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
2329 return handler.failed();
2340 ObjType = Info.Ctx.getRecordType(Base);
2341 if (WasConstQualified)
2348 struct ExtractSubobjectHandler {
2354 typedef bool result_type;
2355 bool failed() {
return false; }
2360 bool found(APSInt &Value,
QualType SubobjType) {
2364 bool found(APFloat &Value,
QualType SubobjType) {
2368 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2381 const SubobjectDesignator &Sub,
2383 ExtractSubobjectHandler Handler = { Info, Result };
2388 struct ModifySubobjectHandler {
2393 typedef bool result_type;
2399 Info.Diag(E, diag::note_constexpr_modify_const_type) << QT;
2405 bool failed() {
return false; }
2407 if (!checkConst(SubobjType))
2410 Subobj.
swap(NewVal);
2413 bool found(APSInt &Value,
QualType SubobjType) {
2414 if (!checkConst(SubobjType))
2416 if (!NewVal.isInt()) {
2421 Value = NewVal.getInt();
2424 bool found(APFloat &Value,
QualType SubobjType) {
2425 if (!checkConst(SubobjType))
2427 Value = NewVal.getFloat();
2430 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2431 llvm_unreachable(
"shouldn't encounter string elements with ExpandArrays");
2441 const SubobjectDesignator &Sub,
2443 ModifySubobjectHandler Handler = { Info, NewVal, E };
2450 const SubobjectDesignator &A,
2451 const SubobjectDesignator &B,
2452 bool &WasArrayIndex) {
2453 unsigned I = 0, N = std::min(A.Entries.size(), B.Entries.size());
2454 for (; I != N; ++I) {
2458 if (A.Entries[I].ArrayIndex != B.Entries[I].ArrayIndex) {
2459 WasArrayIndex =
true;
2467 if (A.Entries[I].BaseOrMember != B.Entries[I].BaseOrMember) {
2468 WasArrayIndex =
false;
2471 if (
const FieldDecl *FD = getAsField(A.Entries[I]))
2473 ObjType = FD->getType();
2479 WasArrayIndex =
false;
2486 const SubobjectDesignator &A,
2487 const SubobjectDesignator &B) {
2488 if (A.Entries.size() != B.Entries.size())
2491 bool IsArray = A.MostDerivedArraySize != 0;
2492 if (IsArray && A.MostDerivedPathLength != A.Entries.size())
2501 return CommonLength >= A.Entries.size() - IsArray;
2509 Info.Diag(E, diag::note_constexpr_access_null) << AK;
2513 CallStackFrame *Frame =
nullptr;
2514 if (LVal.CallIndex) {
2515 Frame = Info.getCallFrame(LVal.CallIndex);
2517 Info.Diag(E, diag::note_constexpr_lifetime_ended, 1)
2518 << AK << LVal.Base.is<
const ValueDecl*>();
2529 if (Info.getLangOpts().CPlusPlus)
2530 Info.Diag(E, diag::note_constexpr_access_volatile_type)
2539 QualType BaseType = getType(LVal.Base);
2561 if (Info.getLangOpts().CPlusPlus) {
2562 Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1)
2564 Info.Note(VD->getLocation(), diag::note_declared_at);
2574 if (Info.getLangOpts().CPlusPlus14 &&
2575 VD == Info.EvaluatingDecl.dyn_cast<
const ValueDecl *>()) {
2581 Info.Diag(E, diag::note_constexpr_modify_global);
2587 if (Info.getLangOpts().CPlusPlus) {
2588 Info.Diag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD;
2589 Info.Note(VD->
getLocation(), diag::note_declared_at);
2599 if (Info.getLangOpts().CPlusPlus11) {
2600 Info.CCEDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
2601 Info.Note(VD->
getLocation(), diag::note_declared_at);
2607 if (Info.getLangOpts().CPlusPlus11) {
2608 Info.Diag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
2609 Info.Note(VD->
getLocation(), diag::note_declared_at);
2620 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
2624 dyn_cast<MaterializeTemporaryExpr>(Base)) {
2625 assert(MTE->getStorageDuration() ==
SD_Static &&
2626 "should have a frame for a non-global materialized temporary");
2643 const ValueDecl *ED = MTE->getExtendingDecl();
2646 !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) {
2647 Info.Diag(E, diag::note_constexpr_access_static_temporary, 1) << AK;
2648 Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here);
2652 BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE,
false);
2653 assert(BaseVal &&
"got reference to unevaluated temporary");
2659 BaseVal = Frame->getTemporary(Base);
2660 assert(BaseVal &&
"missing value for temporary");
2665 if (Info.getLangOpts().CPlusPlus) {
2666 Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1)
2668 Info.Note(Base->
getExprLoc(), diag::note_constexpr_temporary_here);
2680 if (LVal.getLValueBase() == Info.EvaluatingDecl) {
2681 BaseType = Info.Ctx.getCanonicalType(BaseType);
2690 if (Frame && Info.getLangOpts().CPlusPlus14 &&
2691 (Info.EvalStatus.HasSideEffects || Info.keepEvaluatingAfterFailure()))
2710 const LValue &LVal,
APValue &RVal) {
2711 if (LVal.Designator.Invalid)
2715 const Expr *Base = LVal.Base.dyn_cast<
const Expr*>();
2716 if (!LVal.Designator.Invalid && Base && !LVal.CallIndex &&
2722 assert(!Info.getLangOpts().CPlusPlus &&
"lvalue compound literal in c++?");
2728 if (!
Evaluate(Lit, Info, CLE->getInitializer()))
2732 }
else if (isa<StringLiteral>(Base) || isa<PredefinedExpr>(Base)) {
2749 if (LVal.Designator.Invalid)
2752 if (!Info.getLangOpts().CPlusPlus14) {
2767 struct CompoundAssignSubobjectHandler {
2776 typedef bool result_type;
2781 Info.Diag(E, diag::note_constexpr_modify_const_type) << QT;
2787 bool failed() {
return false; }
2791 return found(Subobj.
getInt(), SubobjType);
2792 case APValue::Float:
2793 return found(Subobj.
getFloat(), SubobjType);
2794 case APValue::ComplexInt:
2795 case APValue::ComplexFloat:
2799 case APValue::LValue:
2800 return foundPointer(Subobj, SubobjType);
2807 bool found(APSInt &Value,
QualType SubobjType) {
2808 if (!checkConst(SubobjType))
2825 bool found(APFloat &Value,
QualType SubobjType) {
2826 return checkConst(SubobjType) &&
2833 if (!checkConst(SubobjType))
2840 if (PointeeType.
isNull() || !RHS.isInt() ||
2851 LVal.setFrom(Info.Ctx, Subobj);
2854 LVal.moveInto(Subobj);
2857 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
2858 llvm_unreachable(
"shouldn't encounter string elements here");
2867 EvalInfo &Info,
const Expr *E,
2870 if (LVal.Designator.Invalid)
2873 if (!Info.getLangOpts().CPlusPlus14) {
2879 CompoundAssignSubobjectHandler Handler = { Info, E, PromotedLValType, Opcode,
2881 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
2885 struct IncDecSubobjectHandler {
2891 typedef bool result_type;
2896 Info.Diag(E, diag::note_constexpr_modify_const_type) << QT;
2902 bool failed() {
return false; }
2913 return found(Subobj.
getInt(), SubobjType);
2914 case APValue::Float:
2915 return found(Subobj.
getFloat(), SubobjType);
2916 case APValue::ComplexInt:
2920 case APValue::ComplexFloat:
2924 case APValue::LValue:
2925 return foundPointer(Subobj, SubobjType);
2932 bool found(APSInt &Value,
QualType SubobjType) {
2933 if (!checkConst(SubobjType))
2943 if (Old) *Old =
APValue(Value);
2955 bool WasNegative = Value.isNegative();
2959 if (!WasNegative && Value.isNegative() &&
2961 APSInt ActualValue(Value,
true);
2967 if (WasNegative && !Value.isNegative() &&
2969 unsigned BitWidth = Value.getBitWidth();
2970 APSInt ActualValue(Value.sext(BitWidth + 1),
false);
2971 ActualValue.setBit(BitWidth);
2977 bool found(APFloat &Value,
QualType SubobjType) {
2978 if (!checkConst(SubobjType))
2981 if (Old) *Old =
APValue(Value);
2983 APFloat One(Value.getSemantics(), 1);
2985 Value.add(One, APFloat::rmNearestTiesToEven);
2987 Value.subtract(One, APFloat::rmNearestTiesToEven);
2991 if (!checkConst(SubobjType))
3003 LVal.setFrom(Info.Ctx, Subobj);
3007 LVal.moveInto(Subobj);
3010 bool foundString(
APValue &Subobj,
QualType SubobjType, uint64_t Character) {
3011 llvm_unreachable(
"shouldn't encounter string elements here");
3019 if (LVal.Designator.Invalid)
3022 if (!Info.getLangOpts().CPlusPlus14) {
3029 IncDecSubobjectHandler Handler = { Info, E, AK, Old };
3030 return Obj &&
findSubobject(Info, E, Obj, LVal.Designator, Handler);
3045 Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->
getType();
3064 bool IncludeMember =
true) {
3071 if (!MemPtr.getDecl()) {
3077 if (MemPtr.isDerivedMember()) {
3081 if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
3082 LV.Designator.Entries.size()) {
3086 unsigned PathLengthToMember =
3087 LV.Designator.Entries.size() - MemPtr.Path.size();
3088 for (
unsigned I = 0, N = MemPtr.Path.size(); I != N; ++I) {
3090 LV.Designator.Entries[PathLengthToMember + I]);
3100 PathLengthToMember))
3102 }
else if (!MemPtr.Path.empty()) {
3104 LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
3105 MemPtr.Path.size() + IncludeMember);
3111 assert(RD &&
"member pointer access on non-class-type expression");
3113 for (
unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
3121 MemPtr.getContainingRecord()))
3126 if (IncludeMember) {
3127 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
3131 dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
3135 llvm_unreachable(
"can't construct reference to bound member function");
3139 return MemPtr.getDecl();
3145 bool IncludeMember =
true) {
3149 if (Info.keepEvaluatingAfterFailure()) {
3157 BO->
getRHS(), IncludeMember);
3164 SubobjectDesignator &D = Result.Designator;
3165 if (D.Invalid || !Result.checkNullPointer(Info, E, CSK_Derived))
3173 if (D.MostDerivedPathLength + E->
path_size() > D.Entries.size()) {
3174 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3175 << D.MostDerivedType << TargetQT;
3181 unsigned NewEntriesSize = D.Entries.size() - E->
path_size();
3184 if (NewEntriesSize == D.MostDerivedPathLength)
3185 FinalType = D.MostDerivedType->getAsCXXRecordDecl();
3187 FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
3189 Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
3190 << D.MostDerivedType << TargetQT;
3216 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
3218 if (!VD->hasLocalStorage())
3222 Result.set(VD, Info.CurrentCall->Index);
3223 APValue &Val = Info.CurrentCall->createTemporary(VD,
true);
3225 const Expr *InitE = VD->getInit();
3227 Info.Diag(D->
getLocStart(), diag::note_constexpr_uninitialized)
3228 <<
false << VD->getType();
3249 const Expr *Cond,
bool &Result) {
3250 FullExpressionRAII
Scope(Info);
3264 BlockScopeRAII
Scope(Info);
3267 return ESR_Succeeded;
3270 return ESR_Continue;
3273 case ESR_CaseNotFound:
3276 llvm_unreachable(
"Invalid EvalStmtResult!");
3282 BlockScopeRAII
Scope(Info);
3287 FullExpressionRAII Scope(Info);
3300 if (isa<DefaultStmt>(SC)) {
3305 const CaseStmt *CS = cast<CaseStmt>(SC);
3309 if (LHS <= Value && Value <= RHS) {
3316 return ESR_Succeeded;
3321 return ESR_Succeeded;
3327 case ESR_CaseNotFound:
3330 Info.Diag(Found->
getLocStart(), diag::note_constexpr_stmt_expr_unsupported);
3333 llvm_unreachable(
"Invalid EvalStmtResult!");
3339 if (!Info.nextStep(S))
3349 switch (S->getStmtClass()) {
3350 case Stmt::CompoundStmtClass:
3354 case Stmt::LabelStmtClass:
3355 case Stmt::AttributedStmtClass:
3356 case Stmt::DoStmtClass:
3359 case Stmt::CaseStmtClass:
3360 case Stmt::DefaultStmtClass:
3365 case Stmt::IfStmtClass: {
3368 const IfStmt *IS = cast<IfStmt>(
S);
3372 BlockScopeRAII
Scope(Info);
3375 if (ESR != ESR_CaseNotFound || !IS->
getElse())
3380 case Stmt::WhileStmtClass: {
3383 if (ESR != ESR_Continue)
3388 case Stmt::ForStmtClass: {
3389 const ForStmt *FS = cast<ForStmt>(
S);
3392 if (ESR != ESR_Continue)
3395 FullExpressionRAII IncScope(Info);
3402 case Stmt::DeclStmtClass:
3406 return ESR_CaseNotFound;
3410 switch (S->getStmtClass()) {
3412 if (
const Expr *E = dyn_cast<Expr>(S)) {
3415 FullExpressionRAII
Scope(Info);
3418 return ESR_Succeeded;
3421 Info.Diag(S->getLocStart());
3424 case Stmt::NullStmtClass:
3425 return ESR_Succeeded;
3427 case Stmt::DeclStmtClass: {
3429 for (
const auto *DclIt : DS->
decls()) {
3433 FullExpressionRAII
Scope(Info);
3434 if (!
EvaluateDecl(Info, DclIt) && !Info.keepEvaluatingAfterFailure())
3437 return ESR_Succeeded;
3440 case Stmt::ReturnStmtClass: {
3441 const Expr *RetExpr = cast<ReturnStmt>(
S)->getRetValue();
3442 FullExpressionRAII
Scope(Info);
3443 if (RetExpr && !
Evaluate(Result, Info, RetExpr))
3445 return ESR_Returned;
3448 case Stmt::CompoundStmtClass: {
3449 BlockScopeRAII
Scope(Info);
3452 for (
const auto *BI : CS->
body()) {
3454 if (ESR == ESR_Succeeded)
3456 else if (ESR != ESR_CaseNotFound)
3459 return Case ? ESR_CaseNotFound : ESR_Succeeded;
3462 case Stmt::IfStmtClass: {
3463 const IfStmt *IS = cast<IfStmt>(
S);
3466 BlockScopeRAII
Scope(Info);
3473 if (ESR != ESR_Succeeded)
3476 return ESR_Succeeded;
3479 case Stmt::WhileStmtClass: {
3482 BlockScopeRAII
Scope(Info);
3491 if (ESR != ESR_Continue)
3494 return ESR_Succeeded;
3497 case Stmt::DoStmtClass: {
3498 const DoStmt *DS = cast<DoStmt>(
S);
3502 if (ESR != ESR_Continue)
3506 FullExpressionRAII CondScope(Info);
3510 return ESR_Succeeded;
3513 case Stmt::ForStmtClass: {
3514 const ForStmt *FS = cast<ForStmt>(
S);
3515 BlockScopeRAII
Scope(Info);
3518 if (ESR != ESR_Succeeded)
3522 BlockScopeRAII Scope(Info);
3523 bool Continue =
true;
3531 if (ESR != ESR_Continue)
3535 FullExpressionRAII IncScope(Info);
3540 return ESR_Succeeded;
3543 case Stmt::CXXForRangeStmtClass: {
3545 BlockScopeRAII
Scope(Info);
3549 if (ESR != ESR_Succeeded)
3554 if (ESR != ESR_Succeeded)
3560 bool Continue =
true;
3561 FullExpressionRAII CondExpr(Info);
3569 BlockScopeRAII InnerScope(Info);
3571 if (ESR != ESR_Succeeded)
3576 if (ESR != ESR_Continue)
3584 return ESR_Succeeded;
3587 case Stmt::SwitchStmtClass:
3590 case Stmt::ContinueStmtClass:
3591 return ESR_Continue;
3593 case Stmt::BreakStmtClass:
3596 case Stmt::LabelStmtClass:
3597 return EvaluateStmt(Result, Info, cast<LabelStmt>(S)->getSubStmt(), Case);
3599 case Stmt::AttributedStmtClass:
3602 return EvaluateStmt(Result, Info, cast<AttributedStmt>(S)->getSubStmt(),
3605 case Stmt::CaseStmtClass:
3606 case Stmt::DefaultStmtClass:
3607 return EvaluateStmt(Result, Info, cast<SwitchCase>(S)->getSubStmt(), Case);
3617 bool IsValueInitialization) {
3624 if (!CD->
isConstexpr() && !IsValueInitialization) {
3625 if (Info.getLangOpts().CPlusPlus11) {
3628 Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
3630 Info.Note(CD->
getLocation(), diag::note_declared_at);
3632 Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
3645 if (Info.checkingPotentialConstantExpression() && !Definition &&
3658 if (Info.getLangOpts().CPlusPlus11) {
3659 const FunctionDecl *DiagDecl = Definition ? Definition : Declaration;
3662 Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1)
3663 << DiagDecl->
isConstexpr() << isa<CXXConstructorDecl>(DiagDecl)
3665 Info.Note(DiagDecl->
getLocation(), diag::note_declared_at);
3667 Info.Diag(CallLoc, diag::note_invalid_subexpr_in_const_expr);
3677 for (
auto *FD : RD->
fields()) {
3678 if (FD->isUnnamedBitfield())
3682 for (
auto &Base : RD->
bases())
3683 if (
hasFields(Base.getType()->getAsCXXRecordDecl()))
3695 bool Success =
true;
3698 if (!
Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
3701 if (!Info.keepEvaluatingAfterFailure())
3713 EvalInfo &Info,
APValue &Result) {
3714 ArgVector ArgValues(Args.size());
3718 if (!Info.CheckCallLimit(CallLoc))
3721 CallStackFrame Frame(Info, CallLoc, Callee, This, ArgValues.data());
3730 if (MD && MD->isDefaulted() &&
3731 (MD->getParent()->isUnion() ||
3732 (MD->isTrivial() &&
hasFields(MD->getParent())))) {
3734 (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()));
3736 RHS.setFrom(Info.Ctx, ArgValues[0]);
3744 This->moveInto(Result);
3749 if (ESR == ESR_Succeeded) {
3752 Info.Diag(Callee->
getLocEnd(), diag::note_constexpr_no_return);
3754 return ESR == ESR_Returned;
3761 EvalInfo &Info,
APValue &Result) {
3762 ArgVector ArgValues(Args.size());
3766 if (!Info.CheckCallLimit(CallLoc))
3771 Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD;
3775 CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues.data());
3781 FullExpressionRAII InitScope(Info);
3800 RHS.setFrom(Info.Ctx, ArgValues[0]);
3814 BlockScopeRAII LifetimeExtendedScope(Info);
3816 bool Success =
true;
3817 unsigned BasesSeen = 0;
3821 for (
const auto *I : Definition->
inits()) {
3822 LValue Subobject = This;
3827 if (I->isBaseInitializer()) {
3828 QualType BaseType(I->getBaseClass(), 0);
3832 assert(!BaseIt->
isVirtual() &&
"virtual base for literal type");
3833 assert(Info.Ctx.hasSameType(BaseIt->
getType(), BaseType) &&
3834 "base class initializers not in expected order");
3838 BaseType->getAsCXXRecordDecl(), &Layout))
3841 }
else if ((FD = I->getMember())) {
3853 for (
auto *
C : IFD->chain()) {
3854 FD = cast<FieldDecl>(
C);
3867 std::distance(CD->field_begin(), CD->field_end()));
3877 llvm_unreachable(
"unknown base initializer kind");
3880 FullExpressionRAII InitScope(Info);
3886 if (!Info.keepEvaluatingAfterFailure())
3901 template <
class Derived>
3902 class ExprEvaluatorBase
3905 bool DerivedSuccess(
const APValue &V,
const Expr *E) {
3906 return static_cast<Derived*
>(
this)->
Success(V, E);
3908 bool DerivedZeroInitialization(
const Expr *E) {
3909 return static_cast<Derived*
>(
this)->ZeroInitialization(E);
3915 template<
typename ConditionalOperator>
3917 assert(Info.checkingPotentialConstantExpression());
3922 SpeculativeEvaluationRAII Speculate(Info, &Diag);
3934 Error(E, diag::note_constexpr_conditional_never_const);
3938 template<
typename ConditionalOperator>
3942 if (Info.checkingPotentialConstantExpression())
3943 CheckPotentialConstantConditional(E);
3948 return StmtVisitorTy::Visit(EvalExpr);
3954 typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
3957 return Info.CCEDiag(E, D);
3960 bool ZeroInitialization(
const Expr *E) {
return Error(E); }
3963 ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
3965 EvalInfo &getEvalInfo() {
return Info; }
3974 return Error(E, diag::note_invalid_subexpr_in_const_expr);
3977 bool VisitStmt(
const Stmt *) {
3978 llvm_unreachable(
"Expression evaluator should not be called on stmts");
3980 bool VisitExpr(
const Expr *E) {
3985 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
3987 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
3989 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
3997 {
return StmtVisitorTy::Visit(E->
getExpr()); }
4002 return StmtVisitorTy::Visit(E->
getExpr());
4007 {
return StmtVisitorTy::Visit(E->
getSubExpr()); }
4010 CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
4011 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4014 CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
4015 return static_cast<Derived*
>(
this)->VisitCastExpr(E);
4024 VisitIgnoredValue(E->
getLHS());
4025 return StmtVisitorTy::Visit(E->
getRHS());
4035 return DerivedSuccess(Result, E);
4047 return HandleConditionalOperator(E);
4051 bool IsBcpCall =
false;
4058 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
4063 if (Info.checkingPotentialConstantExpression() && IsBcpCall)
4066 FoldConstant Fold(Info, IsBcpCall);
4067 if (!HandleConditionalOperator(E)) {
4068 Fold.keepDiagnostics();
4076 if (
APValue *Value = Info.CurrentCall->getTemporary(E))
4077 return DerivedSuccess(*Value, E);
4083 assert(0 &&
"OpaqueValueExpr recursively refers to itself");
4086 return StmtVisitorTy::Visit(Source);
4089 bool VisitCallExpr(
const CallExpr *E) {
4094 LValue *This =
nullptr, ThisVal;
4096 bool HasQualifier =
false;
4101 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
4105 Member = ME->getMemberDecl();
4107 HasQualifier = ME->hasQualifier();
4108 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(Callee)) {
4111 if (!Member)
return false;
4114 return Error(Callee);
4118 return Error(Callee);
4124 if (!Call.getLValueOffset().isZero())
4125 return Error(Callee);
4126 FD = dyn_cast_or_null<FunctionDecl>(
4127 Call.getLValueBase().dyn_cast<
const ValueDecl*>());
4129 return Error(Callee);
4144 Args = Args.slice(1);
4153 if (This && !This->checkSubobject(Info, E, CSK_This))
4158 if (This && !HasQualifier &&
4159 isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
4160 return Error(E, diag::note_constexpr_virtual_call);
4171 return DerivedSuccess(Result, E);
4179 return DerivedZeroInitialization(E);
4181 return StmtVisitorTy::Visit(E->
getInit(0));
4185 return DerivedZeroInitialization(E);
4188 return DerivedZeroInitialization(E);
4191 return DerivedZeroInitialization(E);
4196 assert(!E->
isArrow() &&
"missing call to bound member function?");
4205 if (!FD)
return Error(E);
4216 DerivedSuccess(Result, E);
4219 bool VisitCastExpr(
const CastExpr *E) {
4228 return DerivedSuccess(AtomicVal, E);
4233 return StmtVisitorTy::Visit(E->
getSubExpr());
4244 return DerivedSuccess(RVal, E);
4252 return VisitUnaryPostIncDec(UO);
4255 return VisitUnaryPostIncDec(UO);
4258 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4268 return DerivedSuccess(RVal, UO);
4271 bool VisitStmtExpr(
const StmtExpr *E) {
4274 if (Info.checkingForOverflow())
4277 BlockScopeRAII
Scope(Info);
4286 const Expr *FinalExpr = dyn_cast<
Expr>(*BI);
4288 Info.Diag((*BI)->getLocStart(),
4289 diag::note_constexpr_stmt_expr_unsupported);
4292 return this->
Visit(FinalExpr);
4297 if (ESR != ESR_Succeeded) {
4301 if (ESR != ESR_Failed)
4302 Info.Diag((*BI)->getLocStart(),
4303 diag::note_constexpr_stmt_expr_unsupported);
4308 llvm_unreachable(
"Return from function from the loop above.");
4312 void VisitIgnoredValue(
const Expr *E) {
4323 template<
class Derived>
4324 class LValueExprEvaluatorBase
4325 :
public ExprEvaluatorBase<Derived> {
4328 typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
4329 typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
4337 LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
4338 ExprEvaluatorBaseTy(Info), Result(Result) {}
4341 Result.setFrom(this->Info.Ctx, V);
4358 if (!this->Visit(E->
getBase()))
4374 return this->
Error(E);
4389 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
4397 bool VisitCastExpr(
const CastExpr *E) {
4400 return ExprEvaluatorBaseTy::VisitCastExpr(E);
4448 class LValueExprEvaluator
4449 :
public LValueExprEvaluatorBase<LValueExprEvaluator> {
4451 LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
4452 LValueExprEvaluatorBaseTy(Info, Result) {}
4454 bool VisitVarDecl(
const Expr *E,
const VarDecl *VD);
4471 return VisitUnaryPreIncDec(UO);
4474 return VisitUnaryPreIncDec(UO);
4479 bool VisitCastExpr(
const CastExpr *E) {
4482 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
4485 this->CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
4488 Result.Designator.setInvalid();
4507 return LValueExprEvaluator(Info, Result).Visit(E);
4510 bool LValueExprEvaluator::VisitDeclRefExpr(
const DeclRefExpr *E) {
4514 return VisitVarDecl(E, VD);
4518 bool LValueExprEvaluator::VisitVarDecl(
const Expr *E,
const VarDecl *VD) {
4519 CallStackFrame *Frame =
nullptr;
4521 Frame = Info.CurrentCall;
4525 Result.set(VD, Frame->Index);
4535 if (!Info.checkingPotentialConstantExpression())
4536 Info.Diag(E, diag::note_constexpr_use_uninit_reference);
4542 bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
4548 skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
4551 for (
unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
4560 Value = Info.Ctx.getMaterializedTemporaryValue(E,
true);
4564 Value = &Info.CurrentCall->
4566 Result.set(E, Info.CurrentCall->Index);
4580 for (
unsigned I = Adjustments.size(); I != 0; ) {
4582 switch (Adjustments[I].
Kind) {
4583 case SubobjectAdjustment::DerivedToBaseAdjustment:
4587 Type = Adjustments[I].DerivedToBase.BasePath->getType();
4590 case SubobjectAdjustment::FieldAdjustment:
4593 Type = Adjustments[I].Field->getType();
4596 case SubobjectAdjustment::MemberPointerAdjustment:
4598 Adjustments[I].Ptr.RHS))
4600 Type = Adjustments[I].Ptr.MPT->getPointeeType();
4610 assert(!Info.getLangOpts().CPlusPlus &&
"lvalue compound literal in c++?");
4616 bool LValueExprEvaluator::VisitCXXTypeidExpr(
const CXXTypeidExpr *E) {
4620 Info.Diag(E, diag::note_constexpr_typeid_polymorphic)
4626 bool LValueExprEvaluator::VisitCXXUuidofExpr(
const CXXUuidofExpr *E) {
4630 bool LValueExprEvaluator::VisitMemberExpr(
const MemberExpr *E) {
4633 VisitIgnoredValue(E->
getBase());
4634 return VisitVarDecl(E, VD);
4639 if (MD->isStatic()) {
4640 VisitIgnoredValue(E->
getBase());
4646 return LValueExprEvaluatorBaseTy::VisitMemberExpr(E);
4665 bool LValueExprEvaluator::VisitUnaryDeref(
const UnaryOperator *E) {
4669 bool LValueExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
4678 bool LValueExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
4680 "lvalue __imag__ on scalar?");
4687 bool LValueExprEvaluator::VisitUnaryPreIncDec(
const UnaryOperator *UO) {
4688 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4699 bool LValueExprEvaluator::VisitCompoundAssignOperator(
4701 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4707 if (!this->Visit(CAO->
getLHS())) {
4708 if (Info.keepEvaluatingAfterFailure())
4722 bool LValueExprEvaluator::VisitBinAssign(
const BinaryOperator *E) {
4723 if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure())
4728 if (!this->Visit(E->
getLHS())) {
4729 if (Info.keepEvaluatingAfterFailure())
4746 class PointerExprEvaluator
4747 :
public ExprEvaluatorBase<PointerExprEvaluator> {
4756 PointerExprEvaluator(EvalInfo &info, LValue &Result)
4757 : ExprEvaluatorBaseTy(info), Result(Result) {}
4760 Result.setFrom(Info.Ctx, V);
4763 bool ZeroInitialization(
const Expr *E) {
4768 bool VisitCastExpr(
const CastExpr* E);
4776 bool VisitCallExpr(
const CallExpr *E);
4777 bool VisitBlockExpr(
const BlockExpr *E) {
4784 if (Info.checkingPotentialConstantExpression())
4786 if (!Info.CurrentCall->This) {
4787 if (Info.getLangOpts().CPlusPlus11)
4788 Info.Diag(E, diag::note_constexpr_this) << E->
isImplicit();
4793 Result = *Info.CurrentCall->This;
4803 return PointerExprEvaluator(Info, Result).Visit(E);
4806 bool PointerExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
4809 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
4814 std::swap(PExp, IExp);
4817 if (!EvalPtrOK && !Info.keepEvaluatingAfterFailure())
4826 AdditionalOffset = -AdditionalOffset;
4833 bool PointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
4837 bool PointerExprEvaluator::VisitCastExpr(
const CastExpr* E) {
4849 if (!Visit(SubExpr))
4855 Result.Designator.setInvalid();
4857 CCEDiag(E, diag::note_constexpr_invalid_cast)
4860 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
4868 if (!Result.Base && Result.Offset.isZero())
4874 castAs<PointerType>()->getPointeeType(),
4880 if (!Result.Base && Result.Offset.isZero())
4886 return ZeroInitialization(E);
4889 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
4895 if (Value.
isInt()) {
4896 unsigned Size = Info.Ctx.getTypeSize(E->
getType());
4897 uint64_t N = Value.
getInt().extOrTrunc(Size).getZExtValue();
4898 Result.Base = (
Expr*)
nullptr;
4899 Result.Offset = CharUnits::fromQuantity(N);
4900 Result.CallIndex = 0;
4901 Result.Designator.setInvalid();
4905 Result.setFrom(Info.Ctx, Value);
4914 Result.set(SubExpr, Info.CurrentCall->Index);
4915 if (!
EvaluateInPlace(Info.CurrentCall->createTemporary(SubExpr,
false),
4916 Info, Result, SubExpr))
4921 = Info.Ctx.getAsConstantArrayType(SubExpr->
getType()))
4922 Result.addArray(Info, E, CAT);
4924 Result.Designator.setInvalid();
4931 return ExprEvaluatorBaseTy::VisitCastExpr(E);
4942 return Info.Ctx.toCharUnitsFromBits(
4943 Info.Ctx.getPreferredTypeAlign(T.
getTypePtr()));
4955 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
4956 return Info.Ctx.getDeclAlign(DRE->getDecl(),
4959 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E))
4960 return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
4966 bool PointerExprEvaluator::VisitCallExpr(
const CallExpr *E) {
4971 case Builtin::BI__builtin_addressof:
4973 case Builtin::BI__builtin_assume_aligned: {
4980 LValue OffsetResult(Result);
4992 OffsetResult.Offset += CharUnits::fromQuantity(AdditionalOffset);
4996 if (OffsetResult.Base) {
4999 OffsetResult.Base.dyn_cast<
const ValueDecl*>()) {
5000 BaseAlignment = Info.Ctx.getDeclAlign(VD);
5006 if (BaseAlignment < Align) {
5007 Result.Designator.setInvalid();
5011 diag::note_constexpr_baa_insufficient_alignment) << 0
5012 << (
int) BaseAlignment.getQuantity()
5019 if (OffsetResult.Offset.RoundUpToAlignment(Align) != OffsetResult.Offset) {
5020 Result.Designator.setInvalid();
5021 APSInt
Offset(64,
false);
5022 Offset = OffsetResult.Offset.getQuantity();
5024 if (OffsetResult.Base)
5026 diag::note_constexpr_baa_insufficient_alignment) << 1
5029 CCEDiag(E->getArg(0),
5030 diag::note_constexpr_baa_value_insufficient_alignment)
5039 return ExprEvaluatorBaseTy::VisitCallExpr(E);
5048 class MemberPointerExprEvaluator
5049 :
public ExprEvaluatorBase<MemberPointerExprEvaluator> {
5053 Result = MemberPtr(D);
5058 MemberPointerExprEvaluator(EvalInfo &Info, MemberPtr &Result)
5059 : ExprEvaluatorBaseTy(Info), Result(Result) {}
5065 bool ZeroInitialization(
const Expr *E) {
5069 bool VisitCastExpr(
const CastExpr *E);
5077 return MemberPointerExprEvaluator(Info, Result).Visit(E);
5080 bool MemberPointerExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5083 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5087 return ZeroInitialization(E);
5097 typedef std::reverse_iterator<CastExpr::path_const_iterator> ReverseIter;
5099 PathI != PathE; ++PathI) {
5100 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5101 const CXXRecordDecl *Derived = (*PathI)->getType()->getAsCXXRecordDecl();
5102 if (!Result.castToDerived(Derived))
5115 PathE = E->
path_end(); PathI != PathE; ++PathI) {
5116 assert(!(*PathI)->isVirtual() &&
"memptr cast through vbase");
5117 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
5118 if (!Result.castToBase(Base))
5125 bool MemberPointerExprEvaluator::VisitUnaryAddrOf(
const UnaryOperator *E) {
5136 class RecordExprEvaluator
5137 :
public ExprEvaluatorBase<RecordExprEvaluator> {
5142 RecordExprEvaluator(EvalInfo &info,
const LValue &This,
APValue &Result)
5143 : ExprEvaluatorBaseTy(info), This(This), Result(Result) {}
5149 bool ZeroInitialization(
const Expr *E);
5151 bool VisitCastExpr(
const CastExpr *E);
5167 const LValue &This,
APValue &Result) {
5168 assert(!RD->
isUnion() &&
"Expected non-union class type");
5179 End = CD->bases_end(); I !=
End; ++I, ++Index) {
5180 const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
5181 LValue Subobject = This;
5185 Result.getStructBase(Index)))
5190 for (
const auto *I : RD->
fields()) {
5192 if (I->getType()->isReferenceType())
5195 LValue Subobject = This;
5201 Result.getStructField(I->getFieldIndex()), Info, Subobject, &VIE))
5208 bool RecordExprEvaluator::ZeroInitialization(
const Expr *E) {
5220 LValue Subobject = This;
5228 if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
5229 Info.Diag(E, diag::note_constexpr_virtual_base) << RD;
5236 bool RecordExprEvaluator::VisitCastExpr(
const CastExpr *E) {
5239 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5253 APValue *Value = &DerivedObject;
5256 PathE = E->
path_end(); PathI != PathE; ++PathI) {
5257 assert(!(*PathI)->isVirtual() &&
"record rvalue with virtual base");
5258 const CXXRecordDecl *Base = (*PathI)->getType()->getAsCXXRecordDecl();
5268 bool RecordExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5287 LValue Subobject = This;
5292 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
5293 isa<CXXDefaultInitExpr>(InitExpr));
5298 assert((!isa<CXXRecordDecl>(RD) || !cast<CXXRecordDecl>(RD)->getNumBases()) &&
5299 "initializer list for class with base classes");
5302 unsigned ElementNo = 0;
5304 for (
const auto *Field : RD->
fields()) {
5310 LValue Subobject = This;
5317 Subobject, Field, &Layout))
5323 const Expr *Init = HaveInit ? E->
getInit(ElementNo++) : &VIE;
5326 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
5327 isa<CXXDefaultInitExpr>(Init));
5332 FieldVal, Field))) {
5333 if (!Info.keepEvaluatingAfterFailure())
5342 bool RecordExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
5360 return ZeroInitialization(E);
5372 = dyn_cast<MaterializeTemporaryExpr>(E->
getArg(0)))
5373 return Visit(ME->GetTemporaryExpr());
5375 if (ZeroInit && !ZeroInitialization(E))
5380 cast<CXXConstructorDecl>(Definition), Info,
5384 bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
5394 Array.addArray(Info, E, ArrayType);
5403 if (!Field->getType()->isPointerType() ||
5404 !Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
5415 if (Field->getType()->isPointerType() &&
5416 Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
5421 ArrayType->
getSize().getZExtValue()))
5424 }
else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType()))
5437 APValue &Result, EvalInfo &Info) {
5439 "can't evaluate expression as a record rvalue");
5440 return RecordExprEvaluator(Info, This, Result).Visit(E);
5451 class TemporaryExprEvaluator
5452 :
public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
5454 TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
5455 LValueExprEvaluatorBaseTy(Info, Result) {}
5458 bool VisitConstructExpr(
const Expr *E) {
5459 Result.set(E, Info.CurrentCall->Index);
5464 bool VisitCastExpr(
const CastExpr *E) {
5467 return LValueExprEvaluatorBaseTy::VisitCastExpr(E);
5474 return VisitConstructExpr(E);
5477 return VisitConstructExpr(E);
5479 bool VisitCallExpr(
const CallExpr *E) {
5480 return VisitConstructExpr(E);
5483 return VisitConstructExpr(E);
5491 return TemporaryExprEvaluator(Info, Result).Visit(E);
5499 class VectorExprEvaluator
5500 :
public ExprEvaluatorBase<VectorExprEvaluator> {
5504 VectorExprEvaluator(EvalInfo &info,
APValue &Result)
5505 : ExprEvaluatorBaseTy(info), Result(Result) {}
5510 Result =
APValue(V.data(), V.size());
5518 bool ZeroInitialization(
const Expr *E);
5522 bool VisitCastExpr(
const CastExpr* E);
5533 return VectorExprEvaluator(Info, Result).Visit(E);
5536 bool VectorExprEvaluator::VisitCastExpr(
const CastExpr* E) {
5562 return Success(Elts, E);
5566 llvm::APInt SValInt;
5571 unsigned EltSize = Info.Ctx.getTypeSize(EltTy);
5572 bool BigEndian = Info.Ctx.getTargetInfo().isBigEndian();
5575 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(EltTy);
5576 unsigned FloatEltSize = EltSize;
5577 if (&Sem == &APFloat::x87DoubleExtended)
5579 for (
unsigned i = 0; i < NElts; i++) {
5582 Elt = SValInt.rotl(i*EltSize+FloatEltSize).trunc(FloatEltSize);
5584 Elt = SValInt.rotr(i*EltSize).trunc(FloatEltSize);
5585 Elts.push_back(
APValue(APFloat(Sem, Elt)));
5588 for (
unsigned i = 0; i < NElts; i++) {
5591 Elt = SValInt.rotl(i*EltSize+EltSize).zextOrTrunc(EltSize);
5593 Elt = SValInt.rotr(i*EltSize).zextOrTrunc(EltSize);
5599 return Success(Elts, E);
5602 return ExprEvaluatorBaseTy::VisitCastExpr(E);
5607 VectorExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5619 unsigned CountInits = 0, CountElts = 0;
5620 while (CountElts < NumElements) {
5622 if (CountInits < NumInits
5628 for (
unsigned j = 0; j < vlen; j++)
5632 llvm::APSInt sInt(32);
5633 if (CountInits < NumInits) {
5637 sInt = Info.Ctx.MakeIntValue(0, EltTy);
5638 Elements.push_back(
APValue(sInt));
5641 llvm::APFloat f(0.0);
5642 if (CountInits < NumInits) {
5646 f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
5647 Elements.push_back(
APValue(f));
5652 return Success(Elements, E);
5656 VectorExprEvaluator::ZeroInitialization(
const Expr *E) {
5660 if (EltTy->isIntegerType())
5661 ZeroElement =
APValue(Info.Ctx.MakeIntValue(0, EltTy));
5664 APValue(APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy)));
5667 return Success(Elements, E);
5670 bool VectorExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
5672 return ZeroInitialization(E);
5680 class ArrayExprEvaluator
5681 :
public ExprEvaluatorBase<ArrayExprEvaluator> {
5686 ArrayExprEvaluator(EvalInfo &Info,
const LValue &This,
APValue &Result)
5687 : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
5691 "expected array or string literal");
5696 bool ZeroInitialization(
const Expr *E) {
5698 Info.Ctx.getAsConstantArrayType(E->
getType());
5703 CAT->
getSize().getZExtValue());
5704 if (!Result.hasArrayFiller())
return true;
5707 LValue Subobject = This;
5708 Subobject.addArray(Info, E, CAT);
5710 return EvaluateInPlace(Result.getArrayFiller(), Info, Subobject, &VIE);
5716 const LValue &Subobject,
5722 APValue &Result, EvalInfo &Info) {
5724 return ArrayExprEvaluator(Info, This, Result).Visit(E);
5727 bool ArrayExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
5740 return Success(Val, E);
5743 bool Success =
true;
5745 assert((!Result.isArray() || Result.getArrayInitializedElts() == 0) &&
5746 "zero-initialized array shouldn't have any initialized elts");
5748 if (Result.isArray() && Result.hasArrayFiller())
5752 unsigned NumElts = CAT->
getSize().getZExtValue();
5757 if (NumEltsToInit != NumElts && !isa<ImplicitValueInitExpr>(FillerExpr))
5758 NumEltsToInit = NumElts;
5765 for (
unsigned I = 0, E = Result.getArrayInitializedElts(); I != E; ++I)
5766 Result.getArrayInitializedElt(I) = Filler;
5767 if (Result.hasArrayFiller())
5771 LValue Subobject = This;
5772 Subobject.addArray(Info, E, CAT);
5773 for (
unsigned Index = 0; Index != NumEltsToInit; ++Index) {
5777 Info, Subobject, Init) ||
5780 if (!Info.keepEvaluatingAfterFailure())
5786 if (!Result.hasArrayFiller())
5791 assert(FillerExpr &&
"no array filler for incomplete init list");
5793 FillerExpr) && Success;
5796 bool ArrayExprEvaluator::VisitCXXConstructExpr(
const CXXConstructExpr *E) {
5797 return VisitCXXConstructExpr(E, This, &Result, E->
getType());
5801 const LValue &Subobject,
5804 bool HadZeroInit = !Value->
isUninit();
5807 unsigned N = CAT->
getSize().getZExtValue();
5817 for (
unsigned I = 0; I != N; ++I)
5821 LValue ArrayElt = Subobject;
5822 ArrayElt.addArray(Info, E, CAT);
5823 for (
unsigned I = 0; I != N; ++I)
5854 if (ZeroInit && !HadZeroInit) {
5862 cast<CXXConstructorDecl>(Definition),
5875 class IntExprEvaluator
5876 :
public ExprEvaluatorBase<IntExprEvaluator> {
5879 IntExprEvaluator(EvalInfo &info,
APValue &result)
5880 : ExprEvaluatorBaseTy(info), Result(result) {}
5882 bool Success(
const llvm::APSInt &SI,
const Expr *E,
APValue &Result) {
5884 "Invalid evaluation result.");
5886 "Invalid evaluation result.");
5887 assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
5888 "Invalid evaluation result.");
5892 bool Success(
const llvm::APSInt &SI,
const Expr *E) {
5893 return Success(SI, E, Result);
5896 bool Success(
const llvm::APInt &I,
const Expr *E,
APValue &Result) {
5898 "Invalid evaluation result.");
5899 assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->
getType()) &&
5900 "Invalid evaluation result.");
5902 Result.
getInt().setIsUnsigned(
5906 bool Success(
const llvm::APInt &I,
const Expr *E) {
5907 return Success(I, E, Result);
5910 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
5912 "Invalid evaluation result.");
5916 bool Success(uint64_t Value,
const Expr *E) {
5917 return Success(Value, E, Result);
5929 return Success(V.
getInt(), E);
5932 bool ZeroInitialization(
const Expr *E) {
return Success(0, E); }
5945 bool CheckReferencedDecl(
const Expr *E,
const Decl *D);
5947 if (CheckReferencedDecl(E, E->
getDecl()))
5950 return ExprEvaluatorBaseTy::VisitDeclRefExpr(E);
5954 VisitIgnoredValue(E->
getBase());
5958 return ExprEvaluatorBaseTy::VisitMemberExpr(E);
5961 bool VisitCallExpr(
const CallExpr *E);
5966 bool VisitCastExpr(
const CastExpr* E);
5979 return ZeroInitialization(E);
6002 bool TryEvaluateBuiltinObjectSize(
const CallExpr *E);
6018 return IntExprEvaluator(Info, Result).Visit(E);
6028 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
6038 bool IntExprEvaluator::CheckReferencedDecl(
const Expr* E,
const Decl* D) {
6042 bool SameSign = (ECD->getInitVal().isSigned()
6044 bool SameWidth = (ECD->getInitVal().getBitWidth()
6045 == Info.Ctx.getIntWidth(E->
getType()));
6046 if (SameSign && SameWidth)
6047 return Success(ECD->getInitVal(), E);
6051 llvm::APSInt Val = ECD->getInitVal();
6053 Val.setIsSigned(!ECD->getInitVal().isSigned());
6055 Val = Val.extOrTrunc(Info.Ctx.getIntWidth(E->
getType()));
6056 return Success(Val, E);
6067 enum gcc_type_class {
6069 void_type_class, integer_type_class, char_type_class,
6070 enumeral_type_class, boolean_type_class,
6071 pointer_type_class, reference_type_class, offset_type_class,
6072 real_type_class, complex_type_class,
6073 function_type_class, method_type_class,
6074 record_type_class, union_type_class,
6075 array_type_class, string_type_class,
6082 return no_type_class;
6086 return void_type_class;
6088 return enumeral_type_class;
6090 return boolean_type_class;
6092 return string_type_class;
6094 return integer_type_class;
6096 return pointer_type_class;
6098 return reference_type_class;
6100 return real_type_class;
6102 return complex_type_class;
6104 return function_type_class;
6106 return record_type_class;
6108 return union_type_class;
6110 return array_type_class;
6112 return union_type_class;
6114 llvm_unreachable(
"CallExpr::isBuiltinClassifyType(): unimplemented type");
6122 template<
typename LValue>
6124 const Expr *E = LV.getLValueBase().template dyn_cast<
const Expr*>();
6125 return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
6152 if (V.
getKind() == APValue::Int)
6161 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantFold);
6176 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
6178 }
else if (
const Expr *E = B.get<
const Expr*>()) {
6179 if (isa<CompoundLiteralExpr>(E))
6186 bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(
const CallExpr *E) {
6193 SpeculativeEvaluationRAII SpeculativeEval(Info);
6198 if (!Base.getLValueBase()) {
6202 llvm::APSInt TypeIntVaue;
6206 if (TypeIntVaue == 0 || TypeIntVaue == 1)
6207 return Success(-1, E);
6208 if (TypeIntVaue == 2 || TypeIntVaue == 3)
6209 return Success(0, E);
6213 QualType T = GetObjectType(Base.getLValueBase());
6221 CharUnits Size = Info.Ctx.getTypeSizeInChars(T);
6222 CharUnits Offset = Base.getLValueOffset();
6227 Size = CharUnits::Zero();
6228 return Success(Size, E);
6231 bool IntExprEvaluator::VisitCallExpr(
const CallExpr *E) {
6234 return ExprEvaluatorBaseTy::VisitCallExpr(E);
6236 case Builtin::BI__builtin_object_size: {
6237 if (TryEvaluateBuiltinObjectSize(E))
6245 return Success(-1ULL, E);
6246 return Success(0, E);
6251 switch (Info.EvalMode) {
6252 case EvalInfo::EM_ConstantExpression:
6253 case EvalInfo::EM_PotentialConstantExpression:
6254 case EvalInfo::EM_ConstantFold:
6255 case EvalInfo::EM_EvaluateForOverflow:
6256 case EvalInfo::EM_IgnoreSideEffects:
6258 case EvalInfo::EM_ConstantExpressionUnevaluated:
6259 case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
6260 return Success(-1ULL, E);
6264 case Builtin::BI__builtin_bswap16:
6265 case Builtin::BI__builtin_bswap32:
6266 case Builtin::BI__builtin_bswap64: {
6271 return Success(Val.byteSwap(), E);
6274 case Builtin::BI__builtin_classify_type:
6281 case Builtin::BI__builtin_clz:
6282 case Builtin::BI__builtin_clzl:
6283 case Builtin::BI__builtin_clzll:
6284 case Builtin::BI__builtin_clzs: {
6291 return Success(Val.countLeadingZeros(), E);
6294 case Builtin::BI__builtin_constant_p:
6297 case Builtin::BI__builtin_ctz:
6298 case Builtin::BI__builtin_ctzl:
6299 case Builtin::BI__builtin_ctzll:
6300 case Builtin::BI__builtin_ctzs: {
6307 return Success(Val.countTrailingZeros(), E);
6310 case Builtin::BI__builtin_eh_return_data_regno: {
6312 Operand = Info.Ctx.getTargetInfo().getEHDataRegisterNumber(Operand);
6313 return Success(Operand, E);
6316 case Builtin::BI__builtin_expect:
6317 return Visit(E->
getArg(0));
6319 case Builtin::BI__builtin_ffs:
6320 case Builtin::BI__builtin_ffsl:
6321 case Builtin::BI__builtin_ffsll: {
6326 unsigned N = Val.countTrailingZeros();
6327 return Success(N == Val.getBitWidth() ? 0 : N + 1, E);
6330 case Builtin::BI__builtin_fpclassify: {
6335 switch (Val.getCategory()) {
6336 case APFloat::fcNaN: Arg = 0;
break;
6337 case APFloat::fcInfinity: Arg = 1;
break;
6338 case APFloat::fcNormal: Arg = Val.isDenormal() ? 3 : 2;
break;
6339 case APFloat::fcZero: Arg = 4;
break;
6341 return Visit(E->
getArg(Arg));
6344 case Builtin::BI__builtin_isinf_sign: {
6347 Success(Val.isInfinity() ? (Val.isNegative() ? -1 : 1) : 0, E);
6350 case Builtin::BI__builtin_isinf: {
6353 Success(Val.isInfinity() ? 1 : 0, E);
6356 case Builtin::BI__builtin_isfinite: {
6359 Success(Val.isFinite() ? 1 : 0, E);
6362 case Builtin::BI__builtin_isnan: {
6365 Success(Val.isNaN() ? 1 : 0, E);
6368 case Builtin::BI__builtin_isnormal: {
6371 Success(Val.isNormal() ? 1 : 0, E);
6374 case Builtin::BI__builtin_parity:
6375 case Builtin::BI__builtin_parityl:
6376 case Builtin::BI__builtin_parityll: {
6381 return Success(Val.countPopulation() % 2, E);
6384 case Builtin::BI__builtin_popcount:
6385 case Builtin::BI__builtin_popcountl:
6386 case Builtin::BI__builtin_popcountll: {
6391 return Success(Val.countPopulation(), E);
6394 case Builtin::BIstrlen:
6396 if (Info.getLangOpts().CPlusPlus11)
6397 Info.CCEDiag(E, diag::note_constexpr_invalid_function)
6398 << 0 << 0 <<
"'strlen'";
6400 Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
6402 case Builtin::BI__builtin_strlen: {
6410 if (
const StringLiteral *S = dyn_cast_or_null<StringLiteral>(
6411 String.getLValueBase().dyn_cast<
const Expr *>())) {
6414 StringRef Str = S->getBytes();
6415 int64_t Off = String.Offset.getQuantity();
6416 if (Off >= 0 && (uint64_t)Off <= (uint64_t)Str.size() &&
6417 S->getCharByteWidth() == 1) {
6418 Str = Str.substr(Off);
6420 StringRef::size_type Pos = Str.find(0);
6421 if (Pos != StringRef::npos)
6422 Str = Str.substr(0, Pos);
6424 return Success(Str.size(), E);
6432 for (uint64_t Strlen = 0; ; ++Strlen) {
6438 return Success(Strlen, E);
6444 case Builtin::BI__atomic_always_lock_free:
6445 case Builtin::BI__atomic_is_lock_free:
6446 case Builtin::BI__c11_atomic_is_lock_free: {
6461 CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue());
6464 unsigned InlineWidthBits =
6465 Info.Ctx.getTargetInfo().getMaxAtomicInlineWidth();
6466 if (Size <= Info.Ctx.toCharUnitsFromBits(InlineWidthBits)) {
6467 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
6468 Size == CharUnits::One() ||
6470 Expr::NPC_NeverValueDependent))
6473 return Success(1, E);
6476 castAs<PointerType>()->getPointeeType();
6478 Info.Ctx.getTypeAlignInChars(PointeeType) >= Size) {
6480 return Success(1, E);
6485 return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
6486 Success(0, E) :
Error(E);
6492 if (!A.getLValueBase())
6493 return !B.getLValueBase();
6494 if (!B.getLValueBase())
6497 if (A.getLValueBase().getOpaqueValue() !=
6498 B.getLValueBase().getOpaqueValue()) {
6508 A.getLValueCallIndex() == B.getLValueCallIndex();
6517 if (!LV.getLValueBase())
6522 if (!LV.getLValueDesignator().Invalid &&
6523 !LV.getLValueDesignator().isOnePastTheEnd())
6529 return LV.getLValueOffset() == Size;
6539 class DataRecursiveIntBinOpEvaluator {
6544 EvalResult() : Failed(false) { }
6546 void swap(EvalResult &RHS) {
6548 Failed = RHS.Failed;
6555 EvalResult LHSResult;
6556 enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind }
Kind;
6558 Job() : StoredInfo(nullptr) {}
6559 void startSpeculativeEval(EvalInfo &Info) {
6560 OldEvalStatus = Info.EvalStatus;
6561 Info.EvalStatus.Diag =
nullptr;
6566 StoredInfo->EvalStatus = OldEvalStatus;
6570 EvalInfo *StoredInfo;
6576 IntExprEvaluator &IntEval;
6581 DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval,
APValue &Result)
6582 : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
6597 EvalResult PrevResult;
6598 while (!Queue.empty())
6599 process(PrevResult);
6601 if (PrevResult.Failed)
return false;
6603 FinalResult.swap(PrevResult.Val);
6608 bool Success(uint64_t Value,
const Expr *E,
APValue &Result) {
6609 return IntEval.Success(Value, E, Result);
6611 bool Success(
const APSInt &Value,
const Expr *E,
APValue &Result) {
6612 return IntEval.Success(Value, E, Result);
6615 return IntEval.Error(E);
6618 return IntEval.Error(E, D);
6622 return Info.CCEDiag(E, D);
6626 bool VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
6627 bool &SuppressRHSDiags);
6629 bool VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
6632 void EvaluateExpr(
const Expr *E, EvalResult &Result) {
6633 Result.Failed = !
Evaluate(Result.Val, Info, E);
6638 void process(EvalResult &Result);
6640 void enqueue(
const Expr *E) {
6642 Queue.resize(Queue.size()+1);
6644 Queue.back().Kind = Job::AnyExprKind;
6650 bool DataRecursiveIntBinOpEvaluator::
6651 VisitBinOpLHSOnly(EvalResult &LHSResult,
const BinaryOperator *E,
6652 bool &SuppressRHSDiags) {
6655 if (LHSResult.Failed)
6656 return Info.noteSideEffect();
6666 Success(LHSAsBool, E, LHSResult.Val);
6670 LHSResult.Failed =
true;
6674 if (!Info.noteSideEffect())
6680 SuppressRHSDiags =
true;
6689 if (LHSResult.Failed && !Info.keepEvaluatingAfterFailure())
6695 bool DataRecursiveIntBinOpEvaluator::
6696 VisitBinOp(
const EvalResult &LHSResult,
const EvalResult &RHSResult,
6699 if (RHSResult.Failed)
6701 Result = RHSResult.Val;
6706 bool lhsResult, rhsResult;
6713 return Success(lhsResult || rhsResult, E, Result);
6715 return Success(lhsResult && rhsResult, E, Result);
6722 return Success(rhsResult, E, Result);
6732 if (LHSResult.Failed || RHSResult.Failed)
6735 const APValue &LHSVal = LHSResult.Val;
6736 const APValue &RHSVal = RHSResult.Val;
6742 CharUnits::fromQuantity(RHSVal.
getInt().getZExtValue());
6755 CharUnits::fromQuantity(LHSVal.
getInt().getZExtValue());
6766 if (!LHSExpr || !RHSExpr)
6770 if (!LHSAddrExpr || !RHSAddrExpr)
6774 RHSAddrExpr->getLabel()->getDeclContext())
6776 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
6792 return Success(Value, E, Result);
6795 void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
6796 Job &job = Queue.back();
6799 case Job::AnyExprKind: {
6800 if (
const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
6801 if (shouldEnqueue(Bop)) {
6802 job.Kind = Job::BinOpKind;
6803 enqueue(Bop->getLHS());
6808 EvaluateExpr(job.E, Result);
6813 case Job::BinOpKind: {
6815 bool SuppressRHSDiags =
false;
6816 if (!VisitBinOpLHSOnly(Result, Bop, SuppressRHSDiags)) {
6820 if (SuppressRHSDiags)
6821 job.startSpeculativeEval(Info);
6822 job.LHSResult.swap(Result);
6823 job.Kind = Job::BinOpVisitedLHSKind;
6828 case Job::BinOpVisitedLHSKind: {
6832 Result.Failed = !VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
6838 llvm_unreachable(
"Invalid Job::Kind!");
6841 bool IntExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
6845 if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
6846 return DataRecursiveIntBinOpEvaluator(*
this, Result).Traverse(E);
6852 ComplexValue LHS, RHS;
6861 LHS.makeComplexFloat();
6862 LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics());
6867 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
6873 RHS.makeComplexFloat();
6874 RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics());
6878 if (LHS.isComplexFloat()) {
6879 APFloat::cmpResult CR_r =
6880 LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
6881 APFloat::cmpResult CR_i =
6882 LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
6885 return Success((CR_r == APFloat::cmpEqual &&
6886 CR_i == APFloat::cmpEqual), E);
6889 "Invalid complex comparison.");
6890 return Success(((CR_r == APFloat::cmpGreaterThan ||
6891 CR_r == APFloat::cmpLessThan ||
6892 CR_r == APFloat::cmpUnordered) ||
6893 (CR_i == APFloat::cmpGreaterThan ||
6894 CR_i == APFloat::cmpLessThan ||
6895 CR_i == APFloat::cmpUnordered)), E);
6899 return Success((LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
6900 LHS.getComplexIntImag() == RHS.getComplexIntImag()), E);
6903 "Invalid compex comparison.");
6904 return Success((LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
6905 LHS.getComplexIntImag() != RHS.getComplexIntImag()), E);
6912 APFloat RHS(0.0), LHS(0.0);
6915 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
6921 APFloat::cmpResult CR = LHS.compare(RHS);
6925 llvm_unreachable(
"Invalid binary operator!");
6927 return Success(CR == APFloat::cmpLessThan, E);
6929 return Success(CR == APFloat::cmpGreaterThan, E);
6931 return Success(CR == APFloat::cmpLessThan || CR == APFloat::cmpEqual, E);
6933 return Success(CR == APFloat::cmpGreaterThan || CR == APFloat::cmpEqual,
6936 return Success(CR == APFloat::cmpEqual, E);
6938 return Success(CR == APFloat::cmpGreaterThan
6939 || CR == APFloat::cmpLessThan
6940 || CR == APFloat::cmpUnordered, E);
6946 LValue LHSValue, RHSValue;
6949 if (!LHSOK && Info.keepEvaluatingAfterFailure())
6960 if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())
6962 const Expr *LHSExpr = LHSValue.Base.dyn_cast<
const Expr*>();
6963 const Expr *RHSExpr = RHSValue.Base.dyn_cast<
const Expr*>();
6964 if (!LHSExpr || !RHSExpr)
6968 if (!LHSAddrExpr || !RHSAddrExpr)
6972 RHSAddrExpr->getLabel()->getDeclContext())
6974 Result =
APValue(LHSAddrExpr, RHSAddrExpr);
6984 if ((!LHSValue.Base && !LHSValue.Offset.isZero()) ||
6985 (!RHSValue.Base && !RHSValue.Offset.isZero()))
6992 LHSValue.Base && RHSValue.Base)
7000 if ((LHSValue.Base && LHSValue.Offset.isZero() &&
7002 (RHSValue.Base && RHSValue.Offset.isZero() &&
7017 const CharUnits &LHSOffset = LHSValue.getLValueOffset();
7018 const CharUnits &RHSOffset = RHSValue.getLValueOffset();
7020 SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator();
7021 SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator();
7028 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
7030 LHSDesignator, RHSDesignator))
7031 CCEDiag(E, diag::note_constexpr_pointer_subtraction_not_same_array);
7043 if (ElementSize.
isZero()) {
7044 Info.Diag(E, diag::note_constexpr_pointer_subtraction_zero_size)
7058 llvm::APInt(65, (int64_t)LHSOffset.
getQuantity(),
true),
false);
7060 llvm::APInt(65, (int64_t)RHSOffset.
getQuantity(),
true),
false);
7062 llvm::APInt(65, (int64_t)ElementSize.
getQuantity(),
true),
false);
7063 APSInt TrueResult = (LHS - RHS) / ElemSize;
7064 APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E->
getType()));
7066 if (Result.extend(65) != TrueResult)
7068 return Success(Result, E);
7080 CCEDiag(E, diag::note_constexpr_void_comparison);
7090 if (!LHSDesignator.Invalid && !RHSDesignator.Invalid &&
7095 RHSDesignator, WasArrayIndex);
7102 if (!WasArrayIndex && Mismatch < LHSDesignator.Entries.size() &&
7103 Mismatch < RHSDesignator.Entries.size()) {
7104 const FieldDecl *LF = getAsField(LHSDesignator.Entries[Mismatch]);
7105 const FieldDecl *RF = getAsField(RHSDesignator.Entries[Mismatch]);
7107 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_classes);
7109 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
7110 << getAsBaseClass(LHSDesignator.Entries[Mismatch])
7113 CCEDiag(E, diag::note_constexpr_pointer_comparison_base_field)
7114 << getAsBaseClass(RHSDesignator.Entries[Mismatch])
7118 CCEDiag(E, diag::note_constexpr_pointer_comparison_differing_access)
7126 unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);
7129 assert(PtrSize <= 64 &&
"Unexpected pointer width");
7130 uint64_t Mask = ~0ULL >> (64 - PtrSize);
7138 QualType BaseTy = getType(LHSValue.Base);
7141 CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
7143 if (CompareLHS > OffsetLimit || CompareRHS > OffsetLimit)
7148 default: llvm_unreachable(
"missing comparison operator");
7149 case BO_LT:
return Success(CompareLHS < CompareRHS, E);
7150 case BO_GT:
return Success(CompareLHS > CompareRHS, E);
7151 case BO_LE:
return Success(CompareLHS <= CompareRHS, E);
7152 case BO_GE:
return Success(CompareLHS >= CompareRHS, E);
7153 case BO_EQ:
return Success(CompareLHS == CompareRHS, E);
7154 case BO_NE:
return Success(CompareLHS != CompareRHS, E);
7160 assert(E->
isEqualityOp() &&
"unexpected member pointer operation");
7163 MemberPtr LHSValue, RHSValue;
7166 if (!LHSOK && Info.keepEvaluatingAfterFailure())
7175 if (!LHSValue.getDecl() || !RHSValue.getDecl()) {
7176 bool Equal = !LHSValue.getDecl() && !RHSValue.getDecl();
7182 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LHSValue.getDecl()))
7183 if (MD->isVirtual())
7184 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
7185 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(RHSValue.getDecl()))
7186 if (MD->isVirtual())
7187 CCEDiag(E, diag::note_constexpr_compare_virtual_mem_ptr) << MD;
7193 bool Equal = LHSValue == RHSValue;
7199 assert(RHSTy->
isNullPtrType() &&
"missing pointer conversion");
7204 return Success(Opcode ==
BO_EQ || Opcode ==
BO_LE || Opcode ==
BO_GE, E);
7209 "DataRecursiveIntBinOpEvaluator should have handled integral types");
7211 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7216 bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
7237 return Success(n, E);
7239 return Success(1, E);
7252 return Success(Sizeof, E);
7257 Info.Ctx.toCharUnitsFromBits(
7263 llvm_unreachable(
"unknown expr/type trait");
7266 bool IntExprEvaluator::VisitOffsetOfExpr(
const OffsetOfExpr *OOE) {
7272 for (
unsigned i = 0; i != n; ++i) {
7275 case OffsetOfExpr::OffsetOfNode::Array: {
7280 const ArrayType *AT = Info.Ctx.getAsArrayType(CurrentType);
7284 CharUnits ElementSize = Info.Ctx.getTypeSizeInChars(CurrentType);
7285 Result += IdxResult.getSExtValue() * ElementSize;
7289 case OffsetOfExpr::OffsetOfNode::Field: {
7298 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
7304 case OffsetOfExpr::OffsetOfNode::Identifier:
7305 llvm_unreachable(
"dependent __builtin_offsetof");
7307 case OffsetOfExpr::OffsetOfNode::Base: {
7321 CurrentType = BaseSpec->
getType();
7332 return Success(Result, OOE);
7335 bool IntExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
7351 if (!Result.isInt())
return Error(E);
7352 const APSInt &Value = Result.getInt();
7353 if (Value.isSigned() && Value.isMinSignedValue())
7356 return Success(-Value, E);
7361 if (!Result.isInt())
return Error(E);
7362 return Success(~Result.getInt(), E);
7368 return Success(!bres, E);
7375 bool IntExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7414 llvm_unreachable(
"invalid cast kind for integral value");
7430 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7441 return Success(BoolResult, E);
7445 if (!Visit(SubExpr))
7448 if (!Result.isInt()) {
7454 if (Result.isAddrLabelDiff())
7455 return Info.Ctx.getTypeSize(DestType) <= Info.Ctx.getTypeSize(SrcType);
7457 return Info.Ctx.getTypeSize(DestType) == Info.Ctx.getTypeSize(SrcType);
7461 Result.getInt()), E);
7465 CCEDiag(E, diag::note_constexpr_invalid_cast) << 2;
7471 if (LV.getLValueBase()) {
7476 if (Info.Ctx.getTypeSize(DestType) != Info.Ctx.getTypeSize(SrcType))
7479 LV.Designator.setInvalid();
7480 LV.moveInto(Result);
7484 APSInt AsInt = Info.Ctx.MakeIntValue(LV.getLValueOffset().getQuantity(),
7493 return Success(C.getComplexIntReal(), E);
7504 return Success(Value, E);
7508 llvm_unreachable(
"unknown cast resulting in integral value");
7511 bool IntExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
7516 if (!LV.isComplexInt())
7518 return Success(LV.getComplexIntReal(), E);
7524 bool IntExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
7529 if (!LV.isComplexInt())
7531 return Success(LV.getComplexIntImag(), E);
7535 return Success(0, E);
7538 bool IntExprEvaluator::VisitSizeOfPackExpr(
const SizeOfPackExpr *E) {
7542 bool IntExprEvaluator::VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
7551 class FloatExprEvaluator
7552 :
public ExprEvaluatorBase<FloatExprEvaluator> {
7555 FloatExprEvaluator(EvalInfo &info, APFloat &result)
7556 : ExprEvaluatorBaseTy(info), Result(result) {}
7563 bool ZeroInitialization(
const Expr *E) {
7564 Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->
getType()));
7568 bool VisitCallExpr(
const CallExpr *E);
7573 bool VisitCastExpr(
const CastExpr *E);
7584 return FloatExprEvaluator(Info, Result).Visit(E);
7591 llvm::APFloat &Result) {
7593 if (!S)
return false;
7601 fill = llvm::APInt(32, 0);
7602 else if (S->
getString().getAsInteger(0, fill))
7607 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
7609 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
7617 Result = llvm::APFloat::getQNaN(Sem,
false, &fill);
7619 Result = llvm::APFloat::getSNaN(Sem,
false, &fill);
7625 bool FloatExprEvaluator::VisitCallExpr(
const CallExpr *E) {
7628 return ExprEvaluatorBaseTy::VisitCallExpr(E);
7630 case Builtin::BI__builtin_huge_val:
7631 case Builtin::BI__builtin_huge_valf:
7632 case Builtin::BI__builtin_huge_vall:
7633 case Builtin::BI__builtin_inf:
7634 case Builtin::BI__builtin_inff:
7635 case Builtin::BI__builtin_infl: {
7636 const llvm::fltSemantics &Sem =
7637 Info.Ctx.getFloatTypeSemantics(E->
getType());
7638 Result = llvm::APFloat::getInf(Sem);
7642 case Builtin::BI__builtin_nans:
7643 case Builtin::BI__builtin_nansf:
7644 case Builtin::BI__builtin_nansl:
7650 case Builtin::BI__builtin_nan:
7651 case Builtin::BI__builtin_nanf:
7652 case Builtin::BI__builtin_nanl:
7660 case Builtin::BI__builtin_fabs:
7661 case Builtin::BI__builtin_fabsf:
7662 case Builtin::BI__builtin_fabsl:
7666 if (Result.isNegative())
7667 Result.changeSign();
7674 case Builtin::BI__builtin_copysign:
7675 case Builtin::BI__builtin_copysignf:
7676 case Builtin::BI__builtin_copysignl: {
7681 Result.copySign(RHS);
7687 bool FloatExprEvaluator::VisitUnaryReal(
const UnaryOperator *E) {
7692 Result = CV.FloatReal;
7699 bool FloatExprEvaluator::VisitUnaryImag(
const UnaryOperator *E) {
7704 Result = CV.FloatImag;
7709 const llvm::fltSemantics &Sem = Info.Ctx.getFloatTypeSemantics(E->
getType());
7710 Result = llvm::APFloat::getZero(Sem);
7714 bool FloatExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
7716 default:
return Error(E);
7722 Result.changeSign();
7727 bool FloatExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
7729 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7733 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
7739 bool FloatExprEvaluator::VisitFloatingLiteral(
const FloatingLiteral *E) {
7744 bool FloatExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7749 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7759 if (!Visit(SubExpr))
7769 Result = V.getComplexFloatReal();
7780 class ComplexExprEvaluator
7781 :
public ExprEvaluatorBase<ComplexExprEvaluator> {
7782 ComplexValue &Result;
7785 ComplexExprEvaluator(EvalInfo &info, ComplexValue &Result)
7786 : ExprEvaluatorBaseTy(info), Result(Result) {}
7793 bool ZeroInitialization(
const Expr *E);
7800 bool VisitCastExpr(
const CastExpr *E);
7810 return ComplexExprEvaluator(Info, Result).Visit(E);
7813 bool ComplexExprEvaluator::ZeroInitialization(
const Expr *E) {
7816 Result.makeComplexFloat();
7817 APFloat Zero = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(ElemTy));
7818 Result.FloatReal = Zero;
7819 Result.FloatImag = Zero;
7821 Result.makeComplexInt();
7822 APSInt Zero = Info.Ctx.MakeIntValue(0, ElemTy);
7823 Result.IntReal = Zero;
7824 Result.IntImag = Zero;
7829 bool ComplexExprEvaluator::VisitImaginaryLiteral(
const ImaginaryLiteral *E) {
7833 Result.makeComplexFloat();
7834 APFloat &Imag = Result.FloatImag;
7838 Result.FloatReal = APFloat(Imag.getSemantics());
7842 "Unexpected imaginary literal.");
7844 Result.makeComplexInt();
7845 APSInt &Imag = Result.IntImag;
7849 Result.IntReal = APSInt(Imag.getBitWidth(), !Imag.isSigned());
7854 bool ComplexExprEvaluator::VisitCastExpr(
const CastExpr *E) {
7900 llvm_unreachable(
"invalid cast kind for complex value");
7905 return ExprEvaluatorBaseTy::VisitCastExpr(E);
7913 APFloat &Real = Result.FloatReal;
7917 Result.makeComplexFloat();
7918 Result.FloatImag = APFloat(Real.getSemantics());
7941 Result.makeComplexInt();
7943 To, Result.IntReal) &&
7945 To, Result.IntImag);
7949 APSInt &Real = Result.IntReal;
7953 Result.makeComplexInt();
7954 Result.IntImag = APSInt(Real.getBitWidth(), !Real.isSigned());
7978 Result.makeComplexFloat();
7980 To, Result.FloatReal) &&
7982 To, Result.FloatImag);
7986 llvm_unreachable(
"unknown cast resulting in complex value");
7989 bool ComplexExprEvaluator::VisitBinaryOperator(
const BinaryOperator *E) {
7991 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
7995 bool LHSReal =
false, RHSReal =
false;
8000 APFloat &Real = Result.FloatReal;
8003 Result.makeComplexFloat();
8004 Result.FloatImag = APFloat(Real.getSemantics());
8007 LHSOK = Visit(E->
getLHS());
8009 if (!LHSOK && !Info.keepEvaluatingAfterFailure())
8015 APFloat &Real = RHS.FloatReal;
8018 RHS.makeComplexFloat();
8019 RHS.FloatImag = APFloat(Real.getSemantics());
8023 assert(!(LHSReal && RHSReal) &&
8024 "Cannot have both operands of a complex operation be real.");
8026 default:
return Error(E);
8028 if (Result.isComplexFloat()) {
8029 Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
8030 APFloat::rmNearestTiesToEven);
8032 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
8034 Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
8035 APFloat::rmNearestTiesToEven);
8037 Result.getComplexIntReal() += RHS.getComplexIntReal();
8038 Result.getComplexIntImag() += RHS.getComplexIntImag();
8042 if (Result.isComplexFloat()) {
8043 Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
8044 APFloat::rmNearestTiesToEven);
8046 Result.getComplexFloatImag() = RHS.getComplexFloatImag();
8047 Result.getComplexFloatImag().changeSign();
8048 }
else if (!RHSReal) {
8049 Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
8050 APFloat::rmNearestTiesToEven);
8053 Result.getComplexIntReal() -= RHS.getComplexIntReal();
8054 Result.getComplexIntImag() -= RHS.getComplexIntImag();
8058 if (Result.isComplexFloat()) {
8063 ComplexValue LHS = Result;
8064 APFloat &A = LHS.getComplexFloatReal();
8065 APFloat &B = LHS.getComplexFloatImag();
8066 APFloat &C = RHS.getComplexFloatReal();
8067 APFloat &D = RHS.getComplexFloatImag();
8068 APFloat &ResR = Result.getComplexFloatReal();
8069 APFloat &ResI = Result.getComplexFloatImag();
8071 assert(!RHSReal &&
"Cannot have two real operands for a complex op!");
8074 }
else if (RHSReal) {
8086 if (ResR.isNaN() && ResI.isNaN()) {
8087 bool Recalc =
false;
8088 if (A.isInfinity() || B.isInfinity()) {
8089 A = APFloat::copySign(
8090 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
8091 B = APFloat::copySign(
8092 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
8094 C = APFloat::copySign(APFloat(C.getSemantics()), C);
8096 D = APFloat::copySign(APFloat(D.getSemantics()), D);
8099 if (C.isInfinity() || D.isInfinity()) {
8100 C = APFloat::copySign(
8101 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
8102 D = APFloat::copySign(
8103 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
8105 A = APFloat::copySign(APFloat(A.getSemantics()), A);
8107 B = APFloat::copySign(APFloat(B.getSemantics()), B);
8110 if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
8111 AD.isInfinity() || BC.isInfinity())) {
8113 A = APFloat::copySign(APFloat(A.getSemantics()), A);
8115 B = APFloat::copySign(APFloat(B.getSemantics()), B);
8117 C = APFloat::copySign(APFloat(C.getSemantics()), C);
8119 D = APFloat::copySign(APFloat(D.getSemantics()), D);
8123 ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
8124 ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
8129 ComplexValue LHS = Result;
8130 Result.getComplexIntReal() =
8131 (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
8132 LHS.getComplexIntImag() * RHS.getComplexIntImag());
8133 Result.getComplexIntImag() =
8134 (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
8135 LHS.getComplexIntImag() * RHS.getComplexIntReal());
8139 if (Result.isComplexFloat()) {
8144 ComplexValue LHS = Result;
8145 APFloat &A = LHS.getComplexFloatReal();
8146 APFloat &B = LHS.getComplexFloatImag();
8147 APFloat &C = RHS.getComplexFloatReal();
8148 APFloat &D = RHS.getComplexFloatImag();
8149 APFloat &ResR = Result.getComplexFloatReal();
8150 APFloat &ResI = Result.getComplexFloatImag();
8157 B = APFloat::getZero(A.getSemantics());
8160 APFloat MaxCD = maxnum(abs(C), abs(D));
8161 if (MaxCD.isFinite()) {
8162 DenomLogB =
ilogb(MaxCD);
8163 C =
scalbn(C, -DenomLogB);
8164 D =
scalbn(D, -DenomLogB);
8166 APFloat Denom = C * C + D * D;
8167 ResR =
scalbn((A * C + B * D) / Denom, -DenomLogB);
8168 ResI =
scalbn((B * C - A * D) / Denom, -DenomLogB);
8169 if (ResR.isNaN() && ResI.isNaN()) {
8170 if (Denom.isPosZero() && (!A.isNaN() || !B.isNaN())) {
8171 ResR = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * A;
8172 ResI = APFloat::getInf(ResR.getSemantics(), C.isNegative()) * B;
8173 }
else if ((A.isInfinity() || B.isInfinity()) && C.isFinite() &&
8175 A = APFloat::copySign(
8176 APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
8177 B = APFloat::copySign(
8178 APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
8179 ResR = APFloat::getInf(ResR.getSemantics()) * (A * C + B * D);
8180 ResI = APFloat::getInf(ResI.getSemantics()) * (B * C - A * D);
8181 }
else if (MaxCD.isInfinity() && A.isFinite() && B.isFinite()) {
8182 C = APFloat::copySign(
8183 APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
8184 D = APFloat::copySign(
8185 APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
8186 ResR = APFloat::getZero(ResR.getSemantics()) * (A * C + B * D);
8187 ResI = APFloat::getZero(ResI.getSemantics()) * (B * C - A * D);
8192 if (RHS.getComplexIntReal() == 0 && RHS.getComplexIntImag() == 0)
8193 return Error(E, diag::note_expr_divide_by_zero);
8195 ComplexValue LHS = Result;
8196 APSInt Den = RHS.getComplexIntReal() * RHS.getComplexIntReal() +
8197 RHS.getComplexIntImag() * RHS.getComplexIntImag();
8198 Result.getComplexIntReal() =
8199 (LHS.getComplexIntReal() * RHS.getComplexIntReal() +
8200 LHS.getComplexIntImag() * RHS.getComplexIntImag()) / Den;
8201 Result.getComplexIntImag() =
8202 (LHS.getComplexIntImag() * RHS.getComplexIntReal() -
8203 LHS.getComplexIntReal() * RHS.getComplexIntImag()) / Den;
8211 bool ComplexExprEvaluator::VisitUnaryOperator(
const UnaryOperator *E) {
8225 if (Result.isComplexFloat()) {
8226 Result.getComplexFloatReal().changeSign();
8227 Result.getComplexFloatImag().changeSign();
8230 Result.getComplexIntReal() = -Result.getComplexIntReal();
8231 Result.getComplexIntImag() = -Result.getComplexIntImag();
8235 if (Result.isComplexFloat())
8236 Result.getComplexFloatImag().changeSign();
8238 Result.getComplexIntImag() = -Result.getComplexIntImag();
8243 bool ComplexExprEvaluator::VisitInitListExpr(
const InitListExpr *E) {
8246 Result.makeComplexFloat();
8252 Result.makeComplexInt();
8260 return ExprEvaluatorBaseTy::VisitInitListExpr(E);
8269 class AtomicExprEvaluator :
8270 public ExprEvaluatorBase<AtomicExprEvaluator> {
8273 AtomicExprEvaluator(EvalInfo &Info,
APValue &Result)
8274 : ExprEvaluatorBaseTy(Info), Result(Result) {}
8281 bool ZeroInitialization(
const Expr *E) {
8284 return Evaluate(Result, Info, &VIE);
8287 bool VisitCastExpr(
const CastExpr *E) {
8290 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8300 return AtomicExprEvaluator(Info, Result).Visit(E);
8309 class VoidExprEvaluator
8310 :
public ExprEvaluatorBase<VoidExprEvaluator> {
8312 VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
8314 bool Success(
const APValue &V,
const Expr *e) {
return true; }
8316 bool VisitCastExpr(
const CastExpr *E) {
8319 return ExprEvaluatorBaseTy::VisitCastExpr(E);
8326 bool VisitCallExpr(
const CallExpr *E) {
8329 return ExprEvaluatorBaseTy::VisitCallExpr(E);
8330 case Builtin::BI__assume:
8331 case Builtin::BI__builtin_assume:
8341 return VoidExprEvaluator(Info).Visit(E);
8356 LV.moveInto(Result);
8361 if (!IntExprEvaluator(Info, Result).Visit(E))
8367 LV.moveInto(Result);
8369 llvm::APFloat F(0.0);
8386 LV.set(E, Info.CurrentCall->Index);
8387 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
8393 LV.set(E, Info.CurrentCall->Index);
8394 APValue &Value = Info.CurrentCall->createTemporary(E,
false);
8399 if (!Info.getLangOpts().CPlusPlus11)
8400 Info.CCEDiag(E, diag::note_constexpr_nonliteral)
8407 }
else if (Info.getLangOpts().CPlusPlus11) {
8408 Info.Diag(E, diag::note_constexpr_nonliteral) << E->
getType();
8411 Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
8422 const Expr *E,
bool AllowNonLiteralTypes) {
8455 LV.setFrom(Info.Ctx, Result);
8470 L->getType()->isUnsignedIntegerType()));
8504 EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
8517 if (!
getType()->isIntegralOrEnumerationType())
8522 (!AllowSideEffects && ExprResult.HasSideEffects))
8525 Result = ExprResult.Val.getInt();
8530 EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
8538 LV.moveInto(Result.Val);
8552 EStatus.
Diag = &Notes;
8554 EvalInfo InitInfo(Ctx, EStatus, EvalInfo::EM_ConstantFold);
8555 InitInfo.setEvaluatingDecl(VD, Value);
8591 EvalResult.Diag =
Diag;
8594 assert(Result &&
"Could not evaluate expression");
8595 assert(EvalResult.Val.isInt() &&
"Expression did not evaluate to integer");
8597 return EvalResult.Val.getInt();
8604 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
8610 assert(Val.isLValue());
8638 IK_ICEIfUnevaluated,
8654 static ICEDiag
Worst(ICEDiag A, ICEDiag B) {
return A.Kind >= B.Kind ? A : B; }
8660 return ICEDiag(IK_NotICE, E->getLocStart());
8668 return ICEDiag(IK_NotICE, E->getLocStart());
8670 switch (E->getStmtClass()) {
8671 #define ABSTRACT_STMT(Node)
8672 #define STMT(Node, Base) case Expr::Node##Class:
8673 #define EXPR(Node, Base)
8674 #include "clang/AST/StmtNodes.inc"
8675 case Expr::PredefinedExprClass:
8676 case Expr::FloatingLiteralClass:
8677 case Expr::ImaginaryLiteralClass:
8678 case Expr::StringLiteralClass:
8679 case Expr::ArraySubscriptExprClass:
8680 case Expr::MemberExprClass:
8681 case Expr::CompoundAssignOperatorClass:
8682 case Expr::CompoundLiteralExprClass:
8683 case Expr::ExtVectorElementExprClass:
8684 case Expr::DesignatedInitExprClass:
8685 case Expr::NoInitExprClass:
8686 case Expr::DesignatedInitUpdateExprClass:
8687 case Expr::ImplicitValueInitExprClass:
8688 case Expr::ParenListExprClass:
8689 case Expr::VAArgExprClass:
8690 case Expr::AddrLabelExprClass:
8691 case Expr::StmtExprClass:
8692 case Expr::CXXMemberCallExprClass:
8693 case Expr::CUDAKernelCallExprClass:
8694 case Expr::CXXDynamicCastExprClass:
8695 case Expr::CXXTypeidExprClass:
8696 case Expr::CXXUuidofExprClass:
8697 case Expr::MSPropertyRefExprClass:
8698 case Expr::CXXNullPtrLiteralExprClass:
8699 case Expr::UserDefinedLiteralClass:
8700 case Expr::CXXThisExprClass:
8701 case Expr::CXXThrowExprClass:
8702 case Expr::CXXNewExprClass:
8703 case Expr::CXXDeleteExprClass:
8704 case Expr::CXXPseudoDestructorExprClass:
8705 case Expr::UnresolvedLookupExprClass:
8706 case Expr::TypoExprClass:
8707 case Expr::DependentScopeDeclRefExprClass:
8708 case Expr::CXXConstructExprClass:
8709 case Expr::CXXStdInitializerListExprClass:
8710 case Expr::CXXBindTemporaryExprClass:
8711 case Expr::ExprWithCleanupsClass:
8712 case Expr::CXXTemporaryObjectExprClass:
8713 case Expr::CXXUnresolvedConstructExprClass:
8714 case Expr::CXXDependentScopeMemberExprClass:
8715 case Expr::UnresolvedMemberExprClass:
8716 case Expr::ObjCStringLiteralClass:
8717 case Expr::ObjCBoxedExprClass:
8718 case Expr::ObjCArrayLiteralClass:
8719 case Expr::ObjCDictionaryLiteralClass:
8720 case Expr::ObjCEncodeExprClass:
8721 case Expr::ObjCMessageExprClass:
8722 case Expr::ObjCSelectorExprClass:
8723 case Expr::ObjCProtocolExprClass:
8724 case Expr::ObjCIvarRefExprClass:
8725 case Expr::ObjCPropertyRefExprClass:
8726 case Expr::ObjCSubscriptRefExprClass:
8727 case Expr::ObjCIsaExprClass:
8728 case Expr::ShuffleVectorExprClass:
8729 case Expr::ConvertVectorExprClass:
8730 case Expr::BlockExprClass:
8731 case Expr::NoStmtClass:
8732 case Expr::OpaqueValueExprClass:
8733 case Expr::PackExpansionExprClass:
8734 case Expr::SubstNonTypeTemplateParmPackExprClass:
8735 case Expr::FunctionParmPackExprClass:
8736 case Expr::AsTypeExprClass:
8737 case Expr::ObjCIndirectCopyRestoreExprClass:
8738 case Expr::MaterializeTemporaryExprClass:
8739 case Expr::PseudoObjectExprClass:
8740 case Expr::AtomicExprClass:
8741 case Expr::LambdaExprClass:
8742 case Expr::CXXFoldExprClass:
8743 return ICEDiag(IK_NotICE, E->getLocStart());
8745 case Expr::InitListExprClass: {
8751 if (cast<InitListExpr>(E)->getNumInits() == 1)
8752 return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
8753 return ICEDiag(IK_NotICE, E->getLocStart());
8756 case Expr::SizeOfPackExprClass:
8757 case Expr::GNUNullExprClass:
8761 case Expr::SubstNonTypeTemplateParmExprClass:
8763 CheckICE(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement(), Ctx);
8765 case Expr::ParenExprClass:
8766 return CheckICE(cast<ParenExpr>(E)->getSubExpr(), Ctx);
8767 case Expr::GenericSelectionExprClass:
8768 return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
8769 case Expr::IntegerLiteralClass:
8770 case Expr::CharacterLiteralClass:
8771 case Expr::ObjCBoolLiteralExprClass:
8772 case Expr::CXXBoolLiteralExprClass:
8773 case Expr::CXXScalarValueInitExprClass:
8774 case Expr::TypeTraitExprClass:
8775 case Expr::ArrayTypeTraitExprClass:
8776 case Expr::ExpressionTraitExprClass:
8777 case Expr::CXXNoexceptExprClass:
8779 case Expr::CallExprClass:
8780 case Expr::CXXOperatorCallExprClass: {
8784 const CallExpr *CE = cast<CallExpr>(E);
8787 return ICEDiag(IK_NotICE, E->getLocStart());
8789 case Expr::DeclRefExprClass: {
8790 if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
8798 if (isa<ParmVarDecl>(D))
8799 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
8804 if (
const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
8805 if (!Dcl->getType()->isIntegralOrEnumerationType())
8806 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
8814 return ICEDiag(IK_NotICE, cast<DeclRefExpr>(E)->getLocation());
8817 return ICEDiag(IK_NotICE, E->getLocStart());
8819 case Expr::UnaryOperatorClass: {
8831 return ICEDiag(IK_NotICE, E->getLocStart());
8844 case Expr::OffsetOfExprClass: {
8853 case Expr::UnaryExprOrTypeTraitExprClass: {
8857 return ICEDiag(IK_NotICE, E->getLocStart());
8860 case Expr::BinaryOperatorClass: {
8879 return ICEDiag(IK_NotICE, E->getLocStart());
8904 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
8907 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
8908 if (REval.isSigned() && REval.isAllOnesValue()) {
8910 if (LEval.isMinSignedValue())
8911 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
8919 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
8920 return ICEDiag(IK_ICEIfUnevaluated, E->getLocStart());
8923 return ICEDiag(IK_NotICE, E->getLocStart());
8926 return Worst(LHSResult, RHSResult);
8932 if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) {
8942 return Worst(LHSResult, RHSResult);
8946 case Expr::ImplicitCastExprClass:
8947 case Expr::CStyleCastExprClass:
8948 case Expr::CXXFunctionalCastExprClass:
8949 case Expr::CXXStaticCastExprClass:
8950 case Expr::CXXReinterpretCastExprClass:
8951 case Expr::CXXConstCastExprClass:
8952 case Expr::ObjCBridgedCastExprClass: {
8953 const Expr *SubExpr = cast<CastExpr>(E)->getSubExpr();
8954 if (isa<ExplicitCastExpr>(E)) {
8959 APSInt IgnoredVal(DestWidth, !DestSigned);
8964 if (FL->getValue().convertToInteger(IgnoredVal,
8965 llvm::APFloat::rmTowardZero,
8966 &Ignored) & APFloat::opInvalidOp)
8967 return ICEDiag(IK_NotICE, E->getLocStart());
8971 switch (cast<CastExpr>(E)->getCastKind()) {
8980 return ICEDiag(IK_NotICE, E->getLocStart());
8983 case Expr::BinaryConditionalOperatorClass: {
8986 if (CommonResult.Kind == IK_NotICE)
return CommonResult;
8988 if (FalseResult.Kind == IK_NotICE)
return FalseResult;
8989 if (CommonResult.Kind == IK_ICEIfUnevaluated)
return CommonResult;
8990 if (FalseResult.Kind == IK_ICEIfUnevaluated &&
8994 case Expr::ConditionalOperatorClass: {
9002 if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
9005 if (CondResult.Kind == IK_NotICE)
9011 if (TrueResult.Kind == IK_NotICE)
9013 if (FalseResult.Kind == IK_NotICE)
9015 if (CondResult.Kind == IK_ICEIfUnevaluated)
9017 if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE)
9026 case Expr::CXXDefaultArgExprClass:
9027 return CheckICE(cast<CXXDefaultArgExpr>(E)->getExpr(), Ctx);
9028 case Expr::CXXDefaultInitExprClass:
9029 return CheckICE(cast<CXXDefaultInitExpr>(E)->getExpr(), Ctx);
9030 case Expr::ChooseExprClass: {
9031 return CheckICE(cast<ChooseExpr>(E)->getChosenSubExpr(), Ctx);
9035 llvm_unreachable(
"Invalid StmtClass!");
9041 llvm::APSInt *Value,
9052 if (!Result.
isInt()) {
9057 if (Value) *Value = Result.
getInt();
9067 if (D.Kind != IK_ICE) {
9068 if (Loc) *Loc = D.Loc;
9082 llvm_unreachable(
"ICE cannot be evaluated!");
9087 return CheckICE(
this, Ctx).Kind == IK_ICE;
9099 Status.Diag = &Diags;
9100 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
9105 if (!Diags.empty()) {
9106 IsConstExpr =
false;
9107 if (Loc) *Loc = Diags[0].first;
9108 }
else if (!IsConstExpr) {
9120 EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
9122 ArgVector ArgValues(Args.size());
9125 if ((*I)->isValueDependent() ||
9126 !
Evaluate(ArgValues[I - Args.begin()], Info, *I))
9128 ArgValues[I - Args.begin()] =
APValue();
9129 if (Info.EvalStatus.HasSideEffects)
9134 CallStackFrame Frame(Info, Callee->
getLocation(), Callee,
nullptr,
9136 return Evaluate(Value, Info,
this) && !Info.EvalStatus.HasSideEffects;
9149 Status.
Diag = &Diags;
9152 EvalInfo::EM_PotentialConstantExpression);
9161 This.set(&VIE, Info.CurrentCall->Index);
9171 Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
9175 Args, FD->
getBody(), Info, Scratch);
9177 return Diags.empty();
9185 Status.
Diag = &Diags;
9188 EvalInfo::EM_PotentialConstantExpressionUnevaluated);
9192 ArgVector ArgValues(0);
9196 "Failed to set up arguments for potential constant evaluation");
9197 CallStackFrame Frame(Info,
SourceLocation(), FD,
nullptr, ArgValues.data());
9201 return Diags.empty();
unsigned getNumElements() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
Defines the clang::ASTContext interface.
unsigned getNumInits() const
const SwitchCase * getNextSwitchCase() const
CastKind getCastKind() const
The null pointer literal (C++11 [lex.nullptr])
Expr ** getArgs()
Retrieve the call arguments.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
bool isNullPtrType() const
const FieldDecl * getUnionField() const
ParmVarDecl *const * param_const_iterator
static bool IsGlobalLValue(APValue::LValueBase B)
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
bool isEvaluatable(const ASTContext &Ctx) const
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isSpecificBuiltinType(unsigned K) const
isSpecificBuiltinType - Test for a particular builtin type.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool isBitField() const
Determines whether this field is a bitfield.
bool isMemberPointerType() const
QualType getType() const
Retrieves the type of the base class.
bool isElidable() const
Whether this construction is elidable.
bool operator==(CanQual< T > x, CanQual< U > y)
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
CompoundStmt * getSubStmt()
static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info, const Stmt *S, const SwitchCase *SC=nullptr)
bool isArgumentType() const
unsigned getIntWidth(QualType T) const
SourceLocation getLocStart() const LLVM_READONLY
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
void addConst()
addConst - add the specified type qualifier to this QualType.
ActionResult< Expr * > ExprResult
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
TypeSourceInfo * getTypeSourceInfo() const
bool isRecordType() const
unsigned getPackLength() const
Retrieve the length of the parameter pack.
chain_range chain() const
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isLiteralType(const ASTContext &Ctx) const
bool isPowerOfTwo() const
bool isVoidPointerType() const
bool isEnumeralType() const
static bool extractSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &Result)
Extract the designated sub-object of an rvalue.
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
bool isMemberPointer() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static bool IsConstNonVolatile(QualType T)
const Expr * getResultExpr() const
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
bool hasLValuePath() const
Represents a call to a C++ constructor.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent...
bool isBooleanType() const
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx, const LValue &LV)
Determine whether this is a pointer past the end of the complete object referred to by the lvalue...
llvm::DenseMap< Stmt *, Stmt * > MapTy
const Stmt * getElse() const
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "for" statement, if any.
SourceLocation getLocEnd() const LLVM_READONLY
[ARC] Consumes a retainable object pointer that has just been produced, e.g. as the return value of a...
static const ValueDecl * HandleMemberPointerAccess(EvalInfo &Info, QualType LVType, LValue &LV, const Expr *RHS, bool IncludeMember=true)
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result, EvalInfo &Info)
Represents a C++ constructor within a class.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, QualType Type, const LValue &LVal)
const llvm::APInt & getSize() const
Expr * getIndexExpr(unsigned Idx)
static bool EvaluateDecl(EvalInfo &Info, const Decl *D)
const CXXBaseSpecifier *const * path_const_iterator
const Expr * getCallee() const
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E)
APFloat & getComplexFloatReal()
AccessSpecifier getAccess() const
field_iterator field_begin() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CK_Dynamic - A C++ dynamic_cast.
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
UnaryExprOrTypeTrait getKind() const
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E)
unsigned getValue() const
static bool isAssignmentOp(Opcode Opc)
ParmVarDecl - Represents a parameter to a function.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
unsigned path_size() const
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
CompleteObject(APValue *Value, QualType Type)
static bool HasSameBase(const LValue &A, const LValue &B)
Expr * IgnoreImpCasts() LLVM_READONLY
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type, CharUnits &Size)
Get the size of the given type in char units.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
bool isComplexInt() const
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static bool TryEvaluateBuiltinNaN(const ASTContext &Context, QualType ResultTy, const Expr *Arg, bool SNaN, llvm::APFloat &Result)
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Converts between different integral complex types. _Complex char -> _Complex long long _Complex unsig...
static bool EvaluateVector(const Expr *E, APValue &Result, EvalInfo &Info)
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isReferenceType() const
QualType getReturnType() const
bool isStructureOrClassType() const
Converting between two Objective-C object types, which can occur when performing reference binding to...
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info)
bool isPotentiallyEvaluated() const
[ARC] Causes a value of block type to be copied to the heap, if it is not already there...
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E, const RecordDecl *RD, const LValue &This, APValue &Result)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
unsigned getLValueCallIndex() const
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info)
static bool isRelationalOp(Opcode Opc)
Converts a floating point complex to bool by comparing against 0+0i.
static bool IsWeakLValue(const LValue &Value)
static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx)
Describes an C or C++ initializer list.
uint32_t getCodeUnit(size_t i) const
Expr * getChosenSubExpr() const
SmallVectorImpl< PartialDiagnosticAt > * Diag
static bool isEqualityOp(Opcode Opc)
const TargetInfo & getTargetInfo() const
static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, llvm::APInt &Res)
static void HandleOverflow(EvalInfo &Info, const Expr *E, const T &SrcValue, QualType DestType)
static APSInt CheckedIntArithmetic(EvalInfo &Info, const Expr *E, const APSInt &LHS, const APSInt &RHS, unsigned BitWidth, Operation Op)
const LangOptions & getLangOpts() const
unsigned getLength() const
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008. Only MIPS allows a different encoding.
APValue Val
Val - This is the value the expression can be folded to.
static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type, const LValue &LVal, APValue &RVal)
Perform an lvalue-to-rvalue conversion on the given glvalue. This can also be used for 'lvalue-to-lva...
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
Expr * getExprOperand() const
path_iterator path_begin()
field_range fields() const
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E, LValue &Result)
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, int64_t Adjustment)
const ArrayType * getAsArrayType(QualType T) const
static bool isRecordType(QualType T)
A builtin binary operation expression such as "x + y" or "x <= y".
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
bool isValueDependent() const
RecordDecl * getDecl() const
bool isUnsignedIntegerType() const
Expr * IgnoreParenCasts() LLVM_READONLY
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, bool IsIncrement, APValue *Old)
Perform an increment or decrement on LVal.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
uint64_t getFieldOffset(unsigned FieldNo) const
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit, uint64_t Index)
Extract the value of a character from a string literal.
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType)
Find the complete object to which an LValue refers.
base_class_iterator bases_begin()
bool isIncompleteType(NamedDecl **Def=nullptr) const
Def If non-NULL, and the type refers to some kind of declaration that can be completed (such as a C s...
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E, LValue &LVal, QualType EltTy, bool Imag)
static void expandArray(APValue &Array, unsigned Index)
unsigned getBuiltinCallee() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
APSInt & getComplexIntReal()
init_iterator init_begin()
Retrieve an iterator to the first initializer.
A default argument (C++ [dcl.fct.default]).
static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, APSInt &Result)
Perform the given binary integer operation.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
bool isUnnamedBitfield() const
Determines whether this is an unnamed bitfield.
bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result=nullptr, SourceLocation *Loc=nullptr) const
Represents the this expression in C++.
DiagnosticsEngine & getDiagnostics() const
field_iterator field_end() const
APValue & getVectorElt(unsigned I)
bool isAddrLabelDiff() const
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
const ArrayType * castAsArrayTypeUnsafe() const
Expr * getFalseExpr() const
llvm::APInt getValue() const
static bool handleCompoundAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, QualType PromotedLValType, BinaryOperatorKind Opcode, const APValue &RVal)
Perform a compound assignment of LVal <op>= RVal.
Causes a block literal to by copied to the heap and then autoreleased.
static unsigned FindDesignatorMismatch(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B, bool &WasArrayIndex)
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const
QualType Type
The type of the complete object.
APValue & getArrayFiller()
const Expr * getExpr() const
Get the initialization expression that will be used.
QualType getPointeeType() const
bool isFunctionPointerType() const
Converts between different floating point complex types. _Complex float -> _Complex double...
bool isRealFloatingType() const
Floating point categories.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
unsigned getArrayInitializedElts() const
bool isSignedIntegerOrEnumerationType() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
Converts an integral complex to an integral real of the source's element type by discarding the imagi...
static bool HandleConversionToBool(const APValue &Val, bool &Result)
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info)
Evaluate an expression of record type as a temporary.
bool isAnyComplexType() const
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "while" statement, if any.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, LValue &This)
Build an lvalue for the object argument of a member function call.
bool isMemberPointerToDerivedMember() const
bool isComplexFloat() const
bool isAtomicType() const
bool isVariableArrayType() const
DeclContext * getDeclContext()
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AccessKinds
Kinds of access we can perform on an object, for diagnostics.
bool isFloatingType() const
Represents an expression that computes the length of a parameter pack.
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result, EvalInfo &Info)
static int EvaluateBuiltinClassifyType(const CallExpr *E)
Defines the clang::TypeLoc interface and its subclasses.
const SwitchCase * getSwitchCaseList() const
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl, const Expr *Cond, bool &Result)
Evaluate a condition (either a variable declaration or an expression).
unsigned getConstexprBacktraceLimit() const
Retrieve the maximum number of constexpr evaluation notes to emit along with a given diagnostic...
static bool isOverflowingIntegerType(ASTContext &Ctx, QualType T)
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
static bool diagnoseUnreadableFields(EvalInfo &Info, const Expr *E, QualType T)
Expr * getSubExpr() const
bool isDependentType() const
PartialDiagnostic::StorageAllocator & getDiagAllocator()
APValue & getStructField(unsigned i)
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result, const RecordDecl *TruncatedType, unsigned TruncatedElements)
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
static bool IsStringLiteralCall(const CallExpr *E)
Should this call expression be treated as a string literal?
unsigned getNumComponents() const
Converts from an integral complex to a floating complex. _Complex unsigned -> _Complex float...
Represents a reference to a non-type template parameter that has been substituted with a template arg...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
QualType getElementType() const
APSInt & getComplexIntImag()
QualType getComputationLHSType() const
static bool HandleConstructorCall(SourceLocation CallLoc, const LValue &This, ArrayRef< const Expr * > Args, const CXXConstructorDecl *Definition, EvalInfo &Info, APValue &Result)
Evaluate a constructor call.
bool isComplexIntegerType() const
The result type of a method or function.
static bool EvaluateArgs(ArrayRef< const Expr * > Args, ArgVector &ArgValues, EvalInfo &Info)
EvaluateArgs - Evaluate the arguments to a function call.
bool checkInitIsICE() const
Determine whether the value of the initializer attached to this declaration is an integral constant e...
bool isUnsignedIntegerOrEnumerationType() const
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E, QualType DestType, QualType SrcType, APSInt &Value)
static bool HandleFunctionCall(SourceLocation CallLoc, const FunctionDecl *Callee, const LValue *This, ArrayRef< const Expr * > Args, const Stmt *Body, EvalInfo &Info, APValue &Result)
Evaluate a function call.
void EvaluateForOverflow(const ASTContext &Ctx) const
Expr * getTrueExpr() const
const Expr * getAnyInitializer() const
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info, const Stmt *Body, const SwitchCase *Case=nullptr)
Evaluate the body of a loop, and translate the result as appropriate.
bool isLValueOnePastTheEnd() const
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx, const VarDecl *VD, SmallVectorImpl< PartialDiagnosticAt > &Notes) const
APValue & getStructBase(unsigned i)
Stmt * getBody(const FunctionDecl *&Definition) const
SourceLocation getLocStart() const LLVM_READONLY
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
static ICEDiag Worst(ICEDiag A, ICEDiag B)
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const
APValue & getArrayInitializedElt(unsigned I)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
const Type * getTypePtr() const
QualType getElementType() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
Expr * getSourceExpr() const
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
bool isComplexType() const
APValue & getUnionValue()
bool isConstantSizeType() const
ASTContext & getASTContext() const LLVM_READONLY
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result)
ValueKind getKind() const
const Expr * getCond() const
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
static bool IsLiteralLValue(const LValue &Value)
Represents a static or instance method of a struct/union/class.
static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E, APFloat &LHS, BinaryOperatorKind Opcode, const APFloat &RHS)
Perform the given binary floating-point operation, in-place, on LHS.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, APValue &Value, const FieldDecl *FD)
unsigned getCharByteWidth() const
const Type * getBaseElementTypeUnsafe() const
Converts from an integral real to an integral complex whose element type matches the source...
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "switch" statement, if any.
static const ValueDecl * GetLValueBaseDecl(const LValue &LVal)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const
bool isVectorType() const
static bool EvaluateRecord(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
static bool isLogicalOp(Opcode Opc)
An expression trait intrinsic.
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result)
uint64_t getValue() const
static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E)
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const BlockDecl * getBlockDecl() const
bool isCXX98IntegralConstantExpr(const ASTContext &Ctx) const
QualType getType() const
Return the type wrapped by this type source info.
bool isGlobalLValue() const
const OffsetOfNode & getComponent(unsigned Idx) const
SourceLocation getExprLoc() const LLVM_READONLY
bool isPtrMemOp() const
predicates to categorize the respective opcodes.
Represents a C11 generic selection.
EvalStatus is a struct with detailed info about an evaluation in progress.
AddrLabelExpr - The GNU address of label extension, representing &&label.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
static bool EvaluateVoid(const Expr *E, EvalInfo &Info)
Converts a floating point complex to floating point real of the source's element type. Just discards the imaginary component. _Complex long double -> long double.
Expr * getReplacement() const
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base)
VarDecl * getConditionVariable() const
Retrieve the variable declared in this "if" statement, if any.
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition. The opaque value will...
static const Type * getElementType(const Expr *BaseExpr)
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result, EvalInfo &Info)
static unsigned getBaseIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *Base)
const Expr * getExpr() const
[C99 6.4.2.2] - A predefined identifier such as func.
EvalResult is a struct with detailed info about an evaluated expression.
Converts an integral complex to bool by comparing against 0+0i.
bool isZero() const
isZero - Test whether the quantity equals zero.
static bool isZeroSized(const LValue &Value)
return(x >> y)|(x<< (32-y))
const Stmt * getBody() const
void swap(APValue &RHS)
Swaps the contents of this and the given APValue.
bool isInvalidDecl() const
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Kind getKind() const
Determine what kind of offsetof node this is.
StringRef getString() const
static int64_t getExtValue(const APSInt &Value)
unsigned getNumArgs() const
A conversion of a floating point real to a floating point complex of the original type...
unsigned getNumArgs() const
body_iterator body_begin()
Stmt *const * const_body_iterator
llvm::APFloat getValue() const
Expr * IgnoreParenImpCasts() LLVM_READONLY
[ARC] Reclaim a retainable object pointer object that may have been produced and autoreleased as part...
FieldDecl * getField() const
For a field offsetof node, returns the field.
const Stmt * getThen() const
QualType getNonReferenceType() const
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
ArrayRef< LValuePathEntry > getLValuePath() const
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, const ASTRecordLayout *RL=nullptr)
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getTypeOfArgument() const
DeclStmt * getBeginEndStmt()
static bool hasFields(const CXXRecordDecl *RD)
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
llvm::PointerUnion< const ValueDecl *, const Expr * > LValueBase
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T)
[ARC] Produces a retainable object pointer so that it may be consumed, e.g. by being passed to a cons...
static bool modifySubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, APValue &NewVal)
Update the designated sub-object of an rvalue to the given value.
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APSInt &Value, QualType DestType, APFloat &Result)
bool isFunctionType() const
Converts from T to _Atomic(T).
static bool isAdditiveOp(Opcode Opc)
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Converts from a floating complex to an integral complex. _Complex float -> _Complex int...
static bool EvaluateArray(const Expr *E, const LValue &This, APValue &Result, EvalInfo &Info)
const Expr * getSubExpr() const
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E, QualType Type, LValue &Result)
SubobjectHandler::result_type findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const SubobjectDesignator &Sub, SubobjectHandler &handler)
Find the designated sub-object of an rvalue.
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj, const CXXRecordDecl *DerivedDecl, const CXXBaseSpecifier *Base)
SourceLocation getExprLoc() const LLVM_READONLY
LabelDecl * getLabel() const
Represents a base class of a C++ class.
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL=nullptr)
const Expr * getInitializer() const
unsigned getFieldIndex() const
bool isDefaultConstructor() const
DeclStmt * getRangeStmt()
static bool isIncrementOp(Opcode Op)
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This, const Expr *E, bool AllowNonLiteralTypes=false)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
A use of a default initializer in a constructor or in aggregate initialization.
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E, LValue &LVal, const IndirectFieldDecl *IFD)
Update LVal to refer to the given indirect field.
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, const FunctionDecl *Declaration, const FunctionDecl *Definition)
static bool EvaluateBuiltinConstantPForLValue(const LValue &LV)
const Expr * getSubExpr() const
static EvalStmtResult EvaluateSwitch(APValue &Result, EvalInfo &Info, const SwitchStmt *SS)
Evaluate a switch statement.
bool hasArrayFiller() const
Return true if this is an array initializer and its array "filler" has been set.
APFloat & getComplexFloatImag()
const LValueBase getLValueBase() const
Represents a C++ struct/union/class.
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info)
static bool isReadByLvalueToRvalueConversion(QualType T)
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx, const Expr *E, llvm::APSInt *Value, SourceLocation *Loc)
Evaluate an expression as a C++11 integral constant expression.
const Expr * getCond() const
base_class_iterator bases_end()
llvm::PointerIntPair< const Decl *, 1, bool > BaseOrMemberType
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info)
static ICEDiag CheckICE(const Expr *E, const ASTContext &Ctx)
Converts from _Atomic(T) to T.
Defines the clang::TargetInfo interface.
static bool EvaluateBuiltinConstantP(ASTContext &Ctx, const Expr *Arg)
bool isStringLiteralInit() const
APValue * getEvaluatedValue() const
Return the already-evaluated value of this variable's initializer, or NULL if the value is not yet kn...
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
QualType getElementType() const
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
static bool AreElementsOfSameArray(QualType ObjType, const SubobjectDesignator &A, const SubobjectDesignator &B)
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, const VarDecl *VD, CallStackFrame *Frame, APValue *&Result)
const Expr * getInit(unsigned Init) const
static void expandStringLiteral(EvalInfo &Info, const Expr *Lit, APValue &Result)
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
static bool isPotentialConstantExprUnevaluated(Expr *E, const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
DeclStmt * getLoopVarStmt()
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
APValue * Value
The value of the complete object.
SourceLocation getLocation() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E, QualType SrcType, const APFloat &Value, QualType DestType, APSInt &Result)
A boolean literal, per ([C++ lex.bool] Boolean literals).
Automatic storage duration (most local variables).
bool isSignedIntegerType() const
unsigned getArraySize() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const
bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx, const FunctionDecl *Callee, ArrayRef< const Expr * > Args) const
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
static bool isComparisonOp(Opcode Opc)
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, QualType LValType, APValue &Val)
Perform an assignment of Val to LVal. Takes ownership of Val.
unsigned getVectorLength() const
Defines enum values for all the target-independent builtin functions.
Represents an implicitly-generated value initialization of an object of a given type.
static void describeCall(CallStackFrame *Frame, raw_ostream &Out)
Produce a string describing the given constexpr call.
bool hasPointerRepresentation() const
bool isIntegerType() const
bool hasLocalStorage() const
bool hasArrayFiller() const
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc, const CXXConstructorDecl *CD, bool IsValueInitialization)
const RecordDecl * getParent() const
Expr * IgnoreParens() LLVM_READONLY
CharUnits & getLValueOffset()
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isPointerType() const
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result)
QualType getArgumentType() const