47 #ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H
48 #define LLVM_SUPPORT_TRAILINGOBJECTS_H
55 #include <type_traits>
59 namespace trailing_objects_internal {
65 FirstAlignment =
alignof(First),
71 Alignment = FirstAlignment > RestAlignment ? FirstAlignment : RestAlignment
77 enum { Alignment =
alignof(First) };
101 class LLVM_ALIGNAS(2) TrailingObjectsAligner<2> :
public TrailingObjectsBase {};
103 class LLVM_ALIGNAS(4) TrailingObjectsAligner<4> :
public TrailingObjectsBase {};
105 class LLVM_ALIGNAS(8) TrailingObjectsAligner<8> :
public TrailingObjectsBase {};
107 class LLVM_ALIGNAS(16) TrailingObjectsAligner<16> :
public TrailingObjectsBase {
110 class LLVM_ALIGNAS(32) TrailingObjectsAligner<32> :
public TrailingObjectsBase {
128 template <
int Align,
typename BaseTy,
typename TopTrailingObj,
typename PrevTy,
135 template <
int Align,
typename BaseTy,
typename TopTrailingObj,
typename PrevTy,
136 typename NextTy,
typename... MoreTys>
145 struct RequiresRealignment {
146 static const bool value =
alignof(PrevTy) <
alignof(NextTy);
149 static constexpr
bool requiresRealignment() {
150 return RequiresRealignment::value;
155 using ParentType::getTrailingObjectsImpl;
166 static const NextTy *
169 auto *
Ptr = TopTrailingObj::getTrailingObjectsImpl(
171 TopTrailingObj::callNumTrailingObjects(
174 if (requiresRealignment())
175 return reinterpret_cast<const NextTy *
>(
178 return reinterpret_cast<const NextTy *
>(
Ptr);
184 auto *
Ptr = TopTrailingObj::getTrailingObjectsImpl(
186 TopTrailingObj::callNumTrailingObjects(
189 if (requiresRealignment())
192 return reinterpret_cast<NextTy *
>(
Ptr);
199 size_t SizeSoFar,
size_t Count1,
201 return ParentType::additionalSizeToAllocImpl(
202 (requiresRealignment() ?
llvm::alignTo<
alignof(NextTy)>(SizeSoFar)
204 sizeof(NextTy) * Count1,
211 template <
int Align,
typename BaseTy,
typename TopTrailingObj,
typename PrevTy>
218 static void getTrailingObjectsImpl();
233 template <
typename BaseTy,
typename... TrailingTys>
235 trailing_objects_internal::AlignmentCalcHelper<
236 TrailingTys...>::Alignment,
237 BaseTy, TrailingObjects<BaseTy, TrailingTys...>,
238 BaseTy, TrailingTys...> {
240 template <
int A,
typename B,
typename T,
typename P,
typename... M>
243 template <
typename... Tys>
class Foo {};
247 BaseTy,
TrailingObjects<BaseTy, TrailingTys...>, BaseTy, TrailingTys...>
251 using ParentType::getTrailingObjectsImpl;
257 static void verifyTrailingObjectsAssertions() {
259 static_assert(LLVM_IS_FINAL(BaseTy),
"BaseTy must be final.");
264 static const BaseTy *
265 getTrailingObjectsImpl(
const BaseTy *Obj,
266 TrailingObjectsBase::OverloadToken<BaseTy>) {
271 getTrailingObjectsImpl(BaseTy *Obj,
272 TrailingObjectsBase::OverloadToken<BaseTy>) {
284 callNumTrailingObjects(
const BaseTy *Obj,
285 TrailingObjectsBase::OverloadToken<BaseTy>) {
289 template <
typename T>
290 static size_t callNumTrailingObjects(
const BaseTy *Obj,
291 TrailingObjectsBase::OverloadToken<T>) {
292 return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken<T>());
297 using ParentType::OverloadToken;
303 verifyTrailingObjectsAssertions();
306 return this->getTrailingObjectsImpl(
307 static_cast<const BaseTy *>(
this),
315 verifyTrailingObjectsAssertions();
318 return this->getTrailingObjectsImpl(
328 template <
typename... Tys>
329 static constexpr
typename std::enable_if<
330 std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value,
size_t>::type
332 TrailingTys,
size_t>::type... Counts) {
333 return ParentType::additionalSizeToAllocImpl(0, Counts...);
340 template <
typename... Tys>
341 static constexpr
typename std::enable_if<
342 std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value,
size_t>::type
344 TrailingTys,
size_t>::type... Counts) {
345 return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
365 enum { Size = totalSizeToAlloc<Tys...>(Counts...) };
375 assert(p &&
"FixedSizeStorageOwner owns null?");
379 BaseTy *
get() {
return p; }
380 const BaseTy *
get()
const {
return p; }
A type that acts as the owner for an object placed into fixed storage.
static void verifyTrailingObjectsAlignment()
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
A type where its ::with_counts template member has a ::type member suitable for use as uninitialized ...
This helper template works-around MSVC 2013's lack of useful alignas() support.
static constexpr std::enable_if< std::is_same< Foo< TrailingTys...>, Foo< Tys...> >::value, size_t >::type 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 ...
static constexpr std::enable_if< std::is_same< Foo< TrailingTys...>, Foo< Tys...> >::value, size_t >::type 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...
static const NextTy * getTrailingObjectsImpl(const BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
static NextTy * getTrailingObjectsImpl(BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
T * getTrailingObjects()
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
llvm::AlignedCharArray< alignof(BaseTy), Size > type
See the file comment for details on the usage of the TrailingObjects type.
uintptr_t alignAddr(const void *Addr, size_t Alignment)
Aligns Addr to Alignment bytes, rounding up.
The base class for TrailingObjects* classes.
#define LLVM_ALIGNAS(x)
LLVM_ALIGNAS
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar, size_t Count1, typename ExtractSecondType< MoreTys, size_t >::type...MoreCounts)
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Helper template to calculate the max alignment requirement for a set of objects.
FixedSizeStorageOwner(BaseTy *p)
Helper for building an aligned character array type.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
OverloadToken's purpose is to allow specifying function overloads for different types, without actually taking the types as parameters.