Initial check in

Bug: 137197907
diff --git a/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp b/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
new file mode 100644
index 0000000..9940118
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ARMAttributeParser.cpp
@@ -0,0 +1,384 @@
+#include "llvm/Support/ARMAttributeParser.h"
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+
+struct AttributeSection {
+  unsigned Tag;
+  unsigned Value;
+
+  AttributeSection(unsigned tag, unsigned value) : Tag(tag), Value(value) { }
+
+  void write(raw_ostream &OS) {
+    OS.flush();
+    // length = length + "aeabi\0" + TagFile + ByteSize + Tag + Value;
+    // length = 17 bytes
+
+    OS << 'A' << (uint8_t)17 << (uint8_t)0 << (uint8_t)0 << (uint8_t)0;
+    OS << "aeabi" << '\0';
+    OS << (uint8_t)1 << (uint8_t)7 << (uint8_t)0 << (uint8_t)0 << (uint8_t)0;
+    OS << (uint8_t)Tag << (uint8_t)Value;
+
+  }
+};
+
+bool testBuildAttr(unsigned Tag, unsigned Value,
+                   unsigned ExpectedTag, unsigned ExpectedValue) {
+  std::string buffer;
+  raw_string_ostream OS(buffer);
+  AttributeSection Section(Tag, Value);
+  Section.write(OS);
+  ArrayRef<uint8_t> Bytes(
+    reinterpret_cast<const uint8_t*>(OS.str().c_str()), OS.str().size());
+
+  ARMAttributeParser Parser;
+  Parser.Parse(Bytes, true);
+
+  return (Parser.hasAttribute(ExpectedTag) &&
+    Parser.getAttributeValue(ExpectedTag) == ExpectedValue);
+}
+
+bool testTagString(unsigned Tag, const char *name) {
+  return ARMBuildAttrs::AttrTypeAsString(Tag).str() == name;
+}
+
+TEST(CPUArchBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(6, "Tag_CPU_arch"));
+
+  EXPECT_TRUE(testBuildAttr(6, 0, ARMBuildAttrs::CPU_arch,
+                            ARMBuildAttrs::Pre_v4));
+  EXPECT_TRUE(testBuildAttr(6, 1, ARMBuildAttrs::CPU_arch,
+                            ARMBuildAttrs::v4));
+  EXPECT_TRUE(testBuildAttr(6, 2, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v4T));
+  EXPECT_TRUE(testBuildAttr(6, 3, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v5T));
+  EXPECT_TRUE(testBuildAttr(6, 4, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v5TE));
+  EXPECT_TRUE(testBuildAttr(6, 5, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v5TEJ));
+  EXPECT_TRUE(testBuildAttr(6, 6, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6));
+  EXPECT_TRUE(testBuildAttr(6, 7, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6KZ));
+  EXPECT_TRUE(testBuildAttr(6, 8, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6T2));
+  EXPECT_TRUE(testBuildAttr(6, 9, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6K));
+  EXPECT_TRUE(testBuildAttr(6, 10, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v7));
+  EXPECT_TRUE(testBuildAttr(6, 11, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6_M));
+  EXPECT_TRUE(testBuildAttr(6, 12, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v6S_M));
+  EXPECT_TRUE(testBuildAttr(6, 13, ARMBuildAttrs::CPU_arch,
+                               ARMBuildAttrs::v7E_M));
+}
+
+TEST(CPUArchProfileBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(7, "Tag_CPU_arch_profile"));
+  EXPECT_TRUE(testBuildAttr(7, 'A', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::ApplicationProfile));
+  EXPECT_TRUE(testBuildAttr(7, 'R', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::RealTimeProfile));
+  EXPECT_TRUE(testBuildAttr(7, 'M', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::MicroControllerProfile));
+  EXPECT_TRUE(testBuildAttr(7, 'S', ARMBuildAttrs::CPU_arch_profile,
+                               ARMBuildAttrs::SystemProfile));
+}
+
+TEST(ARMISABuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(8, "Tag_ARM_ISA_use"));
+  EXPECT_TRUE(testBuildAttr(8, 0, ARMBuildAttrs::ARM_ISA_use,
+                               ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(8, 1, ARMBuildAttrs::ARM_ISA_use,
+                               ARMBuildAttrs::Allowed));
+}
+
+TEST(ThumbISABuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(9, "Tag_THUMB_ISA_use"));
+  EXPECT_TRUE(testBuildAttr(9, 0, ARMBuildAttrs::THUMB_ISA_use,
+                               ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(9, 1, ARMBuildAttrs::THUMB_ISA_use,
+                               ARMBuildAttrs::Allowed));
+}
+
+TEST(FPArchBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(10, "Tag_FP_arch"));
+  EXPECT_TRUE(testBuildAttr(10, 0, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(10, 1, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::Allowed));
+  EXPECT_TRUE(testBuildAttr(10, 2, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv2));
+  EXPECT_TRUE(testBuildAttr(10, 3, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv3A));
+  EXPECT_TRUE(testBuildAttr(10, 4, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv3B));
+  EXPECT_TRUE(testBuildAttr(10, 5, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv4A));
+  EXPECT_TRUE(testBuildAttr(10, 6, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPv4B));
+  EXPECT_TRUE(testBuildAttr(10, 7, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPARMv8A));
+  EXPECT_TRUE(testBuildAttr(10, 8, ARMBuildAttrs::FP_arch,
+                               ARMBuildAttrs::AllowFPARMv8B));
+}
+
+TEST(WMMXBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(11, "Tag_WMMX_arch"));
+  EXPECT_TRUE(testBuildAttr(11, 0, ARMBuildAttrs::WMMX_arch,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(11, 1, ARMBuildAttrs::WMMX_arch,
+                            ARMBuildAttrs::AllowWMMXv1));
+  EXPECT_TRUE(testBuildAttr(11, 2, ARMBuildAttrs::WMMX_arch,
+                            ARMBuildAttrs::AllowWMMXv2));
+}
+
+TEST(SIMDBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(12, "Tag_Advanced_SIMD_arch"));
+  EXPECT_TRUE(testBuildAttr(12, 0, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(12, 1, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeon));
+  EXPECT_TRUE(testBuildAttr(12, 2, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeon2));
+  EXPECT_TRUE(testBuildAttr(12, 3, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeonARMv8));
+  EXPECT_TRUE(testBuildAttr(12, 4, ARMBuildAttrs::Advanced_SIMD_arch,
+                            ARMBuildAttrs::AllowNeonARMv8_1a));
+}
+
+TEST(FPHPBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(36, "Tag_FP_HP_extension"));
+  EXPECT_TRUE(testBuildAttr(36, 0, ARMBuildAttrs::FP_HP_extension,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(36, 1, ARMBuildAttrs::FP_HP_extension,
+                            ARMBuildAttrs::AllowHPFP));
+}
+
+TEST(CPUAlignBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(34, "Tag_CPU_unaligned_access"));
+  EXPECT_TRUE(testBuildAttr(34, 0, ARMBuildAttrs::CPU_unaligned_access,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(34, 1, ARMBuildAttrs::CPU_unaligned_access,
+                            ARMBuildAttrs::Allowed));
+}
+
+TEST(T2EEBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(66, "Tag_T2EE_use"));
+  EXPECT_TRUE(testBuildAttr(66, 0, ARMBuildAttrs::T2EE_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(66, 1, ARMBuildAttrs::T2EE_use,
+                            ARMBuildAttrs::Allowed));
+}
+
+TEST(VirtualizationBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(68, "Tag_Virtualization_use"));
+  EXPECT_TRUE(testBuildAttr(68, 0, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(68, 1, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::AllowTZ));
+  EXPECT_TRUE(testBuildAttr(68, 2, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::AllowVirtualization));
+  EXPECT_TRUE(testBuildAttr(68, 3, ARMBuildAttrs::Virtualization_use,
+                            ARMBuildAttrs::AllowTZVirtualization));
+}
+
+TEST(MPBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(42, "Tag_MPextension_use"));
+  EXPECT_TRUE(testBuildAttr(42, 0, ARMBuildAttrs::MPextension_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(42, 1, ARMBuildAttrs::MPextension_use,
+                            ARMBuildAttrs::AllowMP));
+}
+
+TEST(DivBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(44, "Tag_DIV_use"));
+  EXPECT_TRUE(testBuildAttr(44, 0, ARMBuildAttrs::DIV_use,
+                            ARMBuildAttrs::AllowDIVIfExists));
+  EXPECT_TRUE(testBuildAttr(44, 1, ARMBuildAttrs::DIV_use,
+                            ARMBuildAttrs::DisallowDIV));
+  EXPECT_TRUE(testBuildAttr(44, 2, ARMBuildAttrs::DIV_use,
+                            ARMBuildAttrs::AllowDIVExt));
+}
+
+TEST(PCS_ConfigBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(13, "Tag_PCS_config"));
+  EXPECT_TRUE(testBuildAttr(13, 0, ARMBuildAttrs::PCS_config, 0));
+  EXPECT_TRUE(testBuildAttr(13, 1, ARMBuildAttrs::PCS_config, 1));
+  EXPECT_TRUE(testBuildAttr(13, 2, ARMBuildAttrs::PCS_config, 2));
+  EXPECT_TRUE(testBuildAttr(13, 3, ARMBuildAttrs::PCS_config, 3));
+  EXPECT_TRUE(testBuildAttr(13, 4, ARMBuildAttrs::PCS_config, 4));
+  EXPECT_TRUE(testBuildAttr(13, 5, ARMBuildAttrs::PCS_config, 5));
+  EXPECT_TRUE(testBuildAttr(13, 6, ARMBuildAttrs::PCS_config, 6));
+  EXPECT_TRUE(testBuildAttr(13, 7, ARMBuildAttrs::PCS_config, 7));
+}
+
+TEST(PCS_R9BuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(14, "Tag_ABI_PCS_R9_use"));
+  EXPECT_TRUE(testBuildAttr(14, 0, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9IsGPR));
+  EXPECT_TRUE(testBuildAttr(14, 1, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9IsSB));
+  EXPECT_TRUE(testBuildAttr(14, 2, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9IsTLSPointer));
+  EXPECT_TRUE(testBuildAttr(14, 3, ARMBuildAttrs::ABI_PCS_R9_use,
+                            ARMBuildAttrs::R9Reserved));
+}
+
+TEST(PCS_RWBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(15, "Tag_ABI_PCS_RW_data"));
+  EXPECT_TRUE(testBuildAttr(15, 0, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(15, 1, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::AddressRWPCRel));
+  EXPECT_TRUE(testBuildAttr(15, 2, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::AddressRWSBRel));
+  EXPECT_TRUE(testBuildAttr(15, 3, ARMBuildAttrs::ABI_PCS_RW_data,
+                            ARMBuildAttrs::AddressRWNone));
+}
+
+TEST(PCS_ROBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(16, "Tag_ABI_PCS_RO_data"));
+  EXPECT_TRUE(testBuildAttr(16, 0, ARMBuildAttrs::ABI_PCS_RO_data,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(16, 1, ARMBuildAttrs::ABI_PCS_RO_data,
+                            ARMBuildAttrs::AddressROPCRel));
+  EXPECT_TRUE(testBuildAttr(16, 2, ARMBuildAttrs::ABI_PCS_RO_data,
+                            ARMBuildAttrs::AddressRONone));
+}
+
+TEST(PCS_GOTBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(17, "Tag_ABI_PCS_GOT_use"));
+  EXPECT_TRUE(testBuildAttr(17, 0, ARMBuildAttrs::ABI_PCS_GOT_use,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(17, 1, ARMBuildAttrs::ABI_PCS_GOT_use,
+                            ARMBuildAttrs::AddressDirect));
+  EXPECT_TRUE(testBuildAttr(17, 2, ARMBuildAttrs::ABI_PCS_GOT_use,
+                            ARMBuildAttrs::AddressGOT));
+}
+
+TEST(PCS_WCharBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(18, "Tag_ABI_PCS_wchar_t"));
+  EXPECT_TRUE(testBuildAttr(18, 0, ARMBuildAttrs::ABI_PCS_wchar_t,
+                            ARMBuildAttrs::WCharProhibited));
+  EXPECT_TRUE(testBuildAttr(18, 2, ARMBuildAttrs::ABI_PCS_wchar_t,
+                            ARMBuildAttrs::WCharWidth2Bytes));
+  EXPECT_TRUE(testBuildAttr(18, 4, ARMBuildAttrs::ABI_PCS_wchar_t,
+                            ARMBuildAttrs::WCharWidth4Bytes));
+}
+
+TEST(EnumSizeBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(26, "Tag_ABI_enum_size"));
+  EXPECT_TRUE(testBuildAttr(26, 0, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::EnumProhibited));
+  EXPECT_TRUE(testBuildAttr(26, 1, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::EnumSmallest));
+  EXPECT_TRUE(testBuildAttr(26, 2, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::Enum32Bit));
+  EXPECT_TRUE(testBuildAttr(26, 3, ARMBuildAttrs::ABI_enum_size,
+                            ARMBuildAttrs::Enum32BitABI));
+}
+
+TEST(AlignNeededBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(24, "Tag_ABI_align_needed"));
+  EXPECT_TRUE(testBuildAttr(24, 0, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(24, 1, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::Align8Byte));
+  EXPECT_TRUE(testBuildAttr(24, 2, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::Align4Byte));
+  EXPECT_TRUE(testBuildAttr(24, 3, ARMBuildAttrs::ABI_align_needed,
+                            ARMBuildAttrs::AlignReserved));
+}
+
+TEST(AlignPreservedBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(25, "Tag_ABI_align_preserved"));
+  EXPECT_TRUE(testBuildAttr(25, 0, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignNotPreserved));
+  EXPECT_TRUE(testBuildAttr(25, 1, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignPreserve8Byte));
+  EXPECT_TRUE(testBuildAttr(25, 2, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignPreserveAll));
+  EXPECT_TRUE(testBuildAttr(25, 3, ARMBuildAttrs::ABI_align_preserved,
+                            ARMBuildAttrs::AlignReserved));
+}
+
+TEST(FPRoundingBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(19, "Tag_ABI_FP_rounding"));
+  EXPECT_TRUE(testBuildAttr(19, 0, ARMBuildAttrs::ABI_FP_rounding, 0));
+  EXPECT_TRUE(testBuildAttr(19, 1, ARMBuildAttrs::ABI_FP_rounding, 1));
+}
+
+TEST(FPDenormalBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(20, "Tag_ABI_FP_denormal"));
+  EXPECT_TRUE(testBuildAttr(20, 0, ARMBuildAttrs::ABI_FP_denormal,
+                            ARMBuildAttrs::PositiveZero));
+  EXPECT_TRUE(testBuildAttr(20, 1, ARMBuildAttrs::ABI_FP_denormal,
+                            ARMBuildAttrs::IEEEDenormals));
+  EXPECT_TRUE(testBuildAttr(20, 2, ARMBuildAttrs::ABI_FP_denormal,
+                            ARMBuildAttrs::PreserveFPSign));
+}
+
+TEST(FPExceptionsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(21, "Tag_ABI_FP_exceptions"));
+  EXPECT_TRUE(testBuildAttr(21, 0, ARMBuildAttrs::ABI_FP_exceptions, 0));
+  EXPECT_TRUE(testBuildAttr(21, 1, ARMBuildAttrs::ABI_FP_exceptions, 1));
+}
+
+TEST(FPUserExceptionsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(22, "Tag_ABI_FP_user_exceptions"));
+  EXPECT_TRUE(testBuildAttr(22, 0, ARMBuildAttrs::ABI_FP_user_exceptions, 0));
+  EXPECT_TRUE(testBuildAttr(22, 1, ARMBuildAttrs::ABI_FP_user_exceptions, 1));
+}
+
+TEST(FPNumberModelBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(23, "Tag_ABI_FP_number_model"));
+  EXPECT_TRUE(testBuildAttr(23, 0, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(23, 1, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::AllowIEEENormal));
+  EXPECT_TRUE(testBuildAttr(23, 2, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::AllowRTABI));
+  EXPECT_TRUE(testBuildAttr(23, 3, ARMBuildAttrs::ABI_FP_number_model,
+                            ARMBuildAttrs::AllowIEEE754));
+}
+
+TEST(FP16BuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(38, "Tag_ABI_FP_16bit_format"));
+  EXPECT_TRUE(testBuildAttr(38, 0, ARMBuildAttrs::ABI_FP_16bit_format,
+                            ARMBuildAttrs::Not_Allowed));
+  EXPECT_TRUE(testBuildAttr(38, 1, ARMBuildAttrs::ABI_FP_16bit_format,
+                            ARMBuildAttrs::FP16FormatIEEE));
+  EXPECT_TRUE(testBuildAttr(38, 2, ARMBuildAttrs::ABI_FP_16bit_format,
+                            ARMBuildAttrs::FP16VFP3));
+}
+
+TEST(HardFPBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(27, "Tag_ABI_HardFP_use"));
+  EXPECT_TRUE(testBuildAttr(27, 0, ARMBuildAttrs::ABI_HardFP_use,
+                            ARMBuildAttrs::HardFPImplied));
+  EXPECT_TRUE(testBuildAttr(27, 1, ARMBuildAttrs::ABI_HardFP_use,
+                            ARMBuildAttrs::HardFPSinglePrecision));
+  EXPECT_TRUE(testBuildAttr(27, 2, ARMBuildAttrs::ABI_HardFP_use, 2));
+}
+
+TEST(VFPArgsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(28, "Tag_ABI_VFP_args"));
+  EXPECT_TRUE(testBuildAttr(28, 0, ARMBuildAttrs::ABI_VFP_args,
+                            ARMBuildAttrs::BaseAAPCS));
+  EXPECT_TRUE(testBuildAttr(28, 1, ARMBuildAttrs::ABI_VFP_args,
+                            ARMBuildAttrs::HardFPAAPCS));
+  EXPECT_TRUE(testBuildAttr(28, 2, ARMBuildAttrs::ABI_VFP_args, 2));
+  EXPECT_TRUE(testBuildAttr(28, 3, ARMBuildAttrs::ABI_VFP_args, 3));
+}
+
+TEST(WMMXArgsBuildAttr, testBuildAttr) {
+  EXPECT_TRUE(testTagString(29, "Tag_ABI_WMMX_args"));
+  EXPECT_TRUE(testBuildAttr(29, 0, ARMBuildAttrs::ABI_WMMX_args, 0));
+  EXPECT_TRUE(testBuildAttr(29, 1, ARMBuildAttrs::ABI_WMMX_args, 1));
+  EXPECT_TRUE(testBuildAttr(29, 2, ARMBuildAttrs::ABI_WMMX_args, 2));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
new file mode 100644
index 0000000..388ca11
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
@@ -0,0 +1,249 @@
+//=== - 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.
+//
+//===----------------------------------------------------------------------===//
+
+#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"
+
+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
+
+// 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.
+#pragma GCC diagnostic warning "-w"
+#endif
+
+// Define some fixed alignment types to use in these tests.
+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; };
+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 {
+  ~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 {
+  ~V7() override;
+};
+struct V8 : V5, virtual V6, V7 { double zz;
+  ~V8() override;
+};
+
+double S6::f() { return 0.0; }
+float D2::g() { return 0.0f; }
+V1::~V1() {}
+V2::~V2() {}
+V3::~V3() {}
+V4::~V4() {}
+V5::~V5() {}
+V6::~V6() {}
+V7::~V7() {}
+V8::~V8() {}
+
+template <typename M> struct T { M m; };
+
+TEST(AlignOfTest, BasicAlignedArray) {
+  EXPECT_LE(1u, alignof(AlignedCharArrayUnion<A1>));
+  EXPECT_LE(2u, alignof(AlignedCharArrayUnion<A2>));
+  EXPECT_LE(4u, alignof(AlignedCharArrayUnion<A4>));
+  EXPECT_LE(8u, alignof(AlignedCharArrayUnion<A8>));
+
+  EXPECT_LE(1u, sizeof(AlignedCharArrayUnion<A1>));
+  EXPECT_LE(2u, sizeof(AlignedCharArrayUnion<A2>));
+  EXPECT_LE(4u, sizeof(AlignedCharArrayUnion<A4>));
+  EXPECT_LE(8u, sizeof(AlignedCharArrayUnion<A8>));
+
+  EXPECT_EQ(1u, (alignof(AlignedCharArrayUnion<A1>)));
+  EXPECT_EQ(2u, (alignof(AlignedCharArrayUnion<A1, A2>)));
+  EXPECT_EQ(4u, (alignof(AlignedCharArrayUnion<A1, A2, A4>)));
+  EXPECT_EQ(8u, (alignof(AlignedCharArrayUnion<A1, A2, A4, A8>)));
+
+  EXPECT_EQ(1u, sizeof(AlignedCharArrayUnion<A1>));
+  EXPECT_EQ(2u, sizeof(AlignedCharArrayUnion<A1, A2>));
+  EXPECT_EQ(4u, sizeof(AlignedCharArrayUnion<A1, A2, A4>));
+  EXPECT_EQ(8u, sizeof(AlignedCharArrayUnion<A1, A2, A4, A8>));
+
+  EXPECT_EQ(1u, (alignof(AlignedCharArrayUnion<A1[1]>)));
+  EXPECT_EQ(2u, (alignof(AlignedCharArrayUnion<A1[2], A2[1]>)));
+  EXPECT_EQ(4u, (alignof(AlignedCharArrayUnion<A1[42], A2[55], A4[13]>)));
+  EXPECT_EQ(8u, (alignof(AlignedCharArrayUnion<A1[2], A2[1], A4, A8>)));
+
+  EXPECT_EQ(1u,  sizeof(AlignedCharArrayUnion<A1[1]>));
+  EXPECT_EQ(2u,  sizeof(AlignedCharArrayUnion<A1[2], A2[1]>));
+  EXPECT_EQ(4u,  sizeof(AlignedCharArrayUnion<A1[3], A2[2], A4>));
+  EXPECT_EQ(16u, sizeof(AlignedCharArrayUnion<A1, A2[3],
+                                              A4[3], A8>));
+
+  // 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(T<char>), alignof(AlignedCharArrayUnion<char>));
+  EXPECT_EQ(alignof(T<short>), alignof(AlignedCharArrayUnion<short>));
+  EXPECT_EQ(alignof(T<int>), alignof(AlignedCharArrayUnion<int>));
+  EXPECT_EQ(alignof(T<long>), alignof(AlignedCharArrayUnion<long>));
+  EXPECT_EQ(alignof(T<long long>), alignof(AlignedCharArrayUnion<long long>));
+  EXPECT_EQ(alignof(T<float>), alignof(AlignedCharArrayUnion<float>));
+  EXPECT_EQ(alignof(T<double>), alignof(AlignedCharArrayUnion<double>));
+  EXPECT_EQ(alignof(T<long double>),
+            alignof(AlignedCharArrayUnion<long double>));
+  EXPECT_EQ(alignof(T<void *>), alignof(AlignedCharArrayUnion<void *>));
+  EXPECT_EQ(alignof(T<int *>), alignof(AlignedCharArrayUnion<int *>));
+  EXPECT_EQ(alignof(T<double (*)(double)>),
+            alignof(AlignedCharArrayUnion<double (*)(double)>));
+  EXPECT_EQ(alignof(T<double (S6::*)()>),
+            alignof(AlignedCharArrayUnion<double (S6::*)()>));
+  EXPECT_EQ(alignof(S1), alignof(AlignedCharArrayUnion<S1>));
+  EXPECT_EQ(alignof(S2), alignof(AlignedCharArrayUnion<S2>));
+  EXPECT_EQ(alignof(S3), alignof(AlignedCharArrayUnion<S3>));
+  EXPECT_EQ(alignof(S4), alignof(AlignedCharArrayUnion<S4>));
+  EXPECT_EQ(alignof(S5), alignof(AlignedCharArrayUnion<S5>));
+  EXPECT_EQ(alignof(S6), alignof(AlignedCharArrayUnion<S6>));
+  EXPECT_EQ(alignof(D1), alignof(AlignedCharArrayUnion<D1>));
+  EXPECT_EQ(alignof(D2), alignof(AlignedCharArrayUnion<D2>));
+  EXPECT_EQ(alignof(D3), alignof(AlignedCharArrayUnion<D3>));
+  EXPECT_EQ(alignof(D4), alignof(AlignedCharArrayUnion<D4>));
+  EXPECT_EQ(alignof(D5), alignof(AlignedCharArrayUnion<D5>));
+  EXPECT_EQ(alignof(D6), alignof(AlignedCharArrayUnion<D6>));
+  EXPECT_EQ(alignof(D7), alignof(AlignedCharArrayUnion<D7>));
+  EXPECT_EQ(alignof(D8), alignof(AlignedCharArrayUnion<D8>));
+  EXPECT_EQ(alignof(D9), alignof(AlignedCharArrayUnion<D9>));
+  EXPECT_EQ(alignof(V1), alignof(AlignedCharArrayUnion<V1>));
+  EXPECT_EQ(alignof(V2), alignof(AlignedCharArrayUnion<V2>));
+  EXPECT_EQ(alignof(V3), alignof(AlignedCharArrayUnion<V3>));
+  EXPECT_EQ(alignof(V4), alignof(AlignedCharArrayUnion<V4>));
+  EXPECT_EQ(alignof(V5), alignof(AlignedCharArrayUnion<V5>));
+  EXPECT_EQ(alignof(V6), alignof(AlignedCharArrayUnion<V6>));
+  EXPECT_EQ(alignof(V7), alignof(AlignedCharArrayUnion<V7>));
+
+  // 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(AlignedCharArrayUnion<V8>));
+#endif
+
+  EXPECT_EQ(sizeof(char), sizeof(AlignedCharArrayUnion<char>));
+  EXPECT_EQ(sizeof(char[1]), sizeof(AlignedCharArrayUnion<char[1]>));
+  EXPECT_EQ(sizeof(char[2]), sizeof(AlignedCharArrayUnion<char[2]>));
+  EXPECT_EQ(sizeof(char[3]), sizeof(AlignedCharArrayUnion<char[3]>));
+  EXPECT_EQ(sizeof(char[4]), sizeof(AlignedCharArrayUnion<char[4]>));
+  EXPECT_EQ(sizeof(char[5]), sizeof(AlignedCharArrayUnion<char[5]>));
+  EXPECT_EQ(sizeof(char[8]), sizeof(AlignedCharArrayUnion<char[8]>));
+  EXPECT_EQ(sizeof(char[13]), sizeof(AlignedCharArrayUnion<char[13]>));
+  EXPECT_EQ(sizeof(char[16]), sizeof(AlignedCharArrayUnion<char[16]>));
+  EXPECT_EQ(sizeof(char[21]), sizeof(AlignedCharArrayUnion<char[21]>));
+  EXPECT_EQ(sizeof(char[32]), sizeof(AlignedCharArrayUnion<char[32]>));
+  EXPECT_EQ(sizeof(short), sizeof(AlignedCharArrayUnion<short>));
+  EXPECT_EQ(sizeof(int), sizeof(AlignedCharArrayUnion<int>));
+  EXPECT_EQ(sizeof(long), sizeof(AlignedCharArrayUnion<long>));
+  EXPECT_EQ(sizeof(long long),
+            sizeof(AlignedCharArrayUnion<long long>));
+  EXPECT_EQ(sizeof(float), sizeof(AlignedCharArrayUnion<float>));
+  EXPECT_EQ(sizeof(double), sizeof(AlignedCharArrayUnion<double>));
+  EXPECT_EQ(sizeof(long double),
+            sizeof(AlignedCharArrayUnion<long double>));
+  EXPECT_EQ(sizeof(void *), sizeof(AlignedCharArrayUnion<void *>));
+  EXPECT_EQ(sizeof(int *), sizeof(AlignedCharArrayUnion<int *>));
+  EXPECT_EQ(sizeof(double (*)(double)),
+            sizeof(AlignedCharArrayUnion<double (*)(double)>));
+  EXPECT_EQ(sizeof(double (S6::*)()),
+            sizeof(AlignedCharArrayUnion<double (S6::*)()>));
+  EXPECT_EQ(sizeof(S1), sizeof(AlignedCharArrayUnion<S1>));
+  EXPECT_EQ(sizeof(S2), sizeof(AlignedCharArrayUnion<S2>));
+  EXPECT_EQ(sizeof(S3), sizeof(AlignedCharArrayUnion<S3>));
+  EXPECT_EQ(sizeof(S4), sizeof(AlignedCharArrayUnion<S4>));
+  EXPECT_EQ(sizeof(S5), sizeof(AlignedCharArrayUnion<S5>));
+  EXPECT_EQ(sizeof(S6), sizeof(AlignedCharArrayUnion<S6>));
+  EXPECT_EQ(sizeof(D1), sizeof(AlignedCharArrayUnion<D1>));
+  EXPECT_EQ(sizeof(D2), sizeof(AlignedCharArrayUnion<D2>));
+  EXPECT_EQ(sizeof(D3), sizeof(AlignedCharArrayUnion<D3>));
+  EXPECT_EQ(sizeof(D4), sizeof(AlignedCharArrayUnion<D4>));
+  EXPECT_EQ(sizeof(D5), sizeof(AlignedCharArrayUnion<D5>));
+  EXPECT_EQ(sizeof(D6), sizeof(AlignedCharArrayUnion<D6>));
+  EXPECT_EQ(sizeof(D7), sizeof(AlignedCharArrayUnion<D7>));
+  EXPECT_EQ(sizeof(D8), sizeof(AlignedCharArrayUnion<D8>));
+  EXPECT_EQ(sizeof(D9), sizeof(AlignedCharArrayUnion<D9>));
+  EXPECT_EQ(sizeof(D9[1]), sizeof(AlignedCharArrayUnion<D9[1]>));
+  EXPECT_EQ(sizeof(D9[2]), sizeof(AlignedCharArrayUnion<D9[2]>));
+  EXPECT_EQ(sizeof(D9[3]), sizeof(AlignedCharArrayUnion<D9[3]>));
+  EXPECT_EQ(sizeof(D9[4]), sizeof(AlignedCharArrayUnion<D9[4]>));
+  EXPECT_EQ(sizeof(D9[5]), sizeof(AlignedCharArrayUnion<D9[5]>));
+  EXPECT_EQ(sizeof(D9[8]), sizeof(AlignedCharArrayUnion<D9[8]>));
+  EXPECT_EQ(sizeof(D9[13]), sizeof(AlignedCharArrayUnion<D9[13]>));
+  EXPECT_EQ(sizeof(D9[16]), sizeof(AlignedCharArrayUnion<D9[16]>));
+  EXPECT_EQ(sizeof(D9[21]), sizeof(AlignedCharArrayUnion<D9[21]>));
+  EXPECT_EQ(sizeof(D9[32]), sizeof(AlignedCharArrayUnion<D9[32]>));
+  EXPECT_EQ(sizeof(V1), sizeof(AlignedCharArrayUnion<V1>));
+  EXPECT_EQ(sizeof(V2), sizeof(AlignedCharArrayUnion<V2>));
+  EXPECT_EQ(sizeof(V3), sizeof(AlignedCharArrayUnion<V3>));
+  EXPECT_EQ(sizeof(V4), sizeof(AlignedCharArrayUnion<V4>));
+  EXPECT_EQ(sizeof(V5), sizeof(AlignedCharArrayUnion<V5>));
+  EXPECT_EQ(sizeof(V6), sizeof(AlignedCharArrayUnion<V6>));
+  EXPECT_EQ(sizeof(V7), sizeof(AlignedCharArrayUnion<V7>));
+
+  // 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(AlignedCharArrayUnion<V8>));
+#endif
+
+  EXPECT_EQ(1u, (alignof(AlignedCharArray<1, 1>)));
+  EXPECT_EQ(2u, (alignof(AlignedCharArray<2, 1>)));
+  EXPECT_EQ(4u, (alignof(AlignedCharArray<4, 1>)));
+  EXPECT_EQ(8u, (alignof(AlignedCharArray<8, 1>)));
+  EXPECT_EQ(16u, (alignof(AlignedCharArray<16, 1>)));
+
+  EXPECT_EQ(1u, sizeof(AlignedCharArray<1, 1>));
+  EXPECT_EQ(7u, sizeof(AlignedCharArray<1, 7>));
+  EXPECT_EQ(2u, sizeof(AlignedCharArray<2, 2>));
+  EXPECT_EQ(16u, sizeof(AlignedCharArray<2, 16>));
+}
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
new file mode 100644
index 0000000..74b394f
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
@@ -0,0 +1,188 @@
+//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator 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/Allocator.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+using namespace llvm;
+
+namespace {
+
+TEST(AllocatorTest, Basics) {
+  BumpPtrAllocator Alloc;
+  int *a = (int*)Alloc.Allocate(sizeof(int), alignof(int));
+  int *b = (int*)Alloc.Allocate(sizeof(int) * 10, alignof(int));
+  int *c = (int*)Alloc.Allocate(sizeof(int), alignof(int));
+  *a = 1;
+  b[0] = 2;
+  b[9] = 2;
+  *c = 3;
+  EXPECT_EQ(1, *a);
+  EXPECT_EQ(2, b[0]);
+  EXPECT_EQ(2, b[9]);
+  EXPECT_EQ(3, *c);
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+
+  BumpPtrAllocator Alloc2 = std::move(Alloc);
+  EXPECT_EQ(0U, Alloc.GetNumSlabs());
+  EXPECT_EQ(1U, Alloc2.GetNumSlabs());
+
+  // Make sure the old pointers still work. These are especially interesting
+  // under ASan or Valgrind.
+  EXPECT_EQ(1, *a);
+  EXPECT_EQ(2, b[0]);
+  EXPECT_EQ(2, b[9]);
+  EXPECT_EQ(3, *c);
+
+  Alloc = std::move(Alloc2);
+  EXPECT_EQ(0U, Alloc2.GetNumSlabs());
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+}
+
+// Allocate enough bytes to create three slabs.
+TEST(AllocatorTest, ThreeSlabs) {
+  BumpPtrAllocator Alloc;
+  Alloc.Allocate(3000, 1);
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+  Alloc.Allocate(3000, 1);
+  EXPECT_EQ(2U, Alloc.GetNumSlabs());
+  Alloc.Allocate(3000, 1);
+  EXPECT_EQ(3U, Alloc.GetNumSlabs());
+}
+
+// Allocate enough bytes to create two slabs, reset the allocator, and do it
+// 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);
+  EXPECT_EQ(2U, Alloc.GetNumSlabs());
+  Alloc.Reset();
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+  Alloc.Allocate(3000, 1);
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+  Alloc.Allocate(3000, 1);
+  EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Test some allocations at varying alignments.
+TEST(AllocatorTest, TestAlignment) {
+  BumpPtrAllocator Alloc;
+  uintptr_t a;
+  a = (uintptr_t)Alloc.Allocate(1, 2);
+  EXPECT_EQ(0U, a & 1);
+  a = (uintptr_t)Alloc.Allocate(1, 4);
+  EXPECT_EQ(0U, a & 3);
+  a = (uintptr_t)Alloc.Allocate(1, 8);
+  EXPECT_EQ(0U, a & 7);
+  a = (uintptr_t)Alloc.Allocate(1, 16);
+  EXPECT_EQ(0U, a & 15);
+  a = (uintptr_t)Alloc.Allocate(1, 32);
+  EXPECT_EQ(0U, a & 31);
+  a = (uintptr_t)Alloc.Allocate(1, 64);
+  EXPECT_EQ(0U, a & 63);
+  a = (uintptr_t)Alloc.Allocate(1, 128);
+  EXPECT_EQ(0U, a & 127);
+}
+
+// Test allocating just over the slab size.  This tests a bug where before the
+// allocator incorrectly calculated the buffer end pointer.
+TEST(AllocatorTest, TestOverflow) {
+  BumpPtrAllocator Alloc;
+
+  // Fill the slab right up until the end pointer.
+  Alloc.Allocate(4096, 1);
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+
+  // If we don't allocate a new slab, then we will have overflowed.
+  Alloc.Allocate(1, 1);
+  EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Test allocating with a size larger than the initial slab size.
+TEST(AllocatorTest, TestSmallSlabSize) {
+  BumpPtrAllocator Alloc;
+
+  Alloc.Allocate(8000, 1);
+  EXPECT_EQ(1U, Alloc.GetNumSlabs());
+}
+
+// Test requesting alignment that goes past the end of the current slab.
+TEST(AllocatorTest, TestAlignmentPastSlab) {
+  BumpPtrAllocator Alloc;
+  Alloc.Allocate(4095, 1);
+
+  // Aligning the current slab pointer is likely to move it past the end of the
+  // slab, which would confuse any unsigned comparisons with the difference of
+  // the end pointer and the aligned pointer.
+  Alloc.Allocate(1024, 8192);
+
+  EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Mock slab allocator that returns slabs aligned on 4096 bytes.  There is no
+// easy portable way to do this, so this is kind of a hack.
+class MockSlabAllocator {
+  static size_t LastSlabSize;
+
+public:
+  ~MockSlabAllocator() { }
+
+  void *Allocate(size_t Size, size_t /*Alignment*/) {
+    // Allocate space for the alignment, the slab, and a void* that goes right
+    // before the slab.
+    size_t Alignment = 4096;
+    void *MemBase = safe_malloc(Size + Alignment - 1 + sizeof(void*));
+
+    // Find the slab start.
+    void *Slab = (void *)alignAddr((char*)MemBase + sizeof(void *), Alignment);
+
+    // Hold a pointer to the base so we can free the whole malloced block.
+    ((void**)Slab)[-1] = MemBase;
+
+    LastSlabSize = Size;
+    return Slab;
+  }
+
+  void Deallocate(void *Slab, size_t Size) {
+    free(((void**)Slab)[-1]);
+  }
+
+  static size_t GetLastSlabSize() { return LastSlabSize; }
+};
+
+size_t MockSlabAllocator::LastSlabSize = 0;
+
+// Allocate a large-ish block with a really large alignment so that the
+// allocator will think that it has space, but after it does the alignment it
+// will not.
+TEST(AllocatorTest, TestBigAlignment) {
+  BumpPtrAllocatorImpl<MockSlabAllocator> Alloc;
+
+  // First allocate a tiny bit to ensure we have to re-align things.
+  (void)Alloc.Allocate(1, 1);
+
+  // Now the big chunk with a big alignment.
+  (void)Alloc.Allocate(3000, 2048);
+
+  // We test that the last slab size is not the default 4096 byte slab, but
+  // rather a custom sized slab that is larger.
+  EXPECT_GT(MockSlabAllocator::GetLastSlabSize(), 4096u);
+}
+
+}  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp b/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
new file mode 100644
index 0000000..1ff97ba
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ArrayRecyclerTest.cpp
@@ -0,0 +1,109 @@
+//===--- unittest/Support/ArrayRecyclerTest.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/ArrayRecycler.h"
+#include "llvm/Support/Allocator.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+using namespace llvm;
+
+namespace {
+
+struct Object {
+  int Num;
+  Object *Other;
+};
+typedef ArrayRecycler<Object> ARO;
+
+TEST(ArrayRecyclerTest, Capacity) {
+  // Capacity size should never be 0.
+  ARO::Capacity Cap = ARO::Capacity::get(0);
+  EXPECT_LT(0u, Cap.getSize());
+
+  size_t PrevSize = Cap.getSize();
+  for (unsigned N = 1; N != 100; ++N) {
+    Cap = ARO::Capacity::get(N);
+    EXPECT_LE(N, Cap.getSize());
+    if (PrevSize >= N)
+      EXPECT_EQ(PrevSize, Cap.getSize());
+    else
+      EXPECT_LT(PrevSize, Cap.getSize());
+    PrevSize = Cap.getSize();
+  }
+
+  // Check that the buckets are monotonically increasing.
+  Cap = ARO::Capacity::get(0);
+  PrevSize = Cap.getSize();
+  for (unsigned N = 0; N != 20; ++N) {
+    Cap = Cap.getNext();
+    EXPECT_LT(PrevSize, Cap.getSize());
+    PrevSize = Cap.getSize();
+  }
+}
+
+TEST(ArrayRecyclerTest, Basics) {
+  BumpPtrAllocator Allocator;
+  ArrayRecycler<Object> DUT;
+
+  ARO::Capacity Cap = ARO::Capacity::get(8);
+  Object *A1 = DUT.allocate(Cap, Allocator);
+  A1[0].Num = 21;
+  A1[7].Num = 17;
+
+  Object *A2 = DUT.allocate(Cap, Allocator);
+  A2[0].Num = 121;
+  A2[7].Num = 117;
+
+  Object *A3 = DUT.allocate(Cap, Allocator);
+  A3[0].Num = 221;
+  A3[7].Num = 217;
+
+  EXPECT_EQ(21, A1[0].Num);
+  EXPECT_EQ(17, A1[7].Num);
+  EXPECT_EQ(121, A2[0].Num);
+  EXPECT_EQ(117, A2[7].Num);
+  EXPECT_EQ(221, A3[0].Num);
+  EXPECT_EQ(217, A3[7].Num);
+
+  DUT.deallocate(Cap, A2);
+
+  // Check that deallocation didn't clobber anything.
+  EXPECT_EQ(21, A1[0].Num);
+  EXPECT_EQ(17, A1[7].Num);
+  EXPECT_EQ(221, A3[0].Num);
+  EXPECT_EQ(217, A3[7].Num);
+
+  // Verify recycling.
+  Object *A2x = DUT.allocate(Cap, Allocator);
+  EXPECT_EQ(A2, A2x);
+
+  DUT.deallocate(Cap, A2x);
+  DUT.deallocate(Cap, A1);
+  DUT.deallocate(Cap, A3);
+
+  // Objects are not required to be recycled in reverse deallocation order, but
+  // that is what the current implementation does.
+  Object *A3x = DUT.allocate(Cap, Allocator);
+  EXPECT_EQ(A3, A3x);
+  Object *A1x = DUT.allocate(Cap, Allocator);
+  EXPECT_EQ(A1, A1x);
+  Object *A2y = DUT.allocate(Cap, Allocator);
+  EXPECT_EQ(A2, A2y);
+
+  // Back to allocation from the BumpPtrAllocator.
+  Object *A4 = DUT.allocate(Cap, Allocator);
+  EXPECT_NE(A1, A4);
+  EXPECT_NE(A2, A4);
+  EXPECT_NE(A3, A4);
+
+  DUT.clear(Allocator);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
new file mode 100644
index 0000000..35a010e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
@@ -0,0 +1,836 @@
+//===- llvm/unittest/Support/BinaryStreamTest.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/BinaryByteStream.h"
+#include "llvm/Support/BinaryItemStream.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gtest/gtest.h"
+
+
+using namespace llvm;
+using namespace llvm::support;
+
+namespace {
+
+class BrokenStream : public WritableBinaryStream {
+public:
+  BrokenStream(MutableArrayRef<uint8_t> Data, endianness Endian,
+                      uint32_t Align)
+      : Data(Data), PartitionIndex(alignDown(Data.size() / 2, Align)),
+        Endian(Endian) {}
+
+  endianness getEndian() const override { return Endian; }
+
+  Error readBytes(uint32_t Offset, uint32_t Size,
+                  ArrayRef<uint8_t> &Buffer) override {
+    if (auto EC = checkOffsetForRead(Offset, Size))
+      return EC;
+    uint32_t S = startIndex(Offset);
+    auto Ref = Data.drop_front(S);
+    if (Ref.size() >= Size) {
+      Buffer = Ref.take_front(Size);
+      return Error::success();
+    }
+
+    uint32_t BytesLeft = Size - Ref.size();
+    uint8_t *Ptr = Allocator.Allocate<uint8_t>(Size);
+    ::memcpy(Ptr, Ref.data(), Ref.size());
+    ::memcpy(Ptr + Ref.size(), Data.data(), BytesLeft);
+    Buffer = makeArrayRef<uint8_t>(Ptr, Size);
+    return Error::success();
+  }
+
+  Error readLongestContiguousChunk(uint32_t Offset,
+                                   ArrayRef<uint8_t> &Buffer) override {
+    if (auto EC = checkOffsetForRead(Offset, 1))
+      return EC;
+    uint32_t S = startIndex(Offset);
+    Buffer = Data.drop_front(S);
+    return Error::success();
+  }
+
+  uint32_t getLength() override { return Data.size(); }
+
+  Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> SrcData) override {
+    if (auto EC = checkOffsetForWrite(Offset, SrcData.size()))
+      return EC;
+    if (SrcData.empty())
+      return Error::success();
+
+    uint32_t S = startIndex(Offset);
+    MutableArrayRef<uint8_t> Ref(Data);
+    Ref = Ref.drop_front(S);
+    if (Ref.size() >= SrcData.size()) {
+      ::memcpy(Ref.data(), SrcData.data(), SrcData.size());
+      return Error::success();
+    }
+
+    uint32_t BytesLeft = SrcData.size() - Ref.size();
+    ::memcpy(Ref.data(), SrcData.data(), Ref.size());
+    ::memcpy(&Data[0], SrcData.data() + Ref.size(), BytesLeft);
+    return Error::success();
+  }
+  Error commit() override { return Error::success(); }
+
+private:
+  uint32_t startIndex(uint32_t Offset) const {
+    return (Offset + PartitionIndex) % Data.size();
+  }
+
+  uint32_t endIndex(uint32_t Offset, uint32_t Size) const {
+    return (startIndex(Offset) + Size - 1) % Data.size();
+  }
+
+  // Buffer is organized like this:
+  // -------------------------------------------------
+  // | N/2 | N/2+1 | ... | N-1 | 0 | 1 | ... | N/2-1 |
+  // -------------------------------------------------
+  // So reads from the beginning actually come from the middle.
+  MutableArrayRef<uint8_t> Data;
+  uint32_t PartitionIndex = 0;
+  endianness Endian;
+  BumpPtrAllocator Allocator;
+};
+
+constexpr endianness Endians[] = {big, little, native};
+constexpr uint32_t NumEndians = llvm::array_lengthof(Endians);
+constexpr uint32_t NumStreams = 2 * NumEndians;
+
+class BinaryStreamTest : public testing::Test {
+
+public:
+  BinaryStreamTest() {}
+
+  void SetUp() override {
+    Streams.clear();
+    Streams.resize(NumStreams);
+    for (uint32_t I = 0; I < NumStreams; ++I)
+      Streams[I].IsContiguous = (I % 2 == 0);
+
+    InputData.clear();
+    OutputData.clear();
+  }
+
+protected:
+  struct StreamPair {
+    bool IsContiguous;
+    std::unique_ptr<BinaryStream> Input;
+    std::unique_ptr<WritableBinaryStream> Output;
+  };
+
+  void initializeInput(ArrayRef<uint8_t> Input, uint32_t Align) {
+    InputData = Input;
+
+    BrokenInputData.resize(InputData.size());
+    if (!Input.empty()) {
+      uint32_t PartitionIndex = alignDown(InputData.size() / 2, Align);
+      uint32_t RightBytes = InputData.size() - PartitionIndex;
+      uint32_t LeftBytes = PartitionIndex;
+      if (RightBytes > 0)
+        ::memcpy(&BrokenInputData[PartitionIndex], Input.data(), RightBytes);
+      if (LeftBytes > 0)
+        ::memcpy(&BrokenInputData[0], Input.data() + RightBytes, LeftBytes);
+    }
+
+    for (uint32_t I = 0; I < NumEndians; ++I) {
+      auto InByteStream =
+          llvm::make_unique<BinaryByteStream>(InputData, Endians[I]);
+      auto InBrokenStream = llvm::make_unique<BrokenStream>(
+          BrokenInputData, Endians[I], Align);
+
+      Streams[I * 2].Input = std::move(InByteStream);
+      Streams[I * 2 + 1].Input = std::move(InBrokenStream);
+    }
+  }
+
+  void initializeOutput(uint32_t Size, uint32_t Align) {
+    OutputData.resize(Size);
+    BrokenOutputData.resize(Size);
+
+    for (uint32_t I = 0; I < NumEndians; ++I) {
+      Streams[I * 2].Output =
+          llvm::make_unique<MutableBinaryByteStream>(OutputData, Endians[I]);
+      Streams[I * 2 + 1].Output = llvm::make_unique<BrokenStream>(
+          BrokenOutputData, Endians[I], Align);
+    }
+  }
+
+  void initializeOutputFromInput(uint32_t Align) {
+    for (uint32_t I = 0; I < NumEndians; ++I) {
+      Streams[I * 2].Output =
+          llvm::make_unique<MutableBinaryByteStream>(InputData, Endians[I]);
+      Streams[I * 2 + 1].Output = llvm::make_unique<BrokenStream>(
+          BrokenInputData, Endians[I], Align);
+    }
+  }
+
+  void initializeInputFromOutput(uint32_t Align) {
+    for (uint32_t I = 0; I < NumEndians; ++I) {
+      Streams[I * 2].Input =
+          llvm::make_unique<BinaryByteStream>(OutputData, Endians[I]);
+      Streams[I * 2 + 1].Input = llvm::make_unique<BrokenStream>(
+          BrokenOutputData, Endians[I], Align);
+    }
+  }
+
+  std::vector<uint8_t> InputData;
+  std::vector<uint8_t> BrokenInputData;
+
+  std::vector<uint8_t> OutputData;
+  std::vector<uint8_t> BrokenOutputData;
+
+  std::vector<StreamPair> Streams;
+};
+
+// Tests that a we can read from a BinaryByteStream without a StreamReader.
+TEST_F(BinaryStreamTest, BinaryByteStreamBounds) {
+  std::vector<uint8_t> InputData = {1, 2, 3, 4, 5};
+  initializeInput(InputData, 1);
+
+  for (auto &Stream : Streams) {
+    ArrayRef<uint8_t> Buffer;
+
+    // 1. If the read fits it should work.
+    ASSERT_EQ(InputData.size(), Stream.Input->getLength());
+    ASSERT_THAT_ERROR(Stream.Input->readBytes(2, 1, Buffer), Succeeded());
+    EXPECT_EQ(makeArrayRef(InputData).slice(2, 1), Buffer);
+    ASSERT_THAT_ERROR(Stream.Input->readBytes(0, 4, Buffer), Succeeded());
+    EXPECT_EQ(makeArrayRef(InputData).slice(0, 4), Buffer);
+
+    // 2. Reading past the bounds of the input should fail.
+    EXPECT_THAT_ERROR(Stream.Input->readBytes(4, 2, Buffer), Failed());
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamRefBounds) {
+  std::vector<uint8_t> InputData = {1, 2, 3, 4, 5};
+  initializeInput(InputData, 1);
+
+  for (const auto &Stream : Streams) {
+    ArrayRef<uint8_t> Buffer;
+    BinaryStreamRef Ref(*Stream.Input);
+
+    // Read 1 byte from offset 2 should work
+    ASSERT_EQ(InputData.size(), Ref.getLength());
+    ASSERT_THAT_ERROR(Ref.readBytes(2, 1, Buffer), Succeeded());
+    EXPECT_EQ(makeArrayRef(InputData).slice(2, 1), Buffer);
+
+    // Reading everything from offset 2 on.
+    ASSERT_THAT_ERROR(Ref.readLongestContiguousChunk(2, Buffer), Succeeded());
+    if (Stream.IsContiguous)
+      EXPECT_EQ(makeArrayRef(InputData).slice(2), Buffer);
+    else
+      EXPECT_FALSE(Buffer.empty());
+
+    // Reading 6 bytes from offset 0 is too big.
+    EXPECT_THAT_ERROR(Ref.readBytes(0, 6, Buffer), Failed());
+    EXPECT_THAT_ERROR(Ref.readLongestContiguousChunk(6, Buffer), Failed());
+
+    // Reading 1 byte from offset 2 after dropping 1 byte is the same as reading
+    // 1 byte from offset 3.
+    Ref = Ref.drop_front(1);
+    ASSERT_THAT_ERROR(Ref.readBytes(2, 1, Buffer), Succeeded());
+    if (Stream.IsContiguous)
+      EXPECT_EQ(makeArrayRef(InputData).slice(3, 1), Buffer);
+    else
+      EXPECT_FALSE(Buffer.empty());
+
+    // Reading everything from offset 2 on after dropping 1 byte.
+    ASSERT_THAT_ERROR(Ref.readLongestContiguousChunk(2, Buffer), Succeeded());
+    if (Stream.IsContiguous)
+      EXPECT_EQ(makeArrayRef(InputData).slice(3), Buffer);
+    else
+      EXPECT_FALSE(Buffer.empty());
+
+    // Reading 2 bytes from offset 2 after dropping 2 bytes is the same as
+    // reading 2 bytes from offset 4, and should fail.
+    Ref = Ref.drop_front(1);
+    EXPECT_THAT_ERROR(Ref.readBytes(2, 2, Buffer), Failed());
+
+    // But if we read the longest contiguous chunk instead, we should still
+    // get the 1 byte at the end.
+    ASSERT_THAT_ERROR(Ref.readLongestContiguousChunk(2, Buffer), Succeeded());
+    EXPECT_EQ(makeArrayRef(InputData).take_back(), Buffer);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamRefDynamicSize) {
+  StringRef Strings[] = {"1", "2", "3", "4"};
+  AppendingBinaryByteStream Stream(support::little);
+
+  BinaryStreamWriter Writer(Stream);
+  BinaryStreamReader Reader(Stream);
+  const uint8_t *Byte;
+  StringRef Str;
+
+  // When the stream is empty, it should report a 0 length and we should get an
+  // error trying to read even 1 byte from it.
+  BinaryStreamRef ConstRef(Stream);
+  EXPECT_EQ(0U, ConstRef.getLength());
+  EXPECT_THAT_ERROR(Reader.readObject(Byte), Failed());
+
+  // But if we write to it, its size should increase and we should be able to
+  // read not just a byte, but the string that was written.
+  EXPECT_THAT_ERROR(Writer.writeCString(Strings[0]), Succeeded());
+  EXPECT_EQ(2U, ConstRef.getLength());
+  EXPECT_THAT_ERROR(Reader.readObject(Byte), Succeeded());
+
+  Reader.setOffset(0);
+  EXPECT_THAT_ERROR(Reader.readCString(Str), Succeeded());
+  EXPECT_EQ(Str, Strings[0]);
+
+  // If we drop some bytes from the front, we should still track the length as
+  // the
+  // underlying stream grows.
+  BinaryStreamRef Dropped = ConstRef.drop_front(1);
+  EXPECT_EQ(1U, Dropped.getLength());
+
+  EXPECT_THAT_ERROR(Writer.writeCString(Strings[1]), Succeeded());
+  EXPECT_EQ(4U, ConstRef.getLength());
+  EXPECT_EQ(3U, Dropped.getLength());
+
+  // If we drop zero bytes from the back, we should continue tracking the
+  // length.
+  Dropped = Dropped.drop_back(0);
+  EXPECT_THAT_ERROR(Writer.writeCString(Strings[2]), Succeeded());
+  EXPECT_EQ(6U, ConstRef.getLength());
+  EXPECT_EQ(5U, Dropped.getLength());
+
+  // If we drop non-zero bytes from the back, we should stop tracking the
+  // length.
+  Dropped = Dropped.drop_back(1);
+  EXPECT_THAT_ERROR(Writer.writeCString(Strings[3]), Succeeded());
+  EXPECT_EQ(8U, ConstRef.getLength());
+  EXPECT_EQ(4U, Dropped.getLength());
+}
+
+TEST_F(BinaryStreamTest, DropOperations) {
+  std::vector<uint8_t> InputData = {1, 2, 3, 4, 5, 4, 3, 2, 1};
+  auto RefData = makeArrayRef(InputData);
+  initializeInput(InputData, 1);
+
+  ArrayRef<uint8_t> Result;
+  BinaryStreamRef Original(InputData, support::little);
+  ASSERT_EQ(InputData.size(), Original.getLength());
+
+  EXPECT_THAT_ERROR(Original.readBytes(0, InputData.size(), Result),
+                    Succeeded());
+  EXPECT_EQ(RefData, Result);
+
+  auto Dropped = Original.drop_front(2);
+  EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
+                    Succeeded());
+  EXPECT_EQ(RefData.drop_front(2), Result);
+
+  Dropped = Original.drop_back(2);
+  EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
+                    Succeeded());
+  EXPECT_EQ(RefData.drop_back(2), Result);
+
+  Dropped = Original.keep_front(2);
+  EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
+                    Succeeded());
+  EXPECT_EQ(RefData.take_front(2), Result);
+
+  Dropped = Original.keep_back(2);
+  EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
+                    Succeeded());
+  EXPECT_EQ(RefData.take_back(2), Result);
+
+  Dropped = Original.drop_symmetric(2);
+  EXPECT_THAT_ERROR(Dropped.readBytes(0, Dropped.getLength(), Result),
+                    Succeeded());
+  EXPECT_EQ(RefData.drop_front(2).drop_back(2), Result);
+}
+
+// Test that we can write to a BinaryStream without a StreamWriter.
+TEST_F(BinaryStreamTest, MutableBinaryByteStreamBounds) {
+  std::vector<uint8_t> InputData = {'T', 'e', 's', 't', '\0'};
+  initializeInput(InputData, 1);
+  initializeOutput(InputData.size(), 1);
+
+  // For every combination of input stream and output stream.
+  for (auto &Stream : Streams) {
+    ASSERT_EQ(InputData.size(), Stream.Input->getLength());
+
+    // 1. Try two reads that are supposed to work.  One from offset 0, and one
+    // from the middle.
+    uint32_t Offsets[] = {0, 3};
+    for (auto Offset : Offsets) {
+      uint32_t ExpectedSize = Stream.Input->getLength() - Offset;
+
+      // Read everything from Offset until the end of the input data.
+      ArrayRef<uint8_t> Data;
+      ASSERT_THAT_ERROR(Stream.Input->readBytes(Offset, ExpectedSize, Data),
+                        Succeeded());
+      ASSERT_EQ(ExpectedSize, Data.size());
+
+      // Then write it to the destination.
+      ASSERT_THAT_ERROR(Stream.Output->writeBytes(0, Data), Succeeded());
+
+      // Then we read back what we wrote, it should match the corresponding
+      // slice of the original input data.
+      ArrayRef<uint8_t> Data2;
+      ASSERT_THAT_ERROR(Stream.Output->readBytes(Offset, ExpectedSize, Data2),
+                        Succeeded());
+      EXPECT_EQ(makeArrayRef(InputData).drop_front(Offset), Data2);
+    }
+
+    std::vector<uint8_t> BigData = {0, 1, 2, 3, 4};
+    // 2. If the write is too big, it should fail.
+    EXPECT_THAT_ERROR(Stream.Output->writeBytes(3, BigData), Failed());
+  }
+}
+
+TEST_F(BinaryStreamTest, AppendingStream) {
+  AppendingBinaryByteStream Stream(llvm::support::little);
+  EXPECT_EQ(0U, Stream.getLength());
+
+  std::vector<uint8_t> InputData = {'T', 'e', 's', 't', 'T', 'e', 's', 't'};
+  auto Test = makeArrayRef(InputData).take_front(4);
+  // Writing past the end of the stream is an error.
+  EXPECT_THAT_ERROR(Stream.writeBytes(4, Test), Failed());
+
+  // Writing exactly at the end of the stream is ok.
+  EXPECT_THAT_ERROR(Stream.writeBytes(0, Test), Succeeded());
+  EXPECT_EQ(Test, Stream.data());
+
+  // And now that the end of the stream is where we couldn't write before, now
+  // we can write.
+  EXPECT_THAT_ERROR(Stream.writeBytes(4, Test), Succeeded());
+  EXPECT_EQ(MutableArrayRef<uint8_t>(InputData), Stream.data());
+}
+
+// Test that FixedStreamArray works correctly.
+TEST_F(BinaryStreamTest, FixedStreamArray) {
+  std::vector<uint32_t> Ints = {90823, 12908, 109823, 209823};
+  ArrayRef<uint8_t> IntBytes(reinterpret_cast<uint8_t *>(Ints.data()),
+                             Ints.size() * sizeof(uint32_t));
+
+  initializeInput(IntBytes, alignof(uint32_t));
+
+  for (auto &Stream : Streams) {
+    ASSERT_EQ(InputData.size(), Stream.Input->getLength());
+
+    FixedStreamArray<uint32_t> Array(*Stream.Input);
+    auto Iter = Array.begin();
+    ASSERT_EQ(Ints[0], *Iter++);
+    ASSERT_EQ(Ints[1], *Iter++);
+    ASSERT_EQ(Ints[2], *Iter++);
+    ASSERT_EQ(Ints[3], *Iter++);
+    ASSERT_EQ(Array.end(), Iter);
+  }
+}
+
+// Ensure FixedStreamArrayIterator::operator-> works.
+// Added for coverage of r302257.
+TEST_F(BinaryStreamTest, FixedStreamArrayIteratorArrow) {
+  std::vector<std::pair<uint32_t, uint32_t>> Pairs = {{867, 5309}, {555, 1212}};
+  ArrayRef<uint8_t> PairBytes(reinterpret_cast<uint8_t *>(Pairs.data()),
+    Pairs.size() * sizeof(Pairs[0]));
+
+  initializeInput(PairBytes, alignof(uint32_t));
+
+  for (auto &Stream : Streams) {
+    ASSERT_EQ(InputData.size(), Stream.Input->getLength());
+
+    const FixedStreamArray<std::pair<uint32_t, uint32_t>> Array(*Stream.Input);
+    auto Iter = Array.begin();
+    ASSERT_EQ(Pairs[0].first, Iter->first);
+    ASSERT_EQ(Pairs[0].second, Iter->second);
+    ++Iter;
+    ASSERT_EQ(Pairs[1].first, Iter->first);
+    ASSERT_EQ(Pairs[1].second, Iter->second);
+    ++Iter;
+    ASSERT_EQ(Array.end(), Iter);
+  }
+}
+
+// Test that VarStreamArray works correctly.
+TEST_F(BinaryStreamTest, VarStreamArray) {
+  StringLiteral Strings("1. Test2. Longer Test3. Really Long Test4. Super "
+                        "Extra Longest Test Of All");
+  ArrayRef<uint8_t> StringBytes(
+      reinterpret_cast<const uint8_t *>(Strings.data()), Strings.size());
+  initializeInput(StringBytes, 1);
+
+  struct StringExtractor {
+  public:
+    Error operator()(BinaryStreamRef Stream, uint32_t &Len, StringRef &Item) {
+      if (Index == 0)
+        Len = strlen("1. Test");
+      else if (Index == 1)
+        Len = strlen("2. Longer Test");
+      else if (Index == 2)
+        Len = strlen("3. Really Long Test");
+      else
+        Len = strlen("4. Super Extra Longest Test Of All");
+      ArrayRef<uint8_t> Bytes;
+      if (auto EC = Stream.readBytes(0, Len, Bytes))
+        return EC;
+      Item =
+          StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
+      ++Index;
+      return Error::success();
+    }
+
+    uint32_t Index = 0;
+  };
+
+  for (auto &Stream : Streams) {
+    VarStreamArray<StringRef, StringExtractor> Array(*Stream.Input);
+    auto Iter = Array.begin();
+    ASSERT_EQ("1. Test", *Iter++);
+    ASSERT_EQ("2. Longer Test", *Iter++);
+    ASSERT_EQ("3. Really Long Test", *Iter++);
+    ASSERT_EQ("4. Super Extra Longest Test Of All", *Iter++);
+    ASSERT_EQ(Array.end(), Iter);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderBounds) {
+  std::vector<uint8_t> Bytes;
+
+  initializeInput(Bytes, 1);
+  for (auto &Stream : Streams) {
+    StringRef S;
+    BinaryStreamReader Reader(*Stream.Input);
+    EXPECT_EQ(0U, Reader.bytesRemaining());
+    EXPECT_THAT_ERROR(Reader.readFixedString(S, 1), Failed());
+  }
+
+  Bytes.resize(5);
+  initializeInput(Bytes, 1);
+  for (auto &Stream : Streams) {
+    StringRef S;
+    BinaryStreamReader Reader(*Stream.Input);
+    EXPECT_EQ(Bytes.size(), Reader.bytesRemaining());
+    EXPECT_THAT_ERROR(Reader.readFixedString(S, 5), Succeeded());
+    EXPECT_THAT_ERROR(Reader.readFixedString(S, 6), Failed());
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderIntegers) {
+  support::ulittle64_t Little{908234};
+  support::ubig32_t Big{28907823};
+  short NS = 2897;
+  int NI = -89723;
+  unsigned long NUL = 902309023UL;
+  constexpr uint32_t Size =
+      sizeof(Little) + sizeof(Big) + sizeof(NS) + sizeof(NI) + sizeof(NUL);
+
+  initializeOutput(Size, alignof(support::ulittle64_t));
+  initializeInputFromOutput(alignof(support::ulittle64_t));
+
+  for (auto &Stream : Streams) {
+    BinaryStreamWriter Writer(*Stream.Output);
+    ASSERT_THAT_ERROR(Writer.writeObject(Little), Succeeded());
+    ASSERT_THAT_ERROR(Writer.writeObject(Big), Succeeded());
+    ASSERT_THAT_ERROR(Writer.writeInteger(NS), Succeeded());
+    ASSERT_THAT_ERROR(Writer.writeInteger(NI), Succeeded());
+    ASSERT_THAT_ERROR(Writer.writeInteger(NUL), Succeeded());
+
+    const support::ulittle64_t *Little2;
+    const support::ubig32_t *Big2;
+    short NS2;
+    int NI2;
+    unsigned long NUL2;
+
+    // 1. Reading fields individually.
+    BinaryStreamReader Reader(*Stream.Input);
+    ASSERT_THAT_ERROR(Reader.readObject(Little2), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readObject(Big2), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readInteger(NS2), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readInteger(NI2), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readInteger(NUL2), Succeeded());
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ(Little, *Little2);
+    EXPECT_EQ(Big, *Big2);
+    EXPECT_EQ(NS, NS2);
+    EXPECT_EQ(NI, NI2);
+    EXPECT_EQ(NUL, NUL2);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderIntegerArray) {
+  // 1. Arrays of integers
+  std::vector<int> Ints = {1, 2, 3, 4, 5};
+  ArrayRef<uint8_t> IntBytes(reinterpret_cast<uint8_t *>(&Ints[0]),
+                             Ints.size() * sizeof(int));
+
+  initializeInput(IntBytes, alignof(int));
+  for (auto &Stream : Streams) {
+    BinaryStreamReader Reader(*Stream.Input);
+    ArrayRef<int> IntsRef;
+    ASSERT_THAT_ERROR(Reader.readArray(IntsRef, Ints.size()), Succeeded());
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+    EXPECT_EQ(makeArrayRef(Ints), IntsRef);
+
+    Reader.setOffset(0);
+    FixedStreamArray<int> FixedIntsRef;
+    ASSERT_THAT_ERROR(Reader.readArray(FixedIntsRef, Ints.size()), Succeeded());
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+    ASSERT_EQ(Ints, std::vector<int>(FixedIntsRef.begin(), FixedIntsRef.end()));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderEnum) {
+  enum class MyEnum : int64_t { Foo = -10, Bar = 0, Baz = 10 };
+
+  std::vector<MyEnum> Enums = {MyEnum::Bar, MyEnum::Baz, MyEnum::Foo};
+
+  initializeOutput(Enums.size() * sizeof(MyEnum), alignof(MyEnum));
+  initializeInputFromOutput(alignof(MyEnum));
+  for (auto &Stream : Streams) {
+    BinaryStreamWriter Writer(*Stream.Output);
+    for (auto Value : Enums)
+      ASSERT_THAT_ERROR(Writer.writeEnum(Value), Succeeded());
+
+    BinaryStreamReader Reader(*Stream.Input);
+
+    FixedStreamArray<MyEnum> FSA;
+
+    for (size_t I = 0; I < Enums.size(); ++I) {
+      MyEnum Value;
+      ASSERT_THAT_ERROR(Reader.readEnum(Value), Succeeded());
+      EXPECT_EQ(Enums[I], Value);
+    }
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderObject) {
+  struct Foo {
+    int X;
+    double Y;
+    char Z;
+
+    bool operator==(const Foo &Other) const {
+      return X == Other.X && Y == Other.Y && Z == Other.Z;
+    }
+  };
+
+  std::vector<Foo> Foos;
+  Foos.push_back({-42, 42.42, 42});
+  Foos.push_back({100, 3.1415, static_cast<char>(-89)});
+  Foos.push_back({200, 2.718, static_cast<char>(-12) });
+
+  const uint8_t *Bytes = reinterpret_cast<const uint8_t *>(&Foos[0]);
+
+  initializeInput(makeArrayRef(Bytes, 3 * sizeof(Foo)), alignof(Foo));
+
+  for (auto &Stream : Streams) {
+    // 1. Reading object pointers.
+    BinaryStreamReader Reader(*Stream.Input);
+    const Foo *FPtrOut = nullptr;
+    const Foo *GPtrOut = nullptr;
+    const Foo *HPtrOut = nullptr;
+    ASSERT_THAT_ERROR(Reader.readObject(FPtrOut), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readObject(GPtrOut), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readObject(HPtrOut), Succeeded());
+    EXPECT_EQ(0U, Reader.bytesRemaining());
+    EXPECT_EQ(Foos[0], *FPtrOut);
+    EXPECT_EQ(Foos[1], *GPtrOut);
+    EXPECT_EQ(Foos[2], *HPtrOut);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamReaderStrings) {
+  std::vector<uint8_t> Bytes = {'O',  'n', 'e', '\0', 'T', 'w', 'o',
+                                '\0', 'T', 'h', 'r',  'e', 'e', '\0',
+                                'F',  'o', 'u', 'r',  '\0'};
+  initializeInput(Bytes, 1);
+
+  for (auto &Stream : Streams) {
+    BinaryStreamReader Reader(*Stream.Input);
+
+    StringRef S1;
+    StringRef S2;
+    StringRef S3;
+    StringRef S4;
+    ASSERT_THAT_ERROR(Reader.readCString(S1), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readCString(S2), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readCString(S3), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readCString(S4), Succeeded());
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ("One", S1);
+    EXPECT_EQ("Two", S2);
+    EXPECT_EQ("Three", S3);
+    EXPECT_EQ("Four", S4);
+
+    S1 = S2 = S3 = S4 = "";
+    Reader.setOffset(0);
+    ASSERT_THAT_ERROR(Reader.readFixedString(S1, 3), Succeeded());
+    ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readFixedString(S2, 3), Succeeded());
+    ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readFixedString(S3, 5), Succeeded());
+    ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
+    ASSERT_THAT_ERROR(Reader.readFixedString(S4, 4), Succeeded());
+    ASSERT_THAT_ERROR(Reader.skip(1), Succeeded());
+    ASSERT_EQ(0U, Reader.bytesRemaining());
+
+    EXPECT_EQ("One", S1);
+    EXPECT_EQ("Two", S2);
+    EXPECT_EQ("Three", S3);
+    EXPECT_EQ("Four", S4);
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterBounds) {
+  initializeOutput(5, 1);
+
+  for (auto &Stream : Streams) {
+    BinaryStreamWriter Writer(*Stream.Output);
+
+    // 1. Can write a string that exactly fills the buffer.
+    EXPECT_EQ(5U, Writer.bytesRemaining());
+    EXPECT_THAT_ERROR(Writer.writeFixedString("abcde"), Succeeded());
+    EXPECT_EQ(0U, Writer.bytesRemaining());
+
+    // 2. Can write an empty string even when you're full
+    EXPECT_THAT_ERROR(Writer.writeFixedString(""), Succeeded());
+    EXPECT_THAT_ERROR(Writer.writeFixedString("a"), Failed());
+
+    // 3. Can't write a string that is one character too long.
+    Writer.setOffset(0);
+    EXPECT_THAT_ERROR(Writer.writeFixedString("abcdef"), Failed());
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterIntegerArrays) {
+  // 3. Arrays of integers
+  std::vector<int> SourceInts = {1, 2, 3, 4, 5};
+  ArrayRef<uint8_t> SourceBytes(reinterpret_cast<uint8_t *>(&SourceInts[0]),
+                                SourceInts.size() * sizeof(int));
+
+  initializeInput(SourceBytes, alignof(int));
+  initializeOutputFromInput(alignof(int));
+
+  for (auto &Stream : Streams) {
+    BinaryStreamReader Reader(*Stream.Input);
+    BinaryStreamWriter Writer(*Stream.Output);
+    ArrayRef<int> Ints;
+    ArrayRef<int> Ints2;
+    // First read them, then write them, then read them back.
+    ASSERT_THAT_ERROR(Reader.readArray(Ints, SourceInts.size()), Succeeded());
+    ASSERT_THAT_ERROR(Writer.writeArray(Ints), Succeeded());
+
+    BinaryStreamReader ReaderBacker(*Stream.Output);
+    ASSERT_THAT_ERROR(ReaderBacker.readArray(Ints2, SourceInts.size()),
+                      Succeeded());
+
+    EXPECT_EQ(makeArrayRef(SourceInts), Ints2);
+  }
+}
+
+TEST_F(BinaryStreamTest, StringWriterStrings) {
+  StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
+
+  size_t Length = 0;
+  for (auto S : Strings)
+    Length += S.size() + 1;
+  initializeOutput(Length, 1);
+  initializeInputFromOutput(1);
+
+  for (auto &Stream : Streams) {
+    BinaryStreamWriter Writer(*Stream.Output);
+    for (auto S : Strings)
+      ASSERT_THAT_ERROR(Writer.writeCString(S), Succeeded());
+    std::vector<StringRef> InStrings;
+    BinaryStreamReader Reader(*Stream.Input);
+    while (!Reader.empty()) {
+      StringRef S;
+      ASSERT_THAT_ERROR(Reader.readCString(S), Succeeded());
+      InStrings.push_back(S);
+    }
+    EXPECT_EQ(makeArrayRef(Strings), makeArrayRef(InStrings));
+  }
+}
+
+TEST_F(BinaryStreamTest, StreamWriterAppend) {
+  StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
+  AppendingBinaryByteStream Stream(support::little);
+  BinaryStreamWriter Writer(Stream);
+
+  for (auto &Str : Strings) {
+    EXPECT_THAT_ERROR(Writer.writeCString(Str), Succeeded());
+  }
+
+  BinaryStreamReader Reader(Stream);
+  for (auto &Str : Strings) {
+    StringRef S;
+    EXPECT_THAT_ERROR(Reader.readCString(S), Succeeded());
+    EXPECT_EQ(Str, S);
+  }
+}
+}
+
+namespace {
+struct BinaryItemStreamObject {
+  explicit BinaryItemStreamObject(ArrayRef<uint8_t> Bytes) : Bytes(Bytes) {}
+
+  ArrayRef<uint8_t> Bytes;
+};
+}
+
+namespace llvm {
+template <> struct BinaryItemTraits<BinaryItemStreamObject> {
+  static size_t length(const BinaryItemStreamObject &Item) {
+    return Item.Bytes.size();
+  }
+
+  static ArrayRef<uint8_t> bytes(const BinaryItemStreamObject &Item) {
+    return Item.Bytes;
+  }
+};
+}
+
+namespace {
+
+TEST_F(BinaryStreamTest, BinaryItemStream) {
+  std::vector<BinaryItemStreamObject> Objects;
+
+  struct Foo {
+    int X;
+    double Y;
+  };
+  std::vector<Foo> Foos = {{1, 1.0}, {2, 2.0}, {3, 3.0}};
+  BumpPtrAllocator Allocator;
+  for (const auto &F : Foos) {
+    uint8_t *Ptr = static_cast<uint8_t *>(Allocator.Allocate(sizeof(Foo),
+                                                             alignof(Foo)));
+    MutableArrayRef<uint8_t> Buffer(Ptr, sizeof(Foo));
+    MutableBinaryByteStream Stream(Buffer, llvm::support::big);
+    BinaryStreamWriter Writer(Stream);
+    ASSERT_THAT_ERROR(Writer.writeObject(F), Succeeded());
+    Objects.push_back(BinaryItemStreamObject(Buffer));
+  }
+
+  BinaryItemStream<BinaryItemStreamObject> ItemStream(big);
+  ItemStream.setItems(Objects);
+  BinaryStreamReader Reader(ItemStream);
+
+  for (const auto &F : Foos) {
+    const Foo *F2;
+    ASSERT_THAT_ERROR(Reader.readObject(F2), Succeeded());
+
+    EXPECT_EQ(F.X, F2->X);
+    EXPECT_DOUBLE_EQ(F.Y, F2->Y);
+  }
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp b/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
new file mode 100644
index 0000000..c1f5671
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/BlockFrequencyTest.cpp
@@ -0,0 +1,128 @@
+//===- 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"
+#include "gtest/gtest.h"
+#include <climits>
+
+using namespace llvm;
+
+namespace {
+
+TEST(BlockFrequencyTest, OneToZero) {
+  BlockFrequency Freq(1);
+  BranchProbability Prob(UINT32_MAX / 3, UINT32_MAX);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 0u);
+
+  Freq = BlockFrequency(1);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 0u);
+}
+
+TEST(BlockFrequencyTest, OneToOne) {
+  BlockFrequency Freq(1);
+  BranchProbability Prob(UINT32_MAX, UINT32_MAX);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 1u);
+
+  Freq = BlockFrequency(1);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 1u);
+}
+
+TEST(BlockFrequencyTest, ThreeToOne) {
+  BlockFrequency Freq(3);
+  BranchProbability Prob(3000000, 9000000);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 1u);
+
+  Freq = BlockFrequency(3);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 1u);
+}
+
+TEST(BlockFrequencyTest, MaxToHalfMax) {
+  BlockFrequency Freq(UINT64_MAX);
+  BranchProbability Prob(UINT32_MAX / 2, UINT32_MAX);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 9223372036854775807ULL);
+
+  Freq = BlockFrequency(UINT64_MAX);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), 9223372036854775807ULL);
+}
+
+TEST(BlockFrequencyTest, BigToBig) {
+  const uint64_t Big = 387246523487234346LL;
+  const uint32_t P = 123456789;
+  BlockFrequency Freq(Big);
+  BranchProbability Prob(P, P);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), Big);
+
+  Freq = BlockFrequency(Big);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), Big);
+}
+
+TEST(BlockFrequencyTest, MaxToMax) {
+  BlockFrequency Freq(UINT64_MAX);
+  BranchProbability Prob(UINT32_MAX, UINT32_MAX);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
+
+  // This additionally makes sure if we have a value equal to our saturating
+  // value, we do not signal saturation if the result equals said value, but
+  // saturating does not occur.
+  Freq = BlockFrequency(UINT64_MAX);
+  Freq *= Prob;
+  EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
+}
+
+TEST(BlockFrequencyTest, Subtract) {
+  BlockFrequency Freq1(0), Freq2(1);
+  EXPECT_EQ((Freq1 - Freq2).getFrequency(), 0u);
+  EXPECT_EQ((Freq2 - Freq1).getFrequency(), 1u);
+}
+
+TEST(BlockFrequency, Divide) {
+  BlockFrequency Freq(0x3333333333333333ULL);
+  Freq /= BranchProbability(1, 2);
+  EXPECT_EQ(Freq.getFrequency(), 0x6666666666666666ULL);
+}
+
+TEST(BlockFrequencyTest, Saturate) {
+  BlockFrequency Freq(0x3333333333333333ULL);
+  Freq /= BranchProbability(100, 300);
+  EXPECT_EQ(Freq.getFrequency(), 0x9999999866666668ULL);
+  Freq /= BranchProbability(1, 2);
+  EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
+
+  Freq = 0x1000000000000000ULL;
+  Freq /= BranchProbability(10000, 170000);
+  EXPECT_EQ(Freq.getFrequency(), UINT64_MAX);
+
+  // Try to cheat the multiplication overflow check.
+  Freq = 0x00000001f0000001ull;
+  Freq /= BranchProbability(1000, 0xf000000f);
+  EXPECT_EQ(33527736066704712ULL, Freq.getFrequency());
+}
+
+TEST(BlockFrequencyTest, SaturatingRightShift) {
+  BlockFrequency Freq(0x10080ULL);
+  Freq >>= 2;
+  EXPECT_EQ(Freq.getFrequency(), 0x4020ULL);
+  Freq >>= 20;
+  EXPECT_EQ(Freq.getFrequency(), 0x1ULL);
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp b/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
new file mode 100644
index 0000000..54948ba
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/BranchProbabilityTest.cpp
@@ -0,0 +1,406 @@
+//===- unittest/Support/BranchProbabilityTest.cpp - BranchProbability 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/BranchProbability.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace llvm {
+void PrintTo(BranchProbability P, ::std::ostream *os) {
+  *os << P.getNumerator() << "/" << P.getDenominator();
+}
+}
+namespace {
+
+typedef BranchProbability BP;
+TEST(BranchProbabilityTest, Accessors) {
+  EXPECT_EQ(306783378u, BP(1, 7).getNumerator());
+  EXPECT_EQ(1u << 31, BP(1, 7).getDenominator());
+  EXPECT_EQ(0u, BP::getZero().getNumerator());
+  EXPECT_EQ(1u << 31, BP::getZero().getDenominator());
+  EXPECT_EQ(1u << 31, BP::getOne().getNumerator());
+  EXPECT_EQ(1u << 31, BP::getOne().getDenominator());
+}
+
+TEST(BranchProbabilityTest, Operators) {
+  EXPECT_TRUE(BP(1, 7) < BP(2, 7));
+  EXPECT_TRUE(BP(1, 7) < BP(1, 4));
+  EXPECT_TRUE(BP(5, 7) < BP(3, 4));
+  EXPECT_FALSE(BP(1, 7) < BP(1, 7));
+  EXPECT_FALSE(BP(1, 7) < BP(2, 14));
+  EXPECT_FALSE(BP(4, 7) < BP(1, 2));
+  EXPECT_FALSE(BP(4, 7) < BP(3, 7));
+
+  EXPECT_FALSE(BP(1, 7) > BP(2, 7));
+  EXPECT_FALSE(BP(1, 7) > BP(1, 4));
+  EXPECT_FALSE(BP(5, 7) > BP(3, 4));
+  EXPECT_FALSE(BP(1, 7) > BP(1, 7));
+  EXPECT_FALSE(BP(1, 7) > BP(2, 14));
+  EXPECT_TRUE(BP(4, 7) > BP(1, 2));
+  EXPECT_TRUE(BP(4, 7) > BP(3, 7));
+
+  EXPECT_TRUE(BP(1, 7) <= BP(2, 7));
+  EXPECT_TRUE(BP(1, 7) <= BP(1, 4));
+  EXPECT_TRUE(BP(5, 7) <= BP(3, 4));
+  EXPECT_TRUE(BP(1, 7) <= BP(1, 7));
+  EXPECT_TRUE(BP(1, 7) <= BP(2, 14));
+  EXPECT_FALSE(BP(4, 7) <= BP(1, 2));
+  EXPECT_FALSE(BP(4, 7) <= BP(3, 7));
+
+  EXPECT_FALSE(BP(1, 7) >= BP(2, 7));
+  EXPECT_FALSE(BP(1, 7) >= BP(1, 4));
+  EXPECT_FALSE(BP(5, 7) >= BP(3, 4));
+  EXPECT_TRUE(BP(1, 7) >= BP(1, 7));
+  EXPECT_TRUE(BP(1, 7) >= BP(2, 14));
+  EXPECT_TRUE(BP(4, 7) >= BP(1, 2));
+  EXPECT_TRUE(BP(4, 7) >= BP(3, 7));
+
+  EXPECT_FALSE(BP(1, 7) == BP(2, 7));
+  EXPECT_FALSE(BP(1, 7) == BP(1, 4));
+  EXPECT_FALSE(BP(5, 7) == BP(3, 4));
+  EXPECT_TRUE(BP(1, 7) == BP(1, 7));
+  EXPECT_TRUE(BP(1, 7) == BP(2, 14));
+  EXPECT_FALSE(BP(4, 7) == BP(1, 2));
+  EXPECT_FALSE(BP(4, 7) == BP(3, 7));
+
+  EXPECT_TRUE(BP(1, 7) != BP(2, 7));
+  EXPECT_TRUE(BP(1, 7) != BP(1, 4));
+  EXPECT_TRUE(BP(5, 7) != BP(3, 4));
+  EXPECT_FALSE(BP(1, 7) != BP(1, 7));
+  EXPECT_FALSE(BP(1, 7) != BP(2, 14));
+  EXPECT_TRUE(BP(4, 7) != BP(1, 2));
+  EXPECT_TRUE(BP(4, 7) != BP(3, 7));
+
+  EXPECT_TRUE(BP(1, 7) == BP(2, 14));
+  EXPECT_TRUE(BP(1, 7) == BP(3, 21));
+  EXPECT_TRUE(BP(5, 7) == BP(25, 35));
+  EXPECT_TRUE(BP(99999998, 100000000) < BP(99999999, 100000000));
+  EXPECT_TRUE(BP(4, 8) == BP(400000000, 800000000));
+}
+
+TEST(BranchProbabilityTest, MoreOperators) {
+  BP A(4, 5);
+  BP B(4U << 29, 5U << 29);
+  BP C(3, 4);
+
+  EXPECT_TRUE(A == B);
+  EXPECT_FALSE(A != B);
+  EXPECT_FALSE(A < B);
+  EXPECT_FALSE(A > B);
+  EXPECT_TRUE(A <= B);
+  EXPECT_TRUE(A >= B);
+
+  EXPECT_FALSE(B == C);
+  EXPECT_TRUE(B != C);
+  EXPECT_FALSE(B < C);
+  EXPECT_TRUE(B > C);
+  EXPECT_FALSE(B <= C);
+  EXPECT_TRUE(B >= C);
+
+  BP BigZero(0, UINT32_MAX);
+  BP BigOne(UINT32_MAX, UINT32_MAX);
+  EXPECT_FALSE(BigZero == BigOne);
+  EXPECT_TRUE(BigZero != BigOne);
+  EXPECT_TRUE(BigZero < BigOne);
+  EXPECT_FALSE(BigZero > BigOne);
+  EXPECT_TRUE(BigZero <= BigOne);
+  EXPECT_FALSE(BigZero >= BigOne);
+}
+
+TEST(BranchProbabilityTest, ArithmeticOperators) {
+  BP Z(0, 1);
+  BP O(1, 1);
+  BP H(1, 2);
+  BP Q(1, 4);
+  BP Q3(3, 4);
+
+  EXPECT_EQ(Z + O, O);
+  EXPECT_EQ(H + Z, H);
+  EXPECT_EQ(H + H, O);
+  EXPECT_EQ(Q + H, Q3);
+  EXPECT_EQ(Q + Q3, O);
+  EXPECT_EQ(H + Q3, O);
+  EXPECT_EQ(Q3 + Q3, O);
+
+  EXPECT_EQ(Z - O, Z);
+  EXPECT_EQ(O - Z, O);
+  EXPECT_EQ(O - H, H);
+  EXPECT_EQ(O - Q, Q3);
+  EXPECT_EQ(Q3 - H, Q);
+  EXPECT_EQ(Q - H, Z);
+  EXPECT_EQ(Q - Q3, Z);
+
+  EXPECT_EQ(Z * O, Z);
+  EXPECT_EQ(H * H, Q);
+  EXPECT_EQ(Q * O, Q);
+  EXPECT_EQ(O * O, O);
+  EXPECT_EQ(Z * Z, Z);
+
+  EXPECT_EQ(Z * 3, Z);
+  EXPECT_EQ(Q * 3, Q3);
+  EXPECT_EQ(H * 3, O);
+  EXPECT_EQ(Q3 * 2, O);
+  EXPECT_EQ(O * UINT32_MAX, O);
+
+  EXPECT_EQ(Z / 4, Z);
+  EXPECT_EQ(O / 4, Q);
+  EXPECT_EQ(Q3 / 3, Q);
+  EXPECT_EQ(H / 2, Q);
+  EXPECT_EQ(O / 2, H);
+  EXPECT_EQ(H / UINT32_MAX, Z);
+
+  BP Min(1, 1u << 31);
+
+  EXPECT_EQ(O / UINT32_MAX, Z);
+  EXPECT_EQ(Min * UINT32_MAX, O);
+}
+
+TEST(BranchProbabilityTest, getCompl) {
+  EXPECT_EQ(BP(5, 7), BP(2, 7).getCompl());
+  EXPECT_EQ(BP(2, 7), BP(5, 7).getCompl());
+  EXPECT_EQ(BP::getZero(), BP(7, 7).getCompl());
+  EXPECT_EQ(BP::getOne(), BP(0, 7).getCompl());
+}
+
+TEST(BranchProbabilityTest, scale) {
+  // Multiply by 1.0.
+  EXPECT_EQ(UINT64_MAX, BP(1, 1).scale(UINT64_MAX));
+  EXPECT_EQ(UINT64_MAX, BP(7, 7).scale(UINT64_MAX));
+  EXPECT_EQ(UINT32_MAX, BP(1, 1).scale(UINT32_MAX));
+  EXPECT_EQ(UINT32_MAX, BP(7, 7).scale(UINT32_MAX));
+  EXPECT_EQ(0u, BP(1, 1).scale(0));
+  EXPECT_EQ(0u, BP(7, 7).scale(0));
+
+  // Multiply by 0.0.
+  EXPECT_EQ(0u, BP(0, 1).scale(UINT64_MAX));
+  EXPECT_EQ(0u, BP(0, 1).scale(UINT64_MAX));
+  EXPECT_EQ(0u, BP(0, 1).scale(0));
+
+  auto Two63 = UINT64_C(1) << 63;
+  auto Two31 = UINT64_C(1) << 31;
+
+  // Multiply by 0.5.
+  EXPECT_EQ(Two63 - 1, BP(1, 2).scale(UINT64_MAX));
+
+  // Big fractions.
+  EXPECT_EQ(1u, BP(Two31, UINT32_MAX).scale(2));
+  EXPECT_EQ(Two31, BP(Two31, UINT32_MAX).scale(Two31 * 2));
+  EXPECT_EQ(9223372036854775807ULL, BP(Two31, UINT32_MAX).scale(UINT64_MAX));
+
+  // High precision.
+  EXPECT_EQ(UINT64_C(9223372045444710399),
+            BP(Two31 + 1, UINT32_MAX - 2).scale(UINT64_MAX));
+}
+
+TEST(BranchProbabilityTest, scaleByInverse) {
+  // Divide by 1.0.
+  EXPECT_EQ(UINT64_MAX, BP(1, 1).scaleByInverse(UINT64_MAX));
+  EXPECT_EQ(UINT64_MAX, BP(7, 7).scaleByInverse(UINT64_MAX));
+  EXPECT_EQ(UINT32_MAX, BP(1, 1).scaleByInverse(UINT32_MAX));
+  EXPECT_EQ(UINT32_MAX, BP(7, 7).scaleByInverse(UINT32_MAX));
+  EXPECT_EQ(0u, BP(1, 1).scaleByInverse(0));
+  EXPECT_EQ(0u, BP(7, 7).scaleByInverse(0));
+
+  auto MAX_DENOMINATOR = BP::getDenominator();
+
+  // Divide by something very small.
+  EXPECT_EQ(UINT64_MAX, BP(1, UINT32_MAX).scaleByInverse(UINT64_MAX));
+  EXPECT_EQ(uint64_t(UINT32_MAX) * MAX_DENOMINATOR,
+            BP(1, MAX_DENOMINATOR).scaleByInverse(UINT32_MAX));
+  EXPECT_EQ(MAX_DENOMINATOR, BP(1, MAX_DENOMINATOR).scaleByInverse(1));
+
+  auto Two63 = UINT64_C(1) << 63;
+  auto Two31 = UINT64_C(1) << 31;
+
+  // Divide by 0.5.
+  EXPECT_EQ(UINT64_MAX - 1, BP(1, 2).scaleByInverse(Two63 - 1));
+  EXPECT_EQ(UINT64_MAX, BP(1, 2).scaleByInverse(Two63));
+
+  // Big fractions.
+  EXPECT_EQ(2u, BP(Two31, UINT32_MAX).scaleByInverse(1));
+  EXPECT_EQ(2u, BP(Two31 - 1, UINT32_MAX).scaleByInverse(1));
+  EXPECT_EQ(Two31 * 2, BP(Two31, UINT32_MAX).scaleByInverse(Two31));
+  EXPECT_EQ(Two31 * 2, BP(Two31 - 1, UINT32_MAX).scaleByInverse(Two31));
+  EXPECT_EQ(UINT64_MAX, BP(Two31, UINT32_MAX).scaleByInverse(Two63 + Two31));
+
+  // High precision.  The exact answers to these are close to the successors of
+  // the floor.  If we were rounding, these would round up.
+  EXPECT_EQ(UINT64_C(18446744060824649767),
+            BP(Two31 + 2, UINT32_MAX - 2)
+                .scaleByInverse(UINT64_C(9223372047592194056)));
+  EXPECT_EQ(UINT64_C(18446744060824649739),
+            BP(Two31 + 1, UINT32_MAX).scaleByInverse(Two63 + Two31));
+}
+
+TEST(BranchProbabilityTest, scaleBruteForce) {
+  struct {
+    uint64_t Num;
+    uint32_t Prob[2];
+    uint64_t Result;
+  } Tests[] = {
+    // Data for scaling that results in <= 64 bit division.
+    { 0x1423e2a50ULL, { 0x64819521, 0x7765dd13 }, 0x10f418888ULL },
+    { 0x35ef14ceULL, { 0x28ade3c7, 0x304532ae }, 0x2d73c33bULL },
+    { 0xd03dbfbe24ULL, { 0x790079, 0xe419f3 }, 0x6e776fc2c4ULL },
+    { 0x21d67410bULL, { 0x302a9dc2, 0x3ddb4442 }, 0x1a5948fd4ULL },
+    { 0x8664aeadULL, { 0x3d523513, 0x403523b1 }, 0x805a04cfULL },
+    { 0x201db0cf4ULL, { 0x35112a7b, 0x79fc0c74 }, 0xdf8b07f8ULL },
+    { 0x13f1e4430aULL, { 0x21c92bf, 0x21e63aae }, 0x13e0cba26ULL },
+    { 0x16c83229ULL, { 0x3793f66f, 0x53180dea }, 0xf3ce7b6ULL },
+    { 0xc62415be8ULL, { 0x9cc4a63, 0x4327ae9b }, 0x1ce8b71c1ULL },
+    { 0x6fac5e434ULL, { 0xe5f9170, 0x1115e10b }, 0x5df23dd4cULL },
+    { 0x1929375f2ULL, { 0x3a851375, 0x76c08456 }, 0xc662b083ULL },
+    { 0x243c89db6ULL, { 0x354ebfc0, 0x450ef197 }, 0x1bf8c1663ULL },
+    { 0x310e9b31aULL, { 0x1b1b8acf, 0x2d3629f0 }, 0x1d69c93f9ULL },
+    { 0xa1fae921dULL, { 0xa7a098c, 0x10469f44 }, 0x684413d6eULL },
+    { 0xc1582d957ULL, { 0x498e061, 0x59856bc }, 0x9edc5f4ecULL },
+    { 0x57cfee75ULL, { 0x1d061dc3, 0x7c8bfc17 }, 0x1476a220ULL },
+    { 0x139220080ULL, { 0x294a6c71, 0x2a2b07c9 }, 0x1329e1c75ULL },
+    { 0x1665d353cULL, { 0x7080db5, 0xde0d75c }, 0xb590d9faULL },
+    { 0xe8f14541ULL, { 0x5188e8b2, 0x736527ef }, 0xa4971be5ULL },
+    { 0x2f4775f29ULL, { 0x254ef0fe, 0x435fcf50 }, 0x1a2e449c1ULL },
+    { 0x27b85d8d7ULL, { 0x304c8220, 0x5de678f2 }, 0x146e3befbULL },
+    { 0x1d362e36bULL, { 0x36c85b12, 0x37a66f55 }, 0x1cc19b8e7ULL },
+    { 0x155fd48c7ULL, { 0xf5894d, 0x1256108 }, 0x11e383604ULL },
+    { 0xb5db2d15ULL, { 0x39bb26c5, 0x5bdcda3e }, 0x72499259ULL },
+    { 0x153990298ULL, { 0x48921c09, 0x706eb817 }, 0xdb3268e7ULL },
+    { 0x28a7c3ed7ULL, { 0x1f776fd7, 0x349f7a70 }, 0x184f73ae2ULL },
+    { 0x724dbeabULL, { 0x1bd149f5, 0x253a085e }, 0x5569c0b3ULL },
+    { 0xd8f0c513ULL, { 0x18c8cc4c, 0x1b72bad0 }, 0xc3e30642ULL },
+    { 0x17ce3dcbULL, { 0x1e4c6260, 0x233b359e }, 0x1478f4afULL },
+    { 0x1ce036ce0ULL, { 0x29e3c8af, 0x5318dd4a }, 0xe8e76195ULL },
+    { 0x1473ae2aULL, { 0x29b897ba, 0x2be29378 }, 0x13718185ULL },
+    { 0x1dd41aa68ULL, { 0x3d0a4441, 0x5a0e8f12 }, 0x1437b6bbfULL },
+    { 0x1b49e4a53ULL, { 0x3430c1fe, 0x5a204aed }, 0xfcd6852fULL },
+    { 0x217941b19ULL, { 0x12ced2bd, 0x21b68310 }, 0x12aca65b1ULL },
+    { 0xac6a4dc8ULL, { 0x3ed68da8, 0x6fdca34c }, 0x60da926dULL },
+    { 0x1c503a4e7ULL, { 0xfcbbd32, 0x11e48d17 }, 0x18fec7d37ULL },
+    { 0x1c885855ULL, { 0x213e919d, 0x25941897 }, 0x193de742ULL },
+    { 0x29b9c168eULL, { 0x2b644aea, 0x45725ee7 }, 0x1a122e5d4ULL },
+    { 0x806a33f2ULL, { 0x30a80a23, 0x5063733a }, 0x4db9a264ULL },
+    { 0x282afc96bULL, { 0x143ae554, 0x1a9863ff }, 0x1e8de5204ULL },
+    // Data for scaling that results in > 64 bit division.
+    { 0x23ca5f2f672ca41cULL, { 0xecbc641, 0x111373f7 }, 0x1f0301e5c76869c6ULL },
+    { 0x5e4f2468142265e3ULL, { 0x1ddf5837, 0x32189233 }, 0x383ca7bad6053ac9ULL },
+    { 0x277a1a6f6b266bf6ULL, { 0x415d81a8, 0x61eb5e1e }, 0x1a5a3e1d1c9e8540ULL },
+    { 0x1bdbb49a237035cbULL, { 0xea5bf17, 0x1d25ffb3 }, 0xdffc51c5cb51cf1ULL },
+    { 0x2bce6d29b64fb8ULL, { 0x3bfd5631, 0x7525c9bb }, 0x166ebedd9581fdULL },
+    { 0x3a02116103df5013ULL, { 0x2ee18a83, 0x3299aea8 }, 0x35be89227276f105ULL },
+    { 0x7b5762390799b18cULL, { 0x12f8e5b9, 0x2563bcd4 }, 0x3e960077695655a3ULL },
+    { 0x69cfd72537021579ULL, { 0x4c35f468, 0x6a40feee }, 0x4be4cb38695a4f30ULL },
+    { 0x49dfdf835120f1c1ULL, { 0x8cb3759, 0x559eb891 }, 0x79663f6e3c8d8f6ULL },
+    { 0x74b5be5c27676381ULL, { 0x47e4c5e0, 0x7c7b19ff }, 0x4367d2dfb22b3265ULL },
+    { 0x4f50f97075e7f431ULL, { 0x9a50a17, 0x11cd1185 }, 0x2af952b30374f382ULL },
+    { 0x2f8b0d712e393be4ULL, { 0x1487e386, 0x15aa356e }, 0x2d0df3649b2b19fcULL },
+    { 0x224c1c75999d3deULL, { 0x3b2df0ea, 0x4523b100 }, 0x1d5b481d160dd8bULL },
+    { 0x2bcbcea22a399a76ULL, { 0x28b58212, 0x48dd013e }, 0x187814d0610c8a56ULL },
+    { 0x1dbfca91257cb2d1ULL, { 0x1a8c04d9, 0x5e92502c }, 0x859cf7d19e83ad0ULL },
+    { 0x7f20039b57cda935ULL, { 0xeccf651, 0x323f476e }, 0x25720cd9054634bdULL },
+    { 0x40512c6a586aa087ULL, { 0x113b0423, 0x398c9eab }, 0x1341c03dbb662054ULL },
+    { 0x63d802693f050a11ULL, { 0xf50cdd6, 0xfce2a44 }, 0x60c0177b667a4feaULL },
+    { 0x2d956b422838de77ULL, { 0xb2d345b, 0x1321e557 }, 0x1aa0ed16b094575cULL },
+    { 0x5a1cdf0c1657bc91ULL, { 0x1d77bb0c, 0x1f991ff1 }, 0x54097ee9907290eaULL },
+    { 0x3801b26d7e00176bULL, { 0xeed25da, 0x1a819d8b }, 0x1f89e96a616b9abeULL },
+    { 0x37655e74338e1e45ULL, { 0x300e170a, 0x5a1595fe }, 0x1d8cfb55ff6a6dbcULL },
+    { 0x7b38703f2a84e6ULL, { 0x66d9053, 0xc79b6b9 }, 0x3f7d4c91b9afb9ULL },
+    { 0x2245063c0acb3215ULL, { 0x30ce2f5b, 0x610e7271 }, 0x113b916455fe2560ULL },
+    { 0x6bc195877b7b8a7eULL, { 0x392004aa, 0x4a24e60c }, 0x530594fabfc81cc3ULL },
+    { 0x40a3fde23c7b43dbULL, { 0x4e712195, 0x6553e56e }, 0x320a799bc205c78dULL },
+    { 0x1d3dfc2866fbccbaULL, { 0x5075b517, 0x5fc42245 }, 0x18917f00745cb781ULL },
+    { 0x19aeb14045a61121ULL, { 0x1bf6edec, 0x707e2f4b }, 0x6626672aa2ba10aULL },
+    { 0x44ff90486c531e9fULL, { 0x66598a, 0x8a90dc }, 0x32f6f2b097001598ULL },
+    { 0x3f3e7121092c5bcbULL, { 0x1c754df7, 0x5951a1b9 }, 0x14267f50d4971583ULL },
+    { 0x60e2dafb7e50a67eULL, { 0x4d96c66e, 0x65bd878d }, 0x49e317155d75e883ULL },
+    { 0x656286667e0e6e29ULL, { 0x9d971a2, 0xacda23b }, 0x5c6ee3159e1deac3ULL },
+    { 0x1114e0974255d507ULL, { 0x1c693, 0x2d6ff }, 0xaae42e4be5f9f8dULL },
+    { 0x508c8baf3a70ff5aULL, { 0x3b26b779, 0x6ad78745 }, 0x2c983876178ed5b1ULL },
+    { 0x5b47bc666bf1f9cfULL, { 0x10a87ed6, 0x187d358a }, 0x3e1767153bea720aULL },
+    { 0x50954e3744460395ULL, { 0x7a42263, 0xcdaa048 }, 0x2fe739f0944a023cULL },
+    { 0x20020b406550dd8fULL, { 0x3318539, 0x42eead0 }, 0x186f326307c0d985ULL },
+    { 0x5bcb0b872439ffd5ULL, { 0x6f61fb2, 0x9af7344 }, 0x41fa1e3c47f0f80dULL },
+    { 0x7a670f365db87a53ULL, { 0x417e102, 0x3bb54c67 }, 0x8642a551d0f41b0ULL },
+    { 0x1ef0db1e7bab1cd0ULL, { 0x2b60cf38, 0x4188f78f }, 0x147ae0d63fc0575aULL }
+  };
+
+  for (const auto &T : Tests) {
+    EXPECT_EQ(T.Result, BP(T.Prob[0], T.Prob[1]).scale(T.Num));
+  }
+}
+
+TEST(BranchProbabilityTest, NormalizeProbabilities) {
+  const auto UnknownProb = BranchProbability::getUnknown();
+  {
+    SmallVector<BranchProbability, 2> Probs{{0, 1}, {0, 1}};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 2> Probs{{0, 1}, {1, 1}};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(0u, Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator(), Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 2> Probs{{1, 100}, {1, 100}};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 2> Probs{{1, 1}, {1, 1}};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 3> Probs{{1, 1}, {1, 1}, {1, 1}};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
+              Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
+              Probs[1].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
+              Probs[2].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 2> Probs{{0, 1}, UnknownProb};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(0U, Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator(), Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 2> Probs{{1, 1}, UnknownProb};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator(), Probs[0].getNumerator());
+    EXPECT_EQ(0U, Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 2> Probs{{1, 2}, UnknownProb};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 2, Probs[1].getNumerator());
+  }
+  {
+    SmallVector<BranchProbability, 4> Probs{
+        {1, 2}, {1, 2}, {1, 2}, UnknownProb};
+    BranchProbability::normalizeProbabilities(Probs.begin(), Probs.end());
+    EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
+              Probs[0].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
+              Probs[1].getNumerator());
+    EXPECT_EQ(BranchProbability::getDenominator() / 3 + 1,
+              Probs[2].getNumerator());
+    EXPECT_EQ(0U, Probs[3].getNumerator());
+  }
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
new file mode 100644
index 0000000..f9c877f
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
@@ -0,0 +1,91 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_llvm_unittest(SupportTests
+  AlignOfTest.cpp
+  AllocatorTest.cpp
+  ARMAttributeParser.cpp
+  ArrayRecyclerTest.cpp
+  BinaryStreamTest.cpp
+  BlockFrequencyTest.cpp
+  BranchProbabilityTest.cpp
+  CachePruningTest.cpp
+  CrashRecoveryTest.cpp
+  Casting.cpp
+  CheckedArithmeticTest.cpp
+  Chrono.cpp
+  CommandLineTest.cpp
+  CompressionTest.cpp
+  ConvertUTFTest.cpp
+  DataExtractorTest.cpp
+  DebugTest.cpp
+  DebugCounterTest.cpp
+  DJBTest.cpp
+  EndianStreamTest.cpp
+  EndianTest.cpp
+  ErrnoTest.cpp
+  ErrorOrTest.cpp
+  ErrorTest.cpp
+  FileOutputBufferTest.cpp
+  FormatVariadicTest.cpp
+  GlobPatternTest.cpp
+  Host.cpp
+  ItaniumManglingCanonicalizerTest.cpp
+  JSONTest.cpp
+  LEB128Test.cpp
+  LineIteratorTest.cpp
+  LockFileManagerTest.cpp
+  MD5Test.cpp
+  ManagedStatic.cpp
+  MathExtrasTest.cpp
+  MemoryBufferTest.cpp
+  MemoryTest.cpp
+  NativeFormatTests.cpp
+  ParallelTest.cpp
+  Path.cpp
+  ProcessTest.cpp
+  ProgramTest.cpp
+  RegexTest.cpp
+  ReverseIterationTest.cpp
+  ReplaceFileTest.cpp
+  ScaledNumberTest.cpp
+  SourceMgrTest.cpp
+  SpecialCaseListTest.cpp
+  StringPool.cpp
+  SwapByteOrderTest.cpp
+  SymbolRemappingReaderTest.cpp
+  TarWriterTest.cpp
+  TargetParserTest.cpp
+  TaskQueueTest.cpp
+  ThreadLocalTest.cpp
+  ThreadPool.cpp
+  Threading.cpp
+  TimerTest.cpp
+  TypeNameTest.cpp
+  TypeTraitsTest.cpp
+  TrailingObjectsTest.cpp
+  TrigramIndexTest.cpp
+  UnicodeTest.cpp
+  VersionTupleTest.cpp
+  VirtualFileSystemTest.cpp
+  YAMLIOTest.cpp
+  YAMLParserTest.cpp
+  formatted_raw_ostream_test.cpp
+  raw_ostream_test.cpp
+  raw_pwrite_stream_test.cpp
+  raw_sha1_ostream_test.cpp
+  xxhashTest.cpp
+  )
+
+target_link_libraries(SupportTests PRIVATE LLVMTestingSupport)
+
+# Disable all warning for AlignOfTest.cpp,
+# as it does things intentionally, and there is no reliable way of
+# disabling all warnings for all the compilers by using pragmas.
+set_source_files_properties(AlignOfTest.cpp PROPERTIES COMPILE_FLAGS -w)
+
+# ManagedStatic.cpp uses <pthread>.
+target_link_libraries(SupportTests PRIVATE LLVMTestingSupport ${LLVM_PTHREAD_LIB})
+
+add_subdirectory(DynamicLibrary)
diff --git a/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp b/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
new file mode 100644
index 0000000..4bc2ad1
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CachePruningTest.cpp
@@ -0,0 +1,97 @@
+//===- CachePruningTest.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/CachePruning.h"
+#include "llvm/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(CachePruningPolicyParser, Empty) {
+  auto P = parseCachePruningPolicy("");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(std::chrono::seconds(1200), P->Interval);
+  EXPECT_EQ(std::chrono::hours(7 * 24), P->Expiration);
+  EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
+}
+
+TEST(CachePruningPolicyParser, Interval) {
+  auto P = parseCachePruningPolicy("prune_interval=1s");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(std::chrono::seconds(1), P->Interval);
+  P = parseCachePruningPolicy("prune_interval=2m");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(std::chrono::minutes(2), *P->Interval);
+  P = parseCachePruningPolicy("prune_interval=3h");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(std::chrono::hours(3), *P->Interval);
+}
+
+TEST(CachePruningPolicyParser, Expiration) {
+  auto P = parseCachePruningPolicy("prune_after=1s");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(std::chrono::seconds(1), P->Expiration);
+}
+
+TEST(CachePruningPolicyParser, MaxSizePercentageOfAvailableSpace) {
+  auto P = parseCachePruningPolicy("cache_size=100%");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(100u, P->MaxSizePercentageOfAvailableSpace);
+  EXPECT_EQ(0u, P->MaxSizeBytes);
+}
+
+TEST(CachePruningPolicyParser, MaxSizeBytes) {
+  auto P = parseCachePruningPolicy("cache_size_bytes=1");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
+  EXPECT_EQ(1u, P->MaxSizeBytes);
+  P = parseCachePruningPolicy("cache_size_bytes=2k");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
+  EXPECT_EQ(2u * 1024u, P->MaxSizeBytes);
+  P = parseCachePruningPolicy("cache_size_bytes=3m");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
+  EXPECT_EQ(3u * 1024u * 1024u, P->MaxSizeBytes);
+  P = parseCachePruningPolicy("cache_size_bytes=4G");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(75u, P->MaxSizePercentageOfAvailableSpace);
+  EXPECT_EQ(4ull * 1024ull * 1024ull * 1024ull, P->MaxSizeBytes);
+}
+
+TEST(CachePruningPolicyParser, Multiple) {
+  auto P = parseCachePruningPolicy("prune_after=1s:cache_size=50%");
+  ASSERT_TRUE(bool(P));
+  EXPECT_EQ(std::chrono::seconds(1200), P->Interval);
+  EXPECT_EQ(std::chrono::seconds(1), P->Expiration);
+  EXPECT_EQ(50u, P->MaxSizePercentageOfAvailableSpace);
+}
+
+TEST(CachePruningPolicyParser, Errors) {
+  EXPECT_EQ("Duration must not be empty",
+            toString(parseCachePruningPolicy("prune_interval=").takeError()));
+  EXPECT_EQ("'foo' not an integer",
+            toString(parseCachePruningPolicy("prune_interval=foos").takeError()));
+  EXPECT_EQ("'24x' must end with one of 's', 'm' or 'h'",
+            toString(parseCachePruningPolicy("prune_interval=24x").takeError()));
+  EXPECT_EQ("'foo' must be a percentage",
+            toString(parseCachePruningPolicy("cache_size=foo").takeError()));
+  EXPECT_EQ("'foo' not an integer",
+            toString(parseCachePruningPolicy("cache_size=foo%").takeError()));
+  EXPECT_EQ("'101' must be between 0 and 100",
+            toString(parseCachePruningPolicy("cache_size=101%").takeError()));
+  EXPECT_EQ(
+      "'foo' not an integer",
+      toString(parseCachePruningPolicy("cache_size_bytes=foo").takeError()));
+  EXPECT_EQ(
+      "'foo' not an integer",
+      toString(parseCachePruningPolicy("cache_size_bytes=foom").takeError()));
+  EXPECT_EQ("Unknown key: 'foo'",
+            toString(parseCachePruningPolicy("foo=bar").takeError()));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/Casting.cpp b/src/llvm-project/llvm/unittests/Support/Casting.cpp
new file mode 100644
index 0000000..9a818f6
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/Casting.cpp
@@ -0,0 +1,405 @@
+//===---------- llvm/unittest/Support/Casting.cpp - Casting 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/Casting.h"
+#include "llvm/IR/User.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+namespace llvm {
+// Used to test illegal cast. If a cast doesn't match any of the "real" ones,
+// it will match this one.
+struct IllegalCast;
+template <typename T> IllegalCast *cast(...) { return nullptr; }
+
+// set up two example classes
+// with conversion facility
+//
+struct bar {
+  bar() {}
+  struct foo *baz();
+  struct foo *caz();
+  struct foo *daz();
+  struct foo *naz();
+private:
+  bar(const bar &);
+};
+struct foo {
+  void ext() const;
+  /*  static bool classof(const bar *X) {
+    cerr << "Classof: " << X << "\n";
+    return true;
+    }*/
+};
+
+struct base {
+  virtual ~base() {}
+};
+
+struct derived : public base {
+  static bool classof(const base *B) { return true; }
+};
+
+template <> struct isa_impl<foo, bar> {
+  static inline bool doit(const bar &Val) {
+    dbgs() << "Classof: " << &Val << "\n";
+    return true;
+  }
+};
+
+template <typename T> struct isa_impl<foo, T> {
+  static inline bool doit(const T &Val) { return false; }
+};
+
+foo *bar::baz() {
+    return cast<foo>(this);
+}
+
+foo *bar::caz() {
+    return cast_or_null<foo>(this);
+}
+
+foo *bar::daz() {
+    return dyn_cast<foo>(this);
+}
+
+foo *bar::naz() {
+    return dyn_cast_or_null<foo>(this);
+}
+
+
+bar *fub();
+
+template <> struct simplify_type<foo> {
+  typedef int SimpleType;
+  static SimpleType getSimplifiedValue(foo &Val) { return 0; }
+};
+
+} // End llvm namespace
+
+using namespace llvm;
+
+
+// Test the peculiar behavior of Use in simplify_type.
+static_assert(std::is_same<simplify_type<Use>::SimpleType, Value *>::value,
+              "Use doesn't simplify correctly!");
+static_assert(std::is_same<simplify_type<Use *>::SimpleType, Value *>::value,
+              "Use doesn't simplify correctly!");
+
+// Test that a regular class behaves as expected.
+static_assert(std::is_same<simplify_type<foo>::SimpleType, int>::value,
+              "Unexpected simplify_type result!");
+static_assert(std::is_same<simplify_type<foo *>::SimpleType, foo *>::value,
+              "Unexpected simplify_type result!");
+
+namespace {
+
+const foo *null_foo = nullptr;
+
+bar B;
+extern bar &B1;
+bar &B1 = B;
+extern const bar *B2;
+// test various configurations of const
+const bar &B3 = B1;
+const bar *const B4 = B2;
+
+TEST(CastingTest, isa) {
+  EXPECT_TRUE(isa<foo>(B1));
+  EXPECT_TRUE(isa<foo>(B2));
+  EXPECT_TRUE(isa<foo>(B3));
+  EXPECT_TRUE(isa<foo>(B4));
+}
+
+TEST(CastingTest, cast) {
+  foo &F1 = cast<foo>(B1);
+  EXPECT_NE(&F1, null_foo);
+  const foo *F3 = cast<foo>(B2);
+  EXPECT_NE(F3, null_foo);
+  const foo *F4 = cast<foo>(B2);
+  EXPECT_NE(F4, null_foo);
+  const foo &F5 = cast<foo>(B3);
+  EXPECT_NE(&F5, null_foo);
+  const foo *F6 = cast<foo>(B4);
+  EXPECT_NE(F6, null_foo);
+  // Can't pass null pointer to cast<>.
+  // foo *F7 = cast<foo>(fub());
+  // EXPECT_EQ(F7, null_foo);
+  foo *F8 = B1.baz();
+  EXPECT_NE(F8, null_foo);
+
+  std::unique_ptr<const bar> BP(B2);
+  auto FP = cast<foo>(std::move(BP));
+  static_assert(std::is_same<std::unique_ptr<const foo>, decltype(FP)>::value,
+                "Incorrect deduced return type!");
+  EXPECT_NE(FP.get(), null_foo);
+  FP.release();
+}
+
+TEST(CastingTest, cast_or_null) {
+  const foo *F11 = cast_or_null<foo>(B2);
+  EXPECT_NE(F11, null_foo);
+  const foo *F12 = cast_or_null<foo>(B2);
+  EXPECT_NE(F12, null_foo);
+  const foo *F13 = cast_or_null<foo>(B4);
+  EXPECT_NE(F13, null_foo);
+  const foo *F14 = cast_or_null<foo>(fub());  // Shouldn't print.
+  EXPECT_EQ(F14, null_foo);
+  foo *F15 = B1.caz();
+  EXPECT_NE(F15, null_foo);
+
+  std::unique_ptr<const bar> BP(fub());
+  auto FP = cast_or_null<foo>(std::move(BP));
+  EXPECT_EQ(FP.get(), null_foo);
+}
+
+TEST(CastingTest, dyn_cast) {
+  const foo *F1 = dyn_cast<foo>(B2);
+  EXPECT_NE(F1, null_foo);
+  const foo *F2 = dyn_cast<foo>(B2);
+  EXPECT_NE(F2, null_foo);
+  const foo *F3 = dyn_cast<foo>(B4);
+  EXPECT_NE(F3, null_foo);
+  // Can't pass null pointer to dyn_cast<>.
+  // foo *F4 = dyn_cast<foo>(fub());
+  // EXPECT_EQ(F4, null_foo);
+  foo *F5 = B1.daz();
+  EXPECT_NE(F5, null_foo);
+}
+
+TEST(CastingTest, dyn_cast_or_null) {
+  const foo *F1 = dyn_cast_or_null<foo>(B2);
+  EXPECT_NE(F1, null_foo);
+  const foo *F2 = dyn_cast_or_null<foo>(B2);
+  EXPECT_NE(F2, null_foo);
+  const foo *F3 = dyn_cast_or_null<foo>(B4);
+  EXPECT_NE(F3, null_foo);
+  foo *F4 = dyn_cast_or_null<foo>(fub());
+  EXPECT_EQ(F4, null_foo);
+  foo *F5 = B1.naz();
+  EXPECT_NE(F5, null_foo);
+}
+
+std::unique_ptr<derived> newd() { return llvm::make_unique<derived>(); }
+std::unique_ptr<base> newb() { return llvm::make_unique<derived>(); }
+
+TEST(CastingTest, unique_dyn_cast) {
+  derived *OrigD = nullptr;
+  auto D = llvm::make_unique<derived>();
+  OrigD = D.get();
+
+  // Converting from D to itself is valid, it should return a new unique_ptr
+  // and the old one should become nullptr.
+  auto NewD = unique_dyn_cast<derived>(D);
+  ASSERT_EQ(OrigD, NewD.get());
+  ASSERT_EQ(nullptr, D);
+
+  // Converting from D to B is valid, B should have a value and D should be
+  // nullptr.
+  auto B = unique_dyn_cast<base>(NewD);
+  ASSERT_EQ(OrigD, B.get());
+  ASSERT_EQ(nullptr, NewD);
+
+  // Converting from B to itself is valid, it should return a new unique_ptr
+  // and the old one should become nullptr.
+  auto NewB = unique_dyn_cast<base>(B);
+  ASSERT_EQ(OrigD, NewB.get());
+  ASSERT_EQ(nullptr, B);
+
+  // Converting from B to D is valid, D should have a value and B should be
+  // nullptr;
+  D = unique_dyn_cast<derived>(NewB);
+  ASSERT_EQ(OrigD, D.get());
+  ASSERT_EQ(nullptr, NewB);
+
+  // Converting between unrelated types should fail.  The original value should
+  // remain unchanged and it should return nullptr.
+  auto F = unique_dyn_cast<foo>(D);
+  ASSERT_EQ(nullptr, F);
+  ASSERT_EQ(OrigD, D.get());
+
+  // All of the above should also hold for temporaries.
+  auto D2 = unique_dyn_cast<derived>(newd());
+  EXPECT_NE(nullptr, D2);
+
+  auto B2 = unique_dyn_cast<derived>(newb());
+  EXPECT_NE(nullptr, B2);
+
+  auto B3 = unique_dyn_cast<base>(newb());
+  EXPECT_NE(nullptr, B3);
+
+  auto F2 = unique_dyn_cast<foo>(newb());
+  EXPECT_EQ(nullptr, F2);
+}
+
+// These lines are errors...
+//foo *F20 = cast<foo>(B2);  // Yields const foo*
+//foo &F21 = cast<foo>(B3);  // Yields const foo&
+//foo *F22 = cast<foo>(B4);  // Yields const foo*
+//foo &F23 = cast_or_null<foo>(B1);
+//const foo &F24 = cast_or_null<foo>(B3);
+
+const bar *B2 = &B;
+}  // anonymous namespace
+
+bar *llvm::fub() { return nullptr; }
+
+namespace {
+namespace inferred_upcasting {
+// This test case verifies correct behavior of inferred upcasts when the
+// types are statically known to be OK to upcast. This is the case when,
+// for example, Derived inherits from Base, and we do `isa<Base>(Derived)`.
+
+// Note: This test will actually fail to compile without inferred
+// upcasting.
+
+class Base {
+public:
+  // No classof. We are testing that the upcast is inferred.
+  Base() {}
+};
+
+class Derived : public Base {
+public:
+  Derived() {}
+};
+
+// Even with no explicit classof() in Base, we should still be able to cast
+// Derived to its base class.
+TEST(CastingTest, UpcastIsInferred) {
+  Derived D;
+  EXPECT_TRUE(isa<Base>(D));
+  Base *BP = dyn_cast<Base>(&D);
+  EXPECT_TRUE(BP != nullptr);
+}
+
+
+// This test verifies that the inferred upcast takes precedence over an
+// explicitly written one. This is important because it verifies that the
+// dynamic check gets optimized away.
+class UseInferredUpcast {
+public:
+  int Dummy;
+  static bool classof(const UseInferredUpcast *) {
+    return false;
+  }
+};
+
+TEST(CastingTest, InferredUpcastTakesPrecedence) {
+  UseInferredUpcast UIU;
+  // Since the explicit classof() returns false, this will fail if the
+  // explicit one is used.
+  EXPECT_TRUE(isa<UseInferredUpcast>(&UIU));
+}
+
+} // end namespace inferred_upcasting
+} // end anonymous namespace
+// Test that we reject casts of temporaries (and so the illegal cast gets used).
+namespace TemporaryCast {
+struct pod {};
+IllegalCast *testIllegalCast() { return cast<foo>(pod()); }
+}
+
+namespace {
+namespace pointer_wrappers {
+
+struct Base {
+  bool IsDerived;
+  Base(bool IsDerived = false) : IsDerived(IsDerived) {}
+};
+
+struct Derived : Base {
+  Derived() : Base(true) {}
+  static bool classof(const Base *B) { return B->IsDerived; }
+};
+
+class PTy {
+  Base *B;
+public:
+  PTy(Base *B) : B(B) {}
+  explicit operator bool() const { return get(); }
+  Base *get() const { return B; }
+};
+
+} // end namespace pointer_wrappers
+} // end namespace
+
+namespace llvm {
+
+template <> struct simplify_type<pointer_wrappers::PTy> {
+  typedef pointer_wrappers::Base *SimpleType;
+  static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
+    return P.get();
+  }
+};
+template <> struct simplify_type<const pointer_wrappers::PTy> {
+  typedef pointer_wrappers::Base *SimpleType;
+  static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
+    return P.get();
+  }
+};
+
+} // end namespace llvm
+
+namespace {
+namespace pointer_wrappers {
+
+// Some objects.
+pointer_wrappers::Base B;
+pointer_wrappers::Derived D;
+
+// Mutable "smart" pointers.
+pointer_wrappers::PTy MN(nullptr);
+pointer_wrappers::PTy MB(&B);
+pointer_wrappers::PTy MD(&D);
+
+// Const "smart" pointers.
+const pointer_wrappers::PTy CN(nullptr);
+const pointer_wrappers::PTy CB(&B);
+const pointer_wrappers::PTy CD(&D);
+
+TEST(CastingTest, smart_isa) {
+  EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
+  EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
+  EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
+  EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
+}
+
+TEST(CastingTest, smart_cast) {
+  EXPECT_TRUE(cast<pointer_wrappers::Derived>(MD) == &D);
+  EXPECT_TRUE(cast<pointer_wrappers::Derived>(CD) == &D);
+}
+
+TEST(CastingTest, smart_cast_or_null) {
+  EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
+  EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
+  EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MD) == &D);
+  EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CD) == &D);
+}
+
+TEST(CastingTest, smart_dyn_cast) {
+  EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MB) == nullptr);
+  EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CB) == nullptr);
+  EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MD) == &D);
+  EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CD) == &D);
+}
+
+TEST(CastingTest, smart_dyn_cast_or_null) {
+  EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
+  EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
+  EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MB) == nullptr);
+  EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CB) == nullptr);
+  EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MD) == &D);
+  EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CD) == &D);
+}
+
+} // end namespace pointer_wrappers
+} // end namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CheckedArithmeticTest.cpp b/src/llvm-project/llvm/unittests/Support/CheckedArithmeticTest.cpp
new file mode 100644
index 0000000..18eee4c
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CheckedArithmeticTest.cpp
@@ -0,0 +1,84 @@
+#include "llvm/Support/CheckedArithmetic.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(CheckedArithmetic, CheckedAdd) {
+  const int64_t Max = std::numeric_limits<int64_t>::max();
+  const int64_t Min = std::numeric_limits<int64_t>::min();
+  EXPECT_EQ(checkedAdd<int64_t>(Max, Max), None);
+  EXPECT_EQ(checkedAdd<int64_t>(Min, -1), None);
+  EXPECT_EQ(checkedAdd<int64_t>(Max, 1), None);
+  EXPECT_EQ(checkedAdd<int64_t>(10, 1), Optional<int64_t>(11));
+}
+
+TEST(CheckedArithmetic, CheckedAddSmall) {
+  const int16_t Max = std::numeric_limits<int16_t>::max();
+  const int16_t Min = std::numeric_limits<int16_t>::min();
+  EXPECT_EQ(checkedAdd<int16_t>(Max, Max), None);
+  EXPECT_EQ(checkedAdd<int16_t>(Min, -1), None);
+  EXPECT_EQ(checkedAdd<int16_t>(Max, 1), None);
+  EXPECT_EQ(checkedAdd<int16_t>(10, 1), Optional<int64_t>(11));
+}
+
+TEST(CheckedArithmetic, CheckedMul) {
+  const int64_t Max = std::numeric_limits<int64_t>::max();
+  const int64_t Min = std::numeric_limits<int64_t>::min();
+  EXPECT_EQ(checkedMul<int64_t>(Max, 2), None);
+  EXPECT_EQ(checkedMul<int64_t>(Max, Max), None);
+  EXPECT_EQ(checkedMul<int64_t>(Min, 2), None);
+  EXPECT_EQ(checkedMul<int64_t>(10, 2), Optional<int64_t>(20));
+}
+
+TEST(CheckedArithmetic, CheckedMulAdd) {
+  const int64_t Max = std::numeric_limits<int64_t>::max();
+  const int64_t Min = std::numeric_limits<int64_t>::min();
+  EXPECT_EQ(checkedMulAdd<int64_t>(Max, 1, 2), None);
+  EXPECT_EQ(checkedMulAdd<int64_t>(1, 1, Max), None);
+  EXPECT_EQ(checkedMulAdd<int64_t>(1, -1, Min), None);
+  EXPECT_EQ(checkedMulAdd<int64_t>(10, 2, 3), Optional<int64_t>(23));
+}
+
+TEST(CheckedArithmetic, CheckedMulSmall) {
+  const int16_t Max = std::numeric_limits<int16_t>::max();
+  const int16_t Min = std::numeric_limits<int16_t>::min();
+  EXPECT_EQ(checkedMul<int16_t>(Max, 2), None);
+  EXPECT_EQ(checkedMul<int16_t>(Max, Max), None);
+  EXPECT_EQ(checkedMul<int16_t>(Min, 2), None);
+  EXPECT_EQ(checkedMul<int16_t>(10, 2), Optional<int16_t>(20));
+}
+
+TEST(CheckedArithmetic, CheckedMulAddSmall) {
+  const int16_t Max = std::numeric_limits<int16_t>::max();
+  const int16_t Min = std::numeric_limits<int16_t>::min();
+  EXPECT_EQ(checkedMulAdd<int16_t>(Max, 1, 2), None);
+  EXPECT_EQ(checkedMulAdd<int16_t>(1, 1, Max), None);
+  EXPECT_EQ(checkedMulAdd<int16_t>(1, -1, Min), None);
+  EXPECT_EQ(checkedMulAdd<int16_t>(10, 2, 3), Optional<int16_t>(23));
+}
+
+TEST(CheckedArithmetic, CheckedAddUnsigned) {
+  const uint64_t Max = std::numeric_limits<uint64_t>::max();
+  EXPECT_EQ(checkedAddUnsigned<uint64_t>(Max, Max), None);
+  EXPECT_EQ(checkedAddUnsigned<uint64_t>(Max, 1), None);
+  EXPECT_EQ(checkedAddUnsigned<uint64_t>(10, 1), Optional<uint64_t>(11));
+}
+
+TEST(CheckedArithmetic, CheckedMulUnsigned) {
+  const uint64_t Max = std::numeric_limits<uint64_t>::max();
+  EXPECT_EQ(checkedMulUnsigned<uint64_t>(Max, 2), llvm::None);
+  EXPECT_EQ(checkedMulUnsigned<uint64_t>(Max, Max), llvm::None);
+  EXPECT_EQ(checkedMulUnsigned<uint64_t>(10, 2), Optional<uint64_t>(20));
+}
+
+TEST(CheckedArithmetic, CheckedMulAddUnsigned) {
+  const uint64_t Max = std::numeric_limits<uint64_t>::max();
+  EXPECT_EQ(checkedMulAddUnsigned<uint64_t>(Max, 1, 2), None);
+  EXPECT_EQ(checkedMulAddUnsigned<uint64_t>(1, 1, Max), None);
+  EXPECT_EQ(checkedMulAddUnsigned<uint64_t>(10, 2, 3), Optional<uint64_t>(23));
+}
+
+
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/Chrono.cpp b/src/llvm-project/llvm/unittests/Support/Chrono.cpp
new file mode 100644
index 0000000..a6b76c8
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/Chrono.cpp
@@ -0,0 +1,112 @@
+//===- llvm/unittest/Support/Chrono.cpp - Time utilities 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/Chrono.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+using namespace std::chrono;
+
+namespace {
+
+TEST(Chrono, TimeTConversion) {
+  EXPECT_EQ(time_t(0), toTimeT(toTimePoint(time_t(0))));
+  EXPECT_EQ(time_t(1), toTimeT(toTimePoint(time_t(1))));
+  EXPECT_EQ(time_t(47), toTimeT(toTimePoint(time_t(47))));
+
+  TimePoint<> TP;
+  EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
+  TP += seconds(1);
+  EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
+  TP += hours(47);
+  EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
+}
+
+TEST(Chrono, TimePointFormat) {
+  using namespace std::chrono;
+  struct tm TM {};
+  TM.tm_year = 106;
+  TM.tm_mon = 0;
+  TM.tm_mday = 2;
+  TM.tm_hour = 15;
+  TM.tm_min = 4;
+  TM.tm_sec = 5;
+  TM.tm_isdst = -1;
+  TimePoint<> T =
+      system_clock::from_time_t(mktime(&TM)) + nanoseconds(123456789);
+
+  // operator<< uses the format YYYY-MM-DD HH:MM:SS.NNNNNNNNN
+  std::string S;
+  raw_string_ostream OS(S);
+  OS << T;
+  EXPECT_EQ("2006-01-02 15:04:05.123456789", OS.str());
+
+  // formatv default style matches operator<<.
+  EXPECT_EQ("2006-01-02 15:04:05.123456789", formatv("{0}", T).str());
+  // formatv supports strftime-style format strings.
+  EXPECT_EQ("15:04:05", formatv("{0:%H:%M:%S}", T).str());
+  // formatv supports our strftime extensions for sub-second precision.
+  EXPECT_EQ("123", formatv("{0:%L}", T).str());
+  EXPECT_EQ("123456", formatv("{0:%f}", T).str());
+  EXPECT_EQ("123456789", formatv("{0:%N}", T).str());
+  // our extensions don't interfere with %% escaping.
+  EXPECT_EQ("%foo", formatv("{0:%%foo}", T).str());
+}
+
+// Test that toTimePoint and toTimeT can be called with a arguments with varying
+// precisions.
+TEST(Chrono, ImplicitConversions) {
+  std::time_t TimeT = 47;
+  TimePoint<seconds> Sec = toTimePoint(TimeT);
+  TimePoint<milliseconds> Milli = toTimePoint(TimeT);
+  TimePoint<microseconds> Micro = toTimePoint(TimeT);
+  TimePoint<nanoseconds> Nano = toTimePoint(TimeT);
+  EXPECT_EQ(Sec, Milli);
+  EXPECT_EQ(Sec, Micro);
+  EXPECT_EQ(Sec, Nano);
+  EXPECT_EQ(TimeT, toTimeT(Sec));
+  EXPECT_EQ(TimeT, toTimeT(Milli));
+  EXPECT_EQ(TimeT, toTimeT(Micro));
+  EXPECT_EQ(TimeT, toTimeT(Nano));
+}
+
+TEST(Chrono, DurationFormat) {
+  EXPECT_EQ("1 h", formatv("{0}", hours(1)).str());
+  EXPECT_EQ("1 m", formatv("{0}", minutes(1)).str());
+  EXPECT_EQ("1 s", formatv("{0}", seconds(1)).str());
+  EXPECT_EQ("1 ms", formatv("{0}", milliseconds(1)).str());
+  EXPECT_EQ("1 us", formatv("{0}", microseconds(1)).str());
+  EXPECT_EQ("1 ns", formatv("{0}", nanoseconds(1)).str());
+
+  EXPECT_EQ("1 s", formatv("{0:+}", seconds(1)).str());
+  EXPECT_EQ("1", formatv("{0:-}", seconds(1)).str());
+
+  EXPECT_EQ("1000 ms", formatv("{0:ms}", seconds(1)).str());
+  EXPECT_EQ("1000000 us", formatv("{0:us}", seconds(1)).str());
+  EXPECT_EQ("1000", formatv("{0:ms-}", seconds(1)).str());
+
+  EXPECT_EQ("1,000 ms", formatv("{0:+n}", milliseconds(1000)).str());
+  EXPECT_EQ("0x3e8", formatv("{0:-x}", milliseconds(1000)).str());
+  EXPECT_EQ("010", formatv("{0:-3}", milliseconds(10)).str());
+  EXPECT_EQ("10,000", formatv("{0:ms-n}", seconds(10)).str());
+
+  EXPECT_EQ("1.00 s", formatv("{0}", duration<float>(1)).str());
+  EXPECT_EQ("0.123 s", formatv("{0:+3}", duration<float>(0.123f)).str());
+  EXPECT_EQ("1.230e-01 s", formatv("{0:+e3}", duration<float>(0.123f)).str());
+
+  typedef duration<float, std::ratio<60 * 60 * 24 * 14, 1000000>>
+      microfortnights;
+  EXPECT_EQ("1.00", formatv("{0:-}", microfortnights(1)).str());
+  EXPECT_EQ("1209.60 ms", formatv("{0:ms}", microfortnights(1)).str());
+}
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
new file mode 100644
index 0000000..9d06f72
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
@@ -0,0 +1,917 @@
+//===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine 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/CommandLine.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/StringSaver.h"
+#include "gtest/gtest.h"
+#include <fstream>
+#include <stdlib.h>
+#include <string>
+
+using namespace llvm;
+
+namespace {
+
+class TempEnvVar {
+ public:
+  TempEnvVar(const char *name, const char *value)
+      : name(name) {
+    const char *old_value = getenv(name);
+    EXPECT_EQ(nullptr, old_value) << old_value;
+#if HAVE_SETENV
+    setenv(name, value, true);
+#else
+#   define SKIP_ENVIRONMENT_TESTS
+#endif
+  }
+
+  ~TempEnvVar() {
+#if HAVE_SETENV
+    // Assume setenv and unsetenv come together.
+    unsetenv(name);
+#else
+    (void)name; // Suppress -Wunused-private-field.
+#endif
+  }
+
+ private:
+  const char *const name;
+};
+
+template <typename T, typename Base = cl::opt<T>>
+class StackOption : public Base {
+public:
+  template <class... Ts>
+  explicit StackOption(Ts &&... Ms) : Base(std::forward<Ts>(Ms)...) {}
+
+  ~StackOption() override { this->removeArgument(); }
+
+  template <class DT> StackOption<T> &operator=(const DT &V) {
+    this->setValue(V);
+    return *this;
+  }
+};
+
+class StackSubCommand : public cl::SubCommand {
+public:
+  StackSubCommand(StringRef Name,
+                  StringRef Description = StringRef())
+      : SubCommand(Name, Description) {}
+
+  StackSubCommand() : SubCommand() {}
+
+  ~StackSubCommand() { unregisterSubCommand(); }
+};
+
+
+cl::OptionCategory TestCategory("Test Options", "Description");
+TEST(CommandLineTest, ModifyExisitingOption) {
+  StackOption<int> TestOption("test-option", cl::desc("old description"));
+
+  static const char Description[] = "New description";
+  static const char ArgString[] = "new-test-option";
+  static const char ValueString[] = "Integer";
+
+  StringMap<cl::Option *> &Map =
+      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
+
+  ASSERT_TRUE(Map.count("test-option") == 1) <<
+    "Could not find option in map.";
+
+  cl::Option *Retrieved = Map["test-option"];
+  ASSERT_EQ(&TestOption, Retrieved) << "Retrieved wrong option.";
+
+  ASSERT_EQ(&cl::GeneralCategory,Retrieved->Category) <<
+    "Incorrect default option category.";
+
+  Retrieved->setCategory(TestCategory);
+  ASSERT_EQ(&TestCategory,Retrieved->Category) <<
+    "Failed to modify option's option category.";
+
+  Retrieved->setDescription(Description);
+  ASSERT_STREQ(Retrieved->HelpStr.data(), Description)
+      << "Changing option description failed.";
+
+  Retrieved->setArgStr(ArgString);
+  ASSERT_STREQ(ArgString, Retrieved->ArgStr.data())
+      << "Failed to modify option's Argument string.";
+
+  Retrieved->setValueStr(ValueString);
+  ASSERT_STREQ(Retrieved->ValueStr.data(), ValueString)
+      << "Failed to modify option's Value string.";
+
+  Retrieved->setHiddenFlag(cl::Hidden);
+  ASSERT_EQ(cl::Hidden, TestOption.getOptionHiddenFlag()) <<
+    "Failed to modify option's hidden flag.";
+}
+#ifndef SKIP_ENVIRONMENT_TESTS
+
+const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS";
+
+cl::opt<std::string> EnvironmentTestOption("env-test-opt");
+TEST(CommandLineTest, ParseEnvironment) {
+  TempEnvVar TEV(test_env_var, "-env-test-opt=hello");
+  EXPECT_EQ("", EnvironmentTestOption);
+  cl::ParseEnvironmentOptions("CommandLineTest", test_env_var);
+  EXPECT_EQ("hello", EnvironmentTestOption);
+}
+
+// This test used to make valgrind complain
+// ("Conditional jump or move depends on uninitialised value(s)")
+//
+// Warning: Do not run any tests after this one that try to gain access to
+// registered command line options because this will likely result in a
+// SEGFAULT. This can occur because the cl::opt in the test below is declared
+// on the stack which will be destroyed after the test completes but the
+// command line system will still hold a pointer to a deallocated cl::Option.
+TEST(CommandLineTest, ParseEnvironmentToLocalVar) {
+  // Put cl::opt on stack to check for proper initialization of fields.
+  StackOption<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
+
+TEST(CommandLineTest, UseOptionCategory) {
+  StackOption<int> TestOption2("test-option", cl::cat(TestCategory));
+
+  ASSERT_EQ(&TestCategory,TestOption2.Category) << "Failed to assign Option "
+                                                  "Category.";
+}
+
+typedef void ParserFunction(StringRef Source, StringSaver &Saver,
+                            SmallVectorImpl<const char *> &NewArgv,
+                            bool MarkEOLs);
+
+void testCommandLineTokenizer(ParserFunction *parse, StringRef Input,
+                              const char *const Output[], size_t OutputSize) {
+  SmallVector<const char *, 0> Actual;
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  parse(Input, Saver, Actual, /*MarkEOLs=*/false);
+  EXPECT_EQ(OutputSize, Actual.size());
+  for (unsigned I = 0, E = Actual.size(); I != E; ++I) {
+    if (I < OutputSize) {
+      EXPECT_STREQ(Output[I], Actual[I]);
+    }
+  }
+}
+
+TEST(CommandLineTest, TokenizeGNUCommandLine) {
+  const char Input[] =
+      "foo\\ bar \"foo bar\" \'foo bar\' 'foo\\\\bar' -DFOO=bar\\(\\) "
+      "foo\"bar\"baz C:\\\\src\\\\foo.cpp \"C:\\src\\foo.cpp\"";
+  const char *const Output[] = {
+      "foo bar",     "foo bar",   "foo bar",          "foo\\bar",
+      "-DFOO=bar()", "foobarbaz", "C:\\src\\foo.cpp", "C:srcfoo.cpp"};
+  testCommandLineTokenizer(cl::TokenizeGNUCommandLine, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeWindowsCommandLine) {
+  const char Input[] = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr "
+                      "\"st \\\"u\" \\v";
+  const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k",
+                                 "lmn", "o", "pqr", "st \"u", "\\v" };
+  testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile1) {
+  const char *Input = "\\";
+  const char *const Output[] = { "\\" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile2) {
+  const char *Input = "\\abc";
+  const char *const Output[] = { "abc" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile3) {
+  const char *Input = "abc\\";
+  const char *const Output[] = { "abc\\" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile4) {
+  const char *Input = "abc\\\n123";
+  const char *const Output[] = { "abc123" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile5) {
+  const char *Input = "abc\\\r\n123";
+  const char *const Output[] = { "abc123" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile6) {
+  const char *Input = "abc\\\n";
+  const char *const Output[] = { "abc" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile7) {
+  const char *Input = "abc\\\r\n";
+  const char *const Output[] = { "abc" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile8) {
+  SmallVector<const char *, 0> Actual;
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  cl::tokenizeConfigFile("\\\n", Saver, Actual, /*MarkEOLs=*/false);
+  EXPECT_TRUE(Actual.empty());
+}
+
+TEST(CommandLineTest, TokenizeConfigFile9) {
+  SmallVector<const char *, 0> Actual;
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  cl::tokenizeConfigFile("\\\r\n", Saver, Actual, /*MarkEOLs=*/false);
+  EXPECT_TRUE(Actual.empty());
+}
+
+TEST(CommandLineTest, TokenizeConfigFile10) {
+  const char *Input = "\\\nabc";
+  const char *const Output[] = { "abc" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, TokenizeConfigFile11) {
+  const char *Input = "\\\r\nabc";
+  const char *const Output[] = { "abc" };
+  testCommandLineTokenizer(cl::tokenizeConfigFile, Input, Output,
+                           array_lengthof(Output));
+}
+
+TEST(CommandLineTest, AliasesWithArguments) {
+  static const size_t ARGC = 3;
+  const char *const Inputs[][ARGC] = {
+    { "-tool", "-actual=x", "-extra" },
+    { "-tool", "-actual", "x" },
+    { "-tool", "-alias=x", "-extra" },
+    { "-tool", "-alias", "x" }
+  };
+
+  for (size_t i = 0, e = array_lengthof(Inputs); i < e; ++i) {
+    StackOption<std::string> Actual("actual");
+    StackOption<bool> Extra("extra");
+    StackOption<std::string> Input(cl::Positional);
+
+    cl::alias Alias("alias", llvm::cl::aliasopt(Actual));
+
+    cl::ParseCommandLineOptions(ARGC, Inputs[i]);
+    EXPECT_EQ("x", Actual);
+    EXPECT_EQ(0, Input.getNumOccurrences());
+
+    Alias.removeArgument();
+  }
+}
+
+void testAliasRequired(int argc, const char *const *argv) {
+  StackOption<std::string> Option("option", cl::Required);
+  cl::alias Alias("o", llvm::cl::aliasopt(Option));
+
+  cl::ParseCommandLineOptions(argc, argv);
+  EXPECT_EQ("x", Option);
+  EXPECT_EQ(1, Option.getNumOccurrences());
+
+  Alias.removeArgument();
+}
+
+TEST(CommandLineTest, AliasRequired) {
+  const char *opts1[] = { "-tool", "-option=x" };
+  const char *opts2[] = { "-tool", "-o", "x" };
+  testAliasRequired(array_lengthof(opts1), opts1);
+  testAliasRequired(array_lengthof(opts2), opts2);
+}
+
+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(*cl::TopLevelSubCommand);
+  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(*cl::TopLevelSubCommand);
+  ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
+      << "Hid default option that should be visable.";
+}
+
+TEST(CommandLineTest, SetValueInSubcategories) {
+  cl::ResetCommandLineParser();
+
+  StackSubCommand SC1("sc1", "First subcommand");
+  StackSubCommand SC2("sc2", "Second subcommand");
+
+  StackOption<bool> TopLevelOpt("top-level", cl::init(false));
+  StackOption<bool> SC1Opt("sc1", cl::sub(SC1), cl::init(false));
+  StackOption<bool> SC2Opt("sc2", cl::sub(SC2), cl::init(false));
+
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_FALSE(SC1Opt);
+  EXPECT_FALSE(SC2Opt);
+  const char *args[] = {"prog", "-top-level"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(TopLevelOpt);
+  EXPECT_FALSE(SC1Opt);
+  EXPECT_FALSE(SC2Opt);
+
+  TopLevelOpt = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_FALSE(SC1Opt);
+  EXPECT_FALSE(SC2Opt);
+  const char *args2[] = {"prog", "sc1", "-sc1"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_TRUE(SC1Opt);
+  EXPECT_FALSE(SC2Opt);
+
+  SC1Opt = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_FALSE(SC1Opt);
+  EXPECT_FALSE(SC2Opt);
+  const char *args3[] = {"prog", "sc2", "-sc2"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args3, StringRef(), &llvm::nulls()));
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_FALSE(SC1Opt);
+  EXPECT_TRUE(SC2Opt);
+}
+
+TEST(CommandLineTest, LookupFailsInWrongSubCommand) {
+  cl::ResetCommandLineParser();
+
+  StackSubCommand SC1("sc1", "First subcommand");
+  StackSubCommand SC2("sc2", "Second subcommand");
+
+  StackOption<bool> SC1Opt("sc1", cl::sub(SC1), cl::init(false));
+  StackOption<bool> SC2Opt("sc2", cl::sub(SC2), cl::init(false));
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  const char *args[] = {"prog", "sc1", "-sc2"};
+  EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, StringRef(), &OS));
+  OS.flush();
+  EXPECT_FALSE(Errs.empty());
+}
+
+TEST(CommandLineTest, AddToAllSubCommands) {
+  cl::ResetCommandLineParser();
+
+  StackSubCommand SC1("sc1", "First subcommand");
+  StackOption<bool> AllOpt("everywhere", cl::sub(*cl::AllSubCommands),
+                           cl::init(false));
+  StackSubCommand SC2("sc2", "Second subcommand");
+
+  const char *args[] = {"prog", "-everywhere"};
+  const char *args2[] = {"prog", "sc1", "-everywhere"};
+  const char *args3[] = {"prog", "sc2", "-everywhere"};
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  EXPECT_FALSE(AllOpt);
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, StringRef(), &OS));
+  EXPECT_TRUE(AllOpt);
+
+  AllOpt = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(AllOpt);
+  EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, StringRef(), &OS));
+  EXPECT_TRUE(AllOpt);
+
+  AllOpt = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(AllOpt);
+  EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, StringRef(), &OS));
+  EXPECT_TRUE(AllOpt);
+
+  // Since all parsing succeeded, the error message should be empty.
+  OS.flush();
+  EXPECT_TRUE(Errs.empty());
+}
+
+TEST(CommandLineTest, ReparseCommandLineOptions) {
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> TopLevelOpt("top-level", cl::sub(*cl::TopLevelSubCommand),
+                                cl::init(false));
+
+  const char *args[] = {"prog", "-top-level"};
+
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(TopLevelOpt);
+
+  TopLevelOpt = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(TopLevelOpt);
+}
+
+TEST(CommandLineTest, RemoveFromRegularSubCommand) {
+  cl::ResetCommandLineParser();
+
+  StackSubCommand SC("sc", "Subcommand");
+  StackOption<bool> RemoveOption("remove-option", cl::sub(SC), cl::init(false));
+  StackOption<bool> KeepOption("keep-option", cl::sub(SC), cl::init(false));
+
+  const char *args[] = {"prog", "sc", "-remove-option"};
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  EXPECT_FALSE(RemoveOption);
+  EXPECT_TRUE(cl::ParseCommandLineOptions(3, args, StringRef(), &OS));
+  EXPECT_TRUE(RemoveOption);
+  OS.flush();
+  EXPECT_TRUE(Errs.empty());
+
+  RemoveOption.removeArgument();
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, StringRef(), &OS));
+  OS.flush();
+  EXPECT_FALSE(Errs.empty());
+}
+
+TEST(CommandLineTest, RemoveFromTopLevelSubCommand) {
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> TopLevelRemove(
+      "top-level-remove", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
+  StackOption<bool> TopLevelKeep(
+      "top-level-keep", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
+
+  const char *args[] = {"prog", "-top-level-remove"};
+
+  EXPECT_FALSE(TopLevelRemove);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(TopLevelRemove);
+
+  TopLevelRemove.removeArgument();
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+}
+
+TEST(CommandLineTest, RemoveFromAllSubCommands) {
+  cl::ResetCommandLineParser();
+
+  StackSubCommand SC1("sc1", "First Subcommand");
+  StackSubCommand SC2("sc2", "Second Subcommand");
+  StackOption<bool> RemoveOption("remove-option", cl::sub(*cl::AllSubCommands),
+                                 cl::init(false));
+  StackOption<bool> KeepOption("keep-option", cl::sub(*cl::AllSubCommands),
+                               cl::init(false));
+
+  const char *args0[] = {"prog", "-remove-option"};
+  const char *args1[] = {"prog", "sc1", "-remove-option"};
+  const char *args2[] = {"prog", "sc2", "-remove-option"};
+
+  // It should work for all subcommands including the top-level.
+  EXPECT_FALSE(RemoveOption);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args0, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(RemoveOption);
+
+  RemoveOption = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(RemoveOption);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args1, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(RemoveOption);
+
+  RemoveOption = false;
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(RemoveOption);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(RemoveOption);
+
+  RemoveOption.removeArgument();
+
+  // It should not work for any subcommands including the top-level.
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(2, args0, StringRef(), &llvm::nulls()));
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(3, args1, StringRef(), &llvm::nulls()));
+  cl::ResetAllOptionOccurrences();
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+}
+
+TEST(CommandLineTest, GetRegisteredSubcommands) {
+  cl::ResetCommandLineParser();
+
+  StackSubCommand SC1("sc1", "First Subcommand");
+  StackOption<bool> Opt1("opt1", cl::sub(SC1), cl::init(false));
+  StackSubCommand SC2("sc2", "Second subcommand");
+  StackOption<bool> Opt2("opt2", cl::sub(SC2), cl::init(false));
+
+  const char *args0[] = {"prog", "sc1"};
+  const char *args1[] = {"prog", "sc2"};
+
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args0, StringRef(), &llvm::nulls()));
+  EXPECT_FALSE(Opt1);
+  EXPECT_FALSE(Opt2);
+  for (auto *S : cl::getRegisteredSubcommands()) {
+    if (*S) {
+      EXPECT_EQ("sc1", S->getName());
+    }
+  }
+
+  cl::ResetAllOptionOccurrences();
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args1, StringRef(), &llvm::nulls()));
+  EXPECT_FALSE(Opt1);
+  EXPECT_FALSE(Opt2);
+  for (auto *S : cl::getRegisteredSubcommands()) {
+    if (*S) {
+      EXPECT_EQ("sc2", S->getName());
+    }
+  }
+}
+
+TEST(CommandLineTest, ArgumentLimit) {
+  std::string args(32 * 4096, 'a');
+  EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data()));
+}
+
+TEST(CommandLineTest, ResponseFileWindows) {
+  if (!Triple(sys::getProcessTriple()).isOSWindows())
+    return;
+
+  StackOption<std::string, cl::list<std::string>> InputFilenames(
+      cl::Positional, cl::desc("<input files>"), cl::ZeroOrMore);
+  StackOption<bool> TopLevelOpt("top-level", cl::init(false));
+
+  // Create response file.
+  int FileDescriptor;
+  SmallString<64> TempPath;
+  std::error_code EC =
+      llvm::sys::fs::createTemporaryFile("resp-", ".txt", FileDescriptor, TempPath);
+  EXPECT_TRUE(!EC);
+
+  std::ofstream RspFile(TempPath.c_str());
+  EXPECT_TRUE(RspFile.is_open());
+  RspFile << "-top-level\npath\\dir\\file1\npath/dir/file2";
+  RspFile.close();
+
+  llvm::SmallString<128> RspOpt;
+  RspOpt.append(1, '@');
+  RspOpt.append(TempPath.c_str());
+  const char *args[] = {"prog", RspOpt.c_str()};
+  EXPECT_FALSE(TopLevelOpt);
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(TopLevelOpt);
+  EXPECT_TRUE(InputFilenames[0] == "path\\dir\\file1");
+  EXPECT_TRUE(InputFilenames[1] == "path/dir/file2");
+
+  llvm::sys::fs::remove(TempPath.c_str());
+}
+
+TEST(CommandLineTest, ResponseFiles) {
+  llvm::SmallString<128> TestDir;
+  std::error_code EC =
+    llvm::sys::fs::createUniqueDirectory("unittest", TestDir);
+  EXPECT_TRUE(!EC);
+
+  // Create included response file of first level.
+  llvm::SmallString<128> IncludedFileName;
+  llvm::sys::path::append(IncludedFileName, TestDir, "resp1");
+  std::ofstream IncludedFile(IncludedFileName.c_str());
+  EXPECT_TRUE(IncludedFile.is_open());
+  IncludedFile << "-option_1 -option_2\n"
+                  "@incdir/resp2\n"
+                  "-option_3=abcd\n";
+  IncludedFile.close();
+
+  // Directory for included file.
+  llvm::SmallString<128> IncDir;
+  llvm::sys::path::append(IncDir, TestDir, "incdir");
+  EC = llvm::sys::fs::create_directory(IncDir);
+  EXPECT_TRUE(!EC);
+
+  // Create included response file of second level.
+  llvm::SmallString<128> IncludedFileName2;
+  llvm::sys::path::append(IncludedFileName2, IncDir, "resp2");
+  std::ofstream IncludedFile2(IncludedFileName2.c_str());
+  EXPECT_TRUE(IncludedFile2.is_open());
+  IncludedFile2 << "-option_21 -option_22\n";
+  IncludedFile2 << "-option_23=abcd\n";
+  IncludedFile2.close();
+
+  // Prepare 'file' with reference to response file.
+  SmallString<128> IncRef;
+  IncRef.append(1, '@');
+  IncRef.append(IncludedFileName.c_str());
+  llvm::SmallVector<const char *, 4> Argv =
+                          { "test/test", "-flag_1", IncRef.c_str(), "-flag_2" };
+
+  // Expand response files.
+  llvm::BumpPtrAllocator A;
+  llvm::StringSaver Saver(A);
+  bool Res = llvm::cl::ExpandResponseFiles(
+                    Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true);
+  EXPECT_TRUE(Res);
+  EXPECT_EQ(Argv.size(), 9U);
+  EXPECT_STREQ(Argv[0], "test/test");
+  EXPECT_STREQ(Argv[1], "-flag_1");
+  EXPECT_STREQ(Argv[2], "-option_1");
+  EXPECT_STREQ(Argv[3], "-option_2");
+  EXPECT_STREQ(Argv[4], "-option_21");
+  EXPECT_STREQ(Argv[5], "-option_22");
+  EXPECT_STREQ(Argv[6], "-option_23=abcd");
+  EXPECT_STREQ(Argv[7], "-option_3=abcd");
+  EXPECT_STREQ(Argv[8], "-flag_2");
+
+  llvm::sys::fs::remove(IncludedFileName2);
+  llvm::sys::fs::remove(IncDir);
+  llvm::sys::fs::remove(IncludedFileName);
+  llvm::sys::fs::remove(TestDir);
+}
+
+TEST(CommandLineTest, SetDefautValue) {
+  cl::ResetCommandLineParser();
+
+  StackOption<std::string> Opt1("opt1", cl::init("true"));
+  StackOption<bool> Opt2("opt2", cl::init(true));
+  cl::alias Alias("alias", llvm::cl::aliasopt(Opt2));
+  StackOption<int> Opt3("opt3", cl::init(3));
+
+  const char *args[] = {"prog", "-opt1=false", "-opt2", "-opt3"};
+
+  EXPECT_TRUE(
+    cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+
+  EXPECT_TRUE(Opt1 == "false");
+  EXPECT_TRUE(Opt2);
+  EXPECT_TRUE(Opt3 == 3);
+
+  Opt2 = false;
+  Opt3 = 1;
+
+  cl::ResetAllOptionOccurrences();
+
+  for (auto &OM : cl::getRegisteredOptions(*cl::TopLevelSubCommand)) {
+    cl::Option *O = OM.second;
+    if (O->ArgStr == "opt2") {
+      continue;
+    }
+    O->setDefault();
+  }
+
+  EXPECT_TRUE(Opt1 == "true");
+  EXPECT_TRUE(Opt2);
+  EXPECT_TRUE(Opt3 == 3);
+  Alias.removeArgument();
+}
+
+TEST(CommandLineTest, ReadConfigFile) {
+  llvm::SmallVector<const char *, 1> Argv;
+
+  llvm::SmallString<128> TestDir;
+  std::error_code EC =
+      llvm::sys::fs::createUniqueDirectory("unittest", TestDir);
+  EXPECT_TRUE(!EC);
+
+  llvm::SmallString<128> TestCfg;
+  llvm::sys::path::append(TestCfg, TestDir, "foo");
+  std::ofstream ConfigFile(TestCfg.c_str());
+  EXPECT_TRUE(ConfigFile.is_open());
+  ConfigFile << "# Comment\n"
+                "-option_1\n"
+                "@subconfig\n"
+                "-option_3=abcd\n"
+                "-option_4=\\\n"
+                "cdef\n";
+  ConfigFile.close();
+
+  llvm::SmallString<128> TestCfg2;
+  llvm::sys::path::append(TestCfg2, TestDir, "subconfig");
+  std::ofstream ConfigFile2(TestCfg2.c_str());
+  EXPECT_TRUE(ConfigFile2.is_open());
+  ConfigFile2 << "-option_2\n"
+                 "\n"
+                 "   # comment\n";
+  ConfigFile2.close();
+
+  // Make sure the current directory is not the directory where config files
+  // resides. In this case the code that expands response files will not find
+  // 'subconfig' unless it resolves nested inclusions relative to the including
+  // file.
+  llvm::SmallString<128> CurrDir;
+  EC = llvm::sys::fs::current_path(CurrDir);
+  EXPECT_TRUE(!EC);
+  EXPECT_TRUE(StringRef(CurrDir) != StringRef(TestDir));
+
+  llvm::BumpPtrAllocator A;
+  llvm::StringSaver Saver(A);
+  bool Result = llvm::cl::readConfigFile(TestCfg, Saver, Argv);
+
+  EXPECT_TRUE(Result);
+  EXPECT_EQ(Argv.size(), 4U);
+  EXPECT_STREQ(Argv[0], "-option_1");
+  EXPECT_STREQ(Argv[1], "-option_2");
+  EXPECT_STREQ(Argv[2], "-option_3=abcd");
+  EXPECT_STREQ(Argv[3], "-option_4=cdef");
+
+  llvm::sys::fs::remove(TestCfg2);
+  llvm::sys::fs::remove(TestCfg);
+  llvm::sys::fs::remove(TestDir);
+}
+
+TEST(CommandLineTest, PositionalEatArgsError) {
+  StackOption<std::string, cl::list<std::string>> PosEatArgs(
+      "positional-eat-args", cl::Positional, cl::desc("<arguments>..."),
+      cl::ZeroOrMore, cl::PositionalEatsArgs);
+
+  const char *args[] = {"prog", "-positional-eat-args=XXXX"};
+  const char *args2[] = {"prog", "-positional-eat-args=XXXX", "-foo"};
+  const char *args3[] = {"prog", "-positional-eat-args", "-foo"};
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+  EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, StringRef(), &OS)); OS.flush();
+  EXPECT_FALSE(Errs.empty()); Errs.clear();
+  EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, StringRef(), &OS)); OS.flush();
+  EXPECT_FALSE(Errs.empty()); Errs.clear();
+  EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, StringRef(), &OS)); OS.flush();
+  EXPECT_TRUE(Errs.empty());
+}
+
+#ifdef _WIN32
+TEST(CommandLineTest, GetCommandLineArguments) {
+  int argc = __argc;
+  char **argv = __argv;
+
+  // GetCommandLineArguments is called in InitLLVM.
+  llvm::InitLLVM X(argc, argv);
+
+  EXPECT_EQ(llvm::sys::path::is_absolute(argv[0]),
+            llvm::sys::path::is_absolute(__argv[0]));
+
+  EXPECT_TRUE(llvm::sys::path::filename(argv[0])
+              .equals_lower("supporttests.exe"))
+      << "Filename of test executable is "
+      << llvm::sys::path::filename(argv[0]);
+}
+#endif
+
+TEST(CommandLineTest, PrefixOptions) {
+  cl::ResetCommandLineParser();
+
+  StackOption<std::string, cl::list<std::string>> IncludeDirs(
+      "I", cl::Prefix, cl::desc("Declare an include directory"));
+
+  // Test non-prefixed variant works with cl::Prefix options.
+  EXPECT_TRUE(IncludeDirs.empty());
+  const char *args[] = {"prog", "-I=/usr/include"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(IncludeDirs.size() == 1);
+  EXPECT_TRUE(IncludeDirs.front().compare("/usr/include") == 0);
+
+  IncludeDirs.erase(IncludeDirs.begin());
+  cl::ResetAllOptionOccurrences();
+
+  // Test non-prefixed variant works with cl::Prefix options when value is
+  // passed in following argument.
+  EXPECT_TRUE(IncludeDirs.empty());
+  const char *args2[] = {"prog", "-I", "/usr/include"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(IncludeDirs.size() == 1);
+  EXPECT_TRUE(IncludeDirs.front().compare("/usr/include") == 0);
+
+  IncludeDirs.erase(IncludeDirs.begin());
+  cl::ResetAllOptionOccurrences();
+
+  // Test prefixed variant works with cl::Prefix options.
+  EXPECT_TRUE(IncludeDirs.empty());
+  const char *args3[] = {"prog", "-I/usr/include"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args3, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(IncludeDirs.size() == 1);
+  EXPECT_TRUE(IncludeDirs.front().compare("/usr/include") == 0);
+
+  StackOption<std::string, cl::list<std::string>> MacroDefs(
+      "D", cl::AlwaysPrefix, cl::desc("Define a macro"),
+      cl::value_desc("MACRO[=VALUE]"));
+
+  cl::ResetAllOptionOccurrences();
+
+  // Test non-prefixed variant does not work with cl::AlwaysPrefix options:
+  // equal sign is part of the value.
+  EXPECT_TRUE(MacroDefs.empty());
+  const char *args4[] = {"prog", "-D=HAVE_FOO"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args4, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(MacroDefs.size() == 1);
+  EXPECT_TRUE(MacroDefs.front().compare("=HAVE_FOO") == 0);
+
+  MacroDefs.erase(MacroDefs.begin());
+  cl::ResetAllOptionOccurrences();
+
+  // Test non-prefixed variant does not allow value to be passed in following
+  // argument with cl::AlwaysPrefix options.
+  EXPECT_TRUE(MacroDefs.empty());
+  const char *args5[] = {"prog", "-D", "HAVE_FOO"};
+  EXPECT_FALSE(
+      cl::ParseCommandLineOptions(3, args5, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(MacroDefs.empty());
+
+  cl::ResetAllOptionOccurrences();
+
+  // Test prefixed variant works with cl::AlwaysPrefix options.
+  EXPECT_TRUE(MacroDefs.empty());
+  const char *args6[] = {"prog", "-DHAVE_FOO"};
+  EXPECT_TRUE(
+      cl::ParseCommandLineOptions(2, args6, StringRef(), &llvm::nulls()));
+  EXPECT_TRUE(MacroDefs.size() == 1);
+  EXPECT_TRUE(MacroDefs.front().compare("HAVE_FOO") == 0);
+}
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp b/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
new file mode 100644
index 0000000..e9f36c5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CompressionTest.cpp
@@ -0,0 +1,77 @@
+//===- llvm/unittest/Support/CompressionTest.cpp - Compression tests ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for the Compression functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Compression.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
+
+void TestZlibCompression(StringRef Input, int Level) {
+  SmallString<32> Compressed;
+  SmallString<32> Uncompressed;
+
+  Error E = zlib::compress(Input, Compressed, Level);
+  EXPECT_FALSE(E);
+  consumeError(std::move(E));
+
+  // Check that uncompressed buffer is the same as original.
+  E = zlib::uncompress(Compressed, Uncompressed, Input.size());
+  EXPECT_FALSE(E);
+  consumeError(std::move(E));
+
+  EXPECT_EQ(Input, Uncompressed);
+  if (Input.size() > 0) {
+    // Uncompression fails if expected length is too short.
+    E = zlib::uncompress(Compressed, Uncompressed, Input.size() - 1);
+    EXPECT_EQ("zlib error: Z_BUF_ERROR", llvm::toString(std::move(E)));
+  }
+}
+
+TEST(CompressionTest, Zlib) {
+  TestZlibCompression("", zlib::DefaultCompression);
+
+  TestZlibCompression("hello, world!", zlib::NoCompression);
+  TestZlibCompression("hello, world!", zlib::BestSizeCompression);
+  TestZlibCompression("hello, world!", zlib::BestSpeedCompression);
+  TestZlibCompression("hello, world!", zlib::DefaultCompression);
+
+  const size_t kSize = 1024;
+  char BinaryData[kSize];
+  for (size_t i = 0; i < kSize; ++i) {
+    BinaryData[i] = i & 255;
+  }
+  StringRef BinaryDataStr(BinaryData, kSize);
+
+  TestZlibCompression(BinaryDataStr, zlib::NoCompression);
+  TestZlibCompression(BinaryDataStr, zlib::BestSizeCompression);
+  TestZlibCompression(BinaryDataStr, zlib::BestSpeedCompression);
+  TestZlibCompression(BinaryDataStr, zlib::DefaultCompression);
+}
+
+TEST(CompressionTest, ZlibCRC32) {
+  EXPECT_EQ(
+      0x414FA339U,
+      zlib::crc32(StringRef("The quick brown fox jumps over the lazy dog")));
+}
+
+#endif
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp b/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
new file mode 100644
index 0000000..dd6e0df
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ConvertUTFTest.cpp
@@ -0,0 +1,1712 @@
+//===- llvm/unittest/Support/ConvertUTFTest.cpp - ConvertUTF 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/ConvertUTF.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <vector>
+
+using namespace llvm;
+
+TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) {
+  // Src is the look of disapproval.
+  static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef<char> Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF16ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
+  // Src is the look of disapproval.
+  static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+  ArrayRef<char> Ref(Src, sizeof(Src) - 1);
+  std::string Result;
+  bool Success = convertUTF16ToUTF8String(Ref, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  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);
+  EXPECT_FALSE(Success);
+}
+
+TEST(ConvertUTFTest, Empty) {
+  std::string Result;
+  bool Success = convertUTF16ToUTF8String(llvm::ArrayRef<char>(None), Result);
+  EXPECT_TRUE(Success);
+  EXPECT_TRUE(Result.empty());
+}
+
+TEST(ConvertUTFTest, HasUTF16BOM) {
+  bool HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xff\xfe", 2));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff", 2));
+  EXPECT_TRUE(HasBOM);
+  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff ", 3));
+  EXPECT_TRUE(HasBOM); // Don't care about odd lengths.
+  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff\x00asdf", 6));
+  EXPECT_TRUE(HasBOM);
+
+  HasBOM = hasUTF16ByteOrderMark(None);
+  EXPECT_FALSE(HasBOM);
+  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe", 1));
+  EXPECT_FALSE(HasBOM);
+}
+
+TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
+  // Src is the look of disapproval.
+  static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+  ArrayRef<UTF16> SrcRef = makeArrayRef((const UTF16 *)Src, 4);
+  std::string Result;
+  bool Success = convertUTF16ToUTF8String(SrcRef, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, ConvertUTF8toWide) {
+  // Src is the look of disapproval.
+  static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
+  std::wstring Result;
+  bool Success = ConvertUTF8toWide((const char*)Src, Result);
+  EXPECT_TRUE(Success);
+  std::wstring Expected(L"\x0ca0_\x0ca0");
+  EXPECT_EQ(Expected, Result);
+  Result.clear();
+  Success = ConvertUTF8toWide(StringRef(Src, 7), Result);
+  EXPECT_TRUE(Success);
+  EXPECT_EQ(Expected, Result);
+}
+
+TEST(ConvertUTFTest, convertWideToUTF8) {
+  // Src is the look of disapproval.
+  static const wchar_t Src[] = L"\x0ca0_\x0ca0";
+  std::string Result;
+  bool Success = convertWideToUTF8(Src, Result);
+  EXPECT_TRUE(Success);
+  std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+  EXPECT_EQ(Expected, Result);
+}
+
+struct ConvertUTFResultContainer {
+  ConversionResult ErrorCode;
+  std::vector<unsigned> UnicodeScalars;
+
+  ConvertUTFResultContainer(ConversionResult ErrorCode)
+      : ErrorCode(ErrorCode) {}
+
+  ConvertUTFResultContainer
+  withScalars(unsigned US0 = 0x110000, unsigned US1 = 0x110000,
+              unsigned US2 = 0x110000, unsigned US3 = 0x110000,
+              unsigned US4 = 0x110000, unsigned US5 = 0x110000,
+              unsigned US6 = 0x110000, unsigned US7 = 0x110000) {
+    ConvertUTFResultContainer Result(*this);
+    if (US0 != 0x110000)
+      Result.UnicodeScalars.push_back(US0);
+    if (US1 != 0x110000)
+      Result.UnicodeScalars.push_back(US1);
+    if (US2 != 0x110000)
+      Result.UnicodeScalars.push_back(US2);
+    if (US3 != 0x110000)
+      Result.UnicodeScalars.push_back(US3);
+    if (US4 != 0x110000)
+      Result.UnicodeScalars.push_back(US4);
+    if (US5 != 0x110000)
+      Result.UnicodeScalars.push_back(US5);
+    if (US6 != 0x110000)
+      Result.UnicodeScalars.push_back(US6);
+    if (US7 != 0x110000)
+      Result.UnicodeScalars.push_back(US7);
+    return Result;
+  }
+};
+
+std::pair<ConversionResult, std::vector<unsigned>>
+ConvertUTF8ToUnicodeScalarsLenient(StringRef S) {
+  const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+
+  const UTF8 *SourceNext = SourceStart;
+  std::vector<UTF32> Decoded(S.size(), 0);
+  UTF32 *TargetStart = Decoded.data();
+
+  auto ErrorCode =
+      ConvertUTF8toUTF32(&SourceNext, SourceStart + S.size(), &TargetStart,
+                         Decoded.data() + Decoded.size(), lenientConversion);
+
+  Decoded.resize(TargetStart - Decoded.data());
+
+  return std::make_pair(ErrorCode, Decoded);
+}
+
+std::pair<ConversionResult, std::vector<unsigned>>
+ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) {
+  const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+
+  const UTF8 *SourceNext = SourceStart;
+  std::vector<UTF32> Decoded(S.size(), 0);
+  UTF32 *TargetStart = Decoded.data();
+
+  auto ErrorCode = ConvertUTF8toUTF32Partial(
+      &SourceNext, SourceStart + S.size(), &TargetStart,
+      Decoded.data() + Decoded.size(), lenientConversion);
+
+  Decoded.resize(TargetStart - Decoded.data());
+
+  return std::make_pair(ErrorCode, Decoded);
+}
+
+::testing::AssertionResult
+CheckConvertUTF8ToUnicodeScalars(ConvertUTFResultContainer Expected,
+                                 StringRef S, bool Partial = false) {
+  ConversionResult ErrorCode;
+  std::vector<unsigned> Decoded;
+  if (!Partial)
+    std::tie(ErrorCode, Decoded) = ConvertUTF8ToUnicodeScalarsLenient(S);
+  else
+    std::tie(ErrorCode, Decoded) = ConvertUTF8ToUnicodeScalarsPartialLenient(S);
+
+  if (Expected.ErrorCode != ErrorCode)
+    return ::testing::AssertionFailure() << "Expected error code "
+                                         << Expected.ErrorCode << ", actual "
+                                         << ErrorCode;
+
+  if (Expected.UnicodeScalars != Decoded)
+    return ::testing::AssertionFailure()
+           << "Expected lenient decoded result:\n"
+           << ::testing::PrintToString(Expected.UnicodeScalars) << "\n"
+           << "Actual result:\n" << ::testing::PrintToString(Decoded);
+
+  return ::testing::AssertionSuccess();
+}
+
+TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
+
+  //
+  // 1-byte sequences
+  //
+
+  // U+0041 LATIN CAPITAL LETTER A
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0041), "\x41"));
+
+  //
+  // 2-byte sequences
+  //
+
+  // U+0283 LATIN SMALL LETTER ESH
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0283),
+      "\xca\x83"));
+
+  // U+03BA GREEK SMALL LETTER KAPPA
+  // U+1F79 GREEK SMALL LETTER OMICRON WITH OXIA
+  // U+03C3 GREEK SMALL LETTER SIGMA
+  // U+03BC GREEK SMALL LETTER MU
+  // U+03B5 GREEK SMALL LETTER EPSILON
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK)
+          .withScalars(0x03ba, 0x1f79, 0x03c3, 0x03bc, 0x03b5),
+      "\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5"));
+
+  //
+  // 3-byte sequences
+  //
+
+  // U+4F8B CJK UNIFIED IDEOGRAPH-4F8B
+  // U+6587 CJK UNIFIED IDEOGRAPH-6587
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x4f8b, 0x6587),
+      "\xe4\xbe\x8b\xe6\x96\x87"));
+
+  // U+D55C HANGUL SYLLABLE HAN
+  // U+AE00 HANGUL SYLLABLE GEUL
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xd55c, 0xae00),
+      "\xed\x95\x9c\xea\xb8\x80"));
+
+  // U+1112 HANGUL CHOSEONG HIEUH
+  // U+1161 HANGUL JUNGSEONG A
+  // U+11AB HANGUL JONGSEONG NIEUN
+  // U+1100 HANGUL CHOSEONG KIYEOK
+  // U+1173 HANGUL JUNGSEONG EU
+  // U+11AF HANGUL JONGSEONG RIEUL
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK)
+          .withScalars(0x1112, 0x1161, 0x11ab, 0x1100, 0x1173, 0x11af),
+      "\xe1\x84\x92\xe1\x85\xa1\xe1\x86\xab\xe1\x84\x80\xe1\x85\xb3"
+      "\xe1\x86\xaf"));
+
+  //
+  // 4-byte sequences
+  //
+
+  // U+E0100 VARIATION SELECTOR-17
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x000E0100),
+      "\xf3\xa0\x84\x80"));
+
+  //
+  // First possible sequence of a certain length
+  //
+
+  // U+0000 NULL
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
+      StringRef("\x00", 1)));
+
+  // U+0080 PADDING CHARACTER
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0080),
+      "\xc2\x80"));
+
+  // U+0800 SAMARITAN LETTER ALAF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0800),
+      "\xe0\xa0\x80"));
+
+  // U+10000 LINEAR B SYLLABLE B008 A
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x10000),
+      "\xf0\x90\x80\x80"));
+
+  // U+200000 (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x88\x80\x80\x80"));
+
+  // U+4000000 (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x84\x80\x80\x80\x80"));
+
+  //
+  // Last possible sequence of a certain length
+  //
+
+  // U+007F DELETE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x007f), "\x7f"));
+
+  // U+07FF (unassigned)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x07ff),
+      "\xdf\xbf"));
+
+  // U+FFFF (noncharacter)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xffff),
+      "\xef\xbf\xbf"));
+
+  // U+1FFFFF (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf7\xbf\xbf\xbf"));
+
+  // U+3FFFFFF (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfb\xbf\xbf\xbf\xbf"));
+
+  // U+7FFFFFFF (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfd\xbf\xbf\xbf\xbf\xbf"));
+
+  //
+  // Other boundary conditions
+  //
+
+  // U+D7FF (unassigned)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xd7ff),
+      "\xed\x9f\xbf"));
+
+  // U+E000 (private use)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xe000),
+      "\xee\x80\x80"));
+
+  // U+FFFD REPLACEMENT CHARACTER
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfffd),
+      "\xef\xbf\xbd"));
+
+  // U+10FFFF (noncharacter)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x10ffff),
+      "\xf4\x8f\xbf\xbf"));
+
+  // U+110000 (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf4\x90\x80\x80"));
+
+  //
+  // Unexpected continuation bytes
+  //
+
+  // A sequence of unexpected continuation bytes that don't follow a first
+  // byte, every byte is a maximal subpart.
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\x80\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xbf\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\x80\xbf\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\x80\xbf\x80\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\x80\xbf\x82\xbf\xaa"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xaa\xb0\xbb\xbf\xaa\xa0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xaa\xb0\xbb\xbf\xaa\xa0\x8f"));
+
+  // All continuation bytes (0x80--0xbf).
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+      "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+      "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+      "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"));
+
+  //
+  // Lonely start bytes
+  //
+
+  // Start bytes of 2-byte sequences (0xc0--0xdf).
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+      "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020),
+      "\xc0\x20\xc1\x20\xc2\x20\xc3\x20\xc4\x20\xc5\x20\xc6\x20\xc7\x20"
+      "\xc8\x20\xc9\x20\xca\x20\xcb\x20\xcc\x20\xcd\x20\xce\x20\xcf\x20"
+      "\xd0\x20\xd1\x20\xd2\x20\xd3\x20\xd4\x20\xd5\x20\xd6\x20\xd7\x20"
+      "\xd8\x20\xd9\x20\xda\x20\xdb\x20\xdc\x20\xdd\x20\xde\x20\xdf\x20"));
+
+  // Start bytes of 3-byte sequences (0xe0--0xef).
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020),
+      "\xe0\x20\xe1\x20\xe2\x20\xe3\x20\xe4\x20\xe5\x20\xe6\x20\xe7\x20"
+      "\xe8\x20\xe9\x20\xea\x20\xeb\x20\xec\x20\xed\x20\xee\x20\xef\x20"));
+
+  // Start bytes of 4-byte sequences (0xf0--0xf7).
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd,
+                       0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020),
+      "\xf0\x20\xf1\x20\xf2\x20\xf3\x20\xf4\x20\xf5\x20\xf6\x20\xf7\x20"));
+
+  // Start bytes of 5-byte sequences (0xf8--0xfb).
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\xf9\xfa\xfb"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020),
+      "\xf8\x20\xf9\x20\xfa\x20\xfb\x20"));
+
+  // Start bytes of 6-byte sequences (0xfc--0xfd).
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfc\xfd"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020),
+      "\xfc\x20\xfd\x20"));
+
+  //
+  // Other bytes (0xc0--0xc1, 0xfe--0xff).
+  //
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xc0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xc1"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfe"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xff"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xc0\xc1\xfe\xff"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfe\xfe\xff\xff"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfe\x80\x80\x80\x80\x80"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xff\x80\x80\x80\x80\x80"));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0x0020, 0xfffd, 0x0020,
+                       0xfffd, 0x0020, 0xfffd, 0x0020),
+      "\xc0\x20\xc1\x20\xfe\x20\xff\x20"));
+
+  //
+  // Sequences with one continuation byte missing
+  //
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xc2"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xdf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xe0\xa0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xe0\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xe1\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xec\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xed\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xed\x9f"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xee\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xef\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf0\x90\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf0\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf1\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf3\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf4\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf4\x8f\xbf"));
+
+  // Overlong sequences with one trailing byte missing.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xc0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xc1"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xe0\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xe0\x9f"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf0\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf0\x8f\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x80\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x80\x80\x80\x80"));
+
+  // Sequences that represent surrogates with one trailing byte missing.
+  // High surrogates
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xed\xa0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xed\xac"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xed\xaf"));
+  // Low surrogates
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xed\xb0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xed\xb4"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xed\xbf"));
+
+  // Ill-formed 4-byte sequences.
+  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+1100xx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf4\x90\x80"));
+  // U+13FBxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf4\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf5\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf6\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf7\x80\x80"));
+  // U+1FFBxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf7\xbf\xbf"));
+
+  // Ill-formed 5-byte sequences.
+  // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+2000xx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x88\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\xbf\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf9\x80\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfa\x80\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfb\x80\x80\x80"));
+  // U+3FFFFxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfb\xbf\xbf\xbf"));
+
+  // Ill-formed 6-byte sequences.
+  // 1111110u 10uuuuuu 10uzzzzz 10zzzyyyy 10yyyyxx 10xxxxxx
+  // U+40000xx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x84\x80\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\xbf\xbf\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfd\x80\x80\x80\x80"));
+  // U+7FFFFFxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfd\xbf\xbf\xbf\xbf"));
+
+  //
+  // Sequences with two continuation bytes missing
+  //
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf0\x90"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf0\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf1\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf3\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf4\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd),
+      "\xf4\x8f"));
+
+  // Overlong sequences with two trailing byte missing.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xe0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf0\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf0\x8f"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x80\x80\x80"));
+
+  // Sequences that represent surrogates with two trailing bytes missing.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xed"));
+
+  // Ill-formed 4-byte sequences.
+  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+110yxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf4\x90"));
+  // U+13Fyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf4\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf5\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf6\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf7\x80"));
+  // U+1FFyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf7\xbf"));
+
+  // Ill-formed 5-byte sequences.
+  // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+200yxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x88\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf8\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xf9\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfa\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfb\x80\x80"));
+  // U+3FFFyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfb\xbf\xbf"));
+
+  // Ill-formed 6-byte sequences.
+  // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+4000yxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x84\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\xbf\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfd\x80\x80\x80"));
+  // U+7FFFFyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfd\xbf\xbf\xbf"));
+
+  //
+  // Sequences with three continuation bytes missing
+  //
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf1"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf2"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf3"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf4"));
+
+  // Broken overlong sequences.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf0"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf8\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x80\x80"));
+
+  // Ill-formed 4-byte sequences.
+  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+14yyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf5"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf6"));
+  // U+1Cyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf7"));
+
+  // Ill-formed 5-byte sequences.
+  // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+20yyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf8\x88"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf8\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xf9\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfa\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfb\x80"));
+  // U+3FCyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfb\xbf"));
+
+  // Ill-formed 6-byte sequences.
+  // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+400yyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x84\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfc\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfd\x80\x80"));
+  // U+7FFCyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xfd\xbf\xbf"));
+
+  //
+  // Sequences with four continuation bytes missing
+  //
+
+  // Ill-formed 5-byte sequences.
+  // 111110uu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+uzyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf8"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf9"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfa"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfb"));
+  // U+3zyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfb"));
+
+  // Broken overlong sequences.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xf8"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfc\x80"));
+
+  // Ill-formed 6-byte sequences.
+  // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+uzzyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfc\x84"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfc\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfd\x80"));
+  // U+7Fzzyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xfd\xbf"));
+
+  //
+  // Sequences with five continuation bytes missing
+  //
+
+  // Ill-formed 6-byte sequences.
+  // 1111110u 10uuuuuu 10zzzzzz 10zzyyyy 10yyyyxx 10xxxxxx
+  // U+uzzyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfc"));
+  // U+uuzzyyxx (invalid)
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd), "\xfd"));
+
+  //
+  // Consecutive sequences with trailing bytes missing
+  //
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, /**/ 0xfffd, 0xfffd, /**/ 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, /**/ 0xfffd, /**/ 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xc0" "\xe0\x80" "\xf0\x80\x80"
+      "\xf8\x80\x80\x80"
+      "\xfc\x80\x80\x80\x80"
+      "\xdf" "\xef\xbf" "\xf7\xbf\xbf"
+      "\xfb\xbf\xbf\xbf"
+      "\xfd\xbf\xbf\xbf\xbf"));
+
+  //
+  // Overlong UTF-8 sequences
+  //
+
+  // U+002F SOLIDUS
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x002f), "\x2f"));
+
+  // Overlong sequences of the above.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xc0\xaf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xe0\x80\xaf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf0\x80\x80\xaf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x80\x80\x80\xaf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x80\x80\x80\x80\xaf"));
+
+  // U+0000 NULL
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
+      StringRef("\x00", 1)));
+
+  // Overlong sequences of the above.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xc0\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xe0\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf0\x80\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x80\x80\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x80\x80\x80\x80\x80"));
+
+  // Other overlong sequences.
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xc0\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xc1\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal).withScalars(0xfffd, 0xfffd),
+      "\xc1\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xe0\x9f\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xa0\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf0\x8f\x80\x80"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf0\x8f\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xf8\x87\xbf\xbf\xbf"));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xfc\x83\xbf\xbf\xbf\xbf"));
+
+  //
+  // Isolated surrogates
+  //
+
+  // Unicode 6.3.0:
+  //
+  //    D71.  High-surrogate code point: A Unicode code point in the range
+  //    U+D800 to U+DBFF.
+  //
+  //    D73.  Low-surrogate code point: A Unicode code point in the range
+  //    U+DC00 to U+DFFF.
+
+  // Note: U+E0100 is <DB40 DD00> in UTF16.
+
+  // High surrogates
+
+  // U+D800
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xa0\x80"));
+
+  // U+DB40
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xac\xa0"));
+
+  // U+DBFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xaf\xbf"));
+
+  // Low surrogates
+
+  // U+DC00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xb0\x80"));
+
+  // U+DD00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xb4\x80"));
+
+  // U+DFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd),
+      "\xed\xbf\xbf"));
+
+  // Surrogate pairs
+
+  // U+D800 U+DC00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xa0\x80\xed\xb0\x80"));
+
+  // U+D800 U+DD00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xa0\x80\xed\xb4\x80"));
+
+  // U+D800 U+DFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xa0\x80\xed\xbf\xbf"));
+
+  // U+DB40 U+DC00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xac\xa0\xed\xb0\x80"));
+
+  // U+DB40 U+DD00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xac\xa0\xed\xb4\x80"));
+
+  // U+DB40 U+DFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xac\xa0\xed\xbf\xbf"));
+
+  // U+DBFF U+DC00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xaf\xbf\xed\xb0\x80"));
+
+  // U+DBFF U+DD00
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xaf\xbf\xed\xb4\x80"));
+
+  // U+DBFF U+DFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceIllegal)
+          .withScalars(0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd),
+      "\xed\xaf\xbf\xed\xbf\xbf"));
+
+  //
+  // Noncharacters
+  //
+
+  // Unicode 6.3.0:
+  //
+  //    D14.  Noncharacter: A code point that is permanently reserved for
+  //    internal use and that should never be interchanged. Noncharacters
+  //    consist of the values U+nFFFE and U+nFFFF (where n is from 0 to 1016)
+  //    and the values U+FDD0..U+FDEF.
+
+  // U+FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfffe),
+      "\xef\xbf\xbe"));
+
+  // U+FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xffff),
+      "\xef\xbf\xbf"));
+
+  // U+1FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x1fffe),
+      "\xf0\x9f\xbf\xbe"));
+
+  // U+1FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x1ffff),
+      "\xf0\x9f\xbf\xbf"));
+
+  // U+2FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x2fffe),
+      "\xf0\xaf\xbf\xbe"));
+
+  // U+2FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x2ffff),
+      "\xf0\xaf\xbf\xbf"));
+
+  // U+3FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x3fffe),
+      "\xf0\xbf\xbf\xbe"));
+
+  // U+3FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x3ffff),
+      "\xf0\xbf\xbf\xbf"));
+
+  // U+4FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x4fffe),
+      "\xf1\x8f\xbf\xbe"));
+
+  // U+4FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x4ffff),
+      "\xf1\x8f\xbf\xbf"));
+
+  // U+5FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x5fffe),
+      "\xf1\x9f\xbf\xbe"));
+
+  // U+5FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x5ffff),
+      "\xf1\x9f\xbf\xbf"));
+
+  // U+6FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x6fffe),
+      "\xf1\xaf\xbf\xbe"));
+
+  // U+6FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x6ffff),
+      "\xf1\xaf\xbf\xbf"));
+
+  // U+7FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x7fffe),
+      "\xf1\xbf\xbf\xbe"));
+
+  // U+7FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x7ffff),
+      "\xf1\xbf\xbf\xbf"));
+
+  // U+8FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x8fffe),
+      "\xf2\x8f\xbf\xbe"));
+
+  // U+8FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x8ffff),
+      "\xf2\x8f\xbf\xbf"));
+
+  // U+9FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x9fffe),
+      "\xf2\x9f\xbf\xbe"));
+
+  // U+9FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x9ffff),
+      "\xf2\x9f\xbf\xbf"));
+
+  // U+AFFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xafffe),
+      "\xf2\xaf\xbf\xbe"));
+
+  // U+AFFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xaffff),
+      "\xf2\xaf\xbf\xbf"));
+
+  // U+BFFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xbfffe),
+      "\xf2\xbf\xbf\xbe"));
+
+  // U+BFFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xbffff),
+      "\xf2\xbf\xbf\xbf"));
+
+  // U+CFFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xcfffe),
+      "\xf3\x8f\xbf\xbe"));
+
+  // U+CFFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xcfffF),
+      "\xf3\x8f\xbf\xbf"));
+
+  // U+DFFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xdfffe),
+      "\xf3\x9f\xbf\xbe"));
+
+  // U+DFFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xdffff),
+      "\xf3\x9f\xbf\xbf"));
+
+  // U+EFFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xefffe),
+      "\xf3\xaf\xbf\xbe"));
+
+  // U+EFFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xeffff),
+      "\xf3\xaf\xbf\xbf"));
+
+  // U+FFFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xffffe),
+      "\xf3\xbf\xbf\xbe"));
+
+  // U+FFFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfffff),
+      "\xf3\xbf\xbf\xbf"));
+
+  // U+10FFFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x10fffe),
+      "\xf4\x8f\xbf\xbe"));
+
+  // U+10FFFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x10ffff),
+      "\xf4\x8f\xbf\xbf"));
+
+  // U+FDD0
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd0),
+      "\xef\xb7\x90"));
+
+  // U+FDD1
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd1),
+      "\xef\xb7\x91"));
+
+  // U+FDD2
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd2),
+      "\xef\xb7\x92"));
+
+  // U+FDD3
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd3),
+      "\xef\xb7\x93"));
+
+  // U+FDD4
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd4),
+      "\xef\xb7\x94"));
+
+  // U+FDD5
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd5),
+      "\xef\xb7\x95"));
+
+  // U+FDD6
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd6),
+      "\xef\xb7\x96"));
+
+  // U+FDD7
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd7),
+      "\xef\xb7\x97"));
+
+  // U+FDD8
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd8),
+      "\xef\xb7\x98"));
+
+  // U+FDD9
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdd9),
+      "\xef\xb7\x99"));
+
+  // U+FDDA
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdda),
+      "\xef\xb7\x9a"));
+
+  // U+FDDB
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfddb),
+      "\xef\xb7\x9b"));
+
+  // U+FDDC
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfddc),
+      "\xef\xb7\x9c"));
+
+  // U+FDDD
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfddd),
+      "\xef\xb7\x9d"));
+
+  // U+FDDE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdde),
+      "\xef\xb7\x9e"));
+
+  // U+FDDF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfddf),
+      "\xef\xb7\x9f"));
+
+  // U+FDE0
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde0),
+      "\xef\xb7\xa0"));
+
+  // U+FDE1
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde1),
+      "\xef\xb7\xa1"));
+
+  // U+FDE2
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde2),
+      "\xef\xb7\xa2"));
+
+  // U+FDE3
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde3),
+      "\xef\xb7\xa3"));
+
+  // U+FDE4
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde4),
+      "\xef\xb7\xa4"));
+
+  // U+FDE5
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde5),
+      "\xef\xb7\xa5"));
+
+  // U+FDE6
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde6),
+      "\xef\xb7\xa6"));
+
+  // U+FDE7
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde7),
+      "\xef\xb7\xa7"));
+
+  // U+FDE8
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde8),
+      "\xef\xb7\xa8"));
+
+  // U+FDE9
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfde9),
+      "\xef\xb7\xa9"));
+
+  // U+FDEA
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdea),
+      "\xef\xb7\xaa"));
+
+  // U+FDEB
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdeb),
+      "\xef\xb7\xab"));
+
+  // U+FDEC
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdec),
+      "\xef\xb7\xac"));
+
+  // U+FDED
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfded),
+      "\xef\xb7\xad"));
+
+  // U+FDEE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdee),
+      "\xef\xb7\xae"));
+
+  // U+FDEF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdef),
+      "\xef\xb7\xaf"));
+
+  // U+FDF0
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf0),
+      "\xef\xb7\xb0"));
+
+  // U+FDF1
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf1),
+      "\xef\xb7\xb1"));
+
+  // U+FDF2
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf2),
+      "\xef\xb7\xb2"));
+
+  // U+FDF3
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf3),
+      "\xef\xb7\xb3"));
+
+  // U+FDF4
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf4),
+      "\xef\xb7\xb4"));
+
+  // U+FDF5
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf5),
+      "\xef\xb7\xb5"));
+
+  // U+FDF6
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf6),
+      "\xef\xb7\xb6"));
+
+  // U+FDF7
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf7),
+      "\xef\xb7\xb7"));
+
+  // U+FDF8
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf8),
+      "\xef\xb7\xb8"));
+
+  // U+FDF9
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdf9),
+      "\xef\xb7\xb9"));
+
+  // U+FDFA
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdfa),
+      "\xef\xb7\xba"));
+
+  // U+FDFB
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdfb),
+      "\xef\xb7\xbb"));
+
+  // U+FDFC
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdfc),
+      "\xef\xb7\xbc"));
+
+  // U+FDFD
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdfd),
+      "\xef\xb7\xbd"));
+
+  // U+FDFE
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdfe),
+      "\xef\xb7\xbe"));
+
+  // U+FDFF
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0xfdff),
+      "\xef\xb7\xbf"));
+}
+
+TEST(ConvertUTFTest, UTF8ToUTF32PartialLenient) {
+  // U+0041 LATIN CAPITAL LETTER A
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(conversionOK).withScalars(0x0041),
+      "\x41", true));
+
+  //
+  // Sequences with one continuation byte missing
+  //
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xc2", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xdf", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xe0\xa0", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xe0\xbf", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xe1\x80", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xec\xbf", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xed\x80", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xed\x9f", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xee\x80", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xef\xbf", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xf0\x90\x80", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xf0\xbf\xbf", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xf1\x80\x80", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xf3\xbf\xbf", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xf4\x80\x80", true));
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted),
+      "\xf4\x8f\xbf", true));
+
+  EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+      ConvertUTFResultContainer(sourceExhausted).withScalars(0x0041),
+      "\x41\xc2", true));
+}
+
diff --git a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
new file mode 100644
index 0000000..ac531b2
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
@@ -0,0 +1,83 @@
+//===- llvm/unittest/Support/CrashRecoveryTest.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/Compiler.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "gtest/gtest.h"
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#define NOGDI
+#include <windows.h>
+#endif
+
+using namespace llvm;
+using namespace llvm::sys;
+
+static int GlobalInt = 0;
+static void nullDeref() { *(volatile int *)0x10 = 0; }
+static void incrementGlobal() { ++GlobalInt; }
+static void llvmTrap() { LLVM_BUILTIN_TRAP; }
+
+TEST(CrashRecoveryTest, Basic) {
+  llvm::CrashRecoveryContext::Enable();
+  GlobalInt = 0;
+  EXPECT_TRUE(CrashRecoveryContext().RunSafely(incrementGlobal));
+  EXPECT_EQ(1, GlobalInt);
+  EXPECT_FALSE(CrashRecoveryContext().RunSafely(nullDeref));
+  EXPECT_FALSE(CrashRecoveryContext().RunSafely(llvmTrap));
+}
+
+struct IncrementGlobalCleanup : CrashRecoveryContextCleanup {
+  IncrementGlobalCleanup(CrashRecoveryContext *CRC)
+      : CrashRecoveryContextCleanup(CRC) {}
+  virtual void recoverResources() { ++GlobalInt; }
+};
+
+static void noop() {}
+
+TEST(CrashRecoveryTest, Cleanup) {
+  llvm::CrashRecoveryContext::Enable();
+  GlobalInt = 0;
+  {
+    CrashRecoveryContext CRC;
+    CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
+    EXPECT_TRUE(CRC.RunSafely(noop));
+  } // run cleanups
+  EXPECT_EQ(1, GlobalInt);
+
+  GlobalInt = 0;
+  {
+    CrashRecoveryContext CRC;
+    CRC.registerCleanup(new IncrementGlobalCleanup(&CRC));
+    EXPECT_FALSE(CRC.RunSafely(nullDeref));
+  } // run cleanups
+  EXPECT_EQ(1, GlobalInt);
+}
+
+#ifdef _WIN32
+static void raiseIt() {
+  RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);
+}
+
+TEST(CrashRecoveryTest, RaiseException) {
+  llvm::CrashRecoveryContext::Enable();
+  EXPECT_FALSE(CrashRecoveryContext().RunSafely(raiseIt));
+}
+
+static void outputString() {
+  OutputDebugStringA("output for debugger\n");
+}
+
+TEST(CrashRecoveryTest, CallOutputDebugString) {
+  llvm::CrashRecoveryContext::Enable();
+  EXPECT_TRUE(CrashRecoveryContext().RunSafely(outputString));
+}
+
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/DJBTest.cpp b/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
new file mode 100644
index 0000000..b157b96
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DJBTest.cpp
@@ -0,0 +1,96 @@
+//===---------- llvm/unittest/Support/DJBTest.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/DJB.h"
+#include "llvm/ADT/Twine.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(DJBTest, caseFolding) {
+  struct TestCase {
+    StringLiteral One;
+    StringLiteral Two;
+  };
+
+  static constexpr TestCase Tests[] = {
+      {{"ASDF"}, {"asdf"}},
+      {{"qWeR"}, {"QwEr"}},
+      {{"qqqqqqqqqqqqqqqqqqqq"}, {"QQQQQQQQQQQQQQQQQQQQ"}},
+
+      {{"I"}, {"i"}},
+      // Latin Small Letter Dotless I
+      {{u8"\u0130"}, {"i"}},
+      // Latin Capital Letter I With Dot Above
+      {{u8"\u0131"}, {"i"}},
+
+      // Latin Capital Letter A With Grave
+      {{u8"\u00c0"}, {u8"\u00e0"}},
+      // Latin Capital Letter A With Macron
+      {{u8"\u0100"}, {u8"\u0101"}},
+      // Latin Capital Letter L With Acute
+      {{u8"\u0139"}, {u8"\u013a"}},
+      // Cyrillic Capital Letter Ie
+      {{u8"\u0415"}, {u8"\u0435"}},
+      // Latin Capital Letter A With Circumflex And Grave
+      {{u8"\u1ea6"}, {u8"\u1ea7"}},
+      // Kelvin Sign
+      {{u8"\u212a"}, {u8"\u006b"}},
+      // Glagolitic Capital Letter Chrivi
+      {{u8"\u2c1d"}, {u8"\u2c4d"}},
+      // Fullwidth Latin Capital Letter M
+      {{u8"\uff2d"}, {u8"\uff4d"}},
+      // Old Hungarian Capital Letter Ej
+      {{u8"\U00010c92"}, {u8"\U00010cd2"}},
+  };
+
+  for (const TestCase &T : Tests) {
+    SCOPED_TRACE("Comparing '" + T.One + "' and '" + T.Two + "'");
+    EXPECT_EQ(caseFoldingDjbHash(T.One), caseFoldingDjbHash(T.Two));
+  }
+}
+
+TEST(DJBTest, knownValuesLowerCase) {
+  struct TestCase {
+    StringLiteral Text;
+    uint32_t Hash;
+  };
+  static constexpr TestCase Tests[] = {
+      {{""}, 5381u},
+      {{"f"}, 177675u},
+      {{"fo"}, 5863386u},
+      {{"foo"}, 193491849u},
+      {{"foob"}, 2090263819u},
+      {{"fooba"}, 259229388u},
+      {{"foobar"}, 4259602622u},
+      {{"pneumonoultramicroscopicsilicovolcanoconiosis"}, 3999417781u},
+  };
+
+  for (const TestCase &T : Tests) {
+    SCOPED_TRACE("Text: '" + T.Text + "'");
+    EXPECT_EQ(T.Hash, djbHash(T.Text));
+    EXPECT_EQ(T.Hash, caseFoldingDjbHash(T.Text));
+    EXPECT_EQ(T.Hash, caseFoldingDjbHash(T.Text.upper()));
+  }
+}
+
+TEST(DJBTest, knownValuesUnicode) {
+  EXPECT_EQ(5866553u, djbHash(u8"\u0130"));
+  EXPECT_EQ(177678u, caseFoldingDjbHash(u8"\u0130"));
+  EXPECT_EQ(
+      1302161417u,
+      djbHash(
+          u8"\u0130\u0131\u00c0\u00e0\u0100\u0101\u0139\u013a\u0415\u0435\u1ea6"
+          u8"\u1ea7\u212a\u006b\u2c1d\u2c4d\uff2d\uff4d\U00010c92\U00010cd2"));
+  EXPECT_EQ(
+      1145571043u,
+      caseFoldingDjbHash(
+          u8"\u0130\u0131\u00c0\u00e0\u0100\u0101\u0139\u013a\u0415\u0435\u1ea6"
+          u8"\u1ea7\u212a\u006b\u2c1d\u2c4d\uff2d\uff4d\U00010c92\U00010cd2"));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
new file mode 100644
index 0000000..8b64552
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
@@ -0,0 +1,120 @@
+//===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor 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/DataExtractor.h"
+#include "gtest/gtest.h"
+using namespace llvm;
+
+namespace {
+
+const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00";
+const char stringData[] = "hellohello\0hello";
+const char leb128data[] = "\xA6\x49";
+const char bigleb128data[] = "\xAA\xA9\xFF\xAA\xFF\xAA\xFF\x4A";
+
+TEST(DataExtractorTest, OffsetOverflow) {
+  DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
+  EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5));
+}
+
+TEST(DataExtractorTest, UnsignedNumbers) {
+  DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
+  uint32_t offset = 0;
+
+  EXPECT_EQ(0x80U, DE.getU8(&offset));
+  EXPECT_EQ(1U, offset);
+  offset = 0;
+  EXPECT_EQ(0x8090U, DE.getU16(&offset));
+  EXPECT_EQ(2U, offset);
+  offset = 0;
+  EXPECT_EQ(0x8090FFFFU, DE.getU32(&offset));
+  EXPECT_EQ(4U, offset);
+  offset = 0;
+  EXPECT_EQ(0x8090FFFF80000000ULL, DE.getU64(&offset));
+  EXPECT_EQ(8U, offset);
+  offset = 0;
+  EXPECT_EQ(0x8090FFFF80000000ULL, DE.getAddress(&offset));
+  EXPECT_EQ(8U, offset);
+  offset = 0;
+
+  uint32_t data[2];
+  EXPECT_EQ(data, DE.getU32(&offset, data, 2));
+  EXPECT_EQ(0x8090FFFFU, data[0]);
+  EXPECT_EQ(0x80000000U, data[1]);
+  EXPECT_EQ(8U, offset);
+  offset = 0;
+
+  // Now for little endian.
+  DE = DataExtractor(StringRef(numberData, sizeof(numberData)-1), true, 4);
+  EXPECT_EQ(0x9080U, DE.getU16(&offset));
+  EXPECT_EQ(2U, offset);
+  offset = 0;
+  EXPECT_EQ(0xFFFF9080U, DE.getU32(&offset));
+  EXPECT_EQ(4U, offset);
+  offset = 0;
+  EXPECT_EQ(0x80FFFF9080ULL, DE.getU64(&offset));
+  EXPECT_EQ(8U, offset);
+  offset = 0;
+  EXPECT_EQ(0xFFFF9080U, DE.getAddress(&offset));
+  EXPECT_EQ(4U, offset);
+  offset = 0;
+
+  EXPECT_EQ(data, DE.getU32(&offset, data, 2));
+  EXPECT_EQ(0xFFFF9080U, data[0]);
+  EXPECT_EQ(0x80U, data[1]);
+  EXPECT_EQ(8U, offset);
+}
+
+TEST(DataExtractorTest, SignedNumbers) {
+  DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
+  uint32_t offset = 0;
+
+  EXPECT_EQ(-128, DE.getSigned(&offset, 1));
+  EXPECT_EQ(1U, offset);
+  offset = 0;
+  EXPECT_EQ(-32624, DE.getSigned(&offset, 2));
+  EXPECT_EQ(2U, offset);
+  offset = 0;
+  EXPECT_EQ(-2137980929, DE.getSigned(&offset, 4));
+  EXPECT_EQ(4U, offset);
+  offset = 0;
+  EXPECT_EQ(-9182558167379214336LL, DE.getSigned(&offset, 8));
+  EXPECT_EQ(8U, offset);
+}
+
+TEST(DataExtractorTest, Strings) {
+  DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8);
+  uint32_t offset = 0;
+
+  EXPECT_EQ(stringData, DE.getCStr(&offset));
+  EXPECT_EQ(11U, offset);
+  EXPECT_EQ(nullptr, DE.getCStr(&offset));
+  EXPECT_EQ(11U, offset);
+}
+
+TEST(DataExtractorTest, LEB128) {
+  DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8);
+  uint32_t offset = 0;
+
+  EXPECT_EQ(9382ULL, DE.getULEB128(&offset));
+  EXPECT_EQ(2U, offset);
+  offset = 0;
+  EXPECT_EQ(-7002LL, DE.getSLEB128(&offset));
+  EXPECT_EQ(2U, offset);
+
+  DataExtractor BDE(StringRef(bigleb128data, sizeof(bigleb128data)-1), false,8);
+  offset = 0;
+  EXPECT_EQ(42218325750568106ULL, BDE.getULEB128(&offset));
+  EXPECT_EQ(8U, offset);
+  offset = 0;
+  EXPECT_EQ(-29839268287359830LL, BDE.getSLEB128(&offset));
+  EXPECT_EQ(8U, offset);
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp b/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
new file mode 100644
index 0000000..32bf56c
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DebugCounterTest.cpp
@@ -0,0 +1,41 @@
+//===- llvm/unittest/Support/DebugCounterTest.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/DebugCounter.h"
+#include "gtest/gtest.h"
+
+#include <string>
+using namespace llvm;
+
+#ifndef NDEBUG
+TEST(DebugCounterTest, CounterCheck) {
+  DEBUG_COUNTER(TestCounter, "test-counter", "Counter used for unit test");
+
+  EXPECT_FALSE(DebugCounter::isCounterSet(TestCounter));
+
+  auto DC = &DebugCounter::instance();
+  DC->push_back("test-counter-skip=1");
+  DC->push_back("test-counter-count=3");
+
+  EXPECT_TRUE(DebugCounter::isCounterSet(TestCounter));
+
+  EXPECT_EQ(0, DebugCounter::getCounterValue(TestCounter));
+  EXPECT_FALSE(DebugCounter::shouldExecute(TestCounter));
+
+  EXPECT_EQ(1, DebugCounter::getCounterValue(TestCounter));
+  EXPECT_TRUE(DebugCounter::shouldExecute(TestCounter));
+
+  DebugCounter::setCounterValue(TestCounter, 3);
+  EXPECT_TRUE(DebugCounter::shouldExecute(TestCounter));
+  EXPECT_FALSE(DebugCounter::shouldExecute(TestCounter));
+
+  DebugCounter::setCounterValue(TestCounter, 100);
+  EXPECT_FALSE(DebugCounter::shouldExecute(TestCounter));
+}
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/DebugTest.cpp b/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
new file mode 100644
index 0000000..7db91ff
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DebugTest.cpp
@@ -0,0 +1,34 @@
+//===- llvm/unittest/Support/DebugTest.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/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+#include <string>
+using namespace llvm;
+
+#ifndef NDEBUG
+TEST(DebugTest, Basic) {
+  std::string s1, s2;
+  raw_string_ostream os1(s1), os2(s2);
+  static const char *DT[] = {"A", "B"};  
+  
+  llvm::DebugFlag = true;
+  setCurrentDebugTypes(DT, 2);
+  DEBUG_WITH_TYPE("A", os1 << "A");
+  DEBUG_WITH_TYPE("B", os1 << "B");
+  EXPECT_EQ("AB", os1.str());
+
+  setCurrentDebugType("A");
+  DEBUG_WITH_TYPE("A", os2 << "A");
+  DEBUG_WITH_TYPE("B", os2 << "B");
+  EXPECT_EQ("A", os2.str());
+}
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt
new file mode 100644
index 0000000..1ea9826
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt
@@ -0,0 +1,51 @@
+# Needed by LLVM's CMake checks because this file defines multiple targets.
+set(LLVM_OPTIONAL_SOURCES ExportedFuncs.cpp PipSqueak.cpp)
+
+set(LLVM_LINK_COMPONENTS Support)
+
+add_library(DynamicLibraryLib STATIC
+  ExportedFuncs.cpp
+  )
+set_target_properties(DynamicLibraryLib PROPERTIES FOLDER "Tests")
+
+# extract_symbols.py relies on all its library arguments being in the same
+# directory, so we must set the output directory in the same way as if
+# add_llvm_library was used.
+set_output_directory(DynamicLibraryLib
+  LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}
+  )
+
+add_llvm_unittest(DynamicLibraryTests
+  DynamicLibraryTest.cpp
+  )
+target_link_libraries(DynamicLibraryTests PRIVATE DynamicLibraryLib)
+export_executable_symbols(DynamicLibraryTests)
+
+function(dynlib_add_module NAME)
+  add_library(${NAME} SHARED
+    PipSqueak.cpp
+    )
+  set_target_properties(${NAME} PROPERTIES FOLDER "Tests")
+
+  set_output_directory(${NAME}
+    BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+    LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+    )
+
+  set_target_properties(${NAME}
+    PROPERTIES PREFIX ""
+    SUFFIX ${LTDL_SHLIB_EXT}
+    )
+
+  add_dependencies(DynamicLibraryTests ${NAME})
+endfunction(dynlib_add_module)
+
+# Revert -Wl,-z,nodelete on this test since it relies on the file
+# being unloaded.
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+  string(REPLACE "-Wl,-z,nodelete" "" CMAKE_SHARED_LINKER_FLAGS
+    ${CMAKE_SHARED_LINKER_FLAGS})
+endif()
+
+dynlib_add_module(PipSqueak)
+dynlib_add_module(SecondLib)
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
new file mode 100644
index 0000000..50a0f1e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp
@@ -0,0 +1,178 @@
+//===- llvm/unittest/Support/DynamicLibrary/DynamicLibraryTest.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/DynamicLibrary.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Path.h"
+#include "gtest/gtest.h"
+
+#include "PipSqueak.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+
+std::string LibPath(const std::string Name = "PipSqueak") {
+  const std::vector<testing::internal::string> &Argvs =
+      testing::internal::GetArgvs();
+  const char *Argv0 =
+      Argvs.size() > 0 ? Argvs[0].c_str() : "DynamicLibraryTests";
+  void *Ptr = (void*)(intptr_t)TestA;
+  std::string Path = fs::getMainExecutable(Argv0, Ptr);
+  llvm::SmallString<256> Buf(path::parent_path(Path));
+  path::append(Buf, (Name + LTDL_SHLIB_EXT).c_str());
+  return Buf.str();
+}
+
+#if defined(_WIN32) || (defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN))
+
+typedef void (*SetStrings)(std::string &GStr, std::string &LStr);
+typedef void (*TestOrder)(std::vector<std::string> &V);
+typedef const char *(*GetString)();
+
+template <class T> static T FuncPtr(void *Ptr) {
+  union {
+    T F;
+    void *P;
+  } Tmp;
+  Tmp.P = Ptr;
+  return Tmp.F;
+}
+template <class T> static void* PtrFunc(T *Func) {
+  union {
+    T *F;
+    void *P;
+  } Tmp;
+  Tmp.F = Func;
+  return Tmp.P;
+}
+
+static const char *OverloadTestA() { return "OverloadCall"; }
+
+std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; }
+
+TEST(DynamicLibrary, Overload) {
+  {
+    std::string Err;
+    llvm_shutdown_obj Shutdown;
+    DynamicLibrary DL =
+        DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
+    EXPECT_TRUE(DL.isValid());
+    EXPECT_TRUE(Err.empty());
+
+    GetString GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS != &TestA);
+    EXPECT_EQ(StdString(GS()), "LibCall");
+
+    GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS != &TestA);
+    EXPECT_EQ(StdString(GS()), "LibCall");
+
+    DL = DynamicLibrary::getPermanentLibrary(nullptr, &Err);
+    EXPECT_TRUE(DL.isValid());
+    EXPECT_TRUE(Err.empty());
+
+    // Test overloading local symbols does not occur by default
+    GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS == &TestA);
+    EXPECT_EQ(StdString(GS()), "ProcessCall");
+
+    GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS == &TestA);
+    EXPECT_EQ(StdString(GS()), "ProcessCall");
+
+    // Test overloading by forcing library priority when searching for a symbol
+    DynamicLibrary::SearchOrder = DynamicLibrary::SO_LoadedFirst;
+    GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS != &TestA);
+    EXPECT_EQ(StdString(GS()), "LibCall");
+
+    DynamicLibrary::AddSymbol("TestA", PtrFunc(&OverloadTestA));
+    GS = FuncPtr<GetString>(DL.getAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS != &OverloadTestA);
+
+    GS = FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol("TestA"));
+    EXPECT_TRUE(GS != nullptr && GS == &OverloadTestA);
+    EXPECT_EQ(StdString(GS()), "OverloadCall");
+  }
+  EXPECT_TRUE(FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol(
+                  "TestA")) == nullptr);
+
+  // Check serach ordering is reset to default after call to llvm_shutdown
+  EXPECT_TRUE(DynamicLibrary::SearchOrder == DynamicLibrary::SO_Linker);
+}
+
+TEST(DynamicLibrary, Shutdown) {
+  std::string A("PipSqueak"), B, C("SecondLib");
+  std::vector<std::string> Order;
+  {
+    std::string Err;
+    llvm_shutdown_obj Shutdown;
+    DynamicLibrary DL =
+        DynamicLibrary::getPermanentLibrary(LibPath(A).c_str(), &Err);
+    EXPECT_TRUE(DL.isValid());
+    EXPECT_TRUE(Err.empty());
+
+    SetStrings SS_0 = FuncPtr<SetStrings>(
+        DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
+    EXPECT_TRUE(SS_0 != nullptr);
+
+    SS_0(A, B);
+    EXPECT_EQ(B, "Local::Local(PipSqueak)");
+
+    TestOrder TO_0 = FuncPtr<TestOrder>(
+        DynamicLibrary::SearchForAddressOfSymbol("TestOrder"));
+    EXPECT_TRUE(TO_0 != nullptr);
+    
+    DynamicLibrary DL2 =
+        DynamicLibrary::getPermanentLibrary(LibPath(C).c_str(), &Err);
+    EXPECT_TRUE(DL2.isValid());
+    EXPECT_TRUE(Err.empty());
+
+    // Should find latest version of symbols in SecondLib
+    SetStrings SS_1 = FuncPtr<SetStrings>(
+        DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
+    EXPECT_TRUE(SS_1 != nullptr);
+    EXPECT_TRUE(SS_0 != SS_1);
+
+    TestOrder TO_1 = FuncPtr<TestOrder>(
+        DynamicLibrary::SearchForAddressOfSymbol("TestOrder"));
+    EXPECT_TRUE(TO_1 != nullptr);
+    EXPECT_TRUE(TO_0 != TO_1);
+
+    B.clear();
+    SS_1(C, B);
+    EXPECT_EQ(B, "Local::Local(SecondLib)");
+
+    TO_0(Order);
+    TO_1(Order);
+  }
+  EXPECT_EQ(A, "Global::~Global");
+  EXPECT_EQ(B, "Local::~Local");
+  EXPECT_TRUE(FuncPtr<SetStrings>(DynamicLibrary::SearchForAddressOfSymbol(
+                  "SetStrings")) == nullptr);
+
+  // Test unload/destruction ordering
+  EXPECT_EQ(Order.size(), 2UL);
+  EXPECT_EQ(Order.front(), "SecondLib");
+  EXPECT_EQ(Order.back(), "PipSqueak");
+}
+
+#else
+
+TEST(DynamicLibrary, Unsupported) {
+  std::string Err;
+  DynamicLibrary DL =
+      DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
+  EXPECT_FALSE(DL.isValid());
+  EXPECT_EQ(Err, "dlopen() not supported on this platform");
+}
+
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
new file mode 100644
index 0000000..370c8cb
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/ExportedFuncs.cpp
@@ -0,0 +1,16 @@
+//===- llvm/unittest/Support/DynamicLibrary/ExportedFuncs.cpp -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PipSqueak.h"
+
+#ifndef PIPSQUEAK_TESTA_RETURN
+#define PIPSQUEAK_TESTA_RETURN "ProcessCall"
+#endif
+
+extern "C" PIPSQUEAK_EXPORT const char *TestA() { return PIPSQUEAK_TESTA_RETURN; }
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
new file mode 100644
index 0000000..e2f1cf7
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
@@ -0,0 +1,49 @@
+//===- llvm/unittest/Support/DynamicLibrary/PipSqueak.cpp -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PipSqueak.h"
+
+struct Global {
+  std::string *Str;
+  std::vector<std::string> *Vec;
+  Global() : Str(nullptr), Vec(nullptr) {}
+  ~Global() {
+    if (Str) {
+      if (Vec)
+        Vec->push_back(*Str);
+      *Str = "Global::~Global";
+    }
+  }
+};
+
+static Global Glb;
+
+struct Local {
+  std::string &Str;
+  Local(std::string &S) : Str(S) {
+    Str = "Local::Local";
+    if (Glb.Str && !Glb.Str->empty())
+      Str += std::string("(") + *Glb.Str + std::string(")");
+  }
+  ~Local() { Str = "Local::~Local"; }
+};
+
+
+extern "C" PIPSQUEAK_EXPORT void SetStrings(std::string &GStr,
+                                            std::string &LStr) {
+  Glb.Str = &GStr;
+  static Local Lcl(LStr);
+}
+
+extern "C" PIPSQUEAK_EXPORT void TestOrder(std::vector<std::string> &V) {
+  Glb.Vec = &V;
+}
+
+#define PIPSQUEAK_TESTA_RETURN "LibCall"
+#include "ExportedFuncs.cpp"
diff --git a/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
new file mode 100644
index 0000000..b44c61d
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
@@ -0,0 +1,34 @@
+//===- llvm/unittest/Support/DynamicLibrary/PipSqueak.h -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PIPSQUEAK_H
+#define LLVM_PIPSQUEAK_H
+
+#if defined(_WIN32) && !defined(__GNUC__)
+// Disable warnings from inclusion of xlocale & exception
+#pragma warning(push)
+#pragma warning(disable: 4530)
+#pragma warning(disable: 4577)
+#include <string>
+#include <vector>
+#pragma warning(pop)
+#else
+#include <string>
+#include <vector>
+#endif
+
+#ifdef _WIN32
+#define PIPSQUEAK_EXPORT __declspec(dllexport)
+#else
+#define PIPSQUEAK_EXPORT
+#endif
+
+extern "C" PIPSQUEAK_EXPORT const char *TestA();
+
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
new file mode 100644
index 0000000..9f938ee
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/EndianStreamTest.cpp
@@ -0,0 +1,208 @@
+//===- 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/Support/EndianStream.h"
+#include "llvm/ADT/SmallString.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 LE(OS, little);
+    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 BE(OS, big);
+    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 LE(OS, little);
+    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 BE(OS, big);
+    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 LE(OS, little);
+    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 BE(OS, big);
+    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 LE(OS, little);
+    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 BE(OS, big);
+    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);
+}
+
+TEST(EndianStream, WriteArrayLE) {
+  SmallString<16> Data;
+
+  {
+    raw_svector_ostream OS(Data);
+    endian::Writer LE(OS, little);
+    LE.write<uint16_t>({0x1234, 0x5678});
+  }
+
+  EXPECT_EQ(static_cast<uint8_t>(Data[0]), 0x34);
+  EXPECT_EQ(static_cast<uint8_t>(Data[1]), 0x12);
+  EXPECT_EQ(static_cast<uint8_t>(Data[2]), 0x78);
+  EXPECT_EQ(static_cast<uint8_t>(Data[3]), 0x56);
+}
+
+TEST(EndianStream, WriteVectorLE) {
+  SmallString<16> Data;
+
+  {
+    raw_svector_ostream OS(Data);
+    endian::Writer LE(OS, little);
+    std::vector<uint16_t> Vec{0x1234, 0x5678};
+    LE.write<uint16_t>(Vec);
+  }
+
+  EXPECT_EQ(static_cast<uint8_t>(Data[0]), 0x34);
+  EXPECT_EQ(static_cast<uint8_t>(Data[1]), 0x12);
+  EXPECT_EQ(static_cast<uint8_t>(Data[2]), 0x78);
+  EXPECT_EQ(static_cast<uint8_t>(Data[3]), 0x56);
+}
+
+TEST(EndianStream, WriteFloatArrayLE) {
+  SmallString<16> Data;
+
+  {
+    raw_svector_ostream OS(Data);
+    endian::Writer LE(OS, little);
+    LE.write<float>({12345.0f, 12346.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);
+
+  EXPECT_EQ(static_cast<uint8_t>(Data[4]), 0x00);
+  EXPECT_EQ(static_cast<uint8_t>(Data[5]), 0xE8);
+  EXPECT_EQ(static_cast<uint8_t>(Data[6]), 0x40);
+  EXPECT_EQ(static_cast<uint8_t>(Data[7]), 0x46);
+}
+
+
+} // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/EndianTest.cpp b/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
new file mode 100644
index 0000000..c2b5572
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/EndianTest.cpp
@@ -0,0 +1,204 @@
+//===- unittests/Support/EndianTest.cpp - Endian.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/Support/Endian.h"
+#include "llvm/Support/DataTypes.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+#include <ctime>
+using namespace llvm;
+using namespace support;
+
+#undef max
+
+namespace {
+
+TEST(Endian, Read) {
+  // These are 5 bytes so we can be sure at least one of the reads is unaligned.
+  unsigned char bigval[] = {0x00, 0x01, 0x02, 0x03, 0x04};
+  unsigned char littleval[] = {0x00, 0x04, 0x03, 0x02, 0x01};
+  int32_t BigAsHost = 0x00010203;
+  EXPECT_EQ(BigAsHost, (endian::read<int32_t, big, unaligned>(bigval)));
+  int32_t LittleAsHost = 0x02030400;
+  EXPECT_EQ(LittleAsHost,(endian::read<int32_t, little, unaligned>(littleval)));
+
+  EXPECT_EQ((endian::read<int32_t, big, unaligned>(bigval + 1)),
+            (endian::read<int32_t, little, unaligned>(littleval + 1)));
+}
+
+TEST(Endian, ReadBitAligned) {
+  // Simple test to make sure we properly pull out the 0x0 word.
+  unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};
+  unsigned char bigval[] = {0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0};
+  EXPECT_EQ(
+      (endian::readAtBitAlignment<int, little, unaligned>(&littleval[0], 6)),
+      0x0);
+  EXPECT_EQ((endian::readAtBitAlignment<int, big, unaligned>(&bigval[0], 6)),
+            0x0);
+  // Test to make sure that signed right shift of 0xf0000000 is masked
+  // properly.
+  unsigned char littleval2[] = {0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00};
+  unsigned char bigval2[] = {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  EXPECT_EQ(
+      (endian::readAtBitAlignment<int, little, unaligned>(&littleval2[0], 4)),
+      0x0f000000);
+  EXPECT_EQ((endian::readAtBitAlignment<int, big, unaligned>(&bigval2[0], 4)),
+            0x0f000000);
+  // Test to make sure left shift of start bit doesn't overflow.
+  EXPECT_EQ(
+      (endian::readAtBitAlignment<int, little, unaligned>(&littleval2[0], 1)),
+      0x78000000);
+  EXPECT_EQ((endian::readAtBitAlignment<int, big, unaligned>(&bigval2[0], 1)),
+            0x78000000);
+  // Test to make sure 64-bit int doesn't overflow.
+  unsigned char littleval3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  unsigned char bigval3[] = {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  EXPECT_EQ((endian::readAtBitAlignment<int64_t, little, unaligned>(
+                &littleval3[0], 4)),
+            0x0f00000000000000);
+  EXPECT_EQ(
+      (endian::readAtBitAlignment<int64_t, big, unaligned>(&bigval3[0], 4)),
+      0x0f00000000000000);
+}
+
+TEST(Endian, WriteBitAligned) {
+  // This test ensures that signed right shift of 0xffffaa is masked
+  // properly.
+  unsigned char bigval[8] = {0x00};
+  endian::writeAtBitAlignment<int32_t, big, unaligned>(bigval, (int)0xffffaaaa,
+                                                       4);
+  EXPECT_EQ(bigval[0], 0xff);
+  EXPECT_EQ(bigval[1], 0xfa);
+  EXPECT_EQ(bigval[2], 0xaa);
+  EXPECT_EQ(bigval[3], 0xa0);
+  EXPECT_EQ(bigval[4], 0x00);
+  EXPECT_EQ(bigval[5], 0x00);
+  EXPECT_EQ(bigval[6], 0x00);
+  EXPECT_EQ(bigval[7], 0x0f);
+
+  unsigned char littleval[8] = {0x00};
+  endian::writeAtBitAlignment<int32_t, little, unaligned>(littleval,
+                                                          (int)0xffffaaaa, 4);
+  EXPECT_EQ(littleval[0], 0xa0);
+  EXPECT_EQ(littleval[1], 0xaa);
+  EXPECT_EQ(littleval[2], 0xfa);
+  EXPECT_EQ(littleval[3], 0xff);
+  EXPECT_EQ(littleval[4], 0x0f);
+  EXPECT_EQ(littleval[5], 0x00);
+  EXPECT_EQ(littleval[6], 0x00);
+  EXPECT_EQ(littleval[7], 0x00);
+
+  // This test makes sure 1<<31 doesn't overflow.
+  // Test to make sure left shift of start bit doesn't overflow.
+  unsigned char bigval2[8] = {0x00};
+  endian::writeAtBitAlignment<int32_t, big, unaligned>(bigval2, (int)0xffffffff,
+                                                       1);
+  EXPECT_EQ(bigval2[0], 0xff);
+  EXPECT_EQ(bigval2[1], 0xff);
+  EXPECT_EQ(bigval2[2], 0xff);
+  EXPECT_EQ(bigval2[3], 0xfe);
+  EXPECT_EQ(bigval2[4], 0x00);
+  EXPECT_EQ(bigval2[5], 0x00);
+  EXPECT_EQ(bigval2[6], 0x00);
+  EXPECT_EQ(bigval2[7], 0x01);
+
+  unsigned char littleval2[8] = {0x00};
+  endian::writeAtBitAlignment<int32_t, little, unaligned>(littleval2,
+                                                          (int)0xffffffff, 1);
+  EXPECT_EQ(littleval2[0], 0xfe);
+  EXPECT_EQ(littleval2[1], 0xff);
+  EXPECT_EQ(littleval2[2], 0xff);
+  EXPECT_EQ(littleval2[3], 0xff);
+  EXPECT_EQ(littleval2[4], 0x01);
+  EXPECT_EQ(littleval2[5], 0x00);
+  EXPECT_EQ(littleval2[6], 0x00);
+  EXPECT_EQ(littleval2[7], 0x00);
+
+  // Test to make sure 64-bit int doesn't overflow.
+  unsigned char bigval64[16] = {0x00};
+  endian::writeAtBitAlignment<int64_t, big, unaligned>(
+      bigval64, (int64_t)0xffffffffffffffff, 1);
+  EXPECT_EQ(bigval64[0], 0xff);
+  EXPECT_EQ(bigval64[1], 0xff);
+  EXPECT_EQ(bigval64[2], 0xff);
+  EXPECT_EQ(bigval64[3], 0xff);
+  EXPECT_EQ(bigval64[4], 0xff);
+  EXPECT_EQ(bigval64[5], 0xff);
+  EXPECT_EQ(bigval64[6], 0xff);
+  EXPECT_EQ(bigval64[7], 0xfe);
+  EXPECT_EQ(bigval64[8], 0x00);
+  EXPECT_EQ(bigval64[9], 0x00);
+  EXPECT_EQ(bigval64[10], 0x00);
+  EXPECT_EQ(bigval64[11], 0x00);
+  EXPECT_EQ(bigval64[12], 0x00);
+  EXPECT_EQ(bigval64[13], 0x00);
+  EXPECT_EQ(bigval64[14], 0x00);
+  EXPECT_EQ(bigval64[15], 0x01);
+
+  unsigned char littleval64[16] = {0x00};
+  endian::writeAtBitAlignment<int64_t, little, unaligned>(
+      littleval64, (int64_t)0xffffffffffffffff, 1);
+  EXPECT_EQ(littleval64[0], 0xfe);
+  EXPECT_EQ(littleval64[1], 0xff);
+  EXPECT_EQ(littleval64[2], 0xff);
+  EXPECT_EQ(littleval64[3], 0xff);
+  EXPECT_EQ(littleval64[4], 0xff);
+  EXPECT_EQ(littleval64[5], 0xff);
+  EXPECT_EQ(littleval64[6], 0xff);
+  EXPECT_EQ(littleval64[7], 0xff);
+  EXPECT_EQ(littleval64[8], 0x01);
+  EXPECT_EQ(littleval64[9], 0x00);
+  EXPECT_EQ(littleval64[10], 0x00);
+  EXPECT_EQ(littleval64[11], 0x00);
+  EXPECT_EQ(littleval64[12], 0x00);
+  EXPECT_EQ(littleval64[13], 0x00);
+  EXPECT_EQ(littleval64[14], 0x00);
+  EXPECT_EQ(littleval64[15], 0x00);
+}
+
+TEST(Endian, Write) {
+  unsigned char data[5];
+  endian::write<int32_t, big, unaligned>(data, -1362446643);
+  EXPECT_EQ(data[0], 0xAE);
+  EXPECT_EQ(data[1], 0xCA);
+  EXPECT_EQ(data[2], 0xB6);
+  EXPECT_EQ(data[3], 0xCD);
+  endian::write<int32_t, big, unaligned>(data + 1, -1362446643);
+  EXPECT_EQ(data[1], 0xAE);
+  EXPECT_EQ(data[2], 0xCA);
+  EXPECT_EQ(data[3], 0xB6);
+  EXPECT_EQ(data[4], 0xCD);
+
+  endian::write<int32_t, little, unaligned>(data, -1362446643);
+  EXPECT_EQ(data[0], 0xCD);
+  EXPECT_EQ(data[1], 0xB6);
+  EXPECT_EQ(data[2], 0xCA);
+  EXPECT_EQ(data[3], 0xAE);
+  endian::write<int32_t, little, unaligned>(data + 1, -1362446643);
+  EXPECT_EQ(data[1], 0xCD);
+  EXPECT_EQ(data[2], 0xB6);
+  EXPECT_EQ(data[3], 0xCA);
+  EXPECT_EQ(data[4], 0xAE);
+}
+
+TEST(Endian, PackedEndianSpecificIntegral) {
+  // These are 5 bytes so we can be sure at least one of the reads is unaligned.
+  unsigned char big[] = {0x00, 0x01, 0x02, 0x03, 0x04};
+  unsigned char little[] = {0x00, 0x04, 0x03, 0x02, 0x01};
+  big32_t    *big_val    =
+    reinterpret_cast<big32_t *>(big + 1);
+  little32_t *little_val =
+    reinterpret_cast<little32_t *>(little + 1);
+
+  EXPECT_EQ(*big_val, *little_val);
+}
+
+} // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
new file mode 100644
index 0000000..701ac96
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ErrnoTest.cpp
@@ -0,0 +1,39 @@
+//===- ErrnoTest.cpp - Error handling unit tests --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Errno.h"
+#include "gtest/gtest.h"
+
+using namespace llvm::sys;
+
+TEST(ErrnoTest, RetryAfterSignal) {
+  EXPECT_EQ(1, RetryAfterSignal(-1, [] { return 1; }));
+
+  EXPECT_EQ(-1, RetryAfterSignal(-1, [] {
+    errno = EAGAIN;
+    return -1;
+  }));
+  EXPECT_EQ(EAGAIN, errno);
+
+  unsigned calls = 0;
+  EXPECT_EQ(1, RetryAfterSignal(-1, [&calls] {
+              errno = EINTR;
+              ++calls;
+              return calls == 1 ? -1 : 1;
+            }));
+  EXPECT_EQ(2u, calls);
+
+  EXPECT_EQ(1, RetryAfterSignal(-1, [](int x) { return x; }, 1));
+
+  std::unique_ptr<int> P(RetryAfterSignal(nullptr, [] { return new int(47); }));
+  EXPECT_EQ(47, *P);
+
+  errno = EINTR;
+  EXPECT_EQ(-1, RetryAfterSignal(-1, [] { return -1; }));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
new file mode 100644
index 0000000..2ffc6e5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ErrorOrTest.cpp
@@ -0,0 +1,140 @@
+//===- unittests/ErrorOrTest.cpp - ErrorOr.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/Support/ErrorOr.h"
+#include "llvm/Support/Errc.h"
+#include "gtest/gtest.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+ErrorOr<int> t1() { return 1; }
+ErrorOr<int> t2() { return errc::invalid_argument; }
+
+TEST(ErrorOr, SimpleValue) {
+  ErrorOr<int> a = t1();
+  // FIXME: This is probably a bug in gtest. EXPECT_TRUE should expand to
+  // include the !! to make it friendly to explicit bool operators.
+  EXPECT_TRUE(!!a);
+  EXPECT_EQ(1, *a);
+
+  ErrorOr<int> b = a;
+  EXPECT_EQ(1, *b);
+
+  a = t2();
+  EXPECT_FALSE(a);
+  EXPECT_EQ(a.getError(), errc::invalid_argument);
+#ifdef EXPECT_DEBUG_DEATH
+  EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists");
+#endif
+}
+
+ErrorOr<std::unique_ptr<int> > t3() {
+  return std::unique_ptr<int>(new int(3));
+}
+
+TEST(ErrorOr, Types) {
+  int x;
+  ErrorOr<int&> a(x);
+  *a = 42;
+  EXPECT_EQ(42, x);
+
+  // Move only types.
+  EXPECT_EQ(3, **t3());
+}
+
+struct B {};
+struct D : B {};
+
+TEST(ErrorOr, Covariant) {
+  ErrorOr<B*> b(ErrorOr<D*>(nullptr));
+  b = ErrorOr<D*>(nullptr);
+
+  ErrorOr<std::unique_ptr<B> > b1(ErrorOr<std::unique_ptr<D> >(nullptr));
+  b1 = ErrorOr<std::unique_ptr<D> >(nullptr);
+
+  ErrorOr<std::unique_ptr<int>> b2(ErrorOr<int *>(nullptr));
+  ErrorOr<int *> b3(nullptr);
+  ErrorOr<std::unique_ptr<int>> b4(b3);
+}
+
+TEST(ErrorOr, Comparison) {
+  ErrorOr<int> x(errc::no_such_file_or_directory);
+  EXPECT_EQ(x, errc::no_such_file_or_directory);
+}
+
+TEST(ErrorOr, ImplicitConversion) {
+  ErrorOr<std::string> x("string literal");
+  EXPECT_TRUE(!!x);
+}
+
+TEST(ErrorOr, ImplicitConversionCausesMove) {
+  struct Source {};
+  struct Destination {
+    Destination(const Source&) {}
+    Destination(Source&&) = delete;
+  };
+  Source s;
+  ErrorOr<Destination> x = s;
+  EXPECT_TRUE(!!x);
+}
+
+TEST(ErrorOr, ImplicitConversionNoAmbiguity) {
+  struct CastsToErrorCode {
+    CastsToErrorCode() = default;
+    CastsToErrorCode(std::error_code) {}
+    operator std::error_code() { return errc::invalid_argument; }
+  } casts_to_error_code;
+  ErrorOr<CastsToErrorCode> x1(casts_to_error_code);
+  ErrorOr<CastsToErrorCode> x2 = casts_to_error_code;
+  ErrorOr<CastsToErrorCode> x3 = {casts_to_error_code};
+  ErrorOr<CastsToErrorCode> x4{casts_to_error_code};
+  ErrorOr<CastsToErrorCode> x5(errc::no_such_file_or_directory);
+  ErrorOr<CastsToErrorCode> x6 = errc::no_such_file_or_directory;
+  ErrorOr<CastsToErrorCode> x7 = {errc::no_such_file_or_directory};
+  ErrorOr<CastsToErrorCode> x8{errc::no_such_file_or_directory};
+  EXPECT_TRUE(!!x1);
+  EXPECT_TRUE(!!x2);
+  EXPECT_TRUE(!!x3);
+  EXPECT_TRUE(!!x4);
+  EXPECT_FALSE(x5);
+  EXPECT_FALSE(x6);
+  EXPECT_FALSE(x7);
+  EXPECT_FALSE(x8);
+}
+
+// ErrorOr<int*> x(nullptr);
+// ErrorOr<std::unique_ptr<int>> y = x; // invalid conversion
+static_assert(
+    !std::is_convertible<const ErrorOr<int *> &,
+                         ErrorOr<std::unique_ptr<int>>>::value,
+    "do not invoke explicit ctors in implicit conversion from lvalue");
+
+// ErrorOr<std::unique_ptr<int>> y = ErrorOr<int*>(nullptr); // invalid
+//                                                           // conversion
+static_assert(
+    !std::is_convertible<ErrorOr<int *> &&,
+                         ErrorOr<std::unique_ptr<int>>>::value,
+    "do not invoke explicit ctors in implicit conversion from rvalue");
+
+// ErrorOr<int*> x(nullptr);
+// ErrorOr<std::unique_ptr<int>> y;
+// y = x; // invalid conversion
+static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&,
+                                  const ErrorOr<int *> &>::value,
+              "do not invoke explicit ctors in assignment");
+
+// ErrorOr<std::unique_ptr<int>> x;
+// x = ErrorOr<int*>(nullptr); // invalid conversion
+static_assert(!std::is_assignable<ErrorOr<std::unique_ptr<int>>&,
+                                  ErrorOr<int *> &&>::value,
+              "do not invoke explicit ctors in assignment");
+} // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
new file mode 100644
index 0000000..eee2fe2
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
@@ -0,0 +1,979 @@
+//===----- unittests/ErrorTest.cpp - Error.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/Support/Error.h"
+#include "llvm-c/Error.h"
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest-spi.h"
+#include "gtest/gtest.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+// Custom error class with a default base class and some random 'info' attached.
+class CustomError : public ErrorInfo<CustomError> {
+public:
+  // Create an error with some info attached.
+  CustomError(int Info) : Info(Info) {}
+
+  // Get the info attached to this error.
+  int getInfo() const { return Info; }
+
+  // Log this error to a stream.
+  void log(raw_ostream &OS) const override {
+    OS << "CustomError {" << getInfo() << "}";
+  }
+
+  std::error_code convertToErrorCode() const override {
+    llvm_unreachable("CustomError doesn't support ECError conversion");
+  }
+
+  // Used by ErrorInfo::classID.
+  static char ID;
+
+protected:
+  // This error is subclassed below, but we can't use inheriting constructors
+  // yet, so we can't propagate the constructors through ErrorInfo. Instead
+  // we have to have a default constructor and have the subclass initialize all
+  // fields.
+  CustomError() : Info(0) {}
+
+  int Info;
+};
+
+char CustomError::ID = 0;
+
+// Custom error class with a custom base class and some additional random
+// 'info'.
+class CustomSubError : public ErrorInfo<CustomSubError, CustomError> {
+public:
+  // Create a sub-error with some info attached.
+  CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) {
+    this->Info = Info;
+  }
+
+  // Get the extra info attached to this error.
+  int getExtraInfo() const { return ExtraInfo; }
+
+  // Log this error to a stream.
+  void log(raw_ostream &OS) const override {
+    OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}";
+  }
+
+  std::error_code convertToErrorCode() const override {
+    llvm_unreachable("CustomSubError doesn't support ECError conversion");
+  }
+
+  // Used by ErrorInfo::classID.
+  static char ID;
+
+protected:
+  int ExtraInfo;
+};
+
+char CustomSubError::ID = 0;
+
+static Error handleCustomError(const CustomError &CE) {
+  return Error::success();
+}
+
+static void handleCustomErrorVoid(const CustomError &CE) {}
+
+static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) {
+  return Error::success();
+}
+
+static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {}
+
+// Test that success values implicitly convert to false, and don't cause crashes
+// once they've been implicitly converted.
+TEST(Error, CheckedSuccess) {
+  Error E = Error::success();
+  EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'";
+}
+
+// Test that unchecked success values cause an abort.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, UncheckedSuccess) {
+  EXPECT_DEATH({ Error E = Error::success(); },
+               "Program aborted due to an unhandled Error:")
+      << "Unchecked Error Succes value did not cause abort()";
+}
+#endif
+
+// ErrorAsOutParameter tester.
+void errAsOutParamHelper(Error &Err) {
+  ErrorAsOutParameter ErrAsOutParam(&Err);
+  // Verify that checked flag is raised - assignment should not crash.
+  Err = Error::success();
+  // Raise the checked bit manually - caller should still have to test the
+  // error.
+  (void)!!Err;
+}
+
+// Test that ErrorAsOutParameter sets the checked flag on construction.
+TEST(Error, ErrorAsOutParameterChecked) {
+  Error E = Error::success();
+  errAsOutParamHelper(E);
+  (void)!!E;
+}
+
+// Test that ErrorAsOutParameter clears the checked flag on destruction.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, ErrorAsOutParameterUnchecked) {
+  EXPECT_DEATH({ Error E = Error::success(); errAsOutParamHelper(E); },
+               "Program aborted due to an unhandled Error:")
+      << "ErrorAsOutParameter did not clear the checked flag on destruction.";
+}
+#endif
+
+// Check that we abort on unhandled failure cases. (Force conversion to bool
+// to make sure that we don't accidentally treat checked errors as handled).
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, UncheckedError) {
+  auto DropUnhandledError = []() {
+    Error E = make_error<CustomError>(42);
+    (void)!E;
+  };
+  EXPECT_DEATH(DropUnhandledError(),
+               "Program aborted due to an unhandled Error:")
+      << "Unhandled Error failure value did not cause abort()";
+}
+#endif
+
+// Check 'Error::isA<T>' method handling.
+TEST(Error, IsAHandling) {
+  // Check 'isA' handling.
+  Error E = make_error<CustomError>(1);
+  Error F = make_error<CustomSubError>(1, 2);
+  Error G = Error::success();
+
+  EXPECT_TRUE(E.isA<CustomError>());
+  EXPECT_FALSE(E.isA<CustomSubError>());
+  EXPECT_TRUE(F.isA<CustomError>());
+  EXPECT_TRUE(F.isA<CustomSubError>());
+  EXPECT_FALSE(G.isA<CustomError>());
+
+  consumeError(std::move(E));
+  consumeError(std::move(F));
+  consumeError(std::move(G));
+}
+
+// Check that we can handle a custom error.
+TEST(Error, HandleCustomError) {
+  int CaughtErrorInfo = 0;
+  handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) {
+    CaughtErrorInfo = CE.getInfo();
+  });
+
+  EXPECT_TRUE(CaughtErrorInfo == 42) << "Wrong result from CustomError handler";
+}
+
+// Check that handler type deduction also works for handlers
+// of the following types:
+// void (const Err&)
+// Error (const Err&) mutable
+// void (const Err&) mutable
+// Error (Err&)
+// void (Err&)
+// Error (Err&) mutable
+// void (Err&) mutable
+// Error (unique_ptr<Err>)
+// void (unique_ptr<Err>)
+// Error (unique_ptr<Err>) mutable
+// void (unique_ptr<Err>) mutable
+TEST(Error, HandlerTypeDeduction) {
+
+  handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {});
+
+  handleAllErrors(
+      make_error<CustomError>(42),
+      [](const CustomError &CE) mutable  -> Error { return Error::success(); });
+
+  handleAllErrors(make_error<CustomError>(42),
+                  [](const CustomError &CE) mutable {});
+
+  handleAllErrors(make_error<CustomError>(42),
+                  [](CustomError &CE) -> Error { return Error::success(); });
+
+  handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {});
+
+  handleAllErrors(make_error<CustomError>(42),
+                  [](CustomError &CE) mutable -> Error { return Error::success(); });
+
+  handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {});
+
+  handleAllErrors(
+      make_error<CustomError>(42),
+      [](std::unique_ptr<CustomError> CE) -> Error { return Error::success(); });
+
+  handleAllErrors(make_error<CustomError>(42),
+                  [](std::unique_ptr<CustomError> CE) {});
+
+  handleAllErrors(
+      make_error<CustomError>(42),
+      [](std::unique_ptr<CustomError> CE) mutable -> Error { return Error::success(); });
+
+  handleAllErrors(make_error<CustomError>(42),
+                  [](std::unique_ptr<CustomError> CE) mutable {});
+
+  // Check that named handlers of type 'Error (const Err&)' work.
+  handleAllErrors(make_error<CustomError>(42), handleCustomError);
+
+  // Check that named handlers of type 'void (const Err&)' work.
+  handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid);
+
+  // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
+  handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP);
+
+  // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work.
+  handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid);
+}
+
+// Test that we can handle errors with custom base classes.
+TEST(Error, HandleCustomErrorWithCustomBaseClass) {
+  int CaughtErrorInfo = 0;
+  int CaughtErrorExtraInfo = 0;
+  handleAllErrors(make_error<CustomSubError>(42, 7),
+                  [&](const CustomSubError &SE) {
+                    CaughtErrorInfo = SE.getInfo();
+                    CaughtErrorExtraInfo = SE.getExtraInfo();
+                  });
+
+  EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7)
+      << "Wrong result from CustomSubError handler";
+}
+
+// Check that we trigger only the first handler that applies.
+TEST(Error, FirstHandlerOnly) {
+  int DummyInfo = 0;
+  int CaughtErrorInfo = 0;
+  int CaughtErrorExtraInfo = 0;
+
+  handleAllErrors(make_error<CustomSubError>(42, 7),
+                  [&](const CustomSubError &SE) {
+                    CaughtErrorInfo = SE.getInfo();
+                    CaughtErrorExtraInfo = SE.getExtraInfo();
+                  },
+                  [&](const CustomError &CE) { DummyInfo = CE.getInfo(); });
+
+  EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7 &&
+              DummyInfo == 0)
+      << "Activated the wrong Error handler(s)";
+}
+
+// Check that general handlers shadow specific ones.
+TEST(Error, HandlerShadowing) {
+  int CaughtErrorInfo = 0;
+  int DummyInfo = 0;
+  int DummyExtraInfo = 0;
+
+  handleAllErrors(
+      make_error<CustomSubError>(42, 7),
+      [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); },
+      [&](const CustomSubError &SE) {
+        DummyInfo = SE.getInfo();
+        DummyExtraInfo = SE.getExtraInfo();
+      });
+
+  EXPECT_TRUE(CaughtErrorInfo == 42 && DummyInfo == 0 && DummyExtraInfo == 0)
+      << "General Error handler did not shadow specific handler";
+}
+
+// Test joinErrors.
+TEST(Error, CheckJoinErrors) {
+  int CustomErrorInfo1 = 0;
+  int CustomErrorInfo2 = 0;
+  int CustomErrorExtraInfo = 0;
+  Error E =
+      joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7));
+
+  handleAllErrors(std::move(E),
+                  [&](const CustomSubError &SE) {
+                    CustomErrorInfo2 = SE.getInfo();
+                    CustomErrorExtraInfo = SE.getExtraInfo();
+                  },
+                  [&](const CustomError &CE) {
+                    // Assert that the CustomError instance above is handled
+                    // before the
+                    // CustomSubError - joinErrors should preserve error
+                    // ordering.
+                    EXPECT_EQ(CustomErrorInfo2, 0)
+                        << "CustomErrorInfo2 should be 0 here. "
+                           "joinErrors failed to preserve ordering.\n";
+                    CustomErrorInfo1 = CE.getInfo();
+                  });
+
+  EXPECT_TRUE(CustomErrorInfo1 == 7 && CustomErrorInfo2 == 42 &&
+              CustomErrorExtraInfo == 7)
+      << "Failed handling compound Error.";
+
+  // Test appending a single item to a list.
+  {
+    int Sum = 0;
+    handleAllErrors(
+        joinErrors(
+            joinErrors(make_error<CustomError>(7),
+                       make_error<CustomError>(7)),
+            make_error<CustomError>(7)),
+        [&](const CustomError &CE) {
+          Sum += CE.getInfo();
+        });
+    EXPECT_EQ(Sum, 21) << "Failed to correctly append error to error list.";
+  }
+
+  // Test prepending a single item to a list.
+  {
+    int Sum = 0;
+    handleAllErrors(
+        joinErrors(
+            make_error<CustomError>(7),
+            joinErrors(make_error<CustomError>(7),
+                       make_error<CustomError>(7))),
+        [&](const CustomError &CE) {
+          Sum += CE.getInfo();
+        });
+    EXPECT_EQ(Sum, 21) << "Failed to correctly prepend error to error list.";
+  }
+
+  // Test concatenating two error lists.
+  {
+    int Sum = 0;
+    handleAllErrors(
+        joinErrors(
+            joinErrors(
+                make_error<CustomError>(7),
+                make_error<CustomError>(7)),
+            joinErrors(
+                make_error<CustomError>(7),
+                make_error<CustomError>(7))),
+        [&](const CustomError &CE) {
+          Sum += CE.getInfo();
+        });
+    EXPECT_EQ(Sum, 28) << "Failed to correctly concatenate error lists.";
+  }
+}
+
+// Test that we can consume success values.
+TEST(Error, ConsumeSuccess) {
+  Error E = Error::success();
+  consumeError(std::move(E));
+}
+
+TEST(Error, ConsumeError) {
+  Error E = make_error<CustomError>(7);
+  consumeError(std::move(E));
+}
+
+// Test that handleAllUnhandledErrors crashes if an error is not caught.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, FailureToHandle) {
+  auto FailToHandle = []() {
+    handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) {
+      errs() << "This should never be called";
+      exit(1);
+    });
+  };
+
+  EXPECT_DEATH(FailToHandle(),
+               "Failure value returned from cantFail wrapped call")
+      << "Unhandled Error in handleAllErrors call did not cause an "
+         "abort()";
+}
+#endif
+
+// Test that handleAllUnhandledErrors crashes if an error is returned from a
+// handler.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, FailureFromHandler) {
+  auto ReturnErrorFromHandler = []() {
+    handleAllErrors(make_error<CustomError>(7),
+                    [&](std::unique_ptr<CustomSubError> SE) {
+                      return Error(std::move(SE));
+                    });
+  };
+
+  EXPECT_DEATH(ReturnErrorFromHandler(),
+               "Failure value returned from cantFail wrapped call")
+      << " Error returned from handler in handleAllErrors call did not "
+         "cause abort()";
+}
+#endif
+
+// Test that we can return values from handleErrors.
+TEST(Error, CatchErrorFromHandler) {
+  int ErrorInfo = 0;
+
+  Error E = handleErrors(
+      make_error<CustomError>(7),
+      [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); });
+
+  handleAllErrors(std::move(E),
+                  [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); });
+
+  EXPECT_EQ(ErrorInfo, 7)
+      << "Failed to handle Error returned from handleErrors.";
+}
+
+TEST(Error, StringError) {
+  std::string Msg;
+  raw_string_ostream S(Msg);
+  logAllUnhandledErrors(
+      make_error<StringError>("foo" + Twine(42), inconvertibleErrorCode()), S);
+  EXPECT_EQ(S.str(), "foo42\n") << "Unexpected StringError log result";
+
+  auto EC =
+    errorToErrorCode(make_error<StringError>("", errc::invalid_argument));
+  EXPECT_EQ(EC, errc::invalid_argument)
+    << "Failed to convert StringError to error_code.";
+}
+
+TEST(Error, createStringError) {
+  static const char *Bar = "bar";
+  static const std::error_code EC = errc::invalid_argument;
+  std::string Msg;
+  raw_string_ostream S(Msg);
+  logAllUnhandledErrors(createStringError(EC, "foo%s%d0x%" PRIx8, Bar, 1, 0xff),
+                        S);
+  EXPECT_EQ(S.str(), "foobar10xff\n")
+    << "Unexpected createStringError() log result";
+
+  S.flush();
+  Msg.clear();
+  logAllUnhandledErrors(createStringError(EC, Bar), S);
+  EXPECT_EQ(S.str(), "bar\n")
+    << "Unexpected createStringError() (overloaded) log result";
+
+  S.flush();
+  Msg.clear();
+  auto Res = errorToErrorCode(createStringError(EC, "foo%s", Bar));
+  EXPECT_EQ(Res, EC)
+    << "Failed to convert createStringError() result to error_code.";
+}
+
+// Test that the ExitOnError utility works as expected.
+TEST(Error, ExitOnError) {
+  ExitOnError ExitOnErr;
+  ExitOnErr.setBanner("Error in tool:");
+  ExitOnErr.setExitCodeMapper([](const Error &E) {
+    if (E.isA<CustomSubError>())
+      return 2;
+    return 1;
+  });
+
+  // Make sure we don't bail on success.
+  ExitOnErr(Error::success());
+  EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7)
+      << "exitOnError returned an invalid value for Expected";
+
+  int A = 7;
+  int &B = ExitOnErr(Expected<int&>(A));
+  EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference";
+
+  // Exit tests.
+  EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)),
+              ::testing::ExitedWithCode(1), "Error in tool:")
+      << "exitOnError returned an unexpected error result";
+
+  EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))),
+              ::testing::ExitedWithCode(2), "Error in tool:")
+      << "exitOnError returned an unexpected error result";
+}
+
+// Test that the ExitOnError utility works as expected.
+TEST(Error, CantFailSuccess) {
+  cantFail(Error::success());
+
+  int X = cantFail(Expected<int>(42));
+  EXPECT_EQ(X, 42) << "Expected value modified by cantFail";
+
+  int Dummy = 42;
+  int &Y = cantFail(Expected<int&>(Dummy));
+  EXPECT_EQ(&Dummy, &Y) << "Reference mangled by cantFail";
+}
+
+// Test that cantFail results in a crash if you pass it a failure value.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG)
+TEST(Error, CantFailDeath) {
+  EXPECT_DEATH(
+      cantFail(make_error<StringError>("foo", inconvertibleErrorCode()),
+               "Cantfail call failed"),
+      "Cantfail call failed")
+    << "cantFail(Error) did not cause an abort for failure value";
+
+  EXPECT_DEATH(
+      {
+        auto IEC = inconvertibleErrorCode();
+        int X = cantFail(Expected<int>(make_error<StringError>("foo", IEC)));
+        (void)X;
+      },
+      "Failure value returned from cantFail wrapped call")
+    << "cantFail(Expected<int>) did not cause an abort for failure value";
+}
+#endif
+
+
+// Test Checked Expected<T> in success mode.
+TEST(Error, CheckedExpectedInSuccessMode) {
+  Expected<int> A = 7;
+  EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'";
+  // Access is safe in second test, since we checked the error in the first.
+  EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";
+}
+
+// Test Expected with reference type.
+TEST(Error, ExpectedWithReferenceType) {
+  int A = 7;
+  Expected<int&> B = A;
+  // 'Check' B.
+  (void)!!B;
+  int &C = *B;
+  EXPECT_EQ(&A, &C) << "Expected failed to propagate reference";
+}
+
+// Test Unchecked Expected<T> in success mode.
+// We expect this to blow up the same way Error would.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, UncheckedExpectedInSuccessModeDestruction) {
+  EXPECT_DEATH({ Expected<int> A = 7; },
+               "Expected<T> must be checked before access or destruction.")
+    << "Unchecekd Expected<T> success value did not cause an abort().";
+}
+#endif
+
+// Test Unchecked Expected<T> in success mode.
+// We expect this to blow up the same way Error would.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, UncheckedExpectedInSuccessModeAccess) {
+  EXPECT_DEATH({ Expected<int> A = 7; *A; },
+               "Expected<T> must be checked before access or destruction.")
+    << "Unchecekd Expected<T> success value did not cause an abort().";
+}
+#endif
+
+// Test Unchecked Expected<T> in success mode.
+// We expect this to blow up the same way Error would.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, UncheckedExpectedInSuccessModeAssignment) {
+  EXPECT_DEATH({ Expected<int> A = 7; A = 7; },
+               "Expected<T> must be checked before access or destruction.")
+    << "Unchecekd Expected<T> success value did not cause an abort().";
+}
+#endif
+
+// Test Expected<T> in failure mode.
+TEST(Error, ExpectedInFailureMode) {
+  Expected<int> A = make_error<CustomError>(42);
+  EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'";
+  Error E = A.takeError();
+  EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value";
+  consumeError(std::move(E));
+}
+
+// Check that an Expected instance with an error value doesn't allow access to
+// operator*.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, AccessExpectedInFailureMode) {
+  Expected<int> A = make_error<CustomError>(42);
+  EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.")
+      << "Incorrect Expected error value";
+  consumeError(A.takeError());
+}
+#endif
+
+// Check that an Expected instance with an error triggers an abort if
+// unhandled.
+// Test runs in debug mode only.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+TEST(Error, UnhandledExpectedInFailureMode) {
+  EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); },
+               "Expected<T> must be checked before access or destruction.")
+      << "Unchecked Expected<T> failure value did not cause an abort()";
+}
+#endif
+
+// Test covariance of Expected.
+TEST(Error, ExpectedCovariance) {
+  class B {};
+  class D : public B {};
+
+  Expected<B *> A1(Expected<D *>(nullptr));
+  // Check A1 by converting to bool before assigning to it.
+  (void)!!A1;
+  A1 = Expected<D *>(nullptr);
+  // Check A1 again before destruction.
+  (void)!!A1;
+
+  Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr));
+  // Check A2 by converting to bool before assigning to it.
+  (void)!!A2;
+  A2 = Expected<std::unique_ptr<D>>(nullptr);
+  // Check A2 again before destruction.
+  (void)!!A2;
+}
+
+// Test that handleExpected just returns success values.
+TEST(Error, HandleExpectedSuccess) {
+  auto ValOrErr =
+    handleExpected(Expected<int>(42),
+                   []() { return Expected<int>(43); });
+  EXPECT_TRUE(!!ValOrErr)
+    << "handleExpected should have returned a success value here";
+  EXPECT_EQ(*ValOrErr, 42)
+    << "handleExpected should have returned the original success value here";
+}
+
+enum FooStrategy { Aggressive, Conservative };
+
+static Expected<int> foo(FooStrategy S) {
+  if (S == Aggressive)
+    return make_error<CustomError>(7);
+  return 42;
+}
+
+// Test that handleExpected invokes the error path if errors are not handled.
+TEST(Error, HandleExpectedUnhandledError) {
+  // foo(Aggressive) should return a CustomError which should pass through as
+  // there is no handler for CustomError.
+  auto ValOrErr =
+    handleExpected(
+      foo(Aggressive),
+      []() { return foo(Conservative); });
+
+  EXPECT_FALSE(!!ValOrErr)
+    << "handleExpected should have returned an error here";
+  auto Err = ValOrErr.takeError();
+  EXPECT_TRUE(Err.isA<CustomError>())
+    << "handleExpected should have returned the CustomError generated by "
+    "foo(Aggressive) here";
+  consumeError(std::move(Err));
+}
+
+// Test that handleExpected invokes the fallback path if errors are handled.
+TEST(Error, HandleExpectedHandledError) {
+  // foo(Aggressive) should return a CustomError which should handle triggering
+  // the fallback path.
+  auto ValOrErr =
+    handleExpected(
+      foo(Aggressive),
+      []() { return foo(Conservative); },
+      [](const CustomError&) { /* do nothing */ });
+
+  EXPECT_TRUE(!!ValOrErr)
+    << "handleExpected should have returned a success value here";
+  EXPECT_EQ(*ValOrErr, 42)
+    << "handleExpected returned the wrong success value";
+}
+
+TEST(Error, ErrorCodeConversions) {
+  // Round-trip a success value to check that it converts correctly.
+  EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())),
+            std::error_code())
+      << "std::error_code() should round-trip via Error conversions";
+
+  // Round-trip an error value to check that it converts correctly.
+  EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)),
+            errc::invalid_argument)
+      << "std::error_code error value should round-trip via Error "
+         "conversions";
+
+  // Round-trip a success value through ErrorOr/Expected to check that it
+  // converts correctly.
+  {
+    auto Orig = ErrorOr<int>(42);
+    auto RoundTripped =
+      expectedToErrorOr(errorOrToExpected(ErrorOr<int>(42)));
+    EXPECT_EQ(*Orig, *RoundTripped)
+      << "ErrorOr<T> success value should round-trip via Expected<T> "
+         "conversions.";
+  }
+
+  // Round-trip a failure value through ErrorOr/Expected to check that it
+  // converts correctly.
+  {
+    auto Orig = ErrorOr<int>(errc::invalid_argument);
+    auto RoundTripped =
+      expectedToErrorOr(
+          errorOrToExpected(ErrorOr<int>(errc::invalid_argument)));
+    EXPECT_EQ(Orig.getError(), RoundTripped.getError())
+      << "ErrorOr<T> failure value should round-trip via Expected<T> "
+         "conversions.";
+  }
+}
+
+// Test that error messages work.
+TEST(Error, ErrorMessage) {
+  EXPECT_EQ(toString(Error::success()).compare(""), 0);
+
+  Error E1 = make_error<CustomError>(0);
+  EXPECT_EQ(toString(std::move(E1)).compare("CustomError {0}"), 0);
+
+  Error E2 = make_error<CustomError>(0);
+  handleAllErrors(std::move(E2), [](const CustomError &CE) {
+    EXPECT_EQ(CE.message().compare("CustomError {0}"), 0);
+  });
+
+  Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1));
+  EXPECT_EQ(toString(std::move(E3))
+                .compare("CustomError {0}\n"
+                         "CustomError {1}"),
+            0);
+}
+
+TEST(Error, Stream) {
+  {
+    Error OK = Error::success();
+    std::string Buf;
+    llvm::raw_string_ostream S(Buf);
+    S << OK;
+    EXPECT_EQ("success", S.str());
+    consumeError(std::move(OK));
+  }
+  {
+    Error E1 = make_error<CustomError>(0);
+    std::string Buf;
+    llvm::raw_string_ostream S(Buf);
+    S << E1;
+    EXPECT_EQ("CustomError {0}", S.str());
+    consumeError(std::move(E1));
+  }
+}
+
+TEST(Error, ErrorMatchers) {
+  EXPECT_THAT_ERROR(Error::success(), Succeeded());
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()),
+      "Expected: succeeded\n  Actual: failed  (CustomError {0})");
+
+  EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed());
+  EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()),
+                          "Expected: failed\n  Actual: succeeded");
+
+  EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomError>());
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_ERROR(Error::success(), Failed<CustomError>()),
+      "Expected: failed with Error of given type\n  Actual: succeeded");
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomSubError>()),
+      "Error was not of given type");
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_ERROR(
+          joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)),
+          Failed<CustomError>()),
+      "multiple errors");
+
+  EXPECT_THAT_ERROR(
+      make_error<CustomError>(0),
+      Failed<CustomError>(testing::Property(&CustomError::getInfo, 0)));
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_ERROR(
+          make_error<CustomError>(0),
+          Failed<CustomError>(testing::Property(&CustomError::getInfo, 1))),
+      "Expected: failed with Error of given type and the error is an object "
+      "whose given property is equal to 1\n"
+      "  Actual: failed  (CustomError {0})");
+  EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<ErrorInfoBase>());
+
+  EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded());
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+                           Succeeded()),
+      "Expected: succeeded\n  Actual: failed  (CustomError {0})");
+
+  EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed());
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()),
+      "Expected: failed\n  Actual: succeeded with value 0");
+
+  EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0));
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+                           HasValue(0)),
+      "Expected: succeeded with value (is equal to 0)\n"
+      "  Actual: failed  (CustomError {0})");
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)),
+      "Expected: succeeded with value (is equal to 0)\n"
+      "  Actual: succeeded with value 1, (isn't equal to 0)");
+
+  EXPECT_THAT_EXPECTED(Expected<int &>(make_error<CustomError>(0)), Failed());
+  int a = 1;
+  EXPECT_THAT_EXPECTED(Expected<int &>(a), Succeeded());
+  EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(testing::Eq(1)));
+
+  EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(testing::Gt(0)));
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(testing::Gt(1))),
+      "Expected: succeeded with value (is > 1)\n"
+      "  Actual: succeeded with value 0, (isn't > 1)");
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+                           HasValue(testing::Gt(1))),
+      "Expected: succeeded with value (is > 1)\n"
+      "  Actual: failed  (CustomError {0})");
+}
+
+TEST(Error, C_API) {
+  EXPECT_THAT_ERROR(unwrap(wrap(Error::success())), Succeeded())
+      << "Failed to round-trip Error success value via C API";
+  EXPECT_THAT_ERROR(unwrap(wrap(make_error<CustomError>(0))),
+                    Failed<CustomError>())
+      << "Failed to round-trip Error failure value via C API";
+
+  auto Err =
+      wrap(make_error<StringError>("test message", inconvertibleErrorCode()));
+  EXPECT_EQ(LLVMGetErrorTypeId(Err), LLVMGetStringErrorTypeId())
+      << "Failed to match error type ids via C API";
+  char *ErrMsg = LLVMGetErrorMessage(Err);
+  EXPECT_STREQ(ErrMsg, "test message")
+      << "Failed to roundtrip StringError error message via C API";
+  LLVMDisposeErrorMessage(ErrMsg);
+
+  bool GotCSE = false;
+  bool GotCE = false;
+  handleAllErrors(
+    unwrap(wrap(joinErrors(make_error<CustomSubError>(42, 7),
+                           make_error<CustomError>(42)))),
+    [&](CustomSubError &CSE) {
+      GotCSE = true;
+    },
+    [&](CustomError &CE) {
+      GotCE = true;
+    });
+  EXPECT_TRUE(GotCSE) << "Failed to round-trip ErrorList via C API";
+  EXPECT_TRUE(GotCE) << "Failed to round-trip ErrorList via C API";
+}
+
+TEST(Error, FileErrorTest) {
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
+    EXPECT_DEATH(
+      {
+        Error S = Error::success();
+        consumeError(createFileError("file.bin", std::move(S)));
+      },
+      "");
+#endif
+  // Not allowed, would fail at compile-time
+  //consumeError(createFileError("file.bin", ErrorSuccess()));
+
+  Error E1 = make_error<CustomError>(1);
+  Error FE1 = createFileError("file.bin", std::move(E1));
+  EXPECT_EQ(toString(std::move(FE1)).compare("'file.bin': CustomError {1}"), 0);
+
+  Error E2 = make_error<CustomError>(2);
+  Error FE2 = createFileError("file.bin", std::move(E2));
+  handleAllErrors(std::move(FE2), [](const FileError &F) {
+    EXPECT_EQ(F.message().compare("'file.bin': CustomError {2}"), 0);
+  });
+
+  Error E3 = make_error<CustomError>(3);
+  Error FE3 = createFileError("file.bin", std::move(E3));
+  auto E31 = handleErrors(std::move(FE3), [](std::unique_ptr<FileError> F) {
+    return F->takeError();
+  });
+  handleAllErrors(std::move(E31), [](const CustomError &C) {
+    EXPECT_EQ(C.message().compare("CustomError {3}"), 0);
+  });
+
+  Error FE4 =
+      joinErrors(createFileError("file.bin", make_error<CustomError>(41)),
+                 createFileError("file2.bin", make_error<CustomError>(42)));
+  EXPECT_EQ(toString(std::move(FE4))
+                .compare("'file.bin': CustomError {41}\n"
+                         "'file2.bin': CustomError {42}"),
+            0);
+}
+
+enum class test_error_code {
+  unspecified = 1,
+  error_1,
+  error_2,
+};
+
+} // end anon namespace
+
+namespace std {
+    template <>
+    struct is_error_code_enum<test_error_code> : std::true_type {};
+} // namespace std
+
+namespace {
+
+const std::error_category &TErrorCategory();
+
+inline std::error_code make_error_code(test_error_code E) {
+    return std::error_code(static_cast<int>(E), TErrorCategory());
+}
+
+class TestDebugError : public ErrorInfo<TestDebugError, StringError> {
+public:
+    using ErrorInfo<TestDebugError, StringError >::ErrorInfo; // inherit constructors
+    TestDebugError(const Twine &S) : ErrorInfo(S, test_error_code::unspecified) {}
+    static char ID;
+};
+
+class TestErrorCategory : public std::error_category {
+public:
+  const char *name() const noexcept override { return "error"; }
+  std::string message(int Condition) const override {
+    switch (static_cast<test_error_code>(Condition)) {
+    case test_error_code::unspecified:
+      return "An unknown error has occurred.";
+    case test_error_code::error_1:
+      return "Error 1.";
+    case test_error_code::error_2:
+      return "Error 2.";
+    }
+    llvm_unreachable("Unrecognized test_error_code");
+  }
+};
+
+static llvm::ManagedStatic<TestErrorCategory> TestErrCategory;
+const std::error_category &TErrorCategory() { return *TestErrCategory; }
+
+char TestDebugError::ID;
+
+TEST(Error, SubtypeStringErrorTest) {
+  auto E1 = make_error<TestDebugError>(test_error_code::error_1);
+  EXPECT_EQ(toString(std::move(E1)).compare("Error 1."), 0);
+
+  auto E2 = make_error<TestDebugError>(test_error_code::error_1,
+                                       "Detailed information");
+  EXPECT_EQ(toString(std::move(E2)).compare("Error 1. Detailed information"),
+            0);
+
+  auto E3 = make_error<TestDebugError>(test_error_code::error_2);
+  handleAllErrors(std::move(E3), [](const TestDebugError &F) {
+    EXPECT_EQ(F.message().compare("Error 2."), 0);
+  });
+
+  auto E4 = joinErrors(make_error<TestDebugError>(test_error_code::error_1,
+                                                  "Detailed information"),
+                       make_error<TestDebugError>(test_error_code::error_2));
+  EXPECT_EQ(toString(std::move(E4))
+                .compare("Error 1. Detailed information\n"
+                         "Error 2."),
+            0);
+}
+
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
new file mode 100644
index 0000000..5548595
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
@@ -0,0 +1,174 @@
+//===- 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/Support/FileOutputBuffer.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
+    SmallString<128> MessageStorage;                                           \
+    raw_svector_ostream Message(MessageStorage);                               \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+
+namespace {
+TEST(FileOutputBuffer, Test) {
+  // Create unique temporary directory for these tests
+  SmallString<128> TestDirectory;
+  {
+    ASSERT_NO_ERROR(
+        fs::createUniqueDirectory("FileOutputBuffer-test", TestDirectory));
+  }
+
+  // TEST 1: Verify commit case.
+  SmallString<128> File1(TestDirectory);
+  File1.append("/file1");
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+        FileOutputBuffer::create(File1, 8192);
+    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
+    // 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(errorToErrorCode(Buffer->commit()));
+  }
+
+  // Verify file is correct size.
+  uint64_t File1Size;
+  ASSERT_NO_ERROR(fs::file_size(Twine(File1), File1Size));
+  ASSERT_EQ(File1Size, 8192ULL);
+  ASSERT_NO_ERROR(fs::remove(File1.str()));
+
+  // TEST 2: Verify abort case.
+  SmallString<128> File2(TestDirectory);
+  File2.append("/file2");
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> Buffer2OrErr =
+        FileOutputBuffer::create(File2, 8192);
+    ASSERT_NO_ERROR(errorToErrorCode(Buffer2OrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer2 = *Buffer2OrErr;
+    // Fill buffer with special header.
+    memcpy(Buffer2->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
+    // Do *not* commit buffer.
+  }
+  // Verify file does not exist (because buffer not committed).
+  ASSERT_EQ(fs::access(Twine(File2), fs::AccessMode::Exist),
+            errc::no_such_file_or_directory);
+  ASSERT_NO_ERROR(fs::remove(File2.str()));
+
+  // TEST 3: Verify sizing down case.
+  SmallString<128> File3(TestDirectory);
+  File3.append("/file3");
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+        FileOutputBuffer::create(File3, 8192000);
+    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
+    // 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);
+    ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
+  }
+
+  // Verify file is correct size.
+  uint64_t File3Size;
+  ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size));
+  ASSERT_EQ(File3Size, 8192000ULL);
+  ASSERT_NO_ERROR(fs::remove(File3.str()));
+
+  // TEST 4: Verify file can be made executable.
+  SmallString<128> File4(TestDirectory);
+  File4.append("/file4");
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+        FileOutputBuffer::create(File4, 8192, FileOutputBuffer::F_executable);
+    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
+    // Start buffer with special header.
+    memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
+    // Commit buffer.
+    ASSERT_NO_ERROR(errorToErrorCode(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);
+  ASSERT_NO_ERROR(fs::remove(File4.str()));
+
+  // Clean up.
+  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+
+TEST(FileOutputBuffer, TestModify) {
+  // Create unique temporary directory for these tests
+  SmallString<128> TestDirectory;
+  {
+    ASSERT_NO_ERROR(
+      fs::createUniqueDirectory("FileOutputBuffer-modify", TestDirectory));
+  }
+
+  SmallString<128> File1(TestDirectory);
+  File1.append("/file");
+  // First write some data.
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+      FileOutputBuffer::create(File1, 10);
+    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
+    memcpy(Buffer->getBufferStart(), "AAAAAAAAAA", 10);
+    ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
+  }
+
+  // Then re-open the file for modify and change only some bytes.
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+        FileOutputBuffer::create(File1, size_t(-1), FileOutputBuffer::F_modify);
+    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
+    ASSERT_EQ(10U, Buffer->getBufferSize());
+    uint8_t *Data = Buffer->getBufferStart();
+    Data[0] = 'X';
+    Data[9] = 'X';
+    ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
+  }
+
+  // Finally, re-open the file for read and verify that it has the modified
+  // contents.
+  {
+    ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFile(File1);
+    ASSERT_NO_ERROR(BufferOrErr.getError());
+    std::unique_ptr<MemoryBuffer> Buffer = std::move(*BufferOrErr);
+    ASSERT_EQ(10U, Buffer->getBufferSize());
+    EXPECT_EQ(StringRef("XAAAAAAAAX"), Buffer->getBuffer());
+  }
+
+  // Clean up.
+  ASSERT_NO_ERROR(fs::remove(File1));
+  ASSERT_NO_ERROR(fs::remove(TestDirectory));
+}
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp b/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
new file mode 100644
index 0000000..91a44ba
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/FormatVariadicTest.cpp
@@ -0,0 +1,691 @@
+//===- FormatVariadicTest.cpp - Unit tests for string formatting ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+// Compile-time tests templates in the detail namespace.
+namespace {
+struct Format : public FormatAdapter<int> {
+  Format(int N) : FormatAdapter<int>(std::move(N)) {}
+  void format(raw_ostream &OS, StringRef Opt) override { OS << "Format"; }
+};
+
+using detail::uses_format_member;
+using detail::uses_missing_provider;
+
+static_assert(uses_format_member<Format>::value, "");
+static_assert(uses_format_member<Format &>::value, "");
+static_assert(uses_format_member<Format &&>::value, "");
+static_assert(uses_format_member<const Format>::value, "");
+static_assert(uses_format_member<const Format &>::value, "");
+static_assert(uses_format_member<const volatile Format>::value, "");
+static_assert(uses_format_member<const volatile Format &>::value, "");
+
+struct NoFormat {};
+static_assert(uses_missing_provider<NoFormat>::value, "");
+}
+
+TEST(FormatVariadicTest, EmptyFormatString) {
+  auto Replacements = formatv_object_base::parseFormatString("");
+  EXPECT_EQ(0U, Replacements.size());
+}
+
+TEST(FormatVariadicTest, NoReplacements) {
+  const StringRef kFormatString = "This is a test";
+  auto Replacements = formatv_object_base::parseFormatString(kFormatString);
+  ASSERT_EQ(1U, Replacements.size());
+  EXPECT_EQ(kFormatString, Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
+}
+
+TEST(FormatVariadicTest, EscapedBrace) {
+  // {{ should be replaced with {
+  auto Replacements = formatv_object_base::parseFormatString("{{");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("{", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
+
+  // An even number N of braces should be replaced with N/2 braces.
+  Replacements = formatv_object_base::parseFormatString("{{{{{{");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("{{{", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
+}
+
+TEST(FormatVariadicTest, ValidReplacementSequence) {
+  // 1. Simple replacement - parameter index only
+  auto Replacements = formatv_object_base::parseFormatString("{0}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(0u, Replacements[0].Align);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  Replacements = formatv_object_base::parseFormatString("{1}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(1u, Replacements[0].Index);
+  EXPECT_EQ(0u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // 2. Parameter index with right alignment
+  Replacements = formatv_object_base::parseFormatString("{0,3}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // 3. And left alignment
+  Replacements = formatv_object_base::parseFormatString("{0,-3}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Left, Replacements[0].Where);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // 4. And center alignment
+  Replacements = formatv_object_base::parseFormatString("{0,=3}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Center, Replacements[0].Where);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // 4. Parameter index with option string
+  Replacements = formatv_object_base::parseFormatString("{0:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(0u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  // 5. Parameter index with alignment before option string
+  Replacements = formatv_object_base::parseFormatString("{0,-3:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Left, Replacements[0].Where);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  // 7. Parameter indices, options, and alignment can all have whitespace.
+  Replacements = formatv_object_base::parseFormatString("{ 0, -3 : foo }");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Left, Replacements[0].Where);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  // 8. Everything after the first option specifier is part of the style, even
+  // if it contains another option specifier.
+  Replacements = formatv_object_base::parseFormatString("{0:0:1}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("0:0:1", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(0u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ("0:1", Replacements[0].Options);
+
+  // 9. Custom padding character
+  Replacements = formatv_object_base::parseFormatString("{0,p+4:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("0,p+4:foo", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(4u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ('p', Replacements[0].Pad);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  // Format string special characters are allowed as padding character
+  Replacements = formatv_object_base::parseFormatString("{0,-+4:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("0,-+4:foo", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(4u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ('-', Replacements[0].Pad);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  Replacements = formatv_object_base::parseFormatString("{0,+-4:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("0,+-4:foo", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(4u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Left, Replacements[0].Where);
+  EXPECT_EQ('+', Replacements[0].Pad);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  Replacements = formatv_object_base::parseFormatString("{0,==4:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("0,==4:foo", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(4u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Center, Replacements[0].Where);
+  EXPECT_EQ('=', Replacements[0].Pad);
+  EXPECT_EQ("foo", Replacements[0].Options);
+
+  Replacements = formatv_object_base::parseFormatString("{0,:=4:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ("0,:=4:foo", Replacements[0].Spec);
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(4u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Center, Replacements[0].Where);
+  EXPECT_EQ(':', Replacements[0].Pad);
+  EXPECT_EQ("foo", Replacements[0].Options);
+}
+
+TEST(FormatVariadicTest, DefaultReplacementValues) {
+  // 2. If options string is missing, it defaults to empty.
+  auto Replacements = formatv_object_base::parseFormatString("{0,3}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // Including if the colon is present but contains no text.
+  Replacements = formatv_object_base::parseFormatString("{0,3:}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(3u, Replacements[0].Align);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // 3. If alignment is missing, it defaults to 0, right, space
+  Replacements = formatv_object_base::parseFormatString("{0:foo}");
+  ASSERT_EQ(1u, Replacements.size());
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ(' ', Replacements[0].Pad);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(0u, Replacements[0].Align);
+  EXPECT_EQ("foo", Replacements[0].Options);
+}
+
+TEST(FormatVariadicTest, MultipleReplacements) {
+  auto Replacements =
+      formatv_object_base::parseFormatString("{0} {1:foo}-{2,-3:bar}");
+  ASSERT_EQ(5u, Replacements.size());
+  // {0}
+  EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
+  EXPECT_EQ(0u, Replacements[0].Index);
+  EXPECT_EQ(0u, Replacements[0].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
+  EXPECT_EQ("", Replacements[0].Options);
+
+  // " "
+  EXPECT_EQ(ReplacementType::Literal, Replacements[1].Type);
+  EXPECT_EQ(" ", Replacements[1].Spec);
+
+  // {1:foo} - Options=foo
+  EXPECT_EQ(ReplacementType::Format, Replacements[2].Type);
+  EXPECT_EQ(1u, Replacements[2].Index);
+  EXPECT_EQ(0u, Replacements[2].Align);
+  EXPECT_EQ(AlignStyle::Right, Replacements[2].Where);
+  EXPECT_EQ("foo", Replacements[2].Options);
+
+  // "-"
+  EXPECT_EQ(ReplacementType::Literal, Replacements[3].Type);
+  EXPECT_EQ("-", Replacements[3].Spec);
+
+  // {2:bar,-3} - Options=bar, Align=-3
+  EXPECT_EQ(ReplacementType::Format, Replacements[4].Type);
+  EXPECT_EQ(2u, Replacements[4].Index);
+  EXPECT_EQ(3u, Replacements[4].Align);
+  EXPECT_EQ(AlignStyle::Left, Replacements[4].Where);
+  EXPECT_EQ("bar", Replacements[4].Options);
+}
+
+TEST(FormatVariadicTest, FormatNoReplacements) {
+  EXPECT_EQ("", formatv("").str());
+  EXPECT_EQ("Test", formatv("Test").str());
+}
+
+TEST(FormatVariadicTest, FormatBasicTypesOneReplacement) {
+  EXPECT_EQ("1", formatv("{0}", 1).str());
+  EXPECT_EQ("c", formatv("{0}", 'c').str());
+  EXPECT_EQ("-3", formatv("{0}", -3).str());
+  EXPECT_EQ("Test", formatv("{0}", "Test").str());
+  EXPECT_EQ("Test2", formatv("{0}", StringRef("Test2")).str());
+  EXPECT_EQ("Test3", formatv("{0}", std::string("Test3")).str());
+}
+
+TEST(FormatVariadicTest, IntegralHexFormatting) {
+  // 1. Trivial cases.  Make sure hex is not the default.
+  EXPECT_EQ("0", formatv("{0}", 0).str());
+  EXPECT_EQ("2748", formatv("{0}", 0xABC).str());
+  EXPECT_EQ("-2748", formatv("{0}", -0xABC).str());
+
+  // 3. various hex prefixes.
+  EXPECT_EQ("0xFF", formatv("{0:X}", 255).str());
+  EXPECT_EQ("0xFF", formatv("{0:X+}", 255).str());
+  EXPECT_EQ("0xff", formatv("{0:x}", 255).str());
+  EXPECT_EQ("0xff", formatv("{0:x+}", 255).str());
+  EXPECT_EQ("FF", formatv("{0:X-}", 255).str());
+  EXPECT_EQ("ff", formatv("{0:x-}", 255).str());
+
+  // 5. Precision pads left of the most significant digit but right of the
+  // prefix (if one exists).
+  EXPECT_EQ("0xFF", formatv("{0:X2}", 255).str());
+  EXPECT_EQ("0xFF", formatv("{0:X+2}", 255).str());
+  EXPECT_EQ("0x0ff", formatv("{0:x3}", 255).str());
+  EXPECT_EQ("0x0ff", formatv("{0:x+3}", 255).str());
+  EXPECT_EQ("00FF", formatv("{0:X-4}", 255).str());
+  EXPECT_EQ("00ff", formatv("{0:x-4}", 255).str());
+
+  // 6. Try some larger types.
+  EXPECT_EQ("0xDEADBEEFDEADBEEF",
+            formatv("{0:X16}", -2401053088876216593LL).str());
+  EXPECT_EQ("0xFEEBDAEDFEEBDAED",
+            formatv("{0:X16}", 0xFEEBDAEDFEEBDAEDULL).str());
+  EXPECT_EQ("0x00000000DEADBEEF", formatv("{0:X16}", 0xDEADBEEF).str());
+
+  // 7. Padding should take into account the prefix
+  EXPECT_EQ("0xff", formatv("{0,4:x}", 255).str());
+  EXPECT_EQ(" 0xff", formatv("{0,5:x+}", 255).str());
+  EXPECT_EQ("  FF", formatv("{0,4:X-}", 255).str());
+  EXPECT_EQ("   ff", formatv("{0,5:x-}", 255).str());
+
+  // 8. Including when it's been zero-padded
+  EXPECT_EQ("  0x0ff", formatv("{0,7:x3}", 255).str());
+  EXPECT_EQ(" 0x00ff", formatv("{0,7:x+4}", 255).str());
+  EXPECT_EQ("  000FF", formatv("{0,7:X-5}", 255).str());
+  EXPECT_EQ(" 0000ff", formatv("{0,7:x-6}", 255).str());
+
+  // 9. Precision with default format specifier should work too
+  EXPECT_EQ("    255", formatv("{0,7:3}", 255).str());
+  EXPECT_EQ("   0255", formatv("{0,7:4}", 255).str());
+  EXPECT_EQ("  00255", formatv("{0,7:5}", 255).str());
+  EXPECT_EQ(" 000255", formatv("{0,7:6}", 255).str());
+}
+
+TEST(FormatVariadicTest, PointerFormatting) {
+  // 1. Trivial cases.  Hex is default.  Default Precision is pointer width.
+  if (sizeof(void *) == 4) {
+    EXPECT_EQ("0x00000000", formatv("{0}", (void *)0).str());
+    EXPECT_EQ("0x00000ABC", formatv("{0}", (void *)0xABC).str());
+  } else {
+    EXPECT_EQ("0x0000000000000000", formatv("{0}", (void *)0).str());
+    EXPECT_EQ("0x0000000000000ABC", formatv("{0}", (void *)0xABC).str());
+  }
+
+  // 2. But we can reduce the precision explicitly.
+  EXPECT_EQ("0x0", formatv("{0:0}", (void *)0).str());
+  EXPECT_EQ("0xABC", formatv("{0:0}", (void *)0xABC).str());
+  EXPECT_EQ("0x0000", formatv("{0:4}", (void *)0).str());
+  EXPECT_EQ("0x0ABC", formatv("{0:4}", (void *)0xABC).str());
+
+  // 3. various hex prefixes.
+  EXPECT_EQ("0x0ABC", formatv("{0:X4}", (void *)0xABC).str());
+  EXPECT_EQ("0x0abc", formatv("{0:x4}", (void *)0xABC).str());
+  EXPECT_EQ("0ABC", formatv("{0:X-4}", (void *)0xABC).str());
+  EXPECT_EQ("0abc", formatv("{0:x-4}", (void *)0xABC).str());
+}
+
+TEST(FormatVariadicTest, IntegralNumberFormatting) {
+  // 1. Test comma grouping with default widths and precisions.
+  EXPECT_EQ("0", formatv("{0:N}", 0).str());
+  EXPECT_EQ("10", formatv("{0:N}", 10).str());
+  EXPECT_EQ("100", formatv("{0:N}", 100).str());
+  EXPECT_EQ("1,000", formatv("{0:N}", 1000).str());
+  EXPECT_EQ("1,234,567,890", formatv("{0:N}", 1234567890).str());
+  EXPECT_EQ("-10", formatv("{0:N}", -10).str());
+  EXPECT_EQ("-100", formatv("{0:N}", -100).str());
+  EXPECT_EQ("-1,000", formatv("{0:N}", -1000).str());
+  EXPECT_EQ("-1,234,567,890", formatv("{0:N}", -1234567890).str());
+
+  // 2. If there is no comma, width and precision pad to the same absolute
+  // size.
+  EXPECT_EQ(" 1", formatv("{0,2:N}", 1).str());
+
+  // 3. But if there is a comma or negative sign, width factors them in but
+  // precision doesn't.
+  EXPECT_EQ(" 1,000", formatv("{0,6:N}", 1000).str());
+  EXPECT_EQ(" -1,000", formatv("{0,7:N}", -1000).str());
+
+  // 4. Large widths all line up.
+  EXPECT_EQ("      1,000", formatv("{0,11:N}", 1000).str());
+  EXPECT_EQ("     -1,000", formatv("{0,11:N}", -1000).str());
+  EXPECT_EQ("   -100,000", formatv("{0,11:N}", -100000).str());
+}
+
+TEST(FormatVariadicTest, StringFormatting) {
+  const char FooArray[] = "FooArray";
+  const char *FooPtr = "FooPtr";
+  llvm::StringRef FooRef("FooRef");
+  constexpr StringLiteral FooLiteral("FooLiteral");
+  std::string FooString("FooString");
+  // 1. Test that we can print various types of strings.
+  EXPECT_EQ(FooArray, formatv("{0}", FooArray).str());
+  EXPECT_EQ(FooPtr, formatv("{0}", FooPtr).str());
+  EXPECT_EQ(FooRef, formatv("{0}", FooRef).str());
+  EXPECT_EQ(FooLiteral, formatv("{0}", FooLiteral).str());
+  EXPECT_EQ(FooString, formatv("{0}", FooString).str());
+
+  // 2. Test that the precision specifier prints the correct number of
+  // characters.
+  EXPECT_EQ("FooA", formatv("{0:4}", FooArray).str());
+  EXPECT_EQ("FooP", formatv("{0:4}", FooPtr).str());
+  EXPECT_EQ("FooR", formatv("{0:4}", FooRef).str());
+  EXPECT_EQ("FooS", formatv("{0:4}", FooString).str());
+
+  // 3. And that padding works.
+  EXPECT_EQ("  FooA", formatv("{0,6:4}", FooArray).str());
+  EXPECT_EQ("  FooP", formatv("{0,6:4}", FooPtr).str());
+  EXPECT_EQ("  FooR", formatv("{0,6:4}", FooRef).str());
+  EXPECT_EQ("  FooS", formatv("{0,6:4}", FooString).str());
+}
+
+TEST(FormatVariadicTest, CharFormatting) {
+  // 1. Not much to see here.  Just print a char with and without padding.
+  EXPECT_EQ("C", formatv("{0}", 'C').str());
+  EXPECT_EQ("  C", formatv("{0,3}", 'C').str());
+
+  // 2. char is really an integral type though, where the only difference is
+  // that the "default" is to print the ASCII.  So if a non-default presentation
+  // specifier exists, it should print as an integer.
+  EXPECT_EQ("37", formatv("{0:D}", (char)37).str());
+  EXPECT_EQ("  037", formatv("{0,5:D3}", (char)37).str());
+}
+
+TEST(FormatVariadicTest, BoolTest) {
+  // 1. Default style is lowercase text (same as 't')
+  EXPECT_EQ("true", formatv("{0}", true).str());
+  EXPECT_EQ("false", formatv("{0}", false).str());
+  EXPECT_EQ("true", formatv("{0:t}", true).str());
+  EXPECT_EQ("false", formatv("{0:t}", false).str());
+
+  // 2. T - uppercase text
+  EXPECT_EQ("TRUE", formatv("{0:T}", true).str());
+  EXPECT_EQ("FALSE", formatv("{0:T}", false).str());
+
+  // 3. D / d - integral
+  EXPECT_EQ("1", formatv("{0:D}", true).str());
+  EXPECT_EQ("0", formatv("{0:D}", false).str());
+  EXPECT_EQ("1", formatv("{0:d}", true).str());
+  EXPECT_EQ("0", formatv("{0:d}", false).str());
+
+  // 4. Y - uppercase yes/no
+  EXPECT_EQ("YES", formatv("{0:Y}", true).str());
+  EXPECT_EQ("NO", formatv("{0:Y}", false).str());
+
+  // 5. y - lowercase yes/no
+  EXPECT_EQ("yes", formatv("{0:y}", true).str());
+  EXPECT_EQ("no", formatv("{0:y}", false).str());
+}
+
+TEST(FormatVariadicTest, DoubleFormatting) {
+  // Test exponents, fixed point, and percent formatting.
+
+  // 1. Signed, unsigned, and zero exponent format.
+  EXPECT_EQ("0.000000E+00", formatv("{0:E}", 0.0).str());
+  EXPECT_EQ("-0.000000E+00", formatv("{0:E}", -0.0).str());
+  EXPECT_EQ("1.100000E+00", formatv("{0:E}", 1.1).str());
+  EXPECT_EQ("-1.100000E+00", formatv("{0:E}", -1.1).str());
+  EXPECT_EQ("1.234568E+03", formatv("{0:E}", 1234.5678).str());
+  EXPECT_EQ("-1.234568E+03", formatv("{0:E}", -1234.5678).str());
+  EXPECT_EQ("1.234568E-03", formatv("{0:E}", .0012345678).str());
+  EXPECT_EQ("-1.234568E-03", formatv("{0:E}", -.0012345678).str());
+
+  // 2. With padding and precision.
+  EXPECT_EQ("  0.000E+00", formatv("{0,11:E3}", 0.0).str());
+  EXPECT_EQ(" -1.100E+00", formatv("{0,11:E3}", -1.1).str());
+  EXPECT_EQ("  1.235E+03", formatv("{0,11:E3}", 1234.5678).str());
+  EXPECT_EQ(" -1.235E-03", formatv("{0,11:E3}", -.0012345678).str());
+
+  // 3. Signed, unsigned, and zero fixed point format.
+  EXPECT_EQ("0.00", formatv("{0:F}", 0.0).str());
+  EXPECT_EQ("-0.00", formatv("{0:F}", -0.0).str());
+  EXPECT_EQ("1.10", formatv("{0:F}", 1.1).str());
+  EXPECT_EQ("-1.10", formatv("{0:F}", -1.1).str());
+  EXPECT_EQ("1234.57", formatv("{0:F}", 1234.5678).str());
+  EXPECT_EQ("-1234.57", formatv("{0:F}", -1234.5678).str());
+  EXPECT_EQ("0.00", formatv("{0:F}", .0012345678).str());
+  EXPECT_EQ("-0.00", formatv("{0:F}", -.0012345678).str());
+
+  // 2. With padding and precision.
+  EXPECT_EQ("   0.000", formatv("{0,8:F3}", 0.0).str());
+  EXPECT_EQ("  -1.100", formatv("{0,8:F3}", -1.1).str());
+  EXPECT_EQ("1234.568", formatv("{0,8:F3}", 1234.5678).str());
+  EXPECT_EQ("  -0.001", formatv("{0,8:F3}", -.0012345678).str());
+}
+
+TEST(FormatVariadicTest, CustomPaddingCharacter) {
+  // 1. Padding with custom character
+  EXPECT_EQ("==123", formatv("{0,=+5}", 123).str());
+  EXPECT_EQ("=123=", formatv("{0,==5}", 123).str());
+  EXPECT_EQ("123==", formatv("{0,=-5}", 123).str());
+
+  // 2. Combined with zero padding
+  EXPECT_EQ("=00123=", formatv("{0,==7:5}", 123).str());
+}
+
+struct format_tuple {
+  const char *Fmt;
+  explicit format_tuple(const char *Fmt) : Fmt(Fmt) {}
+
+  template <typename... Ts>
+  auto operator()(Ts &&... Values) const
+      -> decltype(formatv(Fmt, std::forward<Ts>(Values)...)) {
+    return formatv(Fmt, std::forward<Ts>(Values)...);
+  }
+};
+
+TEST(FormatVariadicTest, BigTest) {
+  using Tuple =
+      std::tuple<char, int, const char *, StringRef, std::string, double, float,
+                 void *, int, double, int64_t, uint64_t, double, uint8_t>;
+  Tuple Ts[] = {
+      Tuple('a', 1, "Str", StringRef(), std::string(), 3.14159, -.17532f,
+            (void *)nullptr, 123456, 6.02E23, -908234908423, 908234908422234,
+            std::numeric_limits<double>::quiet_NaN(), 0xAB),
+      Tuple('x', 0xDDB5B, "LongerStr", "StringRef", "std::string", -2.7,
+            .08215f, (void *)nullptr, 0, 6.62E-34, -908234908423,
+            908234908422234, std::numeric_limits<double>::infinity(), 0x0)};
+  // Test long string formatting with many edge cases combined.
+  const char *Intro =
+      "There are {{{0}} items in the tuple, and {{{1}} tuple(s) in the array.";
+  const char *Header =
+      "{0,6}|{1,8}|{2,=10}|{3,=10}|{4,=13}|{5,7}|{6,7}|{7,10}|{8,"
+      "-7}|{9,10}|{10,16}|{11,17}|{12,6}|{13,4}";
+  const char *Line =
+      "{0,6}|{1,8:X}|{2,=10}|{3,=10:5}|{4,=13}|{5,7:3}|{6,7:P2}|{7,"
+      "10:X8}|{8,-7:N}|{9,10:E4}|{10,16:N}|{11,17:D}|{12,6}|{13,"
+      "4:X}";
+
+  std::string S;
+  llvm::raw_string_ostream Stream(S);
+  Stream << formatv(Intro, std::tuple_size<Tuple>::value,
+                    llvm::array_lengthof(Ts))
+         << "\n";
+  Stream << formatv(Header, "Char", "HexInt", "Str", "Ref", "std::str",
+                    "double", "float", "pointer", "comma", "exp", "bigint",
+                    "bigint2", "limit", "byte")
+         << "\n";
+  for (auto &Item : Ts) {
+    Stream << llvm::apply_tuple(format_tuple(Line), Item) << "\n";
+  }
+  Stream.flush();
+  const char *Expected =
+      R"foo(There are {14} items in the tuple, and {2} tuple(s) in the array.
+  Char|  HexInt|   Str    |   Ref    |  std::str   | double|  float|   pointer|comma  |       exp|          bigint|          bigint2| limit|byte
+     a|     0x1|   Str    |          |             |  3.142|-17.53%|0x00000000|123,456|6.0200E+23|-908,234,908,423|  908234908422234|   nan|0xAB
+     x| 0xDDB5B|LongerStr |  Strin   | std::string | -2.700|  8.21%|0x00000000|0      |6.6200E-34|-908,234,908,423|  908234908422234|   INF| 0x0
+)foo";
+
+  EXPECT_EQ(Expected, S);
+}
+
+TEST(FormatVariadicTest, Range) {
+  std::vector<int> IntRange = {1, 1, 2, 3, 5, 8, 13};
+
+  // 1. Simple range with default separator and element style.
+  EXPECT_EQ("1, 1, 2, 3, 5, 8, 13",
+            formatv("{0}", make_range(IntRange.begin(), IntRange.end())).str());
+  EXPECT_EQ("1, 2, 3, 5, 8",
+            formatv("{0}", make_range(IntRange.begin() + 1, IntRange.end() - 1))
+                .str());
+
+  // 2. Non-default separator
+  EXPECT_EQ(
+      "1/1/2/3/5/8/13",
+      formatv("{0:$[/]}", make_range(IntRange.begin(), IntRange.end())).str());
+
+  // 3. Default separator, non-default element style.
+  EXPECT_EQ(
+      "0x1, 0x1, 0x2, 0x3, 0x5, 0x8, 0xd",
+      formatv("{0:@[x]}", make_range(IntRange.begin(), IntRange.end())).str());
+
+  // 4. Non-default separator and element style.
+  EXPECT_EQ(
+      "0x1 + 0x1 + 0x2 + 0x3 + 0x5 + 0x8 + 0xd",
+      formatv("{0:$[ + ]@[x]}", make_range(IntRange.begin(), IntRange.end()))
+          .str());
+
+  // 5. Element style and/or separator using alternate delimeters to allow using
+  // delimeter characters as part of the separator.
+  EXPECT_EQ(
+      "<0x1><0x1><0x2><0x3><0x5><0x8><0xd>",
+      formatv("<{0:$[><]@(x)}>", make_range(IntRange.begin(), IntRange.end()))
+          .str());
+  EXPECT_EQ(
+      "[0x1][0x1][0x2][0x3][0x5][0x8][0xd]",
+      formatv("[{0:$(][)@[x]}]", make_range(IntRange.begin(), IntRange.end()))
+          .str());
+  EXPECT_EQ(
+      "(0x1)(0x1)(0x2)(0x3)(0x5)(0x8)(0xd)",
+      formatv("({0:$<)(>@<x>})", make_range(IntRange.begin(), IntRange.end()))
+          .str());
+
+  // 5. Empty range.
+  EXPECT_EQ("", formatv("{0:$[+]@[x]}",
+                        make_range(IntRange.begin(), IntRange.begin()))
+                    .str());
+
+  // 6. Empty separator and style.
+  EXPECT_EQ("11235813",
+            formatv("{0:$[]@<>}", make_range(IntRange.begin(), IntRange.end()))
+                .str());
+}
+
+TEST(FormatVariadicTest, Adapter) {
+  class Negative : public FormatAdapter<int> {
+  public:
+    explicit Negative(int N) : FormatAdapter<int>(std::move(N)) {}
+    void format(raw_ostream &S, StringRef Options) override { S << -Item; }
+  };
+
+  EXPECT_EQ("-7", formatv("{0}", Negative(7)).str());
+
+  int N = 171;
+
+  EXPECT_EQ("  171  ",
+            formatv("{0}", fmt_align(N, AlignStyle::Center, 7)).str());
+  EXPECT_EQ("--171--",
+            formatv("{0}", fmt_align(N, AlignStyle::Center, 7, '-')).str());
+  EXPECT_EQ(" 171   ", formatv("{0}", fmt_pad(N, 1, 3)).str());
+  EXPECT_EQ("171171171171171", formatv("{0}", fmt_repeat(N, 5)).str());
+
+  EXPECT_EQ(" ABABABABAB   ",
+            formatv("{0:X-}", fmt_pad(fmt_repeat(N, 5), 1, 3)).str());
+  EXPECT_EQ("   AB    AB    AB    AB    AB     ",
+            formatv("{0,=34:X-}", fmt_repeat(fmt_pad(N, 1, 3), 5)).str());
+}
+
+TEST(FormatVariadicTest, MoveConstructor) {
+  auto fmt = formatv("{0} {1}", 1, 2);
+  auto fmt2 = std::move(fmt);
+  std::string S = fmt2;
+  EXPECT_EQ("1 2", S);
+}
+TEST(FormatVariadicTest, ImplicitConversions) {
+  std::string S = formatv("{0} {1}", 1, 2);
+  EXPECT_EQ("1 2", S);
+
+  SmallString<4> S2 = formatv("{0} {1}", 1, 2);
+  EXPECT_EQ("1 2", S2);
+}
+
+TEST(FormatVariadicTest, FormatAdapter) {
+  EXPECT_EQ("Format", formatv("{0}", Format(1)).str());
+
+  Format var(1);
+  EXPECT_EQ("Format", formatv("{0}", var).str());
+  EXPECT_EQ("Format", formatv("{0}", std::move(var)).str());
+
+  // Not supposed to compile
+  // const Format cvar(1);
+  // EXPECT_EQ("Format", formatv("{0}", cvar).str());
+}
+
+TEST(FormatVariadicTest, FormatFormatvObject) {
+  EXPECT_EQ("Format", formatv("F{0}t", formatv("o{0}a", "rm")).str());
+  EXPECT_EQ("[   ! ]", formatv("[{0,+5}]", formatv("{0,-2}", "!")).str());
+}
+
+namespace {
+struct Recorder {
+  int Copied = 0, Moved = 0;
+  Recorder() = default;
+  Recorder(const Recorder &Copy) : Copied(1 + Copy.Copied), Moved(Copy.Moved) {}
+  Recorder(const Recorder &&Move)
+      : Copied(Move.Copied), Moved(1 + Move.Moved) {}
+};
+} // namespace
+namespace llvm {
+template <> struct format_provider<Recorder> {
+  static void format(const Recorder &R, raw_ostream &OS, StringRef style) {
+    OS << R.Copied << "C " << R.Moved << "M";
+  }
+};
+} // namespace
+
+TEST(FormatVariadicTest, CopiesAndMoves) {
+  Recorder R;
+  EXPECT_EQ("0C 0M", formatv("{0}", R).str());
+  EXPECT_EQ("0C 3M", formatv("{0}", std::move(R)).str());
+  EXPECT_EQ("0C 3M", formatv("{0}", Recorder()).str());
+  EXPECT_EQ(0, R.Copied);
+  EXPECT_EQ(0, R.Moved);
+}
+
+namespace adl {
+struct X {};
+raw_ostream &operator<<(raw_ostream &OS, const X &) { return OS << "X"; }
+} // namespace adl
+TEST(FormatVariadicTest, FormatStreamable) {
+  adl::X X;
+  EXPECT_EQ("X", formatv("{0}", X).str());
+}
+
+TEST(FormatVariadicTest, FormatError) {
+  auto E1 = make_error<StringError>("X", inconvertibleErrorCode());
+  EXPECT_EQ("X", formatv("{0}", E1).str());
+  EXPECT_TRUE(E1.isA<StringError>()); // not consumed
+  EXPECT_EQ("X", formatv("{0}", fmt_consume(std::move(E1))).str());
+  EXPECT_FALSE(E1.isA<StringError>()); // consumed
+}
diff --git a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
new file mode 100644
index 0000000..d7016ab
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
@@ -0,0 +1,79 @@
+//===- llvm/unittest/Support/GlobPatternTest.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/GlobPattern.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+namespace {
+
+class GlobPatternTest : public ::testing::Test {};
+
+TEST_F(GlobPatternTest, Basics) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match(""));
+  EXPECT_FALSE(Pat1->match("a"));
+
+  Expected<GlobPattern> Pat2 = GlobPattern::create("ab*c*def");
+  EXPECT_TRUE((bool)Pat2);
+  EXPECT_TRUE(Pat2->match("abcdef"));
+  EXPECT_TRUE(Pat2->match("abxcxdef"));
+  EXPECT_FALSE(Pat2->match(""));
+  EXPECT_FALSE(Pat2->match("xabcdef"));
+  EXPECT_FALSE(Pat2->match("abcdefx"));
+
+  Expected<GlobPattern> Pat3 = GlobPattern::create("a??c");
+  EXPECT_TRUE((bool)Pat3);
+  EXPECT_TRUE(Pat3->match("axxc"));
+  EXPECT_FALSE(Pat3->match("axxx"));
+  EXPECT_FALSE(Pat3->match(""));
+
+  Expected<GlobPattern> Pat4 = GlobPattern::create("[abc-fy-z]");
+  EXPECT_TRUE((bool)Pat4);
+  EXPECT_TRUE(Pat4->match("a"));
+  EXPECT_TRUE(Pat4->match("b"));
+  EXPECT_TRUE(Pat4->match("c"));
+  EXPECT_TRUE(Pat4->match("d"));
+  EXPECT_TRUE(Pat4->match("e"));
+  EXPECT_TRUE(Pat4->match("f"));
+  EXPECT_TRUE(Pat4->match("y"));
+  EXPECT_TRUE(Pat4->match("z"));
+  EXPECT_FALSE(Pat4->match("g"));
+  EXPECT_FALSE(Pat4->match(""));
+
+  Expected<GlobPattern> Pat5 = GlobPattern::create("[^abc-fy-z]");
+  EXPECT_TRUE((bool)Pat5);
+  EXPECT_TRUE(Pat5->match("g"));
+  EXPECT_FALSE(Pat5->match("a"));
+  EXPECT_FALSE(Pat5->match("b"));
+  EXPECT_FALSE(Pat5->match("c"));
+  EXPECT_FALSE(Pat5->match("d"));
+  EXPECT_FALSE(Pat5->match("e"));
+  EXPECT_FALSE(Pat5->match("f"));
+  EXPECT_FALSE(Pat5->match("y"));
+  EXPECT_FALSE(Pat5->match("z"));
+  EXPECT_FALSE(Pat5->match(""));
+}
+
+TEST_F(GlobPatternTest, Invalid) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("[");
+  EXPECT_FALSE((bool)Pat1);
+  handleAllErrors(Pat1.takeError(), [&](ErrorInfoBase &EIB) {});
+}
+
+TEST_F(GlobPatternTest, ExtSym) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("a*\xFF");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("axxx\xFF"));
+  Expected<GlobPattern> Pat2 = GlobPattern::create("[\xFF-\xFF]");
+  EXPECT_TRUE((bool)Pat2);
+  EXPECT_TRUE(Pat2->match("\xFF"));
+}
+}
diff --git a/src/llvm-project/llvm/unittests/Support/Host.cpp b/src/llvm-project/llvm/unittests/Support/Host.cpp
new file mode 100644
index 0000000..0d257a7
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/Host.cpp
@@ -0,0 +1,298 @@
+//========- unittests/Support/Host.cpp - Host.cpp 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/Host.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+
+#include "gtest/gtest.h"
+
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
+    SmallString<128> MessageStorage;                                           \
+    raw_svector_ostream Message(MessageStorage);                               \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+
+using namespace llvm;
+
+class HostTest : public testing::Test {
+  Triple Host;
+
+protected:
+  bool isSupportedArchAndOS() {
+    // Initially this is only testing detection of the number of
+    // physical cores, which is currently only supported/tested for
+    // x86_64 Linux and Darwin.
+    return (Host.getArch() == Triple::x86_64 &&
+            (Host.isOSDarwin() || Host.getOS() == Triple::Linux));
+  }
+
+  HostTest() : Host(Triple::normalize(sys::getProcessTriple())) {}
+};
+
+TEST_F(HostTest, NumPhysicalCores) {
+  int Num = sys::getHostNumPhysicalCores();
+
+  if (isSupportedArchAndOS())
+    ASSERT_GT(Num, 0);
+  else
+    ASSERT_EQ(Num, -1);
+}
+
+TEST(getLinuxHostCPUName, ARM) {
+  StringRef CortexA9ProcCpuinfo = R"(
+processor       : 0
+model name      : ARMv7 Processor rev 10 (v7l)
+BogoMIPS        : 1393.66
+Features        : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant     : 0x2
+CPU part        : 0xc09
+CPU revision    : 10
+
+processor       : 1
+model name      : ARMv7 Processor rev 10 (v7l)
+BogoMIPS        : 1393.66
+Features        : half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpd32
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant     : 0x2
+CPU part        : 0xc09
+CPU revision    : 10
+
+Hardware        : Generic OMAP4 (Flattened Device Tree)
+Revision        : 0000
+Serial          : 0000000000000000
+)";
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(CortexA9ProcCpuinfo),
+            "cortex-a9");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
+                                              "CPU part        : 0xc0f"),
+            "cortex-a15");
+  // Verify that both CPU implementer and CPU part are checked:
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
+                                              "CPU part        : 0xc0f"),
+            "generic");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0x06f"),
+            "krait");
+}
+
+TEST(getLinuxHostCPUName, AArch64) {
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n"
+                                              "CPU part        : 0xd03"),
+            "cortex-a53");
+  // Verify that both CPU implementer and CPU part are checked:
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n"
+                                              "CPU part        : 0xd03"),
+            "generic");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0x201"),
+            "kryo");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0x800"),
+            "cortex-a73");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0x801"),
+            "cortex-a73");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0xc00"),
+            "falkor");
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n"
+                                              "CPU part        : 0xc01"),
+            "saphira");
+
+  // MSM8992/4 weirdness
+  StringRef MSM8992ProcCpuInfo = R"(
+Processor       : AArch64 Processor rev 3 (aarch64)
+processor       : 0
+processor       : 1
+processor       : 2
+processor       : 3
+processor       : 4
+processor       : 5
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x41
+CPU architecture: 8
+CPU variant     : 0x0
+CPU part        : 0xd03
+CPU revision    : 3
+
+Hardware        : Qualcomm Technologies, Inc MSM8992
+)";
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo),
+            "cortex-a53");
+
+  // Exynos big.LITTLE weirdness
+  const std::string ExynosProcCpuInfo = R"(
+processor       : 0
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x41
+CPU architecture: 8
+CPU variant     : 0x0
+CPU part        : 0xd03
+
+processor       : 1
+Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer : 0x53
+CPU architecture: 8
+)";
+
+  // Verify default for Exynos.
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
+                                              "CPU variant     : 0xc\n"
+                                              "CPU part        : 0xafe"),
+            "exynos-m1");
+  // Verify Exynos M1.
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
+                                              "CPU variant     : 0x1\n"
+                                              "CPU part        : 0x001"),
+            "exynos-m1");
+  // Verify Exynos M2.
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
+                                              "CPU variant     : 0x4\n"
+                                              "CPU part        : 0x001"),
+            "exynos-m2");
+
+  const std::string ThunderX2T99ProcCpuInfo = R"(
+processor	: 0
+BogoMIPS	: 400.00
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
+CPU implementer	: 0x43
+CPU architecture: 8
+CPU variant	: 0x1
+CPU part	: 0x0af
+)";
+
+  // Verify different versions of ThunderX2T99.
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x42\n"
+                                              "CPU part	: 0x516"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x42\n"
+                                              "CPU part	: 0x0516"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x43\n"
+                                              "CPU part	: 0x516"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x43\n"
+                                              "CPU part	: 0x0516"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x42\n"
+                                              "CPU part	: 0xaf"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x42\n"
+                                              "CPU part	: 0x0af"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x43\n"
+                                              "CPU part	: 0xaf"),
+            "thunderx2t99");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderX2T99ProcCpuInfo +
+                                              "CPU implementer	: 0x43\n"
+                                              "CPU part	: 0x0af"),
+            "thunderx2t99");
+
+  // Verify ThunderXT88.
+  const std::string ThunderXT88ProcCpuInfo = R"(
+processor	: 0
+BogoMIPS	: 200.00
+Features	: fp asimd evtstrm aes pmull sha1 sha2 crc32
+CPU implementer	: 0x43
+CPU architecture: 8
+CPU variant	: 0x1
+CPU part	: 0x0a1
+)";
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
+                                              "CPU implementer	: 0x43\n"
+                                              "CPU part	: 0x0a1"),
+            "thunderxt88");
+
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM(ThunderXT88ProcCpuInfo +
+                                              "CPU implementer	: 0x43\n"
+                                              "CPU part	: 0xa1"),
+            "thunderxt88");
+
+  // Verify HiSilicon processors.
+  EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x48\n"
+                                              "CPU part        : 0xd01"),
+            "tsv110");
+}
+
+#if defined(__APPLE__)
+TEST_F(HostTest, getMacOSHostVersion) {
+  using namespace llvm::sys;
+  llvm::Triple HostTriple(getProcessTriple());
+  if (!HostTriple.isMacOSX())
+    return;
+
+  SmallString<128> TestDirectory;
+  ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
+  SmallString<128> OutputFile(TestDirectory);
+  path::append(OutputFile, "out");
+
+  const char *SwVersPath = "/usr/bin/sw_vers";
+  StringRef argv[] = {SwVersPath, "-productVersion"};
+  StringRef OutputPath = OutputFile.str();
+  const Optional<StringRef> Redirects[] = {/*STDIN=*/None,
+                                           /*STDOUT=*/OutputPath,
+                                           /*STDERR=*/None};
+  int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/llvm::None, Redirects);
+  ASSERT_EQ(0, RetCode);
+
+  int FD = 0;
+  ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
+  off_t Size = ::lseek(FD, 0, SEEK_END);
+  ASSERT_NE(-1, Size);
+  ::lseek(FD, 0, SEEK_SET);
+  std::unique_ptr<char[]> Buffer = llvm::make_unique<char[]>(Size);
+  ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
+  ::close(FD);
+
+  // Ensure that the two versions match.
+  StringRef SystemVersion(Buffer.get(), Size);
+  unsigned SystemMajor, SystemMinor, SystemMicro;
+  ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersion))
+                .getMacOSXVersion(SystemMajor, SystemMinor, SystemMicro),
+            true);
+  unsigned HostMajor, HostMinor, HostMicro;
+  ASSERT_EQ(HostTriple.getMacOSXVersion(HostMajor, HostMinor, HostMicro), true);
+
+  // Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
+  // triples.
+  ASSERT_EQ(std::tie(SystemMajor, SystemMinor), std::tie(HostMajor, HostMinor));
+
+  ASSERT_NO_ERROR(fs::remove(OutputPath));
+  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
new file mode 100644
index 0000000..2fd6bd8
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
@@ -0,0 +1,377 @@
+//===-------------- ItaniumManglingCanonicalizerTest.cpp ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ItaniumManglingCanonicalizer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+
+#include <cstdlib>
+#include <map>
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+using EquivalenceError = llvm::ItaniumManglingCanonicalizer::EquivalenceError;
+using FragmentKind = llvm::ItaniumManglingCanonicalizer::FragmentKind;
+
+struct Equivalence {
+  FragmentKind Kind;
+  llvm::StringRef First;
+  llvm::StringRef Second;
+};
+
+// A set of manglings that should all be considered equivalent.
+using EquivalenceClass = std::vector<llvm::StringRef>;
+
+struct Testcase {
+  // A set of equivalences to register.
+  std::vector<Equivalence> Equivalences;
+  // A set of distinct equivalence classes created by registering the
+  // equivalences.
+  std::vector<EquivalenceClass> Classes;
+};
+
+// A function that returns a set of test cases.
+static std::vector<Testcase> getTestcases() {
+  return {
+    // Three different manglings for std::string (old libstdc++, new libstdc++,
+    // libc++).
+    {
+      {
+        {FragmentKind::Type, "Ss",
+         "NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"},
+        {FragmentKind::Type, "Ss",
+         "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"},
+      },
+      {
+        {"_Z1fv"},
+        {"_Z1fSs",
+         "_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE",
+         "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"},
+        {"_ZNKSs4sizeEv",
+         "_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4sizeEv",
+         "_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4sizeEv"},
+      }
+    },
+
+    // Check that substitutions are properly handled.
+    {
+      {
+        // ::X <-> ::N::X<int>
+        {FragmentKind::Type, "1X", "N1N1XIiEE"},
+        // ::T<T<int, int>, T<int, int>> <-> T<int>
+        {FragmentKind::Type, "1TIS_IiiES0_E", "1TIiE"},
+        // A::B::foo <-> AB::foo
+        {FragmentKind::Name, "N1A1B3fooE", "N2AB3fooE"},
+      },
+      {
+        {"_Z1f1XPS_RS_", "_Z1fN1N1XIiEEPS1_RS1_"},
+        {"_ZN1A1B3fooE1TIS1_IiiES2_EPS3_RS3_", "_ZN2AB3fooE1TIiEPS1_RS1_"},
+      }
+    },
+
+    // Check that nested equivalences are properly handled.
+    {
+      {
+        // std::__1::char_traits == std::__cxx11::char_traits
+        // (Note that this is unused and should make no difference,
+        // but it should not cause us to fail to match up the cases
+        // below.)
+        {FragmentKind::Name,
+         "NSt3__111char_traitsE",
+         "NSt7__cxx1111char_traitsE"},
+        // std::__1::allocator == std::allocator
+        {FragmentKind::Name,
+         "NSt3__19allocatorE",
+         "Sa"}, // "Sa" is not strictly a <name> but we accept it as one.
+        // std::__1::vector == std::vector
+        {FragmentKind::Name,
+         "St6vector",
+         "NSt3__16vectorE"},
+        // std::__1::basic_string<
+        //   char
+        //   std::__1::char_traits<char>,
+        //   std::__1::allocator<char>> ==
+        // std::__cxx11::basic_string<
+        //   char,
+        //   std::char_traits<char>,
+        //   std::allocator<char>>
+        {FragmentKind::Type,
+         "NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE",
+         "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"},
+        // X<A> <-> X<B>
+        {FragmentKind::Type, "1XI1AE", "1XI1BE"},
+        // X <-> Y
+        {FragmentKind::Name, "1X", "1Y"},
+      },
+      {
+        // f(std::string)
+        {"_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE",
+         "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"},
+        // f(std::vector<int>)
+        {"_Z1fSt6vectorIiSaIiEE", "_Z1fNSt3__16vectorIiNS_9allocatorIiEEEE"},
+        // f(X<A>), f(X<B>), f(Y<A>), f(Y<B>)
+        {"_Z1f1XI1AE", "_Z1f1XI1BE", "_Z1f1YI1AE", "_Z1f1YI1BE"},
+        // f(X<C>), f(Y<C>)
+        {"_Z1f1XI1CE", "_Z1f1YI1CE"},
+      }
+    },
+
+    // Check namespace equivalences.
+    {
+      {
+        // std::__1 == std::__cxx11
+        {FragmentKind::Name, "St3__1", "St7__cxx11"},
+        // std::__1::allocator == std::allocator
+        {FragmentKind::Name, "NSt3__19allocatorE", "Sa"},
+        // std::vector == std::__1::vector
+        {FragmentKind::Name, "St6vector", "NSt3__16vectorE"},
+        // std::__cxx11::char_traits == std::char_traits
+        // (This indirectly means that std::__1::char_traits == std::char_traits,
+        // due to the std::__cxx11 == std::__1 equivalence, which is what we rely
+        // on below.)
+        {FragmentKind::Name, "NSt7__cxx1111char_traitsE", "St11char_traits"},
+      },
+      {
+        // f(std::foo)
+        {"_Z1fNSt7__cxx113fooE",
+         "_Z1fNSt3__13fooE"},
+        // f(std::string)
+        {"_Z1fNSt7__cxx1111char_traitsIcEE",
+         "_Z1fNSt3__111char_traitsIcEE",
+         "_Z1fSt11char_traitsIcE"},
+        // f(std::string)
+        {"_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE",
+         "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"},
+        // f(std::vector<int>)
+        {"_Z1fSt6vectorIiSaIiEE", "_Z1fNSt3__16vectorIiNS_9allocatorIiEEEE"},
+      }
+    },
+
+    // Check namespace equivalences for namespace 'std'. We support using 'St'
+    // for this, despite it not technically being a <name>.
+    {
+      {
+        // std::__1 == std
+        {FragmentKind::Name, "St3__1", "St"},
+        // std::__1 == std::__cxx11
+        {FragmentKind::Name, "St3__1", "St7__cxx11"},
+        // FIXME: Should a 'std' equivalence also cover the predefined
+        // substitutions?
+        // std::__1::allocator == std::allocator
+        {FragmentKind::Name, "NSt3__19allocatorE", "Sa"},
+      },
+      {
+        {"_Z1fSt3foo", "_Z1fNSt3__13fooE", "_Z1fNSt7__cxx113fooE"},
+        {"_Z1fNSt3bar3bazE", "_Z1fNSt3__13bar3bazE"},
+        // f(std::string)
+        {"_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE",
+         "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"},
+        // f(std::vector<int>)
+        {"_Z1fSt6vectorIiSaIiEE", "_Z1fNSt3__16vectorIiNS_9allocatorIiEEEE"},
+      }
+    },
+
+    // Check mutually-recursive equivalences.
+    {
+      {
+        {FragmentKind::Type, "1A", "1B"},
+        {FragmentKind::Type, "1A", "1C"},
+        {FragmentKind::Type, "1D", "1B"},
+        {FragmentKind::Type, "1C", "1E"},
+      },
+      {
+        {"_Z1f1A", "_Z1f1B", "_Z1f1C", "_Z1f1D", "_Z1f1E"},
+        {"_Z1f1F"},
+      }
+    },
+
+    // Check <encoding>s.
+    {
+      {
+        {FragmentKind::Encoding, "1fv", "1gv"},
+      },
+      {
+        // f(void) -> g(void)
+        {"_Z1fv", "_Z1gv"},
+        // static local 'n' in f(void) -> static local 'n' in g(void)
+        {"_ZZ1fvE1n", "_ZZ1gvE1n"},
+      }
+    },
+
+    // Corner case: the substitution can appear within its own expansion.
+    {
+      {
+        // X <-> Y<X>
+        {FragmentKind::Type, "1X", "1YI1XE"},
+        // A<B> <-> B
+        {FragmentKind::Type, "1AI1BE", "1B"},
+      },
+      {
+        // f(X) == f(Y<X>) == f(Y<Y<X>>) == f(Y<Y<Y<X>>>)
+        {"_Z1f1X", "_Z1f1YI1XE", "_Z1f1YIS_I1XEE", "_Z1f1YIS_IS_I1XEEE"},
+        // f(B) == f(A<B>) == f(A<A<B>>) == f(A<A<A<B>>>)
+        {"_Z1f1B", "_Z1f1AI1BE", "_Z1f1AIS_I1BEE", "_Z1f1AIS_IS_I1BEEE"},
+      }
+    },
+
+    // Redundant equivalences are accepted (and have no effect).
+    {
+      {
+        {FragmentKind::Name, "3std", "St"},
+        {FragmentKind::Name, "1X", "1Y"},
+        {FragmentKind::Name, "N1X1ZE", "N1Y1ZE"},
+      },
+      {}
+    },
+
+    // Check that ctor and dtor variants are considered distinct.
+    {
+      {},
+      {{"_ZN1XC1Ev"}, {"_ZN1XC2Ev"}, {"_ZN1XD1Ev"}, {"_ZN1XD2Ev"}}
+    },
+
+    // Ensure array types with and without bounds are handled properly.
+    {
+      {
+        {FragmentKind::Type, "A_i", "A1_f"},
+      },
+      {
+        {"_Z1fRA_i", "_Z1fRA_i", "_Z1fRA1_f"},
+        {"_Z1fRA1_i"}, {"_Z1fRA_f"},
+      }
+    },
+  };
+}
+
+// A function to get a set of test cases for forward template references.
+static std::vector<Testcase> getForwardTemplateReferenceTestcases() {
+  return {
+    // ForwardTemplateReference does not support canonicalization.
+    // FIXME: We should consider ways of fixing this, perhaps by eliminating
+    // the ForwardTemplateReference node with a tree transformation.
+    {
+      {
+        // X::operator T() <with T = A> == Y::operator T() <with T = A>
+        {FragmentKind::Encoding, "N1XcvT_I1AEEv", "N1YcvT_I1AEEv"},
+        // A == B
+        {FragmentKind::Name, "1A", "1B"},
+      },
+      {
+        // All combinations result in unique equivalence classes.
+        {"_ZN1XcvT_I1AEEv"},
+        {"_ZN1XcvT_I1BEEv"},
+        {"_ZN1YcvT_I1AEEv"},
+        {"_ZN1YcvT_I1BEEv"},
+        // Even giving the same string twice gives a new class.
+        {"_ZN1XcvT_I1AEEv"},
+      }
+    },
+  };
+}
+
+template<bool CanonicalizeFirst>
+static void testTestcases(ArrayRef<Testcase> Testcases) {
+  for (const auto &Testcase : Testcases) {
+    llvm::ItaniumManglingCanonicalizer Canonicalizer;
+    for (const auto &Equiv : Testcase.Equivalences) {
+      auto Result =
+          Canonicalizer.addEquivalence(Equiv.Kind, Equiv.First, Equiv.Second);
+      EXPECT_EQ(Result, EquivalenceError::Success)
+          << "couldn't add equivalence between " << Equiv.First << " and "
+          << Equiv.Second;
+    }
+
+    using CanonKey = llvm::ItaniumManglingCanonicalizer::Key;
+
+    std::map<const EquivalenceClass*, CanonKey> Keys;
+    if (CanonicalizeFirst)
+      for (const auto &Class : Testcase.Classes)
+        Keys.insert({&Class, Canonicalizer.canonicalize(*Class.begin())});
+
+    std::map<CanonKey, llvm::StringRef> Found;
+    for (const auto &Class : Testcase.Classes) {
+      CanonKey ClassKey = Keys[&Class];
+      for (llvm::StringRef Str : Class) {
+        // Force a copy to be made when calling lookup to test that it doesn't
+        // retain any part of the provided string.
+        CanonKey ThisKey = CanonicalizeFirst
+                               ? Canonicalizer.lookup(std::string(Str))
+                               : Canonicalizer.canonicalize(Str);
+        EXPECT_NE(ThisKey, CanonKey()) << "couldn't canonicalize " << Str;
+        if (ClassKey) {
+          EXPECT_EQ(ThisKey, ClassKey)
+              << Str << " not in the same class as " << *Class.begin();
+        } else {
+          ClassKey = ThisKey;
+        }
+      }
+      EXPECT_TRUE(Found.insert({ClassKey, *Class.begin()}).second)
+          << *Class.begin() << " is in the same class as " << Found[ClassKey];
+    }
+  }
+}
+
+TEST(ItaniumManglingCanonicalizerTest, TestCanonicalize) {
+  testTestcases<false>(getTestcases());
+}
+
+TEST(ItaniumManglingCanonicalizerTest, TestLookup) {
+  testTestcases<true>(getTestcases());
+}
+
+TEST(ItaniumManglingCanonicalizerTest, TestForwardTemplateReference) {
+  // lookup(...) after canonicalization (intentionally) returns different
+  // values for this testcase.
+  testTestcases<false>(getForwardTemplateReferenceTestcases());
+}
+
+
+TEST(ItaniumManglingCanonicalizerTest, TestInvalidManglings) {
+  llvm::ItaniumManglingCanonicalizer Canonicalizer;
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "", "1X"),
+            EquivalenceError::InvalidFirstMangling);
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1X", "1ab"),
+            EquivalenceError::InvalidSecondMangling);
+  EXPECT_EQ(Canonicalizer.canonicalize("_Z3fooE"),
+            llvm::ItaniumManglingCanonicalizer::Key());
+  EXPECT_EQ(Canonicalizer.canonicalize("foo"),
+            llvm::ItaniumManglingCanonicalizer::Key());
+
+  // A reference to a template parameter ('T_' etc) cannot appear in a <name>,
+  // because we don't have template arguments to bind to it. (The arguments in
+  // an 'I ... E' construct in the <name> aren't registered as
+  // backreferenceable arguments in this sense, because they're not part of
+  // the template argument list of an <encoding>.
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Name, "N1XcvT_I1AEE",
+                                         "1f"),
+            EquivalenceError::InvalidFirstMangling);
+}
+
+TEST(ItaniumManglingCanonicalizerTest, TestBadEquivalenceOrder) {
+  llvm::ItaniumManglingCanonicalizer Canonicalizer;
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "N1P1XE", "N1Q1XE"),
+            EquivalenceError::Success);
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1P", "1Q"),
+            EquivalenceError::ManglingAlreadyUsed);
+
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "N1C1XE", "N1A1YE"),
+            EquivalenceError::Success);
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1A", "1B"),
+            EquivalenceError::Success);
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1C", "1D"),
+            EquivalenceError::Success);
+  EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1B", "1D"),
+            EquivalenceError::ManglingAlreadyUsed);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
new file mode 100644
index 0000000..9f2d47b
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
@@ -0,0 +1,389 @@
+//===-- JSONTest.cpp - JSON unit tests --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/JSON.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace json {
+
+namespace {
+
+std::string s(const Value &E) { return llvm::formatv("{0}", E).str(); }
+std::string sp(const Value &E) { return llvm::formatv("{0:2}", E).str(); }
+
+TEST(JSONTest, Types) {
+  EXPECT_EQ("true", s(true));
+  EXPECT_EQ("null", s(nullptr));
+  EXPECT_EQ("2.5", s(2.5));
+  EXPECT_EQ(R"("foo")", s("foo"));
+  EXPECT_EQ("[1,2,3]", s({1, 2, 3}));
+  EXPECT_EQ(R"({"x":10,"y":20})", s(Object{{"x", 10}, {"y", 20}}));
+
+#ifdef NDEBUG
+  EXPECT_EQ(R"("��")", s("\xC0\x80"));
+  EXPECT_EQ(R"({"��":0})", s(Object{{"\xC0\x80", 0}}));
+#else
+  EXPECT_DEATH(s("\xC0\x80"), "Invalid UTF-8");
+  EXPECT_DEATH(s(Object{{"\xC0\x80", 0}}), "Invalid UTF-8");
+#endif
+}
+
+TEST(JSONTest, Constructors) {
+  // Lots of edge cases around empty and singleton init lists.
+  EXPECT_EQ("[[[3]]]", s({{{3}}}));
+  EXPECT_EQ("[[[]]]", s({{{}}}));
+  EXPECT_EQ("[[{}]]", s({{Object{}}}));
+  EXPECT_EQ(R"({"A":{"B":{}}})", s(Object{{"A", Object{{"B", Object{}}}}}));
+  EXPECT_EQ(R"({"A":{"B":{"X":"Y"}}})",
+            s(Object{{"A", Object{{"B", Object{{"X", "Y"}}}}}}));
+  EXPECT_EQ("null", s(llvm::Optional<double>()));
+  EXPECT_EQ("2.5", s(llvm::Optional<double>(2.5)));
+  EXPECT_EQ("[[2.5,null]]", s(std::vector<std::vector<llvm::Optional<double>>>{
+                                 {2.5, llvm::None}}));
+}
+
+TEST(JSONTest, StringOwnership) {
+  char X[] = "Hello";
+  Value Alias = static_cast<const char *>(X);
+  X[1] = 'a';
+  EXPECT_EQ(R"("Hallo")", s(Alias));
+
+  std::string Y = "Hello";
+  Value Copy = Y;
+  Y[1] = 'a';
+  EXPECT_EQ(R"("Hello")", s(Copy));
+}
+
+TEST(JSONTest, CanonicalOutput) {
+  // Objects are sorted (but arrays aren't)!
+  EXPECT_EQ(R"({"a":1,"b":2,"c":3})", s(Object{{"a", 1}, {"c", 3}, {"b", 2}}));
+  EXPECT_EQ(R"(["a","c","b"])", s({"a", "c", "b"}));
+  EXPECT_EQ("3", s(3.0));
+}
+
+TEST(JSONTest, Escaping) {
+  std::string test = {
+      0,                    // Strings may contain nulls.
+      '\b',   '\f',         // Have mnemonics, but we escape numerically.
+      '\r',   '\n',   '\t', // Escaped with mnemonics.
+      'S',    '\"',   '\\', // Printable ASCII characters.
+      '\x7f',               // Delete is not escaped.
+      '\xce', '\x94',       // Non-ASCII UTF-8 is not escaped.
+  };
+
+  std::string teststring = R"("\u0000\u0008\u000c\r\n\tS\"\\)"
+                           "\x7f\xCE\x94\"";
+
+  EXPECT_EQ(teststring, s(test));
+
+  EXPECT_EQ(R"({"object keys are\nescaped":true})",
+            s(Object{{"object keys are\nescaped", true}}));
+}
+
+TEST(JSONTest, PrettyPrinting) {
+  const char str[] = R"({
+  "empty_array": [],
+  "empty_object": {},
+  "full_array": [
+    1,
+    null
+  ],
+  "full_object": {
+    "nested_array": [
+      {
+        "property": "value"
+      }
+    ]
+  }
+})";
+
+  EXPECT_EQ(str, sp(Object{
+                     {"empty_object", Object{}},
+                     {"empty_array", {}},
+                     {"full_array", {1, nullptr}},
+                     {"full_object",
+                      Object{
+                          {"nested_array",
+                           {Object{
+                               {"property", "value"},
+                           }}},
+                      }},
+                 }));
+}
+
+TEST(JSONTest, Parse) {
+  auto Compare = [](llvm::StringRef S, Value Expected) {
+    if (auto E = parse(S)) {
+      // Compare both string forms and with operator==, in case we have bugs.
+      EXPECT_EQ(*E, Expected);
+      EXPECT_EQ(sp(*E), sp(Expected));
+    } else {
+      handleAllErrors(E.takeError(), [S](const llvm::ErrorInfoBase &E) {
+        FAIL() << "Failed to parse JSON >>> " << S << " <<<: " << E.message();
+      });
+    }
+  };
+
+  Compare(R"(true)", true);
+  Compare(R"(false)", false);
+  Compare(R"(null)", nullptr);
+
+  Compare(R"(42)", 42);
+  Compare(R"(2.5)", 2.5);
+  Compare(R"(2e50)", 2e50);
+  Compare(R"(1.2e3456789)", std::numeric_limits<double>::infinity());
+
+  Compare(R"("foo")", "foo");
+  Compare(R"("\"\\\b\f\n\r\t")", "\"\\\b\f\n\r\t");
+  Compare(R"("\u0000")", llvm::StringRef("\0", 1));
+  Compare("\"\x7f\"", "\x7f");
+  Compare(R"("\ud801\udc37")", u8"\U00010437"); // UTF16 surrogate pair escape.
+  Compare("\"\xE2\x82\xAC\xF0\x9D\x84\x9E\"", u8"\u20ac\U0001d11e"); // UTF8
+  Compare(
+      R"("LoneLeading=\ud801, LoneTrailing=\udc01, LeadingLeadingTrailing=\ud801\ud801\udc37")",
+      u8"LoneLeading=\ufffd, LoneTrailing=\ufffd, "
+      u8"LeadingLeadingTrailing=\ufffd\U00010437"); // Invalid unicode.
+
+  Compare(R"({"":0,"":0})", Object{{"", 0}});
+  Compare(R"({"obj":{},"arr":[]})", Object{{"obj", Object{}}, {"arr", {}}});
+  Compare(R"({"\n":{"\u0000":[[[[]]]]}})",
+          Object{{"\n", Object{
+                            {llvm::StringRef("\0", 1), {{{{}}}}},
+                        }}});
+  Compare("\r[\n\t] ", {});
+}
+
+TEST(JSONTest, ParseErrors) {
+  auto ExpectErr = [](llvm::StringRef Msg, llvm::StringRef S) {
+    if (auto E = parse(S)) {
+      // Compare both string forms and with operator==, in case we have bugs.
+      FAIL() << "Parsed JSON >>> " << S << " <<< but wanted error: " << Msg;
+    } else {
+      handleAllErrors(E.takeError(), [S, Msg](const llvm::ErrorInfoBase &E) {
+        EXPECT_THAT(E.message(), testing::HasSubstr(Msg)) << S;
+      });
+    }
+  };
+  ExpectErr("Unexpected EOF", "");
+  ExpectErr("Unexpected EOF", "[");
+  ExpectErr("Text after end of document", "[][]");
+  ExpectErr("Invalid JSON value (false?)", "fuzzy");
+  ExpectErr("Expected , or ]", "[2?]");
+  ExpectErr("Expected object key", "{a:2}");
+  ExpectErr("Expected : after object key", R"({"a",2})");
+  ExpectErr("Expected , or } after object property", R"({"a":2 "b":3})");
+  ExpectErr("Invalid JSON value", R"([&%!])");
+  ExpectErr("Invalid JSON value (number?)", "1e1.0");
+  ExpectErr("Unterminated string", R"("abc\"def)");
+  ExpectErr("Control character in string", "\"abc\ndef\"");
+  ExpectErr("Invalid escape sequence", R"("\030")");
+  ExpectErr("Invalid \\u escape sequence", R"("\usuck")");
+  ExpectErr("[3:3, byte=19]", R"({
+  "valid": 1,
+  invalid: 2
+})");
+  ExpectErr("Invalid UTF-8 sequence", "\"\xC0\x80\""); // WTF-8 null
+}
+
+// Direct tests of isUTF8 and fixUTF8. Internal uses are also tested elsewhere.
+TEST(JSONTest, UTF8) {
+  for (const char *Valid : {
+           "this is ASCII text",
+           "thïs tëxt häs BMP chäräctërs",
+           "𐌶𐌰L𐌾𐍈 C𐍈𐌼𐌴𐍃",
+       }) {
+    EXPECT_TRUE(isUTF8(Valid)) << Valid;
+    EXPECT_EQ(fixUTF8(Valid), Valid);
+  }
+  for (auto Invalid : std::vector<std::pair<const char *, const char *>>{
+           {"lone trailing \x81\x82 bytes", "lone trailing �� bytes"},
+           {"missing trailing \xD0 bytes", "missing trailing � bytes"},
+           {"truncated character \xD0", "truncated character �"},
+           {"not \xC1\x80 the \xE0\x9f\xBF shortest \xF0\x83\x83\x83 encoding",
+            "not �� the ��� shortest ���� encoding"},
+           {"too \xF9\x80\x80\x80\x80 long", "too ����� long"},
+           {"surrogate \xED\xA0\x80 invalid \xF4\x90\x80\x80",
+            "surrogate ��� invalid ����"}}) {
+    EXPECT_FALSE(isUTF8(Invalid.first)) << Invalid.first;
+    EXPECT_EQ(fixUTF8(Invalid.first), Invalid.second);
+  }
+}
+
+TEST(JSONTest, Inspection) {
+  llvm::Expected<Value> Doc = parse(R"(
+    {
+      "null": null,
+      "boolean": false,
+      "number": 2.78,
+      "string": "json",
+      "array": [null, true, 3.14, "hello", [1,2,3], {"time": "arrow"}],
+      "object": {"fruit": "banana"}
+    }
+  )");
+  EXPECT_TRUE(!!Doc);
+
+  Object *O = Doc->getAsObject();
+  ASSERT_TRUE(O);
+
+  EXPECT_FALSE(O->getNull("missing"));
+  EXPECT_FALSE(O->getNull("boolean"));
+  EXPECT_TRUE(O->getNull("null"));
+
+  EXPECT_EQ(O->getNumber("number"), llvm::Optional<double>(2.78));
+  EXPECT_FALSE(O->getInteger("number"));
+  EXPECT_EQ(O->getString("string"), llvm::Optional<llvm::StringRef>("json"));
+  ASSERT_FALSE(O->getObject("missing"));
+  ASSERT_FALSE(O->getObject("array"));
+  ASSERT_TRUE(O->getObject("object"));
+  EXPECT_EQ(*O->getObject("object"), (Object{{"fruit", "banana"}}));
+
+  Array *A = O->getArray("array");
+  ASSERT_TRUE(A);
+  EXPECT_EQ((*A)[1].getAsBoolean(), llvm::Optional<bool>(true));
+  ASSERT_TRUE((*A)[4].getAsArray());
+  EXPECT_EQ(*(*A)[4].getAsArray(), (Array{1, 2, 3}));
+  EXPECT_EQ((*(*A)[4].getAsArray())[1].getAsInteger(),
+            llvm::Optional<int64_t>(2));
+  int I = 0;
+  for (Value &E : *A) {
+    if (I++ == 5) {
+      ASSERT_TRUE(E.getAsObject());
+      EXPECT_EQ(E.getAsObject()->getString("time"),
+                llvm::Optional<llvm::StringRef>("arrow"));
+    } else
+      EXPECT_FALSE(E.getAsObject());
+  }
+}
+
+// Verify special integer handling - we try to preserve exact int64 values.
+TEST(JSONTest, Integers) {
+  struct {
+    const char *Desc;
+    Value Val;
+    const char *Str;
+    llvm::Optional<int64_t> AsInt;
+    llvm::Optional<double> AsNumber;
+  } TestCases[] = {
+      {
+          "Non-integer. Stored as double, not convertible.",
+          double{1.5},
+          "1.5",
+          llvm::None,
+          1.5,
+      },
+
+      {
+          "Integer, not exact double. Stored as int64, convertible.",
+          int64_t{0x4000000000000001},
+          "4611686018427387905",
+          int64_t{0x4000000000000001},
+          double{0x4000000000000000},
+      },
+
+      {
+          "Negative integer, not exact double. Stored as int64, convertible.",
+          int64_t{-0x4000000000000001},
+          "-4611686018427387905",
+          int64_t{-0x4000000000000001},
+          double{-0x4000000000000000},
+      },
+
+      {
+          "Dynamically exact integer. Stored as double, convertible.",
+          double{0x6000000000000000},
+          "6.9175290276410819e+18",
+          int64_t{0x6000000000000000},
+          double{0x6000000000000000},
+      },
+
+      {
+          "Dynamically integer, >64 bits. Stored as double, not convertible.",
+          1.5 * double{0x8000000000000000},
+          "1.3835058055282164e+19",
+          llvm::None,
+          1.5 * double{0x8000000000000000},
+      },
+  };
+  for (const auto &T : TestCases) {
+    EXPECT_EQ(T.Str, s(T.Val)) << T.Desc;
+    llvm::Expected<Value> Doc = parse(T.Str);
+    EXPECT_TRUE(!!Doc) << T.Desc;
+    EXPECT_EQ(Doc->getAsInteger(), T.AsInt) << T.Desc;
+    EXPECT_EQ(Doc->getAsNumber(), T.AsNumber) << T.Desc;
+    EXPECT_EQ(T.Val, *Doc) << T.Desc;
+    EXPECT_EQ(T.Str, s(*Doc)) << T.Desc;
+  }
+}
+
+// Sample struct with typical JSON-mapping rules.
+struct CustomStruct {
+  CustomStruct() : B(false) {}
+  CustomStruct(std::string S, llvm::Optional<int> I, bool B)
+      : S(S), I(I), B(B) {}
+  std::string S;
+  llvm::Optional<int> I;
+  bool B;
+};
+inline bool operator==(const CustomStruct &L, const CustomStruct &R) {
+  return L.S == R.S && L.I == R.I && L.B == R.B;
+}
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     const CustomStruct &S) {
+  return OS << "(" << S.S << ", " << (S.I ? std::to_string(*S.I) : "None")
+            << ", " << S.B << ")";
+}
+bool fromJSON(const Value &E, CustomStruct &R) {
+  ObjectMapper O(E);
+  if (!O || !O.map("str", R.S) || !O.map("int", R.I))
+    return false;
+  O.map("bool", R.B);
+  return true;
+}
+
+TEST(JSONTest, Deserialize) {
+  std::map<std::string, std::vector<CustomStruct>> R;
+  CustomStruct ExpectedStruct = {"foo", 42, true};
+  std::map<std::string, std::vector<CustomStruct>> Expected;
+  Value J = Object{
+      {"foo",
+       Array{
+           Object{
+               {"str", "foo"},
+               {"int", 42},
+               {"bool", true},
+               {"unknown", "ignored"},
+           },
+           Object{{"str", "bar"}},
+           Object{
+               {"str", "baz"}, {"bool", "string"}, // OK, deserialize ignores.
+           },
+       }}};
+  Expected["foo"] = {
+      CustomStruct("foo", 42, true),
+      CustomStruct("bar", llvm::None, false),
+      CustomStruct("baz", llvm::None, false),
+  };
+  ASSERT_TRUE(fromJSON(J, R));
+  EXPECT_EQ(R, Expected);
+
+  CustomStruct V;
+  EXPECT_FALSE(fromJSON(nullptr, V)) << "Not an object " << V;
+  EXPECT_FALSE(fromJSON(Object{}, V)) << "Missing required field " << V;
+  EXPECT_FALSE(fromJSON(Object{{"str", 1}}, V)) << "Wrong type " << V;
+  // Optional<T> must parse as the correct type if present.
+  EXPECT_FALSE(fromJSON(Object{{"str", 1}, {"int", "string"}}, V))
+      << "Wrong type for Optional<T> " << V;
+}
+
+} // namespace
+} // namespace json
+} // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp b/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
new file mode 100644
index 0000000..1c9b5db
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/LEB128Test.cpp
@@ -0,0 +1,368 @@
+//===- llvm/unittest/Support/LEB128Test.cpp - LEB128 function 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/LEB128.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include <string>
+using namespace llvm;
+
+namespace {
+
+TEST(LEB128Test, EncodeSLEB128) {
+#define EXPECT_SLEB128_EQ(EXPECTED, VALUE, PAD) \
+  do { \
+    std::string Expected(EXPECTED, sizeof(EXPECTED) - 1); \
+    \
+    /* encodeSLEB128(uint64_t, raw_ostream &, unsigned) */ \
+    std::string Actual1; \
+    raw_string_ostream Stream(Actual1); \
+    encodeSLEB128(VALUE, Stream, PAD); \
+    Stream.flush(); \
+    EXPECT_EQ(Expected, Actual1); \
+    \
+    /* encodeSLEB128(uint64_t, uint8_t *, unsigned) */ \
+    uint8_t Buffer[32]; \
+    unsigned Size = encodeSLEB128(VALUE, Buffer, PAD); \
+    std::string Actual2(reinterpret_cast<const char *>(Buffer), Size); \
+    EXPECT_EQ(Expected, Actual2); \
+  } while (0)
+
+  // Encode SLEB128
+  EXPECT_SLEB128_EQ("\x00", 0, 0);
+  EXPECT_SLEB128_EQ("\x01", 1, 0);
+  EXPECT_SLEB128_EQ("\x7f", -1, 0);
+  EXPECT_SLEB128_EQ("\x3f", 63, 0);
+  EXPECT_SLEB128_EQ("\x41", -63, 0);
+  EXPECT_SLEB128_EQ("\x40", -64, 0);
+  EXPECT_SLEB128_EQ("\xbf\x7f", -65, 0);
+  EXPECT_SLEB128_EQ("\xc0\x00", 64, 0);
+
+  // Encode SLEB128 with some extra padding bytes
+  EXPECT_SLEB128_EQ("\x80\x00", 0, 2);
+  EXPECT_SLEB128_EQ("\x80\x80\x00", 0, 3);
+  EXPECT_SLEB128_EQ("\xff\x80\x00", 0x7f, 3);
+  EXPECT_SLEB128_EQ("\xff\x80\x80\x00", 0x7f, 4);
+  EXPECT_SLEB128_EQ("\x80\x81\x00", 0x80, 3);
+  EXPECT_SLEB128_EQ("\x80\x81\x80\x00", 0x80, 4);
+  EXPECT_SLEB128_EQ("\xc0\x7f", -0x40, 2);
+
+  EXPECT_SLEB128_EQ("\xc0\xff\x7f", -0x40, 3);
+  EXPECT_SLEB128_EQ("\x80\xff\x7f", -0x80, 3);
+  EXPECT_SLEB128_EQ("\x80\xff\xff\x7f", -0x80, 4);
+
+#undef EXPECT_SLEB128_EQ
+}
+
+TEST(LEB128Test, EncodeULEB128) {
+#define EXPECT_ULEB128_EQ(EXPECTED, VALUE, PAD) \
+  do { \
+    std::string Expected(EXPECTED, sizeof(EXPECTED) - 1); \
+    \
+    /* encodeULEB128(uint64_t, raw_ostream &, unsigned) */ \
+    std::string Actual1; \
+    raw_string_ostream Stream(Actual1); \
+    encodeULEB128(VALUE, Stream, PAD); \
+    Stream.flush(); \
+    EXPECT_EQ(Expected, Actual1); \
+    \
+    /* encodeULEB128(uint64_t, uint8_t *, unsigned) */ \
+    uint8_t Buffer[32]; \
+    unsigned Size = encodeULEB128(VALUE, Buffer, PAD); \
+    std::string Actual2(reinterpret_cast<const char *>(Buffer), Size); \
+    EXPECT_EQ(Expected, Actual2); \
+  } while (0)
+
+  // Encode ULEB128
+  EXPECT_ULEB128_EQ("\x00", 0, 0);
+  EXPECT_ULEB128_EQ("\x01", 1, 0);
+  EXPECT_ULEB128_EQ("\x3f", 63, 0);
+  EXPECT_ULEB128_EQ("\x40", 64, 0);
+  EXPECT_ULEB128_EQ("\x7f", 0x7f, 0);
+  EXPECT_ULEB128_EQ("\x80\x01", 0x80, 0);
+  EXPECT_ULEB128_EQ("\x81\x01", 0x81, 0);
+  EXPECT_ULEB128_EQ("\x90\x01", 0x90, 0);
+  EXPECT_ULEB128_EQ("\xff\x01", 0xff, 0);
+  EXPECT_ULEB128_EQ("\x80\x02", 0x100, 0);
+  EXPECT_ULEB128_EQ("\x81\x02", 0x101, 0);
+
+  // Encode ULEB128 with some extra padding bytes
+  EXPECT_ULEB128_EQ("\x80\x00", 0, 2);
+  EXPECT_ULEB128_EQ("\x80\x80\x00", 0, 3);
+  EXPECT_ULEB128_EQ("\xff\x00", 0x7f, 2);
+  EXPECT_ULEB128_EQ("\xff\x80\x00", 0x7f, 3);
+  EXPECT_ULEB128_EQ("\x80\x81\x00", 0x80, 3);
+  EXPECT_ULEB128_EQ("\x80\x81\x80\x00", 0x80, 4);
+
+#undef EXPECT_ULEB128_EQ
+}
+
+TEST(LEB128Test, DecodeULEB128) {
+#define EXPECT_DECODE_ULEB128_EQ(EXPECTED, VALUE) \
+  do { \
+    unsigned ActualSize = 0; \
+    uint64_t Actual = decodeULEB128(reinterpret_cast<const uint8_t *>(VALUE), \
+                                    &ActualSize); \
+    EXPECT_EQ(sizeof(VALUE) - 1, ActualSize); \
+    EXPECT_EQ(EXPECTED, Actual); \
+  } while (0)
+
+  // Decode ULEB128
+  EXPECT_DECODE_ULEB128_EQ(0u, "\x00");
+  EXPECT_DECODE_ULEB128_EQ(1u, "\x01");
+  EXPECT_DECODE_ULEB128_EQ(63u, "\x3f");
+  EXPECT_DECODE_ULEB128_EQ(64u, "\x40");
+  EXPECT_DECODE_ULEB128_EQ(0x7fu, "\x7f");
+  EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x01");
+  EXPECT_DECODE_ULEB128_EQ(0x81u, "\x81\x01");
+  EXPECT_DECODE_ULEB128_EQ(0x90u, "\x90\x01");
+  EXPECT_DECODE_ULEB128_EQ(0xffu, "\xff\x01");
+  EXPECT_DECODE_ULEB128_EQ(0x100u, "\x80\x02");
+  EXPECT_DECODE_ULEB128_EQ(0x101u, "\x81\x02");
+  EXPECT_DECODE_ULEB128_EQ(4294975616ULL, "\x80\xc1\x80\x80\x10");
+
+  // Decode ULEB128 with extra padding bytes
+  EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x00");
+  EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x80\x00");
+  EXPECT_DECODE_ULEB128_EQ(0x7fu, "\xff\x00");
+  EXPECT_DECODE_ULEB128_EQ(0x7fu, "\xff\x80\x00");
+  EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x81\x00");
+  EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x81\x80\x00");
+
+#undef EXPECT_DECODE_ULEB128_EQ
+}
+
+TEST(LEB128Test, DecodeSLEB128) {
+#define EXPECT_DECODE_SLEB128_EQ(EXPECTED, VALUE) \
+  do { \
+    unsigned ActualSize = 0; \
+    int64_t Actual = decodeSLEB128(reinterpret_cast<const uint8_t *>(VALUE), \
+                                    &ActualSize); \
+    EXPECT_EQ(sizeof(VALUE) - 1, ActualSize); \
+    EXPECT_EQ(EXPECTED, Actual); \
+  } while (0)
+
+  // Decode SLEB128
+  EXPECT_DECODE_SLEB128_EQ(0L, "\x00");
+  EXPECT_DECODE_SLEB128_EQ(1L, "\x01");
+  EXPECT_DECODE_SLEB128_EQ(63L, "\x3f");
+  EXPECT_DECODE_SLEB128_EQ(-64L, "\x40");
+  EXPECT_DECODE_SLEB128_EQ(-63L, "\x41");
+  EXPECT_DECODE_SLEB128_EQ(-1L, "\x7f");
+  EXPECT_DECODE_SLEB128_EQ(128L, "\x80\x01");
+  EXPECT_DECODE_SLEB128_EQ(129L, "\x81\x01");
+  EXPECT_DECODE_SLEB128_EQ(-129L, "\xff\x7e");
+  EXPECT_DECODE_SLEB128_EQ(-128L, "\x80\x7f");
+  EXPECT_DECODE_SLEB128_EQ(-127L, "\x81\x7f");
+  EXPECT_DECODE_SLEB128_EQ(64L, "\xc0\x00");
+  EXPECT_DECODE_SLEB128_EQ(-12345L, "\xc7\x9f\x7f");
+
+  // Decode unnormalized SLEB128 with extra padding bytes.
+  EXPECT_DECODE_SLEB128_EQ(0L, "\x80\x00");
+  EXPECT_DECODE_SLEB128_EQ(0L, "\x80\x80\x00");
+  EXPECT_DECODE_SLEB128_EQ(0x7fL, "\xff\x00");
+  EXPECT_DECODE_SLEB128_EQ(0x7fL, "\xff\x80\x00");
+  EXPECT_DECODE_SLEB128_EQ(0x80L, "\x80\x81\x00");
+  EXPECT_DECODE_SLEB128_EQ(0x80L, "\x80\x81\x80\x00");
+
+#undef EXPECT_DECODE_SLEB128_EQ
+}
+
+TEST(LEB128Test, SLEB128Size) {
+  // Positive Value Testing Plan:
+  // (1) 128 ^ n - 1 ........ need (n+1) bytes
+  // (2) 128 ^ n ............ need (n+1) bytes
+  // (3) 128 ^ n * 63 ....... need (n+1) bytes
+  // (4) 128 ^ n * 64 - 1 ... need (n+1) bytes
+  // (5) 128 ^ n * 64 ....... need (n+2) bytes
+
+  EXPECT_EQ(1u, getSLEB128Size(0x0LL));
+  EXPECT_EQ(1u, getSLEB128Size(0x1LL));
+  EXPECT_EQ(1u, getSLEB128Size(0x3fLL));
+  EXPECT_EQ(1u, getSLEB128Size(0x3fLL));
+  EXPECT_EQ(2u, getSLEB128Size(0x40LL));
+
+  EXPECT_EQ(2u, getSLEB128Size(0x7fLL));
+  EXPECT_EQ(2u, getSLEB128Size(0x80LL));
+  EXPECT_EQ(2u, getSLEB128Size(0x1f80LL));
+  EXPECT_EQ(2u, getSLEB128Size(0x1fffLL));
+  EXPECT_EQ(3u, getSLEB128Size(0x2000LL));
+
+  EXPECT_EQ(3u, getSLEB128Size(0x3fffLL));
+  EXPECT_EQ(3u, getSLEB128Size(0x4000LL));
+  EXPECT_EQ(3u, getSLEB128Size(0xfc000LL));
+  EXPECT_EQ(3u, getSLEB128Size(0xfffffLL));
+  EXPECT_EQ(4u, getSLEB128Size(0x100000LL));
+
+  EXPECT_EQ(4u, getSLEB128Size(0x1fffffLL));
+  EXPECT_EQ(4u, getSLEB128Size(0x200000LL));
+  EXPECT_EQ(4u, getSLEB128Size(0x7e00000LL));
+  EXPECT_EQ(4u, getSLEB128Size(0x7ffffffLL));
+  EXPECT_EQ(5u, getSLEB128Size(0x8000000LL));
+
+  EXPECT_EQ(5u, getSLEB128Size(0xfffffffLL));
+  EXPECT_EQ(5u, getSLEB128Size(0x10000000LL));
+  EXPECT_EQ(5u, getSLEB128Size(0x3f0000000LL));
+  EXPECT_EQ(5u, getSLEB128Size(0x3ffffffffLL));
+  EXPECT_EQ(6u, getSLEB128Size(0x400000000LL));
+
+  EXPECT_EQ(6u, getSLEB128Size(0x7ffffffffLL));
+  EXPECT_EQ(6u, getSLEB128Size(0x800000000LL));
+  EXPECT_EQ(6u, getSLEB128Size(0x1f800000000LL));
+  EXPECT_EQ(6u, getSLEB128Size(0x1ffffffffffLL));
+  EXPECT_EQ(7u, getSLEB128Size(0x20000000000LL));
+
+  EXPECT_EQ(7u, getSLEB128Size(0x3ffffffffffLL));
+  EXPECT_EQ(7u, getSLEB128Size(0x40000000000LL));
+  EXPECT_EQ(7u, getSLEB128Size(0xfc0000000000LL));
+  EXPECT_EQ(7u, getSLEB128Size(0xffffffffffffLL));
+  EXPECT_EQ(8u, getSLEB128Size(0x1000000000000LL));
+
+  EXPECT_EQ(8u, getSLEB128Size(0x1ffffffffffffLL));
+  EXPECT_EQ(8u, getSLEB128Size(0x2000000000000LL));
+  EXPECT_EQ(8u, getSLEB128Size(0x7e000000000000LL));
+  EXPECT_EQ(8u, getSLEB128Size(0x7fffffffffffffLL));
+  EXPECT_EQ(9u, getSLEB128Size(0x80000000000000LL));
+
+  EXPECT_EQ(9u, getSLEB128Size(0xffffffffffffffLL));
+  EXPECT_EQ(9u, getSLEB128Size(0x100000000000000LL));
+  EXPECT_EQ(9u, getSLEB128Size(0x3f00000000000000LL));
+  EXPECT_EQ(9u, getSLEB128Size(0x3fffffffffffffffLL));
+  EXPECT_EQ(10u, getSLEB128Size(0x4000000000000000LL));
+
+  EXPECT_EQ(10u, getSLEB128Size(0x7fffffffffffffffLL));
+  EXPECT_EQ(10u, getSLEB128Size(INT64_MAX));
+
+  // Negative Value Testing Plan:
+  // (1) - 128 ^ n - 1 ........ need (n+1) bytes
+  // (2) - 128 ^ n ............ need (n+1) bytes
+  // (3) - 128 ^ n * 63 ....... need (n+1) bytes
+  // (4) - 128 ^ n * 64 ....... need (n+1) bytes (different from positive one)
+  // (5) - 128 ^ n * 65 - 1 ... need (n+2) bytes (if n > 0)
+  // (6) - 128 ^ n * 65 ....... need (n+2) bytes
+
+  EXPECT_EQ(1u, getSLEB128Size(0x0LL));
+  EXPECT_EQ(1u, getSLEB128Size(-0x1LL));
+  EXPECT_EQ(1u, getSLEB128Size(-0x3fLL));
+  EXPECT_EQ(1u, getSLEB128Size(-0x40LL));
+  EXPECT_EQ(1u, getSLEB128Size(-0x40LL)); // special case
+  EXPECT_EQ(2u, getSLEB128Size(-0x41LL));
+
+  EXPECT_EQ(2u, getSLEB128Size(-0x7fLL));
+  EXPECT_EQ(2u, getSLEB128Size(-0x80LL));
+  EXPECT_EQ(2u, getSLEB128Size(-0x1f80LL));
+  EXPECT_EQ(2u, getSLEB128Size(-0x2000LL));
+  EXPECT_EQ(3u, getSLEB128Size(-0x207fLL));
+  EXPECT_EQ(3u, getSLEB128Size(-0x2080LL));
+
+  EXPECT_EQ(3u, getSLEB128Size(-0x3fffLL));
+  EXPECT_EQ(3u, getSLEB128Size(-0x4000LL));
+  EXPECT_EQ(3u, getSLEB128Size(-0xfc000LL));
+  EXPECT_EQ(3u, getSLEB128Size(-0x100000LL));
+  EXPECT_EQ(4u, getSLEB128Size(-0x103fffLL));
+  EXPECT_EQ(4u, getSLEB128Size(-0x104000LL));
+
+  EXPECT_EQ(4u, getSLEB128Size(-0x1fffffLL));
+  EXPECT_EQ(4u, getSLEB128Size(-0x200000LL));
+  EXPECT_EQ(4u, getSLEB128Size(-0x7e00000LL));
+  EXPECT_EQ(4u, getSLEB128Size(-0x8000000LL));
+  EXPECT_EQ(5u, getSLEB128Size(-0x81fffffLL));
+  EXPECT_EQ(5u, getSLEB128Size(-0x8200000LL));
+
+  EXPECT_EQ(5u, getSLEB128Size(-0xfffffffLL));
+  EXPECT_EQ(5u, getSLEB128Size(-0x10000000LL));
+  EXPECT_EQ(5u, getSLEB128Size(-0x3f0000000LL));
+  EXPECT_EQ(5u, getSLEB128Size(-0x400000000LL));
+  EXPECT_EQ(6u, getSLEB128Size(-0x40fffffffLL));
+  EXPECT_EQ(6u, getSLEB128Size(-0x410000000LL));
+
+  EXPECT_EQ(6u, getSLEB128Size(-0x7ffffffffLL));
+  EXPECT_EQ(6u, getSLEB128Size(-0x800000000LL));
+  EXPECT_EQ(6u, getSLEB128Size(-0x1f800000000LL));
+  EXPECT_EQ(6u, getSLEB128Size(-0x20000000000LL));
+  EXPECT_EQ(7u, getSLEB128Size(-0x207ffffffffLL));
+  EXPECT_EQ(7u, getSLEB128Size(-0x20800000000LL));
+
+  EXPECT_EQ(7u, getSLEB128Size(-0x3ffffffffffLL));
+  EXPECT_EQ(7u, getSLEB128Size(-0x40000000000LL));
+  EXPECT_EQ(7u, getSLEB128Size(-0xfc0000000000LL));
+  EXPECT_EQ(7u, getSLEB128Size(-0x1000000000000LL));
+  EXPECT_EQ(8u, getSLEB128Size(-0x103ffffffffffLL));
+  EXPECT_EQ(8u, getSLEB128Size(-0x1040000000000LL));
+
+  EXPECT_EQ(8u, getSLEB128Size(-0x1ffffffffffffLL));
+  EXPECT_EQ(8u, getSLEB128Size(-0x2000000000000LL));
+  EXPECT_EQ(8u, getSLEB128Size(-0x7e000000000000LL));
+  EXPECT_EQ(8u, getSLEB128Size(-0x80000000000000LL));
+  EXPECT_EQ(9u, getSLEB128Size(-0x81ffffffffffffLL));
+  EXPECT_EQ(9u, getSLEB128Size(-0x82000000000000LL));
+
+  EXPECT_EQ(9u, getSLEB128Size(-0xffffffffffffffLL));
+  EXPECT_EQ(9u, getSLEB128Size(-0x100000000000000LL));
+  EXPECT_EQ(9u, getSLEB128Size(-0x3f00000000000000LL));
+  EXPECT_EQ(9u, getSLEB128Size(-0x4000000000000000LL));
+  EXPECT_EQ(10u, getSLEB128Size(-0x40ffffffffffffffLL));
+  EXPECT_EQ(10u, getSLEB128Size(-0x4100000000000000LL));
+
+  EXPECT_EQ(10u, getSLEB128Size(-0x7fffffffffffffffLL));
+  EXPECT_EQ(10u, getSLEB128Size(-0x8000000000000000LL));
+  EXPECT_EQ(10u, getSLEB128Size(INT64_MIN));
+}
+
+TEST(LEB128Test, ULEB128Size) {
+  // Testing Plan:
+  // (1) 128 ^ n ............ need (n+1) bytes
+  // (2) 128 ^ n * 64 ....... need (n+1) bytes
+  // (3) 128 ^ (n+1) - 1 .... need (n+1) bytes
+
+  EXPECT_EQ(1u, getULEB128Size(0)); // special case
+
+  EXPECT_EQ(1u, getULEB128Size(0x1ULL));
+  EXPECT_EQ(1u, getULEB128Size(0x40ULL));
+  EXPECT_EQ(1u, getULEB128Size(0x7fULL));
+
+  EXPECT_EQ(2u, getULEB128Size(0x80ULL));
+  EXPECT_EQ(2u, getULEB128Size(0x2000ULL));
+  EXPECT_EQ(2u, getULEB128Size(0x3fffULL));
+
+  EXPECT_EQ(3u, getULEB128Size(0x4000ULL));
+  EXPECT_EQ(3u, getULEB128Size(0x100000ULL));
+  EXPECT_EQ(3u, getULEB128Size(0x1fffffULL));
+
+  EXPECT_EQ(4u, getULEB128Size(0x200000ULL));
+  EXPECT_EQ(4u, getULEB128Size(0x8000000ULL));
+  EXPECT_EQ(4u, getULEB128Size(0xfffffffULL));
+
+  EXPECT_EQ(5u, getULEB128Size(0x10000000ULL));
+  EXPECT_EQ(5u, getULEB128Size(0x400000000ULL));
+  EXPECT_EQ(5u, getULEB128Size(0x7ffffffffULL));
+
+  EXPECT_EQ(6u, getULEB128Size(0x800000000ULL));
+  EXPECT_EQ(6u, getULEB128Size(0x20000000000ULL));
+  EXPECT_EQ(6u, getULEB128Size(0x3ffffffffffULL));
+
+  EXPECT_EQ(7u, getULEB128Size(0x40000000000ULL));
+  EXPECT_EQ(7u, getULEB128Size(0x1000000000000ULL));
+  EXPECT_EQ(7u, getULEB128Size(0x1ffffffffffffULL));
+
+  EXPECT_EQ(8u, getULEB128Size(0x2000000000000ULL));
+  EXPECT_EQ(8u, getULEB128Size(0x80000000000000ULL));
+  EXPECT_EQ(8u, getULEB128Size(0xffffffffffffffULL));
+
+  EXPECT_EQ(9u, getULEB128Size(0x100000000000000ULL));
+  EXPECT_EQ(9u, getULEB128Size(0x4000000000000000ULL));
+  EXPECT_EQ(9u, getULEB128Size(0x7fffffffffffffffULL));
+
+  EXPECT_EQ(10u, getULEB128Size(0x8000000000000000ULL));
+
+  EXPECT_EQ(10u, getULEB128Size(UINT64_MAX));
+}
+
+}  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp b/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
new file mode 100644
index 0000000..67f9d97
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/LineIteratorTest.cpp
@@ -0,0 +1,193 @@
+//===- LineIterator.cpp - Unit tests --------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+
+namespace {
+
+TEST(LineIteratorTest, Basic) {
+  std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("line 1\n"
+                                                                    "line 2\n"
+                                                                    "line 3");
+
+  line_iterator I = line_iterator(*Buffer), E;
+
+  EXPECT_FALSE(I.is_at_eof());
+  EXPECT_NE(E, I);
+
+  EXPECT_EQ("line 1", *I);
+  EXPECT_EQ(1, I.line_number());
+  ++I;
+  EXPECT_EQ("line 2", *I);
+  EXPECT_EQ(2, I.line_number());
+  ++I;
+  EXPECT_EQ("line 3", *I);
+  EXPECT_EQ(3, I.line_number());
+  ++I;
+
+  EXPECT_TRUE(I.is_at_eof());
+  EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, CommentAndBlankSkipping) {
+  std::unique_ptr<MemoryBuffer> Buffer(
+      MemoryBuffer::getMemBuffer("line 1\n"
+                                 "line 2\n"
+                                 "# Comment 1\n"
+                                 "\n"
+                                 "line 5\n"
+                                 "\n"
+                                 "# Comment 2"));
+
+  line_iterator I = line_iterator(*Buffer, true, '#'), E;
+
+  EXPECT_FALSE(I.is_at_eof());
+  EXPECT_NE(E, I);
+
+  EXPECT_EQ("line 1", *I);
+  EXPECT_EQ(1, I.line_number());
+  ++I;
+  EXPECT_EQ("line 2", *I);
+  EXPECT_EQ(2, I.line_number());
+  ++I;
+  EXPECT_EQ("line 5", *I);
+  EXPECT_EQ(5, I.line_number());
+  ++I;
+
+  EXPECT_TRUE(I.is_at_eof());
+  EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, CommentSkippingKeepBlanks) {
+  std::unique_ptr<MemoryBuffer> Buffer(
+      MemoryBuffer::getMemBuffer("line 1\n"
+                                 "line 2\n"
+                                 "# Comment 1\n"
+                                 "# Comment 2\n"
+                                 "\n"
+                                 "line 6\n"
+                                 "\n"
+                                 "# Comment 3"));
+
+  line_iterator I = line_iterator(*Buffer, false, '#'), E;
+
+  EXPECT_FALSE(I.is_at_eof());
+  EXPECT_NE(E, I);
+
+  EXPECT_EQ("line 1", *I);
+  EXPECT_EQ(1, I.line_number());
+  ++I;
+  EXPECT_EQ("line 2", *I);
+  EXPECT_EQ(2, I.line_number());
+  ++I;
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(5, I.line_number());
+  ++I;
+  EXPECT_EQ("line 6", *I);
+  EXPECT_EQ(6, I.line_number());
+  ++I;
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(7, I.line_number());
+  ++I;
+
+  EXPECT_TRUE(I.is_at_eof());
+  EXPECT_EQ(E, I);
+}
+
+
+TEST(LineIteratorTest, BlankSkipping) {
+  std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("\n\n\n"
+                                                                    "line 1\n"
+                                                                    "\n\n\n"
+                                                                    "line 2\n"
+                                                                    "\n\n\n");
+
+  line_iterator I = line_iterator(*Buffer), E;
+
+  EXPECT_FALSE(I.is_at_eof());
+  EXPECT_NE(E, I);
+
+  EXPECT_EQ("line 1", *I);
+  EXPECT_EQ(4, I.line_number());
+  ++I;
+  EXPECT_EQ("line 2", *I);
+  EXPECT_EQ(8, I.line_number());
+  ++I;
+
+  EXPECT_TRUE(I.is_at_eof());
+  EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, BlankKeeping) {
+  std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("\n\n"
+                                                                    "line 3\n"
+                                                                    "\n"
+                                                                    "line 5\n"
+                                                                    "\n\n");
+  line_iterator I = line_iterator(*Buffer, false), E;
+
+  EXPECT_FALSE(I.is_at_eof());
+  EXPECT_NE(E, I);
+
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(1, I.line_number());
+  ++I;
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(2, I.line_number());
+  ++I;
+  EXPECT_EQ("line 3", *I);
+  EXPECT_EQ(3, I.line_number());
+  ++I;
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(4, I.line_number());
+  ++I;
+  EXPECT_EQ("line 5", *I);
+  EXPECT_EQ(5, I.line_number());
+  ++I;
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(6, I.line_number());
+  ++I;
+  EXPECT_EQ("", *I);
+  EXPECT_EQ(7, I.line_number());
+  ++I;
+
+  EXPECT_TRUE(I.is_at_eof());
+  EXPECT_EQ(E, I);
+}
+
+TEST(LineIteratorTest, EmptyBuffers) {
+  std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer("");
+  EXPECT_TRUE(line_iterator(*Buffer).is_at_eof());
+  EXPECT_EQ(line_iterator(), line_iterator(*Buffer));
+  EXPECT_TRUE(line_iterator(*Buffer, false).is_at_eof());
+  EXPECT_EQ(line_iterator(), line_iterator(*Buffer, false));
+
+  Buffer = MemoryBuffer::getMemBuffer("\n\n\n");
+  EXPECT_TRUE(line_iterator(*Buffer).is_at_eof());
+  EXPECT_EQ(line_iterator(), line_iterator(*Buffer));
+
+  Buffer = MemoryBuffer::getMemBuffer("# foo\n"
+                                      "\n"
+                                      "# bar");
+  EXPECT_TRUE(line_iterator(*Buffer, true, '#').is_at_eof());
+  EXPECT_EQ(line_iterator(), line_iterator(*Buffer, true, '#'));
+
+  Buffer = MemoryBuffer::getMemBuffer("\n"
+                                      "# baz\n"
+                                      "\n");
+  EXPECT_TRUE(line_iterator(*Buffer, true, '#').is_at_eof());
+  EXPECT_EQ(line_iterator(), line_iterator(*Buffer, true, '#'));
+}
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp b/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
new file mode 100644
index 0000000..1775d05
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/LockFileManagerTest.cpp
@@ -0,0 +1,127 @@
+//===- unittests/LockFileManagerTest.cpp - LockFileManager 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/LockFileManager.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "gtest/gtest.h"
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+TEST(LockFileManagerTest, Basic) {
+  SmallString<64> TmpDir;
+  std::error_code EC;
+  EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
+  ASSERT_FALSE(EC);
+
+  SmallString<64> LockedFile(TmpDir);
+  sys::path::append(LockedFile, "file.lock");
+
+  {
+    // The lock file should not exist, so we should successfully acquire it.
+    LockFileManager Locked1(LockedFile);
+    EXPECT_EQ(LockFileManager::LFS_Owned, Locked1.getState());
+
+    // Attempting to reacquire the lock should fail.  Waiting on it would cause
+    // deadlock, so don't try that.
+    LockFileManager Locked2(LockedFile);
+    EXPECT_NE(LockFileManager::LFS_Owned, Locked2.getState());
+  }
+
+  // Now that the lock is out of scope, the file should be gone.
+  EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile)));
+
+  EC = sys::fs::remove(StringRef(TmpDir));
+  ASSERT_FALSE(EC);
+}
+
+TEST(LockFileManagerTest, LinkLockExists) {
+  SmallString<64> TmpDir;
+  std::error_code EC;
+  EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
+  ASSERT_FALSE(EC);
+
+  SmallString<64> LockedFile(TmpDir);
+  sys::path::append(LockedFile, "file");
+
+  SmallString<64> FileLocK(TmpDir);
+  sys::path::append(FileLocK, "file.lock");
+
+  SmallString<64> TmpFileLock(TmpDir);
+  sys::path::append(TmpFileLock, "file.lock-000");
+
+  int FD;
+  EC = sys::fs::openFileForWrite(StringRef(TmpFileLock), FD);
+  ASSERT_FALSE(EC);
+
+  int Ret = close(FD);
+  ASSERT_EQ(Ret, 0);
+
+  EC = sys::fs::create_link(TmpFileLock.str(), FileLocK.str());
+  ASSERT_FALSE(EC);
+
+  EC = sys::fs::remove(StringRef(TmpFileLock));
+  ASSERT_FALSE(EC);
+
+  {
+    // The lock file doesn't point to a real file, so we should successfully
+    // acquire it.
+    LockFileManager Locked(LockedFile);
+    EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
+  }
+
+  // Now that the lock is out of scope, the file should be gone.
+  EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile)));
+
+  EC = sys::fs::remove(StringRef(TmpDir));
+  ASSERT_FALSE(EC);
+}
+
+
+TEST(LockFileManagerTest, RelativePath) {
+  SmallString<64> TmpDir;
+  std::error_code EC;
+  EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
+  ASSERT_FALSE(EC);
+
+  char PathBuf[1024];
+  const char *OrigPath = getcwd(PathBuf, 1024);
+  ASSERT_FALSE(chdir(TmpDir.c_str()));
+
+  sys::fs::create_directory("inner");
+  SmallString<64> LockedFile("inner");
+  sys::path::append(LockedFile, "file");
+
+  SmallString<64> FileLock(LockedFile);
+  FileLock += ".lock";
+
+  {
+    // The lock file should not exist, so we should successfully acquire it.
+    LockFileManager Locked(LockedFile);
+    EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
+    EXPECT_TRUE(sys::fs::exists(FileLock.str()));
+  }
+
+  // Now that the lock is out of scope, the file should be gone.
+  EXPECT_FALSE(sys::fs::exists(LockedFile.str()));
+  EXPECT_FALSE(sys::fs::exists(FileLock.str()));
+
+  EC = sys::fs::remove("inner");
+  ASSERT_FALSE(EC);
+
+  ASSERT_FALSE(chdir(OrigPath));
+
+  EC = sys::fs::remove(StringRef(TmpDir));
+  ASSERT_FALSE(EC);
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MD5Test.cpp b/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
new file mode 100644
index 0000000..bac1ec2
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/MD5Test.cpp
@@ -0,0 +1,72 @@
+//===- llvm/unittest/Support/MD5Test.cpp - MD5 tests ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for the MD5 functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MD5.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+/// Tests an arbitrary set of bytes passed as \p Input.
+void TestMD5Sum(ArrayRef<uint8_t> Input, StringRef Final) {
+  MD5 Hash;
+  Hash.update(Input);
+  MD5::MD5Result MD5Res;
+  Hash.final(MD5Res);
+  SmallString<32> Res;
+  MD5::stringifyResult(MD5Res, Res);
+  EXPECT_EQ(Res, Final);
+}
+
+void TestMD5Sum(StringRef Input, StringRef Final) {
+  MD5 Hash;
+  Hash.update(Input);
+  MD5::MD5Result MD5Res;
+  Hash.final(MD5Res);
+  SmallString<32> Res;
+  MD5::stringifyResult(MD5Res, Res);
+  EXPECT_EQ(Res, Final);
+}
+
+TEST(MD5Test, MD5) {
+  TestMD5Sum(makeArrayRef((const uint8_t *)"", (size_t) 0),
+             "d41d8cd98f00b204e9800998ecf8427e");
+  TestMD5Sum(makeArrayRef((const uint8_t *)"a", (size_t) 1),
+             "0cc175b9c0f1b6a831c399e269772661");
+  TestMD5Sum(makeArrayRef((const uint8_t *)"abcdefghijklmnopqrstuvwxyz",
+                          (size_t) 26),
+             "c3fcd3d76192e4007dfb496cca67e13b");
+  TestMD5Sum(makeArrayRef((const uint8_t *)"\0", (size_t) 1),
+             "93b885adfe0da089cdf634904fd59f71");
+  TestMD5Sum(makeArrayRef((const uint8_t *)"a\0", (size_t) 2),
+             "4144e195f46de78a3623da7364d04f11");
+  TestMD5Sum(makeArrayRef((const uint8_t *)"abcdefghijklmnopqrstuvwxyz\0",
+                          (size_t) 27),
+             "81948d1f1554f58cd1a56ebb01f808cb");
+  TestMD5Sum("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
+}
+
+TEST(MD5HashTest, MD5) {
+  ArrayRef<uint8_t> Input((const uint8_t *)"abcdefghijklmnopqrstuvwxyz", 26);
+  std::array<uint8_t, 16> Vec = MD5::hash(Input);
+  MD5::MD5Result MD5Res;
+  SmallString<32> Res;
+  memcpy(MD5Res.Bytes.data(), Vec.data(), Vec.size());
+  MD5::stringifyResult(MD5Res, Res);
+  EXPECT_EQ(Res, "c3fcd3d76192e4007dfb496cca67e13b");
+  EXPECT_EQ(0x3be167ca6c49fb7dULL, MD5Res.high());
+  EXPECT_EQ(0x00e49261d7d3fcc3ULL, MD5Res.low());
+}
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp b/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
new file mode 100644
index 0000000..d3cc80c
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ManagedStatic.cpp
@@ -0,0 +1,102 @@
+//===- llvm/unittest/Support/ManagedStatic.cpp - ManagedStatic 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/Allocator.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Config/config.h"
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H) && \
+  !__has_feature(memory_sanitizer)
+namespace test1 {
+  llvm::ManagedStatic<int> ms;
+  void *helper(void*) {
+    *ms;
+    return nullptr;
+  }
+
+  // Valgrind's leak checker complains glibc's stack allocation.
+  // To appease valgrind, we provide our own stack for each thread.
+  void *allocate_stack(pthread_attr_t &a, size_t n = 65536) {
+    void *stack = safe_malloc(n);
+    pthread_attr_init(&a);
+#if defined(__linux__)
+    pthread_attr_setstack(&a, stack, n);
+#endif
+    return stack;
+  }
+}
+
+TEST(Initialize, MultipleThreads) {
+  // Run this test under tsan: http://code.google.com/p/data-race-test/
+
+  pthread_attr_t a1, a2;
+  void *p1 = test1::allocate_stack(a1);
+  void *p2 = test1::allocate_stack(a2);
+
+  pthread_t t1, t2;
+  pthread_create(&t1, &a1, test1::helper, nullptr);
+  pthread_create(&t2, &a2, test1::helper, nullptr);
+  pthread_join(t1, nullptr);
+  pthread_join(t2, nullptr);
+  free(p1);
+  free(p2);
+}
+#endif
+
+namespace NestedStatics {
+static ManagedStatic<int> Ms1;
+struct Nest {
+  Nest() {
+    ++(*Ms1);
+  }
+
+  ~Nest() {
+    assert(Ms1.isConstructed());
+    ++(*Ms1);
+  }
+};
+static ManagedStatic<Nest> Ms2;
+
+TEST(ManagedStaticTest, NestedStatics) {
+  EXPECT_FALSE(Ms1.isConstructed());
+  EXPECT_FALSE(Ms2.isConstructed());
+
+  *Ms2;
+  EXPECT_TRUE(Ms1.isConstructed());
+  EXPECT_TRUE(Ms2.isConstructed());
+}
+} // namespace NestedStatics
+
+namespace CustomCreatorDeletor {
+struct CustomCreate {
+  static void *call() {
+    void *Mem = safe_malloc(sizeof(int));
+    *((int *)Mem) = 42;
+    return Mem;
+  }
+};
+struct CustomDelete {
+  static void call(void *P) { std::free(P); }
+};
+static ManagedStatic<int, CustomCreate, CustomDelete> Custom;
+TEST(ManagedStaticTest, CustomCreatorDeletor) {
+  EXPECT_EQ(42, *Custom);
+}
+} // namespace CustomCreatorDeletor
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
new file mode 100644
index 0000000..694a1f2
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
@@ -0,0 +1,472 @@
+//===- unittests/Support/MathExtrasTest.cpp - math utils 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/MathExtras.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(MathExtras, countTrailingZeros) {
+  uint8_t Z8 = 0;
+  uint16_t Z16 = 0;
+  uint32_t Z32 = 0;
+  uint64_t Z64 = 0;
+  EXPECT_EQ(8u, countTrailingZeros(Z8));
+  EXPECT_EQ(16u, countTrailingZeros(Z16));
+  EXPECT_EQ(32u, countTrailingZeros(Z32));
+  EXPECT_EQ(64u, countTrailingZeros(Z64));
+
+  uint8_t NZ8 = 42;
+  uint16_t NZ16 = 42;
+  uint32_t NZ32 = 42;
+  uint64_t NZ64 = 42;
+  EXPECT_EQ(1u, countTrailingZeros(NZ8));
+  EXPECT_EQ(1u, countTrailingZeros(NZ16));
+  EXPECT_EQ(1u, countTrailingZeros(NZ32));
+  EXPECT_EQ(1u, countTrailingZeros(NZ64));
+}
+
+TEST(MathExtras, countLeadingZeros) {
+  uint8_t Z8 = 0;
+  uint16_t Z16 = 0;
+  uint32_t Z32 = 0;
+  uint64_t Z64 = 0;
+  EXPECT_EQ(8u, countLeadingZeros(Z8));
+  EXPECT_EQ(16u, countLeadingZeros(Z16));
+  EXPECT_EQ(32u, countLeadingZeros(Z32));
+  EXPECT_EQ(64u, countLeadingZeros(Z64));
+
+  uint8_t NZ8 = 42;
+  uint16_t NZ16 = 42;
+  uint32_t NZ32 = 42;
+  uint64_t NZ64 = 42;
+  EXPECT_EQ(2u, countLeadingZeros(NZ8));
+  EXPECT_EQ(10u, countLeadingZeros(NZ16));
+  EXPECT_EQ(26u, countLeadingZeros(NZ32));
+  EXPECT_EQ(58u, countLeadingZeros(NZ64));
+
+  EXPECT_EQ(8u, countLeadingZeros(0x00F000FFu));
+  EXPECT_EQ(8u, countLeadingZeros(0x00F12345u));
+  for (unsigned i = 0; i <= 30; ++i) {
+    EXPECT_EQ(31 - i, countLeadingZeros(1u << i));
+  }
+
+  EXPECT_EQ(8u, countLeadingZeros(0x00F1234500F12345ULL));
+  EXPECT_EQ(1u, countLeadingZeros(1ULL << 62));
+  for (unsigned i = 0; i <= 62; ++i) {
+    EXPECT_EQ(63 - i, countLeadingZeros(1ULL << i));
+  }
+}
+
+TEST(MathExtras, onesMask) {
+  EXPECT_EQ(0U, maskLeadingOnes<uint8_t>(0));
+  EXPECT_EQ(0U, maskTrailingOnes<uint8_t>(0));
+  EXPECT_EQ(0U, maskLeadingOnes<uint16_t>(0));
+  EXPECT_EQ(0U, maskTrailingOnes<uint16_t>(0));
+  EXPECT_EQ(0U, maskLeadingOnes<uint32_t>(0));
+  EXPECT_EQ(0U, maskTrailingOnes<uint32_t>(0));
+  EXPECT_EQ(0U, maskLeadingOnes<uint64_t>(0));
+  EXPECT_EQ(0U, maskTrailingOnes<uint64_t>(0));
+
+  EXPECT_EQ(0x00000003U, maskTrailingOnes<uint32_t>(2U));
+  EXPECT_EQ(0xC0000000U, maskLeadingOnes<uint32_t>(2U));
+
+  EXPECT_EQ(0x000007FFU, maskTrailingOnes<uint32_t>(11U));
+  EXPECT_EQ(0xFFE00000U, maskLeadingOnes<uint32_t>(11U));
+
+  EXPECT_EQ(0xFFFFFFFFU, maskTrailingOnes<uint32_t>(32U));
+  EXPECT_EQ(0xFFFFFFFFU, maskLeadingOnes<uint32_t>(32U));
+  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, maskTrailingOnes<uint64_t>(64U));
+  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, maskLeadingOnes<uint64_t>(64U));
+
+  EXPECT_EQ(0x0000FFFFFFFFFFFFULL, maskTrailingOnes<uint64_t>(48U));
+  EXPECT_EQ(0xFFFFFFFFFFFF0000ULL, maskLeadingOnes<uint64_t>(48U));
+}
+
+TEST(MathExtras, findFirstSet) {
+  uint8_t Z8 = 0;
+  uint16_t Z16 = 0;
+  uint32_t Z32 = 0;
+  uint64_t Z64 = 0;
+  EXPECT_EQ(0xFFULL, findFirstSet(Z8));
+  EXPECT_EQ(0xFFFFULL, findFirstSet(Z16));
+  EXPECT_EQ(0xFFFFFFFFULL, findFirstSet(Z32));
+  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, findFirstSet(Z64));
+
+  uint8_t NZ8 = 42;
+  uint16_t NZ16 = 42;
+  uint32_t NZ32 = 42;
+  uint64_t NZ64 = 42;
+  EXPECT_EQ(1u, findFirstSet(NZ8));
+  EXPECT_EQ(1u, findFirstSet(NZ16));
+  EXPECT_EQ(1u, findFirstSet(NZ32));
+  EXPECT_EQ(1u, findFirstSet(NZ64));
+}
+
+TEST(MathExtras, findLastSet) {
+  uint8_t Z8 = 0;
+  uint16_t Z16 = 0;
+  uint32_t Z32 = 0;
+  uint64_t Z64 = 0;
+  EXPECT_EQ(0xFFULL, findLastSet(Z8));
+  EXPECT_EQ(0xFFFFULL, findLastSet(Z16));
+  EXPECT_EQ(0xFFFFFFFFULL, findLastSet(Z32));
+  EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, findLastSet(Z64));
+
+  uint8_t NZ8 = 42;
+  uint16_t NZ16 = 42;
+  uint32_t NZ32 = 42;
+  uint64_t NZ64 = 42;
+  EXPECT_EQ(5u, findLastSet(NZ8));
+  EXPECT_EQ(5u, findLastSet(NZ16));
+  EXPECT_EQ(5u, findLastSet(NZ32));
+  EXPECT_EQ(5u, findLastSet(NZ64));
+}
+
+TEST(MathExtras, isIntN) {
+  EXPECT_TRUE(isIntN(16, 32767));
+  EXPECT_FALSE(isIntN(16, 32768));
+}
+
+TEST(MathExtras, isUIntN) {
+  EXPECT_TRUE(isUIntN(16, 65535));
+  EXPECT_FALSE(isUIntN(16, 65536));
+  EXPECT_TRUE(isUIntN(1, 0));
+  EXPECT_TRUE(isUIntN(6, 63));
+}
+
+TEST(MathExtras, maxIntN) {
+  EXPECT_EQ(32767, maxIntN(16));
+  EXPECT_EQ(2147483647, maxIntN(32));
+  EXPECT_EQ(std::numeric_limits<int32_t>::max(), maxIntN(32));
+  EXPECT_EQ(std::numeric_limits<int64_t>::max(), maxIntN(64));
+}
+
+TEST(MathExtras, minIntN) {
+  EXPECT_EQ(-32768LL, minIntN(16));
+  EXPECT_EQ(-64LL, minIntN(7));
+  EXPECT_EQ(std::numeric_limits<int32_t>::min(), minIntN(32));
+  EXPECT_EQ(std::numeric_limits<int64_t>::min(), minIntN(64));
+}
+
+TEST(MathExtras, maxUIntN) {
+  EXPECT_EQ(0xffffULL, maxUIntN(16));
+  EXPECT_EQ(0xffffffffULL, maxUIntN(32));
+  EXPECT_EQ(0xffffffffffffffffULL, maxUIntN(64));
+  EXPECT_EQ(1ULL, maxUIntN(1));
+  EXPECT_EQ(0x0fULL, maxUIntN(4));
+}
+
+TEST(MathExtras, reverseBits) {
+  uint8_t NZ8 = 42;
+  uint16_t NZ16 = 42;
+  uint32_t NZ32 = 42;
+  uint64_t NZ64 = 42;
+  EXPECT_EQ(0x54ULL, reverseBits(NZ8));
+  EXPECT_EQ(0x5400ULL, reverseBits(NZ16));
+  EXPECT_EQ(0x54000000ULL, reverseBits(NZ32));
+  EXPECT_EQ(0x5400000000000000ULL, reverseBits(NZ64));
+}
+
+TEST(MathExtras, isPowerOf2_32) {
+  EXPECT_FALSE(isPowerOf2_32(0));
+  EXPECT_TRUE(isPowerOf2_32(1 << 6));
+  EXPECT_TRUE(isPowerOf2_32(1 << 12));
+  EXPECT_FALSE(isPowerOf2_32((1 << 19) + 3));
+  EXPECT_FALSE(isPowerOf2_32(0xABCDEF0));
+}
+
+TEST(MathExtras, isPowerOf2_64) {
+  EXPECT_FALSE(isPowerOf2_64(0));
+  EXPECT_TRUE(isPowerOf2_64(1LL << 46));
+  EXPECT_TRUE(isPowerOf2_64(1LL << 12));
+  EXPECT_FALSE(isPowerOf2_64((1LL << 53) + 3));
+  EXPECT_FALSE(isPowerOf2_64(0xABCDEF0ABCDEF0LL));
+}
+
+TEST(MathExtras, PowerOf2Ceil) {
+  EXPECT_EQ(0U, PowerOf2Ceil(0U));
+  EXPECT_EQ(8U, PowerOf2Ceil(8U));
+  EXPECT_EQ(8U, PowerOf2Ceil(7U));
+}
+
+TEST(MathExtras, PowerOf2Floor) {
+  EXPECT_EQ(0U, PowerOf2Floor(0U));
+  EXPECT_EQ(8U, PowerOf2Floor(8U));
+  EXPECT_EQ(4U, PowerOf2Floor(7U));
+}
+
+TEST(MathExtras, ByteSwap_32) {
+  EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344));
+  EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD));
+}
+
+TEST(MathExtras, ByteSwap_64) {
+  EXPECT_EQ(0x8877665544332211ULL, ByteSwap_64(0x1122334455667788LL));
+  EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL));
+}
+
+TEST(MathExtras, countLeadingOnes) {
+  for (int i = 30; i >= 0; --i) {
+    // Start with all ones and unset some bit.
+    EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i)));
+  }
+  for (int i = 62; i >= 0; --i) {
+    // Start with all ones and unset some bit.
+    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(0xFFFFFFFF ^ (1 << i)));
+  }
+}
+
+TEST(MathExtras, FloatBits) {
+  static const float kValue = 5632.34f;
+  EXPECT_FLOAT_EQ(kValue, BitsToFloat(FloatToBits(kValue)));
+}
+
+TEST(MathExtras, DoubleBits) {
+  static const double kValue = 87987234.983498;
+  EXPECT_DOUBLE_EQ(kValue, BitsToDouble(DoubleToBits(kValue)));
+}
+
+TEST(MathExtras, MinAlign) {
+  EXPECT_EQ(1u, MinAlign(2, 3));
+  EXPECT_EQ(2u, MinAlign(2, 4));
+  EXPECT_EQ(1u, MinAlign(17, 64));
+  EXPECT_EQ(256u, MinAlign(256, 512));
+}
+
+TEST(MathExtras, NextPowerOf2) {
+  EXPECT_EQ(4u, NextPowerOf2(3));
+  EXPECT_EQ(16u, NextPowerOf2(15));
+  EXPECT_EQ(256u, NextPowerOf2(128));
+}
+
+TEST(MathExtras, alignTo) {
+  EXPECT_EQ(8u, alignTo(5, 8));
+  EXPECT_EQ(24u, alignTo(17, 8));
+  EXPECT_EQ(0u, alignTo(~0LL, 8));
+
+  EXPECT_EQ(7u, alignTo(5, 8, 7));
+  EXPECT_EQ(17u, alignTo(17, 8, 1));
+  EXPECT_EQ(3u, alignTo(~0LL, 8, 3));
+  EXPECT_EQ(552u, alignTo(321, 255, 42));
+}
+
+template<typename T>
+void SaturatingAddTestHelper()
+{
+  const T Max = std::numeric_limits<T>::max();
+  bool ResultOverflowed;
+
+  EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2)));
+  EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingAdd(Max, T(1)));
+  EXPECT_EQ(Max, SaturatingAdd(Max, T(1), &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 1)));
+  EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 1), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingAdd(T(1), Max));
+  EXPECT_EQ(Max, SaturatingAdd(T(1), Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingAdd(Max, Max));
+  EXPECT_EQ(Max, SaturatingAdd(Max, Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+}
+
+TEST(MathExtras, SaturatingAdd) {
+  SaturatingAddTestHelper<uint8_t>();
+  SaturatingAddTestHelper<uint16_t>();
+  SaturatingAddTestHelper<uint32_t>();
+  SaturatingAddTestHelper<uint64_t>();
+}
+
+template<typename T>
+void SaturatingMultiplyTestHelper()
+{
+  const T Max = std::numeric_limits<T>::max();
+  bool ResultOverflowed;
+
+  // Test basic multiplication.
+  EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3)));
+  EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2)));
+  EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  // Test multiplication by zero.
+  EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0)));
+  EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0)));
+  EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1)));
+  EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0)));
+  EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max));
+  EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max, &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  // Test multiplication by maximum value.
+  EXPECT_EQ(Max, SaturatingMultiply(Max, T(2)));
+  EXPECT_EQ(Max, SaturatingMultiply(Max, T(2), &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingMultiply(T(2), Max));
+  EXPECT_EQ(Max, SaturatingMultiply(T(2), Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingMultiply(Max, Max));
+  EXPECT_EQ(Max, SaturatingMultiply(Max, Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  // Test interesting boundary conditions for algorithm -
+  // ((1 << A) - 1) * ((1 << B) + K) for K in [-1, 0, 1]
+  // and A + B == std::numeric_limits<T>::digits.
+  // We expect overflow iff A > B and K = 1.
+  const int Digits = std::numeric_limits<T>::digits;
+  for (int A = 1, B = Digits - 1; B >= 1; ++A, --B) {
+    for (int K = -1; K <= 1; ++K) {
+      T X = (T(1) << A) - T(1);
+      T Y = (T(1) << B) + K;
+      bool OverflowExpected = A > B && K == 1;
+
+      if(OverflowExpected) {
+        EXPECT_EQ(Max, SaturatingMultiply(X, Y));
+        EXPECT_EQ(Max, SaturatingMultiply(X, Y, &ResultOverflowed));
+        EXPECT_TRUE(ResultOverflowed);
+      } else {
+        EXPECT_EQ(X * Y, SaturatingMultiply(X, Y));
+        EXPECT_EQ(X * Y, SaturatingMultiply(X, Y, &ResultOverflowed));
+        EXPECT_FALSE(ResultOverflowed);
+      }
+    }
+  }
+}
+
+TEST(MathExtras, SaturatingMultiply) {
+  SaturatingMultiplyTestHelper<uint8_t>();
+  SaturatingMultiplyTestHelper<uint16_t>();
+  SaturatingMultiplyTestHelper<uint32_t>();
+  SaturatingMultiplyTestHelper<uint64_t>();
+}
+
+template<typename T>
+void SaturatingMultiplyAddTestHelper()
+{
+  const T Max = std::numeric_limits<T>::max();
+  bool ResultOverflowed;
+
+  // Test basic multiply-add.
+  EXPECT_EQ(T(16), SaturatingMultiplyAdd(T(2), T(3), T(10)));
+  EXPECT_EQ(T(16), SaturatingMultiplyAdd(T(2), T(3), T(10), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  // Test multiply overflows, add doesn't overflow
+  EXPECT_EQ(Max, SaturatingMultiplyAdd(Max, Max, T(0), &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  // Test multiply doesn't overflow, add overflows
+  EXPECT_EQ(Max, SaturatingMultiplyAdd(T(1), T(1), Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  // Test multiply-add with Max as operand
+  EXPECT_EQ(Max, SaturatingMultiplyAdd(T(1), T(1), Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingMultiplyAdd(T(1), Max, T(1), &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingMultiplyAdd(Max, Max, T(1), &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  EXPECT_EQ(Max, SaturatingMultiplyAdd(Max, Max, Max, &ResultOverflowed));
+  EXPECT_TRUE(ResultOverflowed);
+
+  // Test multiply-add with 0 as operand
+  EXPECT_EQ(T(1), SaturatingMultiplyAdd(T(1), T(1), T(0), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(1), SaturatingMultiplyAdd(T(1), T(0), T(1), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(1), SaturatingMultiplyAdd(T(0), T(0), T(1), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+  EXPECT_EQ(T(0), SaturatingMultiplyAdd(T(0), T(0), T(0), &ResultOverflowed));
+  EXPECT_FALSE(ResultOverflowed);
+
+}
+
+TEST(MathExtras, SaturatingMultiplyAdd) {
+  SaturatingMultiplyAddTestHelper<uint8_t>();
+  SaturatingMultiplyAddTestHelper<uint16_t>();
+  SaturatingMultiplyAddTestHelper<uint32_t>();
+  SaturatingMultiplyAddTestHelper<uint64_t>();
+}
+
+TEST(MathExtras, IsShiftedUInt) {
+  EXPECT_TRUE((isShiftedUInt<1, 0>(0)));
+  EXPECT_TRUE((isShiftedUInt<1, 0>(1)));
+  EXPECT_FALSE((isShiftedUInt<1, 0>(2)));
+  EXPECT_FALSE((isShiftedUInt<1, 0>(3)));
+  EXPECT_FALSE((isShiftedUInt<1, 0>(0x8000000000000000)));
+  EXPECT_TRUE((isShiftedUInt<1, 63>(0x8000000000000000)));
+  EXPECT_TRUE((isShiftedUInt<2, 62>(0xC000000000000000)));
+  EXPECT_FALSE((isShiftedUInt<2, 62>(0xE000000000000000)));
+
+  // 0x201 is ten bits long and has a 1 in the MSB and LSB.
+  EXPECT_TRUE((isShiftedUInt<10, 5>(uint64_t(0x201) << 5)));
+  EXPECT_FALSE((isShiftedUInt<10, 5>(uint64_t(0x201) << 4)));
+  EXPECT_FALSE((isShiftedUInt<10, 5>(uint64_t(0x201) << 6)));
+}
+
+TEST(MathExtras, IsShiftedInt) {
+  EXPECT_TRUE((isShiftedInt<1, 0>(0)));
+  EXPECT_TRUE((isShiftedInt<1, 0>(-1)));
+  EXPECT_FALSE((isShiftedInt<1, 0>(2)));
+  EXPECT_FALSE((isShiftedInt<1, 0>(3)));
+  EXPECT_FALSE((isShiftedInt<1, 0>(0x8000000000000000)));
+  EXPECT_TRUE((isShiftedInt<1, 63>(0x8000000000000000)));
+  EXPECT_TRUE((isShiftedInt<2, 62>(0xC000000000000000)));
+  EXPECT_FALSE((isShiftedInt<2, 62>(0xE000000000000000)));
+
+  // 0x201 is ten bits long and has a 1 in the MSB and LSB.
+  EXPECT_TRUE((isShiftedInt<11, 5>(int64_t(0x201) << 5)));
+  EXPECT_FALSE((isShiftedInt<11, 5>(int64_t(0x201) << 3)));
+  EXPECT_FALSE((isShiftedInt<11, 5>(int64_t(0x201) << 6)));
+  EXPECT_TRUE((isShiftedInt<11, 5>(-(int64_t(0x201) << 5))));
+  EXPECT_FALSE((isShiftedInt<11, 5>(-(int64_t(0x201) << 3))));
+  EXPECT_FALSE((isShiftedInt<11, 5>(-(int64_t(0x201) << 6))));
+
+  EXPECT_TRUE((isShiftedInt<6, 10>(-(int64_t(1) << 15))));
+  EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15)));
+}
+
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
new file mode 100644
index 0000000..034b2ea
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
@@ -0,0 +1,292 @@
+//===- llvm/unittest/Support/MemoryBufferTest.cpp - MemoryBuffer tests ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unit tests for the MemoryBuffer support class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class MemoryBufferTest : public testing::Test {
+protected:
+  MemoryBufferTest()
+  : data("this is some data")
+  { }
+
+  void SetUp() override {}
+
+  /// Common testing for different modes of getOpenFileSlice.
+  /// Creates a temporary file with known contents, and uses
+  /// MemoryBuffer::getOpenFileSlice to map it.
+  /// If \p Reopen is true, the file is closed after creating and reopened
+  /// anew before using MemoryBuffer.
+  void testGetOpenFileSlice(bool Reopen);
+
+  typedef std::unique_ptr<MemoryBuffer> OwningBuffer;
+
+  std::string data;
+};
+
+TEST_F(MemoryBufferTest, get) {
+  // Default name and null-terminator flag
+  OwningBuffer MB1(MemoryBuffer::getMemBuffer(data));
+  EXPECT_TRUE(nullptr != MB1.get());
+
+  // RequiresNullTerminator = false
+  OwningBuffer MB2(MemoryBuffer::getMemBuffer(data, "one", false));
+  EXPECT_TRUE(nullptr != MB2.get());
+
+  // RequiresNullTerminator = true
+  OwningBuffer MB3(MemoryBuffer::getMemBuffer(data, "two", true));
+  EXPECT_TRUE(nullptr != MB3.get());
+
+  // verify all 3 buffers point to the same address
+  EXPECT_EQ(MB1->getBufferStart(), MB2->getBufferStart());
+  EXPECT_EQ(MB2->getBufferStart(), MB3->getBufferStart());
+
+  // verify the original data is unmodified after deleting the buffers
+  MB1.reset();
+  MB2.reset();
+  MB3.reset();
+  EXPECT_EQ("this is some data", data);
+}
+
+TEST_F(MemoryBufferTest, NullTerminator4K) {
+  // Test that a file with size that is a multiple of the page size can be null
+  // terminated correctly by MemoryBuffer.
+  int TestFD;
+  SmallString<64> TestPath;
+  sys::fs::createTemporaryFile("MemoryBufferTest_NullTerminator4K", "temp",
+                               TestFD, TestPath);
+  FileRemover Cleanup(TestPath);
+  raw_fd_ostream OF(TestFD, true, /*unbuffered=*/true);
+  for (unsigned i = 0; i < 4096 / 16; ++i) {
+    OF << "0123456789abcdef";
+  }
+  OF.close();
+
+  ErrorOr<OwningBuffer> MB = MemoryBuffer::getFile(TestPath.c_str());
+  std::error_code EC = MB.getError();
+  ASSERT_FALSE(EC);
+
+  const char *BufData = MB.get()->getBufferStart();
+  EXPECT_EQ('f', BufData[4095]);
+  EXPECT_EQ('\0', BufData[4096]);
+}
+
+TEST_F(MemoryBufferTest, copy) {
+  // copy with no name
+  OwningBuffer MBC1(MemoryBuffer::getMemBufferCopy(data));
+  EXPECT_TRUE(nullptr != MBC1.get());
+
+  // copy with a name
+  OwningBuffer MBC2(MemoryBuffer::getMemBufferCopy(data, "copy"));
+  EXPECT_TRUE(nullptr != MBC2.get());
+
+  // verify the two copies do not point to the same place
+  EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart());
+}
+
+TEST_F(MemoryBufferTest, make_new) {
+  // 0-sized buffer
+  OwningBuffer Zero(WritableMemoryBuffer::getNewUninitMemBuffer(0));
+  EXPECT_TRUE(nullptr != Zero.get());
+
+  // uninitialized buffer with no name
+  OwningBuffer One(WritableMemoryBuffer::getNewUninitMemBuffer(321));
+  EXPECT_TRUE(nullptr != One.get());
+
+  // uninitialized buffer with name
+  OwningBuffer Two(WritableMemoryBuffer::getNewUninitMemBuffer(123, "bla"));
+  EXPECT_TRUE(nullptr != Two.get());
+
+  // 0-initialized buffer with no name
+  OwningBuffer Three(WritableMemoryBuffer::getNewMemBuffer(321, data));
+  EXPECT_TRUE(nullptr != Three.get());
+  for (size_t i = 0; i < 321; ++i)
+    EXPECT_EQ(0, Three->getBufferStart()[0]);
+
+  // 0-initialized buffer with name
+  OwningBuffer Four(WritableMemoryBuffer::getNewMemBuffer(123, "zeros"));
+  EXPECT_TRUE(nullptr != Four.get());
+  for (size_t i = 0; i < 123; ++i)
+    EXPECT_EQ(0, Four->getBufferStart()[0]);
+}
+
+void MemoryBufferTest::testGetOpenFileSlice(bool Reopen) {
+  // Test that MemoryBuffer::getOpenFile works properly when no null
+  // terminator is requested and the size is large enough to trigger
+  // the usage of memory mapping.
+  int TestFD;
+  SmallString<64> TestPath;
+  // Create a temporary file and write data into it.
+  sys::fs::createTemporaryFile("prefix", "temp", TestFD, TestPath);
+  FileRemover Cleanup(TestPath);
+  // OF is responsible for closing the file; If the file is not
+  // reopened, it will be unbuffered so that the results are
+  // immediately visible through the fd.
+  raw_fd_ostream OF(TestFD, true, !Reopen);
+  for (int i = 0; i < 60000; ++i) {
+    OF << "0123456789";
+  }
+
+  if (Reopen) {
+    OF.close();
+    EXPECT_FALSE(sys::fs::openFileForRead(TestPath.c_str(), TestFD));
+  }
+
+  ErrorOr<OwningBuffer> Buf =
+      MemoryBuffer::getOpenFileSlice(TestFD, TestPath.c_str(),
+                                     40000, // Size
+                                     80000  // Offset
+                                     );
+
+  std::error_code EC = Buf.getError();
+  EXPECT_FALSE(EC);
+
+  StringRef BufData = Buf.get()->getBuffer();
+  EXPECT_EQ(BufData.size(), 40000U);
+  EXPECT_EQ(BufData[0], '0');
+  EXPECT_EQ(BufData[9], '9');
+}
+
+TEST_F(MemoryBufferTest, getOpenFileNoReopen) {
+  testGetOpenFileSlice(false);
+}
+
+TEST_F(MemoryBufferTest, getOpenFileReopened) {
+  testGetOpenFileSlice(true);
+}
+
+TEST_F(MemoryBufferTest, reference) {
+  OwningBuffer MB(MemoryBuffer::getMemBuffer(data));
+  MemoryBufferRef MBR(*MB);
+
+  EXPECT_EQ(MB->getBufferStart(), MBR.getBufferStart());
+  EXPECT_EQ(MB->getBufferIdentifier(), MBR.getBufferIdentifier());
+}
+
+TEST_F(MemoryBufferTest, slice) {
+  // Create a file that is six pages long with different data on each page.
+  int FD;
+  SmallString<64> TestPath;
+  sys::fs::createTemporaryFile("MemoryBufferTest_Slice", "temp", FD, TestPath);
+  FileRemover Cleanup(TestPath);
+  raw_fd_ostream OF(FD, true, /*unbuffered=*/true);
+  for (unsigned i = 0; i < 0x2000 / 8; ++i) {
+    OF << "12345678";
+  }
+  for (unsigned i = 0; i < 0x2000 / 8; ++i) {
+    OF << "abcdefgh";
+  }
+  for (unsigned i = 0; i < 0x2000 / 8; ++i) {
+    OF << "ABCDEFGH";
+  }
+  OF.close();
+
+  // Try offset of one page.
+  ErrorOr<OwningBuffer> MB = MemoryBuffer::getFileSlice(TestPath.str(),
+                                                        0x4000, 0x1000);
+  std::error_code EC = MB.getError();
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(0x4000UL, MB.get()->getBufferSize());
+ 
+  StringRef BufData = MB.get()->getBuffer();
+  EXPECT_TRUE(BufData.substr(0x0000,8).equals("12345678"));
+  EXPECT_TRUE(BufData.substr(0x0FF8,8).equals("12345678"));
+  EXPECT_TRUE(BufData.substr(0x1000,8).equals("abcdefgh"));
+  EXPECT_TRUE(BufData.substr(0x2FF8,8).equals("abcdefgh"));
+  EXPECT_TRUE(BufData.substr(0x3000,8).equals("ABCDEFGH"));
+  EXPECT_TRUE(BufData.substr(0x3FF8,8).equals("ABCDEFGH"));
+   
+  // Try non-page aligned.
+  ErrorOr<OwningBuffer> MB2 = MemoryBuffer::getFileSlice(TestPath.str(),
+                                                         0x3000, 0x0800);
+  EC = MB2.getError();
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(0x3000UL, MB2.get()->getBufferSize());
+  
+  StringRef BufData2 = MB2.get()->getBuffer();
+  EXPECT_TRUE(BufData2.substr(0x0000,8).equals("12345678"));
+  EXPECT_TRUE(BufData2.substr(0x17F8,8).equals("12345678"));
+  EXPECT_TRUE(BufData2.substr(0x1800,8).equals("abcdefgh"));
+  EXPECT_TRUE(BufData2.substr(0x2FF8,8).equals("abcdefgh"));
+}
+
+TEST_F(MemoryBufferTest, writableSlice) {
+  // Create a file initialized with some data
+  int FD;
+  SmallString<64> TestPath;
+  sys::fs::createTemporaryFile("MemoryBufferTest_WritableSlice", "temp", FD,
+                               TestPath);
+  FileRemover Cleanup(TestPath);
+  raw_fd_ostream OF(FD, true);
+  for (unsigned i = 0; i < 0x1000; ++i)
+    OF << "0123456789abcdef";
+  OF.close();
+
+  {
+    auto MBOrError =
+        WritableMemoryBuffer::getFileSlice(TestPath.str(), 0x6000, 0x2000);
+    ASSERT_FALSE(MBOrError.getError());
+    // Write some data.  It should be mapped private, so that upon completion
+    // the original file contents are not modified.
+    WritableMemoryBuffer &MB = **MBOrError;
+    ASSERT_EQ(0x6000u, MB.getBufferSize());
+    char *Start = MB.getBufferStart();
+    ASSERT_EQ(MB.getBufferEnd(), MB.getBufferStart() + MB.getBufferSize());
+    ::memset(Start, 'x', MB.getBufferSize());
+  }
+
+  auto MBOrError = MemoryBuffer::getFile(TestPath);
+  ASSERT_FALSE(MBOrError.getError());
+  auto &MB = **MBOrError;
+  ASSERT_EQ(0x10000u, MB.getBufferSize());
+  for (size_t i = 0; i < MB.getBufferSize(); i += 0x10)
+    EXPECT_EQ("0123456789abcdef", MB.getBuffer().substr(i, 0x10)) << "i: " << i;
+}
+
+TEST_F(MemoryBufferTest, writeThroughFile) {
+  // Create a file initialized with some data
+  int FD;
+  SmallString<64> TestPath;
+  sys::fs::createTemporaryFile("MemoryBufferTest_WriteThrough", "temp", FD,
+                               TestPath);
+  FileRemover Cleanup(TestPath);
+  raw_fd_ostream OF(FD, true);
+  OF << "0123456789abcdef";
+  OF.close();
+  {
+    auto MBOrError = WriteThroughMemoryBuffer::getFile(TestPath);
+    ASSERT_FALSE(MBOrError.getError());
+    // Write some data.  It should be mapped readwrite, so that upon completion
+    // the original file contents are modified.
+    WriteThroughMemoryBuffer &MB = **MBOrError;
+    ASSERT_EQ(16u, MB.getBufferSize());
+    char *Start = MB.getBufferStart();
+    ASSERT_EQ(MB.getBufferEnd(), MB.getBufferStart() + MB.getBufferSize());
+    ::memset(Start, 'x', MB.getBufferSize());
+  }
+
+  auto MBOrError = MemoryBuffer::getFile(TestPath);
+  ASSERT_FALSE(MBOrError.getError());
+  auto &MB = **MBOrError;
+  ASSERT_EQ(16u, MB.getBufferSize());
+  EXPECT_EQ("xxxxxxxxxxxxxxxx", MB.getBuffer());
+}
+}
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
new file mode 100644
index 0000000..bc2fba0
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/MemoryTest.cpp
@@ -0,0 +1,418 @@
+//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator 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/Memory.h"
+#include "llvm/Support/Process.h"
+#include "gtest/gtest.h"
+#include <cassert>
+#include <cstdlib>
+
+#if defined(__NetBSD__)
+// clang-format off
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <err.h>
+#include <unistd.h>
+// clang-format on
+#endif
+
+using namespace llvm;
+using namespace sys;
+
+namespace {
+
+bool IsMPROTECT() {
+#if defined(__NetBSD__)
+  int mib[3];
+  int paxflags;
+  size_t len = sizeof(paxflags);
+
+  mib[0] = CTL_PROC;
+  mib[1] = getpid();
+  mib[2] = PROC_PID_PAXFLAGS;
+
+  if (sysctl(mib, 3, &paxflags, &len, NULL, 0) != 0)
+    err(EXIT_FAILURE, "sysctl");
+
+  return !!(paxflags & CTL_PROC_PAXFLAGS_MPROTECT);
+#else
+  return false;
+#endif
+}
+
+class MappedMemoryTest : public ::testing::TestWithParam<unsigned> {
+public:
+  MappedMemoryTest() {
+    Flags = GetParam();
+    PageSize = sys::Process::getPageSize();
+  }
+
+protected:
+  // Adds RW flags to permit testing of the resulting memory
+  unsigned getTestableEquivalent(unsigned RequestedFlags) {
+    switch (RequestedFlags) {
+    case Memory::MF_READ:
+    case Memory::MF_WRITE:
+    case Memory::MF_READ|Memory::MF_WRITE:
+      return Memory::MF_READ|Memory::MF_WRITE;
+    case Memory::MF_READ|Memory::MF_EXEC:
+    case Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC:
+    case Memory::MF_EXEC:
+      return Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC;
+    }
+    // Default in case values are added to the enum, as required by some compilers
+    return Memory::MF_READ|Memory::MF_WRITE;
+  }
+
+  // Returns true if the memory blocks overlap
+  bool doesOverlap(MemoryBlock M1, MemoryBlock M2) {
+    if (M1.base() == M2.base())
+      return true;
+
+    if (M1.base() > M2.base())
+      return (unsigned char *)M2.base() + M2.size() > M1.base();
+
+    return (unsigned char *)M1.base() + M1.size() > M2.base();
+  }
+
+  unsigned Flags;
+  size_t   PageSize;
+};
+
+// MPROTECT prevents W+X mmaps
+#define CHECK_UNSUPPORTED() \
+  do { \
+    if ((Flags & Memory::MF_WRITE) && (Flags & Memory::MF_EXEC) && \
+        IsMPROTECT()) \
+      return; \
+  } while (0)
+
+TEST_P(MappedMemoryTest, AllocAndRelease) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(sizeof(int), M1.size());
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+}
+
+TEST_P(MappedMemoryTest, MultipleAllocAndRelease) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(64, nullptr, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(32, nullptr, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(16U, M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(64U, M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(32U, M3.size());
+
+  EXPECT_FALSE(doesOverlap(M1, M2));
+  EXPECT_FALSE(doesOverlap(M2, M3));
+  EXPECT_FALSE(doesOverlap(M1, M3));
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+  MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  EXPECT_NE((void*)nullptr, M4.base());
+  EXPECT_LE(16U, M4.size());
+  EXPECT_FALSE(Memory::releaseMappedMemory(M4));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, BasicWrite) {
+  // This test applies only to readable and writeable combinations
+  if (Flags &&
+      !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
+    return;
+  CHECK_UNSUPPORTED();
+
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(sizeof(int), M1.size());
+
+  int *a = (int*)M1.base();
+  *a = 1;
+  EXPECT_EQ(1, *a);
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+}
+
+TEST_P(MappedMemoryTest, MultipleWrite) {
+  // This test applies only to readable and writeable combinations
+  if (Flags &&
+      !((Flags & Memory::MF_READ) && (Flags & Memory::MF_WRITE)))
+    return;
+  CHECK_UNSUPPORTED();
+
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(sizeof(int), nullptr, Flags,
+                                                EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
+                                                EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
+                                                EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_FALSE(doesOverlap(M1, M2));
+  EXPECT_FALSE(doesOverlap(M2, M3));
+  EXPECT_FALSE(doesOverlap(M1, M3));
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(1U * sizeof(int), M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(8U * sizeof(int), M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(4U * sizeof(int), M3.size());
+
+  int *x = (int*)M1.base();
+  *x = 1;
+
+  int *y = (int*)M2.base();
+  for (int i = 0; i < 8; i++) {
+    y[i] = i;
+  }
+
+  int *z = (int*)M3.base();
+  *z = 42;
+
+  EXPECT_EQ(1, *x);
+  EXPECT_EQ(7, y[7]);
+  EXPECT_EQ(42, *z);
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+
+  MemoryBlock M4 = Memory::allocateMappedMemory(64 * sizeof(int), nullptr,
+                                                Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  EXPECT_NE((void*)nullptr, M4.base());
+  EXPECT_LE(64U * sizeof(int), M4.size());
+  x = (int*)M4.base();
+  *x = 4;
+  EXPECT_EQ(4, *x);
+  EXPECT_FALSE(Memory::releaseMappedMemory(M4));
+
+  // Verify that M2 remains unaffected by other activity
+  for (int i = 0; i < 8; i++) {
+    EXPECT_EQ(i, y[i]);
+  }
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, EnabledWrite) {
+  // MPROTECT prevents W+X, and since this test always adds W we need
+  // to block any variant with X.
+  if ((Flags & Memory::MF_EXEC) && IsMPROTECT())
+    return;
+
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(2 * sizeof(int), nullptr, Flags,
+                                                EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(8 * sizeof(int), nullptr, Flags,
+                                                EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(4 * sizeof(int), nullptr, Flags,
+                                                EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(2U * sizeof(int), M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(8U * sizeof(int), M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(4U * sizeof(int), M3.size());
+
+  EXPECT_FALSE(Memory::protectMappedMemory(M1, getTestableEquivalent(Flags)));
+  EXPECT_FALSE(Memory::protectMappedMemory(M2, getTestableEquivalent(Flags)));
+  EXPECT_FALSE(Memory::protectMappedMemory(M3, getTestableEquivalent(Flags)));
+
+  EXPECT_FALSE(doesOverlap(M1, M2));
+  EXPECT_FALSE(doesOverlap(M2, M3));
+  EXPECT_FALSE(doesOverlap(M1, M3));
+
+  int *x = (int*)M1.base();
+  *x = 1;
+  int *y = (int*)M2.base();
+  for (unsigned int i = 0; i < 8; i++) {
+    y[i] = i;
+  }
+  int *z = (int*)M3.base();
+  *z = 42;
+
+  EXPECT_EQ(1, *x);
+  EXPECT_EQ(7, y[7]);
+  EXPECT_EQ(42, *z);
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+  EXPECT_EQ(6, y[6]);
+
+  MemoryBlock M4 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  EXPECT_NE((void*)nullptr, M4.base());
+  EXPECT_LE(16U, M4.size());
+  EXPECT_EQ(std::error_code(),
+            Memory::protectMappedMemory(M4, getTestableEquivalent(Flags)));
+  x = (int*)M4.base();
+  *x = 4;
+  EXPECT_EQ(4, *x);
+  EXPECT_FALSE(Memory::releaseMappedMemory(M4));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, SuccessiveNear) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock M1 = Memory::allocateMappedMemory(16, nullptr, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(64, &M1, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(32, &M2, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(16U, M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(64U, M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(32U, M3.size());
+
+  EXPECT_FALSE(doesOverlap(M1, M2));
+  EXPECT_FALSE(doesOverlap(M2, M3));
+  EXPECT_FALSE(doesOverlap(M1, M3));
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, DuplicateNear) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock Near((void*)(3*PageSize), 16);
+  MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(16U, M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(64U, M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(32U, M3.size());
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, ZeroNear) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock Near(nullptr, 0);
+  MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(16U, M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(64U, M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(32U, M3.size());
+
+  EXPECT_FALSE(doesOverlap(M1, M2));
+  EXPECT_FALSE(doesOverlap(M2, M3));
+  EXPECT_FALSE(doesOverlap(M1, M3));
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, ZeroSizeNear) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock Near((void*)(4*PageSize), 0);
+  MemoryBlock M1 = Memory::allocateMappedMemory(16, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M2 = Memory::allocateMappedMemory(64, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+  MemoryBlock M3 = Memory::allocateMappedMemory(32, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(16U, M1.size());
+  EXPECT_NE((void*)nullptr, M2.base());
+  EXPECT_LE(64U, M2.size());
+  EXPECT_NE((void*)nullptr, M3.base());
+  EXPECT_LE(32U, M3.size());
+
+  EXPECT_FALSE(doesOverlap(M1, M2));
+  EXPECT_FALSE(doesOverlap(M2, M3));
+  EXPECT_FALSE(doesOverlap(M1, M3));
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M3));
+  EXPECT_FALSE(Memory::releaseMappedMemory(M2));
+}
+
+TEST_P(MappedMemoryTest, UnalignedNear) {
+  CHECK_UNSUPPORTED();
+  std::error_code EC;
+  MemoryBlock Near((void*)(2*PageSize+5), 0);
+  MemoryBlock M1 = Memory::allocateMappedMemory(15, &Near, Flags, EC);
+  EXPECT_EQ(std::error_code(), EC);
+
+  EXPECT_NE((void*)nullptr, M1.base());
+  EXPECT_LE(sizeof(int), M1.size());
+
+  EXPECT_FALSE(Memory::releaseMappedMemory(M1));
+}
+
+// Note that Memory::MF_WRITE is not supported exclusively across
+// operating systems and architectures and can imply MF_READ|MF_WRITE
+unsigned MemoryFlags[] = {
+                           Memory::MF_READ,
+                           Memory::MF_WRITE,
+                           Memory::MF_READ|Memory::MF_WRITE,
+                           Memory::MF_EXEC,
+                           Memory::MF_READ|Memory::MF_EXEC,
+                           Memory::MF_READ|Memory::MF_WRITE|Memory::MF_EXEC
+                         };
+
+INSTANTIATE_TEST_CASE_P(AllocationTests,
+                        MappedMemoryTest,
+                        ::testing::ValuesIn(MemoryFlags),);
+
+}  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp b/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
new file mode 100644
index 0000000..52acb6a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/NativeFormatTests.cpp
@@ -0,0 +1,176 @@
+//===- llvm/unittest/Support/NativeFormatTests.cpp - formatting 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/NativeFormatting.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+#include <type_traits>
+
+using namespace llvm;
+
+namespace {
+
+template <typename T> std::string format_number(T N, IntegerStyle Style) {
+  std::string S;
+  llvm::raw_string_ostream Str(S);
+  write_integer(Str, N, 0, Style);
+  Str.flush();
+  return S;
+}
+
+std::string format_number(uint64_t N, HexPrintStyle Style,
+                          Optional<size_t> Width = None) {
+  std::string S;
+  llvm::raw_string_ostream Str(S);
+  write_hex(Str, N, Style, Width);
+  Str.flush();
+  return S;
+}
+
+std::string format_number(double D, FloatStyle Style,
+                          Optional<size_t> Precision = None) {
+  std::string S;
+  llvm::raw_string_ostream Str(S);
+  write_double(Str, D, Style, Precision);
+  Str.flush();
+  return S;
+}
+
+// Test basic number formatting with various styles and default width and
+// precision.
+TEST(NativeFormatTest, BasicIntegerTests) {
+  // Simple integers with no decimal.
+  EXPECT_EQ("0", format_number(0, IntegerStyle::Integer));
+  EXPECT_EQ("2425", format_number(2425, IntegerStyle::Integer));
+  EXPECT_EQ("-2425", format_number(-2425, IntegerStyle::Integer));
+
+  EXPECT_EQ("0", format_number(0LL, IntegerStyle::Integer));
+  EXPECT_EQ("257257257235709",
+            format_number(257257257235709LL, IntegerStyle::Integer));
+  EXPECT_EQ("-257257257235709",
+            format_number(-257257257235709LL, IntegerStyle::Integer));
+
+  // Number formatting.
+  EXPECT_EQ("0", format_number(0, IntegerStyle::Number));
+  EXPECT_EQ("2,425", format_number(2425, IntegerStyle::Number));
+  EXPECT_EQ("-2,425", format_number(-2425, IntegerStyle::Number));
+  EXPECT_EQ("257,257,257,235,709",
+            format_number(257257257235709LL, IntegerStyle::Number));
+  EXPECT_EQ("-257,257,257,235,709",
+            format_number(-257257257235709LL, IntegerStyle::Number));
+
+  // Hex formatting.
+  // lower case, prefix.
+  EXPECT_EQ("0x0", format_number(0, HexPrintStyle::PrefixLower));
+  EXPECT_EQ("0xbeef", format_number(0xbeefLL, HexPrintStyle::PrefixLower));
+  EXPECT_EQ("0xdeadbeef",
+            format_number(0xdeadbeefLL, HexPrintStyle::PrefixLower));
+
+  // upper-case, prefix.
+  EXPECT_EQ("0x0", format_number(0, HexPrintStyle::PrefixUpper));
+  EXPECT_EQ("0xBEEF", format_number(0xbeefLL, HexPrintStyle::PrefixUpper));
+  EXPECT_EQ("0xDEADBEEF",
+            format_number(0xdeadbeefLL, HexPrintStyle::PrefixUpper));
+
+  // lower-case, no prefix
+  EXPECT_EQ("0", format_number(0, HexPrintStyle::Lower));
+  EXPECT_EQ("beef", format_number(0xbeefLL, HexPrintStyle::Lower));
+  EXPECT_EQ("deadbeef", format_number(0xdeadbeefLL, HexPrintStyle::Lower));
+
+  // upper-case, no prefix.
+  EXPECT_EQ("0", format_number(0, HexPrintStyle::Upper));
+  EXPECT_EQ("BEEF", format_number(0xbeef, HexPrintStyle::Upper));
+  EXPECT_EQ("DEADBEEF", format_number(0xdeadbeef, HexPrintStyle::Upper));
+}
+
+// Test basic floating point formatting with various styles and default width
+// and precision.
+TEST(NativeFormatTest, BasicFloatingPointTests) {
+  // Double
+  EXPECT_EQ("0.000000e+00", format_number(0.0, FloatStyle::Exponent));
+  EXPECT_EQ("-0.000000e+00", format_number(-0.0, FloatStyle::Exponent));
+  EXPECT_EQ("1.100000e+00", format_number(1.1, FloatStyle::Exponent));
+  EXPECT_EQ("1.100000E+00", format_number(1.1, FloatStyle::ExponentUpper));
+
+  // Default precision is 2 for floating points.
+  EXPECT_EQ("1.10", format_number(1.1, FloatStyle::Fixed));
+  EXPECT_EQ("1.34", format_number(1.34, FloatStyle::Fixed));
+  EXPECT_EQ("1.34", format_number(1.344, FloatStyle::Fixed));
+  EXPECT_EQ("1.35", format_number(1.346, FloatStyle::Fixed));
+}
+
+// Test common boundary cases and min/max conditions.
+TEST(NativeFormatTest, BoundaryTests) {
+  // Min and max.
+  EXPECT_EQ("18446744073709551615",
+            format_number(UINT64_MAX, IntegerStyle::Integer));
+
+  EXPECT_EQ("9223372036854775807",
+            format_number(INT64_MAX, IntegerStyle::Integer));
+  EXPECT_EQ("-9223372036854775808",
+            format_number(INT64_MIN, IntegerStyle::Integer));
+
+  EXPECT_EQ("4294967295", format_number(UINT32_MAX, IntegerStyle::Integer));
+  EXPECT_EQ("2147483647", format_number(INT32_MAX, IntegerStyle::Integer));
+  EXPECT_EQ("-2147483648", format_number(INT32_MIN, IntegerStyle::Integer));
+
+  EXPECT_EQ("nan", format_number(std::numeric_limits<double>::quiet_NaN(),
+                                 FloatStyle::Fixed));
+  EXPECT_EQ("INF", format_number(std::numeric_limits<double>::infinity(),
+                                 FloatStyle::Fixed));
+}
+
+TEST(NativeFormatTest, HexTests) {
+  // Test hex formatting with different widths and precisions.
+
+  // Width less than the value should print the full value anyway.
+  EXPECT_EQ("0x0", format_number(0, HexPrintStyle::PrefixLower, 0));
+  EXPECT_EQ("0xabcde", format_number(0xABCDE, HexPrintStyle::PrefixLower, 3));
+
+  // Precision greater than the value should pad with 0s.
+  // TODO: The prefix should not be counted in the precision.  But unfortunately
+  // it is and we have to live with it unless we fix all existing users of
+  // prefixed hex formatting.
+  EXPECT_EQ("0x000", format_number(0, HexPrintStyle::PrefixLower, 5));
+  EXPECT_EQ("0x0abcde", format_number(0xABCDE, HexPrintStyle::PrefixLower, 8));
+
+  EXPECT_EQ("00000", format_number(0, HexPrintStyle::Lower, 5));
+  EXPECT_EQ("000abcde", format_number(0xABCDE, HexPrintStyle::Lower, 8));
+
+  // Try printing more digits than can fit in a uint64.
+  EXPECT_EQ("0x00000000000000abcde",
+            format_number(0xABCDE, HexPrintStyle::PrefixLower, 21));
+}
+
+TEST(NativeFormatTest, IntegerTests) {
+  EXPECT_EQ("-10", format_number(-10, IntegerStyle::Integer));
+  EXPECT_EQ("-100", format_number(-100, IntegerStyle::Integer));
+  EXPECT_EQ("-1000", format_number(-1000, IntegerStyle::Integer));
+  EXPECT_EQ("-1234567890", format_number(-1234567890, IntegerStyle::Integer));
+  EXPECT_EQ("10", format_number(10, IntegerStyle::Integer));
+  EXPECT_EQ("100", format_number(100, IntegerStyle::Integer));
+  EXPECT_EQ("1000", format_number(1000, IntegerStyle::Integer));
+  EXPECT_EQ("1234567890", format_number(1234567890, IntegerStyle::Integer));
+}
+
+TEST(NativeFormatTest, CommaTests) {
+  EXPECT_EQ("0", format_number(0, IntegerStyle::Number));
+  EXPECT_EQ("10", format_number(10, IntegerStyle::Number));
+  EXPECT_EQ("100", format_number(100, IntegerStyle::Number));
+  EXPECT_EQ("1,000", format_number(1000, IntegerStyle::Number));
+  EXPECT_EQ("1,234,567,890", format_number(1234567890, IntegerStyle::Number));
+
+  EXPECT_EQ("-10", format_number(-10, IntegerStyle::Number));
+  EXPECT_EQ("-100", format_number(-100, IntegerStyle::Number));
+  EXPECT_EQ("-1,000", format_number(-1000, IntegerStyle::Number));
+  EXPECT_EQ("-1,234,567,890", format_number(-1234567890, IntegerStyle::Number));
+}
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp b/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
new file mode 100644
index 0000000..8779a61
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ParallelTest.cpp
@@ -0,0 +1,53 @@
+//===- llvm/unittest/Support/ParallelTest.cpp -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Parallel.h unit tests.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Parallel.h"
+#include "gtest/gtest.h"
+#include <array>
+#include <random>
+
+uint32_t array[1024 * 1024];
+
+using namespace llvm;
+
+// Tests below are hanging up on mingw. Investigating.
+#if !defined(__MINGW32__)
+
+TEST(Parallel, sort) {
+  std::mt19937 randEngine;
+  std::uniform_int_distribution<uint32_t> dist;
+
+  for (auto &i : array)
+    i = dist(randEngine);
+
+  sort(parallel::par, std::begin(array), std::end(array));
+  ASSERT_TRUE(std::is_sorted(std::begin(array), std::end(array)));
+}
+
+TEST(Parallel, parallel_for) {
+  // We need to test the case with a TaskSize > 1. We are white-box testing
+  // here. The TaskSize is calculated as (End - Begin) / 1024 at the time of
+  // writing.
+  uint32_t range[2050];
+  std::fill(range, range + 2050, 1);
+  for_each_n(parallel::par, 0, 2049, [&range](size_t I) { ++range[I]; });
+
+  uint32_t expected[2049];
+  std::fill(expected, expected + 2049, 2);
+  ASSERT_TRUE(std::equal(range, range + 2049, expected));
+  // Check that we don't write past the end of the requested range.
+  ASSERT_EQ(range[2049], 1u);
+}
+
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/Path.cpp b/src/llvm-project/llvm/unittests/Support/Path.cpp
new file mode 100644
index 0000000..97b77e2
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/Path.cpp
@@ -0,0 +1,1698 @@
+//===- llvm/unittest/Support/Path.cpp - Path 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/Path.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#ifdef _WIN32
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Chrono.h"
+#include <windows.h>
+#include <winerror.h>
+#endif
+
+#ifdef LLVM_ON_UNIX
+#include <pwd.h>
+#include <sys/stat.h>
+#endif
+
+using namespace llvm;
+using namespace llvm::sys;
+
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
+    SmallString<128> MessageStorage;                                           \
+    raw_svector_ostream Message(MessageStorage);                               \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+
+#define ASSERT_ERROR(x)                                                        \
+  if (!x) {                                                                    \
+    SmallString<128> MessageStorage;                                           \
+    raw_svector_ostream Message(MessageStorage);                               \
+    Message << #x ": did not return a failure error code.\n";                  \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  }
+
+namespace {
+
+struct FileDescriptorCloser {
+  explicit FileDescriptorCloser(int FD) : FD(FD) {}
+  ~FileDescriptorCloser() { ::close(FD); }
+  int FD;
+};
+
+TEST(is_separator, Works) {
+  EXPECT_TRUE(path::is_separator('/'));
+  EXPECT_FALSE(path::is_separator('\0'));
+  EXPECT_FALSE(path::is_separator('-'));
+  EXPECT_FALSE(path::is_separator(' '));
+
+  EXPECT_TRUE(path::is_separator('\\', path::Style::windows));
+  EXPECT_FALSE(path::is_separator('\\', path::Style::posix));
+
+#ifdef _WIN32
+  EXPECT_TRUE(path::is_separator('\\'));
+#else
+  EXPECT_FALSE(path::is_separator('\\'));
+#endif
+}
+
+TEST(Support, Path) {
+  SmallVector<StringRef, 40> paths;
+  paths.push_back("");
+  paths.push_back(".");
+  paths.push_back("..");
+  paths.push_back("foo");
+  paths.push_back("/");
+  paths.push_back("/foo");
+  paths.push_back("foo/");
+  paths.push_back("/foo/");
+  paths.push_back("foo/bar");
+  paths.push_back("/foo/bar");
+  paths.push_back("//net");
+  paths.push_back("//net/");
+  paths.push_back("//net/foo");
+  paths.push_back("///foo///");
+  paths.push_back("///foo///bar");
+  paths.push_back("/.");
+  paths.push_back("./");
+  paths.push_back("/..");
+  paths.push_back("../");
+  paths.push_back("foo/.");
+  paths.push_back("foo/..");
+  paths.push_back("foo/./");
+  paths.push_back("foo/./bar");
+  paths.push_back("foo/..");
+  paths.push_back("foo/../");
+  paths.push_back("foo/../bar");
+  paths.push_back("c:");
+  paths.push_back("c:/");
+  paths.push_back("c:foo");
+  paths.push_back("c:/foo");
+  paths.push_back("c:foo/");
+  paths.push_back("c:/foo/");
+  paths.push_back("c:/foo/bar");
+  paths.push_back("prn:");
+  paths.push_back("c:\\");
+  paths.push_back("c:foo");
+  paths.push_back("c:\\foo");
+  paths.push_back("c:foo\\");
+  paths.push_back("c:\\foo\\");
+  paths.push_back("c:\\foo/");
+  paths.push_back("c:/foo\\bar");
+
+  for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
+                                                  e = paths.end();
+                                                  i != e;
+                                                  ++i) {
+    SCOPED_TRACE(*i);
+    SmallVector<StringRef, 5> ComponentStack;
+    for (sys::path::const_iterator ci = sys::path::begin(*i),
+                                   ce = sys::path::end(*i);
+                                   ci != ce;
+                                   ++ci) {
+      EXPECT_FALSE(ci->empty());
+      ComponentStack.push_back(*ci);
+    }
+
+    SmallVector<StringRef, 5> ReverseComponentStack;
+    for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
+                                     ce = sys::path::rend(*i);
+                                     ci != ce;
+                                     ++ci) {
+      EXPECT_FALSE(ci->empty());
+      ReverseComponentStack.push_back(*ci);
+    }
+    std::reverse(ReverseComponentStack.begin(), ReverseComponentStack.end());
+    EXPECT_THAT(ComponentStack, testing::ContainerEq(ReverseComponentStack));
+
+    // Crash test most of the API - since we're iterating over all of our paths
+    // here there isn't really anything reasonable to assert on in the results.
+    (void)path::has_root_path(*i);
+    (void)path::root_path(*i);
+    (void)path::has_root_name(*i);
+    (void)path::root_name(*i);
+    (void)path::has_root_directory(*i);
+    (void)path::root_directory(*i);
+    (void)path::has_parent_path(*i);
+    (void)path::parent_path(*i);
+    (void)path::has_filename(*i);
+    (void)path::filename(*i);
+    (void)path::has_stem(*i);
+    (void)path::stem(*i);
+    (void)path::has_extension(*i);
+    (void)path::extension(*i);
+    (void)path::is_absolute(*i);
+    (void)path::is_relative(*i);
+
+    SmallString<128> temp_store;
+    temp_store = *i;
+    ASSERT_NO_ERROR(fs::make_absolute(temp_store));
+    temp_store = *i;
+    path::remove_filename(temp_store);
+
+    temp_store = *i;
+    path::replace_extension(temp_store, "ext");
+    StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
+    stem = path::stem(filename);
+    ext  = path::extension(filename);
+    EXPECT_EQ(*sys::path::rbegin(filename), (stem + ext).str());
+
+    path::native(*i, temp_store);
+  }
+
+  SmallString<32> Relative("foo.cpp");
+  sys::fs::make_absolute("/root", Relative);
+  Relative[5] = '/'; // Fix up windows paths.
+  ASSERT_EQ("/root/foo.cpp", Relative);
+}
+
+TEST(Support, FilenameParent) {
+  EXPECT_EQ("/", path::filename("/"));
+  EXPECT_EQ("", path::parent_path("/"));
+
+  EXPECT_EQ("\\", path::filename("c:\\", path::Style::windows));
+  EXPECT_EQ("c:", path::parent_path("c:\\", path::Style::windows));
+
+  EXPECT_EQ("/", path::filename("///"));
+  EXPECT_EQ("", path::parent_path("///"));
+
+  EXPECT_EQ("\\", path::filename("c:\\\\", path::Style::windows));
+  EXPECT_EQ("c:", path::parent_path("c:\\\\", path::Style::windows));
+
+  EXPECT_EQ("bar", path::filename("/foo/bar"));
+  EXPECT_EQ("/foo", path::parent_path("/foo/bar"));
+
+  EXPECT_EQ("foo", path::filename("/foo"));
+  EXPECT_EQ("/", path::parent_path("/foo"));
+
+  EXPECT_EQ("foo", path::filename("foo"));
+  EXPECT_EQ("", path::parent_path("foo"));
+
+  EXPECT_EQ(".", path::filename("foo/"));
+  EXPECT_EQ("foo", path::parent_path("foo/"));
+
+  EXPECT_EQ("//net", path::filename("//net"));
+  EXPECT_EQ("", path::parent_path("//net"));
+
+  EXPECT_EQ("/", path::filename("//net/"));
+  EXPECT_EQ("//net", path::parent_path("//net/"));
+
+  EXPECT_EQ("foo", path::filename("//net/foo"));
+  EXPECT_EQ("//net/", path::parent_path("//net/foo"));
+
+  // These checks are just to make sure we do something reasonable with the
+  // paths below. They are not meant to prescribe the one true interpretation of
+  // these paths. Other decompositions (e.g. "//" -> "" + "//") are also
+  // possible.
+  EXPECT_EQ("/", path::filename("//"));
+  EXPECT_EQ("", path::parent_path("//"));
+
+  EXPECT_EQ("\\", path::filename("\\\\", path::Style::windows));
+  EXPECT_EQ("", path::parent_path("\\\\", path::Style::windows));
+
+  EXPECT_EQ("\\", path::filename("\\\\\\", path::Style::windows));
+  EXPECT_EQ("", path::parent_path("\\\\\\", path::Style::windows));
+}
+
+static std::vector<StringRef>
+GetComponents(StringRef Path, path::Style S = path::Style::native) {
+  return {path::begin(Path, S), path::end(Path)};
+}
+
+TEST(Support, PathIterator) {
+  EXPECT_THAT(GetComponents("/foo"), testing::ElementsAre("/", "foo"));
+  EXPECT_THAT(GetComponents("/"), testing::ElementsAre("/"));
+  EXPECT_THAT(GetComponents("//"), testing::ElementsAre("/"));
+  EXPECT_THAT(GetComponents("///"), testing::ElementsAre("/"));
+  EXPECT_THAT(GetComponents("c/d/e/foo.txt"),
+              testing::ElementsAre("c", "d", "e", "foo.txt"));
+  EXPECT_THAT(GetComponents(".c/.d/../."),
+              testing::ElementsAre(".c", ".d", "..", "."));
+  EXPECT_THAT(GetComponents("/c/d/e/foo.txt"),
+              testing::ElementsAre("/", "c", "d", "e", "foo.txt"));
+  EXPECT_THAT(GetComponents("/.c/.d/../."),
+              testing::ElementsAre("/", ".c", ".d", "..", "."));
+  EXPECT_THAT(GetComponents("c:\\c\\e\\foo.txt", path::Style::windows),
+              testing::ElementsAre("c:", "\\", "c", "e", "foo.txt"));
+  EXPECT_THAT(GetComponents("//net/"), testing::ElementsAre("//net", "/"));
+  EXPECT_THAT(GetComponents("//net/c/foo.txt"),
+              testing::ElementsAre("//net", "/", "c", "foo.txt"));
+}
+
+TEST(Support, AbsolutePathIteratorEnd) {
+  // Trailing slashes are converted to '.' unless they are part of the root path.
+  SmallVector<std::pair<StringRef, path::Style>, 4> Paths;
+  Paths.emplace_back("/foo/", path::Style::native);
+  Paths.emplace_back("/foo//", path::Style::native);
+  Paths.emplace_back("//net/foo/", path::Style::native);
+  Paths.emplace_back("c:\\foo\\", path::Style::windows);
+
+  for (auto &Path : Paths) {
+    SCOPED_TRACE(Path.first);
+    StringRef LastComponent = *path::rbegin(Path.first, Path.second);
+    EXPECT_EQ(".", LastComponent);
+  }
+
+  SmallVector<std::pair<StringRef, path::Style>, 3> RootPaths;
+  RootPaths.emplace_back("/", path::Style::native);
+  RootPaths.emplace_back("//net/", path::Style::native);
+  RootPaths.emplace_back("c:\\", path::Style::windows);
+  RootPaths.emplace_back("//net//", path::Style::native);
+  RootPaths.emplace_back("c:\\\\", path::Style::windows);
+
+  for (auto &Path : RootPaths) {
+    SCOPED_TRACE(Path.first);
+    StringRef LastComponent = *path::rbegin(Path.first, Path.second);
+    EXPECT_EQ(1u, LastComponent.size());
+    EXPECT_TRUE(path::is_separator(LastComponent[0], Path.second));
+  }
+}
+
+TEST(Support, HomeDirectory) {
+  std::string expected;
+#ifdef _WIN32
+  if (wchar_t const *path = ::_wgetenv(L"USERPROFILE")) {
+    auto pathLen = ::wcslen(path);
+    ArrayRef<char> ref{reinterpret_cast<char const *>(path),
+                       pathLen * sizeof(wchar_t)};
+    convertUTF16ToUTF8String(ref, expected);
+  }
+#else
+  if (char const *path = ::getenv("HOME"))
+    expected = path;
+#endif
+  // Do not try to test it if we don't know what to expect.
+  // On Windows we use something better than env vars.
+  if (!expected.empty()) {
+    SmallString<128> HomeDir;
+    auto status = path::home_directory(HomeDir);
+    EXPECT_TRUE(status);
+    EXPECT_EQ(expected, HomeDir);
+  }
+}
+
+#ifdef LLVM_ON_UNIX
+TEST(Support, HomeDirectoryWithNoEnv) {
+  std::string OriginalStorage;
+  char const *OriginalEnv = ::getenv("HOME");
+  if (OriginalEnv) {
+    // We're going to unset it, so make a copy and save a pointer to the copy
+    // so that we can reset it at the end of the test.
+    OriginalStorage = OriginalEnv;
+    OriginalEnv = OriginalStorage.c_str();
+  }
+
+  // Don't run the test if we have nothing to compare against.
+  struct passwd *pw = getpwuid(getuid());
+  if (!pw || !pw->pw_dir) return;
+
+  ::unsetenv("HOME");
+  EXPECT_EQ(nullptr, ::getenv("HOME"));
+  std::string PwDir = pw->pw_dir;
+
+  SmallString<128> HomeDir;
+  auto status = path::home_directory(HomeDir);
+  EXPECT_TRUE(status);
+  EXPECT_EQ(PwDir, HomeDir);
+
+  // Now put the environment back to its original state (meaning that if it was
+  // unset before, we don't reset it).
+  if (OriginalEnv) ::setenv("HOME", OriginalEnv, 1);
+}
+#endif
+
+TEST(Support, TempDirectory) {
+  SmallString<32> TempDir;
+  path::system_temp_directory(false, TempDir);
+  EXPECT_TRUE(!TempDir.empty());
+  TempDir.clear();
+  path::system_temp_directory(true, TempDir);
+  EXPECT_TRUE(!TempDir.empty());
+}
+
+#ifdef _WIN32
+static std::string path2regex(std::string Path) {
+  size_t Pos = 0;
+  while ((Pos = Path.find('\\', Pos)) != std::string::npos) {
+    Path.replace(Pos, 1, "\\\\");
+    Pos += 2;
+  }
+  return Path;
+}
+
+/// Helper for running temp dir test in separated process. See below.
+#define EXPECT_TEMP_DIR(prepare, expected)                                     \
+  EXPECT_EXIT(                                                                 \
+      {                                                                        \
+        prepare;                                                               \
+        SmallString<300> TempDir;                                              \
+        path::system_temp_directory(true, TempDir);                            \
+        raw_os_ostream(std::cerr) << TempDir;                                  \
+        std::exit(0);                                                          \
+      },                                                                       \
+      ::testing::ExitedWithCode(0), path2regex(expected))
+
+TEST(SupportDeathTest, TempDirectoryOnWindows) {
+  // In this test we want to check how system_temp_directory responds to
+  // different values of specific env vars. To prevent corrupting env vars of
+  // the current process all checks are done in separated processes.
+  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:\\OtherFolder"), "C:\\OtherFolder");
+  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:/Unix/Path/Seperators"),
+                  "C:\\Unix\\Path\\Seperators");
+  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"Local Path"), ".+\\Local Path$");
+  EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"F:\\TrailingSep\\"), "F:\\TrailingSep");
+  EXPECT_TEMP_DIR(
+      _wputenv_s(L"TMP", L"C:\\2\x03C0r-\x00B5\x00B3\\\x2135\x2080"),
+      "C:\\2\xCF\x80r-\xC2\xB5\xC2\xB3\\\xE2\x84\xB5\xE2\x82\x80");
+
+  // Test $TMP empty, $TEMP set.
+  EXPECT_TEMP_DIR(
+      {
+        _wputenv_s(L"TMP", L"");
+        _wputenv_s(L"TEMP", L"C:\\Valid\\Path");
+      },
+      "C:\\Valid\\Path");
+
+  // All related env vars empty
+  EXPECT_TEMP_DIR(
+  {
+    _wputenv_s(L"TMP", L"");
+    _wputenv_s(L"TEMP", L"");
+    _wputenv_s(L"USERPROFILE", L"");
+  },
+    "C:\\Temp");
+
+  // Test evn var / path with 260 chars.
+  SmallString<270> Expected{"C:\\Temp\\AB\\123456789"};
+  while (Expected.size() < 260)
+    Expected.append("\\DirNameWith19Charss");
+  ASSERT_EQ(260U, Expected.size());
+  EXPECT_TEMP_DIR(_putenv_s("TMP", Expected.c_str()), Expected.c_str());
+}
+#endif
+
+class FileSystemTest : public testing::Test {
+protected:
+  /// Unique temporary directory in which all created filesystem entities must
+  /// be placed. It is removed at the end of each test (must be empty).
+  SmallString<128> TestDirectory;
+  SmallString<128> NonExistantFile;
+
+  void SetUp() override {
+    ASSERT_NO_ERROR(
+        fs::createUniqueDirectory("file-system-test", TestDirectory));
+    // We don't care about this specific file.
+    errs() << "Test Directory: " << TestDirectory << '\n';
+    errs().flush();
+    NonExistantFile = TestDirectory;
+
+    // Even though this value is hardcoded, is a 128-bit GUID, so we should be
+    // guaranteed that this file will never exist.
+    sys::path::append(NonExistantFile, "1B28B495C16344CB9822E588CD4C3EF0");
+  }
+
+  void TearDown() override { ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); }
+};
+
+TEST_F(FileSystemTest, Unique) {
+  // Create a temp file.
+  int FileDescriptor;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(
+      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
+
+  // The same file should return an identical unique id.
+  fs::UniqueID F1, F2;
+  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F1));
+  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F2));
+  ASSERT_EQ(F1, F2);
+
+  // Different files should return different unique ids.
+  int FileDescriptor2;
+  SmallString<64> TempPath2;
+  ASSERT_NO_ERROR(
+      fs::createTemporaryFile("prefix", "temp", FileDescriptor2, TempPath2));
+
+  fs::UniqueID D;
+  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D));
+  ASSERT_NE(D, F1);
+  ::close(FileDescriptor2);
+
+  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
+
+  // Two paths representing the same file on disk should still provide the
+  // same unique id.  We can test this by making a hard link.
+  ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
+  fs::UniqueID D2;
+  ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D2));
+  ASSERT_EQ(D2, F1);
+
+  ::close(FileDescriptor);
+
+  SmallString<128> Dir1;
+  ASSERT_NO_ERROR(
+     fs::createUniqueDirectory("dir1", Dir1));
+  ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F1));
+  ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F2));
+  ASSERT_EQ(F1, F2);
+
+  SmallString<128> Dir2;
+  ASSERT_NO_ERROR(
+     fs::createUniqueDirectory("dir2", Dir2));
+  ASSERT_NO_ERROR(fs::getUniqueID(Dir2.c_str(), F2));
+  ASSERT_NE(F1, F2);
+  ASSERT_NO_ERROR(fs::remove(Dir1));
+  ASSERT_NO_ERROR(fs::remove(Dir2));
+  ASSERT_NO_ERROR(fs::remove(TempPath2));
+  ASSERT_NO_ERROR(fs::remove(TempPath));
+}
+
+TEST_F(FileSystemTest, RealPath) {
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/test1/test2/test3"));
+  ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/test1/test2/test3"));
+
+  SmallString<64> RealBase;
+  SmallString<64> Expected;
+  SmallString<64> Actual;
+
+  // TestDirectory itself might be under a symlink or have been specified with
+  // a different case than the existing temp directory.  In such cases real_path
+  // on the concatenated path will differ in the TestDirectory portion from
+  // how we specified it.  Make sure to compare against the real_path of the
+  // TestDirectory, and not just the value of TestDirectory.
+  ASSERT_NO_ERROR(fs::real_path(TestDirectory, RealBase));
+  path::native(Twine(RealBase) + "/test1/test2", Expected);
+
+  ASSERT_NO_ERROR(fs::real_path(
+      Twine(TestDirectory) + "/././test1/../test1/test2/./test3/..", Actual));
+
+  EXPECT_EQ(Expected, Actual);
+
+  SmallString<64> HomeDir;
+
+  // This can fail if $HOME is not set and getpwuid fails.
+  bool Result = llvm::sys::path::home_directory(HomeDir);
+  if (Result) {
+    ASSERT_NO_ERROR(fs::real_path(HomeDir, Expected));
+    ASSERT_NO_ERROR(fs::real_path("~", Actual, true));
+    EXPECT_EQ(Expected, Actual);
+    ASSERT_NO_ERROR(fs::real_path("~/", Actual, true));
+    EXPECT_EQ(Expected, Actual);
+  }
+
+  ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/test1"));
+}
+
+TEST_F(FileSystemTest, ExpandTilde) {
+  SmallString<64> Expected;
+  SmallString<64> Actual;
+  SmallString<64> HomeDir;
+
+  // This can fail if $HOME is not set and getpwuid fails.
+  bool Result = llvm::sys::path::home_directory(HomeDir);
+  if (Result) {
+    fs::expand_tilde(HomeDir, Expected);
+
+    fs::expand_tilde("~", Actual);
+    EXPECT_EQ(Expected, Actual);
+
+#ifdef _WIN32
+    Expected += "\\foo";
+    fs::expand_tilde("~\\foo", Actual);
+#else
+    Expected += "/foo";
+    fs::expand_tilde("~/foo", Actual);
+#endif
+
+    EXPECT_EQ(Expected, Actual);
+  }
+}
+
+#ifdef LLVM_ON_UNIX
+TEST_F(FileSystemTest, RealPathNoReadPerm) {
+  SmallString<64> Expanded;
+
+  ASSERT_NO_ERROR(
+    fs::create_directories(Twine(TestDirectory) + "/noreadperm"));
+  ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/noreadperm"));
+
+  fs::setPermissions(Twine(TestDirectory) + "/noreadperm", fs::no_perms);
+  fs::setPermissions(Twine(TestDirectory) + "/noreadperm", fs::all_exe);
+
+  ASSERT_NO_ERROR(fs::real_path(Twine(TestDirectory) + "/noreadperm", Expanded,
+                                false));
+
+  ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/noreadperm"));
+}
+#endif
+
+
+TEST_F(FileSystemTest, TempFileKeepDiscard) {
+  // We can keep then discard.
+  auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
+  ASSERT_TRUE((bool)TempFileOrError);
+  fs::TempFile File = std::move(*TempFileOrError);
+  ASSERT_FALSE((bool)File.keep(TestDirectory + "/keep"));
+  ASSERT_FALSE((bool)File.discard());
+  ASSERT_TRUE(fs::exists(TestDirectory + "/keep"));
+  ASSERT_NO_ERROR(fs::remove(TestDirectory + "/keep"));
+}
+
+TEST_F(FileSystemTest, TempFileDiscardDiscard) {
+  // We can discard twice.
+  auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
+  ASSERT_TRUE((bool)TempFileOrError);
+  fs::TempFile File = std::move(*TempFileOrError);
+  ASSERT_FALSE((bool)File.discard());
+  ASSERT_FALSE((bool)File.discard());
+  ASSERT_FALSE(fs::exists(TestDirectory + "/keep"));
+}
+
+TEST_F(FileSystemTest, TempFiles) {
+  // Create a temp file.
+  int FileDescriptor;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(
+      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
+
+  // Make sure it exists.
+  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
+
+  // Create another temp tile.
+  int FD2;
+  SmallString<64> TempPath2;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD2, TempPath2));
+  ASSERT_TRUE(TempPath2.endswith(".temp"));
+  ASSERT_NE(TempPath.str(), TempPath2.str());
+
+  fs::file_status A, B;
+  ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
+  ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
+  EXPECT_FALSE(fs::equivalent(A, B));
+
+  ::close(FD2);
+
+  // Remove Temp2.
+  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
+  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
+  ASSERT_EQ(fs::remove(Twine(TempPath2), false),
+            errc::no_such_file_or_directory);
+
+  std::error_code EC = fs::status(TempPath2.c_str(), B);
+  EXPECT_EQ(EC, errc::no_such_file_or_directory);
+  EXPECT_EQ(B.type(), fs::file_type::file_not_found);
+
+  // Make sure Temp2 doesn't exist.
+  ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist),
+            errc::no_such_file_or_directory);
+
+  SmallString<64> TempPath3;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
+  ASSERT_FALSE(TempPath3.endswith("."));
+  FileRemover Cleanup3(TempPath3);
+
+  // Create a hard link to Temp1.
+  ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
+  bool equal;
+  ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
+  EXPECT_TRUE(equal);
+  ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
+  ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
+  EXPECT_TRUE(fs::equivalent(A, B));
+
+  // Remove Temp1.
+  ::close(FileDescriptor);
+  ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
+
+  // Remove the hard link.
+  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
+
+  // Make sure Temp1 doesn't exist.
+  ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist),
+            errc::no_such_file_or_directory);
+
+#ifdef _WIN32
+  // Path name > 260 chars should get an error.
+  const char *Path270 =
+    "abcdefghijklmnopqrstuvwxyz9abcdefghijklmnopqrstuvwxyz8"
+    "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
+    "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
+    "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
+    "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
+  EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath),
+            errc::invalid_argument);
+  // Relative path < 247 chars, no problem.
+  const char *Path216 =
+    "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
+    "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
+    "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
+    "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
+  ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath));
+  ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
+#endif
+}
+
+TEST_F(FileSystemTest, TempFileCollisions) {
+  SmallString<128> TestDirectory;
+  ASSERT_NO_ERROR(
+      fs::createUniqueDirectory("CreateUniqueFileTest", TestDirectory));
+  FileRemover Cleanup(TestDirectory);
+  SmallString<128> Model = TestDirectory;
+  path::append(Model, "%.tmp");
+  SmallString<128> Path;
+  std::vector<fs::TempFile> TempFiles;
+
+  auto TryCreateTempFile = [&]() {
+    Expected<fs::TempFile> T = fs::TempFile::create(Model);
+    if (T) {
+      TempFiles.push_back(std::move(*T));
+      return true;
+    } else {
+      logAllUnhandledErrors(T.takeError(), errs(),
+                            "Failed to create temporary file: ");
+      return false;
+    }
+  };
+
+  // We should be able to create exactly 16 temporary files.
+  for (int i = 0; i < 16; ++i)
+    EXPECT_TRUE(TryCreateTempFile());
+  EXPECT_FALSE(TryCreateTempFile());
+
+  for (fs::TempFile &T : TempFiles)
+    cantFail(T.discard());
+}
+
+TEST_F(FileSystemTest, CreateDir) {
+  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
+  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
+  ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
+            errc::file_exists);
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
+
+#ifdef LLVM_ON_UNIX
+  // Set a 0000 umask so that we can test our directory permissions.
+  mode_t OldUmask = ::umask(0000);
+
+  fs::file_status Status;
+  ASSERT_NO_ERROR(
+      fs::create_directory(Twine(TestDirectory) + "baz500", false,
+                           fs::perms::owner_read | fs::perms::owner_exe));
+  ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz500", Status));
+  ASSERT_EQ(Status.permissions() & fs::perms::all_all,
+            fs::perms::owner_read | fs::perms::owner_exe);
+  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "baz777", false,
+                                       fs::perms::all_all));
+  ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz777", Status));
+  ASSERT_EQ(Status.permissions() & fs::perms::all_all, fs::perms::all_all);
+
+  // Restore umask to be safe.
+  ::umask(OldUmask);
+#endif
+
+#ifdef _WIN32
+  // Prove that create_directories() can handle a pathname > 248 characters,
+  // which is the documented limit for CreateDirectory().
+  // (248 is MAX_PATH subtracting room for an 8.3 filename.)
+  // Generate a directory path guaranteed to fall into that range.
+  size_t TmpLen = TestDirectory.size();
+  const char *OneDir = "\\123456789";
+  size_t OneDirLen = strlen(OneDir);
+  ASSERT_LT(OneDirLen, 12U);
+  size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1;
+  SmallString<260> LongDir(TestDirectory);
+  for (size_t I = 0; I < NLevels; ++I)
+    LongDir.append(OneDir);
+  ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
+  ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
+  ASSERT_EQ(fs::create_directories(Twine(LongDir), false),
+            errc::file_exists);
+  // Tidy up, "recursively" removing the directories.
+  StringRef ThisDir(LongDir);
+  for (size_t J = 0; J < NLevels; ++J) {
+    ASSERT_NO_ERROR(fs::remove(ThisDir));
+    ThisDir = path::parent_path(ThisDir);
+  }
+
+  // Also verify that paths with Unix separators are handled correctly.
+  std::string LongPathWithUnixSeparators(TestDirectory.str());
+  // Add at least one subdirectory to TestDirectory, and replace slashes with
+  // backslashes
+  do {
+    LongPathWithUnixSeparators.append("/DirNameWith19Charss");
+  } while (LongPathWithUnixSeparators.size() < 260);
+  std::replace(LongPathWithUnixSeparators.begin(),
+               LongPathWithUnixSeparators.end(),
+               '\\', '/');
+  ASSERT_NO_ERROR(fs::create_directories(Twine(LongPathWithUnixSeparators)));
+  // cleanup
+  ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) +
+                                         "/DirNameWith19Charss"));
+
+  // Similarly for a relative pathname.  Need to set the current directory to
+  // TestDirectory so that the one we create ends up in the right place.
+  char PreviousDir[260];
+  size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir);
+  ASSERT_GT(PreviousDirLen, 0U);
+  ASSERT_LT(PreviousDirLen, 260U);
+  ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0);
+  LongDir.clear();
+  // Generate a relative directory name with absolute length > 248.
+  size_t LongDirLen = 249 - TestDirectory.size();
+  LongDir.assign(LongDirLen, 'a');
+  ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir)));
+  // While we're here, prove that .. and . handling works in these long paths.
+  const char *DotDotDirs = "\\..\\.\\b";
+  LongDir.append(DotDotDirs);
+  ASSERT_NO_ERROR(fs::create_directory("b"));
+  ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists);
+  // And clean up.
+  ASSERT_NO_ERROR(fs::remove("b"));
+  ASSERT_NO_ERROR(fs::remove(
+    Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs)))));
+  ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0);
+#endif
+}
+
+TEST_F(FileSystemTest, DirectoryIteration) {
+  std::error_code ec;
+  for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
+    ASSERT_NO_ERROR(ec);
+
+  // Create a known hierarchy to recurse over.
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/recursive/a0/aa1"));
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/recursive/a0/ab1"));
+  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) +
+                                         "/recursive/dontlookhere/da1"));
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/recursive/z0/za1"));
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/recursive/pop/p1"));
+  typedef std::vector<std::string> v_t;
+  v_t visited;
+  for (fs::recursive_directory_iterator i(Twine(TestDirectory)
+         + "/recursive", ec), e; i != e; i.increment(ec)){
+    ASSERT_NO_ERROR(ec);
+    if (path::filename(i->path()) == "p1") {
+      i.pop();
+      // FIXME: recursive_directory_iterator should be more robust.
+      if (i == e) break;
+    }
+    if (path::filename(i->path()) == "dontlookhere")
+      i.no_push();
+    visited.push_back(path::filename(i->path()));
+  }
+  v_t::const_iterator a0 = find(visited, "a0");
+  v_t::const_iterator aa1 = find(visited, "aa1");
+  v_t::const_iterator ab1 = find(visited, "ab1");
+  v_t::const_iterator dontlookhere = find(visited, "dontlookhere");
+  v_t::const_iterator da1 = find(visited, "da1");
+  v_t::const_iterator z0 = find(visited, "z0");
+  v_t::const_iterator za1 = find(visited, "za1");
+  v_t::const_iterator pop = find(visited, "pop");
+  v_t::const_iterator p1 = find(visited, "p1");
+
+  // Make sure that each path was visited correctly.
+  ASSERT_NE(a0, visited.end());
+  ASSERT_NE(aa1, visited.end());
+  ASSERT_NE(ab1, visited.end());
+  ASSERT_NE(dontlookhere, visited.end());
+  ASSERT_EQ(da1, visited.end()); // Not visited.
+  ASSERT_NE(z0, visited.end());
+  ASSERT_NE(za1, visited.end());
+  ASSERT_NE(pop, visited.end());
+  ASSERT_EQ(p1, visited.end()); // Not visited.
+
+  // Make sure that parents were visited before children. No other ordering
+  // guarantees can be made across siblings.
+  ASSERT_LT(a0, aa1);
+  ASSERT_LT(a0, ab1);
+  ASSERT_LT(z0, za1);
+
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/aa1"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/ab1"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0"));
+  ASSERT_NO_ERROR(
+      fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere/da1"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop/p1"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0/za1"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive"));
+
+  // Test recursive_directory_iterator level()
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/reclevel/a/b/c"));
+  fs::recursive_directory_iterator I(Twine(TestDirectory) + "/reclevel", ec), E;
+  for (int l = 0; I != E; I.increment(ec), ++l) {
+    ASSERT_NO_ERROR(ec);
+    EXPECT_EQ(I.level(), l);
+  }
+  EXPECT_EQ(I, E);
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b/c"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a"));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel"));
+}
+
+#ifdef LLVM_ON_UNIX
+TEST_F(FileSystemTest, BrokenSymlinkDirectoryIteration) {
+  // Create a known hierarchy to recurse over.
+  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) + "/symlink"));
+  ASSERT_NO_ERROR(
+      fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/a"));
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/symlink/b/bb"));
+  ASSERT_NO_ERROR(
+      fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/ba"));
+  ASSERT_NO_ERROR(
+      fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/bc"));
+  ASSERT_NO_ERROR(
+      fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/c"));
+  ASSERT_NO_ERROR(
+      fs::create_directories(Twine(TestDirectory) + "/symlink/d/dd/ddd"));
+  ASSERT_NO_ERROR(fs::create_link(Twine(TestDirectory) + "/symlink/d/dd",
+                                  Twine(TestDirectory) + "/symlink/d/da"));
+  ASSERT_NO_ERROR(
+      fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/e"));
+
+  typedef std::vector<std::string> v_t;
+  v_t VisitedNonBrokenSymlinks;
+  v_t VisitedBrokenSymlinks;
+  std::error_code ec;
+  using testing::UnorderedElementsAre;
+  using testing::UnorderedElementsAreArray;
+
+  // Broken symbol links are expected to throw an error.
+  for (fs::directory_iterator i(Twine(TestDirectory) + "/symlink", ec), e;
+       i != e; i.increment(ec)) {
+    ASSERT_NO_ERROR(ec);
+    if (i->status().getError() ==
+        std::make_error_code(std::errc::no_such_file_or_directory)) {
+      VisitedBrokenSymlinks.push_back(path::filename(i->path()));
+      continue;
+    }
+    VisitedNonBrokenSymlinks.push_back(path::filename(i->path()));
+  }
+  EXPECT_THAT(VisitedNonBrokenSymlinks, UnorderedElementsAre("b", "d"));
+  VisitedNonBrokenSymlinks.clear();
+
+  EXPECT_THAT(VisitedBrokenSymlinks, UnorderedElementsAre("a", "c", "e"));
+  VisitedBrokenSymlinks.clear();
+
+  // Broken symbol links are expected to throw an error.
+  for (fs::recursive_directory_iterator i(
+      Twine(TestDirectory) + "/symlink", ec), e; i != e; i.increment(ec)) {
+    ASSERT_NO_ERROR(ec);
+    if (i->status().getError() ==
+        std::make_error_code(std::errc::no_such_file_or_directory)) {
+      VisitedBrokenSymlinks.push_back(path::filename(i->path()));
+      continue;
+    }
+    VisitedNonBrokenSymlinks.push_back(path::filename(i->path()));
+  }
+  EXPECT_THAT(VisitedNonBrokenSymlinks,
+              UnorderedElementsAre("b", "bb", "d", "da", "dd", "ddd", "ddd"));
+  VisitedNonBrokenSymlinks.clear();
+
+  EXPECT_THAT(VisitedBrokenSymlinks,
+              UnorderedElementsAre("a", "ba", "bc", "c", "e"));
+  VisitedBrokenSymlinks.clear();
+
+  for (fs::recursive_directory_iterator i(
+      Twine(TestDirectory) + "/symlink", ec, /*follow_symlinks=*/false), e;
+       i != e; i.increment(ec)) {
+    ASSERT_NO_ERROR(ec);
+    if (i->status().getError() ==
+        std::make_error_code(std::errc::no_such_file_or_directory)) {
+      VisitedBrokenSymlinks.push_back(path::filename(i->path()));
+      continue;
+    }
+    VisitedNonBrokenSymlinks.push_back(path::filename(i->path()));
+  }
+  EXPECT_THAT(VisitedNonBrokenSymlinks,
+              UnorderedElementsAreArray({"a", "b", "ba", "bb", "bc", "c", "d",
+                                         "da", "dd", "ddd", "e"}));
+  VisitedNonBrokenSymlinks.clear();
+
+  EXPECT_THAT(VisitedBrokenSymlinks, UnorderedElementsAre());
+  VisitedBrokenSymlinks.clear();
+
+  ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/symlink"));
+}
+#endif
+
+TEST_F(FileSystemTest, Remove) {
+  SmallString<64> BaseDir;
+  SmallString<64> Paths[4];
+  int fds[4];
+  ASSERT_NO_ERROR(fs::createUniqueDirectory("fs_remove", BaseDir));
+
+  ASSERT_NO_ERROR(fs::create_directories(Twine(BaseDir) + "/foo/bar/baz"));
+  ASSERT_NO_ERROR(fs::create_directories(Twine(BaseDir) + "/foo/bar/buzz"));
+  ASSERT_NO_ERROR(fs::createUniqueFile(
+      Twine(BaseDir) + "/foo/bar/baz/%%%%%%.tmp", fds[0], Paths[0]));
+  ASSERT_NO_ERROR(fs::createUniqueFile(
+      Twine(BaseDir) + "/foo/bar/baz/%%%%%%.tmp", fds[1], Paths[1]));
+  ASSERT_NO_ERROR(fs::createUniqueFile(
+      Twine(BaseDir) + "/foo/bar/buzz/%%%%%%.tmp", fds[2], Paths[2]));
+  ASSERT_NO_ERROR(fs::createUniqueFile(
+      Twine(BaseDir) + "/foo/bar/buzz/%%%%%%.tmp", fds[3], Paths[3]));
+
+  for (int fd : fds)
+    ::close(fd);
+
+  EXPECT_TRUE(fs::exists(Twine(BaseDir) + "/foo/bar/baz"));
+  EXPECT_TRUE(fs::exists(Twine(BaseDir) + "/foo/bar/buzz"));
+  EXPECT_TRUE(fs::exists(Paths[0]));
+  EXPECT_TRUE(fs::exists(Paths[1]));
+  EXPECT_TRUE(fs::exists(Paths[2]));
+  EXPECT_TRUE(fs::exists(Paths[3]));
+
+  ASSERT_NO_ERROR(fs::remove_directories("D:/footest"));
+
+  ASSERT_NO_ERROR(fs::remove_directories(BaseDir));
+  ASSERT_FALSE(fs::exists(BaseDir));
+}
+
+#ifdef _WIN32
+TEST_F(FileSystemTest, CarriageReturn) {
+  SmallString<128> FilePathname(TestDirectory);
+  std::error_code EC;
+  path::append(FilePathname, "test");
+
+  {
+    raw_fd_ostream File(FilePathname, EC, sys::fs::F_Text);
+    ASSERT_NO_ERROR(EC);
+    File << '\n';
+  }
+  {
+    auto Buf = MemoryBuffer::getFile(FilePathname.str());
+    EXPECT_TRUE((bool)Buf);
+    EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
+  }
+
+  {
+    raw_fd_ostream File(FilePathname, EC, sys::fs::F_None);
+    ASSERT_NO_ERROR(EC);
+    File << '\n';
+  }
+  {
+    auto Buf = MemoryBuffer::getFile(FilePathname.str());
+    EXPECT_TRUE((bool)Buf);
+    EXPECT_EQ(Buf.get()->getBuffer(), "\n");
+  }
+  ASSERT_NO_ERROR(fs::remove(Twine(FilePathname)));
+}
+#endif
+
+TEST_F(FileSystemTest, Resize) {
+  int FD;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+  ASSERT_NO_ERROR(fs::resize_file(FD, 123));
+  fs::file_status Status;
+  ASSERT_NO_ERROR(fs::status(FD, Status));
+  ASSERT_EQ(Status.getSize(), 123U);
+  ::close(FD);
+  ASSERT_NO_ERROR(fs::remove(TempPath));
+}
+
+TEST_F(FileSystemTest, MD5) {
+  int FD;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+  StringRef Data("abcdefghijklmnopqrstuvwxyz");
+  ASSERT_EQ(write(FD, Data.data(), Data.size()), static_cast<ssize_t>(Data.size()));
+  lseek(FD, 0, SEEK_SET);
+  auto Hash = fs::md5_contents(FD);
+  ::close(FD);
+  ASSERT_NO_ERROR(Hash.getError());
+
+  EXPECT_STREQ("c3fcd3d76192e4007dfb496cca67e13b", Hash->digest().c_str());
+}
+
+TEST_F(FileSystemTest, FileMapping) {
+  // Create a temp file.
+  int FileDescriptor;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(
+      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
+  unsigned Size = 4096;
+  ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size));
+
+  // Map in temp file and add some content
+  std::error_code EC;
+  StringRef Val("hello there");
+  {
+    fs::mapped_file_region mfr(FileDescriptor,
+                               fs::mapped_file_region::readwrite, Size, 0, EC);
+    ASSERT_NO_ERROR(EC);
+    std::copy(Val.begin(), Val.end(), mfr.data());
+    // Explicitly add a 0.
+    mfr.data()[Val.size()] = 0;
+    // Unmap temp file
+  }
+  ASSERT_EQ(close(FileDescriptor), 0);
+
+  // Map it back in read-only
+  {
+    int FD;
+    EC = fs::openFileForRead(Twine(TempPath), FD);
+    ASSERT_NO_ERROR(EC);
+    fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+    ASSERT_NO_ERROR(EC);
+
+    // Verify content
+    EXPECT_EQ(StringRef(mfr.const_data()), Val);
+
+    // Unmap temp file
+    fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC);
+    ASSERT_NO_ERROR(EC);
+    ASSERT_EQ(close(FD), 0);
+  }
+  ASSERT_NO_ERROR(fs::remove(TempPath));
+}
+
+TEST(Support, NormalizePath) {
+  using TestTuple = std::tuple<const char *, const char *, const char *>;
+  std::vector<TestTuple> Tests;
+  Tests.emplace_back("a", "a", "a");
+  Tests.emplace_back("a/b", "a\\b", "a/b");
+  Tests.emplace_back("a\\b", "a\\b", "a/b");
+  Tests.emplace_back("a\\\\b", "a\\\\b", "a\\\\b");
+  Tests.emplace_back("\\a", "\\a", "/a");
+  Tests.emplace_back("a\\", "a\\", "a/");
+
+  for (auto &T : Tests) {
+    SmallString<64> Win(std::get<0>(T));
+    SmallString<64> Posix(Win);
+    path::native(Win, path::Style::windows);
+    path::native(Posix, path::Style::posix);
+    EXPECT_EQ(std::get<1>(T), Win);
+    EXPECT_EQ(std::get<2>(T), Posix);
+  }
+
+#if defined(_WIN32)
+  SmallString<64> PathHome;
+  path::home_directory(PathHome);
+
+  const char *Path7a = "~/aaa";
+  SmallString<64> Path7(Path7a);
+  path::native(Path7);
+  EXPECT_TRUE(Path7.endswith("\\aaa"));
+  EXPECT_TRUE(Path7.startswith(PathHome));
+  EXPECT_EQ(Path7.size(), PathHome.size() + strlen(Path7a + 1));
+
+  const char *Path8a = "~";
+  SmallString<64> Path8(Path8a);
+  path::native(Path8);
+  EXPECT_EQ(Path8, PathHome);
+
+  const char *Path9a = "~aaa";
+  SmallString<64> Path9(Path9a);
+  path::native(Path9);
+  EXPECT_EQ(Path9, "~aaa");
+
+  const char *Path10a = "aaa/~/b";
+  SmallString<64> Path10(Path10a);
+  path::native(Path10);
+  EXPECT_EQ(Path10, "aaa\\~\\b");
+#endif
+}
+
+TEST(Support, RemoveLeadingDotSlash) {
+  StringRef Path1("././/foolz/wat");
+  StringRef Path2("./////");
+
+  Path1 = path::remove_leading_dotslash(Path1);
+  EXPECT_EQ(Path1, "foolz/wat");
+  Path2 = path::remove_leading_dotslash(Path2);
+  EXPECT_EQ(Path2, "");
+}
+
+static std::string remove_dots(StringRef path, bool remove_dot_dot,
+                               path::Style style) {
+  SmallString<256> buffer(path);
+  path::remove_dots(buffer, remove_dot_dot, style);
+  return buffer.str();
+}
+
+TEST(Support, RemoveDots) {
+  EXPECT_EQ("foolz\\wat",
+            remove_dots(".\\.\\\\foolz\\wat", false, path::Style::windows));
+  EXPECT_EQ("", remove_dots(".\\\\\\\\\\", false, path::Style::windows));
+
+  EXPECT_EQ("a\\..\\b\\c",
+            remove_dots(".\\a\\..\\b\\c", false, path::Style::windows));
+  EXPECT_EQ("b\\c", remove_dots(".\\a\\..\\b\\c", true, path::Style::windows));
+  EXPECT_EQ("c", remove_dots(".\\.\\c", true, path::Style::windows));
+  EXPECT_EQ("..\\a\\c",
+            remove_dots("..\\a\\b\\..\\c", true, path::Style::windows));
+  EXPECT_EQ("..\\..\\a\\c",
+            remove_dots("..\\..\\a\\b\\..\\c", true, path::Style::windows));
+
+  SmallString<64> Path1(".\\.\\c");
+  EXPECT_TRUE(path::remove_dots(Path1, true, path::Style::windows));
+  EXPECT_EQ("c", Path1);
+
+  EXPECT_EQ("foolz/wat",
+            remove_dots("././/foolz/wat", false, path::Style::posix));
+  EXPECT_EQ("", remove_dots("./////", false, path::Style::posix));
+
+  EXPECT_EQ("a/../b/c", remove_dots("./a/../b/c", false, path::Style::posix));
+  EXPECT_EQ("b/c", remove_dots("./a/../b/c", true, path::Style::posix));
+  EXPECT_EQ("c", remove_dots("././c", true, path::Style::posix));
+  EXPECT_EQ("../a/c", remove_dots("../a/b/../c", true, path::Style::posix));
+  EXPECT_EQ("../../a/c",
+            remove_dots("../../a/b/../c", true, path::Style::posix));
+  EXPECT_EQ("/a/c", remove_dots("/../../a/c", true, path::Style::posix));
+  EXPECT_EQ("/a/c",
+            remove_dots("/../a/b//../././/c", true, path::Style::posix));
+
+  SmallString<64> Path2("././c");
+  EXPECT_TRUE(path::remove_dots(Path2, true, path::Style::posix));
+  EXPECT_EQ("c", Path2);
+}
+
+TEST(Support, ReplacePathPrefix) {
+  SmallString<64> Path1("/foo");
+  SmallString<64> Path2("/old/foo");
+  SmallString<64> OldPrefix("/old");
+  SmallString<64> NewPrefix("/new");
+  SmallString<64> NewPrefix2("/longernew");
+  SmallString<64> EmptyPrefix("");
+
+  SmallString<64> Path = Path1;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix);
+  EXPECT_EQ(Path, "/foo");
+  Path = Path2;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix);
+  EXPECT_EQ(Path, "/new/foo");
+  Path = Path2;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix2);
+  EXPECT_EQ(Path, "/longernew/foo");
+  Path = Path1;
+  path::replace_path_prefix(Path, EmptyPrefix, NewPrefix);
+  EXPECT_EQ(Path, "/new/foo");
+  Path = Path2;
+  path::replace_path_prefix(Path, OldPrefix, EmptyPrefix);
+  EXPECT_EQ(Path, "/foo");
+}
+
+TEST_F(FileSystemTest, OpenFileForRead) {
+  // Create a temp file.
+  int FileDescriptor;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(
+      fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
+  FileRemover Cleanup(TempPath);
+
+  // Make sure it exists.
+  ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
+
+  // Open the file for read
+  int FileDescriptor2;
+  SmallString<64> ResultPath;
+  ASSERT_NO_ERROR(fs::openFileForRead(Twine(TempPath), FileDescriptor2,
+                                      fs::OF_None, &ResultPath))
+
+  // If we succeeded, check that the paths are the same (modulo case):
+  if (!ResultPath.empty()) {
+    // The paths returned by createTemporaryFile and getPathFromOpenFD
+    // should reference the same file on disk.
+    fs::UniqueID D1, D2;
+    ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
+    ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
+    ASSERT_EQ(D1, D2);
+  }
+  ::close(FileDescriptor);
+  ::close(FileDescriptor2);
+
+#ifdef _WIN32
+  // Since Windows Vista, file access time is not updated by default.
+  // This is instead updated manually by openFileForRead.
+  // https://blogs.technet.microsoft.com/filecab/2006/11/07/disabling-last-access-time-in-windows-vista-to-improve-ntfs-performance/
+  // This part of the unit test is Windows specific as the updating of
+  // access times can be disabled on Linux using /etc/fstab.
+
+  // Set access time to UNIX epoch.
+  ASSERT_NO_ERROR(sys::fs::openFileForWrite(Twine(TempPath), FileDescriptor,
+                                            fs::CD_OpenExisting));
+  TimePoint<> Epoch(std::chrono::milliseconds(0));
+  ASSERT_NO_ERROR(fs::setLastAccessAndModificationTime(FileDescriptor, Epoch));
+  ::close(FileDescriptor);
+
+  // Open the file and ensure access time is updated, when forced.
+  ASSERT_NO_ERROR(fs::openFileForRead(Twine(TempPath), FileDescriptor,
+                                      fs::OF_UpdateAtime, &ResultPath));
+
+  sys::fs::file_status Status;
+  ASSERT_NO_ERROR(sys::fs::status(FileDescriptor, Status));
+  auto FileAccessTime = Status.getLastAccessedTime();
+
+  ASSERT_NE(Epoch, FileAccessTime);
+  ::close(FileDescriptor);
+
+  // Ideally this test would include a case when ATime is not forced to update,
+  // however the expected behaviour will differ depending on the configuration
+  // of the Windows file system.
+#endif
+}
+
+static void createFileWithData(const Twine &Path, bool ShouldExistBefore,
+                               fs::CreationDisposition Disp, StringRef Data) {
+  int FD;
+  ASSERT_EQ(ShouldExistBefore, fs::exists(Path));
+  ASSERT_NO_ERROR(fs::openFileForWrite(Path, FD, Disp));
+  FileDescriptorCloser Closer(FD);
+  ASSERT_TRUE(fs::exists(Path));
+
+  ASSERT_EQ(Data.size(), (size_t)write(FD, Data.data(), Data.size()));
+}
+
+static void verifyFileContents(const Twine &Path, StringRef Contents) {
+  auto Buffer = MemoryBuffer::getFile(Path);
+  ASSERT_TRUE((bool)Buffer);
+  StringRef Data = Buffer.get()->getBuffer();
+  ASSERT_EQ(Data, Contents);
+}
+
+TEST_F(FileSystemTest, CreateNew) {
+  int FD;
+  Optional<FileDescriptorCloser> Closer;
+
+  // Succeeds if the file does not exist.
+  ASSERT_FALSE(fs::exists(NonExistantFile));
+  ASSERT_NO_ERROR(fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateNew));
+  ASSERT_TRUE(fs::exists(NonExistantFile));
+
+  FileRemover Cleanup(NonExistantFile);
+  Closer.emplace(FD);
+
+  // And creates a file of size 0.
+  sys::fs::file_status Status;
+  ASSERT_NO_ERROR(sys::fs::status(FD, Status));
+  EXPECT_EQ(0ULL, Status.getSize());
+
+  // Close this first, before trying to re-open the file.
+  Closer.reset();
+
+  // But fails if the file does exist.
+  ASSERT_ERROR(fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateNew));
+}
+
+TEST_F(FileSystemTest, CreateAlways) {
+  int FD;
+  Optional<FileDescriptorCloser> Closer;
+
+  // Succeeds if the file does not exist.
+  ASSERT_FALSE(fs::exists(NonExistantFile));
+  ASSERT_NO_ERROR(
+      fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateAlways));
+
+  Closer.emplace(FD);
+
+  ASSERT_TRUE(fs::exists(NonExistantFile));
+
+  FileRemover Cleanup(NonExistantFile);
+
+  // And creates a file of size 0.
+  uint64_t FileSize;
+  ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+  ASSERT_EQ(0ULL, FileSize);
+
+  // If we write some data to it re-create it with CreateAlways, it succeeds and
+  // truncates to 0 bytes.
+  ASSERT_EQ(4, write(FD, "Test", 4));
+
+  Closer.reset();
+
+  ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+  ASSERT_EQ(4ULL, FileSize);
+
+  ASSERT_NO_ERROR(
+      fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateAlways));
+  Closer.emplace(FD);
+  ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+  ASSERT_EQ(0ULL, FileSize);
+}
+
+TEST_F(FileSystemTest, OpenExisting) {
+  int FD;
+
+  // Fails if the file does not exist.
+  ASSERT_FALSE(fs::exists(NonExistantFile));
+  ASSERT_ERROR(fs::openFileForWrite(NonExistantFile, FD, fs::CD_OpenExisting));
+  ASSERT_FALSE(fs::exists(NonExistantFile));
+
+  // Make a dummy file now so that we can try again when the file does exist.
+  createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
+  FileRemover Cleanup(NonExistantFile);
+  uint64_t FileSize;
+  ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+  ASSERT_EQ(4ULL, FileSize);
+
+  // If we re-create it with different data, it overwrites rather than
+  // appending.
+  createFileWithData(NonExistantFile, true, fs::CD_OpenExisting, "Buzz");
+  verifyFileContents(NonExistantFile, "Buzz");
+}
+
+TEST_F(FileSystemTest, OpenAlways) {
+  // Succeeds if the file does not exist.
+  createFileWithData(NonExistantFile, false, fs::CD_OpenAlways, "Fizz");
+  FileRemover Cleanup(NonExistantFile);
+  uint64_t FileSize;
+  ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+  ASSERT_EQ(4ULL, FileSize);
+
+  // Now re-open it and write again, verifying the contents get over-written.
+  createFileWithData(NonExistantFile, true, fs::CD_OpenAlways, "Bu");
+  verifyFileContents(NonExistantFile, "Buzz");
+}
+
+TEST_F(FileSystemTest, AppendSetsCorrectFileOffset) {
+  fs::CreationDisposition Disps[] = {fs::CD_CreateAlways, fs::CD_OpenAlways,
+                                     fs::CD_OpenExisting};
+
+  // Write some data and re-open it with every possible disposition (this is a
+  // hack that shouldn't work, but is left for compatibility.  F_Append
+  // overrides
+  // the specified disposition.
+  for (fs::CreationDisposition Disp : Disps) {
+    int FD;
+    Optional<FileDescriptorCloser> Closer;
+
+    createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
+
+    FileRemover Cleanup(NonExistantFile);
+
+    uint64_t FileSize;
+    ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+    ASSERT_EQ(4ULL, FileSize);
+    ASSERT_NO_ERROR(
+        fs::openFileForWrite(NonExistantFile, FD, Disp, fs::OF_Append));
+    Closer.emplace(FD);
+    ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
+    ASSERT_EQ(4ULL, FileSize);
+
+    ASSERT_EQ(4, write(FD, "Buzz", 4));
+    Closer.reset();
+
+    verifyFileContents(NonExistantFile, "FizzBuzz");
+  }
+}
+
+static void verifyRead(int FD, StringRef Data, bool ShouldSucceed) {
+  std::vector<char> Buffer;
+  Buffer.resize(Data.size());
+  int Result = ::read(FD, Buffer.data(), Buffer.size());
+  if (ShouldSucceed) {
+    ASSERT_EQ((size_t)Result, Data.size());
+    ASSERT_EQ(Data, StringRef(Buffer.data(), Buffer.size()));
+  } else {
+    ASSERT_EQ(-1, Result);
+    ASSERT_EQ(EBADF, errno);
+  }
+}
+
+static void verifyWrite(int FD, StringRef Data, bool ShouldSucceed) {
+  int Result = ::write(FD, Data.data(), Data.size());
+  if (ShouldSucceed)
+    ASSERT_EQ((size_t)Result, Data.size());
+  else {
+    ASSERT_EQ(-1, Result);
+    ASSERT_EQ(EBADF, errno);
+  }
+}
+
+TEST_F(FileSystemTest, ReadOnlyFileCantWrite) {
+  createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
+  FileRemover Cleanup(NonExistantFile);
+
+  int FD;
+  ASSERT_NO_ERROR(fs::openFileForRead(NonExistantFile, FD));
+  FileDescriptorCloser Closer(FD);
+
+  verifyWrite(FD, "Buzz", false);
+  verifyRead(FD, "Fizz", true);
+}
+
+TEST_F(FileSystemTest, WriteOnlyFileCantRead) {
+  createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
+  FileRemover Cleanup(NonExistantFile);
+
+  int FD;
+  ASSERT_NO_ERROR(
+      fs::openFileForWrite(NonExistantFile, FD, fs::CD_OpenExisting));
+  FileDescriptorCloser Closer(FD);
+  verifyRead(FD, "Fizz", false);
+  verifyWrite(FD, "Buzz", true);
+}
+
+TEST_F(FileSystemTest, ReadWriteFileCanReadOrWrite) {
+  createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
+  FileRemover Cleanup(NonExistantFile);
+
+  int FD;
+  ASSERT_NO_ERROR(fs::openFileForReadWrite(NonExistantFile, FD,
+                                           fs::CD_OpenExisting, fs::OF_None));
+  FileDescriptorCloser Closer(FD);
+  verifyRead(FD, "Fizz", true);
+  verifyWrite(FD, "Buzz", true);
+}
+
+TEST_F(FileSystemTest, set_current_path) {
+  SmallString<128> path;
+
+  ASSERT_NO_ERROR(fs::current_path(path));
+  ASSERT_NE(TestDirectory, path);
+
+  struct RestorePath {
+    SmallString<128> path;
+    RestorePath(const SmallString<128> &path) : path(path) {}
+    ~RestorePath() { fs::set_current_path(path); }
+  } restore_path(path);
+
+  ASSERT_NO_ERROR(fs::set_current_path(TestDirectory));
+
+  ASSERT_NO_ERROR(fs::current_path(path));
+
+  fs::UniqueID D1, D2;
+  ASSERT_NO_ERROR(fs::getUniqueID(TestDirectory, D1));
+  ASSERT_NO_ERROR(fs::getUniqueID(path, D2));
+  ASSERT_EQ(D1, D2) << "D1: " << TestDirectory << "\nD2: " << path;
+}
+
+TEST_F(FileSystemTest, permissions) {
+  int FD;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+  FileRemover Cleanup(TempPath);
+
+  // Make sure it exists.
+  ASSERT_TRUE(fs::exists(Twine(TempPath)));
+
+  auto CheckPermissions = [&](fs::perms Expected) {
+    ErrorOr<fs::perms> Actual = fs::getPermissions(TempPath);
+    return Actual && *Actual == Expected;
+  };
+
+  std::error_code NoError;
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::all_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_read | fs::all_exe));
+
+#if defined(_WIN32)
+  fs::perms ReadOnly = fs::all_read | fs::all_exe;
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe |
+                                             fs::set_gid_on_exe |
+                                             fs::sticky_bit),
+            NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, ReadOnly | fs::set_uid_on_exe |
+                                             fs::set_gid_on_exe |
+                                             fs::sticky_bit),
+            NoError);
+  EXPECT_TRUE(CheckPermissions(ReadOnly));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_all));
+#else
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::no_perms));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::owner_read));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::owner_write));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::owner_exe));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::owner_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::group_read));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::group_write));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::group_exe));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::group_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::others_read));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::others_write));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::others_exe));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::others_all));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_read));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_write));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_exe));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::set_gid_on_exe));
+
+  // Modern BSDs require root to set the sticky bit on files.
+  // AIX without root will mask off (i.e., lose) the sticky bit on files.
+#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) &&  \
+    !defined(_AIX)
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::sticky_bit));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe |
+                                             fs::set_gid_on_exe |
+                                             fs::sticky_bit),
+            NoError);
+  EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe | fs::set_gid_on_exe |
+                               fs::sticky_bit));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::set_uid_on_exe |
+                                             fs::set_gid_on_exe |
+                                             fs::sticky_bit),
+            NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_read | fs::set_uid_on_exe |
+                               fs::set_gid_on_exe | fs::sticky_bit));
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_perms));
+#endif // !FreeBSD && !NetBSD && !OpenBSD && !AIX
+
+  EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms & ~fs::sticky_bit),
+                               NoError);
+  EXPECT_TRUE(CheckPermissions(fs::all_perms & ~fs::sticky_bit));
+#endif
+}
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
new file mode 100644
index 0000000..85b1839
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
@@ -0,0 +1,65 @@
+//===- unittest/Support/ProcessTest.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/Process.h"
+#include "gtest/gtest.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace {
+
+using namespace llvm;
+using namespace sys;
+
+TEST(ProcessTest, GetRandomNumberTest) {
+  const unsigned r1 = Process::GetRandomNumber();
+  const unsigned r2 = Process::GetRandomNumber();
+  // It should be extremely unlikely that both r1 and r2 are 0.
+  EXPECT_NE((r1 | r2), 0u);
+}
+
+#ifdef _MSC_VER
+#define setenv(name, var, ignore) _putenv_s(name, var)
+#endif
+
+#if HAVE_SETENV || _MSC_VER
+TEST(ProcessTest, Basic) {
+  setenv("__LLVM_TEST_ENVIRON_VAR__", "abc", true);
+  Optional<std::string> val(Process::GetEnv("__LLVM_TEST_ENVIRON_VAR__"));
+  EXPECT_TRUE(val.hasValue());
+  EXPECT_STREQ("abc", val->c_str());
+}
+
+TEST(ProcessTest, None) {
+  Optional<std::string> val(
+      Process::GetEnv("__LLVM_TEST_ENVIRON_NO_SUCH_VAR__"));
+  EXPECT_FALSE(val.hasValue());
+}
+#endif
+
+#ifdef _WIN32
+
+TEST(ProcessTest, EmptyVal) {
+  SetEnvironmentVariableA("__LLVM_TEST_ENVIRON_VAR__", "");
+  Optional<std::string> val(Process::GetEnv("__LLVM_TEST_ENVIRON_VAR__"));
+  EXPECT_TRUE(val.hasValue());
+  EXPECT_STREQ("", val->c_str());
+}
+
+TEST(ProcessTest, Wchar) {
+  SetEnvironmentVariableW(L"__LLVM_TEST_ENVIRON_VAR__", L"abcdefghijklmnopqrs");
+  Optional<std::string> val(Process::GetEnv("__LLVM_TEST_ENVIRON_VAR__"));
+  EXPECT_TRUE(val.hasValue());
+  EXPECT_STREQ("abcdefghijklmnopqrs", val->c_str());
+}
+#endif
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp b/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
new file mode 100644
index 0000000..ec1c85a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ProgramTest.cpp
@@ -0,0 +1,340 @@
+//===- unittest/Support/ProgramTest.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/Program.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "gtest/gtest.h"
+#include <stdlib.h>
+#if defined(__APPLE__)
+# include <crt_externs.h>
+#elif !defined(_MSC_VER)
+// Forward declare environ in case it's not provided by stdlib.h.
+extern char **environ;
+#endif
+
+#if defined(LLVM_ON_UNIX)
+#include <unistd.h>
+void sleep_for(unsigned int seconds) {
+  sleep(seconds);
+}
+#elif defined(_WIN32)
+#include <windows.h>
+void sleep_for(unsigned int seconds) {
+  Sleep(seconds * 1000);
+}
+#else
+#error sleep_for is not implemented on your platform.
+#endif
+
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
+    SmallString<128> MessageStorage;                                           \
+    raw_svector_ostream Message(MessageStorage);                               \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+// From TestMain.cpp.
+extern const char *TestMainArgv0;
+
+namespace {
+
+using namespace llvm;
+using namespace sys;
+
+static cl::opt<std::string>
+ProgramTestStringArg1("program-test-string-arg1");
+static cl::opt<std::string>
+ProgramTestStringArg2("program-test-string-arg2");
+
+class ProgramEnvTest : public testing::Test {
+  std::vector<StringRef> EnvTable;
+  std::vector<std::string> EnvStorage;
+
+protected:
+  void SetUp() override {
+    auto EnvP = [] {
+#if defined(_WIN32)
+      _wgetenv(L"TMP"); // Populate _wenviron, initially is null
+      return _wenviron;
+#elif defined(__APPLE__)
+      return *_NSGetEnviron();
+#else
+      return environ;
+#endif
+    }();
+    ASSERT_TRUE(EnvP);
+
+    auto prepareEnvVar = [this](decltype(*EnvP) Var) -> StringRef {
+#if defined(_WIN32)
+      // On Windows convert UTF16 encoded variable to UTF8
+      auto Len = wcslen(Var);
+      ArrayRef<char> Ref{reinterpret_cast<char const *>(Var),
+                         Len * sizeof(*Var)};
+      EnvStorage.emplace_back();
+      auto convStatus = convertUTF16ToUTF8String(Ref, EnvStorage.back());
+      EXPECT_TRUE(convStatus);
+      return EnvStorage.back();
+#else
+      (void)this;
+      return StringRef(Var);
+#endif
+    };
+
+    while (*EnvP != nullptr) {
+      EnvTable.emplace_back(prepareEnvVar(*EnvP));
+      ++EnvP;
+    }
+  }
+
+  void TearDown() override {
+    EnvTable.clear();
+    EnvStorage.clear();
+  }
+
+  void addEnvVar(StringRef Var) { EnvTable.emplace_back(Var); }
+
+  ArrayRef<StringRef> getEnviron() const { return EnvTable; }
+};
+
+#ifdef _WIN32
+TEST_F(ProgramEnvTest, CreateProcessLongPath) {
+  if (getenv("LLVM_PROGRAM_TEST_LONG_PATH"))
+    exit(0);
+
+  // getMainExecutable returns an absolute path; prepend the long-path prefix.
+  std::string MyAbsExe =
+      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+  std::string MyExe;
+  if (!StringRef(MyAbsExe).startswith("\\\\?\\"))
+    MyExe.append("\\\\?\\");
+  MyExe.append(MyAbsExe);
+
+  StringRef ArgV[] = {MyExe,
+                      "--gtest_filter=ProgramEnvTest.CreateProcessLongPath"};
+
+  // Add LLVM_PROGRAM_TEST_LONG_PATH to the environment of the child.
+  addEnvVar("LLVM_PROGRAM_TEST_LONG_PATH=1");
+
+  // Redirect stdout to a long path.
+  SmallString<128> TestDirectory;
+  ASSERT_NO_ERROR(
+    fs::createUniqueDirectory("program-redirect-test", TestDirectory));
+  SmallString<256> LongPath(TestDirectory);
+  LongPath.push_back('\\');
+  // MAX_PATH = 260
+  LongPath.append(260 - TestDirectory.size(), 'a');
+
+  std::string Error;
+  bool ExecutionFailed;
+  Optional<StringRef> Redirects[] = {None, LongPath.str(), None};
+  int RC = ExecuteAndWait(MyExe, ArgV, getEnviron(), Redirects,
+    /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &Error,
+    &ExecutionFailed);
+  EXPECT_FALSE(ExecutionFailed) << Error;
+  EXPECT_EQ(0, RC);
+
+  // Remove the long stdout.
+  ASSERT_NO_ERROR(fs::remove(Twine(LongPath)));
+  ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory)));
+}
+#endif
+
+TEST_F(ProgramEnvTest, CreateProcessTrailingSlash) {
+  if (getenv("LLVM_PROGRAM_TEST_CHILD")) {
+    if (ProgramTestStringArg1 == "has\\\\ trailing\\" &&
+        ProgramTestStringArg2 == "has\\\\ trailing\\") {
+      exit(0);  // Success!  The arguments were passed and parsed.
+    }
+    exit(1);
+  }
+
+  std::string my_exe =
+      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+  StringRef argv[] = {
+      my_exe,
+      "--gtest_filter=ProgramEnvTest.CreateProcessTrailingSlash",
+      "-program-test-string-arg1",
+      "has\\\\ trailing\\",
+      "-program-test-string-arg2",
+      "has\\\\ trailing\\"};
+
+  // Add LLVM_PROGRAM_TEST_CHILD to the environment of the child.
+  addEnvVar("LLVM_PROGRAM_TEST_CHILD=1");
+
+  std::string error;
+  bool ExecutionFailed;
+  // Redirect stdout and stdin to NUL, but let stderr through.
+#ifdef _WIN32
+  StringRef nul("NUL");
+#else
+  StringRef nul("/dev/null");
+#endif
+  Optional<StringRef> redirects[] = { nul, nul, None };
+  int rc = ExecuteAndWait(my_exe, argv, getEnviron(), redirects,
+                          /*secondsToWait=*/ 10, /*memoryLimit=*/ 0, &error,
+                          &ExecutionFailed);
+  EXPECT_FALSE(ExecutionFailed) << error;
+  EXPECT_EQ(0, rc);
+}
+
+TEST_F(ProgramEnvTest, TestExecuteNoWait) {
+  using namespace llvm::sys;
+
+  if (getenv("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT")) {
+    sleep_for(/*seconds*/ 1);
+    exit(0);
+  }
+
+  std::string Executable =
+      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+  StringRef argv[] = {Executable,
+                      "--gtest_filter=ProgramEnvTest.TestExecuteNoWait"};
+
+  // Add LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT to the environment of the child.
+  addEnvVar("LLVM_PROGRAM_TEST_EXECUTE_NO_WAIT=1");
+
+  std::string Error;
+  bool ExecutionFailed;
+  ProcessInfo PI1 = ExecuteNoWait(Executable, argv, getEnviron(), {}, 0, &Error,
+                                  &ExecutionFailed);
+  ASSERT_FALSE(ExecutionFailed) << Error;
+  ASSERT_NE(PI1.Pid, ProcessInfo::InvalidPid) << "Invalid process id";
+
+  unsigned LoopCount = 0;
+
+  // Test that Wait() with WaitUntilTerminates=true works. In this case,
+  // LoopCount should only be incremented once.
+  while (true) {
+    ++LoopCount;
+    ProcessInfo WaitResult = llvm::sys::Wait(PI1, 0, true, &Error);
+    ASSERT_TRUE(Error.empty());
+    if (WaitResult.Pid == PI1.Pid)
+      break;
+  }
+
+  EXPECT_EQ(LoopCount, 1u) << "LoopCount should be 1";
+
+  ProcessInfo PI2 = ExecuteNoWait(Executable, argv, getEnviron(), {}, 0, &Error,
+                                  &ExecutionFailed);
+  ASSERT_FALSE(ExecutionFailed) << Error;
+  ASSERT_NE(PI2.Pid, ProcessInfo::InvalidPid) << "Invalid process id";
+
+  // Test that Wait() with SecondsToWait=0 performs a non-blocking wait. In this
+  // cse, LoopCount should be greater than 1 (more than one increment occurs).
+  while (true) {
+    ++LoopCount;
+    ProcessInfo WaitResult = llvm::sys::Wait(PI2, 0, false, &Error);
+    ASSERT_TRUE(Error.empty());
+    if (WaitResult.Pid == PI2.Pid)
+      break;
+  }
+
+  ASSERT_GT(LoopCount, 1u) << "LoopCount should be >1";
+}
+
+TEST_F(ProgramEnvTest, TestExecuteAndWaitTimeout) {
+  using namespace llvm::sys;
+
+  if (getenv("LLVM_PROGRAM_TEST_TIMEOUT")) {
+    sleep_for(/*seconds*/ 10);
+    exit(0);
+  }
+
+  std::string Executable =
+      sys::fs::getMainExecutable(TestMainArgv0, &ProgramTestStringArg1);
+  StringRef argv[] = {
+      Executable, "--gtest_filter=ProgramEnvTest.TestExecuteAndWaitTimeout"};
+
+  // Add LLVM_PROGRAM_TEST_TIMEOUT to the environment of the child.
+ addEnvVar("LLVM_PROGRAM_TEST_TIMEOUT=1");
+
+  std::string Error;
+  bool ExecutionFailed;
+  int RetCode =
+      ExecuteAndWait(Executable, argv, getEnviron(), {}, /*secondsToWait=*/1, 0,
+                     &Error, &ExecutionFailed);
+  ASSERT_EQ(-2, RetCode);
+}
+
+TEST(ProgramTest, TestExecuteNegative) {
+  std::string Executable = "i_dont_exist";
+  StringRef argv[] = {Executable};
+
+  {
+    std::string Error;
+    bool ExecutionFailed;
+    int RetCode = ExecuteAndWait(Executable, argv, llvm::None, {}, 0, 0, &Error,
+                                 &ExecutionFailed);
+    ASSERT_TRUE(RetCode < 0) << "On error ExecuteAndWait should return 0 or "
+                                "positive value indicating the result code";
+    ASSERT_TRUE(ExecutionFailed);
+    ASSERT_FALSE(Error.empty());
+  }
+
+  {
+    std::string Error;
+    bool ExecutionFailed;
+    ProcessInfo PI = ExecuteNoWait(Executable, argv, llvm::None, {}, 0, &Error,
+                                   &ExecutionFailed);
+    ASSERT_EQ(PI.Pid, ProcessInfo::InvalidPid)
+        << "On error ExecuteNoWait should return an invalid ProcessInfo";
+    ASSERT_TRUE(ExecutionFailed);
+    ASSERT_FALSE(Error.empty());
+  }
+
+}
+
+#ifdef _WIN32
+const char utf16le_text[] =
+    "\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61\x00";
+const char utf16be_text[] =
+    "\x00\x6c\x00\x69\x00\x6e\x00\x67\x00\xfc\x00\x69\x00\xe7\x00\x61";
+#endif
+const char utf8_text[] = "\x6c\x69\x6e\x67\xc3\xbc\x69\xc3\xa7\x61";
+
+TEST(ProgramTest, TestWriteWithSystemEncoding) {
+  SmallString<128> TestDirectory;
+  ASSERT_NO_ERROR(fs::createUniqueDirectory("program-test", TestDirectory));
+  errs() << "Test Directory: " << TestDirectory << '\n';
+  errs().flush();
+  SmallString<128> file_pathname(TestDirectory);
+  path::append(file_pathname, "international-file.txt");
+  // Only on Windows we should encode in UTF16. For other systems, use UTF8
+  ASSERT_NO_ERROR(sys::writeFileWithEncoding(file_pathname.c_str(), utf8_text,
+                                             sys::WEM_UTF16));
+  int fd = 0;
+  ASSERT_NO_ERROR(fs::openFileForRead(file_pathname.c_str(), fd));
+#if defined(_WIN32)
+  char buf[18];
+  ASSERT_EQ(::read(fd, buf, 18), 18);
+  if (strncmp(buf, "\xfe\xff", 2) == 0) { // UTF16-BE
+    ASSERT_EQ(strncmp(&buf[2], utf16be_text, 16), 0);
+  } else if (strncmp(buf, "\xff\xfe", 2) == 0) { // UTF16-LE
+    ASSERT_EQ(strncmp(&buf[2], utf16le_text, 16), 0);
+  } else {
+    FAIL() << "Invalid BOM in UTF-16 file";
+  }
+#else
+  char buf[10];
+  ASSERT_EQ(::read(fd, buf, 10), 10);
+  ASSERT_EQ(strncmp(buf, utf8_text, 10), 0);
+#endif
+  ::close(fd);
+  ASSERT_NO_ERROR(fs::remove(file_pathname.str()));
+  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/RegexTest.cpp b/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
new file mode 100644
index 0000000..7e44a3c
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/RegexTest.cpp
@@ -0,0 +1,182 @@
+//===- llvm/unittest/Support/RegexTest.cpp - Regex 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/Regex.h"
+#include "llvm/ADT/SmallVector.h"
+#include "gtest/gtest.h"
+#include <cstring>
+
+using namespace llvm;
+namespace {
+
+class RegexTest : public ::testing::Test {
+};
+
+TEST_F(RegexTest, Basics) {
+  Regex r1("^[0-9]+$");
+  EXPECT_TRUE(r1.match("916"));
+  EXPECT_TRUE(r1.match("9"));
+  EXPECT_FALSE(r1.match("9a"));
+
+  SmallVector<StringRef, 1> Matches;
+  Regex r2("[0-9]+");
+  EXPECT_TRUE(r2.match("aa216b", &Matches));
+  EXPECT_EQ(1u, Matches.size());
+  EXPECT_EQ("216", Matches[0].str());
+
+  Regex r3("[0-9]+([a-f])?:([0-9]+)");
+  EXPECT_TRUE(r3.match("9a:513b", &Matches));
+  EXPECT_EQ(3u, Matches.size());
+  EXPECT_EQ("9a:513", Matches[0].str());
+  EXPECT_EQ("a", Matches[1].str());
+  EXPECT_EQ("513", Matches[2].str());
+
+  EXPECT_TRUE(r3.match("9:513b", &Matches));
+  EXPECT_EQ(3u, Matches.size());
+  EXPECT_EQ("9:513", Matches[0].str());
+  EXPECT_EQ("", Matches[1].str());
+  EXPECT_EQ("513", Matches[2].str());
+
+  Regex r4("a[^b]+b");
+  std::string String="axxb";
+  String[2] = '\0';
+  EXPECT_FALSE(r4.match("abb"));
+  EXPECT_TRUE(r4.match(String, &Matches));
+  EXPECT_EQ(1u, Matches.size());
+  EXPECT_EQ(String, Matches[0].str());
+
+  std::string NulPattern="X[0-9]+X([a-f])?:([0-9]+)";
+  String="YX99a:513b";
+  NulPattern[7] = '\0';
+  Regex r5(NulPattern);
+  EXPECT_FALSE(r5.match(String));
+  EXPECT_FALSE(r5.match("X9"));
+  String[3]='\0';
+  EXPECT_TRUE(r5.match(String));
+}
+
+TEST_F(RegexTest, Backreferences) {
+  Regex r1("([a-z]+)_\\1");
+  SmallVector<StringRef, 4> Matches;
+  EXPECT_TRUE(r1.match("abc_abc", &Matches));
+  EXPECT_EQ(2u, Matches.size());
+  EXPECT_FALSE(r1.match("abc_ab", &Matches));
+
+  Regex r2("a([0-9])b\\1c\\1");
+  EXPECT_TRUE(r2.match("a4b4c4", &Matches));
+  EXPECT_EQ(2u, Matches.size());
+  EXPECT_EQ("4", Matches[1].str());
+  EXPECT_FALSE(r2.match("a2b2c3"));
+
+  Regex r3("a([0-9])([a-z])b\\1\\2");
+  EXPECT_TRUE(r3.match("a6zb6z", &Matches));
+  EXPECT_EQ(3u, Matches.size());
+  EXPECT_EQ("6", Matches[1].str());
+  EXPECT_EQ("z", Matches[2].str());
+  EXPECT_FALSE(r3.match("a6zb6y"));
+  EXPECT_FALSE(r3.match("a6zb7z"));
+}
+
+TEST_F(RegexTest, Substitution) {
+  std::string Error;
+
+  EXPECT_EQ("aNUMber", Regex("[0-9]+").sub("NUM", "a1234ber"));
+
+  // Standard Escapes
+  EXPECT_EQ("a\\ber", Regex("[0-9]+").sub("\\\\", "a1234ber", &Error));
+  EXPECT_EQ("", Error);
+  EXPECT_EQ("a\nber", Regex("[0-9]+").sub("\\n", "a1234ber", &Error));
+  EXPECT_EQ("", Error);
+  EXPECT_EQ("a\tber", Regex("[0-9]+").sub("\\t", "a1234ber", &Error));
+  EXPECT_EQ("", Error);
+  EXPECT_EQ("ajber", Regex("[0-9]+").sub("\\j", "a1234ber", &Error));
+  EXPECT_EQ("", Error);
+
+  EXPECT_EQ("aber", Regex("[0-9]+").sub("\\", "a1234ber", &Error));
+  EXPECT_EQ(Error, "replacement string contained trailing backslash");
+  
+  // Backreferences
+  EXPECT_EQ("aa1234bber", Regex("a[0-9]+b").sub("a\\0b", "a1234ber", &Error));
+  EXPECT_EQ("", Error);
+
+  EXPECT_EQ("a1234ber", Regex("a([0-9]+)b").sub("a\\1b", "a1234ber", &Error));
+  EXPECT_EQ("", Error);
+
+  EXPECT_EQ("aber", Regex("a[0-9]+b").sub("a\\100b", "a1234ber", &Error));
+  EXPECT_EQ(Error, "invalid backreference string '100'");
+}
+
+TEST_F(RegexTest, IsLiteralERE) {
+  EXPECT_TRUE(Regex::isLiteralERE("abc"));
+  EXPECT_FALSE(Regex::isLiteralERE("a(bc)"));
+  EXPECT_FALSE(Regex::isLiteralERE("^abc"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc$"));
+  EXPECT_FALSE(Regex::isLiteralERE("a|bc"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc*"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc+"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc?"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc."));
+  EXPECT_FALSE(Regex::isLiteralERE("a[bc]"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc\\1"));
+  EXPECT_FALSE(Regex::isLiteralERE("abc{1,2}"));
+}
+
+TEST_F(RegexTest, Escape) {
+  EXPECT_EQ("a\\[bc\\]", Regex::escape("a[bc]"));
+  EXPECT_EQ("abc\\{1\\\\,2\\}", Regex::escape("abc{1\\,2}"));
+}
+
+TEST_F(RegexTest, IsValid) {
+  std::string Error;
+  EXPECT_FALSE(Regex("(foo").isValid(Error));
+  EXPECT_EQ("parentheses not balanced", Error);
+  EXPECT_FALSE(Regex("a[b-").isValid(Error));
+  EXPECT_EQ("invalid character range", Error);
+}
+
+TEST_F(RegexTest, MoveConstruct) {
+  Regex r1("^[0-9]+$");
+  Regex r2(std::move(r1));
+  EXPECT_TRUE(r2.match("916"));
+}
+
+TEST_F(RegexTest, MoveAssign) {
+  Regex r1("^[0-9]+$");
+  Regex r2("abc");
+  r2 = std::move(r1);
+  EXPECT_TRUE(r2.match("916"));
+  std::string Error;
+  EXPECT_FALSE(r1.isValid(Error));
+}
+
+TEST_F(RegexTest, NoArgConstructor) {
+  std::string Error;
+  Regex r1;
+  EXPECT_FALSE(r1.isValid(Error));
+  EXPECT_EQ("invalid regular expression", Error);
+  r1 = Regex("abc");
+  EXPECT_TRUE(r1.isValid(Error));
+}
+
+TEST_F(RegexTest, MatchInvalid) {
+  Regex r1;
+  std::string Error;
+  EXPECT_FALSE(r1.isValid(Error));
+  EXPECT_FALSE(r1.match("X"));
+}
+
+// https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3727
+TEST_F(RegexTest, OssFuzz3727Regression) {
+  // Wrap in a StringRef so the NUL byte doesn't terminate the string
+  Regex r(StringRef("[[[=GS\x00[=][", 10));
+  std::string Error;
+  EXPECT_FALSE(r.isValid(Error));
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp b/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
new file mode 100644
index 0000000..15143be
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ReplaceFileTest.cpp
@@ -0,0 +1,173 @@
+//===- llvm/unittest/Support/ReplaceFileTest.cpp - unit tests -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::sys;
+
+#define ASSERT_NO_ERROR(x)                                                 \
+  do {                                                                     \
+    if (std::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"; \
+    }                                                                      \
+  } while (false)
+
+namespace {
+std::error_code CreateFileWithContent(const SmallString<128> &FilePath,
+                                      const StringRef &content) {
+  int FD = 0;
+  if (std::error_code ec = fs::openFileForWrite(FilePath, FD))
+    return ec;
+
+  const bool ShouldClose = true;
+  raw_fd_ostream OS(FD, ShouldClose);
+  OS << content;
+
+  return std::error_code();
+}
+
+class ScopedFD {
+  int FD;
+
+  ScopedFD(const ScopedFD &) = delete;
+  ScopedFD &operator=(const ScopedFD &) = delete;
+
+ public:
+  explicit ScopedFD(int Descriptor) : FD(Descriptor) {}
+  ~ScopedFD() { Process::SafelyCloseFileDescriptor(FD); }
+};
+
+bool FDHasContent(int FD, StringRef Content) {
+  auto Buffer = MemoryBuffer::getOpenFile(FD, "", -1);
+  assert(Buffer);
+  return Buffer.get()->getBuffer() == Content;
+}
+
+bool FileHasContent(StringRef File, StringRef Content) {
+  int FD = 0;
+  auto EC = fs::openFileForRead(File, FD);
+  (void)EC;
+  assert(!EC);
+  ScopedFD EventuallyCloseIt(FD);
+  return FDHasContent(FD, Content);
+}
+
+TEST(rename, FileOpenedForReadingCanBeReplaced) {
+  // Create unique temporary directory for this test.
+  SmallString<128> TestDirectory;
+  ASSERT_NO_ERROR(fs::createUniqueDirectory(
+      "FileOpenedForReadingCanBeReplaced-test", TestDirectory));
+
+  // Add a couple of files to the test directory.
+  SmallString<128> SourceFileName(TestDirectory);
+  path::append(SourceFileName, "source");
+
+  SmallString<128> TargetFileName(TestDirectory);
+  path::append(TargetFileName, "target");
+
+  ASSERT_NO_ERROR(CreateFileWithContent(SourceFileName, "!!source!!"));
+  ASSERT_NO_ERROR(CreateFileWithContent(TargetFileName, "!!target!!"));
+
+  {
+    // Open the target file for reading.
+    int ReadFD = 0;
+    ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, ReadFD));
+    ScopedFD EventuallyCloseIt(ReadFD);
+
+    // Confirm we can replace the file while it is open.
+    EXPECT_TRUE(!fs::rename(SourceFileName, TargetFileName));
+
+    // We should still be able to read the old data through the existing
+    // descriptor.
+    EXPECT_TRUE(FDHasContent(ReadFD, "!!target!!"));
+
+    // The source file should no longer exist
+    EXPECT_FALSE(fs::exists(SourceFileName));
+  }
+
+  // If we obtain a new descriptor for the target file, we should find that it
+  // contains the content that was in the source file.
+  EXPECT_TRUE(FileHasContent(TargetFileName, "!!source!!"));
+
+  // Rename the target file back to the source file name to confirm that rename
+  // still works if the destination does not already exist.
+  EXPECT_TRUE(!fs::rename(TargetFileName, SourceFileName));
+  EXPECT_FALSE(fs::exists(TargetFileName));
+  ASSERT_TRUE(fs::exists(SourceFileName));
+
+  // Clean up.
+  ASSERT_NO_ERROR(fs::remove(SourceFileName));
+  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+
+TEST(rename, ExistingTemp) {
+  // Test that existing .tmpN files don't get deleted by the Windows
+  // sys::fs::rename implementation.
+  SmallString<128> TestDirectory;
+  ASSERT_NO_ERROR(
+      fs::createUniqueDirectory("ExistingTemp-test", TestDirectory));
+
+  SmallString<128> SourceFileName(TestDirectory);
+  path::append(SourceFileName, "source");
+
+  SmallString<128> TargetFileName(TestDirectory);
+  path::append(TargetFileName, "target");
+
+  SmallString<128> TargetTmp0FileName(TestDirectory);
+  path::append(TargetTmp0FileName, "target.tmp0");
+
+  SmallString<128> TargetTmp1FileName(TestDirectory);
+  path::append(TargetTmp1FileName, "target.tmp1");
+
+  ASSERT_NO_ERROR(CreateFileWithContent(SourceFileName, "!!source!!"));
+  ASSERT_NO_ERROR(CreateFileWithContent(TargetFileName, "!!target!!"));
+  ASSERT_NO_ERROR(CreateFileWithContent(TargetTmp0FileName, "!!target.tmp0!!"));
+
+  {
+    // Use mapped_file_region to make sure that the destination file is mmap'ed.
+    // This will cause SetInformationByHandle to fail when renaming to the
+    // destination, and we will follow the code path that tries to give target
+    // a temporary name.
+    int TargetFD;
+    std::error_code EC;
+    ASSERT_NO_ERROR(fs::openFileForRead(TargetFileName, TargetFD));
+    ScopedFD X(TargetFD);
+    sys::fs::mapped_file_region MFR(
+        TargetFD, sys::fs::mapped_file_region::readonly, 10, 0, EC);
+    ASSERT_FALSE(EC);
+
+    ASSERT_NO_ERROR(fs::rename(SourceFileName, TargetFileName));
+
+#ifdef _WIN32
+    // Make sure that target was temporarily renamed to target.tmp1 on Windows.
+    // This is signified by a permission denied error as opposed to no such file
+    // or directory when trying to open it.
+    int Tmp1FD;
+    EXPECT_EQ(errc::permission_denied,
+              fs::openFileForRead(TargetTmp1FileName, Tmp1FD));
+#endif
+  }
+
+  EXPECT_TRUE(FileHasContent(TargetTmp0FileName, "!!target.tmp0!!"));
+
+  ASSERT_NO_ERROR(fs::remove(TargetFileName));
+  ASSERT_NO_ERROR(fs::remove(TargetTmp0FileName));
+  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+}
+
+}  // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
new file mode 100644
index 0000000..930bd43
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
@@ -0,0 +1,110 @@
+//===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+//
+// Reverse Iteration unit tests.
+//
+//===---------------------------------------------------------------------===//
+
+#include "llvm/Support/ReverseIteration.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(ReverseIterationTest, DenseMapTest1) {
+  static_assert(detail::IsPointerLike<int *>::value,
+                "int * is pointer-like");
+  static_assert(detail::IsPointerLike<uintptr_t>::value,
+                "uintptr_t is pointer-like");
+  static_assert(!detail::IsPointerLike<int>::value,
+                "int is not pointer-like");
+  static_assert(detail::IsPointerLike<void *>::value,
+                "void * is pointer-like");
+  struct IncompleteType;
+  static_assert(detail::IsPointerLike<IncompleteType *>::value,
+                "incomplete * is pointer-like");
+
+  // For a DenseMap with non-pointer-like keys, forward iteration equals
+  // reverse iteration.
+  DenseMap<int, int> Map;
+  int Keys[] = { 1, 2, 3, 4 };
+
+  // Insert keys into the DenseMap.
+  for (auto Key: Keys)
+    Map[Key] = 0;
+
+  // Note: This is the observed order of keys in the DenseMap.
+  // If there is any change in the behavior of the DenseMap, this order
+  // would need to be adjusted accordingly.
+  int IterKeys[] = { 2, 4, 1, 3 };
+
+  // Check that the DenseMap is iterated in the expected order.
+  for (const auto &Tuple : zip(Map, IterKeys))
+    ASSERT_EQ(std::get<0>(Tuple).first, std::get<1>(Tuple));
+
+  // Check operator++ (post-increment).
+  int i = 0;
+  for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
+    ASSERT_EQ(iter->first, IterKeys[i]);
+}
+
+// Define a pointer-like int.
+struct PtrLikeInt { int value; };
+
+namespace llvm {
+
+template<> struct DenseMapInfo<PtrLikeInt *> {
+  static PtrLikeInt *getEmptyKey() {
+    static PtrLikeInt EmptyKey;
+    return &EmptyKey;
+  }
+
+  static PtrLikeInt *getTombstoneKey() {
+    static PtrLikeInt TombstoneKey;
+    return &TombstoneKey;
+  }
+
+  static int getHashValue(const PtrLikeInt *P) {
+    return P->value;
+  }
+
+  static bool isEqual(const PtrLikeInt *LHS, const PtrLikeInt *RHS) {
+    return LHS == RHS;
+  }
+};
+
+} // end namespace llvm
+
+TEST(ReverseIterationTest, DenseMapTest2) {
+  static_assert(detail::IsPointerLike<PtrLikeInt *>::value,
+                "PtrLikeInt * is pointer-like");
+
+  PtrLikeInt a = {4}, b = {8}, c = {12}, d = {16};
+  PtrLikeInt *Keys[] = { &a, &b, &c, &d };
+
+  // Insert keys into the DenseMap.
+  DenseMap<PtrLikeInt *, int> Map;
+  for (auto *Key : Keys)
+    Map[Key] = Key->value;
+
+  // Note: If there is any change in the behavior of the DenseMap,
+  // the observed order of keys would need to be adjusted accordingly.
+  if (shouldReverseIterate<PtrLikeInt *>())
+    std::reverse(&Keys[0], &Keys[4]);
+
+  // Check that the DenseMap is iterated in the expected order.
+  for (const auto &Tuple : zip(Map, Keys))
+    ASSERT_EQ(std::get<0>(Tuple).second, std::get<1>(Tuple)->value);
+
+  // Check operator++ (post-increment).
+  int i = 0;
+  for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
+    ASSERT_EQ(iter->second, Keys[i]->value);
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp b/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
new file mode 100644
index 0000000..9e3f6de
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ScaledNumberTest.cpp
@@ -0,0 +1,566 @@
+//===- llvm/unittest/Support/ScaledNumberTest.cpp - ScaledPair 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/ScaledNumber.h"
+#include "llvm/Support/DataTypes.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::ScaledNumbers;
+
+namespace {
+
+template <class UIntT> struct ScaledPair {
+  UIntT D;
+  int S;
+  ScaledPair(const std::pair<UIntT, int16_t> &F) : D(F.first), S(F.second) {}
+  ScaledPair(UIntT D, int S) : D(D), S(S) {}
+
+  bool operator==(const ScaledPair<UIntT> &X) const {
+    return D == X.D && S == X.S;
+  }
+};
+template <class UIntT>
+bool operator==(const std::pair<UIntT, int16_t> &L,
+                const ScaledPair<UIntT> &R) {
+  return ScaledPair<UIntT>(L) == R;
+}
+template <class UIntT>
+void PrintTo(const ScaledPair<UIntT> &F, ::std::ostream *os) {
+  *os << F.D << "*2^" << F.S;
+}
+
+typedef ScaledPair<uint32_t> SP32;
+typedef ScaledPair<uint64_t> SP64;
+
+TEST(ScaledNumberHelpersTest, getRounded) {
+  EXPECT_EQ(getRounded32(0, 0, false), SP32(0, 0));
+  EXPECT_EQ(getRounded32(0, 0, true), SP32(1, 0));
+  EXPECT_EQ(getRounded32(20, 21, true), SP32(21, 21));
+  EXPECT_EQ(getRounded32(UINT32_MAX, 0, false), SP32(UINT32_MAX, 0));
+  EXPECT_EQ(getRounded32(UINT32_MAX, 0, true), SP32(1 << 31, 1));
+
+  EXPECT_EQ(getRounded64(0, 0, false), SP64(0, 0));
+  EXPECT_EQ(getRounded64(0, 0, true), SP64(1, 0));
+  EXPECT_EQ(getRounded64(20, 21, true), SP64(21, 21));
+  EXPECT_EQ(getRounded64(UINT32_MAX, 0, false), SP64(UINT32_MAX, 0));
+  EXPECT_EQ(getRounded64(UINT32_MAX, 0, true), SP64(UINT64_C(1) << 32, 0));
+  EXPECT_EQ(getRounded64(UINT64_MAX, 0, false), SP64(UINT64_MAX, 0));
+  EXPECT_EQ(getRounded64(UINT64_MAX, 0, true), SP64(UINT64_C(1) << 63, 1));
+}
+
+TEST(ScaledNumberHelpersTest, getAdjusted) {
+  const uint64_t Max32In64 = UINT32_MAX;
+  EXPECT_EQ(getAdjusted32(0), SP32(0, 0));
+  EXPECT_EQ(getAdjusted32(0, 5), SP32(0, 5));
+  EXPECT_EQ(getAdjusted32(UINT32_MAX), SP32(UINT32_MAX, 0));
+  EXPECT_EQ(getAdjusted32(Max32In64 << 1), SP32(UINT32_MAX, 1));
+  EXPECT_EQ(getAdjusted32(Max32In64 << 1, 1), SP32(UINT32_MAX, 2));
+  EXPECT_EQ(getAdjusted32(Max32In64 << 31), SP32(UINT32_MAX, 31));
+  EXPECT_EQ(getAdjusted32(Max32In64 << 32), SP32(UINT32_MAX, 32));
+  EXPECT_EQ(getAdjusted32(Max32In64 + 1), SP32(1u << 31, 1));
+  EXPECT_EQ(getAdjusted32(UINT64_MAX), SP32(1u << 31, 33));
+
+  EXPECT_EQ(getAdjusted64(0), SP64(0, 0));
+  EXPECT_EQ(getAdjusted64(0, 5), SP64(0, 5));
+  EXPECT_EQ(getAdjusted64(UINT32_MAX), SP64(UINT32_MAX, 0));
+  EXPECT_EQ(getAdjusted64(Max32In64 << 1), SP64(Max32In64 << 1, 0));
+  EXPECT_EQ(getAdjusted64(Max32In64 << 1, 1), SP64(Max32In64 << 1, 1));
+  EXPECT_EQ(getAdjusted64(Max32In64 << 31), SP64(Max32In64 << 31, 0));
+  EXPECT_EQ(getAdjusted64(Max32In64 << 32), SP64(Max32In64 << 32, 0));
+  EXPECT_EQ(getAdjusted64(Max32In64 + 1), SP64(Max32In64 + 1, 0));
+  EXPECT_EQ(getAdjusted64(UINT64_MAX), SP64(UINT64_MAX, 0));
+}
+
+TEST(ScaledNumberHelpersTest, getProduct) {
+  // Zero.
+  EXPECT_EQ(SP32(0, 0), getProduct32(0, 0));
+  EXPECT_EQ(SP32(0, 0), getProduct32(0, 1));
+  EXPECT_EQ(SP32(0, 0), getProduct32(0, 33));
+
+  // Basic.
+  EXPECT_EQ(SP32(6, 0), getProduct32(2, 3));
+  EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
+            getProduct32(UINT16_MAX / 3, UINT16_MAX / 5 * 2));
+
+  // Overflow, no loss of precision.
+  // ==> 0xf00010 * 0x1001
+  // ==> 0xf00f00000 + 0x10010
+  // ==> 0xf00f10010
+  // ==> 0xf00f1001 * 2^4
+  EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0xf00010, 0x1001));
+
+  // Overflow, loss of precision, rounds down.
+  // ==> 0xf000070 * 0x1001
+  // ==> 0xf00f000000 + 0x70070
+  // ==> 0xf00f070070
+  // ==> 0xf00f0700 * 2^8
+  EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0xf000070, 0x1001));
+
+  // Overflow, loss of precision, rounds up.
+  // ==> 0xf000080 * 0x1001
+  // ==> 0xf00f000000 + 0x80080
+  // ==> 0xf00f080080
+  // ==> 0xf00f0801 * 2^8
+  EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0xf000080, 0x1001));
+
+  // Reverse operand order.
+  EXPECT_EQ(SP32(0, 0), getProduct32(1, 0));
+  EXPECT_EQ(SP32(0, 0), getProduct32(33, 0));
+  EXPECT_EQ(SP32(6, 0), getProduct32(3, 2));
+  EXPECT_EQ(SP32(UINT16_MAX / 3 * UINT16_MAX / 5 * 2, 0),
+            getProduct32(UINT16_MAX / 5 * 2, UINT16_MAX / 3));
+  EXPECT_EQ(SP32(0xf00f1001, 4), getProduct32(0x1001, 0xf00010));
+  EXPECT_EQ(SP32(0xf00f0700, 8), getProduct32(0x1001, 0xf000070));
+  EXPECT_EQ(SP32(0xf00f0801, 8), getProduct32(0x1001, 0xf000080));
+
+  // Round to overflow.
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, 64),
+            getProduct64(UINT64_C(10376293541461622786),
+                         UINT64_C(16397105843297379211)));
+
+  // Big number with rounding.
+  EXPECT_EQ(SP64(UINT64_C(9223372036854775810), 64),
+            getProduct64(UINT64_C(18446744073709551556),
+                         UINT64_C(9223372036854775840)));
+}
+
+TEST(ScaledNumberHelpersTest, getQuotient) {
+  // Zero.
+  EXPECT_EQ(SP32(0, 0), getQuotient32(0, 0));
+  EXPECT_EQ(SP32(0, 0), getQuotient32(0, 1));
+  EXPECT_EQ(SP32(0, 0), getQuotient32(0, 73));
+  EXPECT_EQ(SP32(UINT32_MAX, MaxScale), getQuotient32(1, 0));
+  EXPECT_EQ(SP32(UINT32_MAX, MaxScale), getQuotient32(6, 0));
+
+  // Powers of two.
+  EXPECT_EQ(SP32(1u << 31, -31), getQuotient32(1, 1));
+  EXPECT_EQ(SP32(1u << 31, -30), getQuotient32(2, 1));
+  EXPECT_EQ(SP32(1u << 31, -33), getQuotient32(4, 16));
+  EXPECT_EQ(SP32(7u << 29, -29), getQuotient32(7, 1));
+  EXPECT_EQ(SP32(7u << 29, -30), getQuotient32(7, 2));
+  EXPECT_EQ(SP32(7u << 29, -33), getQuotient32(7, 16));
+
+  // Divide evenly.
+  EXPECT_EQ(SP32(3u << 30, -30), getQuotient32(9, 3));
+  EXPECT_EQ(SP32(9u << 28, -28), getQuotient32(63, 7));
+
+  // Divide unevenly.
+  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 canonicalize its
+  // output.  However, this is the algorithm the implementation uses:
+  //
+  // - Shift divisor right.
+  // - If we have 1 (power of 2), return early -- not canonicalized.
+  // - Shift dividend left.
+  // - 64-bit integer divide.
+  // - If there's a remainder, continue with long division.
+  //
+  // TODO: require less knowledge about the implementation in the test.
+
+  // Zero.
+  EXPECT_EQ(SP64(0, 0), getQuotient64(0, 0));
+  EXPECT_EQ(SP64(0, 0), getQuotient64(0, 1));
+  EXPECT_EQ(SP64(0, 0), getQuotient64(0, 73));
+  EXPECT_EQ(SP64(UINT64_MAX, MaxScale), getQuotient64(1, 0));
+  EXPECT_EQ(SP64(UINT64_MAX, MaxScale), getQuotient64(6, 0));
+
+  // Powers of two.
+  EXPECT_EQ(SP64(1, 0), getQuotient64(1, 1));
+  EXPECT_EQ(SP64(2, 0), getQuotient64(2, 1));
+  EXPECT_EQ(SP64(4, -4), getQuotient64(4, 16));
+  EXPECT_EQ(SP64(7, 0), getQuotient64(7, 1));
+  EXPECT_EQ(SP64(7, -1), getQuotient64(7, 2));
+  EXPECT_EQ(SP64(7, -4), getQuotient64(7, 16));
+
+  // Divide evenly.
+  EXPECT_EQ(SP64(UINT64_C(3) << 60, -60), getQuotient64(9, 3));
+  EXPECT_EQ(SP64(UINT64_C(9) << 58, -58), getQuotient64(63, 7));
+
+  // Divide unevenly.
+  EXPECT_EQ(SP64(0xaaaaaaaaaaaaaaab, -65), getQuotient64(1, 3));
+  EXPECT_EQ(SP64(0xd555555555555555, -63), getQuotient64(5, 3));
+}
+
+TEST(ScaledNumberHelpersTest, getLg) {
+  EXPECT_EQ(0, getLg(UINT32_C(1), 0));
+  EXPECT_EQ(1, getLg(UINT32_C(1), 1));
+  EXPECT_EQ(1, getLg(UINT32_C(2), 0));
+  EXPECT_EQ(3, getLg(UINT32_C(1), 3));
+  EXPECT_EQ(3, getLg(UINT32_C(7), 0));
+  EXPECT_EQ(3, getLg(UINT32_C(8), 0));
+  EXPECT_EQ(3, getLg(UINT32_C(9), 0));
+  EXPECT_EQ(3, getLg(UINT32_C(64), -3));
+  EXPECT_EQ(31, getLg((UINT32_MAX >> 1) + 2, 0));
+  EXPECT_EQ(32, getLg(UINT32_MAX, 0));
+  EXPECT_EQ(-1, getLg(UINT32_C(1), -1));
+  EXPECT_EQ(-1, getLg(UINT32_C(2), -2));
+  EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), -1));
+  EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 0));
+  EXPECT_EQ(INT32_MIN, getLg(UINT32_C(0), 1));
+
+  EXPECT_EQ(0, getLg(UINT64_C(1), 0));
+  EXPECT_EQ(1, getLg(UINT64_C(1), 1));
+  EXPECT_EQ(1, getLg(UINT64_C(2), 0));
+  EXPECT_EQ(3, getLg(UINT64_C(1), 3));
+  EXPECT_EQ(3, getLg(UINT64_C(7), 0));
+  EXPECT_EQ(3, getLg(UINT64_C(8), 0));
+  EXPECT_EQ(3, getLg(UINT64_C(9), 0));
+  EXPECT_EQ(3, getLg(UINT64_C(64), -3));
+  EXPECT_EQ(63, getLg((UINT64_MAX >> 1) + 2, 0));
+  EXPECT_EQ(64, getLg(UINT64_MAX, 0));
+  EXPECT_EQ(-1, getLg(UINT64_C(1), -1));
+  EXPECT_EQ(-1, getLg(UINT64_C(2), -2));
+  EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), -1));
+  EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 0));
+  EXPECT_EQ(INT32_MIN, getLg(UINT64_C(0), 1));
+}
+
+TEST(ScaledNumberHelpersTest, getLgFloor) {
+  EXPECT_EQ(0, getLgFloor(UINT32_C(1), 0));
+  EXPECT_EQ(1, getLgFloor(UINT32_C(1), 1));
+  EXPECT_EQ(1, getLgFloor(UINT32_C(2), 0));
+  EXPECT_EQ(2, getLgFloor(UINT32_C(7), 0));
+  EXPECT_EQ(3, getLgFloor(UINT32_C(1), 3));
+  EXPECT_EQ(3, getLgFloor(UINT32_C(8), 0));
+  EXPECT_EQ(3, getLgFloor(UINT32_C(9), 0));
+  EXPECT_EQ(3, getLgFloor(UINT32_C(64), -3));
+  EXPECT_EQ(31, getLgFloor((UINT32_MAX >> 1) + 2, 0));
+  EXPECT_EQ(31, getLgFloor(UINT32_MAX, 0));
+  EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), -1));
+  EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 0));
+  EXPECT_EQ(INT32_MIN, getLgFloor(UINT32_C(0), 1));
+
+  EXPECT_EQ(0, getLgFloor(UINT64_C(1), 0));
+  EXPECT_EQ(1, getLgFloor(UINT64_C(1), 1));
+  EXPECT_EQ(1, getLgFloor(UINT64_C(2), 0));
+  EXPECT_EQ(2, getLgFloor(UINT64_C(7), 0));
+  EXPECT_EQ(3, getLgFloor(UINT64_C(1), 3));
+  EXPECT_EQ(3, getLgFloor(UINT64_C(8), 0));
+  EXPECT_EQ(3, getLgFloor(UINT64_C(9), 0));
+  EXPECT_EQ(3, getLgFloor(UINT64_C(64), -3));
+  EXPECT_EQ(63, getLgFloor((UINT64_MAX >> 1) + 2, 0));
+  EXPECT_EQ(63, getLgFloor(UINT64_MAX, 0));
+  EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), -1));
+  EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 0));
+  EXPECT_EQ(INT32_MIN, getLgFloor(UINT64_C(0), 1));
+}
+
+TEST(ScaledNumberHelpersTest, getLgCeiling) {
+  EXPECT_EQ(0, getLgCeiling(UINT32_C(1), 0));
+  EXPECT_EQ(1, getLgCeiling(UINT32_C(1), 1));
+  EXPECT_EQ(1, getLgCeiling(UINT32_C(2), 0));
+  EXPECT_EQ(3, getLgCeiling(UINT32_C(1), 3));
+  EXPECT_EQ(3, getLgCeiling(UINT32_C(7), 0));
+  EXPECT_EQ(3, getLgCeiling(UINT32_C(8), 0));
+  EXPECT_EQ(3, getLgCeiling(UINT32_C(64), -3));
+  EXPECT_EQ(4, getLgCeiling(UINT32_C(9), 0));
+  EXPECT_EQ(32, getLgCeiling(UINT32_MAX, 0));
+  EXPECT_EQ(32, getLgCeiling((UINT32_MAX >> 1) + 2, 0));
+  EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), -1));
+  EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 0));
+  EXPECT_EQ(INT32_MIN, getLgCeiling(UINT32_C(0), 1));
+
+  EXPECT_EQ(0, getLgCeiling(UINT64_C(1), 0));
+  EXPECT_EQ(1, getLgCeiling(UINT64_C(1), 1));
+  EXPECT_EQ(1, getLgCeiling(UINT64_C(2), 0));
+  EXPECT_EQ(3, getLgCeiling(UINT64_C(1), 3));
+  EXPECT_EQ(3, getLgCeiling(UINT64_C(7), 0));
+  EXPECT_EQ(3, getLgCeiling(UINT64_C(8), 0));
+  EXPECT_EQ(3, getLgCeiling(UINT64_C(64), -3));
+  EXPECT_EQ(4, getLgCeiling(UINT64_C(9), 0));
+  EXPECT_EQ(64, getLgCeiling((UINT64_MAX >> 1) + 2, 0));
+  EXPECT_EQ(64, getLgCeiling(UINT64_MAX, 0));
+  EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), -1));
+  EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 0));
+  EXPECT_EQ(INT32_MIN, getLgCeiling(UINT64_C(0), 1));
+}
+
+TEST(ScaledNumberHelpersTest, compare) {
+  EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 1));
+  EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), -10));
+  EXPECT_EQ(0, compare(UINT32_C(0), 0, UINT32_C(0), 20));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(64), -3));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(32), -2));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(16), -1));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(8), 0));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(4), 1));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(2), 2));
+  EXPECT_EQ(0, compare(UINT32_C(8), 0, UINT32_C(1), 3));
+  EXPECT_EQ(-1, compare(UINT32_C(0), 0, UINT32_C(1), 3));
+  EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(1), 3));
+  EXPECT_EQ(-1, compare(UINT32_C(7), 0, UINT32_C(64), -3));
+  EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(1), 3));
+  EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(64), -3));
+  EXPECT_EQ(1, compare(UINT32_C(9), 0, UINT32_C(0), 0));
+
+  EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 1));
+  EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), -10));
+  EXPECT_EQ(0, compare(UINT64_C(0), 0, UINT64_C(0), 20));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(64), -3));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(32), -2));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(16), -1));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(8), 0));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(4), 1));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(2), 2));
+  EXPECT_EQ(0, compare(UINT64_C(8), 0, UINT64_C(1), 3));
+  EXPECT_EQ(-1, compare(UINT64_C(0), 0, UINT64_C(1), 3));
+  EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(1), 3));
+  EXPECT_EQ(-1, compare(UINT64_C(7), 0, UINT64_C(64), -3));
+  EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(1), 3));
+  EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(64), -3));
+  EXPECT_EQ(1, compare(UINT64_C(9), 0, UINT64_C(0), 0));
+  EXPECT_EQ(-1, compare(UINT64_MAX, 0, UINT64_C(1), 64));
+}
+
+TEST(ScaledNumberHelpersTest, matchScales) {
+#define MATCH_SCALES(T, LDIn, LSIn, RDIn, RSIn, LDOut, RDOut, SOut)            \
+  do {                                                                         \
+    T LDx = LDIn;                                                              \
+    T RDx = RDIn;                                                              \
+    T LDy = LDOut;                                                             \
+    T RDy = RDOut;                                                             \
+    int16_t LSx = LSIn;                                                        \
+    int16_t RSx = RSIn;                                                        \
+    int16_t Sy = SOut;                                                         \
+                                                                               \
+    EXPECT_EQ(SOut, matchScales(LDx, LSx, RDx, RSx));                          \
+    EXPECT_EQ(LDy, LDx);                                                       \
+    EXPECT_EQ(RDy, RDx);                                                       \
+    if (LDy) {                                                                 \
+      EXPECT_EQ(Sy, LSx);                                                      \
+    }                                                                          \
+    if (RDy) {                                                                 \
+      EXPECT_EQ(Sy, RSx);                                                      \
+    }                                                                          \
+  } while (false)
+
+  MATCH_SCALES(uint32_t, 0, 0, 0, 0, 0, 0, 0);
+  MATCH_SCALES(uint32_t, 0, 50, 7, 1, 0, 7, 1);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 1, 9, 0, UINT32_C(1) << 31, 4, 1);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 2, 9, 0, UINT32_C(1) << 31, 2, 2);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 3, 9, 0, UINT32_C(1) << 31, 1, 3);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 31, 4, 9, 0, UINT32_C(1) << 31, 0, 4);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 30, 4, 9, 0, UINT32_C(1) << 31, 1, 3);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 29, 4, 9, 0, UINT32_C(1) << 31, 2, 2);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 28, 4, 9, 0, UINT32_C(1) << 31, 4, 1);
+  MATCH_SCALES(uint32_t, UINT32_C(1) << 27, 4, 9, 0, UINT32_C(1) << 31, 9, 0);
+  MATCH_SCALES(uint32_t, 7, 1, 0, 50, 7, 0, 1);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 1, 4, UINT32_C(1) << 31, 1);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 2, 2, UINT32_C(1) << 31, 2);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 3, 1, UINT32_C(1) << 31, 3);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 31, 4, 0, UINT32_C(1) << 31, 4);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 30, 4, 1, UINT32_C(1) << 31, 3);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 29, 4, 2, UINT32_C(1) << 31, 2);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 28, 4, 4, UINT32_C(1) << 31, 1);
+  MATCH_SCALES(uint32_t, 9, 0, UINT32_C(1) << 27, 4, 9, UINT32_C(1) << 31, 0);
+
+  MATCH_SCALES(uint64_t, 0, 0, 0, 0, 0, 0, 0);
+  MATCH_SCALES(uint64_t, 0, 100, 7, 1, 0, 7, 1);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 1, 9, 0, UINT64_C(1) << 63, 4, 1);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 2, 9, 0, UINT64_C(1) << 63, 2, 2);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 3, 9, 0, UINT64_C(1) << 63, 1, 3);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 63, 4, 9, 0, UINT64_C(1) << 63, 0, 4);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 62, 4, 9, 0, UINT64_C(1) << 63, 1, 3);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 61, 4, 9, 0, UINT64_C(1) << 63, 2, 2);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 60, 4, 9, 0, UINT64_C(1) << 63, 4, 1);
+  MATCH_SCALES(uint64_t, UINT64_C(1) << 59, 4, 9, 0, UINT64_C(1) << 63, 9, 0);
+  MATCH_SCALES(uint64_t, 7, 1, 0, 100, 7, 0, 1);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 1, 4, UINT64_C(1) << 63, 1);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 2, 2, UINT64_C(1) << 63, 2);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 3, 1, UINT64_C(1) << 63, 3);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 63, 4, 0, UINT64_C(1) << 63, 4);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 62, 4, 1, UINT64_C(1) << 63, 3);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 61, 4, 2, UINT64_C(1) << 63, 2);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 60, 4, 4, UINT64_C(1) << 63, 1);
+  MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 59, 4, 9, UINT64_C(1) << 63, 0);
+}
+
+TEST(ScaledNumberHelpersTest, getSum) {
+  // Zero.
+  EXPECT_EQ(SP32(1, 0), getSum32(0, 0, 1, 0));
+  EXPECT_EQ(SP32(8, -3), getSum32(0, 0, 8, -3));
+  EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(0, 0, UINT32_MAX, 0));
+
+  // Basic.
+  EXPECT_EQ(SP32(2, 0), getSum32(1, 0, 1, 0));
+  EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 2, 0));
+  EXPECT_EQ(SP32(67, 0), getSum32(7, 0, 60, 0));
+
+  // Different scales.
+  EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 1, 1));
+  EXPECT_EQ(SP32(4, 0), getSum32(2, 0, 1, 1));
+
+  // Loss of precision.
+  EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 32, 1, 0));
+  EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, -32, 1, 0));
+
+  // Not quite loss of precision.
+  EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 32, 1, 1));
+  EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -32, 1, -1));
+
+  // Overflow.
+  EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, UINT32_MAX, 0));
+
+  // Reverse operand order.
+  EXPECT_EQ(SP32(1, 0), getSum32(1, 0, 0, 0));
+  EXPECT_EQ(SP32(8, -3), getSum32(8, -3, 0, 0));
+  EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(UINT32_MAX, 0, 0, 0));
+  EXPECT_EQ(SP32(3, 0), getSum32(2, 0, 1, 0));
+  EXPECT_EQ(SP32(67, 0), getSum32(60, 0, 7, 0));
+  EXPECT_EQ(SP32(3, 0), getSum32(1, 1, 1, 0));
+  EXPECT_EQ(SP32(4, 0), getSum32(1, 1, 2, 0));
+  EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, 1, 32));
+  EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, 0, 1, -32));
+  EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 1, 1, 32));
+  EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -1, 1, -32));
+  EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(UINT32_MAX, 0, 1, 0));
+
+  // Zero.
+  EXPECT_EQ(SP64(1, 0), getSum64(0, 0, 1, 0));
+  EXPECT_EQ(SP64(8, -3), getSum64(0, 0, 8, -3));
+  EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(0, 0, UINT64_MAX, 0));
+
+  // Basic.
+  EXPECT_EQ(SP64(2, 0), getSum64(1, 0, 1, 0));
+  EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 2, 0));
+  EXPECT_EQ(SP64(67, 0), getSum64(7, 0, 60, 0));
+
+  // Different scales.
+  EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 1, 1));
+  EXPECT_EQ(SP64(4, 0), getSum64(2, 0, 1, 1));
+
+  // Loss of precision.
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 64, 1, 0));
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, -64, 1, 0));
+
+  // Not quite loss of precision.
+  EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 64, 1, 1));
+  EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -64, 1, -1));
+
+  // Overflow.
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, UINT64_MAX, 0));
+
+  // Reverse operand order.
+  EXPECT_EQ(SP64(1, 0), getSum64(1, 0, 0, 0));
+  EXPECT_EQ(SP64(8, -3), getSum64(8, -3, 0, 0));
+  EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(UINT64_MAX, 0, 0, 0));
+  EXPECT_EQ(SP64(3, 0), getSum64(2, 0, 1, 0));
+  EXPECT_EQ(SP64(67, 0), getSum64(60, 0, 7, 0));
+  EXPECT_EQ(SP64(3, 0), getSum64(1, 1, 1, 0));
+  EXPECT_EQ(SP64(4, 0), getSum64(1, 1, 2, 0));
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, 1, 64));
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, 0, 1, -64));
+  EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 1, 1, 64));
+  EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -1, 1, -64));
+  EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(UINT64_MAX, 0, 1, 0));
+}
+
+TEST(ScaledNumberHelpersTest, getDifference) {
+  // Basic.
+  EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 0));
+  EXPECT_EQ(SP32(1, 0), getDifference32(2, 0, 1, 0));
+  EXPECT_EQ(SP32(53, 0), getDifference32(60, 0, 7, 0));
+
+  // Equals "0", different scales.
+  EXPECT_EQ(SP32(0, 0), getDifference32(2, 0, 1, 1));
+
+  // Subtract "0".
+  EXPECT_EQ(SP32(1, 0), getDifference32(1, 0, 0, 0));
+  EXPECT_EQ(SP32(8, -3), getDifference32(8, -3, 0, 0));
+  EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(UINT32_MAX, 0, 0, 0));
+
+  // Loss of precision.
+  EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1),
+            getDifference32((UINT32_C(1) << 31) + 1, 1, 1, 0));
+  EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -31),
+            getDifference32((UINT32_C(1) << 31) + 1, -31, 1, -32));
+
+  // Not quite loss of precision.
+  EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(1, 32, 1, 0));
+  EXPECT_EQ(SP32(UINT32_MAX, -32), getDifference32(1, 0, 1, -32));
+
+  // Saturate to "0".
+  EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 1, 0));
+  EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 8, -3));
+  EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, UINT32_MAX, 0));
+  EXPECT_EQ(SP32(0, 0), getDifference32(7, 0, 60, 0));
+  EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 1));
+  EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, 0));
+  EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, -1));
+
+  // Regression tests for cases that failed during bringup.
+  EXPECT_EQ(SP32(UINT32_C(1) << 26, -31),
+            getDifference32(1, 0, UINT32_C(31) << 27, -32));
+
+  // Basic.
+  EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 0));
+  EXPECT_EQ(SP64(1, 0), getDifference64(2, 0, 1, 0));
+  EXPECT_EQ(SP64(53, 0), getDifference64(60, 0, 7, 0));
+
+  // Equals "0", different scales.
+  EXPECT_EQ(SP64(0, 0), getDifference64(2, 0, 1, 1));
+
+  // Subtract "0".
+  EXPECT_EQ(SP64(1, 0), getDifference64(1, 0, 0, 0));
+  EXPECT_EQ(SP64(8, -3), getDifference64(8, -3, 0, 0));
+  EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(UINT64_MAX, 0, 0, 0));
+
+  // Loss of precision.
+  EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1),
+            getDifference64((UINT64_C(1) << 63) + 1, 1, 1, 0));
+  EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -63),
+            getDifference64((UINT64_C(1) << 63) + 1, -63, 1, -64));
+
+  // Not quite loss of precision.
+  EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(1, 64, 1, 0));
+  EXPECT_EQ(SP64(UINT64_MAX, -64), getDifference64(1, 0, 1, -64));
+
+  // Saturate to "0".
+  EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 1, 0));
+  EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 8, -3));
+  EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, UINT64_MAX, 0));
+  EXPECT_EQ(SP64(0, 0), getDifference64(7, 0, 60, 0));
+  EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 1));
+  EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, 0));
+  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/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp b/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
new file mode 100644
index 0000000..7bb76f5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/SourceMgrTest.cpp
@@ -0,0 +1,499 @@
+//===- unittests/Support/SourceMgrTest.cpp - SourceMgr 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/SourceMgr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class SourceMgrTest : public testing::Test {
+public:
+  SourceMgr SM;
+  unsigned MainBufferID;
+  std::string Output;
+
+  void setMainBuffer(StringRef Text, StringRef BufferName) {
+    std::unique_ptr<MemoryBuffer> MainBuffer =
+        MemoryBuffer::getMemBuffer(Text, BufferName);
+    MainBufferID = SM.AddNewSourceBuffer(std::move(MainBuffer), llvm::SMLoc());
+  }
+
+  SMLoc getLoc(unsigned Offset) {
+    return SMLoc::getFromPointer(
+        SM.getMemoryBuffer(MainBufferID)->getBufferStart() + Offset);
+  }
+
+  SMRange getRange(unsigned Offset, unsigned Length) {
+    return SMRange(getLoc(Offset), getLoc(Offset + Length));
+  }
+
+  void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
+                    const Twine &Msg, ArrayRef<SMRange> Ranges,
+                    ArrayRef<SMFixIt> FixIts) {
+    raw_string_ostream OS(Output);
+    SM.PrintMessage(OS, Loc, Kind, Msg, Ranges, FixIts);
+  }
+};
+
+} // unnamed namespace
+
+TEST_F(SourceMgrTest, BasicError) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa bbb\n"
+            "    ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, BasicWarning) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Warning, "message", None, None);
+
+  EXPECT_EQ("file.in:1:5: warning: message\n"
+            "aaa bbb\n"
+            "    ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, BasicRemark) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Remark, "message", None, None);
+
+  EXPECT_EQ("file.in:1:5: remark: message\n"
+            "aaa bbb\n"
+            "    ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, BasicNote) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Note, "message", None, None);
+
+  EXPECT_EQ("file.in:1:5: note: message\n"
+            "aaa bbb\n"
+            "    ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOfLine) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(6), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:7: error: message\n"
+            "aaa bbb\n"
+            "      ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtNewline) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(7), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:8: error: message\n"
+            "aaa bbb\n"
+            "       ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEmptyBuffer) {
+  setMainBuffer("", "file.in");
+  printMessage(getLoc(0), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:1: error: message\n"
+            "\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationJustOnSoleNewline) {
+  setMainBuffer("\n", "file.in");
+  printMessage(getLoc(0), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:1: error: message\n"
+            "\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationJustAfterSoleNewline) {
+  setMainBuffer("\n", "file.in");
+  printMessage(getLoc(1), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:2:1: error: message\n"
+            "\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationJustAfterNonNewline) {
+  setMainBuffer("123", "file.in");
+  printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:4: error: message\n"
+            "123\n"
+            "   ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationOnFirstLineOfMultiline) {
+  setMainBuffer("1234\n6789\n", "file.in");
+  printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:4: error: message\n"
+            "1234\n"
+            "   ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationOnEOLOfFirstLineOfMultiline) {
+  setMainBuffer("1234\n6789\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "1234\n"
+            "    ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationOnSecondLineOfMultiline) {
+  setMainBuffer("1234\n6789\n", "file.in");
+  printMessage(getLoc(5), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:2:1: error: message\n"
+            "6789\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationOnSecondLineOfMultilineNoSecondEOL) {
+  setMainBuffer("1234\n6789", "file.in");
+  printMessage(getLoc(5), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:2:1: error: message\n"
+            "6789\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationOnEOLOfSecondSecondLineOfMultiline) {
+  setMainBuffer("1234\n6789\n", "file.in");
+  printMessage(getLoc(9), SourceMgr::DK_Error, "message", None, None);
+
+  EXPECT_EQ("file.in:2:5: error: message\n"
+            "6789\n"
+            "    ^\n",
+            Output);
+}
+
+#define STRING_LITERAL_253_BYTES \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n1234567890\n" \
+  "1234567890\n"
+
+//===----------------------------------------------------------------------===//
+// 255-byte buffer tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(SourceMgrTest, LocationBeforeEndOf255ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "12"                       // + 2 = 255 bytes
+                , "file.in");
+  printMessage(getLoc(253), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:1: error: message\n"
+            "12\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOf255ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "12"                       // + 2 = 255 bytes
+                , "file.in");
+  printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:2: error: message\n"
+            "12\n"
+            " ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationPastEndOf255ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "12"                       // + 2 = 255 bytes
+                , "file.in");
+  printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:3: error: message\n"
+            "12\n"
+            "  ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationBeforeEndOf255ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "1\n"                      // + 2 = 255 bytes
+                , "file.in");
+  printMessage(getLoc(253), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:1: error: message\n"
+            "1\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOf255ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "1\n"                      // + 2 = 255 bytes
+                , "file.in");
+  printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:2: error: message\n"
+            "1\n"
+            " ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationPastEndOf255ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "1\n"                      // + 2 = 255 bytes
+                , "file.in");
+  printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:25:1: error: message\n"
+            "\n"
+            "^\n",
+            Output);
+}
+
+//===----------------------------------------------------------------------===//
+// 256-byte buffer tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(SourceMgrTest, LocationBeforeEndOf256ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "123"                      // + 3 = 256 bytes
+                , "file.in");
+  printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:2: error: message\n"
+            "123\n"
+            " ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOf256ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "123"                      // + 3 = 256 bytes
+                , "file.in");
+  printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:3: error: message\n"
+            "123\n"
+            "  ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationPastEndOf256ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "123"                      // + 3 = 256 bytes
+                , "file.in");
+  printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:4: error: message\n"
+            "123\n"
+            "   ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationBeforeEndOf256ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "12\n"                     // + 3 = 256 bytes
+                , "file.in");
+  printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:2: error: message\n"
+            "12\n"
+            " ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOf256ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "12\n"                     // + 3 = 256 bytes
+                , "file.in");
+  printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:3: error: message\n"
+            "12\n"
+            "  ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationPastEndOf256ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "12\n"                     // + 3 = 256 bytes
+                , "file.in");
+  printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:25:1: error: message\n"
+            "\n"
+            "^\n",
+            Output);
+}
+
+//===----------------------------------------------------------------------===//
+// 257-byte buffer tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(SourceMgrTest, LocationBeforeEndOf257ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "1234"                     // + 4 = 257 bytes
+                , "file.in");
+  printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:3: error: message\n"
+            "1234\n"
+            "  ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOf257ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "1234"                     // + 4 = 257 bytes
+                , "file.in");
+  printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:4: error: message\n"
+            "1234\n"
+            "   ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationPastEndOf257ByteBuffer) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "1234"                     // + 4 = 257 bytes
+                , "file.in");
+  printMessage(getLoc(257), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:5: error: message\n"
+            "1234\n"
+            "    ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationBeforeEndOf257ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "123\n"                    // + 4 = 257 bytes
+                , "file.in");
+  printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:3: error: message\n"
+            "123\n"
+            "  ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationAtEndOf257ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "123\n"                    // + 4 = 257 bytes
+                , "file.in");
+  printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:24:4: error: message\n"
+            "123\n"
+            "   ^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, LocationPastEndOf257ByteBufferEndingInNewline) {
+  setMainBuffer(STRING_LITERAL_253_BYTES   // first 253 bytes
+                "123\n"                    // + 4 = 257 bytes
+                , "file.in");
+  printMessage(getLoc(257), SourceMgr::DK_Error, "message", None, None);
+  EXPECT_EQ("file.in:25:1: error: message\n"
+            "\n"
+            "^\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, BasicRange) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 3), None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa bbb\n"
+            "    ^~~\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, RangeWithTab) {
+  setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3), None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa     bbb\n"
+            "   ~~~~~^~\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, MultiLineRange) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7), None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa bbb\n"
+            "    ^~~\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, MultipleRanges) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) };
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa bbb\n"
+            "~~~ ^~~\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, OverlappingRanges) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) };
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None);
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa bbb\n"
+            "~~~~^~\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, BasicFixit) {
+  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None,
+               makeArrayRef(SMFixIt(getRange(4, 3), "zzz")));
+
+  EXPECT_EQ("file.in:1:5: error: message\n"
+            "aaa bbb\n"
+            "    ^~~\n"
+            "    zzz\n",
+            Output);
+}
+
+TEST_F(SourceMgrTest, FixitForTab) {
+  setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
+  printMessage(getLoc(3), SourceMgr::DK_Error, "message", None,
+               makeArrayRef(SMFixIt(getRange(3, 1), "zzz")));
+
+  EXPECT_EQ("file.in:1:4: error: message\n"
+            "aaa     bbb\n"
+            "   ^^^^^\n"
+            "   zzz\n",
+            Output);
+}
+
diff --git a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
new file mode 100644
index 0000000..060703e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -0,0 +1,247 @@
+//===- SpecialCaseListTest.cpp - Unit tests for SpecialCaseList -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SpecialCaseList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class SpecialCaseListTest : public ::testing::Test {
+protected:
+  std::unique_ptr<SpecialCaseList> makeSpecialCaseList(StringRef List,
+                                                       std::string &Error) {
+    std::unique_ptr<MemoryBuffer> MB = MemoryBuffer::getMemBuffer(List);
+    return SpecialCaseList::create(MB.get(), Error);
+  }
+
+  std::unique_ptr<SpecialCaseList> makeSpecialCaseList(StringRef List) {
+    std::string Error;
+    auto SCL = makeSpecialCaseList(List, Error);
+    assert(SCL);
+    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) {
+  std::unique_ptr<SpecialCaseList> SCL =
+      makeSpecialCaseList("# This is a comment.\n"
+                          "\n"
+                          "src:hello\n"
+                          "src:bye\n"
+                          "src:hi=category\n"
+                          "src:z*=category\n");
+  EXPECT_TRUE(SCL->inSection("", "src", "hello"));
+  EXPECT_TRUE(SCL->inSection("", "src", "bye"));
+  EXPECT_TRUE(SCL->inSection("", "src", "hi", "category"));
+  EXPECT_TRUE(SCL->inSection("", "src", "zzzz", "category"));
+  EXPECT_FALSE(SCL->inSection("", "src", "hi"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "hello"));
+  EXPECT_FALSE(SCL->inSection("", "src", "hello", "category"));
+
+  EXPECT_EQ(3u, SCL->inSectionBlame("", "src", "hello"));
+  EXPECT_EQ(4u, SCL->inSectionBlame("", "src", "bye"));
+  EXPECT_EQ(5u, SCL->inSectionBlame("", "src", "hi", "category"));
+  EXPECT_EQ(6u, SCL->inSectionBlame("", "src", "zzzz", "category"));
+  EXPECT_EQ(0u, SCL->inSectionBlame("", "src", "hi"));
+  EXPECT_EQ(0u, SCL->inSectionBlame("", "fun", "hello"));
+  EXPECT_EQ(0u, SCL->inSectionBlame("", "src", "hello", "category"));
+}
+
+TEST_F(SpecialCaseListTest, CorrectErrorLineNumberWithBlankLine) {
+  std::string Error;
+  EXPECT_EQ(nullptr, makeSpecialCaseList("# This is a comment.\n"
+                                         "\n"
+                                         "[not valid\n",
+                                         Error));
+  EXPECT_TRUE(
+      ((StringRef)Error).startswith("malformed section header on line 3:"));
+
+  EXPECT_EQ(nullptr, makeSpecialCaseList("\n\n\n"
+                                         "[not valid\n",
+                                         Error));
+  EXPECT_TRUE(
+      ((StringRef)Error).startswith("malformed section header on line 4:"));
+}
+
+TEST_F(SpecialCaseListTest, SectionRegexErrorHandling) {
+  std::string Error;
+  EXPECT_EQ(makeSpecialCaseList("[address", Error), nullptr);
+  EXPECT_TRUE(((StringRef)Error).startswith("malformed section header "));
+
+  EXPECT_EQ(makeSpecialCaseList("[[]", Error), nullptr);
+  EXPECT_TRUE(((StringRef)Error).startswith("malformed regex for section [: "));
+
+  EXPECT_EQ(makeSpecialCaseList("src:=", Error), nullptr);
+  EXPECT_TRUE(((StringRef)Error).endswith("Supplied regexp was blank"));
+}
+
+TEST_F(SpecialCaseListTest, Section) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:global\n"
+                                                             "[sect1|sect2]\n"
+                                                             "src:test1\n"
+                                                             "[sect3*]\n"
+                                                             "src:test2\n");
+  EXPECT_TRUE(SCL->inSection("arbitrary", "src", "global"));
+  EXPECT_TRUE(SCL->inSection("", "src", "global"));
+  EXPECT_TRUE(SCL->inSection("sect1", "src", "test1"));
+  EXPECT_FALSE(SCL->inSection("sect1-arbitrary", "src", "test1"));
+  EXPECT_FALSE(SCL->inSection("sect", "src", "test1"));
+  EXPECT_FALSE(SCL->inSection("sect1", "src", "test2"));
+  EXPECT_TRUE(SCL->inSection("sect2", "src", "test1"));
+  EXPECT_TRUE(SCL->inSection("sect3", "src", "test2"));
+  EXPECT_TRUE(SCL->inSection("sect3-arbitrary", "src", "test2"));
+  EXPECT_FALSE(SCL->inSection("", "src", "test1"));
+  EXPECT_FALSE(SCL->inSection("", "src", "test2"));
+}
+
+TEST_F(SpecialCaseListTest, GlobalInit) {
+  std::unique_ptr<SpecialCaseList> SCL =
+      makeSpecialCaseList("global:foo=init\n");
+  EXPECT_FALSE(SCL->inSection("", "global", "foo"));
+  EXPECT_FALSE(SCL->inSection("", "global", "bar"));
+  EXPECT_TRUE(SCL->inSection("", "global", "foo", "init"));
+  EXPECT_FALSE(SCL->inSection("", "global", "bar", "init"));
+
+  SCL = makeSpecialCaseList("type:t2=init\n");
+  EXPECT_FALSE(SCL->inSection("", "type", "t1"));
+  EXPECT_FALSE(SCL->inSection("", "type", "t2"));
+  EXPECT_FALSE(SCL->inSection("", "type", "t1", "init"));
+  EXPECT_TRUE(SCL->inSection("", "type", "t2", "init"));
+
+  SCL = makeSpecialCaseList("src:hello=init\n");
+  EXPECT_FALSE(SCL->inSection("", "src", "hello"));
+  EXPECT_FALSE(SCL->inSection("", "src", "bye"));
+  EXPECT_TRUE(SCL->inSection("", "src", "hello", "init"));
+  EXPECT_FALSE(SCL->inSection("", "src", "bye", "init"));
+}
+
+TEST_F(SpecialCaseListTest, Substring) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:hello\n"
+                                                             "fun:foo\n"
+                                                             "global:bar\n");
+  EXPECT_FALSE(SCL->inSection("", "src", "othello"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "tomfoolery"));
+  EXPECT_FALSE(SCL->inSection("", "global", "bartender"));
+
+  SCL = makeSpecialCaseList("fun:*foo*\n");
+  EXPECT_TRUE(SCL->inSection("", "fun", "tomfoolery"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "foobar"));
+}
+
+TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
+  std::string Error;
+  EXPECT_EQ(nullptr, makeSpecialCaseList("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",
+            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",
+            Error);
+  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) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("");
+  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"));
+  for (auto &Path : Files)
+    sys::fs::remove(Path);
+}
+
+TEST_F(SpecialCaseListTest, NoTrigramsInRules) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:b.r\n"
+                                                             "fun:za*az\n");
+  EXPECT_TRUE(SCL->inSection("", "fun", "bar"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "baz"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "zakaz"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "zaraza"));
+}
+
+TEST_F(SpecialCaseListTest, NoTrigramsInARule) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*\n"
+                                                             "fun:za*az\n");
+  EXPECT_TRUE(SCL->inSection("", "fun", "abara"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "bor"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "zakaz"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "zaraza"));
+}
+
+TEST_F(SpecialCaseListTest, RepetitiveRule) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*bar*bar*bar*\n"
+                                                             "fun:bar*\n");
+  EXPECT_TRUE(SCL->inSection("", "fun", "bara"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "abara"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "barbarbarbar"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "abarbarbarbar"));
+  EXPECT_FALSE(SCL->inSection("", "fun", "abarbarbar"));
+}
+
+TEST_F(SpecialCaseListTest, SpecialSymbolRule) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n");
+  EXPECT_TRUE(SCL->inSection("", "src", "c++abi"));
+  EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi"));
+}
+
+TEST_F(SpecialCaseListTest, PopularTrigram) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*aaaaaa*\n"
+                                                             "fun:*aaaaa*\n"
+                                                             "fun:*aaaa*\n"
+                                                             "fun:*aaa*\n");
+  EXPECT_TRUE(SCL->inSection("", "fun", "aaa"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "aaaa"));
+  EXPECT_TRUE(SCL->inSection("", "fun", "aaaabbbaaa"));
+}
+
+TEST_F(SpecialCaseListTest, EscapedSymbols) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n"
+                                                             "src:*hello\\\\world*\n");
+  EXPECT_TRUE(SCL->inSection("", "src", "dir/c++abi"));
+  EXPECT_FALSE(SCL->inSection("", "src", "dir/c\\+\\+abi"));
+  EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi"));
+  EXPECT_TRUE(SCL->inSection("", "src", "C:\\hello\\world"));
+  EXPECT_TRUE(SCL->inSection("", "src", "hello\\world"));
+  EXPECT_FALSE(SCL->inSection("", "src", "hello\\\\world"));
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/StringPool.cpp b/src/llvm-project/llvm/unittests/Support/StringPool.cpp
new file mode 100644
index 0000000..ac39fec
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/StringPool.cpp
@@ -0,0 +1,31 @@
+//===- llvm/unittest/Support/StringPoiil.cpp - StringPool 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/StringPool.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(PooledStringPtrTest, OperatorEquals) {
+  StringPool pool;
+  const PooledStringPtr a = pool.intern("a");
+  const PooledStringPtr b = pool.intern("b");
+  EXPECT_FALSE(a == b);
+}
+
+TEST(PooledStringPtrTest, OperatorNotEquals) {
+  StringPool pool;
+  const PooledStringPtr a = pool.intern("a");
+  const PooledStringPtr b = pool.intern("b");
+  EXPECT_TRUE(a != b);
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp b/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
new file mode 100644
index 0000000..474eac6
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/SwapByteOrderTest.cpp
@@ -0,0 +1,201 @@
+//===- unittests/Support/SwapByteOrderTest.cpp - swap byte order test -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/SwapByteOrder.h"
+#include "gtest/gtest.h"
+#include <cstdlib>
+#include <ctime>
+using namespace llvm;
+
+#undef max
+
+namespace {
+
+// In these first two tests all of the original_uintx values are truncated
+// except for 64. We could avoid this, but there's really no point.
+
+TEST(getSwappedBytes, UnsignedRoundTrip) {
+  // The point of the bit twiddling of magic is to test with and without bits
+  // in every byte.
+  uint64_t value = 1;
+  for (std::size_t i = 0; i <= sizeof(value); ++i) {
+    uint8_t original_uint8 = static_cast<uint8_t>(value);
+    EXPECT_EQ(original_uint8,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_uint8)));
+
+    uint16_t original_uint16 = static_cast<uint16_t>(value);
+    EXPECT_EQ(original_uint16,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_uint16)));
+
+    uint32_t original_uint32 = static_cast<uint32_t>(value);
+    EXPECT_EQ(original_uint32,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_uint32)));
+
+    uint64_t original_uint64 = static_cast<uint64_t>(value);
+    EXPECT_EQ(original_uint64,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_uint64)));
+
+    value = (value << 8) | 0x55; // binary 0101 0101.
+  }
+}
+
+TEST(getSwappedBytes, SignedRoundTrip) {
+  // The point of the bit twiddling of magic is to test with and without bits
+  // in every byte.
+  uint64_t value = 1;
+  for (std::size_t i = 0; i <= sizeof(value); ++i) {
+    int8_t original_int8 = static_cast<int8_t>(value);
+    EXPECT_EQ(original_int8,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int8)));
+
+    int16_t original_int16 = static_cast<int16_t>(value);
+    EXPECT_EQ(original_int16,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int16)));
+
+    int32_t original_int32 = static_cast<int32_t>(value);
+    EXPECT_EQ(original_int32,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int32)));
+
+    int64_t original_int64 = static_cast<int64_t>(value);
+    EXPECT_EQ(original_int64,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int64)));
+
+    // Test other sign.
+    value *= -1;
+
+    original_int8 = static_cast<int8_t>(value);
+    EXPECT_EQ(original_int8,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int8)));
+
+    original_int16 = static_cast<int16_t>(value);
+    EXPECT_EQ(original_int16,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int16)));
+
+    original_int32 = static_cast<int32_t>(value);
+    EXPECT_EQ(original_int32,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int32)));
+
+    original_int64 = static_cast<int64_t>(value);
+    EXPECT_EQ(original_int64,
+              sys::getSwappedBytes(sys::getSwappedBytes(original_int64)));
+
+    // Return to normal sign and twiddle.
+    value *= -1;
+    value = (value << 8) | 0x55; // binary 0101 0101.
+  }
+}
+
+TEST(getSwappedBytes, uint8_t) {
+  EXPECT_EQ(uint8_t(0x11), sys::getSwappedBytes(uint8_t(0x11)));
+}
+
+TEST(getSwappedBytes, uint16_t) {
+  EXPECT_EQ(uint16_t(0x1122), sys::getSwappedBytes(uint16_t(0x2211)));
+}
+
+TEST(getSwappedBytes, uint32_t) {
+  EXPECT_EQ(uint32_t(0x11223344), sys::getSwappedBytes(uint32_t(0x44332211)));
+}
+
+TEST(getSwappedBytes, uint64_t) {
+  EXPECT_EQ(uint64_t(0x1122334455667788ULL),
+    sys::getSwappedBytes(uint64_t(0x8877665544332211ULL)));
+}
+
+TEST(getSwappedBytes, int8_t) {
+  EXPECT_EQ(int8_t(0x11), sys::getSwappedBytes(int8_t(0x11)));
+}
+
+TEST(getSwappedBytes, int16_t) {
+  EXPECT_EQ(int16_t(0x1122), sys::getSwappedBytes(int16_t(0x2211)));
+}
+
+TEST(getSwappedBytes, int32_t) {
+  EXPECT_EQ(int32_t(0x11223344), sys::getSwappedBytes(int32_t(0x44332211)));
+}
+
+TEST(getSwappedBytes, int64_t) {
+  EXPECT_EQ(int64_t(0x1122334455667788LL),
+    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);
+  EXPECT_EQ(uint8_t(0x11), value);
+}
+
+TEST(swapByteOrder, uint16_t) {
+  uint16_t value = 0x2211;
+  sys::swapByteOrder(value);
+  EXPECT_EQ(uint16_t(0x1122), value);
+}
+
+TEST(swapByteOrder, uint32_t) {
+  uint32_t value = 0x44332211;
+  sys::swapByteOrder(value);
+  EXPECT_EQ(uint32_t(0x11223344), value);
+}
+
+TEST(swapByteOrder, uint64_t) {
+  uint64_t value = 0x8877665544332211ULL;
+  sys::swapByteOrder(value);
+  EXPECT_EQ(uint64_t(0x1122334455667788ULL), value);
+}
+
+TEST(swapByteOrder, int8_t) {
+  int8_t value = 0x11;
+  sys::swapByteOrder(value);
+  EXPECT_EQ(int8_t(0x11), value);
+}
+
+TEST(swapByteOrder, int16_t) {
+  int16_t value = 0x2211;
+  sys::swapByteOrder(value);
+  EXPECT_EQ(int16_t(0x1122), value);
+}
+
+TEST(swapByteOrder, int32_t) {
+  int32_t value = 0x44332211;
+  sys::swapByteOrder(value);
+  EXPECT_EQ(int32_t(0x11223344), value);
+}
+
+TEST(swapByteOrder, int64_t) {
+  int64_t value = 0x8877665544332211LL;
+  sys::swapByteOrder(value);
+  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/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp b/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
new file mode 100644
index 0000000..717df62
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/SymbolRemappingReaderTest.cpp
@@ -0,0 +1,96 @@
+//===- unittests/Support/SymbolRemappingReaderTest.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/SymbolRemappingReader.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+class SymbolRemappingReaderTest : public testing::Test {
+public:
+  std::unique_ptr<MemoryBuffer> Buffer;
+  SymbolRemappingReader Reader;
+
+  std::string readWithErrors(StringRef Text, StringRef BufferName) {
+    Buffer = MemoryBuffer::getMemBuffer(Text, BufferName);
+    Error E = Reader.read(*Buffer);
+    EXPECT_TRUE((bool)E);
+    return toString(std::move(E));
+  }
+
+  void read(StringRef Text, StringRef BufferName) {
+    Buffer = MemoryBuffer::getMemBuffer(Text, BufferName);
+    Error E = Reader.read(*Buffer);
+    EXPECT_FALSE((bool)E);
+  }
+};
+} // unnamed namespace
+
+TEST_F(SymbolRemappingReaderTest, ParseErrors) {
+  EXPECT_EQ(readWithErrors("error", "foo.map"),
+            "foo.map:1: Expected 'kind mangled_name mangled_name', "
+            "found 'error'");
+
+  EXPECT_EQ(readWithErrors("error m1 m2", "foo.map"),
+            "foo.map:1: Invalid kind, expected 'name', 'type', or 'encoding', "
+            "found 'error'");
+}
+
+TEST_F(SymbolRemappingReaderTest, DemanglingErrors) {
+  EXPECT_EQ(readWithErrors("type i banana", "foo.map"),
+            "foo.map:1: Could not demangle 'banana' as a <type>; "
+            "invalid mangling?");
+  EXPECT_EQ(readWithErrors("name i 1X", "foo.map"),
+            "foo.map:1: Could not demangle 'i' as a <name>; "
+            "invalid mangling?");
+  EXPECT_EQ(readWithErrors("name 1X 1fv", "foo.map"),
+            "foo.map:1: Could not demangle '1fv' as a <name>; "
+            "invalid mangling?");
+  EXPECT_EQ(readWithErrors("encoding 1fv 1f1gE", "foo.map"),
+            "foo.map:1: Could not demangle '1f1gE' as a <encoding>; "
+            "invalid mangling?");
+}
+
+TEST_F(SymbolRemappingReaderTest, BadMappingOrder) {
+  StringRef Map = R"(
+    # N::foo == M::bar
+    name N1N3fooE N1M3barE
+
+    # N:: == M::
+    name 1N 1M
+  )";
+  EXPECT_EQ(readWithErrors(Map, "foo.map"),
+            "foo.map:6: Manglings '1N' and '1M' have both been used in prior "
+            "remappings. Move this remapping earlier in the file.");
+}
+
+TEST_F(SymbolRemappingReaderTest, RemappingsAdded) {
+  StringRef Map = R"(
+    # A::foo == B::bar
+    name N1A3fooE N1B3barE
+
+    # int == long
+    type i l
+
+    # void f<int>() = void g<int>()
+    encoding 1fIiEvv 1gIiEvv
+  )";
+
+  read(Map, "foo.map");
+  auto Key = Reader.insert("_ZN1B3bar3bazIiEEvv");
+  EXPECT_NE(Key, SymbolRemappingReader::Key());
+  EXPECT_EQ(Key, Reader.lookup("_ZN1A3foo3bazIlEEvv"));
+  EXPECT_NE(Key, Reader.lookup("_ZN1C3foo3bazIlEEvv"));
+
+  Key = Reader.insert("_Z1fIiEvv");
+  EXPECT_NE(Key, SymbolRemappingReader::Key());
+  EXPECT_EQ(Key, Reader.lookup("_Z1gIlEvv"));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp b/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
new file mode 100644
index 0000000..901dd90
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TarWriterTest.cpp
@@ -0,0 +1,179 @@
+//===- llvm/unittest/Support/TarWriterTest.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/TarWriter.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+#include <vector>
+
+using namespace llvm;
+namespace {
+
+struct UstarHeader {
+  char Name[100];
+  char Mode[8];
+  char Uid[8];
+  char Gid[8];
+  char Size[12];
+  char Mtime[12];
+  char Checksum[8];
+  char TypeFlag;
+  char Linkname[100];
+  char Magic[6];
+  char Version[2];
+  char Uname[32];
+  char Gname[32];
+  char DevMajor[8];
+  char DevMinor[8];
+  char Prefix[155];
+  char Pad[12];
+};
+
+class TarWriterTest : public ::testing::Test {};
+
+static std::vector<uint8_t> createTar(StringRef Base, StringRef Filename) {
+  // Create a temporary file.
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  // Create a tar file.
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, Base);
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append(Filename, "contents");
+  Tar.reset();
+
+  // Read the tar file.
+  ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path);
+  EXPECT_TRUE((bool)MBOrErr);
+  std::unique_ptr<MemoryBuffer> MB = std::move(*MBOrErr);
+  std::vector<uint8_t> Buf((const uint8_t *)MB->getBufferStart(),
+                           (const uint8_t *)MB->getBufferEnd());
+
+  // Windows does not allow us to remove a mmap'ed files, so
+  // unmap first and then remove the temporary file.
+  MB = nullptr;
+  sys::fs::remove(Path);
+
+  return Buf;
+}
+
+static UstarHeader createUstar(StringRef Base, StringRef Filename) {
+  std::vector<uint8_t> Buf = createTar(Base, Filename);
+  EXPECT_TRUE(Buf.size() >= sizeof(UstarHeader));
+  return *reinterpret_cast<const UstarHeader *>(Buf.data());
+}
+
+TEST_F(TarWriterTest, Basics) {
+  UstarHeader Hdr = createUstar("base", "file");
+  EXPECT_EQ("ustar", StringRef(Hdr.Magic));
+  EXPECT_EQ("00", StringRef(Hdr.Version, 2));
+  EXPECT_EQ("base/file", StringRef(Hdr.Name));
+  EXPECT_EQ("00000000010", StringRef(Hdr.Size));
+}
+
+TEST_F(TarWriterTest, LongFilename) {
+  std::string x154(154, 'x');
+  std::string x155(155, 'x');
+  std::string y99(99, 'y');
+  std::string y100(100, 'y');
+
+  UstarHeader Hdr1 = createUstar("", x154 + "/" + y99);
+  EXPECT_EQ("/" + x154, StringRef(Hdr1.Prefix));
+  EXPECT_EQ(y99, StringRef(Hdr1.Name));
+
+  UstarHeader Hdr2 = createUstar("", x155 + "/" + y99);
+  EXPECT_EQ("", StringRef(Hdr2.Prefix));
+  EXPECT_EQ("", StringRef(Hdr2.Name));
+
+  UstarHeader Hdr3 = createUstar("", x154 + "/" + y100);
+  EXPECT_EQ("", StringRef(Hdr3.Prefix));
+  EXPECT_EQ("", StringRef(Hdr3.Name));
+
+  UstarHeader Hdr4 = createUstar("", x155 + "/" + y100);
+  EXPECT_EQ("", StringRef(Hdr4.Prefix));
+  EXPECT_EQ("", StringRef(Hdr4.Name));
+
+  std::string yz = "yyyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzz";
+  UstarHeader Hdr5 = createUstar("", x154 + "/" + yz);
+  EXPECT_EQ("/" + x154, StringRef(Hdr5.Prefix));
+  EXPECT_EQ(yz, StringRef(Hdr5.Name));
+}
+
+TEST_F(TarWriterTest, Pax) {
+  std::vector<uint8_t> Buf = createTar("", std::string(200, 'x'));
+  EXPECT_TRUE(Buf.size() >= 1024);
+
+  auto *Hdr = reinterpret_cast<const UstarHeader *>(Buf.data());
+  EXPECT_EQ("", StringRef(Hdr->Prefix));
+  EXPECT_EQ("", StringRef(Hdr->Name));
+
+  StringRef Pax = StringRef((char *)(Buf.data() + 512), 512);
+  EXPECT_TRUE(Pax.startswith("211 path=/" + std::string(200, 'x')));
+}
+
+TEST_F(TarWriterTest, SingleFile) {
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append("FooPath", "foo");
+  Tar.reset();
+
+  uint64_t TarSize;
+  EC = sys::fs::file_size(Path, TarSize);
+  EXPECT_FALSE((bool)EC);
+  EXPECT_EQ(TarSize, 2048ULL);
+}
+
+TEST_F(TarWriterTest, NoDuplicate) {
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append("FooPath", "foo");
+  Tar->append("BarPath", "bar");
+  Tar.reset();
+
+  uint64_t TarSize;
+  EC = sys::fs::file_size(Path, TarSize);
+  EXPECT_FALSE((bool)EC);
+  EXPECT_EQ(TarSize, 3072ULL);
+}
+
+TEST_F(TarWriterTest, Duplicate) {
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append("FooPath", "foo");
+  Tar->append("FooPath", "bar");
+  Tar.reset();
+
+  uint64_t TarSize;
+  EC = sys::fs::file_size(Path, TarSize);
+  EXPECT_FALSE((bool)EC);
+  EXPECT_EQ(TarSize, 2048ULL);
+}
+} // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
new file mode 100644
index 0000000..18bbb6a
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
@@ -0,0 +1,1015 @@
+//===----------- TargetParser.cpp - Target Parser -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TargetParser.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ARMBuildAttributes.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+
+namespace {
+const char *ARMArch[] = {
+    "armv2",       "armv2a",       "armv3",       "armv3m",       "armv4",
+    "armv4t",      "armv5",        "armv5t",      "armv5e",       "armv5te",
+    "armv5tej",    "armv6",        "armv6j",      "armv6k",       "armv6hl",
+    "armv6t2",     "armv6kz",      "armv6z",      "armv6zk",      "armv6-m",
+    "armv6m",      "armv6sm",      "armv6s-m",    "armv7-a",      "armv7",
+    "armv7a",      "armv7ve",      "armv7hl",     "armv7l",       "armv7-r",
+    "armv7r",      "armv7-m",      "armv7m",      "armv7k",       "armv7s",
+    "armv7e-m",    "armv7em",      "armv8-a",     "armv8",        "armv8a",
+    "armv8l",      "armv8.1-a",    "armv8.1a",    "armv8.2-a",    "armv8.2a",
+    "armv8.3-a",   "armv8.3a",     "armv8.4-a",   "armv8.4a",     "armv8.5-a",
+    "armv8.5a",     "armv8-r",     "armv8r",      "armv8-m.base", "armv8m.base",
+    "armv8-m.main", "armv8m.main", "iwmmxt",      "iwmmxt2",      "xscale"
+};
+
+bool testARMCPU(StringRef CPUName, StringRef ExpectedArch,
+                StringRef ExpectedFPU, unsigned ExpectedFlags,
+                StringRef CPUAttr) {
+  ARM::ArchKind AK = ARM::parseCPUArch(CPUName);
+  bool pass = ARM::getArchName(AK).equals(ExpectedArch);
+  unsigned FPUKind = ARM::getDefaultFPU(CPUName, AK);
+  pass &= ARM::getFPUName(FPUKind).equals(ExpectedFPU);
+
+  unsigned ExtKind = ARM::getDefaultExtensions(CPUName, AK);
+  if (ExtKind > 1 && (ExtKind & ARM::AEK_NONE))
+    pass &= ((ExtKind ^ ARM::AEK_NONE) == ExpectedFlags);
+  else
+    pass &= (ExtKind == ExpectedFlags);
+
+  pass &= ARM::getCPUAttr(AK).equals(CPUAttr);
+
+  return pass;
+}
+
+TEST(TargetParserTest, testARMCPU) {
+  EXPECT_TRUE(testARMCPU("invalid", "invalid", "invalid",
+                         ARM::AEK_NONE, ""));
+  EXPECT_TRUE(testARMCPU("generic", "invalid", "none",
+                         ARM::AEK_NONE, ""));
+
+  EXPECT_TRUE(testARMCPU("arm2", "armv2", "none",
+                         ARM::AEK_NONE, "2"));
+  EXPECT_TRUE(testARMCPU("arm3", "armv2a", "none",
+                         ARM::AEK_NONE, "2A"));
+  EXPECT_TRUE(testARMCPU("arm6", "armv3", "none",
+                         ARM::AEK_NONE, "3"));
+  EXPECT_TRUE(testARMCPU("arm7m", "armv3m", "none",
+                         ARM::AEK_NONE, "3M"));
+  EXPECT_TRUE(testARMCPU("arm8", "armv4", "none",
+                         ARM::AEK_NONE, "4"));
+  EXPECT_TRUE(testARMCPU("arm810", "armv4", "none",
+                         ARM::AEK_NONE, "4"));
+  EXPECT_TRUE(testARMCPU("strongarm", "armv4", "none",
+                         ARM::AEK_NONE, "4"));
+  EXPECT_TRUE(testARMCPU("strongarm110", "armv4", "none",
+                         ARM::AEK_NONE, "4"));
+  EXPECT_TRUE(testARMCPU("strongarm1100", "armv4", "none",
+                         ARM::AEK_NONE, "4"));
+  EXPECT_TRUE(testARMCPU("strongarm1110", "armv4", "none",
+                         ARM::AEK_NONE, "4"));
+  EXPECT_TRUE(testARMCPU("arm7tdmi", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm7tdmi-s", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm710t", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm720t", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm9", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm9tdmi", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm920", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm920t", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm922t", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm9312", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm940t", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("ep9312", "armv4t", "none",
+                         ARM::AEK_NONE, "4T"));
+  EXPECT_TRUE(testARMCPU("arm10tdmi", "armv5t", "none",
+                         ARM::AEK_NONE, "5T"));
+  EXPECT_TRUE(testARMCPU("arm1020t", "armv5t", "none",
+                         ARM::AEK_NONE, "5T"));
+  EXPECT_TRUE(testARMCPU("arm9e", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm946e-s", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm966e-s", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm968e-s", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm10e", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm1020e", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm1022e", "armv5te", "none",
+                         ARM::AEK_DSP, "5TE"));
+  EXPECT_TRUE(testARMCPU("arm926ej-s", "armv5tej", "none",
+                         ARM::AEK_DSP, "5TEJ"));
+  EXPECT_TRUE(testARMCPU("arm1136j-s", "armv6", "none",
+                         ARM::AEK_DSP, "6"));
+  EXPECT_TRUE(testARMCPU("arm1136jf-s", "armv6", "vfpv2",
+                         ARM::AEK_DSP, "6"));
+  EXPECT_TRUE(testARMCPU("arm1136jz-s", "armv6", "none",
+                         ARM::AEK_DSP, "6"));
+  EXPECT_TRUE(testARMCPU("arm1176jz-s", "armv6kz", "none",
+                         ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"));
+  EXPECT_TRUE(testARMCPU("mpcore", "armv6k", "vfpv2",
+                         ARM::AEK_DSP, "6K"));
+  EXPECT_TRUE(testARMCPU("mpcorenovfp", "armv6k", "none",
+                         ARM::AEK_DSP, "6K"));
+  EXPECT_TRUE(testARMCPU("arm1176jzf-s", "armv6kz", "vfpv2",
+                         ARM::AEK_SEC | ARM::AEK_DSP, "6KZ"));
+  EXPECT_TRUE(testARMCPU("arm1156t2-s", "armv6t2", "none",
+                         ARM::AEK_DSP, "6T2"));
+  EXPECT_TRUE(testARMCPU("arm1156t2f-s", "armv6t2", "vfpv2",
+                         ARM::AEK_DSP, "6T2"));
+  EXPECT_TRUE(testARMCPU("cortex-m0", "armv6-m", "none",
+                         ARM::AEK_NONE, "6-M"));
+  EXPECT_TRUE(testARMCPU("cortex-m0plus", "armv6-m", "none",
+                         ARM::AEK_NONE, "6-M"));
+  EXPECT_TRUE(testARMCPU("cortex-m1", "armv6-m", "none",
+                         ARM::AEK_NONE, "6-M"));
+  EXPECT_TRUE(testARMCPU("sc000", "armv6-m", "none",
+                         ARM::AEK_NONE, "6-M"));
+  EXPECT_TRUE(testARMCPU("cortex-a5", "armv7-a", "neon-vfpv4",
+                         ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a7", "armv7-a", "neon-vfpv4",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM | ARM::AEK_MP |
+                             ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_DSP,
+                         "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a8", "armv7-a", "neon",
+                         ARM::AEK_SEC | ARM::AEK_DSP, "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a9", "armv7-a", "neon-fp16",
+                         ARM::AEK_MP | ARM::AEK_SEC | ARM::AEK_DSP, "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a12", "armv7-a", "neon-vfpv4",
+                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a15", "armv7-a", "neon-vfpv4",
+                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a17", "armv7-a", "neon-vfpv4",
+                         ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT |
+                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "7-A"));
+  EXPECT_TRUE(testARMCPU("krait", "armv7-a", "neon-vfpv4",
+                         ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "7-A"));
+  EXPECT_TRUE(testARMCPU("cortex-r4", "armv7-r", "none",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "7-R"));
+  EXPECT_TRUE(testARMCPU("cortex-r4f", "armv7-r", "vfpv3-d16",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "7-R"));
+  EXPECT_TRUE(testARMCPU("cortex-r5", "armv7-r", "vfpv3-d16",
+                         ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "7-R"));
+  EXPECT_TRUE(testARMCPU("cortex-r7", "armv7-r", "vfpv3-d16-fp16",
+                         ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "7-R"));
+  EXPECT_TRUE(testARMCPU("cortex-r8", "armv7-r", "vfpv3-d16-fp16",
+                         ARM::AEK_MP | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "7-R"));
+  EXPECT_TRUE(testARMCPU("cortex-r52", "armv8-r", "neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_MP | ARM::AEK_VIRT |
+                             ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
+                             ARM::AEK_DSP,
+                         "8-R"));
+  EXPECT_TRUE(
+      testARMCPU("sc300", "armv7-m", "none", ARM::AEK_HWDIVTHUMB, "7-M"));
+  EXPECT_TRUE(
+      testARMCPU("cortex-m3", "armv7-m", "none", ARM::AEK_HWDIVTHUMB, "7-M"));
+  EXPECT_TRUE(testARMCPU("cortex-m4", "armv7e-m", "fpv4-sp-d16",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "7E-M"));
+  EXPECT_TRUE(testARMCPU("cortex-m7", "armv7e-m", "fpv5-d16",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "7E-M"));
+  EXPECT_TRUE(testARMCPU("cortex-a32", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+                         ARM::AEK_RAS | ARM::AEK_DOTPROD,
+                         "8.2-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
+                         ARM::AEK_RAS | ARM::AEK_DOTPROD,
+                         "8.2-A"));
+  EXPECT_TRUE(testARMCPU("cyclone", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                             ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                             ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("exynos-m1", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("exynos-m2", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "8-A"));
+  EXPECT_TRUE(testARMCPU("exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
+                         ARM::AEK_CRC | ARM::AEK_SEC | ARM::AEK_MP |
+                         ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_DOTPROD |
+                         ARM::AEK_FP16 | ARM::AEK_RAS,
+                         "8.2-A"));
+  EXPECT_TRUE(testARMCPU("cortex-m23", "armv8-m.base", "none",
+                         ARM::AEK_HWDIVTHUMB, "8-M.Baseline"));
+  EXPECT_TRUE(testARMCPU("cortex-m33", "armv8-m.main", "fpv5-sp-d16",
+                         ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP, "8-M.Mainline"));
+  EXPECT_TRUE(testARMCPU("iwmmxt", "iwmmxt", "none",
+                         ARM::AEK_NONE, "iwmmxt"));
+  EXPECT_TRUE(testARMCPU("xscale", "xscale", "none",
+                         ARM::AEK_NONE, "xscale"));
+  EXPECT_TRUE(testARMCPU("swift", "armv7s", "neon-vfpv4",
+                         ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP,
+                         "7-S"));
+}
+
+static constexpr unsigned NumARMCPUArchs = 82;
+
+TEST(TargetParserTest, testARMCPUArchList) {
+  SmallVector<StringRef, NumARMCPUArchs> List;
+  ARM::fillValidCPUArchList(List);
+
+  // No list exists for these in this test suite, so ensure all are
+  // valid, and match the expected 'magic' count.
+  EXPECT_EQ(List.size(), NumARMCPUArchs);
+  for(StringRef CPU : List) {
+    EXPECT_NE(ARM::parseCPUArch(CPU), ARM::ArchKind::INVALID);
+  }
+}
+
+TEST(TargetParserTest, testInvalidARMArch) {
+  auto InvalidArchStrings = {"armv", "armv99", "noarm"};
+  for (const char* InvalidArch : InvalidArchStrings)
+    EXPECT_EQ(ARM::parseArch(InvalidArch), ARM::ArchKind::INVALID);
+}
+
+bool testARMArch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
+                 unsigned ArchAttr) {
+  ARM::ArchKind AK = ARM::parseArch(Arch);
+  return (AK!= ARM::ArchKind::INVALID) &
+         ARM::getDefaultCPU(Arch).equals(DefaultCPU) &
+         ARM::getSubArch(AK).equals(SubArch) &
+         (ARM::getArchAttr(AK) == ArchAttr);
+}
+
+TEST(TargetParserTest, testARMArch) {
+  EXPECT_TRUE(
+      testARMArch("armv2", "arm2", "v2",
+                          ARMBuildAttrs::CPUArch::Pre_v4));
+  EXPECT_TRUE(
+      testARMArch("armv2a", "arm3", "v2a",
+                          ARMBuildAttrs::CPUArch::Pre_v4));
+  EXPECT_TRUE(
+      testARMArch("armv3", "arm6", "v3",
+                          ARMBuildAttrs::CPUArch::Pre_v4));
+  EXPECT_TRUE(
+      testARMArch("armv3m", "arm7m", "v3m",
+                          ARMBuildAttrs::CPUArch::Pre_v4));
+  EXPECT_TRUE(
+      testARMArch("armv4", "strongarm", "v4",
+                          ARMBuildAttrs::CPUArch::v4));
+  EXPECT_TRUE(
+      testARMArch("armv4t", "arm7tdmi", "v4t",
+                          ARMBuildAttrs::CPUArch::v4T));
+  EXPECT_TRUE(
+      testARMArch("armv5t", "arm10tdmi", "v5",
+                          ARMBuildAttrs::CPUArch::v5T));
+  EXPECT_TRUE(
+      testARMArch("armv5te", "arm1022e", "v5e",
+                          ARMBuildAttrs::CPUArch::v5TE));
+  EXPECT_TRUE(
+      testARMArch("armv5tej", "arm926ej-s", "v5e",
+                          ARMBuildAttrs::CPUArch::v5TEJ));
+  EXPECT_TRUE(
+      testARMArch("armv6", "arm1136jf-s", "v6",
+                          ARMBuildAttrs::CPUArch::v6));
+  EXPECT_TRUE(
+      testARMArch("armv6k", "mpcore", "v6k",
+                          ARMBuildAttrs::CPUArch::v6K));
+  EXPECT_TRUE(
+      testARMArch("armv6t2", "arm1156t2-s", "v6t2",
+                          ARMBuildAttrs::CPUArch::v6T2));
+  EXPECT_TRUE(
+      testARMArch("armv6kz", "arm1176jzf-s", "v6kz",
+                          ARMBuildAttrs::CPUArch::v6KZ));
+  EXPECT_TRUE(
+      testARMArch("armv6-m", "cortex-m0", "v6m",
+                          ARMBuildAttrs::CPUArch::v6_M));
+  EXPECT_TRUE(
+      testARMArch("armv7-a", "generic", "v7",
+                          ARMBuildAttrs::CPUArch::v7));
+  EXPECT_TRUE(
+      testARMArch("armv7ve", "generic", "v7ve",
+                          ARMBuildAttrs::CPUArch::v7));
+  EXPECT_TRUE(
+      testARMArch("armv7-r", "cortex-r4", "v7r",
+                          ARMBuildAttrs::CPUArch::v7));
+  EXPECT_TRUE(
+      testARMArch("armv7-m", "cortex-m3", "v7m",
+                          ARMBuildAttrs::CPUArch::v7));
+  EXPECT_TRUE(
+      testARMArch("armv7e-m", "cortex-m4", "v7em",
+                          ARMBuildAttrs::CPUArch::v7E_M));
+  EXPECT_TRUE(
+      testARMArch("armv8-a", "generic", "v8",
+                          ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(
+      testARMArch("armv8.1-a", "generic", "v8.1a",
+                          ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(
+      testARMArch("armv8.2-a", "generic", "v8.2a",
+                          ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(
+      testARMArch("armv8.3-a", "generic", "v8.3a",
+                          ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(
+      testARMArch("armv8.4-a", "generic", "v8.4a",
+                          ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(
+      testARMArch("armv8.5-a", "generic", "v8.5a",
+                          ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(
+      testARMArch("armv8-r", "cortex-r52", "v8r",
+                          ARMBuildAttrs::CPUArch::v8_R));
+  EXPECT_TRUE(
+      testARMArch("armv8-m.base", "generic", "v8m.base",
+                          ARMBuildAttrs::CPUArch::v8_M_Base));
+  EXPECT_TRUE(
+      testARMArch("armv8-m.main", "generic", "v8m.main",
+                          ARMBuildAttrs::CPUArch::v8_M_Main));
+  EXPECT_TRUE(
+      testARMArch("iwmmxt", "iwmmxt", "",
+                          ARMBuildAttrs::CPUArch::v5TE));
+  EXPECT_TRUE(
+      testARMArch("iwmmxt2", "generic", "",
+                          ARMBuildAttrs::CPUArch::v5TE));
+  EXPECT_TRUE(
+      testARMArch("xscale", "xscale", "v5e",
+                          ARMBuildAttrs::CPUArch::v5TE));
+  EXPECT_TRUE(
+      testARMArch("armv7s", "swift", "v7s",
+                          ARMBuildAttrs::CPUArch::v7));
+  EXPECT_TRUE(
+      testARMArch("armv7k", "generic", "v7k",
+                          ARMBuildAttrs::CPUArch::v7));
+}
+
+bool testARMExtension(StringRef CPUName,ARM::ArchKind ArchKind, StringRef ArchExt) {
+  return ARM::getDefaultExtensions(CPUName, ArchKind) &
+         ARM::parseArchExt(ArchExt);
+}
+
+TEST(TargetParserTest, testARMExtension) {
+  EXPECT_FALSE(testARMExtension("arm2", ARM::ArchKind::INVALID, "thumb"));
+  EXPECT_FALSE(testARMExtension("arm3", ARM::ArchKind::INVALID, "thumb"));
+  EXPECT_FALSE(testARMExtension("arm6", ARM::ArchKind::INVALID, "thumb"));
+  EXPECT_FALSE(testARMExtension("arm7m", ARM::ArchKind::INVALID, "thumb"));
+  EXPECT_FALSE(testARMExtension("strongarm", ARM::ArchKind::INVALID, "dsp"));
+  EXPECT_FALSE(testARMExtension("arm7tdmi", ARM::ArchKind::INVALID, "dsp"));
+  EXPECT_FALSE(testARMExtension("arm10tdmi",
+                                ARM::ArchKind::INVALID, "simd"));
+  EXPECT_FALSE(testARMExtension("arm1022e", ARM::ArchKind::INVALID, "simd"));
+  EXPECT_FALSE(testARMExtension("arm926ej-s",
+                                ARM::ArchKind::INVALID, "simd"));
+  EXPECT_FALSE(testARMExtension("arm1136jf-s",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("arm1176j-s",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("arm1156t2-s",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("arm1176jzf-s",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("cortex-m0",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("cortex-a8",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("cortex-r4",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("cortex-m3",
+                                ARM::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testARMExtension("cortex-a53",
+                                ARM::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testARMExtension("cortex-a53",
+                                ARM::ArchKind::INVALID, "fp16"));
+  EXPECT_TRUE(testARMExtension("cortex-a55",
+                                ARM::ArchKind::INVALID, "fp16"));
+  EXPECT_FALSE(testARMExtension("cortex-a55",
+                                ARM::ArchKind::INVALID, "fp16fml"));
+  EXPECT_TRUE(testARMExtension("cortex-a75",
+                                ARM::ArchKind::INVALID, "fp16"));
+  EXPECT_FALSE(testARMExtension("cortex-a75",
+                                ARM::ArchKind::INVALID, "fp16fml"));
+  EXPECT_FALSE(testARMExtension("cortex-r52",
+                                ARM::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testARMExtension("iwmmxt", ARM::ArchKind::INVALID, "crc"));
+  EXPECT_FALSE(testARMExtension("xscale", ARM::ArchKind::INVALID, "crc"));
+  EXPECT_FALSE(testARMExtension("swift", ARM::ArchKind::INVALID, "crc"));
+
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV2, "thumb"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV2A, "thumb"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV3, "thumb"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV3M, "thumb"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4, "dsp"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV4T, "dsp"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5T, "simd"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TE, "simd"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV5TEJ, "simd"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6K, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic",
+                                ARM::ArchKind::ARMV6T2, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic",
+                                ARM::ArchKind::ARMV6KZ, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV6M, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7A, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7R, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7M, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic",
+                                ARM::ArchKind::ARMV7EM, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8A, "ras"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_1A, "ras"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "profile"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_2A, "fp16fml"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_3A, "fp16fml"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8_4A, "fp16fml"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV8R, "ras"));
+  EXPECT_FALSE(testARMExtension("generic",
+                                ARM::ArchKind::ARMV8MBaseline, "crc"));
+  EXPECT_FALSE(testARMExtension("generic",
+                                ARM::ArchKind::ARMV8MMainline, "crc"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT, "crc"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::IWMMXT2, "crc"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::XSCALE, "crc"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7S, "crypto"));
+  EXPECT_FALSE(testARMExtension("generic", ARM::ArchKind::ARMV7K, "crypto"));
+}
+
+TEST(TargetParserTest, ARMFPUVersion) {
+  for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
+       FK <= ARM::FPUKind::FK_LAST;
+       FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
+    if (FK == ARM::FK_LAST || ARM::getFPUName(FK) == "invalid" ||
+        ARM::getFPUName(FK) == "none" || ARM::getFPUName(FK) == "softvfp")
+      EXPECT_EQ(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
+    else
+      EXPECT_NE(ARM::FPUVersion::NONE, ARM::getFPUVersion(FK));
+}
+
+TEST(TargetParserTest, ARMFPUNeonSupportLevel) {
+  for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
+       FK <= ARM::FPUKind::FK_LAST;
+       FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
+    if (FK == ARM::FK_LAST ||
+        ARM::getFPUName(FK).find("neon") == std::string::npos)
+      EXPECT_EQ(ARM::NeonSupportLevel::None,
+                 ARM::getFPUNeonSupportLevel(FK));
+    else
+      EXPECT_NE(ARM::NeonSupportLevel::None,
+                ARM::getFPUNeonSupportLevel(FK));
+}
+
+TEST(TargetParserTest, ARMFPURestriction) {
+  for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
+       FK <= ARM::FPUKind::FK_LAST;
+       FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1)) {
+    if (FK == ARM::FK_LAST ||
+        (ARM::getFPUName(FK).find("d16") == std::string::npos &&
+         ARM::getFPUName(FK).find("vfpv3xd") == std::string::npos))
+      EXPECT_EQ(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
+    else
+      EXPECT_NE(ARM::FPURestriction::None, ARM::getFPURestriction(FK));
+  }
+}
+
+TEST(TargetParserTest, ARMExtensionFeatures) {
+  std::vector<StringRef> Features;
+  unsigned Extensions = ARM::AEK_CRC | ARM::AEK_CRYPTO | ARM::AEK_DSP |
+                        ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB | ARM::AEK_MP |
+                        ARM::AEK_SEC | ARM::AEK_VIRT | ARM::AEK_RAS | ARM::AEK_FP16 |
+                        ARM::AEK_FP16FML;
+
+  for (unsigned i = 0; i <= Extensions; i++)
+    EXPECT_TRUE(i == 0 ? !ARM::getExtensionFeatures(i, Features)
+                       : ARM::getExtensionFeatures(i, Features));
+}
+
+TEST(TargetParserTest, ARMFPUFeatures) {
+  std::vector<StringRef> Features;
+  for (ARM::FPUKind FK = static_cast<ARM::FPUKind>(0);
+       FK <= ARM::FPUKind::FK_LAST;
+       FK = static_cast<ARM::FPUKind>(static_cast<unsigned>(FK) + 1))
+    EXPECT_TRUE((FK == ARM::FK_INVALID || FK >= ARM::FK_LAST)
+                    ? !ARM::getFPUFeatures(FK, Features)
+                    : ARM::getFPUFeatures(FK, Features));
+}
+
+TEST(TargetParserTest, ARMArchExtFeature) {
+  const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},
+                              {"crypto", "nocrypto", "+crypto", "-crypto"},
+                              {"dsp", "nodsp", "+dsp", "-dsp"},
+                              {"fp", "nofp", nullptr, nullptr},
+                              {"idiv", "noidiv", nullptr, nullptr},
+                              {"mp", "nomp", nullptr, nullptr},
+                              {"simd", "nosimd", nullptr, nullptr},
+                              {"sec", "nosec", nullptr, nullptr},
+                              {"virt", "novirt", nullptr, nullptr},
+                              {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
+                              {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
+                              {"ras", "noras", "+ras", "-ras"},
+                              {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
+                              {"os", "noos", nullptr, nullptr},
+                              {"iwmmxt", "noiwmmxt", nullptr, nullptr},
+                              {"iwmmxt2", "noiwmmxt2", nullptr, nullptr},
+                              {"maverick", "maverick", nullptr, nullptr},
+                              {"xscale", "noxscale", nullptr, nullptr},
+                              {"sb", "nosb", "+sb", "-sb"}};
+
+  for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
+    EXPECT_EQ(StringRef(ArchExt[i][2]), ARM::getArchExtFeature(ArchExt[i][0]));
+    EXPECT_EQ(StringRef(ArchExt[i][3]), ARM::getArchExtFeature(ArchExt[i][1]));
+  }
+}
+
+TEST(TargetParserTest, ARMparseHWDiv) {
+  const char *hwdiv[] = {"thumb", "arm", "arm,thumb", "thumb,arm"};
+
+  for (unsigned i = 0; i < array_lengthof(hwdiv); i++)
+    EXPECT_NE(ARM::AEK_INVALID, ARM::parseHWDiv((StringRef)hwdiv[i]));
+}
+
+TEST(TargetParserTest, ARMparseArchEndianAndISA) {
+  const char *Arch[] = {
+      "v2",   "v2a",    "v3",    "v3m",    "v4",    "v4t",    "v5",    "v5t",
+      "v5e",  "v5te",   "v5tej", "v6",     "v6j",   "v6k",    "v6hl",  "v6t2",
+      "v6kz", "v6z",    "v6zk",  "v6-m",   "v6m",   "v6sm",   "v6s-m", "v7-a",
+      "v7",   "v7a",    "v7ve",  "v7hl",   "v7l",   "v7-r",   "v7r",   "v7-m",
+      "v7m",  "v7k",    "v7s",   "v7e-m",  "v7em",  "v8-a",   "v8",    "v8a",
+      "v8l",  "v8.1-a", "v8.1a", "v8.2-a", "v8.2a", "v8.3-a", "v8.3a", "v8.4-a",
+      "v8.4a", "v8.5-a","v8.5a", "v8-r"
+  };
+
+  for (unsigned i = 0; i < array_lengthof(Arch); i++) {
+    std::string arm_1 = "armeb" + (std::string)(Arch[i]);
+    std::string arm_2 = "arm" + (std::string)(Arch[i]) + "eb";
+    std::string arm_3 = "arm" + (std::string)(Arch[i]);
+    std::string thumb_1 = "thumbeb" + (std::string)(Arch[i]);
+    std::string thumb_2 = "thumb" + (std::string)(Arch[i]) + "eb";
+    std::string thumb_3 = "thumb" + (std::string)(Arch[i]);
+
+    EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_1));
+    EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(arm_2));
+    EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(arm_3));
+
+    EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_1));
+    EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_2));
+    EXPECT_EQ(ARM::ISAKind::ARM, ARM::parseArchISA(arm_3));
+    if (i >= 4) {
+      EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_1));
+      EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian(thumb_2));
+      EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian(thumb_3));
+
+      EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_1));
+      EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_2));
+      EXPECT_EQ(ARM::ISAKind::THUMB, ARM::parseArchISA(thumb_3));
+    }
+  }
+
+  EXPECT_EQ(ARM::EndianKind::LITTLE, ARM::parseArchEndian("aarch64"));
+  EXPECT_EQ(ARM::EndianKind::BIG, ARM::parseArchEndian("aarch64_be"));
+
+  EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64"));
+  EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("aarch64_be"));
+  EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64"));
+  EXPECT_EQ(ARM::ISAKind::AARCH64, ARM::parseArchISA("arm64_be"));
+}
+
+TEST(TargetParserTest, ARMparseArchProfile) {
+  for (unsigned i = 0; i < array_lengthof(ARMArch); i++) {
+    switch (ARM::parseArch(ARMArch[i])) {
+    case ARM::ArchKind::ARMV6M:
+    case ARM::ArchKind::ARMV7M:
+    case ARM::ArchKind::ARMV7EM:
+    case ARM::ArchKind::ARMV8MMainline:
+    case ARM::ArchKind::ARMV8MBaseline:
+      EXPECT_EQ(ARM::ProfileKind::M, ARM::parseArchProfile(ARMArch[i]));
+      break;
+    case ARM::ArchKind::ARMV7R:
+    case ARM::ArchKind::ARMV8R:
+      EXPECT_EQ(ARM::ProfileKind::R, ARM::parseArchProfile(ARMArch[i]));
+      break;
+    case ARM::ArchKind::ARMV7A:
+    case ARM::ArchKind::ARMV7VE:
+    case ARM::ArchKind::ARMV7K:
+    case ARM::ArchKind::ARMV8A:
+    case ARM::ArchKind::ARMV8_1A:
+    case ARM::ArchKind::ARMV8_2A:
+    case ARM::ArchKind::ARMV8_3A:
+    case ARM::ArchKind::ARMV8_4A:
+    case ARM::ArchKind::ARMV8_5A:
+      EXPECT_EQ(ARM::ProfileKind::A, ARM::parseArchProfile(ARMArch[i]));
+      break;
+    default:
+      EXPECT_EQ(ARM::ProfileKind::INVALID, ARM::parseArchProfile(ARMArch[i]));
+      break;
+    }
+  }
+}
+
+TEST(TargetParserTest, ARMparseArchVersion) {
+  for (unsigned i = 0; i < array_lengthof(ARMArch); i++)
+    if (((std::string)ARMArch[i]).substr(0, 4) == "armv")
+      EXPECT_EQ((ARMArch[i][4] - 48u), ARM::parseArchVersion(ARMArch[i]));
+    else
+      EXPECT_EQ(5u, ARM::parseArchVersion(ARMArch[i]));
+}
+
+bool testAArch64CPU(StringRef CPUName, StringRef ExpectedArch,
+                    StringRef ExpectedFPU, unsigned ExpectedFlags,
+                    StringRef CPUAttr) {
+  AArch64::ArchKind AK = AArch64::parseCPUArch(CPUName);
+  bool pass = AArch64::getArchName(AK).equals(ExpectedArch);
+
+  unsigned ExtKind = AArch64::getDefaultExtensions(CPUName, AK);
+  if (ExtKind > 1 && (ExtKind & AArch64::AEK_NONE))
+    pass &= ((ExtKind ^ AArch64::AEK_NONE) == ExpectedFlags);
+  else
+    pass &= (ExtKind == ExpectedFlags);
+
+  pass &= AArch64::getCPUAttr(AK).equals(CPUAttr);
+
+  return pass;
+}
+
+TEST(TargetParserTest, testAArch64CPU) {
+  EXPECT_TRUE(testAArch64CPU(
+      "invalid", "invalid", "invalid",
+      AArch64::AEK_NONE, ""));
+  EXPECT_TRUE(testAArch64CPU(
+      "generic", "invalid", "none",
+      AArch64::AEK_NONE, ""));
+
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a35", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a53", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a55", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+      AArch64::AEK_RDM | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+      AArch64::AEK_RCPC, "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a57", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a72", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a73", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a75", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+      AArch64::AEK_RDM | AArch64::AEK_FP16 | AArch64::AEK_DOTPROD |
+      AArch64::AEK_RCPC, "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cyclone", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "exynos-m1", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "exynos-m2", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "exynos-m4", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
+      AArch64::AEK_DOTPROD | AArch64::AEK_FP | AArch64::AEK_FP16 |
+      AArch64::AEK_LSE | AArch64::AEK_RAS | AArch64::AEK_RDM |
+      AArch64::AEK_SIMD, "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "falkor", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD | AArch64::AEK_RDM, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "kryo", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "thunderx2t99", "armv8.1-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_LSE |
+      AArch64::AEK_RDM | AArch64::AEK_FP | AArch64::AEK_SIMD, "8.1-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "thunderx", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_SIMD |
+      AArch64::AEK_FP | AArch64::AEK_PROFILE,
+      "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "thunderxt81", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_SIMD |
+      AArch64::AEK_FP | AArch64::AEK_PROFILE,
+      "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "thunderxt83", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_SIMD |
+      AArch64::AEK_FP | AArch64::AEK_PROFILE,
+      "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "thunderxt88", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_SIMD |
+      AArch64::AEK_FP | AArch64::AEK_PROFILE,
+      "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "tsv110", "armv8.2-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+      AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+      AArch64::AEK_RDM | AArch64::AEK_PROFILE | AArch64::AEK_FP16 |
+      AArch64::AEK_FP16FML | AArch64::AEK_DOTPROD,
+      "8.2-A"));
+}
+
+static constexpr unsigned NumAArch64CPUArchs = 21;
+
+TEST(TargetParserTest, testAArch64CPUArchList) {
+  SmallVector<StringRef, NumAArch64CPUArchs> List;
+  AArch64::fillValidCPUArchList(List);
+
+  // No list exists for these in this test suite, so ensure all are
+  // valid, and match the expected 'magic' count.
+  EXPECT_EQ(List.size(), NumAArch64CPUArchs);
+  for(StringRef CPU : List) {
+    EXPECT_NE(AArch64::parseCPUArch(CPU), AArch64::ArchKind::INVALID);
+  }
+}
+
+bool testAArch64Arch(StringRef Arch, StringRef DefaultCPU, StringRef SubArch,
+                     unsigned ArchAttr) {
+  AArch64::ArchKind AK = AArch64::parseArch(Arch);
+  return (AK != AArch64::ArchKind::INVALID) &
+         AArch64::getDefaultCPU(Arch).equals(DefaultCPU) &
+         AArch64::getSubArch(AK).equals(SubArch) &
+         (AArch64::getArchAttr(AK) == ArchAttr);
+}
+
+TEST(TargetParserTest, testAArch64Arch) {
+  EXPECT_TRUE(testAArch64Arch("armv8-a", "cortex-a53", "v8",
+                              ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(testAArch64Arch("armv8.1-a", "generic", "v8.1a",
+                              ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(testAArch64Arch("armv8.2-a", "generic", "v8.2a",
+                              ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(testAArch64Arch("armv8.3-a", "generic", "v8.3a",
+                              ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(testAArch64Arch("armv8.4-a", "generic", "v8.4a",
+                              ARMBuildAttrs::CPUArch::v8_A));
+  EXPECT_TRUE(testAArch64Arch("armv8.5-a", "generic", "v8.5a",
+                              ARMBuildAttrs::CPUArch::v8_A));
+}
+
+bool testAArch64Extension(StringRef CPUName, AArch64::ArchKind AK,
+                          StringRef ArchExt) {
+  return AArch64::getDefaultExtensions(CPUName, AK) &
+         AArch64::parseArchExt(ArchExt);
+}
+
+TEST(TargetParserTest, testAArch64Extension) {
+  EXPECT_FALSE(testAArch64Extension("cortex-a35",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a53",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a55",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a57",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a72",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a73",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a75",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("cyclone",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("exynos-m1",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("exynos-m2",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("exynos-m3",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "rdm"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("exynos-m4",
+                                    AArch64::ArchKind::INVALID, "fullfp16"));
+  EXPECT_TRUE(testAArch64Extension("exynos-m4",
+                                   AArch64::ArchKind::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("falkor",
+                                   AArch64::ArchKind::INVALID, "rdm"));
+  EXPECT_FALSE(testAArch64Extension("kryo",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("saphira",
+                                    AArch64::ArchKind::INVALID, "crc"));
+  EXPECT_TRUE(testAArch64Extension("saphira",
+                                    AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("saphira",
+                                   AArch64::ArchKind::INVALID, "rdm"));
+  EXPECT_TRUE(testAArch64Extension("saphira",
+                                   AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("saphira",
+                                   AArch64::ArchKind::INVALID, "rcpc"));
+  EXPECT_TRUE(testAArch64Extension("saphira",
+                                   AArch64::ArchKind::INVALID, "profile"));
+  EXPECT_FALSE(testAArch64Extension("saphira",
+                                    AArch64::ArchKind::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a55",
+                                    AArch64::ArchKind::INVALID, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a55",
+                                    AArch64::ArchKind::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a55",
+                                    AArch64::ArchKind::INVALID, "dotprod"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a75",
+                                    AArch64::ArchKind::INVALID, "fp16"));
+  EXPECT_FALSE(testAArch64Extension("cortex-a75",
+                                    AArch64::ArchKind::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("cortex-a75",
+                                    AArch64::ArchKind::INVALID, "dotprod"));
+  EXPECT_FALSE(testAArch64Extension("thunderx2t99",
+                                    AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_FALSE(testAArch64Extension("thunderx",
+                                    AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("thunderxt81",
+                                    AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("thunderxt83",
+                                    AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_FALSE(testAArch64Extension("thunderxt88",
+                                    AArch64::ArchKind::INVALID, "lse"));
+  EXPECT_TRUE(testAArch64Extension("tsv110",
+                                   AArch64::ArchKind::INVALID, "crypto"));
+  EXPECT_FALSE(testAArch64Extension("tsv110",
+                                    AArch64::ArchKind::INVALID, "sha3"));
+  EXPECT_FALSE(testAArch64Extension("tsv110",
+                                    AArch64::ArchKind::INVALID, "sm4"));
+  EXPECT_TRUE(testAArch64Extension("tsv110",
+                                   AArch64::ArchKind::INVALID, "ras"));
+  EXPECT_TRUE(testAArch64Extension("tsv110",
+                                   AArch64::ArchKind::INVALID, "profile"));
+  EXPECT_TRUE(testAArch64Extension("tsv110",
+                                   AArch64::ArchKind::INVALID, "fp16"));
+  EXPECT_TRUE(testAArch64Extension("tsv110",
+                                   AArch64::ArchKind::INVALID, "fp16fml"));
+  EXPECT_TRUE(testAArch64Extension("tsv110",
+                                   AArch64::ArchKind::INVALID, "dotprod"));
+
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8A, "ras"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_1A, "ras"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_2A, "profile"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_2A, "fp16"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_2A, "fp16fml"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_3A, "fp16"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_3A, "fp16fml"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_4A, "fp16"));
+  EXPECT_FALSE(testAArch64Extension(
+      "generic", AArch64::ArchKind::ARMV8_4A, "fp16fml"));
+}
+
+TEST(TargetParserTest, AArch64ExtensionFeatures) {
+  std::vector<StringRef> Features;
+  unsigned Extensions = AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
+                        AArch64::AEK_FP | AArch64::AEK_SIMD |
+                        AArch64::AEK_FP16 | AArch64::AEK_PROFILE |
+                        AArch64::AEK_RAS | AArch64::AEK_LSE |
+                        AArch64::AEK_RDM | AArch64::AEK_SVE |
+                        AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
+                        AArch64::AEK_FP16FML;
+
+  for (unsigned i = 0; i <= Extensions; i++)
+    EXPECT_TRUE(i == 0 ? !AArch64::getExtensionFeatures(i, Features)
+                       : AArch64::getExtensionFeatures(i, Features));
+}
+
+TEST(TargetParserTest, AArch64ArchFeatures) {
+  std::vector<StringRef> Features;
+
+  for (auto AK : AArch64::ArchKinds)
+    EXPECT_TRUE((AK == AArch64::ArchKind::INVALID)
+                    ? !AArch64::getArchFeatures(AK, Features)
+                    : AArch64::getArchFeatures(AK, Features));
+}
+
+TEST(TargetParserTest, AArch64ArchExtFeature) {
+  const char *ArchExt[][4] = {{"crc", "nocrc", "+crc", "-crc"},
+                              {"crypto", "nocrypto", "+crypto", "-crypto"},
+                              {"fp", "nofp", "+fp-armv8", "-fp-armv8"},
+                              {"simd", "nosimd", "+neon", "-neon"},
+                              {"fp16", "nofp16", "+fullfp16", "-fullfp16"},
+                              {"fp16fml", "nofp16fml", "+fp16fml", "-fp16fml"},
+                              {"profile", "noprofile", "+spe", "-spe"},
+                              {"ras", "noras", "+ras", "-ras"},
+                              {"lse", "nolse", "+lse", "-lse"},
+                              {"rdm", "nordm", "+rdm", "-rdm"},
+                              {"sve", "nosve", "+sve", "-sve"},
+                              {"dotprod", "nodotprod", "+dotprod", "-dotprod"},
+                              {"rcpc", "norcpc", "+rcpc", "-rcpc" },
+                              {"rng", "norng", "+rand", "-rand"},
+                              {"memtag", "nomemtag", "+mte", "-mte"},
+                              {"ssbs", "nossbs", "+ssbs", "-ssbs"},
+                              {"sb", "nosb", "+sb", "-sb"},
+                              {"predres", "nopredres", "+predres", "-predres"}
+};
+
+  for (unsigned i = 0; i < array_lengthof(ArchExt); i++) {
+    EXPECT_EQ(StringRef(ArchExt[i][2]),
+              AArch64::getArchExtFeature(ArchExt[i][0]));
+    EXPECT_EQ(StringRef(ArchExt[i][3]),
+              AArch64::getArchExtFeature(ArchExt[i][1]));
+  }
+}
+}
diff --git a/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp b/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
new file mode 100644
index 0000000..14ca9c0
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TaskQueueTest.cpp
@@ -0,0 +1,108 @@
+//========- unittests/Support/TaskQueue.cpp - TaskQueue.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/Config/llvm-config.h"
+
+#if LLVM_ENABLE_THREADS
+
+#include "llvm/Support/TaskQueue.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class TaskQueueTest : public testing::Test {
+protected:
+  TaskQueueTest() {}
+};
+
+TEST_F(TaskQueueTest, OrderedFutures) {
+  ThreadPool TP(1);
+  TaskQueue TQ(TP);
+  std::atomic<int> X{ 0 };
+  std::atomic<int> Y{ 0 };
+  std::atomic<int> Z{ 0 };
+
+  std::mutex M1, M2, M3;
+  std::unique_lock<std::mutex> L1(M1);
+  std::unique_lock<std::mutex> L2(M2);
+  std::unique_lock<std::mutex> L3(M3);
+
+  std::future<void> F1 = TQ.async([&] {
+    std::unique_lock<std::mutex> Lock(M1);
+    ++X;
+  });
+  std::future<void> F2 = TQ.async([&] {
+    std::unique_lock<std::mutex> Lock(M2);
+    ++Y;
+  });
+  std::future<void> F3 = TQ.async([&] {
+    std::unique_lock<std::mutex> Lock(M3);
+    ++Z;
+  });
+
+  L1.unlock();
+  F1.wait();
+  ASSERT_EQ(1, X);
+  ASSERT_EQ(0, Y);
+  ASSERT_EQ(0, Z);
+
+  L2.unlock();
+  F2.wait();
+  ASSERT_EQ(1, X);
+  ASSERT_EQ(1, Y);
+  ASSERT_EQ(0, Z);
+
+  L3.unlock();
+  F3.wait();
+  ASSERT_EQ(1, X);
+  ASSERT_EQ(1, Y);
+  ASSERT_EQ(1, Z);
+}
+
+TEST_F(TaskQueueTest, UnOrderedFutures) {
+  ThreadPool TP(1);
+  TaskQueue TQ(TP);
+  std::atomic<int> X{ 0 };
+  std::atomic<int> Y{ 0 };
+  std::atomic<int> Z{ 0 };
+  std::mutex M;
+
+  std::unique_lock<std::mutex> Lock(M);
+
+  std::future<void> F1 = TQ.async([&] { ++X; });
+  std::future<void> F2 = TQ.async([&] { ++Y; });
+  std::future<void> F3 = TQ.async([&M, &Z] {
+    std::unique_lock<std::mutex> Lock(M);
+    ++Z;
+  });
+
+  F2.wait();
+  ASSERT_EQ(1, X);
+  ASSERT_EQ(1, Y);
+  ASSERT_EQ(0, Z);
+
+  Lock.unlock();
+
+  F3.wait();
+  ASSERT_EQ(1, X);
+  ASSERT_EQ(1, Y);
+  ASSERT_EQ(1, Z);
+}
+
+TEST_F(TaskQueueTest, FutureWithReturnValue) {
+  ThreadPool TP(1);
+  TaskQueue TQ(TP);
+  std::future<std::string> F1 = TQ.async([&] { return std::string("Hello"); });
+  std::future<int> F2 = TQ.async([&] { return 42; });
+
+  ASSERT_EQ(42, F2.get());
+  ASSERT_EQ("Hello", F1.get());
+}
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp b/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
new file mode 100644
index 0000000..e71c7db
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ThreadLocalTest.cpp
@@ -0,0 +1,57 @@
+//===- llvm/unittest/Support/ThreadLocalTest.cpp - ThreadLocal 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/ThreadLocal.h"
+#include "gtest/gtest.h"
+#include <type_traits>
+
+using namespace llvm;
+using namespace sys;
+
+namespace {
+
+class ThreadLocalTest : public ::testing::Test {
+};
+
+struct S {
+  int i;
+};
+
+TEST_F(ThreadLocalTest, Basics) {
+  ThreadLocal<const S> x;
+
+  static_assert(
+      std::is_const<std::remove_pointer<decltype(x.get())>::type>::value,
+      "ThreadLocal::get didn't return a pointer to const object");
+
+  EXPECT_EQ(nullptr, x.get());
+
+  S s;
+  x.set(&s);
+  EXPECT_EQ(&s, x.get());
+
+  x.erase();
+  EXPECT_EQ(nullptr, x.get());
+
+  ThreadLocal<S> y;
+
+  static_assert(
+      !std::is_const<std::remove_pointer<decltype(y.get())>::type>::value,
+      "ThreadLocal::get returned a pointer to const object");
+
+  EXPECT_EQ(nullptr, y.get());
+
+  y.set(&s);
+  EXPECT_EQ(&s, y.get());
+
+  y.erase();
+  EXPECT_EQ(nullptr, y.get());
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
new file mode 100644
index 0000000..0da33ad
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
@@ -0,0 +1,166 @@
+//========- unittests/Support/ThreadPools.cpp - ThreadPools.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/Support/ThreadPool.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+// Fixture for the unittests, allowing to *temporarily* disable the unittests
+// on a particular platform
+class ThreadPoolTest : public testing::Test {
+  Triple Host;
+  SmallVector<Triple::ArchType, 4> UnsupportedArchs;
+  SmallVector<Triple::OSType, 4> UnsupportedOSs;
+  SmallVector<Triple::EnvironmentType, 1> UnsupportedEnvironments;
+protected:
+  // This is intended for platform as a temporary "XFAIL"
+  bool isUnsupportedOSOrEnvironment() {
+    Triple Host(Triple::normalize(sys::getProcessTriple()));
+
+    if (find(UnsupportedEnvironments, Host.getEnvironment()) !=
+        UnsupportedEnvironments.end())
+      return true;
+
+    if (is_contained(UnsupportedOSs, Host.getOS()))
+      return true;
+
+    if (is_contained(UnsupportedArchs, Host.getArch()))
+      return true;
+
+    return false;
+  }
+
+  ThreadPoolTest() {
+    // Add unsupported configuration here, example:
+    //   UnsupportedArchs.push_back(Triple::x86_64);
+
+    // See https://llvm.org/bugs/show_bug.cgi?id=25829
+    UnsupportedArchs.push_back(Triple::ppc64le);
+    UnsupportedArchs.push_back(Triple::ppc64);
+  }
+
+  /// Make sure this thread not progress faster than the main thread.
+  void waitForMainThread() {
+    std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
+    WaitMainThread.wait(LockGuard, [&] { return MainThreadReady; });
+  }
+
+  /// Set the readiness of the main thread.
+  void setMainThreadReady() {
+    {
+      std::unique_lock<std::mutex> LockGuard(WaitMainThreadMutex);
+      MainThreadReady = true;
+    }
+    WaitMainThread.notify_all();
+  }
+
+  void SetUp() override { MainThreadReady = false; }
+
+  std::condition_variable WaitMainThread;
+  std::mutex WaitMainThreadMutex;
+  bool MainThreadReady;
+
+};
+
+#define CHECK_UNSUPPORTED() \
+  do { \
+    if (isUnsupportedOSOrEnvironment()) \
+      return; \
+  } while (0); \
+
+TEST_F(ThreadPoolTest, AsyncBarrier) {
+  CHECK_UNSUPPORTED();
+  // test that async & barrier work together properly.
+
+  std::atomic_int checked_in{0};
+
+  ThreadPool Pool;
+  for (size_t i = 0; i < 5; ++i) {
+    Pool.async([this, &checked_in] {
+      waitForMainThread();
+      ++checked_in;
+    });
+  }
+  ASSERT_EQ(0, checked_in);
+  setMainThreadReady();
+  Pool.wait();
+  ASSERT_EQ(5, checked_in);
+}
+
+static void TestFunc(std::atomic_int &checked_in, int i) { checked_in += i; }
+
+TEST_F(ThreadPoolTest, AsyncBarrierArgs) {
+  CHECK_UNSUPPORTED();
+  // Test that async works with a function requiring multiple parameters.
+  std::atomic_int checked_in{0};
+
+  ThreadPool Pool;
+  for (size_t i = 0; i < 5; ++i) {
+    Pool.async(TestFunc, std::ref(checked_in), i);
+  }
+  Pool.wait();
+  ASSERT_EQ(10, checked_in);
+}
+
+TEST_F(ThreadPoolTest, Async) {
+  CHECK_UNSUPPORTED();
+  ThreadPool Pool;
+  std::atomic_int i{0};
+  Pool.async([this, &i] {
+    waitForMainThread();
+    ++i;
+  });
+  Pool.async([&i] { ++i; });
+  ASSERT_NE(2, i.load());
+  setMainThreadReady();
+  Pool.wait();
+  ASSERT_EQ(2, i.load());
+}
+
+TEST_F(ThreadPoolTest, GetFuture) {
+  CHECK_UNSUPPORTED();
+  ThreadPool Pool{2};
+  std::atomic_int i{0};
+  Pool.async([this, &i] {
+    waitForMainThread();
+    ++i;
+  });
+  // Force the future using get()
+  Pool.async([&i] { ++i; }).get();
+  ASSERT_NE(2, i.load());
+  setMainThreadReady();
+  Pool.wait();
+  ASSERT_EQ(2, i.load());
+}
+
+TEST_F(ThreadPoolTest, PoolDestruction) {
+  CHECK_UNSUPPORTED();
+  // Test that we are waiting on destruction
+  std::atomic_int checked_in{0};
+  {
+    ThreadPool Pool;
+    for (size_t i = 0; i < 5; ++i) {
+      Pool.async([this, &checked_in] {
+        waitForMainThread();
+        ++checked_in;
+      });
+    }
+    ASSERT_EQ(0, checked_in);
+    setMainThreadReady();
+  }
+  ASSERT_EQ(5, checked_in);
+}
diff --git a/src/llvm-project/llvm/unittests/Support/Threading.cpp b/src/llvm-project/llvm/unittests/Support/Threading.cpp
new file mode 100644
index 0000000..be53026
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/Threading.cpp
@@ -0,0 +1,25 @@
+//===- unittests/Threading.cpp - Thread 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/Threading.h"
+#include "llvm/Support/thread.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(Threading, PhysicalConcurrency) {
+  auto Num = heavyweight_hardware_concurrency();
+  // Since Num is unsigned this will also catch us trying to
+  // return -1.
+  ASSERT_LE(Num, thread::hardware_concurrency());
+}
+
+} // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/TimerTest.cpp b/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
new file mode 100644
index 0000000..a92ecf1
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TimerTest.cpp
@@ -0,0 +1,65 @@
+//===- unittests/TimerTest.cpp - Timer 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/Timer.h"
+#include "gtest/gtest.h"
+
+#if _WIN32
+#include <windows.h>
+#else
+#include <time.h>
+#endif
+
+using namespace llvm;
+
+namespace {
+
+// FIXME: Put this somewhere in Support, it's also used in LockFileManager.
+void SleepMS() {
+#if _WIN32
+  Sleep(1);
+#else
+  struct timespec Interval;
+  Interval.tv_sec = 0;
+  Interval.tv_nsec = 1000000;
+  nanosleep(&Interval, nullptr);
+#endif
+}
+
+TEST(Timer, Additivity) {
+  Timer T1("T1", "T1");
+
+  EXPECT_TRUE(T1.isInitialized());
+
+  T1.startTimer();
+  T1.stopTimer();
+  auto TR1 = T1.getTotalTime();
+
+  T1.startTimer();
+  SleepMS();
+  T1.stopTimer();
+  auto TR2 = T1.getTotalTime();
+
+  EXPECT_TRUE(TR1 < TR2);
+}
+
+TEST(Timer, CheckIfTriggered) {
+  Timer T1("T1", "T1");
+
+  EXPECT_FALSE(T1.hasTriggered());
+  T1.startTimer();
+  EXPECT_TRUE(T1.hasTriggered());
+  T1.stopTimer();
+  EXPECT_TRUE(T1.hasTriggered());
+
+  T1.clear();
+  EXPECT_FALSE(T1.hasTriggered());
+}
+
+} // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
new file mode 100644
index 0000000..23acc54
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
@@ -0,0 +1,259 @@
+//=== - llvm/unittest/Support/TrailingObjectsTest.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/TrailingObjects.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+// This class, beyond being used by the test case, a nice
+// demonstration of the intended usage of TrailingObjects, with a
+// single trailing array.
+class Class1 final : protected TrailingObjects<Class1, short> {
+  friend TrailingObjects;
+
+  unsigned NumShorts;
+
+protected:
+  size_t numTrailingObjects(OverloadToken<short>) const { return NumShorts; }
+
+  Class1(int *ShortArray, unsigned NumShorts) : NumShorts(NumShorts) {
+    std::uninitialized_copy(ShortArray, ShortArray + NumShorts,
+                            getTrailingObjects<short>());
+  }
+
+public:
+  static Class1 *create(int *ShortArray, unsigned NumShorts) {
+    void *Mem = ::operator new(totalSizeToAlloc<short>(NumShorts));
+    return new (Mem) Class1(ShortArray, NumShorts);
+  }
+  void operator delete(void *p) { ::operator delete(p); }
+
+  short get(unsigned Num) const { return getTrailingObjects<short>()[Num]; }
+
+  unsigned numShorts() const { return NumShorts; }
+
+  // Pull some protected members in as public, for testability.
+  template <typename... Ty>
+  using FixedSizeStorage = TrailingObjects::FixedSizeStorage<Ty...>;
+
+  using TrailingObjects::totalSizeToAlloc;
+  using TrailingObjects::additionalSizeToAlloc;
+  using TrailingObjects::getTrailingObjects;
+};
+
+// Here, there are two singular optional object types appended.  Note
+// that the alignment of Class2 is automatically increased to account
+// for the alignment requirements of the trailing objects.
+class Class2 final : protected TrailingObjects<Class2, double, short> {
+  friend TrailingObjects;
+
+  bool HasShort, HasDouble;
+
+protected:
+  size_t numTrailingObjects(OverloadToken<short>) const {
+    return HasShort ? 1 : 0;
+  }
+  size_t numTrailingObjects(OverloadToken<double>) const {
+    return HasDouble ? 1 : 0;
+  }
+
+  Class2(bool HasShort, bool HasDouble)
+      : HasShort(HasShort), HasDouble(HasDouble) {}
+
+public:
+  static Class2 *create(short S = 0, double D = 0.0) {
+    bool HasShort = S != 0;
+    bool HasDouble = D != 0.0;
+
+    void *Mem =
+        ::operator new(totalSizeToAlloc<double, short>(HasDouble, HasShort));
+    Class2 *C = new (Mem) Class2(HasShort, HasDouble);
+    if (HasShort)
+      *C->getTrailingObjects<short>() = S;
+    if (HasDouble)
+      *C->getTrailingObjects<double>() = D;
+    return C;
+  }
+  void operator delete(void *p) { ::operator delete(p); }
+
+  short getShort() const {
+    if (!HasShort)
+      return 0;
+    return *getTrailingObjects<short>();
+  }
+
+  double getDouble() const {
+    if (!HasDouble)
+      return 0.0;
+    return *getTrailingObjects<double>();
+  }
+
+  // Pull some protected members in as public, for testability.
+  template <typename... Ty>
+  using FixedSizeStorage = TrailingObjects::FixedSizeStorage<Ty...>;
+
+  using TrailingObjects::totalSizeToAlloc;
+  using TrailingObjects::additionalSizeToAlloc;
+  using TrailingObjects::getTrailingObjects;
+};
+
+TEST(TrailingObjects, OneArg) {
+  int arr[] = {1, 2, 3};
+  Class1 *C = Class1::create(arr, 3);
+  EXPECT_EQ(sizeof(Class1), sizeof(unsigned));
+  EXPECT_EQ(Class1::additionalSizeToAlloc<short>(1), sizeof(short));
+  EXPECT_EQ(Class1::additionalSizeToAlloc<short>(3), sizeof(short) * 3);
+
+  EXPECT_EQ(alignof(Class1),
+            alignof(Class1::FixedSizeStorage<short>::with_counts<1>::type));
+  EXPECT_EQ(sizeof(Class1::FixedSizeStorage<short>::with_counts<1>::type),
+            llvm::alignTo(Class1::totalSizeToAlloc<short>(1), alignof(Class1)));
+  EXPECT_EQ(Class1::totalSizeToAlloc<short>(1), sizeof(Class1) + sizeof(short));
+
+  EXPECT_EQ(alignof(Class1),
+            alignof(Class1::FixedSizeStorage<short>::with_counts<3>::type));
+  EXPECT_EQ(sizeof(Class1::FixedSizeStorage<short>::with_counts<3>::type),
+            llvm::alignTo(Class1::totalSizeToAlloc<short>(3), alignof(Class1)));
+  EXPECT_EQ(Class1::totalSizeToAlloc<short>(3),
+            sizeof(Class1) + sizeof(short) * 3);
+
+  EXPECT_EQ(C->getTrailingObjects<short>(), reinterpret_cast<short *>(C + 1));
+  EXPECT_EQ(C->get(0), 1);
+  EXPECT_EQ(C->get(2), 3);
+  delete C;
+}
+
+TEST(TrailingObjects, TwoArg) {
+  Class2 *C1 = Class2::create(4);
+  Class2 *C2 = Class2::create(0, 4.2);
+
+  EXPECT_EQ(sizeof(Class2), llvm::alignTo(sizeof(bool) * 2, alignof(double)));
+  EXPECT_EQ(alignof(Class2), alignof(double));
+
+  EXPECT_EQ((Class2::additionalSizeToAlloc<double, short>(1, 0)),
+            sizeof(double));
+  EXPECT_EQ((Class2::additionalSizeToAlloc<double, short>(0, 1)),
+            sizeof(short));
+  EXPECT_EQ((Class2::additionalSizeToAlloc<double, short>(3, 1)),
+            sizeof(double) * 3 + sizeof(short));
+
+  EXPECT_EQ(
+      alignof(Class2),
+      (alignof(
+          Class2::FixedSizeStorage<double, short>::with_counts<1, 1>::type)));
+  EXPECT_EQ(
+      sizeof(Class2::FixedSizeStorage<double, short>::with_counts<1, 1>::type),
+      llvm::alignTo(Class2::totalSizeToAlloc<double, short>(1, 1),
+                    alignof(Class2)));
+  EXPECT_EQ((Class2::totalSizeToAlloc<double, short>(1, 1)),
+            sizeof(Class2) + sizeof(double) + sizeof(short));
+
+  EXPECT_EQ(C1->getDouble(), 0);
+  EXPECT_EQ(C1->getShort(), 4);
+  EXPECT_EQ(C1->getTrailingObjects<double>(),
+            reinterpret_cast<double *>(C1 + 1));
+  EXPECT_EQ(C1->getTrailingObjects<short>(), reinterpret_cast<short *>(C1 + 1));
+
+  EXPECT_EQ(C2->getDouble(), 4.2);
+  EXPECT_EQ(C2->getShort(), 0);
+  EXPECT_EQ(C2->getTrailingObjects<double>(),
+            reinterpret_cast<double *>(C2 + 1));
+  EXPECT_EQ(C2->getTrailingObjects<short>(),
+            reinterpret_cast<short *>(reinterpret_cast<double *>(C2 + 1) + 1));
+  delete C1;
+  delete C2;
+}
+
+// This test class is not trying to be a usage demo, just asserting
+// that three args does actually work too (it's the same code as
+// handles the second arg, so it's basically covered by the above, but
+// just in case..)
+class Class3 final : public TrailingObjects<Class3, double, short, bool> {
+  friend TrailingObjects;
+
+  size_t numTrailingObjects(OverloadToken<double>) const { return 1; }
+  size_t numTrailingObjects(OverloadToken<short>) const { return 1; }
+};
+
+TEST(TrailingObjects, ThreeArg) {
+  EXPECT_EQ((Class3::additionalSizeToAlloc<double, short, bool>(1, 1, 3)),
+            sizeof(double) + sizeof(short) + 3 * sizeof(bool));
+  EXPECT_EQ(sizeof(Class3), llvm::alignTo(1, alignof(double)));
+
+  EXPECT_EQ(
+      alignof(Class3),
+      (alignof(Class3::FixedSizeStorage<double, short,
+                                        bool>::with_counts<1, 1, 3>::type)));
+  EXPECT_EQ(
+      sizeof(Class3::FixedSizeStorage<double, short,
+                                      bool>::with_counts<1, 1, 3>::type),
+      llvm::alignTo(Class3::totalSizeToAlloc<double, short, bool>(1, 1, 3),
+                    alignof(Class3)));
+
+  std::unique_ptr<char[]> P(new char[1000]);
+  Class3 *C = reinterpret_cast<Class3 *>(P.get());
+  EXPECT_EQ(C->getTrailingObjects<double>(), reinterpret_cast<double *>(C + 1));
+  EXPECT_EQ(C->getTrailingObjects<short>(),
+            reinterpret_cast<short *>(reinterpret_cast<double *>(C + 1) + 1));
+  EXPECT_EQ(
+      C->getTrailingObjects<bool>(),
+      reinterpret_cast<bool *>(
+          reinterpret_cast<short *>(reinterpret_cast<double *>(C + 1) + 1) +
+          1));
+}
+
+class Class4 final : public TrailingObjects<Class4, char, long> {
+  friend TrailingObjects;
+  size_t numTrailingObjects(OverloadToken<char>) const { return 1; }
+};
+
+TEST(TrailingObjects, Realignment) {
+  EXPECT_EQ((Class4::additionalSizeToAlloc<char, long>(1, 1)),
+            llvm::alignTo(sizeof(long) + 1, alignof(long)));
+  EXPECT_EQ(sizeof(Class4), llvm::alignTo(1, alignof(long)));
+
+  EXPECT_EQ(
+      alignof(Class4),
+      (alignof(Class4::FixedSizeStorage<char, long>::with_counts<1, 1>::type)));
+  EXPECT_EQ(
+      sizeof(Class4::FixedSizeStorage<char, long>::with_counts<1, 1>::type),
+      llvm::alignTo(Class4::totalSizeToAlloc<char, long>(1, 1),
+                    alignof(Class4)));
+
+  std::unique_ptr<char[]> P(new char[1000]);
+  Class4 *C = reinterpret_cast<Class4 *>(P.get());
+  EXPECT_EQ(C->getTrailingObjects<char>(), reinterpret_cast<char *>(C + 1));
+  EXPECT_EQ(C->getTrailingObjects<long>(),
+            reinterpret_cast<long *>(llvm::alignAddr(
+                reinterpret_cast<char *>(C + 1) + 1, alignof(long))));
+}
+}
+
+// Test the use of TrailingObjects with a template class. This
+// previously failed to compile due to a bug in MSVC's member access
+// control/lookup handling for OverloadToken.
+template <typename Derived>
+class Class5Tmpl : private llvm::TrailingObjects<Derived, float, int> {
+  using TrailingObjects = typename llvm::TrailingObjects<Derived, float>;
+  friend TrailingObjects;
+
+  size_t numTrailingObjects(
+      typename TrailingObjects::template OverloadToken<float>) const {
+    return 1;
+  }
+
+  size_t numTrailingObjects(
+      typename TrailingObjects::template OverloadToken<int>) const {
+    return 2;
+  }
+};
+
+class Class5 : public Class5Tmpl<Class5> {};
diff --git a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
new file mode 100644
index 0000000..df42c1e
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
@@ -0,0 +1,132 @@
+//===- TrigramIndexTest.cpp - Unit tests for TrigramIndex -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TrigramIndex.h"
+#include "llvm/ADT/STLExtras.h"
+#include "gtest/gtest.h"
+
+#include <string>
+#include <vector>
+
+using namespace llvm;
+
+namespace {
+
+class TrigramIndexTest : public ::testing::Test {
+protected:
+  std::unique_ptr<TrigramIndex> makeTrigramIndex(
+      std::vector<std::string> Rules) {
+    std::unique_ptr<TrigramIndex> TI =
+        make_unique<TrigramIndex>();
+    for (auto &Rule : Rules)
+      TI->insert(Rule);
+    return TI;
+  }
+};
+
+TEST_F(TrigramIndexTest, Empty) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({});
+  EXPECT_FALSE(TI->isDefeated());
+  EXPECT_TRUE(TI->isDefinitelyOut("foo"));
+}
+
+TEST_F(TrigramIndexTest, Basic) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*hello*", "*wor.d*"});
+  EXPECT_FALSE(TI->isDefeated());
+  EXPECT_TRUE(TI->isDefinitelyOut("foo"));
+}
+
+TEST_F(TrigramIndexTest, NoTrigramsInRules) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"b.r", "za*az"});
+  EXPECT_TRUE(TI->isDefeated());
+  EXPECT_FALSE(TI->isDefinitelyOut("foo"));
+  EXPECT_FALSE(TI->isDefinitelyOut("bar"));
+  EXPECT_FALSE(TI->isDefinitelyOut("zakaz"));
+}
+
+TEST_F(TrigramIndexTest, NoTrigramsInARule) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*hello*", "*wo.ld*"});
+  EXPECT_TRUE(TI->isDefeated());
+  EXPECT_FALSE(TI->isDefinitelyOut("foo"));
+}
+
+TEST_F(TrigramIndexTest, RepetitiveRule) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*bar*bar*bar*bar*bar", "bar*bar"});
+  EXPECT_FALSE(TI->isDefeated());
+  EXPECT_TRUE(TI->isDefinitelyOut("foo"));
+  EXPECT_TRUE(TI->isDefinitelyOut("bar"));
+  EXPECT_FALSE(TI->isDefinitelyOut("barbara"));
+  EXPECT_FALSE(TI->isDefinitelyOut("bar+bar"));
+}
+
+TEST_F(TrigramIndexTest, PopularTrigram) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*aaa*", "*aaaa*", "*aaaaa*", "*aaaaa*", "*aaaaaa*"});
+  EXPECT_TRUE(TI->isDefeated());
+}
+
+TEST_F(TrigramIndexTest, PopularTrigram2) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"class1.h", "class2.h", "class3.h", "class4.h", "class.h"});
+  EXPECT_TRUE(TI->isDefeated());
+}
+
+TEST_F(TrigramIndexTest, TooComplicatedRegex) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"[0-9]+"});
+  EXPECT_TRUE(TI->isDefeated());
+}
+
+TEST_F(TrigramIndexTest, TooComplicatedRegex2) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"foo|bar"});
+  EXPECT_TRUE(TI->isDefeated());
+}
+
+TEST_F(TrigramIndexTest, EscapedSymbols) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*c\\+\\+*", "*hello\\\\world*", "a\\tb", "a\\0b"});
+  EXPECT_FALSE(TI->isDefeated());
+  EXPECT_FALSE(TI->isDefinitelyOut("c++"));
+  EXPECT_TRUE(TI->isDefinitelyOut("c\\+\\+"));
+  EXPECT_FALSE(TI->isDefinitelyOut("hello\\world"));
+  EXPECT_TRUE(TI->isDefinitelyOut("hello\\\\world"));
+  EXPECT_FALSE(TI->isDefinitelyOut("atb"));
+  EXPECT_TRUE(TI->isDefinitelyOut("a\\tb"));
+  EXPECT_TRUE(TI->isDefinitelyOut("a\tb"));
+  EXPECT_FALSE(TI->isDefinitelyOut("a0b"));
+}
+
+TEST_F(TrigramIndexTest, Backreference1) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*foo\\1*"});
+  EXPECT_TRUE(TI->isDefeated());
+}
+
+TEST_F(TrigramIndexTest, Backreference2) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"*foo\\2*"});
+  EXPECT_TRUE(TI->isDefeated());
+}
+
+TEST_F(TrigramIndexTest, Sequence) {
+  std::unique_ptr<TrigramIndex> TI =
+      makeTrigramIndex({"class1.h", "class2.h", "class3.h", "class4.h"});
+  EXPECT_FALSE(TI->isDefeated());
+  EXPECT_FALSE(TI->isDefinitelyOut("class1"));
+  EXPECT_TRUE(TI->isDefinitelyOut("class.h"));
+  EXPECT_TRUE(TI->isDefinitelyOut("class"));
+}
+
+}  // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp b/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
new file mode 100644
index 0000000..63381d4
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TypeNameTest.cpp
@@ -0,0 +1,49 @@
+//===- TypeNameTest.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/TypeName.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+namespace N1 {
+struct S1 {};
+class C1 {};
+union U1 {};
+}
+
+TEST(TypeNameTest, Names) {
+  struct S2 {};
+
+  StringRef S1Name = getTypeName<N1::S1>();
+  StringRef C1Name = getTypeName<N1::C1>();
+  StringRef U1Name = getTypeName<N1::U1>();
+  StringRef S2Name = getTypeName<S2>();
+
+#if defined(__clang__) || defined(__GNUC__) || defined(__INTEL_COMPILER) ||    \
+    defined(_MSC_VER)
+  EXPECT_TRUE(S1Name.endswith("::N1::S1")) << S1Name.str();
+  EXPECT_TRUE(C1Name.endswith("::N1::C1")) << C1Name.str();
+  EXPECT_TRUE(U1Name.endswith("::N1::U1")) << U1Name.str();
+#ifdef __clang__
+  EXPECT_TRUE(S2Name.endswith("S2")) << S2Name.str();
+#else
+  EXPECT_TRUE(S2Name.endswith("::S2")) << S2Name.str();
+#endif
+#else
+  EXPECT_EQ("UNKNOWN_TYPE", S1Name);
+  EXPECT_EQ("UNKNOWN_TYPE", C1Name);
+  EXPECT_EQ("UNKNOWN_TYPE", U1Name);
+  EXPECT_EQ("UNKNOWN_TYPE", S2Name);
+#endif
+}
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp b/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
new file mode 100644
index 0000000..7a3ce53
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/TypeTraitsTest.cpp
@@ -0,0 +1,77 @@
+//===- TypeTraitsTest.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/type_traits.h"
+
+namespace {
+
+// Compile-time tests using static assert.
+namespace triviality {
+
+// Helper for compile time checking trivially copy constructible and trivially
+// move constructible type traits.
+template <typename T, bool IsTriviallyCopyConstructible,
+          bool IsTriviallyMoveConstructible>
+void TrivialityTester() {
+  static_assert(llvm::is_trivially_copy_constructible<T>::value ==
+                    IsTriviallyCopyConstructible,
+                "Mismatch in expected trivial copy construction!");
+  static_assert(llvm::is_trivially_move_constructible<T>::value ==
+                    IsTriviallyMoveConstructible,
+                "Mismatch in expected trivial move construction!");
+
+#if defined(_LIBCPP_VERSION) || defined(_MSC_VER)
+  // On compilers with support for the standard traits, make sure they agree.
+  static_assert(std::is_trivially_copy_constructible<T>::value ==
+                    IsTriviallyCopyConstructible,
+                "Mismatch in expected trivial copy construction!");
+  static_assert(std::is_trivially_move_constructible<T>::value ==
+                    IsTriviallyMoveConstructible,
+                "Mismatch in expected trivial move construction!");
+#endif
+}
+
+template void TrivialityTester<int, true, true>();
+template void TrivialityTester<void *, true, true>();
+template void TrivialityTester<int &, true, true>();
+template void TrivialityTester<int &&, false, true>();
+
+struct X {};
+struct Y {
+  Y(const Y &);
+};
+struct Z {
+  Z(const Z &);
+  Z(Z &&);
+};
+struct A {
+  A(const A &) = default;
+  A(A &&);
+};
+struct B {
+  B(const B &);
+  B(B &&) = default;
+};
+
+template void TrivialityTester<X, true, true>();
+template void TrivialityTester<Y, false, false>();
+template void TrivialityTester<Z, false, false>();
+template void TrivialityTester<A, true, false>();
+template void TrivialityTester<B, false, true>();
+
+template void TrivialityTester<Z &, true, true>();
+template void TrivialityTester<A &, true, true>();
+template void TrivialityTester<B &, true, true>();
+template void TrivialityTester<Z &&, false, true>();
+template void TrivialityTester<A &&, false, true>();
+template void TrivialityTester<B &&, false, true>();
+
+} // namespace triviality
+
+} // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp b/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
new file mode 100644
index 0000000..0733397
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/UnicodeTest.cpp
@@ -0,0 +1,93 @@
+//===- unittests/Support/UnicodeTest.cpp - Unicode.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/Support/Unicode.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+namespace sys {
+namespace unicode {
+namespace {
+
+TEST(Unicode, columnWidthUTF8) {
+  EXPECT_EQ(0, columnWidthUTF8(""));
+  EXPECT_EQ(1, columnWidthUTF8(" "));
+  EXPECT_EQ(1, columnWidthUTF8("a"));
+  EXPECT_EQ(1, columnWidthUTF8("~"));
+
+  EXPECT_EQ(6, columnWidthUTF8("abcdef"));
+
+  EXPECT_EQ(-1, columnWidthUTF8("\x01"));
+  EXPECT_EQ(-1, columnWidthUTF8("aaaaaaaaaa\x01"));
+  EXPECT_EQ(-1, columnWidthUTF8("\342\200\213")); // 200B ZERO WIDTH SPACE
+
+  // 00AD SOFT HYPHEN is displayed on most terminals as a space or a dash. Some
+  // text editors display it only when a line is broken at it, some use it as a
+  // line-break hint, but don't display. We choose terminal-oriented
+  // interpretation.
+  EXPECT_EQ(1, columnWidthUTF8("\302\255"));
+
+  EXPECT_EQ(0, columnWidthUTF8("\314\200"));     // 0300 COMBINING GRAVE ACCENT
+  EXPECT_EQ(1, columnWidthUTF8("\340\270\201")); // 0E01 THAI CHARACTER KO KAI
+  EXPECT_EQ(2, columnWidthUTF8("\344\270\200")); // CJK UNIFIED IDEOGRAPH-4E00
+
+  EXPECT_EQ(4, columnWidthUTF8("\344\270\200\344\270\200"));
+  EXPECT_EQ(3, columnWidthUTF8("q\344\270\200"));
+  EXPECT_EQ(3, columnWidthUTF8("\314\200\340\270\201\344\270\200"));
+
+  // Invalid UTF-8 strings, columnWidthUTF8 should error out.
+  EXPECT_EQ(-2, columnWidthUTF8("\344"));
+  EXPECT_EQ(-2, columnWidthUTF8("\344\270"));
+  EXPECT_EQ(-2, columnWidthUTF8("\344\270\033"));
+  EXPECT_EQ(-2, columnWidthUTF8("\344\270\300"));
+  EXPECT_EQ(-2, columnWidthUTF8("\377\366\355"));
+
+  EXPECT_EQ(-2, columnWidthUTF8("qwer\344"));
+  EXPECT_EQ(-2, columnWidthUTF8("qwer\344\270"));
+  EXPECT_EQ(-2, columnWidthUTF8("qwer\344\270\033"));
+  EXPECT_EQ(-2, columnWidthUTF8("qwer\344\270\300"));
+  EXPECT_EQ(-2, columnWidthUTF8("qwer\377\366\355"));
+
+  // UTF-8 sequences longer than 4 bytes correspond to unallocated Unicode
+  // characters.
+  EXPECT_EQ(-2, columnWidthUTF8("\370\200\200\200\200"));     // U+200000
+  EXPECT_EQ(-2, columnWidthUTF8("\374\200\200\200\200\200")); // U+4000000
+}
+
+TEST(Unicode, isPrintable) {
+  EXPECT_FALSE(isPrintable(0)); // <control-0000>-<control-001F>
+  EXPECT_FALSE(isPrintable(0x01));
+  EXPECT_FALSE(isPrintable(0x1F));
+  EXPECT_TRUE(isPrintable(' '));
+  EXPECT_TRUE(isPrintable('A'));
+  EXPECT_TRUE(isPrintable('~'));
+  EXPECT_FALSE(isPrintable(0x7F)); // <control-007F>..<control-009F>
+  EXPECT_FALSE(isPrintable(0x90));
+  EXPECT_FALSE(isPrintable(0x9F));
+
+  EXPECT_TRUE(isPrintable(0xAC));
+  EXPECT_TRUE(isPrintable(0xAD)); // SOFT HYPHEN is displayed on most terminals
+                                  // as either a space or a dash.
+  EXPECT_TRUE(isPrintable(0xAE));
+
+  EXPECT_TRUE(isPrintable(0x0377));  // GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
+  EXPECT_FALSE(isPrintable(0x0378)); // <reserved-0378>..<reserved-0379>
+
+  EXPECT_FALSE(isPrintable(0x0600)); // ARABIC NUMBER SIGN
+
+  EXPECT_FALSE(isPrintable(0x1FFFF)); // <reserved-1F774>..<noncharacter-1FFFF>
+  EXPECT_TRUE(isPrintable(0x20000));  // CJK UNIFIED IDEOGRAPH-20000
+
+  EXPECT_FALSE(isPrintable(0x10FFFF)); // noncharacter
+}
+
+} // namespace
+} // namespace unicode
+} // namespace sys
+} // namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp b/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
new file mode 100644
index 0000000..cd7ecda
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/VersionTupleTest.cpp
@@ -0,0 +1,50 @@
+//===- VersionTupleTests.cpp - Version Number Handling 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/VersionTuple.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(VersionTuple, getAsString) {
+  EXPECT_EQ("0", VersionTuple().getAsString());
+  EXPECT_EQ("1", VersionTuple(1).getAsString());
+  EXPECT_EQ("1.2", VersionTuple(1, 2).getAsString());
+  EXPECT_EQ("1.2.3", VersionTuple(1, 2, 3).getAsString());
+  EXPECT_EQ("1.2.3.4", VersionTuple(1, 2, 3, 4).getAsString());
+}
+
+TEST(VersionTuple, tryParse) {
+  VersionTuple VT;
+
+  EXPECT_FALSE(VT.tryParse("1"));
+  EXPECT_EQ("1", VT.getAsString());
+
+  EXPECT_FALSE(VT.tryParse("1.2"));
+  EXPECT_EQ("1.2", VT.getAsString());
+
+  EXPECT_FALSE(VT.tryParse("1.2.3"));
+  EXPECT_EQ("1.2.3", VT.getAsString());
+
+  EXPECT_FALSE(VT.tryParse("1.2.3.4"));
+  EXPECT_EQ("1.2.3.4", VT.getAsString());
+
+  EXPECT_TRUE(VT.tryParse(""));
+  EXPECT_TRUE(VT.tryParse("1."));
+  EXPECT_TRUE(VT.tryParse("1.2."));
+  EXPECT_TRUE(VT.tryParse("1.2.3."));
+  EXPECT_TRUE(VT.tryParse("1.2.3.4."));
+  EXPECT_TRUE(VT.tryParse("1.2.3.4.5"));
+  EXPECT_TRUE(VT.tryParse("1-2"));
+  EXPECT_TRUE(VT.tryParse("1+2"));
+  EXPECT_TRUE(VT.tryParse(".1"));
+  EXPECT_TRUE(VT.tryParse(" 1"));
+  EXPECT_TRUE(VT.tryParse("1 "));
+  EXPECT_TRUE(VT.tryParse("."));
+}
diff --git a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
new file mode 100644
index 0000000..7b42943
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -0,0 +1,1860 @@
+//===- unittests/Support/VirtualFileSystem.cpp -------------- VFS 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/VirtualFileSystem.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <map>
+#include <string>
+
+using namespace llvm;
+using llvm::sys::fs::UniqueID;
+using testing::ElementsAre;
+using testing::Pair;
+using testing::UnorderedElementsAre;
+
+namespace {
+struct DummyFile : public vfs::File {
+  vfs::Status S;
+  explicit DummyFile(vfs::Status S) : S(S) {}
+  llvm::ErrorOr<vfs::Status> status() override { return S; }
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+  getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
+            bool IsVolatile) override {
+    llvm_unreachable("unimplemented");
+  }
+  std::error_code close() override { return std::error_code(); }
+};
+
+class DummyFileSystem : public vfs::FileSystem {
+  int FSID;   // used to produce UniqueIDs
+  int FileID; // used to produce UniqueIDs
+  std::map<std::string, vfs::Status> FilesAndDirs;
+
+  static int getNextFSID() {
+    static int Count = 0;
+    return Count++;
+  }
+
+public:
+  DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
+
+  ErrorOr<vfs::Status> status(const Twine &Path) override {
+    std::map<std::string, vfs::Status>::iterator I =
+        FilesAndDirs.find(Path.str());
+    if (I == FilesAndDirs.end())
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+    return I->second;
+  }
+  ErrorOr<std::unique_ptr<vfs::File>>
+  openFileForRead(const Twine &Path) override {
+    auto S = status(Path);
+    if (S)
+      return std::unique_ptr<vfs::File>(new DummyFile{*S});
+    return S.getError();
+  }
+  llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
+    return std::string();
+  }
+  std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
+    return std::error_code();
+  }
+  // Map any symlink to "/symlink".
+  std::error_code getRealPath(const Twine &Path,
+                              SmallVectorImpl<char> &Output) const override {
+    auto I = FilesAndDirs.find(Path.str());
+    if (I == FilesAndDirs.end())
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+    if (I->second.isSymlink()) {
+      Output.clear();
+      Twine("/symlink").toVector(Output);
+      return std::error_code();
+    }
+    Output.clear();
+    Path.toVector(Output);
+    return std::error_code();
+  }
+
+  struct DirIterImpl : public llvm::vfs::detail::DirIterImpl {
+    std::map<std::string, vfs::Status> &FilesAndDirs;
+    std::map<std::string, vfs::Status>::iterator I;
+    std::string Path;
+    bool isInPath(StringRef S) {
+      if (Path.size() < S.size() && S.find(Path) == 0) {
+        auto LastSep = S.find_last_of('/');
+        if (LastSep == Path.size() || LastSep == Path.size() - 1)
+          return true;
+      }
+      return false;
+    }
+    DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
+                const Twine &_Path)
+        : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
+          Path(_Path.str()) {
+      for (; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry =
+              vfs::directory_entry(I->second.getName(), I->second.getType());
+          break;
+        }
+      }
+    }
+    std::error_code increment() override {
+      ++I;
+      for (; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry =
+              vfs::directory_entry(I->second.getName(), I->second.getType());
+          break;
+        }
+      }
+      if (I == FilesAndDirs.end())
+        CurrentEntry = vfs::directory_entry();
+      return std::error_code();
+    }
+  };
+
+  vfs::directory_iterator dir_begin(const Twine &Dir,
+                                    std::error_code &EC) override {
+    return vfs::directory_iterator(
+        std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
+  }
+
+  void addEntry(StringRef Path, const vfs::Status &Status) {
+    FilesAndDirs[Path] = Status;
+  }
+
+  void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+    vfs::Status S(Path, UniqueID(FSID, FileID++),
+                  std::chrono::system_clock::now(), 0, 0, 1024,
+                  sys::fs::file_type::regular_file, Perms);
+    addEntry(Path, S);
+  }
+
+  void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+    vfs::Status S(Path, UniqueID(FSID, FileID++),
+                  std::chrono::system_clock::now(), 0, 0, 0,
+                  sys::fs::file_type::directory_file, Perms);
+    addEntry(Path, S);
+  }
+
+  void addSymlink(StringRef Path) {
+    vfs::Status S(Path, UniqueID(FSID, FileID++),
+                  std::chrono::system_clock::now(), 0, 0, 0,
+                  sys::fs::file_type::symlink_file, sys::fs::all_all);
+    addEntry(Path, S);
+  }
+};
+
+/// Replace back-slashes by front-slashes.
+std::string getPosixPath(std::string S) {
+  SmallString<128> Result;
+  llvm::sys::path::native(S, Result, llvm::sys::path::Style::posix);
+  return Result.str();
+}
+} // end anonymous namespace
+
+TEST(VirtualFileSystemTest, StatusQueries) {
+  IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
+  ErrorOr<vfs::Status> Status((std::error_code()));
+
+  D->addRegularFile("/foo");
+  Status = D->status("/foo");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->isStatusKnown());
+  EXPECT_FALSE(Status->isDirectory());
+  EXPECT_TRUE(Status->isRegularFile());
+  EXPECT_FALSE(Status->isSymlink());
+  EXPECT_FALSE(Status->isOther());
+  EXPECT_TRUE(Status->exists());
+
+  D->addDirectory("/bar");
+  Status = D->status("/bar");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->isStatusKnown());
+  EXPECT_TRUE(Status->isDirectory());
+  EXPECT_FALSE(Status->isRegularFile());
+  EXPECT_FALSE(Status->isSymlink());
+  EXPECT_FALSE(Status->isOther());
+  EXPECT_TRUE(Status->exists());
+
+  D->addSymlink("/baz");
+  Status = D->status("/baz");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->isStatusKnown());
+  EXPECT_FALSE(Status->isDirectory());
+  EXPECT_FALSE(Status->isRegularFile());
+  EXPECT_TRUE(Status->isSymlink());
+  EXPECT_FALSE(Status->isOther());
+  EXPECT_TRUE(Status->exists());
+
+  EXPECT_TRUE(Status->equivalent(*Status));
+  ErrorOr<vfs::Status> Status2 = D->status("/foo");
+  ASSERT_FALSE(Status2.getError());
+  EXPECT_FALSE(Status->equivalent(*Status2));
+}
+
+TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
+  IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
+  ErrorOr<vfs::Status> Status((std::error_code()));
+  EXPECT_FALSE(Status = D->status("/foo"));
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
+  EXPECT_FALSE(Status = O->status("/foo"));
+
+  D->addRegularFile("/foo");
+  Status = D->status("/foo");
+  EXPECT_FALSE(Status.getError());
+
+  ErrorOr<vfs::Status> Status2((std::error_code()));
+  Status2 = O->status("/foo");
+  EXPECT_FALSE(Status2.getError());
+  EXPECT_TRUE(Status->equivalent(*Status2));
+}
+
+TEST(VirtualFileSystemTest, GetRealPathInOverlay) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("/foo");
+  Lower->addSymlink("/lower_link");
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  // Regular file.
+  SmallString<16> RealPath;
+  EXPECT_FALSE(O->getRealPath("/foo", RealPath));
+  EXPECT_EQ(RealPath.str(), "/foo");
+
+  // Expect no error getting real path for symlink in lower overlay.
+  EXPECT_FALSE(O->getRealPath("/lower_link", RealPath));
+  EXPECT_EQ(RealPath.str(), "/symlink");
+
+  // Try a non-existing link.
+  EXPECT_EQ(O->getRealPath("/upper_link", RealPath),
+            errc::no_such_file_or_directory);
+
+  // Add a new symlink in upper.
+  Upper->addSymlink("/upper_link");
+  EXPECT_FALSE(O->getRealPath("/upper_link", RealPath));
+  EXPECT_EQ(RealPath.str(), "/symlink");
+}
+
+TEST(VirtualFileSystemTest, OverlayFiles) {
+  IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Base));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Top);
+
+  ErrorOr<vfs::Status> Status1((std::error_code())),
+      Status2((std::error_code())), Status3((std::error_code())),
+      StatusB((std::error_code())), StatusM((std::error_code())),
+      StatusT((std::error_code()));
+
+  Base->addRegularFile("/foo");
+  StatusB = Base->status("/foo");
+  ASSERT_FALSE(StatusB.getError());
+  Status1 = O->status("/foo");
+  ASSERT_FALSE(Status1.getError());
+  Middle->addRegularFile("/foo");
+  StatusM = Middle->status("/foo");
+  ASSERT_FALSE(StatusM.getError());
+  Status2 = O->status("/foo");
+  ASSERT_FALSE(Status2.getError());
+  Top->addRegularFile("/foo");
+  StatusT = Top->status("/foo");
+  ASSERT_FALSE(StatusT.getError());
+  Status3 = O->status("/foo");
+  ASSERT_FALSE(Status3.getError());
+
+  EXPECT_TRUE(Status1->equivalent(*StatusB));
+  EXPECT_TRUE(Status2->equivalent(*StatusM));
+  EXPECT_TRUE(Status3->equivalent(*StatusT));
+
+  EXPECT_FALSE(Status1->equivalent(*Status2));
+  EXPECT_FALSE(Status2->equivalent(*Status3));
+  EXPECT_FALSE(Status1->equivalent(*Status3));
+}
+
+TEST(VirtualFileSystemTest, OverlayDirsNonMerged) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  Lower->addDirectory("/lower-only");
+  Upper->addDirectory("/upper-only");
+
+  // non-merged paths should be the same
+  ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
+  ASSERT_FALSE(Status1.getError());
+  ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
+  ASSERT_FALSE(Status2.getError());
+  EXPECT_TRUE(Status1->equivalent(*Status2));
+
+  Status1 = Upper->status("/upper-only");
+  ASSERT_FALSE(Status1.getError());
+  Status2 = O->status("/upper-only");
+  ASSERT_FALSE(Status2.getError());
+  EXPECT_TRUE(Status1->equivalent(*Status2));
+}
+
+TEST(VirtualFileSystemTest, MergedDirPermissions) {
+  // merged directories get the permissions of the upper dir
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  ErrorOr<vfs::Status> Status((std::error_code()));
+  Lower->addDirectory("/both", sys::fs::owner_read);
+  Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
+  Status = O->status("/both");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_EQ(0740, Status->getPermissions());
+
+  // permissions (as usual) are not recursively applied
+  Lower->addRegularFile("/both/foo", sys::fs::owner_read);
+  Upper->addRegularFile("/both/bar", sys::fs::owner_write);
+  Status = O->status("/both/foo");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_EQ(0400, Status->getPermissions());
+  Status = O->status("/both/bar");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_EQ(0200, Status->getPermissions());
+}
+
+namespace {
+struct ScopedDir {
+  SmallString<128> Path;
+  ScopedDir(const Twine &Name, bool Unique = false) {
+    std::error_code EC;
+    if (Unique) {
+      EC = llvm::sys::fs::createUniqueDirectory(Name, Path);
+    } else {
+      Path = Name.str();
+      EC = llvm::sys::fs::create_directory(Twine(Path));
+    }
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedDir() {
+    if (Path != "") {
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+    }
+  }
+  operator StringRef() { return Path.str(); }
+};
+
+struct ScopedLink {
+  SmallString<128> Path;
+  ScopedLink(const Twine &To, const Twine &From) {
+    Path = From.str();
+    std::error_code EC = sys::fs::create_link(To, From);
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedLink() {
+    if (Path != "") {
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+    }
+  }
+  operator StringRef() { return Path.str(); }
+};
+} // end anonymous namespace
+
+TEST(VirtualFileSystemTest, BasicRealFSIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  std::error_code EC;
+  vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(vfs::directory_iterator(), I); // empty directory is empty
+
+  ScopedDir _a(TestDirectory + "/a");
+  ScopedDir _ab(TestDirectory + "/a/b");
+  ScopedDir _c(TestDirectory + "/c");
+  ScopedDir _cd(TestDirectory + "/c/d");
+
+  I = FS->dir_begin(Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::directory_iterator(), I);
+  // Check either a or c, since we can't rely on the iteration order.
+  EXPECT_TRUE(I->path().endswith("a") || I->path().endswith("c"));
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::directory_iterator(), I);
+  EXPECT_TRUE(I->path().endswith("a") || I->path().endswith("c"));
+  I.increment(EC);
+  EXPECT_EQ(vfs::directory_iterator(), I);
+}
+
+#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, BrokenSymlinkRealFSIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  ScopedLink _a("no_such_file", TestDirectory + "/a");
+  ScopedDir _b(TestDirectory + "/b");
+  ScopedLink _c("no_such_file", TestDirectory + "/c");
+
+  // Should get no iteration error, but a stat error for the broken symlinks.
+  std::map<std::string, std::error_code> StatResults;
+  std::error_code EC;
+  for (vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC), E;
+       I != E; I.increment(EC)) {
+    EXPECT_FALSE(EC);
+    StatResults[sys::path::filename(I->path())] =
+        FS->status(I->path()).getError();
+  }
+  EXPECT_THAT(
+      StatResults,
+      ElementsAre(
+          Pair("a", std::make_error_code(std::errc::no_such_file_or_directory)),
+          Pair("b", std::error_code()),
+          Pair("c",
+               std::make_error_code(std::errc::no_such_file_or_directory))));
+}
+#endif
+
+TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  std::error_code EC;
+  auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(vfs::recursive_directory_iterator(), I); // empty directory is empty
+
+  ScopedDir _a(TestDirectory + "/a");
+  ScopedDir _ab(TestDirectory + "/a/b");
+  ScopedDir _c(TestDirectory + "/c");
+  ScopedDir _cd(TestDirectory + "/c/d");
+
+  I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::recursive_directory_iterator(), I);
+
+  std::vector<std::string> Contents;
+  for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
+       I.increment(EC)) {
+    Contents.push_back(I->path());
+  }
+
+  // Check contents, which may be in any order
+  EXPECT_EQ(4U, Contents.size());
+  int Counts[4] = {0, 0, 0, 0};
+  for (const std::string &Name : Contents) {
+    ASSERT_FALSE(Name.empty());
+    int Index = Name[Name.size() - 1] - 'a';
+    ASSERT_TRUE(Index >= 0 && Index < 4);
+    Counts[Index]++;
+  }
+  EXPECT_EQ(1, Counts[0]); // a
+  EXPECT_EQ(1, Counts[1]); // b
+  EXPECT_EQ(1, Counts[2]); // c
+  EXPECT_EQ(1, Counts[3]); // d
+}
+
+TEST(VirtualFileSystemTest, BasicRealFSRecursiveIterationNoPush) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+
+  ScopedDir _a(TestDirectory + "/a");
+  ScopedDir _ab(TestDirectory + "/a/b");
+  ScopedDir _c(TestDirectory + "/c");
+  ScopedDir _cd(TestDirectory + "/c/d");
+  ScopedDir _e(TestDirectory + "/e");
+  ScopedDir _ef(TestDirectory + "/e/f");
+  ScopedDir _g(TestDirectory + "/g");
+
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  // Test that calling no_push on entries without subdirectories has no effect.
+  {
+    std::error_code EC;
+    auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+    ASSERT_FALSE(EC);
+
+    std::vector<std::string> Contents;
+    for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
+         I.increment(EC)) {
+      Contents.push_back(I->path());
+      char last = I->path().back();
+      switch (last) {
+      case 'b':
+      case 'd':
+      case 'f':
+      case 'g':
+        I.no_push();
+        break;
+      default:
+        break;
+      }
+    }
+    EXPECT_EQ(7U, Contents.size());
+  }
+
+  // Test that calling no_push skips subdirectories.
+  {
+    std::error_code EC;
+    auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+    ASSERT_FALSE(EC);
+
+    std::vector<std::string> Contents;
+    for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
+         I.increment(EC)) {
+      Contents.push_back(I->path());
+      char last = I->path().back();
+      switch (last) {
+      case 'a':
+      case 'c':
+      case 'e':
+        I.no_push();
+        break;
+      default:
+        break;
+      }
+    }
+
+    // Check contents, which may be in any order
+    EXPECT_EQ(4U, Contents.size());
+    int Counts[7] = {0, 0, 0, 0, 0, 0, 0};
+    for (const std::string &Name : Contents) {
+      ASSERT_FALSE(Name.empty());
+      int Index = Name[Name.size() - 1] - 'a';
+      ASSERT_TRUE(Index >= 0 && Index < 7);
+      Counts[Index]++;
+    }
+    EXPECT_EQ(1, Counts[0]); // a
+    EXPECT_EQ(0, Counts[1]); // b
+    EXPECT_EQ(1, Counts[2]); // c
+    EXPECT_EQ(0, Counts[3]); // d
+    EXPECT_EQ(1, Counts[4]); // e
+    EXPECT_EQ(0, Counts[5]); // f
+    EXPECT_EQ(1, Counts[6]); // g
+  }
+}
+
+#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, BrokenSymlinkRealFSRecursiveIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  ScopedLink _a("no_such_file", TestDirectory + "/a");
+  ScopedDir _b(TestDirectory + "/b");
+  ScopedLink _ba("no_such_file", TestDirectory + "/b/a");
+  ScopedDir _bb(TestDirectory + "/b/b");
+  ScopedLink _bc("no_such_file", TestDirectory + "/b/c");
+  ScopedLink _c("no_such_file", TestDirectory + "/c");
+  ScopedDir _d(TestDirectory + "/d");
+  ScopedDir _dd(TestDirectory + "/d/d");
+  ScopedDir _ddd(TestDirectory + "/d/d/d");
+  ScopedLink _e("no_such_file", TestDirectory + "/e");
+
+  std::vector<std::string> VisitedBrokenSymlinks;
+  std::vector<std::string> VisitedNonBrokenSymlinks;
+  std::error_code EC;
+  for (vfs::recursive_directory_iterator I(*FS, Twine(TestDirectory), EC), E;
+       I != E; I.increment(EC)) {
+    EXPECT_FALSE(EC);
+    (FS->status(I->path()) ? VisitedNonBrokenSymlinks : VisitedBrokenSymlinks)
+        .push_back(I->path());
+  }
+
+  // Check visited file names.
+  EXPECT_THAT(VisitedBrokenSymlinks,
+              UnorderedElementsAre(StringRef(_a), StringRef(_ba),
+                                   StringRef(_bc), StringRef(_c),
+                                   StringRef(_e)));
+  EXPECT_THAT(VisitedNonBrokenSymlinks,
+              UnorderedElementsAre(StringRef(_b), StringRef(_bb), StringRef(_d),
+                                   StringRef(_dd), StringRef(_ddd)));
+}
+#endif
+
+template <typename DirIter>
+static void checkContents(DirIter I, ArrayRef<StringRef> ExpectedOut) {
+  std::error_code EC;
+  SmallVector<StringRef, 4> Expected(ExpectedOut.begin(), ExpectedOut.end());
+  SmallVector<std::string, 4> InputToCheck;
+
+  // Do not rely on iteration order to check for contents, sort both
+  // content vectors before comparison.
+  for (DirIter E; !EC && I != E; I.increment(EC))
+    InputToCheck.push_back(I->path());
+
+  llvm::sort(InputToCheck);
+  llvm::sort(Expected);
+  EXPECT_EQ(InputToCheck.size(), Expected.size());
+
+  unsigned LastElt = std::min(InputToCheck.size(), Expected.size());
+  for (unsigned Idx = 0; Idx != LastElt; ++Idx)
+    EXPECT_EQ(StringRef(InputToCheck[Idx]), Expected[Idx]);
+}
+
+TEST(VirtualFileSystemTest, OverlayIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
+
+  Lower->addRegularFile("/file1");
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1"));
+
+  Upper->addRegularFile("/file2");
+  checkContents(O->dir_begin("/", EC), {"/file2", "/file1"});
+
+  Lower->addDirectory("/dir1");
+  Lower->addRegularFile("/dir1/foo");
+  Upper->addDirectory("/dir2");
+  Upper->addRegularFile("/dir2/foo");
+  checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo"));
+  checkContents(O->dir_begin("/", EC), {"/dir2", "/file2", "/dir1", "/file1"});
+}
+
+TEST(VirtualFileSystemTest, OverlayRecursiveIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                ArrayRef<StringRef>());
+
+  Lower->addRegularFile("/file1");
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                ArrayRef<StringRef>("/file1"));
+
+  Upper->addDirectory("/dir");
+  Upper->addRegularFile("/dir/file2");
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                {"/dir", "/dir/file2", "/file1"});
+
+  Lower->addDirectory("/dir1");
+  Lower->addRegularFile("/dir1/foo");
+  Lower->addDirectory("/dir1/a");
+  Lower->addRegularFile("/dir1/a/b");
+  Middle->addDirectory("/a");
+  Middle->addDirectory("/a/b");
+  Middle->addDirectory("/a/b/c");
+  Middle->addRegularFile("/a/b/c/d");
+  Middle->addRegularFile("/hiddenByUp");
+  Upper->addDirectory("/dir2");
+  Upper->addRegularFile("/dir2/foo");
+  Upper->addRegularFile("/hiddenByUp");
+  checkContents(vfs::recursive_directory_iterator(*O, "/dir2", EC),
+                ArrayRef<StringRef>("/dir2/foo"));
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                {"/dir", "/dir/file2", "/dir2", "/dir2/foo", "/hiddenByUp",
+                 "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/dir1", "/dir1/a",
+                 "/dir1/a/b", "/dir1/foo", "/file1"});
+}
+
+TEST(VirtualFileSystemTest, ThreeLevelIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
+
+  Middle->addRegularFile("/file2");
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2"));
+
+  Lower->addRegularFile("/file1");
+  Upper->addRegularFile("/file3");
+  checkContents(O->dir_begin("/", EC), {"/file3", "/file2", "/file1"});
+}
+
+TEST(VirtualFileSystemTest, HiddenInIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  Lower->addRegularFile("/onlyInLow");
+  Lower->addDirectory("/hiddenByMid");
+  Lower->addDirectory("/hiddenByUp");
+  Middle->addRegularFile("/onlyInMid");
+  Middle->addRegularFile("/hiddenByMid");
+  Middle->addDirectory("/hiddenByUp");
+  Upper->addRegularFile("/onlyInUp");
+  Upper->addRegularFile("/hiddenByUp");
+  checkContents(
+      O->dir_begin("/", EC),
+      {"/hiddenByUp", "/onlyInUp", "/hiddenByMid", "/onlyInMid", "/onlyInLow"});
+
+  // Make sure we get the top-most entry
+  {
+    std::error_code EC;
+    vfs::directory_iterator I = O->dir_begin("/", EC), E;
+    for (; !EC && I != E; I.increment(EC))
+      if (I->path() == "/hiddenByUp")
+        break;
+    ASSERT_NE(E, I);
+    EXPECT_EQ(sys::fs::file_type::regular_file, I->type());
+  }
+  {
+    std::error_code EC;
+    vfs::directory_iterator I = O->dir_begin("/", EC), E;
+    for (; !EC && I != E; I.increment(EC))
+      if (I->path() == "/hiddenByMid")
+        break;
+    ASSERT_NE(E, I);
+    EXPECT_EQ(sys::fs::file_type::regular_file, I->type());
+  }
+}
+
+TEST(ProxyFileSystemTest, Basic) {
+  IntrusiveRefCntPtr<vfs::InMemoryFileSystem> Base(
+      new vfs::InMemoryFileSystem());
+  vfs::ProxyFileSystem PFS(Base);
+
+  Base->addFile("/a", 0, MemoryBuffer::getMemBuffer("test"));
+
+  auto Stat = PFS.status("/a");
+  ASSERT_FALSE(Stat.getError());
+
+  auto File = PFS.openFileForRead("/a");
+  ASSERT_FALSE(File.getError());
+  EXPECT_EQ("test", (*(*File)->getBuffer("ignored"))->getBuffer());
+
+  std::error_code EC;
+  vfs::directory_iterator I = PFS.dir_begin("/", EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ("/a", I->path());
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ(vfs::directory_iterator(), I);
+
+  ASSERT_FALSE(PFS.setCurrentWorkingDirectory("/"));
+
+  auto PWD = PFS.getCurrentWorkingDirectory();
+  ASSERT_FALSE(PWD.getError());
+  ASSERT_EQ("/", *PWD);
+
+  SmallString<16> Path;
+  ASSERT_FALSE(PFS.getRealPath("a", Path));
+  ASSERT_EQ("/a", Path);
+
+  bool Local = true;
+  ASSERT_FALSE(PFS.isLocal("/a", Local));
+  ASSERT_EQ(false, Local);
+}
+
+class InMemoryFileSystemTest : public ::testing::Test {
+protected:
+  llvm::vfs::InMemoryFileSystem FS;
+  llvm::vfs::InMemoryFileSystem NormalizedFS;
+
+  InMemoryFileSystemTest()
+      : FS(/*UseNormalizedPaths=*/false),
+        NormalizedFS(/*UseNormalizedPaths=*/true) {}
+};
+
+MATCHER_P2(IsHardLinkTo, FS, Target, "") {
+  StringRef From = arg;
+  StringRef To = Target;
+  auto OpenedFrom = FS->openFileForRead(From);
+  auto OpenedTo = FS->openFileForRead(To);
+  return !OpenedFrom.getError() && !OpenedTo.getError() &&
+         (*OpenedFrom)->status()->getUniqueID() ==
+             (*OpenedTo)->status()->getUniqueID();
+}
+
+TEST_F(InMemoryFileSystemTest, IsEmpty) {
+  auto Stat = FS.status("/a");
+  ASSERT_EQ(Stat.getError(), errc::no_such_file_or_directory) << FS.toString();
+  Stat = FS.status("/");
+  ASSERT_EQ(Stat.getError(), errc::no_such_file_or_directory) << FS.toString();
+}
+
+TEST_F(InMemoryFileSystemTest, WindowsPath) {
+  FS.addFile("c:/windows/system128/foo.cpp", 0, MemoryBuffer::getMemBuffer(""));
+  auto Stat = FS.status("c:");
+#if !defined(_WIN32)
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+#endif
+  Stat = FS.status("c:/windows/system128/foo.cpp");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+  FS.addFile("d:/windows/foo.cpp", 0, MemoryBuffer::getMemBuffer(""));
+  Stat = FS.status("d:/windows/foo.cpp");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+}
+
+TEST_F(InMemoryFileSystemTest, OverlayFile) {
+  FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+  NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+  auto Stat = FS.status("/");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+  Stat = FS.status("/.");
+  ASSERT_FALSE(Stat);
+  Stat = NormalizedFS.status("/.");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << FS.toString();
+  Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_EQ("/a", Stat->getName());
+}
+
+TEST_F(InMemoryFileSystemTest, OverlayFileNoOwn) {
+  auto Buf = MemoryBuffer::getMemBuffer("a");
+  FS.addFileNoOwn("/a", 0, Buf.get());
+  auto Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_EQ("/a", Stat->getName());
+}
+
+TEST_F(InMemoryFileSystemTest, OpenFileForRead) {
+  FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+  FS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
+  FS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
+  NormalizedFS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
+  NormalizedFS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
+  NormalizedFS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
+  auto File = FS.openFileForRead("/a");
+  ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+  File = FS.openFileForRead("/a"); // Open again.
+  ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+  File = NormalizedFS.openFileForRead("/././a"); // Open again.
+  ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
+  File = FS.openFileForRead("/");
+  ASSERT_EQ(File.getError(), errc::invalid_argument) << FS.toString();
+  File = FS.openFileForRead("/b");
+  ASSERT_EQ(File.getError(), errc::no_such_file_or_directory) << FS.toString();
+  File = FS.openFileForRead("./c");
+  ASSERT_FALSE(File);
+  File = FS.openFileForRead("e/../d");
+  ASSERT_FALSE(File);
+  File = NormalizedFS.openFileForRead("./c");
+  ASSERT_EQ("c", (*(*File)->getBuffer("ignored"))->getBuffer());
+  File = NormalizedFS.openFileForRead("e/../d");
+  ASSERT_EQ("d", (*(*File)->getBuffer("ignored"))->getBuffer());
+}
+
+TEST_F(InMemoryFileSystemTest, DuplicatedFile) {
+  ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")));
+  ASSERT_FALSE(FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("a")));
+  ASSERT_TRUE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a")));
+  ASSERT_FALSE(FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("b")));
+}
+
+TEST_F(InMemoryFileSystemTest, DirectoryIteration) {
+  FS.addFile("/a", 0, MemoryBuffer::getMemBuffer(""));
+  FS.addFile("/b/c", 0, MemoryBuffer::getMemBuffer(""));
+
+  std::error_code EC;
+  vfs::directory_iterator I = FS.dir_begin("/", EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ("/a", I->path());
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ("/b", I->path());
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ(vfs::directory_iterator(), I);
+
+  I = FS.dir_begin("/b", EC);
+  ASSERT_FALSE(EC);
+  // When on Windows, we end up with "/b\\c" as the name.  Convert to Posix
+  // path for the sake of the comparison.
+  ASSERT_EQ("/b/c", getPosixPath(I->path()));
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_EQ(vfs::directory_iterator(), I);
+}
+
+TEST_F(InMemoryFileSystemTest, WorkingDirectory) {
+  FS.setCurrentWorkingDirectory("/b");
+  FS.addFile("c", 0, MemoryBuffer::getMemBuffer(""));
+
+  auto Stat = FS.status("/b/c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_EQ("/b/c", Stat->getName());
+  ASSERT_EQ("/b", *FS.getCurrentWorkingDirectory());
+
+  Stat = FS.status("c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+
+  NormalizedFS.setCurrentWorkingDirectory("/b/c");
+  NormalizedFS.setCurrentWorkingDirectory(".");
+  ASSERT_EQ("/b/c",
+            getPosixPath(NormalizedFS.getCurrentWorkingDirectory().get()));
+  NormalizedFS.setCurrentWorkingDirectory("..");
+  ASSERT_EQ("/b",
+            getPosixPath(NormalizedFS.getCurrentWorkingDirectory().get()));
+}
+
+TEST_F(InMemoryFileSystemTest, IsLocal) {
+  FS.setCurrentWorkingDirectory("/b");
+  FS.addFile("c", 0, MemoryBuffer::getMemBuffer(""));
+
+  std::error_code EC;
+  bool IsLocal = true;
+  EC = FS.isLocal("c", IsLocal);
+  ASSERT_FALSE(EC);
+  ASSERT_FALSE(IsLocal);
+}
+
+#if !defined(_WIN32)
+TEST_F(InMemoryFileSystemTest, GetRealPath) {
+  SmallString<16> Path;
+  EXPECT_EQ(FS.getRealPath("b", Path), errc::operation_not_permitted);
+
+  auto GetRealPath = [this](StringRef P) {
+    SmallString<16> Output;
+    auto EC = FS.getRealPath(P, Output);
+    EXPECT_FALSE(EC);
+    return Output.str().str();
+  };
+
+  FS.setCurrentWorkingDirectory("a");
+  EXPECT_EQ(GetRealPath("b"), "a/b");
+  EXPECT_EQ(GetRealPath("../b"), "b");
+  EXPECT_EQ(GetRealPath("b/./c"), "a/b/c");
+
+  FS.setCurrentWorkingDirectory("/a");
+  EXPECT_EQ(GetRealPath("b"), "/a/b");
+  EXPECT_EQ(GetRealPath("../b"), "/b");
+  EXPECT_EQ(GetRealPath("b/./c"), "/a/b/c");
+}
+#endif // _WIN32
+
+TEST_F(InMemoryFileSystemTest, AddFileWithUser) {
+  FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), 0xFEEDFACE);
+  auto Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  ASSERT_EQ(0xFEEDFACE, Stat->getUser());
+  Stat = FS.status("/a/b");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  ASSERT_EQ(0xFEEDFACE, Stat->getUser());
+  Stat = FS.status("/a/b/c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isRegularFile());
+  ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions());
+  ASSERT_EQ(0xFEEDFACE, Stat->getUser());
+}
+
+TEST_F(InMemoryFileSystemTest, AddFileWithGroup) {
+  FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), None, 0xDABBAD00);
+  auto Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  ASSERT_EQ(0xDABBAD00, Stat->getGroup());
+  Stat = FS.status("/a/b");
+  ASSERT_TRUE(Stat->isDirectory());
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_EQ(0xDABBAD00, Stat->getGroup());
+  Stat = FS.status("/a/b/c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isRegularFile());
+  ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions());
+  ASSERT_EQ(0xDABBAD00, Stat->getGroup());
+}
+
+TEST_F(InMemoryFileSystemTest, AddFileWithFileType) {
+  FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), None, None,
+             sys::fs::file_type::socket_file);
+  auto Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  Stat = FS.status("/a/b");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  Stat = FS.status("/a/b/c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_EQ(sys::fs::file_type::socket_file, Stat->getType());
+  ASSERT_EQ(sys::fs::perms::all_all, Stat->getPermissions());
+}
+
+TEST_F(InMemoryFileSystemTest, AddFileWithPerms) {
+  FS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), None, None, None,
+             sys::fs::perms::owner_read | sys::fs::perms::owner_write);
+  auto Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  ASSERT_EQ(sys::fs::perms::owner_read | sys::fs::perms::owner_write |
+                sys::fs::perms::owner_exe,
+            Stat->getPermissions());
+  Stat = FS.status("/a/b");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  ASSERT_EQ(sys::fs::perms::owner_read | sys::fs::perms::owner_write |
+                sys::fs::perms::owner_exe,
+            Stat->getPermissions());
+  Stat = FS.status("/a/b/c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isRegularFile());
+  ASSERT_EQ(sys::fs::perms::owner_read | sys::fs::perms::owner_write,
+            Stat->getPermissions());
+}
+
+TEST_F(InMemoryFileSystemTest, AddDirectoryThenAddChild) {
+  FS.addFile("/a", 0, MemoryBuffer::getMemBuffer(""), /*User=*/None,
+             /*Group=*/None, sys::fs::file_type::directory_file);
+  FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("abc"), /*User=*/None,
+             /*Group=*/None, sys::fs::file_type::regular_file);
+  auto Stat = FS.status("/a");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isDirectory());
+  Stat = FS.status("/a/b");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString();
+  ASSERT_TRUE(Stat->isRegularFile());
+}
+
+// Test that the name returned by status() is in the same form as the path that
+// was requested (to match the behavior of RealFileSystem).
+TEST_F(InMemoryFileSystemTest, StatusName) {
+  NormalizedFS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"),
+                       /*User=*/None,
+                       /*Group=*/None, sys::fs::file_type::regular_file);
+  NormalizedFS.setCurrentWorkingDirectory("/a/b");
+
+  // Access using InMemoryFileSystem::status.
+  auto Stat = NormalizedFS.status("../b/c");
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n"
+                                << NormalizedFS.toString();
+  ASSERT_TRUE(Stat->isRegularFile());
+  ASSERT_EQ("../b/c", Stat->getName());
+
+  // Access using InMemoryFileAdaptor::status.
+  auto File = NormalizedFS.openFileForRead("../b/c");
+  ASSERT_FALSE(File.getError()) << File.getError() << "\n"
+                                << NormalizedFS.toString();
+  Stat = (*File)->status();
+  ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n"
+                                << NormalizedFS.toString();
+  ASSERT_TRUE(Stat->isRegularFile());
+  ASSERT_EQ("../b/c", Stat->getName());
+
+  // Access using a directory iterator.
+  std::error_code EC;
+  llvm::vfs::directory_iterator It = NormalizedFS.dir_begin("../b", EC);
+  // When on Windows, we end up with "../b\\c" as the name.  Convert to Posix
+  // path for the sake of the comparison.
+  ASSERT_EQ("../b/c", getPosixPath(It->path()));
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkToFile) {
+  StringRef FromLink = "/path/to/FROM/link";
+  StringRef Target = "/path/to/TO/file";
+  FS.addFile(Target, 0, MemoryBuffer::getMemBuffer("content of target"));
+  EXPECT_TRUE(FS.addHardLink(FromLink, Target));
+  EXPECT_THAT(FromLink, IsHardLinkTo(&FS, Target));
+  EXPECT_TRUE(FS.status(FromLink)->getSize() == FS.status(Target)->getSize());
+  EXPECT_TRUE(FS.getBufferForFile(FromLink)->get()->getBuffer() ==
+              FS.getBufferForFile(Target)->get()->getBuffer());
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkInChainPattern) {
+  StringRef Link0 = "/path/to/0/link";
+  StringRef Link1 = "/path/to/1/link";
+  StringRef Link2 = "/path/to/2/link";
+  StringRef Target = "/path/to/target";
+  FS.addFile(Target, 0, MemoryBuffer::getMemBuffer("content of target file"));
+  EXPECT_TRUE(FS.addHardLink(Link2, Target));
+  EXPECT_TRUE(FS.addHardLink(Link1, Link2));
+  EXPECT_TRUE(FS.addHardLink(Link0, Link1));
+  EXPECT_THAT(Link0, IsHardLinkTo(&FS, Target));
+  EXPECT_THAT(Link1, IsHardLinkTo(&FS, Target));
+  EXPECT_THAT(Link2, IsHardLinkTo(&FS, Target));
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkToAFileThatWasNotAddedBefore) {
+  EXPECT_FALSE(FS.addHardLink("/path/to/link", "/path/to/target"));
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkFromAFileThatWasAddedBefore) {
+  StringRef Link = "/path/to/link";
+  StringRef Target = "/path/to/target";
+  FS.addFile(Target, 0, MemoryBuffer::getMemBuffer("content of target"));
+  FS.addFile(Link, 0, MemoryBuffer::getMemBuffer("content of link"));
+  EXPECT_FALSE(FS.addHardLink(Link, Target));
+}
+
+TEST_F(InMemoryFileSystemTest, AddSameHardLinkMoreThanOnce) {
+  StringRef Link = "/path/to/link";
+  StringRef Target = "/path/to/target";
+  FS.addFile(Target, 0, MemoryBuffer::getMemBuffer("content of target"));
+  EXPECT_TRUE(FS.addHardLink(Link, Target));
+  EXPECT_FALSE(FS.addHardLink(Link, Target));
+}
+
+TEST_F(InMemoryFileSystemTest, AddFileInPlaceOfAHardLinkWithSameContent) {
+  StringRef Link = "/path/to/link";
+  StringRef Target = "/path/to/target";
+  StringRef Content = "content of target";
+  EXPECT_TRUE(FS.addFile(Target, 0, MemoryBuffer::getMemBuffer(Content)));
+  EXPECT_TRUE(FS.addHardLink(Link, Target));
+  EXPECT_TRUE(FS.addFile(Link, 0, MemoryBuffer::getMemBuffer(Content)));
+}
+
+TEST_F(InMemoryFileSystemTest, AddFileInPlaceOfAHardLinkWithDifferentContent) {
+  StringRef Link = "/path/to/link";
+  StringRef Target = "/path/to/target";
+  StringRef Content = "content of target";
+  StringRef LinkContent = "different content of link";
+  EXPECT_TRUE(FS.addFile(Target, 0, MemoryBuffer::getMemBuffer(Content)));
+  EXPECT_TRUE(FS.addHardLink(Link, Target));
+  EXPECT_FALSE(FS.addFile(Link, 0, MemoryBuffer::getMemBuffer(LinkContent)));
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkToADirectory) {
+  StringRef Dir = "path/to/dummy/dir";
+  StringRef Link = "/path/to/link";
+  StringRef File = "path/to/dummy/dir/target";
+  StringRef Content = "content of target";
+  EXPECT_TRUE(FS.addFile(File, 0, MemoryBuffer::getMemBuffer(Content)));
+  EXPECT_FALSE(FS.addHardLink(Link, Dir));
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkFromADirectory) {
+  StringRef Dir = "path/to/dummy/dir";
+  StringRef Target = "path/to/dummy/dir/target";
+  StringRef Content = "content of target";
+  EXPECT_TRUE(FS.addFile(Target, 0, MemoryBuffer::getMemBuffer(Content)));
+  EXPECT_FALSE(FS.addHardLink(Dir, Target));
+}
+
+TEST_F(InMemoryFileSystemTest, AddHardLinkUnderAFile) {
+  StringRef CommonContent = "content string";
+  FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer(CommonContent));
+  FS.addFile("/c/d", 0, MemoryBuffer::getMemBuffer(CommonContent));
+  EXPECT_FALSE(FS.addHardLink("/c/d/e", "/a/b"));
+}
+
+TEST_F(InMemoryFileSystemTest, RecursiveIterationWithHardLink) {
+  std::error_code EC;
+  FS.addFile("/a/b", 0, MemoryBuffer::getMemBuffer("content string"));
+  EXPECT_TRUE(FS.addHardLink("/c/d", "/a/b"));
+  auto I = vfs::recursive_directory_iterator(FS, "/", EC);
+  ASSERT_FALSE(EC);
+  std::vector<std::string> Nodes;
+  for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
+       I.increment(EC)) {
+    Nodes.push_back(getPosixPath(I->path()));
+  }
+  EXPECT_THAT(Nodes, testing::UnorderedElementsAre("/a", "/a/b", "/c", "/c/d"));
+}
+
+// NOTE: in the tests below, we use '//root/' as our root directory, since it is
+// a legal *absolute* path on Windows as well as *nix.
+class VFSFromYAMLTest : public ::testing::Test {
+public:
+  int NumDiagnostics;
+
+  void SetUp() override { NumDiagnostics = 0; }
+
+  static void CountingDiagHandler(const SMDiagnostic &, void *Context) {
+    VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context);
+    ++Test->NumDiagnostics;
+  }
+
+  IntrusiveRefCntPtr<vfs::FileSystem>
+  getFromYAMLRawString(StringRef Content,
+                       IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
+    std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(Content);
+    return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, "", this,
+                          ExternalFS);
+  }
+
+  IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString(
+      StringRef Content,
+      IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) {
+    std::string VersionPlusContent("{\n  'version':0,\n");
+    VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
+    return getFromYAMLRawString(VersionPlusContent, ExternalFS);
+  }
+
+  // This is intended as a "XFAIL" for windows hosts.
+  bool supportsSameDirMultipleYAMLEntries() {
+    Triple Host(Triple::normalize(sys::getProcessTriple()));
+    return !Host.isOSWindows();
+  }
+};
+
+TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
+  IntrusiveRefCntPtr<vfs::FileSystem> FS;
+  FS = getFromYAMLString("");
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("[]");
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("'string'");
+  EXPECT_EQ(nullptr, FS.get());
+  EXPECT_EQ(3, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, MappedFiles) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/foo/bar/a");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'file1',\n"
+      "                  'external-contents': '//root/foo/bar/a'\n"
+      "                },\n"
+      "                {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'file2',\n"
+      "                  'external-contents': '//root/foo/b'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  // file
+  ErrorOr<vfs::Status> S = O->status("//root/file1");
+  ASSERT_FALSE(S.getError());
+  EXPECT_EQ("//root/foo/bar/a", S->getName());
+  EXPECT_TRUE(S->IsVFSMapped);
+
+  ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
+  EXPECT_EQ("//root/foo/bar/a", SLower->getName());
+  EXPECT_TRUE(S->equivalent(*SLower));
+  EXPECT_FALSE(SLower->IsVFSMapped);
+
+  // file after opening
+  auto OpenedF = O->openFileForRead("//root/file1");
+  ASSERT_FALSE(OpenedF.getError());
+  auto OpenedS = (*OpenedF)->status();
+  ASSERT_FALSE(OpenedS.getError());
+  EXPECT_EQ("//root/foo/bar/a", OpenedS->getName());
+  EXPECT_TRUE(OpenedS->IsVFSMapped);
+
+  // directory
+  S = O->status("//root/");
+  ASSERT_FALSE(S.getError());
+  EXPECT_TRUE(S->isDirectory());
+  EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
+
+  // broken mapping
+  EXPECT_EQ(O->status("//root/file2").getError(),
+            llvm::errc::no_such_file_or_directory);
+  EXPECT_EQ(0, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, CaseInsensitive) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/foo/bar/a");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'case-sensitive': 'false',\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'XX',\n"
+      "                  'external-contents': '//root/foo/bar/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}]}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  ErrorOr<vfs::Status> S = O->status("//root/XX");
+  ASSERT_FALSE(S.getError());
+
+  ErrorOr<vfs::Status> SS = O->status("//root/xx");
+  ASSERT_FALSE(SS.getError());
+  EXPECT_TRUE(S->equivalent(*SS));
+  SS = O->status("//root/xX");
+  EXPECT_TRUE(S->equivalent(*SS));
+  SS = O->status("//root/Xx");
+  EXPECT_TRUE(S->equivalent(*SS));
+  EXPECT_EQ(0, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, CaseSensitive) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/foo/bar/a");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'case-sensitive': 'true',\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'XX',\n"
+      "                  'external-contents': '//root/foo/bar/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}]}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  ErrorOr<vfs::Status> SS = O->status("//root/xx");
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
+  SS = O->status("//root/xX");
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
+  SS = O->status("//root/Xx");
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
+  EXPECT_EQ(0, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+
+  // invalid YAML at top-level
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  // invalid YAML in roots
+  FS = getFromYAMLString("{ 'roots':[}", Lower);
+  // invalid YAML in directory
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // invalid configuration
+  FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // invalid roots
+  FS = getFromYAMLString("{ 'roots':'' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'roots':{} }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // invalid entries
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
+                         "'external-contents': 'other' }",
+                         Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // missing mandatory fields
+  FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // duplicate keys
+  FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS =
+      getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
+                        "'external-contents':'blah' } ] }",
+                        Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // missing version
+  FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // bad version number
+  FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  EXPECT_EQ(24, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, UseExternalName) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/external/file");
+
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+      getFromYAMLString("{ 'roots': [\n"
+                        "  { 'type': 'file', 'name': '//root/A',\n"
+                        "    'external-contents': '//root/external/file'\n"
+                        "  },\n"
+                        "  { 'type': 'file', 'name': '//root/B',\n"
+                        "    'use-external-name': true,\n"
+                        "    'external-contents': '//root/external/file'\n"
+                        "  },\n"
+                        "  { 'type': 'file', 'name': '//root/C',\n"
+                        "    'use-external-name': false,\n"
+                        "    'external-contents': '//root/external/file'\n"
+                        "  }\n"
+                        "] }",
+                        Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+
+  // default true
+  EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
+  // explicit
+  EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
+  EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
+
+  // global configuration
+  FS = getFromYAMLString("{ 'use-external-names': false,\n"
+                         "  'roots': [\n"
+                         "  { 'type': 'file', 'name': '//root/A',\n"
+                         "    'external-contents': '//root/external/file'\n"
+                         "  },\n"
+                         "  { 'type': 'file', 'name': '//root/B',\n"
+                         "    'use-external-name': true,\n"
+                         "    'external-contents': '//root/external/file'\n"
+                         "  },\n"
+                         "  { 'type': 'file', 'name': '//root/C',\n"
+                         "    'use-external-name': false,\n"
+                         "    'external-contents': '//root/external/file'\n"
+                         "  }\n"
+                         "] }",
+                         Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+
+  // default
+  EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
+  // explicit
+  EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
+  EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
+}
+
+TEST_F(VFSFromYAMLTest, MultiComponentPath) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/other");
+
+  // file in roots
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+      getFromYAMLString("{ 'roots': [\n"
+                        "  { 'type': 'file', 'name': '//root/path/to/file',\n"
+                        "    'external-contents': '//root/other' }]\n"
+                        "}",
+                        Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+
+  // at the start
+  FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': '//root/path/to',\n"
+      "    'contents': [ { 'type': 'file', 'name': 'file',\n"
+      "                    'external-contents': '//root/other' }]}]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+
+  // at the end
+  FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': '//root/',\n"
+      "    'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
+      "                    'external-contents': '//root/other' }]}]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+}
+
+TEST_F(VFSFromYAMLTest, TrailingSlashes) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/other");
+
+  // file in roots
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': '//root/path/to////',\n"
+      "    'contents': [ { 'type': 'file', 'name': 'file',\n"
+      "                    'external-contents': '//root/other' }]}]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+}
+
+TEST_F(VFSFromYAMLTest, DirectoryIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addDirectory("//root/foo");
+  Lower->addDirectory("//root/foo/bar");
+  Lower->addRegularFile("//root/foo/bar/a");
+  Lower->addRegularFile("//root/foo/bar/b");
+  Lower->addRegularFile("//root/file3");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'file1',\n"
+      "                  'external-contents': '//root/foo/bar/a'\n"
+      "                },\n"
+      "                {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'file2',\n"
+      "                  'external-contents': '//root/foo/bar/b'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("//root/", EC),
+                {"//root/file1", "//root/file2", "//root/file3", "//root/foo"});
+
+  checkContents(O->dir_begin("//root/foo/bar", EC),
+                {"//root/foo/bar/a", "//root/foo/bar/b"});
+}
+
+TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) {
+  // https://llvm.org/bugs/show_bug.cgi?id=27725
+  if (!supportsSameDirMultipleYAMLEntries())
+    return;
+
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/zab");
+  Lower->addDirectory("//root/baz");
+  Lower->addRegularFile("//root/zab/a");
+  Lower->addRegularFile("//root/zab/b");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/baz/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'x',\n"
+      "                  'external-contents': '//root/zab/a'\n"
+      "                }\n"
+      "              ]\n"
+      "},\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/baz/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'y',\n"
+      "                  'external-contents': '//root/zab/b'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  std::error_code EC;
+
+  checkContents(O->dir_begin("//root/baz/", EC),
+                {"//root/baz/x", "//root/baz/y"});
+}
+
+TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) {
+
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/a");
+  Lower->addDirectory("//root/a/b");
+  Lower->addDirectory("//root/a/b/c");
+  Lower->addRegularFile("//root/a/b/c/file");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/a/b/c/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'file',\n"
+      "                  'external-contents': '//root/a/b/c/file'\n"
+      "                }\n"
+      "              ]\n"
+      "},\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  std::error_code EC;
+
+  // Test recursive_directory_iterator level()
+  vfs::recursive_directory_iterator I = vfs::recursive_directory_iterator(
+                                        *O, "//root", EC),
+                                    E;
+  ASSERT_FALSE(EC);
+  for (int l = 0; I != E; I.increment(EC), ++l) {
+    ASSERT_FALSE(EC);
+    EXPECT_EQ(I.level(), l);
+  }
+  EXPECT_EQ(I, E);
+}
+
+TEST_F(VFSFromYAMLTest, RelativePaths) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  // Filename at root level without a parent directory.
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'file', 'name': 'file-not-in-directory.h',\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  }\n"
+      "] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // Relative file path.
+  FS = getFromYAMLString("{ 'roots': [\n"
+                         "  { 'type': 'file', 'name': 'relative/file/path.h',\n"
+                         "    'external-contents': '//root/external/file'\n"
+                         "  }\n"
+                         "] }",
+                         Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // Relative directory path.
+  FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': 'relative/directory/path.h',\n"
+      "    'contents': []\n"
+      "  }\n"
+      "] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  EXPECT_EQ(3, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, NonFallthroughDirectoryIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addRegularFile("//root/a");
+  Lower->addRegularFile("//root/b");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'fallthrough': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'c',\n"
+      "                  'external-contents': '//root/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  std::error_code EC;
+  checkContents(FS->dir_begin("//root/", EC),
+                {"//root/c"});
+}
+
+TEST_F(VFSFromYAMLTest, DirectoryIterationWithDuplicates) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addRegularFile("//root/a");
+  Lower->addRegularFile("//root/b");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'a',\n"
+      "                  'external-contents': '//root/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+	  Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  std::error_code EC;
+  checkContents(FS->dir_begin("//root/", EC),
+                {"//root/a", "//root/b"});
+}
+
+TEST_F(VFSFromYAMLTest, DirectoryIterationErrorInVFSLayer) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addDirectory("//root/foo");
+  Lower->addRegularFile("//root/foo/a");
+  Lower->addRegularFile("//root/foo/b");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'bar/a',\n"
+      "                  'external-contents': '//root/foo/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  std::error_code EC;
+  checkContents(FS->dir_begin("//root/foo", EC),
+                {"//root/foo/a", "//root/foo/b"});
+}
+
+TEST_F(VFSFromYAMLTest, GetRealPath) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//dir/");
+  Lower->addRegularFile("/foo");
+  Lower->addSymlink("/link");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'bar',\n"
+      "                  'external-contents': '/link'\n"
+      "                }\n"
+      "              ]\n"
+      "},\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//dir/',\n"
+      "  'contents': []\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  // Regular file present in underlying file system.
+  SmallString<16> RealPath;
+  EXPECT_FALSE(FS->getRealPath("/foo", RealPath));
+  EXPECT_EQ(RealPath.str(), "/foo");
+
+  // File present in YAML pointing to symlink in underlying file system.
+  EXPECT_FALSE(FS->getRealPath("//root/bar", RealPath));
+  EXPECT_EQ(RealPath.str(), "/symlink");
+
+  // Directories should fall back to the underlying file system is possible.
+  EXPECT_FALSE(FS->getRealPath("//dir/", RealPath));
+  EXPECT_EQ(RealPath.str(), "//dir/");
+
+  // Try a non-existing file.
+  EXPECT_EQ(FS->getRealPath("/non_existing", RealPath),
+            errc::no_such_file_or_directory);
+}
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
new file mode 100644
index 0000000..17f38f9
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
@@ -0,0 +1,2877 @@
+//===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using llvm::yaml::Hex16;
+using llvm::yaml::Hex32;
+using llvm::yaml::Hex64;
+using llvm::yaml::Hex8;
+using llvm::yaml::Input;
+using llvm::yaml::IO;
+using llvm::yaml::isNumeric;
+using llvm::yaml::MappingNormalization;
+using llvm::yaml::MappingTraits;
+using llvm::yaml::Output;
+using llvm::yaml::ScalarTraits;
+using ::testing::StartsWith;
+
+
+
+
+static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//  Test MappingTraits
+//===----------------------------------------------------------------------===//
+
+struct FooBar {
+  int foo;
+  int bar;
+};
+typedef std::vector<FooBar> FooBarSequence;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
+
+struct FooBarContainer {
+  FooBarSequence fbs;
+};
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<FooBar> {
+    static void mapping(IO &io, FooBar& fb) {
+      io.mapRequired("foo",    fb.foo);
+      io.mapRequired("bar",    fb.bar);
+    }
+  };
+
+  template <> struct MappingTraits<FooBarContainer> {
+    static void mapping(IO &io, FooBarContainer &fb) {
+      io.mapRequired("fbs", fb.fbs);
+    }
+  };
+}
+}
+
+
+//
+// Test the reading of a yaml mapping
+//
+TEST(YAMLIO, TestMapRead) {
+  FooBar doc;
+  {
+    Input yin("---\nfoo:  3\nbar:  5\n...\n");
+    yin >> doc;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(doc.foo, 3);
+    EXPECT_EQ(doc.bar, 5);
+  }
+
+  {
+    Input yin("{foo: 3, bar: 5}");
+    yin >> doc;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(doc.foo, 3);
+    EXPECT_EQ(doc.bar, 5);
+  }
+}
+
+TEST(YAMLIO, TestMalformedMapRead) {
+  FooBar doc;
+  Input yin("{foo: 3; bar: 5}", nullptr, suppressErrorMessages);
+  yin >> doc;
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test the reading of a yaml sequence of mappings
+//
+TEST(YAMLIO, TestSequenceMapRead) {
+  FooBarSequence seq;
+  Input yin("---\n - foo:  3\n   bar:  5\n - foo:  7\n   bar:  9\n...\n");
+  yin >> seq;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(seq.size(), 2UL);
+  FooBar& map1 = seq[0];
+  FooBar& map2 = seq[1];
+  EXPECT_EQ(map1.foo, 3);
+  EXPECT_EQ(map1.bar, 5);
+  EXPECT_EQ(map2.foo, 7);
+  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
+//
+TEST(YAMLIO, TestSequenceMapWriteAndRead) {
+  std::string intermediate;
+  {
+    FooBar entry1;
+    entry1.foo = 10;
+    entry1.bar = -3;
+    FooBar entry2;
+    entry2.foo = 257;
+    entry2.bar = 0;
+    FooBarSequence seq;
+    seq.push_back(entry1);
+    seq.push_back(entry2);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << seq;
+  }
+
+  {
+    Input yin(intermediate);
+    FooBarSequence seq2;
+    yin >> seq2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(seq2.size(), 2UL);
+    FooBar& map1 = seq2[0];
+    FooBar& map2 = seq2[1];
+    EXPECT_EQ(map1.foo, 10);
+    EXPECT_EQ(map1.bar, -3);
+    EXPECT_EQ(map2.foo, 257);
+    EXPECT_EQ(map2.bar, 0);
+  }
+}
+
+//
+// Test YAML filename handling.
+//
+static void testErrorFilename(const llvm::SMDiagnostic &Error, void *) {
+  EXPECT_EQ(Error.getFilename(), "foo.yaml");
+}
+
+TEST(YAMLIO, TestGivenFilename) {
+  auto Buffer = llvm::MemoryBuffer::getMemBuffer("{ x: 42 }", "foo.yaml");
+  Input yin(*Buffer, nullptr, testErrorFilename);
+  FooBar Value;
+  yin >> Value;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+struct WithStringField {
+  std::string str1;
+  std::string str2;
+  std::string str3;
+};
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<WithStringField> {
+  static void mapping(IO &io, WithStringField &fb) {
+    io.mapRequired("str1", fb.str1);
+    io.mapRequired("str2", fb.str2);
+    io.mapRequired("str3", fb.str3);
+  }
+};
+} // namespace yaml
+} // namespace llvm
+
+TEST(YAMLIO, MultilineStrings) {
+  WithStringField Original;
+  Original.str1 = "a multiline string\nfoobarbaz";
+  Original.str2 = "another one\rfoobarbaz";
+  Original.str3 = "a one-line string";
+
+  std::string Serialized;
+  {
+    llvm::raw_string_ostream OS(Serialized);
+    Output YOut(OS);
+    YOut << Original;
+  }
+  auto Expected = "---\n"
+                  "str1:            'a multiline string\n"
+                  "foobarbaz'\n"
+                  "str2:            'another one\r"
+                  "foobarbaz'\n"
+                  "str3:            a one-line string\n"
+                  "...\n";
+  ASSERT_EQ(Serialized, Expected);
+
+  // Also check it parses back without the errors.
+  WithStringField Deserialized;
+  {
+    Input YIn(Serialized);
+    YIn >> Deserialized;
+    ASSERT_FALSE(YIn.error())
+        << "Parsing error occurred during deserialization. Serialized string:\n"
+        << Serialized;
+  }
+  EXPECT_EQ(Original.str1, Deserialized.str1);
+  EXPECT_EQ(Original.str2, Deserialized.str2);
+  EXPECT_EQ(Original.str3, Deserialized.str3);
+}
+
+TEST(YAMLIO, NoQuotesForTab) {
+  WithStringField WithTab;
+  WithTab.str1 = "aba\tcaba";
+  std::string Serialized;
+  {
+    llvm::raw_string_ostream OS(Serialized);
+    Output YOut(OS);
+    YOut << WithTab;
+  }
+  auto ExpectedPrefix = "---\n"
+                        "str1:            aba\tcaba\n";
+  EXPECT_THAT(Serialized, StartsWith(ExpectedPrefix));
+}
+
+//===----------------------------------------------------------------------===//
+//  Test built-in types
+//===----------------------------------------------------------------------===//
+
+struct BuiltInTypes {
+  llvm::StringRef str;
+  std::string stdstr;
+  uint64_t        u64;
+  uint32_t        u32;
+  uint16_t        u16;
+  uint8_t         u8;
+  bool            b;
+  int64_t         s64;
+  int32_t         s32;
+  int16_t         s16;
+  int8_t          s8;
+  float           f;
+  double          d;
+  Hex8            h8;
+  Hex16           h16;
+  Hex32           h32;
+  Hex64           h64;
+};
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<BuiltInTypes> {
+    static void mapping(IO &io, BuiltInTypes& bt) {
+      io.mapRequired("str",      bt.str);
+      io.mapRequired("stdstr",   bt.stdstr);
+      io.mapRequired("u64",      bt.u64);
+      io.mapRequired("u32",      bt.u32);
+      io.mapRequired("u16",      bt.u16);
+      io.mapRequired("u8",       bt.u8);
+      io.mapRequired("b",        bt.b);
+      io.mapRequired("s64",      bt.s64);
+      io.mapRequired("s32",      bt.s32);
+      io.mapRequired("s16",      bt.s16);
+      io.mapRequired("s8",       bt.s8);
+      io.mapRequired("f",        bt.f);
+      io.mapRequired("d",        bt.d);
+      io.mapRequired("h8",       bt.h8);
+      io.mapRequired("h16",      bt.h16);
+      io.mapRequired("h32",      bt.h32);
+      io.mapRequired("h64",      bt.h64);
+    }
+  };
+}
+}
+
+
+//
+// Test the reading of all built-in scalar conversions
+//
+TEST(YAMLIO, TestReadBuiltInTypes) {
+  BuiltInTypes map;
+  Input yin("---\n"
+            "str:      hello there\n"
+            "stdstr:   hello where?\n"
+            "u64:      5000000000\n"
+            "u32:      4000000000\n"
+            "u16:      65000\n"
+            "u8:       255\n"
+            "b:        false\n"
+            "s64:      -5000000000\n"
+            "s32:      -2000000000\n"
+            "s16:      -32000\n"
+            "s8:       -127\n"
+            "f:        137.125\n"
+            "d:        -2.8625\n"
+            "h8:       0xFF\n"
+            "h16:      0x8765\n"
+            "h32:      0xFEDCBA98\n"
+            "h64:      0xFEDCBA9876543210\n"
+           "...\n");
+  yin >> map;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_TRUE(map.str.equals("hello there"));
+  EXPECT_TRUE(map.stdstr == "hello where?");
+  EXPECT_EQ(map.u64, 5000000000ULL);
+  EXPECT_EQ(map.u32, 4000000000U);
+  EXPECT_EQ(map.u16, 65000);
+  EXPECT_EQ(map.u8,  255);
+  EXPECT_EQ(map.b,   false);
+  EXPECT_EQ(map.s64, -5000000000LL);
+  EXPECT_EQ(map.s32, -2000000000L);
+  EXPECT_EQ(map.s16, -32000);
+  EXPECT_EQ(map.s8,  -127);
+  EXPECT_EQ(map.f,   137.125);
+  EXPECT_EQ(map.d,   -2.8625);
+  EXPECT_EQ(map.h8,  Hex8(255));
+  EXPECT_EQ(map.h16, Hex16(0x8765));
+  EXPECT_EQ(map.h32, Hex32(0xFEDCBA98));
+  EXPECT_EQ(map.h64, Hex64(0xFEDCBA9876543210LL));
+}
+
+
+//
+// Test writing then reading back all built-in scalar types
+//
+TEST(YAMLIO, TestReadWriteBuiltInTypes) {
+  std::string intermediate;
+  {
+    BuiltInTypes map;
+    map.str = "one two";
+    map.stdstr = "three four";
+    map.u64 = 6000000000ULL;
+    map.u32 = 3000000000U;
+    map.u16 = 50000;
+    map.u8  = 254;
+    map.b   = true;
+    map.s64 = -6000000000LL;
+    map.s32 = -2000000000;
+    map.s16 = -32000;
+    map.s8  = -128;
+    map.f   = 3.25;
+    map.d   = -2.8625;
+    map.h8  = 254;
+    map.h16 = 50000;
+    map.h32 = 3000000000U;
+    map.h64 = 6000000000LL;
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+  }
+
+  {
+    Input yin(intermediate);
+    BuiltInTypes map;
+    yin >> map;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_TRUE(map.str.equals("one two"));
+    EXPECT_TRUE(map.stdstr == "three four");
+    EXPECT_EQ(map.u64,      6000000000ULL);
+    EXPECT_EQ(map.u32,      3000000000U);
+    EXPECT_EQ(map.u16,      50000);
+    EXPECT_EQ(map.u8,       254);
+    EXPECT_EQ(map.b,        true);
+    EXPECT_EQ(map.s64,      -6000000000LL);
+    EXPECT_EQ(map.s32,      -2000000000L);
+    EXPECT_EQ(map.s16,      -32000);
+    EXPECT_EQ(map.s8,       -128);
+    EXPECT_EQ(map.f,        3.25);
+    EXPECT_EQ(map.d,        -2.8625);
+    EXPECT_EQ(map.h8,       Hex8(254));
+    EXPECT_EQ(map.h16,      Hex16(50000));
+    EXPECT_EQ(map.h32,      Hex32(3000000000U));
+    EXPECT_EQ(map.h64,      Hex64(6000000000LL));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//  Test endian-aware types
+//===----------------------------------------------------------------------===//
+
+struct EndianTypes {
+  typedef llvm::support::detail::packed_endian_specific_integral<
+      float, llvm::support::little, llvm::support::unaligned>
+      ulittle_float;
+  typedef llvm::support::detail::packed_endian_specific_integral<
+      double, llvm::support::little, llvm::support::unaligned>
+      ulittle_double;
+
+  llvm::support::ulittle64_t u64;
+  llvm::support::ulittle32_t u32;
+  llvm::support::ulittle16_t u16;
+  llvm::support::little64_t s64;
+  llvm::support::little32_t s32;
+  llvm::support::little16_t s16;
+  ulittle_float f;
+  ulittle_double d;
+};
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<EndianTypes> {
+  static void mapping(IO &io, EndianTypes &et) {
+    io.mapRequired("u64", et.u64);
+    io.mapRequired("u32", et.u32);
+    io.mapRequired("u16", et.u16);
+    io.mapRequired("s64", et.s64);
+    io.mapRequired("s32", et.s32);
+    io.mapRequired("s16", et.s16);
+    io.mapRequired("f", et.f);
+    io.mapRequired("d", et.d);
+  }
+};
+}
+}
+
+//
+// Test the reading of all endian scalar conversions
+//
+TEST(YAMLIO, TestReadEndianTypes) {
+  EndianTypes map;
+  Input yin("---\n"
+            "u64:      5000000000\n"
+            "u32:      4000000000\n"
+            "u16:      65000\n"
+            "s64:      -5000000000\n"
+            "s32:      -2000000000\n"
+            "s16:      -32000\n"
+            "f:        3.25\n"
+            "d:        -2.8625\n"
+            "...\n");
+  yin >> map;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(map.u64, 5000000000ULL);
+  EXPECT_EQ(map.u32, 4000000000U);
+  EXPECT_EQ(map.u16, 65000);
+  EXPECT_EQ(map.s64, -5000000000LL);
+  EXPECT_EQ(map.s32, -2000000000L);
+  EXPECT_EQ(map.s16, -32000);
+  EXPECT_EQ(map.f, 3.25f);
+  EXPECT_EQ(map.d, -2.8625);
+}
+
+//
+// Test writing then reading back all endian-aware scalar types
+//
+TEST(YAMLIO, TestReadWriteEndianTypes) {
+  std::string intermediate;
+  {
+    EndianTypes map;
+    map.u64 = 6000000000ULL;
+    map.u32 = 3000000000U;
+    map.u16 = 50000;
+    map.s64 = -6000000000LL;
+    map.s32 = -2000000000;
+    map.s16 = -32000;
+    map.f = 3.25f;
+    map.d = -2.8625;
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+  }
+
+  {
+    Input yin(intermediate);
+    EndianTypes map;
+    yin >> map;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(map.u64, 6000000000ULL);
+    EXPECT_EQ(map.u32, 3000000000U);
+    EXPECT_EQ(map.u16, 50000);
+    EXPECT_EQ(map.s64, -6000000000LL);
+    EXPECT_EQ(map.s32, -2000000000L);
+    EXPECT_EQ(map.s16, -32000);
+    EXPECT_EQ(map.f, 3.25f);
+    EXPECT_EQ(map.d, -2.8625);
+  }
+}
+
+struct StringTypes {
+  llvm::StringRef str1;
+  llvm::StringRef str2;
+  llvm::StringRef str3;
+  llvm::StringRef str4;
+  llvm::StringRef str5;
+  llvm::StringRef str6;
+  llvm::StringRef str7;
+  llvm::StringRef str8;
+  llvm::StringRef str9;
+  llvm::StringRef str10;
+  llvm::StringRef str11;
+  std::string stdstr1;
+  std::string stdstr2;
+  std::string stdstr3;
+  std::string stdstr4;
+  std::string stdstr5;
+  std::string stdstr6;
+  std::string stdstr7;
+  std::string stdstr8;
+  std::string stdstr9;
+  std::string stdstr10;
+  std::string stdstr11;
+  std::string stdstr12;
+};
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<StringTypes> {
+    static void mapping(IO &io, StringTypes& st) {
+      io.mapRequired("str1",      st.str1);
+      io.mapRequired("str2",      st.str2);
+      io.mapRequired("str3",      st.str3);
+      io.mapRequired("str4",      st.str4);
+      io.mapRequired("str5",      st.str5);
+      io.mapRequired("str6",      st.str6);
+      io.mapRequired("str7",      st.str7);
+      io.mapRequired("str8",      st.str8);
+      io.mapRequired("str9",      st.str9);
+      io.mapRequired("str10",     st.str10);
+      io.mapRequired("str11",     st.str11);
+      io.mapRequired("stdstr1",   st.stdstr1);
+      io.mapRequired("stdstr2",   st.stdstr2);
+      io.mapRequired("stdstr3",   st.stdstr3);
+      io.mapRequired("stdstr4",   st.stdstr4);
+      io.mapRequired("stdstr5",   st.stdstr5);
+      io.mapRequired("stdstr6",   st.stdstr6);
+      io.mapRequired("stdstr7",   st.stdstr7);
+      io.mapRequired("stdstr8",   st.stdstr8);
+      io.mapRequired("stdstr9",   st.stdstr9);
+      io.mapRequired("stdstr10",  st.stdstr10);
+      io.mapRequired("stdstr11",  st.stdstr11);
+      io.mapRequired("stdstr12",  st.stdstr12);
+    }
+  };
+}
+}
+
+TEST(YAMLIO, TestReadWriteStringTypes) {
+  std::string intermediate;
+  {
+    StringTypes map;
+    map.str1 = "'aaa";
+    map.str2 = "\"bbb";
+    map.str3 = "`ccc";
+    map.str4 = "@ddd";
+    map.str5 = "";
+    map.str6 = "0000000004000000";
+    map.str7 = "true";
+    map.str8 = "FALSE";
+    map.str9 = "~";
+    map.str10 = "0.2e20";
+    map.str11 = "0x30";
+    map.stdstr1 = "'eee";
+    map.stdstr2 = "\"fff";
+    map.stdstr3 = "`ggg";
+    map.stdstr4 = "@hhh";
+    map.stdstr5 = "";
+    map.stdstr6 = "0000000004000000";
+    map.stdstr7 = "true";
+    map.stdstr8 = "FALSE";
+    map.stdstr9 = "~";
+    map.stdstr10 = "0.2e20";
+    map.stdstr11 = "0x30";
+    map.stdstr12 = "- match";
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+  }
+
+  llvm::StringRef flowOut(intermediate);
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'''aaa"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'\"bbb'"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
+  EXPECT_NE(llvm::StringRef::npos, flowOut.find("'- match'\n"));
+  EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
+  EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
+  EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
+  EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
+  EXPECT_NE(std::string::npos, flowOut.find("''\n"));
+  EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
+
+  {
+    Input yin(intermediate);
+    StringTypes map;
+    yin >> map;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_TRUE(map.str1.equals("'aaa"));
+    EXPECT_TRUE(map.str2.equals("\"bbb"));
+    EXPECT_TRUE(map.str3.equals("`ccc"));
+    EXPECT_TRUE(map.str4.equals("@ddd"));
+    EXPECT_TRUE(map.str5.equals(""));
+    EXPECT_TRUE(map.str6.equals("0000000004000000"));
+    EXPECT_TRUE(map.stdstr1 == "'eee");
+    EXPECT_TRUE(map.stdstr2 == "\"fff");
+    EXPECT_TRUE(map.stdstr3 == "`ggg");
+    EXPECT_TRUE(map.stdstr4 == "@hhh");
+    EXPECT_TRUE(map.stdstr5 == "");
+    EXPECT_TRUE(map.stdstr6 == "0000000004000000");
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//  Test ScalarEnumerationTraits
+//===----------------------------------------------------------------------===//
+
+enum Colors {
+    cRed,
+    cBlue,
+    cGreen,
+    cYellow
+};
+
+struct ColorMap {
+  Colors      c1;
+  Colors      c2;
+  Colors      c3;
+  Colors      c4;
+  Colors      c5;
+  Colors      c6;
+};
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct ScalarEnumerationTraits<Colors> {
+    static void enumeration(IO &io, Colors &value) {
+      io.enumCase(value, "red",   cRed);
+      io.enumCase(value, "blue",  cBlue);
+      io.enumCase(value, "green", cGreen);
+      io.enumCase(value, "yellow",cYellow);
+    }
+  };
+  template <>
+  struct MappingTraits<ColorMap> {
+    static void mapping(IO &io, ColorMap& c) {
+      io.mapRequired("c1", c.c1);
+      io.mapRequired("c2", c.c2);
+      io.mapRequired("c3", c.c3);
+      io.mapOptional("c4", c.c4, cBlue);   // supplies default
+      io.mapOptional("c5", c.c5, cYellow); // supplies default
+      io.mapOptional("c6", c.c6, cRed);    // supplies default
+    }
+  };
+}
+}
+
+
+//
+// Test reading enumerated scalars
+//
+TEST(YAMLIO, TestEnumRead) {
+  ColorMap map;
+  Input yin("---\n"
+            "c1:  blue\n"
+            "c2:  red\n"
+            "c3:  green\n"
+            "c5:  yellow\n"
+            "...\n");
+  yin >> map;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(cBlue,  map.c1);
+  EXPECT_EQ(cRed,   map.c2);
+  EXPECT_EQ(cGreen, map.c3);
+  EXPECT_EQ(cBlue,  map.c4);  // tests default
+  EXPECT_EQ(cYellow,map.c5);  // tests overridden
+  EXPECT_EQ(cRed,   map.c6);  // tests default
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//  Test ScalarBitSetTraits
+//===----------------------------------------------------------------------===//
+
+enum MyFlags {
+  flagNone    = 0,
+  flagBig     = 1 << 0,
+  flagFlat    = 1 << 1,
+  flagRound   = 1 << 2,
+  flagPointy  = 1 << 3
+};
+inline MyFlags operator|(MyFlags a, MyFlags b) {
+  return static_cast<MyFlags>(
+                      static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
+}
+
+struct FlagsMap {
+  MyFlags     f1;
+  MyFlags     f2;
+  MyFlags     f3;
+  MyFlags     f4;
+};
+
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct ScalarBitSetTraits<MyFlags> {
+    static void bitset(IO &io, MyFlags &value) {
+      io.bitSetCase(value, "big",   flagBig);
+      io.bitSetCase(value, "flat",  flagFlat);
+      io.bitSetCase(value, "round", flagRound);
+      io.bitSetCase(value, "pointy",flagPointy);
+    }
+  };
+  template <>
+  struct MappingTraits<FlagsMap> {
+    static void mapping(IO &io, FlagsMap& c) {
+      io.mapRequired("f1", c.f1);
+      io.mapRequired("f2", c.f2);
+      io.mapRequired("f3", c.f3);
+      io.mapOptional("f4", c.f4, MyFlags(flagRound));
+     }
+  };
+}
+}
+
+
+//
+// Test reading flow sequence representing bit-mask values
+//
+TEST(YAMLIO, TestFlagsRead) {
+  FlagsMap map;
+  Input yin("---\n"
+            "f1:  [ big ]\n"
+            "f2:  [ round, flat ]\n"
+            "f3:  []\n"
+            "...\n");
+  yin >> map;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(flagBig,              map.f1);
+  EXPECT_EQ(flagRound|flagFlat,   map.f2);
+  EXPECT_EQ(flagNone,             map.f3);  // check empty set
+  EXPECT_EQ(flagRound,            map.f4);  // check optional key
+}
+
+
+//
+// Test writing then reading back bit-mask values
+//
+TEST(YAMLIO, TestReadWriteFlags) {
+  std::string intermediate;
+  {
+    FlagsMap map;
+    map.f1 = flagBig;
+    map.f2 = flagRound | flagFlat;
+    map.f3 = flagNone;
+    map.f4 = flagNone;
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+  }
+
+  {
+    Input yin(intermediate);
+    FlagsMap map2;
+    yin >> map2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(flagBig,              map2.f1);
+    EXPECT_EQ(flagRound|flagFlat,   map2.f2);
+    EXPECT_EQ(flagNone,             map2.f3);
+    //EXPECT_EQ(flagRound,            map2.f4);  // check optional key
+  }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//  Test ScalarTraits
+//===----------------------------------------------------------------------===//
+
+struct MyCustomType {
+  int length;
+  int width;
+};
+
+struct MyCustomTypeMap {
+  MyCustomType     f1;
+  MyCustomType     f2;
+  int              f3;
+};
+
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<MyCustomTypeMap> {
+    static void mapping(IO &io, MyCustomTypeMap& s) {
+      io.mapRequired("f1", s.f1);
+      io.mapRequired("f2", s.f2);
+      io.mapRequired("f3", s.f3);
+     }
+  };
+  // MyCustomType is formatted as a yaml scalar.  A value of
+  // {length=3, width=4} would be represented in yaml as "3 by 4".
+  template<>
+  struct ScalarTraits<MyCustomType> {
+    static void output(const MyCustomType &value, void* ctxt, llvm::raw_ostream &out) {
+      out << llvm::format("%d by %d", value.length, value.width);
+    }
+    static StringRef input(StringRef scalar, void* ctxt, MyCustomType &value) {
+      size_t byStart = scalar.find("by");
+      if ( byStart != StringRef::npos ) {
+        StringRef lenStr = scalar.slice(0, byStart);
+        lenStr = lenStr.rtrim();
+        if ( lenStr.getAsInteger(0, value.length) ) {
+          return "malformed length";
+        }
+        StringRef widthStr = scalar.drop_front(byStart+2);
+        widthStr = widthStr.ltrim();
+        if ( widthStr.getAsInteger(0, value.width) ) {
+          return "malformed width";
+        }
+        return StringRef();
+      }
+      else {
+          return "malformed by";
+      }
+    }
+    static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
+  };
+}
+}
+
+
+//
+// Test writing then reading back custom values
+//
+TEST(YAMLIO, TestReadWriteMyCustomType) {
+  std::string intermediate;
+  {
+    MyCustomTypeMap map;
+    map.f1.length = 1;
+    map.f1.width  = 4;
+    map.f2.length = 100;
+    map.f2.width  = 400;
+    map.f3 = 10;
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+  }
+
+  {
+    Input yin(intermediate);
+    MyCustomTypeMap map2;
+    yin >> map2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(1,      map2.f1.length);
+    EXPECT_EQ(4,      map2.f1.width);
+    EXPECT_EQ(100,    map2.f2.length);
+    EXPECT_EQ(400,    map2.f2.width);
+    EXPECT_EQ(10,     map2.f3);
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+//  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
+//===----------------------------------------------------------------------===//
+
+LLVM_YAML_STRONG_TYPEDEF(int, MyNumber)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber)
+LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, MyString)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyString)
+
+namespace llvm {
+namespace yaml {
+  template<>
+  struct ScalarTraits<MyNumber> {
+    static void output(const MyNumber &value, void *, llvm::raw_ostream &out) {
+      out << value;
+    }
+
+    static StringRef input(StringRef scalar, void *, MyNumber &value) {
+      long long n;
+      if ( getAsSignedInteger(scalar, 0, n) )
+        return "invalid number";
+      value = n;
+      return StringRef();
+    }
+
+    static QuotingType mustQuote(StringRef) { return QuotingType::None; }
+  };
+
+  template <> struct ScalarTraits<MyString> {
+    using Impl = ScalarTraits<StringRef>;
+    static void output(const MyString &V, void *Ctx, raw_ostream &OS) {
+      Impl::output(V, Ctx, OS);
+    }
+    static StringRef input(StringRef S, void *Ctx, MyString &V) {
+      return Impl::input(S, Ctx, V.value);
+    }
+    static QuotingType mustQuote(StringRef S) {
+      return Impl::mustQuote(S);
+    }
+  };
+}
+}
+
+struct NameAndNumbers {
+  llvm::StringRef               name;
+  std::vector<MyString>         strings;
+  std::vector<MyNumber>         single;
+  std::vector<MyNumber>         numbers;
+};
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<NameAndNumbers> {
+    static void mapping(IO &io, NameAndNumbers& nn) {
+      io.mapRequired("name",     nn.name);
+      io.mapRequired("strings",  nn.strings);
+      io.mapRequired("single",   nn.single);
+      io.mapRequired("numbers",  nn.numbers);
+    }
+  };
+}
+}
+
+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
+//
+TEST(YAMLIO, TestReadWriteMyFlowSequence) {
+  std::string intermediate;
+  {
+    NameAndNumbers map;
+    map.name  = "hello";
+    map.strings.push_back(llvm::StringRef("one"));
+    map.strings.push_back(llvm::StringRef("two"));
+    map.single.push_back(1);
+    map.numbers.push_back(10);
+    map.numbers.push_back(-30);
+    map.numbers.push_back(1024);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << map;
+
+    // Verify sequences were written in flow style
+    ostr.flush();
+    llvm::StringRef flowOut(intermediate);
+    EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two"));
+    EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024"));
+  }
+
+  {
+    Input yin(intermediate);
+    NameAndNumbers map2;
+    yin >> map2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_TRUE(map2.name.equals("hello"));
+    EXPECT_EQ(map2.strings.size(), 2UL);
+    EXPECT_TRUE(map2.strings[0].value.equals("one"));
+    EXPECT_TRUE(map2.strings[1].value.equals("two"));
+    EXPECT_EQ(map2.single.size(), 1UL);
+    EXPECT_EQ(1,       map2.single[0]);
+    EXPECT_EQ(map2.numbers.size(), 3UL);
+    EXPECT_EQ(10,      map2.numbers[0]);
+    EXPECT_EQ(-30,     map2.numbers[1]);
+    EXPECT_EQ(1024,    map2.numbers[2]);
+  }
+}
+
+
+//
+// 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
+//===----------------------------------------------------------------------===//
+
+LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds)
+
+typedef std::vector<TotalSeconds> SecondsSequence;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
+
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<TotalSeconds> {
+
+    class NormalizedSeconds {
+    public:
+      NormalizedSeconds(IO &io)
+        : hours(0), minutes(0), seconds(0) {
+      }
+      NormalizedSeconds(IO &, TotalSeconds &secs)
+        : hours(secs/3600),
+          minutes((secs - (hours*3600))/60),
+          seconds(secs % 60) {
+      }
+      TotalSeconds denormalize(IO &) {
+        return TotalSeconds(hours*3600 + minutes*60 + seconds);
+      }
+
+      uint32_t     hours;
+      uint8_t      minutes;
+      uint8_t      seconds;
+    };
+
+    static void mapping(IO &io, TotalSeconds &secs) {
+      MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
+
+      io.mapOptional("hours",    keys->hours,    (uint32_t)0);
+      io.mapOptional("minutes",  keys->minutes,  (uint8_t)0);
+      io.mapRequired("seconds",  keys->seconds);
+    }
+  };
+}
+}
+
+
+//
+// Test the reading of a yaml sequence of mappings
+//
+TEST(YAMLIO, TestReadMySecondsSequence) {
+  SecondsSequence seq;
+  Input yin("---\n - hours:  1\n   seconds:  5\n - seconds:  59\n...\n");
+  yin >> seq;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(seq.size(), 2UL);
+  EXPECT_EQ(seq[0], 3605U);
+  EXPECT_EQ(seq[1], 59U);
+}
+
+
+//
+// Test writing then reading back custom values
+//
+TEST(YAMLIO, TestReadWriteMySecondsSequence) {
+  std::string intermediate;
+  {
+    SecondsSequence seq;
+    seq.push_back(4000);
+    seq.push_back(500);
+    seq.push_back(59);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << seq;
+  }
+  {
+    Input yin(intermediate);
+    SecondsSequence seq2;
+    yin >> seq2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(seq2.size(), 3UL);
+    EXPECT_EQ(seq2[0], 4000U);
+    EXPECT_EQ(seq2[1], 500U);
+    EXPECT_EQ(seq2[2], 59U);
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Test dynamic typing
+//===----------------------------------------------------------------------===//
+
+enum AFlags {
+    a1,
+    a2,
+    a3
+};
+
+enum BFlags {
+    b1,
+    b2,
+    b3
+};
+
+enum Kind {
+    kindA,
+    kindB
+};
+
+struct KindAndFlags {
+  KindAndFlags() : kind(kindA), flags(0) { }
+  KindAndFlags(Kind k, uint32_t f) : kind(k), flags(f) { }
+  Kind        kind;
+  uint32_t    flags;
+};
+
+typedef std::vector<KindAndFlags> KindAndFlagsSequence;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct ScalarEnumerationTraits<AFlags> {
+    static void enumeration(IO &io, AFlags &value) {
+      io.enumCase(value, "a1",  a1);
+      io.enumCase(value, "a2",  a2);
+      io.enumCase(value, "a3",  a3);
+    }
+  };
+  template <>
+  struct ScalarEnumerationTraits<BFlags> {
+    static void enumeration(IO &io, BFlags &value) {
+      io.enumCase(value, "b1",  b1);
+      io.enumCase(value, "b2",  b2);
+      io.enumCase(value, "b3",  b3);
+    }
+  };
+  template <>
+  struct ScalarEnumerationTraits<Kind> {
+    static void enumeration(IO &io, Kind &value) {
+      io.enumCase(value, "A",  kindA);
+      io.enumCase(value, "B",  kindB);
+    }
+  };
+  template <>
+  struct MappingTraits<KindAndFlags> {
+    static void mapping(IO &io, KindAndFlags& kf) {
+      io.mapRequired("kind",  kf.kind);
+      // Type of "flags" field varies depending on "kind" field.
+      // Use memcpy here to avoid breaking strict aliasing rules.
+      if (kf.kind == kindA) {
+        AFlags aflags = static_cast<AFlags>(kf.flags);
+        io.mapRequired("flags", aflags);
+        kf.flags = aflags;
+      } else {
+        BFlags bflags = static_cast<BFlags>(kf.flags);
+        io.mapRequired("flags", bflags);
+        kf.flags = bflags;
+      }
+    }
+  };
+}
+}
+
+
+//
+// Test the reading of a yaml sequence dynamic types
+//
+TEST(YAMLIO, TestReadKindAndFlagsSequence) {
+  KindAndFlagsSequence seq;
+  Input yin("---\n - kind:  A\n   flags:  a2\n - kind:  B\n   flags:  b1\n...\n");
+  yin >> seq;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(seq.size(), 2UL);
+  EXPECT_EQ(seq[0].kind,  kindA);
+  EXPECT_EQ(seq[0].flags, (uint32_t)a2);
+  EXPECT_EQ(seq[1].kind,  kindB);
+  EXPECT_EQ(seq[1].flags, (uint32_t)b1);
+}
+
+//
+// Test writing then reading back dynamic types
+//
+TEST(YAMLIO, TestReadWriteKindAndFlagsSequence) {
+  std::string intermediate;
+  {
+    KindAndFlagsSequence seq;
+    seq.push_back(KindAndFlags(kindA,a1));
+    seq.push_back(KindAndFlags(kindB,b1));
+    seq.push_back(KindAndFlags(kindA,a2));
+    seq.push_back(KindAndFlags(kindB,b2));
+    seq.push_back(KindAndFlags(kindA,a3));
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << seq;
+  }
+  {
+    Input yin(intermediate);
+    KindAndFlagsSequence seq2;
+    yin >> seq2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(seq2.size(), 5UL);
+    EXPECT_EQ(seq2[0].kind,  kindA);
+    EXPECT_EQ(seq2[0].flags, (uint32_t)a1);
+    EXPECT_EQ(seq2[1].kind,  kindB);
+    EXPECT_EQ(seq2[1].flags, (uint32_t)b1);
+    EXPECT_EQ(seq2[2].kind,  kindA);
+    EXPECT_EQ(seq2[2].flags, (uint32_t)a2);
+    EXPECT_EQ(seq2[3].kind,  kindB);
+    EXPECT_EQ(seq2[3].flags, (uint32_t)b2);
+    EXPECT_EQ(seq2[4].kind,  kindA);
+    EXPECT_EQ(seq2[4].flags, (uint32_t)a3);
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Test document list
+//===----------------------------------------------------------------------===//
+
+struct FooBarMap {
+  int foo;
+  int bar;
+};
+typedef std::vector<FooBarMap> FooBarMapDocumentList;
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(FooBarMap)
+
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<FooBarMap> {
+    static void mapping(IO &io, FooBarMap& fb) {
+      io.mapRequired("foo",    fb.foo);
+      io.mapRequired("bar",    fb.bar);
+    }
+  };
+}
+}
+
+
+//
+// Test the reading of a yaml mapping
+//
+TEST(YAMLIO, TestDocRead) {
+  FooBarMap doc;
+  Input yin("---\nfoo:  3\nbar:  5\n...\n");
+  yin >> doc;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(doc.foo, 3);
+  EXPECT_EQ(doc.bar,5);
+}
+
+
+
+//
+// Test writing then reading back a sequence of mappings
+//
+TEST(YAMLIO, TestSequenceDocListWriteAndRead) {
+  std::string intermediate;
+  {
+    FooBarMap doc1;
+    doc1.foo = 10;
+    doc1.bar = -3;
+    FooBarMap doc2;
+    doc2.foo = 257;
+    doc2.bar = 0;
+    std::vector<FooBarMap> docList;
+    docList.push_back(doc1);
+    docList.push_back(doc2);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << docList;
+  }
+
+
+  {
+    Input yin(intermediate);
+    std::vector<FooBarMap> docList2;
+    yin >> docList2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(docList2.size(), 2UL);
+    FooBarMap& map1 = docList2[0];
+    FooBarMap& map2 = docList2[1];
+    EXPECT_EQ(map1.foo, 10);
+    EXPECT_EQ(map1.bar, -3);
+    EXPECT_EQ(map2.foo, 257);
+    EXPECT_EQ(map2.bar, 0);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//  Test document tags
+//===----------------------------------------------------------------------===//
+
+struct MyDouble {
+  MyDouble() : value(0.0) { }
+  MyDouble(double x) : value(x) { }
+  double value;
+};
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble)
+
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<MyDouble> {
+    static void mapping(IO &io, MyDouble &d) {
+      if (io.mapTag("!decimal", true)) {
+        mappingDecimal(io, d);
+      } else if (io.mapTag("!fraction")) {
+        mappingFraction(io, d);
+      }
+    }
+    static void mappingDecimal(IO &io, MyDouble &d) {
+      io.mapRequired("value", d.value);
+    }
+    static void mappingFraction(IO &io, MyDouble &d) {
+        double num, denom;
+        io.mapRequired("numerator",      num);
+        io.mapRequired("denominator",    denom);
+        // convert fraction to double
+        d.value = num/denom;
+    }
+  };
+ }
+}
+
+
+//
+// Test the reading of two different tagged yaml documents.
+//
+TEST(YAMLIO, TestTaggedDocuments) {
+  std::vector<MyDouble> docList;
+  Input yin("--- !decimal\nvalue:  3.0\n"
+            "--- !fraction\nnumerator:  9.0\ndenominator:  2\n...\n");
+  yin >> docList;
+  EXPECT_FALSE(yin.error());
+  EXPECT_EQ(docList.size(), 2UL);
+  EXPECT_EQ(docList[0].value, 3.0);
+  EXPECT_EQ(docList[1].value, 4.5);
+}
+
+
+
+//
+// Test writing then reading back tagged documents
+//
+TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
+  std::string intermediate;
+  {
+    MyDouble a(10.25);
+    MyDouble b(-3.75);
+    std::vector<MyDouble> docList;
+    docList.push_back(a);
+    docList.push_back(b);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << docList;
+  }
+
+  {
+    Input yin(intermediate);
+    std::vector<MyDouble> docList2;
+    yin >> docList2;
+
+    EXPECT_FALSE(yin.error());
+    EXPECT_EQ(docList2.size(), 2UL);
+    EXPECT_EQ(docList2[0].value, 10.25);
+    EXPECT_EQ(docList2[1].value, -3.75);
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Test mapping validation
+//===----------------------------------------------------------------------===//
+
+struct MyValidation {
+  double value;
+};
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyValidation)
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<MyValidation> {
+    static void mapping(IO &io, MyValidation &d) {
+        io.mapRequired("value", d.value);
+    }
+    static StringRef validate(IO &io, MyValidation &d) {
+        if (d.value < 0)
+          return "negative value";
+        return StringRef();
+    }
+  };
+ }
+}
+
+
+//
+// Test that validate() is called and complains about the negative value.
+//
+TEST(YAMLIO, TestValidatingInput) {
+  std::vector<MyValidation> docList;
+  Input yin("--- \nvalue:  3.0\n"
+            "--- \nvalue:  -1.0\n...\n",
+            nullptr, suppressErrorMessages);
+  yin >> docList;
+  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
+//===----------------------------------------------------------------------===//
+
+//
+// Test error handling of unknown enumerated scalar
+//
+TEST(YAMLIO, TestColorsReadError) {
+  ColorMap map;
+  Input yin("---\n"
+            "c1:  blue\n"
+            "c2:  purple\n"
+            "c3:  green\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> map;
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling of flow sequence with unknown value
+//
+TEST(YAMLIO, TestFlagsReadError) {
+  FlagsMap map;
+  Input yin("---\n"
+            "f1:  [ big ]\n"
+            "f2:  [ round, hollow ]\n"
+            "f3:  []\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> map;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in uint8_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
+  std::vector<uint8_t> seq;
+  Input yin("---\n"
+            "- 255\n"
+            "- 0\n"
+            "- 257\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in uint16_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
+  std::vector<uint16_t> seq;
+  Input yin("---\n"
+            "- 65535\n"
+            "- 0\n"
+            "- 66000\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in uint32_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
+  std::vector<uint32_t> seq;
+  Input yin("---\n"
+            "- 4000000000\n"
+            "- 0\n"
+            "- 5000000000\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in uint64_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
+  std::vector<uint64_t> seq;
+  Input yin("---\n"
+            "- 18446744073709551615\n"
+            "- 0\n"
+            "- 19446744073709551615\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in int8_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
+  std::vector<int8_t> seq;
+  Input yin("---\n"
+            "- -128\n"
+            "- 0\n"
+            "- 127\n"
+            "- 128\n"
+           "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in int8_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) {
+  std::vector<int8_t> seq;
+  Input yin("---\n"
+            "- -128\n"
+            "- 0\n"
+            "- 127\n"
+            "- -129\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in int16_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
+  std::vector<int16_t> seq;
+  Input yin("---\n"
+            "- 32767\n"
+            "- 0\n"
+            "- -32768\n"
+            "- -32769\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in int16_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint16OverError) {
+  std::vector<int16_t> seq;
+  Input yin("---\n"
+            "- 32767\n"
+            "- 0\n"
+            "- -32768\n"
+            "- 32768\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in int32_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
+  std::vector<int32_t> seq;
+  Input yin("---\n"
+            "- 2147483647\n"
+            "- 0\n"
+            "- -2147483648\n"
+            "- -2147483649\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in int32_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint32OverError) {
+  std::vector<int32_t> seq;
+  Input yin("---\n"
+            "- 2147483647\n"
+            "- 0\n"
+            "- -2147483648\n"
+            "- 2147483649\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in int64_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
+  std::vector<int64_t> seq;
+  Input yin("---\n"
+            "- -9223372036854775808\n"
+            "- 0\n"
+            "- 9223372036854775807\n"
+            "- -9223372036854775809\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in int64_t type
+//
+TEST(YAMLIO, TestReadBuiltInTypesint64OverError) {
+  std::vector<int64_t> seq;
+  Input yin("---\n"
+            "- -9223372036854775808\n"
+            "- 0\n"
+            "- 9223372036854775807\n"
+            "- 9223372036854775809\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in float type
+//
+TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
+  std::vector<float> seq;
+  Input yin("---\n"
+            "- 0.0\n"
+            "- 1000.1\n"
+            "- -123.456\n"
+            "- 1.2.3\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in float type
+//
+TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
+  std::vector<double> seq;
+  Input yin("---\n"
+            "- 0.0\n"
+            "- 1000.1\n"
+            "- -123.456\n"
+            "- 1.2.3\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in Hex8 type
+//
+LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8)
+TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
+  std::vector<Hex8> seq;
+  Input yin("---\n"
+            "- 0x12\n"
+            "- 0xFE\n"
+            "- 0x123\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+
+//
+// Test error handling reading built-in Hex16 type
+//
+LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16)
+TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
+  std::vector<Hex16> seq;
+  Input yin("---\n"
+            "- 0x0012\n"
+            "- 0xFEFF\n"
+            "- 0x12345\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in Hex32 type
+//
+LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32)
+TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
+  std::vector<Hex32> seq;
+  Input yin("---\n"
+            "- 0x0012\n"
+            "- 0xFEFF0000\n"
+            "- 0x1234556789\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+//
+// Test error handling reading built-in Hex64 type
+//
+LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64)
+TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
+  std::vector<Hex64> seq;
+  Input yin("---\n"
+            "- 0x0012\n"
+            "- 0xFFEEDDCCBBAA9988\n"
+            "- 0x12345567890ABCDEF0\n"
+            "...\n",
+            /*Ctxt=*/nullptr,
+            suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_TRUE(!!yin.error());
+}
+
+TEST(YAMLIO, TestMalformedMapFailsGracefully) {
+  FooBar doc;
+  {
+    // We pass the suppressErrorMessages handler to handle the error
+    // message generated in the constructor of Input.
+    Input yin("{foo:3, bar: 5}", /*Ctxt=*/nullptr, suppressErrorMessages);
+    yin >> doc;
+    EXPECT_TRUE(!!yin.error());
+  }
+
+  {
+    Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/nullptr, suppressErrorMessages);
+    yin >> doc;
+    EXPECT_TRUE(!!yin.error());
+  }
+}
+
+struct OptionalTest {
+  std::vector<int> Numbers;
+};
+
+struct OptionalTestSeq {
+  std::vector<OptionalTest> Tests;
+};
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(OptionalTest)
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<OptionalTest> {
+    static void mapping(IO& IO, OptionalTest &OT) {
+      IO.mapOptional("Numbers", OT.Numbers);
+    }
+  };
+
+  template <>
+  struct MappingTraits<OptionalTestSeq> {
+    static void mapping(IO &IO, OptionalTestSeq &OTS) {
+      IO.mapOptional("Tests", OTS.Tests);
+    }
+  };
+}
+}
+
+TEST(YAMLIO, SequenceElideTest) {
+  // Test that writing out a purely optional structure with its fields set to
+  // default followed by other data is properly read back in.
+  OptionalTestSeq Seq;
+  OptionalTest One, Two, Three, Four;
+  int N[] = {1, 2, 3};
+  Three.Numbers.assign(N, N + 3);
+  Seq.Tests.push_back(One);
+  Seq.Tests.push_back(Two);
+  Seq.Tests.push_back(Three);
+  Seq.Tests.push_back(Four);
+
+  std::string intermediate;
+  {
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << Seq;
+  }
+
+  Input yin(intermediate);
+  OptionalTestSeq Seq2;
+  yin >> Seq2;
+
+  EXPECT_FALSE(yin.error());
+
+  EXPECT_EQ(4UL, Seq2.Tests.size());
+
+  EXPECT_TRUE(Seq2.Tests[0].Numbers.empty());
+  EXPECT_TRUE(Seq2.Tests[1].Numbers.empty());
+
+  EXPECT_EQ(1, Seq2.Tests[2].Numbers[0]);
+  EXPECT_EQ(2, Seq2.Tests[2].Numbers[1]);
+  EXPECT_EQ(3, Seq2.Tests[2].Numbers[2]);
+
+  EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
+}
+
+TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
+  FooBar doc;
+  Input yin("");
+  yin >> doc;
+  EXPECT_TRUE(!!yin.error());
+}
+
+TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
+  OptionalTest doc;
+  Input yin("");
+  yin >> doc;
+  EXPECT_FALSE(yin.error());
+}
+
+TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
+  std::vector<uint8_t> seq;
+  Input yin("", /*Ctxt=*/nullptr, suppressErrorMessages);
+  yin >> seq;
+
+  EXPECT_FALSE(yin.error());
+  EXPECT_TRUE(seq.empty());
+}
+
+struct FlowMap {
+  llvm::StringRef str1, str2, str3;
+  FlowMap(llvm::StringRef str1, llvm::StringRef str2, llvm::StringRef str3)
+    : str1(str1), str2(str2), str3(str3) {}
+};
+
+struct FlowSeq {
+  llvm::StringRef str;
+  FlowSeq(llvm::StringRef S) : str(S) {}
+  FlowSeq() = default;
+};
+
+namespace llvm {
+namespace yaml {
+  template <>
+  struct MappingTraits<FlowMap> {
+    static void mapping(IO &io, FlowMap &fm) {
+      io.mapRequired("str1", fm.str1);
+      io.mapRequired("str2", fm.str2);
+      io.mapRequired("str3", fm.str3);
+    }
+
+    static const bool flow = true;
+  };
+
+template <>
+struct ScalarTraits<FlowSeq> {
+  static void output(const FlowSeq &value, void*, llvm::raw_ostream &out) {
+    out << value.str;
+  }
+  static StringRef input(StringRef scalar, void*, FlowSeq &value) {
+    value.str = scalar;
+    return "";
+  }
+
+  static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
+};
+}
+}
+
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FlowSeq)
+
+TEST(YAMLIO, TestWrapFlow) {
+  std::string out;
+  llvm::raw_string_ostream ostr(out);
+  FlowMap Map("This is str1", "This is str2", "This is str3");
+  std::vector<FlowSeq> Seq;
+  Seq.emplace_back("This is str1");
+  Seq.emplace_back("This is str2");
+  Seq.emplace_back("This is str3");
+
+  {
+    // 20 is just bellow the total length of the first mapping field.
+    // We should wreap at every element.
+    Output yout(ostr, nullptr, 15);
+
+    yout << Map;
+    ostr.flush();
+    EXPECT_EQ(out,
+              "---\n"
+              "{ str1: This is str1, \n"
+              "  str2: This is str2, \n"
+              "  str3: This is str3 }\n"
+              "...\n");
+    out.clear();
+
+    yout << Seq;
+    ostr.flush();
+    EXPECT_EQ(out,
+              "---\n"
+              "[ This is str1, \n"
+              "  This is str2, \n"
+              "  This is str3 ]\n"
+              "...\n");
+    out.clear();
+  }
+  {
+    // 25 will allow the second field to be output on the first line.
+    Output yout(ostr, nullptr, 25);
+
+    yout << Map;
+    ostr.flush();
+    EXPECT_EQ(out,
+              "---\n"
+              "{ str1: This is str1, str2: This is str2, \n"
+              "  str3: This is str3 }\n"
+              "...\n");
+    out.clear();
+
+    yout << Seq;
+    ostr.flush();
+    EXPECT_EQ(out,
+              "---\n"
+              "[ This is str1, This is str2, \n"
+              "  This is str3 ]\n"
+              "...\n");
+    out.clear();
+  }
+  {
+    // 0 means no wrapping.
+    Output yout(ostr, nullptr, 0);
+
+    yout << Map;
+    ostr.flush();
+    EXPECT_EQ(out,
+              "---\n"
+              "{ str1: This is str1, str2: This is str2, str3: This is str3 }\n"
+              "...\n");
+    out.clear();
+
+    yout << Seq;
+    ostr.flush();
+    EXPECT_EQ(out,
+              "---\n"
+              "[ This is str1, This is str2, This is str3 ]\n"
+              "...\n");
+    out.clear();
+  }
+}
+
+struct MappingContext {
+  int A = 0;
+};
+struct SimpleMap {
+  int B = 0;
+  int C = 0;
+};
+
+struct NestedMap {
+  NestedMap(MappingContext &Context) : Context(Context) {}
+  SimpleMap Simple;
+  MappingContext &Context;
+};
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingContextTraits<SimpleMap, MappingContext> {
+  static void mapping(IO &io, SimpleMap &sm, MappingContext &Context) {
+    io.mapRequired("B", sm.B);
+    io.mapRequired("C", sm.C);
+    ++Context.A;
+    io.mapRequired("Context", Context.A);
+  }
+};
+
+template <> struct MappingTraits<NestedMap> {
+  static void mapping(IO &io, NestedMap &nm) {
+    io.mapRequired("Simple", nm.Simple, nm.Context);
+  }
+};
+}
+}
+
+TEST(YAMLIO, TestMapWithContext) {
+  MappingContext Context;
+  NestedMap Nested(Context);
+  std::string out;
+  llvm::raw_string_ostream ostr(out);
+
+  Output yout(ostr, nullptr, 15);
+
+  yout << Nested;
+  ostr.flush();
+  EXPECT_EQ(1, Context.A);
+  EXPECT_EQ("---\n"
+            "Simple:          \n"
+            "  B:               0\n"
+            "  C:               0\n"
+            "  Context:         1\n"
+            "...\n",
+            out);
+
+  out.clear();
+
+  Nested.Simple.B = 2;
+  Nested.Simple.C = 3;
+  yout << Nested;
+  ostr.flush();
+  EXPECT_EQ(2, Context.A);
+  EXPECT_EQ("---\n"
+            "Simple:          \n"
+            "  B:               2\n"
+            "  C:               3\n"
+            "  Context:         2\n"
+            "...\n",
+            out);
+  out.clear();
+}
+
+LLVM_YAML_IS_STRING_MAP(int)
+
+TEST(YAMLIO, TestCustomMapping) {
+  std::map<std::string, int> x;
+  x["foo"] = 1;
+  x["bar"] = 2;
+
+  std::string out;
+  llvm::raw_string_ostream ostr(out);
+  Output xout(ostr, nullptr, 0);
+
+  xout << x;
+  ostr.flush();
+  EXPECT_EQ("---\n"
+            "bar:             2\n"
+            "foo:             1\n"
+            "...\n",
+            out);
+
+  Input yin(out);
+  std::map<std::string, int> y;
+  yin >> y;
+  EXPECT_EQ(2ul, y.size());
+  EXPECT_EQ(1, y["foo"]);
+  EXPECT_EQ(2, y["bar"]);
+}
+
+LLVM_YAML_IS_STRING_MAP(FooBar)
+
+TEST(YAMLIO, TestCustomMappingStruct) {
+  std::map<std::string, FooBar> x;
+  x["foo"].foo = 1;
+  x["foo"].bar = 2;
+  x["bar"].foo = 3;
+  x["bar"].bar = 4;
+
+  std::string out;
+  llvm::raw_string_ostream ostr(out);
+  Output xout(ostr, nullptr, 0);
+
+  xout << x;
+  ostr.flush();
+  EXPECT_EQ("---\n"
+            "bar:             \n"
+            "  foo:             3\n"
+            "  bar:             4\n"
+            "foo:             \n"
+            "  foo:             1\n"
+            "  bar:             2\n"
+            "...\n",
+            out);
+
+  Input yin(out);
+  std::map<std::string, FooBar> y;
+  yin >> y;
+  EXPECT_EQ(2ul, y.size());
+  EXPECT_EQ(1, y["foo"].foo);
+  EXPECT_EQ(2, y["foo"].bar);
+  EXPECT_EQ(3, y["bar"].foo);
+  EXPECT_EQ(4, y["bar"].bar);
+}
+
+static void TestEscaped(llvm::StringRef Input, llvm::StringRef Expected) {
+  std::string out;
+  llvm::raw_string_ostream ostr(out);
+  Output xout(ostr, nullptr, 0);
+
+  llvm::yaml::EmptyContext Ctx;
+  yamlize(xout, Input, true, Ctx);
+
+  ostr.flush();
+
+  // Make a separate StringRef so we get nice byte-by-byte output.
+  llvm::StringRef Got(out);
+  EXPECT_EQ(Expected, Got);
+}
+
+TEST(YAMLIO, TestEscaped) {
+  // Single quote
+  TestEscaped("@abc@", "'@abc@'");
+  // No quote
+  TestEscaped("abc", "abc");
+  // Forward slash quoted
+  TestEscaped("abc/", "'abc/'");
+  // Double quote non-printable
+  TestEscaped("\01@abc@", "\"\\x01@abc@\"");
+  // Double quote inside single quote
+  TestEscaped("abc\"fdf", "'abc\"fdf'");
+  // Double quote inside double quote
+  TestEscaped("\01bc\"fdf", "\"\\x01bc\\\"fdf\"");
+  // Single quote inside single quote
+  TestEscaped("abc'fdf", "'abc''fdf'");
+  // UTF8
+  TestEscaped("/*параметр*/", "\"/*параметр*/\"");
+  // UTF8 with single quote inside double quote
+  TestEscaped("parameter 'параметр' is unused",
+              "\"parameter 'параметр' is unused\"");
+
+  // String with embedded non-printable multibyte UTF-8 sequence (U+200B
+  // zero-width space). The thing to test here is that we emit a
+  // unicode-scalar level escape like \uNNNN (at the YAML level), and don't
+  // just pass the UTF-8 byte sequence through as with quoted printables.
+  {
+    const unsigned char foobar[10] = {'f', 'o', 'o',
+                                      0xE2, 0x80, 0x8B, // UTF-8 of U+200B
+                                      'b', 'a', 'r',
+                                      0x0};
+    TestEscaped((char const *)foobar, "\"foo\\u200Bbar\"");
+  }
+}
+
+TEST(YAMLIO, Numeric) {
+  EXPECT_TRUE(isNumeric(".inf"));
+  EXPECT_TRUE(isNumeric(".INF"));
+  EXPECT_TRUE(isNumeric(".Inf"));
+  EXPECT_TRUE(isNumeric("-.inf"));
+  EXPECT_TRUE(isNumeric("+.inf"));
+
+  EXPECT_TRUE(isNumeric(".nan"));
+  EXPECT_TRUE(isNumeric(".NaN"));
+  EXPECT_TRUE(isNumeric(".NAN"));
+
+  EXPECT_TRUE(isNumeric("0"));
+  EXPECT_TRUE(isNumeric("0."));
+  EXPECT_TRUE(isNumeric("0.0"));
+  EXPECT_TRUE(isNumeric("-0.0"));
+  EXPECT_TRUE(isNumeric("+0.0"));
+
+  EXPECT_TRUE(isNumeric("12345"));
+  EXPECT_TRUE(isNumeric("012345"));
+  EXPECT_TRUE(isNumeric("+12.0"));
+  EXPECT_TRUE(isNumeric(".5"));
+  EXPECT_TRUE(isNumeric("+.5"));
+  EXPECT_TRUE(isNumeric("-1.0"));
+
+  EXPECT_TRUE(isNumeric("2.3e4"));
+  EXPECT_TRUE(isNumeric("-2E+05"));
+  EXPECT_TRUE(isNumeric("+12e03"));
+  EXPECT_TRUE(isNumeric("6.8523015e+5"));
+
+  EXPECT_TRUE(isNumeric("1.e+1"));
+  EXPECT_TRUE(isNumeric(".0e+1"));
+
+  EXPECT_TRUE(isNumeric("0x2aF3"));
+  EXPECT_TRUE(isNumeric("0o01234567"));
+
+  EXPECT_FALSE(isNumeric("not a number"));
+  EXPECT_FALSE(isNumeric("."));
+  EXPECT_FALSE(isNumeric(".e+1"));
+  EXPECT_FALSE(isNumeric(".1e"));
+  EXPECT_FALSE(isNumeric(".1e+"));
+  EXPECT_FALSE(isNumeric(".1e++1"));
+
+  EXPECT_FALSE(isNumeric("ABCD"));
+  EXPECT_FALSE(isNumeric("+0x2AF3"));
+  EXPECT_FALSE(isNumeric("-0x2AF3"));
+  EXPECT_FALSE(isNumeric("0x2AF3Z"));
+  EXPECT_FALSE(isNumeric("0o012345678"));
+  EXPECT_FALSE(isNumeric("0xZ"));
+  EXPECT_FALSE(isNumeric("-0o012345678"));
+  EXPECT_FALSE(isNumeric("000003A8229434B839616A25C16B0291F77A438B"));
+
+  EXPECT_FALSE(isNumeric(""));
+  EXPECT_FALSE(isNumeric("."));
+  EXPECT_FALSE(isNumeric(".e+1"));
+  EXPECT_FALSE(isNumeric(".e+"));
+  EXPECT_FALSE(isNumeric(".e"));
+  EXPECT_FALSE(isNumeric("e1"));
+
+  // Deprecated formats: as for YAML 1.2 specification, the following are not
+  // valid numbers anymore:
+  //
+  // * Sexagecimal numbers
+  // * Decimal numbers with comma s the delimiter
+  // * "inf", "nan" without '.' prefix
+  EXPECT_FALSE(isNumeric("3:25:45"));
+  EXPECT_FALSE(isNumeric("+12,345"));
+  EXPECT_FALSE(isNumeric("-inf"));
+  EXPECT_FALSE(isNumeric("1,230.15"));
+}
+
+//===----------------------------------------------------------------------===//
+//  Test PolymorphicTraits and TaggedScalarTraits
+//===----------------------------------------------------------------------===//
+
+struct Poly {
+  enum NodeKind {
+    NK_Scalar,
+    NK_Seq,
+    NK_Map,
+  } Kind;
+
+  Poly(NodeKind Kind) : Kind(Kind) {}
+
+  virtual ~Poly() = default;
+
+  NodeKind getKind() const { return Kind; }
+};
+
+struct Scalar : Poly {
+  enum ScalarKind {
+    SK_Unknown,
+    SK_Double,
+    SK_Bool,
+  } SKind;
+
+  union {
+    double DoubleValue;
+    bool BoolValue;
+  };
+
+  Scalar() : Poly(NK_Scalar), SKind(SK_Unknown) {}
+  Scalar(double DoubleValue)
+      : Poly(NK_Scalar), SKind(SK_Double), DoubleValue(DoubleValue) {}
+  Scalar(bool BoolValue)
+      : Poly(NK_Scalar), SKind(SK_Bool), BoolValue(BoolValue) {}
+
+  static bool classof(const Poly *N) { return N->getKind() == NK_Scalar; }
+};
+
+struct Seq : Poly, std::vector<std::unique_ptr<Poly>> {
+  Seq() : Poly(NK_Seq) {}
+
+  static bool classof(const Poly *N) { return N->getKind() == NK_Seq; }
+};
+
+struct Map : Poly, llvm::StringMap<std::unique_ptr<Poly>> {
+  Map() : Poly(NK_Map) {}
+
+  static bool classof(const Poly *N) { return N->getKind() == NK_Map; }
+};
+
+namespace llvm {
+namespace yaml {
+
+template <> struct PolymorphicTraits<std::unique_ptr<Poly>> {
+  static NodeKind getKind(const std::unique_ptr<Poly> &N) {
+    if (isa<Scalar>(*N))
+      return NodeKind::Scalar;
+    if (isa<Seq>(*N))
+      return NodeKind::Sequence;
+    if (isa<Map>(*N))
+      return NodeKind::Map;
+    llvm_unreachable("unsupported node type");
+  }
+
+  static Scalar &getAsScalar(std::unique_ptr<Poly> &N) {
+    if (!N || !isa<Scalar>(*N))
+      N = llvm::make_unique<Scalar>();
+    return *cast<Scalar>(N.get());
+  }
+
+  static Seq &getAsSequence(std::unique_ptr<Poly> &N) {
+    if (!N || !isa<Seq>(*N))
+      N = llvm::make_unique<Seq>();
+    return *cast<Seq>(N.get());
+  }
+
+  static Map &getAsMap(std::unique_ptr<Poly> &N) {
+    if (!N || !isa<Map>(*N))
+      N = llvm::make_unique<Map>();
+    return *cast<Map>(N.get());
+  }
+};
+
+template <> struct TaggedScalarTraits<Scalar> {
+  static void output(const Scalar &S, void *Ctxt, raw_ostream &ScalarOS,
+                     raw_ostream &TagOS) {
+    switch (S.SKind) {
+    case Scalar::SK_Unknown:
+      report_fatal_error("output unknown scalar");
+      break;
+    case Scalar::SK_Double:
+      TagOS << "!double";
+      ScalarTraits<double>::output(S.DoubleValue, Ctxt, ScalarOS);
+      break;
+    case Scalar::SK_Bool:
+      TagOS << "!bool";
+      ScalarTraits<bool>::output(S.BoolValue, Ctxt, ScalarOS);
+      break;
+    }
+  }
+
+  static StringRef input(StringRef ScalarStr, StringRef Tag, void *Ctxt,
+                         Scalar &S) {
+    S.SKind = StringSwitch<Scalar::ScalarKind>(Tag)
+                  .Case("!double", Scalar::SK_Double)
+                  .Case("!bool", Scalar::SK_Bool)
+                  .Default(Scalar::SK_Unknown);
+    switch (S.SKind) {
+    case Scalar::SK_Unknown:
+      return StringRef("unknown scalar tag");
+    case Scalar::SK_Double:
+      return ScalarTraits<double>::input(ScalarStr, Ctxt, S.DoubleValue);
+    case Scalar::SK_Bool:
+      return ScalarTraits<bool>::input(ScalarStr, Ctxt, S.BoolValue);
+    }
+    llvm_unreachable("unknown scalar kind");
+  }
+
+  static QuotingType mustQuote(const Scalar &S, StringRef Str) {
+    switch (S.SKind) {
+    case Scalar::SK_Unknown:
+      report_fatal_error("quote unknown scalar");
+    case Scalar::SK_Double:
+      return ScalarTraits<double>::mustQuote(Str);
+    case Scalar::SK_Bool:
+      return ScalarTraits<bool>::mustQuote(Str);
+    }
+    llvm_unreachable("unknown scalar kind");
+  }
+};
+
+template <> struct CustomMappingTraits<Map> {
+  static void inputOne(IO &IO, StringRef Key, Map &M) {
+    IO.mapRequired(Key.str().c_str(), M[Key]);
+  }
+
+  static void output(IO &IO, Map &M) {
+    for (auto &N : M)
+      IO.mapRequired(N.getKey().str().c_str(), N.getValue());
+  }
+};
+
+template <> struct SequenceTraits<Seq> {
+  static size_t size(IO &IO, Seq &A) { return A.size(); }
+
+  static std::unique_ptr<Poly> &element(IO &IO, Seq &A, size_t Index) {
+    if (Index >= A.size())
+      A.resize(Index + 1);
+    return A[Index];
+  }
+};
+
+} // namespace yaml
+} // namespace llvm
+
+TEST(YAMLIO, TestReadWritePolymorphicScalar) {
+  std::string intermediate;
+  std::unique_ptr<Poly> node = llvm::make_unique<Scalar>(true);
+
+  llvm::raw_string_ostream ostr(intermediate);
+  Output yout(ostr);
+#ifdef GTEST_HAS_DEATH_TEST
+#ifndef NDEBUG
+  EXPECT_DEATH(yout << node, "plain scalar documents are not supported");
+#endif
+#endif
+}
+
+TEST(YAMLIO, TestReadWritePolymorphicSeq) {
+  std::string intermediate;
+  {
+    auto seq = llvm::make_unique<Seq>();
+    seq->push_back(llvm::make_unique<Scalar>(true));
+    seq->push_back(llvm::make_unique<Scalar>(1.0));
+    auto node = llvm::unique_dyn_cast<Poly>(seq);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << node;
+  }
+  {
+    Input yin(intermediate);
+    std::unique_ptr<Poly> node;
+    yin >> node;
+
+    EXPECT_FALSE(yin.error());
+    auto seq = llvm::dyn_cast<Seq>(node.get());
+    ASSERT_TRUE(seq);
+    ASSERT_EQ(seq->size(), 2u);
+    auto first = llvm::dyn_cast<Scalar>((*seq)[0].get());
+    ASSERT_TRUE(first);
+    EXPECT_EQ(first->SKind, Scalar::SK_Bool);
+    EXPECT_TRUE(first->BoolValue);
+    auto second = llvm::dyn_cast<Scalar>((*seq)[1].get());
+    ASSERT_TRUE(second);
+    EXPECT_EQ(second->SKind, Scalar::SK_Double);
+    EXPECT_EQ(second->DoubleValue, 1.0);
+  }
+}
+
+TEST(YAMLIO, TestReadWritePolymorphicMap) {
+  std::string intermediate;
+  {
+    auto map = llvm::make_unique<Map>();
+    (*map)["foo"] = llvm::make_unique<Scalar>(false);
+    (*map)["bar"] = llvm::make_unique<Scalar>(2.0);
+    std::unique_ptr<Poly> node = llvm::unique_dyn_cast<Poly>(map);
+
+    llvm::raw_string_ostream ostr(intermediate);
+    Output yout(ostr);
+    yout << node;
+  }
+  {
+    Input yin(intermediate);
+    std::unique_ptr<Poly> node;
+    yin >> node;
+
+    EXPECT_FALSE(yin.error());
+    auto map = llvm::dyn_cast<Map>(node.get());
+    ASSERT_TRUE(map);
+    auto foo = llvm::dyn_cast<Scalar>((*map)["foo"].get());
+    ASSERT_TRUE(foo);
+    EXPECT_EQ(foo->SKind, Scalar::SK_Bool);
+    EXPECT_FALSE(foo->BoolValue);
+    auto bar = llvm::dyn_cast<Scalar>((*map)["bar"].get());
+    ASSERT_TRUE(bar);
+    EXPECT_EQ(bar->SKind, Scalar::SK_Double);
+    EXPECT_EQ(bar->DoubleValue, 2.0);
+  }
+}
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
new file mode 100644
index 0000000..7962f3c
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
@@ -0,0 +1,335 @@
+//===- unittest/Support/YAMLParserTest ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+namespace llvm {
+
+static void SuppressDiagnosticsOutput(const SMDiagnostic &, void *) {
+  // Prevent SourceMgr from writing errors to stderr
+  // to reduce noise in unit test runs.
+}
+
+// Assumes Ctx is an SMDiagnostic where Diag can be stored.
+static void CollectDiagnosticsOutput(const SMDiagnostic &Diag, void *Ctx) {
+  SMDiagnostic* DiagOut = static_cast<SMDiagnostic*>(Ctx);
+  *DiagOut = Diag;
+}
+
+// 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;
+}
+
+// Checks that the given input can be parsed without error.
+static void ExpectParseSuccess(StringRef Message, StringRef Input) {
+  SourceMgr SM;
+  yaml::Stream Stream(Input, SM);
+  EXPECT_TRUE(Stream.validate()) << Message << ": " << Input;
+}
+
+TEST(YAMLParser, ParsesEmptyArray) {
+  ExpectParseSuccess("Empty array", "[]");
+}
+
+TEST(YAMLParser, FailsIfNotClosingArray) {
+  ExpectParseError("Not closing array", "[");
+  ExpectParseError("Not closing array", "  [  ");
+  ExpectParseError("Not closing array", "  [x");
+}
+
+TEST(YAMLParser, ParsesEmptyArrayWithWhitespace) {
+  ExpectParseSuccess("Array with spaces", "  [  ]  ");
+  ExpectParseSuccess("All whitespaces", "\t\r\n[\t\n \t\r ]\t\r \n\n");
+}
+
+TEST(YAMLParser, ParsesEmptyObject) {
+  ExpectParseSuccess("Empty object", "[{}]");
+}
+
+TEST(YAMLParser, ParsesObject) {
+  ExpectParseSuccess("Object with an entry", "[{\"a\":\"/b\"}]");
+}
+
+TEST(YAMLParser, ParsesMultipleKeyValuePairsInObject) {
+  ExpectParseSuccess("Multiple key, value pairs",
+                     "[{\"a\":\"/b\",\"c\":\"d\",\"e\":\"f\"}]");
+}
+
+TEST(YAMLParser, FailsIfNotClosingObject) {
+  ExpectParseError("Missing close on empty", "[{]");
+  ExpectParseError("Missing close after pair", "[{\"a\":\"b\"]");
+}
+
+TEST(YAMLParser, FailsIfMissingColon) {
+  ExpectParseError("Missing colon between key and value", "[{\"a\"\"/b\"}]");
+  ExpectParseError("Missing colon between key and value", "[{\"a\" \"b\"}]");
+}
+
+TEST(YAMLParser, FailsOnMissingQuote) {
+  ExpectParseError("Missing open quote", "[{a\":\"b\"}]");
+  ExpectParseError("Missing closing quote", "[{\"a\":\"b}]");
+}
+
+TEST(YAMLParser, ParsesEscapedQuotes) {
+  ExpectParseSuccess("Parses escaped string in key and value",
+                     "[{\"a\":\"\\\"b\\\"  \\\" \\\"\"}]");
+}
+
+TEST(YAMLParser, ParsesEmptyString) {
+  ExpectParseSuccess("Parses empty string in value", "[{\"a\":\"\"}]");
+}
+
+TEST(YAMLParser, ParsesMultipleObjects) {
+  ExpectParseSuccess(
+      "Multiple objects in array",
+      "["
+      " { \"a\" : \"b\" },"
+      " { \"a\" : \"b\" },"
+      " { \"a\" : \"b\" }"
+      "]");
+}
+
+TEST(YAMLParser, FailsOnMissingComma) {
+  ExpectParseError(
+      "Missing comma",
+      "["
+      " { \"a\" : \"b\" }"
+      " { \"a\" : \"b\" }"
+      "]");
+}
+
+TEST(YAMLParser, ParsesSpacesInBetweenTokens) {
+  ExpectParseSuccess(
+      "Various whitespace between tokens",
+      " \t \n\n \r [ \t \n\n \r"
+      " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
+      " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r,\t \n\n \r"
+      " \t \n\n \r { \t \n\n \r\"a\"\t \n\n \r :"
+      " \t \n\n \r \"b\"\t \n\n \r } \t \n\n \r]\t \n\n \r");
+}
+
+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", "[\"   ");
+  ExpectParseError("In string escaping EOF", "[\"  \\");
+  ExpectParseError("In array starting with EOF", "[");
+  ExpectParseError("In array element starting with EOF", "[[], ");
+  ExpectParseError("In array hitting EOF", "[[] ");
+  ExpectParseError("In array hitting EOF", "[[]");
+  ExpectParseError("In object hitting EOF", "{\"\"");
+}
+
+TEST(YAMLParser, HandlesNullValuesInKeyValueNodesGracefully) {
+  ExpectParseError("KeyValueNode with null key", "? \"\n:");
+  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) {
+  std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
+  SourceMgr SM;
+  yaml::Stream Stream(StringInArray, SM);
+  yaml::SequenceNode *ParsedSequence
+    = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());
+  StringRef ParsedString
+    = dyn_cast<yaml::ScalarNode>(
+      static_cast<yaml::Node*>(ParsedSequence->begin()))->getRawValue();
+  ParsedString = ParsedString.substr(1, ParsedString.size() - 2);
+  EXPECT_EQ(String, ParsedString.str());
+}
+
+// Checks that parsing the given string inside an array fails.
+static void ExpectCannotParseString(StringRef String) {
+  std::string StringInArray = (llvm::Twine("[\"") + String + "\"]").str();
+  ExpectParseError((Twine("When parsing string \"") + String + "\"").str(),
+                   StringInArray);
+}
+
+TEST(YAMLParser, ParsesStrings) {
+  ExpectCanParseString("");
+  ExpectCannotParseString("\\");
+  ExpectCannotParseString("\"");
+  ExpectCanParseString(" ");
+  ExpectCanParseString("\\ ");
+  ExpectCanParseString("\\\"");
+  ExpectCannotParseString("\"\\");
+  ExpectCannotParseString(" \\");
+  ExpectCanParseString("\\\\");
+  ExpectCannotParseString("\\\\\\");
+  ExpectCanParseString("\\\\\\\\");
+  ExpectCanParseString("\\\" ");
+  ExpectCannotParseString("\\\\\" ");
+  ExpectCanParseString("\\\\\\\" ");
+  ExpectCanParseString("    \\\\  \\\"  \\\\\\\"   ");
+}
+
+TEST(YAMLParser, WorksWithIteratorAlgorithms) {
+  SourceMgr SM;
+  yaml::Stream Stream("[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]", SM);
+  yaml::SequenceNode *Array
+    = dyn_cast<yaml::SequenceNode>(Stream.begin()->getRoot());
+  EXPECT_EQ(6, std::distance(Array->begin(), Array->end()));
+}
+
+TEST(YAMLParser, DefaultDiagnosticFilename) {
+  SourceMgr SM;
+
+  SMDiagnostic GeneratedDiag;
+  SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);
+
+  // When we construct a YAML stream over an unnamed string,
+  // the filename is hard-coded as "YAML".
+  yaml::Stream UnnamedStream("[]", SM);
+  UnnamedStream.printError(UnnamedStream.begin()->getRoot(), "Hello, World!");
+  EXPECT_EQ("YAML", GeneratedDiag.getFilename());
+}
+
+TEST(YAMLParser, DiagnosticFilenameFromBufferID) {
+  SourceMgr SM;
+
+  SMDiagnostic GeneratedDiag;
+  SM.setDiagHandler(CollectDiagnosticsOutput, &GeneratedDiag);
+
+  // When we construct a YAML stream over a named buffer,
+  // we get its ID as filename in diagnostics.
+  std::unique_ptr<MemoryBuffer> Buffer =
+      MemoryBuffer::getMemBuffer("[]", "buffername.yaml");
+  yaml::Stream Stream(Buffer->getMemBufferRef(), SM);
+  Stream.printError(Stream.begin()->getRoot(), "Hello, World!");
+  EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename());
+}
+
+TEST(YAMLParser, SameNodeIteratorOperatorNotEquals) {
+  SourceMgr SM;
+  yaml::Stream Stream("[\"1\", \"2\"]", SM);
+
+  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
+                                              Stream.begin()->getRoot());
+
+  auto Begin = Node->begin();
+  auto End = Node->end();
+
+  EXPECT_TRUE(Begin != End);
+  EXPECT_FALSE(Begin != Begin);
+  EXPECT_FALSE(End != End);
+}
+
+TEST(YAMLParser, SameNodeIteratorOperatorEquals) {
+  SourceMgr SM;
+  yaml::Stream Stream("[\"1\", \"2\"]", SM);
+
+  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
+                                              Stream.begin()->getRoot());
+
+  auto Begin = Node->begin();
+  auto End = Node->end();
+
+  EXPECT_FALSE(Begin == End);
+  EXPECT_TRUE(Begin == Begin);
+  EXPECT_TRUE(End == End);
+}
+
+TEST(YAMLParser, DifferentNodesIteratorOperatorNotEquals) {
+  SourceMgr SM;
+  yaml::Stream Stream("[\"1\", \"2\"]", SM);
+  yaml::Stream AnotherStream("[\"1\", \"2\"]", SM);
+
+  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
+                                                  Stream.begin()->getRoot());
+  yaml::SequenceNode *AnotherNode = dyn_cast<yaml::SequenceNode>(
+                                              AnotherStream.begin()->getRoot());
+
+  auto Begin = Node->begin();
+  auto End = Node->end();
+
+  auto AnotherBegin = AnotherNode->begin();
+  auto AnotherEnd = AnotherNode->end();
+
+  EXPECT_TRUE(Begin != AnotherBegin);
+  EXPECT_TRUE(Begin != AnotherEnd);
+  EXPECT_FALSE(End != AnotherEnd);
+}
+
+TEST(YAMLParser, DifferentNodesIteratorOperatorEquals) {
+  SourceMgr SM;
+  yaml::Stream Stream("[\"1\", \"2\"]", SM);
+  yaml::Stream AnotherStream("[\"1\", \"2\"]", SM);
+
+  yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
+                                                    Stream.begin()->getRoot());
+  yaml::SequenceNode *AnotherNode = dyn_cast<yaml::SequenceNode>(
+                                             AnotherStream.begin()->getRoot());
+
+  auto Begin = Node->begin();
+  auto End = Node->end();
+
+  auto AnotherBegin = AnotherNode->begin();
+  auto AnotherEnd = AnotherNode->end();
+
+  EXPECT_FALSE(Begin == AnotherBegin);
+  EXPECT_FALSE(Begin == AnotherEnd);
+  EXPECT_TRUE(End == AnotherEnd);
+}
+
+} // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
new file mode 100644
index 0000000..2b8f065
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/formatted_raw_ostream_test.cpp
@@ -0,0 +1,33 @@
+//===- llvm/unittest/Support/formatted_raw_ostream_test.cpp ---------------===//
+//
+//                     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/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(formatted_raw_ostreamTest, Test_Tell) {
+  // Check offset when underlying stream has buffer contents.
+  SmallString<128> A;
+  raw_svector_ostream B(A);
+  formatted_raw_ostream C(B);
+  char tmp[100] = "";
+
+  for (unsigned i = 0; i != 3; ++i) {
+    C.write(tmp, 100);
+
+    EXPECT_EQ(100*(i+1), (unsigned) C.tell());
+  }
+}
+
+}
diff --git a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
new file mode 100644
index 0000000..a75f446
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
@@ -0,0 +1,346 @@
+//===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream 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/FileSystem.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+template<typename T> std::string printToString(const T &Value) {
+  std::string res;
+  llvm::raw_string_ostream(res) << Value;
+  return res;    
+}
+
+/// printToString - Print the given value to a stream which only has \arg
+/// BytesLeftInBuffer bytes left in the buffer. This is useful for testing edge
+/// cases in the buffer handling logic.
+template<typename T> std::string printToString(const T &Value,
+                                               unsigned BytesLeftInBuffer) {
+  // FIXME: This is relying on internal knowledge of how raw_ostream works to
+  // get the buffer position right.
+  SmallString<256> SVec;
+  assert(BytesLeftInBuffer < 256 && "Invalid buffer count!");
+  llvm::raw_svector_ostream OS(SVec);
+  unsigned StartIndex = 256 - BytesLeftInBuffer;
+  for (unsigned i = 0; i != StartIndex; ++i)
+    OS << '?';
+  OS << Value;
+  return OS.str().substr(StartIndex);
+}
+
+template<typename T> std::string printToStringUnbuffered(const T &Value) {
+  std::string res;
+  llvm::raw_string_ostream OS(res);
+  OS.SetUnbuffered();
+  OS << Value;
+  return res;
+}
+
+TEST(raw_ostreamTest, Types_Buffered) {
+  // Char
+  EXPECT_EQ("c", printToString('c'));
+
+  // String
+  EXPECT_EQ("hello", printToString("hello"));
+  EXPECT_EQ("hello", printToString(std::string("hello")));
+
+  // Int
+  EXPECT_EQ("0", printToString(0));
+  EXPECT_EQ("2425", printToString(2425));
+  EXPECT_EQ("-2425", printToString(-2425));
+
+  // Long long
+  EXPECT_EQ("0", printToString(0LL));
+  EXPECT_EQ("257257257235709", printToString(257257257235709LL));
+  EXPECT_EQ("-257257257235709", printToString(-257257257235709LL));
+
+  // Double
+  EXPECT_EQ("1.100000e+00", printToString(1.1));
+
+  // void*
+  EXPECT_EQ("0x0", printToString((void*) nullptr));
+  EXPECT_EQ("0xbeef", printToString((void*) 0xbeefLL));
+  EXPECT_EQ("0xdeadbeef", printToString((void*) 0xdeadbeefLL));
+
+  // Min and max.
+  EXPECT_EQ("18446744073709551615", printToString(UINT64_MAX));
+  EXPECT_EQ("-9223372036854775808", printToString(INT64_MIN));
+}
+
+TEST(raw_ostreamTest, Types_Unbuffered) {  
+  // Char
+  EXPECT_EQ("c", printToStringUnbuffered('c'));
+
+  // String
+  EXPECT_EQ("hello", printToStringUnbuffered("hello"));
+  EXPECT_EQ("hello", printToStringUnbuffered(std::string("hello")));
+
+  // Int
+  EXPECT_EQ("0", printToStringUnbuffered(0));
+  EXPECT_EQ("2425", printToStringUnbuffered(2425));
+  EXPECT_EQ("-2425", printToStringUnbuffered(-2425));
+
+  // Long long
+  EXPECT_EQ("0", printToStringUnbuffered(0LL));
+  EXPECT_EQ("257257257235709", printToStringUnbuffered(257257257235709LL));
+  EXPECT_EQ("-257257257235709", printToStringUnbuffered(-257257257235709LL));
+
+  // Double
+  EXPECT_EQ("1.100000e+00", printToStringUnbuffered(1.1));
+
+  // void*
+  EXPECT_EQ("0x0", printToStringUnbuffered((void*) nullptr));
+  EXPECT_EQ("0xbeef", printToStringUnbuffered((void*) 0xbeefLL));
+  EXPECT_EQ("0xdeadbeef", printToStringUnbuffered((void*) 0xdeadbeefLL));
+
+  // Min and max.
+  EXPECT_EQ("18446744073709551615", printToStringUnbuffered(UINT64_MAX));
+  EXPECT_EQ("-9223372036854775808", printToStringUnbuffered(INT64_MIN));
+}
+
+TEST(raw_ostreamTest, BufferEdge) {  
+  EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 1));
+  EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 2));
+  EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 3));
+  EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 4));
+  EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 10));
+}
+
+TEST(raw_ostreamTest, TinyBuffer) {
+  std::string Str;
+  raw_string_ostream OS(Str);
+  OS.SetBufferSize(1);
+  OS << "hello";
+  OS << 1;
+  OS << 'w' << 'o' << 'r' << 'l' << 'd';
+  EXPECT_EQ("hello1world", OS.str());
+}
+
+TEST(raw_ostreamTest, WriteEscaped) {
+  std::string Str;
+
+  Str = "";
+  raw_string_ostream(Str).write_escaped("hi");
+  EXPECT_EQ("hi", Str);
+
+  Str = "";
+  raw_string_ostream(Str).write_escaped("\\\t\n\"");
+  EXPECT_EQ("\\\\\\t\\n\\\"", Str);
+
+  Str = "";
+  raw_string_ostream(Str).write_escaped("\1\10\200");
+  EXPECT_EQ("\\001\\010\\200", Str);
+}
+
+TEST(raw_ostreamTest, Justify) {  
+  EXPECT_EQ("xyz   ", printToString(left_justify("xyz", 6), 6));
+  EXPECT_EQ("abc",    printToString(left_justify("abc", 3), 3));
+  EXPECT_EQ("big",    printToString(left_justify("big", 1), 3));
+  EXPECT_EQ("   xyz", printToString(right_justify("xyz", 6), 6));
+  EXPECT_EQ("abc",    printToString(right_justify("abc", 3), 3));
+  EXPECT_EQ("big",    printToString(right_justify("big", 1), 3));
+  EXPECT_EQ("   on    ",    printToString(center_justify("on", 9), 9));
+  EXPECT_EQ("   off    ",    printToString(center_justify("off", 10), 10));
+  EXPECT_EQ("single ",    printToString(center_justify("single", 7), 7));
+  EXPECT_EQ("none",    printToString(center_justify("none", 1), 4));
+  EXPECT_EQ("none",    printToString(center_justify("none", 1), 1));
+}
+
+TEST(raw_ostreamTest, FormatHex) {  
+  EXPECT_EQ("0x1234",     printToString(format_hex(0x1234, 6), 6));
+  EXPECT_EQ("0x001234",   printToString(format_hex(0x1234, 8), 8));
+  EXPECT_EQ("0x00001234", printToString(format_hex(0x1234, 10), 10));
+  EXPECT_EQ("0x1234",     printToString(format_hex(0x1234, 4), 6));
+  EXPECT_EQ("0xff",       printToString(format_hex(255, 4), 4));
+  EXPECT_EQ("0xFF",       printToString(format_hex(255, 4, true), 4));
+  EXPECT_EQ("0x1",        printToString(format_hex(1, 3), 3));
+  EXPECT_EQ("0x12",       printToString(format_hex(0x12, 3), 4));
+  EXPECT_EQ("0x123",      printToString(format_hex(0x123, 3), 5));
+  EXPECT_EQ("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",     
+                          printToString(format_hex((INT64_MIN), 18), 18));
+}
+
+TEST(raw_ostreamTest, FormatDecimal) {  
+  EXPECT_EQ("   0",        printToString(format_decimal(0, 4), 4));
+  EXPECT_EQ("  -1",        printToString(format_decimal(-1, 4), 4));
+  EXPECT_EQ("    -1",      printToString(format_decimal(-1, 6), 6));
+  EXPECT_EQ("1234567890",  printToString(format_decimal(1234567890, 10), 10));
+  EXPECT_EQ("  9223372036854775807", 
+                          printToString(format_decimal(INT64_MAX, 21), 21));
+  EXPECT_EQ(" -9223372036854775808", 
+                          printToString(format_decimal(INT64_MIN, 21), 21));
+}
+
+static std::string formatted_bytes_str(ArrayRef<uint8_t> Bytes,
+                                       llvm::Optional<uint64_t> Offset = None,
+                                       uint32_t NumPerLine = 16,
+                                       uint8_t ByteGroupSize = 4) {
+  std::string S;
+  raw_string_ostream Str(S);
+  Str << format_bytes(Bytes, Offset, NumPerLine, ByteGroupSize);
+  Str.flush();
+  return S;
+}
+
+static std::string format_bytes_with_ascii_str(ArrayRef<uint8_t> Bytes,
+                                               Optional<uint64_t> Offset = None,
+                                               uint32_t NumPerLine = 16,
+                                               uint8_t ByteGroupSize = 4) {
+  std::string S;
+  raw_string_ostream Str(S);
+  Str << format_bytes_with_ascii(Bytes, Offset, NumPerLine, ByteGroupSize);
+  Str.flush();
+  return S;
+}
+
+TEST(raw_ostreamTest, FormattedHexBytes) {
+  std::vector<uint8_t> Buf = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+                              'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
+                              's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',
+                              '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+  ArrayRef<uint8_t> B(Buf);
+
+  // Test invalid input.
+  EXPECT_EQ("", formatted_bytes_str(ArrayRef<uint8_t>()));
+  EXPECT_EQ("", format_bytes_with_ascii_str(ArrayRef<uint8_t>()));
+  //----------------------------------------------------------------------
+  // Test hex byte output with the default 4 byte groups
+  //----------------------------------------------------------------------
+  EXPECT_EQ("61", formatted_bytes_str(B.take_front()));
+  EXPECT_EQ("61626364 65", formatted_bytes_str(B.take_front(5)));
+  // Test that 16 bytes get written to a line correctly.
+  EXPECT_EQ("61626364 65666768 696a6b6c 6d6e6f70",
+            formatted_bytes_str(B.take_front(16)));
+  // Test raw bytes with default 16 bytes per line wrapping.
+  EXPECT_EQ("61626364 65666768 696a6b6c 6d6e6f70\n71",
+            formatted_bytes_str(B.take_front(17)));
+  // Test raw bytes with 1 bytes per line wrapping.
+  EXPECT_EQ("61\n62\n63\n64\n65\n66",
+            formatted_bytes_str(B.take_front(6), None, 1));
+  // Test raw bytes with 7 bytes per line wrapping.
+  EXPECT_EQ("61626364 656667\n68696a6b 6c6d6e\n6f7071",
+            formatted_bytes_str(B.take_front(17), None, 7));
+  // Test raw bytes with 8 bytes per line wrapping.
+  EXPECT_EQ("61626364 65666768\n696a6b6c 6d6e6f70\n71",
+            formatted_bytes_str(B.take_front(17), None, 8));
+  //----------------------------------------------------------------------
+  // Test hex byte output with the 1 byte groups
+  //----------------------------------------------------------------------
+  EXPECT_EQ("61 62 63 64 65",
+            formatted_bytes_str(B.take_front(5), None, 16, 1));
+  // Test that 16 bytes get written to a line correctly.
+  EXPECT_EQ("61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70",
+            formatted_bytes_str(B.take_front(16), None, 16, 1));
+  // Test raw bytes with default 16 bytes per line wrapping.
+  EXPECT_EQ("61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70\n71",
+            formatted_bytes_str(B.take_front(17), None, 16, 1));
+  // Test raw bytes with 7 bytes per line wrapping.
+  EXPECT_EQ("61 62 63 64 65 66 67\n68 69 6a 6b 6c 6d 6e\n6f 70 71",
+            formatted_bytes_str(B.take_front(17), None, 7, 1));
+  // Test raw bytes with 8 bytes per line wrapping.
+  EXPECT_EQ("61 62 63 64 65 66 67 68\n69 6a 6b 6c 6d 6e 6f 70\n71",
+            formatted_bytes_str(B.take_front(17), None, 8, 1));
+
+  //----------------------------------------------------------------------
+  // Test hex byte output with the 2 byte groups
+  //----------------------------------------------------------------------
+  EXPECT_EQ("6162 6364 65", formatted_bytes_str(B.take_front(5), None, 16, 2));
+  // Test that 16 bytes get written to a line correctly.
+  EXPECT_EQ("6162 6364 6566 6768 696a 6b6c 6d6e 6f70",
+            formatted_bytes_str(B.take_front(16), None, 16, 2));
+  // Test raw bytes with default 16 bytes per line wrapping.
+  EXPECT_EQ("6162 6364 6566 6768 696a 6b6c 6d6e 6f70\n71",
+            formatted_bytes_str(B.take_front(17), None, 16, 2));
+  // Test raw bytes with 7 bytes per line wrapping.
+  EXPECT_EQ("6162 6364 6566 67\n6869 6a6b 6c6d 6e\n6f70 71",
+            formatted_bytes_str(B.take_front(17), None, 7, 2));
+  // Test raw bytes with 8 bytes per line wrapping.
+  EXPECT_EQ("6162 6364 6566 6768\n696a 6b6c 6d6e 6f70\n71",
+            formatted_bytes_str(B.take_front(17), None, 8, 2));
+
+  //----------------------------------------------------------------------
+  // Test hex bytes with offset with the default 4 byte groups.
+  //----------------------------------------------------------------------
+  EXPECT_EQ("0000: 61", formatted_bytes_str(B.take_front(), 0x0));
+  EXPECT_EQ("1000: 61", formatted_bytes_str(B.take_front(), 0x1000));
+  EXPECT_EQ("1000: 61\n1001: 62",
+            formatted_bytes_str(B.take_front(2), 0x1000, 1));
+  //----------------------------------------------------------------------
+  // Test hex bytes with ASCII with the default 4 byte groups.
+  //----------------------------------------------------------------------
+  EXPECT_EQ("61626364 65666768 696a6b6c 6d6e6f70  |abcdefghijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16)));
+  EXPECT_EQ("61626364 65666768  |abcdefgh|\n"
+            "696a6b6c 6d6e6f70  |ijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), None, 8));
+  EXPECT_EQ("61626364 65666768  |abcdefgh|\n696a6b6c           |ijkl|",
+            format_bytes_with_ascii_str(B.take_front(12), None, 8));
+  std::vector<uint8_t> Unprintable = {'a', '\x1e', 'b', '\x1f'};
+  // Make sure the ASCII is still lined up correctly when fewer bytes than 16
+  // bytes per line are available. The ASCII should still be aligned as if 16
+  // bytes of hex might be displayed.
+  EXPECT_EQ("611e621f                             |a.b.|",
+            format_bytes_with_ascii_str(Unprintable));
+  //----------------------------------------------------------------------
+  // Test hex bytes with ASCII with offsets with the default 4 byte groups.
+  //----------------------------------------------------------------------
+  EXPECT_EQ("0000: 61626364 65666768 "
+            "696a6b6c 6d6e6f70  |abcdefghijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), 0));
+  EXPECT_EQ("0000: 61626364 65666768  |abcdefgh|\n"
+            "0008: 696a6b6c 6d6e6f70  |ijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), 0, 8));
+  EXPECT_EQ("0000: 61626364 656667  |abcdefg|\n"
+            "0007: 68696a6b 6c      |hijkl|",
+            format_bytes_with_ascii_str(B.take_front(12), 0, 7));
+
+  //----------------------------------------------------------------------
+  // Test hex bytes with ASCII with offsets with the default 2 byte groups.
+  //----------------------------------------------------------------------
+  EXPECT_EQ("0000: 6162 6364 6566 6768 "
+            "696a 6b6c 6d6e 6f70  |abcdefghijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), 0, 16, 2));
+  EXPECT_EQ("0000: 6162 6364 6566 6768  |abcdefgh|\n"
+            "0008: 696a 6b6c 6d6e 6f70  |ijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), 0, 8, 2));
+  EXPECT_EQ("0000: 6162 6364 6566 67  |abcdefg|\n"
+            "0007: 6869 6a6b 6c       |hijkl|",
+            format_bytes_with_ascii_str(B.take_front(12), 0, 7, 2));
+
+  //----------------------------------------------------------------------
+  // Test hex bytes with ASCII with offsets with the default 1 byte groups.
+  //----------------------------------------------------------------------
+  EXPECT_EQ("0000: 61 62 63 64 65 66 67 68 "
+            "69 6a 6b 6c 6d 6e 6f 70  |abcdefghijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), 0, 16, 1));
+  EXPECT_EQ("0000: 61 62 63 64 65 66 67 68  |abcdefgh|\n"
+            "0008: 69 6a 6b 6c 6d 6e 6f 70  |ijklmnop|",
+            format_bytes_with_ascii_str(B.take_front(16), 0, 8, 1));
+  EXPECT_EQ("0000: 61 62 63 64 65 66 67  |abcdefg|\n"
+            "0007: 68 69 6a 6b 6c        |hijkl|",
+            format_bytes_with_ascii_str(B.take_front(12), 0, 7, 1));
+}
+
+TEST(raw_fd_ostreamTest, multiple_raw_fd_ostream_to_stdout) {
+  std::error_code EC;
+
+  { raw_fd_ostream("-", EC, sys::fs::OpenFlags::F_None); }
+  { raw_fd_ostream("-", EC, sys::fs::OpenFlags::F_None); }
+}
+}
diff --git a/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
new file mode 100644
index 0000000..a528fd2
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/raw_pwrite_stream_test.cpp
@@ -0,0 +1,95 @@
+//===- 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 "llvm/ADT/SmallString.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+#define ASSERT_NO_ERROR(x)                                                     \
+  if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
+    SmallString<128> MessageStorage;                                           \
+    raw_svector_ostream Message(MessageStorage);                               \
+    Message << #x ": did not return errc::success.\n"                          \
+            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
+            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
+    GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
+  } else {                                                                     \
+  }
+
+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
+}
+
+#ifdef _WIN32
+#define setenv(name, var, ignore) _putenv_s(name, var)
+#endif
+
+TEST(raw_pwrite_ostreamTest, TestFD) {
+  SmallString<64> Path;
+  int FD;
+
+  // If we want to clean up from a death test, we have to remove the file from
+  // the parent process. Have the parent create the file, pass it via
+  // environment variable to the child, let the child crash, and then remove it
+  // in the parent.
+  const char *ParentPath = getenv("RAW_PWRITE_TEST_FILE");
+  if (ParentPath) {
+    Path = ParentPath;
+    ASSERT_NO_ERROR(sys::fs::openFileForRead(Path, FD));
+  } else {
+    ASSERT_NO_ERROR(sys::fs::createTemporaryFile("foo", "bar", FD, Path));
+    setenv("RAW_PWRITE_TEST_FILE", Path.c_str(), true);
+  }
+  FileRemover Cleanup(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::CD_OpenExisting);
+  raw_fd_ostream OS(FD, true);
+  OS << "abcd";
+  StringRef Test = "test";
+  OS.pwrite(Test.data(), Test.size(), 0);
+  OS.pwrite(Test.data(), Test.size(), 0);
+}
+#endif
+}
diff --git a/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
new file mode 100644
index 0000000..e176f3f
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -0,0 +1,78 @@
+//===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream 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/Format.h"
+#include "llvm/Support/raw_sha1_ostream.h"
+#include "gtest/gtest.h"
+
+#include <string>
+
+using namespace llvm;
+
+static std::string toHex(StringRef Input) {
+  static const char *const LUT = "0123456789ABCDEF";
+  size_t Length = Input.size();
+
+  std::string Output;
+  Output.reserve(2 * Length);
+  for (size_t i = 0; i < Length; ++i) {
+    const unsigned char c = Input[i];
+    Output.push_back(LUT[c >> 4]);
+    Output.push_back(LUT[c & 15]);
+  }
+  return Output;
+}
+
+TEST(raw_sha1_ostreamTest, Basic) {
+  llvm::raw_sha1_ostream Sha1Stream;
+  Sha1Stream << "Hello World!";
+  auto Hash = toHex(Sha1Stream.sha1());
+
+  ASSERT_EQ("2EF7BDE608CE5404E97D5F042F95F89F1C232871", Hash);
+}
+
+TEST(sha1_hash_test, Basic) {
+  ArrayRef<uint8_t> Input((const uint8_t *)"Hello World!", 12);
+  std::array<uint8_t, 20> Vec = SHA1::hash(Input);
+  std::string Hash = toHex({(const char *)Vec.data(), 20});
+  ASSERT_EQ("2EF7BDE608CE5404E97D5F042F95F89F1C232871", Hash);
+}
+
+// Check that getting the intermediate hash in the middle of the stream does
+// not invalidate the final result.
+TEST(raw_sha1_ostreamTest, Intermediate) {
+  llvm::raw_sha1_ostream Sha1Stream;
+  Sha1Stream << "Hello";
+  auto Hash = toHex(Sha1Stream.sha1());
+
+  ASSERT_EQ("F7FF9E8B7BB2E09B70935A5D785E0CC5D9D0ABF0", Hash);
+  Sha1Stream << " World!";
+  Hash = toHex(Sha1Stream.sha1());
+
+  // Compute the non-split hash separately as a reference.
+  llvm::raw_sha1_ostream NonSplitSha1Stream;
+  NonSplitSha1Stream << "Hello World!";
+  auto NonSplitHash = toHex(NonSplitSha1Stream.sha1());
+
+  ASSERT_EQ(NonSplitHash, Hash);
+}
+
+TEST(raw_sha1_ostreamTest, Reset) {
+  llvm::raw_sha1_ostream Sha1Stream;
+  Sha1Stream << "Hello";
+  auto Hash = toHex(Sha1Stream.sha1());
+
+  ASSERT_EQ("F7FF9E8B7BB2E09B70935A5D785E0CC5D9D0ABF0", Hash);
+
+  Sha1Stream.resetHash();
+  Sha1Stream << " World!";
+  Hash = toHex(Sha1Stream.sha1());
+
+  ASSERT_EQ("7447F2A5A42185C8CF91E632789C431830B59067", Hash);
+}
diff --git a/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp b/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
new file mode 100644
index 0000000..6a88a2d
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/xxhashTest.cpp
@@ -0,0 +1,20 @@
+//===- llvm/unittest/Support/xxhashTest.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/xxhash.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(xxhashTest, Basic) {
+  EXPECT_EQ(0x33bf00a859c4ba3fU, xxHash64("foo"));
+  EXPECT_EQ(0x48a37c90ad27a659U, xxHash64("bar"));
+  EXPECT_EQ(0x69196c1b3af0bff9U,
+            xxHash64("0123456789abcdefghijklmnopqrstuvwxyz"));
+}