File indexing completed on 2026-05-10 08:43:07
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_ADT_POINTEREMBEDDEDINT_H
0010 #define LLVM_ADT_POINTEREMBEDDEDINT_H
0011
0012 #include "llvm/ADT/DenseMapInfo.h"
0013 #include "llvm/Support/MathExtras.h"
0014 #include "llvm/Support/PointerLikeTypeTraits.h"
0015 #include <cassert>
0016 #include <climits>
0017 #include <cstdint>
0018 #include <type_traits>
0019
0020 namespace llvm {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 template <typename IntT, int Bits = sizeof(IntT) * CHAR_BIT>
0033 class PointerEmbeddedInt {
0034 uintptr_t Value = 0;
0035
0036
0037
0038 static_assert(Bits < sizeof(uintptr_t) * CHAR_BIT,
0039 "Cannot embed more bits than we have in a pointer!");
0040
0041 enum : uintptr_t {
0042
0043
0044 Shift = sizeof(uintptr_t) * CHAR_BIT - Bits,
0045
0046
0047 Mask = static_cast<uintptr_t>(-1) << Bits
0048 };
0049
0050 struct RawValueTag {
0051 explicit RawValueTag() = default;
0052 };
0053
0054 friend struct PointerLikeTypeTraits<PointerEmbeddedInt>;
0055
0056 explicit PointerEmbeddedInt(uintptr_t Value, RawValueTag) : Value(Value) {}
0057
0058 public:
0059 PointerEmbeddedInt() = default;
0060
0061 PointerEmbeddedInt(IntT I) { *this = I; }
0062
0063 PointerEmbeddedInt &operator=(IntT I) {
0064 assert((std::is_signed<IntT>::value ? isInt<Bits>(I) : isUInt<Bits>(I)) &&
0065 "Integer has bits outside those preserved!");
0066 Value = static_cast<uintptr_t>(I) << Shift;
0067 return *this;
0068 }
0069
0070
0071
0072 operator IntT() const {
0073 if (std::is_signed<IntT>::value)
0074 return static_cast<IntT>(static_cast<intptr_t>(Value) >> Shift);
0075 return static_cast<IntT>(Value >> Shift);
0076 }
0077 };
0078
0079
0080
0081 template <typename IntT, int Bits>
0082 struct PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> {
0083 using T = PointerEmbeddedInt<IntT, Bits>;
0084
0085 static inline void *getAsVoidPointer(const T &P) {
0086 return reinterpret_cast<void *>(P.Value);
0087 }
0088
0089 static inline T getFromVoidPointer(void *P) {
0090 return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
0091 }
0092
0093 static inline T getFromVoidPointer(const void *P) {
0094 return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
0095 }
0096
0097 static constexpr int NumLowBitsAvailable = T::Shift;
0098 };
0099
0100
0101
0102 template <typename IntT, int Bits>
0103 struct DenseMapInfo<PointerEmbeddedInt<IntT, Bits>> {
0104 using T = PointerEmbeddedInt<IntT, Bits>;
0105 using IntInfo = DenseMapInfo<IntT>;
0106
0107 static inline T getEmptyKey() { return IntInfo::getEmptyKey(); }
0108 static inline T getTombstoneKey() { return IntInfo::getTombstoneKey(); }
0109
0110 static unsigned getHashValue(const T &Arg) {
0111 return IntInfo::getHashValue(Arg);
0112 }
0113
0114 static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; }
0115 };
0116
0117 }
0118
0119 #endif