46#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H 
   47#define LLVM_SUPPORT_TRAILINGOBJECTS_H 
   61template <
typename... 
T>
 
   90template <
int Align, 
typename BaseTy, 
typename TopTrailingObj, 
typename PrevTy,
 
   97template <
int Align, 
typename BaseTy, 
typename TopTrailingObj, 
typename PrevTy,
 
   98          typename NextTy, 
typename... MoreTys>
 
  107  struct RequiresRealignment {
 
  108    static const bool value = 
alignof(PrevTy) < 
alignof(NextTy);
 
  111  static constexpr bool requiresRealignment() {
 
  112    return RequiresRealignment::value;
 
  117  using ParentType::getTrailingObjectsImpl;
 
  128  static const NextTy *
 
  131    auto *
Ptr = TopTrailingObj::getTrailingObjectsImpl(
 
  133                TopTrailingObj::callNumTrailingObjects(
 
  136    if (requiresRealignment())
 
  137      return reinterpret_cast<const NextTy *
>(
 
  140      return reinterpret_cast<const NextTy *
>(
Ptr);
 
 
  146    auto *
Ptr = TopTrailingObj::getTrailingObjectsImpl(
 
  148                TopTrailingObj::callNumTrailingObjects(
 
  151    if (requiresRealignment())
 
  154      return reinterpret_cast<NextTy *
>(
Ptr);
 
 
  161      size_t SizeSoFar, 
size_t Count1,
 
  163    return ParentType::additionalSizeToAllocImpl(
 
  164        (requiresRealignment() ? 
llvm::alignTo<
alignof(NextTy)>(SizeSoFar)
 
  166            sizeof(NextTy) * Count1,
 
 
 
  173template <
int Align, 
typename BaseTy, 
typename TopTrailingObj, 
typename PrevTy>
 
 
  193template <
typename BaseTy, 
typename... TrailingTys>
 
  196          trailing_objects_internal::MaxAlignment<TrailingTys...>, BaseTy,
 
  197          TrailingObjects<BaseTy, TrailingTys...>, BaseTy, TrailingTys...> {
 
  199  template <
int A, 
typename B, 
typename T, 
typename P, 
typename... M>
 
  202  template <
typename... Tys> 
class Foo {};
 
  207  using ParentType::getTrailingObjectsImpl;
 
  209  template <
bool Strict> 
static void verifyTrailingObjectsAssertions() {
 
  213    static_assert(std::is_final<BaseTy>(), 
"BaseTy must be final.");
 
  218    static_assert(!Strict || 
sizeof...(TrailingTys) > 1,
 
  219                  "Use templated getTrailingObjects() only when there are " 
  220                  "multiple trailing types");
 
  224  static const BaseTy *
 
  225  getTrailingObjectsImpl(
const BaseTy *Obj,
 
  226                         TrailingObjectsBase::OverloadToken<BaseTy>) {
 
  231  getTrailingObjectsImpl(BaseTy *Obj,
 
  232                         TrailingObjectsBase::OverloadToken<BaseTy>) {
 
  244  callNumTrailingObjects(
const BaseTy *Obj,
 
  245                         TrailingObjectsBase::OverloadToken<BaseTy>) {
 
  249  template <
typename T>
 
  250  static size_t callNumTrailingObjects(
const BaseTy *Obj,
 
  251                                       TrailingObjectsBase::OverloadToken<T>) {
 
  252    return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken<T>());
 
  258  using ParentType::OverloadToken;
 
  262  template <
typename T>
 
  263  using OverloadToken = 
typename ParentType::template OverloadToken<T>;
 
  270    verifyTrailingObjectsAssertions<true>();
 
  273    return this->getTrailingObjectsImpl(
 
  274        static_cast<const BaseTy *
>(
this),
 
 
  282    return const_cast<T *
>(
 
 
  288      typename std::tuple_element_t<0, std::tuple<TrailingTys...>>;
 
  291    static_assert(
sizeof...(TrailingTys) == 1,
 
  292                  "Can use non-templated getTrailingObjects() only when there " 
  293                  "is a single trailing type");
 
  294    verifyTrailingObjectsAssertions<false>();
 
  295    return this->getTrailingObjectsImpl(
 
  296        static_cast<const BaseTy *
>(
this),
 
 
  325    verifyTrailingObjectsAssertions<false>();
 
  326    return this->getTrailingObjectsImpl(
 
  327        static_cast<const BaseTy *
>(
this),
 
 
  333                               ->getTrailingObjectsNonStrict<
T>());
 
 
  336  template <
typename T>
 
  341  template <
typename T>
 
  352  template <
typename... Tys>
 
  353  static constexpr std::enable_if_t<
 
  354      std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>, 
size_t>
 
  356                        TrailingTys, 
size_t>::type... Counts) {
 
  357    return ParentType::additionalSizeToAllocImpl(0, Counts...);
 
 
  364  template <
typename... Tys>
 
  365  static constexpr std::enable_if_t<
 
  366      std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>, 
size_t>
 
  368                   TrailingTys, 
size_t>::type... Counts) {
 
  369    return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
 
 
  407      assert(p && 
"FixedSizeStorageOwner owns null?");
 
 
  411    BaseTy *
get() { 
return p; }
 
  412    const BaseTy *
get()
 const { 
return p; }
 
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
A type that acts as the owner for an object placed into fixed storage.
FixedSizeStorageOwner(BaseTy *p)
const BaseTy * get() const
TrailingObjects & operator=(TrailingObjects &&)=delete
friend class trailing_objects_internal::TrailingObjectsImpl
const FirstTrailingType * getTrailingObjects() const
MutableArrayRef< T > getTrailingObjects(size_t N)
const T * getTrailingObjectsNonStrict() const
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
Returns the total size of an object if it were allocated with the given trailing object counts.
T * getTrailingObjectsNonStrict()
TrailingObjects & operator=(const TrailingObjects &)=delete
FirstTrailingType * getTrailingObjects()
ArrayRef< FirstTrailingType > getTrailingObjects(size_t N) const
ArrayRef< T > getTrailingObjectsNonStrict(size_t N) const
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > additionalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
Returns the size of the trailing data, if an object were allocated with the given counts (The counts ...
TrailingObjects(TrailingObjects &&)=delete
MutableArrayRef< T > getTrailingObjectsNonStrict(size_t N)
T * getTrailingObjects()
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
MutableArrayRef< FirstTrailingType > getTrailingObjects(size_t N)
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
ArrayRef< T > getTrailingObjects(size_t N) const
typename std::tuple_element_t< 0, std::tuple< TrailingTys... > > FirstTrailingType
TrailingObjects()=default
TrailingObjects(const TrailingObjects &)=delete
The base class for TrailingObjects* classes.
static const NextTy * getTrailingObjectsImpl(const BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar, size_t Count1, typename ExtractSecondType< MoreTys, size_t >::type... MoreCounts)
static NextTy * getTrailingObjectsImpl(BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
static void getTrailingObjectsImpl()
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar)
constexpr size_t MaxAlignment
This is an optimization pass for GlobalISel generic memory operations.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static constexpr Align Of()
Allow constructions of constexpr Align from types.
A type where its with_counts template member has a type member suitable for use as uninitialized stor...
OverloadToken's purpose is to allow specifying function overloads for different types,...