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"
30using APSInt = llvm::APSInt;
33template <
unsigned Bits,
bool Signed>
struct Repr;
48template <
unsigned Bits,
bool Signed>
class Integral final {
50 template <
unsigned OtherBits,
bool OtherSigned>
friend class Integral;
57 static const auto Min = std::numeric_limits<ReprT>::min();
58 static const auto Max = std::numeric_limits<ReprT>::max();
61 template <
typename T>
explicit Integral(T
V) :
V(
V) {}
68 template <
unsigned SrcBits,
bool SrcSign>
73 :
V(
V.
isSigned() ?
V.getSExtValue() :
V.getZExtValue()) {}
83 return V >= 0 &&
static_cast<unsigned>(
V) > RHS;
89 template <
unsigned DstBits,
bool DstSign>
95 explicit operator int64_t()
const {
return V; }
96 explicit operator uint64_t()
const {
return V; }
113 constexpr static unsigned bitWidth() {
return Bits; }
133 if (TruncBits >= Bits)
135 const ReprT BitMask = (ReprT(1) << ReprT(TruncBits)) - 1;
136 const ReprT SignBit = ReprT(1) << (TruncBits - 1);
137 const ReprT ExtMask = ~BitMask;
141 void print(llvm::raw_ostream &OS)
const { OS <<
V; }
151 if constexpr (std::is_integral<ValT>::value)
157 template <
unsigned SrcBits,
bool SrcSign>
158 static std::enable_if_t<SrcBits != 0, Integral>
164 if constexpr (SrcSign)
177 return CheckRange<ReprT, Min, Max>(
Value);
189 return CheckAddUB(A.V, B.V, R->V);
193 return CheckSubUB(A.V, B.V, R->V);
197 return CheckMulUB(A.V, B.V, R->V);
235 template <
unsigned RHSBits,
bool RHSSign>
241 template <
unsigned RHSBits,
bool RHSSign>
248 template <
typename T>
static bool CheckAddUB(T A, T B, T &R) {
249 if constexpr (std::is_signed_v<T>) {
250 return llvm::AddOverflow<T>(A, B, R);
257 template <
typename T>
static bool CheckSubUB(T A, T B, T &R) {
258 if constexpr (std::is_signed_v<T>) {
259 return llvm::SubOverflow<T>(A, B, R);
266 template <
typename T>
static bool CheckMulUB(T A, T B, T &R) {
267 if constexpr (std::is_signed_v<T>) {
268 return llvm::MulOverflow<T>(A, B, R);
274 template <
typename T, T Min, T Max>
static bool CheckRange(int64_t
V) {
275 if constexpr (std::is_signed_v<T>) {
276 return Min <=
V &&
V <= Max;
278 return V >= 0 &&
static_cast<uint64_t>(
V) <= Max;
283template <
unsigned Bits,
bool Signed>
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Wrapper around numeric types.
Integral< Bits, false > toUnsigned() const
APValue toAPValue() const
static Integral max(unsigned NumBits)
Integral()
Zero-initializes an integral.
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
unsigned countLeadingZeros() const
Integral operator~() const
Integral truncate(unsigned TruncBits) const
bool operator<(Integral RHS) const
ComparisonCategoryResult compare(const Integral &RHS) const
static Integral from(ValT Value)
static bool neg(Integral A, Integral *R)
bool operator!=(Integral RHS) 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)
APSInt toAPSInt(unsigned NumBits) const
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 Integral from(Integral< 0, SrcSign > Value)
static constexpr bool isSigned()
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)
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.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.