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;
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();
80 template <
typename T>
explicit Integral(
T V) : V(V) {}
89 template <
unsigned SrcBits,
bool SrcSign>
94 : V(V.
isSigned() ? V.getSExtValue() : V.getZExtValue()) {}
103 return static_cast<unsigned>(V) >= RHS;
107 return V >= 0 &&
static_cast<unsigned>(V) > RHS;
116 template <
unsigned DstBits,
bool DstSign>
121 template <
typename Ty,
typename = std::enable_if_t<std::is_
integral_v<Ty>>>
122 explicit operator Ty()
const {
135 .sextOrTrunc(BitWidth);
138 .zextOrTrunc(BitWidth);
164 std::memcpy(Dest, &V,
sizeof(V));
168 assert(BitWidth ==
sizeof(ReprT) * 8);
171 std::memcpy(&V, Src,
sizeof(ReprT));
177 llvm::raw_string_ostream OS(NameStr);
184 return llvm::countl_zero<ReprT>(V);
186 return llvm::countl_zero<typename AsUnsigned::ReprT>(
187 static_cast<typename AsUnsigned::ReprT
>(V));
188 llvm_unreachable(
"Don't call countLeadingZeros() on negative values.");
192 assert(TruncBits >= 1);
193 if (TruncBits >=
Bits)
195 const ReprT BitMask = (ReprT(1) << ReprT(TruncBits)) - 1;
196 const ReprT SignBit = ReprT(1) << (TruncBits - 1);
197 const ReprT ExtMask = ~BitMask;
198 return Integral((V & BitMask) | (
Signed && (V & SignBit) ? ExtMask : 0));
201 void print(llvm::raw_ostream &OS)
const { OS << V; }
207 if constexpr (std::is_integral<ValT>::value)
213 template <
unsigned SrcBits,
bool SrcSign>
214 static std::enable_if_t<SrcBits != 0, Integral>
226 return CheckRange<ReprT, Min, Max>(
Value);
238 return CheckAddUB(A.V, B.V, R->V);
242 return CheckSubUB(A.V, B.V, R->V);
246 return CheckMulUB(A.V, B.V, R->V);
287 template <
unsigned RHSBits,
bool RHSSign>
293 template <
unsigned RHSBits,
bool RHSSign>
300 template <
typename T>
static bool CheckAddUB(
T A,
T B,
T &R) {
301 if constexpr (std::is_signed_v<T>) {
302 return llvm::AddOverflow<T>(A, B, R);
309 template <
typename T>
static bool CheckSubUB(
T A,
T B,
T &R) {
310 if constexpr (std::is_signed_v<T>) {
311 return llvm::SubOverflow<T>(A, B, R);
318 template <
typename T>
static bool CheckMulUB(
T A,
T B,
T &R) {
319 if constexpr (std::is_signed_v<T>) {
320 return llvm::MulOverflow<T>(A, B, R);
321 }
else if constexpr (
sizeof(
T) <
sizeof(
int)) {
324 R =
static_cast<T>(
static_cast<unsigned>(A) *
static_cast<unsigned>(B));
331 template <
typename T, T Min, T Max>
static bool CheckRange(int64_t V) {
332 if constexpr (std::is_signed_v<T>) {
333 return Min <= V && V <= Max;
335 return V >= 0 &&
static_cast<uint64_t>(V) <= Max;
340template <
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 ...
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
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)
Integral< Bits, false > AsUnsigned
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)
bool operator>=(unsigned RHS) const
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.