#include "ByteCode/Context.h"
#include "ByteCode/Frame.h"
#include "ByteCode/State.h"
#include "ExprConstShared.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/CurrentSourceLocExprScope.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OSLog.h"
#include "clang/AST/OptionalDiagnostic.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/APFixedPoint.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/SipHash.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
#include <functional>
#include <optional>
#define DEBUG_TYPE …
usingnamespaceclang;
APFixedPoint;
APInt;
APSInt;
APFloat;
FixedPointSemantics;
namespace {
struct LValue;
class CallStackFrame;
class EvalInfo;
SourceLocExprScopeGuard;
static QualType getType(APValue::LValueBase B) { … }
static const FieldDecl *getAsField(APValue::LValuePathEntry E) { … }
static const CXXRecordDecl *getAsBaseClass(APValue::LValuePathEntry E) { … }
static bool isVirtualBaseClass(APValue::LValuePathEntry E) { … }
static QualType getStorageType(const ASTContext &Ctx, const Expr *E) { … }
static const AllocSizeAttr *getAllocSizeAttr(const CallExpr *CE) { … }
static const CallExpr *tryUnwrapAllocSizeCall(const Expr *E) { … }
static bool isBaseAnAllocSizeCall(APValue::LValueBase Base) { … }
static bool isForManglingOnly(ConstantExprKind Kind) { … }
static bool isTemplateArgument(ConstantExprKind Kind) { … }
static const uint64_t AssumedSizeForUnsizedArray = …;
static unsigned
findMostDerivedSubobject(ASTContext &Ctx, APValue::LValueBase Base,
ArrayRef<APValue::LValuePathEntry> Path,
uint64_t &ArraySize, QualType &Type, bool &IsArray,
bool &FirstEntryIsUnsizedArray) { … }
struct SubobjectDesignator { … };
enum class ScopeKind { … };
struct CallRef { … };
class CallStackFrame : public interp::Frame { … };
class ThisOverrideRAII { … };
class ExprTimeTraceScope { … };
struct MSConstexprContextRAII { … };
}
static bool HandleDestruction(EvalInfo &Info, const Expr *E,
const LValue &This, QualType ThisType);
static bool HandleDestruction(EvalInfo &Info, SourceLocation Loc,
APValue::LValueBase LVBase, APValue &Value,
QualType T);
namespace {
class Cleanup { … };
struct ObjectUnderConstruction { … };
enum class ConstructionPhase { … };
}
namespace llvm {
template<> struct DenseMapInfo<ObjectUnderConstruction> { … };
}
namespace {
struct DynAlloc { … };
struct DynAllocOrder { … };
class EvalInfo : public interp::State { … };
struct FoldConstant { … };
struct IgnoreSideEffectsRAII { … };
class SpeculativeEvaluationRAII { … };
template<ScopeKind Kind>
class ScopeRAII { … };
BlockScopeRAII;
FullExpressionRAII;
CallScopeRAII;
}
bool SubobjectDesignator::checkSubobject(EvalInfo &Info, const Expr *E,
CheckSubobjectKind CSK) { … }
void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
const Expr *E) { … }
void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
const APSInt &N) { … }
CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange,
const FunctionDecl *Callee, const LValue *This,
const Expr *CallExpr, CallRef Call)
: … { … }
CallStackFrame::~CallStackFrame() { … }
static bool isRead(AccessKinds AK) { … }
static bool isModification(AccessKinds AK) { … }
static bool isAnyAccess(AccessKinds AK) { … }
static bool isFormalAccess(AccessKinds AK) { … }
static bool isValidIndeterminateAccess(AccessKinds AK) { … }
namespace {
struct ComplexValue { … };
struct LValue { … };
struct MemberPtr { … };
static bool operator==(const MemberPtr &LHS, const MemberPtr &RHS) { … }
}
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E);
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info,
const LValue &This, const Expr *E,
bool AllowNonLiteralTypes = false);
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
bool InvalidBaseOK = false);
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info,
bool InvalidBaseOK = false);
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
EvalInfo &Info);
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info);
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info);
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result,
EvalInfo &Info);
static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
EvalInfo &Info);
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
EvalInfo &Info,
std::string *StringResult = nullptr);
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
EvalInfo &Info);
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
EvalInfo &Info);
static void negateAsSigned(APSInt &Int) { … }
template<typename KeyT>
APValue &CallStackFrame::createTemporary(const KeyT *Key, QualType T,
ScopeKind Scope, LValue &LV) { … }
APValue &CallStackFrame::createParam(CallRef Args, const ParmVarDecl *PVD,
LValue &LV) { … }
APValue &CallStackFrame::createLocal(APValue::LValueBase Base, const void *Key,
QualType T, ScopeKind Scope) { … }
APValue *EvalInfo::createHeapAlloc(const Expr *E, QualType T, LValue &LV) { … }
void CallStackFrame::describe(raw_ostream &Out) const { … }
static bool EvaluateIgnoredValue(EvalInfo &Info, const Expr *E) { … }
static bool IsOpaqueConstantCall(const CallExpr *E) { … }
static bool IsOpaqueConstantCall(const LValue &LVal) { … }
static bool IsGlobalLValue(APValue::LValueBase B) { … }
static const ValueDecl *GetLValueBaseDecl(const LValue &LVal) { … }
struct LValueBaseString { … };
static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal,
LValueBaseString &AsString) { … }
static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info,
const LValue &LHS,
const LValue &RHS) { … }
static bool IsWeakLValue(const LValue &Value) { … }
static bool isZeroSized(const LValue &Value) { … }
static bool HasSameBase(const LValue &A, const LValue &B) { … }
static void NoteLValueLocation(EvalInfo &Info, APValue::LValueBase Base) { … }
enum class CheckEvaluationResultKind { … };
CheckedTemporaries;
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value,
ConstantExprKind Kind,
const FieldDecl *SubobjectDecl,
CheckedTemporaries &CheckedTemps);
static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
QualType Type, const LValue &LVal,
ConstantExprKind Kind,
CheckedTemporaries &CheckedTemps) { … }
static bool CheckMemberPointerConstantExpression(EvalInfo &Info,
SourceLocation Loc,
QualType Type,
const APValue &Value,
ConstantExprKind Kind) { … }
static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
const LValue *This = nullptr) { … }
static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value,
ConstantExprKind Kind,
const FieldDecl *SubobjectDecl,
CheckedTemporaries &CheckedTemps) { … }
static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value,
ConstantExprKind Kind) { … }
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc,
QualType Type, const APValue &Value) { … }
static bool CheckMemoryLeaks(EvalInfo &Info) { … }
static bool EvalPointerValueAsBool(const APValue &Value, bool &Result) { … }
static bool HandleConversionToBool(const APValue &Val, bool &Result) { … }
static bool EvaluateAsBooleanCondition(const Expr *E, bool &Result,
EvalInfo &Info) { … }
template<typename T>
static bool HandleOverflow(EvalInfo &Info, const Expr *E,
const T &SrcValue, QualType DestType) { … }
static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E,
QualType SrcType, const APFloat &Value,
QualType DestType, APSInt &Result) { … }
static llvm::RoundingMode getActiveRoundingMode(EvalInfo &Info, const Expr *E) { … }
static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E,
APFloat::opStatus St) { … }
static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E,
QualType SrcType, QualType DestType,
APFloat &Result) { … }
static APSInt HandleIntToIntCast(EvalInfo &Info, const Expr *E,
QualType DestType, QualType SrcType,
const APSInt &Value) { … }
static bool HandleIntToFloatCast(EvalInfo &Info, const Expr *E,
const FPOptions FPO,
QualType SrcType, const APSInt &Value,
QualType DestType, APFloat &Result) { … }
static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E,
APValue &Value, const FieldDecl *FD) { … }
template<typename Operation>
static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,
const APSInt &LHS, const APSInt &RHS,
unsigned BitWidth, Operation Op,
APSInt &Result) { … }
static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
const APSInt &LHS, BinaryOperatorKind Opcode,
APSInt RHS, APSInt &Result) { … }
static bool handleFloatFloatBinOp(EvalInfo &Info, const BinaryOperator *E,
APFloat &LHS, BinaryOperatorKind Opcode,
const APFloat &RHS) { … }
static bool handleLogicalOpForVector(const APInt &LHSValue,
BinaryOperatorKind Opcode,
const APInt &RHSValue, APInt &Result) { … }
static bool handleLogicalOpForVector(const APFloat &LHSValue,
BinaryOperatorKind Opcode,
const APFloat &RHSValue, APInt &Result) { … }
static bool handleLogicalOpForVector(const APValue &LHSValue,
BinaryOperatorKind Opcode,
const APValue &RHSValue, APInt &Result) { … }
template <typename APTy>
static bool
handleCompareOpForVectorHelper(const APTy &LHSValue, BinaryOperatorKind Opcode,
const APTy &RHSValue, APInt &Result) { … }
static bool handleCompareOpForVector(const APValue &LHSValue,
BinaryOperatorKind Opcode,
const APValue &RHSValue, APInt &Result) { … }
static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E,
BinaryOperatorKind Opcode,
APValue &LHSValue,
const APValue &RHSValue) { … }
static bool CastToDerivedClass(EvalInfo &Info, const Expr *E, LValue &Result,
const RecordDecl *TruncatedType,
unsigned TruncatedElements) { … }
static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj,
const CXXRecordDecl *Derived,
const CXXRecordDecl *Base,
const ASTRecordLayout *RL = nullptr) { … }
static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
const CXXRecordDecl *DerivedDecl,
const CXXBaseSpecifier *Base) { … }
static bool HandleLValueBasePath(EvalInfo &Info, const CastExpr *E,
QualType Type, LValue &Result) { … }
static bool CastToBaseClass(EvalInfo &Info, const Expr *E, LValue &Result,
const CXXRecordDecl *DerivedRD,
const CXXRecordDecl *BaseRD) { … }
static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
const FieldDecl *FD,
const ASTRecordLayout *RL = nullptr) { … }
static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E,
LValue &LVal,
const IndirectFieldDecl *IFD) { … }
enum class SizeOfType { … };
static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, QualType Type,
CharUnits &Size, SizeOfType SOT = SizeOfType::SizeOf) { … }
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E,
LValue &LVal, QualType EltTy,
APSInt Adjustment) { … }
static bool HandleLValueArrayAdjustment(EvalInfo &Info, const Expr *E,
LValue &LVal, QualType EltTy,
int64_t Adjustment) { … }
static bool HandleLValueComplexElement(EvalInfo &Info, const Expr *E,
LValue &LVal, QualType EltTy,
bool Imag) { … }
static bool HandleLValueVectorElement(EvalInfo &Info, const Expr *E,
LValue &LVal, QualType EltTy,
uint64_t Size, uint64_t Idx) { … }
static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E,
const VarDecl *VD, CallStackFrame *Frame,
unsigned Version, APValue *&Result) { … }
static unsigned getBaseIndex(const CXXRecordDecl *Derived,
const CXXRecordDecl *Base) { … }
static APSInt extractStringLiteralCharacter(EvalInfo &Info, const Expr *Lit,
uint64_t Index) { … }
static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S,
APValue &Result,
QualType AllocType = QualType()) { … }
static void expandArray(APValue &Array, unsigned Index) { … }
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD);
static bool isReadByLvalueToRvalueConversion(QualType T) { … }
static bool isReadByLvalueToRvalueConversion(const CXXRecordDecl *RD) { … }
static bool diagnoseMutableFields(EvalInfo &Info, const Expr *E, AccessKinds AK,
QualType T) { … }
static bool lifetimeStartedInEvaluation(EvalInfo &Info,
APValue::LValueBase Base,
bool MutableSubobject = false) { … }
static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT,
SourceLocation CallLoc = { … }
namespace {
struct CompleteObject { … };
}
static QualType getSubobjectType(QualType ObjType, QualType SubobjType,
bool IsMutable = false) { … }
template<typename SubobjectHandler>
typename SubobjectHandler::result_type
findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
const SubobjectDesignator &Sub, SubobjectHandler &handler) { … }
namespace {
struct ExtractSubobjectHandler { … };
}
static bool extractSubobject(EvalInfo &Info, const Expr *E,
const CompleteObject &Obj,
const SubobjectDesignator &Sub, APValue &Result,
AccessKinds AK = AK_Read) { … }
namespace {
struct ModifySubobjectHandler { … };
}
const AccessKinds ModifySubobjectHandler::AccessKind;
static bool modifySubobject(EvalInfo &Info, const Expr *E,
const CompleteObject &Obj,
const SubobjectDesignator &Sub,
APValue &NewVal) { … }
static unsigned FindDesignatorMismatch(QualType ObjType,
const SubobjectDesignator &A,
const SubobjectDesignator &B,
bool &WasArrayIndex) { … }
static bool AreElementsOfSameArray(QualType ObjType,
const SubobjectDesignator &A,
const SubobjectDesignator &B) { … }
static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
AccessKinds AK, const LValue &LVal,
QualType LValType) { … }
static bool
handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, QualType Type,
const LValue &LVal, APValue &RVal,
bool WantObjectRepresentation = false) { … }
static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal,
QualType LValType, APValue &Val) { … }
namespace {
struct CompoundAssignSubobjectHandler { … };
}
const AccessKinds CompoundAssignSubobjectHandler::AccessKind;
static bool handleCompoundAssignment(EvalInfo &Info,
const CompoundAssignOperator *E,
const LValue &LVal, QualType LValType,
QualType PromotedLValType,
BinaryOperatorKind Opcode,
const APValue &RVal) { … }
namespace {
struct IncDecSubobjectHandler { … };
}
static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal,
QualType LValType, bool IsIncrement, APValue *Old) { … }
static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object,
LValue &This) { … }
static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
QualType LVType,
LValue &LV,
const Expr *RHS,
bool IncludeMember = true) { … }
static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info,
const BinaryOperator *BO,
LValue &LV,
bool IncludeMember = true) { … }
static bool HandleBaseToDerivedCast(EvalInfo &Info, const CastExpr *E,
LValue &Result) { … }
static bool handleDefaultInitValue(QualType T, APValue &Result) { … }
namespace {
enum EvalStmtResult { … };
}
static bool EvaluateVarDecl(EvalInfo &Info, const VarDecl *VD) { … }
static bool EvaluateDecl(EvalInfo &Info, const Decl *D) { … }
static bool EvaluateDependentExpr(const Expr *E, EvalInfo &Info) { … }
static bool EvaluateCond(EvalInfo &Info, const VarDecl *CondDecl,
const Expr *Cond, bool &Result) { … }
namespace {
struct StmtResult { … };
struct TempVersionRAII { … };
}
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
const Stmt *S,
const SwitchCase *SC = nullptr);
static EvalStmtResult EvaluateLoopBody(StmtResult &Result, EvalInfo &Info,
const Stmt *Body,
const SwitchCase *Case = nullptr) { … }
static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info,
const SwitchStmt *SS) { … }
static bool CheckLocalVariableDeclaration(EvalInfo &Info, const VarDecl *VD) { … }
static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
const Stmt *S, const SwitchCase *Case) { … }
static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc,
const CXXConstructorDecl *CD,
bool IsValueInitialization) { … }
static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc,
const FunctionDecl *Declaration,
const FunctionDecl *Definition,
const Stmt *Body) { … }
namespace {
struct CheckDynamicTypeHandler { … };
}
static bool checkDynamicType(EvalInfo &Info, const Expr *E, const LValue &This,
AccessKinds AK, bool Polymorphic) { … }
static bool
checkNonVirtualMemberCallThisPointer(EvalInfo &Info, const Expr *E,
const LValue &This,
const CXXMethodDecl *NamedMember) { … }
struct DynamicType { … };
static const CXXRecordDecl *getBaseClassType(SubobjectDesignator &Designator,
unsigned PathLength) { … }
static std::optional<DynamicType> ComputeDynamicType(EvalInfo &Info,
const Expr *E,
LValue &This,
AccessKinds AK) { … }
static const CXXMethodDecl *HandleVirtualDispatch(
EvalInfo &Info, const Expr *E, LValue &This, const CXXMethodDecl *Found,
llvm::SmallVectorImpl<QualType> &CovariantAdjustmentPath) { … }
static bool HandleCovariantReturnAdjustment(EvalInfo &Info, const Expr *E,
APValue &Result,
ArrayRef<QualType> Path) { … }
static bool isBaseClassPublic(const CXXRecordDecl *Derived,
const CXXRecordDecl *Base) { … }
static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E,
LValue &Ptr) { … }
namespace {
struct StartLifetimeOfUnionMemberHandler { … };
}
const AccessKinds StartLifetimeOfUnionMemberHandler::AccessKind;
static bool MaybeHandleUnionActiveMemberChange(EvalInfo &Info,
const Expr *LHSExpr,
const LValue &LHS) { … }
static bool EvaluateCallArg(const ParmVarDecl *PVD, const Expr *Arg,
CallRef Call, EvalInfo &Info,
bool NonNull = false) { … }
static bool EvaluateArgs(ArrayRef<const Expr *> Args, CallRef Call,
EvalInfo &Info, const FunctionDecl *Callee,
bool RightToLeft = false) { … }
static bool handleTrivialCopy(EvalInfo &Info, const ParmVarDecl *Param,
const Expr *E, APValue &Result,
bool CopyObjectRepresentation) { … }
static bool HandleFunctionCall(SourceLocation CallLoc,
const FunctionDecl *Callee, const LValue *This,
const Expr *E, ArrayRef<const Expr *> Args,
CallRef Call, const Stmt *Body, EvalInfo &Info,
APValue &Result, const LValue *ResultSlot) { … }
static bool HandleConstructorCall(const Expr *E, const LValue &This,
CallRef Call,
const CXXConstructorDecl *Definition,
EvalInfo &Info, APValue &Result) { … }
static bool HandleConstructorCall(const Expr *E, const LValue &This,
ArrayRef<const Expr*> Args,
const CXXConstructorDecl *Definition,
EvalInfo &Info, APValue &Result) { … }
static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange,
const LValue &This, APValue &Value,
QualType T) { … }
namespace {
struct DestroyObjectHandler { … };
}
static bool HandleDestruction(EvalInfo &Info, const Expr *E,
const LValue &This, QualType ThisType) { … }
static bool HandleDestruction(EvalInfo &Info, SourceLocation Loc,
APValue::LValueBase LVBase, APValue &Value,
QualType T) { … }
static bool HandleOperatorNewCall(EvalInfo &Info, const CallExpr *E,
LValue &Result) { … }
static bool hasVirtualDestructor(QualType T) { … }
static const FunctionDecl *getVirtualOperatorDelete(QualType T) { … }
static std::optional<DynAlloc *> CheckDeleteKind(EvalInfo &Info, const Expr *E,
const LValue &Pointer,
DynAlloc::Kind DeallocKind) { … }
bool HandleOperatorDeleteCall(EvalInfo &Info, const CallExpr *E) { … }
namespace {
class BitCastBuffer { … };
class APValueToBufferConverter { … };
class BufferToAPValueConverter { … };
static bool checkBitCastConstexprEligibilityType(SourceLocation Loc,
QualType Ty, EvalInfo *Info,
const ASTContext &Ctx,
bool CheckingDest) { … }
static bool checkBitCastConstexprEligibility(EvalInfo *Info,
const ASTContext &Ctx,
const CastExpr *BCE) { … }
static bool handleRValueToRValueBitCast(EvalInfo &Info, APValue &DestValue,
const APValue &SourceRValue,
const CastExpr *BCE) { … }
static bool handleLValueToRValueBitCast(EvalInfo &Info, APValue &DestValue,
APValue &SourceValue,
const CastExpr *BCE) { … }
template <class Derived>
class ExprEvaluatorBase
: public ConstStmtVisitor<Derived, bool> { … };
}
namespace {
template<class Derived>
class LValueExprEvaluatorBase
: public ExprEvaluatorBase<Derived> { … };
}
namespace {
class LValueExprEvaluator
: public LValueExprEvaluatorBase<LValueExprEvaluator> { … };
}
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result,
const CXXMethodDecl *MD, const FieldDecl *FD,
bool LValueToRValueConversion) { … }
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
bool InvalidBaseOK) { … }
bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { … }
bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { … }
bool LValueExprEvaluator::VisitCallExpr(const CallExpr *E) { … }
bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) { … }
bool
LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { … }
bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { … }
bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { … }
bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) { … }
bool LValueExprEvaluator::VisitExtVectorElementExpr(
const ExtVectorElementExpr *E) { … }
bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { … }
bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) { … }
bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { … }
bool LValueExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { … }
bool LValueExprEvaluator::VisitUnaryPreIncDec(const UnaryOperator *UO) { … }
bool LValueExprEvaluator::VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) { … }
bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) { … }
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
const CallExpr *Call,
llvm::APInt &Result) { … }
static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
const LValue &LVal,
llvm::APInt &Result) { … }
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base,
LValue &Result) { … }
namespace {
class PointerExprEvaluator
: public ExprEvaluatorBase<PointerExprEvaluator> { … };
}
static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info,
bool InvalidBaseOK) { … }
bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { … }
bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { … }
static bool IsDeclSourceLocationCurrent(const FunctionDecl *FD) { … }
bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
static CharUnits GetAlignOfType(EvalInfo &Info, QualType T,
UnaryExprOrTypeTrait ExprKind) { … }
static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E,
UnaryExprOrTypeTrait ExprKind) { … }
static CharUnits getBaseAlignment(EvalInfo &Info, const LValue &Value) { … }
static bool getAlignmentArgument(const Expr *E, QualType ForType,
EvalInfo &Info, APSInt &Alignment) { … }
bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) { … }
bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { … }
static bool isOneByteCharacterType(QualType T) { … }
bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned BuiltinOp) { … }
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
APValue &Result, const InitListExpr *ILE,
QualType AllocType);
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
APValue &Result,
const CXXConstructExpr *CCE,
QualType AllocType);
bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { … }
namespace {
class MemberPointerExprEvaluator
: public ExprEvaluatorBase<MemberPointerExprEvaluator> { … };
}
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
EvalInfo &Info) { … }
bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
bool MemberPointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) { … }
namespace {
class RecordExprEvaluator
: public ExprEvaluatorBase<RecordExprEvaluator> { … };
}
static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
const RecordDecl *RD,
const LValue &This, APValue &Result) { … }
bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) { … }
bool RecordExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) { … }
bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit, ArrayRef<Expr *> Args) { … }
bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
QualType T) { … }
bool RecordExprEvaluator::VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E) { … }
bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
const CXXStdInitializerListExpr *E) { … }
bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) { … }
static bool EvaluateRecord(const Expr *E, const LValue &This,
APValue &Result, EvalInfo &Info) { … }
namespace {
class TemporaryExprEvaluator
: public LValueExprEvaluatorBase<TemporaryExprEvaluator> { … };
}
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info) { … }
namespace {
class VectorExprEvaluator
: public ExprEvaluatorBase<VectorExprEvaluator> { … };
}
static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) { … }
bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
bool
VectorExprEvaluator::VisitInitListExpr(const InitListExpr *E) { … }
bool
VectorExprEvaluator::ZeroInitialization(const Expr *E) { … }
bool VectorExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { … }
bool VectorExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { … }
static std::optional<APValue> handleVectorUnaryOperator(ASTContext &Ctx,
QualType ResultTy,
UnaryOperatorKind Op,
APValue Elt) { … }
bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { … }
static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO,
const Expr *E, QualType SourceTy,
QualType DestTy, APValue const &Original,
APValue &Result) { … }
bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) { … }
static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E,
QualType ElemType, APValue const &VecVal1,
APValue const &VecVal2, unsigned EltNum,
APValue &Result) { … }
bool VectorExprEvaluator::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) { … }
namespace {
class ArrayExprEvaluator
: public ExprEvaluatorBase<ArrayExprEvaluator> { … };
}
static bool EvaluateArray(const Expr *E, const LValue &This,
APValue &Result, EvalInfo &Info) { … }
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
APValue &Result, const InitListExpr *ILE,
QualType AllocType) { … }
static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
APValue &Result,
const CXXConstructExpr *CCE,
QualType AllocType) { … }
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) { … }
bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E,
QualType AllocType) { … }
bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit, ArrayRef<Expr *> Args, const Expr *ArrayFiller,
QualType AllocType) { … }
bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) { … }
bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) { … }
bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
const LValue &Subobject,
APValue *Value,
QualType Type) { … }
bool ArrayExprEvaluator::VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E) { … }
namespace {
class IntExprEvaluator
: public ExprEvaluatorBase<IntExprEvaluator> { … };
class FixedPointExprEvaluator
: public ExprEvaluatorBase<FixedPointExprEvaluator> { … };
}
static bool EvaluateIntegerOrLValue(const Expr *E, APValue &Result,
EvalInfo &Info) { … }
static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info) { … }
bool IntExprEvaluator::VisitSourceLocExpr(const SourceLocExpr *E) { … }
static bool EvaluateFixedPoint(const Expr *E, APFixedPoint &Result,
EvalInfo &Info) { … }
static bool EvaluateFixedPointOrInteger(const Expr *E, APFixedPoint &Result,
EvalInfo &Info) { … }
bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { … }
GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
const LangOptions &LangOpts) { … }
static GCCTypeClass
EvaluateBuiltinClassifyType(const CallExpr *E, const LangOptions &LangOpts) { … }
static bool EvaluateBuiltinConstantPForLValue(const APValue &LV) { … }
static bool EvaluateBuiltinConstantP(EvalInfo &Info, const Expr *Arg) { … }
static QualType getObjectType(APValue::LValueBase B) { … }
static const Expr *ignorePointerCastsAndParens(const Expr *E) { … }
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { … }
static bool refersToCompleteObject(const LValue &LVal) { … }
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal) { … }
static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int,
CharUnits &Result) { … }
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T,
const LValue &LV, CharUnits &Size) { … }
static bool determineEndOffset(EvalInfo &Info, SourceLocation ExprLoc,
unsigned Type, const LValue &LVal,
CharUnits &EndOffset) { … }
static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
EvalInfo &Info, uint64_t &Size) { … }
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { … }
static bool getBuiltinAlignArguments(const CallExpr *E, EvalInfo &Info,
APValue &Val, APSInt &Alignment) { … }
bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned BuiltinOp) { … }
static bool isOnePastTheEndOfCompleteObject(const ASTContext &Ctx,
const LValue &LV) { … }
namespace {
class DataRecursiveIntBinOpEvaluator { … };
}
bool DataRecursiveIntBinOpEvaluator::
VisitBinOpLHSOnly(EvalResult &LHSResult, const BinaryOperator *E,
bool &SuppressRHSDiags) { … }
static void addOrSubLValueAsInteger(APValue &LVal, const APSInt &Index,
bool IsSub) { … }
bool DataRecursiveIntBinOpEvaluator::
VisitBinOp(const EvalResult &LHSResult, const EvalResult &RHSResult,
const BinaryOperator *E, APValue &Result) { … }
void DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) { … }
namespace {
enum class CmpResult { … };
}
template <class SuccessCB, class AfterCB>
static bool
EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
SuccessCB &&Success, AfterCB &&DoAfter) { … }
bool RecordExprEvaluator::VisitBinCmp(const BinaryOperator *E) { … }
bool RecordExprEvaluator::VisitCXXParenListInitExpr(
const CXXParenListInitExpr *E) { … }
bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { … }
bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E) { … }
bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) { … }
bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { … }
bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { … }
bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { … }
bool IntExprEvaluator::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { … }
bool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { … }
bool IntExprEvaluator::VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) { … }
bool IntExprEvaluator::VisitRequiresExpr(const RequiresExpr *E) { … }
bool FixedPointExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { … }
bool FixedPointExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
bool FixedPointExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { … }
namespace {
class FloatExprEvaluator
: public ExprEvaluatorBase<FloatExprEvaluator> { … };
}
static bool EvaluateFloat(const Expr* E, APFloat& Result, EvalInfo &Info) { … }
static bool TryEvaluateBuiltinNaN(const ASTContext &Context,
QualType ResultTy,
const Expr *Arg,
bool SNaN,
llvm::APFloat &Result) { … }
bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { … }
bool FloatExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { … }
bool FloatExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { … }
bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { … }
bool FloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { … }
bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) { … }
bool FloatExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
namespace {
class ComplexExprEvaluator
: public ExprEvaluatorBase<ComplexExprEvaluator> { … };
}
static bool EvaluateComplex(const Expr *E, ComplexValue &Result,
EvalInfo &Info) { … }
bool ComplexExprEvaluator::ZeroInitialization(const Expr *E) { … }
bool ComplexExprEvaluator::VisitImaginaryLiteral(const ImaginaryLiteral *E) { … }
bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { … }
void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
APFloat &ResR, APFloat &ResI) { … }
void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D,
APFloat &ResR, APFloat &ResI) { … }
bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { … }
bool ComplexExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { … }
bool ComplexExprEvaluator::VisitInitListExpr(const InitListExpr *E) { … }
bool ComplexExprEvaluator::VisitCallExpr(const CallExpr *E) { … }
namespace {
class AtomicExprEvaluator :
public ExprEvaluatorBase<AtomicExprEvaluator> { … };
}
static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
EvalInfo &Info) { … }
namespace {
class VoidExprEvaluator
: public ExprEvaluatorBase<VoidExprEvaluator> { … };
}
bool VoidExprEvaluator::VisitCXXDeleteExpr(const CXXDeleteExpr *E) { … }
static bool EvaluateVoid(const Expr *E, EvalInfo &Info) { … }
static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { … }
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
const Expr *E, bool AllowNonLiteralTypes) { … }
static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) { … }
static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
const ASTContext &Ctx, bool &IsConst) { … }
static bool hasUnacceptableSideEffect(Expr::EvalStatus &Result,
Expr::SideEffectsKind SEK) { … }
static bool EvaluateAsRValue(const Expr *E, Expr::EvalResult &Result,
const ASTContext &Ctx, EvalInfo &Info) { … }
static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
const ASTContext &Ctx,
Expr::SideEffectsKind AllowSideEffects,
EvalInfo &Info) { … }
static bool EvaluateAsFixedPoint(const Expr *E, Expr::EvalResult &ExprResult,
const ASTContext &Ctx,
Expr::SideEffectsKind AllowSideEffects,
EvalInfo &Info) { … }
bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
bool InConstantContext) const { … }
bool Expr::EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx,
bool InConstantContext) const { … }
bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects,
bool InConstantContext) const { … }
bool Expr::EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects,
bool InConstantContext) const { … }
bool Expr::EvaluateAsFloat(APFloat &Result, const ASTContext &Ctx,
SideEffectsKind AllowSideEffects,
bool InConstantContext) const { … }
bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
bool InConstantContext) const { … }
static bool EvaluateDestruction(const ASTContext &Ctx, APValue::LValueBase Base,
APValue DestroyedValue, QualType Type,
SourceLocation Loc, Expr::EvalStatus &EStatus,
bool IsConstantDestruction) { … }
bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
ConstantExprKind Kind) const { … }
bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
const VarDecl *VD,
SmallVectorImpl<PartialDiagnosticAt> &Notes,
bool IsConstantInitialization) const { … }
bool VarDecl::evaluateDestruction(
SmallVectorImpl<PartialDiagnosticAt> &Notes) const { … }
bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const { … }
APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx,
SmallVectorImpl<PartialDiagnosticAt> *Diag) const { … }
APSInt Expr::EvaluateKnownConstIntCheckOverflow(
const ASTContext &Ctx, SmallVectorImpl<PartialDiagnosticAt> *Diag) const { … }
void Expr::EvaluateForOverflow(const ASTContext &Ctx) const { … }
bool Expr::EvalResult::isGlobalLValue() const { … }
namespace {
enum ICEKind { … };
struct ICEDiag { … };
}
static ICEDiag NoDiag() { … }
static ICEDiag Worst(ICEDiag A, ICEDiag B) { … }
static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) { … }
static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { … }
static bool EvaluateCPlusPlus11IntegralConstantExpr(const ASTContext &Ctx,
const Expr *E,
llvm::APSInt *Value,
SourceLocation *Loc) { … }
bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc) const { … }
std::optional<llvm::APSInt>
Expr::getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc) const { … }
bool Expr::isCXX98IntegralConstantExpr(const ASTContext &Ctx) const { … }
bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result,
SourceLocation *Loc) const { … }
bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
const FunctionDecl *Callee,
ArrayRef<const Expr*> Args,
const Expr *This) const { … }
bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
SmallVectorImpl<
PartialDiagnosticAt> &Diags) { … }
bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
const FunctionDecl *FD,
SmallVectorImpl<
PartialDiagnosticAt> &Diags) { … }
bool Expr::tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx,
unsigned Type) const { … }static bool EvaluateBuiltinStrLen(const Expr *E, uint64_t &Result,
EvalInfo &Info, std::string *StringResult) { … }std::optional<std::string> Expr::tryEvaluateString(ASTContext &Ctx) const { … }bool Expr::EvaluateCharRangeAsString(std::string &Result,
const Expr *SizeExpression,
const Expr *PtrExpression, ASTContext &Ctx,
EvalResult &Status) const { … }bool Expr::tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const { … }struct IsWithinLifetimeHandler { … }std::optional<bool> EvaluateBuiltinIsWithinLifetime(IntExprEvaluator &IEE,
const CallExpr *E) { … }