summaryrefslogtreecommitdiff
path: root/unittests/Support
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-05-27 18:44:32 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-05-27 18:44:32 +0000
commit5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch)
treea6140557876943cdd800ee997c9317283394b22c /unittests/Support
parentf03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff)
Diffstat (limited to 'unittests/Support')
-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
23 files changed, 1089 insertions, 54 deletions
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
+}