File indexing completed on 2026-05-10 08:44:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
0015 #define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
0016
0017 #include "llvm/Support/DataTypes.h"
0018 #include <cassert>
0019 #include <type_traits>
0020
0021 namespace llvm {
0022
0023
0024
0025 template <typename T> struct PointerLikeTypeTraits;
0026
0027 namespace detail {
0028
0029 template <size_t N>
0030 struct ConstantLog2
0031 : std::integral_constant<size_t, ConstantLog2<N / 2>::value + 1> {};
0032 template <> struct ConstantLog2<1> : std::integral_constant<size_t, 0> {};
0033
0034
0035 template <typename T, typename U = void> struct HasPointerLikeTypeTraits {
0036 static const bool value = false;
0037 };
0038
0039
0040 template <typename T>
0041 struct HasPointerLikeTypeTraits<
0042 T, decltype((sizeof(PointerLikeTypeTraits<T>) + sizeof(T)), void())> {
0043 static const bool value = true;
0044 };
0045
0046 template <typename T> struct IsPointerLike {
0047 static const bool value = HasPointerLikeTypeTraits<T>::value;
0048 };
0049
0050 template <typename T> struct IsPointerLike<T *> {
0051 static const bool value = true;
0052 };
0053 }
0054
0055
0056 template <typename T> struct PointerLikeTypeTraits<T *> {
0057 static inline void *getAsVoidPointer(T *P) { return P; }
0058 static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); }
0059
0060 static constexpr int NumLowBitsAvailable =
0061 detail::ConstantLog2<alignof(T)>::value;
0062 };
0063
0064 template <> struct PointerLikeTypeTraits<void *> {
0065 static inline void *getAsVoidPointer(void *P) { return P; }
0066 static inline void *getFromVoidPointer(void *P) { return P; }
0067
0068
0069
0070
0071
0072
0073
0074
0075 static constexpr int NumLowBitsAvailable = 2;
0076 };
0077
0078
0079 template <typename T> struct PointerLikeTypeTraits<const T> {
0080 typedef PointerLikeTypeTraits<T> NonConst;
0081
0082 static inline const void *getAsVoidPointer(const T P) {
0083 return NonConst::getAsVoidPointer(P);
0084 }
0085 static inline const T getFromVoidPointer(const void *P) {
0086 return NonConst::getFromVoidPointer(const_cast<void *>(P));
0087 }
0088 static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
0089 };
0090
0091
0092 template <typename T> struct PointerLikeTypeTraits<const T *> {
0093 typedef PointerLikeTypeTraits<T *> NonConst;
0094
0095 static inline const void *getAsVoidPointer(const T *P) {
0096 return NonConst::getAsVoidPointer(const_cast<T *>(P));
0097 }
0098 static inline const T *getFromVoidPointer(const void *P) {
0099 return NonConst::getFromVoidPointer(const_cast<void *>(P));
0100 }
0101 static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
0102 };
0103
0104
0105 template <> struct PointerLikeTypeTraits<uintptr_t> {
0106 static inline void *getAsVoidPointer(uintptr_t P) {
0107 return reinterpret_cast<void *>(P);
0108 }
0109 static inline uintptr_t getFromVoidPointer(void *P) {
0110 return reinterpret_cast<uintptr_t>(P);
0111 }
0112
0113 static constexpr int NumLowBitsAvailable = 0;
0114 };
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 template <int Alignment, typename FunctionPointerT>
0125 struct FunctionPointerLikeTypeTraits {
0126 static constexpr int NumLowBitsAvailable =
0127 detail::ConstantLog2<Alignment>::value;
0128 static inline void *getAsVoidPointer(FunctionPointerT P) {
0129 assert((reinterpret_cast<uintptr_t>(P) &
0130 ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 &&
0131 "Alignment not satisfied for an actual function pointer!");
0132 return reinterpret_cast<void *>(P);
0133 }
0134 static inline FunctionPointerT getFromVoidPointer(void *P) {
0135 return reinterpret_cast<FunctionPointerT>(P);
0136 }
0137 };
0138
0139
0140
0141
0142
0143
0144
0145
0146 template <typename ReturnT, typename... ParamTs>
0147 struct PointerLikeTypeTraits<ReturnT (*)(ParamTs...)>
0148 : FunctionPointerLikeTypeTraits<4, ReturnT (*)(ParamTs...)> {};
0149
0150 }
0151
0152 #endif