diff options
author | James Y Knight <jyknight@google.com> | 2015-12-18 22:54:37 +0000 |
---|---|---|
committer | James Y Knight <jyknight@google.com> | 2015-12-18 22:54:37 +0000 |
commit | 64390b4238b674112708d616f1aafc3b00c5c72e (patch) | |
tree | 103f3c99f74dc292188127e3166f29af62a4c111 /llvm/unittests/Support/TrailingObjectsTest.cpp | |
parent | 31ccb51a7f1b6fddaa684095d78c4532598cf51d (diff) | |
download | bcm5719-llvm-64390b4238b674112708d616f1aafc3b00c5c72e.tar.gz bcm5719-llvm-64390b4238b674112708d616f1aafc3b00c5c72e.zip |
Rewrite the TrailingObjects template to provide two new features:
- Automatic alignment of the base type for the alignment requirements
of the trailing types.
- Support for an arbitrary numbers of trailing types, instead of only
1 or 2, by using a variadic template implementation.
Upcoming commits to clang will take advantage of both of these features.
Differential Revision: http://reviews.llvm.org/D12439
llvm-svn: 256054
Diffstat (limited to 'llvm/unittests/Support/TrailingObjectsTest.cpp')
-rw-r--r-- | llvm/unittests/Support/TrailingObjectsTest.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/llvm/unittests/Support/TrailingObjectsTest.cpp b/llvm/unittests/Support/TrailingObjectsTest.cpp index 41e2d4181f5..2b8ab4c5fb8 100644 --- a/llvm/unittests/Support/TrailingObjectsTest.cpp +++ b/llvm/unittests/Support/TrailingObjectsTest.cpp @@ -45,9 +45,10 @@ public: using TrailingObjects::getTrailingObjects; }; -// Here, there are two singular optional object types appended. -// Note that it fails to compile without the alignment spec. -class LLVM_ALIGNAS(8) Class2 final : protected TrailingObjects<Class2, double, short> { +// Here, there are two singular optional object types appended. Note +// that the alignment of Class2 is automatically increased to account +// for the alignment requirements of the trailing objects. +class Class2 final : protected TrailingObjects<Class2, double, short> { friend TrailingObjects; bool HasShort, HasDouble; @@ -117,7 +118,9 @@ TEST(TrailingObjects, TwoArg) { Class2 *C1 = Class2::create(4); Class2 *C2 = Class2::create(0, 4.2); - EXPECT_EQ(sizeof(Class2), 8u); // due to alignment + EXPECT_EQ(sizeof(Class2), llvm::RoundUpToAlignment(sizeof(bool) * 2, + llvm::alignOf<double>())); + EXPECT_EQ(llvm::alignOf<Class2>(), llvm::alignOf<double>()); EXPECT_EQ((Class2::additionalSizeToAlloc<double, short>(1, 0)), sizeof(double)); @@ -144,4 +147,31 @@ TEST(TrailingObjects, TwoArg) { delete C1; delete C2; } + +// This test class is not trying to be a usage demo, just asserting +// that three args does actually work too (it's the same code as +// handles the second arg, so it's basically covered by the above, but +// just in case..) +class Class3 final : public TrailingObjects<Class3, double, short, bool> { + friend TrailingObjects; + + size_t numTrailingObjects(OverloadToken<double>) const { return 1; } + size_t numTrailingObjects(OverloadToken<short>) const { return 1; } +}; + +TEST(TrailingObjects, ThreeArg) { + EXPECT_EQ((Class3::additionalSizeToAlloc<double, short, bool>(1, 1, 3)), + sizeof(double) + sizeof(short) + 3 * sizeof(bool)); + EXPECT_EQ(sizeof(Class3), + llvm::RoundUpToAlignment(1, llvm::alignOf<double>())); + Class3 *C = reinterpret_cast<Class3 *>(::operator new(1000)); + EXPECT_EQ(C->getTrailingObjects<double>(), reinterpret_cast<double *>(C + 1)); + EXPECT_EQ(C->getTrailingObjects<short>(), + reinterpret_cast<short *>(reinterpret_cast<double *>(C + 1) + 1)); + EXPECT_EQ( + C->getTrailingObjects<bool>(), + reinterpret_cast<bool *>( + reinterpret_cast<short *>(reinterpret_cast<double *>(C + 1) + 1) + + 1)); +} } |