summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Support/TrailingObjectsTest.cpp
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2015-12-18 22:54:37 +0000
committerJames Y Knight <jyknight@google.com>2015-12-18 22:54:37 +0000
commit64390b4238b674112708d616f1aafc3b00c5c72e (patch)
tree103f3c99f74dc292188127e3166f29af62a4c111 /llvm/unittests/Support/TrailingObjectsTest.cpp
parent31ccb51a7f1b6fddaa684095d78c4532598cf51d (diff)
downloadbcm5719-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.cpp38
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));
+}
}
OpenPOWER on IntegriCloud