summaryrefslogtreecommitdiffstats
path: root/unittests
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
commitebe69fe11e48d322045d5949c83283927a0d790b (patch)
treec92f1907a6b8006628a4b01615f38264d29834ea /unittests
parentb7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff)
downloadexternal_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ADT/APFloatTest.cpp41
-rw-r--r--unittests/ADT/APIntTest.cpp13
-rw-r--r--unittests/ADT/APSIntTest.cpp102
-rw-r--r--unittests/ADT/ArrayRefTest.cpp21
-rw-r--r--unittests/ADT/HashingTest.cpp25
-rw-r--r--unittests/ADT/MapVectorTest.cpp218
-rw-r--r--unittests/ADT/OptionalTest.cpp10
-rw-r--r--unittests/ADT/PointerIntPairTest.cpp2
-rw-r--r--unittests/ADT/SmallVectorTest.cpp223
-rw-r--r--unittests/ADT/StringMapTest.cpp8
-rw-r--r--unittests/ADT/TinyPtrVectorTest.cpp47
-rw-r--r--unittests/ADT/TripleTest.cpp17
-rw-r--r--unittests/Analysis/CFGTest.cpp10
-rw-r--r--unittests/Analysis/MixedTBAATest.cpp4
-rw-r--r--unittests/Analysis/ScalarEvolutionTest.cpp4
-rw-r--r--unittests/Bitcode/BitReaderTest.cpp2
-rw-r--r--unittests/CMakeLists.txt3
-rw-r--r--unittests/CodeGen/DIEHashTest.cpp4
-rw-r--r--unittests/DebugInfo/CMakeLists.txt12
-rw-r--r--unittests/DebugInfo/DWARF/CMakeLists.txt11
-rw-r--r--unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp (renamed from unittests/DebugInfo/DWARFFormValueTest.cpp)2
-rw-r--r--unittests/DebugInfo/DWARF/Makefile16
-rw-r--r--unittests/DebugInfo/Makefile5
-rw-r--r--unittests/DebugInfo/PDB/CMakeLists.txt11
-rw-r--r--unittests/DebugInfo/PDB/Makefile16
-rw-r--r--unittests/DebugInfo/PDB/PDBApiTest.cpp387
-rw-r--r--unittests/ExecutionEngine/CMakeLists.txt4
-rw-r--r--unittests/ExecutionEngine/MCJIT/CMakeLists.txt1
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp32
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp19
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp4
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h4
-rw-r--r--unittests/ExecutionEngine/Makefile4
-rw-r--r--unittests/ExecutionEngine/Orc/CMakeLists.txt8
-rw-r--r--unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp30
-rw-r--r--unittests/ExecutionEngine/Orc/Makefile16
-rw-r--r--unittests/IR/CMakeLists.txt1
-rw-r--r--unittests/IR/ConstantsTest.cpp16
-rw-r--r--unittests/IR/DebugInfoTest.cpp67
-rw-r--r--unittests/IR/DominatorTreeTest.cpp4
-rw-r--r--unittests/IR/IRBuilderTest.cpp18
-rw-r--r--unittests/IR/LeakDetectorTest.cpp31
-rw-r--r--unittests/IR/LegacyPassManagerTest.cpp19
-rw-r--r--unittests/IR/MDBuilderTest.cpp21
-rw-r--r--unittests/IR/MetadataTest.cpp1773
-rw-r--r--unittests/IR/PassManagerTest.cpp35
-rw-r--r--unittests/IR/UseTest.cpp10
-rw-r--r--unittests/IR/UserTest.cpp2
-rw-r--r--unittests/IR/WaymarkTest.cpp5
-rw-r--r--unittests/Linker/LinkModulesTest.cpp2
-rw-r--r--unittests/MC/CMakeLists.txt6
-rw-r--r--unittests/MC/Hexagon/CMakeLists.txt14
-rw-r--r--unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp53
-rw-r--r--unittests/MC/StringTableBuilderTest.cpp2
-rw-r--r--unittests/Makefile2
-rw-r--r--unittests/ProfileData/CMakeLists.txt10
-rw-r--r--unittests/ProfileData/CoverageMappingTest.cpp262
-rw-r--r--unittests/ProfileData/InstrProfTest.cpp98
-rw-r--r--unittests/ProfileData/Makefile15
-rw-r--r--unittests/Support/AlignOfTest.cpp8
-rw-r--r--unittests/Support/BlockFrequencyTest.cpp9
-rw-r--r--unittests/Support/CMakeLists.txt3
-rw-r--r--unittests/Support/Casting.cpp96
-rw-r--r--unittests/Support/CommandLineTest.cpp47
-rw-r--r--unittests/Support/CompressionTest.cpp2
-rw-r--r--unittests/Support/ConvertUTFTest.cpp18
-rw-r--r--unittests/Support/DwarfTest.cpp141
-rw-r--r--unittests/Support/EndianStreamTest.cpp157
-rw-r--r--unittests/Support/FileOutputBufferTest.cpp7
-rw-r--r--unittests/Support/MathExtrasTest.cpp11
-rw-r--r--unittests/Support/MemoryTest.cpp2
-rw-r--r--unittests/Support/Path.cpp41
-rw-r--r--unittests/Support/ProcessTest.cpp20
-rw-r--r--unittests/Support/ProgramTest.cpp50
-rw-r--r--unittests/Support/ScaledNumberTest.cpp1
-rw-r--r--unittests/Support/SpecialCaseListTest.cpp38
-rw-r--r--unittests/Support/StreamingMemoryObject.cpp29
-rw-r--r--unittests/Support/StringPool.cpp4
-rw-r--r--unittests/Support/ThreadLocalTest.cpp23
-rw-r--r--unittests/Support/raw_ostream_test.cpp2
-rw-r--r--unittests/Transforms/CMakeLists.txt2
-rw-r--r--unittests/Transforms/DebugIR/CMakeLists.txt9
-rw-r--r--unittests/Transforms/DebugIR/DebugIR.cpp308
-rw-r--r--unittests/Transforms/IPO/CMakeLists.txt9
-rw-r--r--unittests/Transforms/IPO/LowerBitSets.cpp95
-rw-r--r--unittests/Transforms/IPO/Makefile (renamed from unittests/Transforms/DebugIR/Makefile)6
-rw-r--r--unittests/Transforms/Makefile2
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp5
88 files changed, 4325 insertions, 622 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index c7ec16b..8b82fb2 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -475,6 +475,47 @@ TEST(APFloatTest, FMA) {
EXPECT_EQ(12.0f, f1.convertToFloat());
}
+ // Test for correct zero sign when answer is exactly zero.
+ // fma(1.0, -1.0, 1.0) -> +ve 0.
+ {
+ APFloat f1(1.0);
+ APFloat f2(-1.0);
+ APFloat f3(1.0);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_TRUE(!f1.isNegative() && f1.isZero());
+ }
+
+ // Test for correct zero sign when answer is exactly zero and rounding towards
+ // negative.
+ // fma(1.0, -1.0, 1.0) -> +ve 0.
+ {
+ APFloat f1(1.0);
+ APFloat f2(-1.0);
+ APFloat f3(1.0);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmTowardNegative);
+ EXPECT_TRUE(f1.isNegative() && f1.isZero());
+ }
+
+ // Test for correct (in this case -ve) sign when adding like signed zeros.
+ // Test fma(0.0, -0.0, -0.0) -> -ve 0.
+ {
+ APFloat f1(0.0);
+ APFloat f2(-0.0);
+ APFloat f3(-0.0);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_TRUE(f1.isNegative() && f1.isZero());
+ }
+
+ // Test -ve sign preservation when small negative results underflow.
+ {
+ APFloat f1(APFloat::IEEEdouble, "-0x1p-1074");
+ APFloat f2(APFloat::IEEEdouble, "+0x1p-1074");
+ APFloat f3(0.0);
+ f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
+ EXPECT_TRUE(f1.isNegative() && f1.isZero());
+ }
+
+ // Test x87 extended precision case from http://llvm.org/PR20728.
{
APFloat M1(APFloat::x87DoubleExtended, 1.0);
APFloat M2(APFloat::x87DoubleExtended, 1.0);
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 8198c71..3b7ac5b 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -678,6 +678,14 @@ TEST(APIntTest, nearestLogBase2) {
EXPECT_EQ(A9.nearestLogBase2(), UINT32_MAX);
}
+#if defined(__clang__)
+// Disable the pragma warning from versions of Clang without -Wself-move
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+// Disable the warning that triggers on exactly what is being tested.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wself-move"
+#endif
TEST(APIntTest, SelfMoveAssignment) {
APInt X(32, 0xdeadbeef);
X = std::move(X);
@@ -694,5 +702,8 @@ TEST(APIntTest, SelfMoveAssignment) {
EXPECT_EQ(0xdeadbeefdeadbeefULL, Raw[0]);
EXPECT_EQ(0xdeadbeefdeadbeefULL, Raw[1]);
}
-
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#pragma clang diagnostic pop
+#endif
}
diff --git a/unittests/ADT/APSIntTest.cpp b/unittests/ADT/APSIntTest.cpp
index eef9c8a..5e4e874 100644
--- a/unittests/ADT/APSIntTest.cpp
+++ b/unittests/ADT/APSIntTest.cpp
@@ -41,4 +41,106 @@ TEST(APSIntTest, MoveTest) {
EXPECT_EQ(Bits, A.getRawData()); // Verify that "Wide" was really moved.
}
+TEST(APSIntTest, get) {
+ EXPECT_TRUE(APSInt::get(7).isSigned());
+ EXPECT_EQ(64u, APSInt::get(7).getBitWidth());
+ EXPECT_EQ(7u, APSInt::get(7).getZExtValue());
+ EXPECT_EQ(7, APSInt::get(7).getSExtValue());
+ EXPECT_TRUE(APSInt::get(-7).isSigned());
+ EXPECT_EQ(64u, APSInt::get(-7).getBitWidth());
+ EXPECT_EQ(-7, APSInt::get(-7).getSExtValue());
+ EXPECT_EQ(UINT64_C(0) - 7, APSInt::get(-7).getZExtValue());
+}
+
+TEST(APSIntTest, getUnsigned) {
+ EXPECT_TRUE(APSInt::getUnsigned(7).isUnsigned());
+ EXPECT_EQ(64u, APSInt::getUnsigned(7).getBitWidth());
+ EXPECT_EQ(7u, APSInt::getUnsigned(7).getZExtValue());
+ EXPECT_EQ(7, APSInt::getUnsigned(7).getSExtValue());
+ EXPECT_TRUE(APSInt::getUnsigned(-7).isUnsigned());
+ EXPECT_EQ(64u, APSInt::getUnsigned(-7).getBitWidth());
+ EXPECT_EQ(-7, APSInt::getUnsigned(-7).getSExtValue());
+ EXPECT_EQ(UINT64_C(0) - 7, APSInt::getUnsigned(-7).getZExtValue());
+}
+
+TEST(APSIntTest, getExtValue) {
+ EXPECT_TRUE(APSInt(APInt(3, 7), true).isUnsigned());
+ EXPECT_TRUE(APSInt(APInt(3, 7), false).isSigned());
+ EXPECT_TRUE(APSInt(APInt(4, 7), true).isUnsigned());
+ EXPECT_TRUE(APSInt(APInt(4, 7), false).isSigned());
+ EXPECT_TRUE(APSInt(APInt(4, -7), true).isUnsigned());
+ EXPECT_TRUE(APSInt(APInt(4, -7), false).isSigned());
+ EXPECT_EQ(7, APSInt(APInt(3, 7), true).getExtValue());
+ EXPECT_EQ(-1, APSInt(APInt(3, 7), false).getExtValue());
+ EXPECT_EQ(7, APSInt(APInt(4, 7), true).getExtValue());
+ EXPECT_EQ(7, APSInt(APInt(4, 7), false).getExtValue());
+ EXPECT_EQ(9, APSInt(APInt(4, -7), true).getExtValue());
+ EXPECT_EQ(-7, APSInt(APInt(4, -7), false).getExtValue());
+}
+
+TEST(APSIntTest, compareValues) {
+ auto U = [](uint64_t V) { return APSInt::getUnsigned(V); };
+ auto S = [](int64_t V) { return APSInt::get(V); };
+
+ // Bit-width matches and is-signed.
+ EXPECT_TRUE(APSInt::compareValues(S(7), S(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(8), S(7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(7), S(7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(8), S(-7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(-8)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-8), S(-7)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7)) == 0);
+
+ // Bit-width matches and not is-signed.
+ EXPECT_TRUE(APSInt::compareValues(U(7), U(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8), U(7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7), U(7)) == 0);
+
+ // Bit-width matches and mixed signs.
+ EXPECT_TRUE(APSInt::compareValues(U(7), S(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8), S(7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7), S(7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8), S(-7)) > 0);
+
+ // Bit-width mismatch and is-signed.
+ EXPECT_TRUE(APSInt::compareValues(S(7).trunc(32), S(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(8).trunc(32), S(7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(7).trunc(32), S(7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(8).trunc(32), S(-7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(-7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(-8)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-8).trunc(32), S(-7)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(-7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(7), S(8).trunc(32)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(8), S(7).trunc(32)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(7), S(7).trunc(32)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(8).trunc(32)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(8), S(-7).trunc(32)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7).trunc(32)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(-8).trunc(32)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-8), S(-7).trunc(32)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7).trunc(32)) == 0);
+
+ // Bit-width mismatch and not is-signed.
+ EXPECT_TRUE(APSInt::compareValues(U(7), U(8).trunc(32)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8), U(7).trunc(32)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7), U(7).trunc(32)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), U(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8).trunc(32), U(7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), U(7)) == 0);
+
+ // Bit-width mismatch and mixed signs.
+ EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), S(8)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8).trunc(32), S(7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), S(7)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8).trunc(32), S(-7)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7), S(8).trunc(32)) < 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8), S(7).trunc(32)) > 0);
+ EXPECT_TRUE(APSInt::compareValues(U(7), S(7).trunc(32)) == 0);
+ EXPECT_TRUE(APSInt::compareValues(U(8), S(-7).trunc(32)) > 0);
+}
+
}
diff --git a/unittests/ADT/ArrayRefTest.cpp b/unittests/ADT/ArrayRefTest.cpp
index f9c98a5..70f8208 100644
--- a/unittests/ADT/ArrayRefTest.cpp
+++ b/unittests/ADT/ArrayRefTest.cpp
@@ -11,6 +11,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
+#include <vector>
using namespace llvm;
// Check that the ArrayRef-of-pointer converting constructor only allows adding
@@ -90,4 +91,24 @@ TEST(ArrayRefTest, ConstConvert) {
a = ArrayRef<int *>(A);
}
+static std::vector<int> ReturnTest12() { return {1, 2}; }
+static void ArgTest12(ArrayRef<int> A) {
+ EXPECT_EQ(2U, A.size());
+ EXPECT_EQ(1, A[0]);
+ EXPECT_EQ(2, A[1]);
+}
+
+TEST(ArrayRefTest, InitializerList) {
+ ArrayRef<int> A = { 0, 1, 2, 3, 4 };
+ for (int i = 0; i < 5; ++i)
+ EXPECT_EQ(i, A[i]);
+
+ std::vector<int> B = ReturnTest12();
+ A = B;
+ EXPECT_EQ(1, A[0]);
+ EXPECT_EQ(2, A[1]);
+
+ ArgTest12({1, 2});
+}
+
} // end anonymous namespace
diff --git a/unittests/ADT/HashingTest.cpp b/unittests/ADT/HashingTest.cpp
index acaa83c..34eb5a5 100644
--- a/unittests/ADT/HashingTest.cpp
+++ b/unittests/ADT/HashingTest.cpp
@@ -421,4 +421,29 @@ TEST(HashingTest, HashCombineBasicTest) {
hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));
}
+TEST(HashingTest, HashCombineArgs18) {
+ // This tests that we can pass in up to 18 args.
+#define CHECK_SAME(...) \
+ EXPECT_EQ(hash_combine(__VA_ARGS__), hash_combine(__VA_ARGS__))
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8);
+ CHECK_SAME(1, 2, 3, 4, 5, 6, 7);
+ CHECK_SAME(1, 2, 3, 4, 5, 6);
+ CHECK_SAME(1, 2, 3, 4, 5);
+ CHECK_SAME(1, 2, 3, 4);
+ CHECK_SAME(1, 2, 3);
+ CHECK_SAME(1, 2);
+ CHECK_SAME(1);
+#undef CHECK_SAME
+}
+
}
diff --git a/unittests/ADT/MapVectorTest.cpp b/unittests/ADT/MapVectorTest.cpp
index 8919799..2caa8c7 100644
--- a/unittests/ADT/MapVectorTest.cpp
+++ b/unittests/ADT/MapVectorTest.cpp
@@ -122,3 +122,221 @@ TEST(MapVectorTest, iteration_test) {
count--;
}
}
+
+TEST(SmallMapVectorSmallTest, insert_pop) {
+ SmallMapVector<int, int, 32> MV;
+ std::pair<SmallMapVector<int, int, 32>::iterator, bool> R;
+
+ R = MV.insert(std::make_pair(1, 2));
+ ASSERT_EQ(R.first, MV.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_TRUE(R.second);
+
+ R = MV.insert(std::make_pair(1, 3));
+ ASSERT_EQ(R.first, MV.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_FALSE(R.second);
+
+ R = MV.insert(std::make_pair(4, 5));
+ ASSERT_NE(R.first, MV.end());
+ EXPECT_EQ(R.first->first, 4);
+ EXPECT_EQ(R.first->second, 5);
+ EXPECT_TRUE(R.second);
+
+ EXPECT_EQ(MV.size(), 2u);
+ EXPECT_EQ(MV[1], 2);
+ EXPECT_EQ(MV[4], 5);
+
+ MV.pop_back();
+ EXPECT_EQ(MV.size(), 1u);
+ EXPECT_EQ(MV[1], 2);
+
+ R = MV.insert(std::make_pair(4, 7));
+ ASSERT_NE(R.first, MV.end());
+ EXPECT_EQ(R.first->first, 4);
+ EXPECT_EQ(R.first->second, 7);
+ EXPECT_TRUE(R.second);
+
+ EXPECT_EQ(MV.size(), 2u);
+ EXPECT_EQ(MV[1], 2);
+ EXPECT_EQ(MV[4], 7);
+}
+
+TEST(SmallMapVectorSmallTest, erase) {
+ SmallMapVector<int, int, 32> 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(SmallMapVectorSmallTest, remove_if) {
+ SmallMapVector<int, int, 32> 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(SmallMapVectorSmallTest, iteration_test) {
+ SmallMapVector<int, int, 32> 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--;
+ }
+}
+
+TEST(SmallMapVectorLargeTest, insert_pop) {
+ SmallMapVector<int, int, 1> MV;
+ std::pair<SmallMapVector<int, int, 1>::iterator, bool> R;
+
+ R = MV.insert(std::make_pair(1, 2));
+ ASSERT_EQ(R.first, MV.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_TRUE(R.second);
+
+ R = MV.insert(std::make_pair(1, 3));
+ ASSERT_EQ(R.first, MV.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_FALSE(R.second);
+
+ R = MV.insert(std::make_pair(4, 5));
+ ASSERT_NE(R.first, MV.end());
+ EXPECT_EQ(R.first->first, 4);
+ EXPECT_EQ(R.first->second, 5);
+ EXPECT_TRUE(R.second);
+
+ EXPECT_EQ(MV.size(), 2u);
+ EXPECT_EQ(MV[1], 2);
+ EXPECT_EQ(MV[4], 5);
+
+ MV.pop_back();
+ EXPECT_EQ(MV.size(), 1u);
+ EXPECT_EQ(MV[1], 2);
+
+ R = MV.insert(std::make_pair(4, 7));
+ ASSERT_NE(R.first, MV.end());
+ EXPECT_EQ(R.first->first, 4);
+ EXPECT_EQ(R.first->second, 7);
+ EXPECT_TRUE(R.second);
+
+ EXPECT_EQ(MV.size(), 2u);
+ EXPECT_EQ(MV[1], 2);
+ EXPECT_EQ(MV[4], 7);
+}
+
+TEST(SmallMapVectorLargeTest, erase) {
+ SmallMapVector<int, int, 1> 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(SmallMapVectorLargeTest, remove_if) {
+ SmallMapVector<int, int, 1> 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(SmallMapVectorLargeTest, iteration_test) {
+ SmallMapVector<int, int, 1> 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 cadadce..92c4eec 100644
--- a/unittests/ADT/OptionalTest.cpp
+++ b/unittests/ADT/OptionalTest.cpp
@@ -183,10 +183,10 @@ struct MultiArgConstructor {
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;
+ MultiArgConstructor(const MultiArgConstructor &) = delete;
+ MultiArgConstructor(MultiArgConstructor &&) = delete;
+ MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
+ MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
static unsigned Destructions;
~MultiArgConstructor() {
@@ -340,7 +340,7 @@ struct Immovable {
}
private:
// This should disable all move/copy operations.
- Immovable(Immovable&& other) LLVM_DELETED_FUNCTION;
+ Immovable(Immovable&& other) = delete;
};
unsigned Immovable::Constructions = 0;
diff --git a/unittests/ADT/PointerIntPairTest.cpp b/unittests/ADT/PointerIntPairTest.cpp
index 296d475..0bbcd9f 100644
--- a/unittests/ADT/PointerIntPairTest.cpp
+++ b/unittests/ADT/PointerIntPairTest.cpp
@@ -42,7 +42,6 @@ TEST_F(PointerIntPairTest, DefaultInitialize) {
EXPECT_EQ(0U, Pair.getInt());
}
-#if !(defined(_MSC_VER) && _MSC_VER==1700)
TEST_F(PointerIntPairTest, ManyUnusedBits) {
// In real code this would be a word-sized integer limited to 31 bits.
struct Fixnum31 {
@@ -71,6 +70,5 @@ TEST_F(PointerIntPairTest, ManyUnusedBits) {
EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
}
-#endif
} // end anonymous namespace
diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp
index 95bf33e..2bbb4ed 100644
--- a/unittests/ADT/SmallVectorTest.cpp
+++ b/unittests/ADT/SmallVectorTest.cpp
@@ -144,8 +144,8 @@ struct NonCopyable {
NonCopyable(NonCopyable &&) {}
NonCopyable &operator=(NonCopyable &&) { return *this; }
private:
- NonCopyable(const NonCopyable &) LLVM_DELETED_FUNCTION;
- NonCopyable &operator=(const NonCopyable &) LLVM_DELETED_FUNCTION;
+ NonCopyable(const NonCopyable &) = delete;
+ NonCopyable &operator=(const NonCopyable &) = delete;
};
LLVM_ATTRIBUTE_USED void CompileTest() {
@@ -153,17 +153,14 @@ LLVM_ATTRIBUTE_USED void CompileTest() {
V.resize(42);
}
-// Test fixture class
-template <typename VectorT>
-class SmallVectorTest : public testing::Test {
+class SmallVectorTestBase : public testing::Test {
protected:
- VectorT theVector;
- VectorT otherVector;
void SetUp() {
Constructable::reset();
}
+ template <typename VectorT>
void assertEmpty(VectorT & v) {
// Size tests
EXPECT_EQ(0u, v.size());
@@ -173,7 +170,8 @@ protected:
EXPECT_TRUE(v.begin() == v.end());
}
- // Assert that theVector contains the specified values, in order.
+ // Assert that v contains the specified values, in order.
+ template <typename VectorT>
void assertValuesInOrder(VectorT & v, size_t size, ...) {
EXPECT_EQ(size, v.size());
@@ -188,6 +186,7 @@ protected:
}
// Generate a sequence of values to initialize the vector.
+ template <typename VectorT>
void makeSequence(VectorT & v, int start, int end) {
for (int i = start; i <= end; ++i) {
v.push_back(Constructable(i));
@@ -195,6 +194,15 @@ protected:
}
};
+// Test fixture class
+template <typename VectorT>
+class SmallVectorTest : public SmallVectorTestBase {
+protected:
+ VectorT theVector;
+ VectorT otherVector;
+};
+
+
typedef ::testing::Types<SmallVector<Constructable, 0>,
SmallVector<Constructable, 1>,
SmallVector<Constructable, 2>,
@@ -664,6 +672,67 @@ TYPED_TEST(SmallVectorTest, IteratorTest) {
this->theVector.insert(this->theVector.end(), L.begin(), L.end());
}
+template <typename InvalidType> class DualSmallVectorsTest;
+
+template <typename VectorT1, typename VectorT2>
+class DualSmallVectorsTest<std::pair<VectorT1, VectorT2>> : public SmallVectorTestBase {
+protected:
+ VectorT1 theVector;
+ VectorT2 otherVector;
+
+ template <typename T, unsigned N>
+ static unsigned NumBuiltinElts(const SmallVector<T, N>&) { return N; }
+};
+
+typedef ::testing::Types<
+ // Small mode -> Small mode.
+ std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 4>>,
+ // Small mode -> Big mode.
+ std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 2>>,
+ // Big mode -> Small mode.
+ std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 4>>,
+ // Big mode -> Big mode.
+ std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>>
+ > DualSmallVectorTestTypes;
+
+TYPED_TEST_CASE(DualSmallVectorsTest, DualSmallVectorTestTypes);
+
+TYPED_TEST(DualSmallVectorsTest, MoveAssignment) {
+ SCOPED_TRACE("MoveAssignTest-DualVectorTypes");
+
+ // Set up our vector with four elements.
+ for (unsigned I = 0; I < 4; ++I)
+ this->otherVector.push_back(Constructable(I));
+
+ const Constructable *OrigDataPtr = this->otherVector.data();
+
+ // Move-assign from the other vector.
+ this->theVector =
+ std::move(static_cast<SmallVectorImpl<Constructable>&>(this->otherVector));
+
+ // Make sure we have the right result.
+ this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3);
+
+ // Make sure the # of constructor/destructor calls line up. There
+ // are two live objects after clearing the other vector.
+ this->otherVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls()-4,
+ Constructable::getNumDestructorCalls());
+
+ // If the source vector (otherVector) was in small-mode, assert that we just
+ // moved the data pointer over.
+ EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 ||
+ this->theVector.data() == OrigDataPtr);
+
+ // There shouldn't be any live objects any more.
+ this->theVector.clear();
+ EXPECT_EQ(Constructable::getNumConstructorCalls(),
+ Constructable::getNumDestructorCalls());
+
+ // We shouldn't have copied anything in this whole process.
+ EXPECT_EQ(Constructable::getNumCopyConstructorCalls(), 0);
+}
+
struct notassignable {
int &x;
notassignable(int &x) : x(x) {}
@@ -699,4 +768,142 @@ TEST(SmallVectorTest, MidInsert) {
EXPECT_TRUE(m.hasValue);
}
+enum EmplaceableArgState {
+ EAS_Defaulted,
+ EAS_Arg,
+ EAS_LValue,
+ EAS_RValue,
+ EAS_Failure
+};
+template <int I> struct EmplaceableArg {
+ EmplaceableArgState State;
+ EmplaceableArg() : State(EAS_Defaulted) {}
+ EmplaceableArg(EmplaceableArg &&X)
+ : State(X.State == EAS_Arg ? EAS_RValue : EAS_Failure) {}
+ EmplaceableArg(EmplaceableArg &X)
+ : State(X.State == EAS_Arg ? EAS_LValue : EAS_Failure) {}
+
+ explicit EmplaceableArg(bool) : State(EAS_Arg) {}
+
+private:
+ EmplaceableArg &operator=(EmplaceableArg &&) = delete;
+ EmplaceableArg &operator=(const EmplaceableArg &) = delete;
+};
+
+enum EmplaceableState { ES_Emplaced, ES_Moved };
+struct Emplaceable {
+ EmplaceableArg<0> A0;
+ EmplaceableArg<1> A1;
+ EmplaceableArg<2> A2;
+ EmplaceableArg<3> A3;
+ EmplaceableState State;
+
+ Emplaceable() : State(ES_Emplaced) {}
+
+ template <class A0Ty>
+ explicit Emplaceable(A0Ty &&A0)
+ : A0(std::forward<A0Ty>(A0)), State(ES_Emplaced) {}
+
+ template <class A0Ty, class A1Ty>
+ Emplaceable(A0Ty &&A0, A1Ty &&A1)
+ : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
+ State(ES_Emplaced) {}
+
+ template <class A0Ty, class A1Ty, class A2Ty>
+ Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2)
+ : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
+ A2(std::forward<A2Ty>(A2)), State(ES_Emplaced) {}
+
+ template <class A0Ty, class A1Ty, class A2Ty, class A3Ty>
+ Emplaceable(A0Ty &&A0, A1Ty &&A1, A2Ty &&A2, A3Ty &&A3)
+ : A0(std::forward<A0Ty>(A0)), A1(std::forward<A1Ty>(A1)),
+ A2(std::forward<A2Ty>(A2)), A3(std::forward<A3Ty>(A3)),
+ State(ES_Emplaced) {}
+
+ Emplaceable(Emplaceable &&) : State(ES_Moved) {}
+ Emplaceable &operator=(Emplaceable &&) {
+ State = ES_Moved;
+ return *this;
+ }
+
+private:
+ Emplaceable(const Emplaceable &) = delete;
+ Emplaceable &operator=(const Emplaceable &) = delete;
+};
+
+TEST(SmallVectorTest, EmplaceBack) {
+ EmplaceableArg<0> A0(true);
+ EmplaceableArg<1> A1(true);
+ EmplaceableArg<2> A2(true);
+ EmplaceableArg<3> A3(true);
+ {
+ SmallVector<Emplaceable, 3> V;
+ V.emplace_back();
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ SmallVector<Emplaceable, 3> V;
+ V.emplace_back(std::move(A0));
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ SmallVector<Emplaceable, 3> V;
+ V.emplace_back(A0);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ SmallVector<Emplaceable, 3> V;
+ V.emplace_back(A0, A1);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ SmallVector<Emplaceable, 3> V;
+ V.emplace_back(std::move(A0), std::move(A1));
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_Defaulted);
+ EXPECT_TRUE(V.back().A3.State == EAS_Defaulted);
+ }
+ {
+ SmallVector<Emplaceable, 3> V;
+ V.emplace_back(std::move(A0), A1, std::move(A2), A3);
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_TRUE(V.back().State == ES_Emplaced);
+ EXPECT_TRUE(V.back().A0.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A1.State == EAS_LValue);
+ EXPECT_TRUE(V.back().A2.State == EAS_RValue);
+ EXPECT_TRUE(V.back().A3.State == EAS_LValue);
+ }
+ {
+ SmallVector<int, 1> V;
+ V.emplace_back();
+ V.emplace_back(42);
+ EXPECT_EQ(2U, V.size());
+ EXPECT_EQ(0, V[0]);
+ EXPECT_EQ(42, V[1]);
+ }
}
+
+} // end namespace
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 33d668f..4ed0b76 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -244,7 +244,7 @@ TEST_F(StringMapTest, InsertRehashingPairTest) {
// Create a non-default constructable value
struct StringMapTestStruct {
StringMapTestStruct(int i) : i(i) {}
- StringMapTestStruct() LLVM_DELETED_FUNCTION;
+ StringMapTestStruct() = delete;
int i;
};
@@ -258,7 +258,7 @@ TEST_F(StringMapTest, NonDefaultConstructable) {
struct Immovable {
Immovable() {}
- Immovable(Immovable&&) LLVM_DELETED_FUNCTION; // will disable the other special members
+ Immovable(Immovable&&) = delete; // will disable the other special members
};
struct MoveOnly {
@@ -272,8 +272,8 @@ struct MoveOnly {
}
private:
- MoveOnly(const MoveOnly &) LLVM_DELETED_FUNCTION;
- MoveOnly &operator=(const MoveOnly &) LLVM_DELETED_FUNCTION;
+ MoveOnly(const MoveOnly &) = delete;
+ MoveOnly &operator=(const MoveOnly &) = delete;
};
TEST_F(StringMapTest, MoveOnly) {
diff --git a/unittests/ADT/TinyPtrVectorTest.cpp b/unittests/ADT/TinyPtrVectorTest.cpp
index ec868d4..294dfac 100644
--- a/unittests/ADT/TinyPtrVectorTest.cpp
+++ b/unittests/ADT/TinyPtrVectorTest.cpp
@@ -412,3 +412,50 @@ TYPED_TEST(TinyPtrVectorTest, InsertRange) {
}
}
+
+TEST(TinyPtrVectorTest, SingleEltCtorTest) {
+ int v = 55;
+ TinyPtrVector<int *> V(&v);
+
+ EXPECT_TRUE(V.size() == 1);
+ EXPECT_FALSE(V.empty());
+ EXPECT_TRUE(V.front() == &v);
+}
+
+TEST(TinyPtrVectorTest, ArrayRefCtorTest) {
+ int data_array[128];
+ std::vector<int *> data;
+
+ for (unsigned i = 0, e = 128; i != e; ++i) {
+ data_array[i] = 324 - int(i);
+ data.push_back(&data_array[i]);
+ }
+
+ TinyPtrVector<int *> V(data);
+ EXPECT_TRUE(V.size() == 128);
+ EXPECT_FALSE(V.empty());
+ for (unsigned i = 0, e = 128; i != e; ++i) {
+ EXPECT_TRUE(V[i] == data[i]);
+ }
+}
+
+TEST(TinyPtrVectorTest, MutableArrayRefTest) {
+ int data_array[128];
+ std::vector<int *> data;
+
+ for (unsigned i = 0, e = 128; i != e; ++i) {
+ data_array[i] = 324 - int(i);
+ data.push_back(&data_array[i]);
+ }
+
+ TinyPtrVector<int *> V(data);
+ EXPECT_TRUE(V.size() == 128);
+ EXPECT_FALSE(V.empty());
+
+ MutableArrayRef<int *> mut_array = V;
+ for (unsigned i = 0, e = 128; i != e; ++i) {
+ EXPECT_TRUE(mut_array[i] == data[i]);
+ mut_array[i] = 324 + mut_array[i];
+ EXPECT_TRUE(mut_array[i] == (324 + data[i]));
+ }
+}
diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp
index cacbde6..1f9aa32 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -665,3 +665,20 @@ TEST(TripleTest, getARMCPUForArch) {
}
}
}
+
+TEST(TripleTest, NormalizeARM) {
+ EXPECT_EQ("armv6--netbsd-eabi", Triple::normalize("armv6-netbsd-eabi"));
+ EXPECT_EQ("armv7--netbsd-eabi", Triple::normalize("armv7-netbsd-eabi"));
+ EXPECT_EQ("armv6eb--netbsd-eabi", Triple::normalize("armv6eb-netbsd-eabi"));
+ EXPECT_EQ("armv7eb--netbsd-eabi", Triple::normalize("armv7eb-netbsd-eabi"));
+ EXPECT_EQ("armv6--netbsd-eabihf", Triple::normalize("armv6-netbsd-eabihf"));
+ EXPECT_EQ("armv7--netbsd-eabihf", Triple::normalize("armv7-netbsd-eabihf"));
+ EXPECT_EQ("armv6eb--netbsd-eabihf", Triple::normalize("armv6eb-netbsd-eabihf"));
+ EXPECT_EQ("armv7eb--netbsd-eabihf", Triple::normalize("armv7eb-netbsd-eabihf"));
+
+ Triple T;
+ T = Triple("armv6--netbsd-eabi");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ T = Triple("armv6eb--netbsd-eabi");
+ EXPECT_EQ(Triple::armeb, T.getArch());
+}
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index dba9d49..4b4ebb6 100644
--- a/unittests/Analysis/CFGTest.cpp
+++ b/unittests/Analysis/CFGTest.cpp
@@ -16,7 +16,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
@@ -72,7 +72,7 @@ protected:
PassInfo *PI = new PassInfo("isPotentiallyReachable testing pass",
"", &ID, nullptr, true, true);
PassRegistry::getPassRegistry()->registerPass(*PI, false);
- initializeLoopInfoPass(*PassRegistry::getPassRegistry());
+ initializeLoopInfoWrapperPassPass(*PassRegistry::getPassRegistry());
initializeDominatorTreeWrapperPassPass(
*PassRegistry::getPassRegistry());
return 0;
@@ -80,7 +80,7 @@ protected:
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
- AU.addRequired<LoopInfo>();
+ AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
}
@@ -88,7 +88,7 @@ protected:
if (!F.hasName() || F.getName() != "test")
return false;
- LoopInfo *LI = &getAnalysis<LoopInfo>();
+ LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DominatorTree *DT =
&getAnalysis<DominatorTreeWrapperPass>().getDomTree();
EXPECT_EQ(isPotentiallyReachable(A, B, nullptr, nullptr),
@@ -107,7 +107,7 @@ protected:
IsPotentiallyReachableTestPass *P =
new IsPotentiallyReachableTestPass(ExpectedResult, A, B);
- PassManager PM;
+ legacy::PassManager PM;
PM.add(P);
PM.run(*M);
}
diff --git a/unittests/Analysis/MixedTBAATest.cpp b/unittests/Analysis/MixedTBAATest.cpp
index d7935e3..7b8a25c 100644
--- a/unittests/Analysis/MixedTBAATest.cpp
+++ b/unittests/Analysis/MixedTBAATest.cpp
@@ -13,7 +13,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/CommandLine.h"
#include "gtest/gtest.h"
@@ -27,7 +27,7 @@ protected:
LLVMContext C;
Module M;
MDBuilder MD;
- PassManager PM;
+ legacy::PassManager PM;
};
TEST_F(MixedTBAATest, MixedTBAA) {
diff --git a/unittests/Analysis/ScalarEvolutionTest.cpp b/unittests/Analysis/ScalarEvolutionTest.cpp
index 90f6997..876a264 100644
--- a/unittests/Analysis/ScalarEvolutionTest.cpp
+++ b/unittests/Analysis/ScalarEvolutionTest.cpp
@@ -14,7 +14,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "gtest/gtest.h"
namespace llvm {
@@ -32,7 +32,7 @@ protected:
}
LLVMContext Context;
Module M;
- PassManager PM;
+ legacy::PassManager PM;
ScalarEvolution &SE;
};
diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp
index 6eb40d6..1f28ec6 100644
--- a/unittests/Bitcode/BitReaderTest.cpp
+++ b/unittests/Bitcode/BitReaderTest.cpp
@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallString.h"
+#include "llvm/AsmParser/Parser.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"
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 65930b5..a1272ed 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -4,7 +4,7 @@ set_target_properties(UnitTests PROPERTIES FOLDER "Tests")
if (APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../../lib")
else(UNIX)
- set(CMAKE_INSTALL_RPATH "\$ORIGIN/../../lib")
+ set(CMAKE_INSTALL_RPATH "\$ORIGIN/../../lib${LLVM_LIBDIR_SUFFIX}")
endif()
function(add_llvm_unittest test_dirname)
@@ -22,5 +22,6 @@ add_subdirectory(LineEditor)
add_subdirectory(Linker)
add_subdirectory(MC)
add_subdirectory(Option)
+add_subdirectory(ProfileData)
add_subdirectory(Support)
add_subdirectory(Transforms)
diff --git a/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp
index 04c5a8a..efb0920 100644
--- a/unittests/CodeGen/DIEHashTest.cpp
+++ b/unittests/CodeGen/DIEHashTest.cpp
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "../lib/CodeGen/AsmPrinter/DIE.h"
+#include "llvm/CodeGen/DIE.h"
#include "../lib/CodeGen/AsmPrinter/DIEHash.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
-#include "llvm/ADT/STLExtras.h"
#include "gtest/gtest.h"
using namespace llvm;
diff --git a/unittests/DebugInfo/CMakeLists.txt b/unittests/DebugInfo/CMakeLists.txt
index e844e95..dae472b 100644
--- a/unittests/DebugInfo/CMakeLists.txt
+++ b/unittests/DebugInfo/CMakeLists.txt
@@ -1,11 +1,3 @@
-set(LLVM_LINK_COMPONENTS
- DebugInfo
- )
-set(DebugInfoSources
- DWARFFormValueTest.cpp
- )
-
-add_llvm_unittest(DebugInfoTests
- ${DebugInfoSources}
- )
+add_subdirectory(DWARF)
+add_subdirectory(PDB)
diff --git a/unittests/DebugInfo/DWARF/CMakeLists.txt b/unittests/DebugInfo/DWARF/CMakeLists.txt
new file mode 100644
index 0000000..4bec17c
--- /dev/null
+++ b/unittests/DebugInfo/DWARF/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS
+ DebugInfoDWARF
+ )
+
+set(DebugInfoSources
+ DWARFFormValueTest.cpp
+ )
+
+add_llvm_unittest(DebugInfoDWARFTests
+ ${DebugInfoSources}
+ )
diff --git a/unittests/DebugInfo/DWARFFormValueTest.cpp b/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
index 38b932e..4521132 100644
--- a/unittests/DebugInfo/DWARFFormValueTest.cpp
+++ b/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/Support/Dwarf.h"
#include "gtest/gtest.h"
using namespace llvm;
diff --git a/unittests/DebugInfo/DWARF/Makefile b/unittests/DebugInfo/DWARF/Makefile
new file mode 100644
index 0000000..b0f40e1
--- /dev/null
+++ b/unittests/DebugInfo/DWARF/Makefile
@@ -0,0 +1,16 @@
+##===- unittests/DebugInfo/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 = DebugInfoDWARF
+LINK_COMPONENTS := DebugInfoDWARF object support
+
+include $(LEVEL)/Makefile.config
+
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/DebugInfo/Makefile b/unittests/DebugInfo/Makefile
index 999ded9..1889ad2 100644
--- a/unittests/DebugInfo/Makefile
+++ b/unittests/DebugInfo/Makefile
@@ -6,11 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
-
LEVEL = ../..
-TESTNAME = DebugInfo
-LINK_COMPONENTS := debuginfo object support
include $(LEVEL)/Makefile.config
+PARALLEL_DIRS := DWARF PDB
+
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/DebugInfo/PDB/CMakeLists.txt b/unittests/DebugInfo/PDB/CMakeLists.txt
new file mode 100644
index 0000000..91924a5
--- /dev/null
+++ b/unittests/DebugInfo/PDB/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS
+ DebugInfoPDB
+ )
+
+set(DebugInfoPDBSources
+ PDBApiTest.cpp
+ )
+
+add_llvm_unittest(DebugInfoPDBTests
+ ${DebugInfoPDBSources}
+ )
diff --git a/unittests/DebugInfo/PDB/Makefile b/unittests/DebugInfo/PDB/Makefile
new file mode 100644
index 0000000..eb118a3
--- /dev/null
+++ b/unittests/DebugInfo/PDB/Makefile
@@ -0,0 +1,16 @@
+##===- unittests/DebugInfo/PDB/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 = DebugInfoPDB
+LINK_COMPONENTS := DebugInfoPDB support
+
+include $(LEVEL)/Makefile.config
+
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/DebugInfo/PDB/PDBApiTest.cpp b/unittests/DebugInfo/PDB/PDBApiTest.cpp
new file mode 100644
index 0000000..629c5f8
--- /dev/null
+++ b/unittests/DebugInfo/PDB/PDBApiTest.cpp
@@ -0,0 +1,387 @@
+//===- llvm/unittest/DebugInfo/PDB/PDBApiTest.cpp -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <unordered_map>
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+#define MOCK_SYMBOL_ACCESSOR(Func) \
+ decltype(std::declval<IPDBRawSymbol>().Func()) Func() const override { \
+ typedef decltype(IPDBRawSymbol::Func()) ReturnType; \
+ return ReturnType(); \
+ }
+
+class MockSession : public IPDBSession {
+ uint64_t getLoadAddress() const override { return 0; }
+ void setLoadAddress(uint64_t Address) override {}
+ std::unique_ptr<PDBSymbolExe> getGlobalScope() const override {
+ return nullptr;
+ }
+ std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBSourceFile>
+ getSourceFileById(uint32_t SymbolId) const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBEnumSourceFiles> getAllSourceFiles() const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBEnumSourceFiles> getSourceFilesForCompiland(
+ const PDBSymbolCompiland &Compiland) const override {
+ return nullptr;
+ }
+
+ std::unique_ptr<IPDBEnumDataStreams> getDebugStreams() const override {
+ return nullptr;
+ }
+};
+
+class MockRawSymbol : public IPDBRawSymbol {
+public:
+ MockRawSymbol(PDB_SymType SymType)
+ : Type(SymType) {}
+
+ void dump(raw_ostream &OS, int Indent) const override {}
+
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildren(PDB_SymType Type) const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildren(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags) const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBEnumSymbols>
+ findChildrenByRVA(PDB_SymType Type, StringRef Name, PDB_NameSearchFlags Flags,
+ uint32_t RVA) const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBEnumSymbols>
+ findInlineFramesByRVA(uint32_t RVA) const override {
+ return nullptr;
+ }
+
+ void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const override {}
+ void getFrontEndVersion(VersionInfo &Version) const override {}
+ void getBackEndVersion(VersionInfo &Version) const override {}
+
+ PDB_SymType getSymTag() const override { return Type; }
+
+ MOCK_SYMBOL_ACCESSOR(getAccess)
+ MOCK_SYMBOL_ACCESSOR(getAddressOffset)
+ MOCK_SYMBOL_ACCESSOR(getAddressSection)
+ MOCK_SYMBOL_ACCESSOR(getAge)
+ MOCK_SYMBOL_ACCESSOR(getArrayIndexTypeId)
+ MOCK_SYMBOL_ACCESSOR(getBaseDataOffset)
+ MOCK_SYMBOL_ACCESSOR(getBaseDataSlot)
+ MOCK_SYMBOL_ACCESSOR(getBaseSymbolId)
+ MOCK_SYMBOL_ACCESSOR(getBuiltinType)
+ MOCK_SYMBOL_ACCESSOR(getBitPosition)
+ MOCK_SYMBOL_ACCESSOR(getCallingConvention)
+ MOCK_SYMBOL_ACCESSOR(getClassParentId)
+ MOCK_SYMBOL_ACCESSOR(getCompilerName)
+ MOCK_SYMBOL_ACCESSOR(getCount)
+ MOCK_SYMBOL_ACCESSOR(getCountLiveRanges)
+ MOCK_SYMBOL_ACCESSOR(getLanguage)
+ MOCK_SYMBOL_ACCESSOR(getLexicalParentId)
+ MOCK_SYMBOL_ACCESSOR(getLibraryName)
+ MOCK_SYMBOL_ACCESSOR(getLiveRangeStartAddressOffset)
+ MOCK_SYMBOL_ACCESSOR(getLiveRangeStartAddressSection)
+ MOCK_SYMBOL_ACCESSOR(getLiveRangeStartRelativeVirtualAddress)
+ MOCK_SYMBOL_ACCESSOR(getLocalBasePointerRegisterId)
+ MOCK_SYMBOL_ACCESSOR(getLowerBoundId)
+ MOCK_SYMBOL_ACCESSOR(getMemorySpaceKind)
+ MOCK_SYMBOL_ACCESSOR(getName)
+ MOCK_SYMBOL_ACCESSOR(getNumberOfAcceleratorPointerTags)
+ MOCK_SYMBOL_ACCESSOR(getNumberOfColumns)
+ MOCK_SYMBOL_ACCESSOR(getNumberOfModifiers)
+ MOCK_SYMBOL_ACCESSOR(getNumberOfRegisterIndices)
+ MOCK_SYMBOL_ACCESSOR(getNumberOfRows)
+ MOCK_SYMBOL_ACCESSOR(getObjectFileName)
+ MOCK_SYMBOL_ACCESSOR(getOemId)
+ MOCK_SYMBOL_ACCESSOR(getOemSymbolId)
+ MOCK_SYMBOL_ACCESSOR(getOffsetInUdt)
+ MOCK_SYMBOL_ACCESSOR(getPlatform)
+ MOCK_SYMBOL_ACCESSOR(getRank)
+ MOCK_SYMBOL_ACCESSOR(getRegisterId)
+ MOCK_SYMBOL_ACCESSOR(getRegisterType)
+ MOCK_SYMBOL_ACCESSOR(getRelativeVirtualAddress)
+ MOCK_SYMBOL_ACCESSOR(getSamplerSlot)
+ MOCK_SYMBOL_ACCESSOR(getSignature)
+ MOCK_SYMBOL_ACCESSOR(getSizeInUdt)
+ MOCK_SYMBOL_ACCESSOR(getSlot)
+ MOCK_SYMBOL_ACCESSOR(getSourceFileName)
+ MOCK_SYMBOL_ACCESSOR(getStride)
+ MOCK_SYMBOL_ACCESSOR(getSubTypeId)
+ MOCK_SYMBOL_ACCESSOR(getSymbolsFileName)
+ MOCK_SYMBOL_ACCESSOR(getSymIndexId)
+ MOCK_SYMBOL_ACCESSOR(getTargetOffset)
+ MOCK_SYMBOL_ACCESSOR(getTargetRelativeVirtualAddress)
+ MOCK_SYMBOL_ACCESSOR(getTargetVirtualAddress)
+ MOCK_SYMBOL_ACCESSOR(getTargetSection)
+ MOCK_SYMBOL_ACCESSOR(getTextureSlot)
+ MOCK_SYMBOL_ACCESSOR(getTimeStamp)
+ MOCK_SYMBOL_ACCESSOR(getToken)
+ MOCK_SYMBOL_ACCESSOR(getTypeId)
+ MOCK_SYMBOL_ACCESSOR(getUavSlot)
+ MOCK_SYMBOL_ACCESSOR(getUndecoratedName)
+ MOCK_SYMBOL_ACCESSOR(getUnmodifiedTypeId)
+ MOCK_SYMBOL_ACCESSOR(getUpperBoundId)
+ MOCK_SYMBOL_ACCESSOR(getVirtualBaseDispIndex)
+ MOCK_SYMBOL_ACCESSOR(getVirtualBaseOffset)
+ MOCK_SYMBOL_ACCESSOR(getVirtualTableShapeId)
+ MOCK_SYMBOL_ACCESSOR(getDataKind)
+ MOCK_SYMBOL_ACCESSOR(getGuid)
+ MOCK_SYMBOL_ACCESSOR(getOffset)
+ MOCK_SYMBOL_ACCESSOR(getThisAdjust)
+ MOCK_SYMBOL_ACCESSOR(getVirtualBasePointerOffset)
+ MOCK_SYMBOL_ACCESSOR(getLocationType)
+ MOCK_SYMBOL_ACCESSOR(getMachineType)
+ MOCK_SYMBOL_ACCESSOR(getThunkOrdinal)
+ MOCK_SYMBOL_ACCESSOR(getLength)
+ MOCK_SYMBOL_ACCESSOR(getLiveRangeLength)
+ MOCK_SYMBOL_ACCESSOR(getVirtualAddress)
+ MOCK_SYMBOL_ACCESSOR(getUdtKind)
+ MOCK_SYMBOL_ACCESSOR(hasConstructor)
+ MOCK_SYMBOL_ACCESSOR(hasCustomCallingConvention)
+ MOCK_SYMBOL_ACCESSOR(hasFarReturn)
+ MOCK_SYMBOL_ACCESSOR(isCode)
+ MOCK_SYMBOL_ACCESSOR(isCompilerGenerated)
+ MOCK_SYMBOL_ACCESSOR(isConstType)
+ MOCK_SYMBOL_ACCESSOR(isEditAndContinueEnabled)
+ MOCK_SYMBOL_ACCESSOR(isFunction)
+ MOCK_SYMBOL_ACCESSOR(getAddressTaken)
+ MOCK_SYMBOL_ACCESSOR(getNoStackOrdering)
+ MOCK_SYMBOL_ACCESSOR(hasAlloca)
+ MOCK_SYMBOL_ACCESSOR(hasAssignmentOperator)
+ MOCK_SYMBOL_ACCESSOR(hasCTypes)
+ MOCK_SYMBOL_ACCESSOR(hasCastOperator)
+ MOCK_SYMBOL_ACCESSOR(hasDebugInfo)
+ MOCK_SYMBOL_ACCESSOR(hasEH)
+ MOCK_SYMBOL_ACCESSOR(hasEHa)
+ MOCK_SYMBOL_ACCESSOR(hasFramePointer)
+ MOCK_SYMBOL_ACCESSOR(hasInlAsm)
+ MOCK_SYMBOL_ACCESSOR(hasInlineAttribute)
+ MOCK_SYMBOL_ACCESSOR(hasInterruptReturn)
+ MOCK_SYMBOL_ACCESSOR(hasLongJump)
+ MOCK_SYMBOL_ACCESSOR(hasManagedCode)
+ MOCK_SYMBOL_ACCESSOR(hasNestedTypes)
+ MOCK_SYMBOL_ACCESSOR(hasNoInlineAttribute)
+ MOCK_SYMBOL_ACCESSOR(hasNoReturnAttribute)
+ MOCK_SYMBOL_ACCESSOR(hasOptimizedCodeDebugInfo)
+ MOCK_SYMBOL_ACCESSOR(hasOverloadedOperator)
+ MOCK_SYMBOL_ACCESSOR(hasSEH)
+ MOCK_SYMBOL_ACCESSOR(hasSecurityChecks)
+ MOCK_SYMBOL_ACCESSOR(hasSetJump)
+ MOCK_SYMBOL_ACCESSOR(hasStrictGSCheck)
+ MOCK_SYMBOL_ACCESSOR(isAcceleratorGroupSharedLocal)
+ MOCK_SYMBOL_ACCESSOR(isAcceleratorPointerTagLiveRange)
+ MOCK_SYMBOL_ACCESSOR(isAcceleratorStubFunction)
+ MOCK_SYMBOL_ACCESSOR(isAggregated)
+ MOCK_SYMBOL_ACCESSOR(isIntroVirtualFunction)
+ MOCK_SYMBOL_ACCESSOR(isCVTCIL)
+ MOCK_SYMBOL_ACCESSOR(isConstructorVirtualBase)
+ MOCK_SYMBOL_ACCESSOR(isCxxReturnUdt)
+ MOCK_SYMBOL_ACCESSOR(isDataAligned)
+ MOCK_SYMBOL_ACCESSOR(isHLSLData)
+ MOCK_SYMBOL_ACCESSOR(isHotpatchable)
+ MOCK_SYMBOL_ACCESSOR(isIndirectVirtualBaseClass)
+ MOCK_SYMBOL_ACCESSOR(isInterfaceUdt)
+ MOCK_SYMBOL_ACCESSOR(isIntrinsic)
+ MOCK_SYMBOL_ACCESSOR(isLTCG)
+ MOCK_SYMBOL_ACCESSOR(isLocationControlFlowDependent)
+ MOCK_SYMBOL_ACCESSOR(isMSILNetmodule)
+ MOCK_SYMBOL_ACCESSOR(isMatrixRowMajor)
+ MOCK_SYMBOL_ACCESSOR(isManagedCode)
+ MOCK_SYMBOL_ACCESSOR(isMSILCode)
+ MOCK_SYMBOL_ACCESSOR(isMultipleInheritance)
+ MOCK_SYMBOL_ACCESSOR(isNaked)
+ MOCK_SYMBOL_ACCESSOR(isNested)
+ MOCK_SYMBOL_ACCESSOR(isOptimizedAway)
+ MOCK_SYMBOL_ACCESSOR(isPacked)
+ MOCK_SYMBOL_ACCESSOR(isPointerBasedOnSymbolValue)
+ MOCK_SYMBOL_ACCESSOR(isPointerToDataMember)
+ MOCK_SYMBOL_ACCESSOR(isPointerToMemberFunction)
+ MOCK_SYMBOL_ACCESSOR(isPureVirtual)
+ MOCK_SYMBOL_ACCESSOR(isRValueReference)
+ MOCK_SYMBOL_ACCESSOR(isRefUdt)
+ MOCK_SYMBOL_ACCESSOR(isReference)
+ MOCK_SYMBOL_ACCESSOR(isRestrictedType)
+ MOCK_SYMBOL_ACCESSOR(isReturnValue)
+ MOCK_SYMBOL_ACCESSOR(isSafeBuffers)
+ MOCK_SYMBOL_ACCESSOR(isScoped)
+ MOCK_SYMBOL_ACCESSOR(isSdl)
+ MOCK_SYMBOL_ACCESSOR(isSingleInheritance)
+ MOCK_SYMBOL_ACCESSOR(isSplitted)
+ MOCK_SYMBOL_ACCESSOR(isStatic)
+ MOCK_SYMBOL_ACCESSOR(hasPrivateSymbols)
+ MOCK_SYMBOL_ACCESSOR(isUnalignedType)
+ MOCK_SYMBOL_ACCESSOR(isUnreached)
+ MOCK_SYMBOL_ACCESSOR(isValueUdt)
+ MOCK_SYMBOL_ACCESSOR(isVirtual)
+ MOCK_SYMBOL_ACCESSOR(isVirtualBaseClass)
+ MOCK_SYMBOL_ACCESSOR(isVirtualInheritance)
+ MOCK_SYMBOL_ACCESSOR(isVolatileType)
+ MOCK_SYMBOL_ACCESSOR(getValue)
+ MOCK_SYMBOL_ACCESSOR(wasInlined)
+ MOCK_SYMBOL_ACCESSOR(getUnused)
+
+private:
+ PDB_SymType Type;
+};
+
+class PDBApiTest : public testing::Test {
+public:
+ std::unordered_map<PDB_SymType, std::unique_ptr<PDBSymbol>> SymbolMap;
+
+ void SetUp() override {
+ Session.reset(new MockSession());
+
+ InsertItemWithTag(PDB_SymType::None);
+ InsertItemWithTag(PDB_SymType::Exe);
+ InsertItemWithTag(PDB_SymType::Compiland);
+ InsertItemWithTag(PDB_SymType::CompilandDetails);
+ InsertItemWithTag(PDB_SymType::CompilandEnv);
+ InsertItemWithTag(PDB_SymType::Function);
+ InsertItemWithTag(PDB_SymType::Block);
+ InsertItemWithTag(PDB_SymType::Data);
+ InsertItemWithTag(PDB_SymType::Annotation);
+ InsertItemWithTag(PDB_SymType::Label);
+ InsertItemWithTag(PDB_SymType::PublicSymbol);
+ InsertItemWithTag(PDB_SymType::UDT);
+ InsertItemWithTag(PDB_SymType::Enum);
+ InsertItemWithTag(PDB_SymType::FunctionSig);
+ InsertItemWithTag(PDB_SymType::PointerType);
+ InsertItemWithTag(PDB_SymType::ArrayType);
+ InsertItemWithTag(PDB_SymType::BuiltinType);
+ InsertItemWithTag(PDB_SymType::Typedef);
+ InsertItemWithTag(PDB_SymType::BaseClass);
+ InsertItemWithTag(PDB_SymType::Friend);
+ InsertItemWithTag(PDB_SymType::FunctionArg);
+ InsertItemWithTag(PDB_SymType::FuncDebugStart);
+ InsertItemWithTag(PDB_SymType::FuncDebugEnd);
+ InsertItemWithTag(PDB_SymType::UsingNamespace);
+ InsertItemWithTag(PDB_SymType::VTableShape);
+ InsertItemWithTag(PDB_SymType::VTable);
+ InsertItemWithTag(PDB_SymType::Custom);
+ InsertItemWithTag(PDB_SymType::Thunk);
+ InsertItemWithTag(PDB_SymType::CustomType);
+ InsertItemWithTag(PDB_SymType::ManagedType);
+ InsertItemWithTag(PDB_SymType::Dimension);
+ InsertItemWithTag(PDB_SymType::Max);
+ }
+
+ template <class ExpectedType> void VerifyDyncast(PDB_SymType Tag) {
+ for (auto item = SymbolMap.begin(); item != SymbolMap.end(); ++item) {
+ EXPECT_EQ(item->first == Tag, llvm::isa<ExpectedType>(*item->second));
+ }
+ }
+
+ void VerifyUnknownDyncasts() {
+ for (auto item = SymbolMap.begin(); item != SymbolMap.end(); ++item) {
+ bool should_match = false;
+ if (item->first == PDB_SymType::None || item->first >= PDB_SymType::Max)
+ should_match = true;
+
+ EXPECT_EQ(should_match, llvm::isa<PDBSymbolUnknown>(*item->second));
+ }
+ }
+
+private:
+ std::unique_ptr<IPDBSession> Session;
+
+ void InsertItemWithTag(PDB_SymType Tag) {
+ auto RawSymbol = llvm::make_unique<MockRawSymbol>(Tag);
+ auto Symbol = PDBSymbol::create(*Session, std::move(RawSymbol));
+ SymbolMap.insert(std::make_pair(Tag, std::move(Symbol)));
+ }
+};
+
+TEST_F(PDBApiTest, Dyncast) {
+
+ // Most of the types have a one-to-one mapping between Tag and concrete type.
+ VerifyDyncast<PDBSymbolExe>(PDB_SymType::Exe);
+ VerifyDyncast<PDBSymbolCompiland>(PDB_SymType::Compiland);
+ VerifyDyncast<PDBSymbolCompilandDetails>(PDB_SymType::CompilandDetails);
+ VerifyDyncast<PDBSymbolCompilandEnv>(PDB_SymType::CompilandEnv);
+ VerifyDyncast<PDBSymbolFunc>(PDB_SymType::Function);
+ VerifyDyncast<PDBSymbolBlock>(PDB_SymType::Block);
+ VerifyDyncast<PDBSymbolData>(PDB_SymType::Data);
+ VerifyDyncast<PDBSymbolAnnotation>(PDB_SymType::Annotation);
+ VerifyDyncast<PDBSymbolLabel>(PDB_SymType::Label);
+ VerifyDyncast<PDBSymbolPublicSymbol>(PDB_SymType::PublicSymbol);
+ VerifyDyncast<PDBSymbolTypeUDT>(PDB_SymType::UDT);
+ VerifyDyncast<PDBSymbolTypeEnum>(PDB_SymType::Enum);
+ VerifyDyncast<PDBSymbolTypeFunctionSig>(PDB_SymType::FunctionSig);
+ VerifyDyncast<PDBSymbolTypePointer>(PDB_SymType::PointerType);
+ VerifyDyncast<PDBSymbolTypeArray>(PDB_SymType::ArrayType);
+ VerifyDyncast<PDBSymbolTypeBuiltin>(PDB_SymType::BuiltinType);
+ VerifyDyncast<PDBSymbolTypeTypedef>(PDB_SymType::Typedef);
+ VerifyDyncast<PDBSymbolTypeBaseClass>(PDB_SymType::BaseClass);
+ VerifyDyncast<PDBSymbolTypeFriend>(PDB_SymType::Friend);
+ VerifyDyncast<PDBSymbolTypeFunctionArg>(PDB_SymType::FunctionArg);
+ VerifyDyncast<PDBSymbolFuncDebugStart>(PDB_SymType::FuncDebugStart);
+ VerifyDyncast<PDBSymbolFuncDebugEnd>(PDB_SymType::FuncDebugEnd);
+ VerifyDyncast<PDBSymbolUsingNamespace>(PDB_SymType::UsingNamespace);
+ VerifyDyncast<PDBSymbolTypeVTableShape>(PDB_SymType::VTableShape);
+ VerifyDyncast<PDBSymbolTypeVTable>(PDB_SymType::VTable);
+ VerifyDyncast<PDBSymbolCustom>(PDB_SymType::Custom);
+ VerifyDyncast<PDBSymbolThunk>(PDB_SymType::Thunk);
+ VerifyDyncast<PDBSymbolTypeCustom>(PDB_SymType::CustomType);
+ VerifyDyncast<PDBSymbolTypeManaged>(PDB_SymType::ManagedType);
+ VerifyDyncast<PDBSymbolTypeDimension>(PDB_SymType::Dimension);
+
+ VerifyUnknownDyncasts();
+}
+
+} // end anonymous namespace
diff --git a/unittests/ExecutionEngine/CMakeLists.txt b/unittests/ExecutionEngine/CMakeLists.txt
index 783c9b5..302de99 100644
--- a/unittests/ExecutionEngine/CMakeLists.txt
+++ b/unittests/ExecutionEngine/CMakeLists.txt
@@ -3,6 +3,8 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
Interpreter
MC
+ OrcJIT
+ RuntimeDyld
Support
)
@@ -10,6 +12,8 @@ add_llvm_unittest(ExecutionEngineTests
ExecutionEngineTest.cpp
)
+add_subdirectory(Orc)
+
# 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)
diff --git a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
index b10cbb4..e29787f 100644
--- a/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
+++ b/unittests/ExecutionEngine/MCJIT/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
IPO
MC
MCJIT
+ RuntimeDyld
ScalarOpts
Support
Target
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index c80b88b..f2a3000 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -347,6 +347,38 @@ TEST_F(MCJITCAPITest, simple_function) {
EXPECT_EQ(42, functionPointer.usable());
}
+TEST_F(MCJITCAPITest, gva) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ Module = LLVMModuleCreateWithName("simple_module");
+ LLVMSetTarget(Module, HostTriple.c_str());
+ LLVMValueRef GlobalVar = LLVMAddGlobal(Module, LLVMInt32Type(), "simple_value");
+ LLVMSetInitializer(GlobalVar, LLVMConstInt(LLVMInt32Type(), 42, 0));
+
+ buildMCJITOptions();
+ buildMCJITEngine();
+ buildAndRunPasses();
+
+ uint64_t raw = LLVMGetGlobalValueAddress(Engine, "simple_value");
+ int32_t *usable = (int32_t *) raw;
+
+ EXPECT_EQ(42, *usable);
+}
+
+TEST_F(MCJITCAPITest, gfa) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ buildSimpleFunction();
+ buildMCJITOptions();
+ buildMCJITEngine();
+ buildAndRunPasses();
+
+ uint64_t raw = LLVMGetFunctionAddress(Engine, "simple_function");
+ int (*usable)() = (int (*)()) raw;
+
+ EXPECT_EQ(42, usable());
+}
+
TEST_F(MCJITCAPITest, custom_memory_manager) {
SKIP_UNSUPPORTED_PLATFORM;
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
index b0d1bb3..da6e25a 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
@@ -392,4 +392,23 @@ TEST_F(MCJITMultipleModuleTest, cross_module_dependency_case3) {
ptr = TheJIT->getFunctionAddress(FB2->getName().str());
checkAccumulate(ptr);
}
+
+// Test that FindFunctionNamed finds the definition of
+// a function in the correct module. We check two functions
+// in two different modules, to make sure that for at least
+// one of them MCJIT had to ignore the extern declaration.
+TEST_F(MCJITMultipleModuleTest, FindFunctionNamed_test) {
+ SKIP_UNSUPPORTED_PLATFORM;
+
+ std::unique_ptr<Module> A, B;
+ Function *FA, *FB1, *FB2;
+ createCrossModuleRecursiveCase(A, FA, B, FB1, FB2);
+
+ createJIT(std::move(A));
+ TheJIT->addModule(std::move(B));
+
+ EXPECT_EQ(FA, TheJIT->FindFunctionNamed(FA->getName().data()));
+ EXPECT_EQ(FB1, TheJIT->FindFunctionNamed(FB1->getName().data()));
+}
+
}
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
index 2736383..2e38dd8 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -163,7 +163,7 @@ TEST_F(MCJITObjectCacheTest, VerifyLoadFromCache) {
TheJIT.reset();
// Create a new memory manager.
- MM = new SectionMemoryManager;
+ MM.reset(new SectionMemoryManager());
// Create a new module and save it. Use a different return code so we can
// tell if MCJIT compiled this module or used the cache.
@@ -197,7 +197,7 @@ TEST_F(MCJITObjectCacheTest, VerifyNonLoadFromCache) {
TheJIT.reset();
// Create a new memory manager.
- MM = new SectionMemoryManager;
+ MM.reset(new SectionMemoryManager());
// Create a new module and save it. Use a different return code so we can
// tell if MCJIT compiled this module or used the cache. Note that we use
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index eea88bb..35af417 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -325,7 +325,7 @@ protected:
EngineBuilder EB(std::move(M));
std::string Error;
TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
- .setMCJITMemoryManager(MM)
+ .setMCJITMemoryManager(std::move(MM))
.setErrorStr(&Error)
.setOptLevel(CodeGenOpt::None)
.setCodeModel(CodeModel::JITDefault)
@@ -344,7 +344,7 @@ protected:
StringRef MArch;
SmallVector<std::string, 1> MAttrs;
std::unique_ptr<ExecutionEngine> TheJIT;
- RTDyldMemoryManager *MM;
+ std::unique_ptr<RTDyldMemoryManager> MM;
std::unique_ptr<Module> M;
};
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index 8ecb883..c19f8d6 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -13,8 +13,10 @@ LINK_COMPONENTS :=interpreter
include $(LEVEL)/Makefile.config
+PARALLEL_DIRS = Orc
+
ifeq ($(TARGET_HAS_JIT),1)
- PARALLEL_DIRS = MCJIT
+ PARALLEL_DIRS += MCJIT
endif
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ExecutionEngine/Orc/CMakeLists.txt b/unittests/ExecutionEngine/Orc/CMakeLists.txt
new file mode 100644
index 0000000..7bc13a1
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(LLVM_LINK_COMPONENTS
+ Core
+ Support
+ )
+
+add_llvm_unittest(OrcJITTests
+ LazyEmittingLayerTest.cpp
+ )
diff --git a/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
new file mode 100644
index 0000000..b0ff127
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
@@ -0,0 +1,30 @@
+//===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+struct MockBaseLayer {
+ typedef int ModuleSetHandleT;
+ ModuleSetHandleT addModuleSet(std::list<std::unique_ptr<llvm::Module>>,
+ std::unique_ptr<llvm::RTDyldMemoryManager> x) {
+ EXPECT_FALSE(x);
+ return 42;
+ }
+};
+
+TEST(LazyEmittingLayerTest, Empty) {
+ MockBaseLayer M;
+ llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
+ L.addModuleSet(std::list<std::unique_ptr<llvm::Module>>(), nullptr);
+}
+
+}
diff --git a/unittests/ExecutionEngine/Orc/Makefile b/unittests/ExecutionEngine/Orc/Makefile
new file mode 100644
index 0000000..c899728
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/Makefile
@@ -0,0 +1,16 @@
+##===- unittests/ExecutionEngine/Orc/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 = OrcJIT
+LINK_COMPONENTS := core ipo mcjit orcjit native support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
+
diff --git a/unittests/IR/CMakeLists.txt b/unittests/IR/CMakeLists.txt
index a046209..0c29796 100644
--- a/unittests/IR/CMakeLists.txt
+++ b/unittests/IR/CMakeLists.txt
@@ -14,7 +14,6 @@ set(IRSources
DominatorTreeTest.cpp
IRBuilderTest.cpp
InstructionsTest.cpp
- LeakDetectorTest.cpp
LegacyPassManagerTest.cpp
MDBuilderTest.cpp
MetadataTest.cpp
diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp
index 5414b25..5d271e2 100644
--- a/unittests/IR/ConstantsTest.cpp
+++ b/unittests/IR/ConstantsTest.cpp
@@ -7,12 +7,14 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
namespace llvm {
@@ -347,5 +349,19 @@ TEST(ConstantsTest, GEPReplaceWithConstant) {
ASSERT_EQ(GEP->getOperand(0), Alias);
}
+TEST(ConstantsTest, AliasCAPI) {
+ LLVMContext Context;
+ SMDiagnostic Error;
+ std::unique_ptr<Module> M =
+ parseAssemblyString("@g = global i32 42", Error, Context);
+ GlobalVariable *G = M->getGlobalVariable("g");
+ Type *I16Ty = Type::getInt16Ty(Context);
+ Type *I16PTy = PointerType::get(I16Ty, 0);
+ Constant *Aliasee = ConstantExpr::getBitCast(G, I16PTy);
+ LLVMValueRef AliasRef =
+ LLVMAddAlias(wrap(M.get()), wrap(I16PTy), wrap(Aliasee), "a");
+ ASSERT_EQ(unwrap<GlobalAlias>(AliasRef)->getAliasee(), Aliasee);
+}
+
} // end anonymous namespace
} // end namespace llvm
diff --git a/unittests/IR/DebugInfoTest.cpp b/unittests/IR/DebugInfoTest.cpp
index 1fa851e..3c6c786 100644
--- a/unittests/IR/DebugInfoTest.cpp
+++ b/unittests/IR/DebugInfoTest.cpp
@@ -65,4 +65,71 @@ TEST(DebugInfoTest, DIHeaderFieldIterator) {
ASSERT_EQ("stuff", *++MAKE_FIELD_ITERATOR("\0stuff"));
}
+TEST(DIDescriptorTest, getFlag) {
+ // Some valid flags.
+ EXPECT_EQ(DIDescriptor::FlagPublic, DIDescriptor::getFlag("DIFlagPublic"));
+ EXPECT_EQ(DIDescriptor::FlagProtected,
+ DIDescriptor::getFlag("DIFlagProtected"));
+ EXPECT_EQ(DIDescriptor::FlagPrivate, DIDescriptor::getFlag("DIFlagPrivate"));
+ EXPECT_EQ(DIDescriptor::FlagVector, DIDescriptor::getFlag("DIFlagVector"));
+ EXPECT_EQ(DIDescriptor::FlagRValueReference,
+ DIDescriptor::getFlag("DIFlagRValueReference"));
+
+ // FlagAccessibility shouldn't work.
+ EXPECT_EQ(0u, DIDescriptor::getFlag("DIFlagAccessibility"));
+
+ // Some other invalid strings.
+ EXPECT_EQ(0u, DIDescriptor::getFlag("FlagVector"));
+ EXPECT_EQ(0u, DIDescriptor::getFlag("Vector"));
+ EXPECT_EQ(0u, DIDescriptor::getFlag("other things"));
+ EXPECT_EQ(0u, DIDescriptor::getFlag("DIFlagOther"));
+}
+
+TEST(DIDescriptorTest, getFlagString) {
+ // Some valid flags.
+ EXPECT_EQ(StringRef("DIFlagPublic"),
+ DIDescriptor::getFlagString(DIDescriptor::FlagPublic));
+ EXPECT_EQ(StringRef("DIFlagProtected"),
+ DIDescriptor::getFlagString(DIDescriptor::FlagProtected));
+ EXPECT_EQ(StringRef("DIFlagPrivate"),
+ DIDescriptor::getFlagString(DIDescriptor::FlagPrivate));
+ EXPECT_EQ(StringRef("DIFlagVector"),
+ DIDescriptor::getFlagString(DIDescriptor::FlagVector));
+ EXPECT_EQ(StringRef("DIFlagRValueReference"),
+ DIDescriptor::getFlagString(DIDescriptor::FlagRValueReference));
+
+ // FlagAccessibility actually equals FlagPublic.
+ EXPECT_EQ(StringRef("DIFlagPublic"),
+ DIDescriptor::getFlagString(DIDescriptor::FlagAccessibility));
+
+ // Some other invalid flags.
+ EXPECT_EQ(StringRef(), DIDescriptor::getFlagString(DIDescriptor::FlagPublic |
+ DIDescriptor::FlagVector));
+ EXPECT_EQ(StringRef(),
+ DIDescriptor::getFlagString(DIDescriptor::FlagFwdDecl |
+ DIDescriptor::FlagArtificial));
+ EXPECT_EQ(StringRef(), DIDescriptor::getFlagString(0xffff));
+}
+
+TEST(DIDescriptorTest, splitFlags) {
+ // Some valid flags.
+#define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \
+ { \
+ SmallVector<unsigned, 8> V; \
+ EXPECT_EQ(REMAINDER, DIDescriptor::splitFlags(FLAGS, V)); \
+ EXPECT_TRUE(makeArrayRef(V).equals VECTOR); \
+ }
+ CHECK_SPLIT(DIDescriptor::FlagPublic, (DIDescriptor::FlagPublic), 0u);
+ CHECK_SPLIT(DIDescriptor::FlagProtected, (DIDescriptor::FlagProtected), 0u);
+ CHECK_SPLIT(DIDescriptor::FlagPrivate, (DIDescriptor::FlagPrivate), 0u);
+ CHECK_SPLIT(DIDescriptor::FlagVector, (DIDescriptor::FlagVector), 0u);
+ CHECK_SPLIT(DIDescriptor::FlagRValueReference, (DIDescriptor::FlagRValueReference), 0u);
+ CHECK_SPLIT(DIDescriptor::FlagFwdDecl | DIDescriptor::FlagVector,
+ (DIDescriptor::FlagFwdDecl, DIDescriptor::FlagVector), 0u);
+ CHECK_SPLIT(0x100000u, (), 0x100000u);
+ CHECK_SPLIT(0x100000u | DIDescriptor::FlagVector, (DIDescriptor::FlagVector),
+ 0x100000u);
+#undef CHECK_SPLIT
+}
+
} // end namespace
diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp
index 6c43d6f..8d2dc41 100644
--- a/unittests/IR/DominatorTreeTest.cpp
+++ b/unittests/IR/DominatorTreeTest.cpp
@@ -13,7 +13,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
@@ -218,7 +218,7 @@ namespace llvm {
TEST(DominatorTree, Unreachable) {
DPass *P = new DPass();
std::unique_ptr<Module> M = makeLLVMModule(P);
- PassManager Passes;
+ legacy::PassManager Passes;
Passes.add(P);
Passes.run(*M);
}
diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp
index df5c840..08a729a 100644
--- a/unittests/IR/IRBuilderTest.cpp
+++ b/unittests/IR/IRBuilderTest.cpp
@@ -10,6 +10,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
@@ -287,5 +288,22 @@ TEST_F(IRBuilderTest, RAIIHelpersTest) {
EXPECT_EQ(BB, Builder.GetInsertBlock());
}
+TEST_F(IRBuilderTest, DIBuilder) {
+ IRBuilder<> Builder(BB);
+ DIBuilder DIB(*M);
+ auto File = DIB.createFile("F.CBL", "/");
+ auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/",
+ "llvm-cobol74", true, "", 0);
+ auto Type = DIB.createSubroutineType(File, DIB.getOrCreateTypeArray(None));
+ auto SP = DIB.createFunction(CU, "foo", "", File, 1, Type,
+ false, true, 1, 0, true, F);
+ EXPECT_TRUE(SP.Verify());
+ AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
+ auto BadScope = DIB.createLexicalBlockFile(DIDescriptor(), File, 0);
+ I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
+ EXPECT_FALSE(SP.Verify());
+ DIB.finalize();
+}
+
}
diff --git a/unittests/IR/LeakDetectorTest.cpp b/unittests/IR/LeakDetectorTest.cpp
deleted file mode 100644
index 94eed4c..0000000
--- a/unittests/IR/LeakDetectorTest.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===- LeakDetectorTest.cpp -----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/LeakDetector.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-namespace {
-
-#ifdef GTEST_HAS_DEATH_TEST
-#ifndef NDEBUG
-TEST(LeakDetector, Death1) {
- LeakDetector::addGarbageObject((void*) 1);
- LeakDetector::addGarbageObject((void*) 2);
-
- EXPECT_DEATH(LeakDetector::addGarbageObject((void*) 1),
- ".*Ts.count\\(o\\) == 0 && \"Object already in set!\"");
- EXPECT_DEATH(LeakDetector::addGarbageObject((void*) 2),
- "Cache != o && \"Object already in set!\"");
-}
-#endif
-#endif
-
-}
diff --git a/unittests/IR/LegacyPassManagerTest.cpp b/unittests/IR/LegacyPassManagerTest.cpp
index 4efc2f5..9cb9414 100644
--- a/unittests/IR/LegacyPassManagerTest.cpp
+++ b/unittests/IR/LegacyPassManagerTest.cpp
@@ -8,13 +8,12 @@
//===----------------------------------------------------------------------===//
//
// This unit test exercises the legacy pass manager infrastructure. We use the
-// old names as well to ensure that the source-level compatibility wrapper
-// works for out-of-tree code that expects to include llvm/PassManager.h and
-// subclass the core pass classes.
+// old names as well to ensure that the source-level compatibility is preserved
+// where possible.
//
//===----------------------------------------------------------------------===//
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -302,7 +301,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
- PassManager Passes;
+ legacy::PassManager Passes;
Passes.add(new DataLayoutPass());
Passes.add(mNDM2);
Passes.add(mNDM);
@@ -326,7 +325,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
- PassManager Passes;
+ legacy::PassManager Passes;
Passes.add(new DataLayoutPass());
Passes.add(mNDM);
Passes.add(mNDNM);
@@ -348,7 +347,7 @@ namespace llvm {
void MemoryTestHelper(int run) {
std::unique_ptr<Module> M(makeLLVMModule());
T *P = new T();
- PassManager Passes;
+ legacy::PassManager Passes;
Passes.add(new DataLayoutPass());
Passes.add(P);
Passes.run(*M);
@@ -359,7 +358,7 @@ namespace llvm {
void MemoryTestHelper(int run, int N) {
Module *M = makeLLVMModule();
T *P = new T();
- PassManager Passes;
+ legacy::PassManager Passes;
Passes.add(new DataLayoutPass());
Passes.add(P);
Passes.run(*M);
@@ -397,7 +396,7 @@ namespace llvm {
{
SCOPED_TRACE("Running OnTheFlyTest");
struct OnTheFlyTest *O = new OnTheFlyTest();
- PassManager Passes;
+ legacy::PassManager Passes;
Passes.add(new DataLayoutPass());
Passes.add(O);
Passes.run(*M);
@@ -554,6 +553,6 @@ INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
INITIALIZE_PASS_END(CGPass, "cgp","cgp", false, false)
INITIALIZE_PASS(FPass, "fp","fp", false, false)
INITIALIZE_PASS_BEGIN(LPass, "lp","lp", false, false)
-INITIALIZE_PASS_DEPENDENCY(LoopInfo)
+INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_END(LPass, "lp","lp", false, false)
INITIALIZE_PASS(BPass, "bp","bp", false, false)
diff --git a/unittests/IR/MDBuilderTest.cpp b/unittests/IR/MDBuilderTest.cpp
index fc4674e..ab2d34e 100644
--- a/unittests/IR/MDBuilderTest.cpp
+++ b/unittests/IR/MDBuilderTest.cpp
@@ -36,10 +36,10 @@ TEST_F(MDBuilderTest, createFPMath) {
EXPECT_EQ(MD0, (MDNode *)nullptr);
EXPECT_NE(MD1, (MDNode *)nullptr);
EXPECT_EQ(MD1->getNumOperands(), 1U);
- Value *Op = MD1->getOperand(0);
- EXPECT_TRUE(isa<ConstantFP>(Op));
- EXPECT_TRUE(Op->getType()->isFloatingPointTy());
- ConstantFP *Val = cast<ConstantFP>(Op);
+ Metadata *Op = MD1->getOperand(0);
+ EXPECT_TRUE(mdconst::hasa<ConstantFP>(Op));
+ ConstantFP *Val = mdconst::extract<ConstantFP>(Op);
+ EXPECT_TRUE(Val->getType()->isFloatingPointTy());
EXPECT_TRUE(Val->isExactlyValue(1.0));
}
TEST_F(MDBuilderTest, createRangeMetadata) {
@@ -50,10 +50,10 @@ TEST_F(MDBuilderTest, createRangeMetadata) {
EXPECT_EQ(R0, (MDNode *)nullptr);
EXPECT_NE(R1, (MDNode *)nullptr);
EXPECT_EQ(R1->getNumOperands(), 2U);
- EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(0)));
- EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(1)));
- ConstantInt *C0 = cast<ConstantInt>(R1->getOperand(0));
- ConstantInt *C1 = cast<ConstantInt>(R1->getOperand(1));
+ EXPECT_TRUE(mdconst::hasa<ConstantInt>(R1->getOperand(0)));
+ EXPECT_TRUE(mdconst::hasa<ConstantInt>(R1->getOperand(1)));
+ ConstantInt *C0 = mdconst::extract<ConstantInt>(R1->getOperand(0));
+ ConstantInt *C1 = mdconst::extract<ConstantInt>(R1->getOperand(1));
EXPECT_EQ(C0->getValue(), A);
EXPECT_EQ(C1->getValue(), B);
}
@@ -101,7 +101,8 @@ TEST_F(MDBuilderTest, createTBAANode) {
EXPECT_EQ(N0->getOperand(1), R);
EXPECT_EQ(N1->getOperand(1), R);
EXPECT_EQ(N2->getOperand(1), R);
- EXPECT_TRUE(isa<ConstantInt>(N2->getOperand(2)));
- EXPECT_EQ(cast<ConstantInt>(N2->getOperand(2))->getZExtValue(), 1U);
+ EXPECT_TRUE(mdconst::hasa<ConstantInt>(N2->getOperand(2)));
+ EXPECT_EQ(mdconst::extract<ConstantInt>(N2->getOperand(2))->getZExtValue(),
+ 1U);
}
}
diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp
index 4f7bd72..6f2372d 100644
--- a/unittests/IR/MetadataTest.cpp
+++ b/unittests/IR/MetadataTest.cpp
@@ -1,4 +1,4 @@
-//===- llvm/unittest/IR/Metadata.cpp - Metadata unit tests ----------------===//
+//===- unittests/IR/MetadataTest.cpp - Metadata unit tests ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,22 +7,67 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/Metadata.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
+TEST(ContextAndReplaceableUsesTest, FromContext) {
+ LLVMContext Context;
+ ContextAndReplaceableUses CRU(Context);
+ EXPECT_EQ(&Context, &CRU.getContext());
+ EXPECT_FALSE(CRU.hasReplaceableUses());
+ EXPECT_FALSE(CRU.getReplaceableUses());
+}
+
+TEST(ContextAndReplaceableUsesTest, FromReplaceableUses) {
+ LLVMContext Context;
+ ContextAndReplaceableUses CRU(make_unique<ReplaceableMetadataImpl>(Context));
+ EXPECT_EQ(&Context, &CRU.getContext());
+ EXPECT_TRUE(CRU.hasReplaceableUses());
+ EXPECT_TRUE(CRU.getReplaceableUses());
+}
+
+TEST(ContextAndReplaceableUsesTest, makeReplaceable) {
+ LLVMContext Context;
+ ContextAndReplaceableUses CRU(Context);
+ CRU.makeReplaceable(make_unique<ReplaceableMetadataImpl>(Context));
+ EXPECT_EQ(&Context, &CRU.getContext());
+ EXPECT_TRUE(CRU.hasReplaceableUses());
+ EXPECT_TRUE(CRU.getReplaceableUses());
+}
+
+TEST(ContextAndReplaceableUsesTest, takeReplaceableUses) {
+ LLVMContext Context;
+ auto ReplaceableUses = make_unique<ReplaceableMetadataImpl>(Context);
+ auto *Ptr = ReplaceableUses.get();
+ ContextAndReplaceableUses CRU(std::move(ReplaceableUses));
+ ReplaceableUses = CRU.takeReplaceableUses();
+ EXPECT_EQ(&Context, &CRU.getContext());
+ EXPECT_FALSE(CRU.hasReplaceableUses());
+ EXPECT_FALSE(CRU.getReplaceableUses());
+ EXPECT_EQ(Ptr, ReplaceableUses.get());
+}
+
class MetadataTest : public testing::Test {
protected:
LLVMContext Context;
+ MDNode *getNode() { return MDNode::get(Context, None); }
+ MDNode *getNode(Metadata *MD) { return MDNode::get(Context, MD); }
+ MDNode *getNode(Metadata *MD1, Metadata *MD2) {
+ Metadata *MDs[] = {MD1, MD2};
+ return MDNode::get(Context, MDs);
+ }
};
typedef MetadataTest MDStringTest;
@@ -58,7 +103,7 @@ TEST_F(MDStringTest, PrintingSimple) {
std::string Str;
raw_string_ostream oss(Str);
s->print(oss);
- EXPECT_STREQ("metadata !\"testing 1 2 3\"", oss.str().c_str());
+ EXPECT_STREQ("!\"testing 1 2 3\"", oss.str().c_str());
}
// Test printing of MDString with non-printable characters.
@@ -68,7 +113,7 @@ TEST_F(MDStringTest, PrintingComplex) {
std::string Str;
raw_string_ostream oss(Str);
s->print(oss);
- EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str());
+ EXPECT_STREQ("!\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str());
}
typedef MetadataTest MDNodeTest;
@@ -80,30 +125,27 @@ TEST_F(MDNodeTest, Simple) {
MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
MDString *s2 = MDString::get(Context, StringRef(&y[0], 3));
- ConstantInt *CI = ConstantInt::get(getGlobalContext(), APInt(8, 0));
+ ConstantAsMetadata *CI = ConstantAsMetadata::get(
+ ConstantInt::get(getGlobalContext(), APInt(8, 0)));
- std::vector<Value *> V;
+ std::vector<Metadata *> V;
V.push_back(s1);
V.push_back(CI);
V.push_back(s2);
MDNode *n1 = MDNode::get(Context, V);
- Value *const c1 = n1;
+ Metadata *const c1 = n1;
MDNode *n2 = MDNode::get(Context, c1);
- Value *const c2 = n2;
+ Metadata *const c2 = n2;
MDNode *n3 = MDNode::get(Context, V);
MDNode *n4 = MDNode::getIfExists(Context, V);
MDNode *n5 = MDNode::getIfExists(Context, c1);
MDNode *n6 = MDNode::getIfExists(Context, c2);
EXPECT_NE(n1, n2);
-#ifdef ENABLE_MDNODE_UNIQUING
EXPECT_EQ(n1, n3);
-#else
- (void) n3;
-#endif
EXPECT_EQ(n4, n1);
EXPECT_EQ(n5, n2);
- EXPECT_EQ(n6, (Value*)nullptr);
+ EXPECT_EQ(n6, (Metadata *)nullptr);
EXPECT_EQ(3u, n1->getNumOperands());
EXPECT_EQ(s1, n1->getOperand(0));
@@ -118,22 +160,1713 @@ TEST_F(MDNodeTest, Delete) {
Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext()));
- Value *const V = I;
+ Metadata *const V = LocalAsMetadata::get(I);
MDNode *n = MDNode::get(Context, V);
- WeakVH wvh = n;
+ TrackingMDRef wvh(n);
EXPECT_EQ(n, wvh);
delete I;
}
+TEST_F(MDNodeTest, SelfReference) {
+ // !0 = !{!0}
+ // !1 = !{!0}
+ {
+ auto Temp = MDNode::getTemporary(Context, None);
+ Metadata *Args[] = {Temp.get()};
+ MDNode *Self = MDNode::get(Context, Args);
+ Self->replaceOperandWith(0, Self);
+ ASSERT_EQ(Self, Self->getOperand(0));
+
+ // Self-references should be distinct, so MDNode::get() should grab a
+ // uniqued node that references Self, not Self.
+ Args[0] = Self;
+ MDNode *Ref1 = MDNode::get(Context, Args);
+ MDNode *Ref2 = MDNode::get(Context, Args);
+ EXPECT_NE(Self, Ref1);
+ EXPECT_EQ(Ref1, Ref2);
+ }
+
+ // !0 = !{!0, !{}}
+ // !1 = !{!0, !{}}
+ {
+ auto Temp = MDNode::getTemporary(Context, None);
+ Metadata *Args[] = {Temp.get(), MDNode::get(Context, None)};
+ MDNode *Self = MDNode::get(Context, Args);
+ Self->replaceOperandWith(0, Self);
+ ASSERT_EQ(Self, Self->getOperand(0));
+
+ // Self-references should be distinct, so MDNode::get() should grab a
+ // uniqued node that references Self, not Self itself.
+ Args[0] = Self;
+ MDNode *Ref1 = MDNode::get(Context, Args);
+ MDNode *Ref2 = MDNode::get(Context, Args);
+ EXPECT_NE(Self, Ref1);
+ EXPECT_EQ(Ref1, Ref2);
+ }
+}
+
+TEST_F(MDNodeTest, Print) {
+ Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7);
+ MDString *S = MDString::get(Context, "foo");
+ MDNode *N0 = getNode();
+ MDNode *N1 = getNode(N0);
+ MDNode *N2 = getNode(N0, N1);
+
+ Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2};
+ MDNode *N = MDNode::get(Context, Args);
+
+ std::string Expected;
+ {
+ raw_string_ostream OS(Expected);
+ OS << "!{";
+ C->printAsOperand(OS);
+ OS << ", ";
+ S->printAsOperand(OS);
+ OS << ", null";
+ MDNode *Nodes[] = {N0, N1, N2};
+ for (auto *Node : Nodes)
+ OS << ", <" << (void *)Node << ">";
+ OS << "}";
+ }
+
+ std::string Actual;
+ {
+ raw_string_ostream OS(Actual);
+ N->print(OS);
+ }
+
+ EXPECT_EQ(Expected, Actual);
+}
+
+TEST_F(MDNodeTest, NullOperand) {
+ // metadata !{}
+ MDNode *Empty = MDNode::get(Context, None);
+
+ // metadata !{metadata !{}}
+ Metadata *Ops[] = {Empty};
+ MDNode *N = MDNode::get(Context, Ops);
+ ASSERT_EQ(Empty, N->getOperand(0));
+
+ // metadata !{metadata !{}} => metadata !{null}
+ N->replaceOperandWith(0, nullptr);
+ ASSERT_EQ(nullptr, N->getOperand(0));
+
+ // metadata !{null}
+ Ops[0] = nullptr;
+ MDNode *NullOp = MDNode::get(Context, Ops);
+ ASSERT_EQ(nullptr, NullOp->getOperand(0));
+ EXPECT_EQ(N, NullOp);
+}
+
+TEST_F(MDNodeTest, DistinctOnUniquingCollision) {
+ // !{}
+ MDNode *Empty = MDNode::get(Context, None);
+ ASSERT_TRUE(Empty->isResolved());
+ EXPECT_FALSE(Empty->isDistinct());
+
+ // !{!{}}
+ Metadata *Wrapped1Ops[] = {Empty};
+ MDNode *Wrapped1 = MDNode::get(Context, Wrapped1Ops);
+ ASSERT_EQ(Empty, Wrapped1->getOperand(0));
+ ASSERT_TRUE(Wrapped1->isResolved());
+ EXPECT_FALSE(Wrapped1->isDistinct());
+
+ // !{!{!{}}}
+ Metadata *Wrapped2Ops[] = {Wrapped1};
+ MDNode *Wrapped2 = MDNode::get(Context, Wrapped2Ops);
+ ASSERT_EQ(Wrapped1, Wrapped2->getOperand(0));
+ ASSERT_TRUE(Wrapped2->isResolved());
+ EXPECT_FALSE(Wrapped2->isDistinct());
+
+ // !{!{!{}}} => !{!{}}
+ Wrapped2->replaceOperandWith(0, Empty);
+ ASSERT_EQ(Empty, Wrapped2->getOperand(0));
+ EXPECT_TRUE(Wrapped2->isDistinct());
+ EXPECT_FALSE(Wrapped1->isDistinct());
+}
+
+TEST_F(MDNodeTest, getDistinct) {
+ // !{}
+ MDNode *Empty = MDNode::get(Context, None);
+ ASSERT_TRUE(Empty->isResolved());
+ ASSERT_FALSE(Empty->isDistinct());
+ ASSERT_EQ(Empty, MDNode::get(Context, None));
+
+ // distinct !{}
+ MDNode *Distinct1 = MDNode::getDistinct(Context, None);
+ MDNode *Distinct2 = MDNode::getDistinct(Context, None);
+ EXPECT_TRUE(Distinct1->isResolved());
+ EXPECT_TRUE(Distinct2->isDistinct());
+ EXPECT_NE(Empty, Distinct1);
+ EXPECT_NE(Empty, Distinct2);
+ EXPECT_NE(Distinct1, Distinct2);
+
+ // !{}
+ ASSERT_EQ(Empty, MDNode::get(Context, None));
+}
+
+TEST_F(MDNodeTest, isUniqued) {
+ MDNode *U = MDTuple::get(Context, None);
+ MDNode *D = MDTuple::getDistinct(Context, None);
+ auto T = MDTuple::getTemporary(Context, None);
+ EXPECT_TRUE(U->isUniqued());
+ EXPECT_FALSE(D->isUniqued());
+ EXPECT_FALSE(T->isUniqued());
+}
+
+TEST_F(MDNodeTest, isDistinct) {
+ MDNode *U = MDTuple::get(Context, None);
+ MDNode *D = MDTuple::getDistinct(Context, None);
+ auto T = MDTuple::getTemporary(Context, None);
+ EXPECT_FALSE(U->isDistinct());
+ EXPECT_TRUE(D->isDistinct());
+ EXPECT_FALSE(T->isDistinct());
+}
+
+TEST_F(MDNodeTest, isTemporary) {
+ MDNode *U = MDTuple::get(Context, None);
+ MDNode *D = MDTuple::getDistinct(Context, None);
+ auto T = MDTuple::getTemporary(Context, None);
+ EXPECT_FALSE(U->isTemporary());
+ EXPECT_FALSE(D->isTemporary());
+ EXPECT_TRUE(T->isTemporary());
+}
+
+TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) {
+ // temporary !{}
+ auto Temp = MDTuple::getTemporary(Context, None);
+ ASSERT_FALSE(Temp->isResolved());
+
+ // distinct !{temporary !{}}
+ Metadata *Ops[] = {Temp.get()};
+ MDNode *Distinct = MDNode::getDistinct(Context, Ops);
+ EXPECT_TRUE(Distinct->isResolved());
+ EXPECT_EQ(Temp.get(), Distinct->getOperand(0));
+
+ // temporary !{} => !{}
+ MDNode *Empty = MDNode::get(Context, None);
+ Temp->replaceAllUsesWith(Empty);
+ EXPECT_EQ(Empty, Distinct->getOperand(0));
+}
+
+TEST_F(MDNodeTest, handleChangedOperandRecursion) {
+ // !0 = !{}
+ MDNode *N0 = MDNode::get(Context, None);
+
+ // !1 = !{!3, null}
+ auto Temp3 = MDTuple::getTemporary(Context, None);
+ Metadata *Ops1[] = {Temp3.get(), nullptr};
+ MDNode *N1 = MDNode::get(Context, Ops1);
+
+ // !2 = !{!3, !0}
+ Metadata *Ops2[] = {Temp3.get(), N0};
+ MDNode *N2 = MDNode::get(Context, Ops2);
+
+ // !3 = !{!2}
+ Metadata *Ops3[] = {N2};
+ MDNode *N3 = MDNode::get(Context, Ops3);
+ Temp3->replaceAllUsesWith(N3);
+
+ // !4 = !{!1}
+ Metadata *Ops4[] = {N1};
+ MDNode *N4 = MDNode::get(Context, Ops4);
+
+ // Confirm that the cycle prevented RAUW from getting dropped.
+ EXPECT_TRUE(N0->isResolved());
+ EXPECT_FALSE(N1->isResolved());
+ EXPECT_FALSE(N2->isResolved());
+ EXPECT_FALSE(N3->isResolved());
+ EXPECT_FALSE(N4->isResolved());
+
+ // Create a couple of distinct nodes to observe what's going on.
+ //
+ // !5 = distinct !{!2}
+ // !6 = distinct !{!3}
+ Metadata *Ops5[] = {N2};
+ MDNode *N5 = MDNode::getDistinct(Context, Ops5);
+ Metadata *Ops6[] = {N3};
+ MDNode *N6 = MDNode::getDistinct(Context, Ops6);
+
+ // Mutate !2 to look like !1, causing a uniquing collision (and an RAUW).
+ // This will ripple up, with !3 colliding with !4, and RAUWing. Since !2
+ // references !3, this can cause a re-entry of handleChangedOperand() when !3
+ // is not ready for it.
+ //
+ // !2->replaceOperandWith(1, nullptr)
+ // !2: !{!3, !0} => !{!3, null}
+ // !2->replaceAllUsesWith(!1)
+ // !3: !{!2] => !{!1}
+ // !3->replaceAllUsesWith(!4)
+ N2->replaceOperandWith(1, nullptr);
+
+ // If all has gone well, N2 and N3 will have been RAUW'ed and deleted from
+ // under us. Just check that the other nodes are sane.
+ //
+ // !1 = !{!4, null}
+ // !4 = !{!1}
+ // !5 = distinct !{!1}
+ // !6 = distinct !{!4}
+ EXPECT_EQ(N4, N1->getOperand(0));
+ EXPECT_EQ(N1, N4->getOperand(0));
+ EXPECT_EQ(N1, N5->getOperand(0));
+ EXPECT_EQ(N4, N6->getOperand(0));
+}
+
+TEST_F(MDNodeTest, replaceResolvedOperand) {
+ // Check code for replacing one resolved operand with another. If doing this
+ // directly (via replaceOperandWith()) becomes illegal, change the operand to
+ // a global value that gets RAUW'ed.
+ //
+ // Use a temporary node to keep N from being resolved.
+ auto Temp = MDTuple::getTemporary(Context, None);
+ Metadata *Ops[] = {nullptr, Temp.get()};
+
+ MDNode *Empty = MDTuple::get(Context, ArrayRef<Metadata *>());
+ MDNode *N = MDTuple::get(Context, Ops);
+ EXPECT_EQ(nullptr, N->getOperand(0));
+ ASSERT_FALSE(N->isResolved());
+
+ // Check code for replacing resolved nodes.
+ N->replaceOperandWith(0, Empty);
+ EXPECT_EQ(Empty, N->getOperand(0));
+
+ // Check code for adding another unresolved operand.
+ N->replaceOperandWith(0, Temp.get());
+ EXPECT_EQ(Temp.get(), N->getOperand(0));
+
+ // Remove the references to Temp; required for teardown.
+ Temp->replaceAllUsesWith(nullptr);
+}
+
+TEST_F(MDNodeTest, replaceWithUniqued) {
+ auto *Empty = MDTuple::get(Context, None);
+ MDTuple *FirstUniqued;
+ {
+ Metadata *Ops[] = {Empty};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ EXPECT_TRUE(Temp->isTemporary());
+
+ // Don't expect a collision.
+ auto *Current = Temp.get();
+ FirstUniqued = MDNode::replaceWithUniqued(std::move(Temp));
+ EXPECT_TRUE(FirstUniqued->isUniqued());
+ EXPECT_TRUE(FirstUniqued->isResolved());
+ EXPECT_EQ(Current, FirstUniqued);
+ }
+ {
+ Metadata *Ops[] = {Empty};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ EXPECT_TRUE(Temp->isTemporary());
+
+ // Should collide with Uniqued above this time.
+ auto *Uniqued = MDNode::replaceWithUniqued(std::move(Temp));
+ EXPECT_TRUE(Uniqued->isUniqued());
+ EXPECT_TRUE(Uniqued->isResolved());
+ EXPECT_EQ(FirstUniqued, Uniqued);
+ }
+ {
+ auto Unresolved = MDTuple::getTemporary(Context, None);
+ Metadata *Ops[] = {Unresolved.get()};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ EXPECT_TRUE(Temp->isTemporary());
+
+ // Shouldn't be resolved.
+ auto *Uniqued = MDNode::replaceWithUniqued(std::move(Temp));
+ EXPECT_TRUE(Uniqued->isUniqued());
+ EXPECT_FALSE(Uniqued->isResolved());
+
+ // Should be a different node.
+ EXPECT_NE(FirstUniqued, Uniqued);
+
+ // Should resolve when we update its node (note: be careful to avoid a
+ // collision with any other nodes above).
+ Uniqued->replaceOperandWith(0, nullptr);
+ EXPECT_TRUE(Uniqued->isResolved());
+ }
+}
+
+TEST_F(MDNodeTest, replaceWithDistinct) {
+ {
+ auto *Empty = MDTuple::get(Context, None);
+ Metadata *Ops[] = {Empty};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ EXPECT_TRUE(Temp->isTemporary());
+
+ // Don't expect a collision.
+ auto *Current = Temp.get();
+ auto *Distinct = MDNode::replaceWithDistinct(std::move(Temp));
+ EXPECT_TRUE(Distinct->isDistinct());
+ EXPECT_TRUE(Distinct->isResolved());
+ EXPECT_EQ(Current, Distinct);
+ }
+ {
+ auto Unresolved = MDTuple::getTemporary(Context, None);
+ Metadata *Ops[] = {Unresolved.get()};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ EXPECT_TRUE(Temp->isTemporary());
+
+ // Don't expect a collision.
+ auto *Current = Temp.get();
+ auto *Distinct = MDNode::replaceWithDistinct(std::move(Temp));
+ EXPECT_TRUE(Distinct->isDistinct());
+ EXPECT_TRUE(Distinct->isResolved());
+ EXPECT_EQ(Current, Distinct);
+
+ // Cleanup; required for teardown.
+ Unresolved->replaceAllUsesWith(nullptr);
+ }
+}
+
+TEST_F(MDNodeTest, replaceWithPermanent) {
+ Metadata *Ops[] = {nullptr};
+ auto Temp = MDTuple::getTemporary(Context, Ops);
+ auto *T = Temp.get();
+
+ // U is a normal, uniqued node that references T.
+ auto *U = MDTuple::get(Context, T);
+ EXPECT_TRUE(U->isUniqued());
+
+ // Make Temp self-referencing.
+ Temp->replaceOperandWith(0, T);
+
+ // Try to uniquify Temp. This should, despite the name in the API, give a
+ // 'distinct' node, since self-references aren't allowed to be uniqued.
+ //
+ // Since it's distinct, N should have the same address as when it was a
+ // temporary (i.e., be equal to T not U).
+ auto *N = MDNode::replaceWithPermanent(std::move(Temp));
+ EXPECT_EQ(N, T);
+ EXPECT_TRUE(N->isDistinct());
+
+ // U should be the canonical unique node with N as the argument.
+ EXPECT_EQ(U, MDTuple::get(Context, N));
+ EXPECT_TRUE(U->isUniqued());
+
+ // This temporary should collide with U when replaced, but it should still be
+ // uniqued.
+ EXPECT_EQ(U, MDNode::replaceWithPermanent(MDTuple::getTemporary(Context, N)));
+ EXPECT_TRUE(U->isUniqued());
+
+ // This temporary should become a new uniqued node.
+ auto Temp2 = MDTuple::getTemporary(Context, U);
+ auto *V = Temp2.get();
+ EXPECT_EQ(V, MDNode::replaceWithPermanent(std::move(Temp2)));
+ EXPECT_TRUE(V->isUniqued());
+ EXPECT_EQ(U, V->getOperand(0));
+}
+
+TEST_F(MDNodeTest, deleteTemporaryWithTrackingRef) {
+ TrackingMDRef Ref;
+ EXPECT_EQ(nullptr, Ref.get());
+ {
+ auto Temp = MDTuple::getTemporary(Context, None);
+ Ref.reset(Temp.get());
+ EXPECT_EQ(Temp.get(), Ref.get());
+ }
+ EXPECT_EQ(nullptr, Ref.get());
+}
+
+typedef MetadataTest MDLocationTest;
+
+TEST_F(MDLocationTest, Overflow) {
+ MDNode *N = MDNode::get(Context, None);
+ {
+ MDLocation *L = MDLocation::get(Context, 2, 7, N);
+ EXPECT_EQ(2u, L->getLine());
+ EXPECT_EQ(7u, L->getColumn());
+ }
+ unsigned U16 = 1u << 16;
+ {
+ MDLocation *L = MDLocation::get(Context, UINT32_MAX, U16 - 1, N);
+ EXPECT_EQ(UINT32_MAX, L->getLine());
+ EXPECT_EQ(U16 - 1, L->getColumn());
+ }
+ {
+ MDLocation *L = MDLocation::get(Context, UINT32_MAX, U16, N);
+ EXPECT_EQ(UINT32_MAX, L->getLine());
+ EXPECT_EQ(0u, L->getColumn());
+ }
+ {
+ MDLocation *L = MDLocation::get(Context, UINT32_MAX, U16 + 1, N);
+ EXPECT_EQ(UINT32_MAX, L->getLine());
+ EXPECT_EQ(0u, L->getColumn());
+ }
+}
+
+TEST_F(MDLocationTest, getDistinct) {
+ MDNode *N = MDNode::get(Context, None);
+ MDLocation *L0 = MDLocation::getDistinct(Context, 2, 7, N);
+ EXPECT_TRUE(L0->isDistinct());
+ MDLocation *L1 = MDLocation::get(Context, 2, 7, N);
+ EXPECT_FALSE(L1->isDistinct());
+ EXPECT_EQ(L1, MDLocation::get(Context, 2, 7, N));
+}
+
+TEST_F(MDLocationTest, getTemporary) {
+ MDNode *N = MDNode::get(Context, None);
+ auto L = MDLocation::getTemporary(Context, 2, 7, N);
+ EXPECT_TRUE(L->isTemporary());
+ EXPECT_FALSE(L->isResolved());
+}
+
+typedef MetadataTest GenericDebugNodeTest;
+
+TEST_F(GenericDebugNodeTest, get) {
+ StringRef Header = "header";
+ auto *Empty = MDNode::get(Context, None);
+ Metadata *Ops1[] = {Empty};
+ auto *N = GenericDebugNode::get(Context, 15, Header, Ops1);
+ EXPECT_EQ(15u, N->getTag());
+ EXPECT_EQ(2u, N->getNumOperands());
+ EXPECT_EQ(Header, N->getHeader());
+ EXPECT_EQ(MDString::get(Context, Header), N->getOperand(0));
+ EXPECT_EQ(1u, N->getNumDwarfOperands());
+ EXPECT_EQ(Empty, N->getDwarfOperand(0));
+ EXPECT_EQ(Empty, N->getOperand(1));
+ ASSERT_TRUE(N->isUniqued());
+
+ EXPECT_EQ(N, GenericDebugNode::get(Context, 15, Header, Ops1));
+
+ N->replaceOperandWith(1, nullptr);
+ EXPECT_EQ(15u, N->getTag());
+ EXPECT_EQ(Header, N->getHeader());
+ EXPECT_EQ(nullptr, N->getDwarfOperand(0));
+ ASSERT_TRUE(N->isUniqued());
+
+ Metadata *Ops2[] = {nullptr};
+ EXPECT_EQ(N, GenericDebugNode::get(Context, 15, Header, Ops2));
+
+ N->replaceDwarfOperandWith(0, Empty);
+ EXPECT_EQ(15u, N->getTag());
+ EXPECT_EQ(Header, N->getHeader());
+ EXPECT_EQ(Empty, N->getDwarfOperand(0));
+ ASSERT_TRUE(N->isUniqued());
+ EXPECT_EQ(N, GenericDebugNode::get(Context, 15, Header, Ops1));
+
+ TempGenericDebugNode Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(GenericDebugNodeTest, getEmptyHeader) {
+ // Canonicalize !"" to null.
+ auto *N = GenericDebugNode::get(Context, 15, StringRef(), None);
+ EXPECT_EQ(StringRef(), N->getHeader());
+ EXPECT_EQ(nullptr, N->getOperand(0));
+}
+
+typedef MetadataTest MDSubrangeTest;
+
+TEST_F(MDSubrangeTest, get) {
+ auto *N = MDSubrange::get(Context, 5, 7);
+ EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
+ EXPECT_EQ(5, N->getCount());
+ EXPECT_EQ(7, N->getLo());
+ EXPECT_EQ(N, MDSubrange::get(Context, 5, 7));
+ EXPECT_EQ(MDSubrange::get(Context, 5, 0), MDSubrange::get(Context, 5));
+
+ TempMDSubrange Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDSubrangeTest, getEmptyArray) {
+ auto *N = MDSubrange::get(Context, -1, 0);
+ EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
+ EXPECT_EQ(-1, N->getCount());
+ EXPECT_EQ(0, N->getLo());
+ EXPECT_EQ(N, MDSubrange::get(Context, -1, 0));
+}
+
+typedef MetadataTest MDEnumeratorTest;
+
+TEST_F(MDEnumeratorTest, get) {
+ auto *N = MDEnumerator::get(Context, 7, "name");
+ EXPECT_EQ(dwarf::DW_TAG_enumerator, N->getTag());
+ EXPECT_EQ(7, N->getValue());
+ EXPECT_EQ("name", N->getName());
+ EXPECT_EQ(N, MDEnumerator::get(Context, 7, "name"));
+
+ EXPECT_NE(N, MDEnumerator::get(Context, 8, "name"));
+ EXPECT_NE(N, MDEnumerator::get(Context, 7, "nam"));
+
+ TempMDEnumerator Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDBasicTypeTest;
+
+TEST_F(MDBasicTypeTest, get) {
+ auto *N =
+ MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7);
+ EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag());
+ EXPECT_EQ("special", N->getName());
+ EXPECT_EQ(33u, N->getSizeInBits());
+ EXPECT_EQ(26u, N->getAlignInBits());
+ EXPECT_EQ(7u, N->getEncoding());
+ EXPECT_EQ(0u, N->getLine());
+ EXPECT_EQ(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 26, 7));
+
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
+ "special", 33, 26, 7));
+ EXPECT_NE(N,
+ MDBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7));
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
+ 26, 7));
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 25, 7));
+ EXPECT_NE(N, MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 26, 6));
+
+ TempMDBasicType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDBasicTypeTest, getWithLargeValues) {
+ auto *N = MDBasicType::get(Context, dwarf::DW_TAG_base_type, "special",
+ UINT64_MAX, UINT64_MAX - 1, 7);
+ EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
+ EXPECT_EQ(UINT64_MAX - 1, N->getAlignInBits());
+}
+
+typedef MetadataTest MDDerivedTypeTest;
+
+TEST_F(MDDerivedTypeTest, get) {
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ Metadata *ExtraData = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, BaseType, 2, 3, 4, 5, ExtraData);
+ EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag());
+ EXPECT_EQ("something", N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(1u, N->getLine());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(BaseType, N->getBaseType());
+ EXPECT_EQ(2u, N->getSizeInBits());
+ EXPECT_EQ(3u, N->getAlignInBits());
+ EXPECT_EQ(4u, N->getOffsetInBits());
+ EXPECT_EQ(5u, N->getFlags());
+ EXPECT_EQ(ExtraData, N->getExtraData());
+ EXPECT_EQ(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_reference_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else",
+ File, 1, Scope, BaseType, 2, 3, 4, 5,
+ ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", Scope, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 2, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N,
+ MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, File, BaseType, 2, 3, 4, 5, ExtraData));
+ EXPECT_NE(N,
+ MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, File, 2, 3, 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 3, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 2,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 5, 5, ExtraData));
+ EXPECT_NE(N, MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 4, ExtraData));
+ EXPECT_NE(N,
+ MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, BaseType, 2, 3, 4, 5, File));
+
+ TempMDDerivedType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDDerivedTypeTest, getWithLargeValues) {
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ Metadata *ExtraData = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something",
+ File, 1, Scope, BaseType, UINT64_MAX,
+ UINT64_MAX - 1, UINT64_MAX - 2, 5, ExtraData);
+ EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
+ EXPECT_EQ(UINT64_MAX - 1, N->getAlignInBits());
+ EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits());
+}
+
+typedef MetadataTest MDCompositeTypeTest;
+
+TEST_F(MDCompositeTypeTest, get) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 1;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ uint64_t SizeInBits = 2;
+ uint64_t AlignInBits = 3;
+ uint64_t OffsetInBits = 4;
+ unsigned Flags = 5;
+ Metadata *Elements = MDTuple::getDistinct(Context, None);
+ unsigned RuntimeLang = 6;
+ Metadata *VTableHolder = MDTuple::getDistinct(Context, None);
+ Metadata *TemplateParams = MDTuple::getDistinct(Context, None);
+ StringRef Identifier = "some id";
+
+ auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier);
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(BaseType, N->getBaseType());
+ EXPECT_EQ(SizeInBits, N->getSizeInBits());
+ EXPECT_EQ(AlignInBits, N->getAlignInBits());
+ EXPECT_EQ(OffsetInBits, N->getOffsetInBits());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(Elements, N->getElements());
+ EXPECT_EQ(RuntimeLang, N->getRuntimeLang());
+ EXPECT_EQ(VTableHolder, N->getVTableHolder());
+ EXPECT_EQ(TemplateParams, N->getTemplateParams());
+ EXPECT_EQ(Identifier, N->getIdentifier());
+
+ EXPECT_EQ(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag + 1, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, "abc", File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, Scope, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line + 1, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, File,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope, File,
+ SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Elements, RuntimeLang, VTableHolder,
+ TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits + 1, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits + 1,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags + 1, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, File, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ File, TemplateParams, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, File, Identifier));
+ EXPECT_NE(N, MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, "other"));
+
+ // Be sure that missing identifiers get null pointers.
+ EXPECT_FALSE(MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, "")->getRawIdentifier());
+ EXPECT_FALSE(MDCompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams)->getRawIdentifier());
+
+ TempMDCompositeType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDCompositeTypeTest, getWithLargeValues) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 1;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ uint64_t SizeInBits = UINT64_MAX;
+ uint64_t AlignInBits = UINT64_MAX - 1;
+ uint64_t OffsetInBits = UINT64_MAX - 2;
+ unsigned Flags = 5;
+ Metadata *Elements = MDTuple::getDistinct(Context, None);
+ unsigned RuntimeLang = 6;
+ Metadata *VTableHolder = MDTuple::getDistinct(Context, None);
+ Metadata *TemplateParams = MDTuple::getDistinct(Context, None);
+ StringRef Identifier = "some id";
+
+ auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier);
+ EXPECT_EQ(SizeInBits, N->getSizeInBits());
+ EXPECT_EQ(AlignInBits, N->getAlignInBits());
+ EXPECT_EQ(OffsetInBits, N->getOffsetInBits());
+}
+
+TEST_F(MDCompositeTypeTest, replaceOperands) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 1;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *BaseType = MDTuple::getDistinct(Context, None);
+ uint64_t SizeInBits = 2;
+ uint64_t AlignInBits = 3;
+ uint64_t OffsetInBits = 4;
+ unsigned Flags = 5;
+ unsigned RuntimeLang = 6;
+ StringRef Identifier = "some id";
+
+ auto *N = MDCompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, nullptr, RuntimeLang,
+ nullptr, nullptr, Identifier);
+
+ auto *Elements = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getElements());
+ N->replaceElements(Elements);
+ EXPECT_EQ(Elements, N->getElements());
+ N->replaceElements(nullptr);
+ EXPECT_EQ(nullptr, N->getElements());
+
+ auto *VTableHolder = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getVTableHolder());
+ N->replaceVTableHolder(VTableHolder);
+ EXPECT_EQ(VTableHolder, N->getVTableHolder());
+ N->replaceVTableHolder(nullptr);
+ EXPECT_EQ(nullptr, N->getVTableHolder());
+
+ auto *TemplateParams = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getTemplateParams());
+ N->replaceTemplateParams(TemplateParams);
+ EXPECT_EQ(TemplateParams, N->getTemplateParams());
+ N->replaceTemplateParams(nullptr);
+ EXPECT_EQ(nullptr, N->getTemplateParams());
+}
+
+typedef MetadataTest MDSubroutineTypeTest;
+
+TEST_F(MDSubroutineTypeTest, get) {
+ unsigned Flags = 1;
+ Metadata *TypeArray = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDSubroutineType::get(Context, Flags, TypeArray);
+ EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(TypeArray, N->getTypeArray());
+ EXPECT_EQ(N, MDSubroutineType::get(Context, Flags, TypeArray));
+
+ EXPECT_NE(N, MDSubroutineType::get(Context, Flags + 1, TypeArray));
+ EXPECT_NE(N, MDSubroutineType::get(Context, Flags,
+ MDTuple::getDistinct(Context, None)));
+
+ TempMDSubroutineType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+
+ // Test always-empty operands.
+ EXPECT_EQ(nullptr, N->getScope());
+ EXPECT_EQ(nullptr, N->getFile());
+ EXPECT_EQ("", N->getName());
+ EXPECT_EQ(nullptr, N->getBaseType());
+ EXPECT_EQ(nullptr, N->getVTableHolder());
+ EXPECT_EQ(nullptr, N->getTemplateParams());
+ EXPECT_EQ("", N->getIdentifier());
+}
+
+typedef MetadataTest MDFileTest;
+
+TEST_F(MDFileTest, get) {
+ StringRef Filename = "file";
+ StringRef Directory = "dir";
+ auto *N = MDFile::get(Context, Filename, Directory);
+
+ EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag());
+ EXPECT_EQ(Filename, N->getFilename());
+ EXPECT_EQ(Directory, N->getDirectory());
+ EXPECT_EQ(N, MDFile::get(Context, Filename, Directory));
+
+ EXPECT_NE(N, MDFile::get(Context, "other", Directory));
+ EXPECT_NE(N, MDFile::get(Context, Filename, "other"));
+
+ TempMDFile Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDCompileUnitTest;
+
+TEST_F(MDCompileUnitTest, get) {
+ unsigned SourceLanguage = 1;
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ StringRef Producer = "some producer";
+ bool IsOptimized = false;
+ StringRef Flags = "flag after flag";
+ unsigned RuntimeVersion = 2;
+ StringRef SplitDebugFilename = "another/file";
+ unsigned EmissionKind = 3;
+ Metadata *EnumTypes = MDTuple::getDistinct(Context, None);
+ Metadata *RetainedTypes = MDTuple::getDistinct(Context, None);
+ Metadata *Subprograms = MDTuple::getDistinct(Context, None);
+ Metadata *GlobalVariables = MDTuple::getDistinct(Context, None);
+ Metadata *ImportedEntities = MDTuple::getDistinct(Context, None);
+ auto *N = MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables, ImportedEntities);
+
+ EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag());
+ EXPECT_EQ(SourceLanguage, N->getSourceLanguage());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Producer, N->getProducer());
+ EXPECT_EQ(IsOptimized, N->isOptimized());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(RuntimeVersion, N->getRuntimeVersion());
+ EXPECT_EQ(SplitDebugFilename, N->getSplitDebugFilename());
+ EXPECT_EQ(EmissionKind, N->getEmissionKind());
+ EXPECT_EQ(EnumTypes, N->getEnumTypes());
+ EXPECT_EQ(RetainedTypes, N->getRetainedTypes());
+ EXPECT_EQ(Subprograms, N->getSubprograms());
+ EXPECT_EQ(GlobalVariables, N->getGlobalVariables());
+ EXPECT_EQ(ImportedEntities, N->getImportedEntities());
+ EXPECT_EQ(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage + 1, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, EnumTypes, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, "other",
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ !IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, "other", RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion + 1,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N,
+ MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion, "other",
+ EmissionKind, EnumTypes, RetainedTypes,
+ Subprograms, GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind + 1,
+ EnumTypes, RetainedTypes, Subprograms,
+ GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, File,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ File, Subprograms, GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, File, GlobalVariables, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, File, ImportedEntities));
+ EXPECT_NE(N, MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables, File));
+
+ TempMDCompileUnit Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDCompileUnitTest, replaceArrays) {
+ unsigned SourceLanguage = 1;
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ StringRef Producer = "some producer";
+ bool IsOptimized = false;
+ StringRef Flags = "flag after flag";
+ unsigned RuntimeVersion = 2;
+ StringRef SplitDebugFilename = "another/file";
+ unsigned EmissionKind = 3;
+ Metadata *EnumTypes = MDTuple::getDistinct(Context, None);
+ Metadata *RetainedTypes = MDTuple::getDistinct(Context, None);
+ Metadata *ImportedEntities = MDTuple::getDistinct(Context, None);
+ auto *N = MDCompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, nullptr, nullptr, ImportedEntities);
+
+ auto *Subprograms = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getSubprograms());
+ N->replaceSubprograms(Subprograms);
+ EXPECT_EQ(Subprograms, N->getSubprograms());
+ N->replaceSubprograms(nullptr);
+ EXPECT_EQ(nullptr, N->getSubprograms());
+
+ auto *GlobalVariables = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getGlobalVariables());
+ N->replaceGlobalVariables(GlobalVariables);
+ EXPECT_EQ(GlobalVariables, N->getGlobalVariables());
+ N->replaceGlobalVariables(nullptr);
+ EXPECT_EQ(nullptr, N->getGlobalVariables());
+}
+
+typedef MetadataTest MDSubprogramTest;
+
+TEST_F(MDSubprogramTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 2;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ unsigned ScopeLine = 3;
+ Metadata *ContainingType = MDTuple::getDistinct(Context, None);
+ unsigned Virtuality = 4;
+ unsigned VirtualIndex = 5;
+ unsigned Flags = 6;
+ bool IsOptimized = false;
+ Metadata *Function = MDTuple::getDistinct(Context, None);
+ Metadata *TemplateParams = MDTuple::getDistinct(Context, None);
+ Metadata *Declaration = MDTuple::getDistinct(Context, None);
+ Metadata *Variables = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDSubprogram::get(
+ Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags,
+ IsOptimized, Function, TemplateParams, Declaration, Variables);
+
+ EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(LinkageName, N->getLinkageName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
+ EXPECT_EQ(IsDefinition, N->isDefinition());
+ EXPECT_EQ(ScopeLine, N->getScopeLine());
+ EXPECT_EQ(ContainingType, N->getContainingType());
+ EXPECT_EQ(Virtuality, N->getVirtuality());
+ EXPECT_EQ(VirtualIndex, N->getVirtualIndex());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(IsOptimized, N->isOptimized());
+ EXPECT_EQ(Function, N->getFunction());
+ EXPECT_EQ(TemplateParams, N->getTemplateParams());
+ EXPECT_EQ(Declaration, N->getDeclaration());
+ EXPECT_EQ(Variables, N->getVariables());
+ EXPECT_EQ(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+
+ EXPECT_NE(N, MDSubprogram::get(Context, File, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, "other", LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, "other", File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, Scope, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File,
+ Line + 1, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Scope, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, !IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, !IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ ScopeLine + 1, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ Type, Virtuality, VirtualIndex, Flags,
+ IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality + 1, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex + 1,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ ~Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, !IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Type, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, Type,
+ Declaration, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Type, Variables));
+ EXPECT_NE(N, MDSubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Type));
+
+ TempMDSubprogram Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDSubprogramTest, replaceFunction) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 2;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ unsigned ScopeLine = 3;
+ Metadata *ContainingType = MDTuple::getDistinct(Context, None);
+ unsigned Virtuality = 4;
+ unsigned VirtualIndex = 5;
+ unsigned Flags = 6;
+ bool IsOptimized = false;
+ Metadata *TemplateParams = MDTuple::getDistinct(Context, None);
+ Metadata *Declaration = MDTuple::getDistinct(Context, None);
+ Metadata *Variables = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDSubprogram::get(
+ Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
+ IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags,
+ IsOptimized, nullptr, TemplateParams, Declaration, Variables);
+
+ EXPECT_EQ(nullptr, N->getFunction());
+
+ std::unique_ptr<Function> F(
+ Function::Create(FunctionType::get(Type::getVoidTy(Context), false),
+ GlobalValue::ExternalLinkage));
+ N->replaceFunction(F.get());
+ EXPECT_EQ(ConstantAsMetadata::get(F.get()), N->getFunction());
+
+ N->replaceFunction(nullptr);
+ EXPECT_EQ(nullptr, N->getFunction());
+}
+
+typedef MetadataTest MDLexicalBlockTest;
+
+TEST_F(MDLexicalBlockTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ unsigned Column = 8;
+
+ auto *N = MDLexicalBlock::get(Context, Scope, File, Line, Column);
+
+ EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Column, N->getColumn());
+ EXPECT_EQ(N, MDLexicalBlock::get(Context, Scope, File, Line, Column));
+
+ EXPECT_NE(N, MDLexicalBlock::get(Context, File, File, Line, Column));
+ EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, Scope, Line, Column));
+ EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line + 1, Column));
+ EXPECT_NE(N, MDLexicalBlock::get(Context, Scope, File, Line, Column + 1));
+
+ TempMDLexicalBlock Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDLexicalBlockFileTest;
+
+TEST_F(MDLexicalBlockFileTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Discriminator = 5;
+
+ auto *N = MDLexicalBlockFile::get(Context, Scope, File, Discriminator);
+
+ EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Discriminator, N->getDiscriminator());
+ EXPECT_EQ(N, MDLexicalBlockFile::get(Context, Scope, File, Discriminator));
+
+ EXPECT_NE(N, MDLexicalBlockFile::get(Context, File, File, Discriminator));
+ EXPECT_NE(N, MDLexicalBlockFile::get(Context, Scope, Scope, Discriminator));
+ EXPECT_NE(N,
+ MDLexicalBlockFile::get(Context, Scope, File, Discriminator + 1));
+
+ TempMDLexicalBlockFile Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDNamespaceTest;
+
+TEST_F(MDNamespaceTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ StringRef Name = "namespace";
+ unsigned Line = 5;
+
+ auto *N = MDNamespace::get(Context, Scope, File, Name, Line);
+
+ EXPECT_EQ(dwarf::DW_TAG_namespace, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(N, MDNamespace::get(Context, Scope, File, Name, Line));
+
+ EXPECT_NE(N, MDNamespace::get(Context, File, File, Name, Line));
+ EXPECT_NE(N, MDNamespace::get(Context, Scope, Scope, Name, Line));
+ EXPECT_NE(N, MDNamespace::get(Context, Scope, File, "other", Line));
+ EXPECT_NE(N, MDNamespace::get(Context, Scope, File, Name, Line + 1));
+
+ TempMDNamespace Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDTemplateTypeParameterTest;
+
+TEST_F(MDTemplateTypeParameterTest, get) {
+ StringRef Name = "template";
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ Metadata *Other = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDTemplateTypeParameter::get(Context, Name, Type);
+
+ EXPECT_EQ(dwarf::DW_TAG_template_type_parameter, N->getTag());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(N, MDTemplateTypeParameter::get(Context, Name, Type));
+
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, "other", Type));
+ EXPECT_NE(N, MDTemplateTypeParameter::get(Context, Name, Other));
+
+ TempMDTemplateTypeParameter Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDTemplateValueParameterTest;
+
+TEST_F(MDTemplateValueParameterTest, get) {
+ unsigned Tag = dwarf::DW_TAG_template_value_parameter;
+ StringRef Name = "template";
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ Metadata *Value = MDTuple::getDistinct(Context, None);
+ Metadata *Other = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDTemplateValueParameter::get(Context, Tag, Name, Type, Value);
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(Value, N->getValue());
+ EXPECT_EQ(N, MDTemplateValueParameter::get(Context, Tag, Name, Type, Value));
+
+ EXPECT_NE(N, MDTemplateValueParameter::get(
+ Context, dwarf::DW_TAG_GNU_template_template_param, Name,
+ Type, Value));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, "other", Type,
+ Value));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Name, Other,
+ Value));
+ EXPECT_NE(N, MDTemplateValueParameter::get(Context, Tag, Name, Type, Other));
+
+ TempMDTemplateValueParameter Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDGlobalVariableTest;
+
+TEST_F(MDGlobalVariableTest, get) {
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ Metadata *Variable = MDTuple::getDistinct(Context, None);
+ Metadata *StaticDataMemberDeclaration = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, Variable,
+ StaticDataMemberDeclaration);
+ EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(LinkageName, N->getLinkageName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
+ EXPECT_EQ(IsDefinition, N->isDefinition());
+ EXPECT_EQ(Variable, N->getVariable());
+ EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration());
+ EXPECT_EQ(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+
+ EXPECT_NE(N, MDGlobalVariable::get(Context, File, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, "other", LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, "other", File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, Scope,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line + 1, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Scope, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, !IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, !IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Type, StaticDataMemberDeclaration));
+ EXPECT_NE(N, MDGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, Type));
+
+ TempMDGlobalVariable Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDLocalVariableTest;
+
+TEST_F(MDLocalVariableTest, get) {
+ unsigned Tag = dwarf::DW_TAG_arg_variable;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ StringRef Name = "name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+ unsigned Arg = 6;
+ unsigned Flags = 7;
+ Metadata *InlinedAt = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags, InlinedAt);
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(Arg, N->getArg());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(InlinedAt, N->getInlinedAt());
+ EXPECT_EQ(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags, InlinedAt));
+
+ EXPECT_NE(N, MDLocalVariable::get(Context, dwarf::DW_TAG_auto_variable, Scope,
+ Name, File, Line, Type, Arg, Flags,
+ InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, File, Name, File, Line,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, "other", File, Line,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, Scope, Line,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line + 1,
+ Type, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line,
+ Scope, Arg, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg + 1, Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, ~Flags, InlinedAt));
+ EXPECT_NE(N, MDLocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags, Scope));
+
+ TempMDLocalVariable Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDExpressionTest;
+
+TEST_F(MDExpressionTest, get) {
+ uint64_t Elements[] = {2, 6, 9, 78, 0};
+ auto *N = MDExpression::get(Context, Elements);
+ EXPECT_EQ(makeArrayRef(Elements), N->getElements());
+ EXPECT_EQ(N, MDExpression::get(Context, Elements));
+
+ EXPECT_EQ(5u, N->getNumElements());
+ EXPECT_EQ(2u, N->getElement(0));
+ EXPECT_EQ(6u, N->getElement(1));
+ EXPECT_EQ(9u, N->getElement(2));
+ EXPECT_EQ(78u, N->getElement(3));
+ EXPECT_EQ(0u, N->getElement(4));
+
+ TempMDExpression Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(MDExpressionTest, isValid) {
+#define EXPECT_VALID(...) \
+ do { \
+ uint64_t Elements[] = {__VA_ARGS__}; \
+ EXPECT_TRUE(MDExpression::get(Context, Elements)->isValid()); \
+ } while (false)
+#define EXPECT_INVALID(...) \
+ do { \
+ uint64_t Elements[] = {__VA_ARGS__}; \
+ EXPECT_FALSE(MDExpression::get(Context, Elements)->isValid()); \
+ } while (false)
+
+ // Empty expression should be valid.
+ EXPECT_TRUE(MDExpression::get(Context, None));
+
+ // Valid constructions.
+ EXPECT_VALID(dwarf::DW_OP_plus, 6);
+ EXPECT_VALID(dwarf::DW_OP_deref);
+ EXPECT_VALID(dwarf::DW_OP_bit_piece, 3, 7);
+ EXPECT_VALID(dwarf::DW_OP_plus, 6, dwarf::DW_OP_deref);
+ EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus, 6);
+ EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_bit_piece, 3, 7);
+ EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus, 6, dwarf::DW_OP_bit_piece, 3, 7);
+
+ // Invalid constructions.
+ EXPECT_INVALID(~0u);
+ EXPECT_INVALID(dwarf::DW_OP_plus);
+ EXPECT_INVALID(dwarf::DW_OP_bit_piece);
+ EXPECT_INVALID(dwarf::DW_OP_bit_piece, 3);
+ EXPECT_INVALID(dwarf::DW_OP_bit_piece, 3, 7, dwarf::DW_OP_plus, 3);
+ EXPECT_INVALID(dwarf::DW_OP_bit_piece, 3, 7, dwarf::DW_OP_deref);
+
+#undef EXPECT_VALID
+#undef EXPECT_INVALID
+}
+
+typedef MetadataTest MDObjCPropertyTest;
+
+TEST_F(MDObjCPropertyTest, get) {
+ StringRef Name = "name";
+ Metadata *File = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ StringRef GetterName = "getter";
+ StringRef SetterName = "setter";
+ unsigned Attributes = 7;
+ Metadata *Type = MDTuple::getDistinct(Context, None);
+
+ auto *N = MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, Type);
+
+ EXPECT_EQ(dwarf::DW_TAG_APPLE_property, N->getTag());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(File, N->getFile());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(GetterName, N->getGetterName());
+ EXPECT_EQ(SetterName, N->getSetterName());
+ EXPECT_EQ(Attributes, N->getAttributes());
+ EXPECT_EQ(Type, N->getType());
+ EXPECT_EQ(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, Type));
+
+ EXPECT_NE(N, MDObjCProperty::get(Context, "other", File, Line, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, Type, Line, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line + 1, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, "other",
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ "other", Attributes, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes + 1, Type));
+ EXPECT_NE(N, MDObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, File));
+
+ TempMDObjCProperty Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MDImportedEntityTest;
+
+TEST_F(MDImportedEntityTest, get) {
+ unsigned Tag = dwarf::DW_TAG_imported_module;
+ Metadata *Scope = MDTuple::getDistinct(Context, None);
+ Metadata *Entity = MDTuple::getDistinct(Context, None);
+ unsigned Line = 5;
+ StringRef Name = "name";
+
+ auto *N = MDImportedEntity::get(Context, Tag, Scope, Entity, Line, Name);
+
+ EXPECT_EQ(Tag, N->getTag());
+ EXPECT_EQ(Scope, N->getScope());
+ EXPECT_EQ(Entity, N->getEntity());
+ EXPECT_EQ(Line, N->getLine());
+ EXPECT_EQ(Name, N->getName());
+ EXPECT_EQ(N, MDImportedEntity::get(Context, Tag, Scope, Entity, Line, Name));
+
+ EXPECT_NE(N,
+ MDImportedEntity::get(Context, dwarf::DW_TAG_imported_declaration,
+ Scope, Entity, Line, Name));
+ EXPECT_NE(N, MDImportedEntity::get(Context, Tag, Entity, Entity, Line, Name));
+ EXPECT_NE(N, MDImportedEntity::get(Context, Tag, Scope, Scope, Line, Name));
+ EXPECT_NE(N,
+ MDImportedEntity::get(Context, Tag, Scope, Entity, Line + 1, Name));
+ EXPECT_NE(N,
+ MDImportedEntity::get(Context, Tag, Scope, Entity, Line, "other"));
+
+ TempMDImportedEntity Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest MetadataAsValueTest;
+
+TEST_F(MetadataAsValueTest, MDNode) {
+ MDNode *N = MDNode::get(Context, None);
+ auto *V = MetadataAsValue::get(Context, N);
+ EXPECT_TRUE(V->getType()->isMetadataTy());
+ EXPECT_EQ(N, V->getMetadata());
+
+ auto *V2 = MetadataAsValue::get(Context, N);
+ EXPECT_EQ(V, V2);
+}
+
+TEST_F(MetadataAsValueTest, MDNodeMDNode) {
+ MDNode *N = MDNode::get(Context, None);
+ Metadata *Ops[] = {N};
+ MDNode *N2 = MDNode::get(Context, Ops);
+ auto *V = MetadataAsValue::get(Context, N2);
+ EXPECT_TRUE(V->getType()->isMetadataTy());
+ EXPECT_EQ(N2, V->getMetadata());
+
+ auto *V2 = MetadataAsValue::get(Context, N2);
+ EXPECT_EQ(V, V2);
+
+ auto *V3 = MetadataAsValue::get(Context, N);
+ EXPECT_TRUE(V3->getType()->isMetadataTy());
+ EXPECT_NE(V, V3);
+ EXPECT_EQ(N, V3->getMetadata());
+}
+
+TEST_F(MetadataAsValueTest, MDNodeConstant) {
+ auto *C = ConstantInt::getTrue(Context);
+ auto *MD = ConstantAsMetadata::get(C);
+ Metadata *Ops[] = {MD};
+ auto *N = MDNode::get(Context, Ops);
+
+ auto *V = MetadataAsValue::get(Context, MD);
+ EXPECT_TRUE(V->getType()->isMetadataTy());
+ EXPECT_EQ(MD, V->getMetadata());
+
+ auto *V2 = MetadataAsValue::get(Context, N);
+ EXPECT_EQ(MD, V2->getMetadata());
+ EXPECT_EQ(V, V2);
+}
+
+typedef MetadataTest ValueAsMetadataTest;
+
+TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) {
+ Type *Ty = Type::getInt1PtrTy(Context);
+ std::unique_ptr<GlobalVariable> GV0(
+ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ auto *MD = ValueAsMetadata::get(GV0.get());
+ EXPECT_TRUE(MD->getValue() == GV0.get());
+ ASSERT_TRUE(GV0->use_empty());
+
+ std::unique_ptr<GlobalVariable> GV1(
+ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ GV0->replaceAllUsesWith(GV1.get());
+ EXPECT_TRUE(MD->getValue() == GV1.get());
+}
+
+TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) {
+ // Create a constant.
+ ConstantAsMetadata *CI = ConstantAsMetadata::get(
+ ConstantInt::get(getGlobalContext(), APInt(8, 0)));
+
+ // Create a temporary to prevent nodes from resolving.
+ auto Temp = MDTuple::getTemporary(Context, None);
+
+ // When the first operand of N1 gets reset to nullptr, it'll collide with N2.
+ Metadata *Ops1[] = {CI, CI, Temp.get()};
+ Metadata *Ops2[] = {nullptr, CI, Temp.get()};
+
+ auto *N1 = MDTuple::get(Context, Ops1);
+ auto *N2 = MDTuple::get(Context, Ops2);
+ ASSERT_NE(N1, N2);
+
+ // Tell metadata that the constant is getting deleted.
+ //
+ // After this, N1 will be invalid, so don't touch it.
+ ValueAsMetadata::handleDeletion(CI->getValue());
+ EXPECT_EQ(nullptr, N2->getOperand(0));
+ EXPECT_EQ(nullptr, N2->getOperand(1));
+ EXPECT_EQ(Temp.get(), N2->getOperand(2));
+
+ // Clean up Temp for teardown.
+ Temp->replaceAllUsesWith(nullptr);
+}
+
+typedef MetadataTest TrackingMDRefTest;
+
+TEST_F(TrackingMDRefTest, UpdatesOnRAUW) {
+ Type *Ty = Type::getInt1PtrTy(Context);
+ std::unique_ptr<GlobalVariable> GV0(
+ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV0.get()));
+ EXPECT_TRUE(MD->getValue() == GV0.get());
+ ASSERT_TRUE(GV0->use_empty());
+
+ std::unique_ptr<GlobalVariable> GV1(
+ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ GV0->replaceAllUsesWith(GV1.get());
+ EXPECT_TRUE(MD->getValue() == GV1.get());
+
+ // Reset it, so we don't inadvertently test deletion.
+ MD.reset();
+}
+
+TEST_F(TrackingMDRefTest, UpdatesOnDeletion) {
+ Type *Ty = Type::getInt1PtrTy(Context);
+ std::unique_ptr<GlobalVariable> GV(
+ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV.get()));
+ EXPECT_TRUE(MD->getValue() == GV.get());
+ ASSERT_TRUE(GV->use_empty());
+
+ GV.reset();
+ EXPECT_TRUE(!MD);
+}
+
TEST(NamedMDNodeTest, Search) {
LLVMContext Context;
- Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1);
- Constant *C2 = ConstantInt::get(Type::getInt32Ty(Context), 2);
+ ConstantAsMetadata *C =
+ ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 1));
+ ConstantAsMetadata *C2 =
+ ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 2));
- Value *const V = C;
- Value *const V2 = C2;
+ Metadata *const V = C;
+ Metadata *const V2 = C2;
MDNode *n = MDNode::get(Context, V);
MDNode *n2 = MDNode::get(Context, V2);
diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp
index d493156..41af0b0 100644
--- a/unittests/IR/PassManagerTest.cpp
+++ b/unittests/IR/PassManagerTest.cpp
@@ -29,13 +29,16 @@ public:
/// \brief Returns an opaque, unique ID for this pass type.
static void *ID() { return (void *)&PassID; }
+ /// \brief Returns the name of the analysis.
+ static StringRef name() { return "TestFunctionAnalysis"; }
+
TestFunctionAnalysis(int &Runs) : Runs(Runs) {}
/// \brief Run the analysis pass over the function and return a result.
- Result run(Function *F, FunctionAnalysisManager *AM) {
+ Result run(Function &F, FunctionAnalysisManager *AM) {
++Runs;
int Count = 0;
- for (Function::iterator BBI = F->begin(), BBE = F->end(); BBI != BBE; ++BBI)
+ for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
++II)
++Count;
@@ -60,12 +63,14 @@ public:
static void *ID() { return (void *)&PassID; }
+ static StringRef name() { return "TestModuleAnalysis"; }
+
TestModuleAnalysis(int &Runs) : Runs(Runs) {}
- Result run(Module *M, ModuleAnalysisManager *AM) {
+ Result run(Module &M, ModuleAnalysisManager *AM) {
++Runs;
int Count = 0;
- for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
++Count;
return Result(Count);
}
@@ -81,7 +86,7 @@ char TestModuleAnalysis::PassID;
struct TestModulePass {
TestModulePass(int &RunCount) : RunCount(RunCount) {}
- PreservedAnalyses run(Module *M) {
+ PreservedAnalyses run(Module &M) {
++RunCount;
return PreservedAnalyses::none();
}
@@ -92,13 +97,13 @@ struct TestModulePass {
};
struct TestPreservingModulePass {
- PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); }
+ PreservedAnalyses run(Module &M) { return PreservedAnalyses::all(); }
static StringRef name() { return "TestPreservingModulePass"; }
};
struct TestMinPreservingModulePass {
- PreservedAnalyses run(Module *M, ModuleAnalysisManager *AM) {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM) {
PreservedAnalyses PA;
// Force running an analysis.
@@ -119,13 +124,13 @@ struct TestFunctionPass {
AnalyzedFunctionCount(AnalyzedFunctionCount),
OnlyUseCachedResults(OnlyUseCachedResults) {}
- PreservedAnalyses run(Function *F, FunctionAnalysisManager *AM) {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager *AM) {
++RunCount;
const ModuleAnalysisManager &MAM =
AM->getResult<ModuleAnalysisManagerFunctionProxy>(F).getManager();
if (TestModuleAnalysis::Result *TMA =
- MAM.getCachedResult<TestModuleAnalysis>(F->getParent()))
+ MAM.getCachedResult<TestModuleAnalysis>(*F.getParent()))
AnalyzedFunctionCount += TMA->FunctionCount;
if (OnlyUseCachedResults) {
@@ -155,9 +160,9 @@ struct TestFunctionPass {
struct TestInvalidationFunctionPass {
TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}
- PreservedAnalyses run(Function *F) {
- return F->getName() == Name ? PreservedAnalyses::none()
- : PreservedAnalyses::all();
+ PreservedAnalyses run(Function &F) {
+ return F.getName() == Name ? PreservedAnalyses::none()
+ : PreservedAnalyses::all();
}
static StringRef name() { return "TestInvalidationFunctionPass"; }
@@ -165,10 +170,10 @@ struct TestInvalidationFunctionPass {
StringRef Name;
};
-Module *parseIR(const char *IR) {
+std::unique_ptr<Module> parseIR(const char *IR) {
LLVMContext &C = getGlobalContext();
SMDiagnostic Err;
- return parseAssemblyString(IR, Err, C).release();
+ return parseAssemblyString(IR, Err, C);
}
class PassManagerTest : public ::testing::Test {
@@ -310,7 +315,7 @@ TEST_F(PassManagerTest, Basic) {
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
}
- MPM.run(M.get(), &MAM);
+ MPM.run(*M, &MAM);
// Validate module pass counters.
EXPECT_EQ(1, ModulePassRunCount);
diff --git a/unittests/IR/UseTest.cpp b/unittests/IR/UseTest.cpp
index 3f33ca6..d9d20af 100644
--- a/unittests/IR/UseTest.cpp
+++ b/unittests/IR/UseTest.cpp
@@ -9,10 +9,10 @@
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.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"
@@ -50,7 +50,7 @@ TEST(UseTest, sort) {
});
unsigned I = 0;
for (User *U : X.users()) {
- snprintf(vnbuf, sizeof(vnbuf), "v%u", I++);
+ format("v%u", I++).snprint(vnbuf, sizeof(vnbuf));
EXPECT_EQ(vnbuf, U->getName());
}
ASSERT_EQ(8u, I);
@@ -60,7 +60,7 @@ TEST(UseTest, sort) {
});
I = 0;
for (User *U : X.users()) {
- snprintf(vnbuf, sizeof(vnbuf), "v%u", (7 - I++));
+ format("v%u", (7 - I++)).snprint(vnbuf, sizeof(vnbuf));
EXPECT_EQ(vnbuf, U->getName());
}
ASSERT_EQ(8u, I);
@@ -95,7 +95,7 @@ TEST(UseTest, reverse) {
});
unsigned I = 0;
for (User *U : X.users()) {
- snprintf(vnbuf, sizeof(vnbuf), "v%u", I++);
+ format("v%u", I++).snprint(vnbuf, sizeof(vnbuf));
EXPECT_EQ(vnbuf, U->getName());
}
ASSERT_EQ(8u, I);
@@ -103,7 +103,7 @@ TEST(UseTest, reverse) {
X.reverseUseList();
I = 0;
for (User *U : X.users()) {
- snprintf(vnbuf, sizeof(vnbuf), "v%u", (7 - I++));
+ format("v%u", (7 - I++)).snprint(vnbuf, sizeof(vnbuf));
EXPECT_EQ(vnbuf, U->getName());
}
ASSERT_EQ(8u, I);
diff --git a/unittests/IR/UserTest.cpp b/unittests/IR/UserTest.cpp
index 5572424..56b054b 100644
--- a/unittests/IR/UserTest.cpp
+++ b/unittests/IR/UserTest.cpp
@@ -9,10 +9,10 @@
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/User.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
using namespace llvm;
diff --git a/unittests/IR/WaymarkTest.cpp b/unittests/IR/WaymarkTest.cpp
index 8e3cd45..a8924ef 100644
--- a/unittests/IR/WaymarkTest.cpp
+++ b/unittests/IR/WaymarkTest.cpp
@@ -29,8 +29,9 @@ TEST(WaymarkTest, NativeArray) {
Value * values[22];
std::transform(tail, tail + 22, values, char2constant);
FunctionType *FT = FunctionType::get(Type::getVoidTy(getGlobalContext()), true);
- Function *F = Function::Create(FT, GlobalValue::ExternalLinkage);
- const CallInst *A = CallInst::Create(F, makeArrayRef(values));
+ std::unique_ptr<Function> F(
+ Function::Create(FT, GlobalValue::ExternalLinkage));
+ const CallInst *A = CallInst::Create(F.get(), makeArrayRef(values));
ASSERT_NE(A, (const CallInst*)nullptr);
ASSERT_EQ(1U + 22, A->getNumOperands());
const Use *U = &A->getOperandUse(0);
diff --git a/unittests/Linker/LinkModulesTest.cpp b/unittests/Linker/LinkModulesTest.cpp
index b15d180..91f97d7 100644
--- a/unittests/Linker/LinkModulesTest.cpp
+++ b/unittests/Linker/LinkModulesTest.cpp
@@ -8,12 +8,12 @@
//===----------------------------------------------------------------------===//
#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/Linker/Linker.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
diff --git a/unittests/MC/CMakeLists.txt b/unittests/MC/CMakeLists.txt
index c82bcde..f83eaf4 100644
--- a/unittests/MC/CMakeLists.txt
+++ b/unittests/MC/CMakeLists.txt
@@ -10,9 +10,3 @@ add_llvm_unittest(MCTests
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/Hexagon/CMakeLists.txt b/unittests/MC/Hexagon/CMakeLists.txt
deleted file mode 100644
index 6d4ee93..0000000
--- a/unittests/MC/Hexagon/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-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
deleted file mode 100644
index 958a21f..0000000
--- a/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#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/StringTableBuilderTest.cpp b/unittests/MC/StringTableBuilderTest.cpp
index 6b5185c..716b9c7 100644
--- a/unittests/MC/StringTableBuilderTest.cpp
+++ b/unittests/MC/StringTableBuilderTest.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/StringTableBuilder.h"
-#include "gtest/gtest.h"
#include "llvm/Support/Endian.h"
+#include "gtest/gtest.h"
#include <string>
using namespace llvm;
diff --git a/unittests/Makefile b/unittests/Makefile
index 603e7d5..fefef07 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -10,7 +10,7 @@
LEVEL = ..
PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo ExecutionEngine IR \
- LineEditor Linker MC Option Support Transforms
+ LineEditor Linker MC Option ProfileData Support Transforms
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/ProfileData/CMakeLists.txt b/unittests/ProfileData/CMakeLists.txt
new file mode 100644
index 0000000..79137c9
--- /dev/null
+++ b/unittests/ProfileData/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+ Core
+ ProfileData
+ Support
+ )
+
+add_llvm_unittest(ProfileDataTests
+ CoverageMappingTest.cpp
+ InstrProfTest.cpp
+ )
diff --git a/unittests/ProfileData/CoverageMappingTest.cpp b/unittests/ProfileData/CoverageMappingTest.cpp
new file mode 100644
index 0000000..9fceacb
--- /dev/null
+++ b/unittests/ProfileData/CoverageMappingTest.cpp
@@ -0,0 +1,262 @@
+//===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ProfileData/CoverageMapping.h"
+#include "llvm/ProfileData/CoverageMappingReader.h"
+#include "llvm/ProfileData/CoverageMappingWriter.h"
+#include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/ProfileData/InstrProfWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+#include <sstream>
+
+using namespace llvm;
+using namespace coverage;
+
+static ::testing::AssertionResult NoError(std::error_code EC) {
+ if (!EC)
+ return ::testing::AssertionSuccess();
+ return ::testing::AssertionFailure() << "error " << EC.value()
+ << ": " << EC.message();
+}
+
+namespace llvm {
+namespace coverage {
+void PrintTo(const Counter &C, ::std::ostream *os) {
+ if (C.isZero())
+ *os << "Zero";
+ else if (C.isExpression())
+ *os << "Expression " << C.getExpressionID();
+ else
+ *os << "Counter " << C.getCounterID();
+}
+
+void PrintTo(const CoverageSegment &S, ::std::ostream *os) {
+ *os << "CoverageSegment(" << S.Line << ", " << S.Col << ", ";
+ if (S.HasCount)
+ *os << S.Count << ", ";
+ *os << (S.IsRegionEntry ? "true" : "false") << ")";
+}
+}
+}
+
+namespace {
+
+struct OneFunctionCoverageReader : CoverageMappingReader {
+ StringRef Name;
+ uint64_t Hash;
+ std::vector<StringRef> Filenames;
+ ArrayRef<CounterMappingRegion> Regions;
+ bool Done;
+
+ OneFunctionCoverageReader(StringRef Name, uint64_t Hash,
+ ArrayRef<StringRef> Filenames,
+ ArrayRef<CounterMappingRegion> Regions)
+ : Name(Name), Hash(Hash), Filenames(Filenames), Regions(Regions),
+ Done(false) {}
+
+ std::error_code readNextRecord(CoverageMappingRecord &Record) override {
+ if (Done)
+ return instrprof_error::eof;
+ Done = true;
+
+ Record.FunctionName = Name;
+ Record.FunctionHash = Hash;
+ Record.Filenames = Filenames;
+ Record.Expressions = {};
+ Record.MappingRegions = Regions;
+ return instrprof_error::success;
+ }
+};
+
+struct CoverageMappingTest : ::testing::Test {
+ StringMap<unsigned> Files;
+ unsigned NextFile;
+ std::vector<CounterMappingRegion> InputCMRs;
+
+ std::vector<StringRef> OutputFiles;
+ std::vector<CounterExpression> OutputExpressions;
+ std::vector<CounterMappingRegion> OutputCMRs;
+
+ InstrProfWriter ProfileWriter;
+ std::unique_ptr<IndexedInstrProfReader> ProfileReader;
+
+ std::unique_ptr<CoverageMapping> LoadedCoverage;
+
+ void SetUp() override {
+ NextFile = 0;
+ }
+
+ unsigned getFile(StringRef Name) {
+ auto R = Files.find(Name);
+ if (R != Files.end())
+ return R->second;
+ Files[Name] = NextFile;
+ return NextFile++;
+ }
+
+ void addCMR(Counter C, StringRef File, unsigned LS, unsigned CS, unsigned LE,
+ unsigned CE) {
+ InputCMRs.push_back(
+ CounterMappingRegion::makeRegion(C, getFile(File), LS, CS, LE, CE));
+ }
+
+ void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS,
+ unsigned CS, unsigned LE, unsigned CE) {
+ InputCMRs.push_back(CounterMappingRegion::makeExpansion(
+ getFile(File), getFile(ExpandedFile), LS, CS, LE, CE));
+ }
+
+ std::string writeCoverageRegions() {
+ SmallVector<unsigned, 8> FileIDs;
+ for (const auto &E : Files)
+ FileIDs.push_back(E.getValue());
+ std::string Coverage;
+ llvm::raw_string_ostream OS(Coverage);
+ CoverageMappingWriter(FileIDs, None, InputCMRs).write(OS);
+ return OS.str();
+ }
+
+ void readCoverageRegions(std::string Coverage) {
+ SmallVector<StringRef, 8> Filenames;
+ for (const auto &E : Files)
+ Filenames.push_back(E.getKey());
+ RawCoverageMappingReader Reader(Coverage, Filenames, OutputFiles,
+ OutputExpressions, OutputCMRs);
+ ASSERT_TRUE(NoError(Reader.read()));
+ }
+
+ void readProfCounts() {
+ auto Profile = ProfileWriter.writeBuffer();
+ auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
+ ASSERT_TRUE(NoError(ReaderOrErr.getError()));
+ ProfileReader = std::move(ReaderOrErr.get());
+ }
+
+ void loadCoverageMapping(StringRef FuncName, uint64_t Hash) {
+ std::string Regions = writeCoverageRegions();
+ readCoverageRegions(Regions);
+
+ SmallVector<StringRef, 8> Filenames;
+ for (const auto &E : Files)
+ Filenames.push_back(E.getKey());
+ OneFunctionCoverageReader CovReader(FuncName, Hash, Filenames, OutputCMRs);
+ auto CoverageOrErr = CoverageMapping::load(CovReader, *ProfileReader);
+ ASSERT_TRUE(NoError(CoverageOrErr.getError()));
+ LoadedCoverage = std::move(CoverageOrErr.get());
+ }
+};
+
+TEST_F(CoverageMappingTest, basic_write_read) {
+ addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1);
+ addCMR(Counter::getCounter(1), "foo", 2, 1, 2, 2);
+ addCMR(Counter::getZero(), "foo", 3, 1, 3, 4);
+ addCMR(Counter::getCounter(2), "foo", 4, 1, 4, 8);
+ addCMR(Counter::getCounter(3), "bar", 1, 2, 3, 4);
+ std::string Coverage = writeCoverageRegions();
+ readCoverageRegions(Coverage);
+
+ size_t N = makeArrayRef(InputCMRs).size();
+ ASSERT_EQ(N, OutputCMRs.size());
+ for (size_t I = 0; I < N; ++I) {
+ ASSERT_EQ(InputCMRs[I].Count, OutputCMRs[I].Count);
+ ASSERT_EQ(InputCMRs[I].FileID, OutputCMRs[I].FileID);
+ ASSERT_EQ(InputCMRs[I].startLoc(), OutputCMRs[I].startLoc());
+ ASSERT_EQ(InputCMRs[I].endLoc(), OutputCMRs[I].endLoc());
+ ASSERT_EQ(InputCMRs[I].Kind, OutputCMRs[I].Kind);
+ }
+}
+
+TEST_F(CoverageMappingTest, expansion_gets_first_counter) {
+ addCMR(Counter::getCounter(1), "foo", 10, 1, 10, 2);
+ // This starts earlier in "foo", so the expansion should get its counter.
+ addCMR(Counter::getCounter(2), "foo", 1, 1, 20, 1);
+ addExpansionCMR("bar", "foo", 3, 3, 3, 3);
+ std::string Coverage = writeCoverageRegions();
+ readCoverageRegions(Coverage);
+
+ ASSERT_EQ(CounterMappingRegion::ExpansionRegion, OutputCMRs[2].Kind);
+ ASSERT_EQ(Counter::getCounter(2), OutputCMRs[2].Count);
+ ASSERT_EQ(3U, OutputCMRs[2].LineStart);
+}
+
+TEST_F(CoverageMappingTest, basic_coverage_iteration) {
+ ProfileWriter.addFunctionCounts("func", 0x1234, {30, 20, 10, 0});
+ readProfCounts();
+
+ addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
+ addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
+ addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
+ addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
+ loadCoverageMapping("func", 0x1234);
+
+ CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
+ std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
+ ASSERT_EQ(7U, Segments.size());
+ ASSERT_EQ(CoverageSegment(1, 1, 20, true), Segments[0]);
+ ASSERT_EQ(CoverageSegment(4, 7, 30, false), Segments[1]);
+ ASSERT_EQ(CoverageSegment(5, 8, 10, true), Segments[2]);
+ ASSERT_EQ(CoverageSegment(9, 1, 30, false), Segments[3]);
+ ASSERT_EQ(CoverageSegment(9, 9, false), Segments[4]);
+ ASSERT_EQ(CoverageSegment(10, 10, 0, true), Segments[5]);
+ ASSERT_EQ(CoverageSegment(11, 11, false), Segments[6]);
+}
+
+TEST_F(CoverageMappingTest, uncovered_function) {
+ readProfCounts();
+
+ addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
+ loadCoverageMapping("func", 0x1234);
+
+ CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
+ std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
+ ASSERT_EQ(2U, Segments.size());
+ ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]);
+ ASSERT_EQ(CoverageSegment(3, 4, false), Segments[1]);
+}
+
+TEST_F(CoverageMappingTest, combine_regions) {
+ ProfileWriter.addFunctionCounts("func", 0x1234, {10, 20, 30});
+ readProfCounts();
+
+ addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
+ addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
+ addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
+ loadCoverageMapping("func", 0x1234);
+
+ CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
+ std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
+ ASSERT_EQ(4U, Segments.size());
+ ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
+ ASSERT_EQ(CoverageSegment(3, 3, 50, true), Segments[1]);
+ ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
+ ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
+}
+
+TEST_F(CoverageMappingTest, dont_combine_expansions) {
+ ProfileWriter.addFunctionCounts("func", 0x1234, {10, 20});
+ readProfCounts();
+
+ addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
+ addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
+ addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7);
+ addExpansionCMR("file1", "include1", 3, 3, 4, 4);
+ loadCoverageMapping("func", 0x1234);
+
+ CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
+ std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
+ ASSERT_EQ(4U, Segments.size());
+ ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
+ ASSERT_EQ(CoverageSegment(3, 3, 20, true), Segments[1]);
+ ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
+ ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
+}
+
+} // end anonymous namespace
diff --git a/unittests/ProfileData/InstrProfTest.cpp b/unittests/ProfileData/InstrProfTest.cpp
new file mode 100644
index 0000000..26ea0e4
--- /dev/null
+++ b/unittests/ProfileData/InstrProfTest.cpp
@@ -0,0 +1,98 @@
+//===- unittest/ProfileData/InstrProfTest.cpp -------------------------------=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/ProfileData/InstrProfWriter.h"
+#include "gtest/gtest.h"
+
+#include <cstdarg>
+
+using namespace llvm;
+
+static ::testing::AssertionResult NoError(std::error_code EC) {
+ if (!EC)
+ return ::testing::AssertionSuccess();
+ return ::testing::AssertionFailure() << "error " << EC.value()
+ << ": " << EC.message();
+}
+
+static ::testing::AssertionResult ErrorEquals(std::error_code Expected,
+ std::error_code Found) {
+ if (Expected == Found)
+ return ::testing::AssertionSuccess();
+ return ::testing::AssertionFailure() << "error " << Found.value()
+ << ": " << Found.message();
+}
+
+namespace {
+
+struct InstrProfTest : ::testing::Test {
+ InstrProfWriter Writer;
+ std::unique_ptr<IndexedInstrProfReader> Reader;
+
+ void readProfile(std::unique_ptr<MemoryBuffer> Profile) {
+ auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
+ ASSERT_TRUE(NoError(ReaderOrErr.getError()));
+ Reader = std::move(ReaderOrErr.get());
+ }
+};
+
+TEST_F(InstrProfTest, write_and_read_empty_profile) {
+ auto Profile = Writer.writeBuffer();
+ readProfile(std::move(Profile));
+ ASSERT_TRUE(Reader->begin() == Reader->end());
+}
+
+TEST_F(InstrProfTest, write_and_read_one_function) {
+ Writer.addFunctionCounts("foo", 0x1234, {1, 2, 3, 4});
+ auto Profile = Writer.writeBuffer();
+ readProfile(std::move(Profile));
+
+ auto I = Reader->begin(), E = Reader->end();
+ ASSERT_TRUE(I != E);
+ ASSERT_EQ(StringRef("foo"), I->Name);
+ ASSERT_EQ(0x1234U, I->Hash);
+ ASSERT_EQ(4U, I->Counts.size());
+ ASSERT_EQ(1U, I->Counts[0]);
+ ASSERT_EQ(2U, I->Counts[1]);
+ ASSERT_EQ(3U, I->Counts[2]);
+ ASSERT_EQ(4U, I->Counts[3]);
+ ASSERT_TRUE(++I == E);
+}
+
+TEST_F(InstrProfTest, get_function_counts) {
+ Writer.addFunctionCounts("foo", 0x1234, {1, 2});
+ auto Profile = Writer.writeBuffer();
+ readProfile(std::move(Profile));
+
+ std::vector<uint64_t> Counts;
+ ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
+ ASSERT_EQ(2U, Counts.size());
+ ASSERT_EQ(1U, Counts[0]);
+ ASSERT_EQ(2U, Counts[1]);
+
+ std::error_code EC;
+ EC = Reader->getFunctionCounts("foo", 0x5678, Counts);
+ ASSERT_TRUE(ErrorEquals(instrprof_error::hash_mismatch, EC));
+
+ EC = Reader->getFunctionCounts("bar", 0x1234, Counts);
+ ASSERT_TRUE(ErrorEquals(instrprof_error::unknown_function, EC));
+}
+
+TEST_F(InstrProfTest, get_max_function_count) {
+ Writer.addFunctionCounts("foo", 0x1234, {1ULL << 31, 2});
+ Writer.addFunctionCounts("bar", 0, {1ULL << 63});
+ Writer.addFunctionCounts("baz", 0x5678, {0, 0, 0, 0});
+ auto Profile = Writer.writeBuffer();
+ readProfile(std::move(Profile));
+
+ ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
+}
+
+} // end anonymous namespace
diff --git a/unittests/ProfileData/Makefile b/unittests/ProfileData/Makefile
new file mode 100644
index 0000000..d017c15
--- /dev/null
+++ b/unittests/ProfileData/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/ProfileData/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 = ProfileData
+LINK_COMPONENTS := ProfileData Core Support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Support/AlignOfTest.cpp b/unittests/Support/AlignOfTest.cpp
index 40f7295..1119019 100644
--- a/unittests/Support/AlignOfTest.cpp
+++ b/unittests/Support/AlignOfTest.cpp
@@ -22,13 +22,13 @@ namespace {
// Suppress direct base '{anonymous}::S1' inaccessible in '{anonymous}::D9'
// due to ambiguity warning.
-//
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Winaccessible-base"
+#elif ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
// Pragma based warning suppression was introduced in GGC 4.2. Additionally
// this warning is "enabled by default". The warning still appears if -Wall is
// suppressed. Apparently GCC suppresses it when -w is specifed, which is odd.
-// At any rate, clang on the other hand gripes about -Wunknown-pragma, so
-// leaving it out of this.
-#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402 && !defined(__clang__)
#pragma GCC diagnostic warning "-w"
#endif
diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp
index f6e3537..0eac8bb 100644
--- a/unittests/Support/BlockFrequencyTest.cpp
+++ b/unittests/Support/BlockFrequencyTest.cpp
@@ -1,3 +1,12 @@
+//===- unittests/Support/BlockFrequencyTest.cpp - BlockFrequency tests ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/DataTypes.h"
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index 7abdd8a..f3b55c3 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -13,6 +13,8 @@ add_llvm_unittest(SupportTests
CompressionTest.cpp
ConvertUTFTest.cpp
DataExtractorTest.cpp
+ DwarfTest.cpp
+ EndianStreamTest.cpp
EndianTest.cpp
ErrorOrTest.cpp
FileOutputBufferTest.cpp
@@ -32,6 +34,7 @@ add_llvm_unittest(SupportTests
ScaledNumberTest.cpp
SourceMgrTest.cpp
SpecialCaseListTest.cpp
+ StreamingMemoryObject.cpp
StringPool.cpp
SwapByteOrderTest.cpp
ThreadLocalTest.cpp
diff --git a/unittests/Support/Casting.cpp b/unittests/Support/Casting.cpp
index 88c7d19..e6c35fc 100644
--- a/unittests/Support/Casting.cpp
+++ b/unittests/Support/Casting.cpp
@@ -232,3 +232,99 @@ namespace TemporaryCast {
struct pod {};
IllegalCast *testIllegalCast() { return cast<foo>(pod()); }
}
+
+namespace {
+namespace pointer_wrappers {
+
+struct Base {
+ bool IsDerived;
+ Base(bool IsDerived = false) : IsDerived(IsDerived) {}
+};
+
+struct Derived : Base {
+ Derived() : Base(true) {}
+ static bool classof(const Base *B) { return B->IsDerived; }
+};
+
+class PTy {
+ Base *B;
+public:
+ PTy(Base *B) : B(B) {}
+ explicit operator bool() const { return get(); }
+ Base *get() const { return B; }
+};
+
+} // end namespace pointer_wrappers
+} // end namespace
+
+namespace llvm {
+
+template <> struct simplify_type<pointer_wrappers::PTy> {
+ typedef pointer_wrappers::Base *SimpleType;
+ static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
+ return P.get();
+ }
+};
+template <> struct simplify_type<const pointer_wrappers::PTy> {
+ typedef pointer_wrappers::Base *SimpleType;
+ static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
+ return P.get();
+ }
+};
+
+} // end namespace llvm
+
+namespace {
+namespace pointer_wrappers {
+
+// Some objects.
+pointer_wrappers::Base B;
+pointer_wrappers::Derived D;
+
+// Mutable "smart" pointers.
+pointer_wrappers::PTy MN(nullptr);
+pointer_wrappers::PTy MB(&B);
+pointer_wrappers::PTy MD(&D);
+
+// Const "smart" pointers.
+const pointer_wrappers::PTy CN(nullptr);
+const pointer_wrappers::PTy CB(&B);
+const pointer_wrappers::PTy CD(&D);
+
+TEST(CastingTest, smart_isa) {
+ EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
+ EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
+ EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
+ EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
+}
+
+TEST(CastingTest, smart_cast) {
+ EXPECT_TRUE(cast<pointer_wrappers::Derived>(MD) == &D);
+ EXPECT_TRUE(cast<pointer_wrappers::Derived>(CD) == &D);
+}
+
+TEST(CastingTest, smart_cast_or_null) {
+ EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
+ EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
+ EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MD) == &D);
+ EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CD) == &D);
+}
+
+TEST(CastingTest, smart_dyn_cast) {
+ EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MB) == nullptr);
+ EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CB) == nullptr);
+ EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MD) == &D);
+ EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CD) == &D);
+}
+
+TEST(CastingTest, smart_dyn_cast_or_null) {
+ EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
+ EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
+ EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MB) == nullptr);
+ EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CB) == nullptr);
+ EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MD) == &D);
+ EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CD) == &D);
+}
+
+} // end namespace pointer_wrappers
+} // end namespace
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
index ac8d3d8..9d7679d 100644
--- a/unittests/Support/CommandLineTest.cpp
+++ b/unittests/Support/CommandLineTest.cpp
@@ -35,6 +35,8 @@ class TempEnvVar {
#if HAVE_SETENV
// Assume setenv and unsetenv come together.
unsetenv(name);
+#else
+ (void)name; // Suppress -Wunused-private-field.
#endif
}
@@ -70,14 +72,14 @@ public:
cl::OptionCategory TestCategory("Test Options", "Description");
-cl::opt<int> TestOption("test-option", cl::desc("old description"));
TEST(CommandLineTest, ModifyExisitingOption) {
+ StackOption<int> TestOption("test-option", cl::desc("old description"));
+
const char Description[] = "New description";
const char ArgString[] = "new-test-option";
const char ValueString[] = "Integer";
- StringMap<cl::Option*> Map;
- cl::getRegisteredOptions(Map);
+ StringMap<cl::Option *> &Map = cl::getRegisteredOptions();
ASSERT_TRUE(Map.count("test-option") == 1) <<
"Could not find option in map.";
@@ -230,5 +232,44 @@ TEST(CommandLineTest, AliasRequired) {
testAliasRequired(array_lengthof(opts2), opts2);
}
+TEST(CommandLineTest, HideUnrelatedOptions) {
+ StackOption<int> TestOption1("hide-option-1");
+ StackOption<int> TestOption2("hide-option-2", cl::cat(TestCategory));
+
+ cl::HideUnrelatedOptions(TestCategory);
+
+ ASSERT_EQ(cl::ReallyHidden, TestOption1.getOptionHiddenFlag())
+ << "Failed to hide extra option.";
+ ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag())
+ << "Hid extra option that should be visable.";
+
+ StringMap<cl::Option *> &Map = cl::getRegisteredOptions();
+ ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
+ << "Hid default option that should be visable.";
+}
+
+cl::OptionCategory TestCategory2("Test Options set 2", "Description");
+
+TEST(CommandLineTest, HideUnrelatedOptionsMulti) {
+ StackOption<int> TestOption1("multi-hide-option-1");
+ StackOption<int> TestOption2("multi-hide-option-2", cl::cat(TestCategory));
+ StackOption<int> TestOption3("multi-hide-option-3", cl::cat(TestCategory2));
+
+ const cl::OptionCategory *VisibleCategories[] = {&TestCategory,
+ &TestCategory2};
+
+ cl::HideUnrelatedOptions(makeArrayRef(VisibleCategories));
+
+ ASSERT_EQ(cl::ReallyHidden, TestOption1.getOptionHiddenFlag())
+ << "Failed to hide extra option.";
+ ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag())
+ << "Hid extra option that should be visable.";
+ ASSERT_EQ(cl::NotHidden, TestOption3.getOptionHiddenFlag())
+ << "Hid extra option that should be visable.";
+
+ StringMap<cl::Option *> &Map = cl::getRegisteredOptions();
+ ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
+ << "Hid default option that should be visable.";
+}
} // anonymous namespace
diff --git a/unittests/Support/CompressionTest.cpp b/unittests/Support/CompressionTest.cpp
index 698ae3a..36b84d8 100644
--- a/unittests/Support/CompressionTest.cpp
+++ b/unittests/Support/CompressionTest.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Compression.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "gtest/gtest.h"
diff --git a/unittests/Support/ConvertUTFTest.cpp b/unittests/Support/ConvertUTFTest.cpp
index 510b1da..d436fc0 100644
--- a/unittests/Support/ConvertUTFTest.cpp
+++ b/unittests/Support/ConvertUTFTest.cpp
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Format.h"
#include "gtest/gtest.h"
#include <string>
-#include <vector>
#include <utility>
+#include <vector>
using namespace llvm;
@@ -37,6 +38,19 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
EXPECT_EQ(Expected, Result);
}
+TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
+ // Src is the look of disapproval.
+ static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
+ StringRef Ref(Src, sizeof(Src) - 1);
+ SmallVector<UTF16, 5> Result;
+ bool Success = convertUTF8ToUTF16String(Ref, Result);
+ EXPECT_TRUE(Success);
+ static const UTF16 Expected[] = {0x0CA0, 0x005f, 0x0CA0, 0};
+ ASSERT_EQ(3u, Result.size());
+ for (int I = 0, E = 3; I != E; ++I)
+ EXPECT_EQ(Expected[I], Result[I]);
+}
+
TEST(ConvertUTFTest, OddLengthInput) {
std::string Result;
bool Success = convertUTF16ToUTF8String(makeArrayRef("xxxxx", 5), Result);
@@ -141,8 +155,8 @@ CheckConvertUTF8ToUnicodeScalars(ConvertUTFResultContainer Expected,
if (!Partial)
std::tie(ErrorCode, Decoded) = ConvertUTF8ToUnicodeScalarsLenient(S);
else
-
std::tie(ErrorCode, Decoded) = ConvertUTF8ToUnicodeScalarsPartialLenient(S);
+
if (Expected.ErrorCode != ErrorCode)
return ::testing::AssertionFailure() << "Expected error code "
<< Expected.ErrorCode << ", actual "
diff --git a/unittests/Support/DwarfTest.cpp b/unittests/Support/DwarfTest.cpp
new file mode 100644
index 0000000..74fcc98
--- /dev/null
+++ b/unittests/Support/DwarfTest.cpp
@@ -0,0 +1,141 @@
+//===- unittest/Support/DwarfTest.cpp - Dwarf support tests ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Dwarf.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::dwarf;
+
+namespace {
+
+TEST(DwarfTest, TagStringOnInvalid) {
+ // This is invalid, so it shouldn't be stringified.
+ EXPECT_EQ(nullptr, TagString(DW_TAG_invalid));
+
+ // These aren't really tags: they describe ranges within tags. They
+ // shouldn't be stringified either.
+ EXPECT_EQ(nullptr, TagString(DW_TAG_lo_user));
+ EXPECT_EQ(nullptr, TagString(DW_TAG_hi_user));
+ EXPECT_EQ(nullptr, TagString(DW_TAG_user_base));
+}
+
+TEST(DwarfTest, getTag) {
+ // A couple of valid tags.
+ EXPECT_EQ(DW_TAG_array_type, getTag("DW_TAG_array_type"));
+ EXPECT_EQ(DW_TAG_module, getTag("DW_TAG_module"));
+
+ // Invalid tags.
+ EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_invalid"));
+ EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_madeuptag"));
+ EXPECT_EQ(DW_TAG_invalid, getTag("something else"));
+
+ // Tag range markers should not be recognized.
+ EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_lo_user"));
+ EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_hi_user"));
+ EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_user_base"));
+}
+
+TEST(DwarfTest, getOperationEncoding) {
+ // Some valid ops.
+ EXPECT_EQ(DW_OP_deref, getOperationEncoding("DW_OP_deref"));
+ EXPECT_EQ(DW_OP_bit_piece, getOperationEncoding("DW_OP_bit_piece"));
+
+ // Invalid ops.
+ EXPECT_EQ(0u, getOperationEncoding("DW_OP_otherthings"));
+ EXPECT_EQ(0u, getOperationEncoding("other"));
+
+ // Markers shouldn't be recognized.
+ EXPECT_EQ(0u, getOperationEncoding("DW_OP_lo_user"));
+ EXPECT_EQ(0u, getOperationEncoding("DW_OP_hi_user"));
+}
+
+TEST(DwarfTest, LanguageStringOnInvalid) {
+ // This is invalid, so it shouldn't be stringified.
+ EXPECT_EQ(nullptr, LanguageString(0));
+
+ // These aren't really tags: they describe ranges within tags. They
+ // shouldn't be stringified either.
+ EXPECT_EQ(nullptr, LanguageString(DW_LANG_lo_user));
+ EXPECT_EQ(nullptr, LanguageString(DW_LANG_hi_user));
+}
+
+TEST(DwarfTest, getLanguage) {
+ // A couple of valid languages.
+ EXPECT_EQ(DW_LANG_C89, getLanguage("DW_LANG_C89"));
+ EXPECT_EQ(DW_LANG_C_plus_plus_11, getLanguage("DW_LANG_C_plus_plus_11"));
+ EXPECT_EQ(DW_LANG_OCaml, getLanguage("DW_LANG_OCaml"));
+ EXPECT_EQ(DW_LANG_Mips_Assembler, getLanguage("DW_LANG_Mips_Assembler"));
+
+ // Invalid languages.
+ EXPECT_EQ(0u, getLanguage("DW_LANG_invalid"));
+ EXPECT_EQ(0u, getLanguage("DW_TAG_array_type"));
+ EXPECT_EQ(0u, getLanguage("something else"));
+
+ // Language range markers should not be recognized.
+ EXPECT_EQ(0u, getLanguage("DW_LANG_lo_user"));
+ EXPECT_EQ(0u, getLanguage("DW_LANG_hi_user"));
+}
+
+TEST(DwarfTest, AttributeEncodingStringOnInvalid) {
+ // This is invalid, so it shouldn't be stringified.
+ EXPECT_EQ(nullptr, AttributeEncodingString(0));
+
+ // These aren't really tags: they describe ranges within tags. They
+ // shouldn't be stringified either.
+ EXPECT_EQ(nullptr, AttributeEncodingString(DW_ATE_lo_user));
+ EXPECT_EQ(nullptr, AttributeEncodingString(DW_ATE_hi_user));
+}
+
+TEST(DwarfTest, getAttributeEncoding) {
+ // A couple of valid languages.
+ EXPECT_EQ(DW_ATE_boolean, getAttributeEncoding("DW_ATE_boolean"));
+ EXPECT_EQ(DW_ATE_imaginary_float,
+ getAttributeEncoding("DW_ATE_imaginary_float"));
+
+ // Invalid languages.
+ EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_invalid"));
+ EXPECT_EQ(0u, getAttributeEncoding("DW_TAG_array_type"));
+ EXPECT_EQ(0u, getAttributeEncoding("something else"));
+
+ // AttributeEncoding range markers should not be recognized.
+ EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_lo_user"));
+ EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_hi_user"));
+}
+
+TEST(DwarfTest, VirtualityString) {
+ EXPECT_EQ(StringRef("DW_VIRTUALITY_none"),
+ VirtualityString(DW_VIRTUALITY_none));
+ EXPECT_EQ(StringRef("DW_VIRTUALITY_virtual"),
+ VirtualityString(DW_VIRTUALITY_virtual));
+ EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual"),
+ VirtualityString(DW_VIRTUALITY_pure_virtual));
+
+ // DW_VIRTUALITY_max should be pure virtual.
+ EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual"),
+ VirtualityString(DW_VIRTUALITY_max));
+
+ // Invalid numbers shouldn't be stringified.
+ EXPECT_EQ(nullptr, VirtualityString(DW_VIRTUALITY_max + 1));
+ EXPECT_EQ(nullptr, VirtualityString(DW_VIRTUALITY_max + 77));
+}
+
+TEST(DwarfTest, getVirtuality) {
+ EXPECT_EQ(DW_VIRTUALITY_none, getVirtuality("DW_VIRTUALITY_none"));
+ EXPECT_EQ(DW_VIRTUALITY_virtual, getVirtuality("DW_VIRTUALITY_virtual"));
+ EXPECT_EQ(DW_VIRTUALITY_pure_virtual,
+ getVirtuality("DW_VIRTUALITY_pure_virtual"));
+
+ // Invalid strings.
+ EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_invalid"));
+ EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_max"));
+ EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("something else"));
+}
+
+} // end namespace
diff --git a/unittests/Support/EndianStreamTest.cpp b/unittests/Support/EndianStreamTest.cpp
new file mode 100644
index 0000000..6a69be5
--- /dev/null
+++ b/unittests/Support/EndianStreamTest.cpp
@@ -0,0 +1,157 @@
+//===- unittests/Support/EndianStreamTest.cpp - EndianStream.h tests ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/DataTypes.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+using namespace support;
+
+namespace {
+
+TEST(EndianStream, WriteInt32LE) {
+ SmallString<16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<little> LE(OS);
+ LE.write(static_cast<int32_t>(-1362446643));
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0xCD);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0xB6);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0xCA);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0xAE);
+}
+
+TEST(EndianStream, WriteInt32BE) {
+ SmallVector<char, 16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<big> BE(OS);
+ BE.write(static_cast<int32_t>(-1362446643));
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0xAE);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0xCA);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0xB6);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0xCD);
+}
+
+
+TEST(EndianStream, WriteFloatLE) {
+ SmallString<16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<little> LE(OS);
+ LE.write(12345.0f);
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0x00);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0xE4);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0x40);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0x46);
+}
+
+TEST(EndianStream, WriteFloatBE) {
+ SmallVector<char, 16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<big> BE(OS);
+ BE.write(12345.0f);
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0x46);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0x40);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0xE4);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0x00);
+}
+
+TEST(EndianStream, WriteInt64LE) {
+ SmallString<16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<little> LE(OS);
+ LE.write(static_cast<int64_t>(-136244664332342323));
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0xCD);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0xAB);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0xED);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0x1B);
+ EXPECT_EQ(static_cast<uint8_t>(data[4]), 0x33);
+ EXPECT_EQ(static_cast<uint8_t>(data[5]), 0xF6);
+ EXPECT_EQ(static_cast<uint8_t>(data[6]), 0x1B);
+ EXPECT_EQ(static_cast<uint8_t>(data[7]), 0xFE);
+}
+
+TEST(EndianStream, WriteInt64BE) {
+ SmallVector<char, 16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<big> BE(OS);
+ BE.write(static_cast<int64_t>(-136244664332342323));
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0xFE);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0x1B);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0xF6);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0x33);
+ EXPECT_EQ(static_cast<uint8_t>(data[4]), 0x1B);
+ EXPECT_EQ(static_cast<uint8_t>(data[5]), 0xED);
+ EXPECT_EQ(static_cast<uint8_t>(data[6]), 0xAB);
+ EXPECT_EQ(static_cast<uint8_t>(data[7]), 0xCD);
+}
+
+TEST(EndianStream, WriteDoubleLE) {
+ SmallString<16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<little> LE(OS);
+ LE.write(-2349214918.58107);
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0x20);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0x98);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0xD2);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0x98);
+ EXPECT_EQ(static_cast<uint8_t>(data[4]), 0xC5);
+ EXPECT_EQ(static_cast<uint8_t>(data[5]), 0x80);
+ EXPECT_EQ(static_cast<uint8_t>(data[6]), 0xE1);
+ EXPECT_EQ(static_cast<uint8_t>(data[7]), 0xC1);
+}
+
+TEST(EndianStream, WriteDoubleBE) {
+ SmallVector<char, 16> data;
+
+ {
+ raw_svector_ostream OS(data);
+ endian::Writer<big> BE(OS);
+ BE.write(-2349214918.58107);
+ }
+
+ EXPECT_EQ(static_cast<uint8_t>(data[0]), 0xC1);
+ EXPECT_EQ(static_cast<uint8_t>(data[1]), 0xE1);
+ EXPECT_EQ(static_cast<uint8_t>(data[2]), 0x80);
+ EXPECT_EQ(static_cast<uint8_t>(data[3]), 0xC5);
+ EXPECT_EQ(static_cast<uint8_t>(data[4]), 0x98);
+ EXPECT_EQ(static_cast<uint8_t>(data[5]), 0xD2);
+ EXPECT_EQ(static_cast<uint8_t>(data[6]), 0x98);
+ EXPECT_EQ(static_cast<uint8_t>(data[7]), 0x20);
+}
+
+
+} // end anon namespace
diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp
index 911d516..c7e1006 100644
--- a/unittests/Support/FileOutputBufferTest.cpp
+++ b/unittests/Support/FileOutputBufferTest.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@@ -80,14 +80,13 @@ TEST(FileOutputBuffer, Test) {
memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
// Write to end of buffer to verify it is writable.
memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20);
- // Commit buffer, but size down to smaller size
- ASSERT_NO_ERROR(Buffer->commit(5000));
+ ASSERT_NO_ERROR(Buffer->commit());
}
// Verify file is correct size.
uint64_t File3Size;
ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size));
- ASSERT_EQ(File3Size, 5000ULL);
+ ASSERT_EQ(File3Size, 8192000ULL);
ASSERT_NO_ERROR(fs::remove(File3.str()));
// TEST 4: Verify file can be made executable.
diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp
index 93a38cb..5c95b50 100644
--- a/unittests/Support/MathExtrasTest.cpp
+++ b/unittests/Support/MathExtrasTest.cpp
@@ -141,21 +141,18 @@ TEST(MathExtras, ByteSwap_64) {
EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL));
}
-TEST(MathExtras, CountLeadingOnes_32) {
+TEST(MathExtras, countLeadingOnes) {
for (int i = 30; i >= 0; --i) {
// Start with all ones and unset some bit.
- EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i)));
+ EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i)));
}
-}
-
-TEST(MathExtras, CountLeadingOnes_64) {
for (int i = 62; i >= 0; --i) {
// Start with all ones and unset some bit.
- EXPECT_EQ(63u - i, CountLeadingOnes_64(0xFFFFFFFFFFFFFFFFLL ^ (1LL << i)));
+ EXPECT_EQ(63u - i, countLeadingOnes(0xFFFFFFFFFFFFFFFFULL ^ (1LL << i)));
}
for (int i = 30; i >= 0; --i) {
// Start with all ones and unset some bit.
- EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i)));
+ EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i)));
}
}
diff --git a/unittests/Support/MemoryTest.cpp b/unittests/Support/MemoryTest.cpp
index 8ad90e0..f439cb2 100644
--- a/unittests/Support/MemoryTest.cpp
+++ b/unittests/Support/MemoryTest.cpp
@@ -21,7 +21,7 @@ class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
public:
MappedMemoryTest() {
Flags = GetParam();
- PageSize = sys::process::get_self()->page_size();
+ PageSize = sys::Process::getPageSize();
}
protected:
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 502cda2..00af989 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -557,6 +557,7 @@ const char macho_dynamically_linked_shared_lib[] =
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 macho_kext_bundle[] = "\xfe\xed\xfa\xce..........\x00\x0b";
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";
@@ -587,6 +588,7 @@ TEST_F(FileSystemTest, Magic) {
DEFINE(macho_bundle),
DEFINE(macho_dynamically_linked_shared_lib_stub),
DEFINE(macho_dsym_companion),
+ DEFINE(macho_kext_bundle),
DEFINE(windows_resource)
#undef DEFINE
};
@@ -638,22 +640,31 @@ TEST_F(FileSystemTest, CarriageReturn) {
}
#endif
+TEST_F(FileSystemTest, Resize) {
+ int FD;
+ SmallString<64> TempPath;
+ ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+ ASSERT_NO_ERROR(fs::resize_file(FD, 123));
+ fs::file_status Status;
+ ASSERT_NO_ERROR(fs::status(FD, Status));
+ ASSERT_EQ(Status.getSize(), 123U);
+}
+
TEST_F(FileSystemTest, FileMapping) {
// Create a temp file.
int FileDescriptor;
SmallString<64> TempPath;
ASSERT_NO_ERROR(
fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
+ unsigned Size = 4096;
+ ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size));
+
// Map in temp file and add some content
std::error_code EC;
StringRef Val("hello there");
{
fs::mapped_file_region mfr(FileDescriptor,
- true,
- fs::mapped_file_region::readwrite,
- 4096,
- 0,
- EC);
+ fs::mapped_file_region::readwrite, Size, 0, EC);
ASSERT_NO_ERROR(EC);
std::copy(Val.begin(), Val.end(), mfr.data());
// Explicitly add a 0.
@@ -662,27 +673,19 @@ TEST_F(FileSystemTest, FileMapping) {
}
// Map it back in read-only
- fs::mapped_file_region mfr(Twine(TempPath),
- fs::mapped_file_region::readonly,
- 0,
- 0,
- EC);
+ int FD;
+ EC = fs::openFileForRead(Twine(TempPath), FD);
+ ASSERT_NO_ERROR(EC);
+ fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
ASSERT_NO_ERROR(EC);
// Verify content
EXPECT_EQ(StringRef(mfr.const_data()), Val);
// Unmap temp file
-
- fs::mapped_file_region m(Twine(TempPath),
- fs::mapped_file_region::readonly,
- 0,
- 0,
- EC);
+ fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
ASSERT_NO_ERROR(EC);
- const char *Data = m.const_data();
- fs::mapped_file_region mfrrv(std::move(m));
- EXPECT_EQ(mfrrv.const_data(), Data);
+ ASSERT_EQ(close(FD), 0);
}
TEST(Support, NormalizePath) {
diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp
index 3045c30..298a0a3 100644
--- a/unittests/Support/ProcessTest.cpp
+++ b/unittests/Support/ProcessTest.cpp
@@ -19,26 +19,6 @@ namespace {
using namespace llvm;
using namespace sys;
-TEST(ProcessTest, SelfProcess) {
- EXPECT_TRUE(process::get_self());
- EXPECT_EQ(process::get_self(), process::get_self());
-
-#if defined(LLVM_ON_UNIX)
- EXPECT_EQ(getpid(), process::get_self()->get_id());
-#elif defined(LLVM_ON_WIN32)
- EXPECT_EQ(GetCurrentProcessId(), process::get_self()->get_id());
-#endif
-
- EXPECT_LT(1u, process::get_self()->page_size());
-
- EXPECT_LT(TimeValue::MinTime(), process::get_self()->get_user_time());
- EXPECT_GT(TimeValue::MaxTime(), process::get_self()->get_user_time());
- EXPECT_LT(TimeValue::MinTime(), process::get_self()->get_system_time());
- EXPECT_GT(TimeValue::MaxTime(), process::get_self()->get_system_time());
- EXPECT_LT(TimeValue::MinTime(), process::get_self()->get_wall_time());
- EXPECT_GT(TimeValue::MaxTime(), process::get_self()->get_wall_time());
-}
-
TEST(ProcessTest, GetRandomNumberTest) {
const unsigned r1 = Process::GetRandomNumber();
const unsigned r2 = Process::GetRandomNumber();
diff --git a/unittests/Support/ProgramTest.cpp b/unittests/Support/ProgramTest.cpp
index c0e6e80..0feed47 100644
--- a/unittests/Support/ProgramTest.cpp
+++ b/unittests/Support/ProgramTest.cpp
@@ -70,6 +70,56 @@ static void CopyEnvironment(std::vector<const char *> &out) {
}
}
+#ifdef LLVM_ON_WIN32
+TEST(ProgramTest, CreateProcessLongPath) {
+ if (getenv("LLVM_PROGRAM_TEST_LONG_PATH"))
+ exit(0);
+
+ // getMainExecutable returns an absolute path; prepend the long-path prefix.
+ std::string MyAbsExe =
+ sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+ std::string MyExe;
+ if (!StringRef(MyAbsExe).startswith("\\\\?\\"))
+ MyExe.append("\\\\?\\");
+ MyExe.append(MyAbsExe);
+
+ const char *ArgV[] = {
+ MyExe.c_str(),
+ "--gtest_filter=ProgramTest.CreateProcessLongPath",
+ nullptr
+ };
+
+ // Add LLVM_PROGRAM_TEST_LONG_PATH to the environment of the child.
+ std::vector<const char *> EnvP;
+ CopyEnvironment(EnvP);
+ EnvP.push_back("LLVM_PROGRAM_TEST_LONG_PATH=1");
+ EnvP.push_back(nullptr);
+
+ // Redirect stdout to a long path.
+ SmallString<128> TestDirectory;
+ ASSERT_NO_ERROR(
+ fs::createUniqueDirectory("program-redirect-test", TestDirectory));
+ SmallString<256> LongPath(TestDirectory);
+ LongPath.push_back('\\');
+ // MAX_PATH = 260
+ LongPath.append(260 - TestDirectory.size(), 'a');
+ StringRef LongPathRef(LongPath);
+
+ std::string Error;
+ bool ExecutionFailed;
+ const StringRef *Redirects[] = { nullptr, &LongPathRef, nullptr };
+ int RC = ExecuteAndWait(MyExe, ArgV, &EnvP[0], Redirects,
+ /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &Error,
+ &ExecutionFailed);
+ EXPECT_FALSE(ExecutionFailed) << Error;
+ EXPECT_EQ(0, RC);
+
+ // Remove the long stdout.
+ ASSERT_NO_ERROR(fs::remove(Twine(LongPath)));
+ ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory)));
+}
+#endif
+
TEST(ProgramTest, CreateProcessTrailingSlash) {
if (getenv("LLVM_PROGRAM_TEST_CHILD")) {
if (ProgramTestStringArg1 == "has\\\\ trailing\\" &&
diff --git a/unittests/Support/ScaledNumberTest.cpp b/unittests/Support/ScaledNumberTest.cpp
index 7bbef7e..d8d6e31 100644
--- a/unittests/Support/ScaledNumberTest.cpp
+++ b/unittests/Support/ScaledNumberTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ScaledNumber.h"
-
#include "llvm/Support/DataTypes.h"
#include "gtest/gtest.h"
diff --git a/unittests/Support/SpecialCaseListTest.cpp b/unittests/Support/SpecialCaseListTest.cpp
index 740dbfe..0657f80 100644
--- a/unittests/Support/SpecialCaseListTest.cpp
+++ b/unittests/Support/SpecialCaseListTest.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SpecialCaseList.h"
#include "gtest/gtest.h"
@@ -30,6 +31,16 @@ protected:
assert(Error == "");
return SCL;
}
+
+ std::string makeSpecialCaseListFile(StringRef Contents) {
+ int FD;
+ SmallString<64> Path;
+ sys::fs::createTemporaryFile("SpecialCaseListTest", "temp", FD, Path);
+ raw_fd_ostream OF(FD, true, true);
+ OF << Contents;
+ OF.close();
+ return Path.str();
+ }
};
TEST_F(SpecialCaseListTest, Basic) {
@@ -86,17 +97,18 @@ TEST_F(SpecialCaseListTest, Substring) {
TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
std::string Error;
EXPECT_EQ(nullptr, makeSpecialCaseList("badline", Error));
- EXPECT_EQ("Malformed line 1: 'badline'", Error);
+ EXPECT_EQ("malformed line 1: 'badline'", Error);
EXPECT_EQ(nullptr, makeSpecialCaseList("src:bad[a-", Error));
- EXPECT_EQ("Malformed regex in line 1: 'bad[a-': invalid character range",
+ EXPECT_EQ("malformed regex in line 1: 'bad[a-': invalid character range",
Error);
EXPECT_EQ(nullptr, makeSpecialCaseList("src:a.c\n"
"fun:fun(a\n",
Error));
- EXPECT_EQ("Malformed regex in line 2: 'fun(a': parentheses not balanced",
+ EXPECT_EQ("malformed regex in line 2: 'fun(a': parentheses not balanced",
Error);
- EXPECT_EQ(nullptr, SpecialCaseList::create("unexisting", Error));
- EXPECT_EQ(0U, Error.find("Can't open file 'unexisting':"));
+ std::vector<std::string> Files(1, "unexisting");
+ EXPECT_EQ(nullptr, SpecialCaseList::create(Files, Error));
+ EXPECT_EQ(0U, Error.find("can't open file 'unexisting':"));
}
TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
@@ -104,6 +116,20 @@ TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
EXPECT_FALSE(SCL->inSection("foo", "bar"));
}
+TEST_F(SpecialCaseListTest, MultipleBlacklists) {
+ std::vector<std::string> Files;
+ Files.push_back(makeSpecialCaseListFile("src:bar\n"
+ "src:*foo*\n"
+ "src:ban=init\n"));
+ Files.push_back(makeSpecialCaseListFile("src:baz\n"
+ "src:*fog*\n"));
+ auto SCL = SpecialCaseList::createOrDie(Files);
+ EXPECT_TRUE(SCL->inSection("src", "bar"));
+ EXPECT_TRUE(SCL->inSection("src", "baz"));
+ EXPECT_FALSE(SCL->inSection("src", "ban"));
+ EXPECT_TRUE(SCL->inSection("src", "ban", "init"));
+ EXPECT_TRUE(SCL->inSection("src", "tomfoolery"));
+ EXPECT_TRUE(SCL->inSection("src", "tomfoglery"));
}
-
+}
diff --git a/unittests/Support/StreamingMemoryObject.cpp b/unittests/Support/StreamingMemoryObject.cpp
new file mode 100644
index 0000000..2013649
--- /dev/null
+++ b/unittests/Support/StreamingMemoryObject.cpp
@@ -0,0 +1,29 @@
+//===- llvm/unittest/Support/StreamingMemoryObject.cpp - 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/Support/StreamingMemoryObject.h"
+#include "gtest/gtest.h"
+#include <string.h>
+
+using namespace llvm;
+
+namespace {
+class NullDataStreamer : public DataStreamer {
+ size_t GetBytes(unsigned char *buf, size_t len) override {
+ memset(buf, 0, len);
+ return len;
+ }
+};
+}
+
+TEST(StreamingMemoryObject, Test) {
+ auto *DS = new NullDataStreamer();
+ StreamingMemoryObject O(DS);
+ EXPECT_TRUE(O.isValidAddress(32 * 1024));
+}
diff --git a/unittests/Support/StringPool.cpp b/unittests/Support/StringPool.cpp
index 7b7805f..ac39fec 100644
--- a/unittests/Support/StringPool.cpp
+++ b/unittests/Support/StringPool.cpp
@@ -1,6 +1,6 @@
-//===- llvm/unittest/Support/ThreadLocalTest.cpp - Therad Local tests ---===//
+//===- llvm/unittest/Support/StringPoiil.cpp - StringPool tests -----------===//
//
-// The LLVM Compiler Infrastructure
+// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
diff --git a/unittests/Support/ThreadLocalTest.cpp b/unittests/Support/ThreadLocalTest.cpp
index ea751be..e71c7db 100644
--- a/unittests/Support/ThreadLocalTest.cpp
+++ b/unittests/Support/ThreadLocalTest.cpp
@@ -1,6 +1,6 @@
-//===- llvm/unittest/Support/ThreadLocalTest.cpp - Therad Local tests ---===//
+//===- llvm/unittest/Support/ThreadLocalTest.cpp - ThreadLocal tests ------===//
//
-// The LLVM Compiler Infrastructure
+// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
@@ -9,6 +9,7 @@
#include "llvm/Support/ThreadLocal.h"
#include "gtest/gtest.h"
+#include <type_traits>
using namespace llvm;
using namespace sys;
@@ -25,6 +26,10 @@ struct S {
TEST_F(ThreadLocalTest, Basics) {
ThreadLocal<const S> x;
+ static_assert(
+ std::is_const<std::remove_pointer<decltype(x.get())>::type>::value,
+ "ThreadLocal::get didn't return a pointer to const object");
+
EXPECT_EQ(nullptr, x.get());
S s;
@@ -33,6 +38,20 @@ TEST_F(ThreadLocalTest, Basics) {
x.erase();
EXPECT_EQ(nullptr, x.get());
+
+ ThreadLocal<S> y;
+
+ static_assert(
+ !std::is_const<std::remove_pointer<decltype(y.get())>::type>::value,
+ "ThreadLocal::get returned a pointer to const object");
+
+ EXPECT_EQ(nullptr, y.get());
+
+ y.set(&s);
+ EXPECT_EQ(&s, y.get());
+
+ y.erase();
+ EXPECT_EQ(nullptr, y.get());
}
}
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index 39cfaf0..ff98602 100644
--- a/unittests/Support/raw_ostream_test.cpp
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -162,6 +162,8 @@ TEST(raw_ostreamTest, FormatHex) {
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("FF", printToString(format_hex_no_prefix(0xFF, 2, true), 4));
+ EXPECT_EQ("ABCD", printToString(format_hex_no_prefix(0xABCD, 2, true), 4));
EXPECT_EQ("0xffffffffffffffff",
printToString(format_hex(UINT64_MAX, 18), 18));
EXPECT_EQ("0x8000000000000000",
diff --git a/unittests/Transforms/CMakeLists.txt b/unittests/Transforms/CMakeLists.txt
index 8ec56f1..5d3b29c 100644
--- a/unittests/Transforms/CMakeLists.txt
+++ b/unittests/Transforms/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_subdirectory(DebugIR)
+add_subdirectory(IPO)
add_subdirectory(Utils)
diff --git a/unittests/Transforms/DebugIR/CMakeLists.txt b/unittests/Transforms/DebugIR/CMakeLists.txt
deleted file mode 100644
index 88734d2..0000000
--- a/unittests/Transforms/DebugIR/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- Core
- Instrumentation
- Support
- )
-
-add_llvm_unittest(DebugIRTests
- DebugIR.cpp
- )
diff --git a/unittests/Transforms/DebugIR/DebugIR.cpp b/unittests/Transforms/DebugIR/DebugIR.cpp
deleted file mode 100644
index 41df147..0000000
--- a/unittests/Transforms/DebugIR/DebugIR.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-//===- DebugIR.cpp - Unit tests for the DebugIR pass ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The tests in this file verify the DebugIR pass that generates debug metadata
-// for LLVM IR.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/Triple.h"
-#include "../lib/Transforms/Instrumentation/DebugIR.h"
-#include "llvm/Config/config.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Transforms/Instrumentation.h"
-
-// These tests do not depend on MCJIT, but we use the TrivialModuleBuilder
-// helper class to construct some trivial Modules.
-#include "../unittests/ExecutionEngine/MCJIT/MCJITTestBase.h"
-
-#include <string>
-
-#include "gtest/gtest.h"
-
-#if defined(LLVM_ON_WIN32)
-#include <direct.h>
-#define getcwd_impl _getcwd
-#elif defined (HAVE_GETCWD)
-#include <unistd.h>
-#define getcwd_impl getcwd
-#endif // LLVM_ON_WIN32
-
-using namespace llvm;
-using namespace std;
-
-namespace {
-
-/// Insert a mock CUDescriptor with the specified producer
-void insertCUDescriptor(Module *M, StringRef File, StringRef Dir,
- StringRef Producer) {
- DIBuilder B(*M);
- B.createCompileUnit(dwarf::DW_LANG_C99, File, Dir, Producer, false, "", 0);
- B.finalize();
-}
-
-/// Attempts to remove file at Path and returns true if it existed, or false if
-/// it did not.
-bool removeIfExists(StringRef Path) {
- // This is an approximation, on error we don't know in general if the file
- // existed or not.
- std::error_code EC = sys::fs::remove(Path, false);
- return EC != llvm::errc::no_such_file_or_directory;
-}
-
-char * current_dir() {
-#if defined(LLVM_ON_WIN32) || defined(HAVE_GETCWD)
- // calling getcwd (or _getcwd() on windows) with a null buffer makes it
- // allocate a sufficiently sized buffer to store the current working dir.
- return getcwd_impl(nullptr, 0);
-#else
- return 0;
-#endif
-}
-
-class TestDebugIR : public ::testing::Test, public TrivialModuleBuilder {
-protected:
- TestDebugIR()
- : TrivialModuleBuilder(sys::getProcessTriple())
- , cwd(current_dir()) {}
-
- ~TestDebugIR() { free(cwd); }
-
- /// Returns a concatenated path string consisting of Dir and Filename
- string getPath(const string &Dir, const string &Filename) {
- SmallVector<char, 8> Path;
- sys::path::append(Path, Dir, Filename);
- Path.resize(Dir.size() + Filename.size() + 2);
- Path[Dir.size() + Filename.size() + 1] = '\0';
- return string(Path.data());
- }
-
- LLVMContext Context;
- char *cwd;
- std::unique_ptr<Module> M;
- std::unique_ptr<DebugIR> D;
-};
-
-// Test empty named Module that is not supposed to be output to disk.
-TEST_F(TestDebugIR, EmptyNamedModuleNoWrite) {
- string Dir = "MadeUpDirectory";
- string File = "empty_module.ll";
- string Path(getPath(Dir, File));
-
- M.reset(createEmptyModule(Path));
-
- // constructing DebugIR with no args should not result in any file generated.
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass()));
- D->runOnModule(*M);
-
- // verify DebugIR did not generate a file
- ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path;
-}
-
-// Test a non-empty unnamed module that is output to an autogenerated file name.
-TEST_F(TestDebugIR, NonEmptyUnnamedModuleWriteToAutogeneratedFile) {
- M.reset(createEmptyModule());
- insertAddFunction(M.get());
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(true, true)));
-
- string Path;
- D->runOnModule(*M, Path);
-
- // verify DebugIR generated a file, and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-}
-
-// Test not specifying a name in the module -- DebugIR should generate a name
-// and write the file contents.
-TEST_F(TestDebugIR, EmptyModuleWriteAnonymousFile) {
- M.reset(createEmptyModule());
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(false, false)));
-
- string Path;
- D->runOnModule(*M, Path);
-
- // verify DebugIR generated a file and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-}
-
-#ifdef HAVE_GETCWD // These tests require get_current_dir_name()
-
-// Test empty named Module that is to be output to path specified at Module
-// construction.
-TEST_F(TestDebugIR, EmptyNamedModuleWriteFile) {
- string Filename("NamedFile1");
- string ExpectedPath(getPath(cwd, Filename));
-
- M.reset(createEmptyModule(ExpectedPath));
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(true, true)));
-
- string Path;
- D->runOnModule(*M, Path);
-
- // verify DebugIR was able to correctly parse the file name from module ID
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR generated a file, and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-}
-
-// Test an empty unnamed module generates an output file whose path is specified
-// at DebugIR construction.
-TEST_F(TestDebugIR, EmptyUnnamedModuleWriteNamedFile) {
- string Filename("NamedFile2");
-
- M.reset(createEmptyModule());
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(
- false, false, StringRef(cwd), StringRef(Filename))));
- string Path;
- D->runOnModule(*M, Path);
-
- string ExpectedPath(getPath(cwd, Filename));
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR generated a file, and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-}
-
-// Test an empty named module generates an output file at the path specified
-// during DebugIR construction.
-TEST_F(TestDebugIR, EmptyNamedModuleWriteNamedFile) {
- string Filename("NamedFile3");
-
- string UnexpectedPath(getPath(cwd, "UnexpectedFilename"));
- M.reset(createEmptyModule(UnexpectedPath));
-
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(
- false, false, StringRef(cwd), StringRef(Filename))));
- string Path;
- D->runOnModule(*M, Path);
-
- string ExpectedPath(getPath(cwd, Filename));
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR generated a file, and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-
- // verify DebugIR did not generate a file at the path specified at Module
- // construction.
- ASSERT_FALSE(removeIfExists(UnexpectedPath)) << "Unexpected file " << Path;
-}
-
-// Test a non-empty named module that is not supposed to be output to disk
-TEST_F(TestDebugIR, NonEmptyNamedModuleNoWrite) {
- string Filename("NamedFile4");
- string ExpectedPath(getPath(cwd, Filename));
-
- M.reset(createEmptyModule(ExpectedPath));
- insertAddFunction(M.get());
-
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass()));
-
- string Path;
- D->runOnModule(*M, Path);
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR did not generate a file
- ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path;
-}
-
-// Test a non-empty named module that is output to disk.
-TEST_F(TestDebugIR, NonEmptyNamedModuleWriteFile) {
- string Filename("NamedFile5");
- string ExpectedPath(getPath(cwd, Filename));
-
- M.reset(createEmptyModule(ExpectedPath));
- insertAddFunction(M.get());
-
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass(true, true)));
-
- string Path;
- D->runOnModule(*M, Path);
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR generated a file, and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-}
-
-// Test a non-empty unnamed module is output to a path specified at DebugIR
-// construction.
-TEST_F(TestDebugIR, NonEmptyUnnamedModuleWriteToNamedFile) {
- string Filename("NamedFile6");
-
- M.reset(createEmptyModule());
- insertAddFunction(M.get());
-
- D.reset(static_cast<DebugIR *>(
- llvm::createDebugIRPass(true, true, cwd, Filename)));
- string Path;
- D->runOnModule(*M, Path);
-
- string ExpectedPath(getPath(cwd, Filename));
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR generated a file, and clean it up
- ASSERT_TRUE(removeIfExists(Path)) << "Missing expected file at " << Path;
-}
-
-// Test that information inside existing debug metadata is retained
-TEST_F(TestDebugIR, ExistingMetadataRetained) {
- string Filename("NamedFile7");
- string ExpectedPath(getPath(cwd, Filename));
-
- M.reset(createEmptyModule(ExpectedPath));
- insertAddFunction(M.get());
-
- StringRef Producer("TestProducer");
- insertCUDescriptor(M.get(), Filename, cwd, Producer);
-
- DebugInfoFinder Finder;
- Finder.processModule(*M);
- ASSERT_EQ((unsigned)1, Finder.compile_unit_count());
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass()));
-
- string Path;
- D->runOnModule(*M, Path);
- ASSERT_EQ(ExpectedPath, Path);
-
- // verify DebugIR did not generate a file
- ASSERT_FALSE(removeIfExists(Path)) << "Unexpected file " << Path;
-
- DICompileUnit CU(*Finder.compile_units().begin());
-
- // Verify original CU information is retained
- ASSERT_EQ(Filename, CU.getFilename());
- ASSERT_EQ(cwd, CU.getDirectory());
- ASSERT_EQ(Producer, CU.getProducer());
-}
-
-#endif // HAVE_GETCWD
-
-#ifdef GTEST_HAS_DEATH_TEST
-
-// Test a non-empty unnamed module that is not supposed to be output to disk
-// NOTE: this test is expected to die with LLVM_ERROR, and such depends on
-// google test's "death test" mode.
-TEST_F(TestDebugIR, NonEmptyUnnamedModuleNoWrite) {
- M.reset(createEmptyModule(StringRef()));
- insertAddFunction(M.get());
- D.reset(static_cast<DebugIR *>(llvm::createDebugIRPass()));
-
- // No name in module or on DebugIR construction ==> DebugIR should assert
- EXPECT_DEATH(D->runOnModule(*M),
- "DebugIR unable to determine file name in input.");
-}
-
-#endif // GTEST_HAS_DEATH_TEST
-}
diff --git a/unittests/Transforms/IPO/CMakeLists.txt b/unittests/Transforms/IPO/CMakeLists.txt
new file mode 100644
index 0000000..58b71b2
--- /dev/null
+++ b/unittests/Transforms/IPO/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+ Core
+ Support
+ IPO
+ )
+
+add_llvm_unittest(IPOTests
+ LowerBitSets.cpp
+ )
diff --git a/unittests/Transforms/IPO/LowerBitSets.cpp b/unittests/Transforms/IPO/LowerBitSets.cpp
new file mode 100644
index 0000000..26a4252
--- /dev/null
+++ b/unittests/Transforms/IPO/LowerBitSets.cpp
@@ -0,0 +1,95 @@
+//===- LowerBitSets.cpp - Unit tests for bitset lowering ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO/LowerBitSets.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(LowerBitSets, BitSetBuilder) {
+ struct {
+ std::vector<uint64_t> Offsets;
+ std::vector<uint8_t> Bits;
+ uint64_t ByteOffset;
+ uint64_t BitSize;
+ unsigned AlignLog2;
+ bool IsSingleOffset;
+ bool IsAllOnes;
+ } BSBTests[] = {
+ {{}, {0}, 0, 1, 0, false, false},
+ {{0}, {1}, 0, 1, 0, true, true},
+ {{4}, {1}, 4, 1, 0, true, true},
+ {{37}, {1}, 37, 1, 0, true, true},
+ {{0, 1}, {3}, 0, 2, 0, false, true},
+ {{0, 4}, {3}, 0, 2, 2, false, true},
+ {{0, uint64_t(1) << 33}, {3}, 0, 2, 33, false, true},
+ {{3, 7}, {3}, 3, 2, 2, false, true},
+ {{0, 1, 7}, {131}, 0, 8, 0, false, false},
+ {{0, 2, 14}, {131}, 0, 8, 1, false, false},
+ {{0, 1, 8}, {3, 1}, 0, 9, 0, false, false},
+ {{0, 2, 16}, {3, 1}, 0, 9, 1, false, false},
+ {{0, 1, 2, 3, 4, 5, 6, 7}, {255}, 0, 8, 0, false, true},
+ {{0, 1, 2, 3, 4, 5, 6, 7, 8}, {255, 1}, 0, 9, 0, false, true},
+ };
+
+ for (auto &&T : BSBTests) {
+ BitSetBuilder BSB;
+ for (auto Offset : T.Offsets)
+ BSB.addOffset(Offset);
+
+ BitSetInfo BSI = BSB.build();
+
+ EXPECT_EQ(T.Bits, BSI.Bits);
+ EXPECT_EQ(T.ByteOffset, BSI.ByteOffset);
+ EXPECT_EQ(T.BitSize, BSI.BitSize);
+ EXPECT_EQ(T.AlignLog2, BSI.AlignLog2);
+ EXPECT_EQ(T.IsSingleOffset, BSI.isSingleOffset());
+ EXPECT_EQ(T.IsAllOnes, BSI.isAllOnes());
+
+ for (auto Offset : T.Offsets)
+ EXPECT_TRUE(BSI.containsGlobalOffset(Offset));
+
+ auto I = T.Offsets.begin();
+ for (uint64_t NonOffset = 0; NonOffset != 256; ++NonOffset) {
+ if (I != T.Offsets.end() && *I == NonOffset) {
+ ++I;
+ continue;
+ }
+
+ EXPECT_FALSE(BSI.containsGlobalOffset(NonOffset));
+ }
+ }
+}
+
+TEST(LowerBitSets, GlobalLayoutBuilder) {
+ struct {
+ uint64_t NumObjects;
+ std::vector<std::set<uint64_t>> Fragments;
+ std::vector<uint64_t> WantLayout;
+ } GLBTests[] = {
+ {0, {}, {}},
+ {4, {{0, 1}, {2, 3}}, {0, 1, 2, 3}},
+ {3, {{0, 1}, {1, 2}}, {0, 1, 2}},
+ {4, {{0, 1}, {1, 2}, {2, 3}}, {0, 1, 2, 3}},
+ {4, {{0, 1}, {2, 3}, {1, 2}}, {0, 1, 2, 3}},
+ {6, {{2, 5}, {0, 1, 2, 3, 4, 5}}, {0, 1, 2, 5, 3, 4}},
+ };
+
+ for (auto &&T : GLBTests) {
+ GlobalLayoutBuilder GLB(T.NumObjects);
+ for (auto &&F : T.Fragments)
+ GLB.addFragment(F);
+
+ std::vector<uint64_t> ComputedLayout;
+ for (auto &&F : GLB.Fragments)
+ ComputedLayout.insert(ComputedLayout.end(), F.begin(), F.end());
+
+ EXPECT_EQ(T.WantLayout, ComputedLayout);
+ }
+}
diff --git a/unittests/Transforms/DebugIR/Makefile b/unittests/Transforms/IPO/Makefile
index 9ace8c3..f807879 100644
--- a/unittests/Transforms/DebugIR/Makefile
+++ b/unittests/Transforms/IPO/Makefile
@@ -1,4 +1,4 @@
-##===- unittests/Transforms/Utils/Makefile -----------------*- Makefile -*-===##
+##===- unittests/Transforms/IPO/Makefile -------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -8,8 +8,8 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../..
-TESTNAME = DebugIR
-LINK_COMPONENTS := Instrumentation
+TESTNAME = IPO
+LINK_COMPONENTS := IPO
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Transforms/Makefile b/unittests/Transforms/Makefile
index d5cca39..3a2cdfc 100644
--- a/unittests/Transforms/Makefile
+++ b/unittests/Transforms/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
-PARALLEL_DIRS = DebugIR Utils
+PARALLEL_DIRS = IPO Utils
include $(LEVEL)/Makefile.common
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index c779979..1d22d5b 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -13,16 +13,15 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Constant.h"
-#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "gtest/gtest.h"
using namespace llvm;