aboutsummaryrefslogtreecommitdiffstats
path: root/unittests
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-12-01 14:51:49 -0800
committerStephen Hines <srhines@google.com>2014-12-02 16:08:10 -0800
commit37ed9c199ca639565f6ce88105f9e39e898d82d0 (patch)
tree8fb36d3910e3ee4c4e1b7422f4f017108efc52f5 /unittests
parentd2327b22152ced7bc46dc629fc908959e8a52d03 (diff)
downloadexternal_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.zip
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.gz
external_llvm-37ed9c199ca639565f6ce88105f9e39e898d82d0.tar.bz2
Update aosp/master LLVM for rebase to r222494.
Change-Id: Ic787f5e0124df789bd26f3f24680f45e678eef2d
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ADT/APFloatTest.cpp164
-rw-r--r--unittests/ADT/APIntTest.cpp25
-rw-r--r--unittests/ADT/ArrayRefTest.cpp53
-rw-r--r--unittests/ADT/CMakeLists.txt2
-rw-r--r--unittests/ADT/DenseMapTest.cpp5
-rw-r--r--unittests/ADT/DenseSetTest.cpp38
-rw-r--r--unittests/ADT/FunctionRefTest.cpp28
-rw-r--r--unittests/ADT/MapVectorTest.cpp69
-rw-r--r--unittests/ADT/OptionalTest.cpp99
-rw-r--r--unittests/ADT/PostOrderIteratorTest.cpp37
-rw-r--r--unittests/ADT/StringMapTest.cpp22
-rw-r--r--unittests/ADT/TripleTest.cpp102
-rw-r--r--unittests/Analysis/CFGTest.cpp10
-rw-r--r--unittests/Analysis/CMakeLists.txt2
-rw-r--r--unittests/Analysis/CallGraphTest.cpp59
-rw-r--r--unittests/Analysis/LazyCallGraphTest.cpp40
-rw-r--r--unittests/Analysis/Makefile2
-rw-r--r--unittests/Analysis/MixedTBAATest.cpp2
-rw-r--r--unittests/Bitcode/BitReaderTest.cpp160
-rw-r--r--unittests/Bitcode/BitstreamReaderTest.cpp56
-rw-r--r--unittests/Bitcode/CMakeLists.txt2
-rw-r--r--unittests/Bitcode/Makefile2
-rw-r--r--unittests/ExecutionEngine/CMakeLists.txt4
-rw-r--r--unittests/ExecutionEngine/ExecutionEngineTest.cpp48
-rw-r--r--unittests/ExecutionEngine/JIT/CMakeLists.txt64
-rw-r--r--unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp113
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp237
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h207
-rw-r--r--unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp302
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp728
-rw-r--r--unittests/ExecutionEngine/JIT/JITTests.def4
-rw-r--r--unittests/ExecutionEngine/JIT/Makefile52
-rw-r--r--unittests/ExecutionEngine/JIT/MultiJITTest.cpp190
-rw-r--r--unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp165
-rw-r--r--unittests/ExecutionEngine/MCJIT/CMakeLists.txt2
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp2
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp1
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp60
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp39
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTest.cpp22
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h6
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h22
-rw-r--r--unittests/ExecutionEngine/MCJIT/Makefile2
-rw-r--r--unittests/ExecutionEngine/Makefile2
-rw-r--r--unittests/IR/CMakeLists.txt2
-rw-r--r--unittests/IR/ConstantsTest.cpp73
-rw-r--r--unittests/IR/DebugInfoTest.cpp68
-rw-r--r--unittests/IR/DominatorTreeTest.cpp7
-rw-r--r--unittests/IR/IRBuilderTest.cpp4
-rw-r--r--unittests/IR/LegacyPassManagerTest.cpp52
-rw-r--r--unittests/IR/PassManagerTest.cpp2
-rw-r--r--unittests/IR/UseTest.cpp112
-rw-r--r--unittests/IR/UserTest.cpp2
-rw-r--r--unittests/IR/ValueMapTest.cpp4
-rw-r--r--unittests/IR/ValueTest.cpp25
-rw-r--r--unittests/LineEditor/CMakeLists.txt1
-rw-r--r--unittests/Linker/CMakeLists.txt1
-rw-r--r--unittests/Linker/LinkModulesTest.cpp44
-rw-r--r--unittests/Linker/Makefile2
-rw-r--r--unittests/MC/CMakeLists.txt13
-rw-r--r--unittests/MC/Disassembler.cpp64
-rw-r--r--unittests/MC/Hexagon/CMakeLists.txt14
-rw-r--r--unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp53
-rw-r--r--unittests/MC/MCAtomTest.cpp31
-rw-r--r--unittests/MC/Makefile2
-rw-r--r--unittests/MC/StringTableBuilderTest.cpp35
-rw-r--r--unittests/Support/AllocatorTest.cpp43
-rw-r--r--unittests/Support/CMakeLists.txt5
-rw-r--r--unittests/Support/CommandLineTest.cpp25
-rw-r--r--unittests/Support/ConvertUTFTest.cpp16
-rw-r--r--unittests/Support/ErrorOrTest.cpp31
-rw-r--r--unittests/Support/FileOutputBufferTest.cpp6
-rw-r--r--unittests/Support/LEB128Test.cpp37
-rw-r--r--unittests/Support/LineIteratorTest.cpp130
-rw-r--r--unittests/Support/LockFileManagerTest.cpp4
-rw-r--r--unittests/Support/MD5Test.cpp16
-rw-r--r--unittests/Support/MemoryBufferTest.cpp50
-rw-r--r--unittests/Support/Path.cpp129
-rw-r--r--unittests/Support/ProcessTest.cpp12
-rw-r--r--unittests/Support/ProgramTest.cpp50
-rw-r--r--unittests/Support/SourceMgrTest.cpp5
-rw-r--r--unittests/Support/SpecialCaseListTest.cpp51
-rw-r--r--unittests/Support/YAMLIOTest.cpp7
-rw-r--r--unittests/Support/YAMLParserTest.cpp7
-rw-r--r--unittests/Support/raw_ostream_test.cpp37
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp7
86 files changed, 2086 insertions, 2444 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index 8f298cd..c7ec16b 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -474,6 +474,40 @@ TEST(APFloatTest, FMA) {
f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
EXPECT_EQ(12.0f, f1.convertToFloat());
}
+
+ {
+ APFloat M1(APFloat::x87DoubleExtended, 1.0);
+ APFloat M2(APFloat::x87DoubleExtended, 1.0);
+ APFloat A(APFloat::x87DoubleExtended, 3.0);
+
+ bool losesInfo = false;
+ M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven);
+ M1.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo);
+ EXPECT_FALSE(losesInfo);
+ EXPECT_EQ(4.0f, M1.convertToFloat());
+ }
+}
+
+TEST(APFloatTest, MinNum) {
+ APFloat f1(1.0);
+ APFloat f2(2.0);
+ APFloat nan = APFloat::getNaN(APFloat::IEEEdouble);
+
+ EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble());
+ EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble());
+ EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble());
+ EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
+}
+
+TEST(APFloatTest, MaxNum) {
+ APFloat f1(1.0);
+ APFloat f2(2.0);
+ APFloat nan = APFloat::getNaN(APFloat::IEEEdouble);
+
+ EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble());
+ EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble());
+ EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble());
+ EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
}
TEST(APFloatTest, Denormal) {
@@ -1342,6 +1376,17 @@ TEST(APFloatTest, getZero) {
}
}
+TEST(APFloatTest, copySign) {
+ EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
+ APFloat::copySign(APFloat(42.0), APFloat(-1.0))));
+ EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
+ APFloat::copySign(APFloat(-42.0), APFloat(1.0))));
+ EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
+ APFloat::copySign(APFloat(-42.0), APFloat(-1.0))));
+ EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
+ APFloat::copySign(APFloat(42.0), APFloat(1.0))));
+}
+
TEST(APFloatTest, convert) {
bool losesInfo;
APFloat test(APFloat::IEEEdouble, "1.0");
@@ -2671,4 +2716,123 @@ TEST(APFloatTest, divide) {
}
}
+TEST(APFloatTest, operatorOverloads) {
+ // This is mostly testing that these operator overloads compile.
+ APFloat One = APFloat(APFloat::IEEEsingle, "0x1p+0");
+ APFloat Two = APFloat(APFloat::IEEEsingle, "0x2p+0");
+ EXPECT_TRUE(Two.bitwiseIsEqual(One + One));
+ EXPECT_TRUE(One.bitwiseIsEqual(Two - One));
+ EXPECT_TRUE(Two.bitwiseIsEqual(One * Two));
+ EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
+}
+
+TEST(APFloatTest, abs) {
+ APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
+ APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
+ APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
+ APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
+ APFloat PQNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
+ APFloat MQNaN = APFloat::getNaN(APFloat::IEEEsingle, true);
+ APFloat PSNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
+ APFloat MSNaN = APFloat::getSNaN(APFloat::IEEEsingle, true);
+ APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
+ APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
+ APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
+ APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
+ APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
+ APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
+ APFloat PSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
+ APFloat MSmallestNormalized =
+ APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
+
+ EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf)));
+ EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf)));
+ EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero)));
+ EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero)));
+ EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN)));
+ EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN)));
+ EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN)));
+ EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN)));
+ EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue)));
+ EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue)));
+ EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue)));
+ EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue)));
+ EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue)));
+ EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue)));
+ EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized)));
+ EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
+}
+
+TEST(APFloatTest, ilogb) {
+ EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+0")));
+ EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "-0x1p+0")));
+ EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+42")));
+ EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p-42")));
+
+ EXPECT_EQ(APFloat::IEK_Inf,
+ ilogb(APFloat::getInf(APFloat::IEEEsingle, false)));
+ EXPECT_EQ(APFloat::IEK_Inf,
+ ilogb(APFloat::getInf(APFloat::IEEEsingle, true)));
+ EXPECT_EQ(APFloat::IEK_Zero,
+ ilogb(APFloat::getZero(APFloat::IEEEsingle, false)));
+ EXPECT_EQ(APFloat::IEK_Zero,
+ ilogb(APFloat::getZero(APFloat::IEEEsingle, true)));
+ EXPECT_EQ(APFloat::IEK_NaN,
+ ilogb(APFloat::getNaN(APFloat::IEEEsingle, false)));
+ EXPECT_EQ(APFloat::IEK_NaN,
+ ilogb(APFloat::getSNaN(APFloat::IEEEsingle, false)));
+
+ EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, false)));
+ EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, true)));
+ EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, false)));
+ EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, true)));
+ EXPECT_EQ(-126,
+ ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, false)));
+ EXPECT_EQ(-126,
+ ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, true)));
+}
+
+TEST(APFloatTest, scalbn) {
+ EXPECT_TRUE(
+ APFloat(APFloat::IEEEsingle, "0x1p+0")
+ .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 0)));
+ EXPECT_TRUE(
+ APFloat(APFloat::IEEEsingle, "0x1p+42")
+ .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 42)));
+ EXPECT_TRUE(
+ APFloat(APFloat::IEEEsingle, "0x1p-42")
+ .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), -42)));
+
+ APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
+ APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
+ APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
+ APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
+ APFloat QPNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
+ APFloat QMNaN = APFloat::getNaN(APFloat::IEEEsingle, true);
+ APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
+
+ EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0)));
+ EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0)));
+ EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0)));
+ EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0)));
+ EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0)));
+ EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0)));
+ EXPECT_TRUE(SNaN.bitwiseIsEqual(scalbn(SNaN, 0)));
+
+ EXPECT_TRUE(
+ PInf.bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 128)));
+ EXPECT_TRUE(MInf.bitwiseIsEqual(
+ scalbn(APFloat(APFloat::IEEEsingle, "-0x1p+0"), 128)));
+ EXPECT_TRUE(
+ PInf.bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+127"), 1)));
+ EXPECT_TRUE(PZero.bitwiseIsEqual(
+ scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), -127)));
+ EXPECT_TRUE(MZero.bitwiseIsEqual(
+ scalbn(APFloat(APFloat::IEEEsingle, "-0x1p+0"), -127)));
+ EXPECT_TRUE(PZero.bitwiseIsEqual(
+ scalbn(APFloat(APFloat::IEEEsingle, "0x1p-126"), -1)));
+ EXPECT_TRUE(PZero.bitwiseIsEqual(
+ scalbn(APFloat(APFloat::IEEEsingle, "0x1p-126"), -1)));
+}
}
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 19c47ab..8198c71 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -614,7 +614,7 @@ TEST(APIntTest, arrayAccess) {
0x7E7FFA5EADD8846ULL,
0x305F341CA00B613DULL
};
- APInt A2(integerPartWidth*4, ArrayRef<integerPart>(E2, 4));
+ APInt A2(integerPartWidth*4, E2);
for (unsigned i = 0; i < 4; ++i) {
for (unsigned j = 0; j < integerPartWidth; ++j) {
EXPECT_EQ(bool(E2[i] & (1ULL << j)),
@@ -653,17 +653,17 @@ TEST(APIntTest, nearestLogBase2) {
// Test round up.
integerPart I4[4] = {0x0, 0xF, 0x18, 0x0};
- APInt A4(integerPartWidth*4, ArrayRef<integerPart>(I4, 4));
+ APInt A4(integerPartWidth*4, I4);
EXPECT_EQ(A4.nearestLogBase2(), A4.ceilLogBase2());
// Test round down.
integerPart I5[4] = {0x0, 0xF, 0x10, 0x0};
- APInt A5(integerPartWidth*4, ArrayRef<integerPart>(I5, 4));
+ APInt A5(integerPartWidth*4, I5);
EXPECT_EQ(A5.nearestLogBase2(), A5.logBase2());
// Test ties round up.
uint64_t I6[4] = {0x0, 0x0, 0x0, 0x18};
- APInt A6(integerPartWidth*4, ArrayRef<integerPart>(I6, 4));
+ APInt A6(integerPartWidth*4, I6);
EXPECT_EQ(A6.nearestLogBase2(), A6.ceilLogBase2());
// Test BitWidth == 1 special cases.
@@ -678,4 +678,21 @@ TEST(APIntTest, nearestLogBase2) {
EXPECT_EQ(A9.nearestLogBase2(), UINT32_MAX);
}
+TEST(APIntTest, SelfMoveAssignment) {
+ APInt X(32, 0xdeadbeef);
+ X = std::move(X);
+ EXPECT_EQ(32u, X.getBitWidth());
+ EXPECT_EQ(0xdeadbeefULL, X.getLimitedValue());
+
+ uint64_t Bits[] = {0xdeadbeefdeadbeefULL, 0xdeadbeefdeadbeefULL};
+ APInt Y(128, Bits);
+ Y = std::move(Y);
+ EXPECT_EQ(128u, Y.getBitWidth());
+ EXPECT_EQ(~0ULL, Y.getLimitedValue());
+ const uint64_t *Raw = Y.getRawData();
+ EXPECT_EQ(2u, Y.getNumWords());
+ EXPECT_EQ(0xdeadbeefdeadbeefULL, Raw[0]);
+ EXPECT_EQ(0xdeadbeefdeadbeefULL, Raw[1]);
+}
+
}
diff --git a/unittests/ADT/ArrayRefTest.cpp b/unittests/ADT/ArrayRefTest.cpp
index 293afc6..f9c98a5 100644
--- a/unittests/ADT/ArrayRefTest.cpp
+++ b/unittests/ADT/ArrayRefTest.cpp
@@ -13,6 +13,23 @@
#include "gtest/gtest.h"
using namespace llvm;
+// Check that the ArrayRef-of-pointer converting constructor only allows adding
+// cv qualifiers (not removing them, or otherwise changing the type)
+static_assert(
+ std::is_convertible<ArrayRef<int *>, ArrayRef<const int *>>::value,
+ "Adding const");
+static_assert(
+ std::is_convertible<ArrayRef<int *>, ArrayRef<volatile int *>>::value,
+ "Adding volatile");
+static_assert(!std::is_convertible<ArrayRef<int *>, ArrayRef<float *>>::value,
+ "Changing pointer of one type to a pointer of another");
+static_assert(
+ !std::is_convertible<ArrayRef<const int *>, ArrayRef<int *>>::value,
+ "Removing const");
+static_assert(
+ !std::is_convertible<ArrayRef<volatile int *>, ArrayRef<int *>>::value,
+ "Removing volatile");
+
namespace llvm {
TEST(ArrayRefTest, AllocatorCopy) {
@@ -36,5 +53,41 @@ TEST(ArrayRefTest, DropBack) {
EXPECT_TRUE(AR1.drop_back().equals(AR2));
}
+TEST(ArrayRefTest, Equals) {
+ static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ ArrayRef<int> AR1(A1);
+ EXPECT_TRUE(AR1.equals(1, 2, 3, 4, 5, 6, 7, 8));
+ EXPECT_FALSE(AR1.equals(8, 1, 2, 4, 5, 6, 6, 7));
+ EXPECT_FALSE(AR1.equals(2, 4, 5, 6, 6, 7, 8, 1));
+ EXPECT_FALSE(AR1.equals(0, 1, 2, 4, 5, 6, 6, 7));
+ EXPECT_FALSE(AR1.equals(1, 2, 42, 4, 5, 6, 7, 8));
+ EXPECT_FALSE(AR1.equals(42, 2, 3, 4, 5, 6, 7, 8));
+ EXPECT_FALSE(AR1.equals(1, 2, 3, 4, 5, 6, 7, 42));
+ EXPECT_FALSE(AR1.equals(1, 2, 3, 4, 5, 6, 7));
+ EXPECT_FALSE(AR1.equals(1, 2, 3, 4, 5, 6, 7, 8, 9));
+
+ ArrayRef<int> AR1a = AR1.drop_back();
+ EXPECT_TRUE(AR1a.equals(1, 2, 3, 4, 5, 6, 7));
+ EXPECT_FALSE(AR1a.equals(1, 2, 3, 4, 5, 6, 7, 8));
+
+ ArrayRef<int> AR1b = AR1a.slice(2, 4);
+ EXPECT_TRUE(AR1b.equals(3, 4, 5, 6));
+ EXPECT_FALSE(AR1b.equals(2, 3, 4, 5, 6));
+ EXPECT_FALSE(AR1b.equals(3, 4, 5, 6, 7));
+}
+
+TEST(ArrayRefTest, EmptyEquals) {
+ EXPECT_TRUE(ArrayRef<unsigned>() == ArrayRef<unsigned>());
+}
+
+TEST(ArrayRefTest, ConstConvert) {
+ int buf[4];
+ for (int i = 0; i < 4; ++i)
+ buf[i] = i;
+
+ static int *A[] = {&buf[0], &buf[1], &buf[2], &buf[3]};
+ ArrayRef<const int *> a((ArrayRef<int *>(A)));
+ a = ArrayRef<int *>(A);
+}
} // end anonymous namespace
diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt
index 0f214f3..d899852 100644
--- a/unittests/ADT/CMakeLists.txt
+++ b/unittests/ADT/CMakeLists.txt
@@ -13,6 +13,7 @@ set(ADTSources
DenseMapTest.cpp
DenseSetTest.cpp
FoldingSet.cpp
+ FunctionRefTest.cpp
HashingTest.cpp
ilistTest.cpp
ImmutableMapTest.cpp
@@ -26,6 +27,7 @@ set(ADTSources
PackedVectorTest.cpp
PointerIntPairTest.cpp
PointerUnionTest.cpp
+ PostOrderIteratorTest.cpp
SCCIteratorTest.cpp
SmallPtrSetTest.cpp
SmallStringTest.cpp
diff --git a/unittests/ADT/DenseMapTest.cpp b/unittests/ADT/DenseMapTest.cpp
index 75a910a..f497983 100644
--- a/unittests/ADT/DenseMapTest.cpp
+++ b/unittests/ADT/DenseMapTest.cpp
@@ -244,6 +244,11 @@ TYPED_TEST(DenseMapTest, AssignmentTest) {
EXPECT_EQ(1u, copyMap.size());
EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
+
+ // test self-assignment.
+ copyMap = copyMap;
+ EXPECT_EQ(1u, copyMap.size());
+ EXPECT_EQ(this->getValue(), copyMap[this->getKey()]);
}
// Test swap method
diff --git a/unittests/ADT/DenseSetTest.cpp b/unittests/ADT/DenseSetTest.cpp
index 154c589..5952353 100644
--- a/unittests/ADT/DenseSetTest.cpp
+++ b/unittests/ADT/DenseSetTest.cpp
@@ -27,4 +27,42 @@ TEST_F(DenseSetTest, DoubleEntrySetTest) {
EXPECT_EQ(0u, set.count(2));
}
+struct TestDenseSetInfo {
+ static inline unsigned getEmptyKey() { return ~0; }
+ static inline unsigned getTombstoneKey() { return ~0U - 1; }
+ static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
+ static unsigned getHashValue(const char* Val) {
+ return (unsigned)(Val[0] - 'a') * 37U;
+ }
+ static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
+ return LHS == RHS;
+ }
+ static bool isEqual(const char* LHS, const unsigned& RHS) {
+ return (unsigned)(LHS[0] - 'a') == RHS;
+ }
+};
+
+TEST(DenseSetCustomTest, FindAsTest) {
+ DenseSet<unsigned, TestDenseSetInfo> set;
+ set.insert(0);
+ set.insert(1);
+ set.insert(2);
+
+ // Size tests
+ EXPECT_EQ(3u, set.size());
+
+ // Normal lookup tests
+ EXPECT_EQ(1u, set.count(1));
+ EXPECT_EQ(0u, *set.find(0));
+ EXPECT_EQ(1u, *set.find(1));
+ EXPECT_EQ(2u, *set.find(2));
+ EXPECT_TRUE(set.find(3) == set.end());
+
+ // find_as() tests
+ EXPECT_EQ(0u, *set.find_as("a"));
+ EXPECT_EQ(1u, *set.find_as("b"));
+ EXPECT_EQ(2u, *set.find_as("c"));
+ EXPECT_TRUE(set.find_as("d") == set.end());
+}
+
}
diff --git a/unittests/ADT/FunctionRefTest.cpp b/unittests/ADT/FunctionRefTest.cpp
new file mode 100644
index 0000000..075d9a0
--- /dev/null
+++ b/unittests/ADT/FunctionRefTest.cpp
@@ -0,0 +1,28 @@
+//===- llvm/unittest/ADT/MakeUniqueTest.cpp - make_unique 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/ADT/STLExtras.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+// Ensure that copies of a function_ref copy the underlying state rather than
+// causing one function_ref to chain to the next.
+TEST(FunctionRefTest, Copy) {
+ auto A = [] { return 1; };
+ auto B = [] { return 2; };
+ function_ref<int()> X = A;
+ function_ref<int()> Y = X;
+ X = B;
+ EXPECT_EQ(1, Y());
+}
+
+}
diff --git a/unittests/ADT/MapVectorTest.cpp b/unittests/ADT/MapVectorTest.cpp
index 11178bc..8919799 100644
--- a/unittests/ADT/MapVectorTest.cpp
+++ b/unittests/ADT/MapVectorTest.cpp
@@ -9,6 +9,7 @@
#include "gtest/gtest.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/iterator_range.h"
#include <utility>
using namespace llvm;
@@ -53,3 +54,71 @@ TEST(MapVectorTest, insert_pop) {
EXPECT_EQ(MV[1], 2);
EXPECT_EQ(MV[4], 7);
}
+
+TEST(MapVectorTest, erase) {
+ MapVector<int, int> MV;
+
+ MV.insert(std::make_pair(1, 2));
+ MV.insert(std::make_pair(3, 4));
+ MV.insert(std::make_pair(5, 6));
+ ASSERT_EQ(MV.size(), 3u);
+
+ MV.erase(MV.find(1));
+ ASSERT_EQ(MV.size(), 2u);
+ ASSERT_EQ(MV.find(1), MV.end());
+ ASSERT_EQ(MV[3], 4);
+ ASSERT_EQ(MV[5], 6);
+
+ ASSERT_EQ(MV.erase(3), 1u);
+ ASSERT_EQ(MV.size(), 1u);
+ ASSERT_EQ(MV.find(3), MV.end());
+ ASSERT_EQ(MV[5], 6);
+
+ ASSERT_EQ(MV.erase(79), 0u);
+ ASSERT_EQ(MV.size(), 1u);
+}
+
+TEST(MapVectorTest, remove_if) {
+ MapVector<int, int> MV;
+
+ MV.insert(std::make_pair(1, 11));
+ MV.insert(std::make_pair(2, 12));
+ MV.insert(std::make_pair(3, 13));
+ MV.insert(std::make_pair(4, 14));
+ MV.insert(std::make_pair(5, 15));
+ MV.insert(std::make_pair(6, 16));
+ ASSERT_EQ(MV.size(), 6u);
+
+ MV.remove_if([](const std::pair<int, int> &Val) { return Val.second % 2; });
+ ASSERT_EQ(MV.size(), 3u);
+ ASSERT_EQ(MV.find(1), MV.end());
+ ASSERT_EQ(MV.find(3), MV.end());
+ ASSERT_EQ(MV.find(5), MV.end());
+ ASSERT_EQ(MV[2], 12);
+ ASSERT_EQ(MV[4], 14);
+ ASSERT_EQ(MV[6], 16);
+}
+
+TEST(MapVectorTest, iteration_test) {
+ MapVector<int, int> MV;
+
+ MV.insert(std::make_pair(1, 11));
+ MV.insert(std::make_pair(2, 12));
+ MV.insert(std::make_pair(3, 13));
+ MV.insert(std::make_pair(4, 14));
+ MV.insert(std::make_pair(5, 15));
+ MV.insert(std::make_pair(6, 16));
+ ASSERT_EQ(MV.size(), 6u);
+
+ int count = 1;
+ for (auto P : make_range(MV.begin(), MV.end())) {
+ ASSERT_EQ(P.first, count);
+ count++;
+ }
+
+ count = 6;
+ for (auto P : make_range(MV.rbegin(), MV.rend())) {
+ ASSERT_EQ(P.first, count);
+ count--;
+ }
+}
diff --git a/unittests/ADT/OptionalTest.cpp b/unittests/ADT/OptionalTest.cpp
index 2da408c..cadadce 100644
--- a/unittests/ADT/OptionalTest.cpp
+++ b/unittests/ADT/OptionalTest.cpp
@@ -169,6 +169,52 @@ TEST_F(OptionalTest, NullCopyConstructionTest) {
EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
}
+TEST_F(OptionalTest, GetValueOr) {
+ Optional<int> A;
+ EXPECT_EQ(42, A.getValueOr(42));
+
+ A = 5;
+ EXPECT_EQ(5, A.getValueOr(42));
+}
+
+struct MultiArgConstructor {
+ int x, y;
+ MultiArgConstructor(int x, int y) : x(x), y(y) {}
+ explicit MultiArgConstructor(int x, bool positive)
+ : x(x), y(positive ? x : -x) {}
+
+ MultiArgConstructor(const MultiArgConstructor &) LLVM_DELETED_FUNCTION;
+ MultiArgConstructor(MultiArgConstructor &&) LLVM_DELETED_FUNCTION;
+ MultiArgConstructor &operator=(const MultiArgConstructor &) LLVM_DELETED_FUNCTION;
+ MultiArgConstructor &operator=(MultiArgConstructor &&) LLVM_DELETED_FUNCTION;
+
+ static unsigned Destructions;
+ ~MultiArgConstructor() {
+ ++Destructions;
+ }
+ static void ResetCounts() {
+ Destructions = 0;
+ }
+};
+unsigned MultiArgConstructor::Destructions = 0;
+
+TEST_F(OptionalTest, Emplace) {
+ MultiArgConstructor::ResetCounts();
+ Optional<MultiArgConstructor> A;
+
+ A.emplace(1, 2);
+ EXPECT_TRUE(A.hasValue());
+ EXPECT_EQ(1, A->x);
+ EXPECT_EQ(2, A->y);
+ EXPECT_EQ(0u, MultiArgConstructor::Destructions);
+
+ A.emplace(5, false);
+ EXPECT_TRUE(A.hasValue());
+ EXPECT_EQ(5, A->x);
+ EXPECT_EQ(-5, A->y);
+ EXPECT_EQ(1u, MultiArgConstructor::Destructions);
+}
+
struct MoveOnly {
static unsigned MoveConstructions;
static unsigned Destructions;
@@ -278,5 +324,58 @@ TEST_F(OptionalTest, MoveOnlyAssigningAssignment) {
EXPECT_EQ(1u, MoveOnly::Destructions);
}
+struct Immovable {
+ static unsigned Constructions;
+ static unsigned Destructions;
+ int val;
+ explicit Immovable(int val) : val(val) {
+ ++Constructions;
+ }
+ ~Immovable() {
+ ++Destructions;
+ }
+ static void ResetCounts() {
+ Constructions = 0;
+ Destructions = 0;
+ }
+private:
+ // This should disable all move/copy operations.
+ Immovable(Immovable&& other) LLVM_DELETED_FUNCTION;
+};
+
+unsigned Immovable::Constructions = 0;
+unsigned Immovable::Destructions = 0;
+
+TEST_F(OptionalTest, ImmovableEmplace) {
+ Optional<Immovable> A;
+ Immovable::ResetCounts();
+ A.emplace(4);
+ EXPECT_TRUE((bool)A);
+ EXPECT_EQ(4, A->val);
+ EXPECT_EQ(1u, Immovable::Constructions);
+ EXPECT_EQ(0u, Immovable::Destructions);
+}
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+
+TEST_F(OptionalTest, MoveGetValueOr) {
+ Optional<MoveOnly> A;
+
+ MoveOnly::ResetCounts();
+ EXPECT_EQ(42, std::move(A).getValueOr(MoveOnly(42)).val);
+ EXPECT_EQ(1u, MoveOnly::MoveConstructions);
+ EXPECT_EQ(0u, MoveOnly::MoveAssignments);
+ EXPECT_EQ(2u, MoveOnly::Destructions);
+
+ A = MoveOnly(5);
+ MoveOnly::ResetCounts();
+ EXPECT_EQ(5, std::move(A).getValueOr(MoveOnly(42)).val);
+ EXPECT_EQ(1u, MoveOnly::MoveConstructions);
+ EXPECT_EQ(0u, MoveOnly::MoveAssignments);
+ EXPECT_EQ(2u, MoveOnly::Destructions);
+}
+
+#endif // LLVM_HAS_RVALUE_REFERENCE_THIS
+
} // end anonymous namespace
diff --git a/unittests/ADT/PostOrderIteratorTest.cpp b/unittests/ADT/PostOrderIteratorTest.cpp
new file mode 100644
index 0000000..1da1078
--- /dev/null
+++ b/unittests/ADT/PostOrderIteratorTest.cpp
@@ -0,0 +1,37 @@
+//===- PostOrderIteratorTest.cpp - PostOrderIterator 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/PostOrderIterator.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+using namespace llvm;
+
+namespace {
+
+// Whether we're able to compile
+TEST(PostOrderIteratorTest, Compiles) {
+ typedef SmallPtrSet<void *, 4> ExtSetTy;
+
+ // Tests that template specializations are kept up to date
+ void *Null = nullptr;
+ po_iterator_storage<std::set<void *>, false> PIS;
+ PIS.insertEdge(Null, Null);
+ ExtSetTy Ext;
+ po_iterator_storage<ExtSetTy, true> PISExt(Ext);
+ PIS.insertEdge(Null, Null);
+
+ // Test above, but going through po_iterator (which inherits from template
+ // base)
+ BasicBlock *NullBB = nullptr;
+ auto PI = po_end(NullBB);
+ PI.insertEdge(NullBB, NullBB);
+ auto PIExt = po_ext_end(NullBB, Ext);
+ PIExt.insertEdge(NullBB, NullBB);
+}
+}
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 028375d..33d668f 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -250,15 +250,21 @@ struct StringMapTestStruct {
TEST_F(StringMapTest, NonDefaultConstructable) {
StringMap<StringMapTestStruct> t;
- t.GetOrCreateValue("Test", StringMapTestStruct(123));
+ t.insert(std::make_pair("Test", StringMapTestStruct(123)));
StringMap<StringMapTestStruct>::iterator iter = t.find("Test");
ASSERT_NE(iter, t.end());
ASSERT_EQ(iter->second.i, 123);
}
+struct Immovable {
+ Immovable() {}
+ Immovable(Immovable&&) LLVM_DELETED_FUNCTION; // will disable the other special members
+};
+
struct MoveOnly {
int i;
MoveOnly(int i) : i(i) {}
+ MoveOnly(const Immovable&) : i(0) {}
MoveOnly(MoveOnly &&RHS) : i(RHS.i) {}
MoveOnly &operator=(MoveOnly &&RHS) {
i = RHS.i;
@@ -270,17 +276,23 @@ private:
MoveOnly &operator=(const MoveOnly &) LLVM_DELETED_FUNCTION;
};
-TEST_F(StringMapTest, MoveOnlyKey) {
+TEST_F(StringMapTest, MoveOnly) {
StringMap<MoveOnly> t;
- t.GetOrCreateValue("Test", MoveOnly(42));
+ t.insert(std::make_pair("Test", MoveOnly(42)));
StringRef Key = "Test";
StringMapEntry<MoveOnly>::Create(Key, MoveOnly(42))
->Destroy();
}
+TEST_F(StringMapTest, CtorArg) {
+ StringRef Key = "Test";
+ StringMapEntry<MoveOnly>::Create(Key, Immovable())
+ ->Destroy();
+}
+
TEST_F(StringMapTest, MoveConstruct) {
StringMap<int> A;
- A.GetOrCreateValue("x", 42);
+ A["x"] = 42;
StringMap<int> B = std::move(A);
ASSERT_EQ(A.size(), 0u);
ASSERT_EQ(B.size(), 1u);
@@ -325,7 +337,7 @@ struct Countable {
TEST_F(StringMapTest, MoveDtor) {
int InstanceCount = 0;
StringMap<Countable> A;
- A.GetOrCreateValue("x", Countable(42, InstanceCount));
+ A.insert(std::make_pair("x", Countable(42, InstanceCount)));
ASSERT_EQ(InstanceCount, 1);
auto I = A.find("x");
ASSERT_NE(I, A.end());
diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp
index 2e9d585..cacbde6 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -129,6 +129,36 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownOS, T.getOS());
EXPECT_EQ(Triple::EABI, T.getEnvironment());
+ T = Triple("amdil-unknown-unknown");
+ EXPECT_EQ(Triple::amdil, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
+ T = Triple("amdil64-unknown-unknown");
+ EXPECT_EQ(Triple::amdil64, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
+ T = Triple("hsail-unknown-unknown");
+ EXPECT_EQ(Triple::hsail, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
+ T = Triple("hsail64-unknown-unknown");
+ EXPECT_EQ(Triple::hsail64, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
+ T = Triple("spir-unknown-unknown");
+ EXPECT_EQ(Triple::spir, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
+ T = Triple("spir64-unknown-unknown");
+ EXPECT_EQ(Triple::spir64, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
}
@@ -190,7 +220,7 @@ TEST(TripleTest, Normalization) {
++Vendor) {
C[1] = Triple::getVendorTypeName(Triple::VendorType(Vendor));
for (int OS = 1+Triple::UnknownOS; OS <= Triple::Minix; ++OS) {
- if (OS == Triple::Cygwin || OS == Triple::MinGW32 || OS == Triple::Win32)
+ if (OS == Triple::Win32)
continue;
C[2] = Triple::getOSTypeName(Triple::OSType(OS));
@@ -341,6 +371,36 @@ TEST(TripleTest, BitWidthPredicates) {
EXPECT_FALSE(T.isArch16Bit());
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());
+
+ T.setArch(Triple::amdil);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::amdil64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
+
+ T.setArch(Triple::hsail);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::hsail64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
+
+ T.setArch(Triple::spir);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::spir64);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
}
TEST(TripleTest, BitWidthArchVariants) {
@@ -399,6 +459,30 @@ TEST(TripleTest, BitWidthArchVariants) {
T.setArch(Triple::x86_64);
EXPECT_EQ(Triple::x86, T.get32BitArchVariant().getArch());
EXPECT_EQ(Triple::x86_64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::amdil);
+ EXPECT_EQ(Triple::amdil, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::amdil64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::amdil64);
+ EXPECT_EQ(Triple::amdil, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::amdil64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::hsail);
+ EXPECT_EQ(Triple::hsail, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::hsail64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::hsail64);
+ EXPECT_EQ(Triple::hsail, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::hsail64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::spir);
+ EXPECT_EQ(Triple::spir, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::spir64, T.get64BitArchVariant().getArch());
+
+ T.setArch(Triple::spir64);
+ EXPECT_EQ(Triple::spir, T.get32BitArchVariant().getArch());
+ EXPECT_EQ(Triple::spir64, T.get64BitArchVariant().getArch());
}
TEST(TripleTest, getOSVersion) {
@@ -564,4 +648,20 @@ TEST(TripleTest, NormalizeWindows) {
EXPECT_EQ("i686-pc-windows-elf", Triple::normalize("i686-pc-windows-elf-elf"));
}
+
+TEST(TripleTest, getARMCPUForArch) {
+ {
+ llvm::Triple Triple("armv6-unknown-freebsd");
+ EXPECT_STREQ("arm1176jzf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7s-apple-ios7");
+ EXPECT_STREQ("swift", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7-apple-ios7");
+ EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch());
+ EXPECT_STREQ("swift", Triple.getARMCPUForArch("armv7s"));
+ }
+}
}
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index ac5e710..dba9d49 100644
--- a/unittests/Analysis/CFGTest.cpp
+++ b/unittests/Analysis/CFGTest.cpp
@@ -30,20 +30,16 @@ namespace {
class IsPotentiallyReachableTest : public testing::Test {
protected:
void ParseAssembly(const char *Assembly) {
- M.reset(new Module("Module", getGlobalContext()));
-
SMDiagnostic Error;
- bool Parsed = ParseAssemblyString(Assembly, M.get(),
- Error, M->getContext()) == M.get();
+ M = parseAssemblyString(Assembly, Error, getGlobalContext());
std::string errMsg;
raw_string_ostream os(errMsg);
Error.print("", os);
- if (!Parsed) {
- // A failure here means that the test itself is buggy.
+ // A failure here means that the test itself is buggy.
+ if (!M)
report_fatal_error(os.str().c_str());
- }
Function *F = M->getFunction("test");
if (F == nullptr)
diff --git a/unittests/Analysis/CMakeLists.txt b/unittests/Analysis/CMakeLists.txt
index 8454860..baf0c28 100644
--- a/unittests/Analysis/CMakeLists.txt
+++ b/unittests/Analysis/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ IPA
Analysis
AsmParser
Core
@@ -6,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_unittest(AnalysisTests
+ CallGraphTest.cpp
CFGTest.cpp
LazyCallGraphTest.cpp
ScalarEvolutionTest.cpp
diff --git a/unittests/Analysis/CallGraphTest.cpp b/unittests/Analysis/CallGraphTest.cpp
new file mode 100644
index 0000000..777907a
--- /dev/null
+++ b/unittests/Analysis/CallGraphTest.cpp
@@ -0,0 +1,59 @@
+//=======- CallGraphTest.cpp - Unit tests for the CG analysis -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+template <typename Ty> void canSpecializeGraphTraitsIterators(Ty *G) {
+ typedef typename GraphTraits<Ty *>::NodeType NodeTy;
+
+ auto I = GraphTraits<Ty *>::nodes_begin(G);
+ auto E = GraphTraits<Ty *>::nodes_end(G);
+ auto X = ++I;
+
+ // Should be able to iterate over all nodes of the graph.
+ static_assert(std::is_same<decltype(*I), NodeTy &>::value,
+ "Node type does not match");
+ static_assert(std::is_same<decltype(*X), NodeTy &>::value,
+ "Node type does not match");
+ static_assert(std::is_same<decltype(*E), NodeTy &>::value,
+ "Node type does not match");
+
+ NodeTy *N = GraphTraits<Ty *>::getEntryNode(G);
+
+ auto S = GraphTraits<NodeTy *>::child_begin(N);
+ auto F = GraphTraits<NodeTy *>::child_end(N);
+
+ // Should be able to iterate over immediate successors of a node.
+ static_assert(std::is_same<decltype(*S), NodeTy *>::value,
+ "Node type does not match");
+ static_assert(std::is_same<decltype(*F), NodeTy *>::value,
+ "Node type does not match");
+}
+
+TEST(CallGraphTest, GraphTraitsSpecialization) {
+ Module M("", getGlobalContext());
+ CallGraph CG(M);
+
+ canSpecializeGraphTraitsIterators(&CG);
+}
+
+TEST(CallGraphTest, GraphTraitsConstSpecialization) {
+ Module M("", getGlobalContext());
+ CallGraph CG(M);
+
+ canSpecializeGraphTraitsIterators(const_cast<const CallGraph *>(&CG));
+}
+}
diff --git a/unittests/Analysis/LazyCallGraphTest.cpp b/unittests/Analysis/LazyCallGraphTest.cpp
index d7c7045..6caccb8 100644
--- a/unittests/Analysis/LazyCallGraphTest.cpp
+++ b/unittests/Analysis/LazyCallGraphTest.cpp
@@ -22,38 +22,38 @@ using namespace llvm;
namespace {
std::unique_ptr<Module> parseAssembly(const char *Assembly) {
- auto M = make_unique<Module>("Module", getGlobalContext());
-
SMDiagnostic Error;
- bool Parsed =
- ParseAssemblyString(Assembly, M.get(), Error, M->getContext()) == M.get();
+ std::unique_ptr<Module> M =
+ parseAssemblyString(Assembly, Error, getGlobalContext());
std::string ErrMsg;
raw_string_ostream OS(ErrMsg);
Error.print("", OS);
// A failure here means that the test itself is buggy.
- if (!Parsed)
+ if (!M)
report_fatal_error(OS.str().c_str());
return M;
}
-// IR forming a call graph with a diamond of triangle-shaped SCCs:
-//
-// d1
-// / \
-// d3--d2
-// / \
-// b1 c1
-// / \ / \
-// b3--b2 c3--c2
-// \ /
-// a1
-// / \
-// a3--a2
-//
-// All call edges go up between SCCs, and clockwise around the SCC.
+/*
+ IR forming a call graph with a diamond of triangle-shaped SCCs:
+
+ d1
+ / \
+ d3--d2
+ / \
+ b1 c1
+ / \ / \
+ b3--b2 c3--c2
+ \ /
+ a1
+ / \
+ a3--a2
+
+ All call edges go up between SCCs, and clockwise around the SCC.
+ */
static const char DiamondOfTriangles[] =
"define void @a1() {\n"
"entry:\n"
diff --git a/unittests/Analysis/Makefile b/unittests/Analysis/Makefile
index 527f452..52296e7 100644
--- a/unittests/Analysis/Makefile
+++ b/unittests/Analysis/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = Analysis
-LINK_COMPONENTS := analysis asmparser
+LINK_COMPONENTS := ipa analysis asmparser
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Analysis/MixedTBAATest.cpp b/unittests/Analysis/MixedTBAATest.cpp
index 142e047..d7935e3 100644
--- a/unittests/Analysis/MixedTBAATest.cpp
+++ b/unittests/Analysis/MixedTBAATest.cpp
@@ -65,7 +65,7 @@ TEST_F(MixedTBAATest, MixedTBAA) {
// Run the TBAA eval pass on a mixture of path-aware and non-path-aware TBAA.
// The order of the metadata (path-aware vs non-path-aware) is important,
// because the AA eval pass only runs one test per store-pair.
- const char* args[] = { "MixedTBAATest", "-evaluate-tbaa" };
+ const char* args[] = { "MixedTBAATest", "-evaluate-aa-metadata" };
cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args);
PM.add(createTypeBasedAliasAnalysisPass());
PM.add(createAAEvalPass());
diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp
index b6a3e9a..6eb40d6 100644
--- a/unittests/Bitcode/BitReaderTest.cpp
+++ b/unittests/Bitcode/BitReaderTest.cpp
@@ -10,58 +10,158 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/PassManager.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
-namespace llvm {
-namespace {
-
-static Module *makeLLVMModule() {
- Module* Mod = new Module("test-mem", getGlobalContext());
+using namespace llvm;
- FunctionType* FuncTy =
- FunctionType::get(Type::getVoidTy(Mod->getContext()), false);
- Function* Func = Function::Create(FuncTy,GlobalValue::ExternalLinkage,
- "func", Mod);
+namespace {
- BasicBlock* Entry = BasicBlock::Create(Mod->getContext(), "entry", Func);
- new UnreachableInst(Mod->getContext(), Entry);
+std::unique_ptr<Module> parseAssembly(const char *Assembly) {
+ SMDiagnostic Error;
+ std::unique_ptr<Module> M =
+ parseAssemblyString(Assembly, Error, getGlobalContext());
- BasicBlock* BB = BasicBlock::Create(Mod->getContext(), "bb", Func);
- new UnreachableInst(Mod->getContext(), BB);
+ std::string ErrMsg;
+ raw_string_ostream OS(ErrMsg);
+ Error.print("", OS);
- PointerType* Int8Ptr = Type::getInt8PtrTy(Mod->getContext());
- new GlobalVariable(*Mod, Int8Ptr, /*isConstant=*/true,
- GlobalValue::ExternalLinkage,
- BlockAddress::get(BB), "table");
+ // A failure here means that the test itself is buggy.
+ if (!M)
+ report_fatal_error(OS.str().c_str());
- return Mod;
+ return M;
}
-static void writeModuleToBuffer(SmallVectorImpl<char> &Buffer) {
- std::unique_ptr<Module> Mod(makeLLVMModule());
+static void writeModuleToBuffer(std::unique_ptr<Module> Mod,
+ SmallVectorImpl<char> &Buffer) {
raw_svector_ostream OS(Buffer);
WriteBitcodeToFile(Mod.get(), OS);
}
+static std::unique_ptr<Module> getLazyModuleFromAssembly(LLVMContext &Context,
+ SmallString<1024> &Mem,
+ const char *Assembly) {
+ writeModuleToBuffer(parseAssembly(Assembly), Mem);
+ std::unique_ptr<MemoryBuffer> Buffer =
+ MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
+ ErrorOr<Module *> ModuleOrErr =
+ getLazyBitcodeModule(std::move(Buffer), Context);
+ return std::unique_ptr<Module>(ModuleOrErr.get());
+}
+
+TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) {
+ SmallString<1024> Mem;
+
+ LLVMContext Context;
+ std::unique_ptr<Module> M = getLazyModuleFromAssembly(
+ Context, Mem, "define internal i32 @func() {\n"
+ "ret i32 0\n"
+ "}\n");
+
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ M->getFunction("func")->materialize();
+ EXPECT_FALSE(M->getFunction("func")->empty());
+ EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
+ GlobalValue::InternalLinkage);
+
+ // Check that the linkage type is preserved after dematerialization.
+ M->getFunction("func")->Dematerialize();
+ EXPECT_TRUE(M->getFunction("func")->empty());
+ EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
+ GlobalValue::InternalLinkage);
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+}
+
TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
SmallString<1024> Mem;
- writeModuleToBuffer(Mem);
- MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Mem.str(), "test", false);
- ErrorOr<Module *> ModuleOrErr =
- getLazyBitcodeModule(Buffer, getGlobalContext());
- std::unique_ptr<Module> m(ModuleOrErr.get());
- PassManager passes;
- passes.add(createVerifierPass());
- passes.add(createDebugInfoVerifierPass());
- passes.run(*m);
+
+ LLVMContext Context;
+ std::unique_ptr<Module> M = getLazyModuleFromAssembly(
+ Context, Mem, "@table = constant i8* blockaddress(@func, %bb)\n"
+ "define void @func() {\n"
+ " unreachable\n"
+ "bb:\n"
+ " unreachable\n"
+ "}\n");
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Try (and fail) to dematerialize @func.
+ M->getFunction("func")->Dematerialize();
+ EXPECT_FALSE(M->getFunction("func")->empty());
}
+TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
+ SmallString<1024> Mem;
+
+ LLVMContext Context;
+ std::unique_ptr<Module> M = getLazyModuleFromAssembly(
+ Context, Mem, "define i8* @before() {\n"
+ " ret i8* blockaddress(@func, %bb)\n"
+ "}\n"
+ "define void @other() {\n"
+ " unreachable\n"
+ "}\n"
+ "define void @func() {\n"
+ " unreachable\n"
+ "bb:\n"
+ " unreachable\n"
+ "}\n");
+ EXPECT_TRUE(M->getFunction("before")->empty());
+ EXPECT_TRUE(M->getFunction("func")->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Materialize @before, pulling in @func.
+ EXPECT_FALSE(M->getFunction("before")->materialize());
+ EXPECT_FALSE(M->getFunction("func")->empty());
+ EXPECT_TRUE(M->getFunction("other")->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Try (and fail) to dematerialize @func.
+ M->getFunction("func")->Dematerialize();
+ EXPECT_FALSE(M->getFunction("func")->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
}
+
+TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
+ SmallString<1024> Mem;
+
+ LLVMContext Context;
+ std::unique_ptr<Module> M = getLazyModuleFromAssembly(
+ Context, Mem, "define void @func() {\n"
+ " unreachable\n"
+ "bb:\n"
+ " unreachable\n"
+ "}\n"
+ "define void @other() {\n"
+ " unreachable\n"
+ "}\n"
+ "define i8* @after() {\n"
+ " ret i8* blockaddress(@func, %bb)\n"
+ "}\n");
+ EXPECT_TRUE(M->getFunction("after")->empty());
+ EXPECT_TRUE(M->getFunction("func")->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Materialize @after, pulling in @func.
+ EXPECT_FALSE(M->getFunction("after")->materialize());
+ EXPECT_FALSE(M->getFunction("func")->empty());
+ EXPECT_TRUE(M->getFunction("other")->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Try (and fail) to dematerialize @func.
+ M->getFunction("func")->Dematerialize();
+ EXPECT_FALSE(M->getFunction("func")->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
}
+
+} // end namespace
diff --git a/unittests/Bitcode/BitstreamReaderTest.cpp b/unittests/Bitcode/BitstreamReaderTest.cpp
new file mode 100644
index 0000000..b11d7fd
--- /dev/null
+++ b/unittests/Bitcode/BitstreamReaderTest.cpp
@@ -0,0 +1,56 @@
+//===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(BitstreamReaderTest, AtEndOfStream) {
+ uint8_t Bytes[4] = {
+ 0x00, 0x01, 0x02, 0x03
+ };
+ BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+ BitstreamCursor Cursor(Reader);
+
+ EXPECT_FALSE(Cursor.AtEndOfStream());
+ (void)Cursor.Read(8);
+ EXPECT_FALSE(Cursor.AtEndOfStream());
+ (void)Cursor.Read(24);
+ EXPECT_TRUE(Cursor.AtEndOfStream());
+
+ Cursor.JumpToBit(0);
+ EXPECT_FALSE(Cursor.AtEndOfStream());
+
+ Cursor.JumpToBit(32);
+ EXPECT_TRUE(Cursor.AtEndOfStream());
+}
+
+TEST(BitstreamReaderTest, AtEndOfStreamJump) {
+ uint8_t Bytes[4] = {
+ 0x00, 0x01, 0x02, 0x03
+ };
+ BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
+ BitstreamCursor Cursor(Reader);
+
+ Cursor.JumpToBit(32);
+ EXPECT_TRUE(Cursor.AtEndOfStream());
+}
+
+TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
+ uint8_t Dummy = 0xFF;
+ BitstreamReader Reader(&Dummy, &Dummy);
+ BitstreamCursor Cursor(Reader);
+
+ EXPECT_TRUE(Cursor.AtEndOfStream());
+}
+
+} // end anonymous namespace
diff --git a/unittests/Bitcode/CMakeLists.txt b/unittests/Bitcode/CMakeLists.txt
index 743ab18..09cbcdc 100644
--- a/unittests/Bitcode/CMakeLists.txt
+++ b/unittests/Bitcode/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ AsmParser
BitReader
BitWriter
Core
@@ -7,4 +8,5 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(BitcodeTests
BitReaderTest.cpp
+ BitstreamReaderTest.cpp
)
diff --git a/unittests/Bitcode/Makefile b/unittests/Bitcode/Makefile
index fcec879..33b09b9 100644
--- a/unittests/Bitcode/Makefile
+++ b/unittests/Bitcode/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = Bitcode
-LINK_COMPONENTS := bitreader bitwriter
+LINK_COMPONENTS := AsmParser BitReader BitWriter Core Support
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt
index 489eaaf..783c9b5 100644
--- a/unittests/ExecutionEngine/CMakeLists.txt
+++ b/unittests/ExecutionEngine/CMakeLists.txt
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
Interpreter
+ MC
Support
)
@@ -9,10 +10,9 @@ add_llvm_unittest(ExecutionEngineTests
ExecutionEngineTest.cpp
)
-# Include JIT/MCJIT tests only if native arch is a built JIT target.
+# Include MCJIT tests only if native arch is a built JIT target.
list(FIND LLVM_TARGETS_TO_BUILD "${LLVM_NATIVE_ARCH}" build_idx)
list(FIND LLVM_TARGETS_WITH_JIT "${LLVM_NATIVE_ARCH}" jit_idx)
if (NOT build_idx LESS 0 AND NOT jit_idx LESS 0)
- add_subdirectory(JIT)
add_subdirectory(MCJIT)
endif()
diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index f23745c..19917a4 100644
--- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -8,10 +8,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Interpreter.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ManagedStatic.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -19,10 +22,14 @@ using namespace llvm;
namespace {
class ExecutionEngineTest : public testing::Test {
+private:
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
protected:
- ExecutionEngineTest()
- : M(new Module("<main>", getGlobalContext())), Error(""),
- Engine(EngineBuilder(M).setErrorStr(&Error).create()) {
+ ExecutionEngineTest() {
+ auto Owner = make_unique<Module>("<main>", getGlobalContext());
+ M = Owner.get();
+ Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
}
virtual void SetUp() {
@@ -35,9 +42,9 @@ protected:
GlobalValue::ExternalLinkage, nullptr, Name);
}
- Module *const M;
std::string Error;
- const std::unique_ptr<ExecutionEngine> Engine;
+ Module *M; // Owned by ExecutionEngine.
+ std::unique_ptr<ExecutionEngine> Engine;
};
TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
@@ -127,4 +134,35 @@ TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
}
+TEST_F(ExecutionEngineTest, LookupWithMangledName) {
+ int x;
+ llvm::sys::DynamicLibrary::AddSymbol("x", &x);
+
+ // Demonstrate that getSymbolAddress accepts mangled names and always strips
+ // the leading underscore.
+ EXPECT_EQ(reinterpret_cast<uint64_t>(&x),
+ RTDyldMemoryManager::getSymbolAddressInProcess("_x"));
+}
+
+TEST_F(ExecutionEngineTest, LookupWithMangledAndDemangledSymbol) {
+ int x;
+ int _x;
+ llvm::sys::DynamicLibrary::AddSymbol("x", &x);
+ llvm::sys::DynamicLibrary::AddSymbol("_x", &_x);
+
+ // Lookup the demangled name first, even if there's a demangled symbol that
+ // matches the input already.
+ EXPECT_EQ(reinterpret_cast<uint64_t>(&x),
+ RTDyldMemoryManager::getSymbolAddressInProcess("_x"));
+}
+
+TEST_F(ExecutionEngineTest, LookupwithDemangledName) {
+ int _x;
+ llvm::sys::DynamicLibrary::AddSymbol("_x", &_x);
+
+ // But do fallback to looking up a demangled name if there's no ambiguity
+ EXPECT_EQ(reinterpret_cast<uint64_t>(&_x),
+ RTDyldMemoryManager::getSymbolAddressInProcess("_x"));
+}
+
}
diff --git a/unittests/ExecutionEngine/JIT/CMakeLists.txt b/unittests/ExecutionEngine/JIT/CMakeLists.txt
deleted file mode 100644
index 72c1df7..0000000
--- a/unittests/ExecutionEngine/JIT/CMakeLists.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- AsmParser
- BitReader
- BitWriter
- Core
- ExecutionEngine
- JIT
- Support
- nativecodegen
- )
-
-# HACK: Declare a couple of source files as optionally compiled to satisfy the
-# missing-file-checker in LLVM's weird CMake build.
-set(LLVM_OPTIONAL_SOURCES
- IntelJITEventListenerTest.cpp
- OProfileJITEventListenerTest.cpp
- )
-
-if( LLVM_USE_INTEL_JITEVENTS )
- set(ProfileTestSources
- IntelJITEventListenerTest.cpp
- )
- set(LLVM_LINK_COMPONENTS
- ${LLVM_LINK_COMPONENTS}
- DebugInfo
- IntelJITEvents
- Object
- )
-endif( LLVM_USE_INTEL_JITEVENTS )
-
-if( LLVM_USE_OPROFILE )
- set(ProfileTestSources
- ${ProfileTestSources}
- OProfileJITEventListenerTest.cpp
- )
- set(LLVM_LINK_COMPONENTS
- ${LLVM_LINK_COMPONENTS}
- OProfileJIT
- )
-endif( LLVM_USE_OPROFILE )
-
-set(JITTestsSources
- JITEventListenerTest.cpp
- JITMemoryManagerTest.cpp
- JITTest.cpp
- MultiJITTest.cpp
- ${ProfileTestSources}
- )
-
-if(MSVC)
- list(APPEND JITTestsSources JITTests.def)
-endif()
-
-# The JIT tests need to dlopen things.
-set(LLVM_NO_DEAD_STRIP 1)
-
-add_llvm_unittest(JITTests
- ${JITTestsSources}
- )
-
-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/IntelJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
deleted file mode 100644
index db90887..0000000
--- a/unittests/ExecutionEngine/JIT/IntelJITEventListenerTest.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-//===- JITEventListenerTest.cpp - Tests for Intel JITEventListener --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "JITEventListenerTestCommon.h"
-
-using namespace llvm;
-
-// Because we want to keep the implementation details of the Intel API used to
-// communicate with Amplifier out of the public header files, the header below
-// is included from the source tree instead.
-#include "../../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h"
-
-#include <map>
-#include <list>
-
-namespace {
-
-// map of function ("method") IDs to source locations
-NativeCodeMap ReportedDebugFuncs;
-
-} // namespace
-
-/// Mock implementaion of Intel JIT API jitprofiling library
-namespace test_jitprofiling {
-
-int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
- switch (EventType) {
- case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
- EXPECT_TRUE(0 != EventSpecificData);
- iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
-
- ReportedDebugFuncs[msg->method_id];
-
- for(unsigned int i = 0; i < msg->line_number_size; ++i) {
- EXPECT_TRUE(0 != msg->line_number_table);
- std::pair<std::string, unsigned int> loc(
- std::string(msg->source_file_name),
- msg->line_number_table[i].LineNumber);
- ReportedDebugFuncs[msg->method_id].push_back(loc);
- }
- }
- break;
- case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
- EXPECT_TRUE(0 != EventSpecificData);
- unsigned int UnloadId
- = *reinterpret_cast<unsigned int*>(EventSpecificData);
- EXPECT_TRUE(1 == ReportedDebugFuncs.erase(UnloadId));
- }
- default:
- break;
- }
- return 0;
-}
-
-iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
- // for testing, pretend we have an Intel Parallel Amplifier XE 2011
- // instance attached
- return iJIT_SAMPLING_ON;
-}
-
-unsigned int GetNewMethodID(void) {
- static unsigned int id = 0;
- return ++id;
-}
-
-} //namespace test_jitprofiling
-
-class IntelJITEventListenerTest
- : public JITEventListenerTestBase<IntelJITEventsWrapper> {
-public:
- IntelJITEventListenerTest()
- : JITEventListenerTestBase<IntelJITEventsWrapper>(
- new IntelJITEventsWrapper(test_jitprofiling::NotifyEvent, 0,
- test_jitprofiling::IsProfilingActive, 0, 0,
- test_jitprofiling::GetNewMethodID))
- {
- EXPECT_TRUE(0 != MockWrapper);
-
- Listener.reset(JITEventListener::createIntelJITEventListener(
- MockWrapper.release()));
- EXPECT_TRUE(0 != Listener);
- EE->RegisterJITEventListener(Listener.get());
- }
-};
-
-TEST_F(IntelJITEventListenerTest, NoDebugInfo) {
- TestNoDebugInfo(ReportedDebugFuncs);
-}
-
-TEST_F(IntelJITEventListenerTest, SingleLine) {
- TestSingleLine(ReportedDebugFuncs);
-}
-
-TEST_F(IntelJITEventListenerTest, MultipleLines) {
- TestMultipleLines(ReportedDebugFuncs);
-}
-
-// This testcase is disabled because the Intel JIT API does not support a single
-// JITted function with source lines associated with multiple files
-/*
-TEST_F(IntelJITEventListenerTest, MultipleFiles) {
- TestMultipleFiles(ReportedDebugFuncs);
-}
-*/
-
-testing::Environment* const jit_env =
- testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
deleted file mode 100644
index 175b9fb..0000000
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-//===- JITEventListenerTest.cpp - Unit tests for JITEventListeners --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/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>
-
-using namespace llvm;
-
-namespace {
-
-struct FunctionEmittedEvent {
- // Indices are local to the RecordingJITEventListener, since the
- // JITEventListener interface makes no guarantees about the order of
- // calls between Listeners.
- unsigned Index;
- const Function *F;
- void *Code;
- size_t Size;
- JITEvent_EmittedFunctionDetails Details;
-};
-struct FunctionFreedEvent {
- unsigned Index;
- void *Code;
-};
-
-struct RecordingJITEventListener : public JITEventListener {
- std::vector<FunctionEmittedEvent> EmittedEvents;
- std::vector<FunctionFreedEvent> FreedEvents;
-
- unsigned NextIndex;
-
- RecordingJITEventListener() : NextIndex(0) {}
-
- virtual void NotifyFunctionEmitted(const Function &F,
- void *Code, size_t Size,
- const EmittedFunctionDetails &Details) {
- FunctionEmittedEvent Event = {NextIndex++, &F, Code, Size, Details};
- EmittedEvents.push_back(Event);
- }
-
- virtual void NotifyFreeingMachineCode(void *OldPtr) {
- FunctionFreedEvent Event = {NextIndex++, OldPtr};
- FreedEvents.push_back(Event);
- }
-};
-
-class JITEventListenerTest : public testing::Test {
- protected:
- JITEventListenerTest()
- : M(new Module("module", getGlobalContext())),
- EE(EngineBuilder(M)
- .setEngineKind(EngineKind::JIT)
- .create()) {
- }
-
- Module *M;
- const std::unique_ptr<ExecutionEngine> EE;
-};
-
-// Tests on SystemZ disabled as we're running the old JIT
-#if !defined(__s390__) && !defined(__aarch64__)
-Function *buildFunction(Module *M) {
- Function *Result = Function::Create(
- TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
- GlobalValue::ExternalLinkage, "id", M);
- Value *Arg = Result->arg_begin();
- BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
- ReturnInst::Create(M->getContext(), Arg, BB);
- return Result;
-}
-
-// Tests that a single JITEventListener follows JIT events accurately.
-TEST_F(JITEventListenerTest, Simple) {
- RecordingJITEventListener Listener;
- EE->RegisterJITEventListener(&Listener);
- Function *F1 = buildFunction(M);
- Function *F2 = buildFunction(M);
-
- void *F1_addr = EE->getPointerToFunction(F1);
- void *F2_addr = EE->getPointerToFunction(F2);
- EE->getPointerToFunction(F1); // Should do nothing.
- EE->freeMachineCodeForFunction(F1);
- EE->freeMachineCodeForFunction(F2);
-
- ASSERT_EQ(2U, Listener.EmittedEvents.size());
- ASSERT_EQ(2U, Listener.FreedEvents.size());
-
- EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
- EXPECT_EQ(F1, Listener.EmittedEvents[0].F);
- EXPECT_EQ(F1_addr, Listener.EmittedEvents[0].Code);
- EXPECT_LT(0U, Listener.EmittedEvents[0].Size)
- << "We don't know how big the function will be, but it had better"
- << " contain some bytes.";
-
- EXPECT_EQ(1U, Listener.EmittedEvents[1].Index);
- EXPECT_EQ(F2, Listener.EmittedEvents[1].F);
- EXPECT_EQ(F2_addr, Listener.EmittedEvents[1].Code);
- EXPECT_LT(0U, Listener.EmittedEvents[1].Size)
- << "We don't know how big the function will be, but it had better"
- << " contain some bytes.";
-
- EXPECT_EQ(2U, Listener.FreedEvents[0].Index);
- EXPECT_EQ(F1_addr, Listener.FreedEvents[0].Code);
-
- EXPECT_EQ(3U, Listener.FreedEvents[1].Index);
- EXPECT_EQ(F2_addr, Listener.FreedEvents[1].Code);
-
- F1->eraseFromParent();
- F2->eraseFromParent();
-}
-
-// Tests that a single JITEventListener follows JIT events accurately.
-TEST_F(JITEventListenerTest, MultipleListenersDontInterfere) {
- RecordingJITEventListener Listener1;
- RecordingJITEventListener Listener2;
- RecordingJITEventListener Listener3;
- Function *F1 = buildFunction(M);
- Function *F2 = buildFunction(M);
-
- EE->RegisterJITEventListener(&Listener1);
- EE->RegisterJITEventListener(&Listener2);
- void *F1_addr = EE->getPointerToFunction(F1);
- EE->RegisterJITEventListener(&Listener3);
- EE->UnregisterJITEventListener(&Listener1);
- void *F2_addr = EE->getPointerToFunction(F2);
- EE->UnregisterJITEventListener(&Listener2);
- EE->UnregisterJITEventListener(&Listener3);
- EE->freeMachineCodeForFunction(F1);
- EE->RegisterJITEventListener(&Listener2);
- EE->RegisterJITEventListener(&Listener3);
- EE->RegisterJITEventListener(&Listener1);
- EE->freeMachineCodeForFunction(F2);
- EE->UnregisterJITEventListener(&Listener1);
- EE->UnregisterJITEventListener(&Listener2);
- EE->UnregisterJITEventListener(&Listener3);
-
- // Listener 1.
- ASSERT_EQ(1U, Listener1.EmittedEvents.size());
- ASSERT_EQ(1U, Listener1.FreedEvents.size());
-
- EXPECT_EQ(0U, Listener1.EmittedEvents[0].Index);
- EXPECT_EQ(F1, Listener1.EmittedEvents[0].F);
- EXPECT_EQ(F1_addr, Listener1.EmittedEvents[0].Code);
- EXPECT_LT(0U, Listener1.EmittedEvents[0].Size)
- << "We don't know how big the function will be, but it had better"
- << " contain some bytes.";
-
- EXPECT_EQ(1U, Listener1.FreedEvents[0].Index);
- EXPECT_EQ(F2_addr, Listener1.FreedEvents[0].Code);
-
- // Listener 2.
- ASSERT_EQ(2U, Listener2.EmittedEvents.size());
- ASSERT_EQ(1U, Listener2.FreedEvents.size());
-
- EXPECT_EQ(0U, Listener2.EmittedEvents[0].Index);
- EXPECT_EQ(F1, Listener2.EmittedEvents[0].F);
- EXPECT_EQ(F1_addr, Listener2.EmittedEvents[0].Code);
- EXPECT_LT(0U, Listener2.EmittedEvents[0].Size)
- << "We don't know how big the function will be, but it had better"
- << " contain some bytes.";
-
- EXPECT_EQ(1U, Listener2.EmittedEvents[1].Index);
- EXPECT_EQ(F2, Listener2.EmittedEvents[1].F);
- EXPECT_EQ(F2_addr, Listener2.EmittedEvents[1].Code);
- EXPECT_LT(0U, Listener2.EmittedEvents[1].Size)
- << "We don't know how big the function will be, but it had better"
- << " contain some bytes.";
-
- EXPECT_EQ(2U, Listener2.FreedEvents[0].Index);
- EXPECT_EQ(F2_addr, Listener2.FreedEvents[0].Code);
-
- // Listener 3.
- ASSERT_EQ(1U, Listener3.EmittedEvents.size());
- ASSERT_EQ(1U, Listener3.FreedEvents.size());
-
- EXPECT_EQ(0U, Listener3.EmittedEvents[0].Index);
- EXPECT_EQ(F2, Listener3.EmittedEvents[0].F);
- EXPECT_EQ(F2_addr, Listener3.EmittedEvents[0].Code);
- EXPECT_LT(0U, Listener3.EmittedEvents[0].Size)
- << "We don't know how big the function will be, but it had better"
- << " contain some bytes.";
-
- EXPECT_EQ(1U, Listener3.FreedEvents[0].Index);
- EXPECT_EQ(F2_addr, Listener3.FreedEvents[0].Code);
-
- F1->eraseFromParent();
- F2->eraseFromParent();
-}
-
-TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
- RecordingJITEventListener Listener;
- MachineCodeInfo MCI;
- Function *F = buildFunction(M);
-
- EE->RegisterJITEventListener(&Listener);
- EE->runJITOnFunction(F, &MCI);
- void *F_addr = EE->getPointerToFunction(F);
- EE->freeMachineCodeForFunction(F);
-
- ASSERT_EQ(1U, Listener.EmittedEvents.size());
- ASSERT_EQ(1U, Listener.FreedEvents.size());
-
- EXPECT_EQ(0U, Listener.EmittedEvents[0].Index);
- EXPECT_EQ(F, Listener.EmittedEvents[0].F);
- EXPECT_EQ(F_addr, Listener.EmittedEvents[0].Code);
- EXPECT_EQ(MCI.address(), Listener.EmittedEvents[0].Code);
- EXPECT_EQ(MCI.size(), Listener.EmittedEvents[0].Size);
-
- EXPECT_EQ(1U, Listener.FreedEvents[0].Index);
- EXPECT_EQ(F_addr, Listener.FreedEvents[0].Code);
-}
-#endif
-
-class JITEnvironment : public testing::Environment {
- virtual void SetUp() {
- // Required to create a JIT.
- InitializeNativeTarget();
- }
-};
-testing::Environment* const jit_env =
- testing::AddGlobalTestEnvironment(new JITEnvironment);
-
-} // anonymous namespace
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h b/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
deleted file mode 100644
index 61220f5..0000000
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
+++ /dev/null
@@ -1,207 +0,0 @@
-//===- JITEventListenerTestCommon.h - Helper for JITEventListener tests ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===-------------------------------------------------------------------------------===//
-
-#ifndef JIT_EVENT_LISTENER_TEST_COMMON_H
-#define JIT_EVENT_LISTENER_TEST_COMMON_H
-
-#include "llvm/CodeGen/MachineCodeInfo.h"
-#include "llvm/Config/config.h"
-#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/ExecutionEngine/JITEventListener.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfo.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 "gtest/gtest.h"
-#include <string>
-#include <utility>
-#include <vector>
-
-typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
-typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
-
-class JITEnvironment : public testing::Environment {
- virtual void SetUp() {
- // Required to create a JIT.
- llvm::InitializeNativeTarget();
- }
-};
-
-inline unsigned int getLine() {
- return 12;
-}
-
-inline unsigned int getCol() {
- return 0;
-}
-
-inline const char* getFilename() {
- return "mock_source_file.cpp";
-}
-
-// Test fixture shared by tests for listener implementations
-template<typename WrapperT>
-class JITEventListenerTestBase : public testing::Test {
-protected:
- std::unique_ptr<WrapperT> MockWrapper;
- std::unique_ptr<llvm::JITEventListener> Listener;
-
-public:
- llvm::Module* M;
- llvm::MDNode* Scope;
- llvm::ExecutionEngine* EE;
- llvm::DIBuilder* DebugBuilder;
- llvm::IRBuilder<> Builder;
-
- JITEventListenerTestBase(WrapperT* w)
- : MockWrapper(w)
- , M(new llvm::Module("module", llvm::getGlobalContext()))
- , EE(llvm::EngineBuilder(M)
- .setEngineKind(llvm::EngineKind::JIT)
- .setOptLevel(llvm::CodeGenOpt::None)
- .create())
- , DebugBuilder(new llvm::DIBuilder(*M))
- , Builder(llvm::getGlobalContext())
- {
- DebugBuilder->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus,
- "JIT",
- "JIT",
- "JIT",
- true,
- "",
- 1);
-
- Scope = DebugBuilder->createFile(getFilename(), ".");
- }
-
- llvm::Function *buildFunction(const SourceLocations& DebugLocations) {
- using namespace llvm;
-
- LLVMContext& GlobalContext = getGlobalContext();
-
- SourceLocations::const_iterator CurrentDebugLocation
- = DebugLocations.begin();
-
- if (CurrentDebugLocation != DebugLocations.end()) {
- DebugLoc DebugLocation = DebugLoc::get(getLine(), getCol(),
- DebugBuilder->createFile(CurrentDebugLocation->first, "."));
- Builder.SetCurrentDebugLocation(DebugLocation);
- CurrentDebugLocation++;
- }
-
- Function *Result = Function::Create(
- TypeBuilder<int32_t(int32_t), false>::get(GlobalContext),
- GlobalValue::ExternalLinkage, "id", M);
- Value *Arg = Result->arg_begin();
- BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
- Builder.SetInsertPoint(BB);
- Value* one = ConstantInt::get(GlobalContext, APInt(32, 1));
- for(; CurrentDebugLocation != DebugLocations.end();
- ++CurrentDebugLocation) {
- Arg = Builder.CreateMul(Arg, Builder.CreateAdd(Arg, one));
- Builder.SetCurrentDebugLocation(
- DebugLoc::get(CurrentDebugLocation->second, 0,
- DebugBuilder->createFile(CurrentDebugLocation->first, ".")));
- }
- Builder.CreateRet(Arg);
- return Result;
- }
-
- void TestNoDebugInfo(NativeCodeMap& ReportedDebugFuncs) {
- SourceLocations DebugLocations;
- llvm::Function* f = buildFunction(DebugLocations);
- EXPECT_TRUE(0 != f);
-
- //Cause JITting and callbacks to our listener
- EXPECT_TRUE(0 != EE->getPointerToFunction(f));
- EXPECT_TRUE(1 == ReportedDebugFuncs.size());
-
- EE->freeMachineCodeForFunction(f);
- EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
- }
-
- void TestSingleLine(NativeCodeMap& ReportedDebugFuncs) {
- SourceLocations DebugLocations;
- DebugLocations.push_back(std::make_pair(std::string(getFilename()),
- getLine()));
- llvm::Function* f = buildFunction(DebugLocations);
- EXPECT_TRUE(0 != f);
-
- EXPECT_TRUE(0 != EE->getPointerToFunction(f));
- EXPECT_TRUE(1 == ReportedDebugFuncs.size());
- EXPECT_STREQ(ReportedDebugFuncs.begin()->second.begin()->first.c_str(),
- getFilename());
- EXPECT_EQ(ReportedDebugFuncs.begin()->second.begin()->second, getLine());
-
- EE->freeMachineCodeForFunction(f);
- EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
- }
-
- void TestMultipleLines(NativeCodeMap& ReportedDebugFuncs) {
- using namespace std;
-
- SourceLocations DebugLocations;
- unsigned int c = 5;
- for(unsigned int i = 0; i < c; ++i) {
- DebugLocations.push_back(make_pair(string(getFilename()), getLine() + i));
- }
-
- llvm::Function* f = buildFunction(DebugLocations);
- EXPECT_TRUE(0 != f);
-
- EXPECT_TRUE(0 != EE->getPointerToFunction(f));
- EXPECT_TRUE(1 == ReportedDebugFuncs.size());
- SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
- EXPECT_EQ(c, FunctionInfo.size());
-
- int VerifyCount = 0;
- for(SourceLocations::iterator i = FunctionInfo.begin();
- i != FunctionInfo.end();
- ++i) {
- EXPECT_STREQ(i->first.c_str(), getFilename());
- EXPECT_EQ(i->second, getLine() + VerifyCount);
- VerifyCount++;
- }
-
- EE->freeMachineCodeForFunction(f);
- EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
- }
-
- void TestMultipleFiles(NativeCodeMap& ReportedDebugFuncs) {
-
- std::string secondFilename("another_file.cpp");
-
- SourceLocations DebugLocations;
- DebugLocations.push_back(std::make_pair(std::string(getFilename()),
- getLine()));
- DebugLocations.push_back(std::make_pair(secondFilename, getLine()));
- llvm::Function* f = buildFunction(DebugLocations);
- EXPECT_TRUE(0 != f);
-
- EXPECT_TRUE(0 != EE->getPointerToFunction(f));
- EXPECT_TRUE(1 == ReportedDebugFuncs.size());
- SourceLocations& FunctionInfo = ReportedDebugFuncs.begin()->second;
- EXPECT_TRUE(2 == FunctionInfo.size());
-
- EXPECT_STREQ(FunctionInfo.at(0).first.c_str(), getFilename());
- EXPECT_STREQ(FunctionInfo.at(1).first.c_str(), secondFilename.c_str());
-
- EXPECT_EQ(FunctionInfo.at(0).second, getLine());
- EXPECT_EQ(FunctionInfo.at(1).second, getLine());
-
- EE->freeMachineCodeForFunction(f);
- EXPECT_TRUE(ReportedDebugFuncs.size() == 0);
- }
-};
-
-#endif //JIT_EVENT_LISTENER_TEST_COMMON_H
diff --git a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
deleted file mode 100644
index 296838d..0000000
--- a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-//===- JITMemoryManagerTest.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/JITMemoryManager.h"
-#include "llvm/ADT/ArrayRef.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;
-
-namespace {
-
-Function *makeFakeFunction() {
- std::vector<Type*> params;
- FunctionType *FTy =
- FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false);
- return Function::Create(FTy, GlobalValue::ExternalLinkage);
-}
-
-// Allocate three simple functions that fit in the initial slab. This exercises
-// the code in the case that we don't have to allocate more memory to store the
-// function bodies.
-TEST(JITMemoryManagerTest, NoAllocations) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- uintptr_t size;
- std::string Error;
-
- // Allocate the functions.
- std::unique_ptr<Function> F1(makeFakeFunction());
- size = 1024;
- uint8_t *FunctionBody1 = MemMgr->startFunctionBody(F1.get(), size);
- memset(FunctionBody1, 0xFF, 1024);
- MemMgr->endFunctionBody(F1.get(), FunctionBody1, FunctionBody1 + 1024);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- std::unique_ptr<Function> F2(makeFakeFunction());
- size = 1024;
- uint8_t *FunctionBody2 = MemMgr->startFunctionBody(F2.get(), size);
- memset(FunctionBody2, 0xFF, 1024);
- MemMgr->endFunctionBody(F2.get(), FunctionBody2, FunctionBody2 + 1024);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- std::unique_ptr<Function> F3(makeFakeFunction());
- size = 1024;
- uint8_t *FunctionBody3 = MemMgr->startFunctionBody(F3.get(), size);
- memset(FunctionBody3, 0xFF, 1024);
- MemMgr->endFunctionBody(F3.get(), FunctionBody3, FunctionBody3 + 1024);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- // Deallocate them out of order, in case that matters.
- MemMgr->deallocateFunctionBody(FunctionBody2);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody1);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody3);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-}
-
-// Make three large functions that take up most of the space in the slab. Then
-// try allocating three smaller functions that don't require additional slabs.
-TEST(JITMemoryManagerTest, TestCodeAllocation) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- uintptr_t size;
- std::string Error;
-
- // Big functions are a little less than the largest block size.
- const uintptr_t smallFuncSize = 1024;
- const uintptr_t bigFuncSize = (MemMgr->GetDefaultCodeSlabSize() -
- smallFuncSize * 2);
-
- // Allocate big functions
- std::unique_ptr<Function> F1(makeFakeFunction());
- size = bigFuncSize;
- uint8_t *FunctionBody1 = MemMgr->startFunctionBody(F1.get(), size);
- ASSERT_LE(bigFuncSize, size);
- memset(FunctionBody1, 0xFF, bigFuncSize);
- MemMgr->endFunctionBody(F1.get(), FunctionBody1, FunctionBody1 + bigFuncSize);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- std::unique_ptr<Function> F2(makeFakeFunction());
- size = bigFuncSize;
- uint8_t *FunctionBody2 = MemMgr->startFunctionBody(F2.get(), size);
- ASSERT_LE(bigFuncSize, size);
- memset(FunctionBody2, 0xFF, bigFuncSize);
- MemMgr->endFunctionBody(F2.get(), FunctionBody2, FunctionBody2 + bigFuncSize);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- std::unique_ptr<Function> F3(makeFakeFunction());
- size = bigFuncSize;
- uint8_t *FunctionBody3 = MemMgr->startFunctionBody(F3.get(), size);
- ASSERT_LE(bigFuncSize, size);
- memset(FunctionBody3, 0xFF, bigFuncSize);
- MemMgr->endFunctionBody(F3.get(), FunctionBody3, FunctionBody3 + bigFuncSize);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- // Check that each large function took it's own slab.
- EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
-
- // Allocate small functions
- std::unique_ptr<Function> F4(makeFakeFunction());
- size = smallFuncSize;
- uint8_t *FunctionBody4 = MemMgr->startFunctionBody(F4.get(), size);
- ASSERT_LE(smallFuncSize, size);
- memset(FunctionBody4, 0xFF, smallFuncSize);
- MemMgr->endFunctionBody(F4.get(), FunctionBody4,
- FunctionBody4 + smallFuncSize);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- std::unique_ptr<Function> F5(makeFakeFunction());
- size = smallFuncSize;
- uint8_t *FunctionBody5 = MemMgr->startFunctionBody(F5.get(), size);
- ASSERT_LE(smallFuncSize, size);
- memset(FunctionBody5, 0xFF, smallFuncSize);
- MemMgr->endFunctionBody(F5.get(), FunctionBody5,
- FunctionBody5 + smallFuncSize);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- std::unique_ptr<Function> F6(makeFakeFunction());
- size = smallFuncSize;
- uint8_t *FunctionBody6 = MemMgr->startFunctionBody(F6.get(), size);
- ASSERT_LE(smallFuncSize, size);
- memset(FunctionBody6, 0xFF, smallFuncSize);
- MemMgr->endFunctionBody(F6.get(), FunctionBody6,
- FunctionBody6 + smallFuncSize);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-
- // Check that the small functions didn't allocate any new slabs.
- EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
-
- // Deallocate them out of order, in case that matters.
- MemMgr->deallocateFunctionBody(FunctionBody2);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody1);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody4);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody3);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody5);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
- MemMgr->deallocateFunctionBody(FunctionBody6);
- EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
-}
-
-// Allocate five global ints of varying widths and alignment, and check their
-// alignment and overlap.
-TEST(JITMemoryManagerTest, TestSmallGlobalInts) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- uint8_t *a = (uint8_t *)MemMgr->allocateGlobal(8, 0);
- uint16_t *b = (uint16_t*)MemMgr->allocateGlobal(16, 2);
- uint32_t *c = (uint32_t*)MemMgr->allocateGlobal(32, 4);
- uint64_t *d = (uint64_t*)MemMgr->allocateGlobal(64, 8);
-
- // Check the alignment.
- EXPECT_EQ(0U, ((uintptr_t)b) & 0x1);
- EXPECT_EQ(0U, ((uintptr_t)c) & 0x3);
- EXPECT_EQ(0U, ((uintptr_t)d) & 0x7);
-
- // Initialize them each one at a time and make sure they don't overlap.
- *a = 0xff;
- *b = 0U;
- *c = 0U;
- *d = 0U;
- EXPECT_EQ(0xffU, *a);
- EXPECT_EQ(0U, *b);
- EXPECT_EQ(0U, *c);
- EXPECT_EQ(0U, *d);
- *a = 0U;
- *b = 0xffffU;
- EXPECT_EQ(0U, *a);
- EXPECT_EQ(0xffffU, *b);
- EXPECT_EQ(0U, *c);
- EXPECT_EQ(0U, *d);
- *b = 0U;
- *c = 0xffffffffU;
- EXPECT_EQ(0U, *a);
- EXPECT_EQ(0U, *b);
- EXPECT_EQ(0xffffffffU, *c);
- EXPECT_EQ(0U, *d);
- *c = 0U;
- *d = 0xffffffffffffffffULL;
- EXPECT_EQ(0U, *a);
- EXPECT_EQ(0U, *b);
- EXPECT_EQ(0U, *c);
- EXPECT_EQ(0xffffffffffffffffULL, *d);
-
- // Make sure we didn't allocate any extra slabs for this tiny amount of data.
- EXPECT_EQ(1U, MemMgr->GetNumDataSlabs());
-}
-
-// Allocate a small global, a big global, and a third global, and make sure we
-// only use two slabs for that.
-TEST(JITMemoryManagerTest, TestLargeGlobalArray) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- size_t Size = 4 * MemMgr->GetDefaultDataSlabSize();
- uint64_t *a = (uint64_t*)MemMgr->allocateGlobal(64, 8);
- uint8_t *g = MemMgr->allocateGlobal(Size, 8);
- uint64_t *b = (uint64_t*)MemMgr->allocateGlobal(64, 8);
-
- // Check the alignment.
- EXPECT_EQ(0U, ((uintptr_t)a) & 0x7);
- EXPECT_EQ(0U, ((uintptr_t)g) & 0x7);
- EXPECT_EQ(0U, ((uintptr_t)b) & 0x7);
-
- // Initialize them to make sure we don't segfault and make sure they don't
- // overlap.
- memset(a, 0x1, 8);
- memset(g, 0x2, Size);
- memset(b, 0x3, 8);
- EXPECT_EQ(0x0101010101010101ULL, *a);
- // Just check the edges.
- EXPECT_EQ(0x02U, g[0]);
- EXPECT_EQ(0x02U, g[Size - 1]);
- EXPECT_EQ(0x0303030303030303ULL, *b);
-
- // Check the number of slabs.
- EXPECT_EQ(2U, MemMgr->GetNumDataSlabs());
-}
-
-// Allocate lots of medium globals so that we can test moving the bump allocator
-// to a new slab.
-TEST(JITMemoryManagerTest, TestManyGlobals) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- size_t SlabSize = MemMgr->GetDefaultDataSlabSize();
- size_t Size = 128;
- int Iters = (SlabSize / Size) + 1;
-
- // We should start with no slabs.
- EXPECT_EQ(0U, MemMgr->GetNumDataSlabs());
-
- // After allocating a bunch of globals, we should have two.
- for (int I = 0; I < Iters; ++I)
- MemMgr->allocateGlobal(Size, 8);
- EXPECT_EQ(2U, MemMgr->GetNumDataSlabs());
-
- // And after much more, we should have three.
- for (int I = 0; I < Iters; ++I)
- MemMgr->allocateGlobal(Size, 8);
- EXPECT_EQ(3U, MemMgr->GetNumDataSlabs());
-}
-
-// Allocate lots of function stubs so that we can test moving the stub bump
-// allocator to a new slab.
-TEST(JITMemoryManagerTest, TestManyStubs) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- size_t SlabSize = MemMgr->GetDefaultStubSlabSize();
- size_t Size = 128;
- int Iters = (SlabSize / Size) + 1;
-
- // We should start with no slabs.
- EXPECT_EQ(0U, MemMgr->GetNumDataSlabs());
-
- // After allocating a bunch of stubs, we should have two.
- for (int I = 0; I < Iters; ++I)
- MemMgr->allocateStub(nullptr, Size, 8);
- EXPECT_EQ(2U, MemMgr->GetNumStubSlabs());
-
- // And after much more, we should have three.
- for (int I = 0; I < Iters; ++I)
- MemMgr->allocateStub(nullptr, Size, 8);
- EXPECT_EQ(3U, MemMgr->GetNumStubSlabs());
-}
-
-// Check section allocation and alignment
-TEST(JITMemoryManagerTest, AllocateSection) {
- std::unique_ptr<JITMemoryManager> MemMgr(
- JITMemoryManager::CreateDefaultMemManager());
- uint8_t *code1 = MemMgr->allocateCodeSection(256, 0, 1, StringRef());
- uint8_t *data1 = MemMgr->allocateDataSection(256, 16, 2, StringRef(), true);
- uint8_t *code2 = MemMgr->allocateCodeSection(257, 32, 3, StringRef());
- uint8_t *data2 = MemMgr->allocateDataSection(256, 64, 4, StringRef(), false);
- uint8_t *code3 = MemMgr->allocateCodeSection(258, 64, 5, StringRef());
-
- EXPECT_NE((uint8_t*)nullptr, code1);
- EXPECT_NE((uint8_t*)nullptr, code2);
- EXPECT_NE((uint8_t*)nullptr, data1);
- EXPECT_NE((uint8_t*)nullptr, data2);
-
- // Check alignment
- EXPECT_EQ((uint64_t)code1 & 0xf, 0u);
- EXPECT_EQ((uint64_t)code2 & 0x1f, 0u);
- EXPECT_EQ((uint64_t)code3 & 0x3f, 0u);
- EXPECT_EQ((uint64_t)data1 & 0xf, 0u);
- EXPECT_EQ((uint64_t)data2 & 0x3f, 0u);
-}
-
-}
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
deleted file mode 100644
index 817d207..0000000
--- a/unittests/ExecutionEngine/JIT/JITTest.cpp
+++ /dev/null
@@ -1,728 +0,0 @@
-//===- JITTest.cpp - Unit tests for the JIT -------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/Bitcode/ReaderWriter.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>
-
-using namespace llvm;
-
-// This variable is intentionally defined differently in the statically-compiled
-// program from the IR input to the JIT to assert that the JIT doesn't use its
-// definition. Note that this variable must be defined even on platforms where
-// JIT tests are disabled as it is referenced from the .def file.
-extern "C" int32_t JITTest_AvailableExternallyGlobal;
-int32_t JITTest_AvailableExternallyGlobal LLVM_ATTRIBUTE_USED = 42;
-
-// This function is intentionally defined differently in the statically-compiled
-// program from the IR input to the JIT to assert that the JIT doesn't use its
-// definition. Note that this function must be defined even on platforms where
-// JIT tests are disabled as it is referenced from the .def file.
-extern "C" int32_t JITTest_AvailableExternallyFunction() LLVM_ATTRIBUTE_USED;
-extern "C" int32_t JITTest_AvailableExternallyFunction() {
- return 42;
-}
-
-namespace {
-
-// Tests on ARM, PowerPC and SystemZ disabled as we're running the old jit
-#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
- && !defined(__aarch64__)
-
-Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) {
- std::vector<Type*> params;
- FunctionType *FTy = FunctionType::get(G->getType()->getElementType(),
- params, false);
- Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
- BasicBlock *Entry = BasicBlock::Create(M->getContext(), "entry", F);
- IRBuilder<> builder(Entry);
- Value *Load = builder.CreateLoad(G);
- Type *GTy = G->getType()->getElementType();
- Value *Add = builder.CreateAdd(Load, ConstantInt::get(GTy, 1LL));
- builder.CreateStore(Add, G);
- builder.CreateRet(Add);
- return F;
-}
-
-std::string DumpFunction(const Function *F) {
- std::string Result;
- raw_string_ostream(Result) << "" << *F;
- return Result;
-}
-
-class RecordingJITMemoryManager : public JITMemoryManager {
- const std::unique_ptr<JITMemoryManager> Base;
-
-public:
- RecordingJITMemoryManager()
- : Base(JITMemoryManager::CreateDefaultMemManager()) {
- stubsAllocated = 0;
- }
- virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true) {
- return Base->getPointerToNamedFunction(Name, AbortOnFailure);
- }
-
- virtual void setMemoryWritable() { Base->setMemoryWritable(); }
- virtual void setMemoryExecutable() { Base->setMemoryExecutable(); }
- virtual void setPoisonMemory(bool poison) { Base->setPoisonMemory(poison); }
- virtual void AllocateGOT() { Base->AllocateGOT(); }
- virtual uint8_t *getGOTBase() const { return Base->getGOTBase(); }
- struct StartFunctionBodyCall {
- StartFunctionBodyCall(uint8_t *Result, const Function *F,
- uintptr_t ActualSize, uintptr_t ActualSizeResult)
- : Result(Result), F(F), F_dump(DumpFunction(F)),
- ActualSize(ActualSize), ActualSizeResult(ActualSizeResult) {}
- uint8_t *Result;
- const Function *F;
- std::string F_dump;
- uintptr_t ActualSize;
- uintptr_t ActualSizeResult;
- };
- std::vector<StartFunctionBodyCall> startFunctionBodyCalls;
- virtual uint8_t *startFunctionBody(const Function *F,
- uintptr_t &ActualSize) {
- uintptr_t InitialActualSize = ActualSize;
- uint8_t *Result = Base->startFunctionBody(F, ActualSize);
- startFunctionBodyCalls.push_back(
- StartFunctionBodyCall(Result, F, InitialActualSize, ActualSize));
- return Result;
- }
- int stubsAllocated;
- uint8_t *allocateStub(const GlobalValue *F, unsigned StubSize,
- unsigned Alignment) override {
- stubsAllocated++;
- return Base->allocateStub(F, StubSize, Alignment);
- }
- struct EndFunctionBodyCall {
- EndFunctionBodyCall(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd)
- : F(F), F_dump(DumpFunction(F)),
- FunctionStart(FunctionStart), FunctionEnd(FunctionEnd) {}
- const Function *F;
- std::string F_dump;
- uint8_t *FunctionStart;
- uint8_t *FunctionEnd;
- };
- std::vector<EndFunctionBodyCall> endFunctionBodyCalls;
- virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
- endFunctionBodyCalls.push_back(
- EndFunctionBodyCall(F, FunctionStart, FunctionEnd));
- Base->endFunctionBody(F, FunctionStart, FunctionEnd);
- }
- virtual uint8_t *allocateDataSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName, bool IsReadOnly) {
- return Base->allocateDataSection(
- Size, Alignment, SectionID, SectionName, IsReadOnly);
- }
- virtual uint8_t *allocateCodeSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName) {
- return Base->allocateCodeSection(
- Size, Alignment, SectionID, SectionName);
- }
- virtual bool finalizeMemory(std::string *ErrMsg) { return false; }
- virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
- return Base->allocateSpace(Size, Alignment);
- }
- virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
- return Base->allocateGlobal(Size, Alignment);
- }
- struct DeallocateFunctionBodyCall {
- DeallocateFunctionBodyCall(const void *Body) : Body(Body) {}
- const void *Body;
- };
- std::vector<DeallocateFunctionBodyCall> deallocateFunctionBodyCalls;
- virtual void deallocateFunctionBody(void *Body) {
- deallocateFunctionBodyCalls.push_back(DeallocateFunctionBodyCall(Body));
- Base->deallocateFunctionBody(Body);
- }
-};
-
-bool LoadAssemblyInto(Module *M, const char *assembly) {
- SMDiagnostic Error;
- bool success =
- nullptr != ParseAssemblyString(assembly, M, Error, M->getContext());
- std::string errMsg;
- raw_string_ostream os(errMsg);
- Error.print("", os);
- EXPECT_TRUE(success) << os.str();
- return success;
-}
-
-class JITTest : public testing::Test {
- protected:
- virtual RecordingJITMemoryManager *createMemoryManager() {
- return new RecordingJITMemoryManager;
- }
-
- virtual void SetUp() {
- M = new Module("<main>", Context);
- RJMM = createMemoryManager();
- RJMM->setPoisonMemory(true);
- std::string Error;
- TargetOptions Options;
- TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
- .setJITMemoryManager(RJMM)
- .setErrorStr(&Error)
- .setTargetOptions(Options).create());
- ASSERT_TRUE(TheJIT.get() != nullptr) << Error;
- }
-
- void LoadAssembly(const char *assembly) {
- LoadAssemblyInto(M, assembly);
- }
-
- LLVMContext Context;
- Module *M; // Owned by ExecutionEngine.
- RecordingJITMemoryManager *RJMM;
- std::unique_ptr<ExecutionEngine> TheJIT;
-};
-
-// Regression test for a bug. The JIT used to allocate globals inside the same
-// memory block used for the function, and when the function code was freed,
-// the global was left in the same place. This test allocates a function
-// that uses and global, deallocates it, and then makes sure that the global
-// stays alive after that.
-TEST(JIT, GlobalInFunction) {
- LLVMContext context;
- Module *M = new Module("<main>", context);
-
- JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
- // Tell the memory manager to poison freed memory so that accessing freed
- // memory is more easily tested.
- MemMgr->setPoisonMemory(true);
- std::string Error;
- std::unique_ptr<ExecutionEngine> JIT(EngineBuilder(M)
- .setEngineKind(EngineKind::JIT)
- .setErrorStr(&Error)
- .setJITMemoryManager(MemMgr)
- // The next line enables the fix:
- .setAllocateGVsWithCode(false)
- .create());
- ASSERT_EQ(Error, "");
-
- // Create a global variable.
- Type *GTy = Type::getInt32Ty(context);
- GlobalVariable *G = new GlobalVariable(
- *M,
- GTy,
- false, // Not constant.
- GlobalValue::InternalLinkage,
- Constant::getNullValue(GTy),
- "myglobal");
-
- // Make a function that points to a global.
- Function *F1 = makeReturnGlobal("F1", G, M);
-
- // Get the pointer to the native code to force it to JIT the function and
- // allocate space for the global.
- void (*F1Ptr)() =
- reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F1));
-
- // Since F1 was codegen'd, a pointer to G should be available.
- int32_t *GPtr = (int32_t*)JIT->getPointerToGlobalIfAvailable(G);
- ASSERT_NE((int32_t*)nullptr, GPtr);
- EXPECT_EQ(0, *GPtr);
-
- // F1() should increment G.
- F1Ptr();
- EXPECT_EQ(1, *GPtr);
-
- // Make a second function identical to the first, referring to the same
- // global.
- Function *F2 = makeReturnGlobal("F2", G, M);
- void (*F2Ptr)() =
- reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F2));
-
- // F2() should increment G.
- F2Ptr();
- EXPECT_EQ(2, *GPtr);
-
- // Deallocate F1.
- JIT->freeMachineCodeForFunction(F1);
-
- // F2() should *still* increment G.
- F2Ptr();
- EXPECT_EQ(3, *GPtr);
-}
-
-int PlusOne(int arg) {
- return arg + 1;
-}
-
-TEST_F(JITTest, FarCallToKnownFunction) {
- // x86-64 can only make direct calls to functions within 32 bits of
- // the current PC. To call anything farther away, we have to load
- // the address into a register and call through the register. The
- // current JIT does this by allocating a stub for any far call.
- // There was a bug in which the JIT tried to emit a direct call when
- // the target was already in the JIT's global mappings and lazy
- // compilation was disabled.
-
- Function *KnownFunction = Function::Create(
- TypeBuilder<int(int), false>::get(Context),
- GlobalValue::ExternalLinkage, "known", M);
- TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne);
-
- // int test() { return known(7); }
- Function *TestFunction = Function::Create(
- TypeBuilder<int(), false>::get(Context),
- GlobalValue::ExternalLinkage, "test", M);
- BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction);
- IRBuilder<> Builder(Entry);
- Value *result = Builder.CreateCall(
- KnownFunction,
- ConstantInt::get(TypeBuilder<int, false>::get(Context), 7));
- Builder.CreateRet(result);
-
- TheJIT->DisableLazyCompilation(true);
- int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>(
- (intptr_t)TheJIT->getPointerToFunction(TestFunction));
- // This used to crash in trying to call PlusOne().
- EXPECT_EQ(8, TestFunctionPtr());
-}
-
-// Test a function C which calls A and B which call each other.
-TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) {
- TheJIT->DisableLazyCompilation(true);
-
- FunctionType *Func1Ty =
- cast<FunctionType>(TypeBuilder<void(void), false>::get(Context));
- std::vector<Type*> arg_types;
- arg_types.push_back(Type::getInt1Ty(Context));
- FunctionType *FuncTy = FunctionType::get(
- Type::getVoidTy(Context), arg_types, false);
- Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage,
- "func1", M);
- Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
- "func2", M);
- Function *Func3 = Function::Create(FuncTy, Function::InternalLinkage,
- "func3", M);
- BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
- BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
- BasicBlock *True2 = BasicBlock::Create(Context, "cond_true", Func2);
- BasicBlock *False2 = BasicBlock::Create(Context, "cond_false", Func2);
- BasicBlock *Block3 = BasicBlock::Create(Context, "block3", Func3);
- BasicBlock *True3 = BasicBlock::Create(Context, "cond_true", Func3);
- BasicBlock *False3 = BasicBlock::Create(Context, "cond_false", Func3);
-
- // Make Func1 call Func2(0) and Func3(0).
- IRBuilder<> Builder(Block1);
- Builder.CreateCall(Func2, ConstantInt::getTrue(Context));
- Builder.CreateCall(Func3, ConstantInt::getTrue(Context));
- Builder.CreateRetVoid();
-
- // void Func2(bool b) { if (b) { Func3(false); return; } return; }
- Builder.SetInsertPoint(Block2);
- Builder.CreateCondBr(Func2->arg_begin(), True2, False2);
- Builder.SetInsertPoint(True2);
- Builder.CreateCall(Func3, ConstantInt::getFalse(Context));
- Builder.CreateRetVoid();
- Builder.SetInsertPoint(False2);
- Builder.CreateRetVoid();
-
- // void Func3(bool b) { if (b) { Func2(false); return; } return; }
- Builder.SetInsertPoint(Block3);
- Builder.CreateCondBr(Func3->arg_begin(), True3, False3);
- Builder.SetInsertPoint(True3);
- Builder.CreateCall(Func2, ConstantInt::getFalse(Context));
- Builder.CreateRetVoid();
- Builder.SetInsertPoint(False3);
- Builder.CreateRetVoid();
-
- // Compile the function to native code
- void (*F1Ptr)() =
- reinterpret_cast<void(*)()>((intptr_t)TheJIT->getPointerToFunction(Func1));
-
- F1Ptr();
-}
-
-// Regression test for PR5162. This used to trigger an AssertingVH inside the
-// JIT's Function to stub mapping.
-TEST_F(JITTest, NonLazyLeaksNoStubs) {
- TheJIT->DisableLazyCompilation(true);
-
- // Create two functions with a single basic block each.
- FunctionType *FuncTy =
- cast<FunctionType>(TypeBuilder<int(), false>::get(Context));
- Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage,
- "func1", M);
- Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
- "func2", M);
- BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
- BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
-
- // The first function calls the second and returns the result
- IRBuilder<> Builder(Block1);
- Value *Result = Builder.CreateCall(Func2);
- Builder.CreateRet(Result);
-
- // The second function just returns a constant
- Builder.SetInsertPoint(Block2);
- Builder.CreateRet(ConstantInt::get(TypeBuilder<int, false>::get(Context),42));
-
- // Compile the function to native code
- (void)TheJIT->getPointerToFunction(Func1);
-
- // Free the JIT state for the functions
- TheJIT->freeMachineCodeForFunction(Func1);
- TheJIT->freeMachineCodeForFunction(Func2);
-
- // Delete the first function (and show that is has no users)
- EXPECT_EQ(Func1->getNumUses(), 0u);
- Func1->eraseFromParent();
-
- // Delete the second function (and show that it has no users - it had one,
- // func1 but that's gone now)
- EXPECT_EQ(Func2->getNumUses(), 0u);
- Func2->eraseFromParent();
-}
-
-TEST_F(JITTest, ModuleDeletion) {
- TheJIT->DisableLazyCompilation(false);
- LoadAssembly("define void @main() { "
- " call i32 @computeVal() "
- " ret void "
- "} "
- " "
- "define internal i32 @computeVal() { "
- " ret i32 0 "
- "} ");
- Function *func = M->getFunction("main");
- TheJIT->getPointerToFunction(func);
- TheJIT->removeModule(M);
- delete M;
-
- SmallPtrSet<const void*, 2> FunctionsDeallocated;
- for (unsigned i = 0, e = RJMM->deallocateFunctionBodyCalls.size();
- i != e; ++i) {
- FunctionsDeallocated.insert(RJMM->deallocateFunctionBodyCalls[i].Body);
- }
- for (unsigned i = 0, e = RJMM->startFunctionBodyCalls.size(); i != e; ++i) {
- EXPECT_TRUE(FunctionsDeallocated.count(
- RJMM->startFunctionBodyCalls[i].Result))
- << "Function leaked: \n" << RJMM->startFunctionBodyCalls[i].F_dump;
- }
- EXPECT_EQ(RJMM->startFunctionBodyCalls.size(),
- RJMM->deallocateFunctionBodyCalls.size());
-}
-
-// ARM, MIPS and PPC still emit stubs for calls since the target may be
-// too far away to call directly. This #if can probably be removed when
-// http://llvm.org/PR5201 is fixed.
-#if !defined(__arm__) && !defined(__mips__) && \
- !defined(__powerpc__) && !defined(__ppc__) && !defined(__aarch64__)
-typedef int (*FooPtr) ();
-
-TEST_F(JITTest, NoStubs) {
- LoadAssembly("define void @bar() {"
- "entry: "
- "ret void"
- "}"
- " "
- "define i32 @foo() {"
- "entry:"
- "call void @bar()"
- "ret i32 undef"
- "}"
- " "
- "define i32 @main() {"
- "entry:"
- "%0 = call i32 @foo()"
- "call void @bar()"
- "ret i32 undef"
- "}");
- Function *foo = M->getFunction("foo");
- uintptr_t tmp = (uintptr_t)(TheJIT->getPointerToFunction(foo));
- FooPtr ptr = (FooPtr)(tmp);
-
- (ptr)();
-
- // We should now allocate no more stubs, we have the code to foo
- // and the existing stub for bar.
- int stubsBefore = RJMM->stubsAllocated;
- Function *func = M->getFunction("main");
- TheJIT->getPointerToFunction(func);
-
- Function *bar = M->getFunction("bar");
- TheJIT->getPointerToFunction(bar);
-
- ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
-}
-#endif // !ARM && !PPC
-
-TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
- TheJIT->DisableLazyCompilation(true);
- LoadAssembly("define i8()* @get_foo_addr() { "
- " ret i8()* @foo "
- "} "
- " "
- "define i8 @foo() { "
- " ret i8 42 "
- "} ");
- Function *F_get_foo_addr = M->getFunction("get_foo_addr");
-
- typedef char(*fooT)();
- fooT (*get_foo_addr)() = reinterpret_cast<fooT(*)()>(
- (intptr_t)TheJIT->getPointerToFunction(F_get_foo_addr));
- fooT foo_addr = get_foo_addr();
-
- // Now free get_foo_addr. This should not free the machine code for foo or
- // any call stub returned as foo's canonical address.
- TheJIT->freeMachineCodeForFunction(F_get_foo_addr);
-
- // Check by calling the reported address of foo.
- EXPECT_EQ(42, foo_addr());
-
- // The reported address should also be the same as the result of a subsequent
- // getPointerToFunction(foo).
-#if 0
- // Fails until PR5126 is fixed:
- Function *F_foo = M->getFunction("foo");
- fooT foo = reinterpret_cast<fooT>(
- (intptr_t)TheJIT->getPointerToFunction(F_foo));
- EXPECT_EQ((intptr_t)foo, (intptr_t)foo_addr);
-#endif
-}
-
-// ARM does not have an implementation of replaceMachineCodeForFunction(),
-// so recompileAndRelinkFunction doesn't work.
-#if !defined(__arm__) && !defined(__aarch64__)
-TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
- Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context),
- GlobalValue::ExternalLinkage, "test", M);
- BasicBlock *Entry = BasicBlock::Create(Context, "entry", F);
- IRBuilder<> Builder(Entry);
- Value *Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 1);
- Builder.CreateRet(Val);
-
- TheJIT->DisableLazyCompilation(true);
- // Compile the function once, and make sure it works.
- int (*OrigFPtr)() = reinterpret_cast<int(*)()>(
- (intptr_t)TheJIT->recompileAndRelinkFunction(F));
- EXPECT_EQ(1, OrigFPtr());
-
- // Now change the function to return a different value.
- Entry->eraseFromParent();
- BasicBlock *NewEntry = BasicBlock::Create(Context, "new_entry", F);
- Builder.SetInsertPoint(NewEntry);
- Val = ConstantInt::get(TypeBuilder<int, false>::get(Context), 2);
- Builder.CreateRet(Val);
- // Recompile it, which should produce a new function pointer _and_ update the
- // old one.
- int (*NewFPtr)() = reinterpret_cast<int(*)()>(
- (intptr_t)TheJIT->recompileAndRelinkFunction(F));
-
- EXPECT_EQ(2, NewFPtr())
- << "The new pointer should call the new version of the function";
- EXPECT_EQ(2, OrigFPtr())
- << "The old pointer's target should now jump to the new version";
-}
-#endif // !defined(__arm__)
-
-TEST_F(JITTest, AvailableExternallyGlobalIsntEmitted) {
- TheJIT->DisableLazyCompilation(true);
- LoadAssembly("@JITTest_AvailableExternallyGlobal = "
- " available_externally global i32 7 "
- " "
- "define i32 @loader() { "
- " %result = load i32* @JITTest_AvailableExternallyGlobal "
- " ret i32 %result "
- "} ");
- Function *loaderIR = M->getFunction("loader");
-
- int32_t (*loader)() = reinterpret_cast<int32_t(*)()>(
- (intptr_t)TheJIT->getPointerToFunction(loaderIR));
- EXPECT_EQ(42, loader()) << "func should return 42 from the external global,"
- << " not 7 from the IR version.";
-}
-
-TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) {
- TheJIT->DisableLazyCompilation(true);
- LoadAssembly("define available_externally i32 "
- " @JITTest_AvailableExternallyFunction() { "
- " ret i32 7 "
- "} "
- " "
- "define i32 @func() { "
- " %result = tail call i32 "
- " @JITTest_AvailableExternallyFunction() "
- " ret i32 %result "
- "} ");
- Function *funcIR = M->getFunction("func");
-
- int32_t (*func)() = reinterpret_cast<int32_t(*)()>(
- (intptr_t)TheJIT->getPointerToFunction(funcIR));
- EXPECT_EQ(42, func()) << "func should return 42 from the static version,"
- << " not 7 from the IR version.";
-}
-
-TEST_F(JITTest, EscapedLazyStubStillCallable) {
- TheJIT->DisableLazyCompilation(false);
- LoadAssembly("define internal i32 @stubbed() { "
- " ret i32 42 "
- "} "
- " "
- "define i32()* @get_stub() { "
- " ret i32()* @stubbed "
- "} ");
- typedef int32_t(*StubTy)();
-
- // Call get_stub() to get the address of @stubbed without actually JITting it.
- Function *get_stubIR = M->getFunction("get_stub");
- StubTy (*get_stub)() = reinterpret_cast<StubTy(*)()>(
- (intptr_t)TheJIT->getPointerToFunction(get_stubIR));
- StubTy stubbed = get_stub();
- // Now get_stubIR is the only reference to stubbed's stub.
- get_stubIR->eraseFromParent();
- // Now there are no references inside the JIT, but we've got a pointer outside
- // it. The stub should be callable and return the right value.
- EXPECT_EQ(42, stubbed());
-}
-
-// Converts the LLVM assembly to bitcode and returns it in a std::string. An
-// empty string indicates an error.
-std::string AssembleToBitcode(LLVMContext &Context, const char *Assembly) {
- Module TempModule("TempModule", Context);
- if (!LoadAssemblyInto(&TempModule, Assembly)) {
- return "";
- }
-
- std::string Result;
- raw_string_ostream OS(Result);
- WriteBitcodeToFile(&TempModule, OS);
- OS.flush();
- return Result;
-}
-
-// Returns a newly-created ExecutionEngine that reads the bitcode in 'Bitcode'
-// lazily. The associated Module (owned by the ExecutionEngine) is returned in
-// M. Both will be NULL on an error. Bitcode must live at least as long as the
-// ExecutionEngine.
-ExecutionEngine *getJITFromBitcode(
- LLVMContext &Context, const std::string &Bitcode, Module *&M) {
- // c_str() is null-terminated like MemoryBuffer::getMemBuffer requires.
- MemoryBuffer *BitcodeBuffer =
- MemoryBuffer::getMemBuffer(Bitcode, "Bitcode for test");
- ErrorOr<Module*> ModuleOrErr = getLazyBitcodeModule(BitcodeBuffer, Context);
- if (std::error_code EC = ModuleOrErr.getError()) {
- ADD_FAILURE() << EC.message();
- delete BitcodeBuffer;
- return nullptr;
- }
- M = ModuleOrErr.get();
- std::string errMsg;
- ExecutionEngine *TheJIT = EngineBuilder(M)
- .setEngineKind(EngineKind::JIT)
- .setErrorStr(&errMsg)
- .create();
- if (TheJIT == nullptr) {
- ADD_FAILURE() << errMsg;
- delete M;
- M = nullptr;
- return nullptr;
- }
- return TheJIT;
-}
-
-TEST(LazyLoadedJITTest, MaterializableAvailableExternallyFunctionIsntCompiled) {
- LLVMContext Context;
- const std::string Bitcode =
- AssembleToBitcode(Context,
- "define available_externally i32 "
- " @JITTest_AvailableExternallyFunction() { "
- " ret i32 7 "
- "} "
- " "
- "define i32 @func() { "
- " %result = tail call i32 "
- " @JITTest_AvailableExternallyFunction() "
- " ret i32 %result "
- "} ");
- ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
- Module *M;
- std::unique_ptr<ExecutionEngine> TheJIT(
- getJITFromBitcode(Context, Bitcode, M));
- ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
- TheJIT->DisableLazyCompilation(true);
-
- Function *funcIR = M->getFunction("func");
- Function *availableFunctionIR =
- M->getFunction("JITTest_AvailableExternallyFunction");
-
- // Double-check that the available_externally function is still unmaterialized
- // when getPointerToFunction needs to find out if it's available_externally.
- EXPECT_TRUE(availableFunctionIR->isMaterializable());
-
- int32_t (*func)() = reinterpret_cast<int32_t(*)()>(
- (intptr_t)TheJIT->getPointerToFunction(funcIR));
- EXPECT_EQ(42, func()) << "func should return 42 from the static version,"
- << " not 7 from the IR version.";
-}
-
-TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) {
- LLVMContext Context;
- const std::string Bitcode =
- AssembleToBitcode(Context,
- "define i32 @recur1(i32 %a) { "
- " %zero = icmp eq i32 %a, 0 "
- " br i1 %zero, label %done, label %notdone "
- "done: "
- " ret i32 3 "
- "notdone: "
- " %am1 = sub i32 %a, 1 "
- " %result = call i32 @recur2(i32 %am1) "
- " ret i32 %result "
- "} "
- " "
- "define i32 @recur2(i32 %b) { "
- " %result = call i32 @recur1(i32 %b) "
- " ret i32 %result "
- "} ");
- ASSERT_FALSE(Bitcode.empty()) << "Assembling failed";
- Module *M;
- std::unique_ptr<ExecutionEngine> TheJIT(
- getJITFromBitcode(Context, Bitcode, M));
- ASSERT_TRUE(TheJIT.get()) << "Failed to create JIT.";
- TheJIT->DisableLazyCompilation(true);
-
- Function *recur1IR = M->getFunction("recur1");
- Function *recur2IR = M->getFunction("recur2");
- EXPECT_TRUE(recur1IR->isMaterializable());
- EXPECT_TRUE(recur2IR->isMaterializable());
-
- int32_t (*recur1)(int32_t) = reinterpret_cast<int32_t(*)(int32_t)>(
- (intptr_t)TheJIT->getPointerToFunction(recur1IR));
- EXPECT_EQ(3, recur1(4));
-}
-#endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
-
-}
diff --git a/unittests/ExecutionEngine/JIT/JITTests.def b/unittests/ExecutionEngine/JIT/JITTests.def
deleted file mode 100644
index 17c91e8..0000000
--- a/unittests/ExecutionEngine/JIT/JITTests.def
+++ /dev/null
@@ -1,4 +0,0 @@
-EXPORTS
-getPointerToNamedFunction
-JITTest_AvailableExternallyFunction
-JITTest_AvailableExternallyGlobal
diff --git a/unittests/ExecutionEngine/JIT/Makefile b/unittests/ExecutionEngine/JIT/Makefile
deleted file mode 100644
index d86c03b..0000000
--- a/unittests/ExecutionEngine/JIT/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-##===- unittests/ExecutionEngine/JIT/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-TESTNAME = JIT
-LINK_COMPONENTS := asmparser bitreader bitwriter jit native
-
-# The JIT tests need to dlopen things.
-NO_DEAD_STRIP := 1
-
-include $(LEVEL)/Makefile.config
-
-SOURCES := JITEventListenerTest.cpp JITMemoryManagerTest.cpp JITTest.cpp MultiJITTest.cpp
-
-
-ifeq ($(USE_INTEL_JITEVENTS), 1)
- # Build the Intel JIT Events interface tests
- SOURCES += IntelJITEventListenerTest.cpp
-
- # Add the Intel JIT Events include directory
- CPPFLAGS += -I$(INTEL_JITEVENTS_INCDIR)
-
- # Link against the LLVM Intel JIT Evens interface library
- LINK_COMPONENTS += debuginfo inteljitevents object
-endif
-
-ifeq ($(USE_OPROFILE), 1)
- # Build the OProfile JIT interface tests
- SOURCES += OProfileJITEventListenerTest.cpp
-
- # Link against the LLVM oprofile interface library
- LINK_COMPONENTS += oprofilejit
-endif
-
-EXPORTED_SYMBOL_FILE = $(PROJ_OBJ_DIR)/JITTests.exports
-
-include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
-
-# Permit these tests to use the JIT's symbolic lookup.
-LD.Flags += $(RDYNAMIC)
-
-# Symbol exports are necessary (at least for now) when building with LTO.
-$(LLVMUnitTestExe): $(NativeExportsFile)
-$(PROJ_OBJ_DIR)/JITTests.exports: $(PROJ_SRC_DIR)/JITTests.def $(PROJ_OBJ_DIR)/.dir
- tail -n +2 $< > $@
-
diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
deleted file mode 100644
index f530e0d..0000000
--- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-//===- MultiJITTest.cpp - Unit tests for instantiating multiple JITs ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/ExecutionEngine/GenericValue.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;
-
-namespace {
-
-// ARM, PowerPC and SystemZ tests disabled pending fix for PR10783.
-#if !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__) \
- && !defined(__aarch64__)
-
-bool LoadAssemblyInto(Module *M, const char *assembly) {
- SMDiagnostic Error;
- bool success =
- nullptr != ParseAssemblyString(assembly, M, Error, M->getContext());
- std::string errMsg;
- raw_string_ostream os(errMsg);
- Error.print("", os);
- EXPECT_TRUE(success) << os.str();
- return success;
-}
-
-void createModule1(LLVMContext &Context1, Module *&M1, Function *&FooF1) {
- M1 = new Module("test1", Context1);
- LoadAssemblyInto(M1,
- "define i32 @add1(i32 %ArgX1) { "
- "entry: "
- " %addresult = add i32 1, %ArgX1 "
- " ret i32 %addresult "
- "} "
- " "
- "define i32 @foo1() { "
- "entry: "
- " %add1 = call i32 @add1(i32 10) "
- " ret i32 %add1 "
- "} ");
- FooF1 = M1->getFunction("foo1");
-}
-
-void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) {
- M2 = new Module("test2", Context2);
- LoadAssemblyInto(M2,
- "define i32 @add2(i32 %ArgX2) { "
- "entry: "
- " %addresult = add i32 2, %ArgX2 "
- " ret i32 %addresult "
- "} "
- " "
- "define i32 @foo2() { "
- "entry: "
- " %add2 = call i32 @add2(i32 10) "
- " ret i32 %add2 "
- "} ");
- FooF2 = M2->getFunction("foo2");
-}
-
-TEST(MultiJitTest, EagerMode) {
- LLVMContext Context1;
- Module *M1 = nullptr;
- Function *FooF1 = nullptr;
- createModule1(Context1, M1, FooF1);
-
- LLVMContext Context2;
- Module *M2 = nullptr;
- Function *FooF2 = nullptr;
- createModule2(Context2, M2, FooF2);
-
- // Now we create the JIT in eager mode
- std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
- EE1->DisableLazyCompilation(true);
- std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
- EE2->DisableLazyCompilation(true);
-
- // Call the `foo' function with no arguments:
- std::vector<GenericValue> noargs;
- GenericValue gv1 = EE1->runFunction(FooF1, noargs);
- GenericValue gv2 = EE2->runFunction(FooF2, noargs);
-
- // Import result of execution:
- EXPECT_EQ(gv1.IntVal, 11);
- EXPECT_EQ(gv2.IntVal, 12);
-
- EE1->freeMachineCodeForFunction(FooF1);
- EE2->freeMachineCodeForFunction(FooF2);
-}
-
-TEST(MultiJitTest, LazyMode) {
- LLVMContext Context1;
- Module *M1 = nullptr;
- Function *FooF1 = nullptr;
- createModule1(Context1, M1, FooF1);
-
- LLVMContext Context2;
- Module *M2 = nullptr;
- Function *FooF2 = nullptr;
- createModule2(Context2, M2, FooF2);
-
- // Now we create the JIT in lazy mode
- std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
- EE1->DisableLazyCompilation(false);
- std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
- EE2->DisableLazyCompilation(false);
-
- // Call the `foo' function with no arguments:
- std::vector<GenericValue> noargs;
- GenericValue gv1 = EE1->runFunction(FooF1, noargs);
- GenericValue gv2 = EE2->runFunction(FooF2, noargs);
-
- // Import result of execution:
- EXPECT_EQ(gv1.IntVal, 11);
- EXPECT_EQ(gv2.IntVal, 12);
-
- EE1->freeMachineCodeForFunction(FooF1);
- EE2->freeMachineCodeForFunction(FooF2);
-}
-
-extern "C" {
- extern void *getPointerToNamedFunction(const char *Name);
-}
-
-TEST(MultiJitTest, JitPool) {
- LLVMContext Context1;
- Module *M1 = nullptr;
- Function *FooF1 = nullptr;
- createModule1(Context1, M1, FooF1);
-
- LLVMContext Context2;
- Module *M2 = nullptr;
- Function *FooF2 = nullptr;
- createModule2(Context2, M2, FooF2);
-
- // Now we create two JITs
- std::unique_ptr<ExecutionEngine> EE1(EngineBuilder(M1).create());
- std::unique_ptr<ExecutionEngine> EE2(EngineBuilder(M2).create());
-
- Function *F1 = EE1->FindFunctionNamed("foo1");
- void *foo1 = EE1->getPointerToFunction(F1);
-
- Function *F2 = EE2->FindFunctionNamed("foo2");
- void *foo2 = EE2->getPointerToFunction(F2);
-
- // Function in M1
- EXPECT_EQ(getPointerToNamedFunction("foo1"), foo1);
-
- // Function in M2
- EXPECT_EQ(getPointerToNamedFunction("foo2"), foo2);
-
- // Symbol search
- intptr_t
- sa = (intptr_t)getPointerToNamedFunction("getPointerToNamedFunction");
- EXPECT_TRUE(sa != 0);
- intptr_t fa = (intptr_t)&getPointerToNamedFunction;
- EXPECT_TRUE(fa != 0);
-#ifdef __i386__
- // getPointerToNamedFunction might be indirect jump on Win32 --enable-shared.
- // FF 25 <disp32>: jmp *(pointer to IAT)
- if (sa != fa && memcmp((char *)fa, "\xFF\x25", 2) == 0) {
- fa = *(intptr_t *)(fa + 2); // Address to IAT
- EXPECT_TRUE(fa != 0);
- fa = *(intptr_t *)fa; // Bound value of IAT
- }
-#elif defined(__x86_64__)
- // getPointerToNamedFunction might be indirect jump
- // on Win32 x64 --enable-shared.
- // FF 25 <pcrel32>: jmp *(RIP + pointer to IAT)
- if (sa != fa && memcmp((char *)fa, "\xFF\x25", 2) == 0) {
- fa += *(int32_t *)(fa + 2) + 6; // Address to IAT(RIP)
- fa = *(intptr_t *)fa; // Bound value of IAT
- }
-#endif
- EXPECT_TRUE(sa == fa);
-}
-#endif // !defined(__arm__) && !defined(__powerpc__) && !defined(__s390__)
-
-} // anonymous namespace
diff --git a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
deleted file mode 100644
index 7057fca..0000000
--- a/unittests/ExecutionEngine/JIT/OProfileJITEventListenerTest.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-//===- OProfileJITEventListenerTest.cpp - Unit tests for OProfileJITEventsListener --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--------------------------------------------------------------------------------------===//
-
-#include "llvm/ExecutionEngine/OProfileWrapper.h"
-#include "JITEventListenerTestCommon.h"
-#include "llvm/ExecutionEngine/JITEventListener.h"
-#include <list>
-#include <map>
-
-using namespace llvm;
-
-namespace {
-
-struct OprofileNativeFunction {
- const char* Name;
- uint64_t Addr;
- const void* CodePtr;
- unsigned int CodeSize;
-
- OprofileNativeFunction(const char* name,
- uint64_t addr,
- const void* code,
- unsigned int size)
- : Name(name)
- , Addr(addr)
- , CodePtr(code)
- , CodeSize(size) {
- }
-};
-
-typedef std::list<OprofileNativeFunction> NativeFunctionList;
-typedef std::list<debug_line_info> NativeDebugList;
-NativeFunctionList NativeFunctions;
-
-NativeCodeMap ReportedDebugFuncs;
-
-} // namespace
-
-/// Mock implementaion of opagent library
-namespace test_opagent {
-
-op_agent_t globalAgent = reinterpret_cast<op_agent_t>(42);
-
-op_agent_t open_agent()
-{
- // return non-null op_agent_t
- return globalAgent;
-}
-
-int close_agent(op_agent_t agent)
-{
- EXPECT_EQ(globalAgent, agent);
- return 0;
-}
-
-int write_native_code(op_agent_t agent,
- const char* name,
- uint64_t addr,
- void const* code,
- unsigned int size)
-{
- EXPECT_EQ(globalAgent, agent);
- OprofileNativeFunction func(name, addr, code, size);
- NativeFunctions.push_back(func);
-
- // Verify no other registration has take place for the same address
- EXPECT_TRUE(ReportedDebugFuncs.find(addr) == ReportedDebugFuncs.end());
-
- ReportedDebugFuncs[addr];
- return 0;
-}
-
-int write_debug_line_info(op_agent_t agent,
- void const* code,
- size_t num_entries,
- struct debug_line_info const* info)
-{
- EXPECT_EQ(globalAgent, agent);
-
- //verify code has been loaded first
- uint64_t addr = reinterpret_cast<uint64_t>(code);
- NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
- EXPECT_TRUE(i != ReportedDebugFuncs.end());
-
- NativeDebugList NativeInfo(info, info + num_entries);
-
- SourceLocations locs;
- for(NativeDebugList::iterator i = NativeInfo.begin();
- i != NativeInfo.end();
- ++i) {
- locs.push_back(std::make_pair(std::string(i->filename), i->lineno));
- }
- ReportedDebugFuncs[addr] = locs;
-
- return 0;
-}
-
-int unload_native_code(op_agent_t agent, uint64_t addr) {
- EXPECT_EQ(globalAgent, agent);
-
- //verify that something for the given JIT addr has been loaded first
- NativeCodeMap::iterator i = ReportedDebugFuncs.find(addr);
- EXPECT_TRUE(i != ReportedDebugFuncs.end());
- ReportedDebugFuncs.erase(i);
- return 0;
-}
-
-int version() {
- return 1;
-}
-
-bool is_oprofile_running() {
- return true;
-}
-
-} //namespace test_opagent
-
-class OProfileJITEventListenerTest
-: public JITEventListenerTestBase<OProfileWrapper>
-{
-public:
- OProfileJITEventListenerTest()
- : JITEventListenerTestBase<OProfileWrapper>(
- new OProfileWrapper(test_opagent::open_agent,
- test_opagent::close_agent,
- test_opagent::write_native_code,
- test_opagent::write_debug_line_info,
- test_opagent::unload_native_code,
- test_opagent::version,
- test_opagent::version,
- test_opagent::is_oprofile_running))
- {
- EXPECT_TRUE(0 != MockWrapper);
-
- Listener.reset(JITEventListener::createOProfileJITEventListener(
- MockWrapper.get()));
- EXPECT_TRUE(0 != Listener);
- EE->RegisterJITEventListener(Listener.get());
- }
-};
-
-TEST_F(OProfileJITEventListenerTest, NoDebugInfo) {
- TestNoDebugInfo(ReportedDebugFuncs);
-}
-
-TEST_F(OProfileJITEventListenerTest, SingleLine) {
- TestSingleLine(ReportedDebugFuncs);
-}
-
-TEST_F(OProfileJITEventListenerTest, MultipleLines) {
- TestMultipleLines(ReportedDebugFuncs);
-}
-
-TEST_F(OProfileJITEventListenerTest, MultipleFiles) {
- TestMultipleFiles(ReportedDebugFuncs);
-}
-
-testing::Environment* const jit_env =
- testing::AddGlobalTestEnvironment(new JITEnvironment);
diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
index afa3f2a..b10cbb4 100644
--- a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
@@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
IPO
- JIT
+ MC
MCJIT
ScalarOpts
Support
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index d03de89..c80b88b 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -139,8 +139,6 @@ protected:
// The operating systems below are known to be sufficiently incompatible
// that they will fail the MCJIT C API tests.
- UnsupportedOSs.push_back(Triple::Cygwin);
-
UnsupportedEnvironments.push_back(Triple::Cygnus);
}
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
index 98587f7..0582c92 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITMemoryManagerTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
-#include "llvm/ExecutionEngine/JIT.h"
#include "gtest/gtest.h"
using namespace llvm;
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
index c5ca36e..b0d1bb3 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
@@ -94,8 +94,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_case) {
Function *FA, *FB;
createTwoModuleCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -114,8 +114,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_reverse_case) {
Function *FA, *FB;
createTwoModuleCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -135,8 +135,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_extern_reverse_case) {
Function *FA, *FB;
createTwoModuleExternCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -156,8 +156,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_extern_case) {
Function *FA, *FB;
createTwoModuleExternCase(A, FA, B, FB);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -177,8 +177,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_consecutive_call_case) {
createTwoModuleExternCase(A, FA1, B, FB);
FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -213,8 +213,8 @@ TEST_F(MCJITMultipleModuleTest, two_module_global_variables_case) {
FB = startFunction<int32_t(void)>(B.get(), "FB");
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t FBPtr = TheJIT->getFunctionAddress(FB->getName().str());
TheJIT->finalizeObject();
@@ -241,9 +241,9 @@ TEST_F(MCJITMultipleModuleTest, three_module_case) {
Function *FA, *FB, *FC;
createThreeModuleCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
checkAdd(ptr);
@@ -266,9 +266,9 @@ TEST_F(MCJITMultipleModuleTest, three_module_case_reverse_order) {
Function *FA, *FB, *FC;
createThreeModuleCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -291,9 +291,9 @@ TEST_F(MCJITMultipleModuleTest, three_module_chain_case) {
Function *FA, *FB, *FC;
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FC->getName().str());
checkAdd(ptr);
@@ -316,9 +316,9 @@ TEST_F(MCJITMultipleModuleTest, three_modules_chain_case_reverse_order) {
Function *FA, *FB, *FC;
createThreeModuleChainedCallsCase(A, FA, B, FB, C, FC);
- createJIT(A.release());
- TheJIT->addModule(B.release());
- TheJIT->addModule(C.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+ TheJIT->addModule(std::move(C));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAdd(ptr);
@@ -341,8 +341,8 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case) {
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FA->getName().str());
checkAccumulate(ptr);
@@ -362,8 +362,8 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case_reverse_order) {
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
checkAccumulate(ptr);
@@ -383,8 +383,8 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) {
Function *FA, *FB1, *FB2;
createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
- createJIT(A.release());
- TheJIT->addModule(B.release());
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
uint64_t ptr = TheJIT->getFunctionAddress(FB1->getName().str());
checkAccumulate(ptr);
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
index fbbab42..2736383 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -11,7 +11,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
@@ -25,17 +24,7 @@ class TestObjectCache : public ObjectCache {
public:
TestObjectCache() : DuplicateInserted(false) { }
- virtual ~TestObjectCache() {
- // Free any buffers we've allocated.
- SmallVectorImpl<MemoryBuffer *>::iterator it, end;
- end = AllocatedBuffers.end();
- for (it = AllocatedBuffers.begin(); it != end; ++it) {
- delete *it;
- }
- AllocatedBuffers.clear();
- }
-
- virtual void notifyObjectCompiled(const Module *M, const MemoryBuffer *Obj) {
+ void notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) override {
// If we've seen this module before, note that.
const std::string ModuleID = M->getModuleIdentifier();
if (ObjMap.find(ModuleID) != ObjMap.end())
@@ -44,7 +33,7 @@ public:
ObjMap[ModuleID] = copyBuffer(Obj);
}
- virtual MemoryBuffer* getObject(const Module* M) {
+ virtual std::unique_ptr<MemoryBuffer> getObject(const Module* M) override {
const MemoryBuffer* BufferFound = getObjectInternal(M);
ModulesLookedUp.insert(M->getModuleIdentifier());
if (!BufferFound)
@@ -72,16 +61,18 @@ public:
}
private:
- MemoryBuffer *copyBuffer(const MemoryBuffer *Buf) {
+ MemoryBuffer *copyBuffer(MemoryBufferRef Buf) {
// Create a local copy of the buffer.
- MemoryBuffer *NewBuffer = MemoryBuffer::getMemBufferCopy(Buf->getBuffer());
- AllocatedBuffers.push_back(NewBuffer);
- return NewBuffer;
+ std::unique_ptr<MemoryBuffer> NewBuffer =
+ MemoryBuffer::getMemBufferCopy(Buf.getBuffer());
+ MemoryBuffer *Ret = NewBuffer.get();
+ AllocatedBuffers.push_back(std::move(NewBuffer));
+ return Ret;
}
StringMap<const MemoryBuffer *> ObjMap;
StringSet<> ModulesLookedUp;
- SmallVector<MemoryBuffer *, 2> AllocatedBuffers;
+ SmallVector<std::unique_ptr<MemoryBuffer>, 2> AllocatedBuffers;
bool DuplicateInserted;
};
@@ -121,7 +112,7 @@ protected:
TEST_F(MCJITObjectCacheTest, SetNullObjectCache) {
SKIP_UNSUPPORTED_PLATFORM;
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(nullptr);
@@ -137,7 +128,7 @@ TEST_F(MCJITObjectCacheTest, VerifyBasicObjectCaching) {
// Save a copy of the module pointer before handing it off to MCJIT.
const Module * SavedModulePointer = M.get();
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
@@ -164,7 +155,7 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Compile this module with an MCJIT engine
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
TheJIT->finalizeObject();
@@ -181,7 +172,7 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
const Module * SecondModulePointer = M.get();
// Create a new MCJIT instance to load this module then execute it.
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
compileAndRun();
@@ -198,7 +189,7 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
std::unique_ptr<TestObjectCache> Cache(new TestObjectCache);
// Compile this module with an MCJIT engine
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
TheJIT->finalizeObject();
@@ -216,7 +207,7 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
const Module * SecondModulePointer = M.get();
// Create a new MCJIT instance to load this module then execute it.
- createJIT(M.release());
+ createJIT(std::move(M));
TheJIT->setObjectCache(Cache.get());
// Verify that our object cache does not contain the module yet.
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
index c37c1d1..64d8c2f 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -49,7 +49,7 @@ TEST_F(MCJITTest, global_variable) {
int initialValue = 5;
GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue);
- createJIT(M.release());
+ createJIT(std::move(M));
void *globalPtr = TheJIT->getPointerToGlobal(Global);
EXPECT_TRUE(nullptr != globalPtr)
<< "Unable to get pointer to global value from JIT";
@@ -62,7 +62,7 @@ TEST_F(MCJITTest, add_function) {
SKIP_UNSUPPORTED_PLATFORM;
Function *F = insertAddFunction(M.get());
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t addPtr = TheJIT->getFunctionAddress(F->getName().str());
EXPECT_TRUE(0 != addPtr)
<< "Unable to get pointer to function from JIT";
@@ -83,7 +83,7 @@ TEST_F(MCJITTest, run_main) {
int rc = 6;
Function *Main = insertMainFunction(M.get(), 6);
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t ptr = TheJIT->getFunctionAddress(Main->getName().str());
EXPECT_TRUE(0 != ptr)
<< "Unable to get pointer to main() from JIT";
@@ -104,7 +104,7 @@ TEST_F(MCJITTest, return_global) {
Value *ReadGlobal = Builder.CreateLoad(GV);
endFunctionWithRet(ReturnGlobal, ReadGlobal);
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t rgvPtr = TheJIT->getFunctionAddress(ReturnGlobal->getName().str());
EXPECT_TRUE(0 != rgvPtr);
@@ -175,7 +175,7 @@ TEST_F(MCJITTest, multiple_functions) {
Inner = Outer;
}
- createJIT(M.release());
+ createJIT(std::move(M));
uint64_t ptr = TheJIT->getFunctionAddress(Outer->getName().str());
EXPECT_TRUE(0 != ptr)
<< "Unable to get pointer to outer function from JIT";
@@ -187,4 +187,16 @@ TEST_F(MCJITTest, multiple_functions) {
#endif /*!defined(__arm__)*/
+TEST_F(MCJITTest, multiple_decl_lookups) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ Function *Foo = insertExternalReferenceToFunction<void(void)>(M.get(), "_exit");
+ createJIT(std::move(M));
+ void *A = TheJIT->getPointerToFunction(Foo);
+ void *B = TheJIT->getPointerToFunction(Foo);
+
+ EXPECT_TRUE(A != 0) << "Failed lookup - test not correctly configured.";
+ EXPECT_EQ(A, B) << "Repeat calls to getPointerToFunction fail.";
+}
+
}
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
index a48c071..7d704de 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestAPICommon.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MCJIT_TEST_API_COMMON_H
-#define MCJIT_TEST_API_COMMON_H
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTAPICOMMON_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTAPICOMMON_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
@@ -93,5 +93,5 @@ protected:
} // namespace llvm
-#endif // MCJIT_TEST_API_COMMON_H
+#endif
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index 25de312..eea88bb 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -14,8 +14,8 @@
//===----------------------------------------------------------------------===//
-#ifndef MCJIT_TEST_BASE_H
-#define MCJIT_TEST_BASE_H
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H
#include "MCJITTestAPICommon.h"
#include "llvm/Config/config.h"
@@ -107,6 +107,15 @@ protected:
return Result;
}
+ // Inserts a declaration to a function defined elsewhere
+ template <typename FuncType>
+ Function *insertExternalReferenceToFunction(Module *M, StringRef Name) {
+ Function *Result = Function::Create(
+ TypeBuilder<FuncType, false>::get(Context),
+ GlobalValue::ExternalLinkage, Name, M);
+ return Result;
+ }
+
// Inserts an declaration to a function defined elsewhere
Function *insertExternalReferenceToFunction(Module *M, StringRef Name,
FunctionType *FuncTy) {
@@ -302,26 +311,23 @@ protected:
// The operating systems below are known to be incompatible with MCJIT as
// they are copied from the test/ExecutionEngine/MCJIT/lit.local.cfg and
// should be kept in sync.
- UnsupportedOSs.push_back(Triple::Cygwin);
UnsupportedOSs.push_back(Triple::Darwin);
UnsupportedEnvironments.push_back(Triple::Cygnus);
}
- void createJIT(Module *M) {
+ void createJIT(std::unique_ptr<Module> M) {
// Due to the EngineBuilder constructor, it is required to have a Module
// in order to construct an ExecutionEngine (i.e. MCJIT)
assert(M != 0 && "a non-null Module must be provided to create MCJIT");
- EngineBuilder EB(M);
+ EngineBuilder EB(std::move(M));
std::string Error;
TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
- .setUseMCJIT(true) /* can this be folded into the EngineKind enum? */
.setMCJITMemoryManager(MM)
.setErrorStr(&Error)
.setOptLevel(CodeGenOpt::None)
- .setAllocateGVsWithCode(false) /*does this do anything?*/
.setCodeModel(CodeModel::JITDefault)
.setRelocationModel(Reloc::Default)
.setMArch(MArch)
@@ -345,4 +351,4 @@ protected:
} // namespace llvm
-#endif // MCJIT_TEST_H
+#endif
diff --git a/unittests/ExecutionEngine/MCJIT/Makefile b/unittests/ExecutionEngine/MCJIT/Makefile
index c4dd740..2822b20 100644
--- a/unittests/ExecutionEngine/MCJIT/Makefile
+++ b/unittests/ExecutionEngine/MCJIT/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../../..
TESTNAME = MCJIT
-LINK_COMPONENTS := core ipo jit mcjit native support
+LINK_COMPONENTS := core ipo mcjit native support
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index 38e667f..8ecb883 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -14,7 +14,7 @@ LINK_COMPONENTS :=interpreter
include $(LEVEL)/Makefile.config
ifeq ($(TARGET_HAS_JIT),1)
- PARALLEL_DIRS = JIT MCJIT
+ PARALLEL_DIRS = MCJIT
endif
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/IR/CMakeLists.txt b/unittests/IR/CMakeLists.txt
index b439d59..a046209 100644
--- a/unittests/IR/CMakeLists.txt
+++ b/unittests/IR/CMakeLists.txt
@@ -10,6 +10,7 @@ set(IRSources
AttributesTest.cpp
ConstantRangeTest.cpp
ConstantsTest.cpp
+ DebugInfoTest.cpp
DominatorTreeTest.cpp
IRBuilderTest.cpp
InstructionsTest.cpp
@@ -21,6 +22,7 @@ set(IRSources
PatternMatch.cpp
TypeBuilderTest.cpp
TypesTest.cpp
+ UseTest.cpp
UserTest.cpp
ValueHandleTest.cpp
ValueMapTest.cpp
diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp
index 0cd8549..5414b25 100644
--- a/unittests/IR/ConstantsTest.cpp
+++ b/unittests/IR/ConstantsTest.cpp
@@ -274,5 +274,78 @@ TEST(ConstantsTest, ReplaceWithConstantTest) {
#undef CHECK
+TEST(ConstantsTest, ConstantArrayReplaceWithConstant) {
+ LLVMContext Context;
+ std::unique_ptr<Module> M(new Module("MyModule", Context));
+
+ Type *IntTy = Type::getInt8Ty(Context);
+ ArrayType *ArrayTy = ArrayType::get(IntTy, 2);
+ Constant *A01Vals[2] = {ConstantInt::get(IntTy, 0),
+ ConstantInt::get(IntTy, 1)};
+ Constant *A01 = ConstantArray::get(ArrayTy, A01Vals);
+
+ Constant *Global = new GlobalVariable(*M, IntTy, false,
+ GlobalValue::ExternalLinkage, nullptr);
+ Constant *GlobalInt = ConstantExpr::getPtrToInt(Global, IntTy);
+ Constant *A0GVals[2] = {ConstantInt::get(IntTy, 0), GlobalInt};
+ Constant *A0G = ConstantArray::get(ArrayTy, A0GVals);
+ ASSERT_NE(A01, A0G);
+
+ GlobalVariable *RefArray =
+ new GlobalVariable(*M, ArrayTy, false, GlobalValue::ExternalLinkage, A0G);
+ ASSERT_EQ(A0G, RefArray->getInitializer());
+
+ GlobalInt->replaceAllUsesWith(ConstantInt::get(IntTy, 1));
+ ASSERT_EQ(A01, RefArray->getInitializer());
+}
+
+TEST(ConstantsTest, ConstantExprReplaceWithConstant) {
+ LLVMContext Context;
+ std::unique_ptr<Module> M(new Module("MyModule", Context));
+
+ Type *IntTy = Type::getInt8Ty(Context);
+ Constant *G1 = new GlobalVariable(*M, IntTy, false,
+ GlobalValue::ExternalLinkage, nullptr);
+ Constant *G2 = new GlobalVariable(*M, IntTy, false,
+ GlobalValue::ExternalLinkage, nullptr);
+ ASSERT_NE(G1, G2);
+
+ Constant *Int1 = ConstantExpr::getPtrToInt(G1, IntTy);
+ Constant *Int2 = ConstantExpr::getPtrToInt(G2, IntTy);
+ ASSERT_NE(Int1, Int2);
+
+ GlobalVariable *Ref =
+ new GlobalVariable(*M, IntTy, false, GlobalValue::ExternalLinkage, Int1);
+ ASSERT_EQ(Int1, Ref->getInitializer());
+
+ G1->replaceAllUsesWith(G2);
+ ASSERT_EQ(Int2, Ref->getInitializer());
+}
+
+TEST(ConstantsTest, GEPReplaceWithConstant) {
+ LLVMContext Context;
+ std::unique_ptr<Module> M(new Module("MyModule", Context));
+
+ Type *IntTy = Type::getInt32Ty(Context);
+ Type *PtrTy = PointerType::get(IntTy, 0);
+ auto *C1 = ConstantInt::get(IntTy, 1);
+ auto *Placeholder = new GlobalVariable(
+ *M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr);
+ auto *GEP = ConstantExpr::getGetElementPtr(Placeholder, C1);
+ ASSERT_EQ(GEP->getOperand(0), Placeholder);
+
+ auto *Ref =
+ new GlobalVariable(*M, PtrTy, false, GlobalValue::ExternalLinkage, GEP);
+ ASSERT_EQ(GEP, Ref->getInitializer());
+
+ auto *Global = new GlobalVariable(*M, PtrTy, false,
+ GlobalValue::ExternalLinkage, nullptr);
+ auto *Alias = GlobalAlias::create(IntTy, 0, GlobalValue::ExternalLinkage,
+ "alias", Global, M.get());
+ Placeholder->replaceAllUsesWith(Alias);
+ ASSERT_EQ(GEP, Ref->getInitializer());
+ ASSERT_EQ(GEP->getOperand(0), Alias);
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/unittests/IR/DebugInfoTest.cpp b/unittests/IR/DebugInfoTest.cpp
new file mode 100644
index 0000000..1fa851e
--- /dev/null
+++ b/unittests/IR/DebugInfoTest.cpp
@@ -0,0 +1,68 @@
+//===- llvm/unittest/IR/DebugInfo.cpp - DebugInfo 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/DebugInfo.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+
+static void PrintTo(const StringRef &S, ::std::ostream *os) {
+ *os << "(" << (const void *)S.data() << "," << S.size() << ") = '";
+ for (auto C : S)
+ if (C)
+ *os << C;
+ else
+ *os << "\\00";
+ *os << "'";
+}
+static void PrintTo(const DIHeaderFieldIterator &I, ::std::ostream *os) {
+ PrintTo(I.getCurrent(), os);
+ *os << " in ";
+ PrintTo(I.getHeader(), os);
+}
+
+} // end namespace llvm
+
+namespace {
+
+#define MAKE_FIELD_ITERATOR(S) \
+ DIHeaderFieldIterator(StringRef(S, sizeof(S) - 1))
+TEST(DebugInfoTest, DIHeaderFieldIterator) {
+ ASSERT_EQ(DIHeaderFieldIterator(), DIHeaderFieldIterator());
+
+ ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR(""));
+ ASSERT_EQ(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR(""));
+ ASSERT_EQ("", *DIHeaderFieldIterator(""));
+
+ ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("stuff"));
+ ASSERT_EQ(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("stuff"));
+ ASSERT_EQ("stuff", *DIHeaderFieldIterator("stuff"));
+
+ ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("st\0uff"));
+ ASSERT_NE(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("st\0uff"));
+ ASSERT_EQ(DIHeaderFieldIterator(), ++++MAKE_FIELD_ITERATOR("st\0uff"));
+ ASSERT_EQ("st", *MAKE_FIELD_ITERATOR("st\0uff"));
+ ASSERT_EQ("uff", *++MAKE_FIELD_ITERATOR("st\0uff"));
+
+ ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("stuff\0"));
+ ASSERT_NE(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("stuff\0"));
+ ASSERT_EQ(DIHeaderFieldIterator(), ++++MAKE_FIELD_ITERATOR("stuff\0"));
+ ASSERT_EQ("stuff", *MAKE_FIELD_ITERATOR("stuff\0"));
+ ASSERT_EQ("", *++MAKE_FIELD_ITERATOR("stuff\0"));
+
+ ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("\0stuff"));
+ ASSERT_NE(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("\0stuff"));
+ ASSERT_EQ(DIHeaderFieldIterator(), ++++MAKE_FIELD_ITERATOR("\0stuff"));
+ ASSERT_EQ("", *MAKE_FIELD_ITERATOR("\0stuff"));
+ ASSERT_EQ("stuff", *++MAKE_FIELD_ITERATOR("\0stuff"));
+}
+
+} // end namespace
diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp
index ab43d1c..6c43d6f 100644
--- a/unittests/IR/DominatorTreeTest.cpp
+++ b/unittests/IR/DominatorTreeTest.cpp
@@ -186,8 +186,7 @@ namespace llvm {
};
char DPass::ID = 0;
-
- Module* makeLLVMModule(DPass *P) {
+ std::unique_ptr<Module> makeLLVMModule(DPass *P) {
const char *ModuleStrig =
"declare i32 @g()\n" \
"define void @f(i32 %x) {\n" \
@@ -213,12 +212,12 @@ namespace llvm {
"}\n";
LLVMContext &C = getGlobalContext();
SMDiagnostic Err;
- return ParseAssemblyString(ModuleStrig, nullptr, Err, C);
+ return parseAssemblyString(ModuleStrig, Err, C);
}
TEST(DominatorTree, Unreachable) {
DPass *P = new DPass();
- std::unique_ptr<Module> M(makeLLVMModule(P));
+ std::unique_ptr<Module> M = makeLLVMModule(P);
PassManager Passes;
Passes.add(P);
Passes.run(*M);
diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp
index 2108575..df5c840 100644
--- a/unittests/IR/IRBuilderTest.cpp
+++ b/unittests/IR/IRBuilderTest.cpp
@@ -189,12 +189,16 @@ TEST_F(IRBuilderTest, FastMathFlags) {
Builder.clearFastMathFlags();
+ // To test a copy, make sure that a '0' and a '1' change state.
F = Builder.CreateFDiv(F, F);
ASSERT_TRUE(isa<Instruction>(F));
FDiv = cast<Instruction>(F);
EXPECT_FALSE(FDiv->getFastMathFlags().any());
+ FDiv->setHasAllowReciprocal(true);
+ FAdd->setHasAllowReciprocal(false);
FDiv->copyFastMathFlags(FAdd);
EXPECT_TRUE(FDiv->hasNoNaNs());
+ EXPECT_FALSE(FDiv->hasAllowReciprocal());
}
diff --git a/unittests/IR/LegacyPassManagerTest.cpp b/unittests/IR/LegacyPassManagerTest.cpp
index 9c2a835..4efc2f5 100644
--- a/unittests/IR/LegacyPassManagerTest.cpp
+++ b/unittests/IR/LegacyPassManagerTest.cpp
@@ -54,11 +54,11 @@ namespace llvm {
static char run;
static char ID;
ModuleNDNM() : ModulePass(ID) { }
- virtual bool runOnModule(Module &M) {
+ bool runOnModule(Module &M) override {
run++;
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
}
};
@@ -70,7 +70,7 @@ namespace llvm {
static char run;
static char ID;
ModuleNDM() : ModulePass(ID) {}
- virtual bool runOnModule(Module &M) {
+ bool runOnModule(Module &M) override {
run++;
return true;
}
@@ -83,7 +83,7 @@ namespace llvm {
static char run;
static char ID;
ModuleNDM2() : ModulePass(ID) {}
- virtual bool runOnModule(Module &M) {
+ bool runOnModule(Module &M) override {
run++;
return true;
}
@@ -98,12 +98,12 @@ namespace llvm {
ModuleDNM() : ModulePass(ID) {
initializeModuleNDMPass(*PassRegistry::getPassRegistry());
}
- virtual bool runOnModule(Module &M) {
+ bool runOnModule(Module &M) override {
EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run++;
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<ModuleNDM>();
AU.setPreservesAll();
}
@@ -139,7 +139,7 @@ namespace llvm {
runc = 0;
}
- virtual void releaseMemory() {
+ void releaseMemory() override {
EXPECT_GT(runc, 0);
EXPECT_GT(allocated, 0);
allocated--;
@@ -157,12 +157,12 @@ namespace llvm {
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
#endif
- virtual bool doInitialization(T &t) {
+ bool doInitialization(T &t) override {
EXPECT_FALSE(PassTestBase<P>::initialized);
PassTestBase<P>::initialized = true;
return false;
}
- virtual bool doFinalization(T &t) {
+ bool doFinalization(T &t) override {
EXPECT_FALSE(PassTestBase<P>::finalized);
PassTestBase<P>::finalized = true;
EXPECT_EQ(0, PassTestBase<P>::allocated);
@@ -175,7 +175,7 @@ namespace llvm {
CGPass() {
initializeCGPassPass(*PassRegistry::getPassRegistry());
}
- virtual bool runOnSCC(CallGraphSCC &SCMM) {
+ bool runOnSCC(CallGraphSCC &SCMM) override {
EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
@@ -184,7 +184,7 @@ namespace llvm {
struct FPass : public PassTest<Module, FunctionPass> {
public:
- virtual bool runOnFunction(Function &F) {
+ bool runOnFunction(Function &F) override {
// FIXME: PR4112
// EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>());
run();
@@ -209,17 +209,17 @@ namespace llvm {
}
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
- virtual bool doInitialization(Loop* L, LPPassManager &LPM) {
+ bool doInitialization(Loop* L, LPPassManager &LPM) override {
initialized = true;
initcount++;
return false;
}
- virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
+ bool runOnLoop(Loop *L, LPPassManager &LPM) override {
EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
- virtual bool doFinalization() {
+ bool doFinalization() override {
fincount++;
finalized = true;
return false;
@@ -242,25 +242,25 @@ namespace llvm {
inited = 0;
fin = 0;
}
- virtual bool doInitialization(Module &M) {
+ bool doInitialization(Module &M) override {
EXPECT_FALSE(initialized);
initialized = true;
return false;
}
- virtual bool doInitialization(Function &F) {
+ bool doInitialization(Function &F) override {
inited++;
return false;
}
- virtual bool runOnBasicBlock(BasicBlock &BB) {
+ bool runOnBasicBlock(BasicBlock &BB) override {
EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
- virtual bool doFinalization(Function &F) {
+ bool doFinalization(Function &F) override {
fin++;
return false;
}
- virtual bool doFinalization(Module &M) {
+ bool doFinalization(Module &M) override {
EXPECT_FALSE(finalized);
finalized = true;
EXPECT_EQ(0, allocated);
@@ -276,7 +276,7 @@ namespace llvm {
OnTheFlyTest() : ModulePass(ID) {
initializeFPassPass(*PassRegistry::getPassRegistry());
}
- virtual bool runOnModule(Module &M) {
+ bool runOnModule(Module &M) override {
EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
Function &F = *I;
@@ -287,7 +287,7 @@ namespace llvm {
}
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<FPass>();
}
};
@@ -303,7 +303,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
PassManager Passes;
- Passes.add(new DataLayoutPass(&M));
+ Passes.add(new DataLayoutPass());
Passes.add(mNDM2);
Passes.add(mNDM);
Passes.add(mNDNM);
@@ -327,7 +327,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
PassManager Passes;
- Passes.add(new DataLayoutPass(&M));
+ Passes.add(new DataLayoutPass());
Passes.add(mNDM);
Passes.add(mNDNM);
Passes.add(mNDM2);// invalidates mNDM needed by mDNM
@@ -349,7 +349,7 @@ namespace llvm {
std::unique_ptr<Module> M(makeLLVMModule());
T *P = new T();
PassManager Passes;
- Passes.add(new DataLayoutPass(M.get()));
+ Passes.add(new DataLayoutPass());
Passes.add(P);
Passes.run(*M);
T::finishedOK(run);
@@ -360,7 +360,7 @@ namespace llvm {
Module *M = makeLLVMModule();
T *P = new T();
PassManager Passes;
- Passes.add(new DataLayoutPass(M));
+ Passes.add(new DataLayoutPass());
Passes.add(P);
Passes.run(*M);
T::finishedOK(run, N);
@@ -398,7 +398,7 @@ namespace llvm {
SCOPED_TRACE("Running OnTheFlyTest");
struct OnTheFlyTest *O = new OnTheFlyTest();
PassManager Passes;
- Passes.add(new DataLayoutPass(M));
+ Passes.add(new DataLayoutPass());
Passes.add(O);
Passes.run(*M);
diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp
index 25037a7..d493156 100644
--- a/unittests/IR/PassManagerTest.cpp
+++ b/unittests/IR/PassManagerTest.cpp
@@ -168,7 +168,7 @@ struct TestInvalidationFunctionPass {
Module *parseIR(const char *IR) {
LLVMContext &C = getGlobalContext();
SMDiagnostic Err;
- return ParseAssemblyString(IR, nullptr, Err, C);
+ return parseAssemblyString(IR, Err, C).release();
}
class PassManagerTest : public ::testing::Test {
diff --git a/unittests/IR/UseTest.cpp b/unittests/IR/UseTest.cpp
new file mode 100644
index 0000000..3f33ca6
--- /dev/null
+++ b/unittests/IR/UseTest.cpp
@@ -0,0 +1,112 @@
+//===- llvm/unittest/IR/UseTest.cpp - Use 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/AsmParser/Parser.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(UseTest, sort) {
+ LLVMContext C;
+
+ const char *ModuleString = "define void @f(i32 %x) {\n"
+ "entry:\n"
+ " %v0 = add i32 %x, 0\n"
+ " %v2 = add i32 %x, 2\n"
+ " %v5 = add i32 %x, 5\n"
+ " %v1 = add i32 %x, 1\n"
+ " %v3 = add i32 %x, 3\n"
+ " %v7 = add i32 %x, 7\n"
+ " %v6 = add i32 %x, 6\n"
+ " %v4 = add i32 %x, 4\n"
+ " ret void\n"
+ "}\n";
+ SMDiagnostic Err;
+ char vnbuf[8];
+ std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
+ Function *F = M->getFunction("f");
+ ASSERT_TRUE(F);
+ ASSERT_TRUE(F->arg_begin() != F->arg_end());
+ Argument &X = *F->arg_begin();
+ ASSERT_EQ("x", X.getName());
+
+ X.sortUseList([](const Use &L, const Use &R) {
+ return L.getUser()->getName() < R.getUser()->getName();
+ });
+ unsigned I = 0;
+ for (User *U : X.users()) {
+ snprintf(vnbuf, sizeof(vnbuf), "v%u", I++);
+ EXPECT_EQ(vnbuf, U->getName());
+ }
+ ASSERT_EQ(8u, I);
+
+ X.sortUseList([](const Use &L, const Use &R) {
+ return L.getUser()->getName() > R.getUser()->getName();
+ });
+ I = 0;
+ for (User *U : X.users()) {
+ snprintf(vnbuf, sizeof(vnbuf), "v%u", (7 - I++));
+ EXPECT_EQ(vnbuf, U->getName());
+ }
+ ASSERT_EQ(8u, I);
+}
+
+TEST(UseTest, reverse) {
+ LLVMContext C;
+
+ const char *ModuleString = "define void @f(i32 %x) {\n"
+ "entry:\n"
+ " %v0 = add i32 %x, 0\n"
+ " %v2 = add i32 %x, 2\n"
+ " %v5 = add i32 %x, 5\n"
+ " %v1 = add i32 %x, 1\n"
+ " %v3 = add i32 %x, 3\n"
+ " %v7 = add i32 %x, 7\n"
+ " %v6 = add i32 %x, 6\n"
+ " %v4 = add i32 %x, 4\n"
+ " ret void\n"
+ "}\n";
+ SMDiagnostic Err;
+ char vnbuf[8];
+ std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
+ Function *F = M->getFunction("f");
+ ASSERT_TRUE(F);
+ ASSERT_TRUE(F->arg_begin() != F->arg_end());
+ Argument &X = *F->arg_begin();
+ ASSERT_EQ("x", X.getName());
+
+ X.sortUseList([](const Use &L, const Use &R) {
+ return L.getUser()->getName() < R.getUser()->getName();
+ });
+ unsigned I = 0;
+ for (User *U : X.users()) {
+ snprintf(vnbuf, sizeof(vnbuf), "v%u", I++);
+ EXPECT_EQ(vnbuf, U->getName());
+ }
+ ASSERT_EQ(8u, I);
+
+ X.reverseUseList();
+ I = 0;
+ for (User *U : X.users()) {
+ snprintf(vnbuf, sizeof(vnbuf), "v%u", (7 - I++));
+ EXPECT_EQ(vnbuf, U->getName());
+ }
+ ASSERT_EQ(8u, I);
+}
+
+} // end anonymous namespace
diff --git a/unittests/IR/UserTest.cpp b/unittests/IR/UserTest.cpp
index eb07e82..5572424 100644
--- a/unittests/IR/UserTest.cpp
+++ b/unittests/IR/UserTest.cpp
@@ -65,7 +65,7 @@ TEST(UserTest, ValueOpIteration) {
" ret void\n"
"}\n";
SMDiagnostic Err;
- Module *M = ParseAssemblyString(ModuleString, nullptr, Err, C);
+ std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
Function *F = M->getFunction("f");
BasicBlock &ExitBB = F->back();
diff --git a/unittests/IR/ValueMapTest.cpp b/unittests/IR/ValueMapTest.cpp
index 0b7198f..a6bad71 100644
--- a/unittests/IR/ValueMapTest.cpp
+++ b/unittests/IR/ValueMapTest.cpp
@@ -186,11 +186,11 @@ struct LockMutex : ValueMapConfig<KeyT, MutexT> {
};
static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
*Data.CalledRAUW = true;
- EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked.";
+ EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
}
static void onDelete(const ExtraData &Data, KeyT Old) {
*Data.CalledDeleted = true;
- EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked.";
+ EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
}
static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
};
diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp
index 61e44a9..4dd0c2c 100644
--- a/unittests/IR/ValueTest.cpp
+++ b/unittests/IR/ValueTest.cpp
@@ -34,7 +34,7 @@ TEST(ValueTest, UsedInBasicBlock) {
" ret void\n"
"}\n";
SMDiagnostic Err;
- Module *M = ParseAssemblyString(ModuleString, nullptr, Err, C);
+ std::unique_ptr<Module> M = parseAssemblyString(ModuleString, Err, C);
Function *F = M->getFunction("f");
@@ -60,6 +60,10 @@ TEST(GlobalTest, CreateAddressSpace) {
GlobalVariable::NotThreadLocal,
1);
+ EXPECT_TRUE(Value::MaximumAlignment == 536870912U);
+ Dummy0->setAlignment(536870912U);
+ EXPECT_EQ(Dummy0->getAlignment(), 536870912U);
+
// Make sure the address space isn't dropped when returning this.
Constant *Dummy1 = M->getOrInsertGlobal("dummy", Int32Ty);
EXPECT_EQ(Dummy0, Dummy1);
@@ -83,4 +87,23 @@ TEST(GlobalTest, CreateAddressSpace) {
EXPECT_EQ(1u, DummyCast1->getType()->getPointerAddressSpace());
EXPECT_NE(DummyCast0, DummyCast1) << *DummyCast1;
}
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+TEST(GlobalTest, AlignDeath) {
+ LLVMContext &Ctx = getGlobalContext();
+ std::unique_ptr<Module> M(new Module("TestModule", Ctx));
+ Type *Int32Ty = Type::getInt32Ty(Ctx);
+ GlobalVariable *Var =
+ new GlobalVariable(*M, Int32Ty, true, GlobalValue::ExternalLinkage,
+ Constant::getAllOnesValue(Int32Ty), "var", nullptr,
+ GlobalVariable::NotThreadLocal, 1);
+
+ EXPECT_DEATH(Var->setAlignment(536870913U), "Alignment is not a power of 2");
+ EXPECT_DEATH(Var->setAlignment(1073741824U),
+ "Alignment is greater than MaximumAlignment");
+}
+#endif
+#endif
+
} // end anonymous namespace
diff --git a/unittests/LineEditor/CMakeLists.txt b/unittests/LineEditor/CMakeLists.txt
index c6823d8..70d7497 100644
--- a/unittests/LineEditor/CMakeLists.txt
+++ b/unittests/LineEditor/CMakeLists.txt
@@ -1,5 +1,6 @@
set(LLVM_LINK_COMPONENTS
LineEditor
+ Support
)
add_llvm_unittest(LineEditorTests
diff --git a/unittests/Linker/CMakeLists.txt b/unittests/Linker/CMakeLists.txt
index c3dccb6..05f45c0 100644
--- a/unittests/Linker/CMakeLists.txt
+++ b/unittests/Linker/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ AsmParser
core
linker
)
diff --git a/unittests/Linker/LinkModulesTest.cpp b/unittests/Linker/LinkModulesTest.cpp
index 4ccced1..b15d180 100644
--- a/unittests/Linker/LinkModulesTest.cpp
+++ b/unittests/Linker/LinkModulesTest.cpp
@@ -7,12 +7,14 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/AsmParser/Parser.h"
#include "llvm/Linker/Linker.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -88,7 +90,7 @@ TEST_F(LinkModuleTest, BlockAddress) {
Builder.CreateRet(ConstantPointerNull::get(Type::getInt8PtrTy(Ctx)));
Module *LinkedModule = new Module("MyModuleLinked", Ctx);
- Linker::LinkModules(LinkedModule, M.get(), Linker::PreserveSource, nullptr);
+ Linker::LinkModules(LinkedModule, M.get());
// Delete the original module.
M.reset();
@@ -122,12 +124,13 @@ TEST_F(LinkModuleTest, BlockAddress) {
delete LinkedModule;
}
-TEST_F(LinkModuleTest, EmptyModule) {
+static Module *getInternal(LLVMContext &Ctx) {
Module *InternalM = new Module("InternalModule", Ctx);
FunctionType *FTy = FunctionType::get(
Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), false /*=isVarArgs*/);
- F = Function::Create(FTy, Function::InternalLinkage, "bar", InternalM);
+ Function *F =
+ Function::Create(FTy, Function::InternalLinkage, "bar", InternalM);
F->setCallingConv(CallingConv::C);
BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
@@ -141,16 +144,37 @@ TEST_F(LinkModuleTest, EmptyModule) {
GlobalValue::InternalLinkage, nullptr, "g");
GV->setInitializer(ConstantStruct::get(STy, F));
+ return InternalM;
+}
+
+TEST_F(LinkModuleTest, EmptyModule) {
+ std::unique_ptr<Module> InternalM(getInternal(Ctx));
+ std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
+ Linker::LinkModules(EmptyM.get(), InternalM.get());
+}
+
+TEST_F(LinkModuleTest, EmptyModule2) {
+ std::unique_ptr<Module> InternalM(getInternal(Ctx));
+ std::unique_ptr<Module> EmptyM(new Module("EmptyModule1", Ctx));
+ Linker::LinkModules(InternalM.get(), EmptyM.get());
+}
+
+TEST_F(LinkModuleTest, TypeMerge) {
+ LLVMContext C;
+ SMDiagnostic Err;
+
+ const char *M1Str = "%t = type {i32}\n"
+ "@t1 = weak global %t zeroinitializer\n";
+ std::unique_ptr<Module> M1 = parseAssemblyString(M1Str, Err, C);
- Module *EmptyM = new Module("EmptyModule1", Ctx);
- Linker::LinkModules(EmptyM, InternalM, Linker::PreserveSource, nullptr);
+ const char *M2Str = "%t = type {i32}\n"
+ "@t2 = weak global %t zeroinitializer\n";
+ std::unique_ptr<Module> M2 = parseAssemblyString(M2Str, Err, C);
- delete EmptyM;
- EmptyM = new Module("EmptyModule2", Ctx);
- Linker::LinkModules(InternalM, EmptyM, Linker::PreserveSource, nullptr);
+ Linker::LinkModules(M1.get(), M2.get(), [](const llvm::DiagnosticInfo &){});
- delete EmptyM;
- delete InternalM;
+ EXPECT_EQ(M1->getNamedGlobal("t1")->getType(),
+ M1->getNamedGlobal("t2")->getType());
}
} // end anonymous namespace
diff --git a/unittests/Linker/Makefile b/unittests/Linker/Makefile
index c6058c4..ddbce07 100644
--- a/unittests/Linker/Makefile
+++ b/unittests/Linker/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = Linker
-LINK_COMPONENTS := core linker
+LINK_COMPONENTS := core linker asmparser
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/MC/CMakeLists.txt b/unittests/MC/CMakeLists.txt
index e2beab2..c82bcde 100644
--- a/unittests/MC/CMakeLists.txt
+++ b/unittests/MC/CMakeLists.txt
@@ -1,9 +1,18 @@
set(LLVM_LINK_COMPONENTS
- MCAnalysis
+ ${LLVM_TARGETS_TO_BUILD}
+ MC
+ MCDisassembler
+ Support
)
add_llvm_unittest(MCTests
- MCAtomTest.cpp
+ Disassembler.cpp
StringTableBuilderTest.cpp
YAMLTest.cpp
)
+
+foreach(t ${LLVM_TARGETS_TO_BUILD})
+ if (IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${t}")
+ add_subdirectory(${t})
+ endif (IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${t}")
+endforeach()
diff --git a/unittests/MC/Disassembler.cpp b/unittests/MC/Disassembler.cpp
new file mode 100644
index 0000000..dd0f1ef
--- /dev/null
+++ b/unittests/MC/Disassembler.cpp
@@ -0,0 +1,64 @@
+//===- llvm/unittest/Object/Disassembler.cpp ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/Disassembler.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+static const char *symbolLookupCallback(void *DisInfo, uint64_t ReferenceValue,
+ uint64_t *ReferenceType,
+ uint64_t ReferencePC,
+ const char **ReferenceName) {
+ *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
+ return nullptr;
+}
+
+TEST(Disassembler, Test1) {
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllDisassemblers();
+
+ uint8_t Bytes[] = {0x90, 0x90, 0xeb, 0xfd};
+ uint8_t *BytesP = Bytes;
+ const char OutStringSize = 100;
+ char OutString[OutStringSize];
+ LLVMDisasmContextRef DCR = LLVMCreateDisasm("x86_64-pc-linux", nullptr, 0,
+ nullptr, symbolLookupCallback);
+ if (!DCR)
+ return;
+
+ size_t InstSize;
+ unsigned NumBytes = sizeof(Bytes);
+ unsigned PC = 0;
+
+ InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
+ OutStringSize);
+ EXPECT_EQ(InstSize, 1U);
+ EXPECT_EQ(StringRef(OutString), "\tnop");
+ PC += InstSize;
+ BytesP += InstSize;
+ NumBytes -= InstSize;
+
+ InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
+ OutStringSize);
+ EXPECT_EQ(InstSize, 1U);
+ EXPECT_EQ(StringRef(OutString), "\tnop");
+ PC += InstSize;
+ BytesP += InstSize;
+ NumBytes -= InstSize;
+
+ InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
+ OutStringSize);
+ EXPECT_EQ(InstSize, 2U);
+ EXPECT_EQ(StringRef(OutString), "\tjmp\t0x1");
+
+ LLVMDisasmDispose(DCR);
+}
diff --git a/unittests/MC/Hexagon/CMakeLists.txt b/unittests/MC/Hexagon/CMakeLists.txt
new file mode 100644
index 0000000..6d4ee93
--- /dev/null
+++ b/unittests/MC/Hexagon/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS
+ HexagonCodeGen
+ HexagonDesc
+ HexagonInfo
+ MC
+ Support
+ )
+
+include_directories (${LLVM_MAIN_SRC_DIR}/lib/Target/Hexagon)
+include_directories (${LLVM_BINARY_DIR}/lib/Target/Hexagon)
+
+add_llvm_unittest(HexagonTests
+ HexagonMCCodeEmitterTest.cpp
+ )
diff --git a/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp b/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp
new file mode 100644
index 0000000..958a21f
--- /dev/null
+++ b/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp
@@ -0,0 +1,53 @@
+#include "gtest/gtest.h"
+
+#include <memory>
+
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "MCTargetDesc/HexagonMCInst.h"
+#include "MCTargetDesc/HexagonMCTargetDesc.h"
+
+namespace {
+class TestEmitter {
+public:
+ TestEmitter() : Triple("hexagon-unknown-elf") {
+ LLVMInitializeHexagonTargetInfo();
+ LLVMInitializeHexagonTarget();
+ LLVMInitializeHexagonTargetMC();
+ std::string error;
+ Target = llvm::TargetRegistry::lookupTarget("hexagon", error);
+ assert(Target != nullptr && "Expected to find target");
+ assert(error.empty() && "Error should be empty if we have a target");
+ RegisterInfo = Target->createMCRegInfo(Triple);
+ assert(RegisterInfo != nullptr && "Expecting to find register info");
+ AsmInfo = Target->createMCAsmInfo(*RegisterInfo, Triple);
+ assert(AsmInfo != nullptr && "Expecting to find asm info");
+ Context = new llvm::MCContext(AsmInfo, RegisterInfo, nullptr);
+ assert(Context != nullptr && "Expecting to create a context");
+ Subtarget = Target->createMCSubtargetInfo(Triple, "hexagonv4", "");
+ assert(Subtarget != nullptr && "Expecting to find a subtarget");
+ InstrInfo = Target->createMCInstrInfo();
+ assert(InstrInfo != nullptr && "Expecting to find instr info");
+ Emitter = Target->createMCCodeEmitter(*InstrInfo, *RegisterInfo, *Subtarget,
+ *Context);
+ assert(Emitter != nullptr);
+ }
+ std::string Triple;
+ llvm::Target const *Target;
+ llvm::MCRegisterInfo *RegisterInfo;
+ llvm::MCAsmInfo *AsmInfo;
+ llvm::MCContext *Context;
+ llvm::MCSubtargetInfo *Subtarget;
+ llvm::MCInstrInfo *InstrInfo;
+ llvm::MCCodeEmitter *Emitter;
+};
+TestEmitter Emitter;
+}
+
+TEST(HexagonMCCodeEmitter, emitter_creation) {
+ ASSERT_NE(nullptr, Emitter.Emitter);
+}
diff --git a/unittests/MC/MCAtomTest.cpp b/unittests/MC/MCAtomTest.cpp
deleted file mode 100644
index 16228b5..0000000
--- a/unittests/MC/MCAtomTest.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===- llvm/unittest/MC/MCAtomTest.cpp - Instructions 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/MC/MCAnalysis/MCAtom.h"
-#include "llvm/MC/MCAnalysis/MCModule.h"
-#include "gtest/gtest.h"
-
-namespace llvm {
-namespace {
-
-TEST(MCAtomTest, MCDataSize) {
- MCModule M;
- MCDataAtom *Atom = M.createDataAtom(0, 0);
- EXPECT_EQ(uint64_t(0), Atom->getEndAddr());
- Atom->addData(0);
- EXPECT_EQ(uint64_t(0), Atom->getEndAddr());
- Atom->addData(1);
- EXPECT_EQ(uint64_t(1), Atom->getEndAddr());
- Atom->addData(2);
- EXPECT_EQ(uint64_t(2), Atom->getEndAddr());
- EXPECT_EQ(size_t(3), Atom->getData().size());
-}
-
-} // end anonymous namespace
-} // end namespace llvm
diff --git a/unittests/MC/Makefile b/unittests/MC/Makefile
index 07a608e..3f8d1ef 100644
--- a/unittests/MC/Makefile
+++ b/unittests/MC/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = MC
-LINK_COMPONENTS := MCAnalysis
+LINK_COMPONENTS := all-targets MCDisassembler Object
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/MC/StringTableBuilderTest.cpp b/unittests/MC/StringTableBuilderTest.cpp
index d30dc62..6b5185c 100644
--- a/unittests/MC/StringTableBuilderTest.cpp
+++ b/unittests/MC/StringTableBuilderTest.cpp
@@ -9,20 +9,21 @@
#include "llvm/MC/StringTableBuilder.h"
#include "gtest/gtest.h"
+#include "llvm/Support/Endian.h"
#include <string>
using namespace llvm;
namespace {
-TEST(StringTableBuilderTest, Basic) {
+TEST(StringTableBuilderTest, BasicELF) {
StringTableBuilder B;
B.add("foo");
B.add("bar");
B.add("foobar");
- B.finalize();
+ B.finalize(StringTableBuilder::ELF);
std::string Expected;
Expected += '\x00';
@@ -37,4 +38,34 @@ TEST(StringTableBuilderTest, Basic) {
EXPECT_EQ(8U, B.getOffset("foo"));
}
+TEST(StringTableBuilderTest, BasicWinCOFF) {
+ StringTableBuilder B;
+
+ // Strings must be 9 chars or longer to go in the table.
+ B.add("hippopotamus");
+ B.add("pygmy hippopotamus");
+ B.add("river horse");
+
+ B.finalize(StringTableBuilder::WinCOFF);
+
+ // size_field + "pygmy hippopotamus\0" + "river horse\0"
+ uint32_t ExpectedSize = 4 + 19 + 12;
+ EXPECT_EQ(ExpectedSize, B.data().size());
+
+ std::string Expected;
+
+ ExpectedSize =
+ support::endian::byte_swap<uint32_t, support::little>(ExpectedSize);
+ Expected.append((const char*)&ExpectedSize, 4);
+ Expected += "pygmy hippopotamus";
+ Expected += '\x00';
+ Expected += "river horse";
+ Expected += '\x00';
+
+ EXPECT_EQ(Expected, B.data());
+ EXPECT_EQ(4U, B.getOffset("pygmy hippopotamus"));
+ EXPECT_EQ(10U, B.getOffset("hippopotamus"));
+ EXPECT_EQ(23U, B.getOffset("river horse"));
+}
+
}
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
index 0fc84c7..7f15776 100644
--- a/unittests/Support/AllocatorTest.cpp
+++ b/unittests/Support/AllocatorTest.cpp
@@ -17,9 +17,9 @@ namespace {
TEST(AllocatorTest, Basics) {
BumpPtrAllocator Alloc;
- int *a = (int*)Alloc.Allocate(sizeof(int), 0);
- int *b = (int*)Alloc.Allocate(sizeof(int) * 10, 0);
- int *c = (int*)Alloc.Allocate(sizeof(int), 0);
+ int *a = (int*)Alloc.Allocate(sizeof(int), 1);
+ int *b = (int*)Alloc.Allocate(sizeof(int) * 10, 1);
+ int *c = (int*)Alloc.Allocate(sizeof(int), 1);
*a = 1;
b[0] = 2;
b[9] = 2;
@@ -49,11 +49,11 @@ TEST(AllocatorTest, Basics) {
// Allocate enough bytes to create three slabs.
TEST(AllocatorTest, ThreeSlabs) {
BumpPtrAllocator Alloc;
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(3U, Alloc.GetNumSlabs());
}
@@ -61,15 +61,15 @@ TEST(AllocatorTest, ThreeSlabs) {
// again.
TEST(AllocatorTest, TestReset) {
BumpPtrAllocator Alloc;
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
Alloc.Reset();
EXPECT_EQ(1U, Alloc.GetNumSlabs());
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
- Alloc.Allocate(3000, 0);
+ Alloc.Allocate(3000, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
@@ -99,11 +99,11 @@ TEST(AllocatorTest, TestOverflow) {
BumpPtrAllocator Alloc;
// Fill the slab right up until the end pointer.
- Alloc.Allocate(4096, 0);
+ Alloc.Allocate(4096, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
// If we don't allocate a new slab, then we will have overflowed.
- Alloc.Allocate(1, 0);
+ Alloc.Allocate(1, 1);
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
@@ -111,7 +111,20 @@ TEST(AllocatorTest, TestOverflow) {
TEST(AllocatorTest, TestSmallSlabSize) {
BumpPtrAllocator Alloc;
- Alloc.Allocate(8000, 0);
+ Alloc.Allocate(8000, 1);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+}
+
+// Test requesting alignment that goes past the end of the current slab.
+TEST(AllocatorTest, TestAlignmentPastSlab) {
+ BumpPtrAllocator Alloc;
+ Alloc.Allocate(4095, 1);
+
+ // Aligning the current slab pointer is likely to move it past the end of the
+ // slab, which would confuse any unsigned comparisons with the difference of
+ // the the end pointer and the aligned pointer.
+ Alloc.Allocate(1024, 8192);
+
EXPECT_EQ(2U, Alloc.GetNumSlabs());
}
@@ -130,7 +143,7 @@ public:
void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));
// Find the slab start.
- void *Slab = alignPtr((char *)MemBase + sizeof(void *), Alignment);
+ void *Slab = (void *)alignAddr((char*)MemBase + sizeof(void *), Alignment);
// Hold a pointer to the base so we can free the whole malloced block.
((void**)Slab)[-1] = MemBase;
@@ -155,7 +168,7 @@ TEST(AllocatorTest, TestBigAlignment) {
BumpPtrAllocatorImpl<MockSlabAllocator> Alloc;
// First allocate a tiny bit to ensure we have to re-align things.
- (void)Alloc.Allocate(1, 0);
+ (void)Alloc.Allocate(1, 1);
// Now the big chunk with a big alignment.
(void)Alloc.Allocate(3000, 2048);
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index 97c5c43..7abdd8a 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -42,3 +42,8 @@ add_llvm_unittest(SupportTests
formatted_raw_ostream_test.cpp
raw_ostream_test.cpp
)
+
+# ManagedStatic.cpp uses <pthread>.
+if(LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD)
+ target_link_libraries(SupportTests pthread)
+endif()
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
index b2d71ab..ac8d3d8 100644
--- a/unittests/Support/CommandLineTest.cpp
+++ b/unittests/Support/CommandLineTest.cpp
@@ -153,14 +153,14 @@ class StrDupSaver : public cl::StringSaver {
};
typedef void ParserFunction(StringRef Source, llvm::cl::StringSaver &Saver,
- SmallVectorImpl<const char *> &NewArgv);
-
+ SmallVectorImpl<const char *> &NewArgv,
+ bool MarkEOLs);
void testCommandLineTokenizer(ParserFunction *parse, const char *Input,
const char *const Output[], size_t OutputSize) {
SmallVector<const char *, 0> Actual;
StrDupSaver Saver;
- parse(Input, Saver, Actual);
+ parse(Input, Saver, Actual, /*MarkEOLs=*/false);
EXPECT_EQ(OutputSize, Actual.size());
for (unsigned I = 0, E = Actual.size(); I != E; ++I) {
if (I < OutputSize)
@@ -212,4 +212,23 @@ TEST(CommandLineTest, AliasesWithArguments) {
}
}
+void testAliasRequired(int argc, const char *const *argv) {
+ StackOption<std::string> Option("option", cl::Required);
+ cl::alias Alias("o", llvm::cl::aliasopt(Option));
+
+ cl::ParseCommandLineOptions(argc, argv);
+ EXPECT_EQ("x", Option);
+ EXPECT_EQ(1, Option.getNumOccurrences());
+
+ Alias.removeArgument();
+}
+
+TEST(CommandLineTest, AliasRequired) {
+ const char *opts1[] = { "-tool", "-option=x" };
+ const char *opts2[] = { "-tool", "-o", "x" };
+ testAliasRequired(array_lengthof(opts1), opts1);
+ testAliasRequired(array_lengthof(opts2), opts2);
+}
+
+
} // anonymous namespace
diff --git a/unittests/Support/ConvertUTFTest.cpp b/unittests/Support/ConvertUTFTest.cpp
index 16c9beb..510b1da 100644
--- a/unittests/Support/ConvertUTFTest.cpp
+++ b/unittests/Support/ConvertUTFTest.cpp
@@ -39,30 +39,30 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
TEST(ConvertUTFTest, OddLengthInput) {
std::string Result;
- bool Success = convertUTF16ToUTF8String(ArrayRef<char>("xxxxx", 5), Result);
+ bool Success = convertUTF16ToUTF8String(makeArrayRef("xxxxx", 5), Result);
EXPECT_FALSE(Success);
}
TEST(ConvertUTFTest, Empty) {
std::string Result;
- bool Success = convertUTF16ToUTF8String(ArrayRef<char>(), Result);
+ bool Success = convertUTF16ToUTF8String(None, Result);
EXPECT_TRUE(Success);
EXPECT_TRUE(Result.empty());
}
TEST(ConvertUTFTest, HasUTF16BOM) {
- bool HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>("\xff\xfe", 2));
+ bool HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xff\xfe", 2));
EXPECT_TRUE(HasBOM);
- HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>("\xfe\xff", 2));
+ HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff", 2));
EXPECT_TRUE(HasBOM);
- HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>("\xfe\xff ", 3));
+ HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff ", 3));
EXPECT_TRUE(HasBOM); // Don't care about odd lengths.
- HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>("\xfe\xff\x00asdf", 6));
+ HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff\x00asdf", 6));
EXPECT_TRUE(HasBOM);
- HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>());
+ HasBOM = hasUTF16ByteOrderMark(None);
EXPECT_FALSE(HasBOM);
- HasBOM = hasUTF16ByteOrderMark(ArrayRef<char>("\xfe", 1));
+ HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe", 1));
EXPECT_FALSE(HasBOM);
}
diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp
index d76e7d6..82bbe09 100644
--- a/unittests/Support/ErrorOrTest.cpp
+++ b/unittests/Support/ErrorOrTest.cpp
@@ -60,5 +60,36 @@ TEST(ErrorOr, Covariant) {
ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr));
b1 = ErrorOr<std::unique_ptr<D> >(nullptr);
+
+ ErrorOr<std::unique_ptr<int>> b2(ErrorOr<int *>(nullptr));
+ ErrorOr<int *> b3(nullptr);
+ ErrorOr<std::unique_ptr<int>> b4(b3);
}
+
+// ErrorOr<int*> x(nullptr);
+// ErrorOr<std::unique_ptr<int>> y = x; // invalid conversion
+static_assert(
+ !std::is_convertible<const ErrorOr<int *> &,
+ ErrorOr<std::unique_ptr<int>>>::value,
+ "do not invoke explicit ctors in implicit conversion from lvalue");
+
+// ErrorOr<std::unique_ptr<int>> y = ErrorOr<int*>(nullptr); // invalid
+// // conversion
+static_assert(
+ !std::is_convertible<ErrorOr<int *> &&,
+ ErrorOr<std::unique_ptr<int>>>::value,
+ "do not invoke explicit ctors in implicit conversion from rvalue");
+
+// ErrorOr<int*> x(nullptr);
+// ErrorOr<std::unique_ptr<int>> y;
+// y = x; // invalid conversion
+static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>,
+ const ErrorOr<int *> &>::value,
+ "do not invoke explicit ctors in assignment");
+
+// ErrorOr<std::unique_ptr<int>> x;
+// x = ErrorOr<int*>(nullptr); // invalid conversion
+static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>,
+ ErrorOr<int *> &&>::value,
+ "do not invoke explicit ctors in assignment");
} // end anon namespace
diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp
index b086f1e..911d516 100644
--- a/unittests/Support/FileOutputBufferTest.cpp
+++ b/unittests/Support/FileOutputBufferTest.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
@@ -65,9 +66,8 @@ TEST(FileOutputBuffer, Test) {
// Do *not* commit buffer.
}
// Verify file does not exist (because buffer not committed).
- bool Exists = false;
- ASSERT_NO_ERROR(fs::exists(Twine(File2), Exists));
- EXPECT_FALSE(Exists);
+ ASSERT_EQ(fs::access(Twine(File2), fs::AccessMode::Exist),
+ errc::no_such_file_or_directory);
ASSERT_NO_ERROR(fs::remove(File2.str()));
// TEST 3: Verify sizing down case.
diff --git a/unittests/Support/LEB128Test.cpp b/unittests/Support/LEB128Test.cpp
index b1ca13e..76b63e5 100644
--- a/unittests/Support/LEB128Test.cpp
+++ b/unittests/Support/LEB128Test.cpp
@@ -106,6 +106,7 @@ TEST(LEB128Test, DecodeULEB128) {
EXPECT_DECODE_ULEB128_EQ(0xffu, "\xff\x01");
EXPECT_DECODE_ULEB128_EQ(0x100u, "\x80\x02");
EXPECT_DECODE_ULEB128_EQ(0x101u, "\x81\x02");
+ EXPECT_DECODE_ULEB128_EQ(4294975616ULL, "\x80\xc1\x80\x80\x10");
// Decode ULEB128 with extra padding bytes
EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x00");
@@ -118,6 +119,42 @@ TEST(LEB128Test, DecodeULEB128) {
#undef EXPECT_DECODE_ULEB128_EQ
}
+TEST(LEB128Test, DecodeSLEB128) {
+#define EXPECT_DECODE_SLEB128_EQ(EXPECTED, VALUE) \
+ do { \
+ unsigned ActualSize = 0; \
+ int64_t Actual = decodeSLEB128(reinterpret_cast<const uint8_t *>(VALUE), \
+ &ActualSize); \
+ EXPECT_EQ(sizeof(VALUE) - 1, ActualSize); \
+ EXPECT_EQ(EXPECTED, Actual); \
+ } while (0)
+
+ // Decode SLEB128
+ EXPECT_DECODE_SLEB128_EQ(0L, "\x00");
+ EXPECT_DECODE_SLEB128_EQ(1L, "\x01");
+ EXPECT_DECODE_SLEB128_EQ(63L, "\x3f");
+ EXPECT_DECODE_SLEB128_EQ(-64L, "\x40");
+ EXPECT_DECODE_SLEB128_EQ(-63L, "\x41");
+ EXPECT_DECODE_SLEB128_EQ(-1L, "\x7f");
+ EXPECT_DECODE_SLEB128_EQ(128L, "\x80\x01");
+ EXPECT_DECODE_SLEB128_EQ(129L, "\x81\x01");
+ EXPECT_DECODE_SLEB128_EQ(-129L, "\xff\x7e");
+ EXPECT_DECODE_SLEB128_EQ(-128L, "\x80\x7f");
+ EXPECT_DECODE_SLEB128_EQ(-127L, "\x81\x7f");
+ EXPECT_DECODE_SLEB128_EQ(64L, "\xc0\x00");
+ EXPECT_DECODE_SLEB128_EQ(-12345L, "\xc7\x9f\x7f");
+
+ // Decode unnormalized SLEB128 with extra padding bytes.
+ EXPECT_DECODE_SLEB128_EQ(0L, "\x80\x00");
+ EXPECT_DECODE_SLEB128_EQ(0L, "\x80\x80\x00");
+ EXPECT_DECODE_SLEB128_EQ(0x7fL, "\xff\x00");
+ EXPECT_DECODE_SLEB128_EQ(0x7fL, "\xff\x80\x00");
+ EXPECT_DECODE_SLEB128_EQ(0x80L, "\x80\x81\x00");
+ EXPECT_DECODE_SLEB128_EQ(0x80L, "\x80\x81\x80\x00");
+
+#undef EXPECT_DECODE_SLEB128_EQ
+}
+
TEST(LEB128Test, SLEB128Size) {
// Positive Value Testing Plan:
// (1) 128 ^ n - 1 ........ need (n+1) bytes
diff --git a/unittests/Support/LineIteratorTest.cpp b/unittests/Support/LineIteratorTest.cpp
index 18f3fa9..67f9d97 100644
--- a/unittests/Support/LineIteratorTest.cpp
+++ b/unittests/Support/LineIteratorTest.cpp
@@ -17,9 +17,9 @@ using namespace llvm::sys;
namespace {
TEST(LineIteratorTest, Basic) {
- std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer("line 1\n"
- "line 2\n"
- "line 3"));
+ std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("line 1\n"
+ "line 2\n"
+ "line 3");
line_iterator I = line_iterator(*Buffer), E;
@@ -40,15 +40,17 @@ TEST(LineIteratorTest, Basic) {
EXPECT_EQ(E, I);
}
-TEST(LineIteratorTest, CommentSkipping) {
+TEST(LineIteratorTest, CommentAndBlankSkipping) {
std::unique_ptr<MemoryBuffer> Buffer(
MemoryBuffer::getMemBuffer("line 1\n"
"line 2\n"
"# Comment 1\n"
- "line 4\n"
+ "\n"
+ "line 5\n"
+ "\n"
"# Comment 2"));
- line_iterator I = line_iterator(*Buffer, '#'), E;
+ line_iterator I = line_iterator(*Buffer, true, '#'), E;
EXPECT_FALSE(I.is_at_eof());
EXPECT_NE(E, I);
@@ -59,20 +61,57 @@ TEST(LineIteratorTest, CommentSkipping) {
EXPECT_EQ("line 2", *I);
EXPECT_EQ(2, I.line_number());
++I;
- EXPECT_EQ("line 4", *I);
- EXPECT_EQ(4, I.line_number());
+ EXPECT_EQ("line 5", *I);
+ EXPECT_EQ(5, I.line_number());
+ ++I;
+
+ EXPECT_TRUE(I.is_at_eof());
+ EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, CommentSkippingKeepBlanks) {
+ std::unique_ptr<MemoryBuffer> Buffer(
+ MemoryBuffer::getMemBuffer("line 1\n"
+ "line 2\n"
+ "# Comment 1\n"
+ "# Comment 2\n"
+ "\n"
+ "line 6\n"
+ "\n"
+ "# Comment 3"));
+
+ line_iterator I = line_iterator(*Buffer, false, '#'), E;
+
+ EXPECT_FALSE(I.is_at_eof());
+ EXPECT_NE(E, I);
+
+ EXPECT_EQ("line 1", *I);
+ EXPECT_EQ(1, I.line_number());
+ ++I;
+ EXPECT_EQ("line 2", *I);
+ EXPECT_EQ(2, I.line_number());
+ ++I;
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(5, I.line_number());
+ ++I;
+ EXPECT_EQ("line 6", *I);
+ EXPECT_EQ(6, I.line_number());
+ ++I;
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(7, I.line_number());
++I;
EXPECT_TRUE(I.is_at_eof());
EXPECT_EQ(E, I);
}
+
TEST(LineIteratorTest, BlankSkipping) {
- std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer("\n\n\n"
- "line 1\n"
- "\n\n\n"
- "line 2\n"
- "\n\n\n"));
+ std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("\n\n\n"
+ "line 1\n"
+ "\n\n\n"
+ "line 2\n"
+ "\n\n\n");
line_iterator I = line_iterator(*Buffer), E;
@@ -90,26 +129,65 @@ TEST(LineIteratorTest, BlankSkipping) {
EXPECT_EQ(E, I);
}
+TEST(LineIteratorTest, BlankKeeping) {
+ std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("\n\n"
+ "line 3\n"
+ "\n"
+ "line 5\n"
+ "\n\n");
+ line_iterator I = line_iterator(*Buffer, false), E;
+
+ EXPECT_FALSE(I.is_at_eof());
+ EXPECT_NE(E, I);
+
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(1, I.line_number());
+ ++I;
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(2, I.line_number());
+ ++I;
+ EXPECT_EQ("line 3", *I);
+ EXPECT_EQ(3, I.line_number());
+ ++I;
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(4, I.line_number());
+ ++I;
+ EXPECT_EQ("line 5", *I);
+ EXPECT_EQ(5, I.line_number());
+ ++I;
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(6, I.line_number());
+ ++I;
+ EXPECT_EQ("", *I);
+ EXPECT_EQ(7, I.line_number());
+ ++I;
+
+ EXPECT_TRUE(I.is_at_eof());
+ EXPECT_EQ(E, I);
+}
+
TEST(LineIteratorTest, EmptyBuffers) {
- std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(""));
+ std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("");
EXPECT_TRUE(line_iterator(*Buffer).is_at_eof());
EXPECT_EQ(line_iterator(), line_iterator(*Buffer));
+ EXPECT_TRUE(line_iterator(*Buffer, false).is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer, false));
- Buffer.reset(MemoryBuffer::getMemBuffer("\n\n\n"));
+ Buffer = MemoryBuffer::getMemBuffer("\n\n\n");
EXPECT_TRUE(line_iterator(*Buffer).is_at_eof());
EXPECT_EQ(line_iterator(), line_iterator(*Buffer));
- Buffer.reset(MemoryBuffer::getMemBuffer("# foo\n"
- "\n"
- "# bar"));
- EXPECT_TRUE(line_iterator(*Buffer, '#').is_at_eof());
- EXPECT_EQ(line_iterator(), line_iterator(*Buffer, '#'));
-
- Buffer.reset(MemoryBuffer::getMemBuffer("\n"
- "# baz\n"
- "\n"));
- EXPECT_TRUE(line_iterator(*Buffer, '#').is_at_eof());
- EXPECT_EQ(line_iterator(), line_iterator(*Buffer, '#'));
+ Buffer = MemoryBuffer::getMemBuffer("# foo\n"
+ "\n"
+ "# bar");
+ EXPECT_TRUE(line_iterator(*Buffer, true, '#').is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer, true, '#'));
+
+ Buffer = MemoryBuffer::getMemBuffer("\n"
+ "# baz\n"
+ "\n");
+ EXPECT_TRUE(line_iterator(*Buffer, true, '#').is_at_eof());
+ EXPECT_EQ(line_iterator(), line_iterator(*Buffer, true, '#'));
}
} // anonymous namespace
diff --git a/unittests/Support/LockFileManagerTest.cpp b/unittests/Support/LockFileManagerTest.cpp
index 885b7d6..efe3c30 100644
--- a/unittests/Support/LockFileManagerTest.cpp
+++ b/unittests/Support/LockFileManagerTest.cpp
@@ -95,7 +95,7 @@ TEST(LockFileManagerTest, RelativePath) {
char PathBuf[1024];
const char *OrigPath = getcwd(PathBuf, 1024);
- chdir(TmpDir.c_str());
+ ASSERT_FALSE(chdir(TmpDir.c_str()));
sys::fs::create_directory("inner");
SmallString<64> LockedFile("inner");
@@ -118,7 +118,7 @@ TEST(LockFileManagerTest, RelativePath) {
EC = sys::fs::remove("inner");
ASSERT_FALSE(EC);
- chdir(OrigPath);
+ ASSERT_FALSE(chdir(OrigPath));
EC = sys::fs::remove(StringRef(TmpDir));
ASSERT_FALSE(EC);
diff --git a/unittests/Support/MD5Test.cpp b/unittests/Support/MD5Test.cpp
index 7c1331b..c4fa5cd 100644
--- a/unittests/Support/MD5Test.cpp
+++ b/unittests/Support/MD5Test.cpp
@@ -41,19 +41,19 @@ void TestMD5Sum(StringRef Input, StringRef Final) {
}
TEST(MD5Test, MD5) {
- TestMD5Sum(ArrayRef<uint8_t>((const uint8_t *)"", (size_t) 0),
+ TestMD5Sum(makeArrayRef((const uint8_t *)"", (size_t) 0),
"d41d8cd98f00b204e9800998ecf8427e");
- TestMD5Sum(ArrayRef<uint8_t>((const uint8_t *)"a", (size_t) 1),
+ TestMD5Sum(makeArrayRef((const uint8_t *)"a", (size_t) 1),
"0cc175b9c0f1b6a831c399e269772661");
- TestMD5Sum(ArrayRef<uint8_t>((const uint8_t *)"abcdefghijklmnopqrstuvwxyz",
- (size_t) 26),
+ TestMD5Sum(makeArrayRef((const uint8_t *)"abcdefghijklmnopqrstuvwxyz",
+ (size_t) 26),
"c3fcd3d76192e4007dfb496cca67e13b");
- TestMD5Sum(ArrayRef<uint8_t>((const uint8_t *)"\0", (size_t) 1),
+ TestMD5Sum(makeArrayRef((const uint8_t *)"\0", (size_t) 1),
"93b885adfe0da089cdf634904fd59f71");
- TestMD5Sum(ArrayRef<uint8_t>((const uint8_t *)"a\0", (size_t) 2),
+ TestMD5Sum(makeArrayRef((const uint8_t *)"a\0", (size_t) 2),
"4144e195f46de78a3623da7364d04f11");
- TestMD5Sum(ArrayRef<uint8_t>((const uint8_t *)"abcdefghijklmnopqrstuvwxyz\0",
- (size_t) 27),
+ TestMD5Sum(makeArrayRef((const uint8_t *)"abcdefghijklmnopqrstuvwxyz\0",
+ (size_t) 27),
"81948d1f1554f58cd1a56ebb01f808cb");
TestMD5Sum("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
}
diff --git a/unittests/Support/MemoryBufferTest.cpp b/unittests/Support/MemoryBufferTest.cpp
index 93bf301..1cdd6ad 100644
--- a/unittests/Support/MemoryBufferTest.cpp
+++ b/unittests/Support/MemoryBufferTest.cpp
@@ -169,4 +169,54 @@ TEST_F(MemoryBufferTest, getOpenFileReopened) {
testGetOpenFileSlice(true);
}
+
+TEST_F(MemoryBufferTest, slice) {
+ // Create a file that is six pages long with different data on each page.
+ int FD;
+ SmallString<64> TestPath;
+ sys::fs::createTemporaryFile("MemoryBufferTest_Slice", "temp", FD, TestPath);
+ raw_fd_ostream OF(FD, true, /*unbuffered=*/true);
+ for (unsigned i = 0; i < 0x2000 / 8; ++i) {
+ OF << "12345678";
+ }
+ for (unsigned i = 0; i < 0x2000 / 8; ++i) {
+ OF << "abcdefgh";
+ }
+ for (unsigned i = 0; i < 0x2000 / 8; ++i) {
+ OF << "ABCDEFGH";
+ }
+ OF.close();
+
+ // Try offset of one page.
+ ErrorOr<OwningBuffer> MB = MemoryBuffer::getFileSlice(TestPath.str(),
+ 0x4000, 0x1000);
+ std::error_code EC = MB.getError();
+ ASSERT_FALSE(EC);
+ EXPECT_EQ(0x4000UL, MB.get()->getBufferSize());
+
+ StringRef BufData = MB.get()->getBuffer();
+ EXPECT_TRUE(BufData.substr(0x0000,8).equals("12345678"));
+ EXPECT_TRUE(BufData.substr(0x0FF8,8).equals("12345678"));
+ EXPECT_TRUE(BufData.substr(0x1000,8).equals("abcdefgh"));
+ EXPECT_TRUE(BufData.substr(0x2FF8,8).equals("abcdefgh"));
+ EXPECT_TRUE(BufData.substr(0x3000,8).equals("ABCDEFGH"));
+ EXPECT_TRUE(BufData.substr(0x3FF8,8).equals("ABCDEFGH"));
+
+ // Try non-page aligned.
+ ErrorOr<OwningBuffer> MB2 = MemoryBuffer::getFileSlice(TestPath.str(),
+ 0x3000, 0x0800);
+ EC = MB2.getError();
+ ASSERT_FALSE(EC);
+ EXPECT_EQ(0x3000UL, MB2.get()->getBufferSize());
+
+ StringRef BufData2 = MB2.get()->getBuffer();
+ EXPECT_TRUE(BufData2.substr(0x0000,8).equals("12345678"));
+ EXPECT_TRUE(BufData2.substr(0x17F8,8).equals("12345678"));
+ EXPECT_TRUE(BufData2.substr(0x1800,8).equals("abcdefgh"));
+ EXPECT_TRUE(BufData2.substr(0x2FF8,8).equals("abcdefgh"));
+
+}
+
+
+
}
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index cf2e1ee..502cda2 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -16,6 +16,7 @@
#include "gtest/gtest.h"
#ifdef LLVM_ON_WIN32
+#include <Windows.h>
#include <winerror.h>
#endif
@@ -91,6 +92,7 @@ TEST(Support, Path) {
paths.push_back("c:\\foo/");
paths.push_back("c:/foo\\bar");
+ SmallVector<StringRef, 5> ComponentStack;
for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
e = paths.end();
i != e;
@@ -100,18 +102,17 @@ TEST(Support, Path) {
ci != ce;
++ci) {
ASSERT_FALSE(ci->empty());
+ ComponentStack.push_back(*ci);
}
-#if 0 // Valgrind is whining about this.
- outs() << " Reverse Iteration: [";
for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
ce = sys::path::rend(*i);
ci != ce;
++ci) {
- outs() << *ci << ',';
+ ASSERT_TRUE(*ci == ComponentStack.back());
+ ComponentStack.pop_back();
}
- outs() << "]\n";
-#endif
+ ASSERT_TRUE(ComponentStack.empty());
path::has_root_path(*i);
path::root_path(*i);
@@ -141,7 +142,7 @@ TEST(Support, Path) {
StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
stem = path::stem(filename);
ext = path::extension(filename);
- EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str());
+ EXPECT_EQ(*sys::path::rbegin(filename), (stem + ext).str());
path::native(*i, temp_store);
}
@@ -227,7 +228,7 @@ TEST(Support, AbsolutePathIteratorEnd) {
#endif
for (StringRef Path : Paths) {
- StringRef LastComponent = *--path::end(Path);
+ StringRef LastComponent = *path::rbegin(Path);
EXPECT_EQ(".", LastComponent);
}
@@ -239,7 +240,7 @@ TEST(Support, AbsolutePathIteratorEnd) {
#endif
for (StringRef Path : RootPaths) {
- StringRef LastComponent = *--path::end(Path);
+ StringRef LastComponent = *path::rbegin(Path);
EXPECT_EQ(1u, LastComponent.size());
EXPECT_TRUE(path::is_separator(LastComponent[0]));
}
@@ -261,7 +262,7 @@ TEST(Support, HomeDirectory) {
class FileSystemTest : public testing::Test {
protected:
/// Unique temporary directory in which all created filesystem entities must
- /// be placed. It is recursively removed at the end of each test.
+ /// be placed. It is removed at the end of each test (must be empty).
SmallString<128> TestDirectory;
virtual void SetUp() {
@@ -334,9 +335,7 @@ TEST_F(FileSystemTest, TempFiles) {
fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
// Make sure it exists.
- bool TempFileExists;
- ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists));
- EXPECT_TRUE(TempFileExists);
+ ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
// Create another temp tile.
int FD2;
@@ -363,8 +362,8 @@ TEST_F(FileSystemTest, TempFiles) {
EXPECT_EQ(B.type(), fs::file_type::file_not_found);
// Make sure Temp2 doesn't exist.
- ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
- EXPECT_FALSE(TempFileExists);
+ ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist),
+ errc::no_such_file_or_directory);
SmallString<64> TempPath3;
ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
@@ -387,8 +386,8 @@ TEST_F(FileSystemTest, TempFiles) {
ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
// Make sure Temp1 doesn't exist.
- ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
- EXPECT_FALSE(TempFileExists);
+ ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist),
+ errc::no_such_file_or_directory);
#ifdef LLVM_ON_WIN32
// Path name > 260 chars should get an error.
@@ -398,8 +397,16 @@ TEST_F(FileSystemTest, TempFiles) {
"abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
"abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
"abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
- EXPECT_EQ(fs::createUniqueFile(Twine(Path270), FileDescriptor, TempPath),
- errc::no_such_file_or_directory);
+ EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath),
+ errc::invalid_argument);
+ // Relative path < 247 chars, no problem.
+ const char *Path216 =
+ "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
+ "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
+ "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
+ "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
+ ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath));
+ ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
#endif
}
@@ -409,6 +416,54 @@ TEST_F(FileSystemTest, CreateDir) {
ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
errc::file_exists);
ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
+
+#ifdef LLVM_ON_WIN32
+ // Prove that create_directories() can handle a pathname > 248 characters,
+ // which is the documented limit for CreateDirectory().
+ // (248 is MAX_PATH subtracting room for an 8.3 filename.)
+ // Generate a directory path guaranteed to fall into that range.
+ size_t TmpLen = TestDirectory.size();
+ const char *OneDir = "\\123456789";
+ size_t OneDirLen = strlen(OneDir);
+ ASSERT_LT(OneDirLen, 12U);
+ size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1;
+ SmallString<260> LongDir(TestDirectory);
+ for (size_t I = 0; I < NLevels; ++I)
+ LongDir.append(OneDir);
+ ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
+ ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
+ ASSERT_EQ(fs::create_directories(Twine(LongDir), false),
+ errc::file_exists);
+ // Tidy up, "recursively" removing the directories.
+ StringRef ThisDir(LongDir);
+ for (size_t J = 0; J < NLevels; ++J) {
+ ASSERT_NO_ERROR(fs::remove(ThisDir));
+ ThisDir = path::parent_path(ThisDir);
+ }
+
+ // Similarly for a relative pathname. Need to set the current directory to
+ // TestDirectory so that the one we create ends up in the right place.
+ char PreviousDir[260];
+ size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir);
+ ASSERT_GT(PreviousDirLen, 0U);
+ ASSERT_LT(PreviousDirLen, 260U);
+ ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0);
+ LongDir.clear();
+ // Generate a relative directory name with absolute length > 248.
+ size_t LongDirLen = 249 - TestDirectory.size();
+ LongDir.assign(LongDirLen, 'a');
+ ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir)));
+ // While we're here, prove that .. and . handling works in these long paths.
+ const char *DotDotDirs = "\\..\\.\\b";
+ LongDir.append(DotDotDirs);
+ ASSERT_NO_ERROR(fs::create_directory("b"));
+ ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists);
+ // And clean up.
+ ASSERT_NO_ERROR(fs::remove("b"));
+ ASSERT_NO_ERROR(fs::remove(
+ Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs)))));
+ ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0);
+#endif
}
TEST_F(FileSystemTest, DirectoryIteration) {
@@ -485,6 +540,8 @@ TEST_F(FileSystemTest, DirectoryIteration) {
const char archive[] = "!<arch>\x0A";
const char bitcode[] = "\xde\xc0\x17\x0b";
const char coff_object[] = "\x00\x00......";
+const char coff_bigobj[] = "\x00\x00\xff\xff\x00\x02......"
+ "\xc7\xa1\xba\xd1\xee\xba\xa9\x4b\xaf\x20\xfa\xf6\x6a\xa4\xdc\xb8";
const char coff_import_library[] = "\x00\x00\xff\xff....";
const char elf_relocatable[] = { 0x7f, 'E', 'L', 'F', 1, 2, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1 };
@@ -501,6 +558,8 @@ const char macho_dynamic_linker[] = "\xfe\xed\xfa\xce..........\x00\x07";
const char macho_bundle[] = "\xfe\xed\xfa\xce..........\x00\x08";
const char macho_dsym_companion[] = "\xfe\xed\xfa\xce..........\x00\x0a";
const char windows_resource[] = "\x00\x00\x00\x00\x020\x00\x00\x00\xff";
+const char macho_dynamically_linked_shared_lib_stub[] =
+ "\xfe\xed\xfa\xce..........\x00\x09";
TEST_F(FileSystemTest, Magic) {
struct type {
@@ -514,6 +573,7 @@ TEST_F(FileSystemTest, Magic) {
DEFINE(archive),
DEFINE(bitcode),
DEFINE(coff_object),
+ { "coff_bigobj", coff_bigobj, sizeof(coff_bigobj), fs::file_magic::coff_object },
DEFINE(coff_import_library),
DEFINE(elf_relocatable),
DEFINE(macho_universal_binary),
@@ -525,6 +585,7 @@ TEST_F(FileSystemTest, Magic) {
DEFINE(macho_dynamically_linked_shared_lib),
DEFINE(macho_dynamic_linker),
DEFINE(macho_bundle),
+ DEFINE(macho_dynamically_linked_shared_lib_stub),
DEFINE(macho_dsym_companion),
DEFINE(windows_resource)
#undef DEFINE
@@ -535,8 +596,8 @@ TEST_F(FileSystemTest, Magic) {
++i) {
SmallString<128> file_pathname(TestDirectory);
path::append(file_pathname, i->filename);
- std::string ErrMsg;
- raw_fd_ostream file(file_pathname.c_str(), ErrMsg, sys::fs::F_None);
+ std::error_code EC;
+ raw_fd_ostream file(file_pathname, EC, sys::fs::F_None);
ASSERT_FALSE(file.has_error());
StringRef magic(i->magic_str, i->magic_str_len);
file << magic;
@@ -549,27 +610,27 @@ TEST_F(FileSystemTest, Magic) {
#ifdef LLVM_ON_WIN32
TEST_F(FileSystemTest, CarriageReturn) {
SmallString<128> FilePathname(TestDirectory);
- std::string ErrMsg;
+ std::error_code EC;
path::append(FilePathname, "test");
{
- raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_Text);
- EXPECT_EQ(ErrMsg, "");
+ raw_fd_ostream File(FilePathname, EC, sys::fs::F_Text);
+ ASSERT_NO_ERROR(EC);
File << '\n';
}
{
- auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
+ auto Buf = MemoryBuffer::getFile(FilePathname.str());
EXPECT_TRUE((bool)Buf);
EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
}
{
- raw_fd_ostream File(FilePathname.c_str(), ErrMsg, sys::fs::F_None);
- EXPECT_EQ(ErrMsg, "");
+ raw_fd_ostream File(FilePathname, EC, sys::fs::F_None);
+ ASSERT_NO_ERROR(EC);
File << '\n';
}
{
- auto Buf = MemoryBuffer::getFile(FilePathname.c_str());
+ auto Buf = MemoryBuffer::getFile(FilePathname.str());
EXPECT_TRUE((bool)Buf);
EXPECT_EQ(Buf.get()->getBuffer(), "\n");
}
@@ -640,22 +701,22 @@ TEST(Support, NormalizePath) {
SmallString<64> Path5("\\a");
SmallString<64> Path6("a\\");
- ASSERT_NO_ERROR(fs::normalize_separators(Path1));
+ path::native(Path1);
EXPECT_PATH_IS(Path1, "a", "a");
- ASSERT_NO_ERROR(fs::normalize_separators(Path2));
- EXPECT_PATH_IS(Path2, "a/b", "a/b");
+ path::native(Path2);
+ EXPECT_PATH_IS(Path2, "a\\b", "a/b");
- ASSERT_NO_ERROR(fs::normalize_separators(Path3));
+ path::native(Path3);
EXPECT_PATH_IS(Path3, "a\\b", "a/b");
- ASSERT_NO_ERROR(fs::normalize_separators(Path4));
+ path::native(Path4);
EXPECT_PATH_IS(Path4, "a\\\\b", "a\\\\b");
- ASSERT_NO_ERROR(fs::normalize_separators(Path5));
+ path::native(Path5);
EXPECT_PATH_IS(Path5, "\\a", "/a");
- ASSERT_NO_ERROR(fs::normalize_separators(Path6));
+ path::native(Path6);
EXPECT_PATH_IS(Path6, "a\\", "a/");
#undef EXPECT_PATH_IS
diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp
index f406072..3045c30 100644
--- a/unittests/Support/ProcessTest.cpp
+++ b/unittests/Support/ProcessTest.cpp
@@ -31,12 +31,12 @@ TEST(ProcessTest, SelfProcess) {
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());
+ 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());
}
TEST(ProcessTest, GetRandomNumberTest) {
diff --git a/unittests/Support/ProgramTest.cpp b/unittests/Support/ProgramTest.cpp
index 4e7316f..c0e6e80 100644
--- a/unittests/Support/ProgramTest.cpp
+++ b/unittests/Support/ProgramTest.cpp
@@ -34,6 +34,16 @@ void sleep_for(unsigned int seconds) {
#error sleep_for is not implemented on your platform.
#endif
+#define ASSERT_NO_ERROR(x) \
+ if (std::error_code ASSERT_NO_ERROR_ec = x) { \
+ SmallString<128> MessageStorage; \
+ raw_svector_ostream Message(MessageStorage); \
+ Message << #x ": did not return errc::success.\n" \
+ << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
+ << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
+ GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
+ } else { \
+ }
// From TestMain.cpp.
extern const char *TestMainArgv0;
@@ -220,4 +230,44 @@ TEST(ProgramTest, TestExecuteNegative) {
}
+#ifdef LLVM_ON_WIN32
+const char utf16le_text[] =
+ "\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61\x00";
+const char utf16be_text[] =
+ "\x00\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61";
+#endif
+const char utf8_text[] = "\x6c\x69\x6e\x67\xc3\xbc\x69\xc3\xa7\x61";
+
+TEST(ProgramTest, TestWriteWithSystemEncoding) {
+ SmallString<128> TestDirectory;
+ ASSERT_NO_ERROR(fs::createUniqueDirectory("program-test", TestDirectory));
+ errs() << "Test Directory: " << TestDirectory << '\n';
+ errs().flush();
+ SmallString<128> file_pathname(TestDirectory);
+ path::append(file_pathname, "international-file.txt");
+ // Only on Windows we should encode in UTF16. For other systems, use UTF8
+ ASSERT_NO_ERROR(sys::writeFileWithEncoding(file_pathname.c_str(), utf8_text,
+ sys::WEM_UTF16));
+ int fd = 0;
+ ASSERT_NO_ERROR(fs::openFileForRead(file_pathname.c_str(), fd));
+#if defined(LLVM_ON_WIN32)
+ char buf[18];
+ ASSERT_EQ(::read(fd, buf, 18), 18);
+ if (strncmp(buf, "\xfe\xff", 2) == 0) { // UTF16-BE
+ ASSERT_EQ(strncmp(&buf[2], utf16be_text, 16), 0);
+ } else if (strncmp(buf, "\xff\xfe", 2) == 0) { // UTF16-LE
+ ASSERT_EQ(strncmp(&buf[2], utf16le_text, 16), 0);
+ } else {
+ FAIL() << "Invalid BOM in UTF-16 file";
+ }
+#else
+ char buf[10];
+ ASSERT_EQ(::read(fd, buf, 10), 10);
+ ASSERT_EQ(strncmp(buf, utf8_text, 10), 0);
+#endif
+ ::close(fd);
+ ASSERT_NO_ERROR(fs::remove(file_pathname.str()));
+ ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+
} // end anonymous namespace
diff --git a/unittests/Support/SourceMgrTest.cpp b/unittests/Support/SourceMgrTest.cpp
index 2b69fe9..79c2d72 100644
--- a/unittests/Support/SourceMgrTest.cpp
+++ b/unittests/Support/SourceMgrTest.cpp
@@ -23,8 +23,9 @@ public:
std::string Output;
void setMainBuffer(StringRef Text, StringRef BufferName) {
- MemoryBuffer *MainBuffer = MemoryBuffer::getMemBuffer(Text, BufferName);
- MainBufferID = SM.AddNewSourceBuffer(MainBuffer, llvm::SMLoc());
+ std::unique_ptr<MemoryBuffer> MainBuffer =
+ MemoryBuffer::getMemBuffer(Text, BufferName);
+ MainBufferID = SM.AddNewSourceBuffer(std::move(MainBuffer), llvm::SMLoc());
}
SMLoc getLoc(unsigned Offset) {
diff --git a/unittests/Support/SpecialCaseListTest.cpp b/unittests/Support/SpecialCaseListTest.cpp
index bb9c351..740dbfe 100644
--- a/unittests/Support/SpecialCaseListTest.cpp
+++ b/unittests/Support/SpecialCaseListTest.cpp
@@ -17,14 +17,15 @@ namespace {
class SpecialCaseListTest : public ::testing::Test {
protected:
- SpecialCaseList *makeSpecialCaseList(StringRef List, std::string &Error) {
- std::unique_ptr<MemoryBuffer> MB(MemoryBuffer::getMemBuffer(List));
+ std::unique_ptr<SpecialCaseList> makeSpecialCaseList(StringRef List,
+ std::string &Error) {
+ std::unique_ptr<MemoryBuffer> MB = MemoryBuffer::getMemBuffer(List);
return SpecialCaseList::create(MB.get(), Error);
}
- SpecialCaseList *makeSpecialCaseList(StringRef List) {
+ std::unique_ptr<SpecialCaseList> makeSpecialCaseList(StringRef List) {
std::string Error;
- SpecialCaseList *SCL = makeSpecialCaseList(List, Error);
+ auto SCL = makeSpecialCaseList(List, Error);
assert(SCL);
assert(Error == "");
return SCL;
@@ -32,13 +33,13 @@ protected:
};
TEST_F(SpecialCaseListTest, Basic) {
- std::unique_ptr<SpecialCaseList> SCL(
+ std::unique_ptr<SpecialCaseList> SCL =
makeSpecialCaseList("# This is a comment.\n"
"\n"
"src:hello\n"
"src:bye\n"
"src:hi=category\n"
- "src:z*=category\n"));
+ "src:z*=category\n");
EXPECT_TRUE(SCL->inSection("src", "hello"));
EXPECT_TRUE(SCL->inSection("src", "bye"));
EXPECT_TRUE(SCL->inSection("src", "hi", "category"));
@@ -48,39 +49,21 @@ TEST_F(SpecialCaseListTest, Basic) {
EXPECT_FALSE(SCL->inSection("src", "hello", "category"));
}
-TEST_F(SpecialCaseListTest, GlobalInitCompat) {
- std::unique_ptr<SpecialCaseList> SCL(
- makeSpecialCaseList("global:foo=init\n"));
+TEST_F(SpecialCaseListTest, GlobalInit) {
+ std::unique_ptr<SpecialCaseList> SCL =
+ makeSpecialCaseList("global:foo=init\n");
EXPECT_FALSE(SCL->inSection("global", "foo"));
EXPECT_FALSE(SCL->inSection("global", "bar"));
EXPECT_TRUE(SCL->inSection("global", "foo", "init"));
EXPECT_FALSE(SCL->inSection("global", "bar", "init"));
- SCL.reset(makeSpecialCaseList("global-init:foo\n"));
- EXPECT_FALSE(SCL->inSection("global", "foo"));
- EXPECT_FALSE(SCL->inSection("global", "bar"));
- EXPECT_TRUE(SCL->inSection("global", "foo", "init"));
- EXPECT_FALSE(SCL->inSection("global", "bar", "init"));
-
- SCL.reset(makeSpecialCaseList("type:t2=init\n"));
+ SCL = makeSpecialCaseList("type:t2=init\n");
EXPECT_FALSE(SCL->inSection("type", "t1"));
EXPECT_FALSE(SCL->inSection("type", "t2"));
EXPECT_FALSE(SCL->inSection("type", "t1", "init"));
EXPECT_TRUE(SCL->inSection("type", "t2", "init"));
- SCL.reset(makeSpecialCaseList("global-init-type:t2\n"));
- EXPECT_FALSE(SCL->inSection("type", "t1"));
- EXPECT_FALSE(SCL->inSection("type", "t2"));
- EXPECT_FALSE(SCL->inSection("type", "t1", "init"));
- EXPECT_TRUE(SCL->inSection("type", "t2", "init"));
-
- SCL.reset(makeSpecialCaseList("src:hello=init\n"));
- EXPECT_FALSE(SCL->inSection("src", "hello"));
- EXPECT_FALSE(SCL->inSection("src", "bye"));
- EXPECT_TRUE(SCL->inSection("src", "hello", "init"));
- EXPECT_FALSE(SCL->inSection("src", "bye", "init"));
-
- SCL.reset(makeSpecialCaseList("global-init-src:hello\n"));
+ SCL = makeSpecialCaseList("src:hello=init\n");
EXPECT_FALSE(SCL->inSection("src", "hello"));
EXPECT_FALSE(SCL->inSection("src", "bye"));
EXPECT_TRUE(SCL->inSection("src", "hello", "init"));
@@ -88,14 +71,14 @@ TEST_F(SpecialCaseListTest, GlobalInitCompat) {
}
TEST_F(SpecialCaseListTest, Substring) {
- std::unique_ptr<SpecialCaseList> SCL(makeSpecialCaseList("src:hello\n"
- "fun:foo\n"
- "global:bar\n"));
+ std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:hello\n"
+ "fun:foo\n"
+ "global:bar\n");
EXPECT_FALSE(SCL->inSection("src", "othello"));
EXPECT_FALSE(SCL->inSection("fun", "tomfoolery"));
EXPECT_FALSE(SCL->inSection("global", "bartender"));
- SCL.reset(makeSpecialCaseList("fun:*foo*\n"));
+ SCL = makeSpecialCaseList("fun:*foo*\n");
EXPECT_TRUE(SCL->inSection("fun", "tomfoolery"));
EXPECT_TRUE(SCL->inSection("fun", "foobar"));
}
@@ -117,7 +100,7 @@ TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
}
TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
- std::unique_ptr<SpecialCaseList> SCL(makeSpecialCaseList(""));
+ std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("");
EXPECT_FALSE(SCL->inSection("foo", "bar"));
}
diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp
index 8aed980..074e27f 100644
--- a/unittests/Support/YAMLIOTest.cpp
+++ b/unittests/Support/YAMLIOTest.cpp
@@ -84,6 +84,13 @@ TEST(YAMLIO, TestMapRead) {
}
}
+TEST(YAMLIO, TestMalformedMapRead) {
+ FooBar doc;
+ Input yin("{foo: 3; bar: 5}", nullptr, suppressErrorMessages);
+ yin >> doc;
+ EXPECT_TRUE(!!yin.error());
+}
+
//
// Test the reading of a yaml sequence of mappings
//
diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp
index e983935..823a0d6 100644
--- a/unittests/Support/YAMLParserTest.cpp
+++ b/unittests/Support/YAMLParserTest.cpp
@@ -18,7 +18,7 @@
namespace llvm {
static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) {
- // Prevent SourceMgr from writing errors to stderr
+ // Prevent SourceMgr from writing errors to stderr
// to reduce noise in unit test runs.
}
@@ -210,8 +210,9 @@ TEST(YAMLParser, DiagnosticFilenameFromBufferID) {
// 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);
+ std::unique_ptr<MemoryBuffer> Buffer =
+ MemoryBuffer::getMemBuffer("[]", "buffername.yaml");
+ yaml::Stream Stream(Buffer->getMemBufferRef(), SM);
Stream.printError(Stream.begin()->getRoot(), "Hello, World!");
EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename());
}
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index 44d27d0..39cfaf0 100644
--- a/unittests/Support/raw_ostream_test.cpp
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -143,4 +143,41 @@ TEST(raw_ostreamTest, WriteEscaped) {
EXPECT_EQ("\\001\\010\\200", Str);
}
+TEST(raw_ostreamTest, Justify) {
+ EXPECT_EQ("xyz ", printToString(left_justify("xyz", 6), 6));
+ EXPECT_EQ("abc", printToString(left_justify("abc", 3), 3));
+ EXPECT_EQ("big", printToString(left_justify("big", 1), 3));
+ EXPECT_EQ(" xyz", printToString(right_justify("xyz", 6), 6));
+ EXPECT_EQ("abc", printToString(right_justify("abc", 3), 3));
+ EXPECT_EQ("big", printToString(right_justify("big", 1), 3));
+}
+
+TEST(raw_ostreamTest, FormatHex) {
+ EXPECT_EQ("0x1234", printToString(format_hex(0x1234, 6), 6));
+ EXPECT_EQ("0x001234", printToString(format_hex(0x1234, 8), 8));
+ EXPECT_EQ("0x00001234", printToString(format_hex(0x1234, 10), 10));
+ EXPECT_EQ("0x1234", printToString(format_hex(0x1234, 4), 6));
+ EXPECT_EQ("0xff", printToString(format_hex(255, 4), 4));
+ EXPECT_EQ("0xFF", printToString(format_hex(255, 4, true), 4));
+ EXPECT_EQ("0x1", printToString(format_hex(1, 3), 3));
+ EXPECT_EQ("0x12", printToString(format_hex(0x12, 3), 4));
+ EXPECT_EQ("0x123", printToString(format_hex(0x123, 3), 5));
+ EXPECT_EQ("0xffffffffffffffff",
+ printToString(format_hex(UINT64_MAX, 18), 18));
+ EXPECT_EQ("0x8000000000000000",
+ printToString(format_hex((INT64_MIN), 18), 18));
+}
+
+TEST(raw_ostreamTest, FormatDecimal) {
+ EXPECT_EQ(" 0", printToString(format_decimal(0, 4), 4));
+ EXPECT_EQ(" -1", printToString(format_decimal(-1, 4), 4));
+ EXPECT_EQ(" -1", printToString(format_decimal(-1, 6), 6));
+ EXPECT_EQ("1234567890", printToString(format_decimal(1234567890, 10), 10));
+ EXPECT_EQ(" 9223372036854775807",
+ printToString(format_decimal(INT64_MAX, 21), 21));
+ EXPECT_EQ(" -9223372036854775808",
+ printToString(format_decimal(INT64_MIN, 21), 21));
+}
+
+
}
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index b3a1f5b..c779979 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -232,7 +232,7 @@ protected:
// Function DI
DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
- DIArray ParamTypes = DBuilder.getOrCreateArray(ArrayRef<Value*>());
+ DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
"filename.c", "/file/dir", "CloneFunc", false, "", 0);
@@ -255,10 +255,11 @@ protected:
// Create a local variable around the alloca
DIType IntType = DBuilder.createBasicType("int", 32, 0,
dwarf::DW_ATE_signed);
+ DIExpression E = DBuilder.createExpression();
DIVariable Variable = DBuilder.createLocalVariable(
dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
- DBuilder.insertDeclare(Alloca, Variable, Store);
- DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, Terminator);
+ DBuilder.insertDeclare(Alloca, Variable, E, Store);
+ DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, Terminator);
// Finalize the debug info
DBuilder.finalize();