Skip to content

Commit 600296a

Browse files
committed
[LLVM][Support] Add getTrailingObjects() for single trailing type
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 e0e3d05 commit 600296a

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

llvm/include/llvm/Support/TrailingObjects.h

Lines changed: 36 additions & 0 deletions
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 {getTrailingObjects<T>(), N};
326+
}
327+
328+
template <typename T> ArrayRef<T> getTrailingObjects(size_t N) const {
329+
return {getTrailingObjects<T>(), N};
330+
}
331+
332+
MutableArrayRef<FirstTrailingType> getTrailingObjects(size_t N) {
333+
return {getTrailingObjects(), N};
334+
}
335+
336+
ArrayRef<FirstTrailingType> getTrailingObjects(size_t N) const {
337+
return {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

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@
1414
using namespace llvm;
1515

1616
namespace {
17-
// This class, beyond being used by the test case, a nice
18-
// demonstration of the intended usage of TrailingObjects, with a
19-
// single trailing array.
20-
class Class1 final : protected TrailingObjects<Class1, short> {
17+
// This class, beyond being used by the test case, a nice demonstration of the
18+
// intended usage of TrailingObjects, with a single trailing array.
19+
class Class1 final : private TrailingObjects<Class1, short> {
2120
friend TrailingObjects;
2221

2322
unsigned NumShorts;
2423

2524
protected:
26-
size_t numTrailingObjects(OverloadToken<short>) const { return NumShorts; }
27-
2825
Class1(ArrayRef<int> ShortArray) : NumShorts(ShortArray.size()) {
29-
llvm::copy(ShortArray, getTrailingObjects<short>());
26+
// This tests the non-templated getTrailingObjects() when using a single
27+
// trailing type.
28+
llvm::copy(ShortArray, getTrailingObjects());
29+
EXPECT_EQ(getTrailingObjects(), getTrailingObjects<short>());
3030
}
3131

3232
public:
@@ -36,7 +36,8 @@ class Class1 final : protected TrailingObjects<Class1, short> {
3636
}
3737
void operator delete(void *Ptr) { ::operator delete(Ptr); }
3838

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

4142
unsigned numShorts() const { return NumShorts; }
4243

@@ -49,9 +50,9 @@ class Class1 final : protected TrailingObjects<Class1, short> {
4950
using TrailingObjects::getTrailingObjects;
5051
};
5152

52-
// Here, there are two singular optional object types appended. Note
53-
// that the alignment of Class2 is automatically increased to account
54-
// for the alignment requirements of the trailing objects.
53+
// Here, there are two singular optional object types appended. Note that the
54+
// alignment of Class2 is automatically increased to account for the alignment
55+
// requirements of the trailing objects.
5556
class Class2 final : protected TrailingObjects<Class2, double, short> {
5657
friend TrailingObjects;
5758

@@ -172,10 +173,9 @@ TEST(TrailingObjects, TwoArg) {
172173
delete C2;
173174
}
174175

175-
// This test class is not trying to be a usage demo, just asserting
176-
// that three args does actually work too (it's the same code as
177-
// handles the second arg, so it's basically covered by the above, but
178-
// just in case..)
176+
// This test class is not trying to be a usage demo, just asserting that three
177+
// args does actually work too (it's the same code as handles the second arg, so
178+
// it's basically covered by the above, but just in case..)
179179
class Class3 final : public TrailingObjects<Class3, double, short, bool> {
180180
friend TrailingObjects;
181181

@@ -237,9 +237,9 @@ TEST(TrailingObjects, Realignment) {
237237
}
238238
}
239239

240-
// Test the use of TrailingObjects with a template class. This
241-
// previously failed to compile due to a bug in MSVC's member access
242-
// control/lookup handling for OverloadToken.
240+
// Test the use of TrailingObjects with a template class. This previously failed
241+
// to compile due to a bug in MSVC's member access control/lookup handling for
242+
// OverloadToken.
243243
template <typename Derived>
244244
class Class5Tmpl : private llvm::TrailingObjects<Derived, float, int> {
245245
using TrailingObjects = typename llvm::TrailingObjects<Derived, float>;

0 commit comments

Comments
 (0)