Skip to content

Commit f4853d7

Browse files
authored
[LLVM][Support] Add getTrailingObjects() for single trailing type (#138970)
Add a specialization of getTrailingObjects() for a single trailing type. This is a common case and with the specialization you don't need to specify the single trailing type redundantly. Also add an overload for getTrailingObjects which takes size and returns an ArryaRef/MutableArrayRef as that's a common use case as well.
1 parent a783edf commit f4853d7

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

llvm/include/llvm/Support/TrailingObjects.h

+36
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H
4747
#define LLVM_SUPPORT_TRAILINGOBJECTS_H
4848

49+
#include "llvm/ADT/ArrayRef.h"
4950
#include "llvm/Support/Alignment.h"
5051
#include "llvm/Support/Compiler.h"
5152
#include "llvm/Support/MathExtras.h"
@@ -301,6 +302,41 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
301302
static_cast<BaseTy *>(this), TrailingObjectsBase::OverloadToken<T>());
302303
}
303304

305+
// getTrailingObjects() specialization for a single trailing type.
306+
using FirstTrailingType =
307+
typename std::tuple_element_t<0, std::tuple<TrailingTys...>>;
308+
309+
const FirstTrailingType *getTrailingObjects() const {
310+
static_assert(sizeof...(TrailingTys) == 1,
311+
"Can use non-templated getTrailingObjects() only when there "
312+
"is a single trailing type");
313+
return getTrailingObjects<FirstTrailingType>();
314+
}
315+
316+
FirstTrailingType *getTrailingObjects() {
317+
static_assert(sizeof...(TrailingTys) == 1,
318+
"Can use non-templated getTrailingObjects() only when there "
319+
"is a single trailing type");
320+
return getTrailingObjects<FirstTrailingType>();
321+
}
322+
323+
// Functions that return the trailing objects as ArrayRefs.
324+
template <typename T> MutableArrayRef<T> getTrailingObjects(size_t N) {
325+
return MutableArrayRef(getTrailingObjects<T>(), N);
326+
}
327+
328+
template <typename T> ArrayRef<T> getTrailingObjects(size_t N) const {
329+
return ArrayRef(getTrailingObjects<T>(), N);
330+
}
331+
332+
MutableArrayRef<FirstTrailingType> getTrailingObjects(size_t N) {
333+
return MutableArrayRef(getTrailingObjects(), N);
334+
}
335+
336+
ArrayRef<FirstTrailingType> getTrailingObjects(size_t N) const {
337+
return ArrayRef(getTrailingObjects(), N);
338+
}
339+
304340
/// Returns the size of the trailing data, if an object were
305341
/// allocated with the given counts (The counts are in the same order
306342
/// as the template arguments). This does not include the size of the

llvm/unittests/Support/TrailingObjectsTest.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ class Class1 final : protected TrailingObjects<Class1, short> {
2626
size_t numTrailingObjects(OverloadToken<short>) const { return NumShorts; }
2727

2828
Class1(ArrayRef<int> ShortArray) : NumShorts(ShortArray.size()) {
29-
llvm::copy(ShortArray, getTrailingObjects<short>());
29+
// This tests the non-templated getTrailingObjects() that returns a pointer
30+
// when using a single trailing type.
31+
llvm::copy(ShortArray, getTrailingObjects());
3032
}
3133

3234
public:
@@ -36,7 +38,8 @@ class Class1 final : protected TrailingObjects<Class1, short> {
3638
}
3739
void operator delete(void *Ptr) { ::operator delete(Ptr); }
3840

39-
short get(unsigned Num) const { return getTrailingObjects<short>()[Num]; }
41+
// This indexes into the ArrayRef<> returned by `getTrailingObjects`.
42+
short get(unsigned Num) const { return getTrailingObjects(NumShorts)[Num]; }
4043

4144
unsigned numShorts() const { return NumShorts; }
4245

@@ -128,6 +131,9 @@ TEST(TrailingObjects, OneArg) {
128131
EXPECT_EQ(C->getTrailingObjects<short>(), reinterpret_cast<short *>(C + 1));
129132
EXPECT_EQ(C->get(0), 1);
130133
EXPECT_EQ(C->get(2), 3);
134+
135+
EXPECT_EQ(C->getTrailingObjects(), C->getTrailingObjects<short>());
136+
131137
delete C;
132138
}
133139

0 commit comments

Comments
 (0)