LLVM: include/llvm/Support/TrailingObjects.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H
47#define LLVM_SUPPORT_TRAILINGOBJECTS_H
48
54#include
55#include <type_traits>
56
57namespace llvm {
58
60
61template <typename... T>
62inline constexpr size_t MaxAlignment = std::max({alignof(T)...});
63
64
66protected:
67
68
69
70
71
73};
74
75
76
77
81
82
83
84
85
86
87
88
89
90template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy,
91 typename... MoreTys>
96
97template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy,
98 typename NextTy, typename... MoreTys>
100 MoreTys...>
102 MoreTys...> {
103
104 using ParentType =
106
107 struct RequiresRealignment {
108 static const bool value = alignof(PrevTy) < alignof(NextTy);
109 };
110
111 static constexpr bool requiresRealignment() {
112 return RequiresRealignment::value;
113 }
114
115protected:
116
117 using ParentType::getTrailingObjectsImpl;
118
119
120
121
122
123
124
125
126
127
128 static const NextTy *
131 auto *Ptr = TopTrailingObj::getTrailingObjectsImpl(
133 TopTrailingObj::callNumTrailingObjects(
135
136 if (requiresRealignment())
137 return reinterpret_cast<const NextTy *>(
139 else
140 return reinterpret_cast<const NextTy *>(Ptr);
141 }
142
143 static NextTy *
146 auto *Ptr = TopTrailingObj::getTrailingObjectsImpl(
148 TopTrailingObj::callNumTrailingObjects(
150
151 if (requiresRealignment())
153 else
154 return reinterpret_cast<NextTy *>(Ptr);
155 }
156
157
158
159
161 size_t SizeSoFar, size_t Count1,
163 return ParentType::additionalSizeToAllocImpl(
164 (requiresRealignment() ? llvm::alignTo<alignof(NextTy)>(SizeSoFar)
165 : SizeSoFar) +
166 sizeof(NextTy) * Count1,
167 MoreCounts...);
168 }
169};
170
171
172
173template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy>
176protected:
177
178
179
181
183 return SizeSoFar;
184 }
185};
186
187}
188
189
190
191
192
193template <typename BaseTy, typename... TrailingTys>
196 trailing_objects_internal::MaxAlignment<TrailingTys...>, BaseTy,
197 TrailingObjects<BaseTy, TrailingTys...>, BaseTy, TrailingTys...> {
198
199 template <int A, typename B, typename T, typename P, typename... M>
201
202 template <typename... Tys> class Foo {};
203
206
207 using ParentType::getTrailingObjectsImpl;
208
209 template static void verifyTrailingObjectsAssertions() {
210
211
212
213 static_assert(std::is_final(), "BaseTy must be final.");
214
215
216
217
218 static_assert(!Strict || sizeof...(TrailingTys) > 1,
219 "Use templated getTrailingObjects() only when there are "
220 "multiple trailing types");
221 }
222
223
224 static const BaseTy *
225 getTrailingObjectsImpl(const BaseTy *Obj,
226 TrailingObjectsBase::OverloadToken) {
227 return Obj;
228 }
229
230 static BaseTy *
231 getTrailingObjectsImpl(BaseTy *Obj,
232 TrailingObjectsBase::OverloadToken) {
233 return Obj;
234 }
235
236
237
238
239
240
241
242
243 static size_t
244 callNumTrailingObjects(const BaseTy *Obj,
245 TrailingObjectsBase::OverloadToken) {
246 return 1;
247 }
248
249 template
250 static size_t callNumTrailingObjects(const BaseTy *Obj,
251 TrailingObjectsBase::OverloadToken) {
252 return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken());
253 }
254
255public:
256
257#ifndef _MSC_VER
258 using ParentType::OverloadToken;
259#else
260
261
262 template
263 using OverloadToken = typename ParentType::template OverloadToken;
264#endif
265
266
267
268
270 verifyTrailingObjectsAssertions();
271
272
273 return this->getTrailingObjectsImpl(
274 static_cast<const BaseTy *>(this),
276 }
277
278
279
280
282 return const_cast<T *>(
283 static_cast<const TrailingObjects *>(this)->getTrailingObjects<T>());
284 }
285
286
288 typename std::tuple_element_t<0, std::tuple<TrailingTys...>>;
289
291 static_assert(sizeof...(TrailingTys) == 1,
292 "Can use non-templated getTrailingObjects() only when there "
293 "is a single trailing type");
294 verifyTrailingObjectsAssertions();
295 return this->getTrailingObjectsImpl(
296 static_cast<const BaseTy *>(this),
298 }
299
302 static_cast<const TrailingObjects *>(this)->getTrailingObjects());
303 }
304
305
309
313
317
321
322
323
325 verifyTrailingObjectsAssertions();
326 return this->getTrailingObjectsImpl(
327 static_cast<const BaseTy *>(this),
329 }
330
332 return const_cast<T *>(static_cast<const TrailingObjects *>(this)
333 ->getTrailingObjectsNonStrict<T>());
334 }
335
336 template
340
341 template
345
346
347
348
349
350
351
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...);
358 }
359
360
361
362
363
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...);
370 }
371
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
401
402
404 public:
407 assert(p && "FixedSizeStorageOwner owns null?");
408 p->~BaseTy();
409 }
410
411 BaseTy *get() { return p; }
412 const BaseTy *get() const { return p; }
413
414 private:
419
420 BaseTy *const p;
421 };
422};
423
424}
425
426#endif
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.
Definition TrailingObjects.h:403
FixedSizeStorageOwner(BaseTy *p)
Definition TrailingObjects.h:405
BaseTy * get()
Definition TrailingObjects.h:411
const BaseTy * get() const
Definition TrailingObjects.h:412
~FixedSizeStorageOwner()
Definition TrailingObjects.h:406
TrailingObjects & operator=(TrailingObjects &&)=delete
friend class trailing_objects_internal::TrailingObjectsImpl
Definition TrailingObjects.h:200
const FirstTrailingType * getTrailingObjects() const
Definition TrailingObjects.h:290
MutableArrayRef< T > getTrailingObjects(size_t N)
Definition TrailingObjects.h:306
const T * getTrailingObjectsNonStrict() const
Definition TrailingObjects.h:324
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.
Definition TrailingObjects.h:367
T * getTrailingObjectsNonStrict()
Definition TrailingObjects.h:331
TrailingObjects & operator=(const TrailingObjects &)=delete
FirstTrailingType * getTrailingObjects()
Definition TrailingObjects.h:300
ArrayRef< FirstTrailingType > getTrailingObjects(size_t N) const
Definition TrailingObjects.h:318
ArrayRef< T > getTrailingObjectsNonStrict(size_t N) const
Definition TrailingObjects.h:342
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 ...
Definition TrailingObjects.h:355
TrailingObjects(TrailingObjects &&)=delete
MutableArrayRef< T > getTrailingObjectsNonStrict(size_t N)
Definition TrailingObjects.h:337
T * getTrailingObjects()
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
Definition TrailingObjects.h:281
MutableArrayRef< FirstTrailingType > getTrailingObjects(size_t N)
Definition TrailingObjects.h:314
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
Definition TrailingObjects.h:269
ArrayRef< T > getTrailingObjects(size_t N) const
Definition TrailingObjects.h:310
typename std::tuple_element_t< 0, std::tuple< TrailingTys... > > FirstTrailingType
Definition TrailingObjects.h:287
TrailingObjects()=default
TrailingObjects(const TrailingObjects &)=delete
The base class for TrailingObjects* classes.
Definition TrailingObjects.h:65
static const NextTy * getTrailingObjectsImpl(const BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
Definition TrailingObjects.h:129
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar, size_t Count1, typename ExtractSecondType< MoreTys, size_t >::type... MoreCounts)
Definition TrailingObjects.h:160
static NextTy * getTrailingObjectsImpl(BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
Definition TrailingObjects.h:144
static void getTrailingObjectsImpl()
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar)
Definition TrailingObjects.h:182
Definition TrailingObjects.h:92
Definition TrailingObjects.h:59
constexpr size_t MaxAlignment
Definition TrailingObjects.h:62
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.
Definition TrailingObjects.h:396
char buffer[Size]
Definition TrailingObjects.h:397
Definition TrailingObjects.h:394
@ Size
Definition TrailingObjects.h:395
A type where its with_counts template member has a type member suitable for use as uninitialized stor...
Definition TrailingObjects.h:393
OverloadToken's purpose is to allow specifying function overloads for different types,...
Definition TrailingObjects.h:72