summaryrefslogtreecommitdiff
path: root/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ADT/APFloatTest.cpp7
-rw-r--r--unittests/ADT/APIntTest.cpp137
-rw-r--r--unittests/ADT/APSIntTest.cpp102
-rw-r--r--unittests/ADT/ArrayRefTest.cpp49
-rw-r--r--unittests/ADT/DAGDeltaAlgorithmTest.cpp2
-rw-r--r--unittests/ADT/DeltaAlgorithmTest.cpp4
-rw-r--r--unittests/ADT/DenseMapTest.cpp1
-rw-r--r--unittests/ADT/HashingTest.cpp26
-rw-r--r--unittests/ADT/MapVectorTest.cpp25
-rw-r--r--unittests/ADT/OptionalTest.cpp10
-rw-r--r--unittests/ADT/PointerIntPairTest.cpp2
-rw-r--r--unittests/ADT/SCCIteratorTest.cpp4
-rw-r--r--unittests/ADT/SmallVectorTest.cpp125
-rw-r--r--unittests/ADT/StringMapTest.cpp8
-rw-r--r--unittests/ADT/TinyPtrVectorTest.cpp21
-rw-r--r--unittests/ADT/TripleTest.cpp296
-rw-r--r--unittests/ADT/TwineTest.cpp10
-rw-r--r--unittests/ADT/ilistTest.cpp3
-rw-r--r--unittests/Analysis/AliasAnalysisTest.cpp104
-rw-r--r--unittests/Analysis/CFGTest.cpp14
-rw-r--r--unittests/Analysis/CMakeLists.txt1
-rw-r--r--unittests/Analysis/MixedTBAATest.cpp4
-rw-r--r--unittests/Analysis/ScalarEvolutionTest.cpp6
-rw-r--r--unittests/AsmParser/AsmParserTest.cpp47
-rw-r--r--unittests/AsmParser/CMakeLists.txt9
-rw-r--r--unittests/AsmParser/Makefile15
-rw-r--r--unittests/Bitcode/BitReaderTest.cpp72
-rw-r--r--unittests/CMakeLists.txt2
-rw-r--r--unittests/CodeGen/DIEHashTest.cpp126
-rw-r--r--unittests/DebugInfo/CMakeLists.txt12
-rw-r--r--unittests/DebugInfo/DWARF/CMakeLists.txt11
-rw-r--r--unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp124
-rw-r--r--unittests/DebugInfo/DWARF/Makefile16
-rw-r--r--unittests/DebugInfo/DWARFFormValueTest.cpp49
-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.cpp397
-rw-r--r--unittests/ExecutionEngine/CMakeLists.txt3
-rw-r--r--unittests/ExecutionEngine/ExecutionEngineTest.cpp4
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp28
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp19
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp4
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTest.cpp4
-rw-r--r--unittests/ExecutionEngine/MCJIT/MCJITTestBase.h5
-rw-r--r--unittests/ExecutionEngine/Makefile4
-rw-r--r--unittests/ExecutionEngine/Orc/CMakeLists.txt11
-rw-r--r--unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp48
-rw-r--r--unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp32
-rw-r--r--unittests/ExecutionEngine/Orc/Makefile16
-rw-r--r--unittests/ExecutionEngine/Orc/OrcTestCommon.cpp23
-rw-r--r--unittests/ExecutionEngine/Orc/OrcTestCommon.h66
-rw-r--r--unittests/IR/ConstantRangeTest.cpp65
-rw-r--r--unittests/IR/ConstantsTest.cpp49
-rw-r--r--unittests/IR/DebugInfoTest.cpp103
-rw-r--r--unittests/IR/DominatorTreeTest.cpp36
-rw-r--r--unittests/IR/IRBuilderTest.cpp44
-rw-r--r--unittests/IR/InstructionsTest.cpp30
-rw-r--r--unittests/IR/LegacyPassManagerTest.cpp29
-rw-r--r--unittests/IR/MetadataTest.cpp1808
-rw-r--r--unittests/IR/UseTest.cpp8
-rw-r--r--unittests/IR/ValueHandleTest.cpp28
-rw-r--r--unittests/IR/ValueMapTest.cpp3
-rw-r--r--unittests/LineEditor/LineEditor.cpp2
-rw-r--r--unittests/Linker/LinkModulesTest.cpp9
-rw-r--r--unittests/Makefile5
-rw-r--r--unittests/Option/OptionParsingTest.cpp14
-rw-r--r--unittests/Option/Opts.td2
-rw-r--r--unittests/ProfileData/CMakeLists.txt10
-rw-r--r--unittests/ProfileData/CoverageMappingTest.cpp291
-rw-r--r--unittests/ProfileData/InstrProfTest.cpp98
-rw-r--r--unittests/ProfileData/Makefile15
-rw-r--r--unittests/Support/AlignOfTest.cpp56
-rw-r--r--unittests/Support/AllocatorTest.cpp7
-rw-r--r--unittests/Support/BlockFrequencyTest.cpp9
-rw-r--r--unittests/Support/CMakeLists.txt5
-rw-r--r--unittests/Support/Casting.cpp2
-rw-r--r--unittests/Support/CommandLineTest.cpp51
-rw-r--r--unittests/Support/ConvertUTFTest.cpp14
-rw-r--r--unittests/Support/DwarfTest.cpp141
-rw-r--r--unittests/Support/EndianStreamTest.cpp157
-rw-r--r--unittests/Support/ErrorOrTest.cpp5
-rw-r--r--unittests/Support/Makefile2
-rw-r--r--unittests/Support/MathExtrasTest.cpp11
-rw-r--r--unittests/Support/MemoryBufferTest.cpp2
-rw-r--r--unittests/Support/Path.cpp51
-rw-r--r--unittests/Support/ScaledNumberTest.cpp31
-rw-r--r--unittests/Support/SpecialCaseListTest.cpp38
-rw-r--r--unittests/Support/StreamingMemoryObject.cpp9
-rw-r--r--unittests/Support/SwapByteOrderTest.cpp25
-rw-r--r--unittests/Support/TargetRegistry.cpp42
-rw-r--r--unittests/Support/YAMLIOTest.cpp376
-rw-r--r--unittests/Support/YAMLParserTest.cpp43
-rw-r--r--unittests/Support/raw_ostream_test.cpp2
-rw-r--r--unittests/Support/raw_pwrite_stream_test.cpp64
-rw-r--r--unittests/Transforms/CMakeLists.txt1
-rw-r--r--unittests/Transforms/IPO/CMakeLists.txt9
-rw-r--r--unittests/Transforms/IPO/LowerBitSets.cpp155
-rw-r--r--unittests/Transforms/IPO/Makefile15
-rw-r--r--unittests/Transforms/Makefile2
-rw-r--r--unittests/Transforms/Utils/CMakeLists.txt1
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp109
-rw-r--r--unittests/Transforms/Utils/ValueMapperTest.cpp27
103 files changed, 5765 insertions, 486 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
index 8b82fb2f4ed6f..a4445f6e4651c 100644
--- a/unittests/ADT/APFloatTest.cpp
+++ b/unittests/ADT/APFloatTest.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
+#include <cmath>
#include <ostream>
#include <string>
@@ -1305,13 +1306,13 @@ TEST(APFloatTest, roundToIntegral) {
EXPECT_EQ(-0.0, P.convertToDouble());
P = APFloat::getNaN(APFloat::IEEEdouble);
P.roundToIntegral(APFloat::rmTowardZero);
- EXPECT_TRUE(IsNAN(P.convertToDouble()));
+ EXPECT_TRUE(std::isnan(P.convertToDouble()));
P = APFloat::getInf(APFloat::IEEEdouble);
P.roundToIntegral(APFloat::rmTowardZero);
- EXPECT_TRUE(IsInf(P.convertToDouble()) && P.convertToDouble() > 0.0);
+ EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0);
P = APFloat::getInf(APFloat::IEEEdouble, true);
P.roundToIntegral(APFloat::rmTowardZero);
- EXPECT_TRUE(IsInf(P.convertToDouble()) && P.convertToDouble() < 0.0);
+ EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
}
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 3b7ac5b894029..498f50c9c81ff 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -209,6 +209,103 @@ TEST(APIntTest, i1) {
}
}
+
+// Tests different div/rem varaints using scheme (a * b + c) / a
+void testDiv(APInt a, APInt b, APInt c) {
+ ASSERT_TRUE(a.uge(b)); // Must: a >= b
+ ASSERT_TRUE(a.ugt(c)); // Must: a > c
+
+ auto p = a * b + c;
+
+ auto q = p.udiv(a);
+ auto r = p.urem(a);
+ EXPECT_EQ(b, q);
+ EXPECT_EQ(c, r);
+ APInt::udivrem(p, a, q, r);
+ EXPECT_EQ(b, q);
+ EXPECT_EQ(c, r);
+ q = p.sdiv(a);
+ r = p.srem(a);
+ EXPECT_EQ(b, q);
+ EXPECT_EQ(c, r);
+ APInt::sdivrem(p, a, q, r);
+ EXPECT_EQ(b, q);
+ EXPECT_EQ(c, r);
+
+ if (b.ugt(c)) { // Test also symmetric case
+ q = p.udiv(b);
+ r = p.urem(b);
+ EXPECT_EQ(a, q);
+ EXPECT_EQ(c, r);
+ APInt::udivrem(p, b, q, r);
+ EXPECT_EQ(a, q);
+ EXPECT_EQ(c, r);
+ q = p.sdiv(b);
+ r = p.srem(b);
+ EXPECT_EQ(a, q);
+ EXPECT_EQ(c, r);
+ APInt::sdivrem(p, b, q, r);
+ EXPECT_EQ(a, q);
+ EXPECT_EQ(c, r);
+ }
+}
+
+TEST(APIntTest, divrem_big1) {
+ // Tests KnuthDiv rare step D6
+ testDiv({256, "1ffffffffffffffff", 16},
+ {256, "1ffffffffffffffff", 16},
+ {256, 0});
+}
+
+TEST(APIntTest, divrem_big2) {
+ // Tests KnuthDiv rare step D6
+ testDiv({1024, "112233ceff"
+ "cecece000000ffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffff33", 16},
+ {1024, "111111ffffffffffffffff"
+ "ffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffccf"
+ "ffffffffffffffffffffffffffffff00", 16},
+ {1024, 7919});
+}
+
+TEST(APIntTest, divrem_big3) {
+ // Tests KnuthDiv case without shift
+ testDiv({256, "80000001ffffffffffffffff", 16},
+ {256, "ffffffffffffff0000000", 16},
+ {256, 4219});
+}
+
+TEST(APIntTest, divrem_big4) {
+ // Tests heap allocation in divide() enfoced by huge numbers
+ testDiv(APInt{4096, 5}.shl(2001),
+ APInt{4096, 1}.shl(2000),
+ APInt{4096, 4219*13});
+}
+
+TEST(APIntTest, divrem_big5) {
+ // Tests one word divisor case of divide()
+ testDiv(APInt{1024, 19}.shl(811),
+ APInt{1024, 4356013}, // one word
+ APInt{1024, 1});
+}
+
+TEST(APIntTest, divrem_big6) {
+ // Tests some rare "borrow" cases in D4 step
+ testDiv(APInt{512, "ffffffffffffffff00000000000000000000000001", 16},
+ APInt{512, "10000000000000001000000000000001", 16},
+ APInt{512, "10000000000000000000000000000000", 16});
+}
+
+TEST(APIntTest, divrem_big7) {
+ // Yet another test for KnuthDiv rare step D6.
+ testDiv({224, "800000008000000200000005", 16},
+ {224, "fffffffd", 16},
+ {224, "80000000800000010000000f", 16});
+}
+
TEST(APIntTest, fromString) {
EXPECT_EQ(APInt(32, 0), APInt(32, "0", 2));
EXPECT_EQ(APInt(32, 1), APInt(32, "1", 2));
@@ -678,6 +775,46 @@ TEST(APIntTest, nearestLogBase2) {
EXPECT_EQ(A9.nearestLogBase2(), UINT32_MAX);
}
+TEST(APIntTest, IsSplat) {
+ APInt A(32, 0x01010101);
+ EXPECT_FALSE(A.isSplat(1));
+ EXPECT_FALSE(A.isSplat(2));
+ EXPECT_FALSE(A.isSplat(4));
+ EXPECT_TRUE(A.isSplat(8));
+ EXPECT_TRUE(A.isSplat(16));
+ EXPECT_TRUE(A.isSplat(32));
+
+ APInt B(24, 0xAAAAAA);
+ EXPECT_FALSE(B.isSplat(1));
+ EXPECT_TRUE(B.isSplat(2));
+ EXPECT_TRUE(B.isSplat(4));
+ EXPECT_TRUE(B.isSplat(8));
+ EXPECT_TRUE(B.isSplat(24));
+
+ APInt C(24, 0xABAAAB);
+ EXPECT_FALSE(C.isSplat(1));
+ EXPECT_FALSE(C.isSplat(2));
+ EXPECT_FALSE(C.isSplat(4));
+ EXPECT_FALSE(C.isSplat(8));
+ EXPECT_TRUE(C.isSplat(24));
+
+ APInt D(32, 0xABBAABBA);
+ EXPECT_FALSE(D.isSplat(1));
+ EXPECT_FALSE(D.isSplat(2));
+ EXPECT_FALSE(D.isSplat(4));
+ EXPECT_FALSE(D.isSplat(8));
+ EXPECT_TRUE(D.isSplat(16));
+ EXPECT_TRUE(D.isSplat(32));
+
+ APInt E(32, 0);
+ EXPECT_TRUE(E.isSplat(1));
+ EXPECT_TRUE(E.isSplat(2));
+ EXPECT_TRUE(E.isSplat(4));
+ EXPECT_TRUE(E.isSplat(8));
+ EXPECT_TRUE(E.isSplat(16));
+ EXPECT_TRUE(E.isSplat(32));
+}
+
#if defined(__clang__)
// Disable the pragma warning from versions of Clang without -Wself-move
#pragma clang diagnostic push
diff --git a/unittests/ADT/APSIntTest.cpp b/unittests/ADT/APSIntTest.cpp
index eef9c8a90af98..5e4e87440bdb7 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 f9c98a563fa3c..6955036f11319 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
@@ -56,24 +57,24 @@ TEST(ArrayRefTest, DropBack) {
TEST(ArrayRefTest, Equals) {
static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};
ArrayRef<int> AR1(A1);
- EXPECT_TRUE(AR1.equals(1, 2, 3, 4, 5, 6, 7, 8));
- EXPECT_FALSE(AR1.equals(8, 1, 2, 4, 5, 6, 6, 7));
- EXPECT_FALSE(AR1.equals(2, 4, 5, 6, 6, 7, 8, 1));
- EXPECT_FALSE(AR1.equals(0, 1, 2, 4, 5, 6, 6, 7));
- EXPECT_FALSE(AR1.equals(1, 2, 42, 4, 5, 6, 7, 8));
- EXPECT_FALSE(AR1.equals(42, 2, 3, 4, 5, 6, 7, 8));
- EXPECT_FALSE(AR1.equals(1, 2, 3, 4, 5, 6, 7, 42));
- EXPECT_FALSE(AR1.equals(1, 2, 3, 4, 5, 6, 7));
- EXPECT_FALSE(AR1.equals(1, 2, 3, 4, 5, 6, 7, 8, 9));
+ EXPECT_TRUE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 8}));
+ EXPECT_FALSE(AR1.equals({8, 1, 2, 4, 5, 6, 6, 7}));
+ EXPECT_FALSE(AR1.equals({2, 4, 5, 6, 6, 7, 8, 1}));
+ EXPECT_FALSE(AR1.equals({0, 1, 2, 4, 5, 6, 6, 7}));
+ EXPECT_FALSE(AR1.equals({1, 2, 42, 4, 5, 6, 7, 8}));
+ EXPECT_FALSE(AR1.equals({42, 2, 3, 4, 5, 6, 7, 8}));
+ EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 42}));
+ EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7}));
+ EXPECT_FALSE(AR1.equals({1, 2, 3, 4, 5, 6, 7, 8, 9}));
ArrayRef<int> AR1a = AR1.drop_back();
- EXPECT_TRUE(AR1a.equals(1, 2, 3, 4, 5, 6, 7));
- EXPECT_FALSE(AR1a.equals(1, 2, 3, 4, 5, 6, 7, 8));
+ EXPECT_TRUE(AR1a.equals({1, 2, 3, 4, 5, 6, 7}));
+ EXPECT_FALSE(AR1a.equals({1, 2, 3, 4, 5, 6, 7, 8}));
ArrayRef<int> AR1b = AR1a.slice(2, 4);
- EXPECT_TRUE(AR1b.equals(3, 4, 5, 6));
- EXPECT_FALSE(AR1b.equals(2, 3, 4, 5, 6));
- EXPECT_FALSE(AR1b.equals(3, 4, 5, 6, 7));
+ EXPECT_TRUE(AR1b.equals({3, 4, 5, 6}));
+ EXPECT_FALSE(AR1b.equals({2, 3, 4, 5, 6}));
+ EXPECT_FALSE(AR1b.equals({3, 4, 5, 6, 7}));
}
TEST(ArrayRefTest, EmptyEquals) {
@@ -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/DAGDeltaAlgorithmTest.cpp b/unittests/ADT/DAGDeltaAlgorithmTest.cpp
index 370b7c20a0934..190df7f574707 100644
--- a/unittests/ADT/DAGDeltaAlgorithmTest.cpp
+++ b/unittests/ADT/DAGDeltaAlgorithmTest.cpp
@@ -22,7 +22,7 @@ class FixedDAGDeltaAlgorithm : public DAGDeltaAlgorithm {
unsigned NumTests;
protected:
- virtual bool ExecuteOneTest(const changeset_ty &Changes) {
+ bool ExecuteOneTest(const changeset_ty &Changes) override {
++NumTests;
return std::includes(Changes.begin(), Changes.end(),
FailingSet.begin(), FailingSet.end());
diff --git a/unittests/ADT/DeltaAlgorithmTest.cpp b/unittests/ADT/DeltaAlgorithmTest.cpp
index a1884cd8f3a14..bed57b1a17254 100644
--- a/unittests/ADT/DeltaAlgorithmTest.cpp
+++ b/unittests/ADT/DeltaAlgorithmTest.cpp
@@ -32,12 +32,12 @@ std::ostream &operator<<(std::ostream &OS,
namespace {
-class FixedDeltaAlgorithm : public DeltaAlgorithm {
+class FixedDeltaAlgorithm final : public DeltaAlgorithm {
changeset_ty FailingSet;
unsigned NumTests;
protected:
- virtual bool ExecuteOneTest(const changeset_ty &Changes) {
+ bool ExecuteOneTest(const changeset_ty &Changes) override {
++NumTests;
return std::includes(Changes.begin(), Changes.end(),
FailingSet.begin(), FailingSet.end());
diff --git a/unittests/ADT/DenseMapTest.cpp b/unittests/ADT/DenseMapTest.cpp
index f4979839c78d5..97807771725d4 100644
--- a/unittests/ADT/DenseMapTest.cpp
+++ b/unittests/ADT/DenseMapTest.cpp
@@ -46,6 +46,7 @@ public:
CtorTester(const CtorTester &Arg) : Value(Arg.Value) {
EXPECT_TRUE(Constructed.insert(this).second);
}
+ CtorTester &operator=(const CtorTester &) = default;
~CtorTester() {
EXPECT_EQ(1u, Constructed.erase(this));
}
diff --git a/unittests/ADT/HashingTest.cpp b/unittests/ADT/HashingTest.cpp
index acaa83cddddd8..b28561bd01155 100644
--- a/unittests/ADT/HashingTest.cpp
+++ b/unittests/ADT/HashingTest.cpp
@@ -33,7 +33,6 @@ struct LargeTestInteger { uint64_t arr[8]; };
struct NonPOD {
uint64_t x, y;
NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
- ~NonPOD() {}
friend hash_code hash_value(const NonPOD &obj) {
return hash_combine(obj.x, obj.y);
}
@@ -421,4 +420,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 2caa8c7b5bb5c..ff8464293c79c 100644
--- a/unittests/ADT/MapVectorTest.cpp
+++ b/unittests/ADT/MapVectorTest.cpp
@@ -14,6 +14,31 @@
using namespace llvm;
+TEST(MapVectorTest, swap) {
+ MapVector<int, int> MV1, MV2;
+ std::pair<MapVector<int, int>::iterator, bool> R;
+
+ R = MV1.insert(std::make_pair(1, 2));
+ ASSERT_EQ(R.first, MV1.begin());
+ EXPECT_EQ(R.first->first, 1);
+ EXPECT_EQ(R.first->second, 2);
+ EXPECT_TRUE(R.second);
+
+ EXPECT_FALSE(MV1.empty());
+ EXPECT_TRUE(MV2.empty());
+ MV2.swap(MV1);
+ EXPECT_TRUE(MV1.empty());
+ EXPECT_FALSE(MV2.empty());
+
+ auto I = MV1.find(1);
+ ASSERT_EQ(MV1.end(), I);
+
+ I = MV2.find(1);
+ ASSERT_EQ(I, MV2.begin());
+ EXPECT_EQ(I->first, 1);
+ EXPECT_EQ(I->second, 2);
+}
+
TEST(MapVectorTest, insert_pop) {
MapVector<int, int> MV;
std::pair<MapVector<int, int>::iterator, bool> R;
diff --git a/unittests/ADT/OptionalTest.cpp b/unittests/ADT/OptionalTest.cpp
index cadadced13972..92c4eec487a67 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 296d47590d788..0bbcd9f869eca 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/SCCIteratorTest.cpp b/unittests/ADT/SCCIteratorTest.cpp
index 3f1ba1c5843f6..da8c04483f9ca 100644
--- a/unittests/ADT/SCCIteratorTest.cpp
+++ b/unittests/ADT/SCCIteratorTest.cpp
@@ -39,8 +39,6 @@ public:
NodeSubset() : Elements(0) {
assert(N <= sizeof(BitVector)*CHAR_BIT && "Graph too big!");
}
- /// NodeSubset - Copy constructor.
- NodeSubset(const NodeSubset &other) : Elements(other.Elements) {}
/// Comparison operators.
bool operator==(const NodeSubset &other) const {
@@ -252,7 +250,7 @@ TEST(SCCIteratorTest, AllSmallGraphs) {
typedef Graph<NUM_NODES> GT;
/// Enumerate all graphs using NUM_GRAPHS bits.
- assert(NUM_GRAPHS < sizeof(unsigned) * CHAR_BIT && "Too many graphs!");
+ static_assert(NUM_GRAPHS < sizeof(unsigned) * CHAR_BIT, "Too many graphs!");
for (unsigned GraphDescriptor = 0; GraphDescriptor < (1U << NUM_GRAPHS);
++GraphDescriptor) {
GT G;
diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp
index ba6c395e69fa1..46f7021ac165d 100644
--- a/unittests/ADT/SmallVectorTest.cpp
+++ b/unittests/ADT/SmallVectorTest.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "gtest/gtest.h"
@@ -144,8 +145,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 +154,11 @@ 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();
- }
+ void SetUp() override { Constructable::reset(); }
+ template <typename VectorT>
void assertEmpty(VectorT & v) {
// Size tests
EXPECT_EQ(0u, v.size());
@@ -173,7 +168,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 +184,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 +192,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 +670,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) {}
@@ -717,8 +784,8 @@ template <int I> struct EmplaceableArg {
explicit EmplaceableArg(bool) : State(EAS_Arg) {}
private:
- EmplaceableArg &operator=(EmplaceableArg &&) LLVM_DELETED_FUNCTION;
- EmplaceableArg &operator=(const EmplaceableArg &) LLVM_DELETED_FUNCTION;
+ EmplaceableArg &operator=(EmplaceableArg &&) = delete;
+ EmplaceableArg &operator=(const EmplaceableArg &) = delete;
};
enum EmplaceableState { ES_Emplaced, ES_Moved };
@@ -758,8 +825,8 @@ struct Emplaceable {
}
private:
- Emplaceable(const Emplaceable &) LLVM_DELETED_FUNCTION;
- Emplaceable &operator=(const Emplaceable &) LLVM_DELETED_FUNCTION;
+ Emplaceable(const Emplaceable &) = delete;
+ Emplaceable &operator=(const Emplaceable &) = delete;
};
TEST(SmallVectorTest, EmplaceBack) {
@@ -827,6 +894,32 @@ TEST(SmallVectorTest, EmplaceBack) {
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]);
+ }
+}
+
+TEST(SmallVectorTest, InitializerList) {
+ SmallVector<int, 2> V1 = {};
+ EXPECT_TRUE(V1.empty());
+ V1 = {0, 0};
+ EXPECT_TRUE(makeArrayRef(V1).equals({0, 0}));
+ V1 = {-1, -1};
+ EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1}));
+
+ SmallVector<int, 2> V2 = {1, 2, 3, 4};
+ EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4}));
+ V2.assign({4});
+ EXPECT_TRUE(makeArrayRef(V2).equals({4}));
+ V2.append({3, 2});
+ EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2}));
+ V2.insert(V2.begin() + 1, 5);
+ EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2}));
}
} // end namespace
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 33d668fe2ddf9..4ed0b76f0f41a 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 a402e8be9df6d..294dfac0c6336 100644
--- a/unittests/ADT/TinyPtrVectorTest.cpp
+++ b/unittests/ADT/TinyPtrVectorTest.cpp
@@ -438,3 +438,24 @@ TEST(TinyPtrVectorTest, ArrayRefCtorTest) {
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 1f9aa32aeab01..b0f01b26e7229 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -129,6 +129,18 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownOS, T.getOS());
EXPECT_EQ(Triple::EABI, T.getEnvironment());
+ T = Triple("armv6hl-none-linux-gnueabi");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ EXPECT_EQ(Triple::Linux, T.getOS());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::GNUEABI, T.getEnvironment());
+
+ T = Triple("armv7hl-none-linux-gnueabi");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ EXPECT_EQ(Triple::Linux, T.getOS());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::GNUEABI, T.getEnvironment());
+
T = Triple("amdil-unknown-unknown");
EXPECT_EQ(Triple::amdil, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
@@ -149,6 +161,11 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::UnknownOS, T.getOS());
+ T = Triple("sparcel-unknown-unknown");
+ EXPECT_EQ(Triple::sparcel, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
+
T = Triple("spir-unknown-unknown");
EXPECT_EQ(Triple::spir, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
@@ -159,6 +176,12 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::UnknownOS, T.getOS());
+ T = Triple("x86_64-unknown-cloudabi");
+ EXPECT_EQ(Triple::x86_64, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::CloudABI, T.getOS());
+ EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
}
@@ -214,12 +237,12 @@ TEST(TripleTest, Normalization) {
// Check that normalizing a permutated set of valid components returns a
// triple with the unpermuted components.
StringRef C[4];
- for (int Arch = 1+Triple::UnknownArch; Arch <= Triple::amdil; ++Arch) {
+ for (int Arch = 1+Triple::UnknownArch; Arch <= Triple::LastArchType; ++Arch) {
C[0] = Triple::getArchTypeName(Triple::ArchType(Arch));
- for (int Vendor = 1+Triple::UnknownVendor; Vendor <= Triple::PC;
+ for (int Vendor = 1+Triple::UnknownVendor; Vendor <= Triple::LastVendorType;
++Vendor) {
C[1] = Triple::getVendorTypeName(Triple::VendorType(Vendor));
- for (int OS = 1+Triple::UnknownOS; OS <= Triple::Minix; ++OS) {
+ for (int OS = 1+Triple::UnknownOS; OS <= Triple::LastOSType; ++OS) {
if (OS == Triple::Win32)
continue;
@@ -234,7 +257,7 @@ TEST(TripleTest, Normalization) {
EXPECT_EQ(E, Triple::normalize(Join(C[2], C[0], C[1])));
EXPECT_EQ(E, Triple::normalize(Join(C[2], C[1], C[0])));
- for (int Env = 1 + Triple::UnknownEnvironment; Env <= Triple::Android;
+ for (int Env = 1 + Triple::UnknownEnvironment; Env <= Triple::LastEnvironmentType;
++Env) {
C[3] = Triple::getEnvironmentTypeName(Triple::EnvironmentType(Env));
@@ -401,6 +424,21 @@ TEST(TripleTest, BitWidthPredicates) {
EXPECT_FALSE(T.isArch16Bit());
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());
+
+ T.setArch(Triple::sparc);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::sparcel);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_TRUE(T.isArch32Bit());
+ EXPECT_FALSE(T.isArch64Bit());
+
+ T.setArch(Triple::sparcv9);
+ EXPECT_FALSE(T.isArch16Bit());
+ EXPECT_FALSE(T.isArch32Bit());
+ EXPECT_TRUE(T.isArch64Bit());
}
TEST(TripleTest, BitWidthArchVariants) {
@@ -650,20 +688,177 @@ TEST(TripleTest, NormalizeWindows) {
}
TEST(TripleTest, getARMCPUForArch) {
+ // Standard ARM Architectures.
+ {
+ llvm::Triple Triple("armv4-unknown-eabi");
+ EXPECT_STREQ("strongarm", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv4t-unknown-eabi");
+ EXPECT_STREQ("arm7tdmi", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv5-unknown-eabi");
+ EXPECT_STREQ("arm10tdmi", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv5t-unknown-eabi");
+ EXPECT_STREQ("arm10tdmi", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv5e-unknown-eabi");
+ EXPECT_STREQ("arm1022e", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv5tej-unknown-eabi");
+ EXPECT_STREQ("arm926ej-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6-unknown-eabi");
+ EXPECT_STREQ("arm1136jf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6j-unknown-eabi");
+ EXPECT_STREQ("arm1136j-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6k-unknown-eabi");
+ EXPECT_STREQ("arm1176jzf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6zk-unknown-eabi");
+ EXPECT_STREQ("arm1176jzf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6t2-unknown-eabi");
+ EXPECT_STREQ("arm1156t2-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6m-unknown-eabi");
+ EXPECT_STREQ("cortex-m0", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7-unknown-eabi");
+ EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7a-unknown-eabi");
+ EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7m-unknown-eabi");
+ EXPECT_STREQ("cortex-m3", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7r-unknown-eabi");
+ EXPECT_STREQ("cortex-r4", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7r-unknown-eabi");
+ EXPECT_STREQ("cortex-r4", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7r-unknown-eabi");
+ EXPECT_STREQ("cortex-r4", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7r-unknown-eabi");
+ EXPECT_STREQ("cortex-r4", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv8a-unknown-eabi");
+ EXPECT_STREQ("cortex-a53", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv8.1a-unknown-eabi");
+ EXPECT_STREQ("generic", Triple.getARMCPUForArch());
+ }
+ // Non-synonym names, using -march style, not default arch.
+ {
+ llvm::Triple Triple("arm");
+ EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch("armv7-a"));
+ }
+ {
+ llvm::Triple Triple("arm");
+ EXPECT_STREQ("cortex-m3", Triple.getARMCPUForArch("armv7-m"));
+ }
+ {
+ llvm::Triple Triple("arm");
+ EXPECT_STREQ("cortex-a53", Triple.getARMCPUForArch("armv8"));
+ }
+ {
+ llvm::Triple Triple("arm");
+ EXPECT_STREQ("cortex-a53", Triple.getARMCPUForArch("armv8-a"));
+ }
+ // Platform specific defaults.
+ {
+ llvm::Triple Triple("arm--nacl");
+ EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch());
+ }
{
llvm::Triple Triple("armv6-unknown-freebsd");
EXPECT_STREQ("arm1176jzf-s", Triple.getARMCPUForArch());
}
{
+ llvm::Triple Triple("arm--win32");
+ EXPECT_STREQ("cortex-a9", Triple.getARMCPUForArch());
+ }
+ // Some alternative architectures
+ {
+ llvm::Triple Triple("xscale-unknown-eabi");
+ EXPECT_STREQ("xscale", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("iwmmxt-unknown-eabi");
+ EXPECT_STREQ("iwmmxt", Triple.getARMCPUForArch());
+ }
+ {
llvm::Triple Triple("armv7s-apple-ios7");
EXPECT_STREQ("swift", Triple.getARMCPUForArch());
}
{
- llvm::Triple Triple("armv7-apple-ios7");
+ llvm::Triple Triple("armv7em-apple-ios7");
+ EXPECT_STREQ("cortex-m4", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv7l-linux-gnueabihf");
EXPECT_STREQ("cortex-a8", Triple.getARMCPUForArch());
- EXPECT_STREQ("swift", Triple.getARMCPUForArch("armv7s"));
}
-}
+ {
+ llvm::Triple Triple("armv6sm-apple-ios7");
+ EXPECT_STREQ("cortex-m0", Triple.getARMCPUForArch());
+ }
+ // armeb is permitted, but armebeb is not
+ {
+ llvm::Triple Triple("armeb-none-eabi");
+ EXPECT_STREQ("arm7tdmi", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armebeb-none-eabi");
+ EXPECT_EQ(nullptr, Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armebv6eb-none-eabi");
+ EXPECT_EQ(nullptr, Triple.getARMCPUForArch());
+ }
+ // armebv6 and armv6eb are permitted, but armebv6eb is not
+ {
+ llvm::Triple Triple("armebv6-non-eabi");
+ EXPECT_STREQ("arm1136jf-s", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armv6eb-none-eabi");
+ EXPECT_STREQ("arm1136jf-s", Triple.getARMCPUForArch());
+ }
+ // xscaleeb is permitted, but armebxscale is not
+ {
+ llvm::Triple Triple("xscaleeb-none-eabi");
+ EXPECT_STREQ("xscale", Triple.getARMCPUForArch());
+ }
+ {
+ llvm::Triple Triple("armebxscale-none-eabi");
+ EXPECT_EQ(nullptr, Triple.getARMCPUForArch());
+ }
}
TEST(TripleTest, NormalizeARM) {
@@ -682,3 +877,90 @@ TEST(TripleTest, NormalizeARM) {
T = Triple("armv6eb--netbsd-eabi");
EXPECT_EQ(Triple::armeb, T.getArch());
}
+
+TEST(TripleTest, ParseARMArch) {
+ // ARM
+ {
+ Triple T = Triple("arm");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ }
+ {
+ Triple T = Triple("armv6t2");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ }
+ {
+ Triple T = Triple("armv8");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ }
+ {
+ Triple T = Triple("armeb");
+ EXPECT_EQ(Triple::armeb, T.getArch());
+ }
+ {
+ Triple T = Triple("armv5eb");
+ EXPECT_EQ(Triple::armeb, T.getArch());
+ }
+ {
+ Triple T = Triple("armebv7m");
+ EXPECT_EQ(Triple::armeb, T.getArch());
+ }
+ {
+ Triple T = Triple("armv7eb");
+ EXPECT_EQ(Triple::armeb, T.getArch());
+ }
+ // THUMB
+ {
+ Triple T = Triple("thumb");
+ EXPECT_EQ(Triple::thumb, T.getArch());
+ }
+ {
+ Triple T = Triple("thumbv7a");
+ EXPECT_EQ(Triple::thumb, T.getArch());
+ }
+ {
+ Triple T = Triple("thumbeb");
+ EXPECT_EQ(Triple::thumbeb, T.getArch());
+ }
+ {
+ Triple T = Triple("thumbv4teb");
+ EXPECT_EQ(Triple::thumbeb, T.getArch());
+ }
+ {
+ Triple T = Triple("thumbebv7");
+ EXPECT_EQ(Triple::thumbeb, T.getArch());
+ }
+ {
+ Triple T = Triple("armv6m");
+ EXPECT_EQ(Triple::thumb, T.getArch());
+ }
+ {
+ Triple T = Triple("thumbv2");
+ EXPECT_EQ(Triple::UnknownArch, T.getArch());
+ }
+ {
+ Triple T = Triple("thumbebv6eb");
+ EXPECT_EQ(Triple::UnknownArch, T.getArch());
+ }
+ // AARCH64
+ {
+ Triple T = Triple("arm64");
+ EXPECT_EQ(Triple::aarch64, T.getArch());
+ }
+ {
+ Triple T = Triple("aarch64");
+ EXPECT_EQ(Triple::aarch64, T.getArch());
+ }
+ {
+ Triple T = Triple("aarch64_be");
+ EXPECT_EQ(Triple::aarch64_be, T.getArch());
+ }
+ {
+ Triple T = Triple("aarch64be");
+ EXPECT_EQ(Triple::UnknownArch, T.getArch());
+ }
+ {
+ Triple T = Triple("arm64be");
+ EXPECT_EQ(Triple::UnknownArch, T.getArch());
+ }
+}
+} // end anonymous namespace
diff --git a/unittests/ADT/TwineTest.cpp b/unittests/ADT/TwineTest.cpp
index 39d3b561b6689..9683e97511b6c 100644
--- a/unittests/ADT/TwineTest.cpp
+++ b/unittests/ADT/TwineTest.cpp
@@ -29,6 +29,7 @@ TEST(TwineTest, Construction) {
EXPECT_EQ("hi", Twine(StringRef("hi")).str());
EXPECT_EQ("hi", Twine(StringRef(std::string("hi"))).str());
EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str());
+ EXPECT_EQ("hi", Twine(SmallString<4>("hi")).str());
}
TEST(TwineTest, Numbers) {
@@ -62,6 +63,10 @@ TEST(TwineTest, Concat) {
repr(Twine("hi").concat(Twine())));
EXPECT_EQ("(Twine cstring:\"hi\" empty)",
repr(Twine().concat(Twine("hi"))));
+ EXPECT_EQ("(Twine smallstring:\"hi\" empty)",
+ repr(Twine().concat(Twine(SmallString<5>("hi")))));
+ EXPECT_EQ("(Twine smallstring:\"hey\" cstring:\"there\")",
+ repr(Twine(SmallString<7>("hey")).concat(Twine("there"))));
// Concatenation of unary ropes.
EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")",
@@ -72,6 +77,8 @@ TEST(TwineTest, Concat) {
repr(Twine("a").concat(Twine("b")).concat(Twine("c"))));
EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine cstring:\"b\" cstring:\"c\"))",
repr(Twine("a").concat(Twine("b").concat(Twine("c")))));
+ EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine smallstring:\"b\" cstring:\"c\"))",
+ repr(Twine("a").concat(Twine(SmallString<3>("b")).concat(Twine("c")))));
}
TEST(TwineTest, toNullTerminatedStringRef) {
@@ -79,6 +86,9 @@ TEST(TwineTest, toNullTerminatedStringRef) {
EXPECT_EQ(0, *Twine("hello").toNullTerminatedStringRef(storage).end());
EXPECT_EQ(0,
*Twine(StringRef("hello")).toNullTerminatedStringRef(storage).end());
+ EXPECT_EQ(0, *Twine(SmallString<11>("hello"))
+ .toNullTerminatedStringRef(storage)
+ .end());
}
// I suppose linking in the entire code generator to add a unit test to check
diff --git a/unittests/ADT/ilistTest.cpp b/unittests/ADT/ilistTest.cpp
index 44442ebf75adc..9127b05b4b8fd 100644
--- a/unittests/ADT/ilistTest.cpp
+++ b/unittests/ADT/ilistTest.cpp
@@ -21,7 +21,8 @@ struct Node : ilist_node<Node> {
int Value;
Node() {}
- Node(int _Value) : Value(_Value) {}
+ Node(int Value) : Value(Value) {}
+ Node(const Node&) = default;
~Node() { Value = -1; }
};
diff --git a/unittests/Analysis/AliasAnalysisTest.cpp b/unittests/Analysis/AliasAnalysisTest.cpp
new file mode 100644
index 0000000000000..66ed4637c7ae5
--- /dev/null
+++ b/unittests/Analysis/AliasAnalysisTest.cpp
@@ -0,0 +1,104 @@
+//===--- AliasAnalysisTest.cpp - Mixed TBAA unit tests --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/Support/CommandLine.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace {
+
+class AliasAnalysisTest : public testing::Test {
+protected:
+ AliasAnalysisTest() : M("AliasAnalysisTBAATest", C) {}
+
+ // This is going to check that calling getModRefInfo without a location, and
+ // with a default location, first, doesn't crash, and second, gives the right
+ // answer.
+ void CheckModRef(Instruction *I, AliasAnalysis::ModRefResult Result) {
+ static char ID;
+ class CheckModRefTestPass : public FunctionPass {
+ public:
+ CheckModRefTestPass(Instruction *I, AliasAnalysis::ModRefResult Result)
+ : FunctionPass(ID), ExpectResult(Result), I(I) {}
+ static int initialize() {
+ PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID,
+ nullptr, true, true);
+ PassRegistry::getPassRegistry()->registerPass(*PI, false);
+ initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry());
+ initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry());
+ return 0;
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequiredTransitive<AliasAnalysis>();
+ }
+ bool runOnFunction(Function &) override {
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+ EXPECT_EQ(AA.getModRefInfo(I, AliasAnalysis::Location()), ExpectResult);
+ EXPECT_EQ(AA.getModRefInfo(I), ExpectResult);
+ return false;
+ }
+ AliasAnalysis::ModRefResult ExpectResult;
+ Instruction *I;
+ };
+ static int initialize = CheckModRefTestPass::initialize();
+ (void)initialize;
+ CheckModRefTestPass *P = new CheckModRefTestPass(I, Result);
+ legacy::PassManager PM;
+ PM.add(createBasicAliasAnalysisPass());
+ PM.add(P);
+ PM.run(M);
+ }
+
+ LLVMContext C;
+ Module M;
+};
+
+TEST_F(AliasAnalysisTest, getModRefInfo) {
+ // Setup function.
+ FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(C), std::vector<Type *>(), false);
+ auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+ auto *BB = BasicBlock::Create(C, "entry", F);
+ auto IntType = Type::getInt32Ty(C);
+ auto PtrType = Type::getInt32PtrTy(C);
+ auto *Value = ConstantInt::get(IntType, 42);
+ auto *Addr = ConstantPointerNull::get(PtrType);
+
+ auto *Store1 = new StoreInst(Value, Addr, BB);
+ auto *Load1 = new LoadInst(Addr, "load", BB);
+ auto *Add1 = BinaryOperator::CreateAdd(Value, Value, "add", BB);
+ auto *VAArg1 = new VAArgInst(Addr, PtrType, "vaarg", BB);
+ auto *CmpXChg1 = new AtomicCmpXchgInst(Addr, ConstantInt::get(IntType, 0),
+ ConstantInt::get(IntType, 1),
+ Monotonic, Monotonic, CrossThread, BB);
+ auto *AtomicRMW =
+ new AtomicRMWInst(AtomicRMWInst::Xchg, Addr, ConstantInt::get(IntType, 1),
+ Monotonic, CrossThread, BB);
+
+ ReturnInst::Create(C, nullptr, BB);
+
+ // Check basic results
+ CheckModRef(Store1, AliasAnalysis::ModRefResult::Mod);
+ CheckModRef(Load1, AliasAnalysis::ModRefResult::Ref);
+ CheckModRef(Add1, AliasAnalysis::ModRefResult::NoModRef);
+ CheckModRef(VAArg1, AliasAnalysis::ModRefResult::ModRef);
+ CheckModRef(CmpXChg1, AliasAnalysis::ModRefResult::ModRef);
+ CheckModRef(AtomicRMW, AliasAnalysis::ModRefResult::ModRef);
+}
+
+} // end anonymous namspace
+} // end llvm namespace
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index dba9d4991ec58..b29c168ce08b3 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,23 +72,23 @@ 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;
}
- void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
- AU.addRequired<LoopInfo>();
+ AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
}
- bool runOnFunction(Function &F) {
+ bool runOnFunction(Function &F) override {
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/CMakeLists.txt b/unittests/Analysis/CMakeLists.txt
index baf0c28a8d9cc..35a6d92ce1793 100644
--- a/unittests/Analysis/CMakeLists.txt
+++ b/unittests/Analysis/CMakeLists.txt
@@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_unittest(AnalysisTests
+ AliasAnalysisTest.cpp
CallGraphTest.cpp
CFGTest.cpp
LazyCallGraphTest.cpp
diff --git a/unittests/Analysis/MixedTBAATest.cpp b/unittests/Analysis/MixedTBAATest.cpp
index d7935e35548ac..7b8a25c443892 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 90f6997e98cda..6ce7ff43a312f 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 {
@@ -25,14 +25,14 @@ namespace {
class ScalarEvolutionsTest : public testing::Test {
protected:
ScalarEvolutionsTest() : M("", Context), SE(*new ScalarEvolution) {}
- ~ScalarEvolutionsTest() {
+ ~ScalarEvolutionsTest() override {
// Manually clean up, since we allocated new SCEV objects after the
// pass was finished.
SE.releaseMemory();
}
LLVMContext Context;
Module M;
- PassManager PM;
+ legacy::PassManager PM;
ScalarEvolution &SE;
};
diff --git a/unittests/AsmParser/AsmParserTest.cpp b/unittests/AsmParser/AsmParserTest.cpp
new file mode 100644
index 0000000000000..8847b18716731
--- /dev/null
+++ b/unittests/AsmParser/AsmParserTest.cpp
@@ -0,0 +1,47 @@
+//===- llvm/unittest/AsmParser/AsmParserTest.cpp - asm parser unittests ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(AsmParserTest, NullTerminatedInput) {
+ LLVMContext &Ctx = getGlobalContext();
+ StringRef Source = "; Empty module \n";
+ SMDiagnostic Error;
+ auto Mod = parseAssemblyString(Source, Error, Ctx);
+
+ EXPECT_TRUE(Mod != nullptr);
+ EXPECT_TRUE(Error.getMessage().empty());
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+
+TEST(AsmParserTest, NonNullTerminatedInput) {
+ LLVMContext &Ctx = getGlobalContext();
+ StringRef Source = "; Empty module \n\1\2";
+ SMDiagnostic Error;
+ std::unique_ptr<Module> Mod;
+ EXPECT_DEATH(Mod = parseAssemblyString(Source.substr(0, Source.size() - 2),
+ Error, Ctx),
+ "Buffer is not null terminated!");
+}
+
+#endif
+#endif
+
+} // end anonymous namespace
diff --git a/unittests/AsmParser/CMakeLists.txt b/unittests/AsmParser/CMakeLists.txt
new file mode 100644
index 0000000000000..1920bfaa3aac7
--- /dev/null
+++ b/unittests/AsmParser/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+ AsmParser
+ Core
+ Support
+ )
+
+add_llvm_unittest(AsmParserTests
+ AsmParserTest.cpp
+ )
diff --git a/unittests/AsmParser/Makefile b/unittests/AsmParser/Makefile
new file mode 100644
index 0000000000000..41eadd4304338
--- /dev/null
+++ b/unittests/AsmParser/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/AsmParser/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 = AsmParser
+LINK_COMPONENTS := AsmParser Core Support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Bitcode/BitReaderTest.cpp b/unittests/Bitcode/BitReaderTest.cpp
index 1f28ec6f0d6d9..2e6dd0b499dec 100644
--- a/unittests/Bitcode/BitReaderTest.cpp
+++ b/unittests/Bitcode/BitReaderTest.cpp
@@ -75,13 +75,77 @@ TEST(BitReaderTest, DematerializeFunctionPreservesLinkageType) {
GlobalValue::InternalLinkage);
// Check that the linkage type is preserved after dematerialization.
- M->getFunction("func")->Dematerialize();
+ M->getFunction("func")->dematerialize();
EXPECT_TRUE(M->getFunction("func")->empty());
EXPECT_TRUE(M->getFunction("func")->getLinkage() ==
GlobalValue::InternalLinkage);
EXPECT_FALSE(verifyModule(*M, &dbgs()));
}
+// Tests that lazy evaluation can parse functions out of order.
+TEST(BitReaderTest, MaterializeFunctionsOutOfOrder) {
+ SmallString<1024> Mem;
+ LLVMContext Context;
+ std::unique_ptr<Module> M = getLazyModuleFromAssembly(
+ Context, Mem, "define void @f() {\n"
+ " unreachable\n"
+ "}\n"
+ "define void @g() {\n"
+ " unreachable\n"
+ "}\n"
+ "define void @h() {\n"
+ " unreachable\n"
+ "}\n"
+ "define void @j() {\n"
+ " unreachable\n"
+ "}\n");
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ Function *F = M->getFunction("f");
+ Function *G = M->getFunction("g");
+ Function *H = M->getFunction("h");
+ Function *J = M->getFunction("j");
+
+ // Initially all functions are not materialized (no basic blocks).
+ EXPECT_TRUE(F->empty());
+ EXPECT_TRUE(G->empty());
+ EXPECT_TRUE(H->empty());
+ EXPECT_TRUE(J->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Materialize h.
+ H->materialize();
+ EXPECT_TRUE(F->empty());
+ EXPECT_TRUE(G->empty());
+ EXPECT_FALSE(H->empty());
+ EXPECT_TRUE(J->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Materialize g.
+ G->materialize();
+ EXPECT_TRUE(F->empty());
+ EXPECT_FALSE(G->empty());
+ EXPECT_FALSE(H->empty());
+ EXPECT_TRUE(J->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Materialize j.
+ J->materialize();
+ EXPECT_TRUE(F->empty());
+ EXPECT_FALSE(G->empty());
+ EXPECT_FALSE(H->empty());
+ EXPECT_FALSE(J->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+
+ // Materialize f.
+ F->materialize();
+ EXPECT_FALSE(F->empty());
+ EXPECT_FALSE(G->empty());
+ EXPECT_FALSE(H->empty());
+ EXPECT_FALSE(J->empty());
+ EXPECT_FALSE(verifyModule(*M, &dbgs()));
+}
+
TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
SmallString<1024> Mem;
@@ -96,7 +160,7 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddr) { // PR11677
EXPECT_FALSE(verifyModule(*M, &dbgs()));
// Try (and fail) to dematerialize @func.
- M->getFunction("func")->Dematerialize();
+ M->getFunction("func")->dematerialize();
EXPECT_FALSE(M->getFunction("func")->empty());
}
@@ -127,7 +191,7 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionBefore) {
EXPECT_FALSE(verifyModule(*M, &dbgs()));
// Try (and fail) to dematerialize @func.
- M->getFunction("func")->Dematerialize();
+ M->getFunction("func")->dematerialize();
EXPECT_FALSE(M->getFunction("func")->empty());
EXPECT_FALSE(verifyModule(*M, &dbgs()));
}
@@ -159,7 +223,7 @@ TEST(BitReaderTest, MaterializeFunctionsForBlockAddrInFunctionAfter) {
EXPECT_FALSE(verifyModule(*M, &dbgs()));
// Try (and fail) to dematerialize @func.
- M->getFunction("func")->Dematerialize();
+ M->getFunction("func")->dematerialize();
EXPECT_FALSE(M->getFunction("func")->empty());
EXPECT_FALSE(verifyModule(*M, &dbgs()));
}
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 19c2d24534b20..e5befcec6e0f1 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -13,6 +13,7 @@ endfunction()
add_subdirectory(ADT)
add_subdirectory(Analysis)
+add_subdirectory(AsmParser)
add_subdirectory(Bitcode)
add_subdirectory(CodeGen)
add_subdirectory(DebugInfo)
@@ -22,5 +23,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 efb0920b179fe..c1b11600252b6 100644
--- a/unittests/CodeGen/DIEHashTest.cpp
+++ b/unittests/CodeGen/DIEHashTest.cpp
@@ -10,6 +10,7 @@
#include "llvm/CodeGen/DIE.h"
#include "../lib/CodeGen/AsmPrinter/DIEHash.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Format.h"
@@ -18,7 +19,20 @@
using namespace llvm;
namespace {
-TEST(DIEHashTest, Data1) {
+
+// Test fixture
+class DIEHashTest : public testing::Test {
+ StringMap<DwarfStringPoolEntry> Pool;
+
+public:
+ DIEString getString(StringRef S) {
+ DwarfStringPoolEntry Entry = {nullptr, 1, 1};
+ return DIEString(
+ DwarfStringPoolEntryRef(*Pool.insert(std::make_pair(S, Entry)).first));
+ }
+};
+
+TEST_F(DIEHashTest, Data1) {
DIEHash Hash;
DIE Die(dwarf::DW_TAG_base_type);
DIEInteger Size(4);
@@ -28,7 +42,7 @@ TEST(DIEHashTest, Data1) {
}
// struct {};
-TEST(DIEHashTest, TrivialType) {
+TEST_F(DIEHashTest, TrivialType) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
@@ -43,10 +57,10 @@ TEST(DIEHashTest, TrivialType) {
}
// struct foo { };
-TEST(DIEHashTest, NamedType) {
+TEST_F(DIEHashTest, NamedType) {
DIE Foo(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
- DIEString FooStr(&One, "foo");
+ DIEString FooStr = getString("foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
@@ -57,19 +71,19 @@ TEST(DIEHashTest, NamedType) {
}
// namespace space { struct foo { }; }
-TEST(DIEHashTest, NamespacedType) {
+TEST_F(DIEHashTest, NamespacedType) {
DIE CU(dwarf::DW_TAG_compile_unit);
auto Space = make_unique<DIE>(dwarf::DW_TAG_namespace);
DIEInteger One(1);
- DIEString SpaceStr(&One, "space");
+ DIEString SpaceStr = getString("space");
Space->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &SpaceStr);
// DW_AT_declaration is ignored.
Space->addValue(dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, &One);
// sibling?
auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
- DIEString FooStr(&One, "foo");
+ DIEString FooStr = getString("foo");
Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
@@ -84,13 +98,13 @@ TEST(DIEHashTest, NamespacedType) {
}
// struct { int member; };
-TEST(DIEHashTest, TypeWithMember) {
+TEST_F(DIEHashTest, TypeWithMember) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger Four(4);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
DIE Int(dwarf::DW_TAG_base_type);
- DIEString IntStr(&Four, "int");
+ DIEString IntStr = getString("int");
Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
DIEInteger Five(5);
@@ -99,7 +113,7 @@ TEST(DIEHashTest, TypeWithMember) {
DIEEntry IntRef(Int);
auto Member = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString MemberStr(&Four, "member");
+ DIEString MemberStr = getString("member");
Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
DIEInteger Zero(0);
Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
@@ -114,14 +128,14 @@ TEST(DIEHashTest, TypeWithMember) {
}
// struct foo { int mem1, mem2; };
-TEST(DIEHashTest, ReusedType) {
+TEST_F(DIEHashTest, ReusedType) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger Eight(8);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
DIEInteger Four(4);
DIE Int(dwarf::DW_TAG_base_type);
- DIEString IntStr(&Four, "int");
+ DIEString IntStr = getString("int");
Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
DIEInteger Five(5);
@@ -130,7 +144,7 @@ TEST(DIEHashTest, ReusedType) {
DIEEntry IntRef(Int);
auto Mem1 = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString Mem1Str(&Four, "mem1");
+ DIEString Mem1Str = getString("mem1");
Mem1->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem1Str);
DIEInteger Zero(0);
Mem1->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
@@ -140,7 +154,7 @@ TEST(DIEHashTest, ReusedType) {
Unnamed.addChild(std::move(Mem1));
auto Mem2 = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString Mem2Str(&Four, "mem2");
+ DIEString Mem2Str = getString("mem2");
Mem2->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &Mem2Str);
Mem2->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
&Four);
@@ -154,15 +168,15 @@ TEST(DIEHashTest, ReusedType) {
}
// struct foo { static foo f; };
-TEST(DIEHashTest, RecursiveType) {
+TEST_F(DIEHashTest, RecursiveType) {
DIE Foo(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
- DIEString FooStr(&One, "foo");
+ DIEString FooStr = getString("foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString MemStr(&One, "mem");
+ DIEString MemStr = getString("mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEEntry FooRef(Foo);
Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
@@ -176,15 +190,15 @@ TEST(DIEHashTest, RecursiveType) {
}
// struct foo { foo *mem; };
-TEST(DIEHashTest, Pointer) {
+TEST_F(DIEHashTest, Pointer) {
DIE Foo(dwarf::DW_TAG_structure_type);
DIEInteger Eight(8);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEString FooStr(&Eight, "foo");
+ DIEString FooStr = getString("foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString MemStr(&Eight, "mem");
+ DIEString MemStr = getString("mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
@@ -205,15 +219,15 @@ TEST(DIEHashTest, Pointer) {
}
// struct foo { foo &mem; };
-TEST(DIEHashTest, Reference) {
+TEST_F(DIEHashTest, Reference) {
DIE Foo(dwarf::DW_TAG_structure_type);
DIEInteger Eight(8);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEString FooStr(&Eight, "foo");
+ DIEString FooStr = getString("foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString MemStr(&Eight, "mem");
+ DIEString MemStr = getString("mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
@@ -238,15 +252,15 @@ TEST(DIEHashTest, Reference) {
}
// struct foo { foo &&mem; };
-TEST(DIEHashTest, RValueReference) {
+TEST_F(DIEHashTest, RValueReference) {
DIE Foo(dwarf::DW_TAG_structure_type);
DIEInteger Eight(8);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEString FooStr(&Eight, "foo");
+ DIEString FooStr = getString("foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString MemStr(&Eight, "mem");
+ DIEString MemStr = getString("mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
@@ -271,15 +285,15 @@ TEST(DIEHashTest, RValueReference) {
}
// struct foo { foo foo::*mem; };
-TEST(DIEHashTest, PtrToMember) {
+TEST_F(DIEHashTest, PtrToMember) {
DIE Foo(dwarf::DW_TAG_structure_type);
DIEInteger Eight(8);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
- DIEString FooStr(&Eight, "foo");
+ DIEString FooStr = getString("foo");
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
auto Mem = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString MemStr(&Eight, "mem");
+ DIEString MemStr = getString("mem");
Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
DIEInteger Zero(0);
Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
@@ -305,13 +319,13 @@ TEST(DIEHashTest, PtrToMember) {
//
// struct bar; // { };
// struct foo { bar foo::*mem; };
-TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
+TEST_F(DIEHashTest, PtrToMemberDeclDefMatch) {
DIEInteger Zero(0);
DIEInteger One(1);
DIEInteger Eight(8);
- DIEString FooStr(&Eight, "foo");
- DIEString BarStr(&Eight, "bar");
- DIEString MemStr(&Eight, "mem");
+ DIEString FooStr = getString("foo");
+ DIEString BarStr = getString("bar");
+ DIEString MemStr = getString("mem");
uint64_t MD5ResDecl;
{
DIE Bar(dwarf::DW_TAG_structure_type);
@@ -378,13 +392,13 @@ TEST(DIEHashTest, PtrToMemberDeclDefMatch) {
//
// struct bar; // { };
// struct foo { bar bar::*mem; };
-TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
+TEST_F(DIEHashTest, PtrToMemberDeclDefMisMatch) {
DIEInteger Zero(0);
DIEInteger One(1);
DIEInteger Eight(8);
- DIEString FooStr(&Eight, "foo");
- DIEString BarStr(&Eight, "bar");
- DIEString MemStr(&Eight, "mem");
+ DIEString FooStr = getString("foo");
+ DIEString BarStr = getString("bar");
+ DIEString MemStr = getString("mem");
uint64_t MD5ResDecl;
{
DIE Bar(dwarf::DW_TAG_structure_type);
@@ -451,12 +465,12 @@ TEST(DIEHashTest, PtrToMemberDeclDefMisMatch) {
// struct { } a;
// struct foo { decltype(a) mem; };
-TEST(DIEHashTest, RefUnnamedType) {
+TEST_F(DIEHashTest, RefUnnamedType) {
DIEInteger Zero(0);
DIEInteger One(1);
DIEInteger Eight(8);
- DIEString FooStr(&Zero, "foo");
- DIEString MemStr(&Zero, "mem");
+ DIEString FooStr = getString("foo");
+ DIEString MemStr = getString("mem");
DIE Unnamed(dwarf::DW_TAG_structure_type);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
@@ -485,13 +499,13 @@ TEST(DIEHashTest, RefUnnamedType) {
}
// struct { struct foo { }; };
-TEST(DIEHashTest, NestedType) {
+TEST_F(DIEHashTest, NestedType) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
auto Foo = make_unique<DIE>(dwarf::DW_TAG_structure_type);
- DIEString FooStr(&One, "foo");
+ DIEString FooStr = getString("foo");
Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
@@ -504,13 +518,13 @@ TEST(DIEHashTest, NestedType) {
}
// struct { static void func(); };
-TEST(DIEHashTest, MemberFunc) {
+TEST_F(DIEHashTest, MemberFunc) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
- DIEString FuncStr(&One, "func");
+ DIEString FuncStr = getString("func");
Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
Unnamed.addChild(std::move(Func));
@@ -524,18 +538,18 @@ TEST(DIEHashTest, MemberFunc) {
// struct A {
// static void func();
// };
-TEST(DIEHashTest, MemberFuncFlag) {
+TEST_F(DIEHashTest, MemberFuncFlag) {
DIE A(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
- DIEString AStr(&One, "A");
+ DIEString AStr = getString("A");
A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
auto Func = make_unique<DIE>(dwarf::DW_TAG_subprogram);
- DIEString FuncStr(&One, "func");
- DIEString FuncLinkage(&One, "_ZN1A4funcEv");
+ DIEString FuncStr = getString("func");
+ DIEString FuncLinkage = getString("_ZN1A4funcEv");
DIEInteger Two(2);
Func->addValue(dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, &One);
Func->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FuncStr);
@@ -557,10 +571,10 @@ TEST(DIEHashTest, MemberFuncFlag) {
// const static int PI = -3;
// };
// A a;
-TEST(DIEHashTest, MemberSdata) {
+TEST_F(DIEHashTest, MemberSdata) {
DIE A(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
- DIEString AStr(&One, "A");
+ DIEString AStr = getString("A");
A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
@@ -568,7 +582,7 @@ TEST(DIEHashTest, MemberSdata) {
DIEInteger Four(4);
DIEInteger Five(5);
- DIEString FStr(&One, "int");
+ DIEString FStr = getString("int");
DIE IntTyDIE(dwarf::DW_TAG_base_type);
IntTyDIE.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
IntTyDIE.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
@@ -580,7 +594,7 @@ TEST(DIEHashTest, MemberSdata) {
DIEEntry PITy(*PITyDIE);
auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString PIStr(&One, "PI");
+ DIEString PIStr = getString("PI");
DIEInteger Two(2);
DIEInteger NegThree(-3);
PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
@@ -602,17 +616,17 @@ TEST(DIEHashTest, MemberSdata) {
// const static float PI = 3.14;
// };
// A a;
-TEST(DIEHashTest, MemberBlock) {
+TEST_F(DIEHashTest, MemberBlock) {
DIE A(dwarf::DW_TAG_structure_type);
DIEInteger One(1);
- DIEString AStr(&One, "A");
+ DIEString AStr = getString("A");
A.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &AStr);
A.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
A.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
A.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
DIEInteger Four(4);
- DIEString FStr(&One, "float");
+ DIEString FStr = getString("float");
auto FloatTyDIE = make_unique<DIE>(dwarf::DW_TAG_base_type);
FloatTyDIE->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
FloatTyDIE->addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Four);
@@ -624,7 +638,7 @@ TEST(DIEHashTest, MemberBlock) {
DIEEntry PITy(*PITyDIE);
auto PI = make_unique<DIE>(dwarf::DW_TAG_member);
- DIEString PIStr(&One, "PI");
+ DIEString PIStr = getString("PI");
DIEInteger Two(2);
PI->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &PIStr);
PI->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
diff --git a/unittests/DebugInfo/CMakeLists.txt b/unittests/DebugInfo/CMakeLists.txt
index e844e95251ab2..dae472bafdd71 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 0000000000000..4bec17cbb524c
--- /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/DWARF/DWARFFormValueTest.cpp b/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
new file mode 100644
index 0000000000000..371e2af95decf
--- /dev/null
+++ b/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp
@@ -0,0 +1,124 @@
+//===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/LEB128.h"
+#include "gtest/gtest.h"
+#include <climits>
+using namespace llvm;
+using namespace dwarf;
+
+namespace {
+
+TEST(DWARFFormValue, FixedFormSizes) {
+ // Size of DW_FORM_addr and DW_FORM_ref_addr are equal in DWARF2,
+ // DW_FORM_ref_addr is always 4 bytes in DWARF32 starting from DWARF3.
+ ArrayRef<uint8_t> sizes = DWARFFormValue::getFixedFormSizes(4, 2);
+ EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
+ sizes = DWARFFormValue::getFixedFormSizes(8, 2);
+ EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
+ sizes = DWARFFormValue::getFixedFormSizes(8, 3);
+ EXPECT_EQ(4, sizes[DW_FORM_ref_addr]);
+ // Check that we don't have fixed form sizes for weird address sizes.
+ EXPECT_EQ(0U, DWARFFormValue::getFixedFormSizes(16, 2).size());
+}
+
+bool isFormClass(uint16_t Form, DWARFFormValue::FormClass FC) {
+ return DWARFFormValue(Form).isFormClass(FC);
+}
+
+TEST(DWARFFormValue, FormClass) {
+ EXPECT_TRUE(isFormClass(DW_FORM_addr, DWARFFormValue::FC_Address));
+ EXPECT_FALSE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Address));
+ EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Constant));
+ EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_SectionOffset));
+ EXPECT_TRUE(
+ isFormClass(DW_FORM_sec_offset, DWARFFormValue::FC_SectionOffset));
+ EXPECT_TRUE(isFormClass(DW_FORM_GNU_str_index, DWARFFormValue::FC_String));
+ EXPECT_TRUE(isFormClass(DW_FORM_GNU_addr_index, DWARFFormValue::FC_Address));
+ EXPECT_FALSE(isFormClass(DW_FORM_ref_addr, DWARFFormValue::FC_Address));
+ EXPECT_TRUE(isFormClass(DW_FORM_ref_addr, DWARFFormValue::FC_Reference));
+ EXPECT_TRUE(isFormClass(DW_FORM_ref_sig8, DWARFFormValue::FC_Reference));
+}
+
+template<typename RawTypeT>
+DWARFFormValue createDataXFormValue(uint16_t Form, RawTypeT Value) {
+ char Raw[sizeof(RawTypeT)];
+ memcpy(Raw, &Value, sizeof(RawTypeT));
+ uint32_t Offset = 0;
+ DWARFFormValue Result(Form);
+ DataExtractor Data(StringRef(Raw, sizeof(RawTypeT)),
+ sys::IsLittleEndianHost, sizeof(void*));
+ Result.extractValue(Data, &Offset, nullptr);
+ return Result;
+}
+
+DWARFFormValue createULEBFormValue(uint64_t Value) {
+ SmallString<10> RawData;
+ raw_svector_ostream OS(RawData);
+ encodeULEB128(Value, OS);
+ uint32_t Offset = 0;
+ DWARFFormValue Result(DW_FORM_udata);
+ DataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void*));
+ Result.extractValue(Data, &Offset, nullptr);
+ return Result;
+}
+
+DWARFFormValue createSLEBFormValue(int64_t Value) {
+ SmallString<10> RawData;
+ raw_svector_ostream OS(RawData);
+ encodeSLEB128(Value, OS);
+ uint32_t Offset = 0;
+ DWARFFormValue Result(DW_FORM_sdata);
+ DataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void*));
+ Result.extractValue(Data, &Offset, nullptr);
+ return Result;
+}
+
+TEST(DWARFFormValue, SignedConstantForms) {
+ // Check that we correctly sign extend fixed size forms.
+ auto Sign1 = createDataXFormValue<uint8_t>(DW_FORM_data1, -123);
+ auto Sign2 = createDataXFormValue<uint16_t>(DW_FORM_data2, -12345);
+ auto Sign4 = createDataXFormValue<uint32_t>(DW_FORM_data4, -123456789);
+ auto Sign8 = createDataXFormValue<uint64_t>(DW_FORM_data8, -1);
+ EXPECT_EQ(Sign1.getAsSignedConstant().getValue(), -123);
+ EXPECT_EQ(Sign2.getAsSignedConstant().getValue(), -12345);
+ EXPECT_EQ(Sign4.getAsSignedConstant().getValue(), -123456789);
+ EXPECT_EQ(Sign8.getAsSignedConstant().getValue(), -1);
+
+ // Check that we can handle big positive values, but that we return
+ // an error just over the limit.
+ auto UMax = createULEBFormValue(LLONG_MAX);
+ auto TooBig = createULEBFormValue(uint64_t(LLONG_MAX) + 1);
+ EXPECT_EQ(UMax.getAsSignedConstant().getValue(), LLONG_MAX);
+ EXPECT_EQ(TooBig.getAsSignedConstant().hasValue(), false);
+
+ // Sanity check some other forms.
+ auto Data1 = createDataXFormValue<uint8_t>(DW_FORM_data1, 120);
+ auto Data2 = createDataXFormValue<uint16_t>(DW_FORM_data2, 32000);
+ auto Data4 = createDataXFormValue<uint32_t>(DW_FORM_data4, 2000000000);
+ auto Data8 = createDataXFormValue<uint64_t>(DW_FORM_data8, 0x1234567812345678LL);
+ auto LEBMin = createSLEBFormValue(LLONG_MIN);
+ auto LEBMax = createSLEBFormValue(LLONG_MAX);
+ auto LEB1 = createSLEBFormValue(-42);
+ auto LEB2 = createSLEBFormValue(42);
+ EXPECT_EQ(Data1.getAsSignedConstant().getValue(), 120);
+ EXPECT_EQ(Data2.getAsSignedConstant().getValue(), 32000);
+ EXPECT_EQ(Data4.getAsSignedConstant().getValue(), 2000000000);
+ EXPECT_EQ(Data8.getAsSignedConstant().getValue(), 0x1234567812345678LL);
+ EXPECT_EQ(LEBMin.getAsSignedConstant().getValue(), LLONG_MIN);
+ EXPECT_EQ(LEBMax.getAsSignedConstant().getValue(), LLONG_MAX);
+ EXPECT_EQ(LEB1.getAsSignedConstant().getValue(), -42);
+ EXPECT_EQ(LEB2.getAsSignedConstant().getValue(), 42);
+}
+
+} // end anonymous namespace
diff --git a/unittests/DebugInfo/DWARF/Makefile b/unittests/DebugInfo/DWARF/Makefile
new file mode 100644
index 0000000000000..b0f40e1ca9d94
--- /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/DWARFFormValueTest.cpp b/unittests/DebugInfo/DWARFFormValueTest.cpp
deleted file mode 100644
index 38b932e3c9caf..0000000000000
--- a/unittests/DebugInfo/DWARFFormValueTest.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//===- llvm/unittest/DebugInfo/DWARFFormValueTest.cpp ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARFFormValue.h"
-#include "llvm/Support/Dwarf.h"
-#include "gtest/gtest.h"
-using namespace llvm;
-using namespace dwarf;
-
-namespace {
-
-TEST(DWARFFormValue, FixedFormSizes) {
- // Size of DW_FORM_addr and DW_FORM_ref_addr are equal in DWARF2,
- // DW_FORM_ref_addr is always 4 bytes in DWARF32 starting from DWARF3.
- ArrayRef<uint8_t> sizes = DWARFFormValue::getFixedFormSizes(4, 2);
- EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
- sizes = DWARFFormValue::getFixedFormSizes(8, 2);
- EXPECT_EQ(sizes[DW_FORM_addr], sizes[DW_FORM_ref_addr]);
- sizes = DWARFFormValue::getFixedFormSizes(8, 3);
- EXPECT_EQ(4, sizes[DW_FORM_ref_addr]);
- // Check that we don't have fixed form sizes for weird address sizes.
- EXPECT_EQ(0U, DWARFFormValue::getFixedFormSizes(16, 2).size());
-}
-
-bool isFormClass(uint16_t Form, DWARFFormValue::FormClass FC) {
- return DWARFFormValue(Form).isFormClass(FC);
-}
-
-TEST(DWARFFormValue, FormClass) {
- EXPECT_TRUE(isFormClass(DW_FORM_addr, DWARFFormValue::FC_Address));
- EXPECT_FALSE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Address));
- EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Constant));
- EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_SectionOffset));
- EXPECT_TRUE(
- isFormClass(DW_FORM_sec_offset, DWARFFormValue::FC_SectionOffset));
- EXPECT_TRUE(isFormClass(DW_FORM_GNU_str_index, DWARFFormValue::FC_String));
- EXPECT_TRUE(isFormClass(DW_FORM_GNU_addr_index, DWARFFormValue::FC_Address));
- EXPECT_FALSE(isFormClass(DW_FORM_ref_addr, DWARFFormValue::FC_Address));
- EXPECT_TRUE(isFormClass(DW_FORM_ref_addr, DWARFFormValue::FC_Reference));
- EXPECT_TRUE(isFormClass(DW_FORM_ref_sig8, DWARFFormValue::FC_Reference));
-}
-
-} // end anonymous namespace
diff --git a/unittests/DebugInfo/Makefile b/unittests/DebugInfo/Makefile
index 999ded90b0f68..1889ad22db113 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 0000000000000..91924a5a87544
--- /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 0000000000000..eb118a3fd2bd1
--- /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 0000000000000..ebd3d7bb6b3ca
--- /dev/null
+++ b/unittests/DebugInfo/PDB/PDBApiTest.cpp
@@ -0,0 +1,397 @@
+//===- 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<PDBSymbol>
+ findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override {
+ return nullptr;
+ }
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByAddress(uint64_t Address, uint32_t Length) 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 05e093e0c0b40..302de9943ffe4 100644
--- a/unittests/ExecutionEngine/CMakeLists.txt
+++ b/unittests/ExecutionEngine/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
ExecutionEngine
Interpreter
MC
+ OrcJIT
RuntimeDyld
Support
)
@@ -11,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/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
index 19917a41350c7..bb47c4c00304c 100644
--- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp
+++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -9,6 +9,7 @@
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
@@ -32,7 +33,7 @@ protected:
Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
}
- virtual void SetUp() {
+ void SetUp() override {
ASSERT_TRUE(Engine.get() != nullptr) << "EngineBuilder returned error: '"
<< Error << "'";
}
@@ -53,6 +54,7 @@ TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
int32_t Mem1 = 3;
Engine->addGlobalMapping(G1, &Mem1);
EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
+ EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable("Global1"));
int32_t Mem2 = 4;
Engine->updateGlobalMapping(G1, &Mem2);
EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
index f2a3000906e32..a7c9ae02b384d 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITCAPITest.cpp
@@ -85,13 +85,11 @@ public:
ReservedCodeSize(0), UsedCodeSize(0), ReservedDataSizeRO(0),
UsedDataSizeRO(0), ReservedDataSizeRW(0), UsedDataSizeRW(0) {
}
-
- virtual bool needsToReserveAllocationSpace() {
- return true;
- }
- virtual void reserveAllocationSpace(
- uintptr_t CodeSize, uintptr_t DataSizeRO, uintptr_t DataSizeRW) {
+ bool needsToReserveAllocationSpace() override { return true; }
+
+ void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
+ uintptr_t DataSizeRW) override {
ReservedCodeSize = CodeSize;
ReservedDataSizeRO = DataSizeRO;
ReservedDataSizeRW = DataSizeRW;
@@ -103,15 +101,17 @@ public:
*UsedSize = AlignedBegin + AlignedSize;
}
- virtual uint8_t* allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName, bool IsReadOnly) {
+ uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, StringRef SectionName,
+ bool IsReadOnly) override {
useSpace(IsReadOnly ? &UsedDataSizeRO : &UsedDataSizeRW, Size, Alignment);
return SectionMemoryManager::allocateDataSection(Size, Alignment,
SectionID, SectionName, IsReadOnly);
}
- uint8_t* allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName) {
+ uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) override {
useSpace(&UsedCodeSize, Size, Alignment);
return SectionMemoryManager::allocateCodeSection(Size, Alignment,
SectionID, SectionName);
@@ -141,8 +141,8 @@ protected:
// that they will fail the MCJIT C API tests.
UnsupportedEnvironments.push_back(Triple::Cygnus);
}
-
- virtual void SetUp() {
+
+ void SetUp() override {
didCallAllocateCodeSection = false;
didAllocateCompactUnwindSection = false;
didCallYield = false;
@@ -151,8 +151,8 @@ protected:
Engine = nullptr;
Error = nullptr;
}
-
- virtual void TearDown() {
+
+ void TearDown() override {
if (Engine)
LLVMDisposeExecutionEngine(Engine);
else if (Module)
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITMultipleModuleTest.cpp
index b0d1bb39c7f34..da6e25a3d516b 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 2e38dd88b0fdc..ff5b6e3deccca 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITObjectCacheTest.cpp
@@ -33,7 +33,7 @@ public:
ObjMap[ModuleID] = copyBuffer(Obj);
}
- virtual std::unique_ptr<MemoryBuffer> getObject(const Module* M) override {
+ std::unique_ptr<MemoryBuffer> getObject(const Module *M) override {
const MemoryBuffer* BufferFound = getObjectInternal(M);
ModulesLookedUp.insert(M->getModuleIdentifier());
if (!BufferFound)
@@ -84,7 +84,7 @@ protected:
ReplacementRC = 7
};
- virtual void SetUp() {
+ void SetUp() override {
M.reset(createEmptyModule("<main>"));
Main = insertMainFunction(M.get(), OriginalRC);
}
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
index 64d8c2fca042a..f65ec96d944b9 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp
@@ -22,7 +22,7 @@ namespace {
class MCJITTest : public testing::Test, public MCJITTestBase {
protected:
- virtual void SetUp() { M.reset(createEmptyModule("<main>")); }
+ void SetUp() override { M.reset(createEmptyModule("<main>")); }
};
// FIXME: Ensure creating an execution engine does not crash when constructed
@@ -169,7 +169,7 @@ TEST_F(MCJITTest, multiple_functions) {
std::stringstream funcName;
funcName << "level_" << i;
Outer = startFunction<int32_t(void)>(M.get(), funcName.str());
- Value *innerResult = Builder.CreateCall(Inner);
+ Value *innerResult = Builder.CreateCall(Inner, {});
endFunctionWithRet(Outer, innerResult);
Inner = Outer;
diff --git a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
index 35af417bf1474..901f142d09cdf 100644
--- a/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
+++ b/unittests/ExecutionEngine/MCJIT/MCJITTestBase.h
@@ -308,11 +308,6 @@ protected:
SupportedSubArchs.push_back("armv6");
SupportedSubArchs.push_back("armv7");
- // The operating systems below are known to be incompatible with MCJIT as
- // they are copied from the test/ExecutionEngine/MCJIT/lit.local.cfg and
- // should be kept in sync.
- UnsupportedOSs.push_back(Triple::Darwin);
-
UnsupportedEnvironments.push_back(Triple::Cygnus);
}
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index 8ecb883ba9d7d..c19f8d688d1bc 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 0000000000000..67b215ebc6d4e
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS
+ Core
+ OrcJIT
+ Support
+ )
+
+add_llvm_unittest(OrcJITTests
+ IndirectionUtilsTest.cpp
+ LazyEmittingLayerTest.cpp
+ OrcTestCommon.cpp
+ )
diff --git a/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp b/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
new file mode 100644
index 0000000000000..1a533b05838d9
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/IndirectionUtilsTest.cpp
@@ -0,0 +1,48 @@
+//===- 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 "OrcTestCommon.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(IndirectionUtilsTest, MakeStub) {
+ ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", "");
+ Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>(MB.getModule(), "");
+ SmallVector<AttributeSet, 4> Attrs;
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), 1U,
+ AttrBuilder().addAttribute(Attribute::StructRet)));
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), 2U,
+ AttrBuilder().addAttribute(Attribute::ByVal)));
+ Attrs.push_back(
+ AttributeSet::get(MB.getModule()->getContext(), ~0U,
+ AttrBuilder().addAttribute(Attribute::NoUnwind)));
+ F->setAttributes(AttributeSet::get(MB.getModule()->getContext(), Attrs));
+
+ auto ImplPtr = orc::createImplPointer(*F->getType(), *MB.getModule(), "", nullptr);
+ orc::makeStub(*F, *ImplPtr);
+
+ auto II = F->getEntryBlock().begin();
+ EXPECT_TRUE(isa<LoadInst>(*II)) << "First instruction of stub should be a load.";
+ auto *Call = dyn_cast<CallInst>(std::next(II));
+ EXPECT_TRUE(Call != nullptr) << "Second instruction of stub should be a call.";
+ EXPECT_TRUE(Call->isTailCall()) << "Indirect call from stub should be tail call.";
+ EXPECT_TRUE(Call->hasStructRetAttr())
+ << "makeStub should propagate sret attr on 1st argument.";
+ EXPECT_TRUE(Call->paramHasAttr(2U, Attribute::ByVal))
+ << "makeStub should propagate byval attr on 2nd argument.";
+}
+
+}
diff --git a/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp b/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
new file mode 100644
index 0000000000000..a495766db91a0
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp
@@ -0,0 +1,32 @@
+//===- 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::RuntimeDyld::MemoryManager> MemMgr,
+ std::unique_ptr<llvm::RuntimeDyld::SymbolResolver> Resolver) {
+ EXPECT_FALSE(MemMgr);
+ return 42;
+ }
+};
+
+TEST(LazyEmittingLayerTest, Empty) {
+ MockBaseLayer M;
+ llvm::orc::LazyEmittingLayer<MockBaseLayer> L(M);
+ L.addModuleSet(std::list<std::unique_ptr<llvm::Module>>(), nullptr, nullptr);
+}
+
+}
diff --git a/unittests/ExecutionEngine/Orc/Makefile b/unittests/ExecutionEngine/Orc/Makefile
new file mode 100644
index 0000000000000..c899728e50789
--- /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/ExecutionEngine/Orc/OrcTestCommon.cpp b/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
new file mode 100644
index 0000000000000..5fea3c89f86c2
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.cpp
@@ -0,0 +1,23 @@
+//===--------- OrcTestCommon.cpp - Utilities for Orc Unit Tests -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for Orc unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcTestCommon.h"
+
+using namespace llvm;
+
+ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
+ StringRef Name)
+ : M(new Module(Name, Context)),
+ Builder(Context) {
+ M->setTargetTriple(Triple);
+}
diff --git a/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/unittests/ExecutionEngine/Orc/OrcTestCommon.h
new file mode 100644
index 0000000000000..1b2859b51d094
--- /dev/null
+++ b/unittests/ExecutionEngine/Orc/OrcTestCommon.h
@@ -0,0 +1,66 @@
+//===------ OrcTestCommon.h - Utilities for Orc Unit Tests ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common utilities for the Orc unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
+#define LLVM_UNITTESTS_EXECUTIONENGINE_ORC_ORCTESTCOMMON_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeBuilder.h"
+#include <memory>
+
+namespace llvm {
+
+ class ModuleBuilder {
+ public:
+ ModuleBuilder(LLVMContext &Context, StringRef Triple,
+ StringRef Name);
+
+ template <typename FuncType>
+ Function* createFunctionDecl(Module *M, StringRef Name) {
+ return Function::Create(
+ TypeBuilder<FuncType, false>::get(M->getContext()),
+ GlobalValue::ExternalLinkage, Name, M);
+ }
+
+ Module* getModule() { return M.get(); }
+ const Module* getModule() const { return M.get(); }
+ std::unique_ptr<Module> takeModule() { return std::move(M); }
+
+ private:
+ std::unique_ptr<Module> M;
+ IRBuilder<> Builder;
+ };
+
+ // Dummy struct type.
+ struct DummyStruct {
+ int X[256];
+ };
+
+ // TypeBuilder specialization for DummyStruct.
+ template <bool XCompile>
+ class TypeBuilder<DummyStruct, XCompile> {
+ public:
+ static StructType *get(LLVMContext &Context) {
+ return StructType::get(
+ TypeBuilder<types::i<32>[256], XCompile>::get(Context), nullptr);
+ }
+ };
+
+
+} // namespace llvm
+
+#endif
diff --git a/unittests/IR/ConstantRangeTest.cpp b/unittests/IR/ConstantRangeTest.cpp
index fa03302ad2bb3..de4eec4abf5d3 100644
--- a/unittests/IR/ConstantRangeTest.cpp
+++ b/unittests/IR/ConstantRangeTest.cpp
@@ -400,6 +400,13 @@ TEST_F(ConstantRangeTest, Multiply) {
EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply(
ConstantRange(APInt(4, 6), APInt(4, 2))),
ConstantRange(4, /*isFullSet=*/true));
+
+ EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 0)).multiply(
+ ConstantRange(APInt(8, 252), APInt(8, 4))),
+ ConstantRange(APInt(8, 250), APInt(8, 9)));
+ EXPECT_EQ(ConstantRange(APInt(8, 254), APInt(8, 255)).multiply(
+ ConstantRange(APInt(8, 2), APInt(8, 4))),
+ ConstantRange(APInt(8, 250), APInt(8, 253)));
}
TEST_F(ConstantRangeTest, UMax) {
@@ -502,11 +509,63 @@ TEST_F(ConstantRangeTest, Lshr) {
EXPECT_EQ(Wrap.lshr(Wrap), Full);
}
-TEST(ConstantRange, MakeICmpRegion) {
+TEST(ConstantRange, MakeAllowedICmpRegion) {
// PR8250
ConstantRange SMax = ConstantRange(APInt::getSignedMaxValue(32));
- EXPECT_TRUE(ConstantRange::makeICmpRegion(ICmpInst::ICMP_SGT,
- SMax).isEmptySet());
+ EXPECT_TRUE(ConstantRange::makeAllowedICmpRegion(ICmpInst::ICMP_SGT, SMax)
+ .isEmptySet());
+}
+
+TEST(ConstantRange, MakeSatisfyingICmpRegion) {
+ ConstantRange LowHalf(APInt(8, 0), APInt(8, 128));
+ ConstantRange HighHalf(APInt(8, 128), APInt(8, 0));
+ ConstantRange EmptySet(8, /* isFullSet = */ false);
+
+ EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_NE, LowHalf),
+ HighHalf);
+
+ EXPECT_EQ(
+ ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_NE, HighHalf),
+ LowHalf);
+
+ EXPECT_TRUE(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_EQ,
+ HighHalf).isEmptySet());
+
+ ConstantRange UnsignedSample(APInt(8, 5), APInt(8, 200));
+
+ EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_ULT,
+ UnsignedSample),
+ ConstantRange(APInt(8, 0), APInt(8, 5)));
+
+ EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_ULE,
+ UnsignedSample),
+ ConstantRange(APInt(8, 0), APInt(8, 6)));
+
+ EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_UGT,
+ UnsignedSample),
+ ConstantRange(APInt(8, 200), APInt(8, 0)));
+
+ EXPECT_EQ(ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_UGE,
+ UnsignedSample),
+ ConstantRange(APInt(8, 199), APInt(8, 0)));
+
+ ConstantRange SignedSample(APInt(8, -5), APInt(8, 5));
+
+ EXPECT_EQ(
+ ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SLT, SignedSample),
+ ConstantRange(APInt(8, -128), APInt(8, -5)));
+
+ EXPECT_EQ(
+ ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SLE, SignedSample),
+ ConstantRange(APInt(8, -128), APInt(8, -4)));
+
+ EXPECT_EQ(
+ ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SGT, SignedSample),
+ ConstantRange(APInt(8, 5), APInt(8, -128)));
+
+ EXPECT_EQ(
+ ConstantRange::makeSatisfyingICmpRegion(ICmpInst::ICMP_SGE, SignedSample),
+ ConstantRange(APInt(8, 4), APInt(8, -128)));
}
} // anonymous namespace
diff --git a/unittests/IR/ConstantsTest.cpp b/unittests/IR/ConstantsTest.cpp
index 5414b25ca3adf..2df008a78ccd7 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 {
@@ -185,6 +187,13 @@ TEST(ConstantsTest, AsInstructionsTest) {
Constant *P6 = ConstantExpr::getBitCast(P4, VectorType::get(Int16Ty, 2));
Constant *One = ConstantInt::get(Int32Ty, 1);
+ Constant *Two = ConstantInt::get(Int64Ty, 2);
+ Constant *Big = ConstantInt::get(getGlobalContext(),
+ APInt{256, uint64_t(-1), true});
+ Constant *Elt = ConstantInt::get(Int16Ty, 2015);
+ Constant *Undef16 = UndefValue::get(Int16Ty);
+ Constant *Undef64 = UndefValue::get(Int64Ty);
+ Constant *UndefV16 = UndefValue::get(P6->getType());
#define P0STR "ptrtoint (i32** @dummy to i32)"
#define P1STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to float)"
@@ -246,12 +255,23 @@ TEST(ConstantsTest, AsInstructionsTest) {
// FIXME: getGetElementPtr() actually creates an inbounds ConstantGEP,
// not a normal one!
//CHECK(ConstantExpr::getGetElementPtr(Global, V, false),
- // "getelementptr i32** @dummy, i32 1");
- CHECK(ConstantExpr::getInBoundsGetElementPtr(Global, V),
- "getelementptr inbounds i32** @dummy, i32 1");
+ // "getelementptr i32*, i32** @dummy, i32 1");
+ CHECK(ConstantExpr::getInBoundsGetElementPtr(PointerType::getUnqual(Int32Ty),
+ Global, V),
+ "getelementptr inbounds i32*, i32** @dummy, i32 1");
CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> "
P6STR ", i32 1");
+
+ EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Two));
+ EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Big));
+ EXPECT_EQ(Undef16, ConstantExpr::getExtractElement(P6, Undef64));
+
+ EXPECT_EQ(Elt, ConstantExpr::getExtractElement(
+ ConstantExpr::getInsertElement(P6, Elt, One), One));
+ EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Two));
+ EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Big));
+ EXPECT_EQ(UndefV16, ConstantExpr::getInsertElement(P6, Elt, Undef64));
}
#ifdef GTEST_HAS_DEATH_TEST
@@ -264,7 +284,8 @@ TEST(ConstantsTest, ReplaceWithConstantTest) {
Constant *Global =
M->getOrInsertGlobal("dummy", PointerType::getUnqual(Int32Ty));
- Constant *GEP = ConstantExpr::getGetElementPtr(Global, One);
+ Constant *GEP = ConstantExpr::getGetElementPtr(
+ PointerType::getUnqual(Int32Ty), Global, One);
EXPECT_DEATH(Global->replaceAllUsesWith(GEP),
"this->replaceAllUsesWith\\(expr\\(this\\)\\) is NOT valid!");
}
@@ -327,11 +348,11 @@ TEST(ConstantsTest, GEPReplaceWithConstant) {
std::unique_ptr<Module> M(new Module("MyModule", Context));
Type *IntTy = Type::getInt32Ty(Context);
- Type *PtrTy = PointerType::get(IntTy, 0);
+ auto *PtrTy = PointerType::get(IntTy, 0);
auto *C1 = ConstantInt::get(IntTy, 1);
auto *Placeholder = new GlobalVariable(
*M, IntTy, false, GlobalValue::ExternalWeakLinkage, nullptr);
- auto *GEP = ConstantExpr::getGetElementPtr(Placeholder, C1);
+ auto *GEP = ConstantExpr::getGetElementPtr(IntTy, Placeholder, C1);
ASSERT_EQ(GEP->getOperand(0), Placeholder);
auto *Ref =
@@ -340,12 +361,26 @@ TEST(ConstantsTest, GEPReplaceWithConstant) {
auto *Global = new GlobalVariable(*M, PtrTy, false,
GlobalValue::ExternalLinkage, nullptr);
- auto *Alias = GlobalAlias::create(IntTy, 0, GlobalValue::ExternalLinkage,
+ auto *Alias = GlobalAlias::create(PtrTy, GlobalValue::ExternalLinkage,
"alias", Global, M.get());
Placeholder->replaceAllUsesWith(Alias);
ASSERT_EQ(GEP, Ref->getInitializer());
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 1fa851e39ae98..f633782b37995 100644
--- a/unittests/IR/DebugInfoTest.cpp
+++ b/unittests/IR/DebugInfoTest.cpp
@@ -7,62 +7,75 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "gtest/gtest.h"
using namespace llvm;
-namespace llvm {
-
-static void PrintTo(const StringRef &S, ::std::ostream *os) {
- *os << "(" << (const void *)S.data() << "," << S.size() << ") = '";
- for (auto C : S)
- if (C)
- *os << C;
- else
- *os << "\\00";
- *os << "'";
-}
-static void PrintTo(const DIHeaderFieldIterator &I, ::std::ostream *os) {
- PrintTo(I.getCurrent(), os);
- *os << " in ";
- PrintTo(I.getHeader(), os);
-}
-
-} // end namespace llvm
-
namespace {
-#define MAKE_FIELD_ITERATOR(S) \
- DIHeaderFieldIterator(StringRef(S, sizeof(S) - 1))
-TEST(DebugInfoTest, DIHeaderFieldIterator) {
- ASSERT_EQ(DIHeaderFieldIterator(), DIHeaderFieldIterator());
+TEST(DINodeTest, getFlag) {
+ // Some valid flags.
+ EXPECT_EQ(DINode::FlagPublic, DINode::getFlag("DIFlagPublic"));
+ EXPECT_EQ(DINode::FlagProtected, DINode::getFlag("DIFlagProtected"));
+ EXPECT_EQ(DINode::FlagPrivate, DINode::getFlag("DIFlagPrivate"));
+ EXPECT_EQ(DINode::FlagVector, DINode::getFlag("DIFlagVector"));
+ EXPECT_EQ(DINode::FlagRValueReference,
+ DINode::getFlag("DIFlagRValueReference"));
+
+ // FlagAccessibility shouldn't work.
+ EXPECT_EQ(0u, DINode::getFlag("DIFlagAccessibility"));
- ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR(""));
- ASSERT_EQ(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR(""));
- ASSERT_EQ("", *DIHeaderFieldIterator(""));
+ // Some other invalid strings.
+ EXPECT_EQ(0u, DINode::getFlag("FlagVector"));
+ EXPECT_EQ(0u, DINode::getFlag("Vector"));
+ EXPECT_EQ(0u, DINode::getFlag("other things"));
+ EXPECT_EQ(0u, DINode::getFlag("DIFlagOther"));
+}
- ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("stuff"));
- ASSERT_EQ(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("stuff"));
- ASSERT_EQ("stuff", *DIHeaderFieldIterator("stuff"));
+TEST(DINodeTest, getFlagString) {
+ // Some valid flags.
+ EXPECT_EQ(StringRef("DIFlagPublic"),
+ DINode::getFlagString(DINode::FlagPublic));
+ EXPECT_EQ(StringRef("DIFlagProtected"),
+ DINode::getFlagString(DINode::FlagProtected));
+ EXPECT_EQ(StringRef("DIFlagPrivate"),
+ DINode::getFlagString(DINode::FlagPrivate));
+ EXPECT_EQ(StringRef("DIFlagVector"),
+ DINode::getFlagString(DINode::FlagVector));
+ EXPECT_EQ(StringRef("DIFlagRValueReference"),
+ DINode::getFlagString(DINode::FlagRValueReference));
- ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("st\0uff"));
- ASSERT_NE(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("st\0uff"));
- ASSERT_EQ(DIHeaderFieldIterator(), ++++MAKE_FIELD_ITERATOR("st\0uff"));
- ASSERT_EQ("st", *MAKE_FIELD_ITERATOR("st\0uff"));
- ASSERT_EQ("uff", *++MAKE_FIELD_ITERATOR("st\0uff"));
+ // FlagAccessibility actually equals FlagPublic.
+ EXPECT_EQ(StringRef("DIFlagPublic"),
+ DINode::getFlagString(DINode::FlagAccessibility));
- ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("stuff\0"));
- ASSERT_NE(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("stuff\0"));
- ASSERT_EQ(DIHeaderFieldIterator(), ++++MAKE_FIELD_ITERATOR("stuff\0"));
- ASSERT_EQ("stuff", *MAKE_FIELD_ITERATOR("stuff\0"));
- ASSERT_EQ("", *++MAKE_FIELD_ITERATOR("stuff\0"));
+ // Some other invalid flags.
+ EXPECT_EQ(StringRef(),
+ DINode::getFlagString(DINode::FlagPublic | DINode::FlagVector));
+ EXPECT_EQ(StringRef(), DINode::getFlagString(DINode::FlagFwdDecl |
+ DINode::FlagArtificial));
+ EXPECT_EQ(StringRef(), DINode::getFlagString(0xffff));
+}
- ASSERT_NE(DIHeaderFieldIterator(), MAKE_FIELD_ITERATOR("\0stuff"));
- ASSERT_NE(DIHeaderFieldIterator(), ++MAKE_FIELD_ITERATOR("\0stuff"));
- ASSERT_EQ(DIHeaderFieldIterator(), ++++MAKE_FIELD_ITERATOR("\0stuff"));
- ASSERT_EQ("", *MAKE_FIELD_ITERATOR("\0stuff"));
- ASSERT_EQ("stuff", *++MAKE_FIELD_ITERATOR("\0stuff"));
+TEST(DINodeTest, splitFlags) {
+// Some valid flags.
+#define CHECK_SPLIT(FLAGS, VECTOR, REMAINDER) \
+ { \
+ SmallVector<unsigned, 8> V; \
+ EXPECT_EQ(REMAINDER, DINode::splitFlags(FLAGS, V)); \
+ EXPECT_TRUE(makeArrayRef(V).equals(VECTOR)); \
+ }
+ CHECK_SPLIT(DINode::FlagPublic, {DINode::FlagPublic}, 0u);
+ CHECK_SPLIT(DINode::FlagProtected, {DINode::FlagProtected}, 0u);
+ CHECK_SPLIT(DINode::FlagPrivate, {DINode::FlagPrivate}, 0u);
+ CHECK_SPLIT(DINode::FlagVector, {DINode::FlagVector}, 0u);
+ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u);
+ unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector};
+ CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u);
+ CHECK_SPLIT(0x100000u, {}, 0x100000u);
+ CHECK_SPLIT(0x100000u | DINode::FlagVector, {DINode::FlagVector}, 0x100000u);
+#undef CHECK_SPLIT
}
} // end namespace
diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp
index 6c43d6fe7c7bc..6a5838e693acf 100644
--- a/unittests/IR/DominatorTreeTest.cpp
+++ b/unittests/IR/DominatorTreeTest.cpp
@@ -10,10 +10,11 @@
#include "llvm/IR/Dominators.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
@@ -25,7 +26,7 @@ namespace llvm {
namespace {
struct DPass : public FunctionPass {
static char ID;
- virtual bool runOnFunction(Function &F) {
+ bool runOnFunction(Function &F) override {
DominatorTree *DT =
&getAnalysis<DominatorTreeWrapperPass>().getDomTree();
PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>();
@@ -174,9 +175,36 @@ namespace llvm {
EXPECT_EQ(DominatedBBs.size(), 0UL);
EXPECT_EQ(PostDominatedBBs.size(), 0UL);
+ // Check DFS Numbers before
+ EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
+ EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
+ EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
+ EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
+ EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
+ EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
+ EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
+ EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
+
+ // Reattach block 3 to block 1 and recalculate
+ BB1->getTerminator()->eraseFromParent();
+ BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
+ DT->recalculate(F);
+
+ // Check DFS Numbers after
+ EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
+ EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
+ EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
+ EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
+ EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
+ EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
+ EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
+ EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
+ EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
+ EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
+
return false;
}
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<DominatorTreeWrapperPass>();
AU.addRequired<PostDominatorTree>();
}
@@ -218,7 +246,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 df5c840647798..e8aaaea077554 100644
--- a/unittests/IR/IRBuilderTest.cpp
+++ b/unittests/IR/IRBuilderTest.cpp
@@ -10,12 +10,14 @@
#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"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
+#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -24,7 +26,7 @@ namespace {
class IRBuilderTest : public testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
M.reset(new Module("MyModule", Ctx));
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
/*isVarArg=*/false);
@@ -34,7 +36,7 @@ protected:
GlobalValue::ExternalLinkage, nullptr);
}
- virtual void TearDown() {
+ void TearDown() override {
BB = nullptr;
M.reset();
}
@@ -110,9 +112,9 @@ TEST_F(IRBuilderTest, LandingPadName) {
TEST_F(IRBuilderTest, DataLayout) {
std::unique_ptr<Module> M(new Module("test", Ctx));
M->setDataLayout("e-n32");
- EXPECT_TRUE(M->getDataLayout()->isLegalInteger(32));
+ EXPECT_TRUE(M->getDataLayout().isLegalInteger(32));
M->setDataLayout("e");
- EXPECT_FALSE(M->getDataLayout()->isLegalInteger(32));
+ EXPECT_FALSE(M->getDataLayout().isLegalInteger(32));
}
TEST_F(IRBuilderTest, GetIntTy) {
@@ -121,7 +123,7 @@ TEST_F(IRBuilderTest, GetIntTy) {
EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1));
DataLayout* DL = new DataLayout(M.get());
- IntegerType *IntPtrTy = Builder.getIntPtrTy(DL);
+ IntegerType *IntPtrTy = Builder.getIntPtrTy(*DL);
unsigned IntPtrBitSize = DL->getPointerSizeInBits(0);
EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize));
delete DL;
@@ -287,5 +289,37 @@ 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));
+ DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true, F);
+ AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
+ auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
+ 0, true, nullptr);
+ auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
+ I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
+ DIB.finalize();
+ EXPECT_TRUE(verifyModule(*M));
+}
+
+TEST_F(IRBuilderTest, InsertExtractElement) {
+ IRBuilder<> Builder(BB);
+
+ auto VecTy = VectorType::get(Builder.getInt64Ty(), 4);
+ auto Elt1 = Builder.getInt64(-1);
+ auto Elt2 = Builder.getInt64(-2);
+ Value *Vec = UndefValue::get(VecTy);
+ Vec = Builder.CreateInsertElement(Vec, Elt1, Builder.getInt8(1));
+ Vec = Builder.CreateInsertElement(Vec, Elt2, 2);
+ auto X1 = Builder.CreateExtractElement(Vec, 1);
+ auto X2 = Builder.CreateExtractElement(Vec, Builder.getInt32(2));
+ EXPECT_EQ(Elt1, X1);
+ EXPECT_EQ(Elt2, X2);
+}
+
}
diff --git a/unittests/IR/InstructionsTest.cpp b/unittests/IR/InstructionsTest.cpp
index 7ec9b62207fbc..3ca3ad2b6e837 100644
--- a/unittests/IR/InstructionsTest.cpp
+++ b/unittests/IR/InstructionsTest.cpp
@@ -291,8 +291,10 @@ TEST(InstructionsTest, VectorGep) {
LLVMContext &C(getGlobalContext());
// Type Definitions
- PointerType *Ptri8Ty = PointerType::get(IntegerType::get(C, 8), 0);
- PointerType *Ptri32Ty = PointerType::get(IntegerType::get(C, 32), 0);
+ Type *I8Ty = IntegerType::get(C, 8);
+ Type *I32Ty = IntegerType::get(C, 32);
+ PointerType *Ptri8Ty = PointerType::get(I8Ty, 0);
+ PointerType *Ptri32Ty = PointerType::get(I32Ty, 0);
VectorType *V2xi8PTy = VectorType::get(Ptri8Ty, 2);
VectorType *V2xi32PTy = VectorType::get(Ptri32Ty, 2);
@@ -318,10 +320,10 @@ TEST(InstructionsTest, VectorGep) {
ICmpInst *ICmp2 = new ICmpInst(*BB0, ICmpInst::ICMP_SGE, PtrVecA, PtrVecB);
EXPECT_NE(ICmp0, ICmp2); // suppress warning.
- GetElementPtrInst *Gep0 = GetElementPtrInst::Create(PtrVecA, C2xi32a);
- GetElementPtrInst *Gep1 = GetElementPtrInst::Create(PtrVecA, C2xi32b);
- GetElementPtrInst *Gep2 = GetElementPtrInst::Create(PtrVecB, C2xi32a);
- GetElementPtrInst *Gep3 = GetElementPtrInst::Create(PtrVecB, C2xi32b);
+ GetElementPtrInst *Gep0 = GetElementPtrInst::Create(I32Ty, PtrVecA, C2xi32a);
+ GetElementPtrInst *Gep1 = GetElementPtrInst::Create(I32Ty, PtrVecA, C2xi32b);
+ GetElementPtrInst *Gep2 = GetElementPtrInst::Create(I32Ty, PtrVecB, C2xi32a);
+ GetElementPtrInst *Gep3 = GetElementPtrInst::Create(I32Ty, PtrVecB, C2xi32b);
CastInst *BTC0 = new BitCastInst(Gep0, V2xi8PTy);
CastInst *BTC1 = new BitCastInst(Gep1, V2xi8PTy);
@@ -343,16 +345,16 @@ TEST(InstructionsTest, VectorGep) {
"2:32:32-f64:64:64-v64:64:64-v128:128:128-a:0:64-s:64:64-f80"
":128:128-n8:16:32:64-S128");
// Make sure we don't crash
- GetPointerBaseWithConstantOffset(Gep0, Offset, &TD);
- GetPointerBaseWithConstantOffset(Gep1, Offset, &TD);
- GetPointerBaseWithConstantOffset(Gep2, Offset, &TD);
- GetPointerBaseWithConstantOffset(Gep3, Offset, &TD);
+ GetPointerBaseWithConstantOffset(Gep0, Offset, TD);
+ GetPointerBaseWithConstantOffset(Gep1, Offset, TD);
+ GetPointerBaseWithConstantOffset(Gep2, Offset, TD);
+ GetPointerBaseWithConstantOffset(Gep3, Offset, TD);
// Gep of Geps
- GetElementPtrInst *GepII0 = GetElementPtrInst::Create(Gep0, C2xi32b);
- GetElementPtrInst *GepII1 = GetElementPtrInst::Create(Gep1, C2xi32a);
- GetElementPtrInst *GepII2 = GetElementPtrInst::Create(Gep2, C2xi32b);
- GetElementPtrInst *GepII3 = GetElementPtrInst::Create(Gep3, C2xi32a);
+ GetElementPtrInst *GepII0 = GetElementPtrInst::Create(I32Ty, Gep0, C2xi32b);
+ GetElementPtrInst *GepII1 = GetElementPtrInst::Create(I32Ty, Gep1, C2xi32a);
+ GetElementPtrInst *GepII2 = GetElementPtrInst::Create(I32Ty, Gep2, C2xi32b);
+ GetElementPtrInst *GepII3 = GetElementPtrInst::Create(I32Ty, Gep3, C2xi32a);
EXPECT_EQ(GepII0->getNumIndices(), 1u);
EXPECT_EQ(GepII1->getNumIndices(), 1u);
diff --git a/unittests/IR/LegacyPassManagerTest.cpp b/unittests/IR/LegacyPassManagerTest.cpp
index 4efc2f5b80574..66fd1ccd7f209 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"
@@ -99,7 +98,6 @@ namespace llvm {
initializeModuleNDMPass(*PassRegistry::getPassRegistry());
}
bool runOnModule(Module &M) override {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run++;
return false;
}
@@ -176,7 +174,6 @@ namespace llvm {
initializeCGPassPass(*PassRegistry::getPassRegistry());
}
bool runOnSCC(CallGraphSCC &SCMM) override {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
@@ -215,7 +212,6 @@ namespace llvm {
return false;
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
@@ -252,7 +248,6 @@ namespace llvm {
return false;
}
bool runOnBasicBlock(BasicBlock &BB) override {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
run();
return false;
}
@@ -277,7 +272,6 @@ namespace llvm {
initializeFPassPass(*PassRegistry::getPassRegistry());
}
bool runOnModule(Module &M) override {
- EXPECT_TRUE(getAnalysisIfAvailable<DataLayoutPass>());
for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) {
Function &F = *I;
{
@@ -302,8 +296,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
- PassManager Passes;
- Passes.add(new DataLayoutPass());
+ legacy::PassManager Passes;
Passes.add(mNDM2);
Passes.add(mNDM);
Passes.add(mNDNM);
@@ -326,8 +319,7 @@ namespace llvm {
mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0;
- PassManager Passes;
- Passes.add(new DataLayoutPass());
+ legacy::PassManager Passes;
Passes.add(mNDM);
Passes.add(mNDNM);
Passes.add(mNDM2);// invalidates mNDM needed by mDNM
@@ -348,8 +340,7 @@ namespace llvm {
void MemoryTestHelper(int run) {
std::unique_ptr<Module> M(makeLLVMModule());
T *P = new T();
- PassManager Passes;
- Passes.add(new DataLayoutPass());
+ legacy::PassManager Passes;
Passes.add(P);
Passes.run(*M);
T::finishedOK(run);
@@ -359,8 +350,7 @@ namespace llvm {
void MemoryTestHelper(int run, int N) {
Module *M = makeLLVMModule();
T *P = new T();
- PassManager Passes;
- Passes.add(new DataLayoutPass());
+ legacy::PassManager Passes;
Passes.add(P);
Passes.run(*M);
T::finishedOK(run, N);
@@ -397,8 +387,7 @@ namespace llvm {
{
SCOPED_TRACE("Running OnTheFlyTest");
struct OnTheFlyTest *O = new OnTheFlyTest();
- PassManager Passes;
- Passes.add(new DataLayoutPass());
+ legacy::PassManager Passes;
Passes.add(O);
Passes.run(*M);
@@ -554,6 +543,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/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp
index f862f049fccc3..6994e2133f6f0 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
//
@@ -9,26 +9,113 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfo.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/Verifier.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 {
+public:
+ MetadataTest() : M("test", Context), Counter(0) {}
+
protected:
LLVMContext Context;
+ Module M;
+ int Counter;
+
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);
}
+
+ MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); }
+ DISubroutineType *getSubroutineType() {
+ return DISubroutineType::getDistinct(Context, 0, getNode(nullptr));
+ }
+ DISubprogram *getSubprogram() {
+ return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0,
+ nullptr, false, false, 0, nullptr, 0, 0, 0,
+ 0);
+ }
+ DIScopeRef getSubprogramRef() { return getSubprogram()->getRef(); }
+ DIFile *getFile() {
+ return DIFile::getDistinct(Context, "file.c", "/path/to/dir");
+ }
+ DITypeRef getBasicType(StringRef Name) {
+ return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name)
+ ->getRef();
+ }
+ DITypeRef getDerivedType() {
+ return DIDerivedType::getDistinct(Context, dwarf::DW_TAG_pointer_type, "",
+ nullptr, 0, nullptr,
+ getBasicType("basictype"), 1, 2, 0, 0)
+ ->getRef();
+ }
+ Constant *getConstant() {
+ return ConstantInt::get(Type::getInt32Ty(Context), Counter++);
+ }
+ ConstantAsMetadata *getConstantAsMetadata() {
+ return ConstantAsMetadata::get(getConstant());
+ }
+ DITypeRef getCompositeType() {
+ return DICompositeType::getDistinct(
+ Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr,
+ nullptr, 32, 32, 0, 0, nullptr, 0, nullptr, nullptr, "")
+ ->getRef();
+ }
+ Function *getFunction(StringRef Name) {
+ return cast<Function>(M.getOrInsertFunction(
+ Name, FunctionType::get(Type::getVoidTy(Context), None, false)));
+ }
};
typedef MetadataTest MDStringTest;
@@ -130,19 +217,14 @@ TEST_F(MDNodeTest, Delete) {
delete I;
}
-TEST_F(MDNodeTest, DeleteMDNodeFwdDecl) {
- delete MDNode::getTemporary(Context, None);
-}
-
TEST_F(MDNodeTest, SelfReference) {
// !0 = !{!0}
// !1 = !{!0}
{
- MDNode *Temp = MDNode::getTemporary(Context, None);
- Metadata *Args[] = {Temp};
+ auto Temp = MDNode::getTemporary(Context, None);
+ Metadata *Args[] = {Temp.get()};
MDNode *Self = MDNode::get(Context, Args);
Self->replaceOperandWith(0, Self);
- MDNode::deleteTemporary(Temp);
ASSERT_EQ(Self, Self->getOperand(0));
// Self-references should be distinct, so MDNode::get() should grab a
@@ -157,11 +239,10 @@ TEST_F(MDNodeTest, SelfReference) {
// !0 = !{!0, !{}}
// !1 = !{!0, !{}}
{
- MDNode *Temp = MDNode::getTemporary(Context, None);
- Metadata *Args[] = {Temp, MDNode::get(Context, None)};
+ auto Temp = MDNode::getTemporary(Context, None);
+ Metadata *Args[] = {Temp.get(), MDNode::get(Context, None)};
MDNode *Self = MDNode::get(Context, Args);
Self->replaceOperandWith(0, Self);
- MDNode::deleteTemporary(Temp);
ASSERT_EQ(Self, Self->getOperand(0));
// Self-references should be distinct, so MDNode::get() should grab a
@@ -187,7 +268,7 @@ TEST_F(MDNodeTest, Print) {
std::string Expected;
{
raw_string_ostream OS(Expected);
- OS << "!{";
+ OS << "<" << (void *)N << "> = !{";
C->printAsOperand(OS);
OS << ", ";
S->printAsOperand(OS);
@@ -195,7 +276,7 @@ TEST_F(MDNodeTest, Print) {
MDNode *Nodes[] = {N0, N1, N2};
for (auto *Node : Nodes)
OS << ", <" << (void *)Node << ">";
- OS << "}\n";
+ OS << "}";
}
std::string Actual;
@@ -207,6 +288,105 @@ TEST_F(MDNodeTest, Print) {
EXPECT_EQ(Expected, Actual);
}
+#define EXPECT_PRINTER_EQ(EXPECTED, PRINT) \
+ do { \
+ std::string Actual_; \
+ raw_string_ostream OS(Actual_); \
+ PRINT; \
+ OS.flush(); \
+ std::string Expected_(EXPECTED); \
+ EXPECT_EQ(Expected_, Actual_); \
+ } while (false)
+
+TEST_F(MDNodeTest, PrintTemporary) {
+ MDNode *Arg = getNode();
+ TempMDNode Temp = MDNode::getTemporary(Context, Arg);
+ MDNode *N = getNode(Temp.get());
+ Module M("test", Context);
+ NamedMDNode *NMD = M.getOrInsertNamedMetadata("named");
+ NMD->addOperand(N);
+
+ EXPECT_PRINTER_EQ("!0 = !{!1}", N->print(OS, &M));
+ EXPECT_PRINTER_EQ("!1 = <temporary!> !{!2}", Temp->print(OS, &M));
+ EXPECT_PRINTER_EQ("!2 = !{}", Arg->print(OS, &M));
+
+ // Cleanup.
+ Temp->replaceAllUsesWith(Arg);
+}
+
+TEST_F(MDNodeTest, PrintFromModule) {
+ 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);
+ Module M("test", Context);
+ NamedMDNode *NMD = M.getOrInsertNamedMetadata("named");
+ NMD->addOperand(N);
+
+ std::string Expected;
+ {
+ raw_string_ostream OS(Expected);
+ OS << "!0 = !{";
+ C->printAsOperand(OS);
+ OS << ", ";
+ S->printAsOperand(OS);
+ OS << ", null, !1, !2, !3}";
+ }
+
+ EXPECT_PRINTER_EQ(Expected, N->print(OS, &M));
+}
+
+TEST_F(MDNodeTest, PrintFromFunction) {
+ Module M("test", Context);
+ auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
+ auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
+ auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
+ auto *BB0 = BasicBlock::Create(Context, "entry", F0);
+ auto *BB1 = BasicBlock::Create(Context, "entry", F1);
+ auto *R0 = ReturnInst::Create(Context, BB0);
+ auto *R1 = ReturnInst::Create(Context, BB1);
+ auto *N0 = MDNode::getDistinct(Context, None);
+ auto *N1 = MDNode::getDistinct(Context, None);
+ R0->setMetadata("md", N0);
+ R1->setMetadata("md", N1);
+
+ EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, &M));
+ EXPECT_PRINTER_EQ("!1 = distinct !{}", N1->print(OS, &M));
+}
+
+TEST_F(MDNodeTest, PrintFromMetadataAsValue) {
+ Module M("test", Context);
+
+ auto *Intrinsic =
+ Function::Create(FunctionType::get(Type::getVoidTy(Context),
+ Type::getMetadataTy(Context), false),
+ GlobalValue::ExternalLinkage, "llvm.intrinsic", &M);
+
+ auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
+ auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
+ auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
+ auto *BB0 = BasicBlock::Create(Context, "entry", F0);
+ auto *BB1 = BasicBlock::Create(Context, "entry", F1);
+ auto *N0 = MDNode::getDistinct(Context, None);
+ auto *N1 = MDNode::getDistinct(Context, None);
+ auto *MAV0 = MetadataAsValue::get(Context, N0);
+ auto *MAV1 = MetadataAsValue::get(Context, N1);
+ CallInst::Create(Intrinsic, MAV0, "", BB0);
+ CallInst::Create(Intrinsic, MAV1, "", BB1);
+
+ EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS));
+ EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS));
+ EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false));
+ EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false));
+ EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true));
+ EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true));
+}
+#undef EXPECT_PRINTER_EQ
+
TEST_F(MDNodeTest, NullOperand) {
// metadata !{}
MDNode *Empty = MDNode::get(Context, None);
@@ -274,27 +454,47 @@ TEST_F(MDNodeTest, getDistinct) {
ASSERT_EQ(Empty, MDNode::get(Context, None));
}
-TEST_F(MDNodeTest, TempIsDistinct) {
- MDNode *T = MDNode::getTemporary(Context, None);
- EXPECT_TRUE(T->isDistinct());
- MDNode::deleteTemporary(T);
+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 !{}
- MDNodeFwdDecl *Temp = MDNode::getTemporary(Context, None);
+ auto Temp = MDTuple::getTemporary(Context, None);
ASSERT_FALSE(Temp->isResolved());
// distinct !{temporary !{}}
- Metadata *Ops[] = {Temp};
+ Metadata *Ops[] = {Temp.get()};
MDNode *Distinct = MDNode::getDistinct(Context, Ops);
EXPECT_TRUE(Distinct->isResolved());
- EXPECT_EQ(Temp, Distinct->getOperand(0));
+ EXPECT_EQ(Temp.get(), Distinct->getOperand(0));
// temporary !{} => !{}
MDNode *Empty = MDNode::get(Context, None);
Temp->replaceAllUsesWith(Empty);
- MDNode::deleteTemporary(Temp);
EXPECT_EQ(Empty, Distinct->getOperand(0));
}
@@ -303,7 +503,7 @@ TEST_F(MDNodeTest, handleChangedOperandRecursion) {
MDNode *N0 = MDNode::get(Context, None);
// !1 = !{!3, null}
- std::unique_ptr<MDNodeFwdDecl> Temp3(MDNode::getTemporary(Context, None));
+ auto Temp3 = MDTuple::getTemporary(Context, None);
Metadata *Ops1[] = {Temp3.get(), nullptr};
MDNode *N1 = MDNode::get(Context, Ops1);
@@ -367,7 +567,7 @@ TEST_F(MDNodeTest, replaceResolvedOperand) {
// a global value that gets RAUW'ed.
//
// Use a temporary node to keep N from being resolved.
- std::unique_ptr<MDNodeFwdDecl> Temp(MDNodeFwdDecl::get(Context, None));
+ auto Temp = MDTuple::getTemporary(Context, None);
Metadata *Ops[] = {nullptr, Temp.get()};
MDNode *Empty = MDTuple::get(Context, ArrayRef<Metadata *>());
@@ -387,41 +587,1432 @@ TEST_F(MDNodeTest, replaceResolvedOperand) {
Temp->replaceAllUsesWith(nullptr);
}
-typedef MetadataTest MDLocationTest;
+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());
-TEST_F(MDLocationTest, Overflow) {
- MDNode *N = MDNode::get(Context, None);
+ // 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);
+ }
{
- MDLocation *L = MDLocation::get(Context, 2, 7, N);
+ 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, replaceWithUniquedResolvingOperand) {
+ // temp !{}
+ MDTuple *Op = MDTuple::getTemporary(Context, None).release();
+ EXPECT_FALSE(Op->isResolved());
+
+ // temp !{temp !{}}
+ Metadata *Ops[] = {Op};
+ MDTuple *N = MDTuple::getTemporary(Context, Ops).release();
+ EXPECT_FALSE(N->isResolved());
+
+ // temp !{temp !{}} => !{temp !{}}
+ ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N)));
+ EXPECT_FALSE(N->isResolved());
+
+ // !{temp !{}} => !{!{}}
+ ASSERT_EQ(Op, MDNode::replaceWithUniqued(TempMDTuple(Op)));
+ EXPECT_TRUE(Op->isResolved());
+ EXPECT_TRUE(N->isResolved());
+}
+
+TEST_F(MDNodeTest, replaceWithUniquedChangingOperand) {
+ // i1* @GV
+ Type *Ty = Type::getInt1PtrTy(Context);
+ std::unique_ptr<GlobalVariable> GV(
+ new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
+ ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get());
+
+ // temp !{i1* @GV}
+ Metadata *Ops[] = {Op};
+ MDTuple *N = MDTuple::getTemporary(Context, Ops).release();
+
+ // temp !{i1* @GV} => !{i1* @GV}
+ ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N)));
+ ASSERT_TRUE(N->isUniqued());
+
+ // !{i1* @GV} => !{null}
+ GV.reset();
+ ASSERT_TRUE(N->isUniqued());
+ Metadata *NullOps[] = {nullptr};
+ ASSERT_EQ(N, MDTuple::get(Context, NullOps));
+}
+
+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 DILocationTest;
+
+TEST_F(DILocationTest, Overflow) {
+ DISubprogram *N = getSubprogram();
+ {
+ DILocation *L = DILocation::get(Context, 2, 7, N);
EXPECT_EQ(2u, L->getLine());
EXPECT_EQ(7u, L->getColumn());
}
- unsigned U24 = 1u << 24;
- unsigned U8 = 1u << 8;
+ unsigned U16 = 1u << 16;
{
- MDLocation *L = MDLocation::get(Context, U24 - 1, U8 - 1, N);
- EXPECT_EQ(U24 - 1, L->getLine());
- EXPECT_EQ(U8 - 1, L->getColumn());
+ DILocation *L = DILocation::get(Context, UINT32_MAX, U16 - 1, N);
+ EXPECT_EQ(UINT32_MAX, L->getLine());
+ EXPECT_EQ(U16 - 1, L->getColumn());
}
{
- MDLocation *L = MDLocation::get(Context, U24, U8, N);
- EXPECT_EQ(0u, L->getLine());
+ DILocation *L = DILocation::get(Context, UINT32_MAX, U16, N);
+ EXPECT_EQ(UINT32_MAX, L->getLine());
EXPECT_EQ(0u, L->getColumn());
}
{
- MDLocation *L = MDLocation::get(Context, U24 + 1, U8 + 1, N);
- EXPECT_EQ(0u, L->getLine());
+ DILocation *L = DILocation::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);
+TEST_F(DILocationTest, getDistinct) {
+ MDNode *N = getSubprogram();
+ DILocation *L0 = DILocation::getDistinct(Context, 2, 7, N);
EXPECT_TRUE(L0->isDistinct());
- MDLocation *L1 = MDLocation::get(Context, 2, 7, N);
+ DILocation *L1 = DILocation::get(Context, 2, 7, N);
EXPECT_FALSE(L1->isDistinct());
- EXPECT_EQ(L1, MDLocation::get(Context, 2, 7, N));
+ EXPECT_EQ(L1, DILocation::get(Context, 2, 7, N));
+}
+
+TEST_F(DILocationTest, getTemporary) {
+ MDNode *N = MDNode::get(Context, None);
+ auto L = DILocation::getTemporary(Context, 2, 7, N);
+ EXPECT_TRUE(L->isTemporary());
+ EXPECT_FALSE(L->isResolved());
+}
+
+typedef MetadataTest GenericDINodeTest;
+
+TEST_F(GenericDINodeTest, get) {
+ StringRef Header = "header";
+ auto *Empty = MDNode::get(Context, None);
+ Metadata *Ops1[] = {Empty};
+ auto *N = GenericDINode::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, GenericDINode::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, GenericDINode::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, GenericDINode::get(Context, 15, Header, Ops1));
+
+ TempGenericDINode Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(GenericDINodeTest, getEmptyHeader) {
+ // Canonicalize !"" to null.
+ auto *N = GenericDINode::get(Context, 15, StringRef(), None);
+ EXPECT_EQ(StringRef(), N->getHeader());
+ EXPECT_EQ(nullptr, N->getOperand(0));
+}
+
+typedef MetadataTest DISubrangeTest;
+
+TEST_F(DISubrangeTest, get) {
+ auto *N = DISubrange::get(Context, 5, 7);
+ EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
+ EXPECT_EQ(5, N->getCount());
+ EXPECT_EQ(7, N->getLowerBound());
+ EXPECT_EQ(N, DISubrange::get(Context, 5, 7));
+ EXPECT_EQ(DISubrange::get(Context, 5, 0), DISubrange::get(Context, 5));
+
+ TempDISubrange Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DISubrangeTest, getEmptyArray) {
+ auto *N = DISubrange::get(Context, -1, 0);
+ EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
+ EXPECT_EQ(-1, N->getCount());
+ EXPECT_EQ(0, N->getLowerBound());
+ EXPECT_EQ(N, DISubrange::get(Context, -1, 0));
+}
+
+typedef MetadataTest DIEnumeratorTest;
+
+TEST_F(DIEnumeratorTest, get) {
+ auto *N = DIEnumerator::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, DIEnumerator::get(Context, 7, "name"));
+
+ EXPECT_NE(N, DIEnumerator::get(Context, 8, "name"));
+ EXPECT_NE(N, DIEnumerator::get(Context, 7, "nam"));
+
+ TempDIEnumerator Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DIBasicTypeTest;
+
+TEST_F(DIBasicTypeTest, get) {
+ auto *N =
+ DIBasicType::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, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 26, 7));
+
+ EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
+ "special", 33, 26, 7));
+ EXPECT_NE(N,
+ DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7));
+ EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
+ 26, 7));
+ EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 25, 7));
+ EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+ 26, 6));
+
+ TempDIBasicType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DIBasicTypeTest, getWithLargeValues) {
+ auto *N = DIBasicType::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());
+}
+
+TEST_F(DIBasicTypeTest, getUnspecified) {
+ auto *N =
+ DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, "unspecified");
+ EXPECT_EQ(dwarf::DW_TAG_unspecified_type, N->getTag());
+ EXPECT_EQ("unspecified", N->getName());
+ EXPECT_EQ(0u, N->getSizeInBits());
+ EXPECT_EQ(0u, N->getAlignInBits());
+ EXPECT_EQ(0u, N->getEncoding());
+ EXPECT_EQ(0u, N->getLine());
+}
+
+typedef MetadataTest DITypeTest;
+
+TEST_F(DITypeTest, clone) {
+ // Check that DIType has a specialized clone that returns TempDIType.
+ DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32,
+ dwarf::DW_ATE_signed);
+
+ TempDIType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DITypeTest, setFlags) {
+ // void (void)
+ Metadata *TypesOps[] = {nullptr};
+ Metadata *Types = MDTuple::get(Context, TypesOps);
+
+ DIType *D = DISubroutineType::getDistinct(Context, 0u, Types);
+ EXPECT_EQ(0u, D->getFlags());
+ D->setFlags(DINode::FlagRValueReference);
+ EXPECT_EQ(DINode::FlagRValueReference, D->getFlags());
+ D->setFlags(0u);
+ EXPECT_EQ(0u, D->getFlags());
+
+ TempDIType T = DISubroutineType::getTemporary(Context, 0u, Types);
+ EXPECT_EQ(0u, T->getFlags());
+ T->setFlags(DINode::FlagRValueReference);
+ EXPECT_EQ(DINode::FlagRValueReference, T->getFlags());
+ T->setFlags(0u);
+ EXPECT_EQ(0u, T->getFlags());
+}
+
+typedef MetadataTest DIDerivedTypeTest;
+
+TEST_F(DIDerivedTypeTest, get) {
+ DIFile *File = getFile();
+ DIScopeRef Scope = getSubprogramRef();
+ DITypeRef BaseType = getBasicType("basic");
+ MDTuple *ExtraData = getTuple();
+
+ auto *N = DIDerivedType::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, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else",
+ File, 1, Scope, BaseType, 2, 3, 4, 5,
+ ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", getFile(), 1, Scope, BaseType, 2,
+ 3, 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 2, Scope, BaseType, 2, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, getSubprogramRef(),
+ BaseType, 2, 3, 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(
+ Context, dwarf::DW_TAG_pointer_type, "something", File, 1,
+ Scope, getBasicType("basic2"), 2, 3, 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 3, 3,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 2,
+ 4, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 5, 5, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 4, ExtraData));
+ EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
+ "something", File, 1, Scope, BaseType, 2, 3,
+ 4, 5, getTuple()));
+
+ TempDIDerivedType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DIDerivedTypeTest, getWithLargeValues) {
+ DIFile *File = getFile();
+ DIScopeRef Scope = getSubprogramRef();
+ DITypeRef BaseType = getBasicType("basic");
+ MDTuple *ExtraData = getTuple();
+
+ auto *N = DIDerivedType::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 DICompositeTypeTest;
+
+TEST_F(DICompositeTypeTest, get) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ DIFile *File = getFile();
+ unsigned Line = 1;
+ DIScopeRef Scope = getSubprogramRef();
+ DITypeRef BaseType = getCompositeType();
+ uint64_t SizeInBits = 2;
+ uint64_t AlignInBits = 3;
+ uint64_t OffsetInBits = 4;
+ unsigned Flags = 5;
+ MDTuple *Elements = getTuple();
+ unsigned RuntimeLang = 6;
+ DITypeRef VTableHolder = getCompositeType();
+ MDTuple *TemplateParams = getTuple();
+ StringRef Identifier = "some id";
+
+ auto *N = DICompositeType::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().get());
+ EXPECT_EQ(RuntimeLang, N->getRuntimeLang());
+ EXPECT_EQ(VTableHolder, N->getVTableHolder());
+ EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
+ EXPECT_EQ(Identifier, N->getIdentifier());
+
+ EXPECT_EQ(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+
+ EXPECT_NE(N, DICompositeType::get(Context, Tag + 1, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(Context, Tag, "abc", File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, getFile(), Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line + 1, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, getSubprogramRef(), BaseType,
+ SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
+ RuntimeLang, VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, getBasicType("other"),
+ SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
+ RuntimeLang, VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits + 1, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits + 1,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags + 1, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, getTuple(), RuntimeLang,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1,
+ VTableHolder, TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(
+ Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
+ AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
+ getCompositeType(), TemplateParams, Identifier));
+ EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, getTuple(), Identifier));
+ EXPECT_NE(N, DICompositeType::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(DICompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams, "")
+ ->getRawIdentifier());
+ EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope,
+ BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang,
+ VTableHolder, TemplateParams)
+ ->getRawIdentifier());
+
+ TempDICompositeType Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DICompositeTypeTest, getWithLargeValues) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ DIFile *File = getFile();
+ unsigned Line = 1;
+ DIScopeRef Scope = getSubprogramRef();
+ DITypeRef BaseType = getCompositeType();
+ uint64_t SizeInBits = UINT64_MAX;
+ uint64_t AlignInBits = UINT64_MAX - 1;
+ uint64_t OffsetInBits = UINT64_MAX - 2;
+ unsigned Flags = 5;
+ MDTuple *Elements = getTuple();
+ unsigned RuntimeLang = 6;
+ DITypeRef VTableHolder = getCompositeType();
+ MDTuple *TemplateParams = getTuple();
+ StringRef Identifier = "some id";
+
+ auto *N = DICompositeType::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(DICompositeTypeTest, replaceOperands) {
+ unsigned Tag = dwarf::DW_TAG_structure_type;
+ StringRef Name = "some name";
+ DIFile *File = getFile();
+ unsigned Line = 1;
+ DIScopeRef Scope = getSubprogramRef();
+ DITypeRef BaseType = getCompositeType();
+ uint64_t SizeInBits = 2;
+ uint64_t AlignInBits = 3;
+ uint64_t OffsetInBits = 4;
+ unsigned Flags = 5;
+ unsigned RuntimeLang = 6;
+ StringRef Identifier = "some id";
+
+ auto *N = DICompositeType::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().get());
+ N->replaceElements(Elements);
+ EXPECT_EQ(Elements, N->getElements().get());
+ N->replaceElements(nullptr);
+ EXPECT_EQ(nullptr, N->getElements().get());
+
+ DITypeRef VTableHolder = getCompositeType();
+ 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().get());
+ N->replaceTemplateParams(TemplateParams);
+ EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
+ N->replaceTemplateParams(nullptr);
+ EXPECT_EQ(nullptr, N->getTemplateParams().get());
+}
+
+typedef MetadataTest DISubroutineTypeTest;
+
+TEST_F(DISubroutineTypeTest, get) {
+ unsigned Flags = 1;
+ MDTuple *TypeArray = getTuple();
+
+ auto *N = DISubroutineType::get(Context, Flags, TypeArray);
+ EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag());
+ EXPECT_EQ(Flags, N->getFlags());
+ EXPECT_EQ(TypeArray, N->getTypeArray().get());
+ EXPECT_EQ(N, DISubroutineType::get(Context, Flags, TypeArray));
+
+ EXPECT_NE(N, DISubroutineType::get(Context, Flags + 1, TypeArray));
+ EXPECT_NE(N, DISubroutineType::get(Context, Flags, getTuple()));
+
+ TempDISubroutineType 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().get());
+ EXPECT_EQ("", N->getIdentifier());
+}
+
+typedef MetadataTest DIFileTest;
+
+TEST_F(DIFileTest, get) {
+ StringRef Filename = "file";
+ StringRef Directory = "dir";
+ auto *N = DIFile::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, DIFile::get(Context, Filename, Directory));
+
+ EXPECT_NE(N, DIFile::get(Context, "other", Directory));
+ EXPECT_NE(N, DIFile::get(Context, Filename, "other"));
+
+ TempDIFile Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DIFileTest, ScopeGetFile) {
+ // Ensure that DIScope::getFile() returns itself.
+ DIScope *N = DIFile::get(Context, "file", "dir");
+ EXPECT_EQ(N, N->getFile());
+}
+
+typedef MetadataTest DICompileUnitTest;
+
+TEST_F(DICompileUnitTest, get) {
+ unsigned SourceLanguage = 1;
+ DIFile *File = getFile();
+ StringRef Producer = "some producer";
+ bool IsOptimized = false;
+ StringRef Flags = "flag after flag";
+ unsigned RuntimeVersion = 2;
+ StringRef SplitDebugFilename = "another/file";
+ unsigned EmissionKind = 3;
+ MDTuple *EnumTypes = getTuple();
+ MDTuple *RetainedTypes = getTuple();
+ MDTuple *Subprograms = getTuple();
+ MDTuple *GlobalVariables = getTuple();
+ MDTuple *ImportedEntities = getTuple();
+ uint64_t DWOId = 0xc0ffee;
+ auto *N = DICompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, DWOId);
+
+ 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().get());
+ EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get());
+ EXPECT_EQ(Subprograms, N->getSubprograms().get());
+ EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get());
+ EXPECT_EQ(ImportedEntities, N->getImportedEntities().get());
+ EXPECT_EQ(DWOId, N->getDWOId());
+ EXPECT_EQ(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage + 1, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, getFile(), Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, "other",
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ !IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, "other", RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion + 1,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion, "other",
+ EmissionKind, EnumTypes, RetainedTypes,
+ Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind + 1,
+ EnumTypes, RetainedTypes, Subprograms,
+ GlobalVariables, ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, getTuple(),
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ getTuple(), Subprograms, GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, getTuple(), GlobalVariables,
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, getTuple(),
+ ImportedEntities, DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ getTuple(), DWOId));
+ EXPECT_NE(N, DICompileUnit::get(Context, SourceLanguage, File, Producer,
+ IsOptimized, Flags, RuntimeVersion,
+ SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, Subprograms, GlobalVariables,
+ ImportedEntities, DWOId + 1));
+
+ TempDICompileUnit Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DICompileUnitTest, replaceArrays) {
+ unsigned SourceLanguage = 1;
+ DIFile *File = getFile();
+ StringRef Producer = "some producer";
+ bool IsOptimized = false;
+ StringRef Flags = "flag after flag";
+ unsigned RuntimeVersion = 2;
+ StringRef SplitDebugFilename = "another/file";
+ unsigned EmissionKind = 3;
+ MDTuple *EnumTypes = MDTuple::getDistinct(Context, None);
+ MDTuple *RetainedTypes = MDTuple::getDistinct(Context, None);
+ MDTuple *ImportedEntities = MDTuple::getDistinct(Context, None);
+ uint64_t DWOId = 0xc0ffee;
+ auto *N = DICompileUnit::get(
+ Context, SourceLanguage, File, Producer, IsOptimized, Flags,
+ RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
+ RetainedTypes, nullptr, nullptr, ImportedEntities, DWOId);
+
+ auto *Subprograms = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getSubprograms().get());
+ N->replaceSubprograms(Subprograms);
+ EXPECT_EQ(Subprograms, N->getSubprograms().get());
+ N->replaceSubprograms(nullptr);
+ EXPECT_EQ(nullptr, N->getSubprograms().get());
+
+ auto *GlobalVariables = MDTuple::getDistinct(Context, None);
+ EXPECT_EQ(nullptr, N->getGlobalVariables().get());
+ N->replaceGlobalVariables(GlobalVariables);
+ EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get());
+ N->replaceGlobalVariables(nullptr);
+ EXPECT_EQ(nullptr, N->getGlobalVariables().get());
+}
+
+typedef MetadataTest DISubprogramTest;
+
+TEST_F(DISubprogramTest, get) {
+ DIScopeRef Scope = getCompositeType();
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ DIFile *File = getFile();
+ unsigned Line = 2;
+ DISubroutineType *Type = getSubroutineType();
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ unsigned ScopeLine = 3;
+ DITypeRef ContainingType = getCompositeType();
+ unsigned Virtuality = 4;
+ unsigned VirtualIndex = 5;
+ unsigned Flags = 6;
+ bool IsOptimized = false;
+ llvm::Function *Function = getFunction("foo");
+ MDTuple *TemplateParams = getTuple();
+ DISubprogram *Declaration = getSubprogram();
+ MDTuple *Variables = getTuple();
+
+ auto *N = DISubprogram::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().get());
+ EXPECT_EQ(Declaration, N->getDeclaration());
+ EXPECT_EQ(Variables, N->getVariables().get());
+ EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+
+ EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName,
+ File, Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(),
+ Line, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File,
+ Line + 1, Type, IsLocalToUnit, IsDefinition,
+ ScopeLine, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(
+ Context, Scope, Name, LinkageName, File, Line,
+ getSubroutineType(), IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex, Flags, IsOptimized,
+ Function, TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, !IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, !IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ ScopeLine + 1, ContainingType, Virtuality,
+ VirtualIndex, Flags, IsOptimized, Function,
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ getCompositeType(), Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality + 1, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex + 1,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ ~Flags, IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, !IsOptimized, Function, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, getFunction("bar"),
+ TemplateParams, Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, getTuple(),
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ getSubprogram(), Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Function, TemplateParams,
+ Declaration, getTuple()));
+
+ TempDISubprogram Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DISubprogramTest, replaceFunction) {
+ DIScopeRef Scope = getCompositeType();
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ DIFile *File = getFile();
+ unsigned Line = 2;
+ DISubroutineType *Type = getSubroutineType();
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ unsigned ScopeLine = 3;
+ DITypeRef ContainingType = getCompositeType();
+ unsigned Virtuality = 4;
+ unsigned VirtualIndex = 5;
+ unsigned Flags = 6;
+ bool IsOptimized = false;
+ MDTuple *TemplateParams = getTuple();
+ DISubprogram *Declaration = getSubprogram();
+ MDTuple *Variables = getTuple();
+
+ auto *N = DISubprogram::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(F.get(), N->getFunction());
+
+ N->replaceFunction(nullptr);
+ EXPECT_EQ(nullptr, N->getFunction());
+}
+
+typedef MetadataTest DILexicalBlockTest;
+
+TEST_F(DILexicalBlockTest, get) {
+ DILocalScope *Scope = getSubprogram();
+ DIFile *File = getFile();
+ unsigned Line = 5;
+ unsigned Column = 8;
+
+ auto *N = DILexicalBlock::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, DILexicalBlock::get(Context, Scope, File, Line, Column));
+
+ EXPECT_NE(N,
+ DILexicalBlock::get(Context, getSubprogram(), File, Line, Column));
+ EXPECT_NE(N, DILexicalBlock::get(Context, Scope, getFile(), Line, Column));
+ EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line + 1, Column));
+ EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line, Column + 1));
+
+ TempDILexicalBlock Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DILexicalBlockFileTest;
+
+TEST_F(DILexicalBlockFileTest, get) {
+ DILocalScope *Scope = getSubprogram();
+ DIFile *File = getFile();
+ unsigned Discriminator = 5;
+
+ auto *N = DILexicalBlockFile::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, DILexicalBlockFile::get(Context, Scope, File, Discriminator));
+
+ EXPECT_NE(N, DILexicalBlockFile::get(Context, getSubprogram(), File,
+ Discriminator));
+ EXPECT_NE(N,
+ DILexicalBlockFile::get(Context, Scope, getFile(), Discriminator));
+ EXPECT_NE(N,
+ DILexicalBlockFile::get(Context, Scope, File, Discriminator + 1));
+
+ TempDILexicalBlockFile Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DINamespaceTest;
+
+TEST_F(DINamespaceTest, get) {
+ DIScope *Scope = getFile();
+ DIFile *File = getFile();
+ StringRef Name = "namespace";
+ unsigned Line = 5;
+
+ auto *N = DINamespace::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, DINamespace::get(Context, Scope, File, Name, Line));
+
+ EXPECT_NE(N, DINamespace::get(Context, getFile(), File, Name, Line));
+ EXPECT_NE(N, DINamespace::get(Context, Scope, getFile(), Name, Line));
+ EXPECT_NE(N, DINamespace::get(Context, Scope, File, "other", Line));
+ EXPECT_NE(N, DINamespace::get(Context, Scope, File, Name, Line + 1));
+
+ TempDINamespace Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DITemplateTypeParameterTest;
+
+TEST_F(DITemplateTypeParameterTest, get) {
+ StringRef Name = "template";
+ DITypeRef Type = getBasicType("basic");
+
+ auto *N = DITemplateTypeParameter::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, DITemplateTypeParameter::get(Context, Name, Type));
+
+ EXPECT_NE(N, DITemplateTypeParameter::get(Context, "other", Type));
+ EXPECT_NE(N,
+ DITemplateTypeParameter::get(Context, Name, getBasicType("other")));
+
+ TempDITemplateTypeParameter Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DITemplateValueParameterTest;
+
+TEST_F(DITemplateValueParameterTest, get) {
+ unsigned Tag = dwarf::DW_TAG_template_value_parameter;
+ StringRef Name = "template";
+ DITypeRef Type = getBasicType("basic");
+ Metadata *Value = getConstantAsMetadata();
+
+ auto *N = DITemplateValueParameter::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, DITemplateValueParameter::get(Context, Tag, Name, Type, Value));
+
+ EXPECT_NE(N, DITemplateValueParameter::get(
+ Context, dwarf::DW_TAG_GNU_template_template_param, Name,
+ Type, Value));
+ EXPECT_NE(N,
+ DITemplateValueParameter::get(Context, Tag, "other", Type, Value));
+ EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name,
+ getBasicType("other"), Value));
+ EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name, Type,
+ getConstantAsMetadata()));
+
+ TempDITemplateValueParameter Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DIGlobalVariableTest;
+
+TEST_F(DIGlobalVariableTest, get) {
+ DIScope *Scope = getSubprogram();
+ StringRef Name = "name";
+ StringRef LinkageName = "linkage";
+ DIFile *File = getFile();
+ unsigned Line = 5;
+ DITypeRef Type = getDerivedType();
+ bool IsLocalToUnit = false;
+ bool IsDefinition = true;
+ Constant *Variable = getConstant();
+ DIDerivedType *StaticDataMemberDeclaration =
+ cast<DIDerivedType>(getDerivedType());
+
+ auto *N = DIGlobalVariable::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, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+
+ EXPECT_NE(N,
+ DIGlobalVariable::get(Context, getSubprogram(), Name, LinkageName,
+ File, Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File,
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(),
+ Line, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line + 1, Type, IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
+ getDerivedType(), IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, !IsLocalToUnit, IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
+ Line, Type, IsLocalToUnit, !IsDefinition,
+ Variable, StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition,
+ getConstant(), StaticDataMemberDeclaration));
+ EXPECT_NE(N,
+ DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, Variable,
+ cast<DIDerivedType>(getDerivedType())));
+
+ TempDIGlobalVariable Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DILocalVariableTest;
+
+TEST_F(DILocalVariableTest, get) {
+ unsigned Tag = dwarf::DW_TAG_arg_variable;
+ DILocalScope *Scope = getSubprogram();
+ StringRef Name = "name";
+ DIFile *File = getFile();
+ unsigned Line = 5;
+ DITypeRef Type = getDerivedType();
+ unsigned Arg = 6;
+ unsigned Flags = 7;
+
+ auto *N = DILocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags);
+ 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(N, DILocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, Flags));
+
+ EXPECT_NE(N, DILocalVariable::get(Context, dwarf::DW_TAG_auto_variable, Scope,
+ Name, File, Line, Type, Arg, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, getSubprogram(), Name, File,
+ Line, Type, Arg, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, Scope, "other", File, Line,
+ Type, Arg, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, Scope, Name, getFile(), Line,
+ Type, Arg, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, Scope, Name, File, Line + 1,
+ Type, Arg, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, Scope, Name, File, Line,
+ getDerivedType(), Arg, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg + 1, Flags));
+ EXPECT_NE(N, DILocalVariable::get(Context, Tag, Scope, Name, File, Line, Type,
+ Arg, ~Flags));
+
+ TempDILocalVariable Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DILocalVariableTest, getArg256) {
+ EXPECT_EQ(255u, DILocalVariable::get(Context, dwarf::DW_TAG_arg_variable,
+ getSubprogram(), "", getFile(), 0,
+ nullptr, 255, 0)
+ ->getArg());
+ EXPECT_EQ(256u, DILocalVariable::get(Context, dwarf::DW_TAG_arg_variable,
+ getSubprogram(), "", getFile(), 0,
+ nullptr, 256, 0)
+ ->getArg());
+ EXPECT_EQ(257u, DILocalVariable::get(Context, dwarf::DW_TAG_arg_variable,
+ getSubprogram(), "", getFile(), 0,
+ nullptr, 257, 0)
+ ->getArg());
+ unsigned Max = UINT16_MAX;
+ EXPECT_EQ(Max, DILocalVariable::get(Context, dwarf::DW_TAG_arg_variable,
+ getSubprogram(), "", getFile(), 0,
+ nullptr, Max, 0)
+ ->getArg());
+}
+
+typedef MetadataTest DIExpressionTest;
+
+TEST_F(DIExpressionTest, get) {
+ uint64_t Elements[] = {2, 6, 9, 78, 0};
+ auto *N = DIExpression::get(Context, Elements);
+ EXPECT_EQ(makeArrayRef(Elements), N->getElements());
+ EXPECT_EQ(N, DIExpression::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));
+
+ TempDIExpression Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+TEST_F(DIExpressionTest, isValid) {
+#define EXPECT_VALID(...) \
+ do { \
+ uint64_t Elements[] = {__VA_ARGS__}; \
+ EXPECT_TRUE(DIExpression::get(Context, Elements)->isValid()); \
+ } while (false)
+#define EXPECT_INVALID(...) \
+ do { \
+ uint64_t Elements[] = {__VA_ARGS__}; \
+ EXPECT_FALSE(DIExpression::get(Context, Elements)->isValid()); \
+ } while (false)
+
+ // Empty expression should be valid.
+ EXPECT_TRUE(DIExpression::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 DIObjCPropertyTest;
+
+TEST_F(DIObjCPropertyTest, get) {
+ StringRef Name = "name";
+ DIFile *File = getFile();
+ unsigned Line = 5;
+ StringRef GetterName = "getter";
+ StringRef SetterName = "setter";
+ unsigned Attributes = 7;
+ DIType *Type = cast<DIBasicType>(getBasicType("basic"));
+
+ auto *N = DIObjCProperty::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, DIObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes, Type));
+
+ EXPECT_NE(N, DIObjCProperty::get(Context, "other", File, Line, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, DIObjCProperty::get(Context, Name, getFile(), Line, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line + 1, GetterName,
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, "other",
+ SetterName, Attributes, Type));
+ EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
+ "other", Attributes, Type));
+ EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes + 1, Type));
+ EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
+ SetterName, Attributes,
+ cast<DIBasicType>(getBasicType("other"))));
+
+ TempDIObjCProperty Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
+}
+
+typedef MetadataTest DIImportedEntityTest;
+
+TEST_F(DIImportedEntityTest, get) {
+ unsigned Tag = dwarf::DW_TAG_imported_module;
+ DIScope *Scope = getSubprogram();
+ DINodeRef Entity = getCompositeType();
+ unsigned Line = 5;
+ StringRef Name = "name";
+
+ auto *N = DIImportedEntity::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, DIImportedEntity::get(Context, Tag, Scope, Entity, Line, Name));
+
+ EXPECT_NE(N,
+ DIImportedEntity::get(Context, dwarf::DW_TAG_imported_declaration,
+ Scope, Entity, Line, Name));
+ EXPECT_NE(N, DIImportedEntity::get(Context, Tag, getSubprogram(), Entity,
+ Line, Name));
+ EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, getCompositeType(),
+ Line, Name));
+ EXPECT_NE(N,
+ DIImportedEntity::get(Context, Tag, Scope, Entity, Line + 1, Name));
+ EXPECT_NE(N,
+ DIImportedEntity::get(Context, Tag, Scope, Entity, Line, "other"));
+
+ TempDIImportedEntity Temp = N->clone();
+ EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
}
typedef MetadataTest MetadataAsValueTest;
@@ -490,7 +2081,7 @@ TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) {
ConstantInt::get(getGlobalContext(), APInt(8, 0)));
// Create a temporary to prevent nodes from resolving.
- std::unique_ptr<MDNodeFwdDecl> Temp(MDNode::getTemporary(Context, None));
+ 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()};
@@ -567,4 +2158,137 @@ TEST(NamedMDNodeTest, Search) {
EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n",
oss.str().c_str());
}
+
+typedef MetadataTest FunctionAttachmentTest;
+TEST_F(FunctionAttachmentTest, setMetadata) {
+ Function *F = getFunction("foo");
+ ASSERT_FALSE(F->hasMetadata());
+ EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg));
+ EXPECT_EQ(nullptr, F->getMetadata("dbg"));
+ EXPECT_EQ(nullptr, F->getMetadata("other"));
+
+ DISubprogram *SP1 = getSubprogram();
+ DISubprogram *SP2 = getSubprogram();
+ ASSERT_NE(SP1, SP2);
+
+ F->setMetadata("dbg", SP1);
+ EXPECT_TRUE(F->hasMetadata());
+ EXPECT_EQ(SP1, F->getMetadata(LLVMContext::MD_dbg));
+ EXPECT_EQ(SP1, F->getMetadata("dbg"));
+ EXPECT_EQ(nullptr, F->getMetadata("other"));
+
+ F->setMetadata(LLVMContext::MD_dbg, SP2);
+ EXPECT_TRUE(F->hasMetadata());
+ EXPECT_EQ(SP2, F->getMetadata(LLVMContext::MD_dbg));
+ EXPECT_EQ(SP2, F->getMetadata("dbg"));
+ EXPECT_EQ(nullptr, F->getMetadata("other"));
+
+ F->setMetadata("dbg", nullptr);
+ EXPECT_FALSE(F->hasMetadata());
+ EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg));
+ EXPECT_EQ(nullptr, F->getMetadata("dbg"));
+ EXPECT_EQ(nullptr, F->getMetadata("other"));
+
+ MDTuple *T1 = getTuple();
+ MDTuple *T2 = getTuple();
+ ASSERT_NE(T1, T2);
+
+ F->setMetadata("other1", T1);
+ F->setMetadata("other2", T2);
+ EXPECT_TRUE(F->hasMetadata());
+ EXPECT_EQ(T1, F->getMetadata("other1"));
+ EXPECT_EQ(T2, F->getMetadata("other2"));
+ EXPECT_EQ(nullptr, F->getMetadata("dbg"));
+
+ F->setMetadata("other1", T2);
+ F->setMetadata("other2", T1);
+ EXPECT_EQ(T2, F->getMetadata("other1"));
+ EXPECT_EQ(T1, F->getMetadata("other2"));
+
+ F->setMetadata("other1", nullptr);
+ F->setMetadata("other2", nullptr);
+ EXPECT_FALSE(F->hasMetadata());
+ EXPECT_EQ(nullptr, F->getMetadata("other1"));
+ EXPECT_EQ(nullptr, F->getMetadata("other2"));
+}
+
+TEST_F(FunctionAttachmentTest, getAll) {
+ Function *F = getFunction("foo");
+
+ MDTuple *T1 = getTuple();
+ MDTuple *T2 = getTuple();
+ MDTuple *P = getTuple();
+ DISubprogram *SP = getSubprogram();
+
+ F->setMetadata("other1", T2);
+ F->setMetadata(LLVMContext::MD_dbg, SP);
+ F->setMetadata("other2", T1);
+ F->setMetadata(LLVMContext::MD_prof, P);
+ F->setMetadata("other2", T2);
+ F->setMetadata("other1", T1);
+
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ F->getAllMetadata(MDs);
+ ASSERT_EQ(4u, MDs.size());
+ EXPECT_EQ(LLVMContext::MD_dbg, MDs[0].first);
+ EXPECT_EQ(LLVMContext::MD_prof, MDs[1].first);
+ EXPECT_EQ(Context.getMDKindID("other1"), MDs[2].first);
+ EXPECT_EQ(Context.getMDKindID("other2"), MDs[3].first);
+ EXPECT_EQ(SP, MDs[0].second);
+ EXPECT_EQ(P, MDs[1].second);
+ EXPECT_EQ(T1, MDs[2].second);
+ EXPECT_EQ(T2, MDs[3].second);
+}
+
+TEST_F(FunctionAttachmentTest, dropUnknownMetadata) {
+ Function *F = getFunction("foo");
+
+ MDTuple *T1 = getTuple();
+ MDTuple *T2 = getTuple();
+ MDTuple *P = getTuple();
+ DISubprogram *SP = getSubprogram();
+
+ F->setMetadata("other1", T1);
+ F->setMetadata(LLVMContext::MD_dbg, SP);
+ F->setMetadata("other2", T2);
+ F->setMetadata(LLVMContext::MD_prof, P);
+
+ unsigned Known[] = {Context.getMDKindID("other2"), LLVMContext::MD_prof};
+ F->dropUnknownMetadata(Known);
+
+ EXPECT_EQ(T2, F->getMetadata("other2"));
+ EXPECT_EQ(P, F->getMetadata(LLVMContext::MD_prof));
+ EXPECT_EQ(nullptr, F->getMetadata("other1"));
+ EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg));
+
+ F->setMetadata("other2", nullptr);
+ F->setMetadata(LLVMContext::MD_prof, nullptr);
+ EXPECT_FALSE(F->hasMetadata());
+}
+
+TEST_F(FunctionAttachmentTest, Verifier) {
+ Function *F = getFunction("foo");
+ F->setMetadata("attach", getTuple());
+
+ // Confirm this has no body.
+ ASSERT_TRUE(F->empty());
+
+ // Functions without a body cannot have metadata attachments (they also can't
+ // be verified directly, so check that the module fails to verify).
+ EXPECT_TRUE(verifyModule(*F->getParent()));
+
+ // Functions with a body can.
+ (void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F));
+ EXPECT_FALSE(verifyModule(*F->getParent()));
+ EXPECT_FALSE(verifyFunction(*F));
+}
+
+TEST_F(FunctionAttachmentTest, EntryCount) {
+ Function *F = getFunction("foo");
+ EXPECT_FALSE(F->getEntryCount().hasValue());
+ F->setEntryCount(12304);
+ EXPECT_TRUE(F->getEntryCount().hasValue());
+ EXPECT_EQ(12304u, *F->getEntryCount());
+}
+
}
diff --git a/unittests/IR/UseTest.cpp b/unittests/IR/UseTest.cpp
index b575a59784085..d9d20af941d64 100644
--- a/unittests/IR/UseTest.cpp
+++ b/unittests/IR/UseTest.cpp
@@ -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/ValueHandleTest.cpp b/unittests/IR/ValueHandleTest.cpp
index 403d2bcbda16e..e6eb7cbedc681 100644
--- a/unittests/IR/ValueHandleTest.cpp
+++ b/unittests/IR/ValueHandleTest.cpp
@@ -21,7 +21,7 @@ namespace {
class ValueHandle : public testing::Test {
protected:
Constant *ConstantV;
- std::auto_ptr<BitCastInst> BitcastV;
+ std::unique_ptr<BitCastInst> BitcastV;
ValueHandle() :
ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
@@ -244,8 +244,11 @@ TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
private:
- virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
- virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
+ void deleted() override {
+ DeletedCalls++;
+ CallbackVH::deleted();
+ }
+ void allUsesReplacedWith(Value *) override { AURWCalls++; }
};
RecordingVH RVH;
@@ -268,8 +271,11 @@ TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
: CallbackVH(V), DeletedCalls(0), AURWArgument(nullptr) {}
private:
- virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
- virtual void allUsesReplacedWith(Value *new_value) {
+ void deleted() override {
+ DeletedCalls++;
+ CallbackVH::deleted();
+ }
+ void allUsesReplacedWith(Value *new_value) override {
EXPECT_EQ(nullptr, AURWArgument);
AURWArgument = new_value;
}
@@ -298,11 +304,11 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
Context(&getGlobalContext()) {}
private:
- virtual void deleted() {
+ void deleted() override {
getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
setValPtr(nullptr);
}
- virtual void allUsesReplacedWith(Value *new_value) {
+ void allUsesReplacedWith(Value *new_value) override {
ASSERT_TRUE(nullptr != getValPtr());
EXPECT_EQ(1U, getValPtr()->getNumUses());
EXPECT_EQ(nullptr, AURWArgument);
@@ -314,7 +320,7 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
// a CallbackVH to remove the uses before the check for no uses.
RecoveringVH RVH;
RVH = BitcastV.get();
- std::auto_ptr<BinaryOperator> BitcastUser(
+ std::unique_ptr<BinaryOperator> BitcastUser(
BinaryOperator::CreateAdd(RVH,
Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
@@ -341,12 +347,12 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
setValPtr(V);
ToClear[1].reset(new WeakVH(V));
}
- virtual void deleted() {
+ void deleted() override {
ToClear[0].reset();
ToClear[1].reset();
CallbackVH::deleted();
}
- virtual void allUsesReplacedWith(Value *) {
+ void allUsesReplacedWith(Value *) override {
ToClear[0].reset();
ToClear[1].reset();
}
@@ -388,7 +394,7 @@ TEST_F(ValueHandle, AssertingVHCheckedLast) {
ToClear[1] = &A1;
}
- virtual void deleted() {
+ void deleted() override {
*ToClear[0] = nullptr;
*ToClear[1] = nullptr;
CallbackVH::deleted();
diff --git a/unittests/IR/ValueMapTest.cpp b/unittests/IR/ValueMapTest.cpp
index a6bad71cf630f..1431a8d87de4a 100644
--- a/unittests/IR/ValueMapTest.cpp
+++ b/unittests/IR/ValueMapTest.cpp
@@ -194,7 +194,8 @@ struct LockMutex : ValueMapConfig<KeyT, MutexT> {
}
static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
};
-#if LLVM_ENABLE_THREADS
+// FIXME: These tests started failing on Windows.
+#if LLVM_ENABLE_THREADS && !defined(LLVM_ON_WIN32)
TYPED_TEST(ValueMapTest, LocksMutex) {
sys::Mutex M(false); // Not recursive.
bool CalledRAUW = false, CalledDeleted = false;
diff --git a/unittests/LineEditor/LineEditor.cpp b/unittests/LineEditor/LineEditor.cpp
index 26053c0ede241..4d9081fd5c201 100644
--- a/unittests/LineEditor/LineEditor.cpp
+++ b/unittests/LineEditor/LineEditor.cpp
@@ -29,7 +29,7 @@ public:
LE = new LineEditor("test", HistPath);
}
- ~LineEditorTest() {
+ ~LineEditorTest() override {
delete LE;
sys::fs::remove(HistPath.str());
}
diff --git a/unittests/Linker/LinkModulesTest.cpp b/unittests/Linker/LinkModulesTest.cpp
index 91f97d76c9edb..b4689cba560e8 100644
--- a/unittests/Linker/LinkModulesTest.cpp
+++ b/unittests/Linker/LinkModulesTest.cpp
@@ -23,7 +23,7 @@ namespace {
class LinkModuleTest : public testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
M.reset(new Module("MyModule", Ctx));
FunctionType *FTy = FunctionType::get(
Type::getInt8PtrTy(Ctx), Type::getInt32Ty(Ctx), false /*=isVarArg*/);
@@ -35,7 +35,7 @@ protected:
SwitchCase2BB = BasicBlock::Create(Ctx, "switch.case.2", F);
ExitBB = BasicBlock::Create(Ctx, "exit", F);
- ArrayType *AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
+ AT = ArrayType::get(Type::getInt8PtrTy(Ctx), 3);
GV = new GlobalVariable(*M.get(), AT, false /*=isConstant*/,
GlobalValue::InternalLinkage, nullptr,"switch.bas");
@@ -56,11 +56,12 @@ protected:
GV->setInitializer(ConstantArray::get(AT, Init));
}
- virtual void TearDown() { M.reset(); }
+ void TearDown() override { M.reset(); }
LLVMContext Ctx;
std::unique_ptr<Module> M;
Function *F;
+ ArrayType *AT;
GlobalVariable *GV;
BasicBlock *EntryBB;
BasicBlock *SwitchCase1BB;
@@ -75,7 +76,7 @@ TEST_F(LinkModuleTest, BlockAddress) {
GEPIndices.push_back(ConstantInt::get(Type::getInt32Ty(Ctx), 0));
GEPIndices.push_back(F->arg_begin());
- Value *GEP = Builder.CreateGEP(GV, GEPIndices, "switch.gep");
+ Value *GEP = Builder.CreateGEP(AT, GV, GEPIndices, "switch.gep");
Value *Load = Builder.CreateLoad(GEP, "switch.load");
Builder.CreateRet(Load);
diff --git a/unittests/Makefile b/unittests/Makefile
index 603e7d58f8c70..bf2ed22efea78 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -9,8 +9,9 @@
LEVEL = ..
-PARALLEL_DIRS = ADT Analysis Bitcode CodeGen DebugInfo ExecutionEngine IR \
- LineEditor Linker MC Option Support Transforms
+PARALLEL_DIRS = ADT Analysis AsmParser Bitcode CodeGen DebugInfo \
+ ExecutionEngine IR LineEditor Linker MC Option ProfileData \
+ Support Transforms
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Option/OptionParsingTest.cpp b/unittests/Option/OptionParsingTest.cpp
index aa32da3a595fd..521009a9e663f 100644
--- a/unittests/Option/OptionParsingTest.cpp
+++ b/unittests/Option/OptionParsingTest.cpp
@@ -209,3 +209,17 @@ TEST(Option, Slurp) {
EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[1], "--");
EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[2], "foo");
}
+
+TEST(Option, FlagAliasToJoined) {
+ TestOptTable T;
+ unsigned MAI, MAC;
+
+ // Check that a flag alias provides an empty argument to a joined option.
+ const char *MyArgs[] = { "-K" };
+ std::unique_ptr<InputArgList> AL(
+ T.ParseArgs(std::begin(MyArgs), std::end(MyArgs), MAI, MAC));
+ EXPECT_EQ(AL->size(), 1U);
+ EXPECT_TRUE(AL->hasArg(OPT_B));
+ EXPECT_EQ(AL->getAllArgValues(OPT_B).size(), 1U);
+ EXPECT_EQ(AL->getAllArgValues(OPT_B)[0], "");
+}
diff --git a/unittests/Option/Opts.td b/unittests/Option/Opts.td
index aaed6b2101e00..c96774a68e0b0 100644
--- a/unittests/Option/Opts.td
+++ b/unittests/Option/Opts.td
@@ -23,4 +23,6 @@ def I : Flag<["-"], "I">, Alias<H>, Group<my_group>;
def J : Flag<["-"], "J">, Alias<B>, AliasArgs<["foo"]>;
def Joo : Flag<["-"], "Joo">, Alias<B>, AliasArgs<["bar"]>;
+def K : Flag<["-"], "K">, Alias<B>;
+
def Slurp : Option<["-"], "slurp", KIND_REMAINING_ARGS>;
diff --git a/unittests/ProfileData/CMakeLists.txt b/unittests/ProfileData/CMakeLists.txt
new file mode 100644
index 0000000000000..79137c9510aee
--- /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 0000000000000..a0995fbbc0287
--- /dev/null
+++ b/unittests/ProfileData/CoverageMappingTest.cpp
@@ -0,0 +1,291 @@
+//===- 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, uncovered_function_with_mapping) {
+ readProfCounts();
+
+ addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
+ addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
+ loadCoverageMapping("func", 0x1234);
+
+ CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
+ std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
+ ASSERT_EQ(3U, Segments.size());
+ ASSERT_EQ(CoverageSegment(1, 1, 0, true), Segments[0]);
+ ASSERT_EQ(CoverageSegment(4, 7, 0, false), Segments[1]);
+ ASSERT_EQ(CoverageSegment(9, 9, false), Segments[2]);
+}
+
+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]);
+}
+
+TEST_F(CoverageMappingTest, strip_filename_prefix) {
+ ProfileWriter.addFunctionCounts("file1:func", 0x1234, {10});
+ readProfCounts();
+
+ addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
+ loadCoverageMapping("file1:func", 0x1234);
+
+ std::vector<std::string> Names;
+ for (const auto &Func : LoadedCoverage->getCoveredFunctions())
+ Names.push_back(Func.Name);
+ ASSERT_EQ(1U, Names.size());
+ ASSERT_EQ("func", Names[0]);
+}
+
+} // end anonymous namespace
diff --git a/unittests/ProfileData/InstrProfTest.cpp b/unittests/ProfileData/InstrProfTest.cpp
new file mode 100644
index 0000000000000..26ea0e44ca42e
--- /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 0000000000000..d017c15c00adc
--- /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 40f729585728c..e0859fc747f4c 100644
--- a/unittests/Support/AlignOfTest.cpp
+++ b/unittests/Support/AlignOfTest.cpp
@@ -7,6 +7,12 @@
//
//===----------------------------------------------------------------------===//
+#ifdef _MSC_VER
+// Disable warnings about alignment-based structure padding.
+// This must be above the includes to suppress warnings in included templates.
+#pragma warning(disable:4324)
+#endif
+
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "gtest/gtest.h"
@@ -22,35 +28,21 @@ 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
// Define some fixed alignment types to use in these tests.
-#if __has_feature(cxx_alignas)
-struct alignas(1) A1 { };
-struct alignas(2) A2 { };
-struct alignas(4) A4 { };
-struct alignas(8) A8 { };
-#elif defined(__GNUC__)
-struct A1 { } __attribute__((aligned(1)));
-struct A2 { } __attribute__((aligned(2)));
-struct A4 { } __attribute__((aligned(4)));
-struct A8 { } __attribute__((aligned(8)));
-#elif defined(_MSC_VER)
-__declspec(align(1)) struct A1 { };
-__declspec(align(2)) struct A2 { };
-__declspec(align(4)) struct A4 { };
-__declspec(align(8)) struct A8 { };
-#else
-# error No supported align as directive.
-#endif
+struct LLVM_ALIGNAS(1) A1 {};
+struct LLVM_ALIGNAS(2) A2 {};
+struct LLVM_ALIGNAS(4) A4 {};
+struct LLVM_ALIGNAS(8) A8 {};
struct S1 {};
struct S2 { char a; };
@@ -69,12 +61,22 @@ struct D8 : S1, D4, D5 { double x[2]; };
struct D9 : S1, D1 { S1 s1; };
struct V1 { virtual ~V1(); };
struct V2 { int x; virtual ~V2(); };
-struct V3 : V1 { virtual ~V3(); };
-struct V4 : virtual V2 { int y; virtual ~V4(); };
-struct V5 : V4, V3 { double z; virtual ~V5(); };
+struct V3 : V1 {
+ ~V3() override;
+};
+struct V4 : virtual V2 { int y;
+ ~V4() override;
+};
+struct V5 : V4, V3 { double z;
+ ~V5() override;
+};
struct V6 : S1 { virtual ~V6(); };
-struct V7 : virtual V2, virtual V6 { virtual ~V7(); };
-struct V8 : V5, virtual V6, V7 { double zz; virtual ~V8(); };
+struct V7 : virtual V2, virtual V6 {
+ ~V7() override;
+};
+struct V8 : V5, virtual V6, V7 { double zz;
+ ~V8() override;
+};
double S6::f() { return 0.0; }
float D2::g() { return 0.0f; }
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
index 7f15776d6f007..38c7fcba8afd4 100644
--- a/unittests/Support/AllocatorTest.cpp
+++ b/unittests/Support/AllocatorTest.cpp
@@ -61,6 +61,13 @@ TEST(AllocatorTest, ThreeSlabs) {
// again.
TEST(AllocatorTest, TestReset) {
BumpPtrAllocator Alloc;
+
+ // Allocate something larger than the SizeThreshold=4096.
+ (void)Alloc.Allocate(5000, 1);
+ Alloc.Reset();
+ // Calling Reset should free all CustomSizedSlabs.
+ EXPECT_EQ(0u, Alloc.GetNumSlabs());
+
Alloc.Allocate(3000, 1);
EXPECT_EQ(1U, Alloc.GetNumSlabs());
Alloc.Allocate(3000, 1);
diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp
index f6e3537de91a9..0eac8bb8811bc 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 dd270ccea42de..564d189d49c2b 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
Support
)
@@ -13,6 +14,8 @@ add_llvm_unittest(SupportTests
CompressionTest.cpp
ConvertUTFTest.cpp
DataExtractorTest.cpp
+ DwarfTest.cpp
+ EndianStreamTest.cpp
EndianTest.cpp
ErrorOrTest.cpp
FileOutputBufferTest.cpp
@@ -35,6 +38,7 @@ add_llvm_unittest(SupportTests
StreamingMemoryObject.cpp
StringPool.cpp
SwapByteOrderTest.cpp
+ TargetRegistry.cpp
ThreadLocalTest.cpp
TimeValueTest.cpp
UnicodeTest.cpp
@@ -42,6 +46,7 @@ add_llvm_unittest(SupportTests
YAMLParserTest.cpp
formatted_raw_ostream_test.cpp
raw_ostream_test.cpp
+ raw_pwrite_stream_test.cpp
)
# ManagedStatic.cpp uses <pthread>.
diff --git a/unittests/Support/Casting.cpp b/unittests/Support/Casting.cpp
index 3218189eeab6c..e6c35fc21eb7d 100644
--- a/unittests/Support/Casting.cpp
+++ b/unittests/Support/Casting.cpp
@@ -250,7 +250,7 @@ class PTy {
Base *B;
public:
PTy(Base *B) : B(B) {}
- LLVM_EXPLICIT operator bool() const { return get(); }
+ explicit operator bool() const { return get(); }
Base *get() const { return B; }
};
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
index ac8d3d8c9d633..328c4b7fcf300 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
}
@@ -63,21 +65,19 @@ public:
StackOption(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
: Base(M0, M1, M2, M3) {}
- ~StackOption() {
- this->removeArgument();
- }
+ ~StackOption() override { this->removeArgument(); }
};
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 +230,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/ConvertUTFTest.cpp b/unittests/Support/ConvertUTFTest.cpp
index 49748db4ae971..d436fc0228963 100644
--- a/unittests/Support/ConvertUTFTest.cpp
+++ b/unittests/Support/ConvertUTFTest.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Format.h"
#include "gtest/gtest.h"
#include <string>
#include <utility>
@@ -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);
diff --git a/unittests/Support/DwarfTest.cpp b/unittests/Support/DwarfTest.cpp
new file mode 100644
index 0000000000000..74fcc989b45a2
--- /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 0000000000000..6a69be55f9266
--- /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/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp
index 82bbe090960ac..5e8d442a70394 100644
--- a/unittests/Support/ErrorOrTest.cpp
+++ b/unittests/Support/ErrorOrTest.cpp
@@ -66,6 +66,11 @@ TEST(ErrorOr, Covariant) {
ErrorOr<std::unique_ptr<int>> b4(b3);
}
+TEST(ErrorOr, Comparison) {
+ ErrorOr<int> x(std::errc::no_such_file_or_directory);
+ EXPECT_EQ(x, std::errc::no_such_file_or_directory);
+}
+
// ErrorOr<int*> x(nullptr);
// ErrorOr<std::unique_ptr<int>> y = x; // invalid conversion
static_assert(
diff --git a/unittests/Support/Makefile b/unittests/Support/Makefile
index 9c0a7f94d7725..21657f12e3dc1 100644
--- a/unittests/Support/Makefile
+++ b/unittests/Support/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
TESTNAME = Support
-LINK_COMPONENTS := core support
+LINK_COMPONENTS := all-targets core support
include $(LEVEL)/Makefile.config
include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp
index 93a38cb03fd93..5c95b500dd4c8 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/MemoryBufferTest.cpp b/unittests/Support/MemoryBufferTest.cpp
index 1cdd6adbf8ba3..ffb809aa207b2 100644
--- a/unittests/Support/MemoryBufferTest.cpp
+++ b/unittests/Support/MemoryBufferTest.cpp
@@ -26,7 +26,7 @@ protected:
: data("this is some data")
{ }
- virtual void SetUp() { }
+ void SetUp() override {}
/// Common testing for different modes of getOpenFileSlice.
/// Creates a temporary file with known contents, and uses
diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp
index 0d661c8ae6c00..262d27260ce43 100644
--- a/unittests/Support/Path.cpp
+++ b/unittests/Support/Path.cpp
@@ -168,6 +168,26 @@ TEST(Support, RelativePathIterator) {
}
}
+TEST(Support, RelativePathDotIterator) {
+ SmallString<64> Path(StringRef(".c/.d/../."));
+ typedef SmallVector<StringRef, 4> PathComponents;
+ PathComponents ExpectedPathComponents;
+ PathComponents ActualPathComponents;
+
+ StringRef(Path).split(ExpectedPathComponents, "/");
+
+ for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
+ ++I) {
+ ActualPathComponents.push_back(*I);
+ }
+
+ ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
+
+ for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
+ EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
+ }
+}
+
TEST(Support, AbsolutePathIterator) {
SmallString<64> Path(StringRef("/c/d/e/foo.txt"));
typedef SmallVector<StringRef, 4> PathComponents;
@@ -191,6 +211,29 @@ TEST(Support, AbsolutePathIterator) {
}
}
+TEST(Support, AbsolutePathDotIterator) {
+ SmallString<64> Path(StringRef("/.c/.d/../."));
+ typedef SmallVector<StringRef, 4> PathComponents;
+ PathComponents ExpectedPathComponents;
+ PathComponents ActualPathComponents;
+
+ StringRef(Path).split(ExpectedPathComponents, "/");
+
+ // The root path will also be a component when iterating
+ ExpectedPathComponents[0] = "/";
+
+ for (path::const_iterator I = path::begin(Path), E = path::end(Path); I != E;
+ ++I) {
+ ActualPathComponents.push_back(*I);
+ }
+
+ ASSERT_EQ(ExpectedPathComponents.size(), ActualPathComponents.size());
+
+ for (size_t i = 0; i <ExpectedPathComponents.size(); ++i) {
+ EXPECT_EQ(ExpectedPathComponents[i].str(), ActualPathComponents[i].str());
+ }
+}
+
#ifdef LLVM_ON_WIN32
TEST(Support, AbsolutePathIteratorWin32) {
SmallString<64> Path(StringRef("c:\\c\\e\\foo.txt"));
@@ -265,7 +308,7 @@ protected:
/// be placed. It is removed at the end of each test (must be empty).
SmallString<128> TestDirectory;
- virtual void SetUp() {
+ void SetUp() override {
ASSERT_NO_ERROR(
fs::createUniqueDirectory("file-system-test", TestDirectory));
// We don't care about this specific file.
@@ -273,9 +316,7 @@ protected:
errs().flush();
}
- virtual void TearDown() {
- ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
- }
+ void TearDown() override { ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); }
};
TEST_F(FileSystemTest, Unique) {
@@ -557,6 +598,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 +629,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
};
diff --git a/unittests/Support/ScaledNumberTest.cpp b/unittests/Support/ScaledNumberTest.cpp
index d8d6e310ff9fc..2f38b2a40fb8f 100644
--- a/unittests/Support/ScaledNumberTest.cpp
+++ b/unittests/Support/ScaledNumberTest.cpp
@@ -155,7 +155,7 @@ TEST(ScaledNumberHelpersTest, getQuotient) {
EXPECT_EQ(SP32(0xaaaaaaab, -33), getQuotient32(1, 3));
EXPECT_EQ(SP32(0xd5555555, -31), getQuotient32(5, 3));
- // 64-bit division is hard to test, since divide64 doesn't canonicalized its
+ // 64-bit division is hard to test, since divide64 doesn't canonicalize its
// output. However, this is the algorithm the implementation uses:
//
// - Shift divisor right.
@@ -532,4 +532,33 @@ TEST(ScaledNumberHelpersTest, getDifference) {
EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, -1));
}
+TEST(ScaledNumberHelpersTest, arithmeticOperators) {
+ EXPECT_EQ(ScaledNumber<uint32_t>(10, 0),
+ ScaledNumber<uint32_t>(1, 3) + ScaledNumber<uint32_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint32_t>(6, 0),
+ ScaledNumber<uint32_t>(1, 3) - ScaledNumber<uint32_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint32_t>(2, 3),
+ ScaledNumber<uint32_t>(1, 3) * ScaledNumber<uint32_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint32_t>(1, 2),
+ ScaledNumber<uint32_t>(1, 3) / ScaledNumber<uint32_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint32_t>(1, 2), ScaledNumber<uint32_t>(1, 3) >> 1);
+ EXPECT_EQ(ScaledNumber<uint32_t>(1, 4), ScaledNumber<uint32_t>(1, 3) << 1);
+
+ EXPECT_EQ(ScaledNumber<uint64_t>(10, 0),
+ ScaledNumber<uint64_t>(1, 3) + ScaledNumber<uint64_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint64_t>(6, 0),
+ ScaledNumber<uint64_t>(1, 3) - ScaledNumber<uint64_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint64_t>(2, 3),
+ ScaledNumber<uint64_t>(1, 3) * ScaledNumber<uint64_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint64_t>(1, 2),
+ ScaledNumber<uint64_t>(1, 3) / ScaledNumber<uint64_t>(1, 1));
+ EXPECT_EQ(ScaledNumber<uint64_t>(1, 2), ScaledNumber<uint64_t>(1, 3) >> 1);
+ EXPECT_EQ(ScaledNumber<uint64_t>(1, 4), ScaledNumber<uint64_t>(1, 3) << 1);
+}
+
+TEST(ScaledNumberHelpersTest, toIntBug) {
+ ScaledNumber<uint32_t> n(1, 0);
+ EXPECT_EQ(1u, (n * n).toInt<uint32_t>());
+}
+
} // end namespace
diff --git a/unittests/Support/SpecialCaseListTest.cpp b/unittests/Support/SpecialCaseListTest.cpp
index 740dbfef40447..0657f8003e8be 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
index 20136491ab8bd..c043efbb5e473 100644
--- a/unittests/Support/StreamingMemoryObject.cpp
+++ b/unittests/Support/StreamingMemoryObject.cpp
@@ -27,3 +27,12 @@ TEST(StreamingMemoryObject, Test) {
StreamingMemoryObject O(DS);
EXPECT_TRUE(O.isValidAddress(32 * 1024));
}
+
+TEST(StreamingMemoryObject, TestSetKnownObjectSize) {
+ auto *DS = new NullDataStreamer();
+ StreamingMemoryObject O(DS);
+ uint8_t Buf[32];
+ EXPECT_EQ((uint64_t) 16, O.readBytes(Buf, 16, 0));
+ O.setKnownObjectSize(24);
+ EXPECT_EQ((uint64_t) 8, O.readBytes(Buf, 16, 16));
+}
diff --git a/unittests/Support/SwapByteOrderTest.cpp b/unittests/Support/SwapByteOrderTest.cpp
index 525cfc1aea82c..4f2537c4d5dee 100644
--- a/unittests/Support/SwapByteOrderTest.cpp
+++ b/unittests/Support/SwapByteOrderTest.cpp
@@ -125,6 +125,19 @@ TEST(getSwappedBytes, int64_t) {
sys::getSwappedBytes(int64_t(0x8877665544332211LL)));
}
+TEST(getSwappedBytes, float) {
+ EXPECT_EQ(1.79366203433576585078237386661e-43f, sys::getSwappedBytes(-0.0f));
+ // 0x11223344
+ EXPECT_EQ(7.1653228759765625e2f, sys::getSwappedBytes(1.2795344e-28f));
+}
+
+TEST(getSwappedBytes, double) {
+ EXPECT_EQ(6.32404026676795576546008054871e-322, sys::getSwappedBytes(-0.0));
+ // 0x1122334455667788
+ EXPECT_EQ(-7.08687663657301358331704585496e-268,
+ sys::getSwappedBytes(3.84141202447173065923064450234e-226));
+}
+
TEST(swapByteOrder, uint8_t) {
uint8_t value = 0x11;
sys::swapByteOrder(value);
@@ -173,4 +186,16 @@ TEST(swapByteOrder, int64_t) {
EXPECT_EQ(int64_t(0x1122334455667788LL), value);
}
+TEST(swapByteOrder, float) {
+ float value = 7.1653228759765625e2f; // 0x44332211
+ sys::swapByteOrder(value);
+ EXPECT_EQ(1.2795344e-28f, value);
+}
+
+TEST(swapByteOrder, double) {
+ double value = -7.08687663657301358331704585496e-268; // 0x8877665544332211
+ sys::swapByteOrder(value);
+ EXPECT_EQ(3.84141202447173065923064450234e-226, value);
+}
+
}
diff --git a/unittests/Support/TargetRegistry.cpp b/unittests/Support/TargetRegistry.cpp
new file mode 100644
index 0000000000000..ae89c8b649303
--- /dev/null
+++ b/unittests/Support/TargetRegistry.cpp
@@ -0,0 +1,42 @@
+//===- unittests/Support/TargetRegistry.cpp - -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(TargetRegistry, TargetHasArchType) {
+ // Presence of at least one target will be asserted when done with the loop,
+ // else this would pass by accident if InitializeAllTargetInfos were omitted.
+ int Count = 0;
+
+ llvm::InitializeAllTargetInfos();
+
+ for (const Target &T : TargetRegistry::targets()) {
+ StringRef Name = T.getName();
+ // There is really no way (at present) to ask a Target whether it targets
+ // a specific architecture, because the logic for that is buried in a
+ // predicate.
+ // We can't ask the predicate "Are you a function that always returns
+ // false?"
+ // So given that the cpp backend truly has no target arch, it is skipped.
+ if (Name != "cpp") {
+ Triple::ArchType Arch = Triple::getArchTypeForLLVMName(Name);
+ EXPECT_NE(Arch, Triple::UnknownArch);
+ ++Count;
+ }
+ }
+ ASSERT_NE(Count, 0);
+}
+
+} // end namespace
diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp
index 074e27f8318dc..7248124992b4d 100644
--- a/unittests/Support/YAMLIOTest.cpp
+++ b/unittests/Support/YAMLIOTest.cpp
@@ -46,6 +46,9 @@ typedef std::vector<FooBar> FooBarSequence;
LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
+struct FooBarContainer {
+ FooBarSequence fbs;
+};
namespace llvm {
namespace yaml {
@@ -56,6 +59,12 @@ namespace yaml {
io.mapRequired("bar", fb.bar);
}
};
+
+ template <> struct MappingTraits<FooBarContainer> {
+ static void mapping(IO &io, FooBarContainer &fb) {
+ io.mapRequired("fbs", fb.fbs);
+ }
+ };
}
}
@@ -109,6 +118,83 @@ TEST(YAMLIO, TestSequenceMapRead) {
EXPECT_EQ(map2.bar, 9);
}
+//
+// Test the reading of a map containing a yaml sequence of mappings
+//
+TEST(YAMLIO, TestContainerSequenceMapRead) {
+ {
+ FooBarContainer cont;
+ Input yin2("---\nfbs:\n - foo: 3\n bar: 5\n - foo: 7\n bar: 9\n...\n");
+ yin2 >> cont;
+
+ EXPECT_FALSE(yin2.error());
+ EXPECT_EQ(cont.fbs.size(), 2UL);
+ EXPECT_EQ(cont.fbs[0].foo, 3);
+ EXPECT_EQ(cont.fbs[0].bar, 5);
+ EXPECT_EQ(cont.fbs[1].foo, 7);
+ EXPECT_EQ(cont.fbs[1].bar, 9);
+ }
+
+ {
+ FooBarContainer cont;
+ Input yin("---\nfbs:\n...\n");
+ yin >> cont;
+ // Okay: Empty node represents an empty array.
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(cont.fbs.size(), 0UL);
+ }
+
+ {
+ FooBarContainer cont;
+ Input yin("---\nfbs: !!null null\n...\n");
+ yin >> cont;
+ // Okay: null represents an empty array.
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(cont.fbs.size(), 0UL);
+ }
+
+ {
+ FooBarContainer cont;
+ Input yin("---\nfbs: ~\n...\n");
+ yin >> cont;
+ // Okay: null represents an empty array.
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(cont.fbs.size(), 0UL);
+ }
+
+ {
+ FooBarContainer cont;
+ Input yin("---\nfbs: null\n...\n");
+ yin >> cont;
+ // Okay: null represents an empty array.
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(cont.fbs.size(), 0UL);
+ }
+}
+
+//
+// Test the reading of a map containing a malformed yaml sequence
+//
+TEST(YAMLIO, TestMalformedContainerSequenceMapRead) {
+ {
+ FooBarContainer cont;
+ Input yin("---\nfbs:\n foo: 3\n bar: 5\n...\n", nullptr,
+ suppressErrorMessages);
+ yin >> cont;
+ // Error: fbs is not a sequence.
+ EXPECT_TRUE(!!yin.error());
+ EXPECT_EQ(cont.fbs.size(), 0UL);
+ }
+
+ {
+ FooBarContainer cont;
+ Input yin("---\nfbs: 'scalar'\n...\n", nullptr, suppressErrorMessages);
+ yin >> cont;
+ // This should be an error.
+ EXPECT_TRUE(!!yin.error());
+ EXPECT_EQ(cont.fbs.size(), 0UL);
+ }
+}
//
// Test writing then reading back a sequence of mappings
@@ -694,6 +780,146 @@ TEST(YAMLIO, TestReadWriteMyCustomType) {
//===----------------------------------------------------------------------===//
+// Test BlockScalarTraits
+//===----------------------------------------------------------------------===//
+
+struct MultilineStringType {
+ std::string str;
+};
+
+struct MultilineStringTypeMap {
+ MultilineStringType name;
+ MultilineStringType description;
+ MultilineStringType ingredients;
+ MultilineStringType recipes;
+ MultilineStringType warningLabels;
+ MultilineStringType documentation;
+ int price;
+};
+
+namespace llvm {
+namespace yaml {
+ template <>
+ struct MappingTraits<MultilineStringTypeMap> {
+ static void mapping(IO &io, MultilineStringTypeMap& s) {
+ io.mapRequired("name", s.name);
+ io.mapRequired("description", s.description);
+ io.mapRequired("ingredients", s.ingredients);
+ io.mapRequired("recipes", s.recipes);
+ io.mapRequired("warningLabels", s.warningLabels);
+ io.mapRequired("documentation", s.documentation);
+ io.mapRequired("price", s.price);
+ }
+ };
+
+ // MultilineStringType is formatted as a yaml block literal scalar. A value of
+ // "Hello\nWorld" would be represented in yaml as
+ // |
+ // Hello
+ // World
+ template <>
+ struct BlockScalarTraits<MultilineStringType> {
+ static void output(const MultilineStringType &value, void *ctxt,
+ llvm::raw_ostream &out) {
+ out << value.str;
+ }
+ static StringRef input(StringRef scalar, void *ctxt,
+ MultilineStringType &value) {
+ value.str = scalar.str();
+ return StringRef();
+ }
+ };
+}
+}
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MultilineStringType)
+
+//
+// Test writing then reading back custom values
+//
+TEST(YAMLIO, TestReadWriteMultilineStringType) {
+ std::string intermediate;
+ {
+ MultilineStringTypeMap map;
+ map.name.str = "An Item";
+ map.description.str = "Hello\nWorld";
+ map.ingredients.str = "SubItem 1\nSub Item 2\n\nSub Item 3\n";
+ map.recipes.str = "\n\nTest 1\n\n\n";
+ map.warningLabels.str = "";
+ map.documentation.str = "\n\n";
+ map.price = 350;
+
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << map;
+ }
+ {
+ Input yin(intermediate);
+ MultilineStringTypeMap map2;
+ yin >> map2;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(map2.name.str, "An Item\n");
+ EXPECT_EQ(map2.description.str, "Hello\nWorld\n");
+ EXPECT_EQ(map2.ingredients.str, "SubItem 1\nSub Item 2\n\nSub Item 3\n");
+ EXPECT_EQ(map2.recipes.str, "\n\nTest 1\n");
+ EXPECT_TRUE(map2.warningLabels.str.empty());
+ EXPECT_TRUE(map2.documentation.str.empty());
+ EXPECT_EQ(map2.price, 350);
+ }
+}
+
+//
+// Test writing then reading back custom values
+//
+TEST(YAMLIO, TestReadWriteBlockScalarDocuments) {
+ std::string intermediate;
+ {
+ std::vector<MultilineStringType> documents;
+ MultilineStringType doc;
+ doc.str = "Hello\nWorld";
+ documents.push_back(doc);
+
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << documents;
+
+ // Verify that the block scalar header was written out on the same line
+ // as the document marker.
+ EXPECT_NE(llvm::StringRef::npos, llvm::StringRef(ostr.str()).find("--- |"));
+ }
+ {
+ Input yin(intermediate);
+ std::vector<MultilineStringType> documents2;
+ yin >> documents2;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(documents2.size(), size_t(1));
+ EXPECT_EQ(documents2[0].str, "Hello\nWorld\n");
+ }
+}
+
+TEST(YAMLIO, TestReadWriteBlockScalarValue) {
+ std::string intermediate;
+ {
+ MultilineStringType doc;
+ doc.str = "Just a block\nscalar doc";
+
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << doc;
+ }
+ {
+ Input yin(intermediate);
+ MultilineStringType doc;
+ yin >> doc;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(doc.str, "Just a block\nscalar doc\n");
+ }
+}
+
+//===----------------------------------------------------------------------===//
// Test flow sequences
//===----------------------------------------------------------------------===//
@@ -743,6 +969,26 @@ namespace yaml {
}
}
+typedef std::vector<MyNumber> MyNumberFlowSequence;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(MyNumberFlowSequence)
+
+struct NameAndNumbersFlow {
+ llvm::StringRef name;
+ std::vector<MyNumberFlowSequence> sequenceOfNumbers;
+};
+
+namespace llvm {
+namespace yaml {
+ template <>
+ struct MappingTraits<NameAndNumbersFlow> {
+ static void mapping(IO &io, NameAndNumbersFlow& nn) {
+ io.mapRequired("name", nn.name);
+ io.mapRequired("sequenceOfNumbers", nn.sequenceOfNumbers);
+ }
+ };
+}
+}
//
// Test writing then reading back custom values
@@ -790,6 +1036,51 @@ TEST(YAMLIO, TestReadWriteMyFlowSequence) {
}
+//
+// Test writing then reading back a sequence of flow sequences.
+//
+TEST(YAMLIO, TestReadWriteSequenceOfMyFlowSequence) {
+ std::string intermediate;
+ {
+ NameAndNumbersFlow map;
+ map.name = "hello";
+ MyNumberFlowSequence single = { 0 };
+ MyNumberFlowSequence numbers = { 12, 1, -512 };
+ map.sequenceOfNumbers.push_back(single);
+ map.sequenceOfNumbers.push_back(numbers);
+ map.sequenceOfNumbers.push_back(MyNumberFlowSequence());
+
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << map;
+
+ // Verify sequences were written in flow style
+ // and that the parent sequence used '-'.
+ ostr.flush();
+ llvm::StringRef flowOut(intermediate);
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ 0 ]"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ 12, 1, -512 ]"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("- [ ]"));
+ }
+
+ {
+ Input yin(intermediate);
+ NameAndNumbersFlow map2;
+ yin >> map2;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_TRUE(map2.name.equals("hello"));
+ EXPECT_EQ(map2.sequenceOfNumbers.size(), 3UL);
+ EXPECT_EQ(map2.sequenceOfNumbers[0].size(), 1UL);
+ EXPECT_EQ(0, map2.sequenceOfNumbers[0][0]);
+ EXPECT_EQ(map2.sequenceOfNumbers[1].size(), 3UL);
+ EXPECT_EQ(12, map2.sequenceOfNumbers[1][0]);
+ EXPECT_EQ(1, map2.sequenceOfNumbers[1][1]);
+ EXPECT_EQ(-512, map2.sequenceOfNumbers[1][2]);
+ EXPECT_TRUE(map2.sequenceOfNumbers[2].empty());
+ }
+}
+
//===----------------------------------------------------------------------===//
// Test normalizing/denormalizing
//===----------------------------------------------------------------------===//
@@ -1216,6 +1507,91 @@ TEST(YAMLIO, TestValidatingInput) {
EXPECT_TRUE(!!yin.error());
}
+//===----------------------------------------------------------------------===//
+// Test flow mapping
+//===----------------------------------------------------------------------===//
+
+struct FlowFooBar {
+ int foo;
+ int bar;
+
+ FlowFooBar() : foo(0), bar(0) {}
+ FlowFooBar(int foo, int bar) : foo(foo), bar(bar) {}
+};
+
+typedef std::vector<FlowFooBar> FlowFooBarSequence;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(FlowFooBar)
+
+struct FlowFooBarDoc {
+ FlowFooBar attribute;
+ FlowFooBarSequence seq;
+};
+
+namespace llvm {
+namespace yaml {
+ template <>
+ struct MappingTraits<FlowFooBar> {
+ static void mapping(IO &io, FlowFooBar &fb) {
+ io.mapRequired("foo", fb.foo);
+ io.mapRequired("bar", fb.bar);
+ }
+
+ static const bool flow = true;
+ };
+
+ template <>
+ struct MappingTraits<FlowFooBarDoc> {
+ static void mapping(IO &io, FlowFooBarDoc &fb) {
+ io.mapRequired("attribute", fb.attribute);
+ io.mapRequired("seq", fb.seq);
+ }
+ };
+}
+}
+
+//
+// Test writing then reading back custom mappings
+//
+TEST(YAMLIO, TestReadWriteMyFlowMapping) {
+ std::string intermediate;
+ {
+ FlowFooBarDoc doc;
+ doc.attribute = FlowFooBar(42, 907);
+ doc.seq.push_back(FlowFooBar(1, 2));
+ doc.seq.push_back(FlowFooBar(0, 0));
+ doc.seq.push_back(FlowFooBar(-1, 1024));
+
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << doc;
+
+ // Verify that mappings were written in flow style
+ ostr.flush();
+ llvm::StringRef flowOut(intermediate);
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("{ foo: 42, bar: 907 }"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: 1, bar: 2 }"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: 0, bar: 0 }"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("- { foo: -1, bar: 1024 }"));
+ }
+
+ {
+ Input yin(intermediate);
+ FlowFooBarDoc doc2;
+ yin >> doc2;
+
+ EXPECT_FALSE(yin.error());
+ EXPECT_EQ(doc2.attribute.foo, 42);
+ EXPECT_EQ(doc2.attribute.bar, 907);
+ EXPECT_EQ(doc2.seq.size(), 3UL);
+ EXPECT_EQ(doc2.seq[0].foo, 1);
+ EXPECT_EQ(doc2.seq[0].bar, 2);
+ EXPECT_EQ(doc2.seq[1].foo, 0);
+ EXPECT_EQ(doc2.seq[1].bar, 0);
+ EXPECT_EQ(doc2.seq[2].foo, -1);
+ EXPECT_EQ(doc2.seq[2].bar, 1024);
+ }
+}
//===----------------------------------------------------------------------===//
// Test error handling
diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp
index 823a0d6e3e03e..69b354a91d11e 100644
--- a/unittests/Support/YAMLParserTest.cpp
+++ b/unittests/Support/YAMLParserTest.cpp
@@ -130,6 +130,45 @@ TEST(YAMLParser, ParsesArrayOfArrays) {
ExpectParseSuccess("Array of arrays", "[[]]");
}
+TEST(YAMLParser, ParsesBlockLiteralScalars) {
+ ExpectParseSuccess("Block literal scalar", "test: |\n Hello\n World\n");
+ ExpectParseSuccess("Block literal scalar EOF", "test: |\n Hello\n World");
+ ExpectParseSuccess("Empty block literal scalar header EOF", "test: | ");
+ ExpectParseSuccess("Empty block literal scalar", "test: |\ntest2: 20");
+ ExpectParseSuccess("Empty block literal scalar 2", "- | \n \n\n \n- 42");
+ ExpectParseSuccess("Block literal scalar in sequence",
+ "- |\n Testing\n Out\n\n- 22");
+ ExpectParseSuccess("Block literal scalar in document",
+ "--- |\n Document\n...");
+ ExpectParseSuccess("Empty non indented lines still count",
+ "- |\n First line\n \n\n Another line\n\n- 2");
+ ExpectParseSuccess("Comment in block literal scalar header",
+ "test: | # Comment \n No Comment\ntest 2: | # Void");
+ ExpectParseSuccess("Chomping indicators in block literal scalar header",
+ "test: |- \n Hello\n\ntest 2: |+ \n\n World\n\n\n");
+ ExpectParseSuccess("Indent indicators in block literal scalar header",
+ "test: |1 \n \n Hello \n World\n");
+ ExpectParseSuccess("Chomping and indent indicators in block literals",
+ "test: |-1\n Hello\ntest 2: |9+\n World");
+ ExpectParseSuccess("Trailing comments in block literals",
+ "test: |\n Content\n # Trailing\n #Comment\ntest 2: 3");
+ ExpectParseError("Invalid block scalar header", "test: | failure");
+ ExpectParseError("Invalid line indentation", "test: |\n First line\n Error");
+ ExpectParseError("Long leading space line", "test: |\n \n Test\n");
+}
+
+TEST(YAMLParser, NullTerminatedBlockScalars) {
+ SourceMgr SM;
+ yaml::Stream Stream("test: |\n Hello\n World\n", SM);
+ yaml::Document &Doc = *Stream.begin();
+ yaml::MappingNode *Map = cast<yaml::MappingNode>(Doc.getRoot());
+ StringRef Value =
+ cast<yaml::BlockScalarNode>(Map->begin()->getValue())->getValue();
+
+ EXPECT_EQ(Value, "Hello\nWorld\n");
+ EXPECT_EQ(Value.data()[Value.size()], '\0');
+}
+
TEST(YAMLParser, HandlesEndOfFileGracefully) {
ExpectParseError("In string starting with EOF", "[\"");
ExpectParseError("In string hitting EOF", "[\" ");
@@ -141,6 +180,10 @@ TEST(YAMLParser, HandlesEndOfFileGracefully) {
ExpectParseError("In object hitting EOF", "{\"\"");
}
+TEST(YAMLParser, HandlesNullValuesInKeyValueNodesGracefully) {
+ ExpectParseError("KeyValueNode with null value", "test: '");
+}
+
// Checks that the given string can be parsed into an identical string inside
// of an array.
static void ExpectCanParseString(StringRef String) {
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index 39cfaf004c72b..ff986025b2ccb 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/Support/raw_pwrite_stream_test.cpp b/unittests/Support/raw_pwrite_stream_test.cpp
new file mode 100644
index 0000000000000..a62f6bacb0703
--- /dev/null
+++ b/unittests/Support/raw_pwrite_stream_test.cpp
@@ -0,0 +1,64 @@
+//===- raw_pwrite_stream_test.cpp - raw_pwrite_stream tests ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(raw_pwrite_ostreamTest, TestSVector) {
+ SmallVector<char, 0> Buffer;
+ raw_svector_ostream OS(Buffer);
+ OS << "abcd";
+ StringRef Test = "test";
+ OS.pwrite(Test.data(), Test.size(), 0);
+ EXPECT_EQ(Test, OS.str());
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+ EXPECT_DEATH(OS.pwrite("12345", 5, 0),
+ "We don't support extending the stream");
+#endif
+#endif
+}
+
+TEST(raw_pwrite_ostreamTest, TestFD) {
+ SmallString<64> Path;
+ int FD;
+ sys::fs::createTemporaryFile("foo", "bar", FD, Path);
+ raw_fd_ostream OS(FD, true);
+ OS << "abcd";
+ StringRef Test = "test";
+ OS.pwrite(Test.data(), Test.size(), 0);
+ OS.pwrite(Test.data(), Test.size(), 0);
+
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+ EXPECT_DEATH(OS.pwrite("12345", 5, 0),
+ "We don't support extending the stream");
+#endif
+#endif
+}
+
+#ifdef LLVM_ON_UNIX
+TEST(raw_pwrite_ostreamTest, TestDevNull) {
+ int FD;
+ sys::fs::openFileForWrite("/dev/null", FD, sys::fs::F_None);
+ raw_fd_ostream OS(FD, true);
+ OS << "abcd";
+ StringRef Test = "test";
+ OS.pwrite(Test.data(), Test.size(), 0);
+ OS.pwrite(Test.data(), Test.size(), 0);
+}
+#endif
+}
diff --git a/unittests/Transforms/CMakeLists.txt b/unittests/Transforms/CMakeLists.txt
index e3ce185e0d5b4..5d3b29c94d72e 100644
--- a/unittests/Transforms/CMakeLists.txt
+++ b/unittests/Transforms/CMakeLists.txt
@@ -1 +1,2 @@
+add_subdirectory(IPO)
add_subdirectory(Utils)
diff --git a/unittests/Transforms/IPO/CMakeLists.txt b/unittests/Transforms/IPO/CMakeLists.txt
new file mode 100644
index 0000000000000..58b71b2bce03f
--- /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 0000000000000..49a42cd20d7a9
--- /dev/null
+++ b/unittests/Transforms/IPO/LowerBitSets.cpp
@@ -0,0 +1,155 @@
+//===- 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::set<uint64_t> Bits;
+ uint64_t ByteOffset;
+ uint64_t BitSize;
+ unsigned AlignLog2;
+ bool IsSingleOffset;
+ bool IsAllOnes;
+ } BSBTests[] = {
+ {{}, std::set<uint64_t>{}, 0, 1, 0, false, false},
+ {{0}, {0}, 0, 1, 0, true, true},
+ {{4}, {0}, 4, 1, 0, true, true},
+ {{37}, {0}, 37, 1, 0, true, true},
+ {{0, 1}, {0, 1}, 0, 2, 0, false, true},
+ {{0, 4}, {0, 1}, 0, 2, 2, false, true},
+ {{0, uint64_t(1) << 33}, {0, 1}, 0, 2, 33, false, true},
+ {{3, 7}, {0, 1}, 3, 2, 2, false, true},
+ {{0, 1, 7}, {0, 1, 7}, 0, 8, 0, false, false},
+ {{0, 2, 14}, {0, 1, 7}, 0, 8, 1, false, false},
+ {{0, 1, 8}, {0, 1, 8}, 0, 9, 0, false, false},
+ {{0, 2, 16}, {0, 1, 8}, 0, 9, 1, false, false},
+ {{0, 1, 2, 3, 4, 5, 6, 7},
+ {0, 1, 2, 3, 4, 5, 6, 7},
+ 0,
+ 8,
+ 0,
+ false,
+ true},
+ {{0, 1, 2, 3, 4, 5, 6, 7, 8},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8},
+ 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);
+ }
+}
+
+TEST(LowerBitSets, ByteArrayBuilder) {
+ struct BABAlloc {
+ std::set<uint64_t> Bits;
+ uint64_t BitSize;
+ uint64_t WantByteOffset;
+ uint8_t WantMask;
+ };
+
+ struct {
+ std::vector<BABAlloc> Allocs;
+ std::vector<uint8_t> WantBytes;
+ } BABTests[] = {
+ {{{{0}, 1, 0, 1}, {{0}, 1, 0, 2}}, {3}},
+ {{{{0}, 16, 0, 1},
+ {{1}, 15, 0, 2},
+ {{2}, 14, 0, 4},
+ {{3}, 13, 0, 8},
+ {{4}, 12, 0, 0x10},
+ {{5}, 11, 0, 0x20},
+ {{6}, 10, 0, 0x40},
+ {{7}, 9, 0, 0x80},
+ {{0}, 7, 9, 0x80},
+ {{0}, 6, 10, 0x40},
+ {{0}, 5, 11, 0x20},
+ {{0}, 4, 12, 0x10},
+ {{0}, 3, 13, 8},
+ {{0}, 2, 14, 4},
+ {{0}, 1, 15, 2}},
+ {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0, 0x80, 0x40, 0x20, 0x10, 8, 4,
+ 2}},
+ };
+
+ for (auto &&T : BABTests) {
+ ByteArrayBuilder BABuilder;
+
+ for (auto &&A : T.Allocs) {
+ uint64_t GotByteOffset;
+ uint8_t GotMask;
+
+ BABuilder.allocate(A.Bits, A.BitSize, GotByteOffset, GotMask);
+ EXPECT_EQ(A.WantByteOffset, GotByteOffset);
+ EXPECT_EQ(A.WantMask, GotMask);
+ }
+
+ EXPECT_EQ(T.WantBytes, BABuilder.Bytes);
+ }
+}
diff --git a/unittests/Transforms/IPO/Makefile b/unittests/Transforms/IPO/Makefile
new file mode 100644
index 0000000000000..f807879c2b5f6
--- /dev/null
+++ b/unittests/Transforms/IPO/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/Transforms/IPO/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 = 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 599b18a057dcf..3a2cdfc2c74a0 100644
--- a/unittests/Transforms/Makefile
+++ b/unittests/Transforms/Makefile
@@ -9,7 +9,7 @@
LEVEL = ../..
-PARALLEL_DIRS = Utils
+PARALLEL_DIRS = IPO Utils
include $(LEVEL)/Makefile.common
diff --git a/unittests/Transforms/Utils/CMakeLists.txt b/unittests/Transforms/Utils/CMakeLists.txt
index ffa1d49d380bd..517ff99ea46bc 100644
--- a/unittests/Transforms/Utils/CMakeLists.txt
+++ b/unittests/Transforms/Utils/CMakeLists.txt
@@ -9,4 +9,5 @@ add_llvm_unittest(UtilsTests
Cloning.cpp
IntegerDivision.cpp
Local.cpp
+ ValueMapperTest.cpp
)
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
index 1d22d5b15c9ba..18d3ca6267535 100644
--- a/unittests/Transforms/Utils/Cloning.cpp
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -30,9 +31,7 @@ namespace {
class CloneInstruction : public ::testing::Test {
protected:
- virtual void SetUp() {
- V = nullptr;
- }
+ void SetUp() override { V = nullptr; }
template <typename T>
T *clone(T *V1) {
@@ -46,7 +45,7 @@ protected:
DeleteContainerPointers(Clones);
}
- virtual void TearDown() {
+ void TearDown() override {
eraseClones();
DeleteContainerPointers(Orig);
delete V;
@@ -135,7 +134,8 @@ TEST_F(CloneInstruction, Inbounds) {
Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
std::vector<Value *> ops;
ops.push_back(Z);
- GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops);
+ GetElementPtrInst *GEP =
+ GetElementPtrInst::Create(Type::getInt32Ty(context), V, ops);
EXPECT_FALSE(this->clone(GEP)->isInBounds());
GEP->setIsInBounds();
@@ -204,16 +204,14 @@ TEST_F(CloneInstruction, CallingConvention) {
class CloneFunc : public ::testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
SetupModule();
CreateOldFunc();
CreateNewFunc();
SetupFinder();
}
- virtual void TearDown() {
- delete Finder;
- }
+ void TearDown() override { delete Finder; }
void SetupModule() {
M = new Module("", C);
@@ -230,14 +228,16 @@ protected:
IRBuilder<> IBuilder(C);
// Function DI
- DIFile File = DBuilder.createFile("filename.c", "/file/dir/");
- DITypeArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
- DICompositeType FuncType = DBuilder.createSubroutineType(File, ParamTypes);
- DICompileUnit CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99,
- "filename.c", "/file/dir", "CloneFunc", false, "", 0);
+ auto *File = DBuilder.createFile("filename.c", "/file/dir/");
+ DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None);
+ DISubroutineType *FuncType =
+ DBuilder.createSubroutineType(File, ParamTypes);
+ auto *CU =
+ DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c",
+ "/file/dir", "CloneFunc", false, "", 0);
- DISubprogram Subprogram = DBuilder.createFunction(CU, "f", "f", File, 4,
- FuncType, true, true, 3, 0, false, OldFunc);
+ auto *Subprogram = DBuilder.createFunction(
+ CU, "f", "f", File, 4, FuncType, true, true, 3, 0, false, OldFunc);
// Function body
BasicBlock* Entry = BasicBlock::Create(C, "", OldFunc);
@@ -252,13 +252,15 @@ protected:
Instruction* Terminator = IBuilder.CreateRetVoid();
// Create a local variable around the alloca
- DIType IntType = DBuilder.createBasicType("int", 32, 0,
- dwarf::DW_ATE_signed);
- DIExpression E = DBuilder.createExpression();
- DIVariable Variable = DBuilder.createLocalVariable(
- dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
- DBuilder.insertDeclare(Alloca, Variable, E, Store);
- DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, Terminator);
+ auto *IntType =
+ DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed);
+ auto *E = DBuilder.createExpression();
+ auto *Variable = DBuilder.createLocalVariable(
+ dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true);
+ auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
+ DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
+ DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
+ Terminator);
// Finalize the debug info
DBuilder.finalize();
@@ -296,38 +298,41 @@ TEST_F(CloneFunc, NewFunctionCreated) {
// Test that a new subprogram entry was added and is pointing to the new
// function, while the original subprogram still points to the old one.
TEST_F(CloneFunc, Subprogram) {
+ EXPECT_FALSE(verifyModule(*M));
+
unsigned SubprogramCount = Finder->subprogram_count();
EXPECT_EQ(2U, SubprogramCount);
auto Iter = Finder->subprograms().begin();
- DISubprogram Sub1(*Iter);
- EXPECT_TRUE(Sub1.Verify());
+ auto *Sub1 = cast<DISubprogram>(*Iter);
Iter++;
- DISubprogram Sub2(*Iter);
- EXPECT_TRUE(Sub2.Verify());
+ auto *Sub2 = cast<DISubprogram>(*Iter);
- EXPECT_TRUE((Sub1.getFunction() == OldFunc && Sub2.getFunction() == NewFunc)
- || (Sub1.getFunction() == NewFunc && Sub2.getFunction() == OldFunc));
+ EXPECT_TRUE(
+ (Sub1->getFunction() == OldFunc && Sub2->getFunction() == NewFunc) ||
+ (Sub1->getFunction() == NewFunc && Sub2->getFunction() == OldFunc));
}
// Test that the new subprogram entry was not added to the CU which doesn't
// contain the old subprogram entry.
TEST_F(CloneFunc, SubprogramInRightCU) {
+ EXPECT_FALSE(verifyModule(*M));
+
EXPECT_EQ(2U, Finder->compile_unit_count());
auto Iter = Finder->compile_units().begin();
- DICompileUnit CU1(*Iter);
- EXPECT_TRUE(CU1.Verify());
+ auto *CU1 = cast<DICompileUnit>(*Iter);
Iter++;
- DICompileUnit CU2(*Iter);
- EXPECT_TRUE(CU2.Verify());
- EXPECT_TRUE(CU1.getSubprograms().getNumElements() == 0
- || CU2.getSubprograms().getNumElements() == 0);
+ auto *CU2 = cast<DICompileUnit>(*Iter);
+ EXPECT_TRUE(CU1->getSubprograms().size() == 0 ||
+ CU2->getSubprograms().size() == 0);
}
// Test that instructions in the old function still belong to it in the
// metadata, while instruction in the new function belong to the new one.
TEST_F(CloneFunc, InstructionOwnership) {
+ EXPECT_FALSE(verifyModule(*M));
+
inst_iterator OldIter = inst_begin(OldFunc);
inst_iterator OldEnd = inst_end(OldFunc);
inst_iterator NewIter = inst_begin(NewFunc);
@@ -345,14 +350,12 @@ TEST_F(CloneFunc, InstructionOwnership) {
// Verify that the debug location data is the same
EXPECT_EQ(OldDL.getLine(), NewDL.getLine());
EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
-
+
// But that they belong to different functions
- DISubprogram OldSubprogram(OldDL.getScope(C));
- DISubprogram NewSubprogram(NewDL.getScope(C));
- EXPECT_TRUE(OldSubprogram.Verify());
- EXPECT_TRUE(NewSubprogram.Verify());
- EXPECT_EQ(OldFunc, OldSubprogram.getFunction());
- EXPECT_EQ(NewFunc, NewSubprogram.getFunction());
+ auto *OldSubprogram = cast<DISubprogram>(OldDL.getScope());
+ auto *NewSubprogram = cast<DISubprogram>(NewDL.getScope());
+ EXPECT_EQ(OldFunc, OldSubprogram->getFunction());
+ EXPECT_EQ(NewFunc, NewSubprogram->getFunction());
}
++OldIter;
@@ -365,6 +368,8 @@ TEST_F(CloneFunc, InstructionOwnership) {
// Test that the arguments for debug intrinsics in the new function were
// properly cloned
TEST_F(CloneFunc, DebugIntrinsics) {
+ EXPECT_FALSE(verifyModule(*M));
+
inst_iterator OldIter = inst_begin(OldFunc);
inst_iterator OldEnd = inst_end(OldFunc);
inst_iterator NewIter = inst_begin(NewFunc);
@@ -384,21 +389,25 @@ TEST_F(CloneFunc, DebugIntrinsics) {
getParent()->getParent());
// Old variable must belong to the old function
- EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(OldFunc,
+ cast<DISubprogram>(OldIntrin->getVariable()->getScope())
+ ->getFunction());
// New variable must belong to the New function
- EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(NewFunc,
+ cast<DISubprogram>(NewIntrin->getVariable()->getScope())
+ ->getFunction());
} else if (DbgValueInst* OldIntrin = dyn_cast<DbgValueInst>(&OldI)) {
DbgValueInst* NewIntrin = dyn_cast<DbgValueInst>(&NewI);
EXPECT_TRUE(NewIntrin);
// Old variable must belong to the old function
- EXPECT_EQ(OldFunc, DISubprogram(DIVariable(OldIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(OldFunc,
+ cast<DISubprogram>(OldIntrin->getVariable()->getScope())
+ ->getFunction());
// New variable must belong to the New function
- EXPECT_EQ(NewFunc, DISubprogram(DIVariable(NewIntrin->getVariable())
- .getContext()).getFunction());
+ EXPECT_EQ(NewFunc,
+ cast<DISubprogram>(NewIntrin->getVariable()->getScope())
+ ->getFunction());
}
++OldIter;
diff --git a/unittests/Transforms/Utils/ValueMapperTest.cpp b/unittests/Transforms/Utils/ValueMapperTest.cpp
new file mode 100644
index 0000000000000..137a2607c848b
--- /dev/null
+++ b/unittests/Transforms/Utils/ValueMapperTest.cpp
@@ -0,0 +1,27 @@
+//===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(ValueMapperTest, MapMetadataUnresolved) {
+ LLVMContext Context;
+ TempMDTuple T = MDTuple::getTemporary(Context, None);
+
+ ValueToValueMapTy VM;
+ EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
+}
+
+}