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" 41 template <
unsigned Bits,
bool Signed>
struct Repr;
56 template <
unsigned Bits,
bool Signed>
class Integral {
58 template <
unsigned OtherBits,
bool OtherSigned>
friend class Integral;
69 template <
typename T>
explicit Integral(T V) : V(V) {}
76 template <
unsigned SrcBits,
bool SrcSign>
81 : V(V.isSigned() ? V.getSExtValue() : V.getZExtValue()) {}
91 return V >= 0 &&
static_cast<unsigned>(
V) > RHS;
97 template <
unsigned DstBits,
bool DstSign>
102 explicit operator unsigned()
const {
return V; }
103 explicit operator int64_t()
const {
return V; }
104 explicit operator uint64_t()
const {
return V; }
107 return APSInt(
APInt(Bits, static_cast<uint64_t>(V), Signed), !Signed);
111 return APSInt(toAPSInt().sextOrTrunc(NumBits), !Signed);
113 return APSInt(toAPSInt().zextOrTrunc(NumBits), !Signed);
121 constexpr
static unsigned bitWidth() {
return Bits; }
125 bool isMin()
const {
return *
this ==
min(bitWidth()); }
129 constexpr
static bool isSigned() {
return Signed; }
141 if (TruncBits >= Bits)
143 const T BitMask = (T(1) << T(TruncBits)) - 1;
144 const T SignBit = T(1) << (TruncBits - 1);
145 const T ExtMask = ~BitMask;
146 return Integral((V & BitMask) | (Signed && (V & SignBit) ? ExtMask : 0));
149 void print(llvm::raw_ostream &OS)
const { OS <<
V; }
158 template <
typename T>
159 static typename std::enable_if<std::is_integral<T>::value,
Integral>
::type 164 template <
unsigned SrcBits,
bool SrcSign>
172 return Integral(Value.V.getSExtValue());
174 return Integral(Value.V.getZExtValue());
184 return CheckRange<T, Min, Max>(
Value);
196 return CheckAddUB(A.V, B.V, R->V);
200 return CheckSubUB(A.V, B.V, R->V);
204 return CheckMulUB(A.V, B.V, R->V);
208 template <
typename T>
209 static typename std::enable_if<std::is_signed<T>::value,
bool>
::type 210 CheckAddUB(T A, T B, T &R) {
211 return llvm::AddOverflow<T>(A, B, R);
214 template <
typename T>
215 static typename std::enable_if<std::is_unsigned<T>::value,
bool>
::type 216 CheckAddUB(T A, T B, T &R) {
221 template <
typename T>
222 static typename std::enable_if<std::is_signed<T>::value,
bool>
::type 223 CheckSubUB(T A, T B, T &R) {
224 return llvm::SubOverflow<T>(A, B, R);
227 template <
typename T>
228 static typename std::enable_if<std::is_unsigned<T>::value,
bool>
::type 229 CheckSubUB(T A, T B, T &R) {
234 template <
typename T>
235 static typename std::enable_if<std::is_signed<T>::value,
bool>
::type 236 CheckMulUB(T A, T B, T &R) {
237 return llvm::MulOverflow<T>(A, B, R);
240 template <
typename T>
241 static typename std::enable_if<std::is_unsigned<T>::value,
bool>
::type 242 CheckMulUB(T A, T B, T &R) {
247 template <
typename T, T Min, T Max>
248 static typename std::enable_if<std::is_signed<T>::value,
bool>
::type 250 return Min <= V && V <= Max;
253 template <
typename T, T Min, T Max>
254 static typename std::enable_if<std::is_unsigned<T>::value,
bool>
::type 256 return V >= 0 &&
static_cast<uint64_t
>(
V) <= Max;
260 template <
unsigned Bits,
bool Signed>
261 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Integral<Bits, Signed> I) {
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
static bool mul(Integral A, Integral B, unsigned OpBits, Integral *R)
bool operator!=(Integral RHS) const
Wrapper around numeric types.
APValue toAPValue() const
ComparisonCategoryResult compare(const Integral &RHS) const
Integral operator~() const
static Integral max(unsigned NumBits)
static bool increment(Integral A, Integral *R)
Integral< Bits, false > toUnsigned() const
__DEVICE__ int max(int __a, int __b)
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
static bool sub(Integral A, Integral B, unsigned OpBits, Integral *R)
bool operator<(Integral RHS) const
Integral truncate(unsigned TruncBits) const
bool operator<=(Integral RHS) const
bool operator==(Integral RHS) const
static Integral from(Integral< 0, SrcSign > Value)
Integral(const APSInt &V)
Construct an integral from a value based on signedness.
static bool inRange(int64_t Value, unsigned NumBits)
static bool decrement(Integral A, Integral *R)
static std::enable_if< SrcBits !=0, Integral >::type from(Integral< SrcBits, SrcSign > Value)
static Integral min(unsigned NumBits)
static constexpr unsigned bitWidth()
void print(llvm::raw_ostream &OS) const
APSInt toAPSInt(unsigned NumBits) const
Integral operator-() const
static bool add(Integral A, Integral B, unsigned OpBits, Integral *R)
Integral(Integral< SrcBits, SrcSign > V)
Constructs an integral from another integral.
ComparisonCategoryResult Compare(const T &X, const T &Y)
Helper to compare two comparable types.
Dataflow Directional Tag Classes.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
bool operator>=(Integral RHS) const
unsigned countLeadingZeros() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
__DEVICE__ int min(int __a, int __b)
static constexpr bool isSigned()
bool operator>(unsigned RHS) const
Integral()
Zero-initializes an integral.
static std::enable_if< std::is_integral< T >::value, Integral >::type from(T Value)
static Integral from(T Value, unsigned NumBits)
bool operator>(Integral RHS) const