diff options
Diffstat (limited to 'unittests/Support')
-rw-r--r-- | unittests/Support/AlignOfTest.cpp | 328 | ||||
-rw-r--r-- | unittests/Support/BlockFrequencyTest.cpp | 2 | ||||
-rw-r--r-- | unittests/Support/CMakeLists.txt | 27 | ||||
-rw-r--r-- | unittests/Support/CommandLineTest.cpp | 11 | ||||
-rw-r--r-- | unittests/Support/ConstantRangeTest.cpp | 78 | ||||
-rw-r--r-- | unittests/Support/FileOutputBufferTest.cpp | 137 | ||||
-rw-r--r-- | unittests/Support/IRBuilderTest.cpp | 72 | ||||
-rw-r--r-- | unittests/Support/IntegersSubsetTest.cpp | 328 | ||||
-rw-r--r-- | unittests/Support/MDBuilderTest.cpp | 105 | ||||
-rw-r--r-- | unittests/Support/Path.cpp | 68 | ||||
-rw-r--r-- | unittests/Support/TypeBuilderTest.cpp | 254 | ||||
-rw-r--r-- | unittests/Support/YAMLParserTest.cpp | 6 |
12 files changed, 979 insertions, 437 deletions
diff --git a/unittests/Support/AlignOfTest.cpp b/unittests/Support/AlignOfTest.cpp new file mode 100644 index 0000000..c45db2c --- /dev/null +++ b/unittests/Support/AlignOfTest.cpp @@ -0,0 +1,328 @@ +//===- llvm/unittest/Support/AlignOfTest.cpp - Alignment utility 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/AlignOf.h" +#include "llvm/Support/Compiler.h" + +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +// Disable warnings about questionable type definitions. +// We're testing that even questionable types work with the alignment utilities. +#ifdef _MSC_VER +#pragma warning(disable:4584) +#endif + +// Define some fixed alignment types to use in these tests. +#if __cplusplus == 201103L || __has_feature(cxx_alignas) +typedef char alignas(1) A1; +typedef char alignas(2) A2; +typedef char alignas(4) A4; +typedef char alignas(8) A8; +#elif defined(__clang__) || defined(__GNUC__) +typedef char A1 __attribute__((aligned(1))); +typedef char A2 __attribute__((aligned(2))); +typedef char A4 __attribute__((aligned(4))); +typedef char A8 __attribute__((aligned(8))); +#elif defined(_MSC_VER) +typedef __declspec(align(1)) char A1; +typedef __declspec(align(2)) char A2; +typedef __declspec(align(4)) char A4; +typedef __declspec(align(8)) char A8; +#else +# error No supported align as directive. +#endif + +// Wrap the forced aligned types in structs to hack around compiler bugs. +struct SA1 { A1 a; }; +struct SA2 { A2 a; }; +struct SA4 { A4 a; }; +struct SA8 { A8 a; }; + +struct S1 {}; +struct S2 { char a; }; +struct S3 { int x; }; +struct S4 { double y; }; +struct S5 { A1 a1; A2 a2; A4 a4; A8 a8; }; +struct S6 { double f(); }; +struct D1 : S1 {}; +struct D2 : S6 { float g(); }; +struct D3 : S2 {}; +struct D4 : S2 { int x; }; +struct D5 : S3 { char c; }; +struct D6 : S2, S3 {}; +struct D7 : S1, S3 {}; +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 V6 : S1 { virtual ~V6(); }; +struct V7 : virtual V2, virtual V6 { virtual ~V7(); }; +struct V8 : V5, virtual V6, V7 { double zz; virtual ~V8(); }; + +// Ensure alignment is a compile-time constant. +char LLVM_ATTRIBUTE_UNUSED test_arr1 + [AlignOf<char>::Alignment > 0] + [AlignOf<short>::Alignment > 0] + [AlignOf<int>::Alignment > 0] + [AlignOf<long>::Alignment > 0] + [AlignOf<long long>::Alignment > 0] + [AlignOf<float>::Alignment > 0] + [AlignOf<double>::Alignment > 0] + [AlignOf<long double>::Alignment > 0] + [AlignOf<void *>::Alignment > 0] + [AlignOf<int *>::Alignment > 0] + [AlignOf<double (*)(double)>::Alignment > 0] + [AlignOf<double (S6::*)()>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr2 + [AlignOf<A1>::Alignment > 0] + [AlignOf<A2>::Alignment > 0] + [AlignOf<A4>::Alignment > 0] + [AlignOf<A8>::Alignment > 0] + [AlignOf<SA1>::Alignment > 0] + [AlignOf<SA2>::Alignment > 0] + [AlignOf<SA4>::Alignment > 0] + [AlignOf<SA8>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr3 + [AlignOf<S1>::Alignment > 0] + [AlignOf<S2>::Alignment > 0] + [AlignOf<S3>::Alignment > 0] + [AlignOf<S4>::Alignment > 0] + [AlignOf<S5>::Alignment > 0] + [AlignOf<S6>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr4 + [AlignOf<D1>::Alignment > 0] + [AlignOf<D2>::Alignment > 0] + [AlignOf<D3>::Alignment > 0] + [AlignOf<D4>::Alignment > 0] + [AlignOf<D5>::Alignment > 0] + [AlignOf<D6>::Alignment > 0] + [AlignOf<D7>::Alignment > 0] + [AlignOf<D8>::Alignment > 0] + [AlignOf<D9>::Alignment > 0]; +char LLVM_ATTRIBUTE_UNUSED test_arr5 + [AlignOf<V1>::Alignment > 0] + [AlignOf<V2>::Alignment > 0] + [AlignOf<V3>::Alignment > 0] + [AlignOf<V4>::Alignment > 0] + [AlignOf<V5>::Alignment > 0] + [AlignOf<V6>::Alignment > 0] + [AlignOf<V7>::Alignment > 0] + [AlignOf<V8>::Alignment > 0]; + +TEST(AlignOfTest, BasicAlignmentInvariants) { + // For a very strange reason, many compilers do not support this. Both Clang + // and GCC fail to align these properly. + EXPECT_EQ(1u, alignOf<A1>()); +#if 0 + EXPECT_EQ(2u, alignOf<A2>()); + EXPECT_EQ(4u, alignOf<A4>()); + EXPECT_EQ(8u, alignOf<A8>()); +#endif + + // But once wrapped in structs, the alignment is correctly managed. + EXPECT_LE(1u, alignOf<SA1>()); + EXPECT_LE(2u, alignOf<SA2>()); + EXPECT_LE(4u, alignOf<SA4>()); + EXPECT_LE(8u, alignOf<SA8>()); + + EXPECT_EQ(1u, alignOf<char>()); + EXPECT_LE(alignOf<char>(), alignOf<short>()); + EXPECT_LE(alignOf<short>(), alignOf<int>()); + EXPECT_LE(alignOf<int>(), alignOf<long>()); + EXPECT_LE(alignOf<long>(), alignOf<long long>()); + EXPECT_LE(alignOf<char>(), alignOf<float>()); + EXPECT_LE(alignOf<float>(), alignOf<double>()); + EXPECT_LE(alignOf<char>(), alignOf<long double>()); + EXPECT_LE(alignOf<char>(), alignOf<void *>()); + EXPECT_EQ(alignOf<void *>(), alignOf<int *>()); + EXPECT_LE(alignOf<char>(), alignOf<S1>()); + EXPECT_LE(alignOf<S1>(), alignOf<S2>()); + EXPECT_LE(alignOf<S1>(), alignOf<S3>()); + EXPECT_LE(alignOf<S1>(), alignOf<S4>()); + EXPECT_LE(alignOf<S1>(), alignOf<S5>()); + EXPECT_LE(alignOf<S1>(), alignOf<S6>()); + EXPECT_LE(alignOf<S1>(), alignOf<D1>()); + EXPECT_LE(alignOf<S1>(), alignOf<D2>()); + EXPECT_LE(alignOf<S1>(), alignOf<D3>()); + EXPECT_LE(alignOf<S1>(), alignOf<D4>()); + EXPECT_LE(alignOf<S1>(), alignOf<D5>()); + EXPECT_LE(alignOf<S1>(), alignOf<D6>()); + EXPECT_LE(alignOf<S1>(), alignOf<D7>()); + EXPECT_LE(alignOf<S1>(), alignOf<D8>()); + EXPECT_LE(alignOf<S1>(), alignOf<D9>()); + EXPECT_LE(alignOf<S1>(), alignOf<V1>()); + EXPECT_LE(alignOf<V1>(), alignOf<V2>()); + EXPECT_LE(alignOf<V1>(), alignOf<V3>()); + EXPECT_LE(alignOf<V1>(), alignOf<V4>()); + EXPECT_LE(alignOf<V1>(), alignOf<V5>()); + EXPECT_LE(alignOf<V1>(), alignOf<V6>()); + EXPECT_LE(alignOf<V1>(), alignOf<V7>()); + EXPECT_LE(alignOf<V1>(), alignOf<V8>()); +} + +TEST(AlignOfTest, BasicAlignedArray) { + // Note: this code exclusively uses the struct-wrapped arbitrarily aligned + // types because of the bugs mentioned above where GCC and Clang both + // disregard the arbitrary alignment specifier until the type is used to + // declare a member of a struct. + EXPECT_LE(1u, alignOf<AlignedCharArray<SA1>::union_type>()); + EXPECT_LE(2u, alignOf<AlignedCharArray<SA2>::union_type>()); + EXPECT_LE(4u, alignOf<AlignedCharArray<SA4>::union_type>()); + EXPECT_LE(8u, alignOf<AlignedCharArray<SA8>::union_type>()); + + EXPECT_LE(1u, sizeof(AlignedCharArray<SA1>::union_type)); + EXPECT_LE(2u, sizeof(AlignedCharArray<SA2>::union_type)); + EXPECT_LE(4u, sizeof(AlignedCharArray<SA4>::union_type)); + EXPECT_LE(8u, sizeof(AlignedCharArray<SA8>::union_type)); + + EXPECT_EQ(1u, (alignOf<AlignedCharArray<SA1>::union_type>())); + EXPECT_EQ(2u, (alignOf<AlignedCharArray<SA1, SA2>::union_type>())); + EXPECT_EQ(4u, (alignOf<AlignedCharArray<SA1, SA2, SA4>::union_type>())); + EXPECT_EQ(8u, (alignOf<AlignedCharArray<SA1, SA2, SA4, SA8>::union_type>())); + + EXPECT_EQ(1u, sizeof(AlignedCharArray<SA1>::union_type)); + EXPECT_EQ(2u, sizeof(AlignedCharArray<SA1, SA2>::union_type)); + EXPECT_EQ(4u, sizeof(AlignedCharArray<SA1, SA2, SA4>::union_type)); + EXPECT_EQ(8u, sizeof(AlignedCharArray<SA1, SA2, SA4, SA8>::union_type)); + + EXPECT_EQ(1u, (alignOf<AlignedCharArray<SA1[1]>::union_type>())); + EXPECT_EQ(2u, (alignOf<AlignedCharArray<SA1[2], SA2[1]>::union_type>())); + EXPECT_EQ(4u, (alignOf<AlignedCharArray<SA1[42], SA2[55], + SA4[13]>::union_type>())); + EXPECT_EQ(8u, (alignOf<AlignedCharArray<SA1[2], SA2[1], + SA4, SA8>::union_type>())); + + EXPECT_EQ(1u, sizeof(AlignedCharArray<SA1[1]>::union_type)); + EXPECT_EQ(2u, sizeof(AlignedCharArray<SA1[2], SA2[1]>::union_type)); + EXPECT_EQ(4u, sizeof(AlignedCharArray<SA1[3], SA2[2], SA4>::union_type)); + EXPECT_EQ(16u, sizeof(AlignedCharArray<SA1, SA2[3], + SA4[3], SA8>::union_type)); + + // For other tests we simply assert that the alignment of the union mathes + // that of the fundamental type and hope that we have any weird type + // productions that would trigger bugs. + EXPECT_EQ(alignOf<char>(), alignOf<AlignedCharArray<char>::union_type>()); + EXPECT_EQ(alignOf<short>(), alignOf<AlignedCharArray<short>::union_type>()); + EXPECT_EQ(alignOf<int>(), alignOf<AlignedCharArray<int>::union_type>()); + EXPECT_EQ(alignOf<long>(), alignOf<AlignedCharArray<long>::union_type>()); + EXPECT_EQ(alignOf<long long>(), + alignOf<AlignedCharArray<long long>::union_type>()); + EXPECT_EQ(alignOf<float>(), alignOf<AlignedCharArray<float>::union_type>()); + EXPECT_EQ(alignOf<double>(), alignOf<AlignedCharArray<double>::union_type>()); + EXPECT_EQ(alignOf<long double>(), + alignOf<AlignedCharArray<long double>::union_type>()); + EXPECT_EQ(alignOf<void *>(), alignOf<AlignedCharArray<void *>::union_type>()); + EXPECT_EQ(alignOf<int *>(), alignOf<AlignedCharArray<int *>::union_type>()); + EXPECT_EQ(alignOf<double (*)(double)>(), + alignOf<AlignedCharArray<double (*)(double)>::union_type>()); + EXPECT_EQ(alignOf<double (S6::*)()>(), + alignOf<AlignedCharArray<double (S6::*)()>::union_type>()); + EXPECT_EQ(alignOf<S1>(), alignOf<AlignedCharArray<S1>::union_type>()); + EXPECT_EQ(alignOf<S2>(), alignOf<AlignedCharArray<S2>::union_type>()); + EXPECT_EQ(alignOf<S3>(), alignOf<AlignedCharArray<S3>::union_type>()); + EXPECT_EQ(alignOf<S4>(), alignOf<AlignedCharArray<S4>::union_type>()); + EXPECT_EQ(alignOf<S5>(), alignOf<AlignedCharArray<S5>::union_type>()); + EXPECT_EQ(alignOf<S6>(), alignOf<AlignedCharArray<S6>::union_type>()); + EXPECT_EQ(alignOf<D1>(), alignOf<AlignedCharArray<D1>::union_type>()); + EXPECT_EQ(alignOf<D2>(), alignOf<AlignedCharArray<D2>::union_type>()); + EXPECT_EQ(alignOf<D3>(), alignOf<AlignedCharArray<D3>::union_type>()); + EXPECT_EQ(alignOf<D4>(), alignOf<AlignedCharArray<D4>::union_type>()); + EXPECT_EQ(alignOf<D5>(), alignOf<AlignedCharArray<D5>::union_type>()); + EXPECT_EQ(alignOf<D6>(), alignOf<AlignedCharArray<D6>::union_type>()); + EXPECT_EQ(alignOf<D7>(), alignOf<AlignedCharArray<D7>::union_type>()); + EXPECT_EQ(alignOf<D8>(), alignOf<AlignedCharArray<D8>::union_type>()); + EXPECT_EQ(alignOf<D9>(), alignOf<AlignedCharArray<D9>::union_type>()); + EXPECT_EQ(alignOf<V1>(), alignOf<AlignedCharArray<V1>::union_type>()); + EXPECT_EQ(alignOf<V2>(), alignOf<AlignedCharArray<V2>::union_type>()); + EXPECT_EQ(alignOf<V3>(), alignOf<AlignedCharArray<V3>::union_type>()); + EXPECT_EQ(alignOf<V4>(), alignOf<AlignedCharArray<V4>::union_type>()); + EXPECT_EQ(alignOf<V5>(), alignOf<AlignedCharArray<V5>::union_type>()); + EXPECT_EQ(alignOf<V6>(), alignOf<AlignedCharArray<V6>::union_type>()); + EXPECT_EQ(alignOf<V7>(), alignOf<AlignedCharArray<V7>::union_type>()); + + // Some versions of MSVC get this wrong somewhat disturbingly. The failure + // appears to be benign: alignOf<V8>() produces a preposterous value: 12 +#ifndef _MSC_VER + EXPECT_EQ(alignOf<V8>(), alignOf<AlignedCharArray<V8>::union_type>()); +#endif + + EXPECT_EQ(sizeof(char), sizeof(AlignedCharArray<char>::union_type)); + EXPECT_EQ(sizeof(char[1]), sizeof(AlignedCharArray<char[1]>::union_type)); + EXPECT_EQ(sizeof(char[2]), sizeof(AlignedCharArray<char[2]>::union_type)); + EXPECT_EQ(sizeof(char[3]), sizeof(AlignedCharArray<char[3]>::union_type)); + EXPECT_EQ(sizeof(char[4]), sizeof(AlignedCharArray<char[4]>::union_type)); + EXPECT_EQ(sizeof(char[5]), sizeof(AlignedCharArray<char[5]>::union_type)); + EXPECT_EQ(sizeof(char[8]), sizeof(AlignedCharArray<char[8]>::union_type)); + EXPECT_EQ(sizeof(char[13]), sizeof(AlignedCharArray<char[13]>::union_type)); + EXPECT_EQ(sizeof(char[16]), sizeof(AlignedCharArray<char[16]>::union_type)); + EXPECT_EQ(sizeof(char[21]), sizeof(AlignedCharArray<char[21]>::union_type)); + EXPECT_EQ(sizeof(char[32]), sizeof(AlignedCharArray<char[32]>::union_type)); + EXPECT_EQ(sizeof(short), sizeof(AlignedCharArray<short>::union_type)); + EXPECT_EQ(sizeof(int), sizeof(AlignedCharArray<int>::union_type)); + EXPECT_EQ(sizeof(long), sizeof(AlignedCharArray<long>::union_type)); + EXPECT_EQ(sizeof(long long), + sizeof(AlignedCharArray<long long>::union_type)); + EXPECT_EQ(sizeof(float), sizeof(AlignedCharArray<float>::union_type)); + EXPECT_EQ(sizeof(double), sizeof(AlignedCharArray<double>::union_type)); + EXPECT_EQ(sizeof(long double), + sizeof(AlignedCharArray<long double>::union_type)); + EXPECT_EQ(sizeof(void *), sizeof(AlignedCharArray<void *>::union_type)); + EXPECT_EQ(sizeof(int *), sizeof(AlignedCharArray<int *>::union_type)); + EXPECT_EQ(sizeof(double (*)(double)), + sizeof(AlignedCharArray<double (*)(double)>::union_type)); + EXPECT_EQ(sizeof(double (S6::*)()), + sizeof(AlignedCharArray<double (S6::*)()>::union_type)); + EXPECT_EQ(sizeof(S1), sizeof(AlignedCharArray<S1>::union_type)); + EXPECT_EQ(sizeof(S2), sizeof(AlignedCharArray<S2>::union_type)); + EXPECT_EQ(sizeof(S3), sizeof(AlignedCharArray<S3>::union_type)); + EXPECT_EQ(sizeof(S4), sizeof(AlignedCharArray<S4>::union_type)); + EXPECT_EQ(sizeof(S5), sizeof(AlignedCharArray<S5>::union_type)); + EXPECT_EQ(sizeof(S6), sizeof(AlignedCharArray<S6>::union_type)); + EXPECT_EQ(sizeof(D1), sizeof(AlignedCharArray<D1>::union_type)); + EXPECT_EQ(sizeof(D2), sizeof(AlignedCharArray<D2>::union_type)); + EXPECT_EQ(sizeof(D3), sizeof(AlignedCharArray<D3>::union_type)); + EXPECT_EQ(sizeof(D4), sizeof(AlignedCharArray<D4>::union_type)); + EXPECT_EQ(sizeof(D5), sizeof(AlignedCharArray<D5>::union_type)); + EXPECT_EQ(sizeof(D6), sizeof(AlignedCharArray<D6>::union_type)); + EXPECT_EQ(sizeof(D7), sizeof(AlignedCharArray<D7>::union_type)); + EXPECT_EQ(sizeof(D8), sizeof(AlignedCharArray<D8>::union_type)); + EXPECT_EQ(sizeof(D9), sizeof(AlignedCharArray<D9>::union_type)); + EXPECT_EQ(sizeof(D9[1]), sizeof(AlignedCharArray<D9[1]>::union_type)); + EXPECT_EQ(sizeof(D9[2]), sizeof(AlignedCharArray<D9[2]>::union_type)); + EXPECT_EQ(sizeof(D9[3]), sizeof(AlignedCharArray<D9[3]>::union_type)); + EXPECT_EQ(sizeof(D9[4]), sizeof(AlignedCharArray<D9[4]>::union_type)); + EXPECT_EQ(sizeof(D9[5]), sizeof(AlignedCharArray<D9[5]>::union_type)); + EXPECT_EQ(sizeof(D9[8]), sizeof(AlignedCharArray<D9[8]>::union_type)); + EXPECT_EQ(sizeof(D9[13]), sizeof(AlignedCharArray<D9[13]>::union_type)); + EXPECT_EQ(sizeof(D9[16]), sizeof(AlignedCharArray<D9[16]>::union_type)); + EXPECT_EQ(sizeof(D9[21]), sizeof(AlignedCharArray<D9[21]>::union_type)); + EXPECT_EQ(sizeof(D9[32]), sizeof(AlignedCharArray<D9[32]>::union_type)); + EXPECT_EQ(sizeof(V1), sizeof(AlignedCharArray<V1>::union_type)); + EXPECT_EQ(sizeof(V2), sizeof(AlignedCharArray<V2>::union_type)); + EXPECT_EQ(sizeof(V3), sizeof(AlignedCharArray<V3>::union_type)); + EXPECT_EQ(sizeof(V4), sizeof(AlignedCharArray<V4>::union_type)); + EXPECT_EQ(sizeof(V5), sizeof(AlignedCharArray<V5>::union_type)); + EXPECT_EQ(sizeof(V6), sizeof(AlignedCharArray<V6>::union_type)); + EXPECT_EQ(sizeof(V7), sizeof(AlignedCharArray<V7>::union_type)); + + // Some versions of MSVC also get this wrong. The failure again appears to be + // benign: sizeof(V8) is only 52 bytes, but our array reserves 56. +#ifndef _MSC_VER + EXPECT_EQ(sizeof(V8), sizeof(AlignedCharArray<V8>::union_type)); +#endif +} + +} diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp index df25642..9c5bd7b 100644 --- a/unittests/Support/BlockFrequencyTest.cpp +++ b/unittests/Support/BlockFrequencyTest.cpp @@ -34,7 +34,7 @@ TEST(BlockFrequencyTest, MaxToHalfMax) { BlockFrequency Freq(UINT64_MAX); BranchProbability Prob(UINT32_MAX / 2, UINT32_MAX); Freq *= Prob; - EXPECT_EQ(Freq.getFrequency(), 9223372034707292159LLu); + EXPECT_EQ(Freq.getFrequency(), 9223372034707292159ULL); } TEST(BlockFrequencyTest, BigToBig) { diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt new file mode 100644 index 0000000..3b9bf84 --- /dev/null +++ b/unittests/Support/CMakeLists.txt @@ -0,0 +1,27 @@ +set(LLVM_LINK_COMPONENTS + Support + Core + ) + +add_llvm_unittest(SupportTests + AlignOfTest.cpp + AllocatorTest.cpp + BlockFrequencyTest.cpp + Casting.cpp + CommandLineTest.cpp + ConstantRangeTest.cpp + DataExtractorTest.cpp + EndianTest.cpp + FileOutputBufferTest.cpp + IntegersSubsetTest.cpp + LeakDetectorTest.cpp + ManagedStatic.cpp + MathExtrasTest.cpp + Path.cpp + raw_ostream_test.cpp + RegexTest.cpp + SwapByteOrderTest.cpp + TimeValue.cpp + ValueHandleTest.cpp + YAMLParserTest.cpp + ) diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index 72fa24a..13e9038 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -55,6 +55,17 @@ TEST(CommandLineTest, ParseEnvironment) { EXPECT_EQ("hello", EnvironmentTestOption); } +// This test used to make valgrind complain +// ("Conditional jump or move depends on uninitialised value(s)") +TEST(CommandLineTest, ParseEnvironmentToLocalVar) { + // Put cl::opt on stack to check for proper initialization of fields. + cl::opt<std::string> EnvironmentTestOptionLocal("env-test-opt-local"); + TempEnvVar TEV(test_env_var, "-env-test-opt-local=hello-local"); + EXPECT_EQ("", EnvironmentTestOptionLocal); + cl::ParseEnvironmentOptions("CommandLineTest", test_env_var); + EXPECT_EQ("hello-local", EnvironmentTestOptionLocal); +} + #endif // SKIP_ENVIRONMENT_TESTS } // anonymous namespace diff --git a/unittests/Support/ConstantRangeTest.cpp b/unittests/Support/ConstantRangeTest.cpp index 742bcb4..263f93c 100644 --- a/unittests/Support/ConstantRangeTest.cpp +++ b/unittests/Support/ConstantRangeTest.cpp @@ -114,11 +114,15 @@ TEST_F(ConstantRangeTest, SingleElement) { } TEST_F(ConstantRangeTest, GetSetSize) { - EXPECT_EQ(Full.getSetSize(), APInt(16, 0)); - EXPECT_EQ(Empty.getSetSize(), APInt(16, 0)); - EXPECT_EQ(One.getSetSize(), APInt(16, 1)); - EXPECT_EQ(Some.getSetSize(), APInt(16, 0xaa0)); - EXPECT_EQ(Wrap.getSetSize(), APInt(16, 0x10000 - 0xaa0)); + EXPECT_EQ(Full.getSetSize(), APInt(17, 65536)); + EXPECT_EQ(Empty.getSetSize(), APInt(17, 0)); + EXPECT_EQ(One.getSetSize(), APInt(17, 1)); + EXPECT_EQ(Some.getSetSize(), APInt(17, 0xaa0)); + + ConstantRange Wrap(APInt(4, 7), APInt(4, 3)); + ConstantRange Wrap2(APInt(4, 8), APInt(4, 7)); + EXPECT_EQ(Wrap.getSetSize(), APInt(5, 12)); + EXPECT_EQ(Wrap2.getSetSize(), APInt(5, 15)); } TEST_F(ConstantRangeTest, GetMinsAndMaxes) { @@ -189,6 +193,10 @@ TEST_F(ConstantRangeTest, ZExt) { EXPECT_EQ(ZSome, ConstantRange(Some.getLower().zext(20), Some.getUpper().zext(20))); EXPECT_EQ(ZWrap, ConstantRange(APInt(20, 0), APInt(20, 0x10000))); + + // zext([5, 0), 3->7) = [5, 8) + ConstantRange FiveZero(APInt(3, 5), APInt(3, 0)); + EXPECT_EQ(FiveZero.zeroExtend(7), ConstantRange(APInt(7, 5), APInt(7, 8))); } TEST_F(ConstantRangeTest, SExt) { @@ -232,6 +240,41 @@ TEST_F(ConstantRangeTest, IntersectWith) { ConstantRange LHS(APInt(16, 4), APInt(16, 2)); ConstantRange RHS(APInt(16, 6), APInt(16, 5)); EXPECT_TRUE(LHS.intersectWith(RHS) == LHS); + + // previous bug: intersection of [min, 3) and [2, max) should be 2 + LHS = ConstantRange(APInt(32, -2147483646), APInt(32, 3)); + RHS = ConstantRange(APInt(32, 2), APInt(32, 2147483646)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2))); + + // [2, 0) /\ [4, 3) = [2, 0) + LHS = ConstantRange(APInt(32, 2), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 4), APInt(32, 3)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 2), APInt(32, 0))); + + // [2, 0) /\ [4, 2) = [4, 0) + LHS = ConstantRange(APInt(32, 2), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 4), APInt(32, 2)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 0))); + + // [4, 2) /\ [5, 1) = [5, 1) + LHS = ConstantRange(APInt(32, 4), APInt(32, 2)); + RHS = ConstantRange(APInt(32, 5), APInt(32, 1)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 5), APInt(32, 1))); + + // [2, 0) /\ [7, 4) = [7, 4) + LHS = ConstantRange(APInt(32, 2), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 7), APInt(32, 4)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 7), APInt(32, 4))); + + // [4, 2) /\ [1, 0) = [1, 0) + LHS = ConstantRange(APInt(32, 4), APInt(32, 2)); + RHS = ConstantRange(APInt(32, 1), APInt(32, 0)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 4), APInt(32, 2))); + + // [15, 0) /\ [7, 6) = [15, 0) + LHS = ConstantRange(APInt(32, 15), APInt(32, 0)); + RHS = ConstantRange(APInt(32, 7), APInt(32, 6)); + EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0))); } TEST_F(ConstantRangeTest, UnionWith) { @@ -254,6 +297,23 @@ TEST_F(ConstantRangeTest, UnionWith) { ConstantRange(16)); } +TEST_F(ConstantRangeTest, SetDifference) { + EXPECT_EQ(Full.difference(Empty), Full); + EXPECT_EQ(Full.difference(Full), Empty); + EXPECT_EQ(Empty.difference(Empty), Empty); + EXPECT_EQ(Empty.difference(Full), Empty); + + ConstantRange A(APInt(16, 3), APInt(16, 7)); + ConstantRange B(APInt(16, 5), APInt(16, 9)); + ConstantRange C(APInt(16, 3), APInt(16, 5)); + ConstantRange D(APInt(16, 7), APInt(16, 9)); + ConstantRange E(APInt(16, 5), APInt(16, 4)); + ConstantRange F(APInt(16, 7), APInt(16, 3)); + EXPECT_EQ(A.difference(B), C); + EXPECT_EQ(B.difference(A), D); + EXPECT_EQ(E.difference(A), F); +} + TEST_F(ConstantRangeTest, SubtractAPInt) { EXPECT_EQ(Full.subtract(APInt(16, 4)), Full); EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty); @@ -326,6 +386,14 @@ TEST_F(ConstantRangeTest, Multiply) { EXPECT_EQ(Some.multiply(Wrap), Full); EXPECT_EQ(Wrap.multiply(Wrap), Full); + ConstantRange Zero(APInt(16, 0)); + EXPECT_EQ(Zero.multiply(Full), Zero); + EXPECT_EQ(Zero.multiply(Some), Zero); + EXPECT_EQ(Zero.multiply(Wrap), Zero); + EXPECT_EQ(Full.multiply(Zero), Zero); + EXPECT_EQ(Some.multiply(Zero), Zero); + EXPECT_EQ(Wrap.multiply(Zero), Zero); + // http://llvm.org/PR4545 EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply( ConstantRange(APInt(4, 6), APInt(4, 2))), diff --git a/unittests/Support/FileOutputBufferTest.cpp b/unittests/Support/FileOutputBufferTest.cpp new file mode 100644 index 0000000..edd350a --- /dev/null +++ b/unittests/Support/FileOutputBufferTest.cpp @@ -0,0 +1,137 @@ +//===- llvm/unittest/Support/FileOutputBuffer.cpp - unit tests ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/PathV2.h" +#include "llvm/Support/raw_ostream.h" + +#include "gtest/gtest.h" + +using namespace llvm; +using namespace llvm::sys; + +#define ASSERT_NO_ERROR(x) \ + if (error_code ASSERT_NO_ERROR_ec = x) { \ + errs() << #x ": did not return errc::success.\n" \ + << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \ + << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \ + } else {} + +namespace { + + +// NOTE: Temporarily run this test on unix only. Once the file mapping +// routines are ported to Windows, this conditional can be removed. +#if LLVM_ON_UNIX + + +TEST(FileOutputBuffer, Test) { + // Create unique temporary directory for these tests + SmallString<128> TestDirectory; + { + int fd; + ASSERT_NO_ERROR( + fs::unique_file("FileOutputBuffer-test-%%-%%-%%-%%/dir", fd, + TestDirectory)); + ::close(fd); + TestDirectory = path::parent_path(TestDirectory); + } + + // TEST 1: Verify commit case. + SmallString<128> File1(TestDirectory); + File1.append("/file1"); + { + OwningPtr<FileOutputBuffer> Buffer; + ASSERT_NO_ERROR(FileOutputBuffer::create(File1, 8192, Buffer)); + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Write to end of buffer to verify it is writable. + memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer. + ASSERT_NO_ERROR(Buffer->commit()); + } + // Verify file exists and starts with special header. + bool MagicMatches = false; + ASSERT_NO_ERROR(fs::has_magic(Twine(File1), Twine("AABBCCDDEEFFGGHHIIJJ"), + MagicMatches)); + EXPECT_TRUE(MagicMatches); + // Verify file is correct size. + uint64_t File1Size; + ASSERT_NO_ERROR(fs::file_size(Twine(File1), File1Size)); + ASSERT_EQ(File1Size, 8192ULL); + + // TEST 2: Verify abort case. + SmallString<128> File2(TestDirectory); + File2.append("/file2"); + { + OwningPtr<FileOutputBuffer> Buffer2; + ASSERT_NO_ERROR(FileOutputBuffer::create(File2, 8192, Buffer2)); + // Fill buffer with special header. + memcpy(Buffer2->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Do *not* commit buffer. + } + // Verify file does not exist (because buffer not commited). + bool Exists = false; + ASSERT_NO_ERROR(fs::exists(Twine(File2), Exists)); + EXPECT_FALSE(Exists); + + + // TEST 3: Verify sizing down case. + SmallString<128> File3(TestDirectory); + File3.append("/file3"); + { + OwningPtr<FileOutputBuffer> Buffer; + ASSERT_NO_ERROR(FileOutputBuffer::create(File3, 8192000, Buffer)); + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Write to end of buffer to verify it is writable. + memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer, but size down to smaller size + ASSERT_NO_ERROR(Buffer->commit(5000)); + } + // Verify file exists and starts with special header. + bool MagicMatches3 = false; + ASSERT_NO_ERROR(fs::has_magic(Twine(File3), Twine("AABBCCDDEEFFGGHHIIJJ"), + MagicMatches3)); + EXPECT_TRUE(MagicMatches3); + // Verify file is correct size. + uint64_t File3Size; + ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size)); + ASSERT_EQ(File3Size, 5000ULL); + + + // TEST 4: Verify file can be made executable. + SmallString<128> File4(TestDirectory); + File4.append("/file4"); + { + OwningPtr<FileOutputBuffer> Buffer; + ASSERT_NO_ERROR(FileOutputBuffer::create(File4, 8192, Buffer, + FileOutputBuffer::F_executable)); + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer. + ASSERT_NO_ERROR(Buffer->commit()); + } + // Verify file exists and is executable. + fs::file_status Status; + ASSERT_NO_ERROR(fs::status(Twine(File4), Status)); + bool IsExecutable = (Status.permissions() & fs::owner_exe); + EXPECT_TRUE(IsExecutable); + + // Clean up. + uint32_t RemovedCount; + ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), RemovedCount)); +} + +#endif // LLVM_ON_UNIX + +} // anonymous namespace diff --git a/unittests/Support/IRBuilderTest.cpp b/unittests/Support/IRBuilderTest.cpp deleted file mode 100644 index b15de9e..0000000 --- a/unittests/Support/IRBuilderTest.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===- llvm/unittest/Support/IRBuilderTest.cpp - IRBuilder 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/IRBuilder.h" -#include "llvm/BasicBlock.h" -#include "llvm/Function.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/ADT/OwningPtr.h" - -#include "gtest/gtest.h" - -using namespace llvm; - -namespace { -class IRBuilderTest : public testing::Test { -protected: - virtual void SetUp() { - M.reset(new Module("MyModule", getGlobalContext())); - FunctionType *FTy = FunctionType::get(Type::getVoidTy(getGlobalContext()), - /*isVarArg=*/false); - Function *F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); - BB = BasicBlock::Create(getGlobalContext(), "", F); - } - - virtual void TearDown() { - BB = 0; - M.reset(); - } - - OwningPtr<Module> M; - BasicBlock *BB; -}; -} - -TEST_F(IRBuilderTest, Lifetime) { - IRBuilder<> Builder(BB); - AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty()); - AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty()); - AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(), - Builder.getInt32(123)); - - CallInst *Start1 = Builder.CreateLifetimeStart(Var1); - CallInst *Start2 = Builder.CreateLifetimeStart(Var2); - CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100)); - - EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1)); - EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1)); - EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100)); - - EXPECT_EQ(Start1->getArgOperand(1), Var1); - EXPECT_NE(Start2->getArgOperand(1), Var2); - EXPECT_EQ(Start3->getArgOperand(1), Var3); - - Value *End1 = Builder.CreateLifetimeEnd(Var1); - Builder.CreateLifetimeEnd(Var2); - Builder.CreateLifetimeEnd(Var3); - - IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1); - IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1); - ASSERT_TRUE(II_Start1 != NULL); - EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start); - ASSERT_TRUE(II_End1 != NULL); - EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end); -} diff --git a/unittests/Support/IntegersSubsetTest.cpp b/unittests/Support/IntegersSubsetTest.cpp new file mode 100644 index 0000000..5d1dde4 --- /dev/null +++ b/unittests/Support/IntegersSubsetTest.cpp @@ -0,0 +1,328 @@ +//===- llvm/unittest/Support/IntegersSubsetTest.cpp - IntegersSubset 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/APInt.h" +#include "llvm/Support/IntegersSubset.h" +#include "llvm/Support/IntegersSubsetMapping.h" + +#include "gtest/gtest.h" + +#include <vector> + +using namespace llvm; + +namespace { + + class Int : public APInt { + public: + Int() {} + Int(uint64_t V) : APInt(64, V) {} + Int(const APInt& Src) : APInt(Src) {} + bool operator < (const APInt& RHS) const { return ult(RHS); } + bool operator > (const APInt& RHS) const { return ugt(RHS); } + bool operator <= (const APInt& RHS) const { return ule(RHS); } + bool operator >= (const APInt& RHS) const { return uge(RHS); } + }; + + typedef IntRange<Int> Range; + typedef IntegersSubsetGeneric<Int> Subset; + typedef IntegersSubsetMapping<unsigned,Subset,Int> Mapping; + + TEST(IntegersSubsetTest, GeneralTest) { + + // Test construction. + + std::vector<Range> Ranges; + Ranges.reserve(3); + + // Initialize Subset as union of three pairs: + // { {0, 8}, {10, 18}, {20, 28} } + for (unsigned i = 0; i < 3; ++i) + Ranges.push_back(Range(Int(i*10), Int(i*10 + 8))); + + Subset TheSubset(Ranges); + + for (unsigned i = 0; i < 3; ++i) { + EXPECT_EQ(TheSubset.getItem(i).getLow(), Int(i*10)); + EXPECT_EQ(TheSubset.getItem(i).getHigh(), Int(i*10 + 8)); + } + + EXPECT_EQ(TheSubset.getNumItems(), 3ULL); + + // Test belonging to range. + + EXPECT_TRUE(TheSubset.isSatisfies(Int(5))); + EXPECT_FALSE(TheSubset.isSatisfies(Int(9))); + + // Test when subset contains the only item. + + Ranges.clear(); + Ranges.push_back(Range(Int(10), Int(10))); + + Subset TheSingleNumber(Ranges); + + EXPECT_TRUE(TheSingleNumber.isSingleNumber()); + + Ranges.push_back(Range(Int(12), Int(15))); + + Subset NotASingleNumber(Ranges); + + EXPECT_FALSE(NotASingleNumber.isSingleNumber()); + + // Test when subset contains items that are not a ranges but + // the single numbers. + + Ranges.clear(); + Ranges.push_back(Range(Int(10), Int(10))); + Ranges.push_back(Range(Int(15), Int(19))); + + Subset WithSingleNumberItems(Ranges); + + EXPECT_TRUE(WithSingleNumberItems.isSingleNumber(0)); + EXPECT_FALSE(WithSingleNumberItems.isSingleNumber(1)); + + // Test size of subset. Note subset itself may be not optimized (improper), + // so it may contain duplicates, and the size of subset { {0, 9} {5, 9} } + // will 15 instead of 10. + + Ranges.clear(); + Ranges.push_back(Range(Int(0), Int(9))); + Ranges.push_back(Range(Int(5), Int(9))); + + Subset NotOptimizedSubset(Ranges); + + EXPECT_EQ(NotOptimizedSubset.getSize(), 15ULL); + + // Test access to a single value. + // getSingleValue(idx) method represents subset as flat numbers collection, + // so subset { {0, 3}, {8, 10} } will represented as array + // { 0, 1, 2, 3, 8, 9, 10 }. + + Ranges.clear(); + Ranges.push_back(Range(Int(0), Int(3))); + Ranges.push_back(Range(Int(8), Int(10))); + + Subset OneMoreSubset(Ranges); + + EXPECT_EQ(OneMoreSubset.getSingleValue(5), Int(9)); + } + + TEST(IntegersSubsetTest, MappingTest) { + + Mapping::Cases TheCases; + + unsigned Successors[3] = {0, 1, 2}; + + // Test construction. + + Mapping TheMapping; + for (unsigned i = 0; i < 3; ++i) + TheMapping.add(Int(10*i), Int(10*i + 9), Successors + i); + TheMapping.add(Int(111), Int(222), Successors); + TheMapping.removeItem(--TheMapping.end()); + + TheMapping.getCases(TheCases); + + EXPECT_EQ(TheCases.size(), 3ULL); + + for (unsigned i = 0; i < 3; ++i) { + Mapping::Cases::iterator CaseIt = TheCases.begin(); + std::advance(CaseIt, i); + EXPECT_EQ(CaseIt->first, Successors + i); + EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL); + EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(10*i), Int(10*i + 9))); + } + + // Test verification. + + Mapping ImproperMapping; + ImproperMapping.add(Int(10), Int(11), Successors + 0); + ImproperMapping.add(Int(11), Int(12), Successors + 1); + + Mapping::RangeIterator ErrItem; + EXPECT_FALSE(ImproperMapping.verify(ErrItem)); + EXPECT_EQ(ErrItem, --ImproperMapping.end()); + + Mapping ProperMapping; + ProperMapping.add(Int(10), Int(11), Successors + 0); + ProperMapping.add(Int(12), Int(13), Successors + 1); + + EXPECT_TRUE(ProperMapping.verify(ErrItem)); + + // Test optimization. + + Mapping ToBeOptimized; + + for (unsigned i = 0; i < 3; ++i) { + ToBeOptimized.add(Int(i * 10), Int(i * 10 + 1), Successors + i); + ToBeOptimized.add(Int(i * 10 + 2), Int(i * 10 + 9), Successors + i); + } + + ToBeOptimized.optimize(); + + TheCases.clear(); + ToBeOptimized.getCases(TheCases); + + EXPECT_EQ(TheCases.size(), 3ULL); + + for (unsigned i = 0; i < 3; ++i) { + Mapping::Cases::iterator CaseIt = TheCases.begin(); + std::advance(CaseIt, i); + EXPECT_EQ(CaseIt->first, Successors + i); + EXPECT_EQ(CaseIt->second.getNumItems(), 1ULL); + EXPECT_EQ(CaseIt->second.getItem(0), Range(Int(i * 10), Int(i * 10 + 9))); + } + } + + typedef unsigned unsigned_pair[2]; + typedef unsigned_pair unsigned_ranges[]; + + void TestDiff( + const unsigned_ranges LHS, + unsigned LSize, + const unsigned_ranges RHS, + unsigned RSize, + const unsigned_ranges ExcludeRes, + unsigned ExcludeResSize, + const unsigned_ranges IntersectRes, + unsigned IntersectResSize + ) { + + Mapping::RangesCollection Ranges; + + Mapping LHSMapping; + for (unsigned i = 0; i < LSize; ++i) + Ranges.push_back(Range(Int(LHS[i][0]), Int(LHS[i][1]))); + LHSMapping.add(Ranges); + + Ranges.clear(); + + Mapping RHSMapping; + for (unsigned i = 0; i < RSize; ++i) + Ranges.push_back(Range(Int(RHS[i][0]), Int(RHS[i][1]))); + RHSMapping.add(Ranges); + + Mapping LExclude, Intersection; + + LHSMapping.diff(&LExclude, &Intersection, 0, RHSMapping); + + if (ExcludeResSize) { + EXPECT_EQ(LExclude.size(), ExcludeResSize); + + unsigned i = 0; + for (Mapping::RangeIterator rei = LExclude.begin(), + e = LExclude.end(); rei != e; ++rei, ++i) + EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1])); + } else + EXPECT_TRUE(LExclude.empty()); + + if (IntersectResSize) { + EXPECT_EQ(Intersection.size(), IntersectResSize); + + unsigned i = 0; + for (Mapping::RangeIterator ii = Intersection.begin(), + e = Intersection.end(); ii != e; ++ii, ++i) + EXPECT_EQ(ii->first, Range(IntersectRes[i][0], IntersectRes[i][1])); + } else + EXPECT_TRUE(Intersection.empty()); + + LExclude.clear(); + Intersection.clear(); + RHSMapping.diff(0, &Intersection, &LExclude, LHSMapping); + + // Check LExclude again. + if (ExcludeResSize) { + EXPECT_EQ(LExclude.size(), ExcludeResSize); + + unsigned i = 0; + for (Mapping::RangeIterator rei = LExclude.begin(), + e = LExclude.end(); rei != e; ++rei, ++i) + EXPECT_EQ(rei->first, Range(ExcludeRes[i][0], ExcludeRes[i][1])); + } else + EXPECT_TRUE(LExclude.empty()); + } + + TEST(IntegersSubsetTest, DiffTest) { + + static const unsigned NOT_A_NUMBER = 0xffff; + + { + unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } }; + unsigned_ranges RHS = { { 3, 14 } }; + unsigned_ranges ExcludeRes = { { 0, 2 }, { 15, 17 } }; + unsigned_ranges IntersectRes = { { 3, 4 }, { 7, 10 }, { 13, 14 } }; + + TestDiff(LHS, 3, RHS, 1, ExcludeRes, 2, IntersectRes, 3); + } + + { + unsigned_ranges LHS = { { 0, 4 }, { 7, 10 }, { 13, 17 } }; + unsigned_ranges RHS = { { 0, 4 }, { 13, 17 } }; + unsigned_ranges ExcludeRes = { { 7, 10 } }; + unsigned_ranges IntersectRes = { { 0, 4 }, { 13, 17 } }; + + TestDiff(LHS, 3, RHS, 2, ExcludeRes, 1, IntersectRes, 2); + } + + { + unsigned_ranges LHS = { { 0, 17 } }; + unsigned_ranges RHS = { { 1, 5 }, { 10, 12 }, { 15, 16 } }; + unsigned_ranges ExcludeRes = + { { 0, 0 }, { 6, 9 }, { 13, 14 }, { 17, 17 } }; + unsigned_ranges IntersectRes = { { 1, 5 }, { 10, 12 }, { 15, 16 } }; + + TestDiff(LHS, 1, RHS, 3, ExcludeRes, 4, IntersectRes, 3); + } + + { + unsigned_ranges LHS = { { 2, 4 } }; + unsigned_ranges RHS = { { 0, 5 } }; + unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} }; + unsigned_ranges IntersectRes = { { 2, 4 } }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 0, IntersectRes, 1); + } + + { + unsigned_ranges LHS = { { 2, 4 } }; + unsigned_ranges RHS = { { 7, 8 } }; + unsigned_ranges ExcludeRes = { { 2, 4 } }; + unsigned_ranges IntersectRes = { {NOT_A_NUMBER, NOT_A_NUMBER} }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0); + } + + { + unsigned_ranges LHS = { { 3, 7 } }; + unsigned_ranges RHS = { { 1, 4 } }; + unsigned_ranges ExcludeRes = { { 5, 7 } }; + unsigned_ranges IntersectRes = { { 3, 4 } }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 1); + } + + { + unsigned_ranges LHS = { { 0, 7 } }; + unsigned_ranges RHS = { { 0, 5 }, { 6, 9 } }; + unsigned_ranges ExcludeRes = { {NOT_A_NUMBER, NOT_A_NUMBER} }; + unsigned_ranges IntersectRes = { { 0, 5 }, {6, 7} }; + + TestDiff(LHS, 1, RHS, 2, ExcludeRes, 0, IntersectRes, 2); + } + + { + unsigned_ranges LHS = { { 17, 17 } }; + unsigned_ranges RHS = { { 4, 4 } }; + unsigned_ranges ExcludeRes = { {17, 17} }; + unsigned_ranges IntersectRes = { { NOT_A_NUMBER, NOT_A_NUMBER } }; + + TestDiff(LHS, 1, RHS, 1, ExcludeRes, 1, IntersectRes, 0); + } + } +} diff --git a/unittests/Support/MDBuilderTest.cpp b/unittests/Support/MDBuilderTest.cpp deleted file mode 100644 index d54c7e8..0000000 --- a/unittests/Support/MDBuilderTest.cpp +++ /dev/null @@ -1,105 +0,0 @@ -//===- llvm/unittests/Support/MDBuilderTest.cpp - MDBuilder unit tests ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "gtest/gtest.h" -#include "llvm/Operator.h" -#include "llvm/Support/IRBuilder.h" -#include "llvm/Support/MDBuilder.h" -using namespace llvm; - -namespace { - -class MDBuilderTest : public testing::Test { -protected: - LLVMContext Context; -}; - -TEST_F(MDBuilderTest, createString) { - MDBuilder MDHelper(Context); - MDString *Str0 = MDHelper.createString(""); - MDString *Str1 = MDHelper.createString("string"); - EXPECT_EQ(Str0->getString(), StringRef("")); - EXPECT_EQ(Str1->getString(), StringRef("string")); -} -TEST_F(MDBuilderTest, createFPMath) { - MDBuilder MDHelper(Context); - MDNode *MD0 = MDHelper.createFPMath(0.0); - MDNode *MD1 = MDHelper.createFPMath(1.0); - EXPECT_EQ(MD0, (MDNode *)0); - EXPECT_NE(MD1, (MDNode *)0); - EXPECT_EQ(MD1->getNumOperands(), 1U); - Value *Op = MD1->getOperand(0); - EXPECT_TRUE(isa<ConstantFP>(Op)); - EXPECT_TRUE(Op->getType()->isFloatingPointTy()); - ConstantFP *Val = cast<ConstantFP>(Op); - EXPECT_TRUE(Val->isExactlyValue(1.0)); -} -TEST_F(MDBuilderTest, createRangeMetadata) { - MDBuilder MDHelper(Context); - APInt A(8, 1), B(8, 2); - MDNode *R0 = MDHelper.createRange(A, A); - MDNode *R1 = MDHelper.createRange(A, B); - EXPECT_EQ(R0, (MDNode *)0); - EXPECT_NE(R1, (MDNode *)0); - EXPECT_EQ(R1->getNumOperands(), 2U); - EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(0))); - EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(1))); - ConstantInt *C0 = cast<ConstantInt>(R1->getOperand(0)); - ConstantInt *C1 = cast<ConstantInt>(R1->getOperand(1)); - EXPECT_EQ(C0->getValue(), A); - EXPECT_EQ(C1->getValue(), B); -} -TEST_F(MDBuilderTest, createAnonymousTBAARoot) { - MDBuilder MDHelper(Context); - MDNode *R0 = MDHelper.createAnonymousTBAARoot(); - MDNode *R1 = MDHelper.createAnonymousTBAARoot(); - EXPECT_NE(R0, R1); - EXPECT_GE(R0->getNumOperands(), 1U); - EXPECT_GE(R1->getNumOperands(), 1U); - EXPECT_EQ(R0->getOperand(0), R0); - EXPECT_EQ(R1->getOperand(0), R1); - EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == 0); - EXPECT_TRUE(R1->getNumOperands() == 1 || R1->getOperand(1) == 0); -} -TEST_F(MDBuilderTest, createTBAARoot) { - MDBuilder MDHelper(Context); - MDNode *R0 = MDHelper.createTBAARoot("Root"); - MDNode *R1 = MDHelper.createTBAARoot("Root"); - EXPECT_EQ(R0, R1); - EXPECT_GE(R0->getNumOperands(), 1U); - EXPECT_TRUE(isa<MDString>(R0->getOperand(0))); - EXPECT_EQ(cast<MDString>(R0->getOperand(0))->getString(), "Root"); - EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == 0); -} -TEST_F(MDBuilderTest, createTBAANode) { - MDBuilder MDHelper(Context); - MDNode *R = MDHelper.createTBAARoot("Root"); - MDNode *N0 = MDHelper.createTBAANode("Node", R); - MDNode *N1 = MDHelper.createTBAANode("edoN", R); - MDNode *N2 = MDHelper.createTBAANode("Node", R, true); - MDNode *N3 = MDHelper.createTBAANode("Node", R); - EXPECT_EQ(N0, N3); - EXPECT_NE(N0, N1); - EXPECT_NE(N0, N2); - EXPECT_GE(N0->getNumOperands(), 2U); - EXPECT_GE(N1->getNumOperands(), 2U); - EXPECT_GE(N2->getNumOperands(), 3U); - EXPECT_TRUE(isa<MDString>(N0->getOperand(0))); - EXPECT_TRUE(isa<MDString>(N1->getOperand(0))); - EXPECT_TRUE(isa<MDString>(N2->getOperand(0))); - EXPECT_EQ(cast<MDString>(N0->getOperand(0))->getString(), "Node"); - EXPECT_EQ(cast<MDString>(N1->getOperand(0))->getString(), "edoN"); - EXPECT_EQ(cast<MDString>(N2->getOperand(0))->getString(), "Node"); - EXPECT_EQ(N0->getOperand(1), R); - EXPECT_EQ(N1->getOperand(1), R); - EXPECT_EQ(N2->getOperand(1), R); - EXPECT_TRUE(isa<ConstantInt>(N2->getOperand(2))); - EXPECT_EQ(cast<ConstantInt>(N2->getOperand(2))->getZExtValue(), 1U); -} -} diff --git a/unittests/Support/Path.cpp b/unittests/Support/Path.cpp index 358dad0..a071a5a 100644 --- a/unittests/Support/Path.cpp +++ b/unittests/Support/Path.cpp @@ -312,4 +312,72 @@ TEST_F(FileSystemTest, Magic) { } } +#if !defined(_WIN32) // FIXME: Win32 has different permission schema. +TEST_F(FileSystemTest, Permissions) { + // Create a temp file. + int FileDescriptor; + SmallString<64> TempPath; + ASSERT_NO_ERROR( + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath)); + + // Mark file as read-only + const fs::perms AllWrite = fs::owner_write|fs::group_write|fs::others_write; + ASSERT_NO_ERROR(fs::permissions(Twine(TempPath), fs::remove_perms|AllWrite)); + + // Verify file is read-only + fs::file_status Status; + ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status)); + bool AnyWriteBits = (Status.permissions() & AllWrite); + EXPECT_FALSE(AnyWriteBits); + + // Mark file as read-write + ASSERT_NO_ERROR(fs::permissions(Twine(TempPath), fs::add_perms|AllWrite)); + + // Verify file is read-write + ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status)); + AnyWriteBits = (Status.permissions() & AllWrite); + EXPECT_TRUE(AnyWriteBits); +} +#endif + +#if !defined(_WIN32) // FIXME: temporary suppressed. +TEST_F(FileSystemTest, FileMapping) { + // Create a temp file. + int FileDescriptor; + SmallString<64> TempPath; + ASSERT_NO_ERROR( + fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath)); + + // Grow temp file to be 4096 bytes + ASSERT_NO_ERROR(sys::fs::resize_file(Twine(TempPath), 4096)); + + // Map in temp file and add some content + void* MappedMemory; + ASSERT_NO_ERROR(fs::map_file_pages(Twine(TempPath), 0, 4096, + true /*writable*/, MappedMemory)); + char* Memory = reinterpret_cast<char*>(MappedMemory); + strcpy(Memory, "hello there"); + + // Unmap temp file + ASSERT_NO_ERROR(fs::unmap_file_pages(MappedMemory, 4096)); + MappedMemory = NULL; + Memory = NULL; + + // Map it back in read-only + ASSERT_NO_ERROR(fs::map_file_pages(Twine(TempPath), 0, 4096, + false /*read-only*/, MappedMemory)); + + // Verify content + Memory = reinterpret_cast<char*>(MappedMemory); + bool SAME = (strcmp(Memory, "hello there") == 0); + EXPECT_TRUE(SAME); + + // Unmap temp file + ASSERT_NO_ERROR(fs::unmap_file_pages(MappedMemory, 4096)); + MappedMemory = NULL; + Memory = NULL; +} +#endif + + } // anonymous namespace diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp deleted file mode 100644 index 20d0e73..0000000 --- a/unittests/Support/TypeBuilderTest.cpp +++ /dev/null @@ -1,254 +0,0 @@ -//===- llvm/unittest/Support/TypeBuilderTest.cpp - TypeBuilder tests -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/TypeBuilder.h" -#include "llvm/LLVMContext.h" -#include "llvm/ADT/ArrayRef.h" - -#include "gtest/gtest.h" - -using namespace llvm; - -namespace { - -TEST(TypeBuilderTest, Void) { - EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext()))); - // Special cases for C compatibility: - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<void*, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<const void*, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<volatile void*, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<const volatile void*, false>::get( - getGlobalContext()))); -} - -TEST(TypeBuilderTest, HostIntegers) { - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext()))); - - EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT), - (TypeBuilder<size_t, false>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT), - (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext()))); -} - -TEST(TypeBuilderTest, CrossCompilableIntegers) { - EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext()))); - EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext()))); -} - -TEST(TypeBuilderTest, Float) { - EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext()))); - // long double isn't supported yet. - EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext()))); -} - -TEST(TypeBuilderTest, Derived) { - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), - (TypeBuilder<int8_t**, false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), - (TypeBuilder<int8_t[7], false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), - (TypeBuilder<int8_t[], false>::get(getGlobalContext()))); - - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), - (TypeBuilder<types::i<8>**, false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), - (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), - (TypeBuilder<types::i<8>[], false>::get(getGlobalContext()))); - - EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())), - (TypeBuilder<types::i<8>**, true>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7), - (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext()))); - EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0), - (TypeBuilder<types::i<8>[], true>::get(getGlobalContext()))); - - - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const int8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<volatile int8_t, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext()))); - - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const types::i<8>, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext()))); - - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const types::i<8>, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext()))); - EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), - (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext()))); - - EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()), - (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext()))); -} - -TEST(TypeBuilderTest, Functions) { - std::vector<Type*> params; - EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false), - (TypeBuilder<void(), true>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char*, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, char, char, ...), - false>::get(getGlobalContext()))); - params.push_back(TypeBuilder<char, false>::get(getGlobalContext())); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false), - (TypeBuilder<int8_t(int32_t*, void*, char, char, char), - false>::get(getGlobalContext()))); - EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true), - (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...), - false>::get(getGlobalContext()))); -} - -TEST(TypeBuilderTest, Context) { - // We used to cache TypeBuilder results in static local variables. This - // produced the same type for different contexts, which of course broke - // things. - LLVMContext context1; - EXPECT_EQ(&context1, - &(TypeBuilder<types::i<1>, true>::get(context1))->getContext()); - LLVMContext context2; - EXPECT_EQ(&context2, - &(TypeBuilder<types::i<1>, true>::get(context2))->getContext()); -} - -class MyType { - int a; - int *b; - void *array[1]; -}; - -class MyPortableType { - int32_t a; - int32_t *b; - void *array[1]; -}; - -} // anonymous namespace - -namespace llvm { -template<bool cross> class TypeBuilder<MyType, cross> { -public: - static StructType *get(LLVMContext &Context) { - // Using the static result variable ensures that the type is - // only looked up once. - std::vector<Type*> st; - st.push_back(TypeBuilder<int, cross>::get(Context)); - st.push_back(TypeBuilder<int*, cross>::get(Context)); - st.push_back(TypeBuilder<void*[], cross>::get(Context)); - static StructType *const result = StructType::get(Context, st); - return result; - } - - // You may find this a convenient place to put some constants - // to help with getelementptr. They don't have any effect on - // the operation of TypeBuilder. - enum Fields { - FIELD_A, - FIELD_B, - FIELD_ARRAY - }; -}; - -template<bool cross> class TypeBuilder<MyPortableType, cross> { -public: - static StructType *get(LLVMContext &Context) { - // Using the static result variable ensures that the type is - // only looked up once. - std::vector<Type*> st; - st.push_back(TypeBuilder<types::i<32>, cross>::get(Context)); - st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context)); - st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context)); - static StructType *const result = StructType::get(Context, st); - return result; - } - - // You may find this a convenient place to put some constants - // to help with getelementptr. They don't have any effect on - // the operation of TypeBuilder. - enum Fields { - FIELD_A, - FIELD_B, - FIELD_ARRAY - }; -}; -} // namespace llvm -namespace { - -TEST(TypeBuilderTest, Extensions) { - EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<int, false>::get(getGlobalContext()), - TypeBuilder<int*, false>::get(getGlobalContext()), - TypeBuilder<void*[], false>::get(getGlobalContext()), - (void*)0)), - (TypeBuilder<MyType*, false>::get(getGlobalContext()))); - EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<types::i<32>, false>::get(getGlobalContext()), - TypeBuilder<types::i<32>*, false>::get(getGlobalContext()), - TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()), - (void*)0)), - (TypeBuilder<MyPortableType*, false>::get(getGlobalContext()))); - EXPECT_EQ(PointerType::getUnqual(StructType::get( - TypeBuilder<types::i<32>, false>::get(getGlobalContext()), - TypeBuilder<types::i<32>*, false>::get(getGlobalContext()), - TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()), - (void*)0)), - (TypeBuilder<MyPortableType*, true>::get(getGlobalContext()))); -} - -} // anonymous namespace diff --git a/unittests/Support/YAMLParserTest.cpp b/unittests/Support/YAMLParserTest.cpp index e88427a..480a573 100644 --- a/unittests/Support/YAMLParserTest.cpp +++ b/unittests/Support/YAMLParserTest.cpp @@ -16,11 +16,17 @@ namespace llvm { +static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) { + // Prevent SourceMgr from writing errors to stderr + // to reduce noise in unit test runs. +} + // Checks that the given input gives a parse error. Makes sure that an error // text is available and the parse fails. static void ExpectParseError(StringRef Message, StringRef Input) { SourceMgr SM; yaml::Stream Stream(Input, SM); + SM.setDiagHandler(SuppressDiagnosticsOutput); EXPECT_FALSE(Stream.validate()) << Message << ": " << Input; EXPECT_TRUE(Stream.failed()) << Message << ": " << Input; } |