File indexing completed on 2026-05-10 08:44:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef LLVM_SUPPORT_ALLOCATORBASE_H
0020 #define LLVM_SUPPORT_ALLOCATORBASE_H
0021
0022 #ifdef _MSC_VER
0023 #define LLVM_ALLOCATORHOLDER_EMPTYBASE __declspec(empty_bases)
0024 #else
0025 #define LLVM_ALLOCATORHOLDER_EMPTYBASE
0026 #endif
0027
0028 #include "llvm/Support/Compiler.h"
0029 #include "llvm/Support/MemAlloc.h"
0030 #include <type_traits>
0031
0032 namespace llvm {
0033
0034
0035
0036
0037
0038
0039
0040 template <typename DerivedT> class AllocatorBase {
0041 public:
0042
0043
0044 void *Allocate(size_t Size, size_t Alignment) {
0045 #ifdef __clang__
0046 static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
0047 &AllocatorBase::Allocate) !=
0048 static_cast<void *(DerivedT::*)(size_t, size_t)>(
0049 &DerivedT::Allocate),
0050 "Class derives from AllocatorBase without implementing the "
0051 "core Allocate(size_t, size_t) overload!");
0052 #endif
0053 return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
0054 }
0055
0056
0057
0058 void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
0059 #ifdef __clang__
0060 static_assert(
0061 static_cast<void (AllocatorBase::*)(const void *, size_t, size_t)>(
0062 &AllocatorBase::Deallocate) !=
0063 static_cast<void (DerivedT::*)(const void *, size_t, size_t)>(
0064 &DerivedT::Deallocate),
0065 "Class derives from AllocatorBase without implementing the "
0066 "core Deallocate(void *) overload!");
0067 #endif
0068 return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size, Alignment);
0069 }
0070
0071
0072
0073
0074
0075 template <typename T> T *Allocate(size_t Num = 1) {
0076 return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
0077 }
0078
0079
0080 template <typename T>
0081 std::enable_if_t<!std::is_same_v<std::remove_cv_t<T>, void>, void>
0082 Deallocate(T *Ptr, size_t Num = 1) {
0083 Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T), alignof(T));
0084 }
0085 };
0086
0087 class MallocAllocator : public AllocatorBase<MallocAllocator> {
0088 public:
0089 void Reset() {}
0090
0091 LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
0092 return allocate_buffer(Size, Alignment);
0093 }
0094
0095
0096 using AllocatorBase<MallocAllocator>::Allocate;
0097
0098 void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
0099 deallocate_buffer(const_cast<void *>(Ptr), Size, Alignment);
0100 }
0101
0102
0103 using AllocatorBase<MallocAllocator>::Deallocate;
0104
0105 void PrintStats() const {}
0106 };
0107
0108 namespace detail {
0109
0110 template <typename Alloc> class AllocatorHolder : Alloc {
0111 public:
0112 AllocatorHolder() = default;
0113 AllocatorHolder(const Alloc &A) : Alloc(A) {}
0114 AllocatorHolder(Alloc &&A) : Alloc(static_cast<Alloc &&>(A)) {}
0115 Alloc &getAllocator() { return *this; }
0116 const Alloc &getAllocator() const { return *this; }
0117 };
0118
0119 template <typename Alloc> class AllocatorHolder<Alloc &> {
0120 Alloc &A;
0121
0122 public:
0123 AllocatorHolder(Alloc &A) : A(A) {}
0124 Alloc &getAllocator() { return A; }
0125 const Alloc &getAllocator() const { return A; }
0126 };
0127
0128 }
0129
0130 }
0131
0132 #endif