summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/ADT
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2016-01-10 08:48:23 +0000
committerChandler Carruth <chandlerc@gmail.com>2016-01-10 08:48:23 +0000
commit0190d07300f8e4f8b3b056c5d331344620f1b936 (patch)
treea2b4bc81eefe398dbc8fb329257515f9f3172127 /llvm/unittests/ADT
parent6a50189fb4f4b012c2e3426f336998166ce64d45 (diff)
downloadbcm5719-llvm-0190d07300f8e4f8b3b056c5d331344620f1b936.tar.gz
bcm5719-llvm-0190d07300f8e4f8b3b056c5d331344620f1b936.zip
[ADT] Add a sum type abstraction for pointer-like types.
This is a much more general and powerful form of PointerUnion. It provides a reasonably complete sum type (from type theory) for pointer-like types. It has several significant advantages over the existing PointerUnion infrastructure: 1) It allows more than two pointer types to participate without awkward nesting structures. 2) It directly exposes the tag so that it is convenient to write switches over the possible members. 3) It can re-use the same type for multiple tag values, something that has been worked around by either abusing PointerIntPair or defining nonce types and doing unsafe pointer casting. 4) It supports customization of the PointerLikeTypeTraits used for specific member types. This means it could (in theory) be used even with types that are over-aligned on allocation to expose larger numbers of bits to the tag. All in all, I think it is at least complimentary to the existing infrastructure, and a strict improvement for some use cases. Differential Revision: http://reviews.llvm.org/D15843 llvm-svn: 257282
Diffstat (limited to 'llvm/unittests/ADT')
-rw-r--r--llvm/unittests/ADT/CMakeLists.txt1
-rw-r--r--llvm/unittests/ADT/PointerSumTypeTest.cpp113
2 files changed, 114 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt
index cb878c61b85..5eb477aceac 100644
--- a/llvm/unittests/ADT/CMakeLists.txt
+++ b/llvm/unittests/ADT/CMakeLists.txt
@@ -26,6 +26,7 @@ set(ADTSources
OptionalTest.cpp
PackedVectorTest.cpp
PointerIntPairTest.cpp
+ PointerSumTypeTest.cpp
PointerUnionTest.cpp
PostOrderIteratorTest.cpp
RangeAdapterTest.cpp
diff --git a/llvm/unittests/ADT/PointerSumTypeTest.cpp b/llvm/unittests/ADT/PointerSumTypeTest.cpp
new file mode 100644
index 00000000000..75c88f7fee9
--- /dev/null
+++ b/llvm/unittests/ADT/PointerSumTypeTest.cpp
@@ -0,0 +1,113 @@
+//===- llvm/unittest/ADT/PointerSumTypeTest.cpp ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/PointerSumType.h"
+using namespace llvm;
+
+namespace {
+
+struct PointerSumTypeTest : public testing::Test {
+ enum Kinds { Float, Int1, Int2 };
+ float f;
+ int i1, i2;
+
+ typedef PointerSumType<Kinds, PointerSumTypeMember<Float, float *>,
+ PointerSumTypeMember<Int1, int *>,
+ PointerSumTypeMember<Int2, int *>>
+ SumType;
+ SumType a, b, c, n;
+
+ PointerSumTypeTest()
+ : f(3.14f), i1(42), i2(-1), a(SumType::create<Float>(&f)),
+ b(SumType::create<Int1>(&i1)), c(SumType::create<Int2>(&i2)), n() {}
+};
+
+TEST_F(PointerSumTypeTest, NullTest) {
+ EXPECT_TRUE(a);
+ EXPECT_TRUE(b);
+ EXPECT_TRUE(c);
+ EXPECT_FALSE(n);
+}
+
+TEST_F(PointerSumTypeTest, GetTag) {
+ EXPECT_EQ(Float, a.getTag());
+ EXPECT_EQ(Int1, b.getTag());
+ EXPECT_EQ(Int2, c.getTag());
+ EXPECT_EQ((Kinds)0, n.getTag());
+}
+
+TEST_F(PointerSumTypeTest, Is) {
+ EXPECT_TRUE(a.is<Float>());
+ EXPECT_FALSE(a.is<Int1>());
+ EXPECT_FALSE(a.is<Int2>());
+ EXPECT_FALSE(b.is<Float>());
+ EXPECT_TRUE(b.is<Int1>());
+ EXPECT_FALSE(b.is<Int2>());
+ EXPECT_FALSE(c.is<Float>());
+ EXPECT_FALSE(c.is<Int1>());
+ EXPECT_TRUE(c.is<Int2>());
+}
+
+TEST_F(PointerSumTypeTest, Get) {
+ EXPECT_EQ(&f, a.get<Float>());
+ EXPECT_EQ(nullptr, a.get<Int1>());
+ EXPECT_EQ(nullptr, a.get<Int2>());
+ EXPECT_EQ(nullptr, b.get<Float>());
+ EXPECT_EQ(&i1, b.get<Int1>());
+ EXPECT_EQ(nullptr, b.get<Int2>());
+ EXPECT_EQ(nullptr, c.get<Float>());
+ EXPECT_EQ(nullptr, c.get<Int1>());
+ EXPECT_EQ(&i2, c.get<Int2>());
+
+ // Note that we can use .get even on a null sum type. It just always produces
+ // a null pointer, even if one of the discriminants is null.
+ EXPECT_EQ(nullptr, n.get<Float>());
+ EXPECT_EQ(nullptr, n.get<Int1>());
+ EXPECT_EQ(nullptr, n.get<Int2>());
+}
+
+TEST_F(PointerSumTypeTest, Cast) {
+ EXPECT_EQ(&f, a.cast<Float>());
+ EXPECT_EQ(&i1, b.cast<Int1>());
+ EXPECT_EQ(&i2, c.cast<Int2>());
+}
+
+TEST_F(PointerSumTypeTest, Assignment) {
+ b = SumType::create<Int2>(&i2);
+ EXPECT_EQ(nullptr, b.get<Float>());
+ EXPECT_EQ(nullptr, b.get<Int1>());
+ EXPECT_EQ(&i2, b.get<Int2>());
+
+ b = SumType::create<Int2>(&i1);
+ EXPECT_EQ(nullptr, b.get<Float>());
+ EXPECT_EQ(nullptr, b.get<Int1>());
+ EXPECT_EQ(&i1, b.get<Int2>());
+
+ float Local = 1.616f;
+ b = SumType::create<Float>(&Local);
+ EXPECT_EQ(&Local, b.get<Float>());
+ EXPECT_EQ(nullptr, b.get<Int1>());
+ EXPECT_EQ(nullptr, b.get<Int2>());
+
+ n = SumType::create<Int1>(&i2);
+ EXPECT_TRUE(n);
+ EXPECT_EQ(nullptr, n.get<Float>());
+ EXPECT_EQ(&i2, n.get<Int1>());
+ EXPECT_EQ(nullptr, n.get<Int2>());
+
+ n = SumType::create<Float>(nullptr);
+ EXPECT_FALSE(n);
+ EXPECT_EQ(nullptr, n.get<Float>());
+ EXPECT_EQ(nullptr, n.get<Int1>());
+ EXPECT_EQ(nullptr, n.get<Int2>());
+}
+
+
+} // end anonymous namespace
OpenPOWER on IntegriCloud