13#ifndef LLVM_CLANG_AST_INTERP_INTEGRAL_H
14#define LLVM_CLANG_AST_INTERP_INTEGRAL_H
19#include "llvm/ADT/APSInt.h"
20#include "llvm/Support/MathExtras.h"
21#include "llvm/Support/raw_ostream.h"
32using APInt = llvm::APInt;
33using APSInt = llvm::APSInt;
38template <
unsigned Bits,
bool Signed>
struct Repr;
69template <
unsigned Bits,
bool Signed>
class Integral final {
70 static_assert(
Bits >= 16);
78 static_assert(std::is_trivially_copyable_v<ReprT>);
79 template <
unsigned OtherBits,
bool OtherSigned>
friend class Integral;
95 static const auto Min = std::numeric_limits<ReprT>::min();
96 static const auto Max = std::numeric_limits<ReprT>::max();
99 template <
typename T>
explicit Integral(T
V) :
V(
V) {}
100 template <
typename T>
101 explicit Integral(IntegralKind Kind, T
V) : Kind(Kind),
V(
V) {}
110 template <
unsigned SrcBits,
bool SrcSign>
150 :
V(
V.
isSigned() ?
V.getSExtValue() :
V.getZExtValue()) {}
159 return static_cast<unsigned>(
V) >= RHS;
163 return V >= 0 &&
static_cast<unsigned>(
V) > RHS;
172 template <
unsigned DstBits,
bool DstSign>
177 template <
typename Ty,
typename = std::enable_if_t<std::is_
integral_v<Ty>>>
178 explicit operator Ty()
const {
195 .sextOrTrunc(BitWidth);
198 .zextOrTrunc(BitWidth);
232 llvm_unreachable(
"Unhandled IntegralKind");
254 std::memcpy(Dest, &
V,
sizeof(
V));
258 assert(BitWidth ==
sizeof(
ReprT) * 8);
261 std::memcpy(&
V, Src,
sizeof(
ReprT));
267 llvm::raw_string_ostream OS(NameStr);
275 return llvm::countl_zero<ReprT>(
V);
277 return llvm::countl_zero<typename AsUnsigned::ReprT>(
279 llvm_unreachable(
"Don't call countLeadingZeros() on negative values.");
283 assert(TruncBits >= 1);
284 if (TruncBits >=
Bits)
287 const ReprT SignBit =
ReprT(1) << (TruncBits - 1);
288 const ReprT ExtMask = ~BitMask;
292 void print(llvm::raw_ostream &OS)
const {
301 OS <<
Ptr.P <<
" + " <<
Ptr.Offset <<
" (Address)";
304 OS <<
Ptr.P <<
" + " <<
Ptr.Offset <<
" (BlockAddress)";
307 OS <<
Ptr.P <<
" + " <<
Ptr.Offset <<
" (LabelAddress)";
310 OS <<
Ptr.P <<
" + " <<
Ptr.Offset <<
" (FunctionAddress)";
318 template <
typename ValT>
319 static std::enable_if_t<!std::is_same_v<ValT, IntegralKind>,
Integral>
320 from(ValT
V,
unsigned NumBits = 0) {
321 if constexpr (std::is_integral_v<ValT>)
327 template <
unsigned SrcBits,
bool SrcSign>
328 static std::enable_if_t<SrcBits != 0, Integral>
334 return Integral(
V.getLabel1(),
V.getLabel2());
339 return Integral(
V.getKind(),
V.getPtr(),
V.getOffset());
341 llvm_unreachable(
"Unhandled IntegralKind");
416 template <
unsigned RHSBits,
bool RHSSign>
422 template <
unsigned RHSBits,
bool RHSSign>
429template <
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 ...
AddrLabelExpr - The GNU address of label extension, representing &&label.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
This represents one expression.
Represents a function declaration or definition.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
A memory block, either on the stack or in the heap.
const Descriptor * getDescriptor() const
Returns the block's descriptor.
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
IntegralKind getKind() 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
struct clang::interp::Integral::@160043211265056200131370130202171044251230110336::@236040326051144126115245243244367376012363112306 AddrLabelDiff
typename Repr< Bits, Signed >::Type ReprT
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)
struct clang::interp::Integral::@160043211265056200131370130202171044251230110336::@320007000314117147377312357337153052223131102230 Ptr
ComparisonCategoryResult compare(const Integral &RHS) const
Integral< Bits, false > AsUnsigned
static bool neg(Integral A, Integral *R)
static Integral from(IntegralKind Kind, T V)
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.
bool operator<=(Integral RHS) const
const AddrLabelExpr * getLabel2() const
static bool div(Integral A, Integral B, unsigned OpBits, Integral *R)
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
static std::enable_if_t<!std::is_same_v< ValT, IntegralKind >, Integral > from(ValT V, unsigned NumBits=0)
Integral(const APSInt &V)
Construct an integral from a value based on signedness.
Integral(IntegralKind Kind, const void *P, OffsetT Offset=0)
Pointer integral of the given kind.
static std::enable_if_t< SrcBits !=0, Integral > from(Integral< SrcBits, SrcSign > V)
static Integral min(unsigned NumBits)
bool operator>=(unsigned RHS) const
const void * getPtr() const
const AddrLabelExpr * getLabel1() 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 bool add(Integral A, Integral B, unsigned OpBits, Integral *R)
static bool increment(Integral A, Integral *R)
Integral(const AddrLabelExpr *P1, const AddrLabelExpr *P2)
AddrLabelDiff integral.
static bool bitAnd(Integral A, Integral B, unsigned OpBits, Integral *R)
bool CheckMulUB(T A, T B, T &R)
@ BlockAddress
A pointer to an interp::Block.
@ AddrLabelDiff
Difference between two AddrLabelExpr.
@ Number
Just a number, nothing else.
@ Address
A pointer to a ValueDecl.
@ LabelAddress
A pointer to a AddrLabelExpr.
@ FunctionAddress
A pointer to a FunctionDecl.
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.
bool CheckSubUB(T A, T B, T &R)
bool CheckAddUB(T A, T B, T &R)
The JSON file list parser is used to communicate input to InstallAPI.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Other
Other implicit parameter.
__INTPTR_TYPE__ intptr_t
A signed integer type with the property that any valid pointer to void can be converted to this type,...
Describes a memory block created by an allocation site.
const ValueDecl * asValueDecl() const
const Expr * asExpr() const