aboutsummaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ADT/APFloatTest.cpp24
-rw-r--r--unittests/ADT/APIntTest.cpp42
-rw-r--r--unittests/ADT/BitVectorTest.cpp46
-rw-r--r--unittests/ADT/DenseMapTest.cpp41
-rw-r--r--unittests/ADT/HashingTest.cpp424
-rw-r--r--unittests/ADT/IntrusiveRefCntPtrTest.cpp64
-rw-r--r--unittests/ADT/SmallPtrSetTest.cpp72
-rw-r--r--unittests/ADT/SmallStringTest.cpp148
-rw-r--r--unittests/ADT/SparseSetTest.cpp186
-rw-r--r--unittests/ADT/StringRefTest.cpp143
-rw-r--r--unittests/ADT/TripleTest.cpp143
-rw-r--r--unittests/ADT/VariadicFunctionTest.cpp110
-rw-r--r--unittests/Bitcode/BitReaderTest.cpp65
-rw-r--r--unittests/Bitcode/Makefile15
-rw-r--r--unittests/CMakeLists.txt37
-rw-r--r--unittests/ExecutionEngine/ExecutionEngineTest.cpp8
-rw-r--r--unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp110
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h209
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp14
-rw-r--r--unittests/ExecutionEngine/JIT/Makefile24
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp19
-rw-r--r--unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp166
-rw-r--r--unittests/ExecutionEngine/Makefile4
-rw-r--r--unittests/Makefile2
-rw-r--r--unittests/Makefile.unittest2
-rw-r--r--unittests/Support/AllocatorTest.cpp8
-rw-r--r--unittests/Support/BlockFrequencyTest.cpp29
-rw-r--r--unittests/Support/Casting.cpp5
-rw-r--r--unittests/Support/IRBuilderTest.cpp2
-rw-r--r--unittests/Support/JSONParserTest.cpp191
-rw-r--r--unittests/Support/ManagedStatic.cpp44
-rw-r--r--unittests/Support/Path.cpp62
-rw-r--r--unittests/Support/YAMLParserTest.cpp179
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp2
-rw-r--r--unittests/VMCore/DominatorTreeTest.cpp195
-rw-r--r--unittests/VMCore/InstructionsTest.cpp97
-rw-r--r--unittests/VMCore/Makefile2
-rw-r--r--unittests/VMCore/MetadataTest.cpp7
-rw-r--r--unittests/VMCore/ValueMapTest.cpp4
39 files changed, 2913 insertions, 32 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index b6e02e3a9a3e..cc207f764da2 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -653,4 +653,28 @@ TEST(APFloatTest, getLargest) {
EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble).convertToDouble());
}
+TEST(APFloatTest, convert) {
+ bool losesInfo;
+ APFloat test(APFloat::IEEEdouble, "1.0");
+ test.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_EQ(1.0f, test.convertToFloat());
+ EXPECT_FALSE(losesInfo);
+
+ test = APFloat(APFloat::x87DoubleExtended, "0x1p-53");
+ test.add(APFloat(APFloat::x87DoubleExtended, "1.0"), APFloat::rmNearestTiesToEven);
+ test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_EQ(1.0, test.convertToDouble());
+ EXPECT_TRUE(losesInfo);
+
+ test = APFloat(APFloat::IEEEquad, "0x1p-53");
+ test.add(APFloat(APFloat::IEEEquad, "1.0"), APFloat::rmNearestTiesToEven);
+ test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_EQ(1.0, test.convertToDouble());
+ EXPECT_TRUE(losesInfo);
+
+ test = APFloat(APFloat::x87DoubleExtended, "0xf.fffffffp+28");
+ test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_EQ(4294967295.0, test.convertToDouble());
+ EXPECT_FALSE(losesInfo);
+}
}
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 490811deb8f9..89b8aa94e464 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -144,6 +144,12 @@ TEST(APIntTest, i1) {
EXPECT_EQ(zero, one.lshr(1));
EXPECT_EQ(zero, one.ashr(1));
+ // Rotates.
+ EXPECT_EQ(one, one.rotl(0));
+ EXPECT_EQ(one, one.rotl(1));
+ EXPECT_EQ(one, one.rotr(0));
+ EXPECT_EQ(one, one.rotr(1));
+
// Multiplies.
EXPECT_EQ(neg_one, neg_one * one);
EXPECT_EQ(neg_one, one * neg_one);
@@ -354,7 +360,7 @@ TEST(APIntTest, toString) {
APInt(8, 0).toString(S, 16, true, true);
EXPECT_EQ(S.str().str(), "0x0");
S.clear();
- APInt(8, 0).toString(S, 36, true, true);
+ APInt(8, 0).toString(S, 36, true, false);
EXPECT_EQ(S.str().str(), "0");
S.clear();
@@ -371,7 +377,7 @@ TEST(APIntTest, toString) {
APInt(8, 255, isSigned).toString(S, 16, isSigned, true);
EXPECT_EQ(S.str().str(), "0xFF");
S.clear();
- APInt(8, 255, isSigned).toString(S, 36, isSigned, true);
+ APInt(8, 255, isSigned).toString(S, 36, isSigned, false);
EXPECT_EQ(S.str().str(), "73");
S.clear();
@@ -388,7 +394,7 @@ TEST(APIntTest, toString) {
APInt(8, 255, isSigned).toString(S, 16, isSigned, true);
EXPECT_EQ(S.str().str(), "-0x1");
S.clear();
- APInt(8, 255, isSigned).toString(S, 36, isSigned, true);
+ APInt(8, 255, isSigned).toString(S, 36, isSigned, false);
EXPECT_EQ(S.str().str(), "-1");
S.clear();
}
@@ -450,4 +456,34 @@ TEST(APIntTest, mul_clear) {
EXPECT_EQ(ValA.toString(10, false), ValC.toString(10, false));
}
+TEST(APIntTest, Rotate) {
+ EXPECT_EQ(APInt(8, 1), APInt(8, 1).rotl(0));
+ EXPECT_EQ(APInt(8, 2), APInt(8, 1).rotl(1));
+ EXPECT_EQ(APInt(8, 4), APInt(8, 1).rotl(2));
+ EXPECT_EQ(APInt(8, 16), APInt(8, 1).rotl(4));
+ EXPECT_EQ(APInt(8, 1), APInt(8, 1).rotl(8));
+
+ EXPECT_EQ(APInt(8, 16), APInt(8, 16).rotl(0));
+ EXPECT_EQ(APInt(8, 32), APInt(8, 16).rotl(1));
+ EXPECT_EQ(APInt(8, 64), APInt(8, 16).rotl(2));
+ EXPECT_EQ(APInt(8, 1), APInt(8, 16).rotl(4));
+ EXPECT_EQ(APInt(8, 16), APInt(8, 16).rotl(8));
+
+ EXPECT_EQ(APInt(8, 16), APInt(8, 16).rotr(0));
+ EXPECT_EQ(APInt(8, 8), APInt(8, 16).rotr(1));
+ EXPECT_EQ(APInt(8, 4), APInt(8, 16).rotr(2));
+ EXPECT_EQ(APInt(8, 1), APInt(8, 16).rotr(4));
+ EXPECT_EQ(APInt(8, 16), APInt(8, 16).rotr(8));
+
+ EXPECT_EQ(APInt(8, 1), APInt(8, 1).rotr(0));
+ EXPECT_EQ(APInt(8, 128), APInt(8, 1).rotr(1));
+ EXPECT_EQ(APInt(8, 64), APInt(8, 1).rotr(2));
+ EXPECT_EQ(APInt(8, 16), APInt(8, 1).rotr(4));
+ EXPECT_EQ(APInt(8, 1), APInt(8, 1).rotr(8));
+
+ APInt Big(256, "00004000800000000000000000003fff8000000000000000", 16);
+ APInt Rot(256, "3fff80000000000000000000000000000000000040008000", 16);
+ EXPECT_EQ(Rot, Big.rotr(144));
+}
+
}
diff --git a/unittests/ADT/BitVectorTest.cpp b/unittests/ADT/BitVectorTest.cpp
index fa663121a8a6..f733e13fdfc3 100644
--- a/unittests/ADT/BitVectorTest.cpp
+++ b/unittests/ADT/BitVectorTest.cpp
@@ -196,6 +196,52 @@ TEST(BitVectorTest, ProxyIndex) {
EXPECT_TRUE(Vec.none());
}
+TEST(BitVectorTest, PortableBitMask) {
+ BitVector A;
+ const uint32_t Mask1[] = { 0x80000000, 6, 5 };
+
+ A.resize(10);
+ A.setBitsInMask(Mask1, 3);
+ EXPECT_EQ(10u, A.size());
+ EXPECT_FALSE(A.test(0));
+
+ A.resize(32);
+ A.setBitsInMask(Mask1, 3);
+ EXPECT_FALSE(A.test(0));
+ EXPECT_TRUE(A.test(31));
+ EXPECT_EQ(1u, A.count());
+
+ A.resize(33);
+ A.setBitsInMask(Mask1, 1);
+ EXPECT_EQ(1u, A.count());
+ A.setBitsInMask(Mask1, 2);
+ EXPECT_EQ(1u, A.count());
+
+ A.resize(34);
+ A.setBitsInMask(Mask1, 2);
+ EXPECT_EQ(2u, A.count());
+
+ A.resize(65);
+ A.setBitsInMask(Mask1, 3);
+ EXPECT_EQ(4u, A.count());
+
+ A.setBitsNotInMask(Mask1, 1);
+ EXPECT_EQ(32u+3u, A.count());
+
+ A.setBitsNotInMask(Mask1, 3);
+ EXPECT_EQ(65u, A.count());
+
+ A.resize(96);
+ EXPECT_EQ(65u, A.count());
+
+ A.clear();
+ A.resize(128);
+ A.setBitsNotInMask(Mask1, 3);
+ EXPECT_EQ(96u-5u, A.count());
+
+ A.clearBitsNotInMask(Mask1, 1);
+ EXPECT_EQ(64-4u, A.count());
+}
}
#endif
diff --git a/unittests/ADT/DenseMapTest.cpp b/unittests/ADT/DenseMapTest.cpp
index afac651a6b2b..e0ee7782ccbb 100644
--- a/unittests/ADT/DenseMapTest.cpp
+++ b/unittests/ADT/DenseMapTest.cpp
@@ -176,4 +176,45 @@ TEST_F(DenseMapTest, ConstIteratorTest) {
EXPECT_TRUE(cit == cit2);
}
+// Key traits that allows lookup with either an unsigned or char* key;
+// In the latter case, "a" == 0, "b" == 1 and so on.
+struct TestDenseMapInfo {
+ static inline unsigned getEmptyKey() { return ~0; }
+ static inline unsigned getTombstoneKey() { return ~0U - 1; }
+ static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
+ static unsigned getHashValue(const char* Val) {
+ return (unsigned)(Val[0] - 'a') * 37U;
+ }
+ static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
+ return LHS == RHS;
+ }
+ static bool isEqual(const char* LHS, const unsigned& RHS) {
+ return (unsigned)(LHS[0] - 'a') == RHS;
+ }
+};
+
+// find_as() tests
+TEST_F(DenseMapTest, FindAsTest) {
+ DenseMap<unsigned, unsigned, TestDenseMapInfo> map;
+ map[0] = 1;
+ map[1] = 2;
+ map[2] = 3;
+
+ // Size tests
+ EXPECT_EQ(3u, map.size());
+
+ // Normal lookup tests
+ EXPECT_EQ(1, map.count(1));
+ EXPECT_EQ(1u, map.find(0)->second);
+ EXPECT_EQ(2u, map.find(1)->second);
+ EXPECT_EQ(3u, map.find(2)->second);
+ EXPECT_TRUE(map.find(3) == map.end());
+
+ // find_as() tests
+ EXPECT_EQ(1u, map.find_as("a")->second);
+ EXPECT_EQ(2u, map.find_as("b")->second);
+ EXPECT_EQ(3u, map.find_as("c")->second);
+ EXPECT_TRUE(map.find_as("d") == map.end());
+}
+
}
diff --git a/unittests/ADT/HashingTest.cpp b/unittests/ADT/HashingTest.cpp
new file mode 100644
index 000000000000..b148f144513c
--- /dev/null
+++ b/unittests/ADT/HashingTest.cpp
@@ -0,0 +1,424 @@
+//===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hashing.h unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/Support/DataTypes.h"
+#include <deque>
+#include <list>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+// Helper for test code to print hash codes.
+void PrintTo(const hash_code &code, std::ostream *os) {
+ *os << static_cast<size_t>(code);
+}
+
+// Fake an object that is recognized as hashable data to test super large
+// objects.
+struct LargeTestInteger { uint64_t arr[8]; };
+
+struct NonPOD {
+ uint64_t x, y;
+ NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
+ ~NonPOD() {}
+ friend hash_code hash_value(const NonPOD &obj) {
+ return hash_combine(obj.x, obj.y);
+ }
+};
+
+namespace hashing {
+namespace detail {
+template <> struct is_hashable_data<LargeTestInteger> : true_type {};
+} // namespace detail
+} // namespace hashing
+
+} // namespace llvm
+
+using namespace llvm;
+
+namespace {
+
+enum TestEnumeration {
+ TE_Foo = 42,
+ TE_Bar = 43
+};
+
+TEST(HashingTest, HashValueBasicTest) {
+ int x = 42, y = 43, c = 'x';
+ void *p = 0;
+ uint64_t i = 71;
+ const unsigned ci = 71;
+ volatile int vi = 71;
+ const volatile int cvi = 71;
+ uintptr_t addr = reinterpret_cast<uintptr_t>(&y);
+ EXPECT_EQ(hash_value(42), hash_value(x));
+ EXPECT_EQ(hash_value(42), hash_value(TE_Foo));
+ EXPECT_NE(hash_value(42), hash_value(y));
+ EXPECT_NE(hash_value(42), hash_value(TE_Bar));
+ EXPECT_NE(hash_value(42), hash_value(p));
+ EXPECT_EQ(hash_value(71), hash_value(i));
+ EXPECT_EQ(hash_value(71), hash_value(ci));
+ EXPECT_EQ(hash_value(71), hash_value(vi));
+ EXPECT_EQ(hash_value(71), hash_value(cvi));
+ EXPECT_EQ(hash_value(c), hash_value('x'));
+ EXPECT_EQ(hash_value('4'), hash_value('0' + 4));
+ EXPECT_EQ(hash_value(addr), hash_value(&y));
+}
+
+TEST(HashingTest, HashValueStdPair) {
+ EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
+ EXPECT_NE(hash_combine(43, 42), hash_value(std::make_pair(42, 43)));
+ EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43ull)));
+ EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42, 43ull)));
+ EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43)));
+
+ // Note that pairs are implicitly flattened to a direct sequence of data and
+ // hashed efficiently as a consequence.
+ EXPECT_EQ(hash_combine(42, 43, 44),
+ hash_value(std::make_pair(42, std::make_pair(43, 44))));
+ EXPECT_EQ(hash_value(std::make_pair(42, std::make_pair(43, 44))),
+ hash_value(std::make_pair(std::make_pair(42, 43), 44)));
+
+ // Ensure that pairs which have padding bytes *inside* them don't get treated
+ // this way.
+ EXPECT_EQ(hash_combine('0', hash_combine(1ull, '2')),
+ hash_value(std::make_pair('0', std::make_pair(1ull, '2'))));
+
+ // Ensure that non-POD pairs don't explode the traits used.
+ NonPOD obj1(1, 2), obj2(3, 4), obj3(5, 6);
+ EXPECT_EQ(hash_combine(obj1, hash_combine(obj2, obj3)),
+ hash_value(std::make_pair(obj1, std::make_pair(obj2, obj3))));
+}
+
+TEST(HashingTest, HashValueStdString) {
+ std::string s = "Hello World!";
+ EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size()), hash_value(s));
+ EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size() - 1),
+ hash_value(s.substr(0, s.size() - 1)));
+ EXPECT_EQ(hash_combine_range(s.c_str() + 1, s.c_str() + s.size() - 1),
+ hash_value(s.substr(1, s.size() - 2)));
+
+ std::wstring ws = L"Hello Wide World!";
+ EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size()),
+ hash_value(ws));
+ EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size() - 1),
+ hash_value(ws.substr(0, ws.size() - 1)));
+ EXPECT_EQ(hash_combine_range(ws.c_str() + 1, ws.c_str() + ws.size() - 1),
+ hash_value(ws.substr(1, ws.size() - 2)));
+}
+
+template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
+template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
+
+// Provide a dummy, hashable type designed for easy verification: its hash is
+// the same as its value.
+struct HashableDummy { size_t value; };
+hash_code hash_value(HashableDummy dummy) { return dummy.value; }
+
+TEST(HashingTest, HashCombineRangeBasicTest) {
+ // Leave this uninitialized in the hope that valgrind will catch bad reads.
+ int dummy;
+ hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
+ EXPECT_NE(hash_code(0), dummy_hash);
+
+ const int arr1[] = { 1, 2, 3 };
+ hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
+ EXPECT_NE(dummy_hash, arr1_hash);
+ EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
+
+ const std::vector<int> vec(begin(arr1), end(arr1));
+ EXPECT_EQ(arr1_hash, hash_combine_range(vec.begin(), vec.end()));
+
+ const std::list<int> list(begin(arr1), end(arr1));
+ EXPECT_EQ(arr1_hash, hash_combine_range(list.begin(), list.end()));
+
+ const std::deque<int> deque(begin(arr1), end(arr1));
+ EXPECT_EQ(arr1_hash, hash_combine_range(deque.begin(), deque.end()));
+
+ const int arr2[] = { 3, 2, 1 };
+ hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
+ EXPECT_NE(dummy_hash, arr2_hash);
+ EXPECT_NE(arr1_hash, arr2_hash);
+
+ const int arr3[] = { 1, 1, 2, 3 };
+ hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
+ EXPECT_NE(dummy_hash, arr3_hash);
+ EXPECT_NE(arr1_hash, arr3_hash);
+
+ const int arr4[] = { 1, 2, 3, 3 };
+ hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
+ EXPECT_NE(dummy_hash, arr4_hash);
+ EXPECT_NE(arr1_hash, arr4_hash);
+
+ const size_t arr5[] = { 1, 2, 3 };
+ const HashableDummy d_arr5[] = { {1}, {2}, {3} };
+ hash_code arr5_hash = hash_combine_range(begin(arr5), end(arr5));
+ hash_code d_arr5_hash = hash_combine_range(begin(d_arr5), end(d_arr5));
+ EXPECT_EQ(arr5_hash, d_arr5_hash);
+}
+
+TEST(HashingTest, HashCombineRangeLengthDiff) {
+ // Test that as only the length varies, we compute different hash codes for
+ // sequences.
+ std::map<size_t, size_t> code_to_size;
+ std::vector<char> all_one_c(256, '\xff');
+ for (unsigned Idx = 1, Size = all_one_c.size(); Idx < Size; ++Idx) {
+ hash_code code = hash_combine_range(&all_one_c[0], &all_one_c[0] + Idx);
+ std::map<size_t, size_t>::iterator
+ I = code_to_size.insert(std::make_pair(code, Idx)).first;
+ EXPECT_EQ(Idx, I->second);
+ }
+ code_to_size.clear();
+ std::vector<char> all_zero_c(256, '\0');
+ for (unsigned Idx = 1, Size = all_zero_c.size(); Idx < Size; ++Idx) {
+ hash_code code = hash_combine_range(&all_zero_c[0], &all_zero_c[0] + Idx);
+ std::map<size_t, size_t>::iterator
+ I = code_to_size.insert(std::make_pair(code, Idx)).first;
+ EXPECT_EQ(Idx, I->second);
+ }
+ code_to_size.clear();
+ std::vector<unsigned> all_one_int(512, -1);
+ for (unsigned Idx = 1, Size = all_one_int.size(); Idx < Size; ++Idx) {
+ hash_code code = hash_combine_range(&all_one_int[0], &all_one_int[0] + Idx);
+ std::map<size_t, size_t>::iterator
+ I = code_to_size.insert(std::make_pair(code, Idx)).first;
+ EXPECT_EQ(Idx, I->second);
+ }
+ code_to_size.clear();
+ std::vector<unsigned> all_zero_int(512, 0);
+ for (unsigned Idx = 1, Size = all_zero_int.size(); Idx < Size; ++Idx) {
+ hash_code code = hash_combine_range(&all_zero_int[0], &all_zero_int[0] + Idx);
+ std::map<size_t, size_t>::iterator
+ I = code_to_size.insert(std::make_pair(code, Idx)).first;
+ EXPECT_EQ(Idx, I->second);
+ }
+}
+
+TEST(HashingTest, HashCombineRangeGoldenTest) {
+ struct { const char *s; uint64_t hash; } golden_data[] = {
+#if SIZE_MAX == UINT64_MAX
+ { "a", 0xaeb6f9d5517c61f8ULL },
+ { "ab", 0x7ab1edb96be496b4ULL },
+ { "abc", 0xe38e60bf19c71a3fULL },
+ { "abcde", 0xd24461a66de97f6eULL },
+ { "abcdefgh", 0x4ef872ec411dec9dULL },
+ { "abcdefghijklm", 0xe8a865539f4eadfeULL },
+ { "abcdefghijklmnopqrstu", 0x261cdf85faaf4e79ULL },
+ { "abcdefghijklmnopqrstuvwxyzabcdef", 0x43ba70e4198e3b2aULL },
+ { "abcdefghijklmnopqrstuvwxyzabcdef"
+ "abcdefghijklmnopqrstuvwxyzghijkl"
+ "abcdefghijklmnopqrstuvwxyzmnopqr"
+ "abcdefghijklmnopqrstuvwxyzstuvwx"
+ "abcdefghijklmnopqrstuvwxyzyzabcd", 0xdcd57fb2afdf72beULL },
+ { "a", 0xaeb6f9d5517c61f8ULL },
+ { "aa", 0xf2b3b69a9736a1ebULL },
+ { "aaa", 0xf752eb6f07b1cafeULL },
+ { "aaaaa", 0x812bd21e1236954cULL },
+ { "aaaaaaaa", 0xff07a2cff08ac587ULL },
+ { "aaaaaaaaaaaaa", 0x84ac949d54d704ecULL },
+ { "aaaaaaaaaaaaaaaaaaaaa", 0xcb2c8fb6be8f5648ULL },
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xcc40ab7f164091b6ULL },
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xc58e174c1e78ffe9ULL },
+ { "z", 0x1ba160d7e8f8785cULL },
+ { "zz", 0x2c5c03172f1285d7ULL },
+ { "zzz", 0x9d2c4f4b507a2ac3ULL },
+ { "zzzzz", 0x0f03b9031735693aULL },
+ { "zzzzzzzz", 0xe674147c8582c08eULL },
+ { "zzzzzzzzzzzzz", 0x3162d9fa6938db83ULL },
+ { "zzzzzzzzzzzzzzzzzzzzz", 0x37b9a549e013620cULL },
+ { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x8921470aff885016ULL },
+ { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0xf60fdcd9beb08441ULL },
+ { "a", 0xaeb6f9d5517c61f8ULL },
+ { "ab", 0x7ab1edb96be496b4ULL },
+ { "aba", 0x3edb049950884d0aULL },
+ { "ababa", 0x8f2de9e73a97714bULL },
+ { "abababab", 0xee14a29ddf0ce54cULL },
+ { "ababababababa", 0x38b3ddaada2d52b4ULL },
+ { "ababababababababababa", 0xd3665364219f2b85ULL },
+ { "abababababababababababababababab", 0xa75cd6afbf1bc972ULL },
+ { "abababababababababababababababab"
+ "abababababababababababababababab"
+ "abababababababababababababababab"
+ "abababababababababababababababab"
+ "abababababababababababababababab", 0x840192d129f7a22bULL }
+#elif SIZE_MAX == UINT32_MAX
+ { "a", 0x000000004605f745ULL },
+ { "ab", 0x00000000d5f06301ULL },
+ { "abc", 0x00000000559fe1eeULL },
+ { "abcde", 0x00000000424028d7ULL },
+ { "abcdefgh", 0x000000007bb119f8ULL },
+ { "abcdefghijklm", 0x00000000edbca513ULL },
+ { "abcdefghijklmnopqrstu", 0x000000007c15712eULL },
+ { "abcdefghijklmnopqrstuvwxyzabcdef", 0x000000000b3aad66ULL },
+ { "abcdefghijklmnopqrstuvwxyzabcdef"
+ "abcdefghijklmnopqrstuvwxyzghijkl"
+ "abcdefghijklmnopqrstuvwxyzmnopqr"
+ "abcdefghijklmnopqrstuvwxyzstuvwx"
+ "abcdefghijklmnopqrstuvwxyzyzabcd", 0x000000008c758c8bULL },
+ { "a", 0x000000004605f745ULL },
+ { "aa", 0x00000000dc0a52daULL },
+ { "aaa", 0x00000000b309274fULL },
+ { "aaaaa", 0x00000000203b5ef6ULL },
+ { "aaaaaaaa", 0x00000000a429e18fULL },
+ { "aaaaaaaaaaaaa", 0x000000008662070bULL },
+ { "aaaaaaaaaaaaaaaaaaaaa", 0x000000003f11151cULL },
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000008600fe20ULL },
+ { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0x000000004e0e0804ULL },
+ { "z", 0x00000000c5e405e9ULL },
+ { "zz", 0x00000000a8d8a2c6ULL },
+ { "zzz", 0x00000000fc2af672ULL },
+ { "zzzzz", 0x0000000047d9efe6ULL },
+ { "zzzzzzzz", 0x0000000080d77794ULL },
+ { "zzzzzzzzzzzzz", 0x00000000405f93adULL },
+ { "zzzzzzzzzzzzzzzzzzzzz", 0x00000000fc72838dULL },
+ { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x000000007ce160f1ULL },
+ { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
+ "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x00000000aed9ed1bULL },
+ { "a", 0x000000004605f745ULL },
+ { "ab", 0x00000000d5f06301ULL },
+ { "aba", 0x00000000a85cd91bULL },
+ { "ababa", 0x000000009e3bb52eULL },
+ { "abababab", 0x000000002709b3b9ULL },
+ { "ababababababa", 0x000000003a234174ULL },
+ { "ababababababababababa", 0x000000005c63e5ceULL },
+ { "abababababababababababababababab", 0x0000000013f74334ULL },
+ { "abababababababababababababababab"
+ "abababababababababababababababab"
+ "abababababababababababababababab"
+ "abababababababababababababababab"
+ "abababababababababababababababab", 0x00000000c1a6f135ULL },
+#else
+#error This test only supports 64-bit and 32-bit systems.
+#endif
+ };
+ for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
+ StringRef str = golden_data[i].s;
+ hash_code hash = hash_combine_range(str.begin(), str.end());
+#if 0 // Enable this to generate paste-able text for the above structure.
+ std::string member_str = "\"" + str.str() + "\",";
+ fprintf(stderr, " { %-35s 0x%016llxULL },\n",
+ member_str.c_str(), static_cast<uint64_t>(hash));
+#endif
+ EXPECT_EQ(static_cast<size_t>(golden_data[i].hash),
+ static_cast<size_t>(hash));
+ }
+}
+
+TEST(HashingTest, HashCombineBasicTest) {
+ // Hashing a sequence of homogenous types matches range hashing.
+ const int i1 = 42, i2 = 43, i3 = 123, i4 = 999, i5 = 0, i6 = 79;
+ const int arr1[] = { i1, i2, i3, i4, i5, i6 };
+ EXPECT_EQ(hash_combine_range(arr1, arr1 + 1), hash_combine(i1));
+ EXPECT_EQ(hash_combine_range(arr1, arr1 + 2), hash_combine(i1, i2));
+ EXPECT_EQ(hash_combine_range(arr1, arr1 + 3), hash_combine(i1, i2, i3));
+ EXPECT_EQ(hash_combine_range(arr1, arr1 + 4), hash_combine(i1, i2, i3, i4));
+ EXPECT_EQ(hash_combine_range(arr1, arr1 + 5),
+ hash_combine(i1, i2, i3, i4, i5));
+ EXPECT_EQ(hash_combine_range(arr1, arr1 + 6),
+ hash_combine(i1, i2, i3, i4, i5, i6));
+
+ // Hashing a sequence of heterogenous types which *happen* to all produce the
+ // same data for hashing produces the same as a range-based hash of the
+ // fundamental values.
+ const size_t s1 = 1024, s2 = 8888, s3 = 9000000;
+ const HashableDummy d1 = { 1024 }, d2 = { 8888 }, d3 = { 9000000 };
+ const size_t arr2[] = { s1, s2, s3 };
+ EXPECT_EQ(hash_combine_range(begin(arr2), end(arr2)),
+ hash_combine(s1, s2, s3));
+ EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, s2, d3));
+ EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, d2, s3));
+ EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, s2, s3));
+ EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, s3));
+ EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, d3));
+
+ // Permuting values causes hashes to change.
+ EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i1, i2));
+ EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i2, i1));
+ EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i1, i1));
+ EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i1));
+ EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i2));
+ EXPECT_NE(hash_combine(i2, i1, i1), hash_combine(i1, i1, i2));
+ EXPECT_NE(hash_combine(i1, i1, i2), hash_combine(i1, i2, i1));
+ EXPECT_NE(hash_combine(i1, i2, i1), hash_combine(i2, i1, i1));
+
+ // Changing type w/o changing value causes hashes to change.
+ EXPECT_NE(hash_combine(i1, i2, i3), hash_combine((char)i1, i2, i3));
+ EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, (char)i2, i3));
+ EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, i2, (char)i3));
+
+ // This is array of uint64, but it should have the exact same byte pattern as
+ // an array of LargeTestIntegers.
+ const uint64_t bigarr[] = {
+ 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+ 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+ 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
+ 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+ 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+ 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
+ 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+ 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+ 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
+ };
+ // Hash a preposterously large integer, both aligned with the buffer and
+ // misaligned.
+ const LargeTestInteger li = { {
+ 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
+ 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
+ 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
+ } };
+ // Rotate the storage from 'li'.
+ const LargeTestInteger l2 = { {
+ 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL,
+ 0xfefefefededededeULL, 0xafafafafededededULL, 0xffffeeeeddddccccULL,
+ 0xaaaacbcbffffababULL, 0xaaaaaaaaababababULL
+ } };
+ const LargeTestInteger l3 = { {
+ 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL,
+ 0xafafafafededededULL, 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
+ 0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL
+ } };
+ EXPECT_EQ(hash_combine_range(begin(bigarr), end(bigarr)),
+ hash_combine(li, li, li));
+ EXPECT_EQ(hash_combine_range(bigarr, bigarr + 9),
+ hash_combine(bigarr[0], l2));
+ EXPECT_EQ(hash_combine_range(bigarr, bigarr + 10),
+ hash_combine(bigarr[0], bigarr[1], l3));
+ EXPECT_EQ(hash_combine_range(bigarr, bigarr + 17),
+ hash_combine(li, bigarr[0], l2));
+ EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
+ hash_combine(li, bigarr[0], bigarr[1], l3));
+ EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
+ hash_combine(bigarr[0], l2, bigarr[9], l3));
+ EXPECT_EQ(hash_combine_range(bigarr, bigarr + 20),
+ hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));
+}
+
+}
diff --git a/unittests/ADT/IntrusiveRefCntPtrTest.cpp b/unittests/ADT/IntrusiveRefCntPtrTest.cpp
new file mode 100644
index 000000000000..0c8c4ca16dd7
--- /dev/null
+++ b/unittests/ADT/IntrusiveRefCntPtrTest.cpp
@@ -0,0 +1,64 @@
+//===- unittest/ADT/IntrusiveRefCntPtrTest.cpp ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+struct VirtualRefCounted : public RefCountedBaseVPTR {
+ virtual void f() {}
+};
+
+// Run this test with valgrind to detect memory leaks.
+TEST(IntrusiveRefCntPtr, RefCountedBaseVPTRCopyDoesNotLeak) {
+ VirtualRefCounted *V1 = new VirtualRefCounted;
+ IntrusiveRefCntPtr<VirtualRefCounted> R1 = V1;
+ VirtualRefCounted *V2 = new VirtualRefCounted(*V1);
+ IntrusiveRefCntPtr<VirtualRefCounted> R2 = V2;
+}
+
+struct SimpleRefCounted : public RefCountedBase<SimpleRefCounted> {};
+
+// Run this test with valgrind to detect memory leaks.
+TEST(IntrusiveRefCntPtr, RefCountedBaseCopyDoesNotLeak) {
+ SimpleRefCounted *S1 = new SimpleRefCounted;
+ IntrusiveRefCntPtr<SimpleRefCounted> R1 = S1;
+ SimpleRefCounted *S2 = new SimpleRefCounted(*S1);
+ IntrusiveRefCntPtr<SimpleRefCounted> R2 = S2;
+}
+
+struct InterceptRefCounted : public RefCountedBase<InterceptRefCounted> {
+ InterceptRefCounted(bool *Released, bool *Retained)
+ : Released(Released), Retained(Retained) {}
+ bool * const Released;
+ bool * const Retained;
+};
+template <> struct IntrusiveRefCntPtrInfo<InterceptRefCounted> {
+ static void retain(InterceptRefCounted *I) {
+ *I->Retained = true;
+ I->Retain();
+ }
+ static void release(InterceptRefCounted *I) {
+ *I->Released = true;
+ I->Release();
+ }
+};
+TEST(IntrusiveRefCntPtr, UsesTraitsToRetainAndRelease) {
+ bool Released = false;
+ bool Retained = false;
+ {
+ InterceptRefCounted *I = new InterceptRefCounted(&Released, &Retained);
+ IntrusiveRefCntPtr<InterceptRefCounted> R = I;
+ }
+ EXPECT_TRUE(Released);
+ EXPECT_TRUE(Retained);
+}
+
+} // end namespace llvm
diff --git a/unittests/ADT/SmallPtrSetTest.cpp b/unittests/ADT/SmallPtrSetTest.cpp
new file mode 100644
index 000000000000..9114875e0035
--- /dev/null
+++ b/unittests/ADT/SmallPtrSetTest.cpp
@@ -0,0 +1,72 @@
+//===- llvm/unittest/ADT/SmallPtrSetTest.cpp ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// SmallPtrSet unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+using namespace llvm;
+
+// SmallPtrSet swapping test.
+TEST(SmallPtrSetTest, SwapTest) {
+ int buf[10];
+
+ SmallPtrSet<int *, 2> a;
+ SmallPtrSet<int *, 2> b;
+
+ a.insert(&buf[0]);
+ a.insert(&buf[1]);
+ b.insert(&buf[2]);
+
+ std::swap(a, b);
+
+ EXPECT_EQ(1U, a.size());
+ EXPECT_EQ(2U, b.size());
+ EXPECT_TRUE(a.count(&buf[2]));
+ EXPECT_TRUE(b.count(&buf[0]));
+ EXPECT_TRUE(b.count(&buf[1]));
+
+ b.insert(&buf[3]);
+ std::swap(a, b);
+
+ EXPECT_EQ(3U, a.size());
+ EXPECT_EQ(1U, b.size());
+ EXPECT_TRUE(a.count(&buf[0]));
+ EXPECT_TRUE(a.count(&buf[1]));
+ EXPECT_TRUE(a.count(&buf[3]));
+ EXPECT_TRUE(b.count(&buf[2]));
+
+ std::swap(a, b);
+
+ EXPECT_EQ(1U, a.size());
+ EXPECT_EQ(3U, b.size());
+ EXPECT_TRUE(a.count(&buf[2]));
+ EXPECT_TRUE(b.count(&buf[0]));
+ EXPECT_TRUE(b.count(&buf[1]));
+ EXPECT_TRUE(b.count(&buf[3]));
+
+ a.insert(&buf[4]);
+ a.insert(&buf[5]);
+ a.insert(&buf[6]);
+
+ std::swap(b, a);
+
+ EXPECT_EQ(3U, a.size());
+ EXPECT_EQ(4U, b.size());
+ EXPECT_TRUE(b.count(&buf[2]));
+ EXPECT_TRUE(b.count(&buf[4]));
+ EXPECT_TRUE(b.count(&buf[5]));
+ EXPECT_TRUE(b.count(&buf[6]));
+ EXPECT_TRUE(a.count(&buf[0]));
+ EXPECT_TRUE(a.count(&buf[1]));
+ EXPECT_TRUE(a.count(&buf[3]));
+}
diff --git a/unittests/ADT/SmallStringTest.cpp b/unittests/ADT/SmallStringTest.cpp
index 099d8159c917..660ac44a8bca 100644
--- a/unittests/ADT/SmallStringTest.cpp
+++ b/unittests/ADT/SmallStringTest.cpp
@@ -44,5 +44,153 @@ TEST_F(SmallStringTest, EmptyStringTest) {
EXPECT_TRUE(theString.rbegin() == theString.rend());
}
+TEST_F(SmallStringTest, AssignRepeated) {
+ theString.assign(3, 'a');
+ EXPECT_EQ(3u, theString.size());
+ EXPECT_STREQ("aaa", theString.c_str());
}
+TEST_F(SmallStringTest, AssignIterPair) {
+ StringRef abc = "abc";
+ theString.assign(abc.begin(), abc.end());
+ EXPECT_EQ(3u, theString.size());
+ EXPECT_STREQ("abc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AssignStringRef) {
+ StringRef abc = "abc";
+ theString.assign(abc);
+ EXPECT_EQ(3u, theString.size());
+ EXPECT_STREQ("abc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AssignSmallVector) {
+ StringRef abc = "abc";
+ SmallVector<char, 10> abcVec(abc.begin(), abc.end());
+ theString.assign(abcVec);
+ EXPECT_EQ(3u, theString.size());
+ EXPECT_STREQ("abc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AppendIterPair) {
+ StringRef abc = "abc";
+ theString.append(abc.begin(), abc.end());
+ theString.append(abc.begin(), abc.end());
+ EXPECT_EQ(6u, theString.size());
+ EXPECT_STREQ("abcabc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AppendStringRef) {
+ StringRef abc = "abc";
+ theString.append(abc);
+ theString.append(abc);
+ EXPECT_EQ(6u, theString.size());
+ EXPECT_STREQ("abcabc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, AppendSmallVector) {
+ StringRef abc = "abc";
+ SmallVector<char, 10> abcVec(abc.begin(), abc.end());
+ theString.append(abcVec);
+ theString.append(abcVec);
+ EXPECT_EQ(6u, theString.size());
+ EXPECT_STREQ("abcabc", theString.c_str());
+}
+
+TEST_F(SmallStringTest, Substr) {
+ theString = "hello";
+ EXPECT_EQ("lo", theString.substr(3));
+ EXPECT_EQ("", theString.substr(100));
+ EXPECT_EQ("hello", theString.substr(0, 100));
+ EXPECT_EQ("o", theString.substr(4, 10));
+}
+
+TEST_F(SmallStringTest, Slice) {
+ theString = "hello";
+ EXPECT_EQ("l", theString.slice(2, 3));
+ EXPECT_EQ("ell", theString.slice(1, 4));
+ EXPECT_EQ("llo", theString.slice(2, 100));
+ EXPECT_EQ("", theString.slice(2, 1));
+ EXPECT_EQ("", theString.slice(10, 20));
+}
+
+TEST_F(SmallStringTest, Find) {
+ theString = "hello";
+ EXPECT_EQ(2U, theString.find('l'));
+ EXPECT_EQ(StringRef::npos, theString.find('z'));
+ EXPECT_EQ(StringRef::npos, theString.find("helloworld"));
+ EXPECT_EQ(0U, theString.find("hello"));
+ EXPECT_EQ(1U, theString.find("ello"));
+ EXPECT_EQ(StringRef::npos, theString.find("zz"));
+ EXPECT_EQ(2U, theString.find("ll", 2));
+ EXPECT_EQ(StringRef::npos, theString.find("ll", 3));
+ EXPECT_EQ(0U, theString.find(""));
+
+ EXPECT_EQ(3U, theString.rfind('l'));
+ EXPECT_EQ(StringRef::npos, theString.rfind('z'));
+ EXPECT_EQ(StringRef::npos, theString.rfind("helloworld"));
+ EXPECT_EQ(0U, theString.rfind("hello"));
+ EXPECT_EQ(1U, theString.rfind("ello"));
+ EXPECT_EQ(StringRef::npos, theString.rfind("zz"));
+
+ EXPECT_EQ(2U, theString.find_first_of('l'));
+ EXPECT_EQ(1U, theString.find_first_of("el"));
+ EXPECT_EQ(StringRef::npos, theString.find_first_of("xyz"));
+
+ EXPECT_EQ(1U, theString.find_first_not_of('h'));
+ EXPECT_EQ(4U, theString.find_first_not_of("hel"));
+ EXPECT_EQ(StringRef::npos, theString.find_first_not_of("hello"));
+
+ theString = "hellx xello hell ello world foo bar hello";
+ EXPECT_EQ(36U, theString.find("hello"));
+ EXPECT_EQ(28U, theString.find("foo"));
+ EXPECT_EQ(12U, theString.find("hell", 2));
+ EXPECT_EQ(0U, theString.find(""));
+}
+
+TEST_F(SmallStringTest, Count) {
+ theString = "hello";
+ EXPECT_EQ(2U, theString.count('l'));
+ EXPECT_EQ(1U, theString.count('o'));
+ EXPECT_EQ(0U, theString.count('z'));
+ EXPECT_EQ(0U, theString.count("helloworld"));
+ EXPECT_EQ(1U, theString.count("hello"));
+ EXPECT_EQ(1U, theString.count("ello"));
+ EXPECT_EQ(0U, theString.count("zz"));
+}
+
+TEST(StringRefTest, Comparisons) {
+ EXPECT_EQ(-1, SmallString<10>("aab").compare("aad"));
+ EXPECT_EQ( 0, SmallString<10>("aab").compare("aab"));
+ EXPECT_EQ( 1, SmallString<10>("aab").compare("aaa"));
+ EXPECT_EQ(-1, SmallString<10>("aab").compare("aabb"));
+ EXPECT_EQ( 1, SmallString<10>("aab").compare("aa"));
+ EXPECT_EQ( 1, SmallString<10>("\xFF").compare("\1"));
+
+ EXPECT_EQ(-1, SmallString<10>("AaB").compare_lower("aAd"));
+ EXPECT_EQ( 0, SmallString<10>("AaB").compare_lower("aab"));
+ EXPECT_EQ( 1, SmallString<10>("AaB").compare_lower("AAA"));
+ EXPECT_EQ(-1, SmallString<10>("AaB").compare_lower("aaBb"));
+ EXPECT_EQ( 1, SmallString<10>("AaB").compare_lower("aA"));
+ EXPECT_EQ( 1, SmallString<10>("\xFF").compare_lower("\1"));
+
+ EXPECT_EQ(-1, SmallString<10>("aab").compare_numeric("aad"));
+ EXPECT_EQ( 0, SmallString<10>("aab").compare_numeric("aab"));
+ EXPECT_EQ( 1, SmallString<10>("aab").compare_numeric("aaa"));
+ EXPECT_EQ(-1, SmallString<10>("aab").compare_numeric("aabb"));
+ EXPECT_EQ( 1, SmallString<10>("aab").compare_numeric("aa"));
+ EXPECT_EQ(-1, SmallString<10>("1").compare_numeric("10"));
+ EXPECT_EQ( 0, SmallString<10>("10").compare_numeric("10"));
+ EXPECT_EQ( 0, SmallString<10>("10a").compare_numeric("10a"));
+ EXPECT_EQ( 1, SmallString<10>("2").compare_numeric("1"));
+ EXPECT_EQ( 0, SmallString<10>("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty"));
+ EXPECT_EQ( 1, SmallString<10>("\xFF").compare_numeric("\1"));
+ EXPECT_EQ( 1, SmallString<10>("V16").compare_numeric("V1_q0"));
+ EXPECT_EQ(-1, SmallString<10>("V1_q0").compare_numeric("V16"));
+ EXPECT_EQ(-1, SmallString<10>("V8_q0").compare_numeric("V16"));
+ EXPECT_EQ( 1, SmallString<10>("V16").compare_numeric("V8_q0"));
+ EXPECT_EQ(-1, SmallString<10>("V1_q0").compare_numeric("V8_q0"));
+ EXPECT_EQ( 1, SmallString<10>("V8_q0").compare_numeric("V1_q0"));
+}
+
+}
diff --git a/unittests/ADT/SparseSetTest.cpp b/unittests/ADT/SparseSetTest.cpp
new file mode 100644
index 000000000000..a6ea7572ce44
--- /dev/null
+++ b/unittests/ADT/SparseSetTest.cpp
@@ -0,0 +1,186 @@
+//===------ ADT/SparseSetTest.cpp - SparseSet unit tests - -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SparseSet.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+typedef SparseSet<unsigned> USet;
+
+// Empty set tests.
+TEST(SparseSetTest, EmptySet) {
+ USet Set;
+ EXPECT_TRUE(Set.empty());
+ EXPECT_TRUE(Set.begin() == Set.end());
+ EXPECT_EQ(0u, Set.size());
+
+ Set.setUniverse(10);
+
+ // Lookups on empty set.
+ EXPECT_TRUE(Set.find(0) == Set.end());
+ EXPECT_TRUE(Set.find(9) == Set.end());
+
+ // Same thing on a const reference.
+ const USet &CSet = Set;
+ EXPECT_TRUE(CSet.empty());
+ EXPECT_TRUE(CSet.begin() == CSet.end());
+ EXPECT_EQ(0u, CSet.size());
+ EXPECT_TRUE(CSet.find(0) == CSet.end());
+ USet::const_iterator I = CSet.find(5);
+ EXPECT_TRUE(I == CSet.end());
+}
+
+// Single entry set tests.
+TEST(SparseSetTest, SingleEntrySet) {
+ USet Set;
+ Set.setUniverse(10);
+ std::pair<USet::iterator, bool> IP = Set.insert(5);
+ EXPECT_TRUE(IP.second);
+ EXPECT_TRUE(IP.first == Set.begin());
+
+ EXPECT_FALSE(Set.empty());
+ EXPECT_FALSE(Set.begin() == Set.end());
+ EXPECT_TRUE(Set.begin() + 1 == Set.end());
+ EXPECT_EQ(1u, Set.size());
+
+ EXPECT_TRUE(Set.find(0) == Set.end());
+ EXPECT_TRUE(Set.find(9) == Set.end());
+
+ EXPECT_FALSE(Set.count(0));
+ EXPECT_TRUE(Set.count(5));
+
+ // Redundant insert.
+ IP = Set.insert(5);
+ EXPECT_FALSE(IP.second);
+ EXPECT_TRUE(IP.first == Set.begin());
+
+ // Erase non-existent element.
+ EXPECT_FALSE(Set.erase(1));
+ EXPECT_EQ(1u, Set.size());
+ EXPECT_EQ(5u, *Set.begin());
+
+ // Erase iterator.
+ USet::iterator I = Set.find(5);
+ EXPECT_TRUE(I == Set.begin());
+ I = Set.erase(I);
+ EXPECT_TRUE(I == Set.end());
+ EXPECT_TRUE(Set.empty());
+}
+
+// Multiple entry set tests.
+TEST(SparseSetTest, MultipleEntrySet) {
+ USet Set;
+ Set.setUniverse(10);
+
+ Set.insert(5);
+ Set.insert(3);
+ Set.insert(2);
+ Set.insert(1);
+ Set.insert(4);
+ EXPECT_EQ(5u, Set.size());
+
+ // Without deletions, iteration order == insertion order.
+ USet::const_iterator I = Set.begin();
+ EXPECT_EQ(5u, *I);
+ ++I;
+ EXPECT_EQ(3u, *I);
+ ++I;
+ EXPECT_EQ(2u, *I);
+ ++I;
+ EXPECT_EQ(1u, *I);
+ ++I;
+ EXPECT_EQ(4u, *I);
+ ++I;
+ EXPECT_TRUE(I == Set.end());
+
+ // Redundant insert.
+ std::pair<USet::iterator, bool> IP = Set.insert(3);
+ EXPECT_FALSE(IP.second);
+ EXPECT_TRUE(IP.first == Set.begin() + 1);
+
+ // Erase last element by key.
+ EXPECT_TRUE(Set.erase(4));
+ EXPECT_EQ(4u, Set.size());
+ EXPECT_FALSE(Set.count(4));
+ EXPECT_FALSE(Set.erase(4));
+ EXPECT_EQ(4u, Set.size());
+ EXPECT_FALSE(Set.count(4));
+
+ // Erase first element by key.
+ EXPECT_TRUE(Set.count(5));
+ EXPECT_TRUE(Set.find(5) == Set.begin());
+ EXPECT_TRUE(Set.erase(5));
+ EXPECT_EQ(3u, Set.size());
+ EXPECT_FALSE(Set.count(5));
+ EXPECT_FALSE(Set.erase(5));
+ EXPECT_EQ(3u, Set.size());
+ EXPECT_FALSE(Set.count(5));
+
+ Set.insert(6);
+ Set.insert(7);
+ EXPECT_EQ(5u, Set.size());
+
+ // Erase last element by iterator.
+ I = Set.erase(Set.end() - 1);
+ EXPECT_TRUE(I == Set.end());
+ EXPECT_EQ(4u, Set.size());
+
+ // Erase second element by iterator.
+ I = Set.erase(Set.begin() + 1);
+ EXPECT_TRUE(I == Set.begin() + 1);
+
+ // Clear and resize the universe.
+ Set.clear();
+ EXPECT_FALSE(Set.count(5));
+ Set.setUniverse(1000);
+
+ // Add more than 256 elements.
+ for (unsigned i = 100; i != 800; ++i)
+ Set.insert(i);
+
+ for (unsigned i = 0; i != 10; ++i)
+ Set.erase(i);
+
+ for (unsigned i = 100; i != 800; ++i)
+ EXPECT_TRUE(Set.count(i));
+
+ EXPECT_FALSE(Set.count(99));
+ EXPECT_FALSE(Set.count(800));
+ EXPECT_EQ(700u, Set.size());
+}
+
+struct Alt {
+ unsigned Value;
+ explicit Alt(unsigned x) : Value(x) {}
+ unsigned getSparseSetKey() const { return Value - 1000; }
+};
+
+TEST(SparseSetTest, AltStructSet) {
+ typedef SparseSet<Alt> ASet;
+ ASet Set;
+ Set.setUniverse(10);
+ Set.insert(Alt(1005));
+
+ ASet::iterator I = Set.find(5);
+ ASSERT_TRUE(I == Set.begin());
+ EXPECT_EQ(1005u, I->Value);
+
+ Set.insert(Alt(1006));
+ Set.insert(Alt(1006));
+ I = Set.erase(Set.begin());
+ ASSERT_TRUE(I == Set.begin());
+ EXPECT_EQ(1006u, I->Value);
+
+ EXPECT_FALSE(Set.erase(5));
+ EXPECT_TRUE(Set.erase(6));
+}
+} // namespace
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
index 8364eac82748..cc7a7fbe332d 100644
--- a/unittests/ADT/StringRefTest.cpp
+++ b/unittests/ADT/StringRefTest.cpp
@@ -9,6 +9,7 @@
#include "gtest/gtest.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -245,6 +246,12 @@ TEST(StringRefTest, Find) {
EXPECT_EQ(StringRef::npos, Str.find("zz"));
EXPECT_EQ(2U, Str.find("ll", 2));
EXPECT_EQ(StringRef::npos, Str.find("ll", 3));
+ EXPECT_EQ(0U, Str.find(""));
+ StringRef LongStr("hellx xello hell ello world foo bar hello");
+ EXPECT_EQ(36U, LongStr.find("hello"));
+ EXPECT_EQ(28U, LongStr.find("foo"));
+ EXPECT_EQ(12U, LongStr.find("hell", 2));
+ EXPECT_EQ(0U, LongStr.find(""));
EXPECT_EQ(3U, Str.rfind('l'));
EXPECT_EQ(StringRef::npos, Str.rfind('z'));
@@ -285,4 +292,140 @@ TEST(StringRefTest, Misc) {
EXPECT_EQ("hello", OS.str());
}
+TEST(StringRefTest, Hashing) {
+ EXPECT_EQ(hash_value(std::string()), hash_value(StringRef()));
+ EXPECT_EQ(hash_value(std::string()), hash_value(StringRef("")));
+ std::string S = "hello world";
+ hash_code H = hash_value(S);
+ EXPECT_EQ(H, hash_value(StringRef("hello world")));
+ EXPECT_EQ(H, hash_value(StringRef(S)));
+ EXPECT_NE(H, hash_value(StringRef("hello worl")));
+ EXPECT_EQ(hash_value(std::string("hello worl")),
+ hash_value(StringRef("hello worl")));
+ EXPECT_NE(H, hash_value(StringRef("hello world ")));
+ EXPECT_EQ(hash_value(std::string("hello world ")),
+ hash_value(StringRef("hello world ")));
+ EXPECT_EQ(H, hash_value(StringRef("hello world\0")));
+ EXPECT_NE(hash_value(std::string("ello worl")),
+ hash_value(StringRef("hello world").slice(1, -1)));
+}
+
+struct UnsignedPair {
+ const char *Str;
+ uint64_t Expected;
+} Unsigned[] =
+ { {"0", 0}
+ , {"255", 255}
+ , {"256", 256}
+ , {"65535", 65535}
+ , {"65536", 65536}
+ , {"4294967295", 4294967295ULL}
+ , {"4294967296", 4294967296ULL}
+ , {"18446744073709551615", 18446744073709551615ULL}
+ , {"042", 34}
+ , {"0x42", 66}
+ , {"0b101010", 42}
+ };
+
+struct SignedPair {
+ const char *Str;
+ int64_t Expected;
+} Signed[] =
+ { {"0", 0}
+ , {"-0", 0}
+ , {"127", 127}
+ , {"128", 128}
+ , {"-128", -128}
+ , {"-129", -129}
+ , {"32767", 32767}
+ , {"32768", 32768}
+ , {"-32768", -32768}
+ , {"-32769", -32769}
+ , {"2147483647", 2147483647LL}
+ , {"2147483648", 2147483648LL}
+ , {"-2147483648", -2147483648LL}
+ , {"-2147483649", -2147483649LL}
+ , {"-9223372036854775808", -(9223372036854775807LL) - 1}
+ , {"042", 34}
+ , {"0x42", 66}
+ , {"0b101010", 42}
+ , {"-042", -34}
+ , {"-0x42", -66}
+ , {"-0b101010", -42}
+ };
+
+TEST(StringRefTest, getAsInteger) {
+ uint8_t U8;
+ uint16_t U16;
+ uint32_t U32;
+ uint64_t U64;
+
+ for (size_t i = 0; i < array_lengthof(Unsigned); ++i) {
+ bool U8Success = StringRef(Unsigned[i].Str).getAsInteger(0, U8);
+ if (static_cast<uint8_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U8Success);
+ EXPECT_EQ(U8, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U8Success);
+ }
+ bool U16Success = StringRef(Unsigned[i].Str).getAsInteger(0, U16);
+ if (static_cast<uint16_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U16Success);
+ EXPECT_EQ(U16, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U16Success);
+ }
+ bool U32Success = StringRef(Unsigned[i].Str).getAsInteger(0, U32);
+ if (static_cast<uint32_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U32Success);
+ EXPECT_EQ(U32, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U32Success);
+ }
+ bool U64Success = StringRef(Unsigned[i].Str).getAsInteger(0, U64);
+ if (static_cast<uint64_t>(Unsigned[i].Expected) == Unsigned[i].Expected) {
+ ASSERT_FALSE(U64Success);
+ EXPECT_EQ(U64, Unsigned[i].Expected);
+ } else {
+ ASSERT_TRUE(U64Success);
+ }
+ }
+
+ int8_t S8;
+ int16_t S16;
+ int32_t S32;
+ int64_t S64;
+
+ for (size_t i = 0; i < array_lengthof(Signed); ++i) {
+ bool S8Success = StringRef(Signed[i].Str).getAsInteger(0, S8);
+ if (static_cast<int8_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S8Success);
+ EXPECT_EQ(S8, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S8Success);
+ }
+ bool S16Success = StringRef(Signed[i].Str).getAsInteger(0, S16);
+ if (static_cast<int16_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S16Success);
+ EXPECT_EQ(S16, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S16Success);
+ }
+ bool S32Success = StringRef(Signed[i].Str).getAsInteger(0, S32);
+ if (static_cast<int32_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S32Success);
+ EXPECT_EQ(S32, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S32Success);
+ }
+ bool S64Success = StringRef(Signed[i].Str).getAsInteger(0, S64);
+ if (static_cast<int64_t>(Signed[i].Expected) == Signed[i].Expected) {
+ ASSERT_FALSE(S64Success);
+ EXPECT_EQ(S64, Signed[i].Expected);
+ } else {
+ ASSERT_TRUE(S64Success);
+ }
+ }
+}
+
} // end anonymous namespace
diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp
index 160b69253b6f..479046e01d7f 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -87,6 +87,24 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::Linux, T.getOS());
EXPECT_EQ(Triple::GNU, T.getEnvironment());
+ T = Triple("powerpc-bgp-linux");
+ EXPECT_EQ(Triple::ppc, T.getArch());
+ EXPECT_EQ(Triple::BGP, T.getVendor());
+ EXPECT_EQ(Triple::Linux, T.getOS());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
+ T = Triple("powerpc-bgp-cnk");
+ EXPECT_EQ(Triple::ppc, T.getArch());
+ EXPECT_EQ(Triple::BGP, T.getVendor());
+ EXPECT_EQ(Triple::CNK, T.getOS());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
+ T = Triple("powerpc64-bgq-linux");
+ EXPECT_EQ(Triple::ppc64, T.getArch());
+ EXPECT_EQ(Triple::BGQ, T.getVendor());
+ EXPECT_EQ(Triple::Linux, T.getOS());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
T = Triple("powerpc-dunno-notsure");
EXPECT_EQ(Triple::ppc, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
@@ -154,7 +172,7 @@ TEST(TripleTest, Normalization) {
// Check that normalizing a permutated set of valid components returns a
// triple with the unpermuted components.
StringRef C[4];
- for (int Arch = 1+Triple::UnknownArch; Arch < Triple::InvalidArch; ++Arch) {
+ for (int Arch = 1+Triple::UnknownArch; Arch <= Triple::amdil; ++Arch) {
C[0] = Triple::getArchTypeName(Triple::ArchType(Arch));
for (int Vendor = 1+Triple::UnknownVendor; Vendor <= Triple::PC;
++Vendor) {
@@ -162,12 +180,6 @@ TEST(TripleTest, Normalization) {
for (int OS = 1+Triple::UnknownOS; OS <= Triple::Minix; ++OS) {
C[2] = Triple::getOSTypeName(Triple::OSType(OS));
- // If a value has multiple interpretations, then the permutation
- // test will inevitably fail. Currently this is only the case for
- // "psp" which parses as both an architecture and an O/S.
- if (OS == Triple::Psp)
- continue;
-
std::string E = Join(C[0], C[1], C[2]);
EXPECT_EQ(E, Triple::normalize(Join(C[0], C[1], C[2])));
@@ -212,9 +224,6 @@ TEST(TripleTest, Normalization) {
}
}
- EXPECT_EQ("a-b-psp", Triple::normalize("a-b-psp"));
- EXPECT_EQ("psp-b-c", Triple::normalize("psp-b-c"));
-
// Various real-world funky triples. The value returned by GCC's config.sub
// is given in the comment.
EXPECT_EQ("i386--mingw32", Triple::normalize("i386-mingw32")); // i386-pc-mingw32
@@ -267,4 +276,118 @@ TEST(TripleTest, MutateName) {
}
+TEST(TripleTest, BitWidthPredicates) {
+ Triple T;
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::arm);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::hexagon);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::mips);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::mips64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
+
+ T.setArch(Triple::msp430);
+ EXPECT_TRUE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::ppc);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::ppc64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
+
+ T.setArch(Triple::x86);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::x86_64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
+}
+
+TEST(TripleTest, BitWidthArchVariants) {
+ Triple T;
+ EXPECT_EQ(Triple::UnknownArch, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::UnknownArch);
+ EXPECT_EQ(Triple::UnknownArch, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::arm);
+ EXPECT_EQ(Triple::arm, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::mips);
+ EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::mipsel);
+ EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::ppc);
+ EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::ppc64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::ptx32);
+ EXPECT_EQ(Triple::ptx32, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::ptx64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::sparc);
+ EXPECT_EQ(Triple::sparc, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::sparcv9, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::x86);
+ EXPECT_EQ(Triple::x86, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::x86_64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::mips64);
+ EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::mips64el);
+ EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::ppc64);
+ EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::ppc64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::ptx64);
+ EXPECT_EQ(Triple::ptx32, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::ptx64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::sparcv9);
+ EXPECT_EQ(Triple::sparc, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::sparcv9, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::x86_64);
+ EXPECT_EQ(Triple::x86, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::x86_64, T.get64BitArchVariant().getArch());
+}
+
}
diff --git a/unittests/ADT/VariadicFunctionTest.cpp b/unittests/ADT/VariadicFunctionTest.cpp
new file mode 100644
index 000000000000..cde31205966c
--- /dev/null
+++ b/unittests/ADT/VariadicFunctionTest.cpp
@@ -0,0 +1,110 @@
+//===----------- VariadicFunctionTest.cpp - VariadicFunction unit tests ---===//
+//
+// 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/ArrayRef.h"
+#include "llvm/ADT/VariadicFunction.h"
+
+using namespace llvm;
+namespace {
+
+// Defines a variadic function StringCat() to join strings.
+// StringCat()'s arguments and return value have class types.
+std::string StringCatImpl(ArrayRef<const std::string *> Args) {
+ std::string S;
+ for (unsigned i = 0, e = Args.size(); i < e; ++i)
+ S += *Args[i];
+ return S;
+}
+const VariadicFunction<std::string, std::string, StringCatImpl> StringCat = {};
+
+TEST(VariadicFunctionTest, WorksForClassTypes) {
+ EXPECT_EQ("", StringCat());
+ EXPECT_EQ("a", StringCat("a"));
+ EXPECT_EQ("abc", StringCat("a", "bc"));
+ EXPECT_EQ("0123456789abcdefghijklmnopqrstuv",
+ StringCat("0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
+ "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
+ "u", "v"));
+}
+
+// Defines a variadic function Sum(), whose arguments and return value
+// have primitive types.
+// The return type of SumImp() is deliberately different from its
+// argument type, as we want to test that this works.
+long SumImpl(ArrayRef<const int *> Args) {
+ long Result = 0;
+ for (unsigned i = 0, e = Args.size(); i < e; ++i)
+ Result += *Args[i];
+ return Result;
+}
+const VariadicFunction<long, int, SumImpl> Sum = {};
+
+TEST(VariadicFunctionTest, WorksForPrimitiveTypes) {
+ EXPECT_EQ(0, Sum());
+ EXPECT_EQ(1, Sum(1));
+ EXPECT_EQ(12, Sum(10, 2));
+ EXPECT_EQ(1234567, Sum(1000000, 200000, 30000, 4000, 500, 60, 7));
+}
+
+// Appends an array of strings to dest and returns the number of
+// characters appended.
+int StringAppendImpl(std::string *Dest, ArrayRef<const std::string *> Args) {
+ int Chars = 0;
+ for (unsigned i = 0, e = Args.size(); i < e; ++i) {
+ Chars += Args[i]->size();
+ *Dest += *Args[i];
+ }
+ return Chars;
+}
+const VariadicFunction1<int, std::string *, std::string,
+ StringAppendImpl> StringAppend = {};
+
+TEST(VariadicFunction1Test, Works) {
+ std::string S0("hi");
+ EXPECT_EQ(0, StringAppend(&S0));
+ EXPECT_EQ("hi", S0);
+
+ std::string S1("bin");
+ EXPECT_EQ(2, StringAppend(&S1, "go"));
+ EXPECT_EQ("bingo", S1);
+
+ std::string S4("Fab4");
+ EXPECT_EQ(4 + 4 + 6 + 5,
+ StringAppend(&S4, "John", "Paul", "George", "Ringo"));
+ EXPECT_EQ("Fab4JohnPaulGeorgeRingo", S4);
+}
+
+// Counts how many optional arguments fall in the given range.
+// Returns the result in *num_in_range. We make the return type void
+// as we want to test that VariadicFunction* can handle it.
+void CountInRangeImpl(int *NumInRange, int Low, int High,
+ ArrayRef<const int *> Args) {
+ *NumInRange = 0;
+ for (unsigned i = 0, e = Args.size(); i < e; ++i)
+ if (Low <= *Args[i] && *Args[i] <= High)
+ ++(*NumInRange);
+}
+const VariadicFunction3<void, int *, int, int, int,
+ CountInRangeImpl> CountInRange = {};
+
+TEST(VariadicFunction3Test, Works) {
+ int N = -1;
+ CountInRange(&N, -100, 100);
+ EXPECT_EQ(0, N);
+
+ CountInRange(&N, -100, 100, 42);
+ EXPECT_EQ(1, N);
+
+ CountInRange(&N, -100, 100, 1, 999, -200, 42);
+ EXPECT_EQ(2, N);
+}
+
+} // namespace
diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp
new file mode 100644
index 000000000000..68cfe2836a29
--- /dev/null
+++ b/unittests/Bitcode/BitReaderTest.cpp
@@ -0,0 +1,65 @@
+//===- llvm/unittest/Bitcode/BitReaderTest.cpp - Tests for BitReader ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+static Module *makeLLVMModule() {
+ Module* Mod = new Module("test-mem", getGlobalContext());
+
+ FunctionType* FuncTy =
+ FunctionType::get(Type::getVoidTy(Mod->getContext()), false);
+ Function* Func = Function::Create(FuncTy,GlobalValue::ExternalLinkage,
+ "func", Mod);
+
+ BasicBlock* Entry = BasicBlock::Create(Mod->getContext(), "entry", Func);
+ new UnreachableInst(Mod->getContext(), Entry);
+
+ BasicBlock* BB = BasicBlock::Create(Mod->getContext(), "bb", Func);
+ new UnreachableInst(Mod->getContext(), BB);
+
+ PointerType* Int8Ptr = Type::getInt8PtrTy(Mod->getContext());
+ new GlobalVariable(*Mod, Int8Ptr, /*isConstant=*/true,
+ GlobalValue::ExternalLinkage,
+ BlockAddress::get(BB), "table");
+
+ return Mod;
+}
+
+static void writeModuleToBuffer(SmallVectorImpl<char> &Buffer) {
+ Module *Mod = makeLLVMModule();
+ raw_svector_ostream OS(Buffer);
+ WriteBitcodeToFile(Mod, OS);
+}
+
+TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
+ SmallString<1024> Mem;
+ writeModuleToBuffer(Mem);
+ MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
+ std::string errMsg;
+ Module *m = getLazyBitcodeModule(Buffer, getGlobalContext(), &errMsg);
+ PassManager passes;
+ passes.add(createVerifierPass());
+ passes.run(*m);
+}
+
+}
+}
diff --git a/unittests/Bitcode/Makefile b/unittests/Bitcode/Makefile
new file mode 100644
index 000000000000..aa437e7e2cc5
--- /dev/null
+++ b/unittests/Bitcode/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/Bitcode/Makefile --------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+TESTNAME = Bitcode
+LINK_COMPONENTS := core support bitreader bitwriter
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 81d702981f82..5d691728d80f 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -60,19 +60,23 @@ add_llvm_unittest(ADT
ADT/DenseMapTest.cpp
ADT/DenseSetTest.cpp
ADT/FoldingSet.cpp
+ ADT/HashingTest.cpp
ADT/ilistTest.cpp
ADT/ImmutableSetTest.cpp
ADT/IntEqClassesTest.cpp
ADT/IntervalMapTest.cpp
+ ADT/IntrusiveRefCntPtrTest.cpp
ADT/PackedVectorTest.cpp
ADT/SmallBitVectorTest.cpp
ADT/SmallStringTest.cpp
ADT/SmallVectorTest.cpp
ADT/SparseBitVectorTest.cpp
+ ADT/SparseSetTest.cpp
ADT/StringMapTest.cpp
ADT/StringRefTest.cpp
ADT/TripleTest.cpp
ADT/TwineTest.cpp
+ ADT/VariadicFunctionTest.cpp
)
add_llvm_unittest(Analysis
@@ -83,11 +87,35 @@ add_llvm_unittest(ExecutionEngine
ExecutionEngine/ExecutionEngineTest.cpp
)
+if( LLVM_USE_INTEL_JITEVENTS )
+ include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} )
+ link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
+ set(ProfileTestSources
+ ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
+ )
+ set(LLVM_LINK_COMPONENTS
+ ${LLVM_LINK_COMPONENTS}
+ IntelJITEvents
+ )
+endif( LLVM_USE_INTEL_JITEVENTS )
+
+if( LLVM_USE_OPROFILE )
+ set(ProfileTestSources
+ ${ProfileTestSources}
+ ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
+ )
+ set(LLVM_LINK_COMPONENTS
+ ${LLVM_LINK_COMPONENTS}
+ OProfileJIT
+ )
+endif( LLVM_USE_OPROFILE )
+
set(JITTestsSources
ExecutionEngine/JIT/JITEventListenerTest.cpp
ExecutionEngine/JIT/JITMemoryManagerTest.cpp
ExecutionEngine/JIT/JITTest.cpp
ExecutionEngine/JIT/MultiJITTest.cpp
+ ${ProfileTestSources}
)
if(MSVC)
@@ -96,7 +124,7 @@ endif()
add_llvm_unittest(ExecutionEngine/JIT ${JITTestsSources})
-if(MINGW)
+if(MINGW OR CYGWIN)
set_property(TARGET JITTests PROPERTY LINK_FLAGS -Wl,--export-all-symbols)
endif()
@@ -111,6 +139,7 @@ set(VMCoreSources
VMCore/PassManagerTest.cpp
VMCore/ValueMapTest.cpp
VMCore/VerifierTest.cpp
+ VMCore/DominatorTreeTest.cpp
)
# MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug.
@@ -121,6 +150,10 @@ endif()
add_llvm_unittest(VMCore ${VMCoreSources})
+add_llvm_unittest(Bitcode
+ Bitcode/BitReaderTest.cpp
+ )
+
set(LLVM_LINK_COMPONENTS
Support
Core
@@ -132,6 +165,7 @@ add_llvm_unittest(Support
Support/CommandLineTest.cpp
Support/ConstantRangeTest.cpp
Support/EndianTest.cpp
+ Support/JSONParserTest.cpp
Support/LeakDetectorTest.cpp
Support/MathExtrasTest.cpp
Support/Path.cpp
@@ -141,4 +175,5 @@ add_llvm_unittest(Support
Support/TimeValue.cpp
Support/TypeBuilderTest.cpp
Support/ValueHandleTest.cpp
+ Support/YAMLParserTest.cpp
)
diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index 4dcef20c6e77..74a2ccdd0663 100644
--- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -22,12 +22,13 @@ namespace {
class ExecutionEngineTest : public testing::Test {
protected:
ExecutionEngineTest()
- : M(new Module("<main>", getGlobalContext())),
- Engine(EngineBuilder(M).create()) {
+ : M(new Module("<main>", getGlobalContext())), Error(""),
+ Engine(EngineBuilder(M).setErrorStr(&Error).create()) {
}
virtual void SetUp() {
- ASSERT_TRUE(Engine.get() != NULL);
+ ASSERT_TRUE(Engine.get() != NULL) << "EngineBuilder returned error: '"
+ << Error << "'";
}
GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) {
@@ -36,6 +37,7 @@ protected:
}
Module *const M;
+ std::string Error;
const OwningPtr<ExecutionEngine> Engine;
};
diff --git a/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
new file mode 100644
index 000000000000..8ed7a15be37c
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
@@ -0,0 +1,110 @@
+//===- JITEventListenerTest.cpp - Tests for Intel JITEventListener --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JITEventListenerTestCommon.h"
+
+using namespace llvm;
+
+#include "llvm/ExecutionEngine/IntelJITEventsWrapper.h"
+
+#include <map>
+#include <list>
+
+namespace {
+
+// map of function ("method") IDs to source locations
+NativeCodeMap ReportedDebugFuncs;
+
+} // namespace
+
+/// Mock implementaion of Intel JIT API jitprofiling library
+namespace test_jitprofiling {
+
+int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
+ switch (EventType) {
+ case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
+ EXPECT_TRUE(0 != EventSpecificData);
+ iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
+
+ ReportedDebugFuncs[msg->method_id];
+
+ for(unsigned int i = 0; i < msg->line_number_size; ++i) {
+ EXPECT_TRUE(0 != msg->line_number_table);
+ std::pair<std::string, unsigned int> loc(
+ std::string(msg->source_file_name),
+ msg->line_number_table[i].LineNumber);
+ ReportedDebugFuncs[msg->method_id].push_back(loc);
+ }
+ }
+ break;
+ case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
+ EXPECT_TRUE(0 != EventSpecificData);
+ unsigned int UnloadId
+ = *reinterpret_cast<unsigned int*>(EventSpecificData);
+ EXPECT_TRUE(1 == ReportedDebugFuncs.erase(UnloadId));
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
+ // for testing, pretend we have an Intel Parallel Amplifier XE 2011
+ // instance attached
+ return iJIT_SAMPLING_ON;
+}
+
+unsigned int GetNewMethodID(void) {
+ static unsigned int id = 0;
+ return ++id;
+}
+
+} //namespace test_jitprofiling
+
+class IntelJITEventListenerTest
+ : public JITEventListenerTestBase<IntelJITEventsWrapper> {
+public:
+ IntelJITEventListenerTest()
+ : JITEventListenerTestBase<IntelJITEventsWrapper>(
+ new IntelJITEventsWrapper(test_jitprofiling::NotifyEvent, 0,
+ test_jitprofiling::IsProfilingActive, 0, 0,
+ test_jitprofiling::GetNewMethodID))
+ {
+ EXPECT_TRUE(0 != MockWrapper);
+
+ Listener.reset(JITEventListener::createIntelJITEventListener(
+ MockWrapper.get()));
+ EXPECT_TRUE(0 != Listener);
+ EE->RegisterJITEventListener(Listener.get());
+ }
+};
+
+TEST_F(IntelJITEventListenerTest, NoDebugInfo) {
+ TestNoDebugInfo(ReportedDebugFuncs);
+}
+
+TEST_F(IntelJITEventListenerTest, SingleLine) {
+ TestSingleLine(ReportedDebugFuncs);
+}
+
+TEST_F(IntelJITEventListenerTest, MultipleLines) {
+ TestMultipleLines(ReportedDebugFuncs);
+}
+
+// This testcase is disabled because the Intel JIT API does not support a single
+// JITted function with source lines associated with multiple files
+/*
+TEST_F(IntelJITEventListenerTest, MultipleFiles) {
+ TestMultipleFiles(ReportedDebugFuncs);
+}
+*/
+
+testing::Environment* const jit_env =
+ testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
new file mode 100644
index 000000000000..53608cbfce3d
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
@@ -0,0 +1,209 @@
+//===- JITEventListenerTestCommon.h - Helper for JITEventListener tests ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===-------------------------------------------------------------------------------===//
+
+#ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
+#define JIT_EVENT_LISTENER_TEST_COMMON_H
+
+#include "llvm/Analysis/DIBuilder.h"
+#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/CodeGen/MachineCodeInfo.h"
+#include "llvm/Config/config.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/TypeBuilder.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "gtest/gtest.h"
+
+#include <vector>
+#include <string>
+#include <utility>
+
+typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
+typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
+
+class JITEnvironment : public testing::Environment {
+ virtual void SetUp() {
+ // Required to create a JIT.
+ llvm::InitializeNativeTarget();
+ }
+};
+
+inline unsigned int getLine() {
+ return 12;
+}
+
+inline unsigned int getCol() {
+ return 0;
+}
+
+inline const char* getFilename() {
+ return "mock_source_file.cpp";
+}
+
+// Test fixture shared by tests for listener implementations
+template<typename WrapperT>
+class JITEventListenerTestBase : public testing::Test {
+protected:
+ llvm::OwningPtr<WrapperT> MockWrapper;
+ llvm::OwningPtr<llvm::JITEventListener> Listener;
+
+public:
+ llvm::Module* M;
+ llvm::MDNode* Scope;
+ llvm::ExecutionEngine* EE;
+ llvm::DIBuilder* DebugBuilder;
+ llvm::IRBuilder<> Builder;
+
+ JITEventListenerTestBase(WrapperT* w)
+ : MockWrapper(w)
+ , M(new llvm::Module("module", llvm::getGlobalContext()))
+ , EE(llvm::EngineBuilder(M)
+ .setEngineKind(llvm::EngineKind::JIT)
+ .setOptLevel(llvm::CodeGenOpt::None)
+ .create())
+ , DebugBuilder(new llvm::DIBuilder(*M))
+ , Builder(llvm::getGlobalContext())
+ {
+ DebugBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus,
+ "JIT",
+ "JIT",
+ "JIT",
+ true,
+ "",
+ 1);
+
+ Scope = DebugBuilder->createFile(getFilename(), ".");
+ }
+
+ llvm::Function *buildFunction(const SourceLocations& DebugLocations) {
+ using namespace llvm;
+
+ LLVMContext& GlobalContext = getGlobalContext();
+
+ SourceLocations::const_iterator CurrentDebugLocation
+ = DebugLocations.begin();
+
+ if (CurrentDebugLocation != DebugLocations.end()) {
+ DebugLoc DebugLocation = DebugLoc::get(getLine(), getCol(),
+ DebugBuilder->createFile(CurrentDebugLocation->first, "."));
+ Builder.SetCurrentDebugLocation(DebugLocation);
+ CurrentDebugLocation++;
+ }
+
+ Function *Result = Function::Create(
+ TypeBuilder<int32_t(int32_t), false>::get(GlobalContext),
+ GlobalValue::ExternalLinkage, "id", M);
+ Value *Arg = Result->arg_begin();
+ BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
+ Builder.SetInsertPoint(BB);
+ Value* one = ConstantInt::get(GlobalContext, APInt(32, 1));
+ for(; CurrentDebugLocation != DebugLocations.end();
+ ++CurrentDebugLocation) {
+ Arg = Builder.CreateMul(Arg, Builder.CreateAdd(Arg, one));
+ Builder.SetCurrentDebugLocation(
+ DebugLoc::get(CurrentDebugLocation->second, 0,
+ DebugBuilder->createFile(CurrentDebugLocation->first, ".")));
+ }
+ Builder.CreateRet(Arg);
+ return Result;
+ }
+
+ void TestNoDebugInfo(NativeCodeMap& ReportedDebugFuncs) {
+ SourceLocations DebugLocations;
+ llvm::Function* f = buildFunction(DebugLocations);
+ EXPECT_TRUE(0 != f);
+
+ //Cause JITting and callbacks to our listener
+ EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+ EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+
+ EE->freeMachineCodeForFunction(f);
+ EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+ }
+
+ void TestSingleLine(NativeCodeMap& ReportedDebugFuncs) {
+ SourceLocations DebugLocations;
+ DebugLocations.push_back(std::make_pair(std::string(getFilename()),
+ getLine()));
+ llvm::Function* f = buildFunction(DebugLocations);
+ EXPECT_TRUE(0 != f);
+
+ EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+ EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+ EXPECT_STREQ(ReportedDebugFuncs.begin()->second.begin()->first.c_str(),
+ getFilename());
+ EXPECT_EQ(ReportedDebugFuncs.begin()->second.begin()->second, getLine());
+
+ EE->freeMachineCodeForFunction(f);
+ EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+ }
+
+ void TestMultipleLines(NativeCodeMap& ReportedDebugFuncs) {
+ using namespace std;
+
+ SourceLocations DebugLocations;
+ unsigned int c = 5;
+ for(unsigned int i = 0; i < c; ++i) {
+ DebugLocations.push_back(make_pair(string(getFilename()), getLine() + i));
+ }
+
+ llvm::Function* f = buildFunction(DebugLocations);
+ EXPECT_TRUE(0 != f);
+
+ EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+ EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+ SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
+ EXPECT_EQ(c, FunctionInfo.size());
+
+ int VerifyCount = 0;
+ for(SourceLocations::iterator i = FunctionInfo.begin();
+ i != FunctionInfo.end();
+ ++i) {
+ EXPECT_STREQ(i->first.c_str(), getFilename());
+ EXPECT_EQ(i->second, getLine() + VerifyCount);
+ VerifyCount++;
+ }
+
+ EE->freeMachineCodeForFunction(f);
+ EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+ }
+
+ void TestMultipleFiles(NativeCodeMap& ReportedDebugFuncs) {
+
+ std::string secondFilename("another_file.cpp");
+
+ SourceLocations DebugLocations;
+ DebugLocations.push_back(std::make_pair(std::string(getFilename()),
+ getLine()));
+ DebugLocations.push_back(std::make_pair(secondFilename, getLine()));
+ llvm::Function* f = buildFunction(DebugLocations);
+ EXPECT_TRUE(0 != f);
+
+ EXPECT_TRUE(0 != EE->getPointerToFunction(f));
+ EXPECT_TRUE(1 == ReportedDebugFuncs.size());
+ SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
+ EXPECT_TRUE(2 == FunctionInfo.size());
+
+ EXPECT_STREQ(FunctionInfo.at(0).first.c_str(), getFilename());
+ EXPECT_STREQ(FunctionInfo.at(1).first.c_str(), secondFilename.c_str());
+
+ EXPECT_EQ(FunctionInfo.at(0).second, getLine());
+ EXPECT_EQ(FunctionInfo.at(1).second, getLine());
+
+ EE->freeMachineCodeForFunction(f);
+ EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
+ }
+};
+
+#endif //JIT_EVENT_LISTENER_TEST_COMMON_H
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
index 2ef273020f9e..fa52321b32e0 100644
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -64,6 +64,10 @@ public:
: Base(JITMemoryManager::CreateDefaultMemManager()) {
stubsAllocated = 0;
}
+ virtual void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true) {
+ return Base->getPointerToNamedFunction(Name, AbortOnFailure);
+ }
virtual void setMemoryWritable() { Base->setMemoryWritable(); }
virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
@@ -113,6 +117,14 @@ public:
EndFunctionBodyCall(F, FunctionStart, FunctionEnd));
Base->endFunctionBody(F, FunctionStart, FunctionEnd);
}
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID) {
+ return Base->allocateDataSection(Size, Alignment, SectionID);
+ }
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID) {
+ return Base->allocateCodeSection(Size, Alignment, SectionID);
+ }
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
return Base->allocateSpace(Size, Alignment);
}
@@ -184,7 +196,7 @@ bool LoadAssemblyInto(Module *M, const char *assembly) {
NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
std::string errMsg;
raw_string_ostream os(errMsg);
- Error.Print("", os);
+ Error.print("", os);
EXPECT_TRUE(success) << os.str();
return success;
}
diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile
index f5abe75a8f68..c404fb002a62 100644
--- a/unittests/ExecutionEngine/JIT/Makefile
+++ b/unittests/ExecutionEngine/JIT/Makefile
@@ -12,6 +12,30 @@ TESTNAME = JIT
LINK_COMPONENTS := asmparser bitreader bitwriter core jit native support
include $(LEVEL)/Makefile.config
+
+SOURCES := JITEventListenerTest.cpp JITMemoryManagerTest.cpp JITTest.cpp MultiJITTest.cpp
+
+
+ifeq ($(USE_INTEL_JITEVENTS), 1)
+ # Build the Intel JIT Events interface tests
+ SOURCES += IntelJITEventListenerTest.cpp
+
+ # Add the Intel JIT Events include directory
+ CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
+
+ # Link against the LLVM Intel JIT Evens interface library
+ LINK_COMPONENTS += inteljitevents
+endif
+
+ifeq ($(USE_OPROFILE), 1)
+ # Build the OProfile JIT interface tests
+ SOURCES += OProfileJITEventListenerTest.cpp
+
+ # Link against the LLVM oprofile interface library
+ LINK_COMPONENTS += oprofilejit
+endif
+
+
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
# Permit these tests to use the JIT's symbolic lookup.
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
index 91ea64aa53c9..5b99d5b676e2 100644
--- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
+++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
@@ -26,7 +26,7 @@ bool LoadAssemblyInto(Module *M, const char *assembly) {
NULL != ParseAssemblyString(assembly, M, Error, M->getContext());
std::string errMsg;
raw_string_ostream os(errMsg);
- Error.Print("", os);
+ Error.print("", os);
EXPECT_TRUE(success) << os.str();
return success;
}
@@ -160,8 +160,21 @@ TEST(MultiJitTest, JitPool) {
EXPECT_EQ(getPointerToNamedFunction("foo2"), foo2);
// Symbol search
- EXPECT_EQ((intptr_t)getPointerToNamedFunction("getPointerToNamedFunction"),
- (intptr_t)&getPointerToNamedFunction);
+ intptr_t
+ sa = (intptr_t)getPointerToNamedFunction("getPointerToNamedFunction");
+ EXPECT_TRUE(sa != 0);
+ intptr_t fa = (intptr_t)&getPointerToNamedFunction;
+ EXPECT_TRUE(fa != 0);
+#ifdef __i386__
+ // getPointerToNamedFunction might be indirect jump on Win32 --enable-shared.
+ // FF 25 <disp32>: jmp *(pointer to IAT)
+ if (sa != fa && memcmp((char *)fa, "\xFF\x25", 2) == 0) {
+ fa = *(intptr_t *)(fa + 2); // Address to IAT
+ EXPECT_TRUE(fa != 0);
+ fa = *(intptr_t *)fa; // Bound value of IAT
+ }
+#endif
+ EXPECT_TRUE(sa == fa);
}
#endif // !defined(__arm__)
diff --git a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
new file mode 100644
index 000000000000..9b0ee609923c
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
@@ -0,0 +1,166 @@
+//===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--------------------------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/OProfileWrapper.h"
+#include "JITEventListenerTestCommon.h"
+
+#include <map>
+#include <list>
+
+using namespace llvm;
+
+namespace {
+
+struct OprofileNativeFunction {
+ const char* Name;
+ uint64_t Addr;
+ const void* CodePtr;
+ unsigned int CodeSize;
+
+ OprofileNativeFunction(const char* name,
+ uint64_t addr,
+ const void* code,
+ unsigned int size)
+ : Name(name)
+ , Addr(addr)
+ , CodePtr(code)
+ , CodeSize(size) {
+ }
+};
+
+typedef std::list<OprofileNativeFunction> NativeFunctionList;
+typedef std::list<debug_line_info> NativeDebugList;
+NativeFunctionList NativeFunctions;
+
+NativeCodeMap ReportedDebugFuncs;
+
+} // namespace
+
+/// Mock implementaion of opagent library
+namespace test_opagent {
+
+op_agent_t globalAgent = reinterpret_cast<op_agent_t>(42);
+
+op_agent_t open_agent()
+{
+ // return non-null op_agent_t
+ return globalAgent;
+}
+
+int close_agent(op_agent_t agent)
+{
+ EXPECT_EQ(globalAgent, agent);
+ return 0;
+}
+
+int write_native_code(op_agent_t agent,
+ const char* name,
+ uint64_t addr,
+ void const* code,
+ unsigned int size)
+{
+ EXPECT_EQ(globalAgent, agent);
+ OprofileNativeFunction func(name, addr, code, size);
+ NativeFunctions.push_back(func);
+
+ // Verify no other registration has take place for the same address
+ EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
+
+ ReportedDebugFuncs[addr];
+ return 0;
+}
+
+int write_debug_line_info(op_agent_t agent,
+ void const* code,
+ size_t num_entries,
+ struct debug_line_info const* info)
+{
+ EXPECT_EQ(globalAgent, agent);
+
+ //verify code has been loaded first
+ uint64_t addr = reinterpret_cast<uint64_t>(code);
+ NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
+ EXPECT_TRUE(i != ReportedDebugFuncs.end());
+
+ NativeDebugList NativeInfo(info, info + num_entries);
+
+ SourceLocations locs;
+ for(NativeDebugList::iterator i = NativeInfo.begin();
+ i != NativeInfo.end();
+ ++i) {
+ locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
+ }
+ ReportedDebugFuncs[addr] = locs;
+
+ return 0;
+}
+
+int unload_native_code(op_agent_t agent, uint64_t addr) {
+ EXPECT_EQ(globalAgent, agent);
+
+ //verify that something for the given JIT addr has been loaded first
+ NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
+ EXPECT_TRUE(i != ReportedDebugFuncs.end());
+ ReportedDebugFuncs.erase(i);
+ return 0;
+}
+
+int version() {
+ return 1;
+}
+
+bool is_oprofile_running() {
+ return true;
+}
+
+} //namespace test_opagent
+
+class OProfileJITEventListenerTest
+: public JITEventListenerTestBase<OProfileWrapper>
+{
+public:
+ OProfileJITEventListenerTest()
+ : JITEventListenerTestBase<OProfileWrapper>(
+ new OProfileWrapper(test_opagent::open_agent,
+ test_opagent::close_agent,
+ test_opagent::write_native_code,
+ test_opagent::write_debug_line_info,
+ test_opagent::unload_native_code,
+ test_opagent::version,
+ test_opagent::version,
+ test_opagent::is_oprofile_running))
+ {
+ EXPECT_TRUE(0 != MockWrapper);
+
+ Listener.reset(JITEventListener::createOProfileJITEventListener(
+ MockWrapper.get()));
+ EXPECT_TRUE(0 != Listener);
+ EE->RegisterJITEventListener(Listener.get());
+ }
+};
+
+TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
+ TestNoDebugInfo(ReportedDebugFuncs);
+}
+
+TEST_F(OProfileJITEventListenerTest, SingleLine) {
+ TestSingleLine(ReportedDebugFuncs);
+}
+
+TEST_F(OProfileJITEventListenerTest, MultipleLines) {
+ TestMultipleLines(ReportedDebugFuncs);
+}
+
+TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
+ TestMultipleFiles(ReportedDebugFuncs);
+}
+
+testing::Environment* const jit_env =
+ testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index d4ef92ffb392..a0395cdad3bf 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -10,9 +10,7 @@
LEVEL = ../..
TESTNAME = ExecutionEngine
LINK_COMPONENTS := engine interpreter
-
-include $(LEVEL)/Makefile.config
-
PARALLEL_DIRS = JIT
+include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Makefile b/unittests/Makefile
index 0401cd1c673a..27afccf02e36 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -9,7 +9,7 @@
LEVEL = ..
-PARALLEL_DIRS = ADT ExecutionEngine Support Transforms VMCore Analysis
+PARALLEL_DIRS = ADT ExecutionEngine Support Transforms VMCore Analysis Bitcode
include $(LEVEL)/Makefile.common
diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest
index 580ad7d71918..bd32aed4b0a2 100644
--- a/unittests/Makefile.unittest
+++ b/unittests/Makefile.unittest
@@ -34,7 +34,7 @@ ifneq ($(HAVE_PTHREAD), 1)
CPP.Flags += -DGTEST_HAS_PTHREAD=0
endif
-TESTLIBS = -lGoogleTest -lUnitTestMain
+TESTLIBS = -lgtest -lgtest_main
ifeq ($(ENABLE_SHARED), 1)
ifneq (,$(RPATH))
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
index 6c0fca90456e..8b463c11dfca 100644
--- a/unittests/Support/AllocatorTest.cpp
+++ b/unittests/Support/AllocatorTest.cpp
@@ -93,6 +93,14 @@ TEST(AllocatorTest, TestOverflow) {
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
+// Test allocating with a size larger than the initial slab size.
+TEST(AllocatorTest, TestSmallSlabSize) {
+ BumpPtrAllocator Alloc(128);
+
+ Alloc.Allocate(200, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
// Mock slab allocator that returns slabs aligned on 4096 bytes. There is no
// easy portable way to do this, so this is kind of a hack.
class MockSlabAllocator : public SlabAllocator {
diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp
index edeea9b357f5..df256424b82d 100644
--- a/unittests/Support/BlockFrequencyTest.cpp
+++ b/unittests/Support/BlockFrequencyTest.cpp
@@ -53,4 +53,33 @@ TEST(BlockFrequencyTest, MaxToMax) {
EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
}
+TEST(BlockFrequencyTest, ProbabilityCompare) {
+ BranchProbability A(4, 5);
+ BranchProbability B(4U << 29, 5U << 29);
+ BranchProbability C(3, 4);
+
+ EXPECT_TRUE(A == B);
+ EXPECT_FALSE(A != B);
+ EXPECT_FALSE(A < B);
+ EXPECT_FALSE(A > B);
+ EXPECT_TRUE(A <= B);
+ EXPECT_TRUE(A >= B);
+
+ EXPECT_FALSE(B == C);
+ EXPECT_TRUE(B != C);
+ EXPECT_FALSE(B < C);
+ EXPECT_TRUE(B > C);
+ EXPECT_FALSE(B <= C);
+ EXPECT_TRUE(B >= C);
+
+ BranchProbability BigZero(0, UINT32_MAX);
+ BranchProbability BigOne(UINT32_MAX, UINT32_MAX);
+ EXPECT_FALSE(BigZero == BigOne);
+ EXPECT_TRUE(BigZero != BigOne);
+ EXPECT_TRUE(BigZero < BigOne);
+ EXPECT_FALSE(BigZero > BigOne);
+ EXPECT_TRUE(BigZero <= BigOne);
+ EXPECT_FALSE(BigZero >= BigOne);
+}
+
}
diff --git a/unittests/Support/Casting.cpp b/unittests/Support/Casting.cpp
index ae84693bd636..ca0b40b1f55b 100644
--- a/unittests/Support/Casting.cpp
+++ b/unittests/Support/Casting.cpp
@@ -69,7 +69,9 @@ namespace {
const foo *null_foo = NULL;
+bar B;
extern bar &B1;
+bar &B1 = B;
extern const bar *B2;
// test various configurations of const
const bar &B3 = B1;
@@ -145,9 +147,6 @@ TEST(CastingTest, dyn_cast_or_null) {
//foo &F23 = cast_or_null<foo>(B1);
//const foo &F24 = cast_or_null<foo>(B3);
-
-bar B;
-bar &B1 = B;
const bar *B2 = &B;
} // anonymous namespace
diff --git a/unittests/Support/IRBuilderTest.cpp b/unittests/Support/IRBuilderTest.cpp
index 5d635ae361e0..b15de9ed3839 100644
--- a/unittests/Support/IRBuilderTest.cpp
+++ b/unittests/Support/IRBuilderTest.cpp
@@ -19,6 +19,7 @@
using namespace llvm;
+namespace {
class IRBuilderTest : public testing::Test {
protected:
virtual void SetUp() {
@@ -37,6 +38,7 @@ protected:
OwningPtr<Module> M;
BasicBlock *BB;
};
+}
TEST_F(IRBuilderTest, Lifetime) {
IRBuilder<> Builder(BB);
diff --git a/unittests/Support/JSONParserTest.cpp b/unittests/Support/JSONParserTest.cpp
new file mode 100644
index 000000000000..e9efb817c298
--- /dev/null
+++ b/unittests/Support/JSONParserTest.cpp
@@ -0,0 +1,191 @@
+//===- unittest/Tooling/JSONParserTest ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/JSONParser.h"
+#include "llvm/ADT/Twine.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+// Checks that the given input gives a parse error. Makes sure that an error
+// text is available and the parse fails.
+static void ExpectParseError(StringRef Message, StringRef Input) {
+ SourceMgr SM;
+ JSONParser Parser(Input, &SM);
+ EXPECT_FALSE(Parser.validate()) << Message << ": " << Input;
+ EXPECT_TRUE(Parser.failed()) << Message << ": " << Input;
+}
+
+// Checks that the given input can be parsed without error.
+static void ExpectParseSuccess(StringRef Message, StringRef Input) {
+ SourceMgr SM;
+ JSONParser Parser(Input, &SM);
+ EXPECT_TRUE(Parser.validate()) << Message << ": " << Input;
+}
+
+TEST(JSONParser, FailsOnEmptyString) {
+ ExpectParseError("Empty JSON text", "");
+}
+
+TEST(JSONParser, FailsIfStartsWithString) {
+ ExpectParseError("Top-level string", "\"x\"");
+}
+
+TEST(JSONParser, ParsesEmptyArray) {
+ ExpectParseSuccess("Empty array", "[]");
+}
+
+TEST(JSONParser, FailsIfNotClosingArray) {
+ ExpectParseError("Not closing array", "[");
+ ExpectParseError("Not closing array", " [ ");
+ ExpectParseError("Not closing array", " [x");
+}
+
+TEST(JSONParser, ParsesEmptyArrayWithWhitespace) {
+ ExpectParseSuccess("Array with spaces", " [ ] ");
+ ExpectParseSuccess("All whitespaces", "\t\r\n[\t\n \t\r ]\t\r \n\n");
+}
+
+TEST(JSONParser, ParsesEmptyObject) {
+ ExpectParseSuccess("Empty object", "[{}]");
+}
+
+TEST(JSONParser, ParsesObject) {
+ ExpectParseSuccess("Object with an entry", "[{\"a\":\"/b\"}]");
+}
+
+TEST(JSONParser, ParsesMultipleKeyValuePairsInObject) {
+ ExpectParseSuccess("Multiple key, value pairs",
+ "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]");
+}
+
+TEST(JSONParser, FailsIfNotClosingObject) {
+ ExpectParseError("Missing close on empty", "[{]");
+ ExpectParseError("Missing close after pair", "[{\"a\":\"b\"]");
+}
+
+TEST(JSONParser, FailsIfMissingColon) {
+ ExpectParseError("Missing colon between key and value", "[{\"a\"\"/b\"}]");
+ ExpectParseError("Missing colon between key and value", "[{\"a\" \"b\"}]");
+}
+
+TEST(JSONParser, FailsOnMissingQuote) {
+ ExpectParseError("Missing open quote", "[{a\":\"b\"}]");
+ ExpectParseError("Missing closing quote", "[{\"a\":\"b}]");
+}
+
+TEST(JSONParser, ParsesEscapedQuotes) {
+ ExpectParseSuccess("Parses escaped string in key and value",
+ "[{\"a\":\"\\\"b\\\" \\\" \\\"\"}]");
+}
+
+TEST(JSONParser, ParsesEmptyString) {
+ ExpectParseSuccess("Parses empty string in value", "[{\"a\":\"\"}]");
+}
+
+TEST(JSONParser, FailsOnMissingString) {
+ ExpectParseError("Missing value", "[{\"a\":}]");
+ ExpectParseError("Missing key", "[{:\"b\"}]");
+}
+
+TEST(JSONParser, ParsesMultipleObjects) {
+ ExpectParseSuccess(
+ "Multiple objects in array",
+ "["
+ " { \"a\" : \"b\" },"
+ " { \"a\" : \"b\" },"
+ " { \"a\" : \"b\" }"
+ "]");
+}
+
+TEST(JSONParser, FailsOnMissingComma) {
+ ExpectParseError(
+ "Missing comma",
+ "["
+ " { \"a\" : \"b\" }"
+ " { \"a\" : \"b\" }"
+ "]");
+}
+
+TEST(JSONParser, FailsOnSuperfluousComma) {
+ ExpectParseError("Superfluous comma in array", "[ { \"a\" : \"b\" }, ]");
+ ExpectParseError("Superfluous comma in object", "{ \"a\" : \"b\", }");
+}
+
+TEST(JSONParser, ParsesSpacesInBetweenTokens) {
+ ExpectParseSuccess(
+ "Various whitespace between tokens",
+ " \t \n\n \r [ \t \n\n \r"
+ " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
+ " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r,\t \n\n \r"
+ " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
+ " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r]\t \n\n \r");
+}
+
+TEST(JSONParser, ParsesArrayOfArrays) {
+ ExpectParseSuccess("Array of arrays", "[[]]");
+}
+
+TEST(JSONParser, HandlesEndOfFileGracefully) {
+ ExpectParseError("In string starting with EOF", "[\"");
+ ExpectParseError("In string hitting EOF", "[\" ");
+ ExpectParseError("In string escaping EOF", "[\" \\");
+ ExpectParseError("In array starting with EOF", "[");
+ ExpectParseError("In array element starting with EOF", "[[], ");
+ ExpectParseError("In array hitting EOF", "[[] ");
+ ExpectParseError("In array hitting EOF", "[[]");
+ ExpectParseError("In object hitting EOF", "{\"\"");
+}
+
+// Checks that the given string can be parsed into an identical string inside
+// of an array.
+static void ExpectCanParseString(StringRef String) {
+ std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
+ SourceMgr SM;
+ JSONParser Parser(StringInArray, &SM);
+ const JSONArray *ParsedArray = dyn_cast<JSONArray>(Parser.parseRoot());
+ StringRef ParsedString =
+ dyn_cast<JSONString>(*ParsedArray->begin())->getRawText();
+ EXPECT_EQ(String, ParsedString.str());
+}
+
+// Checks that parsing the given string inside an array fails.
+static void ExpectCannotParseString(StringRef String) {
+ std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
+ ExpectParseError((Twine("When parsing string \"") + String + "\"").str(),
+ StringInArray);
+}
+
+TEST(JSONParser, ParsesStrings) {
+ ExpectCanParseString("");
+ ExpectCannotParseString("\\");
+ ExpectCannotParseString("\"");
+ ExpectCanParseString(" ");
+ ExpectCanParseString("\\ ");
+ ExpectCanParseString("\\\"");
+ ExpectCannotParseString("\"\\");
+ ExpectCannotParseString(" \\");
+ ExpectCanParseString("\\\\");
+ ExpectCannotParseString("\\\\\\");
+ ExpectCanParseString("\\\\\\\\");
+ ExpectCanParseString("\\\" ");
+ ExpectCannotParseString("\\\\\" ");
+ ExpectCanParseString("\\\\\\\" ");
+ ExpectCanParseString(" \\\\ \\\" \\\\\\\" ");
+}
+
+TEST(JSONParser, WorksWithIteratorAlgorithms) {
+ SourceMgr SM;
+ JSONParser Parser("[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]", &SM);
+ const JSONArray *Array = dyn_cast<JSONArray>(Parser.parseRoot());
+ EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));
+}
+
+} // end namespace llvm
diff --git a/unittests/Support/ManagedStatic.cpp b/unittests/Support/ManagedStatic.cpp
new file mode 100644
index 000000000000..bfeb0a7b6fba
--- /dev/null
+++ b/unittests/Support/ManagedStatic.cpp
@@ -0,0 +1,44 @@
+//===- llvm/unittest/Support/ManagedStatic.cpp - ManagedStatic tests ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Config/config.h"
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+#ifdef HAVE_PTHREAD_H
+namespace test1 {
+ llvm::ManagedStatic<int> ms;
+ void *helper(void*) {
+ *ms;
+ return NULL;
+ }
+}
+
+TEST(Initialize, MultipleThreads) {
+ // Run this test under tsan: http://code.google.com/p/data-race-test/
+
+ llvm_start_multithreaded();
+ pthread_t t1, t2;
+ pthread_create(&t1, NULL, test1::helper, NULL);
+ pthread_create(&t2, NULL, test1::helper, NULL);
+ pthread_join(t1, NULL);
+ pthread_join(t2, NULL);
+ llvm_stop_multithreaded();
+}
+#endif
+
+} // anonymous namespace
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 60d08bc92dbe..358dad0f838f 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -183,6 +183,11 @@ TEST_F(FileSystemTest, TempFiles) {
ASSERT_NO_ERROR(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2));
ASSERT_NE(TempPath.str(), TempPath2.str());
+ fs::file_status A, B;
+ ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
+ ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
+ EXPECT_FALSE(fs::equivalent(A, B));
+
// Try to copy the first to the second.
EXPECT_EQ(
fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists);
@@ -204,6 +209,9 @@ TEST_F(FileSystemTest, TempFiles) {
bool equal;
ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
EXPECT_TRUE(equal);
+ ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
+ ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
+ EXPECT_TRUE(fs::equivalent(A, B));
// Remove Temp1.
::close(FileDescriptor);
@@ -223,6 +231,60 @@ TEST_F(FileSystemTest, DirectoryIteration) {
error_code ec;
for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
ASSERT_NO_ERROR(ec);
+
+ // Create a known hierarchy to recurse over.
+ bool existed;
+ ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
+ + "/recursive/a0/aa1", existed));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
+ + "/recursive/a0/ab1", existed));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
+ + "/recursive/dontlookhere/da1", existed));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
+ + "/recursive/z0/za1", existed));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
+ + "/recursive/pop/p1", existed));
+ typedef std::vector<std::string> v_t;
+ v_t visited;
+ for (fs::recursive_directory_iterator i(Twine(TestDirectory)
+ + "/recursive", ec), e; i != e; i.increment(ec)){
+ ASSERT_NO_ERROR(ec);
+ if (path::filename(i->path()) == "p1") {
+ i.pop();
+ // FIXME: recursive_directory_iterator should be more robust.
+ if (i == e) break;
+ }
+ if (path::filename(i->path()) == "dontlookhere")
+ i.no_push();
+ visited.push_back(path::filename(i->path()));
+ }
+ v_t::const_iterator a0 = std::find(visited.begin(), visited.end(), "a0");
+ v_t::const_iterator aa1 = std::find(visited.begin(), visited.end(), "aa1");
+ v_t::const_iterator ab1 = std::find(visited.begin(), visited.end(), "ab1");
+ v_t::const_iterator dontlookhere = std::find(visited.begin(), visited.end(),
+ "dontlookhere");
+ v_t::const_iterator da1 = std::find(visited.begin(), visited.end(), "da1");
+ v_t::const_iterator z0 = std::find(visited.begin(), visited.end(), "z0");
+ v_t::const_iterator za1 = std::find(visited.begin(), visited.end(), "za1");
+ v_t::const_iterator pop = std::find(visited.begin(), visited.end(), "pop");
+ v_t::const_iterator p1 = std::find(visited.begin(), visited.end(), "p1");
+
+ // Make sure that each path was visited correctly.
+ ASSERT_NE(a0, visited.end());
+ ASSERT_NE(aa1, visited.end());
+ ASSERT_NE(ab1, visited.end());
+ ASSERT_NE(dontlookhere, visited.end());
+ ASSERT_EQ(da1, visited.end()); // Not visited.
+ ASSERT_NE(z0, visited.end());
+ ASSERT_NE(za1, visited.end());
+ ASSERT_NE(pop, visited.end());
+ ASSERT_EQ(p1, visited.end()); // Not visited.
+
+ // Make sure that parents were visited before children. No other ordering
+ // guarantees can be made across siblings.
+ ASSERT_LT(a0, aa1);
+ ASSERT_LT(a0, ab1);
+ ASSERT_LT(z0, za1);
}
TEST_F(FileSystemTest, Magic) {
diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp
new file mode 100644
index 000000000000..e88427ac09d3
--- /dev/null
+++ b/unittests/Support/YAMLParserTest.cpp
@@ -0,0 +1,179 @@
+//===- unittest/Support/YAMLParserTest ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+// Checks that the given input gives a parse error. Makes sure that an error
+// text is available and the parse fails.
+static void ExpectParseError(StringRef Message, StringRef Input) {
+ SourceMgr SM;
+ yaml::Stream Stream(Input, SM);
+ EXPECT_FALSE(Stream.validate()) << Message << ": " << Input;
+ EXPECT_TRUE(Stream.failed()) << Message << ": " << Input;
+}
+
+// Checks that the given input can be parsed without error.
+static void ExpectParseSuccess(StringRef Message, StringRef Input) {
+ SourceMgr SM;
+ yaml::Stream Stream(Input, SM);
+ EXPECT_TRUE(Stream.validate()) << Message << ": " << Input;
+}
+
+TEST(YAMLParser, ParsesEmptyArray) {
+ ExpectParseSuccess("Empty array", "[]");
+}
+
+TEST(YAMLParser, FailsIfNotClosingArray) {
+ ExpectParseError("Not closing array", "[");
+ ExpectParseError("Not closing array", " [ ");
+ ExpectParseError("Not closing array", " [x");
+}
+
+TEST(YAMLParser, ParsesEmptyArrayWithWhitespace) {
+ ExpectParseSuccess("Array with spaces", " [ ] ");
+ ExpectParseSuccess("All whitespaces", "\t\r\n[\t\n \t\r ]\t\r \n\n");
+}
+
+TEST(YAMLParser, ParsesEmptyObject) {
+ ExpectParseSuccess("Empty object", "[{}]");
+}
+
+TEST(YAMLParser, ParsesObject) {
+ ExpectParseSuccess("Object with an entry", "[{\"a\":\"/b\"}]");
+}
+
+TEST(YAMLParser, ParsesMultipleKeyValuePairsInObject) {
+ ExpectParseSuccess("Multiple key, value pairs",
+ "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]");
+}
+
+TEST(YAMLParser, FailsIfNotClosingObject) {
+ ExpectParseError("Missing close on empty", "[{]");
+ ExpectParseError("Missing close after pair", "[{\"a\":\"b\"]");
+}
+
+TEST(YAMLParser, FailsIfMissingColon) {
+ ExpectParseError("Missing colon between key and value", "[{\"a\"\"/b\"}]");
+ ExpectParseError("Missing colon between key and value", "[{\"a\" \"b\"}]");
+}
+
+TEST(YAMLParser, FailsOnMissingQuote) {
+ ExpectParseError("Missing open quote", "[{a\":\"b\"}]");
+ ExpectParseError("Missing closing quote", "[{\"a\":\"b}]");
+}
+
+TEST(YAMLParser, ParsesEscapedQuotes) {
+ ExpectParseSuccess("Parses escaped string in key and value",
+ "[{\"a\":\"\\\"b\\\" \\\" \\\"\"}]");
+}
+
+TEST(YAMLParser, ParsesEmptyString) {
+ ExpectParseSuccess("Parses empty string in value", "[{\"a\":\"\"}]");
+}
+
+TEST(YAMLParser, ParsesMultipleObjects) {
+ ExpectParseSuccess(
+ "Multiple objects in array",
+ "["
+ " { \"a\" : \"b\" },"
+ " { \"a\" : \"b\" },"
+ " { \"a\" : \"b\" }"
+ "]");
+}
+
+TEST(YAMLParser, FailsOnMissingComma) {
+ ExpectParseError(
+ "Missing comma",
+ "["
+ " { \"a\" : \"b\" }"
+ " { \"a\" : \"b\" }"
+ "]");
+}
+
+TEST(YAMLParser, ParsesSpacesInBetweenTokens) {
+ ExpectParseSuccess(
+ "Various whitespace between tokens",
+ " \t \n\n \r [ \t \n\n \r"
+ " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
+ " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r,\t \n\n \r"
+ " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
+ " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r]\t \n\n \r");
+}
+
+TEST(YAMLParser, ParsesArrayOfArrays) {
+ ExpectParseSuccess("Array of arrays", "[[]]");
+}
+
+TEST(YAMLParser, HandlesEndOfFileGracefully) {
+ ExpectParseError("In string starting with EOF", "[\"");
+ ExpectParseError("In string hitting EOF", "[\" ");
+ ExpectParseError("In string escaping EOF", "[\" \\");
+ ExpectParseError("In array starting with EOF", "[");
+ ExpectParseError("In array element starting with EOF", "[[], ");
+ ExpectParseError("In array hitting EOF", "[[] ");
+ ExpectParseError("In array hitting EOF", "[[]");
+ ExpectParseError("In object hitting EOF", "{\"\"");
+}
+
+// Checks that the given string can be parsed into an identical string inside
+// of an array.
+static void ExpectCanParseString(StringRef String) {
+ std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
+ SourceMgr SM;
+ yaml::Stream Stream(StringInArray, SM);
+ yaml::SequenceNode *ParsedSequence
+ = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());
+ StringRef ParsedString
+ = dyn_cast<yaml::ScalarNode>(
+ static_cast<yaml::Node*>(ParsedSequence->begin()))->getRawValue();
+ ParsedString = ParsedString.substr(1, ParsedString.size() - 2);
+ EXPECT_EQ(String, ParsedString.str());
+}
+
+// Checks that parsing the given string inside an array fails.
+static void ExpectCannotParseString(StringRef String) {
+ std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
+ ExpectParseError((Twine("When parsing string \"") + String + "\"").str(),
+ StringInArray);
+}
+
+TEST(YAMLParser, ParsesStrings) {
+ ExpectCanParseString("");
+ ExpectCannotParseString("\\");
+ ExpectCannotParseString("\"");
+ ExpectCanParseString(" ");
+ ExpectCanParseString("\\ ");
+ ExpectCanParseString("\\\"");
+ ExpectCannotParseString("\"\\");
+ ExpectCannotParseString(" \\");
+ ExpectCanParseString("\\\\");
+ ExpectCannotParseString("\\\\\\");
+ ExpectCanParseString("\\\\\\\\");
+ ExpectCanParseString("\\\" ");
+ ExpectCannotParseString("\\\\\" ");
+ ExpectCanParseString("\\\\\\\" ");
+ ExpectCanParseString(" \\\\ \\\" \\\\\\\" ");
+}
+
+TEST(YAMLParser, WorksWithIteratorAlgorithms) {
+ SourceMgr SM;
+ yaml::Stream Stream("[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]", SM);
+ yaml::SequenceNode *Array
+ = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());
+ EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));
+}
+
+} // end namespace llvm
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index 1b858695b1d3..4243b2d39de7 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -17,6 +17,7 @@
using namespace llvm;
+namespace {
class CloneInstruction : public ::testing::Test {
protected:
virtual void SetUp() {
@@ -47,6 +48,7 @@ protected:
LLVMContext context;
Value *V;
};
+}
TEST_F(CloneInstruction, OverflowBits) {
V = new Argument(Type::getInt32Ty(context));
diff --git a/unittests/VMCore/DominatorTreeTest.cpp b/unittests/VMCore/DominatorTreeTest.cpp
new file mode 100644
index 000000000000..f6a90605a716
--- /dev/null
+++ b/unittests/VMCore/DominatorTreeTest.cpp
@@ -0,0 +1,195 @@
+#include "llvm/Instructions.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Assembly/Parser.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+ void initializeDPassPass(PassRegistry&);
+
+ namespace {
+ struct DPass : public FunctionPass {
+ static char ID;
+ virtual bool runOnFunction(Function &F) {
+ DominatorTree *DT = &getAnalysis<DominatorTree>();
+ Function::iterator FI = F.begin();
+
+ BasicBlock *BB0 = FI++;
+ BasicBlock::iterator BBI = BB0->begin();
+ Instruction *Y1 = BBI++;
+ Instruction *Y2 = BBI++;
+ Instruction *Y3 = BBI++;
+
+ BasicBlock *BB1 = FI++;
+ BBI = BB1->begin();
+ Instruction *Y4 = BBI++;
+
+ BasicBlock *BB2 = FI++;
+ BBI = BB2->begin();
+ Instruction *Y5 = BBI++;
+
+ BasicBlock *BB3 = FI++;
+ BBI = BB3->begin();
+ Instruction *Y6 = BBI++;
+ Instruction *Y7 = BBI++;
+
+ BasicBlock *BB4 = FI++;
+ BBI = BB4->begin();
+ Instruction *Y8 = BBI++;
+ Instruction *Y9 = BBI++;
+
+ // Reachability
+ EXPECT_TRUE(DT->isReachableFromEntry(BB0));
+ EXPECT_TRUE(DT->isReachableFromEntry(BB1));
+ EXPECT_TRUE(DT->isReachableFromEntry(BB2));
+ EXPECT_FALSE(DT->isReachableFromEntry(BB3));
+ EXPECT_TRUE(DT->isReachableFromEntry(BB4));
+
+ // BB dominance
+ EXPECT_TRUE(DT->dominates(BB0, BB0));
+ EXPECT_TRUE(DT->dominates(BB0, BB1));
+ EXPECT_TRUE(DT->dominates(BB0, BB2));
+ EXPECT_TRUE(DT->dominates(BB0, BB3));
+ EXPECT_TRUE(DT->dominates(BB0, BB4));
+
+ EXPECT_FALSE(DT->dominates(BB1, BB0));
+ EXPECT_TRUE(DT->dominates(BB1, BB1));
+ EXPECT_FALSE(DT->dominates(BB1, BB2));
+ EXPECT_TRUE(DT->dominates(BB1, BB3));
+ EXPECT_FALSE(DT->dominates(BB1, BB4));
+
+ EXPECT_FALSE(DT->dominates(BB2, BB0));
+ EXPECT_FALSE(DT->dominates(BB2, BB1));
+ EXPECT_TRUE(DT->dominates(BB2, BB2));
+ EXPECT_TRUE(DT->dominates(BB2, BB3));
+ EXPECT_FALSE(DT->dominates(BB2, BB4));
+
+ EXPECT_FALSE(DT->dominates(BB3, BB0));
+ EXPECT_FALSE(DT->dominates(BB3, BB1));
+ EXPECT_FALSE(DT->dominates(BB3, BB2));
+ EXPECT_TRUE(DT->dominates(BB3, BB3));
+ EXPECT_FALSE(DT->dominates(BB3, BB4));
+
+ // BB proper dominance
+ EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
+ EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
+ EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
+ EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
+
+ EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
+ EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
+ EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
+ EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
+
+ EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
+ EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
+ EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
+ EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
+
+ EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
+ EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
+ EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
+ EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
+
+ // Instruction dominance in the same reachable BB
+ EXPECT_FALSE(DT->dominates(Y1, Y1));
+ EXPECT_TRUE(DT->dominates(Y1, Y2));
+ EXPECT_FALSE(DT->dominates(Y2, Y1));
+ EXPECT_FALSE(DT->dominates(Y2, Y2));
+
+ // Instruction dominance in the same unreachable BB
+ EXPECT_TRUE(DT->dominates(Y6, Y6));
+ EXPECT_TRUE(DT->dominates(Y6, Y7));
+ EXPECT_TRUE(DT->dominates(Y7, Y6));
+ EXPECT_TRUE(DT->dominates(Y7, Y7));
+
+ // Invoke
+ EXPECT_TRUE(DT->dominates(Y3, Y4));
+ EXPECT_FALSE(DT->dominates(Y3, Y5));
+
+ // Phi
+ EXPECT_TRUE(DT->dominates(Y2, Y9));
+ EXPECT_FALSE(DT->dominates(Y3, Y9));
+ EXPECT_FALSE(DT->dominates(Y8, Y9));
+
+ // Anything dominates unreachable
+ EXPECT_TRUE(DT->dominates(Y1, Y6));
+ EXPECT_TRUE(DT->dominates(Y3, Y6));
+
+ // Unreachable doesn't dominate reachable
+ EXPECT_FALSE(DT->dominates(Y6, Y1));
+
+ // Instruction, BB dominance
+ EXPECT_FALSE(DT->dominates(Y1, BB0));
+ EXPECT_TRUE(DT->dominates(Y1, BB1));
+ EXPECT_TRUE(DT->dominates(Y1, BB2));
+ EXPECT_TRUE(DT->dominates(Y1, BB3));
+ EXPECT_TRUE(DT->dominates(Y1, BB4));
+
+ EXPECT_FALSE(DT->dominates(Y3, BB0));
+ EXPECT_TRUE(DT->dominates(Y3, BB1));
+ EXPECT_FALSE(DT->dominates(Y3, BB2));
+ EXPECT_TRUE(DT->dominates(Y3, BB3));
+ EXPECT_FALSE(DT->dominates(Y3, BB4));
+
+ EXPECT_TRUE(DT->dominates(Y6, BB3));
+
+ return false;
+ }
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<DominatorTree>();
+ }
+ DPass() : FunctionPass(ID) {
+ initializeDPassPass(*PassRegistry::getPassRegistry());
+ }
+ };
+ char DPass::ID = 0;
+
+
+ Module* makeLLVMModule(DPass *P) {
+ const char *ModuleStrig =
+ "declare i32 @g()\n" \
+ "define void @f(i32 %x) {\n" \
+ "bb0:\n" \
+ " %y1 = add i32 %x, 1\n" \
+ " %y2 = add i32 %x, 1\n" \
+ " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n" \
+ "bb1:\n" \
+ " %y4 = add i32 %x, 1\n" \
+ " br label %bb4\n" \
+ "bb2:\n" \
+ " %y5 = landingpad i32 personality i32 ()* @g\n" \
+ " cleanup\n" \
+ " br label %bb4\n" \
+ "bb3:\n" \
+ " %y6 = add i32 %x, 1\n" \
+ " %y7 = add i32 %x, 1\n" \
+ " ret void\n" \
+ "bb4:\n" \
+ " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n"
+ " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n"
+ " ret void\n" \
+ "}\n";
+ LLVMContext &C = getGlobalContext();
+ SMDiagnostic Err;
+ return ParseAssemblyString(ModuleStrig, NULL, Err, C);
+ }
+
+ TEST(DominatorTree, Unreachable) {
+ DPass *P = new DPass();
+ Module *M = makeLLVMModule(P);
+ PassManager Passes;
+ Passes.add(P);
+ Passes.run(*M);
+ }
+ }
+}
+
+INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
+INITIALIZE_PASS_DEPENDENCY(DominatorTree)
+INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)
diff --git a/unittests/VMCore/InstructionsTest.cpp b/unittests/VMCore/InstructionsTest.cpp
index f0197bb671ab..218a9a08c439 100644
--- a/unittests/VMCore/InstructionsTest.cpp
+++ b/unittests/VMCore/InstructionsTest.cpp
@@ -13,6 +13,8 @@
#include "llvm/DerivedTypes.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Target/TargetData.h"
#include "gtest/gtest.h"
namespace llvm {
@@ -129,5 +131,100 @@ TEST(InstructionsTest, CastInst) {
EXPECT_EQ(CastInst::SExt, CastInst::getCastOpcode(c8, true, V8x64Ty, true));
}
+
+
+TEST(InstructionsTest, VectorGep) {
+ LLVMContext &C(getGlobalContext());
+
+ // Type Definitions
+ PointerType *Ptri8Ty = PointerType::get(IntegerType::get(C, 8), 0);
+ PointerType *Ptri32Ty = PointerType::get(IntegerType::get(C, 8), 0);
+
+ VectorType *V2xi8PTy = VectorType::get(Ptri8Ty, 2);
+ VectorType *V2xi32PTy = VectorType::get(Ptri32Ty, 2);
+
+ // Test different aspects of the vector-of-pointers type
+ // and GEPs which use this type.
+ ConstantInt *Ci32a = ConstantInt::get(C, APInt(32, 1492));
+ ConstantInt *Ci32b = ConstantInt::get(C, APInt(32, 1948));
+ std::vector<Constant*> ConstVa(2, Ci32a);
+ std::vector<Constant*> ConstVb(2, Ci32b);
+ Constant *C2xi32a = ConstantVector::get(ConstVa);
+ Constant *C2xi32b = ConstantVector::get(ConstVb);
+
+ CastInst *PtrVecA = new IntToPtrInst(C2xi32a, V2xi32PTy);
+ CastInst *PtrVecB = new IntToPtrInst(C2xi32b, V2xi32PTy);
+
+ ICmpInst *ICmp0 = new ICmpInst(ICmpInst::ICMP_SGT, PtrVecA, PtrVecB);
+ ICmpInst *ICmp1 = new ICmpInst(ICmpInst::ICMP_ULT, PtrVecA, PtrVecB);
+ EXPECT_NE(ICmp0, ICmp1); // suppress warning.
+
+ GetElementPtrInst *Gep0 = GetElementPtrInst::Create(PtrVecA, C2xi32a);
+ GetElementPtrInst *Gep1 = GetElementPtrInst::Create(PtrVecA, C2xi32b);
+ GetElementPtrInst *Gep2 = GetElementPtrInst::Create(PtrVecB, C2xi32a);
+ GetElementPtrInst *Gep3 = GetElementPtrInst::Create(PtrVecB, C2xi32b);
+
+ CastInst *BTC0 = new BitCastInst(Gep0, V2xi8PTy);
+ CastInst *BTC1 = new BitCastInst(Gep1, V2xi8PTy);
+ CastInst *BTC2 = new BitCastInst(Gep2, V2xi8PTy);
+ CastInst *BTC3 = new BitCastInst(Gep3, V2xi8PTy);
+
+ Value *S0 = BTC0->stripPointerCasts();
+ Value *S1 = BTC1->stripPointerCasts();
+ Value *S2 = BTC2->stripPointerCasts();
+ Value *S3 = BTC3->stripPointerCasts();
+
+ EXPECT_NE(S0, Gep0);
+ EXPECT_NE(S1, Gep1);
+ EXPECT_NE(S2, Gep2);
+ EXPECT_NE(S3, Gep3);
+
+ int64_t Offset;
+ TargetData TD("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3"
+ "2:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80"
+ ":128:128-n8:16:32:64-S128");
+ // Make sure we don't crash
+ GetPointerBaseWithConstantOffset(Gep0, Offset, TD);
+ GetPointerBaseWithConstantOffset(Gep1, Offset, TD);
+ GetPointerBaseWithConstantOffset(Gep2, Offset, TD);
+ GetPointerBaseWithConstantOffset(Gep3, Offset, TD);
+
+ // Gep of Geps
+ GetElementPtrInst *GepII0 = GetElementPtrInst::Create(Gep0, C2xi32b);
+ GetElementPtrInst *GepII1 = GetElementPtrInst::Create(Gep1, C2xi32a);
+ GetElementPtrInst *GepII2 = GetElementPtrInst::Create(Gep2, C2xi32b);
+ GetElementPtrInst *GepII3 = GetElementPtrInst::Create(Gep3, C2xi32a);
+
+ EXPECT_EQ(GepII0->getNumIndices(), 1u);
+ EXPECT_EQ(GepII1->getNumIndices(), 1u);
+ EXPECT_EQ(GepII2->getNumIndices(), 1u);
+ EXPECT_EQ(GepII3->getNumIndices(), 1u);
+
+ EXPECT_FALSE(GepII0->hasAllZeroIndices());
+ EXPECT_FALSE(GepII1->hasAllZeroIndices());
+ EXPECT_FALSE(GepII2->hasAllZeroIndices());
+ EXPECT_FALSE(GepII3->hasAllZeroIndices());
+
+ delete GepII0;
+ delete GepII1;
+ delete GepII2;
+ delete GepII3;
+
+ delete BTC0;
+ delete BTC1;
+ delete BTC2;
+ delete BTC3;
+
+ delete Gep0;
+ delete Gep1;
+ delete Gep2;
+ delete Gep3;
+
+ delete ICmp0;
+ delete ICmp1;
+ delete PtrVecA;
+ delete PtrVecB;
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/unittests/VMCore/Makefile b/unittests/VMCore/Makefile
index 1b2b69c6d60b..df55065e1916 100644
--- a/unittests/VMCore/Makefile
+++ b/unittests/VMCore/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = VMCore
-LINK_COMPONENTS := core support target ipa
+LINK_COMPONENTS := core support target ipa asmparser
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp
index 12ac2e704c8e..08927a2ff526 100644
--- a/unittests/VMCore/MetadataTest.cpp
+++ b/unittests/VMCore/MetadataTest.cpp
@@ -90,13 +90,20 @@ TEST_F(MDNodeTest, Simple) {
MDNode *n1 = MDNode::get(Context, V);
Value *const c1 = n1;
MDNode *n2 = MDNode::get(Context, c1);
+ Value *const c2 = n2;
MDNode *n3 = MDNode::get(Context, V);
+ MDNode *n4 = MDNode::getIfExists(Context, V);
+ MDNode *n5 = MDNode::getIfExists(Context, c1);
+ MDNode *n6 = MDNode::getIfExists(Context, c2);
EXPECT_NE(n1, n2);
#ifdef ENABLE_MDNODE_UNIQUING
EXPECT_EQ(n1, n3);
#else
(void) n3;
#endif
+ EXPECT_EQ(n4, n1);
+ EXPECT_EQ(n5, n2);
+ EXPECT_EQ(n6, (Value*)0);
EXPECT_EQ(3u, n1->getNumOperands());
EXPECT_EQ(s1, n1->getOperand(0));
diff --git a/unittests/VMCore/ValueMapTest.cpp b/unittests/VMCore/ValueMapTest.cpp
index b4939208e7d4..9bed37dff33e 100644
--- a/unittests/VMCore/ValueMapTest.cpp
+++ b/unittests/VMCore/ValueMapTest.cpp
@@ -12,7 +12,7 @@
#include "llvm/Instructions.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
#include "gtest/gtest.h"
@@ -195,7 +195,7 @@ struct LockMutex : ValueMapConfig<KeyT> {
}
static sys::Mutex *getMutex(const ExtraData &Data) { return Data.M; }
};
-#if ENABLE_THREADS
+#if LLVM_ENABLE_THREADS
TYPED_TEST(ValueMapTest, LocksMutex) {
sys::Mutex M(false); // Not recursive.
bool CalledRAUW = false, CalledDeleted = false;