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) };
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())
190 return reinterpret_cast<NextTy *
>(
llvm::alignAddr(Ptr,
alignof(NextTy)));
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,
271 getTrailingObjectsImpl(BaseTy *Obj,
284 callNumTrailingObjects(
const BaseTy *Obj,
289 template <
typename T>
290 static size_t callNumTrailingObjects(
const BaseTy *Obj,
298 using ParentType::OverloadToken;
302 template <
typename T>
303 using OverloadToken =
typename ParentType::template OverloadToken<T>;
310 verifyTrailingObjectsAssertions();
313 return this->getTrailingObjectsImpl(
314 static_cast<const BaseTy *>(
this),
322 verifyTrailingObjectsAssertions();
325 return this->getTrailingObjectsImpl(
335 template <
typename... Tys>
336 static constexpr
typename std::enable_if<
337 std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value,
size_t>
::type 339 TrailingTys,
size_t>::
type... Counts) {
340 return ParentType::additionalSizeToAllocImpl(0, Counts...);
347 template <
typename... Tys>
348 static constexpr
typename std::enable_if<
349 std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value,
size_t>
::type 351 TrailingTys,
size_t>::
type... Counts) {
352 return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
372 enum {
Size = totalSizeToAlloc<Tys...>(Counts...) };
382 assert(p &&
"FixedSizeStorageOwner owns null?");
386 BaseTy *
get() {
return p; }
387 const BaseTy *
get()
const {
return p; }
A type that acts as the owner for an object placed into fixed storage.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
This class represents lattice values for constants.
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 GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static NextTy * getTrailingObjectsImpl(BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
T * getTrailingObjects()
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar, size_t Count1, typename ExtractSecondType< MoreTys, size_t >::type... MoreCounts)
llvm::AlignedCharArray< alignof(BaseTy), Size > type
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
See the file comment for details on the usage of the TrailingObjects type.
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...
uintptr_t alignAddr(const void *Addr, size_t Alignment)
Aligns Addr to Alignment bytes, rounding up.
The base class for TrailingObjects* classes.
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const NextTy * getTrailingObjectsImpl(const BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
Helper template to calculate the max alignment requirement for a set of objects.
FixedSizeStorageOwner(BaseTy *p)
Helper for building an aligned character array type.
OverloadToken's purpose is to allow specifying function overloads for different types, without actually taking the types as parameters.