diff options
Diffstat (limited to 'unittests')
80 files changed, 3904 insertions, 1031 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp index 117b820..2789835 100644 --- a/unittests/ADT/APFloatTest.cpp +++ b/unittests/ADT/APFloatTest.cpp @@ -7,14 +7,14 @@ // //===----------------------------------------------------------------------===// -#include <ostream> -#include <string> -#include "llvm/Support/raw_ostream.h" -#include "gtest/gtest.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" +#include <ostream> +#include <string> using namespace llvm; @@ -33,6 +33,58 @@ static std::string convertToString(double d, unsigned Prec, unsigned Pad) { namespace { +TEST(APFloatTest, Denormal) { + APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven; + + // Test single precision + { + const char *MinNormalStr = "1.17549435082228750797e-38"; + EXPECT_FALSE(APFloat(APFloat::IEEEsingle, MinNormalStr).isDenormal()); + EXPECT_FALSE(APFloat(APFloat::IEEEsingle, 0.0).isDenormal()); + + APFloat Val2(APFloat::IEEEsingle, 2.0e0); + APFloat T(APFloat::IEEEsingle, MinNormalStr); + T.divide(Val2, rdmd); + EXPECT_TRUE(T.isDenormal()); + } + + // Test double precision + { + const char *MinNormalStr = "2.22507385850720138309e-308"; + EXPECT_FALSE(APFloat(APFloat::IEEEdouble, MinNormalStr).isDenormal()); + EXPECT_FALSE(APFloat(APFloat::IEEEdouble, 0.0).isDenormal()); + + APFloat Val2(APFloat::IEEEdouble, 2.0e0); + APFloat T(APFloat::IEEEdouble, MinNormalStr); + T.divide(Val2, rdmd); + EXPECT_TRUE(T.isDenormal()); + } + + // Test Intel double-ext + { + const char *MinNormalStr = "3.36210314311209350626e-4932"; + EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended, MinNormalStr).isDenormal()); + EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended, 0.0).isDenormal()); + + APFloat Val2(APFloat::x87DoubleExtended, 2.0e0); + APFloat T(APFloat::x87DoubleExtended, MinNormalStr); + T.divide(Val2, rdmd); + EXPECT_TRUE(T.isDenormal()); + } + + // Test quadruple precision + { + const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932"; + EXPECT_FALSE(APFloat(APFloat::IEEEquad, MinNormalStr).isDenormal()); + EXPECT_FALSE(APFloat(APFloat::IEEEquad, 0.0).isDenormal()); + + APFloat Val2(APFloat::IEEEquad, 2.0e0); + APFloat T(APFloat::IEEEquad, MinNormalStr); + T.divide(Val2, rdmd); + EXPECT_TRUE(T.isDenormal()); + } +} + TEST(APFloatTest, Zero) { EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat()); EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat()); @@ -742,6 +794,32 @@ TEST(APFloatTest, convert) { test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo); EXPECT_EQ(4294967295.0, test.convertToDouble()); EXPECT_FALSE(losesInfo); + + test = APFloat::getSNaN(APFloat::IEEEsingle); + APFloat X87SNaN = APFloat::getSNaN(APFloat::x87DoubleExtended); + test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven, + &losesInfo); + EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN)); + EXPECT_FALSE(losesInfo); + + test = APFloat::getQNaN(APFloat::IEEEsingle); + APFloat X87QNaN = APFloat::getQNaN(APFloat::x87DoubleExtended); + test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven, + &losesInfo); + EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN)); + EXPECT_FALSE(losesInfo); + + test = APFloat::getSNaN(APFloat::x87DoubleExtended); + test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven, + &losesInfo); + EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN)); + EXPECT_FALSE(losesInfo); + + test = APFloat::getQNaN(APFloat::x87DoubleExtended); + test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven, + &losesInfo); + EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN)); + EXPECT_FALSE(losesInfo); } TEST(APFloatTest, PPCDoubleDouble) { diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 49d7e70..f129fa7 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include <ostream> -#include "gtest/gtest.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallString.h" +#include "gtest/gtest.h" +#include <ostream> using namespace llvm; @@ -56,6 +56,14 @@ TEST(APIntTest, i33_Count) { #endif TEST(APIntTest, i65_Count) { + APInt i65(65, 0, true); + EXPECT_EQ(65u, i65.countLeadingZeros()); + EXPECT_EQ(0u, i65.countLeadingOnes()); + EXPECT_EQ(0u, i65.getActiveBits()); + EXPECT_EQ(1u, i65.getActiveWords()); + EXPECT_EQ(65u, i65.countTrailingZeros()); + EXPECT_EQ(0u, i65.countPopulation()); + APInt i65minus(65, 0, true); i65minus.setBit(64); EXPECT_EQ(0u, i65minus.countLeadingZeros()); @@ -514,4 +522,14 @@ TEST(APIntTest, Rotate) { EXPECT_EQ(Rot, Big.rotr(144)); } +TEST(APIntTest, Splat) { + APInt ValA(8, 0x01); + EXPECT_EQ(ValA, APInt::getSplat(8, ValA)); + EXPECT_EQ(APInt(64, 0x0101010101010101ULL), APInt::getSplat(64, ValA)); + + APInt ValB(3, 5); + EXPECT_EQ(APInt(4, 0xD), APInt::getSplat(4, ValB)); + EXPECT_EQ(APInt(15, 0xDB6D), APInt::getSplat(15, ValB)); +} + } diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt index 94f7fda..9aad793 100644 --- a/unittests/ADT/CMakeLists.txt +++ b/unittests/ADT/CMakeLists.txt @@ -18,12 +18,15 @@ set(ADTSources IntEqClassesTest.cpp IntervalMapTest.cpp IntrusiveRefCntPtrTest.cpp + MapVectorTest.cpp + OptionalTest.cpp PackedVectorTest.cpp SCCIteratorTest.cpp SmallPtrSetTest.cpp SmallStringTest.cpp SmallVectorTest.cpp SparseBitVectorTest.cpp + SparseMultiSetTest.cpp SparseSetTest.cpp StringMapTest.cpp StringRefTest.cpp diff --git a/unittests/ADT/MapVectorTest.cpp b/unittests/ADT/MapVectorTest.cpp new file mode 100644 index 0000000..11178bc --- /dev/null +++ b/unittests/ADT/MapVectorTest.cpp @@ -0,0 +1,55 @@ +//===- unittest/ADT/MapVectorTest.cpp - MapVector 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/MapVector.h" +#include <utility> + +using namespace llvm; + +TEST(MapVectorTest, insert_pop) { + MapVector<int, int> MV; + std::pair<MapVector<int, int>::iterator, bool> R; + + R = MV.insert(std::make_pair(1, 2)); + ASSERT_EQ(R.first, MV.begin()); + EXPECT_EQ(R.first->first, 1); + EXPECT_EQ(R.first->second, 2); + EXPECT_TRUE(R.second); + + R = MV.insert(std::make_pair(1, 3)); + ASSERT_EQ(R.first, MV.begin()); + EXPECT_EQ(R.first->first, 1); + EXPECT_EQ(R.first->second, 2); + EXPECT_FALSE(R.second); + + R = MV.insert(std::make_pair(4, 5)); + ASSERT_NE(R.first, MV.end()); + EXPECT_EQ(R.first->first, 4); + EXPECT_EQ(R.first->second, 5); + EXPECT_TRUE(R.second); + + EXPECT_EQ(MV.size(), 2u); + EXPECT_EQ(MV[1], 2); + EXPECT_EQ(MV[4], 5); + + MV.pop_back(); + EXPECT_EQ(MV.size(), 1u); + EXPECT_EQ(MV[1], 2); + + R = MV.insert(std::make_pair(4, 7)); + ASSERT_NE(R.first, MV.end()); + EXPECT_EQ(R.first->first, 4); + EXPECT_EQ(R.first->second, 7); + EXPECT_TRUE(R.second); + + EXPECT_EQ(MV.size(), 2u); + EXPECT_EQ(MV[1], 2); + EXPECT_EQ(MV[4], 7); +} diff --git a/unittests/ADT/OptionalTest.cpp b/unittests/ADT/OptionalTest.cpp new file mode 100644 index 0000000..21e3847 --- /dev/null +++ b/unittests/ADT/OptionalTest.cpp @@ -0,0 +1,284 @@ +//===- llvm/unittest/ADT/OptionalTest.cpp - Optional 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/Optional.h" +using namespace llvm; + +namespace { + +struct NonDefaultConstructible { + static unsigned CopyConstructions; + static unsigned Destructions; + static unsigned CopyAssignments; + explicit NonDefaultConstructible(int) { + } + NonDefaultConstructible(const NonDefaultConstructible&) { + ++CopyConstructions; + } + NonDefaultConstructible &operator=(const NonDefaultConstructible&) { + ++CopyAssignments; + return *this; + } + ~NonDefaultConstructible() { + ++Destructions; + } + static void ResetCounts() { + CopyConstructions = 0; + Destructions = 0; + CopyAssignments = 0; + } +}; + +unsigned NonDefaultConstructible::CopyConstructions = 0; +unsigned NonDefaultConstructible::Destructions = 0; +unsigned NonDefaultConstructible::CopyAssignments = 0; + +// Test fixture +class OptionalTest : public testing::Test { +}; + +TEST_F(OptionalTest, NonDefaultConstructibleTest) { + Optional<NonDefaultConstructible> O; + EXPECT_FALSE(O); +} + +TEST_F(OptionalTest, ResetTest) { + NonDefaultConstructible::ResetCounts(); + Optional<NonDefaultConstructible> O(NonDefaultConstructible(3)); + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + O.reset(); + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); +} + +TEST_F(OptionalTest, InitializationLeakTest) { + NonDefaultConstructible::ResetCounts(); + Optional<NonDefaultConstructible>(NonDefaultConstructible(3)); + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(2u, NonDefaultConstructible::Destructions); +} + +TEST_F(OptionalTest, CopyConstructionTest) { + NonDefaultConstructible::ResetCounts(); + { + Optional<NonDefaultConstructible> A(NonDefaultConstructible(3)); + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + Optional<NonDefaultConstructible> B(A); + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + } + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(2u, NonDefaultConstructible::Destructions); +} + +TEST_F(OptionalTest, ConstructingCopyAssignmentTest) { + NonDefaultConstructible::ResetCounts(); + { + Optional<NonDefaultConstructible> A(NonDefaultConstructible(3)); + Optional<NonDefaultConstructible> B; + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + B = A; + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + } + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(2u, NonDefaultConstructible::Destructions); +} + +TEST_F(OptionalTest, CopyingCopyAssignmentTest) { + NonDefaultConstructible::ResetCounts(); + { + Optional<NonDefaultConstructible> A(NonDefaultConstructible(3)); + Optional<NonDefaultConstructible> B(NonDefaultConstructible(4)); + EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(2u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + B = A; + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + } + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(2u, NonDefaultConstructible::Destructions); +} + +TEST_F(OptionalTest, DeletingCopyAssignmentTest) { + NonDefaultConstructible::ResetCounts(); + { + Optional<NonDefaultConstructible> A; + Optional<NonDefaultConstructible> B(NonDefaultConstructible(3)); + EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + B = A; + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(1u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + } + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); +} + +TEST_F(OptionalTest, NullCopyConstructionTest) { + NonDefaultConstructible::ResetCounts(); + { + Optional<NonDefaultConstructible> A; + Optional<NonDefaultConstructible> B; + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + B = A; + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); + NonDefaultConstructible::ResetCounts(); + } + EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions); + EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments); + EXPECT_EQ(0u, NonDefaultConstructible::Destructions); +} + +#if LLVM_HAS_RVALUE_REFERENCES +struct MoveOnly { + static unsigned MoveConstructions; + static unsigned Destructions; + static unsigned MoveAssignments; + int val; + explicit MoveOnly(int val) : val(val) { + } + MoveOnly(MoveOnly&& other) { + val = other.val; + ++MoveConstructions; + } + MoveOnly &operator=(MoveOnly&& other) { + val = other.val; + ++MoveAssignments; + return *this; + } + ~MoveOnly() { + ++Destructions; + } + static void ResetCounts() { + MoveConstructions = 0; + Destructions = 0; + MoveAssignments = 0; + } +}; + +unsigned MoveOnly::MoveConstructions = 0; +unsigned MoveOnly::Destructions = 0; +unsigned MoveOnly::MoveAssignments = 0; + +TEST_F(OptionalTest, MoveOnlyNull) { + MoveOnly::ResetCounts(); + Optional<MoveOnly> O; + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyConstruction) { + MoveOnly::ResetCounts(); + Optional<MoveOnly> O(MoveOnly(3)); + EXPECT_TRUE((bool)O); + EXPECT_EQ(3, O->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyMoveConstruction) { + Optional<MoveOnly> A(MoveOnly(3)); + MoveOnly::ResetCounts(); + Optional<MoveOnly> B(std::move(A)); + EXPECT_FALSE((bool)A); + EXPECT_TRUE((bool)B); + EXPECT_EQ(3, B->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyAssignment) { + MoveOnly::ResetCounts(); + Optional<MoveOnly> O; + O = MoveOnly(3); + EXPECT_TRUE((bool)O); + EXPECT_EQ(3, O->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyInitializingAssignment) { + Optional<MoveOnly> A(MoveOnly(3)); + Optional<MoveOnly> B; + MoveOnly::ResetCounts(); + B = std::move(A); + EXPECT_FALSE((bool)A); + EXPECT_TRUE((bool)B); + EXPECT_EQ(3, B->val); + EXPECT_EQ(1u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyNullingAssignment) { + Optional<MoveOnly> A; + Optional<MoveOnly> B(MoveOnly(3)); + MoveOnly::ResetCounts(); + B = std::move(A); + EXPECT_FALSE((bool)A); + EXPECT_FALSE((bool)B); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} + +TEST_F(OptionalTest, MoveOnlyAssigningAssignment) { + Optional<MoveOnly> A(MoveOnly(3)); + Optional<MoveOnly> B(MoveOnly(4)); + MoveOnly::ResetCounts(); + B = std::move(A); + EXPECT_FALSE((bool)A); + EXPECT_TRUE((bool)B); + EXPECT_EQ(3, B->val); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(1u, MoveOnly::MoveAssignments); + EXPECT_EQ(1u, MoveOnly::Destructions); +} +#endif + +} // end anonymous namespace + diff --git a/unittests/ADT/SCCIteratorTest.cpp b/unittests/ADT/SCCIteratorTest.cpp index 00fa066..92b4b31 100644 --- a/unittests/ADT/SCCIteratorTest.cpp +++ b/unittests/ADT/SCCIteratorTest.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include <limits.h> -#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SCCIterator.h" +#include "llvm/ADT/GraphTraits.h" #include "gtest/gtest.h" +#include <limits.h> using namespace llvm; diff --git a/unittests/ADT/SmallPtrSetTest.cpp b/unittests/ADT/SmallPtrSetTest.cpp index 9114875..f85d7c9 100644 --- a/unittests/ADT/SmallPtrSetTest.cpp +++ b/unittests/ADT/SmallPtrSetTest.cpp @@ -17,6 +17,61 @@ using namespace llvm; // SmallPtrSet swapping test. +TEST(SmallPtrSetTest, GrowthTest) { + int i; + int buf[8]; + for(i=0; i<8; ++i) buf[i]=0; + + + SmallPtrSet<int *, 4> s; + typedef SmallPtrSet<int *, 4>::iterator iter; + + s.insert(&buf[0]); + s.insert(&buf[1]); + s.insert(&buf[2]); + s.insert(&buf[3]); + EXPECT_EQ(4U, s.size()); + + i = 0; + for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i) + (**I)++; + EXPECT_EQ(4, i); + for(i=0; i<8; ++i) + EXPECT_EQ(i<4?1:0,buf[i]); + + s.insert(&buf[4]); + s.insert(&buf[5]); + s.insert(&buf[6]); + s.insert(&buf[7]); + + i = 0; + for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i) + (**I)++; + EXPECT_EQ(8, i); + s.erase(&buf[4]); + s.erase(&buf[5]); + s.erase(&buf[6]); + s.erase(&buf[7]); + EXPECT_EQ(4U, s.size()); + + i = 0; + for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i) + (**I)++; + EXPECT_EQ(4, i); + for(i=0; i<8; ++i) + EXPECT_EQ(i<4?3:1,buf[i]); + + s.clear(); + for(i=0; i<8; ++i) buf[i]=0; + for(i=0; i<128; ++i) s.insert(&buf[i%8]); // test repeated entires + EXPECT_EQ(8U, s.size()); + for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i) + (**I)++; + for(i=0; i<8; ++i) + EXPECT_EQ(1,buf[i]); +} + + TEST(SmallPtrSetTest, SwapTest) { int buf[10]; diff --git a/unittests/ADT/SmallStringTest.cpp b/unittests/ADT/SmallStringTest.cpp index 660ac44..9398e99 100644 --- a/unittests/ADT/SmallStringTest.cpp +++ b/unittests/ADT/SmallStringTest.cpp @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" #include "llvm/ADT/SmallString.h" -#include <stdarg.h> +#include "gtest/gtest.h" #include <climits> #include <cstring> +#include <stdarg.h> using namespace llvm; diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index 7fd71f5..90c7982 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" -#include <stdarg.h> +#include "gtest/gtest.h" #include <list> +#include <stdarg.h> using namespace llvm; diff --git a/unittests/ADT/SparseMultiSetTest.cpp b/unittests/ADT/SparseMultiSetTest.cpp new file mode 100644 index 0000000..032990e --- /dev/null +++ b/unittests/ADT/SparseMultiSetTest.cpp @@ -0,0 +1,235 @@ +//===------ 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/SparseMultiSet.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +typedef SparseMultiSet<unsigned> USet; + +// Empty set tests. +TEST(SparseMultiSetTest, EmptySet) { + USet Set; + EXPECT_TRUE(Set.empty()); + 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_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(SparseMultiSetTest, SingleEntrySet) { + USet Set; + Set.setUniverse(10); + USet::iterator I = Set.insert(5); + EXPECT_TRUE(I != Set.end()); + EXPECT_TRUE(*I == 5); + + EXPECT_FALSE(Set.empty()); + EXPECT_EQ(1u, Set.size()); + + EXPECT_TRUE(Set.find(0) == Set.end()); + EXPECT_TRUE(Set.find(9) == Set.end()); + + EXPECT_FALSE(Set.contains(0)); + EXPECT_TRUE(Set.contains(5)); + + // Extra insert. + I = Set.insert(5); + EXPECT_TRUE(I != Set.end()); + EXPECT_TRUE(I == ++Set.find(5)); + I--; + EXPECT_TRUE(I == Set.find(5)); + + // Erase non-existent element. + I = Set.find(1); + EXPECT_TRUE(I == Set.end()); + EXPECT_EQ(2u, Set.size()); + EXPECT_EQ(5u, *Set.find(5)); + + // Erase iterator. + I = Set.find(5); + EXPECT_TRUE(I != Set.end()); + I = Set.erase(I); + EXPECT_TRUE(I != Set.end()); + I = Set.erase(I); + EXPECT_TRUE(I == Set.end()); + EXPECT_TRUE(Set.empty()); +} + +// Multiple entry set tests. +TEST(SparseMultiSetTest, MultipleEntrySet) { + USet Set; + Set.setUniverse(10); + + Set.insert(5); + Set.insert(5); + Set.insert(5); + Set.insert(3); + Set.insert(2); + Set.insert(1); + Set.insert(4); + EXPECT_EQ(7u, Set.size()); + + // Erase last element by key. + EXPECT_TRUE(Set.erase(Set.find(4)) == Set.end()); + EXPECT_EQ(6u, Set.size()); + EXPECT_FALSE(Set.contains(4)); + EXPECT_TRUE(Set.find(4) == Set.end()); + + // Erase first element by key. + EXPECT_EQ(3u, Set.count(5)); + EXPECT_TRUE(Set.find(5) != Set.end()); + EXPECT_TRUE(Set.erase(Set.find(5)) != Set.end()); + EXPECT_EQ(5u, Set.size()); + EXPECT_EQ(2u, Set.count(5)); + + Set.insert(6); + Set.insert(7); + EXPECT_EQ(7u, Set.size()); + + // Erase tail by iterator. + EXPECT_TRUE(Set.getTail(6) == Set.getHead(6)); + USet::iterator I = Set.erase(Set.find(6)); + EXPECT_TRUE(I == Set.end()); + EXPECT_EQ(6u, Set.size()); + + // Erase tails by iterator. + EXPECT_EQ(2u, Set.count(5)); + I = Set.getTail(5); + I = Set.erase(I); + EXPECT_TRUE(I == Set.end()); + --I; + EXPECT_EQ(1u, Set.count(5)); + EXPECT_EQ(5u, *I); + I = Set.erase(I); + EXPECT_TRUE(I == Set.end()); + EXPECT_EQ(0u, Set.count(5)); + + Set.insert(8); + Set.insert(8); + Set.insert(8); + Set.insert(8); + Set.insert(8); + + // Erase all the 8s + EXPECT_EQ(5, std::distance(Set.getHead(8), Set.end())); + Set.eraseAll(8); + EXPECT_EQ(0, std::distance(Set.getHead(8), Set.end())); + + // Clear and resize the universe. + Set.clear(); + EXPECT_EQ(0u, Set.size()); + EXPECT_FALSE(Set.contains(3)); + 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.eraseAll(i); + + for (unsigned i = 100; i != 800; ++i) + EXPECT_EQ(1u, Set.count(i)); + + EXPECT_FALSE(Set.contains(99)); + EXPECT_FALSE(Set.contains(800)); + EXPECT_EQ(700u, Set.size()); +} + +// Test out iterators +TEST(SparseMultiSetTest, Iterators) { + USet Set; + Set.setUniverse(100); + + Set.insert(0); + Set.insert(1); + Set.insert(2); + Set.insert(0); + Set.insert(1); + Set.insert(0); + + USet::RangePair RangePair = Set.equal_range(0); + USet::iterator B = RangePair.first; + USet::iterator E = RangePair.second; + + // Move the iterators around, going to end and coming back. + EXPECT_EQ(3, std::distance(B, E)); + EXPECT_EQ(B, --(--(--E))); + EXPECT_EQ(++(++(++E)), Set.end()); + EXPECT_EQ(B, --(--(--E))); + EXPECT_EQ(++(++(++E)), Set.end()); + + // Insert into the tail, and move around again + Set.insert(0); + EXPECT_EQ(B, --(--(--(--E)))); + EXPECT_EQ(++(++(++(++E))), Set.end()); + EXPECT_EQ(B, --(--(--(--E)))); + EXPECT_EQ(++(++(++(++E))), Set.end()); + + // Erase a tail, and move around again + USet::iterator Erased = Set.erase(Set.getTail(0)); + EXPECT_EQ(Erased, E); + EXPECT_EQ(B, --(--(--E))); + + USet Set2; + Set2.setUniverse(11); + Set2.insert(3); + EXPECT_TRUE(!Set2.contains(0)); + EXPECT_TRUE(!Set.contains(3)); + + EXPECT_EQ(Set2.getHead(3), Set2.getTail(3)); + EXPECT_EQ(Set2.getHead(0), Set2.getTail(0)); + B = Set2.find(3); + EXPECT_EQ(Set2.find(3), --(++B)); +} + +struct Alt { + unsigned Value; + explicit Alt(unsigned x) : Value(x) {} + unsigned getSparseSetIndex() const { return Value - 1000; } +}; + +TEST(SparseMultiSetTest, AltStructSet) { + typedef SparseMultiSet<Alt> ASet; + ASet Set; + Set.setUniverse(10); + Set.insert(Alt(1005)); + + ASet::iterator I = Set.find(5); + ASSERT_TRUE(I != Set.end()); + EXPECT_EQ(1005u, I->Value); + + Set.insert(Alt(1006)); + Set.insert(Alt(1006)); + I = Set.erase(Set.find(6)); + ASSERT_TRUE(I != Set.end()); + EXPECT_EQ(1006u, I->Value); + I = Set.erase(Set.find(6)); + ASSERT_TRUE(I == Set.end()); + + EXPECT_TRUE(Set.contains(5)); + EXPECT_FALSE(Set.contains(6)); +} +} // namespace diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp index ead372f..fa87cd0 100644 --- a/unittests/ADT/StringRefTest.cpp +++ b/unittests/ADT/StringRefTest.cpp @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#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" +#include "gtest/gtest.h" using namespace llvm; namespace llvm { diff --git a/unittests/ADT/TinyPtrVectorTest.cpp b/unittests/ADT/TinyPtrVectorTest.cpp index 05dd797..a4f92ff 100644 --- a/unittests/ADT/TinyPtrVectorTest.cpp +++ b/unittests/ADT/TinyPtrVectorTest.cpp @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/type_traits.h" +#include "gtest/gtest.h" #include <algorithm> #include <list> #include <vector> @@ -157,7 +157,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveCtorTest) { this->expectValues(Copy2, this->testArray(42)); this->expectValues(this->V2, this->testArray(0)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES TypeParam Move(std::move(Copy2)); this->expectValues(Move, this->testArray(42)); this->expectValues(Copy2, this->testArray(0)); @@ -168,7 +168,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(0)); this->expectValues(this->V2, this->testArray(0)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(0)); #endif @@ -177,7 +177,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(0)); this->expectValues(this->V2, this->testArray(0)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(1), this->testArray(0)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(0)); @@ -187,7 +187,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(0)); this->expectValues(this->V2, this->testArray(0)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(2), this->testArray(0)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(0)); @@ -197,7 +197,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(0)); this->expectValues(this->V2, this->testArray(0)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(42), this->testArray(0)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(0)); @@ -207,7 +207,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(1)); this->expectValues(this->V2, this->testArray(1)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(0), this->testArray(1)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(1)); @@ -217,7 +217,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(2)); this->expectValues(this->V2, this->testArray(2)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(0), this->testArray(2)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(2)); @@ -227,7 +227,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(42)); this->expectValues(this->V2, this->testArray(42)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(0), this->testArray(42)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(42)); @@ -237,7 +237,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(1)); this->expectValues(this->V2, this->testArray(1)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(1)); #endif @@ -246,7 +246,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(2)); this->expectValues(this->V2, this->testArray(2)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(1), this->testArray(2)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(2)); @@ -256,7 +256,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(42)); this->expectValues(this->V2, this->testArray(42)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(1), this->testArray(42)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(42)); @@ -266,7 +266,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(1)); this->expectValues(this->V2, this->testArray(1)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(2), this->testArray(1)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(1)); @@ -276,7 +276,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(2)); this->expectValues(this->V2, this->testArray(2)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(2), this->testArray(2)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(2)); @@ -286,7 +286,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(42)); this->expectValues(this->V2, this->testArray(42)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(2), this->testArray(42)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(42)); @@ -296,7 +296,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(1)); this->expectValues(this->V2, this->testArray(1)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(42), this->testArray(1)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(1)); @@ -306,7 +306,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(2)); this->expectValues(this->V2, this->testArray(2)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(42), this->testArray(2)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(2)); @@ -316,7 +316,7 @@ TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { this->V = this->V2; this->expectValues(this->V, this->testArray(42)); this->expectValues(this->V2, this->testArray(42)); -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES this->setVectors(this->testArray(42), this->testArray(42)); this->V = std::move(this->V2); this->expectValues(this->V, this->testArray(42)); diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index 7c3ab97..b402896 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -407,6 +407,11 @@ TEST(TripleTest, getOSVersion) { unsigned Major, Minor, Micro; T = Triple("i386-apple-darwin9"); + EXPECT_TRUE(T.isMacOSX()); + EXPECT_FALSE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); T.getMacOSXVersion(Major, Minor, Micro); EXPECT_EQ((unsigned)10, Major); EXPECT_EQ((unsigned)5, Minor); @@ -417,6 +422,11 @@ TEST(TripleTest, getOSVersion) { EXPECT_EQ((unsigned)0, Micro); T = Triple("x86_64-apple-darwin9"); + EXPECT_TRUE(T.isMacOSX()); + EXPECT_FALSE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); T.getMacOSXVersion(Major, Minor, Micro); EXPECT_EQ((unsigned)10, Major); EXPECT_EQ((unsigned)5, Minor); @@ -427,6 +437,11 @@ TEST(TripleTest, getOSVersion) { EXPECT_EQ((unsigned)0, Micro); T = Triple("x86_64-apple-macosx"); + EXPECT_TRUE(T.isMacOSX()); + EXPECT_FALSE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); T.getMacOSXVersion(Major, Minor, Micro); EXPECT_EQ((unsigned)10, Major); EXPECT_EQ((unsigned)4, Minor); @@ -437,6 +452,11 @@ TEST(TripleTest, getOSVersion) { EXPECT_EQ((unsigned)0, Micro); T = Triple("x86_64-apple-macosx10.7"); + EXPECT_TRUE(T.isMacOSX()); + EXPECT_FALSE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); T.getMacOSXVersion(Major, Minor, Micro); EXPECT_EQ((unsigned)10, Major); EXPECT_EQ((unsigned)7, Minor); @@ -447,6 +467,11 @@ TEST(TripleTest, getOSVersion) { EXPECT_EQ((unsigned)0, Micro); T = Triple("armv7-apple-ios"); + EXPECT_FALSE(T.isMacOSX()); + EXPECT_TRUE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); T.getMacOSXVersion(Major, Minor, Micro); EXPECT_EQ((unsigned)10, Major); EXPECT_EQ((unsigned)4, Minor); @@ -457,6 +482,11 @@ TEST(TripleTest, getOSVersion) { EXPECT_EQ((unsigned)0, Micro); T = Triple("armv7-apple-ios5.0"); + EXPECT_FALSE(T.isMacOSX()); + EXPECT_TRUE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_TRUE(T.isArch32Bit()); + EXPECT_FALSE(T.isArch64Bit()); T.getMacOSXVersion(Major, Minor, Micro); EXPECT_EQ((unsigned)10, Major); EXPECT_EQ((unsigned)4, Minor); diff --git a/unittests/ADT/TwineTest.cpp b/unittests/ADT/TwineTest.cpp index e9cc41d..39d3b56 100644 --- a/unittests/ADT/TwineTest.cpp +++ b/unittests/ADT/TwineTest.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" using namespace llvm; namespace { diff --git a/unittests/ADT/ilistTest.cpp b/unittests/ADT/ilistTest.cpp index 09a699a..0c0cd0f 100644 --- a/unittests/ADT/ilistTest.cpp +++ b/unittests/ADT/ilistTest.cpp @@ -7,10 +7,11 @@ // //===----------------------------------------------------------------------===// -#include <ostream> -#include "gtest/gtest.h" #include "llvm/ADT/ilist.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ilist_node.h" +#include "gtest/gtest.h" +#include <ostream> using namespace llvm; @@ -21,6 +22,7 @@ struct Node : ilist_node<Node> { Node() {} Node(int _Value) : Value(_Value) {} + ~Node() { Value = -1; } }; TEST(ilistTest, Basic) { @@ -41,4 +43,56 @@ TEST(ilistTest, Basic) { EXPECT_EQ(1, ConstList.back().getPrevNode()->Value); } +TEST(ilistTest, SpliceOne) { + ilist<Node> List; + List.push_back(1); + + // The single-element splice operation supports noops. + List.splice(List.begin(), List, List.begin()); + EXPECT_EQ(1u, List.size()); + EXPECT_EQ(1, List.front().Value); + EXPECT_TRUE(llvm::next(List.begin()) == List.end()); + + // Altenative noop. Move the first element behind itself. + List.push_back(2); + List.push_back(3); + List.splice(llvm::next(List.begin()), List, List.begin()); + EXPECT_EQ(3u, List.size()); + EXPECT_EQ(1, List.front().Value); + EXPECT_EQ(2, llvm::next(List.begin())->Value); + EXPECT_EQ(3, List.back().Value); +} + +TEST(ilistTest, UnsafeClear) { + ilist<Node> List; + + // Before even allocating a sentinel. + List.clearAndLeakNodesUnsafely(); + EXPECT_EQ(0u, List.size()); + + // Empty list with sentinel. + ilist<Node>::iterator E = List.end(); + List.clearAndLeakNodesUnsafely(); + EXPECT_EQ(0u, List.size()); + // The sentinel shouldn't change. + EXPECT_TRUE(E == List.end()); + + // List with contents. + List.push_back(1); + ASSERT_EQ(1u, List.size()); + Node *N = List.begin(); + EXPECT_EQ(1, N->Value); + List.clearAndLeakNodesUnsafely(); + EXPECT_EQ(0u, List.size()); + ASSERT_EQ(1, N->Value); + delete N; + + // List is still functional. + List.push_back(5); + List.push_back(6); + ASSERT_EQ(2u, List.size()); + EXPECT_EQ(5, List.front().Value); + EXPECT_EQ(6, List.back().Value); +} + } diff --git a/unittests/Analysis/ScalarEvolutionTest.cpp b/unittests/Analysis/ScalarEvolutionTest.cpp index c30492a..398d09e 100644 --- a/unittests/Analysis/ScalarEvolutionTest.cpp +++ b/unittests/Analysis/ScalarEvolutionTest.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Constants.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/PassManager.h" -#include "llvm/ADT/SmallVector.h" #include "gtest/gtest.h" namespace llvm { diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp index 68cfe28..f33af2f 100644 --- a/unittests/Bitcode/BitReaderTest.cpp +++ b/unittests/Bitcode/BitReaderTest.cpp @@ -11,10 +11,10 @@ #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/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/MemoryBuffer.h" #include "gtest/gtest.h" @@ -45,9 +45,9 @@ static Module *makeLLVMModule() { } static void writeModuleToBuffer(SmallVectorImpl<char> &Buffer) { - Module *Mod = makeLLVMModule(); + OwningPtr<Module> Mod(makeLLVMModule()); raw_svector_ostream OS(Buffer); - WriteBitcodeToFile(Mod, OS); + WriteBitcodeToFile(Mod.get(), OS); } TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 @@ -55,7 +55,7 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677 writeModuleToBuffer(Mem); MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false); std::string errMsg; - Module *m = getLazyBitcodeModule(Buffer, getGlobalContext(), &errMsg); + OwningPtr<Module> m(getLazyBitcodeModule(Buffer, getGlobalContext(), &errMsg)); PassManager passes; passes.add(createVerifierPass()); passes.run(*m); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 84bd444..a3f8bf3 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(ADT) add_subdirectory(Analysis) add_subdirectory(ExecutionEngine) add_subdirectory(Bitcode) +add_subdirectory(Option) add_subdirectory(Support) add_subdirectory(Transforms) -add_subdirectory(VMCore) +add_subdirectory(IR) diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt index ed7f10a..4eefc1e 100644 --- a/unittests/ExecutionEngine/CMakeLists.txt +++ b/unittests/ExecutionEngine/CMakeLists.txt @@ -6,5 +6,9 @@ add_llvm_unittest(ExecutionEngineTests ExecutionEngineTest.cpp ) -add_subdirectory(JIT) -add_subdirectory(MCJIT) +# Include JIT/MCJIT tests only if native arch is a JIT target. +list(FIND LLVM_TARGETS_WITH_JIT "${LLVM_NATIVE_ARCH}" have_jit) +if (NOT have_jit EQUAL -1 ) + add_subdirectory(JIT) + add_subdirectory(MCJIT) +endif() diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp index 74a2ccd..3e304e7 100644 --- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp +++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DerivedTypes.h" -#include "llvm/GlobalVariable.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ExecutionEngine/Interpreter.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/ExecutionEngine/JIT/CMakeLists.txt b/unittests/ExecutionEngine/JIT/CMakeLists.txt index 11cf784..ef37026 100644 --- a/unittests/ExecutionEngine/JIT/CMakeLists.txt +++ b/unittests/ExecutionEngine/JIT/CMakeLists.txt @@ -19,7 +19,9 @@ if( LLVM_USE_INTEL_JITEVENTS ) ) set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} + DebugInfo IntelJITEvents + Object ) endif( LLVM_USE_INTEL_JITEVENTS ) @@ -53,3 +55,4 @@ add_llvm_unittest(JITTests if(MINGW OR CYGWIN) set_property(TARGET JITTests PROPERTY LINK_FLAGS -Wl,--export-all-symbols) endif() +set_target_properties(JITTests PROPERTIES ENABLE_EXPORTS 1) diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp index 333888a..6ba8bc4 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp @@ -8,14 +8,13 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/JITEventListener.h" - -#include "llvm/LLVMContext.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/TypeBuilder.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/ExecutionEngine/JIT.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" #include <vector> diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h index 5f02b38..d1c2124 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h @@ -10,24 +10,22 @@ #ifndef JIT_EVENT_LISTENER_TEST_COMMON_H #define JIT_EVENT_LISTENER_TEST_COMMON_H +#include "llvm/CodeGen/MachineCodeInfo.h" +#include "llvm/Config/config.h" #include "llvm/DIBuilder.h" #include "llvm/DebugInfo.h" -#include "llvm/IRBuilder.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/TypeBuilder.h" -#include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/JITEventListener.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/Config/config.h" - #include "gtest/gtest.h" - -#include <vector> #include <string> #include <utility> +#include <vector> typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations; typedef std::map<uint64_t, SourceLocations> NativeCodeMap; diff --git a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp index be5d152..21ca0d4 100644 --- a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp @@ -7,14 +7,14 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalValue.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/LLVMContext.h" +#include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index 59604df..30dadc9 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -7,28 +7,27 @@ // //===----------------------------------------------------------------------===// -#include "llvm/BasicBlock.h" -#include "llvm/Constant.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalValue.h" -#include "llvm/GlobalVariable.h" -#include "llvm/IRBuilder.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/TypeBuilder.h" +#include "llvm/ExecutionEngine/JIT.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Assembly/Parser.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" - #include "gtest/gtest.h" #include <vector> @@ -118,13 +117,14 @@ public: Base->endFunctionBody(F, FunctionStart, FunctionEnd); } virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) { - return Base->allocateDataSection(Size, Alignment, SectionID); + unsigned SectionID, bool IsReadOnly) { + return Base->allocateDataSection(Size, Alignment, SectionID, IsReadOnly); } virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { return Base->allocateCodeSection(Size, Alignment, SectionID); } + virtual bool applyPermissions(std::string *ErrMsg) { return false; } virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { return Base->allocateSpace(Size, Alignment); } @@ -161,7 +161,7 @@ public: uintptr_t ActualSizeResult; }; std::vector<StartExceptionTableCall> startExceptionTableCalls; - virtual uint8_t* startExceptionTable(const Function* F, + virtual uint8_t *startExceptionTable(const Function *F, uintptr_t &ActualSize) { uintptr_t InitialActualSize = ActualSize; uint8_t *Result = Base->startExceptionTable(F, ActualSize); @@ -203,14 +203,21 @@ bool LoadAssemblyInto(Module *M, const char *assembly) { class JITTest : public testing::Test { protected: + virtual RecordingJITMemoryManager *createMemoryManager() { + return new RecordingJITMemoryManager; + } + virtual void SetUp() { M = new Module("<main>", Context); - RJMM = new RecordingJITMemoryManager; + RJMM = createMemoryManager(); RJMM->setPoisonMemory(true); std::string Error; + TargetOptions Options; + Options.JITExceptionHandling = true; TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT) .setJITMemoryManager(RJMM) - .setErrorStr(&Error).create()); + .setErrorStr(&Error) + .setTargetOptions(Options).create()); ASSERT_TRUE(TheJIT.get() != NULL) << Error; } @@ -297,6 +304,46 @@ TEST(JIT, GlobalInFunction) { #endif // !defined(__arm__) && !defined(__powerpc__) +// Regression test for a bug. The JITEmitter wasn't checking to verify that +// it hadn't run out of space while generating the DWARF exception information +// for an emitted function. + +class ExceptionMemoryManagerMock : public RecordingJITMemoryManager { + public: + virtual uint8_t *startExceptionTable(const Function *F, + uintptr_t &ActualSize) { + // force an insufficient size the first time through. + bool ChangeActualSize = false; + if (ActualSize == 0) + ChangeActualSize = true;; + uint8_t *result = + RecordingJITMemoryManager::startExceptionTable(F, ActualSize); + if (ChangeActualSize) + ActualSize = 1; + return result; + } +}; + +class JITExceptionMemoryTest : public JITTest { + protected: + virtual RecordingJITMemoryManager *createMemoryManager() { + return new ExceptionMemoryManagerMock; + } +}; + +TEST_F(JITExceptionMemoryTest, ExceptionTableOverflow) { + Function *F = Function::Create(TypeBuilder<void(void), false>::get(Context), + Function::ExternalLinkage, + "func1", M); + BasicBlock *Block = BasicBlock::Create(Context, "block", F); + IRBuilder<> Builder(Block); + Builder.CreateRetVoid(); + TheJIT->getPointerToFunction(F); + ASSERT_TRUE(RJMM->startExceptionTableCalls.size() == 2); + ASSERT_TRUE(RJMM->deallocateExceptionTableCalls.size() == 1); + ASSERT_TRUE(RJMM->endExceptionTableCalls.size() == 1); +} + int PlusOne(int arg) { return arg + 1; } diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile index 9e0bb9e..ef8b827 100644 --- a/unittests/ExecutionEngine/JIT/Makefile +++ b/unittests/ExecutionEngine/JIT/Makefile @@ -24,7 +24,7 @@ ifeq ($(USE_INTEL_JITEVENTS), 1) CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR) # Link against the LLVM Intel JIT Evens interface library - LINK_COMPONENTS += inteljitevents + LINK_COMPONENTS += debuginfo inteljitevents object endif ifeq ($(USE_OPROFILE), 1) diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp index 4a22e2f..5301467 100644 --- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp +++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/ExecutionEngine/JIT.h" #include "llvm/Assembly/Parser.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/JIT.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Support/SourceMgr.h" +#include "gtest/gtest.h" #include <vector> using namespace llvm; diff --git a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp index 9b0ee60..7057fca 100644 --- a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp +++ b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp @@ -7,12 +7,11 @@ // //===--------------------------------------------------------------------------------------===// -#include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/OProfileWrapper.h" #include "JITEventListenerTestCommon.h" - -#include <map> +#include "llvm/ExecutionEngine/JITEventListener.h" #include <list> +#include <map> using namespace llvm; diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt index 3e9c5b6..c6b1f77 100644 --- a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt +++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt @@ -2,14 +2,14 @@ set(LLVM_LINK_COMPONENTS asmparser bitreader bitwriter - mcjit jit + mcjit nativecodegen ) set(MCJITTestsSources MCJITTest.cpp - SectionMemoryManager.cpp + MCJITMemoryManagerTest.cpp ) if(MSVC) diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp new file mode 100644 index 0000000..ab09aca --- /dev/null +++ b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp @@ -0,0 +1,172 @@ +//===- MCJITMemoryManagerTest.cpp - Unit tests for the JIT memory manager -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/SectionMemoryManager.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(MCJITMemoryManagerTest, BasicAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t *code1 = MemMgr->allocateCodeSection(256, 0, 1);
+ uint8_t *data1 = MemMgr->allocateDataSection(256, 0, 2, true);
+ uint8_t *code2 = MemMgr->allocateCodeSection(256, 0, 3);
+ uint8_t *data2 = MemMgr->allocateDataSection(256, 0, 4, false);
+
+ EXPECT_NE((uint8_t*)0, code1);
+ EXPECT_NE((uint8_t*)0, code2);
+ EXPECT_NE((uint8_t*)0, data1);
+ EXPECT_NE((uint8_t*)0, data2);
+
+ // Initialize the data
+ for (unsigned i = 0; i < 256; ++i) {
+ code1[i] = 1;
+ code2[i] = 2;
+ data1[i] = 3;
+ data2[i] = 4;
+ }
+
+ // Verify the data (this is checking for overlaps in the addresses)
+ for (unsigned i = 0; i < 256; ++i) {
+ EXPECT_EQ(1, code1[i]);
+ EXPECT_EQ(2, code2[i]);
+ EXPECT_EQ(3, data1[i]);
+ EXPECT_EQ(4, data2[i]);
+ }
+
+ std::string Error;
+ EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+}
+
+TEST(MCJITMemoryManagerTest, LargeAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t *code1 = MemMgr->allocateCodeSection(0x100000, 0, 1);
+ uint8_t *data1 = MemMgr->allocateDataSection(0x100000, 0, 2, true);
+ uint8_t *code2 = MemMgr->allocateCodeSection(0x100000, 0, 3);
+ uint8_t *data2 = MemMgr->allocateDataSection(0x100000, 0, 4, false);
+
+ EXPECT_NE((uint8_t*)0, code1);
+ EXPECT_NE((uint8_t*)0, code2);
+ EXPECT_NE((uint8_t*)0, data1);
+ EXPECT_NE((uint8_t*)0, data2);
+
+ // Initialize the data
+ for (unsigned i = 0; i < 0x100000; ++i) {
+ code1[i] = 1;
+ code2[i] = 2;
+ data1[i] = 3;
+ data2[i] = 4;
+ }
+
+ // Verify the data (this is checking for overlaps in the addresses)
+ for (unsigned i = 0; i < 0x100000; ++i) {
+ EXPECT_EQ(1, code1[i]);
+ EXPECT_EQ(2, code2[i]);
+ EXPECT_EQ(3, data1[i]);
+ EXPECT_EQ(4, data2[i]);
+ }
+
+ std::string Error;
+ EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+}
+
+TEST(MCJITMemoryManagerTest, ManyAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t* code[10000];
+ uint8_t* data[10000];
+
+ for (unsigned i = 0; i < 10000; ++i) {
+ const bool isReadOnly = i % 2 == 0;
+
+ code[i] = MemMgr->allocateCodeSection(32, 0, 1);
+ data[i] = MemMgr->allocateDataSection(32, 0, 2, isReadOnly);
+
+ for (unsigned j = 0; j < 32; j++) {
+ code[i][j] = 1 + (i % 254);
+ data[i][j] = 2 + (i % 254);
+ }
+
+ EXPECT_NE((uint8_t *)0, code[i]);
+ EXPECT_NE((uint8_t *)0, data[i]);
+ }
+
+ // Verify the data (this is checking for overlaps in the addresses)
+ for (unsigned i = 0; i < 10000; ++i) {
+ for (unsigned j = 0; j < 32;j++ ) {
+ uint8_t ExpectedCode = 1 + (i % 254);
+ uint8_t ExpectedData = 2 + (i % 254);
+ EXPECT_EQ(ExpectedCode, code[i][j]);
+ EXPECT_EQ(ExpectedData, data[i][j]);
+ }
+ }
+
+ std::string Error;
+ EXPECT_FALSE(MemMgr->applyPermissions(&Error));
+}
+
+TEST(MCJITMemoryManagerTest, ManyVariedAllocations) {
+ OwningPtr<SectionMemoryManager> MemMgr(new SectionMemoryManager());
+
+ uint8_t* code[10000];
+ uint8_t* data[10000];
+
+ for (unsigned i = 0; i < 10000; ++i) {
+ uintptr_t CodeSize = i % 16 + 1;
+ uintptr_t DataSize = i % 8 + 1;
+
+ bool isReadOnly = i % 3 == 0;
+ unsigned Align = 8 << (i % 4);
+
+ code[i] = MemMgr->allocateCodeSection(CodeSize, Align, i);
+ data[i] = MemMgr->allocateDataSection(DataSize, Align, i + 10000,
+ isReadOnly);
+
+ for (unsigned j = 0; j < CodeSize; j++) {
+ code[i][j] = 1 + (i % 254);
+ }
+
+ for (unsigned j = 0; j < DataSize; j++) {
+ data[i][j] = 2 + (i % 254);
+ }
+
+ EXPECT_NE((uint8_t *)0, code[i]);
+ EXPECT_NE((uint8_t *)0, data[i]);
+
+ uintptr_t CodeAlign = Align ? (uintptr_t)code[i] % Align : 0;
+ uintptr_t DataAlign = Align ? (uintptr_t)data[i] % Align : 0;
+
+ EXPECT_EQ((uintptr_t)0, CodeAlign);
+ EXPECT_EQ((uintptr_t)0, DataAlign);
+ }
+
+ for (unsigned i = 0; i < 10000; ++i) {
+ uintptr_t CodeSize = i % 16 + 1;
+ uintptr_t DataSize = i % 8 + 1;
+
+ for (unsigned j = 0; j < CodeSize; j++) {
+ uint8_t ExpectedCode = 1 + (i % 254);
+ EXPECT_EQ(ExpectedCode, code[i][j]);
+ }
+
+ for (unsigned j = 0; j < DataSize; j++) {
+ uint8_t ExpectedData = 2 + (i % 254);
+ EXPECT_EQ(ExpectedData, data[i][j]);
+ }
+ }
+}
+
+} // Namespace
+
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp index 6b79a68..e9cf904 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp +++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp @@ -14,7 +14,6 @@ #include "llvm/ExecutionEngine/MCJIT.h" #include "MCJITTestBase.h" -#include "SectionMemoryManager.h" #include "gtest/gtest.h" using namespace llvm; @@ -47,6 +46,7 @@ TEST_F(MCJITTest, global_variable) { GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue); createJIT(M.take()); void *globalPtr = TheJIT->getPointerToGlobal(Global); + MM->applyPermissions(); static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); EXPECT_TRUE(0 != globalPtr) << "Unable to get pointer to global value from JIT"; @@ -61,6 +61,7 @@ TEST_F(MCJITTest, add_function) { Function *F = insertAddFunction(M.get()); createJIT(M.take()); void *addPtr = TheJIT->getPointerToFunction(F); + MM->applyPermissions(); static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); EXPECT_TRUE(0 != addPtr) << "Unable to get pointer to function from JIT"; @@ -78,6 +79,7 @@ TEST_F(MCJITTest, run_main) { Function *Main = insertMainFunction(M.get(), 6); createJIT(M.take()); void *vPtr = TheJIT->getPointerToFunction(Main); + MM->applyPermissions(); static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); EXPECT_TRUE(0 != vPtr) << "Unable to get pointer to main() from JIT"; @@ -100,6 +102,7 @@ TEST_F(MCJITTest, return_global) { createJIT(M.take()); void *rgvPtr = TheJIT->getPointerToFunction(ReturnGlobal); + MM->applyPermissions(); static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); EXPECT_TRUE(0 != rgvPtr); @@ -169,6 +172,7 @@ TEST_F(MCJITTest, multiple_functions) { createJIT(M.take()); void *vPtr = TheJIT->getPointerToFunction(Outer); + MM->applyPermissions(); static_cast<SectionMemoryManager*>(MM)->invalidateInstructionCache(); EXPECT_TRUE(0 != vPtr) << "Unable to get pointer to outer function from JIT"; diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h index 9b4a4ac..fc774ab 100644 --- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h +++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h @@ -17,20 +17,19 @@ #ifndef MCJIT_TEST_BASE_H #define MCJIT_TEST_BASE_H -#include "llvm/ADT/Triple.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/Config/config.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/Function.h" -#include "llvm/IRBuilder.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/ExecutionEngine/SectionMemoryManager.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetSelect.h" -#include "llvm/TypeBuilder.h" - -#include "SectionMemoryManager.h" // Used to skip tests on unsupported architectures and operating systems. // To skip a test, add this macro at the top of a test-case in a suite that @@ -53,7 +52,7 @@ protected: , MArch("") , Builder(Context) , MM(new SectionMemoryManager) - , HostTriple(LLVM_HOSTTRIPLE) + , HostTriple(sys::getProcessTriple()) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp deleted file mode 100644 index d6baf3c..0000000 --- a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp +++ /dev/null @@ -1,143 +0,0 @@ -//===-- SectionMemoryManager.cpp - The memory manager for MCJIT -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the implementation of the section-based memory manager -// used by MCJIT. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" -#include "llvm/Support/DynamicLibrary.h" -#include "llvm/Support/MathExtras.h" - -#include "SectionMemoryManager.h" - -#ifdef __linux__ -// These includes used by SectionMemoryManager::getPointerToNamedFunction() -// for Glibc trickery. Look comments in this function for more information. -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#include <fcntl.h> -#include <unistd.h> -#endif - -namespace llvm { - -uint8_t *SectionMemoryManager::allocateDataSection(uintptr_t Size, - unsigned Alignment, - unsigned SectionID) { - if (!Alignment) - Alignment = 16; - // Ensure that enough memory is requested to allow aligning. - size_t NumElementsAligned = 1 + (Size + Alignment - 1)/Alignment; - uint8_t *Addr = (uint8_t*)calloc(NumElementsAligned, Alignment); - - // Honour the alignment requirement. - uint8_t *AlignedAddr = (uint8_t*)RoundUpToAlignment((uint64_t)Addr, Alignment); - - // Store the original address from calloc so we can free it later. - AllocatedDataMem.push_back(sys::MemoryBlock(Addr, NumElementsAligned*Alignment)); - return AlignedAddr; -} - -uint8_t *SectionMemoryManager::allocateCodeSection(uintptr_t Size, - unsigned Alignment, - unsigned SectionID) { - if (!Alignment) - Alignment = 16; - unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1); - uintptr_t Addr = 0; - // Look in the list of free code memory regions and use a block there if one - // is available. - for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) { - sys::MemoryBlock &MB = FreeCodeMem[i]; - if (MB.size() >= NeedAllocate) { - Addr = (uintptr_t)MB.base(); - uintptr_t EndOfBlock = Addr + MB.size(); - // Align the address. - Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); - // Store cutted free memory block. - FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size), - EndOfBlock - Addr - Size); - return (uint8_t*)Addr; - } - } - - // No pre-allocated free block was large enough. Allocate a new memory region. - sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0); - - AllocatedCodeMem.push_back(MB); - Addr = (uintptr_t)MB.base(); - uintptr_t EndOfBlock = Addr + MB.size(); - // Align the address. - Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); - // The AllocateRWX may allocate much more memory than we need. In this case, - // we store the unused memory as a free memory block. - unsigned FreeSize = EndOfBlock-Addr-Size; - if (FreeSize > 16) - FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize)); - - // Return aligned address - return (uint8_t*)Addr; -} - -void SectionMemoryManager::invalidateInstructionCache() { - for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i) - sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(), - AllocatedCodeMem[i].size()); -} - -void *SectionMemoryManager::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure) { -#if defined(__linux__) - //===--------------------------------------------------------------------===// - // Function stubs that are invoked instead of certain library calls - // - // Force the following functions to be linked in to anything that uses the - // JIT. This is a hack designed to work around the all-too-clever Glibc - // strategy of making these functions work differently when inlined vs. when - // not inlined, and hiding their real definitions in a separate archive file - // that the dynamic linker can't see. For more info, search for - // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274. - if (Name == "stat") return (void*)(intptr_t)&stat; - if (Name == "fstat") return (void*)(intptr_t)&fstat; - if (Name == "lstat") return (void*)(intptr_t)&lstat; - if (Name == "stat64") return (void*)(intptr_t)&stat64; - if (Name == "fstat64") return (void*)(intptr_t)&fstat64; - if (Name == "lstat64") return (void*)(intptr_t)&lstat64; - if (Name == "atexit") return (void*)(intptr_t)&atexit; - if (Name == "mknod") return (void*)(intptr_t)&mknod; -#endif // __linux__ - - const char *NameStr = Name.c_str(); - void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); - if (Ptr) return Ptr; - - // If it wasn't found and if it starts with an underscore ('_') character, - // try again without the underscore. - if (NameStr[0] == '_') { - Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1); - if (Ptr) return Ptr; - } - - if (AbortOnFailure) - report_fatal_error("Program used external function '" + Name + - "' which could not be resolved!"); - return 0; -} - -SectionMemoryManager::~SectionMemoryManager() { - for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i) - sys::Memory::ReleaseRWX(AllocatedCodeMem[i]); - for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i) - free(AllocatedDataMem[i].base()); -} - -} // namespace llvm diff --git a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h b/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h deleted file mode 100644 index e44217c..0000000 --- a/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h +++ /dev/null @@ -1,118 +0,0 @@ -//===-- SectionMemoryManager.h - Memory allocator for MCJIT -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of a section-based memory manager used by -// the MCJIT execution engine. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H -#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Memory.h" - -namespace llvm { - -// Section-based memory manager for MCJIT -class SectionMemoryManager : public JITMemoryManager { - -public: - - SectionMemoryManager() { } - ~SectionMemoryManager(); - - virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID); - - virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID); - - virtual void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); - - // Invalidate instruction cache for code sections. Some platforms with - // separate data cache and instruction cache require explicit cache flush, - // otherwise JIT code manipulations (like resolved relocations) will get to - // the data cache but not to the instruction cache. - virtual void invalidateInstructionCache(); - -private: - - SmallVector<sys::MemoryBlock, 16> AllocatedDataMem; - SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem; - SmallVector<sys::MemoryBlock, 16> FreeCodeMem; - -public: - - /// - /// Functions below are not used by MCJIT, but must be implemented because - /// they are declared as pure virtuals in the base class. - /// - - virtual void setMemoryWritable() { - llvm_unreachable("Unexpected call!"); - } - virtual void setMemoryExecutable() { - llvm_unreachable("Unexpected call!"); - } - virtual void setPoisonMemory(bool poison) { - llvm_unreachable("Unexpected call!"); - } - virtual void AllocateGOT() { - llvm_unreachable("Unexpected call!"); - } - virtual uint8_t *getGOTBase() const { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual uint8_t *startFunctionBody(const Function *F, - uintptr_t &ActualSize){ - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd) { - llvm_unreachable("Unexpected call!"); - } - virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void deallocateFunctionBody(void *Body) { - llvm_unreachable("Unexpected call!"); - } - virtual uint8_t *startExceptionTable(const Function *F, - uintptr_t &ActualSize) { - llvm_unreachable("Unexpected call!"); - return 0; - } - virtual void endExceptionTable(const Function *F, uint8_t *TableStart, - uint8_t *TableEnd, uint8_t *FrameRegister) { - llvm_unreachable("Unexpected call!"); - } - virtual void deallocateExceptionTable(void *ET) { - llvm_unreachable("Unexpected call!"); - } -}; - -} - -#endif // LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile index ca11956..c779a6a 100644 --- a/unittests/ExecutionEngine/Makefile +++ b/unittests/ExecutionEngine/Makefile @@ -10,7 +10,10 @@ LEVEL = ../.. TESTNAME = ExecutionEngine LINK_COMPONENTS :=interpreter -PARALLEL_DIRS = JIT MCJIT + +ifeq ($(TARGET_HAS_JIT),1) + PARALLEL_DIRS = JIT MCJIT +endif include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/IR/AttributesTest.cpp b/unittests/IR/AttributesTest.cpp new file mode 100644 index 0000000..2368bdf --- /dev/null +++ b/unittests/IR/AttributesTest.cpp @@ -0,0 +1,34 @@ +//===- llvm/unittest/IR/AttributesTest.cpp - Attributes 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/IR/Attributes.h" +#include "llvm/IR/LLVMContext.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(Attributes, Uniquing) { + LLVMContext C; + + Attribute AttrA = Attribute::get(C, Attribute::AlwaysInline); + Attribute AttrB = Attribute::get(C, Attribute::AlwaysInline); + EXPECT_EQ(AttrA, AttrB); + + AttributeSet ASs[] = { + AttributeSet::get(C, 1, Attribute::ZExt), + AttributeSet::get(C, 2, Attribute::SExt) + }; + + AttributeSet SetA = AttributeSet::get(C, ASs); + AttributeSet SetB = AttributeSet::get(C, ASs); + EXPECT_EQ(SetA, SetB); +} + +} // end anonymous namespace diff --git a/unittests/VMCore/CMakeLists.txt b/unittests/IR/CMakeLists.txt index 4025c7a..aed4597 100644 --- a/unittests/VMCore/CMakeLists.txt +++ b/unittests/IR/CMakeLists.txt @@ -4,7 +4,8 @@ set(LLVM_LINK_COMPONENTS ipa ) -set(VMCoreSources +set(IRSources + AttributesTest.cpp ConstantsTest.cpp DominatorTreeTest.cpp IRBuilderTest.cpp @@ -16,12 +17,13 @@ set(VMCoreSources TypesTest.cpp ValueMapTest.cpp VerifierTest.cpp + WaymarkTest.cpp ) # MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug. # See issue#331418 in Visual Studio. if(MSVC AND MSVC_VERSION LESS 1600) - list(REMOVE_ITEM VMCoreSources ValueMapTest.cpp) + list(REMOVE_ITEM IRSources ValueMapTest.cpp) endif() # HACK: Declare a couple of source files as optionally compiled to satisfy the @@ -30,6 +32,6 @@ set(LLVM_OPTIONAL_SOURCES ValueMapTest.cpp ) -add_llvm_unittest(VMCoreTests - ${VMCoreSources} +add_llvm_unittest(IRTests + ${IRSources} ) diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp new file mode 100644 index 0000000..fee38b8 --- /dev/null +++ b/unittests/IR/ConstantsTest.cpp @@ -0,0 +1,260 @@ +//===- llvm/unittest/IR/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/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "gtest/gtest.h" + +namespace llvm { +namespace { + +TEST(ConstantsTest, Integer_i1) { + IntegerType* Int1 = IntegerType::get(getGlobalContext(), 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) { + IntegerType* Int8Ty = Type::getInt8Ty(getGlobalContext()); + 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()); +} + +TEST(ConstantsTest, FP128Test) { + Type *FP128Ty = Type::getFP128Ty(getGlobalContext()); + + IntegerType *Int128Ty = Type::getIntNTy(getGlobalContext(), 128); + Constant *Zero128 = Constant::getNullValue(Int128Ty); + Constant *X = ConstantExpr::getUIToFP(Zero128, FP128Ty); + EXPECT_TRUE(isa<ConstantFP>(X)); +} + +TEST(ConstantsTest, PointerCast) { + LLVMContext &C(getGlobalContext()); + Type *Int8PtrTy = Type::getInt8PtrTy(C); + Type *Int32PtrTy = Type::getInt32PtrTy(C); + Type *Int64Ty = Type::getInt64Ty(C); + VectorType *Int8PtrVecTy = VectorType::get(Int8PtrTy, 4); + VectorType *Int32PtrVecTy = VectorType::get(Int32PtrTy, 4); + VectorType *Int64VecTy = VectorType::get(Int64Ty, 4); + + // ptrtoint i8* to i64 + EXPECT_EQ(Constant::getNullValue(Int64Ty), + ConstantExpr::getPointerCast( + Constant::getNullValue(Int8PtrTy), Int64Ty)); + + // bitcast i8* to i32* + EXPECT_EQ(Constant::getNullValue(Int32PtrTy), + ConstantExpr::getPointerCast( + Constant::getNullValue(Int8PtrTy), Int32PtrTy)); + + // ptrtoint <4 x i8*> to <4 x i64> + EXPECT_EQ(Constant::getNullValue(Int64VecTy), + ConstantExpr::getPointerCast( + Constant::getNullValue(Int8PtrVecTy), Int64VecTy)); + + // bitcast <4 x i8*> to <4 x i32*> + EXPECT_EQ(Constant::getNullValue(Int32PtrVecTy), + ConstantExpr::getPointerCast( + Constant::getNullValue(Int8PtrVecTy), Int32PtrVecTy)); +} + +#define CHECK(x, y) { \ + std::string __s; \ + raw_string_ostream __o(__s); \ + Instruction *__I = cast<ConstantExpr>(x)->getAsInstruction(); \ + __I->print(__o); \ + delete __I; \ + __o.flush(); \ + EXPECT_EQ(std::string(" <badref> = " y), __s); \ + } + +TEST(ConstantsTest, AsInstructionsTest) { + OwningPtr<Module> M(new Module("MyModule", getGlobalContext())); + + Type *Int64Ty = Type::getInt64Ty(getGlobalContext()); + Type *Int32Ty = Type::getInt32Ty(getGlobalContext()); + Type *Int16Ty = Type::getInt16Ty(getGlobalContext()); + Type *Int1Ty = Type::getInt1Ty(getGlobalContext()); + Type *FloatTy = Type::getFloatTy(getGlobalContext()); + Type *DoubleTy = Type::getDoubleTy(getGlobalContext()); + + Constant *Global = M->getOrInsertGlobal("dummy", + PointerType::getUnqual(Int32Ty)); + Constant *Global2 = M->getOrInsertGlobal("dummy2", + PointerType::getUnqual(Int32Ty)); + + Constant *P0 = ConstantExpr::getPtrToInt(Global, Int32Ty); + Constant *P1 = ConstantExpr::getUIToFP(P0, FloatTy); + Constant *P2 = ConstantExpr::getUIToFP(P0, DoubleTy); + Constant *P3 = ConstantExpr::getTrunc(P0, Int1Ty); + Constant *P4 = ConstantExpr::getPtrToInt(Global2, Int32Ty); + Constant *P5 = ConstantExpr::getUIToFP(P4, FloatTy); + Constant *P6 = ConstantExpr::getBitCast(P4, VectorType::get(Int16Ty, 2)); + + Constant *One = ConstantInt::get(Int32Ty, 1); + + #define P0STR "ptrtoint (i32** @dummy to i32)" + #define P1STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to float)" + #define P2STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to double)" + #define P3STR "ptrtoint (i32** @dummy to i1)" + #define P4STR "ptrtoint (i32** @dummy2 to i32)" + #define P5STR "uitofp (i32 ptrtoint (i32** @dummy2 to i32) to float)" + #define P6STR "bitcast (i32 ptrtoint (i32** @dummy2 to i32) to <2 x i16>)" + + CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR); + CHECK(ConstantExpr::getFNeg(P1), "fsub float -0.000000e+00, " P1STR); + CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1"); + CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getAdd(P0, P0, false, true), "add nsw i32 " P0STR ", " + P0STR); + CHECK(ConstantExpr::getAdd(P0, P0, true, true), "add nuw nsw i32 " P0STR ", " + P0STR); + CHECK(ConstantExpr::getFAdd(P1, P1), "fadd float " P1STR ", " P1STR); + CHECK(ConstantExpr::getSub(P0, P0), "sub i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getFSub(P1, P1), "fsub float " P1STR ", " P1STR); + CHECK(ConstantExpr::getMul(P0, P0), "mul i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getFMul(P1, P1), "fmul float " P1STR ", " P1STR); + CHECK(ConstantExpr::getUDiv(P0, P0), "udiv i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getSDiv(P0, P0), "sdiv i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getFDiv(P1, P1), "fdiv float " P1STR ", " P1STR); + CHECK(ConstantExpr::getURem(P0, P0), "urem i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getSRem(P0, P0), "srem i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getFRem(P1, P1), "frem float " P1STR ", " P1STR); + CHECK(ConstantExpr::getAnd(P0, P0), "and i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getOr(P0, P0), "or i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getXor(P0, P0), "xor i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getShl(P0, P0), "shl i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getShl(P0, P0, true), "shl nuw i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getShl(P0, P0, false, true), "shl nsw i32 " P0STR ", " + P0STR); + CHECK(ConstantExpr::getLShr(P0, P0, false), "lshr i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getLShr(P0, P0, true), "lshr exact i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getAShr(P0, P0, false), "ashr i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getAShr(P0, P0, true), "ashr exact i32 " P0STR ", " P0STR); + + CHECK(ConstantExpr::getSExt(P0, Int64Ty), "sext i32 " P0STR " to i64"); + CHECK(ConstantExpr::getZExt(P0, Int64Ty), "zext i32 " P0STR " to i64"); + CHECK(ConstantExpr::getFPTrunc(P2, FloatTy), "fptrunc double " P2STR + " to float"); + CHECK(ConstantExpr::getFPExtend(P1, DoubleTy), "fpext float " P1STR + " to double"); + + CHECK(ConstantExpr::getExactUDiv(P0, P0), "udiv exact i32 " P0STR ", " P0STR); + + CHECK(ConstantExpr::getSelect(P3, P0, P4), "select i1 " P3STR ", i32 " P0STR + ", i32 " P4STR); + CHECK(ConstantExpr::getICmp(CmpInst::ICMP_EQ, P0, P4), "icmp eq i32 " P0STR + ", " P4STR); + CHECK(ConstantExpr::getFCmp(CmpInst::FCMP_ULT, P1, P5), "fcmp ult float " + P1STR ", " P5STR); + + std::vector<Constant*> V; + V.push_back(One); + // FIXME: getGetElementPtr() actually creates an inbounds ConstantGEP, + // not a normal one! + //CHECK(ConstantExpr::getGetElementPtr(Global, V, false), + // "getelementptr i32** @dummy, i32 1"); + CHECK(ConstantExpr::getInBoundsGetElementPtr(Global, V), + "getelementptr inbounds i32** @dummy, i32 1"); + + CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> " + P6STR ", i32 1"); +} + +#undef CHECK + +} // end anonymous namespace +} // end namespace llvm diff --git a/unittests/VMCore/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp index f6a9060..4e5af93 100644 --- a/unittests/VMCore/DominatorTreeTest.cpp +++ b/unittests/IR/DominatorTreeTest.cpp @@ -1,9 +1,18 @@ -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" +//===- llvm/unittests/IR/DominatorTreeTest.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/Analysis/Dominators.h" #include "llvm/Assembly/Parser.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/PassManager.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" @@ -182,7 +191,7 @@ namespace llvm { TEST(DominatorTree, Unreachable) { DPass *P = new DPass(); - Module *M = makeLLVMModule(P); + OwningPtr<Module> M(makeLLVMModule(P)); PassManager Passes; Passes.add(P); Passes.run(*M); diff --git a/unittests/VMCore/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp index 9f26936..fecc4a4 100644 --- a/unittests/VMCore/IRBuilderTest.cpp +++ b/unittests/IR/IRBuilderTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/VMCore/IRBuilderTest.cpp - IRBuilder tests -----------===// +//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===// // // The LLVM Compiler Infrastructure // @@ -7,16 +7,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/BasicBlock.h" -#include "llvm/DataLayout.h" -#include "llvm/Function.h" -#include "llvm/IRBuilder.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/LLVMContext.h" -#include "llvm/MDBuilder.h" -#include "llvm/Module.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/ADT/OwningPtr.h" - +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Module.h" #include "gtest/gtest.h" using namespace llvm; @@ -31,6 +30,8 @@ protected: /*isVarArg=*/false); F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); BB = BasicBlock::Create(getGlobalContext(), "", F); + GV = new GlobalVariable(*M, Type::getFloatTy(getGlobalContext()), true, + GlobalValue::ExternalLinkage, 0); } virtual void TearDown() { @@ -41,6 +42,7 @@ protected: OwningPtr<Module> M; Function *F; BasicBlock *BB; + GlobalVariable *GV; }; TEST_F(IRBuilderTest, Lifetime) { @@ -97,6 +99,13 @@ TEST_F(IRBuilderTest, CreateCondBr) { EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof)); } +TEST_F(IRBuilderTest, LandingPadName) { + IRBuilder<> Builder(BB); + LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(), + Builder.getInt32(0), 0, "LP"); + EXPECT_EQ(LP->getName(), "LP"); +} + TEST_F(IRBuilderTest, GetIntTy) { IRBuilder<> Builder(BB); IntegerType *Ty1 = Builder.getInt1Ty(); @@ -106,6 +115,71 @@ TEST_F(IRBuilderTest, GetIntTy) { IntegerType *IntPtrTy = Builder.getIntPtrTy(DL); unsigned IntPtrBitSize = DL->getPointerSizeInBits(0); EXPECT_EQ(IntPtrTy, IntegerType::get(getGlobalContext(), IntPtrBitSize)); + delete DL; +} + +TEST_F(IRBuilderTest, FastMathFlags) { + IRBuilder<> Builder(BB); + Value *F; + Instruction *FDiv, *FAdd; + + F = Builder.CreateLoad(GV); + F = Builder.CreateFAdd(F, F); + + EXPECT_FALSE(Builder.getFastMathFlags().any()); + ASSERT_TRUE(isa<Instruction>(F)); + FAdd = cast<Instruction>(F); + EXPECT_FALSE(FAdd->hasNoNaNs()); + + FastMathFlags FMF; + Builder.SetFastMathFlags(FMF); + + F = Builder.CreateFAdd(F, F); + EXPECT_FALSE(Builder.getFastMathFlags().any()); + + FMF.setUnsafeAlgebra(); + Builder.SetFastMathFlags(FMF); + + F = Builder.CreateFAdd(F, F); + EXPECT_TRUE(Builder.getFastMathFlags().any()); + ASSERT_TRUE(isa<Instruction>(F)); + FAdd = cast<Instruction>(F); + EXPECT_TRUE(FAdd->hasNoNaNs()); + + F = Builder.CreateFDiv(F, F); + EXPECT_TRUE(Builder.getFastMathFlags().any()); + EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra); + ASSERT_TRUE(isa<Instruction>(F)); + FDiv = cast<Instruction>(F); + EXPECT_TRUE(FDiv->hasAllowReciprocal()); + + Builder.clearFastMathFlags(); + + F = Builder.CreateFDiv(F, F); + ASSERT_TRUE(isa<Instruction>(F)); + FDiv = cast<Instruction>(F); + EXPECT_FALSE(FDiv->hasAllowReciprocal()); + + FMF.clear(); + FMF.setAllowReciprocal(); + Builder.SetFastMathFlags(FMF); + + F = Builder.CreateFDiv(F, F); + EXPECT_TRUE(Builder.getFastMathFlags().any()); + EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal); + ASSERT_TRUE(isa<Instruction>(F)); + FDiv = cast<Instruction>(F); + EXPECT_TRUE(FDiv->hasAllowReciprocal()); + + Builder.clearFastMathFlags(); + + F = Builder.CreateFDiv(F, F); + ASSERT_TRUE(isa<Instruction>(F)); + FDiv = cast<Instruction>(F); + EXPECT_FALSE(FDiv->getFastMathFlags().any()); + FDiv->copyFastMathFlags(FAdd); + EXPECT_TRUE(FDiv->hasNoNaNs()); + } } diff --git a/unittests/VMCore/InstructionsTest.cpp b/unittests/IR/InstructionsTest.cpp index a3b13ce..9f66af1 100644 --- a/unittests/VMCore/InstructionsTest.cpp +++ b/unittests/IR/InstructionsTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/VMCore/InstructionsTest.cpp - Instructions unit tests ===// +//===- llvm/unittest/IR/InstructionsTest.cpp - Instructions unit tests ----===// // // The LLVM Compiler Infrastructure // @@ -7,17 +7,17 @@ // //===----------------------------------------------------------------------===// -#include "llvm/BasicBlock.h" -#include "llvm/Constants.h" -#include "llvm/DataLayout.h" -#include "llvm/DerivedTypes.h" -#include "llvm/IRBuilder.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" -#include "llvm/MDBuilder.h" -#include "llvm/Operator.h" +#include "llvm/IR/Instructions.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Operator.h" #include "gtest/gtest.h" namespace llvm { @@ -162,6 +162,11 @@ TEST(InstructionsTest, VectorGep) { ICmpInst *ICmp1 = new ICmpInst(ICmpInst::ICMP_ULT, PtrVecA, PtrVecB); EXPECT_NE(ICmp0, ICmp1); // suppress warning. + BasicBlock* BB0 = BasicBlock::Create(C); + // Test InsertAtEnd ICmpInst constructor. + ICmpInst *ICmp2 = new ICmpInst(*BB0, ICmpInst::ICMP_SGE, PtrVecA, PtrVecB); + EXPECT_NE(ICmp0, ICmp2); // suppress warning. + GetElementPtrInst *Gep0 = GetElementPtrInst::Create(PtrVecA, C2xi32a); GetElementPtrInst *Gep1 = GetElementPtrInst::Create(PtrVecA, C2xi32b); GetElementPtrInst *Gep2 = GetElementPtrInst::Create(PtrVecB, C2xi32a); @@ -187,10 +192,10 @@ TEST(InstructionsTest, VectorGep) { "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); + 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); @@ -223,6 +228,9 @@ TEST(InstructionsTest, VectorGep) { delete Gep2; delete Gep3; + ICmp2->eraseFromParent(); + delete BB0; + delete ICmp0; delete ICmp1; delete PtrVecA; diff --git a/unittests/VMCore/MDBuilderTest.cpp b/unittests/IR/MDBuilderTest.cpp index 847039b..665d559 100644 --- a/unittests/VMCore/MDBuilderTest.cpp +++ b/unittests/IR/MDBuilderTest.cpp @@ -7,10 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IRBuilder.h" -#include "llvm/MDBuilder.h" -#include "llvm/Operator.h" - +#include "llvm/IR/MDBuilder.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Operator.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/VMCore/Makefile b/unittests/IR/Makefile index d743dc5..7c59003 100644 --- a/unittests/VMCore/Makefile +++ b/unittests/IR/Makefile @@ -1,4 +1,4 @@ -##===- unittests/VMCore/Makefile ---------------------------*- Makefile -*-===## +##===- unittests/IR/Makefile -------------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. -TESTNAME = VMCore +TESTNAME = IR LINK_COMPONENTS := core ipa asmparser include $(LEVEL)/Makefile.config diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 08927a2..352e83e 100644 --- a/unittests/VMCore/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/VMCore/Metadata.cpp - Metadata unit tests ------------===// +//===- llvm/unittest/IR/Metadata.cpp - Metadata unit tests ----------------===// // // The LLVM Compiler Infrastructure // @@ -7,15 +7,15 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" -#include "llvm/Metadata.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" #include "llvm/Support/ValueHandle.h" +#include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" using namespace llvm; namespace { diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp index 9c070c8..1097da6 100644 --- a/unittests/VMCore/PassManagerTest.cpp +++ b/unittests/IR/PassManagerTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/VMCore/PassManager.cpp - Constants unit tests ------===// +//===- llvm/unittest/IR/PassManager.cpp - PassManager unit tests ----------===// // // The LLVM Compiler Infrastructure // @@ -7,29 +7,27 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Module.h" -#include "llvm/LLVMContext.h" #include "llvm/PassManager.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LoopInfo.h" -#include "llvm/Pass.h" #include "llvm/Analysis/LoopPass.h" -#include "llvm/CallGraphSCCPass.h" -#include "llvm/DataLayout.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Constants.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Function.h" -#include "llvm/CallingConv.h" -#include "llvm/BasicBlock.h" -#include "llvm/Instructions.h" -#include "llvm/InlineAsm.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/PassManager.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/PrintModulePass.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" using namespace llvm; @@ -148,6 +146,10 @@ namespace llvm { template<typename T, typename P> struct PassTest : public PassTestBase<P> { public: +#ifndef _MSC_VER // MSVC complains that Pass is not base class. + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; +#endif virtual bool doInitialization(T &t) { EXPECT_FALSE(PassTestBase<P>::initialized); PassTestBase<P>::initialized = true; @@ -198,6 +200,8 @@ namespace llvm { EXPECT_EQ(run, initcount); EXPECT_EQ(finalized, fincount); } + using llvm::Pass::doInitialization; + using llvm::Pass::doFinalization; virtual bool doInitialization(Loop* L, LPPassManager &LPM) { initialized = true; initcount++; @@ -426,7 +430,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test1", mod); func_test1->setCallingConv(CallingConv::C); - AttrListPtr func_test1_PAL; + AttributeSet func_test1_PAL; func_test1->setAttributes(func_test1_PAL); Function* func_test2 = Function::Create( @@ -434,7 +438,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test2", mod); func_test2->setCallingConv(CallingConv::C); - AttrListPtr func_test2_PAL; + AttributeSet func_test2_PAL; func_test2->setAttributes(func_test2_PAL); Function* func_test3 = Function::Create( @@ -442,7 +446,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test3", mod); func_test3->setCallingConv(CallingConv::C); - AttrListPtr func_test3_PAL; + AttributeSet func_test3_PAL; func_test3->setAttributes(func_test3_PAL); Function* func_test4 = Function::Create( @@ -450,7 +454,7 @@ namespace llvm { /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"test4", mod); func_test4->setCallingConv(CallingConv::C); - AttrListPtr func_test4_PAL; + AttributeSet func_test4_PAL; func_test4->setAttributes(func_test4_PAL); // Global Variable Declarations @@ -470,7 +474,7 @@ namespace llvm { // Block entry (label_entry) CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry); int32_3->setCallingConv(CallingConv::C); - int32_3->setTailCall(false);AttrListPtr int32_3_PAL; + int32_3->setTailCall(false);AttributeSet int32_3_PAL; int32_3->setAttributes(int32_3_PAL); ReturnInst::Create(getGlobalContext(), int32_3, label_entry); @@ -485,7 +489,7 @@ namespace llvm { // Block entry (label_entry_5) CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5); int32_6->setCallingConv(CallingConv::C); - int32_6->setTailCall(false);AttrListPtr int32_6_PAL; + int32_6->setTailCall(false);AttributeSet int32_6_PAL; int32_6->setAttributes(int32_6_PAL); ReturnInst::Create(getGlobalContext(), int32_6, label_entry_5); @@ -500,7 +504,7 @@ namespace llvm { // Block entry (label_entry_8) CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8); int32_9->setCallingConv(CallingConv::C); - int32_9->setTailCall(false);AttrListPtr int32_9_PAL; + int32_9->setTailCall(false);AttributeSet int32_9_PAL; int32_9->setAttributes(int32_9_PAL); ReturnInst::Create(getGlobalContext(), int32_9, label_entry_8); diff --git a/unittests/VMCore/TypeBuilderTest.cpp b/unittests/IR/TypeBuilderTest.cpp index a746b1f..be493cd 100644 --- a/unittests/VMCore/TypeBuilderTest.cpp +++ b/unittests/IR/TypeBuilderTest.cpp @@ -7,10 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/TypeBuilder.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/ADT/ArrayRef.h" - +#include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/VMCore/TypesTest.cpp b/unittests/IR/TypesTest.cpp index 0416643..2cee640 100644 --- a/unittests/VMCore/TypesTest.cpp +++ b/unittests/IR/TypesTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/VMCore/TypesTest.cpp - Type unit tests ---------------===// +//===- llvm/unittest/IR/TypesTest.cpp - Type unit tests -------------------===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/VMCore/ValueMapTest.cpp b/unittests/IR/ValueMapTest.cpp index 9bed37d..5aaf905 100644 --- a/unittests/VMCore/ValueMapTest.cpp +++ b/unittests/IR/ValueMapTest.cpp @@ -8,12 +8,11 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/ValueMap.h" -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Config/llvm-config.h" - +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/VMCore/VerifierTest.cpp b/unittests/IR/VerifierTest.cpp index 324b4e1..8911936 100644 --- a/unittests/VMCore/VerifierTest.cpp +++ b/unittests/IR/VerifierTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/VMCore/VerifierTest.cpp - Verifier unit tests --------===// +//===- llvm/unittest/IR/VerifierTest.cpp - Verifier unit tests ------------===// // // The LLVM Compiler Infrastructure // @@ -7,16 +7,16 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalAlias.h" -#include "llvm/GlobalVariable.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "gtest/gtest.h" namespace llvm { diff --git a/unittests/IR/WaymarkTest.cpp b/unittests/IR/WaymarkTest.cpp new file mode 100644 index 0000000..cf7d76d --- /dev/null +++ b/unittests/IR/WaymarkTest.cpp @@ -0,0 +1,56 @@ +//===- llvm/unittest/IR/WaymarkTest.cpp - getUser() unit tests ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// we perform white-box tests +// +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" +#include "gtest/gtest.h" +#include <algorithm> + +namespace llvm { +namespace { + +Constant *char2constant(char c) { + return ConstantInt::get(Type::getInt8Ty(getGlobalContext()), c); +} + + +TEST(WaymarkTest, NativeArray) { + static uint8_t tail[22] = "s02s33s30y2y0s1x0syxS"; + Value * values[22]; + std::transform(tail, tail + 22, values, char2constant); + FunctionType *FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), true); + Function *F = Function::Create(FT, GlobalValue::ExternalLinkage); + const CallInst *A = CallInst::Create(F, makeArrayRef(values)); + ASSERT_NE(A, (const CallInst*)NULL); + ASSERT_EQ(1U + 22, A->getNumOperands()); + const Use *U = &A->getOperandUse(0); + const Use *Ue = &A->getOperandUse(22); + for (; U != Ue; ++U) + { + EXPECT_EQ(A, U->getUser()); + } + delete A; +} + +TEST(WaymarkTest, TwoBit) { + Use* many = (Use*)calloc(sizeof(Use), 8212 + 1); + ASSERT_TRUE(many); + Use::initTags(many, many + 8212); + for (Use *U = many, *Ue = many + 8212 - 1; U != Ue; ++U) + { + EXPECT_EQ(reinterpret_cast<User *>(Ue + 1), U->getUser()); + } + free(many); +} + +} // end anonymous namespace +} // end namespace llvm diff --git a/unittests/Makefile b/unittests/Makefile index 27afccf..926459a 100644 --- a/unittests/Makefile +++ b/unittests/Makefile @@ -9,7 +9,7 @@ LEVEL = .. -PARALLEL_DIRS = ADT ExecutionEngine Support Transforms VMCore Analysis Bitcode +PARALLEL_DIRS = ADT ExecutionEngine Support Transforms IR Analysis Bitcode include $(LEVEL)/Makefile.common diff --git a/unittests/Option/CMakeLists.txt b/unittests/Option/CMakeLists.txt new file mode 100644 index 0000000..185d503 --- /dev/null +++ b/unittests/Option/CMakeLists.txt @@ -0,0 +1,15 @@ +set(LLVM_LINK_COMPONENTS + Option + Support + ) + +set(LLVM_TARGET_DEFINITIONS Opts.td) + +tablegen(LLVM Opts.inc -gen-opt-parser-defs) +add_public_tablegen_target(OptsTestTableGen) + +add_llvm_unittest(OptionTests + OptionParsingTest.cpp + ) + +add_dependencies(OptionTests OptsTestTableGen) diff --git a/unittests/Option/OptionParsingTest.cpp b/unittests/Option/OptionParsingTest.cpp new file mode 100644 index 0000000..30944d9 --- /dev/null +++ b/unittests/Option/OptionParsingTest.cpp @@ -0,0 +1,106 @@ +//===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Option/Arg.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Option/Option.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::opt; + +enum ID { + OPT_INVALID = 0, // This is not an option ID. +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) OPT_##ID, +#include "Opts.inc" + LastOption +#undef OPTION +}; + +#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#include "Opts.inc" +#undef PREFIX + +static const OptTable::Info InfoTable[] = { +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \ + HELPTEXT, METAVAR) \ + { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \ + FLAGS, OPT_##GROUP, OPT_##ALIAS }, +#include "Opts.inc" +#undef OPTION +}; + +namespace { +class TestOptTable : public OptTable { +public: + TestOptTable() + : OptTable(InfoTable, sizeof(InfoTable) / sizeof(InfoTable[0])) {} +}; +} + +const char *Args[] = { + "-A", + "-Bhi", + "--C=desu", + "-C", "bye", + "-D,adena", + "-E", "apple", "bloom", + "-Fblarg", + "-F", "42", + "-Gchuu", "2" + }; + +TEST(Support, OptionParsing) { + TestOptTable T; + unsigned MAI, MAC; + OwningPtr<InputArgList> + AL(T.ParseArgs(Args, + Args + (sizeof(Args) / sizeof(Args[0])), + MAI, + MAC)); + + // Check they all exist. + EXPECT_TRUE(AL->hasArg(OPT_A)); + EXPECT_TRUE(AL->hasArg(OPT_B)); + EXPECT_TRUE(AL->hasArg(OPT_C)); + EXPECT_TRUE(AL->hasArg(OPT_D)); + EXPECT_TRUE(AL->hasArg(OPT_E)); + EXPECT_TRUE(AL->hasArg(OPT_F)); + EXPECT_TRUE(AL->hasArg(OPT_G)); + + // Check the values. + EXPECT_EQ(AL->getLastArgValue(OPT_B), "hi"); + EXPECT_EQ(AL->getLastArgValue(OPT_C), "bye"); + EXPECT_EQ(AL->getLastArgValue(OPT_D), "adena"); + std::vector<std::string> Es = AL->getAllArgValues(OPT_E); + EXPECT_EQ(Es[0], "apple"); + EXPECT_EQ(Es[1], "bloom"); + EXPECT_EQ(AL->getLastArgValue(OPT_F), "42"); + std::vector<std::string> Gs = AL->getAllArgValues(OPT_G); + EXPECT_EQ(Gs[0], "chuu"); + EXPECT_EQ(Gs[1], "2"); + + // Check the help text. + std::string Help; + raw_string_ostream RSO(Help); + T.PrintHelp(RSO, "test", "title!"); + EXPECT_NE(Help.find("-A"), std::string::npos); + + // Test aliases. + arg_iterator Cs = AL->filtered_begin(OPT_C); + ASSERT_NE(Cs, AL->filtered_end()); + EXPECT_EQ(StringRef((*Cs)->getValue()), "desu"); + ArgStringList ASL; + (*Cs)->render(*AL, ASL); + ASSERT_EQ(ASL.size(), 2u); + EXPECT_EQ(StringRef(ASL[0]), "-C"); + EXPECT_EQ(StringRef(ASL[1]), "desu"); +} diff --git a/unittests/Option/Opts.td b/unittests/Option/Opts.td new file mode 100644 index 0000000..3d6242f --- /dev/null +++ b/unittests/Option/Opts.td @@ -0,0 +1,13 @@ +include "llvm/Option/OptParser.td" + +def A : Flag<["-"], "A">, HelpText<"The A option">; +def B : Joined<["-"], "B">, HelpText<"The B option">, MetaVarName<"B">; +def C : Separate<["-"], "C">, HelpText<"The C option">, MetaVarName<"C">; +def D : CommaJoined<["-"], "D">, HelpText<"The D option">, MetaVarName<"D">; +def E : MultiArg<["-"], "E", 2>; +def F : JoinedOrSeparate<["-"], "F">, HelpText<"The F option">, MetaVarName<"F">; +def G : JoinedAndSeparate<["-"], "G">, HelpText<"The G option">, MetaVarName<"G">; + +def Ceq : Joined<["-", "--"], "C=">, Alias<C>; + +def H : Flag<["-"], "H">, Flags<[HelpHidden]>; diff --git a/unittests/Support/AlignOfTest.cpp b/unittests/Support/AlignOfTest.cpp index f01e660..40f7295 100644 --- a/unittests/Support/AlignOfTest.cpp +++ b/unittests/Support/AlignOfTest.cpp @@ -9,19 +9,29 @@ #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" - #include "gtest/gtest.h" using namespace llvm; namespace { - // Disable warnings about questionable type definitions. // We're testing that even questionable types work with the alignment utilities. #ifdef _MSC_VER #pragma warning(disable:4584) #endif +// Suppress direct base '{anonymous}::S1' inaccessible in '{anonymous}::D9' +// due to ambiguity warning. +// +// Pragma based warning suppression was introduced in GGC 4.2. Additionally +// this warning is "enabled by default". The warning still appears if -Wall is +// suppressed. Apparently GCC suppresses it when -w is specifed, which is odd. +// At any rate, clang on the other hand gripes about -Wunknown-pragma, so +// leaving it out of this. +#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 && !defined(__clang__) +#pragma GCC diagnostic warning "-w" +#endif + // Define some fixed alignment types to use in these tests. #if __has_feature(cxx_alignas) struct alignas(1) A1 { }; @@ -310,6 +320,16 @@ TEST(AlignOfTest, BasicAlignedArray) { #ifndef _MSC_VER EXPECT_EQ(sizeof(V8), sizeof(AlignedCharArrayUnion<V8>)); #endif -} + EXPECT_EQ(1u, (alignOf<AlignedCharArray<1, 1> >())); + EXPECT_EQ(2u, (alignOf<AlignedCharArray<2, 1> >())); + EXPECT_EQ(4u, (alignOf<AlignedCharArray<4, 1> >())); + EXPECT_EQ(8u, (alignOf<AlignedCharArray<8, 1> >())); + EXPECT_EQ(16u, (alignOf<AlignedCharArray<16, 1> >())); + + EXPECT_EQ(1u, sizeof(AlignedCharArray<1, 1>)); + EXPECT_EQ(7u, sizeof(AlignedCharArray<1, 7>)); + EXPECT_EQ(2u, sizeof(AlignedCharArray<2, 2>)); + EXPECT_EQ(16u, sizeof(AlignedCharArray<2, 16>)); +} } diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp index 8b463c1..cb9fa43 100644 --- a/unittests/Support/AllocatorTest.cpp +++ b/unittests/Support/AllocatorTest.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Allocator.h" - #include "gtest/gtest.h" #include <cstdlib> diff --git a/unittests/Support/ArrayRecyclerTest.cpp b/unittests/Support/ArrayRecyclerTest.cpp new file mode 100644 index 0000000..1ff97ba --- /dev/null +++ b/unittests/Support/ArrayRecyclerTest.cpp @@ -0,0 +1,109 @@ +//===--- unittest/Support/ArrayRecyclerTest.cpp ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ArrayRecycler.h" +#include "llvm/Support/Allocator.h" +#include "gtest/gtest.h" +#include <cstdlib> + +using namespace llvm; + +namespace { + +struct Object { + int Num; + Object *Other; +}; +typedef ArrayRecycler<Object> ARO; + +TEST(ArrayRecyclerTest, Capacity) { + // Capacity size should never be 0. + ARO::Capacity Cap = ARO::Capacity::get(0); + EXPECT_LT(0u, Cap.getSize()); + + size_t PrevSize = Cap.getSize(); + for (unsigned N = 1; N != 100; ++N) { + Cap = ARO::Capacity::get(N); + EXPECT_LE(N, Cap.getSize()); + if (PrevSize >= N) + EXPECT_EQ(PrevSize, Cap.getSize()); + else + EXPECT_LT(PrevSize, Cap.getSize()); + PrevSize = Cap.getSize(); + } + + // Check that the buckets are monotonically increasing. + Cap = ARO::Capacity::get(0); + PrevSize = Cap.getSize(); + for (unsigned N = 0; N != 20; ++N) { + Cap = Cap.getNext(); + EXPECT_LT(PrevSize, Cap.getSize()); + PrevSize = Cap.getSize(); + } +} + +TEST(ArrayRecyclerTest, Basics) { + BumpPtrAllocator Allocator; + ArrayRecycler<Object> DUT; + + ARO::Capacity Cap = ARO::Capacity::get(8); + Object *A1 = DUT.allocate(Cap, Allocator); + A1[0].Num = 21; + A1[7].Num = 17; + + Object *A2 = DUT.allocate(Cap, Allocator); + A2[0].Num = 121; + A2[7].Num = 117; + + Object *A3 = DUT.allocate(Cap, Allocator); + A3[0].Num = 221; + A3[7].Num = 217; + + EXPECT_EQ(21, A1[0].Num); + EXPECT_EQ(17, A1[7].Num); + EXPECT_EQ(121, A2[0].Num); + EXPECT_EQ(117, A2[7].Num); + EXPECT_EQ(221, A3[0].Num); + EXPECT_EQ(217, A3[7].Num); + + DUT.deallocate(Cap, A2); + + // Check that deallocation didn't clobber anything. + EXPECT_EQ(21, A1[0].Num); + EXPECT_EQ(17, A1[7].Num); + EXPECT_EQ(221, A3[0].Num); + EXPECT_EQ(217, A3[7].Num); + + // Verify recycling. + Object *A2x = DUT.allocate(Cap, Allocator); + EXPECT_EQ(A2, A2x); + + DUT.deallocate(Cap, A2x); + DUT.deallocate(Cap, A1); + DUT.deallocate(Cap, A3); + + // Objects are not required to be recycled in reverse deallocation order, but + // that is what the current implementation does. + Object *A3x = DUT.allocate(Cap, Allocator); + EXPECT_EQ(A3, A3x); + Object *A1x = DUT.allocate(Cap, Allocator); + EXPECT_EQ(A1, A1x); + Object *A2y = DUT.allocate(Cap, Allocator); + EXPECT_EQ(A2, A2y); + + // Back to allocation from the BumpPtrAllocator. + Object *A4 = DUT.allocate(Cap, Allocator); + EXPECT_NE(A1, A4); + EXPECT_NE(A2, A4); + EXPECT_NE(A3, A4); + + DUT.clear(Allocator); +} + +} // end anonymous namespace diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp index 9c5bd7b..ff66bc4 100644 --- a/unittests/Support/BlockFrequencyTest.cpp +++ b/unittests/Support/BlockFrequencyTest.cpp @@ -1,7 +1,6 @@ -#include "llvm/Support/DataTypes.h" #include "llvm/Support/BlockFrequency.h" #include "llvm/Support/BranchProbability.h" - +#include "llvm/Support/DataTypes.h" #include "gtest/gtest.h" #include <climits> diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt index 09a0ea5..b4b982f 100644 --- a/unittests/Support/CMakeLists.txt +++ b/unittests/Support/CMakeLists.txt @@ -6,12 +6,14 @@ set(LLVM_LINK_COMPONENTS add_llvm_unittest(SupportTests AlignOfTest.cpp AllocatorTest.cpp + ArrayRecyclerTest.cpp BlockFrequencyTest.cpp Casting.cpp CommandLineTest.cpp ConstantRangeTest.cpp DataExtractorTest.cpp EndianTest.cpp + ErrorOrTest.cpp FileOutputBufferTest.cpp IntegersSubsetTest.cpp LeakDetectorTest.cpp @@ -20,10 +22,12 @@ add_llvm_unittest(SupportTests MemoryBufferTest.cpp MemoryTest.cpp Path.cpp + ProcessTest.cpp RegexTest.cpp SwapByteOrderTest.cpp TimeValue.cpp ValueHandleTest.cpp + YAMLIOTest.cpp YAMLParserTest.cpp formatted_raw_ostream_test.cpp raw_ostream_test.cpp diff --git a/unittests/Support/Casting.cpp b/unittests/Support/Casting.cpp index ad564aa..01583e4 100644 --- a/unittests/Support/Casting.cpp +++ b/unittests/Support/Casting.cpp @@ -10,7 +10,6 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" - #include "gtest/gtest.h" #include <cstdlib> diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index 13e9038..43c8cbd 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -9,11 +9,9 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Config/config.h" - #include "gtest/gtest.h" - -#include <string> #include <stdlib.h> +#include <string> using namespace llvm; diff --git a/unittests/Support/ConstantRangeTest.cpp b/unittests/Support/ConstantRangeTest.cpp index 263f93c..4d6bbf6 100644 --- a/unittests/Support/ConstantRangeTest.cpp +++ b/unittests/Support/ConstantRangeTest.cpp @@ -8,8 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/ConstantRange.h" -#include "llvm/Instructions.h" - +#include "llvm/IR/Instructions.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/Support/EndianTest.cpp b/unittests/Support/EndianTest.cpp index 6fe0247..8f93553 100644 --- a/unittests/Support/EndianTest.cpp +++ b/unittests/Support/EndianTest.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" #include "llvm/Support/Endian.h" #include "llvm/Support/DataTypes.h" +#include "gtest/gtest.h" #include <cstdlib> #include <ctime> using namespace llvm; @@ -21,36 +21,36 @@ namespace { TEST(Endian, Read) { // These are 5 bytes so we can be sure at least one of the reads is unaligned. - unsigned char big[] = {0x00, 0x01, 0x02, 0x03, 0x04}; - unsigned char little[] = {0x00, 0x04, 0x03, 0x02, 0x01}; + unsigned char bigval[] = {0x00, 0x01, 0x02, 0x03, 0x04}; + unsigned char littleval[] = {0x00, 0x04, 0x03, 0x02, 0x01}; int32_t BigAsHost = 0x00010203; - EXPECT_EQ(BigAsHost, (endian::read_be<int32_t, unaligned>(big))); + EXPECT_EQ(BigAsHost, (endian::read<int32_t, big, unaligned>(bigval))); int32_t LittleAsHost = 0x02030400; - EXPECT_EQ(LittleAsHost, (endian::read_le<int32_t, unaligned>(little))); + EXPECT_EQ(LittleAsHost,(endian::read<int32_t, little, unaligned>(littleval))); - EXPECT_EQ((endian::read_be<int32_t, unaligned>(big + 1)), - (endian::read_le<int32_t, unaligned>(little + 1))); + EXPECT_EQ((endian::read<int32_t, big, unaligned>(bigval + 1)), + (endian::read<int32_t, little, unaligned>(littleval + 1))); } TEST(Endian, Write) { unsigned char data[5]; - endian::write_be<int32_t, unaligned>(data, -1362446643); + endian::write<int32_t, big, unaligned>(data, -1362446643); EXPECT_EQ(data[0], 0xAE); EXPECT_EQ(data[1], 0xCA); EXPECT_EQ(data[2], 0xB6); EXPECT_EQ(data[3], 0xCD); - endian::write_be<int32_t, unaligned>(data + 1, -1362446643); + endian::write<int32_t, big, unaligned>(data + 1, -1362446643); EXPECT_EQ(data[1], 0xAE); EXPECT_EQ(data[2], 0xCA); EXPECT_EQ(data[3], 0xB6); EXPECT_EQ(data[4], 0xCD); - endian::write_le<int32_t, unaligned>(data, -1362446643); + endian::write<int32_t, little, unaligned>(data, -1362446643); EXPECT_EQ(data[0], 0xCD); EXPECT_EQ(data[1], 0xB6); EXPECT_EQ(data[2], 0xCA); EXPECT_EQ(data[3], 0xAE); - endian::write_le<int32_t, unaligned>(data + 1, -1362446643); + endian::write<int32_t, little, unaligned>(data + 1, -1362446643); EXPECT_EQ(data[1], 0xCD); EXPECT_EQ(data[2], 0xB6); EXPECT_EQ(data[3], 0xCA); @@ -69,4 +69,4 @@ TEST(Endian, PackedEndianSpecificIntegral) { EXPECT_EQ(*big_val, *little_val); } -} +} // end anon namespace diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp new file mode 100644 index 0000000..4853426 --- /dev/null +++ b/unittests/Support/ErrorOrTest.cpp @@ -0,0 +1,104 @@ +//===- unittests/ErrorOrTest.cpp - ErrorOr.h 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/ErrorOr.h" + +#include "gtest/gtest.h" + +#include <memory> + +using namespace llvm; + +namespace { + +ErrorOr<int> t1() {return 1;} +ErrorOr<int> t2() { return errc::invalid_argument; } + +TEST(ErrorOr, SimpleValue) { + ErrorOr<int> a = t1(); + EXPECT_TRUE(a); + EXPECT_EQ(1, *a); + + a = t2(); + EXPECT_FALSE(a); + EXPECT_EQ(errc::invalid_argument, a); +#ifdef EXPECT_DEBUG_DEATH + EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists"); +#endif +} + +#if LLVM_HAS_CXX11_STDLIB +ErrorOr<std::unique_ptr<int> > t3() { + return std::unique_ptr<int>(new int(3)); +} +#endif + +TEST(ErrorOr, Types) { + int x; + ErrorOr<int&> a(x); + *a = 42; + EXPECT_EQ(42, x); + + EXPECT_FALSE(ErrorOr<void>(errc::broken_pipe)); + EXPECT_TRUE(ErrorOr<void>(errc::success)); + +#if LLVM_HAS_CXX11_STDLIB + // Move only types. + EXPECT_EQ(3, **t3()); +#endif +} + +struct B {}; +struct D : B {}; + +TEST(ErrorOr, Covariant) { + ErrorOr<B*> b(ErrorOr<D*>(0)); + b = ErrorOr<D*>(0); + +#if LLVM_HAS_CXX11_STDLIB + ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(0)); + b1 = ErrorOr<std::unique_ptr<D> >(0); +#endif +} +} // end anon namespace + +struct InvalidArgError { + InvalidArgError() {} + InvalidArgError(std::string S) : ArgName(S) {} + std::string ArgName; +}; + +namespace llvm { +template<> +struct ErrorOrUserDataTraits<InvalidArgError> : true_type { + static error_code error() { + return make_error_code(errc::invalid_argument); + } +}; +} // end namespace llvm + +ErrorOr<int> t4() { + return InvalidArgError("adena"); +} + +ErrorOr<void> t5() { + return InvalidArgError("pie"); +} + +namespace { +TEST(ErrorOr, UserErrorData) { + ErrorOr<int> a = t4(); + EXPECT_EQ(errc::invalid_argument, a); + EXPECT_EQ("adena", t4().getError<InvalidArgError>().ArgName); + + ErrorOr<void> b = t5(); + EXPECT_EQ(errc::invalid_argument, b); + EXPECT_EQ("pie", b.getError<InvalidArgError>().ArgName); +} +} // end anon namespace diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp index edd350a..80d7245 100644 --- a/unittests/Support/FileOutputBufferTest.cpp +++ b/unittests/Support/FileOutputBufferTest.cpp @@ -7,13 +7,12 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/FileOutputBuffer.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/PathV2.h" #include "llvm/Support/raw_ostream.h" - #include "gtest/gtest.h" using namespace llvm; @@ -27,13 +26,6 @@ using namespace llvm::sys; } else {} namespace { - - -// NOTE: Temporarily run this test on unix only. Once the file mapping -// routines are ported to Windows, this conditional can be removed. -#if LLVM_ON_UNIX - - TEST(FileOutputBuffer, Test) { // Create unique temporary directory for these tests SmallString<128> TestDirectory; @@ -45,7 +37,7 @@ TEST(FileOutputBuffer, Test) { ::close(fd); TestDirectory = path::parent_path(TestDirectory); } - + // TEST 1: Verify commit case. SmallString<128> File1(TestDirectory); File1.append("/file1"); @@ -61,7 +53,7 @@ TEST(FileOutputBuffer, Test) { } // Verify file exists and starts with special header. bool MagicMatches = false; - ASSERT_NO_ERROR(fs::has_magic(Twine(File1), Twine("AABBCCDDEEFFGGHHIIJJ"), + ASSERT_NO_ERROR(fs::has_magic(Twine(File1), Twine("AABBCCDDEEFFGGHHIIJJ"), MagicMatches)); EXPECT_TRUE(MagicMatches); // Verify file is correct size. @@ -82,8 +74,7 @@ TEST(FileOutputBuffer, Test) { // Verify file does not exist (because buffer not commited). bool Exists = false; ASSERT_NO_ERROR(fs::exists(Twine(File2), Exists)); - EXPECT_FALSE(Exists); - + EXPECT_FALSE(Exists); // TEST 3: Verify sizing down case. SmallString<128> File3(TestDirectory); @@ -100,7 +91,7 @@ TEST(FileOutputBuffer, Test) { } // Verify file exists and starts with special header. bool MagicMatches3 = false; - ASSERT_NO_ERROR(fs::has_magic(Twine(File3), Twine("AABBCCDDEEFFGGHHIIJJ"), + ASSERT_NO_ERROR(fs::has_magic(Twine(File3), Twine("AABBCCDDEEFFGGHHIIJJ"), MagicMatches3)); EXPECT_TRUE(MagicMatches3); // Verify file is correct size. @@ -108,13 +99,12 @@ TEST(FileOutputBuffer, Test) { ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size)); ASSERT_EQ(File3Size, 5000ULL); - // TEST 4: Verify file can be made executable. SmallString<128> File4(TestDirectory); File4.append("/file4"); { OwningPtr<FileOutputBuffer> Buffer; - ASSERT_NO_ERROR(FileOutputBuffer::create(File4, 8192, Buffer, + ASSERT_NO_ERROR(FileOutputBuffer::create(File4, 8192, Buffer, FileOutputBuffer::F_executable)); // Start buffer with special header. memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); @@ -131,7 +121,4 @@ TEST(FileOutputBuffer, Test) { uint32_t RemovedCount; ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), RemovedCount)); } - -#endif // LLVM_ON_UNIX - } // anonymous namespace diff --git a/unittests/Support/IntegersSubsetTest.cpp b/unittests/Support/IntegersSubsetTest.cpp index 5d1dde4..f4298bf 100644 --- a/unittests/Support/IntegersSubsetTest.cpp +++ b/unittests/Support/IntegersSubsetTest.cpp @@ -7,12 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/APInt.h" #include "llvm/Support/IntegersSubset.h" +#include "llvm/ADT/APInt.h" #include "llvm/Support/IntegersSubsetMapping.h" - #include "gtest/gtest.h" - #include <vector> using namespace llvm; diff --git a/unittests/Support/ManagedStatic.cpp b/unittests/Support/ManagedStatic.cpp index bfeb0a7..8ddad38 100644 --- a/unittests/Support/ManagedStatic.cpp +++ b/unittests/Support/ManagedStatic.cpp @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Threading.h" #include "llvm/Config/config.h" +#include "llvm/Support/Threading.h" #ifdef HAVE_PTHREAD_H #include <pthread.h> #endif @@ -19,24 +19,41 @@ using namespace llvm; namespace { -#ifdef HAVE_PTHREAD_H +#if defined(HAVE_PTHREAD_H) && !__has_feature(memory_sanitizer) namespace test1 { llvm::ManagedStatic<int> ms; void *helper(void*) { *ms; return NULL; } + + // Valgrind's leak checker complains glibc's stack allocation. + // To appease valgrind, we provide our own stack for each thread. + void *allocate_stack(pthread_attr_t &a, size_t n = 65536) { + void *stack = malloc(n); + pthread_attr_init(&a); +#if defined(__linux__) + pthread_attr_setstack(&a, stack, n); +#endif + return stack; + } } TEST(Initialize, MultipleThreads) { // Run this test under tsan: http://code.google.com/p/data-race-test/ + pthread_attr_t a1, a2; + void *p1 = test1::allocate_stack(a1); + void *p2 = test1::allocate_stack(a2); + llvm_start_multithreaded(); pthread_t t1, t2; - pthread_create(&t1, NULL, test1::helper, NULL); - pthread_create(&t2, NULL, test1::helper, NULL); + pthread_create(&t1, &a1, test1::helper, NULL); + pthread_create(&t2, &a2, test1::helper, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); + free(p1); + free(p2); llvm_stop_multithreaded(); } #endif diff --git a/unittests/Support/MemoryBufferTest.cpp b/unittests/Support/MemoryBufferTest.cpp index 6c78cd8..1d9f482 100644 --- a/unittests/Support/MemoryBufferTest.cpp +++ b/unittests/Support/MemoryBufferTest.cpp @@ -13,7 +13,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/OwningPtr.h" - #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/Support/MemoryTest.cpp b/unittests/Support/MemoryTest.cpp index 21cb27e..fae67a8 100644 --- a/unittests/Support/MemoryTest.cpp +++ b/unittests/Support/MemoryTest.cpp @@ -1,356 +1,357 @@ -//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator 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/Memory.h"
-#include "llvm/Support/Process.h"
-
-#include "gtest/gtest.h"
-#include <cstdlib>
-
-using namespace llvm;
-using namespace sys;
-
-namespace {
-
-class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
-public:
- MappedMemoryTest() {
- Flags = GetParam();
- PageSize = sys::Process::GetPageSize();
- }
-
-protected:
- // Adds RW flags to permit testing of the resulting memory
- unsigned getTestableEquivalent(unsigned RequestedFlags) {
- switch (RequestedFlags) {
- case Memory::MF_READ:
- case Memory::MF_WRITE:
- case Memory::MF_READ|Memory::MF_WRITE:
- return Memory::MF_READ|Memory::MF_WRITE;
- case Memory::MF_READ|Memory::MF_EXEC:
- case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
- case Memory::MF_EXEC:
- return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
- }
- // Default in case values are added to the enum, as required by some compilers
- return Memory::MF_READ|Memory::MF_WRITE;
- }
-
- // Returns true if the memory blocks overlap
- bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
- if (M1.base() == M2.base())
- return true;
-
- if (M1.base() > M2.base())
- return (unsigned char *)M2.base() + M2.size() > M1.base();
-
- return (unsigned char *)M1.base() + M1.size() > M2.base();
- }
-
- unsigned Flags;
- size_t PageSize;
-};
-
-TEST_P(MappedMemoryTest, AllocAndRelease) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(sizeof(int), M1.size());
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
-}
-
-TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(64, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(32, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(32U, M3.size());
-
- EXPECT_FALSE(doesOverlap(M1, M2));
- EXPECT_FALSE(doesOverlap(M2, M3));
- EXPECT_FALSE(doesOverlap(M1, M3));
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- EXPECT_NE((void*)0, M4.base());
- EXPECT_LE(16U, M4.size());
- EXPECT_FALSE(Memory::releaseMappedMemory(M4));
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, BasicWrite) {
- // This test applies only to writeable combinations
- if (Flags && !(Flags & Memory::MF_WRITE))
- return;
-
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(sizeof(int), M1.size());
-
- int *a = (int*)M1.base();
- *a = 1;
- EXPECT_EQ(1, *a);
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
-}
-
-TEST_P(MappedMemoryTest, MultipleWrite) {
- // This test applies only to writeable combinations
- if (Flags && !(Flags & Memory::MF_WRITE))
- return;
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_FALSE(doesOverlap(M1, M2));
- EXPECT_FALSE(doesOverlap(M2, M3));
- EXPECT_FALSE(doesOverlap(M1, M3));
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(1U * sizeof(int), M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(8U * sizeof(int), M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(4U * sizeof(int), M3.size());
-
- int *x = (int*)M1.base();
- *x = 1;
-
- int *y = (int*)M2.base();
- for (int i = 0; i < 8; i++) {
- y[i] = i;
- }
-
- int *z = (int*)M3.base();
- *z = 42;
-
- EXPECT_EQ(1, *x);
- EXPECT_EQ(7, y[7]);
- EXPECT_EQ(42, *z);
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
-
- MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- EXPECT_NE((void*)0, M4.base());
- EXPECT_LE(64U * sizeof(int), M4.size());
- x = (int*)M4.base();
- *x = 4;
- EXPECT_EQ(4, *x);
- EXPECT_FALSE(Memory::releaseMappedMemory(M4));
-
- // Verify that M2 remains unaffected by other activity
- for (int i = 0; i < 8; i++) {
- EXPECT_EQ(i, y[i]);
- }
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, EnabledWrite) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(2U * sizeof(int), M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(8U * sizeof(int), M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(4U * sizeof(int), M3.size());
-
- EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
- EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
- EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
-
- EXPECT_FALSE(doesOverlap(M1, M2));
- EXPECT_FALSE(doesOverlap(M2, M3));
- EXPECT_FALSE(doesOverlap(M1, M3));
-
- int *x = (int*)M1.base();
- *x = 1;
- int *y = (int*)M2.base();
- for (unsigned int i = 0; i < 8; i++) {
- y[i] = i;
- }
- int *z = (int*)M3.base();
- *z = 42;
-
- EXPECT_EQ(1, *x);
- EXPECT_EQ(7, y[7]);
- EXPECT_EQ(42, *z);
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- EXPECT_EQ(6, y[6]);
-
- MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- EXPECT_NE((void*)0, M4.base());
- EXPECT_LE(16U, M4.size());
- EXPECT_EQ(error_code::success(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
- x = (int*)M4.base();
- *x = 4;
- EXPECT_EQ(4, *x);
- EXPECT_FALSE(Memory::releaseMappedMemory(M4));
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, SuccessiveNear) {
- error_code EC;
- MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(32U, M3.size());
-
- EXPECT_FALSE(doesOverlap(M1, M2));
- EXPECT_FALSE(doesOverlap(M2, M3));
- EXPECT_FALSE(doesOverlap(M1, M3));
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, DuplicateNear) {
- error_code EC;
- MemoryBlock Near((void*)(3*PageSize), 16);
- MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(32U, M3.size());
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, ZeroNear) {
- error_code EC;
- MemoryBlock Near(0, 0);
- MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(32U, M3.size());
-
- EXPECT_FALSE(doesOverlap(M1, M2));
- EXPECT_FALSE(doesOverlap(M2, M3));
- EXPECT_FALSE(doesOverlap(M1, M3));
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, ZeroSizeNear) {
- error_code EC;
- MemoryBlock Near((void*)(4*PageSize), 0);
- MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
- MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(16U, M1.size());
- EXPECT_NE((void*)0, M2.base());
- EXPECT_LE(64U, M2.size());
- EXPECT_NE((void*)0, M3.base());
- EXPECT_LE(32U, M3.size());
-
- EXPECT_FALSE(doesOverlap(M1, M2));
- EXPECT_FALSE(doesOverlap(M2, M3));
- EXPECT_FALSE(doesOverlap(M1, M3));
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
- EXPECT_FALSE(Memory::releaseMappedMemory(M3));
- EXPECT_FALSE(Memory::releaseMappedMemory(M2));
-}
-
-TEST_P(MappedMemoryTest, UnalignedNear) {
- error_code EC;
- MemoryBlock Near((void*)(2*PageSize+5), 0);
- MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
- EXPECT_EQ(error_code::success(), EC);
-
- EXPECT_NE((void*)0, M1.base());
- EXPECT_LE(sizeof(int), M1.size());
-
- EXPECT_FALSE(Memory::releaseMappedMemory(M1));
-}
-
-// Note that Memory::MF_WRITE is not supported exclusively across
-// operating systems and architectures and can imply MF_READ|MF_WRITE
-unsigned MemoryFlags[] = {
- Memory::MF_READ,
- Memory::MF_WRITE,
- Memory::MF_READ|Memory::MF_WRITE,
- Memory::MF_EXEC,
- Memory::MF_READ|Memory::MF_EXEC,
- Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
- };
-
-INSTANTIATE_TEST_CASE_P(AllocationTests,
- MappedMemoryTest,
- ::testing::ValuesIn(MemoryFlags));
-
-} // anonymous namespace
+//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator 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/Memory.h" +#include "llvm/Support/Process.h" +#include "gtest/gtest.h" +#include <cstdlib> + +using namespace llvm; +using namespace sys; + +namespace { + +class MappedMemoryTest : public ::testing::TestWithParam<unsigned> { +public: + MappedMemoryTest() { + Flags = GetParam(); + PageSize = sys::process::get_self()->page_size(); + } + +protected: + // Adds RW flags to permit testing of the resulting memory + unsigned getTestableEquivalent(unsigned RequestedFlags) { + switch (RequestedFlags) { + case Memory::MF_READ: + case Memory::MF_WRITE: + case Memory::MF_READ|Memory::MF_WRITE: + return Memory::MF_READ|Memory::MF_WRITE; + case Memory::MF_READ|Memory::MF_EXEC: + case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC: + case Memory::MF_EXEC: + return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC; + } + // Default in case values are added to the enum, as required by some compilers + return Memory::MF_READ|Memory::MF_WRITE; + } + + // Returns true if the memory blocks overlap + bool doesOverlap(MemoryBlock M1, MemoryBlock M2) { + if (M1.base() == M2.base()) + return true; + + if (M1.base() > M2.base()) + return (unsigned char *)M2.base() + M2.size() > M1.base(); + + return (unsigned char *)M1.base() + M1.size() > M2.base(); + } + + unsigned Flags; + size_t PageSize; +}; + +TEST_P(MappedMemoryTest, AllocAndRelease) { + error_code EC; + MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(sizeof(int), M1.size()); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); +} + +TEST_P(MappedMemoryTest, MultipleAllocAndRelease) { + error_code EC; + MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(64, 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(32, 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(16U, M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(64U, M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(32U, M3.size()); + + EXPECT_FALSE(doesOverlap(M1, M2)); + EXPECT_FALSE(doesOverlap(M2, M3)); + EXPECT_FALSE(doesOverlap(M1, M3)); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + EXPECT_NE((void*)0, M4.base()); + EXPECT_LE(16U, M4.size()); + EXPECT_FALSE(Memory::releaseMappedMemory(M4)); + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, BasicWrite) { + // This test applies only to readable and writeable combinations + if (Flags && + !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE))) + return; + + error_code EC; + MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(sizeof(int), M1.size()); + + int *a = (int*)M1.base(); + *a = 1; + EXPECT_EQ(1, *a); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); +} + +TEST_P(MappedMemoryTest, MultipleWrite) { + // This test applies only to readable and writeable combinations + if (Flags && + !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE))) + return; + error_code EC; + MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_FALSE(doesOverlap(M1, M2)); + EXPECT_FALSE(doesOverlap(M2, M3)); + EXPECT_FALSE(doesOverlap(M1, M3)); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(1U * sizeof(int), M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(8U * sizeof(int), M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(4U * sizeof(int), M3.size()); + + int *x = (int*)M1.base(); + *x = 1; + + int *y = (int*)M2.base(); + for (int i = 0; i < 8; i++) { + y[i] = i; + } + + int *z = (int*)M3.base(); + *z = 42; + + EXPECT_EQ(1, *x); + EXPECT_EQ(7, y[7]); + EXPECT_EQ(42, *z); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + + MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + EXPECT_NE((void*)0, M4.base()); + EXPECT_LE(64U * sizeof(int), M4.size()); + x = (int*)M4.base(); + *x = 4; + EXPECT_EQ(4, *x); + EXPECT_FALSE(Memory::releaseMappedMemory(M4)); + + // Verify that M2 remains unaffected by other activity + for (int i = 0; i < 8; i++) { + EXPECT_EQ(i, y[i]); + } + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, EnabledWrite) { + error_code EC; + MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(2U * sizeof(int), M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(8U * sizeof(int), M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(4U * sizeof(int), M3.size()); + + EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags))); + EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags))); + EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags))); + + EXPECT_FALSE(doesOverlap(M1, M2)); + EXPECT_FALSE(doesOverlap(M2, M3)); + EXPECT_FALSE(doesOverlap(M1, M3)); + + int *x = (int*)M1.base(); + *x = 1; + int *y = (int*)M2.base(); + for (unsigned int i = 0; i < 8; i++) { + y[i] = i; + } + int *z = (int*)M3.base(); + *z = 42; + + EXPECT_EQ(1, *x); + EXPECT_EQ(7, y[7]); + EXPECT_EQ(42, *z); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + EXPECT_EQ(6, y[6]); + + MemoryBlock M4 = Memory::allocateMappedMemory(16, 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + EXPECT_NE((void*)0, M4.base()); + EXPECT_LE(16U, M4.size()); + EXPECT_EQ(error_code::success(), Memory::protectMappedMemory(M4, getTestableEquivalent(Flags))); + x = (int*)M4.base(); + *x = 4; + EXPECT_EQ(4, *x); + EXPECT_FALSE(Memory::releaseMappedMemory(M4)); + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, SuccessiveNear) { + error_code EC; + MemoryBlock M1 = Memory::allocateMappedMemory(16, 0, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(16U, M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(64U, M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(32U, M3.size()); + + EXPECT_FALSE(doesOverlap(M1, M2)); + EXPECT_FALSE(doesOverlap(M2, M3)); + EXPECT_FALSE(doesOverlap(M1, M3)); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, DuplicateNear) { + error_code EC; + MemoryBlock Near((void*)(3*PageSize), 16); + MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(16U, M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(64U, M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(32U, M3.size()); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, ZeroNear) { + error_code EC; + MemoryBlock Near(0, 0); + MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(16U, M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(64U, M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(32U, M3.size()); + + EXPECT_FALSE(doesOverlap(M1, M2)); + EXPECT_FALSE(doesOverlap(M2, M3)); + EXPECT_FALSE(doesOverlap(M1, M3)); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, ZeroSizeNear) { + error_code EC; + MemoryBlock Near((void*)(4*PageSize), 0); + MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(16U, M1.size()); + EXPECT_NE((void*)0, M2.base()); + EXPECT_LE(64U, M2.size()); + EXPECT_NE((void*)0, M3.base()); + EXPECT_LE(32U, M3.size()); + + EXPECT_FALSE(doesOverlap(M1, M2)); + EXPECT_FALSE(doesOverlap(M2, M3)); + EXPECT_FALSE(doesOverlap(M1, M3)); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); + EXPECT_FALSE(Memory::releaseMappedMemory(M3)); + EXPECT_FALSE(Memory::releaseMappedMemory(M2)); +} + +TEST_P(MappedMemoryTest, UnalignedNear) { + error_code EC; + MemoryBlock Near((void*)(2*PageSize+5), 0); + MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC); + EXPECT_EQ(error_code::success(), EC); + + EXPECT_NE((void*)0, M1.base()); + EXPECT_LE(sizeof(int), M1.size()); + + EXPECT_FALSE(Memory::releaseMappedMemory(M1)); +} + +// Note that Memory::MF_WRITE is not supported exclusively across +// operating systems and architectures and can imply MF_READ|MF_WRITE +unsigned MemoryFlags[] = { + Memory::MF_READ, + Memory::MF_WRITE, + Memory::MF_READ|Memory::MF_WRITE, + Memory::MF_EXEC, + Memory::MF_READ|Memory::MF_EXEC, + Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC + }; + +INSTANTIATE_TEST_CASE_P(AllocationTests, + MappedMemoryTest, + ::testing::ValuesIn(MemoryFlags)); + +} // anonymous namespace diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index 63c9ae0..4511259 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -7,11 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/FileSystem.h" #include "llvm/Support/PathV2.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" - #include "gtest/gtest.h" using namespace llvm; @@ -225,6 +224,18 @@ TEST_F(FileSystemTest, TempFiles) { // Make sure Temp1 doesn't exist. ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists)); EXPECT_FALSE(TempFileExists); + +#ifdef LLVM_ON_WIN32 + // Path name > 260 chars should get an error. + const char *Path270 = + "abcdefghijklmnopqrstuvwxyz9abcdefghijklmnopqrstuvwxyz8" + "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6" + "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4" + "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2" + "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0"; + EXPECT_EQ(fs::unique_file(Twine(Path270), FileDescriptor, TempPath), + windows_error::path_not_found); +#endif } TEST_F(FileSystemTest, DirectoryIteration) { @@ -351,6 +362,7 @@ TEST_F(FileSystemTest, FileMapping) { StringRef Val("hello there"); { fs::mapped_file_region mfr(FileDescriptor, + true, fs::mapped_file_region::readwrite, 4096, 0, @@ -375,7 +387,7 @@ TEST_F(FileSystemTest, FileMapping) { // Unmap temp file -#if LLVM_USE_RVALUE_REFERENCES +#if LLVM_HAS_RVALUE_REFERENCES fs::mapped_file_region m(Twine(TempPath), fs::mapped_file_region::readonly, 0, diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp new file mode 100644 index 0000000..e57c0e6 --- /dev/null +++ b/unittests/Support/ProcessTest.cpp @@ -0,0 +1,42 @@ +//===- unittest/Support/ProcessTest.cpp -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Process.h" +#include "gtest/gtest.h" + +#ifdef LLVM_ON_WIN32 +#include "windows.h" +#endif + +namespace { + +using namespace llvm; +using namespace sys; + +TEST(ProcessTest, SelfProcess) { + EXPECT_TRUE(process::get_self()); + EXPECT_EQ(process::get_self(), process::get_self()); + +#if defined(LLVM_ON_UNIX) + EXPECT_EQ(getpid(), process::get_self()->get_id()); +#elif defined(LLVM_ON_WIN32) + EXPECT_EQ(GetCurrentProcess(), process::get_self()->get_id()); +#endif + + EXPECT_LT(1u, process::get_self()->page_size()); + + EXPECT_LT(TimeValue::MinTime, process::get_self()->get_user_time()); + EXPECT_GT(TimeValue::MaxTime, process::get_self()->get_user_time()); + EXPECT_LT(TimeValue::MinTime, process::get_self()->get_system_time()); + EXPECT_GT(TimeValue::MaxTime, process::get_self()->get_system_time()); + EXPECT_LT(TimeValue::MinTime, process::get_self()->get_wall_time()); + EXPECT_GT(TimeValue::MaxTime, process::get_self()->get_wall_time()); +} + +} // end anonymous namespace diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp index 65b66c3..3577d10 100644 --- a/unittests/Support/RegexTest.cpp +++ b/unittests/Support/RegexTest.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" #include "llvm/Support/Regex.h" #include "llvm/ADT/SmallVector.h" +#include "gtest/gtest.h" #include <cstring> using namespace llvm; @@ -51,7 +51,6 @@ TEST_F(RegexTest, Basics) { EXPECT_EQ(1u, Matches.size()); EXPECT_EQ(String, Matches[0].str()); - std::string NulPattern="X[0-9]+X([a-f])?:([0-9]+)"; String="YX99a:513b"; NulPattern[7] = '\0'; @@ -62,6 +61,28 @@ TEST_F(RegexTest, Basics) { EXPECT_TRUE(r5.match(String)); } +TEST_F(RegexTest, Backreferences) { + Regex r1("([a-z]+)_\\1"); + SmallVector<StringRef, 4> Matches; + EXPECT_TRUE(r1.match("abc_abc", &Matches)); + EXPECT_EQ(2u, Matches.size()); + EXPECT_FALSE(r1.match("abc_ab", &Matches)); + + Regex r2("a([0-9])b\\1c\\1"); + EXPECT_TRUE(r2.match("a4b4c4", &Matches)); + EXPECT_EQ(2u, Matches.size()); + EXPECT_EQ("4", Matches[1].str()); + EXPECT_FALSE(r2.match("a2b2c3")); + + Regex r3("a([0-9])([a-z])b\\1\\2"); + EXPECT_TRUE(r3.match("a6zb6z", &Matches)); + EXPECT_EQ(3u, Matches.size()); + EXPECT_EQ("6", Matches[1].str()); + EXPECT_EQ("z", Matches[2].str()); + EXPECT_FALSE(r3.match("a6zb6y")); + EXPECT_FALSE(r3.match("a6zb7z")); +} + TEST_F(RegexTest, Substitution) { std::string Error; diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp index 2e5e5b1..05aafa2 100644 --- a/unittests/Support/ValueHandleTest.cpp +++ b/unittests/Support/ValueHandleTest.cpp @@ -8,14 +8,11 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/ValueHandle.h" - -#include "llvm/Constants.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" #include "llvm/ADT/OwningPtr.h" - +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" - #include <memory> using namespace llvm; diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp new file mode 100644 index 0000000..0993d8c --- /dev/null +++ b/unittests/Support/YAMLIOTest.cpp @@ -0,0 +1,1299 @@ +//===- unittest/Support/YAMLIOTest.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/SmallString.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/YAMLTraits.h" +#include "gtest/gtest.h" + + +using llvm::yaml::Input; +using llvm::yaml::Output; +using llvm::yaml::IO; +using llvm::yaml::MappingTraits; +using llvm::yaml::MappingNormalization; +using llvm::yaml::ScalarTraits; +using llvm::yaml::Hex8; +using llvm::yaml::Hex16; +using llvm::yaml::Hex32; +using llvm::yaml::Hex64; + + +//===----------------------------------------------------------------------===// +// Test MappingTraits +//===----------------------------------------------------------------------===// + +struct FooBar { + int foo; + int bar; +}; +typedef std::vector<FooBar> FooBarSequence; + +LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar) + + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits<FooBar> { + static void mapping(IO &io, FooBar& fb) { + io.mapRequired("foo", fb.foo); + io.mapRequired("bar", fb.bar); + } + }; +} +} + + +// +// Test the reading of a yaml mapping +// +TEST(YAMLIO, TestMapRead) { + FooBar doc; + Input yin("---\nfoo: 3\nbar: 5\n...\n"); + yin >> doc; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(doc.foo, 3); + EXPECT_EQ(doc.bar,5); +} + + +// +// Test the reading of a yaml sequence of mappings +// +TEST(YAMLIO, TestSequenceMapRead) { + FooBarSequence seq; + Input yin("---\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n"); + yin >> seq; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(seq.size(), 2UL); + FooBar& map1 = seq[0]; + FooBar& map2 = seq[1]; + EXPECT_EQ(map1.foo, 3); + EXPECT_EQ(map1.bar, 5); + EXPECT_EQ(map2.foo, 7); + EXPECT_EQ(map2.bar, 9); +} + + +// +// Test writing then reading back a sequence of mappings +// +TEST(YAMLIO, TestSequenceMapWriteAndRead) { + std::string intermediate; + { + FooBar entry1; + entry1.foo = 10; + entry1.bar = -3; + FooBar entry2; + entry2.foo = 257; + entry2.bar = 0; + FooBarSequence seq; + seq.push_back(entry1); + seq.push_back(entry2); + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << seq; + } + + { + Input yin(intermediate); + FooBarSequence seq2; + yin >> seq2; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(seq2.size(), 2UL); + FooBar& map1 = seq2[0]; + FooBar& map2 = seq2[1]; + EXPECT_EQ(map1.foo, 10); + EXPECT_EQ(map1.bar, -3); + EXPECT_EQ(map2.foo, 257); + EXPECT_EQ(map2.bar, 0); + } +} + + +//===----------------------------------------------------------------------===// +// Test built-in types +//===----------------------------------------------------------------------===// + +struct BuiltInTypes { + llvm::StringRef str; + uint64_t u64; + uint32_t u32; + uint16_t u16; + uint8_t u8; + bool b; + int64_t s64; + int32_t s32; + int16_t s16; + int8_t s8; + float f; + double d; + Hex8 h8; + Hex16 h16; + Hex32 h32; + Hex64 h64; +}; + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits<BuiltInTypes> { + static void mapping(IO &io, BuiltInTypes& bt) { + io.mapRequired("str", bt.str); + io.mapRequired("u64", bt.u64); + io.mapRequired("u32", bt.u32); + io.mapRequired("u16", bt.u16); + io.mapRequired("u8", bt.u8); + io.mapRequired("b", bt.b); + io.mapRequired("s64", bt.s64); + io.mapRequired("s32", bt.s32); + io.mapRequired("s16", bt.s16); + io.mapRequired("s8", bt.s8); + io.mapRequired("f", bt.f); + io.mapRequired("d", bt.d); + io.mapRequired("h8", bt.h8); + io.mapRequired("h16", bt.h16); + io.mapRequired("h32", bt.h32); + io.mapRequired("h64", bt.h64); + } + }; +} +} + + +// +// Test the reading of all built-in scalar conversions +// +TEST(YAMLIO, TestReadBuiltInTypes) { + BuiltInTypes map; + Input yin("---\n" + "str: hello there\n" + "u64: 5000000000\n" + "u32: 4000000000\n" + "u16: 65000\n" + "u8: 255\n" + "b: false\n" + "s64: -5000000000\n" + "s32: -2000000000\n" + "s16: -32000\n" + "s8: -127\n" + "f: 137.125\n" + "d: -2.8625\n" + "h8: 0xFF\n" + "h16: 0x8765\n" + "h32: 0xFEDCBA98\n" + "h64: 0xFEDCBA9876543210\n" + "...\n"); + yin >> map; + + EXPECT_FALSE(yin.error()); + EXPECT_TRUE(map.str.equals("hello there")); + EXPECT_EQ(map.u64, 5000000000ULL); + EXPECT_EQ(map.u32, 4000000000U); + EXPECT_EQ(map.u16, 65000); + EXPECT_EQ(map.u8, 255); + EXPECT_EQ(map.b, false); + EXPECT_EQ(map.s64, -5000000000LL); + EXPECT_EQ(map.s32, -2000000000L); + EXPECT_EQ(map.s16, -32000); + EXPECT_EQ(map.s8, -127); + EXPECT_EQ(map.f, 137.125); + EXPECT_EQ(map.d, -2.8625); + EXPECT_EQ(map.h8, Hex8(255)); + EXPECT_EQ(map.h16, Hex16(0x8765)); + EXPECT_EQ(map.h32, Hex32(0xFEDCBA98)); + EXPECT_EQ(map.h64, Hex64(0xFEDCBA9876543210LL)); +} + + +// +// Test writing then reading back all built-in scalar types +// +TEST(YAMLIO, TestReadWriteBuiltInTypes) { + std::string intermediate; + { + BuiltInTypes map; + map.str = "one two"; + map.u64 = 6000000000ULL; + map.u32 = 3000000000U; + map.u16 = 50000; + map.u8 = 254; + map.b = true; + map.s64 = -6000000000LL; + map.s32 = -2000000000; + map.s16 = -32000; + map.s8 = -128; + map.f = 3.25; + map.d = -2.8625; + map.h8 = 254; + map.h16 = 50000; + map.h32 = 3000000000U; + map.h64 = 6000000000LL; + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << map; + } + + { + Input yin(intermediate); + BuiltInTypes map; + yin >> map; + + EXPECT_FALSE(yin.error()); + EXPECT_TRUE(map.str.equals("one two")); + EXPECT_EQ(map.u64, 6000000000ULL); + EXPECT_EQ(map.u32, 3000000000U); + EXPECT_EQ(map.u16, 50000); + EXPECT_EQ(map.u8, 254); + EXPECT_EQ(map.b, true); + EXPECT_EQ(map.s64, -6000000000LL); + EXPECT_EQ(map.s32, -2000000000L); + EXPECT_EQ(map.s16, -32000); + EXPECT_EQ(map.s8, -128); + EXPECT_EQ(map.f, 3.25); + EXPECT_EQ(map.d, -2.8625); + EXPECT_EQ(map.h8, Hex8(254)); + EXPECT_EQ(map.h16, Hex16(50000)); + EXPECT_EQ(map.h32, Hex32(3000000000U)); + EXPECT_EQ(map.h64, Hex64(6000000000LL)); + } +} + + + +//===----------------------------------------------------------------------===// +// Test ScalarEnumerationTraits +//===----------------------------------------------------------------------===// + +enum Colors { + cRed, + cBlue, + cGreen, + cYellow +}; + +struct ColorMap { + Colors c1; + Colors c2; + Colors c3; + Colors c4; + Colors c5; + Colors c6; +}; + +namespace llvm { +namespace yaml { + template <> + struct ScalarEnumerationTraits<Colors> { + static void enumeration(IO &io, Colors &value) { + io.enumCase(value, "red", cRed); + io.enumCase(value, "blue", cBlue); + io.enumCase(value, "green", cGreen); + io.enumCase(value, "yellow",cYellow); + } + }; + template <> + struct MappingTraits<ColorMap> { + static void mapping(IO &io, ColorMap& c) { + io.mapRequired("c1", c.c1); + io.mapRequired("c2", c.c2); + io.mapRequired("c3", c.c3); + io.mapOptional("c4", c.c4, cBlue); // supplies default + io.mapOptional("c5", c.c5, cYellow); // supplies default + io.mapOptional("c6", c.c6, cRed); // supplies default + } + }; +} +} + + +// +// Test reading enumerated scalars +// +TEST(YAMLIO, TestEnumRead) { + ColorMap map; + Input yin("---\n" + "c1: blue\n" + "c2: red\n" + "c3: green\n" + "c5: yellow\n" + "...\n"); + yin >> map; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(cBlue, map.c1); + EXPECT_EQ(cRed, map.c2); + EXPECT_EQ(cGreen, map.c3); + EXPECT_EQ(cBlue, map.c4); // tests default + EXPECT_EQ(cYellow,map.c5); // tests overridden + EXPECT_EQ(cRed, map.c6); // tests default +} + + + +//===----------------------------------------------------------------------===// +// Test ScalarBitSetTraits +//===----------------------------------------------------------------------===// + +enum MyFlags { + flagNone = 0, + flagBig = 1 << 0, + flagFlat = 1 << 1, + flagRound = 1 << 2, + flagPointy = 1 << 3 +}; +inline MyFlags operator|(MyFlags a, MyFlags b) { + return static_cast<MyFlags>( + static_cast<uint32_t>(a) | static_cast<uint32_t>(b)); +} + +struct FlagsMap { + MyFlags f1; + MyFlags f2; + MyFlags f3; + MyFlags f4; +}; + + +namespace llvm { +namespace yaml { + template <> + struct ScalarBitSetTraits<MyFlags> { + static void bitset(IO &io, MyFlags &value) { + io.bitSetCase(value, "big", flagBig); + io.bitSetCase(value, "flat", flagFlat); + io.bitSetCase(value, "round", flagRound); + io.bitSetCase(value, "pointy",flagPointy); + } + }; + template <> + struct MappingTraits<FlagsMap> { + static void mapping(IO &io, FlagsMap& c) { + io.mapRequired("f1", c.f1); + io.mapRequired("f2", c.f2); + io.mapRequired("f3", c.f3); + io.mapOptional("f4", c.f4, MyFlags(flagRound)); + } + }; +} +} + + +// +// Test reading flow sequence representing bit-mask values +// +TEST(YAMLIO, TestFlagsRead) { + FlagsMap map; + Input yin("---\n" + "f1: [ big ]\n" + "f2: [ round, flat ]\n" + "f3: []\n" + "...\n"); + yin >> map; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(flagBig, map.f1); + EXPECT_EQ(flagRound|flagFlat, map.f2); + EXPECT_EQ(flagNone, map.f3); // check empty set + EXPECT_EQ(flagRound, map.f4); // check optional key +} + + +// +// Test writing then reading back bit-mask values +// +TEST(YAMLIO, TestReadWriteFlags) { + std::string intermediate; + { + FlagsMap map; + map.f1 = flagBig; + map.f2 = flagRound | flagFlat; + map.f3 = flagNone; + map.f4 = flagNone; + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << map; + } + + { + Input yin(intermediate); + FlagsMap map2; + yin >> map2; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(flagBig, map2.f1); + EXPECT_EQ(flagRound|flagFlat, map2.f2); + EXPECT_EQ(flagNone, map2.f3); + //EXPECT_EQ(flagRound, map2.f4); // check optional key + } +} + + + +//===----------------------------------------------------------------------===// +// Test ScalarTraits +//===----------------------------------------------------------------------===// + +struct MyCustomType { + int length; + int width; +}; + +struct MyCustomTypeMap { + MyCustomType f1; + MyCustomType f2; + int f3; +}; + + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits<MyCustomTypeMap> { + static void mapping(IO &io, MyCustomTypeMap& s) { + io.mapRequired("f1", s.f1); + io.mapRequired("f2", s.f2); + io.mapRequired("f3", s.f3); + } + }; + // MyCustomType is formatted as a yaml scalar. A value of + // {length=3, width=4} would be represented in yaml as "3 by 4". + template<> + struct ScalarTraits<MyCustomType> { + static void output(const MyCustomType &value, void* ctxt, llvm::raw_ostream &out) { + out << llvm::format("%d by %d", value.length, value.width); + } + static StringRef input(StringRef scalar, void* ctxt, MyCustomType &value) { + size_t byStart = scalar.find("by"); + if ( byStart != StringRef::npos ) { + StringRef lenStr = scalar.slice(0, byStart); + lenStr = lenStr.rtrim(); + if ( lenStr.getAsInteger(0, value.length) ) { + return "malformed length"; + } + StringRef widthStr = scalar.drop_front(byStart+2); + widthStr = widthStr.ltrim(); + if ( widthStr.getAsInteger(0, value.width) ) { + return "malformed width"; + } + return StringRef(); + } + else { + return "malformed by"; + } + } + }; +} +} + + +// +// Test writing then reading back custom values +// +TEST(YAMLIO, TestReadWriteMyCustomType) { + std::string intermediate; + { + MyCustomTypeMap map; + map.f1.length = 1; + map.f1.width = 4; + map.f2.length = 100; + map.f2.width = 400; + map.f3 = 10; + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << map; + } + + { + Input yin(intermediate); + MyCustomTypeMap map2; + yin >> map2; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(1, map2.f1.length); + EXPECT_EQ(4, map2.f1.width); + EXPECT_EQ(100, map2.f2.length); + EXPECT_EQ(400, map2.f2.width); + EXPECT_EQ(10, map2.f3); + } +} + + +//===----------------------------------------------------------------------===// +// Test flow sequences +//===----------------------------------------------------------------------===// + +LLVM_YAML_STRONG_TYPEDEF(int, MyNumber) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::StringRef) + +namespace llvm { +namespace yaml { + template<> + struct ScalarTraits<MyNumber> { + static void output(const MyNumber &value, void *, llvm::raw_ostream &out) { + out << value; + } + + static StringRef input(StringRef scalar, void *, MyNumber &value) { + long long n; + if ( getAsSignedInteger(scalar, 0, n) ) + return "invalid number"; + value = n; + return StringRef(); + } + }; +} +} + +struct NameAndNumbers { + llvm::StringRef name; + std::vector<llvm::StringRef> strings; + std::vector<MyNumber> single; + std::vector<MyNumber> numbers; +}; + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits<NameAndNumbers> { + static void mapping(IO &io, NameAndNumbers& nn) { + io.mapRequired("name", nn.name); + io.mapRequired("strings", nn.strings); + io.mapRequired("single", nn.single); + io.mapRequired("numbers", nn.numbers); + } + }; +} +} + + +// +// Test writing then reading back custom values +// +TEST(YAMLIO, TestReadWriteMyFlowSequence) { + std::string intermediate; + { + NameAndNumbers map; + map.name = "hello"; + map.strings.push_back(llvm::StringRef("one")); + map.strings.push_back(llvm::StringRef("two")); + map.single.push_back(1); + map.numbers.push_back(10); + map.numbers.push_back(-30); + map.numbers.push_back(1024); + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << map; + + // Verify sequences were written in flow style + ostr.flush(); + llvm::StringRef flowOut(intermediate); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two")); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024")); + } + + { + Input yin(intermediate); + NameAndNumbers map2; + yin >> map2; + + EXPECT_FALSE(yin.error()); + EXPECT_TRUE(map2.name.equals("hello")); + EXPECT_EQ(map2.strings.size(), 2UL); + EXPECT_TRUE(map2.strings[0].equals("one")); + EXPECT_TRUE(map2.strings[1].equals("two")); + EXPECT_EQ(map2.single.size(), 1UL); + EXPECT_EQ(1, map2.single[0]); + EXPECT_EQ(map2.numbers.size(), 3UL); + EXPECT_EQ(10, map2.numbers[0]); + EXPECT_EQ(-30, map2.numbers[1]); + EXPECT_EQ(1024, map2.numbers[2]); + } +} + + +//===----------------------------------------------------------------------===// +// Test normalizing/denormalizing +//===----------------------------------------------------------------------===// + +LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds) + +typedef std::vector<TotalSeconds> SecondsSequence; + +LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds) + + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits<TotalSeconds> { + + class NormalizedSeconds { + public: + NormalizedSeconds(IO &io) + : hours(0), minutes(0), seconds(0) { + } + NormalizedSeconds(IO &, TotalSeconds &secs) + : hours(secs/3600), + minutes((secs - (hours*3600))/60), + seconds(secs % 60) { + } + TotalSeconds denormalize(IO &) { + return TotalSeconds(hours*3600 + minutes*60 + seconds); + } + + uint32_t hours; + uint8_t minutes; + uint8_t seconds; + }; + + static void mapping(IO &io, TotalSeconds &secs) { + MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs); + + io.mapOptional("hours", keys->hours, (uint32_t)0); + io.mapOptional("minutes", keys->minutes, (uint8_t)0); + io.mapRequired("seconds", keys->seconds); + } + }; +} +} + + +// +// Test the reading of a yaml sequence of mappings +// +TEST(YAMLIO, TestReadMySecondsSequence) { + SecondsSequence seq; + Input yin("---\n - hours: 1\n seconds: 5\n - seconds: 59\n...\n"); + yin >> seq; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(seq.size(), 2UL); + EXPECT_EQ(seq[0], 3605U); + EXPECT_EQ(seq[1], 59U); +} + + +// +// Test writing then reading back custom values +// +TEST(YAMLIO, TestReadWriteMySecondsSequence) { + std::string intermediate; + { + SecondsSequence seq; + seq.push_back(4000); + seq.push_back(500); + seq.push_back(59); + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << seq; + } + { + Input yin(intermediate); + SecondsSequence seq2; + yin >> seq2; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(seq2.size(), 3UL); + EXPECT_EQ(seq2[0], 4000U); + EXPECT_EQ(seq2[1], 500U); + EXPECT_EQ(seq2[2], 59U); + } +} + + +//===----------------------------------------------------------------------===// +// Test dynamic typing +//===----------------------------------------------------------------------===// + +enum AFlags { + a1, + a2, + a3 +}; + +enum BFlags { + b1, + b2, + b3 +}; + +enum Kind { + kindA, + kindB +}; + +struct KindAndFlags { + KindAndFlags() : kind(kindA), flags(0) { } + KindAndFlags(Kind k, uint32_t f) : kind(k), flags(f) { } + Kind kind; + uint32_t flags; +}; + +typedef std::vector<KindAndFlags> KindAndFlagsSequence; + +LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags) + +namespace llvm { +namespace yaml { + template <> + struct ScalarEnumerationTraits<AFlags> { + static void enumeration(IO &io, AFlags &value) { + io.enumCase(value, "a1", a1); + io.enumCase(value, "a2", a2); + io.enumCase(value, "a3", a3); + } + }; + template <> + struct ScalarEnumerationTraits<BFlags> { + static void enumeration(IO &io, BFlags &value) { + io.enumCase(value, "b1", b1); + io.enumCase(value, "b2", b2); + io.enumCase(value, "b3", b3); + } + }; + template <> + struct ScalarEnumerationTraits<Kind> { + static void enumeration(IO &io, Kind &value) { + io.enumCase(value, "A", kindA); + io.enumCase(value, "B", kindB); + } + }; + template <> + struct MappingTraits<KindAndFlags> { + static void mapping(IO &io, KindAndFlags& kf) { + io.mapRequired("kind", kf.kind); + // Type of "flags" field varies depending on "kind" field. + // Use memcpy here to avoid breaking strict aliasing rules. + if (kf.kind == kindA) { + AFlags aflags = static_cast<AFlags>(kf.flags); + io.mapRequired("flags", aflags); + kf.flags = aflags; + } else { + BFlags bflags = static_cast<BFlags>(kf.flags); + io.mapRequired("flags", bflags); + kf.flags = bflags; + } + } + }; +} +} + + +// +// Test the reading of a yaml sequence dynamic types +// +TEST(YAMLIO, TestReadKindAndFlagsSequence) { + KindAndFlagsSequence seq; + Input yin("---\n - kind: A\n flags: a2\n - kind: B\n flags: b1\n...\n"); + yin >> seq; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(seq.size(), 2UL); + EXPECT_EQ(seq[0].kind, kindA); + EXPECT_EQ(seq[0].flags, (uint32_t)a2); + EXPECT_EQ(seq[1].kind, kindB); + EXPECT_EQ(seq[1].flags, (uint32_t)b1); +} + +// +// Test writing then reading back dynamic types +// +TEST(YAMLIO, TestReadWriteKindAndFlagsSequence) { + std::string intermediate; + { + KindAndFlagsSequence seq; + seq.push_back(KindAndFlags(kindA,a1)); + seq.push_back(KindAndFlags(kindB,b1)); + seq.push_back(KindAndFlags(kindA,a2)); + seq.push_back(KindAndFlags(kindB,b2)); + seq.push_back(KindAndFlags(kindA,a3)); + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << seq; + } + { + Input yin(intermediate); + KindAndFlagsSequence seq2; + yin >> seq2; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(seq2.size(), 5UL); + EXPECT_EQ(seq2[0].kind, kindA); + EXPECT_EQ(seq2[0].flags, (uint32_t)a1); + EXPECT_EQ(seq2[1].kind, kindB); + EXPECT_EQ(seq2[1].flags, (uint32_t)b1); + EXPECT_EQ(seq2[2].kind, kindA); + EXPECT_EQ(seq2[2].flags, (uint32_t)a2); + EXPECT_EQ(seq2[3].kind, kindB); + EXPECT_EQ(seq2[3].flags, (uint32_t)b2); + EXPECT_EQ(seq2[4].kind, kindA); + EXPECT_EQ(seq2[4].flags, (uint32_t)a3); + } +} + + +//===----------------------------------------------------------------------===// +// Test document list +//===----------------------------------------------------------------------===// + +struct FooBarMap { + int foo; + int bar; +}; +typedef std::vector<FooBarMap> FooBarMapDocumentList; + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(FooBarMap) + + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits<FooBarMap> { + static void mapping(IO &io, FooBarMap& fb) { + io.mapRequired("foo", fb.foo); + io.mapRequired("bar", fb.bar); + } + }; +} +} + + +// +// Test the reading of a yaml mapping +// +TEST(YAMLIO, TestDocRead) { + FooBarMap doc; + Input yin("---\nfoo: 3\nbar: 5\n...\n"); + yin >> doc; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(doc.foo, 3); + EXPECT_EQ(doc.bar,5); +} + + + +// +// Test writing then reading back a sequence of mappings +// +TEST(YAMLIO, TestSequenceDocListWriteAndRead) { + std::string intermediate; + { + FooBarMap doc1; + doc1.foo = 10; + doc1.bar = -3; + FooBarMap doc2; + doc2.foo = 257; + doc2.bar = 0; + std::vector<FooBarMap> docList; + docList.push_back(doc1); + docList.push_back(doc2); + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << docList; + } + + + { + Input yin(intermediate); + std::vector<FooBarMap> docList2; + yin >> docList2; + + EXPECT_FALSE(yin.error()); + EXPECT_EQ(docList2.size(), 2UL); + FooBarMap& map1 = docList2[0]; + FooBarMap& map2 = docList2[1]; + EXPECT_EQ(map1.foo, 10); + EXPECT_EQ(map1.bar, -3); + EXPECT_EQ(map2.foo, 257); + EXPECT_EQ(map2.bar, 0); + } +} + + +//===----------------------------------------------------------------------===// +// Test error handling +//===----------------------------------------------------------------------===// + + + +static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) { +} + + +// +// Test error handling of unknown enumerated scalar +// +TEST(YAMLIO, TestColorsReadError) { + ColorMap map; + Input yin("---\n" + "c1: blue\n" + "c2: purple\n" + "c3: green\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> map; + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling of flow sequence with unknown value +// +TEST(YAMLIO, TestFlagsReadError) { + FlagsMap map; + Input yin("---\n" + "f1: [ big ]\n" + "f2: [ round, hollow ]\n" + "f3: []\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> map; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in uint8_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t) +TEST(YAMLIO, TestReadBuiltInTypesUint8Error) { + std::vector<uint8_t> seq; + Input yin("---\n" + "- 255\n" + "- 0\n" + "- 257\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in uint16_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(uint16_t) +TEST(YAMLIO, TestReadBuiltInTypesUint16Error) { + std::vector<uint16_t> seq; + Input yin("---\n" + "- 65535\n" + "- 0\n" + "- 66000\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in uint32_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(uint32_t) +TEST(YAMLIO, TestReadBuiltInTypesUint32Error) { + std::vector<uint32_t> seq; + Input yin("---\n" + "- 4000000000\n" + "- 0\n" + "- 5000000000\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in uint64_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(uint64_t) +TEST(YAMLIO, TestReadBuiltInTypesUint64Error) { + std::vector<uint64_t> seq; + Input yin("---\n" + "- 18446744073709551615\n" + "- 0\n" + "- 19446744073709551615\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in int8_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(int8_t) +TEST(YAMLIO, TestReadBuiltInTypesint8OverError) { + std::vector<int8_t> seq; + Input yin("---\n" + "- -128\n" + "- 0\n" + "- 127\n" + "- 128\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in int8_t type +// +TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) { + std::vector<int8_t> seq; + Input yin("---\n" + "- -128\n" + "- 0\n" + "- 127\n" + "- -129\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in int16_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(int16_t) +TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) { + std::vector<int16_t> seq; + Input yin("---\n" + "- 32767\n" + "- 0\n" + "- -32768\n" + "- -32769\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in int16_t type +// +TEST(YAMLIO, TestReadBuiltInTypesint16OverError) { + std::vector<int16_t> seq; + Input yin("---\n" + "- 32767\n" + "- 0\n" + "- -32768\n" + "- 32768\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in int32_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(int32_t) +TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) { + std::vector<int32_t> seq; + Input yin("---\n" + "- 2147483647\n" + "- 0\n" + "- -2147483648\n" + "- -2147483649\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in int32_t type +// +TEST(YAMLIO, TestReadBuiltInTypesint32OverError) { + std::vector<int32_t> seq; + Input yin("---\n" + "- 2147483647\n" + "- 0\n" + "- -2147483648\n" + "- 2147483649\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in int64_t type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t) +TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) { + std::vector<int64_t> seq; + Input yin("---\n" + "- -9223372036854775808\n" + "- 0\n" + "- 9223372036854775807\n" + "- -9223372036854775809\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in int64_t type +// +TEST(YAMLIO, TestReadBuiltInTypesint64OverError) { + std::vector<int64_t> seq; + Input yin("---\n" + "- -9223372036854775808\n" + "- 0\n" + "- 9223372036854775807\n" + "- 9223372036854775809\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in float type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(float) +TEST(YAMLIO, TestReadBuiltInTypesFloatError) { + std::vector<float> seq; + Input yin("---\n" + "- 0.0\n" + "- 1000.1\n" + "- -123.456\n" + "- 1.2.3\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in float type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(double) +TEST(YAMLIO, TestReadBuiltInTypesDoubleError) { + std::vector<double> seq; + Input yin("---\n" + "- 0.0\n" + "- 1000.1\n" + "- -123.456\n" + "- 1.2.3\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in Hex8 type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8) +TEST(YAMLIO, TestReadBuiltInTypesHex8Error) { + std::vector<Hex8> seq; + Input yin("---\n" + "- 0x12\n" + "- 0xFE\n" + "- 0x123\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + + +// +// Test error handling reading built-in Hex16 type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16) +TEST(YAMLIO, TestReadBuiltInTypesHex16Error) { + std::vector<Hex16> seq; + Input yin("---\n" + "- 0x0012\n" + "- 0xFEFF\n" + "- 0x12345\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in Hex32 type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32) +TEST(YAMLIO, TestReadBuiltInTypesHex32Error) { + std::vector<Hex32> seq; + Input yin("---\n" + "- 0x0012\n" + "- 0xFEFF0000\n" + "- 0x1234556789\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + +// +// Test error handling reading built-in Hex64 type +// +LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64) +TEST(YAMLIO, TestReadBuiltInTypesHex64Error) { + std::vector<Hex64> seq; + Input yin("---\n" + "- 0x0012\n" + "- 0xFFEEDDCCBBAA9988\n" + "- 0x12345567890ABCDEF0\n" + "...\n"); + yin.setDiagHandler(suppressErrorMessages); + yin >> seq; + + EXPECT_TRUE(yin.error()); +} + diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp index 480a573..e983935 100644 --- a/unittests/Support/YAMLParserTest.cpp +++ b/unittests/Support/YAMLParserTest.cpp @@ -10,6 +10,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLParser.h" #include "gtest/gtest.h" @@ -21,6 +22,12 @@ static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) { // to reduce noise in unit test runs. } +// Assumes Ctx is an SMDiagnostic where Diag can be stored. +static void CollectDiagnosticsOutput(const SMDiagnostic &Diag, void *Ctx) { + SMDiagnostic* DiagOut = static_cast<SMDiagnostic*>(Ctx); + *DiagOut = Diag; +} + // 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) { @@ -182,4 +189,31 @@ TEST(YAMLParser, WorksWithIteratorAlgorithms) { EXPECT_EQ(6, std::distance(Array->begin(), Array->end())); } +TEST(YAMLParser, DefaultDiagnosticFilename) { + SourceMgr SM; + + SMDiagnostic GeneratedDiag; + SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag); + + // When we construct a YAML stream over an unnamed string, + // the filename is hard-coded as "YAML". + yaml::Stream UnnamedStream("[]", SM); + UnnamedStream.printError(UnnamedStream.begin()->getRoot(), "Hello, World!"); + EXPECT_EQ("YAML", GeneratedDiag.getFilename()); +} + +TEST(YAMLParser, DiagnosticFilenameFromBufferID) { + SourceMgr SM; + + SMDiagnostic GeneratedDiag; + SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag); + + // When we construct a YAML stream over a named buffer, + // we get its ID as filename in diagnostics. + MemoryBuffer* Buffer = MemoryBuffer::getMemBuffer("[]", "buffername.yaml"); + yaml::Stream Stream(Buffer, SM); + Stream.printError(Stream.begin()->getRoot(), "Hello, World!"); + EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename()); +} + } // end namespace llvm diff --git a/unittests/Support/formatted_raw_ostream_test.cpp b/unittests/Support/formatted_raw_ostream_test.cpp index 4725ced..9bb8046 100644 --- a/unittests/Support/formatted_raw_ostream_test.cpp +++ b/unittests/Support/formatted_raw_ostream_test.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/FormattedStream.h" +#include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp index ea3d5be..cd304e7 100644 --- a/unittests/Transforms/Utils/Cloning.cpp +++ b/unittests/Transforms/Utils/Cloning.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" -#include "llvm/Argument.h" -#include "llvm/Constant.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Instructions.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Argument.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/LLVMContext.h" +#include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/Transforms/Utils/IntegerDivision.cpp b/unittests/Transforms/Utils/IntegerDivision.cpp index a321139..44c2328 100644 --- a/unittests/Transforms/Utils/IntegerDivision.cpp +++ b/unittests/Transforms/Utils/IntegerDivision.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" -#include "llvm/BasicBlock.h" -#include "llvm/GlobalValue.h" -#include "llvm/Function.h" -#include "llvm/IRBuilder.h" -#include "llvm/Module.h" #include "llvm/Transforms/Utils/IntegerDivision.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Module.h" +#include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/Transforms/Utils/Local.cpp b/unittests/Transforms/Utils/Local.cpp index 727f5ea..f0c3ecf 100644 --- a/unittests/Transforms/Utils/Local.cpp +++ b/unittests/Transforms/Utils/Local.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/BasicBlock.h" -#include "llvm/IRBuilder.h" -#include "llvm/Instructions.h" -#include "llvm/LLVMContext.h" #include "llvm/Transforms/Utils/Local.h" - +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" using namespace llvm; diff --git a/unittests/VMCore/ConstantsTest.cpp b/unittests/VMCore/ConstantsTest.cpp deleted file mode 100644 index 623ea0d..0000000 --- a/unittests/VMCore/ConstantsTest.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//===- 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 "llvm/LLVMContext.h" -#include "gtest/gtest.h" - -namespace llvm { -namespace { - -TEST(ConstantsTest, Integer_i1) { - IntegerType* Int1 = IntegerType::get(getGlobalContext(), 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) { - IntegerType* Int8Ty = Type::getInt8Ty(getGlobalContext()); - 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()); -} - -TEST(ConstantsTest, FP128Test) { - Type *FP128Ty = Type::getFP128Ty(getGlobalContext()); - - IntegerType *Int128Ty = Type::getIntNTy(getGlobalContext(), 128); - Constant *Zero128 = Constant::getNullValue(Int128Ty); - Constant *X = ConstantExpr::getUIToFP(Zero128, FP128Ty); - EXPECT_TRUE(isa<ConstantFP>(X)); -} - -} // end anonymous namespace -} // end namespace llvm |