diff options
author | ed <ed@FreeBSD.org> | 2009-06-02 17:52:33 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-02 17:52:33 +0000 |
commit | 3277b69d734b9c90b44ebde4ede005717e2c3b2e (patch) | |
tree | 64ba909838c23261cace781ece27d106134ea451 /unittests | |
download | FreeBSD-src-3277b69d734b9c90b44ebde4ede005717e2c3b2e.zip FreeBSD-src-3277b69d734b9c90b44ebde4ede005717e2c3b2e.tar.gz |
Import LLVM, at r72732.
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/ADT/APIntTest.cpp | 188 | ||||
-rw-r--r-- | unittests/ADT/DenseMapTest.cpp | 167 | ||||
-rw-r--r-- | unittests/ADT/DenseSetTest.cpp | 30 | ||||
-rw-r--r-- | unittests/ADT/ImmutableSetTest.cpp | 201 | ||||
-rw-r--r-- | unittests/ADT/Makefile | 15 | ||||
-rw-r--r-- | unittests/ADT/SmallVectorTest.cpp | 383 | ||||
-rw-r--r-- | unittests/ADT/StringMapTest.cpp | 202 | ||||
-rw-r--r-- | unittests/ADT/TripleTest.cpp | 137 | ||||
-rw-r--r-- | unittests/Makefile | 24 | ||||
-rw-r--r-- | unittests/Makefile.unittest | 35 | ||||
-rw-r--r-- | unittests/Support/Makefile | 15 | ||||
-rw-r--r-- | unittests/Support/MathExtrasTest.cpp | 104 | ||||
-rw-r--r-- | unittests/Support/TypeBuilderTest.cpp | 233 | ||||
-rw-r--r-- | unittests/Support/ValueHandleTest.cpp | 317 | ||||
-rw-r--r-- | unittests/Support/raw_ostream_test.cpp | 85 | ||||
-rw-r--r-- | unittests/TestMain.cpp | 15 | ||||
-rw-r--r-- | unittests/VMCore/ConstantsTest.cpp | 112 | ||||
-rw-r--r-- | unittests/VMCore/Makefile | 15 | ||||
-rw-r--r-- | unittests/VMCore/MetadataTest.cpp | 139 |
19 files changed, 2417 insertions, 0 deletions
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp new file mode 100644 index 0000000..8ff7d1d --- /dev/null +++ b/unittests/ADT/APIntTest.cpp @@ -0,0 +1,188 @@ +//===- llvm/unittest/ADT/APInt.cpp - APInt unit tests ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <ostream> +#include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/SmallString.h" + +using namespace llvm; + +namespace { + +// Make the Google Test failure output equivalent to APInt::dump() +std::ostream& operator<<(std::ostream &OS, const llvm::APInt& I) { + llvm::raw_os_ostream raw_os(OS); + + SmallString<40> S, U; + I.toStringUnsigned(U); + I.toStringSigned(S); + raw_os << "APInt(" << I.getBitWidth()<< "b, " + << U.c_str() << "u " << S.c_str() << "s)"; + raw_os.flush(); + return OS; +} + +// Test that APInt shift left works when bitwidth > 64 and shiftamt == 0 +TEST(APIntTest, ShiftLeftByZero) { + APInt One = APInt::getNullValue(65) + 1; + APInt Shl = One.shl(0); + EXPECT_EQ(true, Shl[0]); + EXPECT_EQ(false, Shl[1]); +} + +TEST(APIntTest, i128_NegativeCount) { + APInt Minus3(128, static_cast<uint64_t>(-3), true); + EXPECT_EQ(126u, Minus3.countLeadingOnes()); + EXPECT_EQ(-3, Minus3.getSExtValue()); + + APInt Minus1(128, static_cast<uint64_t>(-1), true); + EXPECT_EQ(0u, Minus1.countLeadingZeros()); + EXPECT_EQ(128u, Minus1.countLeadingOnes()); + EXPECT_EQ(128u, Minus1.getActiveBits()); + EXPECT_EQ(0u, Minus1.countTrailingZeros()); + EXPECT_EQ(128u, Minus1.countTrailingOnes()); + EXPECT_EQ(128u, Minus1.countPopulation()); + EXPECT_EQ(-1, Minus1.getSExtValue()); +} + +TEST(APIntTest, i33_Count) { + APInt i33minus2(33, static_cast<uint64_t>(-2), true); + EXPECT_EQ(0u, i33minus2.countLeadingZeros()); + EXPECT_EQ(32u, i33minus2.countLeadingOnes()); + EXPECT_EQ(33u, i33minus2.getActiveBits()); + EXPECT_EQ(1u, i33minus2.countTrailingZeros()); + EXPECT_EQ(32u, i33minus2.countPopulation()); + EXPECT_EQ(-2, i33minus2.getSExtValue()); + EXPECT_EQ(((uint64_t)-2)&((1ull<<33) -1), i33minus2.getZExtValue()); +} + +TEST(APIntTest, i65_Count) { + APInt i65minus(65, 0, true); + i65minus.set(64); + EXPECT_EQ(0u, i65minus.countLeadingZeros()); + EXPECT_EQ(1u, i65minus.countLeadingOnes()); + EXPECT_EQ(65u, i65minus.getActiveBits()); + EXPECT_EQ(64u, i65minus.countTrailingZeros()); + EXPECT_EQ(1u, i65minus.countPopulation()); +} + +TEST(APIntTest, i128_PositiveCount) { + APInt u128max = APInt::getAllOnesValue(128); + EXPECT_EQ(128u, u128max.countLeadingOnes()); + EXPECT_EQ(0u, u128max.countLeadingZeros()); + EXPECT_EQ(128u, u128max.getActiveBits()); + EXPECT_EQ(0u, u128max.countTrailingZeros()); + EXPECT_EQ(128u, u128max.countTrailingOnes()); + EXPECT_EQ(128u, u128max.countPopulation()); + + APInt u64max(128, static_cast<uint64_t>(-1), false); + EXPECT_EQ(64u, u64max.countLeadingZeros()); + EXPECT_EQ(0u, u64max.countLeadingOnes()); + EXPECT_EQ(64u, u64max.getActiveBits()); + EXPECT_EQ(0u, u64max.countTrailingZeros()); + EXPECT_EQ(64u, u64max.countTrailingOnes()); + EXPECT_EQ(64u, u64max.countPopulation()); + EXPECT_EQ((uint64_t)~0ull, u64max.getZExtValue()); + + APInt zero(128, 0, true); + EXPECT_EQ(128u, zero.countLeadingZeros()); + EXPECT_EQ(0u, zero.countLeadingOnes()); + EXPECT_EQ(0u, zero.getActiveBits()); + EXPECT_EQ(128u, zero.countTrailingZeros()); + EXPECT_EQ(0u, zero.countTrailingOnes()); + EXPECT_EQ(0u, zero.countPopulation()); + EXPECT_EQ(0u, zero.getSExtValue()); + EXPECT_EQ(0u, zero.getZExtValue()); + + APInt one(128, 1, true); + EXPECT_EQ(127u, one.countLeadingZeros()); + EXPECT_EQ(0u, one.countLeadingOnes()); + EXPECT_EQ(1u, one.getActiveBits()); + EXPECT_EQ(0u, one.countTrailingZeros()); + EXPECT_EQ(1u, one.countTrailingOnes()); + EXPECT_EQ(1u, one.countPopulation()); + EXPECT_EQ(1, one.getSExtValue()); + EXPECT_EQ(1u, one.getZExtValue()); +} + +TEST(APIntTest, i1) { + const APInt neg_two(1, static_cast<uint64_t>(-2), true); + const APInt neg_one(1, static_cast<uint64_t>(-1), true); + const APInt zero(1, 0); + const APInt one(1, 1); + const APInt two(1, 2); + + EXPECT_EQ(0, neg_two.getSExtValue()); + EXPECT_EQ(-1, neg_one.getSExtValue()); + EXPECT_EQ(1u, neg_one.getZExtValue()); + EXPECT_EQ(0u, zero.getZExtValue()); + EXPECT_EQ(-1, one.getSExtValue()); + EXPECT_EQ(1u, one.getZExtValue()); + EXPECT_EQ(0u, two.getZExtValue()); + EXPECT_EQ(0, two.getSExtValue()); + + // Basic equalities for 1-bit values. + EXPECT_EQ(zero, two); + EXPECT_EQ(zero, neg_two); + EXPECT_EQ(one, neg_one); + EXPECT_EQ(two, neg_two); + + // Additions. + EXPECT_EQ(two, one + one); + EXPECT_EQ(zero, neg_one + one); + EXPECT_EQ(neg_two, neg_one + neg_one); + + // Subtractions. + EXPECT_EQ(neg_two, neg_one - one); + EXPECT_EQ(two, one - neg_one); + EXPECT_EQ(zero, one - one); + + // Shifts. + EXPECT_EQ(zero, one << one); + EXPECT_EQ(one, one << zero); + EXPECT_EQ(zero, one.shl(1)); + EXPECT_EQ(one, one.shl(0)); + EXPECT_EQ(zero, one.lshr(1)); + EXPECT_EQ(zero, one.ashr(1)); + + // Multiplies. + EXPECT_EQ(neg_one, neg_one * one); + EXPECT_EQ(neg_one, one * neg_one); + EXPECT_EQ(one, neg_one * neg_one); + EXPECT_EQ(one, one * one); + + // Divides. + EXPECT_EQ(neg_one, one.sdiv(neg_one)); + EXPECT_EQ(neg_one, neg_one.sdiv(one)); + EXPECT_EQ(one, neg_one.sdiv(neg_one)); + EXPECT_EQ(one, one.sdiv(one)); + + EXPECT_EQ(neg_one, one.udiv(neg_one)); + EXPECT_EQ(neg_one, neg_one.udiv(one)); + EXPECT_EQ(one, neg_one.udiv(neg_one)); + EXPECT_EQ(one, one.udiv(one)); + + // Remainders. + EXPECT_EQ(zero, neg_one.srem(one)); + EXPECT_EQ(zero, neg_one.urem(one)); + EXPECT_EQ(zero, one.srem(neg_one)); +} + +TEST(APIntTest, fromString) { + EXPECT_EQ(APInt(1, 0), APInt(1, "0", 1, 10)); + EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 10)); + EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 2, 10)); + EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 2)); + EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 8)); + EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 16)); +} + +} diff --git a/unittests/ADT/DenseMapTest.cpp b/unittests/ADT/DenseMapTest.cpp new file mode 100644 index 0000000..15a5379 --- /dev/null +++ b/unittests/ADT/DenseMapTest.cpp @@ -0,0 +1,167 @@ +//===- llvm/unittest/ADT/DenseMapMap.cpp - DenseMap 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 "gtest/gtest.h" +#include "llvm/ADT/DenseMap.h" + +using namespace llvm; + +namespace { + +// Test fixture +class DenseMapTest : public testing::Test { +protected: + DenseMap<uint32_t, uint32_t> uintMap; + DenseMap<uint32_t *, uint32_t *> uintPtrMap; + uint32_t dummyInt; +}; + +// Empty map tests +TEST_F(DenseMapTest, EmptyIntMapTest) { + // Size tests + EXPECT_EQ(0u, uintMap.size()); + EXPECT_TRUE(uintMap.empty()); + + // Iterator tests + EXPECT_TRUE(uintMap.begin() == uintMap.end()); + + // Lookup tests + EXPECT_FALSE(uintMap.count(0u)); + EXPECT_TRUE(uintMap.find(0u) == uintMap.end()); + EXPECT_EQ(0u, uintMap.lookup(0u)); +} + +// Empty map tests for pointer map +TEST_F(DenseMapTest, EmptyPtrMapTest) { + // Size tests + EXPECT_EQ(0u, uintPtrMap.size()); + EXPECT_TRUE(uintPtrMap.empty()); + + // Iterator tests + EXPECT_TRUE(uintPtrMap.begin() == uintPtrMap.end()); + + // Lookup tests + EXPECT_FALSE(uintPtrMap.count(&dummyInt)); + EXPECT_TRUE(uintPtrMap.find(&dummyInt) == uintPtrMap.begin()); + EXPECT_EQ(0, uintPtrMap.lookup(&dummyInt)); +} + +// Constant map tests +TEST_F(DenseMapTest, ConstEmptyMapTest) { + const DenseMap<uint32_t, uint32_t> & constUintMap = uintMap; + const DenseMap<uint32_t *, uint32_t *> & constUintPtrMap = uintPtrMap; + EXPECT_EQ(0u, constUintMap.size()); + EXPECT_EQ(0u, constUintPtrMap.size()); + EXPECT_TRUE(constUintMap.empty()); + EXPECT_TRUE(constUintPtrMap.empty()); + EXPECT_TRUE(constUintMap.begin() == constUintMap.end()); + EXPECT_TRUE(constUintPtrMap.begin() == constUintPtrMap.end()); +} + +// A map with a single entry +TEST_F(DenseMapTest, SingleEntryMapTest) { + uintMap[0] = 1; + + // Size tests + EXPECT_EQ(1u, uintMap.size()); + EXPECT_FALSE(uintMap.begin() == uintMap.end()); + EXPECT_FALSE(uintMap.empty()); + + // Iterator tests + DenseMap<uint32_t, uint32_t>::iterator it = uintMap.begin(); + EXPECT_EQ(0u, it->first); + EXPECT_EQ(1u, it->second); + ++it; + EXPECT_TRUE(it == uintMap.end()); + + // Lookup tests + EXPECT_TRUE(uintMap.count(0u)); + EXPECT_TRUE(uintMap.find(0u) == uintMap.begin()); + EXPECT_EQ(1u, uintMap.lookup(0u)); + EXPECT_EQ(1u, uintMap[0]); +} + +// Test clear() method +TEST_F(DenseMapTest, ClearTest) { + uintMap[0] = 1; + uintMap.clear(); + + EXPECT_EQ(0u, uintMap.size()); + EXPECT_TRUE(uintMap.empty()); + EXPECT_TRUE(uintMap.begin() == uintMap.end()); +} + +// Test erase(iterator) method +TEST_F(DenseMapTest, EraseTest) { + uintMap[0] = 1; + uintMap.erase(uintMap.begin()); + + EXPECT_EQ(0u, uintMap.size()); + EXPECT_TRUE(uintMap.empty()); + EXPECT_TRUE(uintMap.begin() == uintMap.end()); +} + +// Test erase(value) method +TEST_F(DenseMapTest, EraseTest2) { + uintMap[0] = 1; + uintMap.erase(0); + + EXPECT_EQ(0u, uintMap.size()); + EXPECT_TRUE(uintMap.empty()); + EXPECT_TRUE(uintMap.begin() == uintMap.end()); +} + +// Test insert() method +TEST_F(DenseMapTest, InsertTest) { + uintMap.insert(std::make_pair(0u, 1u)); + EXPECT_EQ(1u, uintMap.size()); + EXPECT_EQ(1u, uintMap[0]); +} + +// Test copy constructor method +TEST_F(DenseMapTest, CopyConstructorTest) { + uintMap[0] = 1; + DenseMap<uint32_t, uint32_t> copyMap(uintMap); + + EXPECT_EQ(1u, copyMap.size()); + EXPECT_EQ(1u, copyMap[0]); +} + +// Test assignment operator method +TEST_F(DenseMapTest, AssignmentTest) { + uintMap[0] = 1; + DenseMap<uint32_t, uint32_t> copyMap = uintMap; + + EXPECT_EQ(1u, copyMap.size()); + EXPECT_EQ(1u, copyMap[0]); +} + +// A more complex iteration test +TEST_F(DenseMapTest, IterationTest) { + bool visited[100]; + + // Insert 100 numbers into the map + for (int i = 0; i < 100; ++i) { + visited[i] = false; + uintMap[i] = 3; + } + + // Iterate over all numbers and mark each one found. + for (DenseMap<uint32_t, uint32_t>::iterator it = uintMap.begin(); + it != uintMap.end(); ++it) { + visited[it->first] = true; + } + + // Ensure every number was visited. + for (int i = 0; i < 100; ++i) { + ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited"; + } +} + +} diff --git a/unittests/ADT/DenseSetTest.cpp b/unittests/ADT/DenseSetTest.cpp new file mode 100644 index 0000000..7a35f52 --- /dev/null +++ b/unittests/ADT/DenseSetTest.cpp @@ -0,0 +1,30 @@ +//===- llvm/unittest/ADT/DenseSetTest.cpp - DenseSet 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 "gtest/gtest.h" +#include <llvm/ADT/DenseSet.h> + +using namespace llvm; + +namespace { + +// Test fixture +class DenseSetTest : public testing::Test { +}; + +// Test hashing with a set of only two entries. +TEST_F(DenseSetTest, DoubleEntrySetTest) { + llvm::DenseSet<unsigned> set(2); + set.insert(0); + set.insert(1); + // Original failure was an infinite loop in this call: + EXPECT_EQ(0, set.count(2)); +} + +} diff --git a/unittests/ADT/ImmutableSetTest.cpp b/unittests/ADT/ImmutableSetTest.cpp new file mode 100644 index 0000000..1be510d --- /dev/null +++ b/unittests/ADT/ImmutableSetTest.cpp @@ -0,0 +1,201 @@ +//===----------- ImmutableSetTest.cpp - ImmutableSet 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/ImmutableSet.h" + +using namespace llvm; + +namespace { +class ImmutableSetTest : public testing::Test { +protected: + // for callback tests + static char buffer[10]; + + struct MyIter { + int counter; + char *ptr; + + MyIter() : counter(0), ptr(buffer) { + for (unsigned i=0; i<sizeof(buffer);++i) buffer[i]='\0'; + } + void operator()(char c) { + *ptr++ = c; + ++counter; + } + }; +}; +char ImmutableSetTest::buffer[10]; + + +TEST_F(ImmutableSetTest, EmptyIntSetTest) { + ImmutableSet<int>::Factory f; + + EXPECT_TRUE(f.GetEmptySet() == f.GetEmptySet()); + EXPECT_FALSE(f.GetEmptySet() != f.GetEmptySet()); + EXPECT_TRUE(f.GetEmptySet().isEmpty()); + + ImmutableSet<int> S = f.GetEmptySet(); + EXPECT_EQ(0u, S.getHeight()); + EXPECT_TRUE(S.begin() == S.end()); + EXPECT_FALSE(S.begin() != S.end()); +} + + +TEST_F(ImmutableSetTest, OneElemIntSetTest) { + ImmutableSet<int>::Factory f; + ImmutableSet<int> S = f.GetEmptySet(); + + ImmutableSet<int> S2 = f.Add(S, 3); + EXPECT_TRUE(S.isEmpty()); + EXPECT_FALSE(S2.isEmpty()); + EXPECT_FALSE(S == S2); + EXPECT_TRUE(S != S2); + EXPECT_FALSE(S.contains(3)); + EXPECT_TRUE(S2.contains(3)); + EXPECT_FALSE(S2.begin() == S2.end()); + EXPECT_TRUE(S2.begin() != S2.end()); + + ImmutableSet<int> S3 = f.Add(S, 2); + EXPECT_TRUE(S.isEmpty()); + EXPECT_FALSE(S3.isEmpty()); + EXPECT_FALSE(S == S3); + EXPECT_TRUE(S != S3); + EXPECT_FALSE(S.contains(2)); + EXPECT_TRUE(S3.contains(2)); + + EXPECT_FALSE(S2 == S3); + EXPECT_TRUE(S2 != S3); + EXPECT_FALSE(S2.contains(2)); + EXPECT_FALSE(S3.contains(3)); +} + +TEST_F(ImmutableSetTest, MultiElemIntSetTest) { + ImmutableSet<int>::Factory f; + ImmutableSet<int> S = f.GetEmptySet(); + + ImmutableSet<int> S2 = f.Add(f.Add(f.Add(S, 3), 4), 5); + ImmutableSet<int> S3 = f.Add(f.Add(f.Add(S2, 9), 20), 43); + ImmutableSet<int> S4 = f.Add(S2, 9); + + EXPECT_TRUE(S.isEmpty()); + EXPECT_FALSE(S2.isEmpty()); + EXPECT_FALSE(S3.isEmpty()); + EXPECT_FALSE(S4.isEmpty()); + + EXPECT_FALSE(S.contains(3)); + EXPECT_FALSE(S.contains(9)); + + EXPECT_TRUE(S2.contains(3)); + EXPECT_TRUE(S2.contains(4)); + EXPECT_TRUE(S2.contains(5)); + EXPECT_FALSE(S2.contains(9)); + EXPECT_FALSE(S2.contains(0)); + + EXPECT_TRUE(S3.contains(43)); + EXPECT_TRUE(S3.contains(20)); + EXPECT_TRUE(S3.contains(9)); + EXPECT_TRUE(S3.contains(3)); + EXPECT_TRUE(S3.contains(4)); + EXPECT_TRUE(S3.contains(5)); + EXPECT_FALSE(S3.contains(0)); + + EXPECT_TRUE(S4.contains(9)); + EXPECT_TRUE(S4.contains(3)); + EXPECT_TRUE(S4.contains(4)); + EXPECT_TRUE(S4.contains(5)); + EXPECT_FALSE(S4.contains(20)); + EXPECT_FALSE(S4.contains(43)); +} + +TEST_F(ImmutableSetTest, RemoveIntSetTest) { + ImmutableSet<int>::Factory f; + ImmutableSet<int> S = f.GetEmptySet(); + + ImmutableSet<int> S2 = f.Add(f.Add(S, 4), 5); + ImmutableSet<int> S3 = f.Add(S2, 3); + ImmutableSet<int> S4 = f.Remove(S3, 3); + + EXPECT_TRUE(S3.contains(3)); + EXPECT_FALSE(S2.contains(3)); + EXPECT_FALSE(S4.contains(3)); + + EXPECT_TRUE(S2 == S4); + EXPECT_TRUE(S3 != S2); + EXPECT_TRUE(S3 != S4); + + EXPECT_TRUE(S3.contains(4)); + EXPECT_TRUE(S3.contains(5)); + + EXPECT_TRUE(S4.contains(4)); + EXPECT_TRUE(S4.contains(5)); +} + +TEST_F(ImmutableSetTest, CallbackCharSetTest) { + ImmutableSet<char>::Factory f; + ImmutableSet<char> S = f.GetEmptySet(); + + ImmutableSet<char> S2 = f.Add(f.Add(f.Add(S, 'a'), 'e'), 'i'); + ImmutableSet<char> S3 = f.Add(f.Add(S2, 'o'), 'u'); + + S3.foreach<MyIter>(); + + ASSERT_STREQ("aeiou", buffer); +} + +TEST_F(ImmutableSetTest, Callback2CharSetTest) { + ImmutableSet<char>::Factory f; + ImmutableSet<char> S = f.GetEmptySet(); + + ImmutableSet<char> S2 = f.Add(f.Add(f.Add(S, 'b'), 'c'), 'd'); + ImmutableSet<char> S3 = f.Add(f.Add(f.Add(S2, 'f'), 'g'), 'h'); + + MyIter obj; + S3.foreach<MyIter>(obj); + ASSERT_STREQ("bcdfgh", buffer); + ASSERT_EQ(6, obj.counter); + + MyIter obj2; + S2.foreach<MyIter>(obj2); + ASSERT_STREQ("bcd", buffer); + ASSERT_EQ(3, obj2.counter); + + MyIter obj3; + S.foreach<MyIter>(obj); + ASSERT_STREQ("", buffer); + ASSERT_EQ(0, obj3.counter); +} + +TEST_F(ImmutableSetTest, IterLongSetTest) { + ImmutableSet<long>::Factory f; + ImmutableSet<long> S = f.GetEmptySet(); + + ImmutableSet<long> S2 = f.Add(f.Add(f.Add(S, 0), 1), 2); + ImmutableSet<long> S3 = f.Add(f.Add(f.Add(S2, 3), 4), 5); + + int i = 0; + for (ImmutableSet<long>::iterator I = S.begin(), E = S.end(); I != E; ++I) { + ASSERT_EQ(i++, *I); + } + ASSERT_EQ(0, i); + + i = 0; + for (ImmutableSet<long>::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { + ASSERT_EQ(i++, *I); + } + ASSERT_EQ(3, i); + + i = 0; + for (ImmutableSet<long>::iterator I = S3.begin(), E = S3.end(); I != E; I++) { + ASSERT_EQ(i++, *I); + } + ASSERT_EQ(6, i); +} + +} diff --git a/unittests/ADT/Makefile b/unittests/ADT/Makefile new file mode 100644 index 0000000..c56b951 --- /dev/null +++ b/unittests/ADT/Makefile @@ -0,0 +1,15 @@ +##===- unittests/ADT/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 = ADT +LINK_COMPONENTS := core support + +include $(LEVEL)/Makefile.config +include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp new file mode 100644 index 0000000..19ef099 --- /dev/null +++ b/unittests/ADT/SmallVectorTest.cpp @@ -0,0 +1,383 @@ +//===- llvm/unittest/ADT/SmallVectorTest.cpp ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// SmallVector unit tests. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "llvm/ADT/SmallVector.h" +#include <stdarg.h> + +using namespace llvm; + +namespace { + +/// A helper class that counts the total number of constructor and +/// destructor calls. +class Constructable { +private: + static int numConstructorCalls; + static int numDestructorCalls; + static int numAssignmentCalls; + + int value; + +public: + Constructable() : value(0) { + ++numConstructorCalls; + } + + Constructable(int val) : value(val) { + ++numConstructorCalls; + } + + Constructable(const Constructable & src) { + value = src.value; + ++numConstructorCalls; + } + + ~Constructable() { + ++numDestructorCalls; + } + + Constructable & operator=(const Constructable & src) { + value = src.value; + ++numAssignmentCalls; + return *this; + } + + int getValue() const { + return abs(value); + } + + static void reset() { + numConstructorCalls = 0; + numDestructorCalls = 0; + numAssignmentCalls = 0; + } + + static int getNumConstructorCalls() { + return numConstructorCalls; + } + + static int getNumDestructorCalls() { + return numDestructorCalls; + } + + friend bool operator==(const Constructable & c0, const Constructable & c1) { + return c0.getValue() == c1.getValue(); + } + + friend bool operator!=(const Constructable & c0, const Constructable & c1) { + return c0.getValue() != c1.getValue(); + } +}; + +int Constructable::numConstructorCalls; +int Constructable::numDestructorCalls; +int Constructable::numAssignmentCalls; + +// Test fixture class +class SmallVectorTest : public testing::Test { +protected: + typedef SmallVector<Constructable, 4> VectorType; + + VectorType theVector; + VectorType otherVector; + + void SetUp() { + Constructable::reset(); + } + + void assertEmpty(VectorType & v) { + // Size tests + EXPECT_EQ(0u, v.size()); + EXPECT_TRUE(v.empty()); + + // Iterator tests + EXPECT_TRUE(v.begin() == v.end()); + } + + // Assert that theVector contains the specified values, in order. + void assertValuesInOrder(VectorType & v, size_t size, ...) { + EXPECT_EQ(size, v.size()); + + va_list ap; + va_start(ap, size); + for (size_t i = 0; i < size; ++i) { + int value = va_arg(ap, int); + EXPECT_EQ(value, v[i].getValue()); + } + + va_end(ap); + } + + // Generate a sequence of values to initialize the vector. + void makeSequence(VectorType & v, int start, int end) { + for (int i = start; i <= end; ++i) { + v.push_back(Constructable(i)); + } + } +}; + +// New vector test. +TEST_F(SmallVectorTest, EmptyVectorTest) { + SCOPED_TRACE("EmptyVectorTest"); + assertEmpty(theVector); + EXPECT_TRUE(theVector.rbegin() == theVector.rend()); + EXPECT_EQ(0, Constructable::getNumConstructorCalls()); + EXPECT_EQ(0, Constructable::getNumDestructorCalls()); +} + +// Simple insertions and deletions. +TEST_F(SmallVectorTest, PushPopTest) { + SCOPED_TRACE("PushPopTest"); + + // Push an element + theVector.push_back(Constructable(1)); + + // Size tests + assertValuesInOrder(theVector, 1u, 1); + EXPECT_FALSE(theVector.begin() == theVector.end()); + EXPECT_FALSE(theVector.empty()); + + // Push another element + theVector.push_back(Constructable(2)); + assertValuesInOrder(theVector, 2u, 1, 2); + + // Pop one element + theVector.pop_back(); + assertValuesInOrder(theVector, 1u, 1); + + // Pop another element + theVector.pop_back(); + assertEmpty(theVector); + + // Check number of constructor calls. Should be 2 for each list element, + // one for the argument to push_back, and one for the list element itself. + EXPECT_EQ(4, Constructable::getNumConstructorCalls()); + EXPECT_EQ(4, Constructable::getNumDestructorCalls()); +} + +// Clear test. +TEST_F(SmallVectorTest, ClearTest) { + SCOPED_TRACE("ClearTest"); + + makeSequence(theVector, 1, 2); + theVector.clear(); + + assertEmpty(theVector); + EXPECT_EQ(4, Constructable::getNumConstructorCalls()); + EXPECT_EQ(4, Constructable::getNumDestructorCalls()); +} + +// Resize smaller test. +TEST_F(SmallVectorTest, ResizeShrinkTest) { + SCOPED_TRACE("ResizeShrinkTest"); + + makeSequence(theVector, 1, 3); + theVector.resize(1); + + assertValuesInOrder(theVector, 1u, 1); + EXPECT_EQ(6, Constructable::getNumConstructorCalls()); + EXPECT_EQ(5, Constructable::getNumDestructorCalls()); +} + +// Resize bigger test. +TEST_F(SmallVectorTest, ResizeGrowTest) { + SCOPED_TRACE("ResizeGrowTest"); + + theVector.resize(2); + + // XXX: I don't know where the extra construct/destruct is coming from. + EXPECT_EQ(3, Constructable::getNumConstructorCalls()); + EXPECT_EQ(1, Constructable::getNumDestructorCalls()); + EXPECT_EQ(2u, theVector.size()); +} + +// Resize with fill value. +TEST_F(SmallVectorTest, ResizeFillTest) { + SCOPED_TRACE("ResizeFillTest"); + + theVector.resize(3, Constructable(77)); + assertValuesInOrder(theVector, 3u, 77, 77, 77); +} + +// Overflow past fixed size. +TEST_F(SmallVectorTest, OverflowTest) { + SCOPED_TRACE("OverflowTest"); + + // Push more elements than the fixed size + makeSequence(theVector, 1, 10); + + // test size and values + EXPECT_EQ(10u, theVector.size()); + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(i+1, theVector[i].getValue()); + } + + // Now resize back to fixed size + theVector.resize(1); + + assertValuesInOrder(theVector, 1u, 1); +} + +// Iteration tests. +TEST_F(SmallVectorTest, IterationTest) { + makeSequence(theVector, 1, 2); + + // Forward Iteration + VectorType::iterator it = theVector.begin(); + EXPECT_TRUE(*it == theVector.front()); + EXPECT_TRUE(*it == theVector[0]); + EXPECT_EQ(1, it->getValue()); + ++it; + EXPECT_TRUE(*it == theVector[1]); + EXPECT_TRUE(*it == theVector.back()); + EXPECT_EQ(2, it->getValue()); + ++it; + EXPECT_TRUE(it == theVector.end()); + --it; + EXPECT_TRUE(*it == theVector[1]); + EXPECT_EQ(2, it->getValue()); + --it; + EXPECT_TRUE(*it == theVector[0]); + EXPECT_EQ(1, it->getValue()); + + // Reverse Iteration + VectorType::reverse_iterator rit = theVector.rbegin(); + EXPECT_TRUE(*rit == theVector[1]); + EXPECT_EQ(2, rit->getValue()); + ++rit; + EXPECT_TRUE(*rit == theVector[0]); + EXPECT_EQ(1, rit->getValue()); + ++rit; + EXPECT_TRUE(rit == theVector.rend()); + --rit; + EXPECT_TRUE(*rit == theVector[0]); + EXPECT_EQ(1, rit->getValue()); + --rit; + EXPECT_TRUE(*rit == theVector[1]); + EXPECT_EQ(2, rit->getValue()); +} + +// Swap test. +TEST_F(SmallVectorTest, SwapTest) { + SCOPED_TRACE("SwapTest"); + + makeSequence(theVector, 1, 2); + std::swap(theVector, otherVector); + + assertEmpty(theVector); + assertValuesInOrder(otherVector, 2u, 1, 2); +} + +// Append test +TEST_F(SmallVectorTest, AppendTest) { + SCOPED_TRACE("AppendTest"); + + makeSequence(otherVector, 2, 3); + + theVector.push_back(Constructable(1)); + theVector.append(otherVector.begin(), otherVector.end()); + + assertValuesInOrder(theVector, 3u, 1, 2, 3); +} + +// Append repeated test +TEST_F(SmallVectorTest, AppendRepeatedTest) { + SCOPED_TRACE("AppendRepeatedTest"); + + theVector.push_back(Constructable(1)); + theVector.append(2, Constructable(77)); + assertValuesInOrder(theVector, 3u, 1, 77, 77); +} + +// Assign test +TEST_F(SmallVectorTest, AssignTest) { + SCOPED_TRACE("AssignTest"); + + theVector.push_back(Constructable(1)); + theVector.assign(2, Constructable(77)); + assertValuesInOrder(theVector, 2u, 77, 77); +} + +// Erase a single element +TEST_F(SmallVectorTest, EraseTest) { + SCOPED_TRACE("EraseTest"); + + makeSequence(theVector, 1, 3); + theVector.erase(theVector.begin()); + assertValuesInOrder(theVector, 2u, 2, 3); +} + +// Erase a range of elements +TEST_F(SmallVectorTest, EraseRangeTest) { + SCOPED_TRACE("EraseRangeTest"); + + makeSequence(theVector, 1, 3); + theVector.erase(theVector.begin(), theVector.begin() + 2); + assertValuesInOrder(theVector, 1u, 3); +} + +// Insert a single element. +TEST_F(SmallVectorTest, InsertTest) { + SCOPED_TRACE("InsertTest"); + + makeSequence(theVector, 1, 3); + theVector.insert(theVector.begin() + 1, Constructable(77)); + assertValuesInOrder(theVector, 4u, 1, 77, 2, 3); +} + +// Insert repeated elements. +TEST_F(SmallVectorTest, InsertRepeatedTest) { + SCOPED_TRACE("InsertRepeatedTest"); + + makeSequence(theVector, 10, 15); + theVector.insert(theVector.begin() + 1, 2, Constructable(16)); + assertValuesInOrder(theVector, 8u, 10, 16, 16, 11, 12, 13, 14, 15); +} + +// Insert range. +TEST_F(SmallVectorTest, InsertRangeTest) { + SCOPED_TRACE("InsertRepeatedTest"); + + makeSequence(theVector, 1, 3); + theVector.insert(theVector.begin() + 1, 3, Constructable(77)); + assertValuesInOrder(theVector, 6u, 1, 77, 77, 77, 2, 3); +} + +// Comparison tests. +TEST_F(SmallVectorTest, ComparisonTest) { + SCOPED_TRACE("ComparisonTest"); + + makeSequence(theVector, 1, 3); + makeSequence(otherVector, 1, 3); + + EXPECT_TRUE(theVector == otherVector); + EXPECT_FALSE(theVector != otherVector); + + otherVector.clear(); + makeSequence(otherVector, 2, 4); + + EXPECT_FALSE(theVector == otherVector); + EXPECT_TRUE(theVector != otherVector); +} + +// Constant vector tests. +TEST_F(SmallVectorTest, ConstVectorTest) { + const VectorType constVector; + + EXPECT_EQ(0u, constVector.size()); + EXPECT_TRUE(constVector.empty()); + EXPECT_TRUE(constVector.begin() == constVector.end()); +} + +} diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp new file mode 100644 index 0000000..9f9f2e4 --- /dev/null +++ b/unittests/ADT/StringMapTest.cpp @@ -0,0 +1,202 @@ +//===- llvm/unittest/ADT/StringMapMap.cpp - StringMap 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/StringMap.h" +using namespace llvm; + +namespace { + +// Test fixture +class StringMapTest : public testing::Test { +protected: + StringMap<uint32_t> testMap; + + static const char testKey[]; + static const uint32_t testValue; + static const char* testKeyFirst; + static const char* testKeyLast; + static const std::string testKeyStr; + + void assertEmptyMap() { + // Size tests + EXPECT_EQ(0u, testMap.size()); + EXPECT_TRUE(testMap.empty()); + + // Iterator tests + EXPECT_TRUE(testMap.begin() == testMap.end()); + + // Lookup tests + EXPECT_EQ(0u, testMap.count(testKey)); + EXPECT_EQ(0u, testMap.count(testKeyFirst, testKeyLast)); + EXPECT_EQ(0u, testMap.count(testKeyStr)); + EXPECT_TRUE(testMap.find(testKey) == testMap.end()); + EXPECT_TRUE(testMap.find(testKeyFirst, testKeyLast) == testMap.end()); + EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end()); + } + + void assertSingleItemMap() { + // Size tests + EXPECT_EQ(1u, testMap.size()); + EXPECT_FALSE(testMap.begin() == testMap.end()); + EXPECT_FALSE(testMap.empty()); + + // Iterator tests + StringMap<uint32_t>::iterator it = testMap.begin(); + EXPECT_STREQ(testKey, it->first()); + EXPECT_EQ(testValue, it->second); + ++it; + EXPECT_TRUE(it == testMap.end()); + + // Lookup tests + EXPECT_EQ(1u, testMap.count(testKey)); + EXPECT_EQ(1u, testMap.count(testKeyFirst, testKeyLast)); + EXPECT_EQ(1u, testMap.count(testKeyStr)); + EXPECT_TRUE(testMap.find(testKey) == testMap.begin()); + EXPECT_TRUE(testMap.find(testKeyFirst, testKeyLast) == testMap.begin()); + EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin()); + } +}; + +const char StringMapTest::testKey[] = "key"; +const uint32_t StringMapTest::testValue = 1u; +const char* StringMapTest::testKeyFirst = testKey; +const char* StringMapTest::testKeyLast = testKey + sizeof(testKey) - 1; +const std::string StringMapTest::testKeyStr(testKey); + +// Empty map tests. +TEST_F(StringMapTest, EmptyMapTest) { + SCOPED_TRACE("EmptyMapTest"); + assertEmptyMap(); +} + +// Constant map tests. +TEST_F(StringMapTest, ConstEmptyMapTest) { + const StringMap<uint32_t>& constTestMap = testMap; + + // Size tests + EXPECT_EQ(0u, constTestMap.size()); + EXPECT_TRUE(constTestMap.empty()); + + // Iterator tests + EXPECT_TRUE(constTestMap.begin() == constTestMap.end()); + + // Lookup tests + EXPECT_EQ(0u, constTestMap.count(testKey)); + EXPECT_EQ(0u, constTestMap.count(testKeyFirst, testKeyLast)); + EXPECT_EQ(0u, constTestMap.count(testKeyStr)); + EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end()); + EXPECT_TRUE(constTestMap.find(testKeyFirst, testKeyLast) == + constTestMap.end()); + EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end()); +} + +// A map with a single entry. +TEST_F(StringMapTest, SingleEntryMapTest) { + SCOPED_TRACE("SingleEntryMapTest"); + testMap[testKey] = testValue; + assertSingleItemMap(); +} + +// Test clear() method. +TEST_F(StringMapTest, ClearTest) { + SCOPED_TRACE("ClearTest"); + testMap[testKey] = testValue; + testMap.clear(); + assertEmptyMap(); +} + +// Test erase(iterator) method. +TEST_F(StringMapTest, EraseIteratorTest) { + SCOPED_TRACE("EraseIteratorTest"); + testMap[testKey] = testValue; + testMap.erase(testMap.begin()); + assertEmptyMap(); +} + +// Test erase(value) method. +TEST_F(StringMapTest, EraseValueTest) { + SCOPED_TRACE("EraseValueTest"); + testMap[testKey] = testValue; + testMap.erase(testKey); + assertEmptyMap(); +} + +// Test inserting two values and erasing one. +TEST_F(StringMapTest, InsertAndEraseTest) { + SCOPED_TRACE("InsertAndEraseTest"); + testMap[testKey] = testValue; + testMap["otherKey"] = 2; + testMap.erase("otherKey"); + assertSingleItemMap(); +} + +// A more complex iteration test. +TEST_F(StringMapTest, IterationTest) { + bool visited[100]; + + // Insert 100 numbers into the map + for (int i = 0; i < 100; ++i) { + std::stringstream ss; + ss << "key_" << i; + testMap[ss.str()] = i; + visited[i] = false; + } + + // Iterate over all numbers and mark each one found. + for (StringMap<uint32_t>::iterator it = testMap.begin(); + it != testMap.end(); ++it) { + std::stringstream ss; + ss << "key_" << it->second; + ASSERT_STREQ(ss.str().c_str(), it->first()); + visited[it->second] = true; + } + + // Ensure every number was visited. + for (int i = 0; i < 100; ++i) { + ASSERT_TRUE(visited[i]) << "Entry #" << i << " was never visited"; + } +} + +} // end anonymous namespace + +namespace llvm { + +template <> +class StringMapEntryInitializer<uint32_t> { +public: + template <typename InitTy> + static void Initialize(StringMapEntry<uint32_t> &T, InitTy InitVal) { + T.second = InitVal; + } +}; + +} // end llvm namespace + +namespace { + +// Test StringMapEntry::Create() method. +TEST_F(StringMapTest, StringMapEntryTest) { + StringMap<uint32_t>::value_type* entry = + StringMap<uint32_t>::value_type::Create( + testKeyFirst, testKeyLast, 1u); + EXPECT_STREQ(testKey, entry->first()); + EXPECT_EQ(1u, entry->second); +} + +// Test insert() method. +TEST_F(StringMapTest, InsertTest) { + SCOPED_TRACE("InsertTest"); + testMap.insert( + StringMap<uint32_t>::value_type::Create( + testKeyFirst, testKeyLast, testMap.getAllocator(), 1u)); + assertSingleItemMap(); +} + +} // end anonymous namespace diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp new file mode 100644 index 0000000..771d1c7 --- /dev/null +++ b/unittests/ADT/TripleTest.cpp @@ -0,0 +1,137 @@ +//===----------- Triple.cpp - Triple 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/Triple.h" + +using namespace llvm; + +namespace { + +TEST(TripleTest, BasicParsing) { + Triple T; + + T = Triple(""); + EXPECT_EQ(T.getArchName(), ""); + EXPECT_EQ(T.getVendorName(), ""); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("-"); + EXPECT_EQ(T.getArchName(), ""); + EXPECT_EQ(T.getVendorName(), ""); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("--"); + EXPECT_EQ(T.getArchName(), ""); + EXPECT_EQ(T.getVendorName(), ""); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("---"); + EXPECT_EQ(T.getArchName(), ""); + EXPECT_EQ(T.getVendorName(), ""); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("----"); + EXPECT_EQ(T.getArchName(), ""); + EXPECT_EQ(T.getVendorName(), ""); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), "-"); + + T = Triple("a"); + EXPECT_EQ(T.getArchName(), "a"); + EXPECT_EQ(T.getVendorName(), ""); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("a-b"); + EXPECT_EQ(T.getArchName(), "a"); + EXPECT_EQ(T.getVendorName(), "b"); + EXPECT_EQ(T.getOSName(), ""); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("a-b-c"); + EXPECT_EQ(T.getArchName(), "a"); + EXPECT_EQ(T.getVendorName(), "b"); + EXPECT_EQ(T.getOSName(), "c"); + EXPECT_EQ(T.getEnvironmentName(), ""); + + T = Triple("a-b-c-d"); + EXPECT_EQ(T.getArchName(), "a"); + EXPECT_EQ(T.getVendorName(), "b"); + EXPECT_EQ(T.getOSName(), "c"); + EXPECT_EQ(T.getEnvironmentName(), "d"); +} + +TEST(TripleTest, ParsedIDs) { + Triple T; + + T = Triple("i386-apple-darwin"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getVendor(), Triple::Apple); + EXPECT_EQ(T.getOS(), Triple::Darwin); + + T = Triple("x86_64-pc-linux-gnu"); + EXPECT_EQ(T.getArch(), Triple::x86_64); + EXPECT_EQ(T.getVendor(), Triple::PC); + EXPECT_EQ(T.getOS(), Triple::Linux); + + T = Triple("powerpc-dunno-notsure"); + EXPECT_EQ(T.getArch(), Triple::ppc); + EXPECT_EQ(T.getVendor(), Triple::UnknownVendor); + EXPECT_EQ(T.getOS(), Triple::UnknownOS); + + T = Triple("huh"); + EXPECT_EQ(T.getArch(), Triple::UnknownArch); +} + +TEST(TripleTest, MutateName) { + Triple T; + EXPECT_EQ(T.getArch(), Triple::UnknownArch); + EXPECT_EQ(T.getVendor(), Triple::UnknownVendor); + EXPECT_EQ(T.getOS(), Triple::UnknownOS); + + T.setArchName("i386"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getTriple(), "i386--"); + + T.setVendorName("pc"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getVendor(), Triple::PC); + EXPECT_EQ(T.getTriple(), "i386-pc-"); + + T.setOSName("linux"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getVendor(), Triple::PC); + EXPECT_EQ(T.getOS(), Triple::Linux); + EXPECT_EQ(T.getTriple(), "i386-pc-linux"); + + T.setEnvironmentName("gnu"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getVendor(), Triple::PC); + EXPECT_EQ(T.getOS(), Triple::Linux); + EXPECT_EQ(T.getTriple(), "i386-pc-linux-gnu"); + + T.setOSName("freebsd"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getVendor(), Triple::PC); + EXPECT_EQ(T.getOS(), Triple::FreeBSD); + EXPECT_EQ(T.getTriple(), "i386-pc-freebsd-gnu"); + + T.setOSAndEnvironmentName("darwin"); + EXPECT_EQ(T.getArch(), Triple::x86); + EXPECT_EQ(T.getVendor(), Triple::PC); + EXPECT_EQ(T.getOS(), Triple::Darwin); + EXPECT_EQ(T.getTriple(), "i386-pc-darwin"); +} + +} diff --git a/unittests/Makefile b/unittests/Makefile new file mode 100644 index 0000000..1ff54111 --- /dev/null +++ b/unittests/Makefile @@ -0,0 +1,24 @@ +##===- unittests/Makefile ----------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = .. + +include $(LEVEL)/Makefile.config + +LIBRARYNAME = UnitTestMain +BUILD_ARCHIVE = 1 +CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/ +CPP.Flags += -Wno-variadic-macros + +PARALLEL_DIRS = ADT Support VMCore + +include $(LEVEL)/Makefile.common + +clean:: + $(Verb) $(RM) -f *Tests diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest new file mode 100644 index 0000000..1c75e44 --- /dev/null +++ b/unittests/Makefile.unittest @@ -0,0 +1,35 @@ +##===- unittests/Makefile.unittest -------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This file is included by all of the unit test makefiles. +# +##===----------------------------------------------------------------------===## + +# Set up variables for building a unit test. +ifdef TESTNAME + +include $(LEVEL)/Makefile.common + +LLVMUnitTestExe = $(BuildMode)/$(TESTNAME)Tests$(EXEEXT) + +CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/ +CPP.Flags += -Wno-variadic-macros +LIBS += -lGoogleTest -lUnitTestMain + +$(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths) + $(Echo) Linking $(BuildMode) unit test $(TESTNAME) $(StripWarnMsg) + $(Verb) $(Link) -o $@ $(TOOLLINKOPTS) $(ObjectsO) $(ProjLibsOptions) \ + $(LLVMLibsOptions) $(ExtraLibs) $(TOOLLINKOPTSB) $(LIBS) + $(Echo) ======= Finished Linking $(BuildMode) Unit test $(TESTNAME) \ + $(StripWarnMsg) + +all:: $(LLVMUnitTestExe) + $(LLVMUnitTestExe) + +endif diff --git a/unittests/Support/Makefile b/unittests/Support/Makefile new file mode 100644 index 0000000..815bdd2 --- /dev/null +++ b/unittests/Support/Makefile @@ -0,0 +1,15 @@ +##===- unittests/ADT/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 = Support +LINK_COMPONENTS := core support + +include $(LEVEL)/Makefile.config +include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp new file mode 100644 index 0000000..1f19468 --- /dev/null +++ b/unittests/Support/MathExtrasTest.cpp @@ -0,0 +1,104 @@ +//===- llvm/unittest/Support/MathExtrasTest.cpp - math utils 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/Support/MathExtras.h" + +using namespace llvm; + +namespace { + +TEST(MathExtras, isPowerOf2_32) { + EXPECT_TRUE(isPowerOf2_32(1 << 6)); + EXPECT_TRUE(isPowerOf2_32(1 << 12)); + EXPECT_FALSE(isPowerOf2_32((1 << 19) + 3)); + EXPECT_FALSE(isPowerOf2_32(0xABCDEF0)); +} + +TEST(MathExtras, isPowerOf2_64) { + EXPECT_TRUE(isPowerOf2_64(1LL << 46)); + EXPECT_TRUE(isPowerOf2_64(1LL << 12)); + EXPECT_FALSE(isPowerOf2_64((1LL << 53) + 3)); + EXPECT_FALSE(isPowerOf2_64(0xABCDEF0ABCDEF0LL)); +} + +TEST(MathExtras, ByteSwap_32) { + EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344)); + EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD)); +} + +TEST(MathExtras, ByteSwap_64) { + EXPECT_EQ(0x8877665544332211ULL, ByteSwap_64(0x1122334455667788LL)); + EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL)); +} + +TEST(MathExtras, CountLeadingZeros_32) { + EXPECT_EQ(8u, CountLeadingZeros_32(0x00F000FF)); + EXPECT_EQ(8u, CountLeadingZeros_32(0x00F12345)); + for (unsigned i = 0; i <= 30; ++i) { + EXPECT_EQ(31 - i, CountLeadingZeros_32(1 << i)); + } +} + +TEST(MathExtras, CountLeadingZeros_64) { + EXPECT_EQ(8u, CountLeadingZeros_64(0x00F1234500F12345LL)); + EXPECT_EQ(1u, CountLeadingZeros_64(1LL << 62)); + for (unsigned i = 0; i <= 62; ++i) { + EXPECT_EQ(63 - i, CountLeadingZeros_64(1LL << i)); + } +} + +TEST(MathExtras, CountLeadingOnes_32) { + for (int i = 30; i >= 0; --i) { + // Start with all ones and unset some bit. + EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i))); + } +} + +TEST(MathExtras, CountLeadingOnes_64) { + for (int i = 62; i >= 0; --i) { + // Start with all ones and unset some bit. + EXPECT_EQ(63u - i, CountLeadingOnes_64(0xFFFFFFFFFFFFFFFFLL ^ (1LL << i))); + } + for (int i = 30; i >= 0; --i) { + // Start with all ones and unset some bit. + EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i))); + } +} + +TEST(MathExtras, FloatBits) { + static const float kValue = 5632.34; + EXPECT_FLOAT_EQ(kValue, BitsToFloat(FloatToBits(kValue))); +} + +TEST(MathExtras, DoubleBits) { + static const double kValue = 87987234.983498; + EXPECT_FLOAT_EQ(kValue, BitsToDouble(DoubleToBits(kValue))); +} + +TEST(MathExtras, MinAlign) { + EXPECT_EQ(1u, MinAlign(2, 3)); + EXPECT_EQ(2u, MinAlign(2, 4)); + EXPECT_EQ(1u, MinAlign(17, 64)); + EXPECT_EQ(256u, MinAlign(256, 512)); +} + +TEST(MathExtras, NextPowerOf2) { + EXPECT_EQ(4u, NextPowerOf2(3)); + EXPECT_EQ(16u, NextPowerOf2(15)); + EXPECT_EQ(256u, NextPowerOf2(128)); +} + +TEST(MathExtras, RoundUpToAlignment) { + EXPECT_EQ(8u, RoundUpToAlignment(5, 8)); + EXPECT_EQ(24u, RoundUpToAlignment(17, 8)); + EXPECT_EQ(0u, RoundUpToAlignment(~0LL, 8)); +} + +} diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp new file mode 100644 index 0000000..425ee6b --- /dev/null +++ b/unittests/Support/TypeBuilderTest.cpp @@ -0,0 +1,233 @@ +//===- llvm/unittest/Support/TypeBuilderTest.cpp - TypeBuilder 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/TypeBuilder.h" + +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +TEST(TypeBuilderTest, Void) { + EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, true>::get())); + EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, false>::get())); + // Special case for C compatibility: + EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty), + (TypeBuilder<void*, false>::get())); +} + +TEST(TypeBuilderTest, HostIntegers) { + EXPECT_EQ(Type::Int8Ty, (TypeBuilder<int8_t, false>::get())); + EXPECT_EQ(Type::Int8Ty, (TypeBuilder<uint8_t, false>::get())); + EXPECT_EQ(Type::Int16Ty, (TypeBuilder<int16_t, false>::get())); + EXPECT_EQ(Type::Int16Ty, (TypeBuilder<uint16_t, false>::get())); + EXPECT_EQ(Type::Int32Ty, (TypeBuilder<int32_t, false>::get())); + EXPECT_EQ(Type::Int32Ty, (TypeBuilder<uint32_t, false>::get())); + EXPECT_EQ(Type::Int64Ty, (TypeBuilder<int64_t, false>::get())); + EXPECT_EQ(Type::Int64Ty, (TypeBuilder<uint64_t, false>::get())); + + EXPECT_EQ(IntegerType::get(sizeof(size_t) * CHAR_BIT), + (TypeBuilder<size_t, false>::get())); + EXPECT_EQ(IntegerType::get(sizeof(ptrdiff_t) * CHAR_BIT), + (TypeBuilder<ptrdiff_t, false>::get())); +} + +TEST(TypeBuilderTest, CrossCompilableIntegers) { + EXPECT_EQ(IntegerType::get(1), (TypeBuilder<types::i<1>, true>::get())); + EXPECT_EQ(IntegerType::get(1), (TypeBuilder<types::i<1>, false>::get())); + EXPECT_EQ(IntegerType::get(72), (TypeBuilder<types::i<72>, true>::get())); + EXPECT_EQ(IntegerType::get(72), (TypeBuilder<types::i<72>, false>::get())); +} + +TEST(TypeBuilderTest, Float) { + EXPECT_EQ(Type::FloatTy, (TypeBuilder<float, false>::get())); + EXPECT_EQ(Type::DoubleTy, (TypeBuilder<double, false>::get())); + // long double isn't supported yet. + EXPECT_EQ(Type::FloatTy, (TypeBuilder<types::ieee_float, true>::get())); + EXPECT_EQ(Type::FloatTy, (TypeBuilder<types::ieee_float, false>::get())); + EXPECT_EQ(Type::DoubleTy, (TypeBuilder<types::ieee_double, true>::get())); + EXPECT_EQ(Type::DoubleTy, (TypeBuilder<types::ieee_double, false>::get())); + EXPECT_EQ(Type::X86_FP80Ty, (TypeBuilder<types::x86_fp80, true>::get())); + EXPECT_EQ(Type::X86_FP80Ty, (TypeBuilder<types::x86_fp80, false>::get())); + EXPECT_EQ(Type::FP128Ty, (TypeBuilder<types::fp128, true>::get())); + EXPECT_EQ(Type::FP128Ty, (TypeBuilder<types::fp128, false>::get())); + EXPECT_EQ(Type::PPC_FP128Ty, (TypeBuilder<types::ppc_fp128, true>::get())); + EXPECT_EQ(Type::PPC_FP128Ty, (TypeBuilder<types::ppc_fp128, false>::get())); +} + +TEST(TypeBuilderTest, Derived) { + EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)), + (TypeBuilder<int8_t**, false>::get())); + EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7), + (TypeBuilder<int8_t[7], false>::get())); + EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0), + (TypeBuilder<int8_t[], false>::get())); + + EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)), + (TypeBuilder<types::i<8>**, false>::get())); + EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7), + (TypeBuilder<types::i<8>[7], false>::get())); + EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0), + (TypeBuilder<types::i<8>[], false>::get())); + + EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)), + (TypeBuilder<types::i<8>**, true>::get())); + EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7), + (TypeBuilder<types::i<8>[7], true>::get())); + EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0), + (TypeBuilder<types::i<8>[], true>::get())); + + + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<const int8_t, false>::get())); + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<volatile int8_t, false>::get())); + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<const volatile int8_t, false>::get())); + + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<const types::i<8>, false>::get())); + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<volatile types::i<8>, false>::get())); + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<const volatile types::i<8>, false>::get())); + + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<const types::i<8>, true>::get())); + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<volatile types::i<8>, true>::get())); + EXPECT_EQ(Type::Int8Ty, + (TypeBuilder<const volatile types::i<8>, true>::get())); + + EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty), + (TypeBuilder<const volatile int8_t*const volatile, false>::get())); +} + +TEST(TypeBuilderTest, Functions) { + std::vector<const Type*> params; + EXPECT_EQ(FunctionType::get(Type::VoidTy, params, false), + (TypeBuilder<void(), true>::get())); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true), + (TypeBuilder<int8_t(...), false>::get())); + params.push_back(TypeBuilder<int32_t*, false>::get()); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false), + (TypeBuilder<int8_t(const int32_t*), false>::get())); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true), + (TypeBuilder<int8_t(const int32_t*, ...), false>::get())); + params.push_back(TypeBuilder<char*, false>::get()); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false), + (TypeBuilder<int8_t(int32_t*, void*), false>::get())); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true), + (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get())); + params.push_back(TypeBuilder<char, false>::get()); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false), + (TypeBuilder<int8_t(int32_t*, void*, char), false>::get())); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true), + (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get())); + params.push_back(TypeBuilder<char, false>::get()); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false), + (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get())); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true), + (TypeBuilder<int8_t(int32_t*, char*, char, char, ...), + false>::get())); + params.push_back(TypeBuilder<char, false>::get()); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false), + (TypeBuilder<int8_t(int32_t*, void*, char, char, char), + false>::get())); + EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true), + (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...), + false>::get())); +} + +class MyType { + int a; + int *b; + void *array[1]; +}; + +class MyPortableType { + int32_t a; + int32_t *b; + void *array[1]; +}; + +} // anonymous namespace + +namespace llvm { +template<bool cross> class TypeBuilder<MyType, cross> { +public: + static const StructType *get() { + // Using the static result variable ensures that the type is + // only looked up once. + static const StructType *const result = StructType::get( + TypeBuilder<int, cross>::get(), + TypeBuilder<int*, cross>::get(), + TypeBuilder<void*[], cross>::get(), + NULL); + return result; + } + + // You may find this a convenient place to put some constants + // to help with getelementptr. They don't have any effect on + // the operation of TypeBuilder. + enum Fields { + FIELD_A, + FIELD_B, + FIELD_ARRAY + }; +}; + +template<bool cross> class TypeBuilder<MyPortableType, cross> { +public: + static const StructType *get() { + // Using the static result variable ensures that the type is + // only looked up once. + static const StructType *const result = StructType::get( + TypeBuilder<types::i<32>, cross>::get(), + TypeBuilder<types::i<32>*, cross>::get(), + TypeBuilder<types::i<8>*[], cross>::get(), + NULL); + return result; + } + + // You may find this a convenient place to put some constants + // to help with getelementptr. They don't have any effect on + // the operation of TypeBuilder. + enum Fields { + FIELD_A, + FIELD_B, + FIELD_ARRAY + }; +}; +} // namespace llvm +namespace { + +TEST(TypeBuilderTest, Extensions) { + EXPECT_EQ(PointerType::getUnqual(StructType::get( + TypeBuilder<int, false>::get(), + TypeBuilder<int*, false>::get(), + TypeBuilder<void*[], false>::get(), + NULL)), + (TypeBuilder<MyType*, false>::get())); + EXPECT_EQ(PointerType::getUnqual(StructType::get( + TypeBuilder<types::i<32>, false>::get(), + TypeBuilder<types::i<32>*, false>::get(), + TypeBuilder<types::i<8>*[], false>::get(), + NULL)), + (TypeBuilder<MyPortableType*, false>::get())); + EXPECT_EQ(PointerType::getUnqual(StructType::get( + TypeBuilder<types::i<32>, false>::get(), + TypeBuilder<types::i<32>*, false>::get(), + TypeBuilder<types::i<8>*[], false>::get(), + NULL)), + (TypeBuilder<MyPortableType*, true>::get())); +} + +} // anonymous namespace diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp new file mode 100644 index 0000000..336e7d9 --- /dev/null +++ b/unittests/Support/ValueHandleTest.cpp @@ -0,0 +1,317 @@ +//===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle 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/ValueHandle.h" + +#include "llvm/Constants.h" +#include "llvm/Instructions.h" + +#include "gtest/gtest.h" + +#include <memory> + +using namespace llvm; + +namespace { + +class ValueHandle : public testing::Test { +protected: + Constant *ConstantV; + std::auto_ptr<BitCastInst> BitcastV; + + ValueHandle() : ConstantV(ConstantInt::get(Type::Int32Ty, 0)), + BitcastV(new BitCastInst(ConstantV, Type::Int32Ty)) { + } +}; + +class ConcreteCallbackVH : public CallbackVH { +public: + ConcreteCallbackVH() : CallbackVH() {} + ConcreteCallbackVH(Value *V) : CallbackVH(V) {} +}; + +TEST_F(ValueHandle, WeakVH_BasicOperation) { + WeakVH WVH(BitcastV.get()); + EXPECT_EQ(BitcastV.get(), WVH); + WVH = ConstantV; + EXPECT_EQ(ConstantV, WVH); + + // Make sure I can call a method on the underlying Value. It + // doesn't matter which method. + EXPECT_EQ(Type::Int32Ty, WVH->getType()); + EXPECT_EQ(Type::Int32Ty, (*WVH).getType()); +} + +TEST_F(ValueHandle, WeakVH_Comparisons) { + WeakVH BitcastWVH(BitcastV.get()); + WeakVH ConstantWVH(ConstantV); + + EXPECT_TRUE(BitcastWVH == BitcastWVH); + EXPECT_TRUE(BitcastV.get() == BitcastWVH); + EXPECT_TRUE(BitcastWVH == BitcastV.get()); + EXPECT_FALSE(BitcastWVH == ConstantWVH); + + EXPECT_TRUE(BitcastWVH != ConstantWVH); + EXPECT_TRUE(BitcastV.get() != ConstantWVH); + EXPECT_TRUE(BitcastWVH != ConstantV); + EXPECT_FALSE(BitcastWVH != BitcastWVH); + + // Cast to Value* so comparisons work. + Value *BV = BitcastV.get(); + Value *CV = ConstantV; + EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH); + EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH); + EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH); + EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH); + + EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH); + EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH); + EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH); + EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH); + + EXPECT_EQ(BV < CV, BitcastWVH < ConstantV); + EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV); + EXPECT_EQ(BV > CV, BitcastWVH > ConstantV); + EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV); +} + +TEST_F(ValueHandle, WeakVH_FollowsRAUW) { + WeakVH WVH(BitcastV.get()); + WeakVH WVH_Copy(WVH); + WeakVH WVH_Recreated(BitcastV.get()); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_EQ(ConstantV, WVH); + EXPECT_EQ(ConstantV, WVH_Copy); + EXPECT_EQ(ConstantV, WVH_Recreated); +} + +TEST_F(ValueHandle, WeakVH_NullOnDeletion) { + WeakVH WVH(BitcastV.get()); + WeakVH WVH_Copy(WVH); + WeakVH WVH_Recreated(BitcastV.get()); + BitcastV.reset(); + Value *null_value = NULL; + EXPECT_EQ(null_value, WVH); + EXPECT_EQ(null_value, WVH_Copy); + EXPECT_EQ(null_value, WVH_Recreated); +} + + +TEST_F(ValueHandle, AssertingVH_BasicOperation) { + AssertingVH<CastInst> AVH(BitcastV.get()); + CastInst *implicit_to_exact_type = AVH; + implicit_to_exact_type = implicit_to_exact_type; // Avoid warning. + + AssertingVH<Value> GenericAVH(BitcastV.get()); + EXPECT_EQ(BitcastV.get(), GenericAVH); + GenericAVH = ConstantV; + EXPECT_EQ(ConstantV, GenericAVH); + + // Make sure I can call a method on the underlying CastInst. It + // doesn't matter which method. + EXPECT_FALSE(AVH->mayWriteToMemory()); + EXPECT_FALSE((*AVH).mayWriteToMemory()); +} + +TEST_F(ValueHandle, AssertingVH_Comparisons) { + AssertingVH<Value> BitcastAVH(BitcastV.get()); + AssertingVH<Value> ConstantAVH(ConstantV); + + EXPECT_TRUE(BitcastAVH == BitcastAVH); + EXPECT_TRUE(BitcastV.get() == BitcastAVH); + EXPECT_TRUE(BitcastAVH == BitcastV.get()); + EXPECT_FALSE(BitcastAVH == ConstantAVH); + + EXPECT_TRUE(BitcastAVH != ConstantAVH); + EXPECT_TRUE(BitcastV.get() != ConstantAVH); + EXPECT_TRUE(BitcastAVH != ConstantV); + EXPECT_FALSE(BitcastAVH != BitcastAVH); + + // Cast to Value* so comparisons work. + Value *BV = BitcastV.get(); + Value *CV = ConstantV; + EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH); + EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH); + EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH); + EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH); + + EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH); + EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH); + EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH); + EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH); + + EXPECT_EQ(BV < CV, BitcastAVH < ConstantV); + EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV); + EXPECT_EQ(BV > CV, BitcastAVH > ConstantV); + EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV); +} + +TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) { + AssertingVH<Value> AVH(BitcastV.get()); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_EQ(BitcastV.get(), AVH); +} + +#ifdef NDEBUG + +TEST_F(ValueHandle, AssertingVH_ReducesToPointer) { + EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>)); +} + +#else // !NDEBUG + +#ifdef GTEST_HAS_DEATH_TEST + +TEST_F(ValueHandle, AssertingVH_Asserts) { + AssertingVH<Value> AVH(BitcastV.get()); + EXPECT_DEATH({BitcastV.reset();}, + "An asserting value handle still pointed to this value!"); + AssertingVH<Value> Copy(AVH); + AVH = NULL; + EXPECT_DEATH({BitcastV.reset();}, + "An asserting value handle still pointed to this value!"); + Copy = NULL; + BitcastV.reset(); +} + +#endif // GTEST_HAS_DEATH_TEST + +#endif // NDEBUG + +TEST_F(ValueHandle, CallbackVH_BasicOperation) { + ConcreteCallbackVH CVH(BitcastV.get()); + EXPECT_EQ(BitcastV.get(), CVH); + CVH = ConstantV; + EXPECT_EQ(ConstantV, CVH); + + // Make sure I can call a method on the underlying Value. It + // doesn't matter which method. + EXPECT_EQ(Type::Int32Ty, CVH->getType()); + EXPECT_EQ(Type::Int32Ty, (*CVH).getType()); +} + +TEST_F(ValueHandle, CallbackVH_Comparisons) { + ConcreteCallbackVH BitcastCVH(BitcastV.get()); + ConcreteCallbackVH ConstantCVH(ConstantV); + + EXPECT_TRUE(BitcastCVH == BitcastCVH); + EXPECT_TRUE(BitcastV.get() == BitcastCVH); + EXPECT_TRUE(BitcastCVH == BitcastV.get()); + EXPECT_FALSE(BitcastCVH == ConstantCVH); + + EXPECT_TRUE(BitcastCVH != ConstantCVH); + EXPECT_TRUE(BitcastV.get() != ConstantCVH); + EXPECT_TRUE(BitcastCVH != ConstantV); + EXPECT_FALSE(BitcastCVH != BitcastCVH); + + // Cast to Value* so comparisons work. + Value *BV = BitcastV.get(); + Value *CV = ConstantV; + EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH); + EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH); + EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH); + EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH); + + EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH); + EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH); + EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH); + EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH); + + EXPECT_EQ(BV < CV, BitcastCVH < ConstantV); + EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV); + EXPECT_EQ(BV > CV, BitcastCVH > ConstantV); + EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV); +} + +TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) { + class RecordingVH : public CallbackVH { + public: + int DeletedCalls; + int AURWCalls; + + RecordingVH() : DeletedCalls(0), AURWCalls(0) {} + RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {} + + private: + virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); } + virtual void allUsesReplacedWith(Value *) { AURWCalls++; } + }; + + RecordingVH RVH; + RVH = BitcastV.get(); + EXPECT_EQ(0, RVH.DeletedCalls); + EXPECT_EQ(0, RVH.AURWCalls); + BitcastV.reset(); + EXPECT_EQ(1, RVH.DeletedCalls); + EXPECT_EQ(0, RVH.AURWCalls); +} + +TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) { + class RecordingVH : public CallbackVH { + public: + int DeletedCalls; + Value *AURWArgument; + + RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {} + RecordingVH(Value *V) + : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {} + + private: + virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); } + virtual void allUsesReplacedWith(Value *new_value) { + EXPECT_EQ(NULL, AURWArgument); + AURWArgument = new_value; + } + }; + + RecordingVH RVH; + RVH = BitcastV.get(); + EXPECT_EQ(0, RVH.DeletedCalls); + EXPECT_EQ(NULL, RVH.AURWArgument); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_EQ(0, RVH.DeletedCalls); + EXPECT_EQ(ConstantV, RVH.AURWArgument); +} + +TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) { + class RecoveringVH : public CallbackVH { + public: + int DeletedCalls; + Value *AURWArgument; + + RecoveringVH() : DeletedCalls(0), AURWArgument(NULL) {} + RecoveringVH(Value *V) + : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {} + + private: + virtual void deleted() { + getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty)); + setValPtr(NULL); + } + virtual void allUsesReplacedWith(Value *new_value) { + ASSERT_TRUE(NULL != getValPtr()); + EXPECT_EQ(1U, getValPtr()->getNumUses()); + EXPECT_EQ(NULL, AURWArgument); + AURWArgument = new_value; + } + }; + + // Normally, if a value has uses, deleting it will crash. However, we can use + // a CallbackVH to remove the uses before the check for no uses. + RecoveringVH RVH; + RVH = BitcastV.get(); + std::auto_ptr<BinaryOperator> BitcastUser( + BinaryOperator::CreateAdd(RVH, Constant::getNullValue(Type::Int32Ty))); + EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0)); + BitcastV.reset(); // Would crash without the ValueHandler. + EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), RVH.AURWArgument); + EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), BitcastUser->getOperand(0)); +} + +} diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp new file mode 100644 index 0000000..feb0152 --- /dev/null +++ b/unittests/Support/raw_ostream_test.cpp @@ -0,0 +1,85 @@ +//===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream 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/Support/raw_ostream.h" + +using namespace llvm; + +namespace { + +template<typename T> std::string printToString(const T &Value) { + std::string res; + llvm::raw_string_ostream(res) << Value; + return res; +} + +template<typename T> std::string printToStringUnbuffered(const T &Value) { + std::string res; + llvm::raw_string_ostream OS(res); + OS.SetUnbuffered(); + OS << Value; + return res; +} + +TEST(raw_ostreamTest, Types_Buffered) { + // Char + EXPECT_EQ("c", printToString('c')); + + // String + EXPECT_EQ("hello", printToString("hello")); + EXPECT_EQ("hello", printToString(std::string("hello"))); + + // Int + EXPECT_EQ("0", printToString(0)); + EXPECT_EQ("2425", printToString(2425)); + EXPECT_EQ("-2425", printToString(-2425)); + + // Long long + EXPECT_EQ("0", printToString(0LL)); + EXPECT_EQ("257257257235709", printToString(257257257235709LL)); + EXPECT_EQ("-257257257235709", printToString(-257257257235709LL)); + + // Double + EXPECT_EQ("1.100000e+00", printToString(1.1)); + + // void* + EXPECT_EQ("0x0", printToString((void*) 0)); + EXPECT_EQ("0xbeef", printToString((void*) 0xbeef)); + EXPECT_EQ("0xdeadbeef", printToString((void*) 0xdeadbeef)); +} + +TEST(raw_ostreamTest, Types_Unbuffered) { + // Char + EXPECT_EQ("c", printToStringUnbuffered('c')); + + // String + EXPECT_EQ("hello", printToStringUnbuffered("hello")); + EXPECT_EQ("hello", printToStringUnbuffered(std::string("hello"))); + + // Int + EXPECT_EQ("0", printToStringUnbuffered(0)); + EXPECT_EQ("2425", printToStringUnbuffered(2425)); + EXPECT_EQ("-2425", printToStringUnbuffered(-2425)); + + // Long long + EXPECT_EQ("0", printToStringUnbuffered(0LL)); + EXPECT_EQ("257257257235709", printToStringUnbuffered(257257257235709LL)); + EXPECT_EQ("-257257257235709", printToStringUnbuffered(-257257257235709LL)); + + // Double + EXPECT_EQ("1.100000e+00", printToStringUnbuffered(1.1)); + + // void* + EXPECT_EQ("0x0", printToStringUnbuffered((void*) 0)); + EXPECT_EQ("0xbeef", printToStringUnbuffered((void*) 0xbeef)); + EXPECT_EQ("0xdeadbeef", printToStringUnbuffered((void*) 0xdeadbeef)); +} + +} diff --git a/unittests/TestMain.cpp b/unittests/TestMain.cpp new file mode 100644 index 0000000..095076b --- /dev/null +++ b/unittests/TestMain.cpp @@ -0,0 +1,15 @@ +//===--- unittests/TestMain.cpp - unittest driver -------------------------===// +// +// 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" + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/unittests/VMCore/ConstantsTest.cpp b/unittests/VMCore/ConstantsTest.cpp new file mode 100644 index 0000000..519d928 --- /dev/null +++ b/unittests/VMCore/ConstantsTest.cpp @@ -0,0 +1,112 @@ +//===- llvm/unittest/VMCore/ConstantsTest.cpp - Constants unit tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "gtest/gtest.h" + +namespace llvm { +namespace { + +TEST(ConstantsTest, Integer_i1) { + const IntegerType* Int1 = IntegerType::get(1); + Constant* One = ConstantInt::get(Int1, 1, true); + Constant* Zero = ConstantInt::get(Int1, 0); + Constant* NegOne = ConstantInt::get(Int1, static_cast<uint64_t>(-1), true); + EXPECT_EQ(NegOne, ConstantInt::getSigned(Int1, -1)); + Constant* Undef = UndefValue::get(Int1); + + // Input: @b = constant i1 add(i1 1 , i1 1) + // Output: @b = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getAdd(One, One)); + + // @c = constant i1 add(i1 -1, i1 1) + // @c = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, One)); + + // @d = constant i1 add(i1 -1, i1 -1) + // @d = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getAdd(NegOne, NegOne)); + + // @e = constant i1 sub(i1 -1, i1 1) + // @e = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getSub(NegOne, One)); + + // @f = constant i1 sub(i1 1 , i1 -1) + // @f = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getSub(One, NegOne)); + + // @g = constant i1 sub(i1 1 , i1 1) + // @g = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getSub(One, One)); + + // @h = constant i1 shl(i1 1 , i1 1) ; undefined + // @h = constant i1 undef + EXPECT_EQ(Undef, ConstantExpr::getShl(One, One)); + + // @i = constant i1 shl(i1 1 , i1 0) + // @i = constant i1 true + EXPECT_EQ(One, ConstantExpr::getShl(One, Zero)); + + // @j = constant i1 lshr(i1 1, i1 1) ; undefined + // @j = constant i1 undef + EXPECT_EQ(Undef, ConstantExpr::getLShr(One, One)); + + // @m = constant i1 ashr(i1 1, i1 1) ; undefined + // @m = constant i1 undef + EXPECT_EQ(Undef, ConstantExpr::getAShr(One, One)); + + // @n = constant i1 mul(i1 -1, i1 1) + // @n = constant i1 true + EXPECT_EQ(One, ConstantExpr::getMul(NegOne, One)); + + // @o = constant i1 sdiv(i1 -1, i1 1) ; overflow + // @o = constant i1 true + EXPECT_EQ(One, ConstantExpr::getSDiv(NegOne, One)); + + // @p = constant i1 sdiv(i1 1 , i1 -1); overflow + // @p = constant i1 true + EXPECT_EQ(One, ConstantExpr::getSDiv(One, NegOne)); + + // @q = constant i1 udiv(i1 -1, i1 1) + // @q = constant i1 true + EXPECT_EQ(One, ConstantExpr::getUDiv(NegOne, One)); + + // @r = constant i1 udiv(i1 1, i1 -1) + // @r = constant i1 true + EXPECT_EQ(One, ConstantExpr::getUDiv(One, NegOne)); + + // @s = constant i1 srem(i1 -1, i1 1) ; overflow + // @s = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getSRem(NegOne, One)); + + // @t = constant i1 urem(i1 -1, i1 1) + // @t = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getURem(NegOne, One)); + + // @u = constant i1 srem(i1 1, i1 -1) ; overflow + // @u = constant i1 false + EXPECT_EQ(Zero, ConstantExpr::getSRem(One, NegOne)); +} + +TEST(ConstantsTest, IntSigns) { + const IntegerType* Int8Ty = Type::Int8Ty; + EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue()); + EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue()); + EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue()); + EXPECT_EQ(-50, ConstantInt::get(Int8Ty, 206)->getSExtValue()); + EXPECT_EQ(-50, ConstantInt::getSigned(Int8Ty, -50)->getSExtValue()); + EXPECT_EQ(206U, ConstantInt::getSigned(Int8Ty, -50)->getZExtValue()); + + // Overflow is handled by truncation. + EXPECT_EQ(0x3b, ConstantInt::get(Int8Ty, 0x13b)->getSExtValue()); +} + +} // end anonymous namespace +} // end namespace llvm diff --git a/unittests/VMCore/Makefile b/unittests/VMCore/Makefile new file mode 100644 index 0000000..1aa1560 --- /dev/null +++ b/unittests/VMCore/Makefile @@ -0,0 +1,15 @@ +##===- unittests/VMCore/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 = VMCore +LINK_COMPONENTS := core support + +include $(LEVEL)/Makefile.config +include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp new file mode 100644 index 0000000..2de3a92 --- /dev/null +++ b/unittests/VMCore/MetadataTest.cpp @@ -0,0 +1,139 @@ +//===- llvm/unittest/VMCore/Metadata.cpp - Metadata 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/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/MDNode.h" +#include "llvm/Type.h" +#include "llvm/Support/ValueHandle.h" +#include <sstream> + +using namespace llvm; + +namespace { + +// Test that construction of MDString with different value produces different +// MDString objects, even with the same string pointer and nulls in the string. +TEST(MDStringTest, CreateDifferent) { + char x[3] = { 'f', 0, 'A' }; + MDString *s1 = MDString::get(&x[0], &x[3]); + x[2] = 'B'; + MDString *s2 = MDString::get(&x[0], &x[3]); + EXPECT_NE(s1, s2); +} + +// Test that creation of MDStrings with the same string contents produces the +// same MDString object, even with different pointers. +TEST(MDStringTest, CreateSame) { + char x[4] = { 'a', 'b', 'c', 'X' }; + char y[4] = { 'a', 'b', 'c', 'Y' }; + + MDString *s1 = MDString::get(&x[0], &x[3]); + MDString *s2 = MDString::get(&y[0], &y[3]); + EXPECT_EQ(s1, s2); +} + +// Test that MDString prints out the string we fed it. +TEST(MDStringTest, PrintingSimple) { + char *str = new char[13]; + strncpy(str, "testing 1 2 3", 13); + MDString *s = MDString::get(str, str+13); + strncpy(str, "aaaaaaaaaaaaa", 13); + delete[] str; + + std::ostringstream oss; + s->print(oss); + EXPECT_STREQ("metadata !\"testing 1 2 3\"", oss.str().c_str()); +} + +// Test printing of MDString with non-printable characters. +TEST(MDStringTest, PrintingComplex) { + char str[5] = {0, '\n', '"', '\\', -1}; + MDString *s = MDString::get(str+0, str+5); + std::ostringstream oss; + s->print(oss); + EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str()); +} + +// Test the two constructors, and containing other Constants. +TEST(MDNodeTest, Simple) { + char x[3] = { 'a', 'b', 'c' }; + char y[3] = { '1', '2', '3' }; + + MDString *s1 = MDString::get(&x[0], &x[3]); + MDString *s2 = MDString::get(&y[0], &y[3]); + ConstantInt *CI = ConstantInt::get(APInt(8, 0)); + + std::vector<Value *> V; + V.push_back(s1); + V.push_back(CI); + V.push_back(s2); + + MDNode *n1 = MDNode::get(&V[0], 3); + Value *const c1 = n1; + MDNode *n2 = MDNode::get(&c1, 1); + MDNode *n3 = MDNode::get(&V[0], 3); + EXPECT_NE(n1, n2); + EXPECT_EQ(n1, n3); + + EXPECT_EQ(3u, n1->getNumElements()); + EXPECT_EQ(s1, n1->getElement(0)); + EXPECT_EQ(CI, n1->getElement(1)); + EXPECT_EQ(s2, n1->getElement(2)); + + EXPECT_EQ(1u, n2->getNumElements()); + EXPECT_EQ(n1, n2->getElement(0)); + + std::ostringstream oss1, oss2; + n1->print(oss1); + n2->print(oss2); + EXPECT_STREQ("metadata !{metadata !\"abc\", i8 0, metadata !\"123\"}", + oss1.str().c_str()); + EXPECT_STREQ("metadata !{metadata !{metadata !\"abc\", i8 0, " + "metadata !\"123\"}}", + oss2.str().c_str()); +} + +TEST(MDNodeTest, RAUW) { + Constant *C = ConstantInt::get(Type::Int32Ty, 1); + Instruction *I = new BitCastInst(C, Type::Int32Ty); + + Value *const V1 = I; + MDNode *n1 = MDNode::get(&V1, 1); + WeakVH wn1 = n1; + + Value *const V2 = C; + MDNode *n2 = MDNode::get(&V2, 1); + WeakVH wn2 = n2; + + EXPECT_NE(wn1, wn2); + + I->replaceAllUsesWith(C); + + EXPECT_EQ(wn1, wn2); +} + +TEST(MDNodeTest, Delete) { + Constant *C = ConstantInt::get(Type::Int32Ty, 1); + Instruction *I = new BitCastInst(C, Type::Int32Ty); + + Value *const V = I; + MDNode *n = MDNode::get(&V, 1); + WeakVH wvh = n; + + EXPECT_EQ(n, wvh); + + delete I; + + std::ostringstream oss; + wvh->print(oss); + EXPECT_STREQ("metadata !{null}", oss.str().c_str()); +} +} |