Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:27

0001 //===- AllocatorBase.h - Simple memory allocation abstraction ---*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 /// \file
0009 ///
0010 /// This file defines MallocAllocator. MallocAllocator conforms to the LLVM
0011 /// "Allocator" concept which consists of an Allocate method accepting a size
0012 /// and alignment, and a Deallocate accepting a pointer and size. Further, the
0013 /// LLVM "Allocator" concept has overloads of Allocate and Deallocate for
0014 /// setting size and alignment based on the final type. These overloads are
0015 /// typically provided by a base class template \c AllocatorBase.
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 // _MSC_VER
0027 
0028 #include "llvm/Support/Compiler.h"
0029 #include "llvm/Support/MemAlloc.h"
0030 #include <type_traits>
0031 
0032 namespace llvm {
0033 
0034 /// CRTP base class providing obvious overloads for the core \c
0035 /// Allocate() methods of LLVM-style allocators.
0036 ///
0037 /// This base class both documents the full public interface exposed by all
0038 /// LLVM-style allocators, and redirects all of the overloads to a single core
0039 /// set of methods which the derived class must define.
0040 template <typename DerivedT> class AllocatorBase {
0041 public:
0042   /// Allocate \a Size bytes of \a Alignment aligned memory. This method
0043   /// must be implemented by \c DerivedT.
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   /// Deallocate \a Ptr to \a Size bytes of memory allocated by this
0057   /// allocator.
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   // The rest of these methods are helpers that redirect to one of the above
0072   // core methods.
0073 
0074   /// Allocate space for a sequence of objects without constructing them.
0075   template <typename T> T *Allocate(size_t Num = 1) {
0076     return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
0077   }
0078 
0079   /// Deallocate space for a sequence of objects without constructing them.
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   // Pull in base class overloads.
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   // Pull in base class overloads.
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 } // namespace detail
0129 
0130 } // namespace llvm
0131 
0132 #endif // LLVM_SUPPORT_ALLOCATORBASE_H