13#ifndef LLVM_CLANG_AST_INTERP_INTEGRAL_H
14#define LLVM_CLANG_AST_INTERP_INTEGRAL_H
18#include "llvm/ADT/APSInt.h"
19#include "llvm/Support/MathExtras.h"
20#include "llvm/Support/raw_ostream.h"
29using APInt = llvm::APInt;
30using APSInt = llvm::APSInt;
32template <
bool Signed>
class IntegralAP;
35template <
unsigned Bits,
bool Signed>
struct Repr;
66template <
unsigned Bits,
bool Signed>
class Integral final {
68 template <
unsigned OtherBits,
bool OtherSigned>
friend class Integral;
73 static_assert(std::is_trivially_copyable_v<ReprT>);
76 static const auto Min = std::numeric_limits<ReprT>::min();
77 static const auto Max = std::numeric_limits<ReprT>::max();
89 template <
unsigned SrcBits,
bool SrcSign>
94 :
V(
V.
isSigned() ?
V.getSExtValue() :
V.getZExtValue()) {}
104 return V >= 0 &&
static_cast<unsigned>(
V) > RHS;
113 template <
unsigned DstBits,
bool DstSign>
118 template <
typename Ty,
typename = std::enable_if_t<std::is_
integral_v<Ty>>>
119 explicit operator Ty()
const {
132 .sextOrTrunc(BitWidth);
135 .zextOrTrunc(BitWidth);
161 std::memcpy(Dest, &
V,
sizeof(
V));
165 assert(BitWidth ==
sizeof(ReprT) * 8);
168 std::memcpy(&
V, Src,
sizeof(ReprT));
174 llvm::raw_string_ostream OS(NameStr);
181 return llvm::countl_zero<ReprT>(
V);
183 return llvm::countl_zero<typename AsUnsigned::ReprT>(
184 static_cast<typename AsUnsigned::ReprT
>(
V));
185 llvm_unreachable(
"Don't call countLeadingZeros() on negative values.");
189 assert(TruncBits >= 1);
190 if (TruncBits >=
Bits)
192 const ReprT BitMask = (ReprT(1) << ReprT(TruncBits)) - 1;
193 const ReprT SignBit = ReprT(1) << (TruncBits - 1);
194 const ReprT ExtMask = ~BitMask;
198 void print(llvm::raw_ostream &OS)
const { OS <<
V; }
204 if constexpr (std::is_integral<ValT>::value)
210 template <
unsigned SrcBits,
bool SrcSign>
211 static std::enable_if_t<SrcBits != 0, Integral>
223 return CheckRange<ReprT, Min, Max>(
Value);
235 return CheckAddUB(A.V, B.V, R->V);
239 return CheckSubUB(A.V, B.V, R->V);
243 return CheckMulUB(A.V, B.V, R->V);
284 template <
unsigned RHSBits,
bool RHSSign>
290 template <
unsigned RHSBits,
bool RHSSign>
297 template <
typename T>
static bool CheckAddUB(
T A,
T B,
T &R) {
298 if constexpr (std::is_signed_v<T>) {
299 return llvm::AddOverflow<T>(A, B, R);
306 template <
typename T>
static bool CheckSubUB(
T A,
T B,
T &R) {
307 if constexpr (std::is_signed_v<T>) {
308 return llvm::SubOverflow<T>(A, B, R);
315 template <
typename T>
static bool CheckMulUB(
T A,
T B,
T &R) {
316 if constexpr (std::is_signed_v<T>) {
317 return llvm::MulOverflow<T>(A, B, R);
323 template <
typename T, T Min, T Max>
static bool CheckRange(int64_t
V) {
324 if constexpr (std::is_signed_v<T>) {
325 return Min <=
V &&
V <= Max;
327 return V >= 0 &&
static_cast<uint64_t>(
V) <= Max;
332template <
unsigned Bits,
bool Signed>
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Wrapper around numeric types.
static Integral bitcastFromMemory(const std::byte *Src, unsigned BitWidth)
Integral< Bits, false > toUnsigned() const
static Integral max(unsigned NumBits)
Integral()
Zero-initializes an integral.
std::string toDiagnosticString(const ASTContext &Ctx) const
static bool mul(Integral A, Integral B, unsigned OpBits, Integral *R)
bool operator>=(Integral RHS) const
void print(llvm::raw_ostream &OS) const
static bool sub(Integral A, Integral B, unsigned OpBits, Integral *R)
static constexpr unsigned bitWidth()
static void shiftRight(const Integral A, const Integral< RHSBits, RHSSign > B, unsigned OpBits, Integral *R)
bool operator>(Integral RHS) const
bool operator>(unsigned RHS) const
Integral operator-(const Integral &Other) const
unsigned countLeadingZeros() const
Integral operator~() const
Integral truncate(unsigned TruncBits) const
bool operator<(Integral RHS) const
static Integral zero(unsigned BitWidth=0)
ComparisonCategoryResult compare(const Integral &RHS) const
static Integral from(ValT Value)
static bool neg(Integral A, Integral *R)
bool operator!=(Integral RHS) const
APValue toAPValue(const ASTContext &) const
APSInt toAPSInt(unsigned BitWidth) const
static bool decrement(Integral A, Integral *R)
static bool comp(Integral A, Integral *R)
Integral(Integral< SrcBits, SrcSign > V)
Constructs an integral from another integral.
static Integral from(T Value, unsigned NumBits)
bool operator<=(Integral RHS) const
static bool div(Integral A, Integral B, unsigned OpBits, Integral *R)
static bool inRange(int64_t Value, unsigned NumBits)
static bool bitXor(Integral A, Integral B, unsigned OpBits, Integral *R)
static bool rem(Integral A, Integral B, unsigned OpBits, Integral *R)
bool operator==(Integral RHS) const
Integral(const APSInt &V)
Construct an integral from a value based on signedness.
static Integral min(unsigned NumBits)
static constexpr bool isSigned()
APInt toAPInt(unsigned BitWidth) const
static void shiftLeft(const Integral A, const Integral< RHSBits, RHSSign > B, unsigned OpBits, Integral *R)
static bool bitOr(Integral A, Integral B, unsigned OpBits, Integral *R)
void bitcastToMemory(std::byte *Dest) const
Integral operator-() const
static std::enable_if_t< SrcBits !=0, Integral > from(Integral< SrcBits, SrcSign > Value)
static bool add(Integral A, Integral B, unsigned OpBits, Integral *R)
static bool increment(Integral A, Integral *R)
static bool bitAnd(Integral A, Integral B, unsigned OpBits, Integral *R)
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
ComparisonCategoryResult Compare(const T &X, const T &Y)
Helper to compare two comparable types.
The JSON file list parser is used to communicate input to InstallAPI.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
const FunctionProtoType * T
@ Other
Other implicit parameter.