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>
195template <
typename BaseTy,
typename... TrailingTys>
198 trailing_objects_internal::MaxAlignment<TrailingTys...>, BaseTy,
199 TrailingObjects<BaseTy, TrailingTys...>, BaseTy, TrailingTys...> {
201 template <
int A,
typename B,
typename T,
typename P,
typename... M>
204 template <
typename... Tys>
class Foo {};
212 using ParentType::getTrailingObjectsImpl;
214 template <
bool Strict>
static void verifyTrailingObjectsAssertions() {
218 static_assert(std::is_final<BaseTy>(),
"BaseTy must be final.");
223 static_assert(!Strict ||
sizeof...(TrailingTys) > 1,
224 "Use templated getTrailingObjects() only when there are "
225 "multiple trailing types");
229 static const BaseTy *
230 getTrailingObjectsImpl(
const BaseTy *Obj,
231 TrailingObjectsBase::OverloadToken<BaseTy>) {
236 getTrailingObjectsImpl(BaseTy *Obj,
237 TrailingObjectsBase::OverloadToken<BaseTy>) {
249 callNumTrailingObjects(
const BaseTy *Obj,
250 TrailingObjectsBase::OverloadToken<BaseTy>) {
254 template <
typename T>
255 static size_t callNumTrailingObjects(
const BaseTy *Obj,
256 TrailingObjectsBase::OverloadToken<T>) {
257 return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken<T>());
263 using ParentType::OverloadToken;
267 template <
typename T>
268 using OverloadToken =
typename ParentType::template OverloadToken<T>;
275 verifyTrailingObjectsAssertions<true>();
278 return this->getTrailingObjectsImpl(
279 static_cast<const BaseTy *
>(
this),
287 return const_cast<T *
>(
293 typename std::tuple_element_t<0, std::tuple<TrailingTys...>>;
296 static_assert(
sizeof...(TrailingTys) == 1,
297 "Can use non-templated getTrailingObjects() only when there "
298 "is a single trailing type");
299 verifyTrailingObjectsAssertions<false>();
300 return this->getTrailingObjectsImpl(
301 static_cast<const BaseTy *
>(
this),
330 verifyTrailingObjectsAssertions<false>();
331 return this->getTrailingObjectsImpl(
332 static_cast<const BaseTy *
>(
this),
338 ->getTrailingObjectsNonStrict<
T>());
341 template <
typename T>
346 template <
typename T>
357 template <
typename... Tys>
358 static constexpr std::enable_if_t<
359 std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>,
size_t>
361 TrailingTys,
size_t>::type... Counts) {
362 return ParentType::additionalSizeToAllocImpl(0, Counts...);
369 template <
typename... Tys>
370 static constexpr std::enable_if_t<
371 std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>,
size_t>
373 TrailingTys,
size_t>::type... Counts) {
374 return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
412 assert(p &&
"FixedSizeStorageOwner owns null?");
416 BaseTy *
get() {
return p; }
417 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
See the file comment for details on the usage of the TrailingObjects type.
TrailingObjects & operator=(TrailingObjects &&)=delete
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)
static void verifyTrailingObjectsAlignment()
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,...