Importing rustc-1.45.2

Change-Id: Idd187dd729f3089d9529753a17db5fbb40bacdeb
diff --git a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
index 94c6f5a..d8cabde 100644
--- a/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/AlignOfTest.cpp
@@ -38,10 +38,10 @@
 #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 alignas(1) A1 {};
+struct alignas(2) A2 {};
+struct alignas(4) A4 {};
+struct alignas(8) A8 {};
 
 struct S1 {};
 struct S2 { char a; };
@@ -233,16 +233,5 @@
 #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/AlignmentTest.cpp b/src/llvm-project/llvm/unittests/Support/AlignmentTest.cpp
new file mode 100644
index 0000000..cbd0856
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/AlignmentTest.cpp
@@ -0,0 +1,396 @@
+//=== - llvm/unittest/Support/Alignment.cpp - Alignment utility tests -----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Alignment.h"
+#include "gtest/gtest.h"
+
+#include <vector>
+
+#ifdef _MSC_VER
+// Disable warnings about potential divide by 0.
+#pragma warning(push)
+#pragma warning(disable : 4723)
+#endif
+
+using namespace llvm;
+
+namespace {
+
+TEST(AlignmentTest, AlignOfConstant) {
+  EXPECT_EQ(Align::Of<uint8_t>(), Align(alignof(uint8_t)));
+  EXPECT_EQ(Align::Of<uint16_t>(), Align(alignof(uint16_t)));
+  EXPECT_EQ(Align::Of<uint32_t>(), Align(alignof(uint32_t)));
+  EXPECT_EQ(Align::Of<uint64_t>(), Align(alignof(uint64_t)));
+}
+
+TEST(AlignmentTest, AlignConstant) {
+  EXPECT_EQ(Align::Constant<1>(), Align(1));
+  EXPECT_EQ(Align::Constant<2>(), Align(2));
+  EXPECT_EQ(Align::Constant<4>(), Align(4));
+  EXPECT_EQ(Align::Constant<8>(), Align(8));
+  EXPECT_EQ(Align::Constant<16>(), Align(16));
+  EXPECT_EQ(Align::Constant<32>(), Align(32));
+  EXPECT_EQ(Align::Constant<64>(), Align(64));
+}
+
+TEST(AlignmentTest, AlignConstexprConstant) {
+  constexpr Align kConstantAlign = Align::Of<uint64_t>();
+  EXPECT_EQ(Align(alignof(uint64_t)), kConstantAlign);
+}
+
+std::vector<uint64_t> getValidAlignments() {
+  std::vector<uint64_t> Out;
+  for (size_t Shift = 0; Shift < 64; ++Shift)
+    Out.push_back(1ULL << Shift);
+  return Out;
+}
+
+TEST(AlignmentTest, AlignDefaultCTor) {
+  EXPECT_EQ(Align().value(), 1ULL);
+  EXPECT_EQ(Align::None().value(), 1ULL);
+}
+
+TEST(AlignmentTest, MaybeAlignDefaultCTor) {
+  EXPECT_FALSE(MaybeAlign().hasValue());
+}
+
+TEST(AlignmentTest, ValidCTors) {
+  for (uint64_t Value : getValidAlignments()) {
+    EXPECT_EQ(Align(Value).value(), Value);
+    EXPECT_EQ((*MaybeAlign(Value)).value(), Value);
+  }
+}
+
+TEST(AlignmentTest, CheckMaybeAlignHasValue) {
+  EXPECT_TRUE(MaybeAlign(1));
+  EXPECT_TRUE(MaybeAlign(1).hasValue());
+  EXPECT_FALSE(MaybeAlign(0));
+  EXPECT_FALSE(MaybeAlign(0).hasValue());
+  EXPECT_FALSE(MaybeAlign());
+  EXPECT_FALSE(MaybeAlign().hasValue());
+}
+
+TEST(AlignmentTest, Division) {
+  for (uint64_t Value : getValidAlignments()) {
+    if (Value > 1) {
+      EXPECT_EQ(Align(Value) / 2, Value / 2);
+      EXPECT_EQ(MaybeAlign(Value) / 2, Value / 2);
+    }
+  }
+  EXPECT_EQ(MaybeAlign(0) / 2, MaybeAlign(0));
+}
+
+TEST(AlignmentTest, AlignTo) {
+  struct {
+    uint64_t alignment;
+    uint64_t offset;
+    uint64_t rounded;
+    const void *forgedAddr() const {
+      //  A value of any integral or enumeration type can be converted to a
+      //  pointer type.
+      return reinterpret_cast<const void *>(offset);
+    }
+  } kTests[] = {
+      // MaybeAlign
+      {0, 0, 0},
+      {0, 1, 1},
+      {0, 5, 5},
+      // MaybeAlign / Align
+      {1, 0, 0},
+      {1, 1, 1},
+      {1, 5, 5},
+      {2, 0, 0},
+      {2, 1, 2},
+      {2, 2, 2},
+      {2, 7, 8},
+      {2, 16, 16},
+      {4, 0, 0},
+      {4, 1, 4},
+      {4, 4, 4},
+      {4, 6, 8},
+  };
+  for (const auto &T : kTests) {
+    MaybeAlign A(T.alignment);
+    // Test MaybeAlign
+    EXPECT_EQ(alignTo(T.offset, A), T.rounded);
+    // Test Align
+    if (A) {
+      EXPECT_EQ(alignTo(T.offset, A.getValue()), T.rounded);
+      EXPECT_EQ(alignAddr(T.forgedAddr(), A.getValue()), T.rounded);
+    }
+  }
+}
+
+TEST(AlignmentTest, Log2) {
+  for (uint64_t Value : getValidAlignments()) {
+    EXPECT_EQ(Log2(Align(Value)), Log2_64(Value));
+    EXPECT_EQ(Log2(MaybeAlign(Value)), Log2_64(Value));
+  }
+}
+
+TEST(AlignmentTest, MinAlign) {
+  struct {
+    uint64_t A;
+    uint64_t B;
+    uint64_t MinAlign;
+  } kTests[] = {
+      // MaybeAlign
+      {0, 0, 0},
+      {0, 8, 8},
+      {2, 0, 2},
+      // MaybeAlign / Align
+      {1, 2, 1},
+      {8, 4, 4},
+  };
+  for (const auto &T : kTests) {
+    EXPECT_EQ(commonAlignment(MaybeAlign(T.A), MaybeAlign(T.B)), T.MinAlign);
+    EXPECT_EQ(MinAlign(T.A, T.B), T.MinAlign);
+    if (T.A) {
+      EXPECT_EQ(commonAlignment(Align(T.A), MaybeAlign(T.B)), T.MinAlign);
+    }
+    if (T.B) {
+      EXPECT_EQ(commonAlignment(MaybeAlign(T.A), Align(T.B)), T.MinAlign);
+    }
+    if (T.A && T.B) {
+      EXPECT_EQ(commonAlignment(Align(T.A), Align(T.B)), T.MinAlign);
+    }
+  }
+}
+
+TEST(AlignmentTest, Encode_Decode) {
+  for (uint64_t Value : getValidAlignments()) {
+    {
+      Align Actual(Value);
+      Align Expected = decodeMaybeAlign(encode(Actual)).getValue();
+      EXPECT_EQ(Expected, Actual);
+    }
+    {
+      MaybeAlign Actual(Value);
+      MaybeAlign Expected = decodeMaybeAlign(encode(Actual));
+      EXPECT_EQ(Expected, Actual);
+    }
+  }
+  MaybeAlign Actual(0);
+  MaybeAlign Expected = decodeMaybeAlign(encode(Actual));
+  EXPECT_EQ(Expected, Actual);
+}
+
+TEST(AlignmentTest, isAligned_isAddrAligned) {
+  struct {
+    uint64_t alignment;
+    uint64_t offset;
+    bool isAligned;
+    const void *forgedAddr() const {
+      //  A value of any integral or enumeration type can be converted to a
+      //  pointer type.
+      return reinterpret_cast<const void *>(offset);
+    }
+  } kTests[] = {
+      {1, 0, true},  {1, 1, true},  {1, 5, true},  {2, 0, true},
+      {2, 1, false}, {2, 2, true},  {2, 7, false}, {2, 16, true},
+      {4, 0, true},  {4, 1, false}, {4, 4, true},  {4, 6, false},
+  };
+  for (const auto &T : kTests) {
+    MaybeAlign A(T.alignment);
+    // Test MaybeAlign
+    EXPECT_EQ(isAligned(A, T.offset), T.isAligned);
+    // Test Align
+    if (A) {
+      EXPECT_EQ(isAligned(A.getValue(), T.offset), T.isAligned);
+      EXPECT_EQ(isAddrAligned(A.getValue(), T.forgedAddr()), T.isAligned);
+    }
+  }
+}
+
+TEST(AlignmentTest, offsetToAlignment) {
+  struct {
+    uint64_t alignment;
+    uint64_t offset;
+    uint64_t alignedOffset;
+    const void *forgedAddr() const {
+      //  A value of any integral or enumeration type can be converted to a
+      //  pointer type.
+      return reinterpret_cast<const void *>(offset);
+    }
+  } kTests[] = {
+      {1, 0, 0}, {1, 1, 0},  {1, 5, 0}, {2, 0, 0}, {2, 1, 1}, {2, 2, 0},
+      {2, 7, 1}, {2, 16, 0}, {4, 0, 0}, {4, 1, 3}, {4, 4, 0}, {4, 6, 2},
+  };
+  for (const auto &T : kTests) {
+    const Align A(T.alignment);
+    EXPECT_EQ(offsetToAlignment(T.offset, A), T.alignedOffset);
+    EXPECT_EQ(offsetToAlignedAddr(T.forgedAddr(), A), T.alignedOffset);
+  }
+}
+
+TEST(AlignmentTest, AlignComparisons) {
+  std::vector<uint64_t> ValidAlignments = getValidAlignments();
+  std::sort(ValidAlignments.begin(), ValidAlignments.end());
+  for (size_t I = 1; I < ValidAlignments.size(); ++I) {
+    assert(I >= 1);
+    const Align A(ValidAlignments[I - 1]);
+    const Align B(ValidAlignments[I]);
+    EXPECT_EQ(A, A);
+    EXPECT_NE(A, B);
+    EXPECT_LT(A, B);
+    EXPECT_GT(B, A);
+    EXPECT_LE(A, B);
+    EXPECT_GE(B, A);
+    EXPECT_LE(A, A);
+    EXPECT_GE(A, A);
+
+    EXPECT_EQ(A, A.value());
+    EXPECT_NE(A, B.value());
+    EXPECT_LT(A, B.value());
+    EXPECT_GT(B, A.value());
+    EXPECT_LE(A, B.value());
+    EXPECT_GE(B, A.value());
+    EXPECT_LE(A, A.value());
+    EXPECT_GE(A, A.value());
+
+    EXPECT_EQ(std::max(A, B), B);
+    EXPECT_EQ(std::min(A, B), A);
+
+    const MaybeAlign MA(ValidAlignments[I - 1]);
+    const MaybeAlign MB(ValidAlignments[I]);
+    EXPECT_EQ(MA, MA);
+    EXPECT_NE(MA, MB);
+    EXPECT_LT(MA, MB);
+    EXPECT_GT(MB, MA);
+    EXPECT_LE(MA, MB);
+    EXPECT_GE(MB, MA);
+    EXPECT_LE(MA, MA);
+    EXPECT_GE(MA, MA);
+
+    EXPECT_EQ(MA, MA ? (*MA).value() : 0);
+    EXPECT_NE(MA, MB ? (*MB).value() : 0);
+    EXPECT_LT(MA, MB ? (*MB).value() : 0);
+    EXPECT_GT(MB, MA ? (*MA).value() : 0);
+    EXPECT_LE(MA, MB ? (*MB).value() : 0);
+    EXPECT_GE(MB, MA ? (*MA).value() : 0);
+    EXPECT_LE(MA, MA ? (*MA).value() : 0);
+    EXPECT_GE(MA, MA ? (*MA).value() : 0);
+
+    EXPECT_EQ(std::max(A, B), B);
+    EXPECT_EQ(std::min(A, B), A);
+  }
+}
+
+TEST(AlignmentTest, Max) {
+  // We introduce std::max here to test ADL.
+  using std::max;
+
+  // Uses llvm::max.
+  EXPECT_EQ(max(MaybeAlign(), Align(2)), Align(2));
+  EXPECT_EQ(max(Align(2), MaybeAlign()), Align(2));
+
+  EXPECT_EQ(max(MaybeAlign(1), Align(2)), Align(2));
+  EXPECT_EQ(max(Align(2), MaybeAlign(1)), Align(2));
+
+  EXPECT_EQ(max(MaybeAlign(2), Align(2)), Align(2));
+  EXPECT_EQ(max(Align(2), MaybeAlign(2)), Align(2));
+
+  EXPECT_EQ(max(MaybeAlign(4), Align(2)), Align(4));
+  EXPECT_EQ(max(Align(2), MaybeAlign(4)), Align(4));
+
+  // Uses std::max.
+  EXPECT_EQ(max(Align(2), Align(4)), Align(4));
+  EXPECT_EQ(max(MaybeAlign(2), MaybeAlign(4)), MaybeAlign(4));
+  EXPECT_EQ(max(MaybeAlign(), MaybeAlign()), MaybeAlign());
+}
+
+TEST(AlignmentTest, AssumeAligned) {
+  EXPECT_EQ(assumeAligned(0), Align(1));
+  EXPECT_EQ(assumeAligned(0), Align());
+  EXPECT_EQ(assumeAligned(1), Align(1));
+  EXPECT_EQ(assumeAligned(1), Align());
+}
+
+// Death tests reply on assert which is disabled in release mode.
+#ifndef NDEBUG
+
+// We use a subset of valid alignments for DEATH_TESTs as they are particularly
+// slow.
+std::vector<uint64_t> getValidAlignmentsForDeathTest() {
+  return {1, 1ULL << 31, 1ULL << 63};
+}
+
+std::vector<uint64_t> getNonPowerOfTwo() { return {3, 10, 15}; }
+
+TEST(AlignmentDeathTest, Log2) {
+  EXPECT_DEATH(Log2(MaybeAlign(0)), ".* should be defined");
+}
+
+TEST(AlignmentDeathTest, CantConvertUnsetMaybe) {
+  EXPECT_DEATH((MaybeAlign(0).getValue()), ".*");
+}
+
+TEST(AlignmentDeathTest, Division) {
+  EXPECT_DEATH(Align(1) / 2, "Can't halve byte alignment");
+  EXPECT_DEATH(MaybeAlign(1) / 2, "Can't halve byte alignment");
+
+  EXPECT_DEATH(Align(8) / 0, "Divisor must be positive and a power of 2");
+  EXPECT_DEATH(Align(8) / 3, "Divisor must be positive and a power of 2");
+}
+
+TEST(AlignmentDeathTest, InvalidCTors) {
+  EXPECT_DEATH((Align(0)), "Value must not be 0");
+  for (uint64_t Value : getNonPowerOfTwo()) {
+    EXPECT_DEATH((Align(Value)), "Alignment is not a power of 2");
+    EXPECT_DEATH((MaybeAlign(Value)),
+                 "Alignment is neither 0 nor a power of 2");
+  }
+}
+
+TEST(AlignmentDeathTest, ComparisonsWithZero) {
+  for (uint64_t Value : getValidAlignmentsForDeathTest()) {
+    EXPECT_DEATH((void)(Align(Value) == 0), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) != 0), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) >= 0), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) <= 0), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) > 0), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) < 0), ".* should be defined");
+  }
+}
+
+TEST(AlignmentDeathTest, CompareMaybeAlignToZero) {
+  for (uint64_t Value : getValidAlignmentsForDeathTest()) {
+    // MaybeAlign is allowed to be == or != 0
+    (void)(MaybeAlign(Value) == 0);
+    (void)(MaybeAlign(Value) != 0);
+    EXPECT_DEATH((void)(MaybeAlign(Value) >= 0), ".* should be defined");
+    EXPECT_DEATH((void)(MaybeAlign(Value) <= 0), ".* should be defined");
+    EXPECT_DEATH((void)(MaybeAlign(Value) > 0), ".* should be defined");
+    EXPECT_DEATH((void)(MaybeAlign(Value) < 0), ".* should be defined");
+  }
+}
+
+TEST(AlignmentDeathTest, CompareAlignToUndefMaybeAlign) {
+  for (uint64_t Value : getValidAlignmentsForDeathTest()) {
+    EXPECT_DEATH((void)(Align(Value) == MaybeAlign(0)), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) != MaybeAlign(0)), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) >= MaybeAlign(0)), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) <= MaybeAlign(0)), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) > MaybeAlign(0)), ".* should be defined");
+    EXPECT_DEATH((void)(Align(Value) < MaybeAlign(0)), ".* should be defined");
+  }
+}
+
+TEST(AlignmentDeathTest, AlignAddr) {
+  const void *const unaligned_high_ptr =
+      reinterpret_cast<const void *>(std::numeric_limits<uintptr_t>::max() - 1);
+  EXPECT_DEATH(alignAddr(unaligned_high_ptr, Align(16)), "Overflow");
+}
+
+#endif // NDEBUG
+
+} // end anonymous namespace
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
index a0223ea..8a07ddd 100644
--- a/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/AllocatorTest.cpp
@@ -145,8 +145,8 @@
   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*));
+    Align Alignment(4096);
+    void *MemBase = safe_malloc(Size + Alignment.value() - 1 + sizeof(void *));
 
     // Find the slab start.
     void *Slab = (void *)alignAddr((char*)MemBase + sizeof(void *), Alignment);
diff --git a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
index 5291a31..6d6ecc4 100644
--- a/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/BinaryStreamTest.cpp
@@ -144,8 +144,8 @@
 
     for (uint32_t I = 0; I < NumEndians; ++I) {
       auto InByteStream =
-          llvm::make_unique<BinaryByteStream>(InputData, Endians[I]);
-      auto InBrokenStream = llvm::make_unique<BrokenStream>(
+          std::make_unique<BinaryByteStream>(InputData, Endians[I]);
+      auto InBrokenStream = std::make_unique<BrokenStream>(
           BrokenInputData, Endians[I], Align);
 
       Streams[I * 2].Input = std::move(InByteStream);
@@ -159,8 +159,8 @@
 
     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>(
+          std::make_unique<MutableBinaryByteStream>(OutputData, Endians[I]);
+      Streams[I * 2 + 1].Output = std::make_unique<BrokenStream>(
           BrokenOutputData, Endians[I], Align);
     }
   }
@@ -168,8 +168,8 @@
   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>(
+          std::make_unique<MutableBinaryByteStream>(InputData, Endians[I]);
+      Streams[I * 2 + 1].Output = std::make_unique<BrokenStream>(
           BrokenInputData, Endians[I], Align);
     }
   }
@@ -177,8 +177,8 @@
   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>(
+          std::make_unique<BinaryByteStream>(OutputData, Endians[I]);
+      Streams[I * 2 + 1].Input = std::make_unique<BrokenStream>(
           BrokenOutputData, Endians[I], Align);
     }
   }
diff --git a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
index da2b501..1618915 100644
--- a/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
+++ b/src/llvm-project/llvm/unittests/Support/CMakeLists.txt
@@ -3,6 +3,7 @@
   )
 
 add_llvm_unittest(SupportTests
+  AlignmentTest.cpp
   AlignOfTest.cpp
   AllocatorTest.cpp
   AnnotationsTest.cpp
@@ -30,7 +31,9 @@
   ErrorOrTest.cpp
   ErrorTest.cpp
   FileCheckTest.cpp
+  FileCollectorTest.cpp
   FileOutputBufferTest.cpp
+  FileUtilitiesTest.cpp
   FormatVariadicTest.cpp
   GlobPatternTest.cpp
   Host.cpp
diff --git a/src/llvm-project/llvm/unittests/Support/CRCTest.cpp b/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
index 71afb0a..32d2cf7 100644
--- a/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CRCTest.cpp
@@ -11,19 +11,54 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/CRC.h"
+#include "llvm/ADT/StringExtras.h"
 #include "gtest/gtest.h"
+#include <stdlib.h>
 
 using namespace llvm;
 
 namespace {
 
 TEST(CRCTest, CRC32) {
-  EXPECT_EQ(0x414FA339U,
-            llvm::crc32(
-                0, StringRef("The quick brown fox jumps over the lazy dog")));
+  EXPECT_EQ(0x414FA339U, llvm::crc32(arrayRefFromStringRef(
+                             "The quick brown fox jumps over the lazy dog")));
+
   // CRC-32/ISO-HDLC test vector
   // http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32c
-  EXPECT_EQ(0xCBF43926U, llvm::crc32(0, StringRef("123456789")));
+  EXPECT_EQ(0xCBF43926U, llvm::crc32(arrayRefFromStringRef("123456789")));
+
+  // Check the CRC-32 of each byte value, exercising all of CRCTable.
+  for (int i = 0; i < 256; i++) {
+    // Compute CRCTable[i] using Hacker's Delight (2nd ed.) Figure 14-7.
+    uint32_t crc = i;
+    for (int j = 7; j >= 0; j--) {
+      uint32_t mask = -(crc & 1);
+      crc = (crc >> 1) ^ (0xEDB88320 & mask);
+    }
+
+    // CRCTable[i] is the CRC-32 of i without the initial and final bit flips.
+    uint8_t byte = i;
+    EXPECT_EQ(crc, ~llvm::crc32(0xFFFFFFFFU, byte));
+  }
+
+  EXPECT_EQ(0x00000000U, llvm::crc32(arrayRefFromStringRef("")));
 }
 
+#if (SIZE_MAX > UINT32_MAX) && defined(EXPENSIVE_CHECKS)
+TEST(CRCTest, LargeCRC32) {
+  // Check that crc32 can handle inputs with sizes larger than 32 bits.
+  size_t TestSize = (size_t)UINT32_MAX + 42;
+  uint8_t *TestData = (uint8_t*)calloc(TestSize, 1);
+  if (!TestData)
+    return;
+
+  // Test expectation generated with:
+  // $ truncate --size=`echo 2^32-1+42 | bc` /tmp/foo
+  // $ crc32 /tmp/foo
+  EXPECT_EQ(0xE46F28FBU, llvm::crc32(makeArrayRef(TestData, TestSize)));
+
+  free(TestData);
+}
+#endif
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/Casting.cpp b/src/llvm-project/llvm/unittests/Support/Casting.cpp
index bcdaca9..a196fc2 100644
--- a/src/llvm-project/llvm/unittests/Support/Casting.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Casting.cpp
@@ -193,12 +193,12 @@
   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>(); }
+std::unique_ptr<derived> newd() { return std::make_unique<derived>(); }
+std::unique_ptr<base> newb() { return std::make_unique<derived>(); }
 
 TEST(CastingTest, unique_dyn_cast) {
   derived *OrigD = nullptr;
-  auto D = llvm::make_unique<derived>();
+  auto D = std::make_unique<derived>();
   OrigD = D.get();
 
   // Converting from D to itself is valid, it should return a new unique_ptr
diff --git a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
index 1a1c8a4..a435200 100644
--- a/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CommandLineTest.cpp
@@ -9,23 +9,33 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Config/config.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/InitLLVM.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/StringSaver.h"
+#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include <fstream>
 #include <stdlib.h>
 #include <string>
+#include <tuple>
 
 using namespace llvm;
 
 namespace {
 
+MATCHER(StringEquality, "Checks if two char* are equal as strings") {
+  return std::string(std::get<0>(arg)) == std::string(std::get<1>(arg));
+}
+
 class TempEnvVar {
  public:
   TempEnvVar(const char *name, const char *value)
@@ -61,7 +71,7 @@
   ~StackOption() override { this->removeArgument(); }
 
   template <class DT> StackOption<T> &operator=(const DT &V) {
-    this->setValue(V);
+    Base::operator=(V);
     return *this;
   }
 };
@@ -778,119 +788,99 @@
 }
 
 TEST(CommandLineTest, ResponseFiles) {
-  llvm::SmallString<128> TestDir;
-  std::error_code EC =
-    llvm::sys::fs::createUniqueDirectory("unittest", TestDir);
-  EXPECT_TRUE(!EC);
+  vfs::InMemoryFileSystem FS;
+#ifdef _WIN32
+  const char *TestRoot = "C:\\";
+#else
+  const char *TestRoot = "/";
+#endif
+  FS.setCurrentWorkingDirectory(TestRoot);
 
   // 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"
-                  "@incdir/resp3\n"
-                  "-option_4=efjk\n";
-  IncludedFile.close();
+  llvm::StringRef IncludedFileName = "resp1";
+  FS.addFile(IncludedFileName, 0,
+             llvm::MemoryBuffer::getMemBuffer("-option_1 -option_2\n"
+                                              "@incdir/resp2\n"
+                                              "-option_3=abcd\n"
+                                              "@incdir/resp3\n"
+                                              "-option_4=efjk\n"));
 
   // 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);
+  llvm::StringRef IncDir = "incdir";
 
   // 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();
+  FS.addFile(IncludedFileName2, 0,
+             MemoryBuffer::getMemBuffer("-option_21 -option_22\n"
+                                        "-option_23=abcd\n"));
 
   // Create second included response file of second level.
   llvm::SmallString<128> IncludedFileName3;
   llvm::sys::path::append(IncludedFileName3, IncDir, "resp3");
-  std::ofstream IncludedFile3(IncludedFileName3.c_str());
-  EXPECT_TRUE(IncludedFile3.is_open());
-  IncludedFile3 << "-option_31 -option_32\n";
-  IncludedFile3 << "-option_33=abcd\n";
-  IncludedFile3.close();
+  FS.addFile(IncludedFileName3, 0,
+             MemoryBuffer::getMemBuffer("-option_31 -option_32\n"
+                                        "-option_33=abcd\n"));
 
   // 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" };
+  IncRef.append(IncludedFileName);
+  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(), 13U);
-  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], "-option_31");
-  EXPECT_STREQ(Argv[9], "-option_32");
-  EXPECT_STREQ(Argv[10], "-option_33=abcd");
-  EXPECT_STREQ(Argv[11], "-option_4=efjk");
-  EXPECT_STREQ(Argv[12], "-flag_2");
-
-  llvm::sys::fs::remove(IncludedFileName3);
-  llvm::sys::fs::remove(IncludedFileName2);
-  llvm::sys::fs::remove(IncDir);
-  llvm::sys::fs::remove(IncludedFileName);
-  llvm::sys::fs::remove(TestDir);
+  ASSERT_TRUE(llvm::cl::ExpandResponseFiles(
+      Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true, FS,
+      /*CurrentDir=*/StringRef(TestRoot)));
+  EXPECT_THAT(Argv, testing::Pointwise(
+                        StringEquality(),
+                        {"test/test", "-flag_1", "-option_1", "-option_2",
+                         "-option_21", "-option_22", "-option_23=abcd",
+                         "-option_3=abcd", "-option_31", "-option_32",
+                         "-option_33=abcd", "-option_4=efjk", "-flag_2"}));
 }
 
 TEST(CommandLineTest, RecursiveResponseFiles) {
-  SmallString<128> TestDir;
-  std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
-  EXPECT_TRUE(!EC);
+  vfs::InMemoryFileSystem FS;
+#ifdef _WIN32
+  const char *TestRoot = "C:\\";
+#else
+  const char *TestRoot = "/";
+#endif
+  FS.setCurrentWorkingDirectory(TestRoot);
 
-  SmallString<128> SelfFilePath;
-  sys::path::append(SelfFilePath, TestDir, "self.rsp");
-  std::string SelfFileRef = std::string("@") + SelfFilePath.c_str();
+  StringRef SelfFilePath = "self.rsp";
+  std::string SelfFileRef = ("@" + SelfFilePath).str();
 
-  SmallString<128> NestedFilePath;
-  sys::path::append(NestedFilePath, TestDir, "nested.rsp");
-  std::string NestedFileRef = std::string("@") + NestedFilePath.c_str();
+  StringRef NestedFilePath = "nested.rsp";
+  std::string NestedFileRef = ("@" + NestedFilePath).str();
 
-  SmallString<128> FlagFilePath;
-  sys::path::append(FlagFilePath, TestDir, "flag.rsp");
-  std::string FlagFileRef = std::string("@") + FlagFilePath.c_str();
+  StringRef FlagFilePath = "flag.rsp";
+  std::string FlagFileRef = ("@" + FlagFilePath).str();
 
-  std::ofstream SelfFile(SelfFilePath.str());
-  EXPECT_TRUE(SelfFile.is_open());
+  std::string SelfFileContents;
+  raw_string_ostream SelfFile(SelfFileContents);
   SelfFile << "-option_1\n";
   SelfFile << FlagFileRef << "\n";
   SelfFile << NestedFileRef << "\n";
   SelfFile << SelfFileRef << "\n";
-  SelfFile.close();
+  FS.addFile(SelfFilePath, 0, MemoryBuffer::getMemBuffer(SelfFile.str()));
 
-  std::ofstream NestedFile(NestedFilePath.str());
-  EXPECT_TRUE(NestedFile.is_open());
+  std::string NestedFileContents;
+  raw_string_ostream NestedFile(NestedFileContents);
   NestedFile << "-option_2\n";
   NestedFile << FlagFileRef << "\n";
   NestedFile << SelfFileRef << "\n";
   NestedFile << NestedFileRef << "\n";
-  NestedFile.close();
+  FS.addFile(NestedFilePath, 0, MemoryBuffer::getMemBuffer(NestedFile.str()));
 
-  std::ofstream FlagFile(FlagFilePath.str());
-  EXPECT_TRUE(FlagFile.is_open());
+  std::string FlagFileContents;
+  raw_string_ostream FlagFile(FlagFileContents);
   FlagFile << "-option_x\n";
-  FlagFile.close();
+  FS.addFile(FlagFilePath, 0, MemoryBuffer::getMemBuffer(FlagFile.str()));
 
   // Ensure:
   // Recursive expansion terminates
@@ -905,47 +895,48 @@
 #else
   cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine;
 #endif
-  bool Res = cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false);
-  EXPECT_FALSE(Res);
+  ASSERT_FALSE(
+      cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, FS,
+                              /*CurrentDir=*/llvm::StringRef(TestRoot)));
 
-  EXPECT_EQ(Argv.size(), 9U);
-  EXPECT_STREQ(Argv[0], "test/test");
-  EXPECT_STREQ(Argv[1], "-option_1");
-  EXPECT_STREQ(Argv[2], "-option_x");
-  EXPECT_STREQ(Argv[3], "-option_2");
-  EXPECT_STREQ(Argv[4], "-option_x");
-  EXPECT_STREQ(Argv[5], SelfFileRef.c_str());
-  EXPECT_STREQ(Argv[6], NestedFileRef.c_str());
-  EXPECT_STREQ(Argv[7], SelfFileRef.c_str());
-  EXPECT_STREQ(Argv[8], "-option_3");
+  EXPECT_THAT(Argv,
+              testing::Pointwise(StringEquality(),
+                                 {"test/test", "-option_1", "-option_x",
+                                  "-option_2", "-option_x", SelfFileRef.c_str(),
+                                  NestedFileRef.c_str(), SelfFileRef.c_str(),
+                                  "-option_3"}));
 }
 
 TEST(CommandLineTest, ResponseFilesAtArguments) {
-  SmallString<128> TestDir;
-  std::error_code EC = sys::fs::createUniqueDirectory("unittest", TestDir);
-  EXPECT_TRUE(!EC);
+  vfs::InMemoryFileSystem FS;
+#ifdef _WIN32
+  const char *TestRoot = "C:\\";
+#else
+  const char *TestRoot = "/";
+#endif
+  FS.setCurrentWorkingDirectory(TestRoot);
 
-  SmallString<128> ResponseFilePath;
-  sys::path::append(ResponseFilePath, TestDir, "test.rsp");
+  StringRef ResponseFilePath = "test.rsp";
 
-  std::ofstream ResponseFile(ResponseFilePath.c_str());
-  EXPECT_TRUE(ResponseFile.is_open());
+  std::string ResponseFileContents;
+  raw_string_ostream ResponseFile(ResponseFileContents);
   ResponseFile << "-foo" << "\n";
   ResponseFile << "-bar" << "\n";
-  ResponseFile.close();
+  FS.addFile(ResponseFilePath, 0,
+             MemoryBuffer::getMemBuffer(ResponseFile.str()));
 
   // Ensure we expand rsp files after lots of non-rsp arguments starting with @.
   constexpr size_t NON_RSP_AT_ARGS = 64;
   SmallVector<const char *, 4> Argv = {"test/test"};
   Argv.append(NON_RSP_AT_ARGS, "@non_rsp_at_arg");
-  std::string ResponseFileRef = std::string("@") + ResponseFilePath.c_str();
+  std::string ResponseFileRef = ("@" + ResponseFilePath).str();
   Argv.push_back(ResponseFileRef.c_str());
 
   BumpPtrAllocator A;
   StringSaver Saver(A);
-  bool Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
-                                     false, false);
-  EXPECT_FALSE(Res);
+  ASSERT_FALSE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
+                                       false, false, FS,
+                                       /*CurrentDir=*/StringRef(TestRoot)));
 
   // ASSERT instead of EXPECT to prevent potential out-of-bounds access.
   ASSERT_EQ(Argv.size(), 1 + NON_RSP_AT_ARGS + 2);
@@ -957,6 +948,34 @@
   EXPECT_STREQ(Argv[i++], "-bar");
 }
 
+TEST(CommandLineTest, ResponseFileRelativePath) {
+  vfs::InMemoryFileSystem FS;
+#ifdef _WIN32
+  const char *TestRoot = "C:\\";
+#else
+  const char *TestRoot = "//net";
+#endif
+  FS.setCurrentWorkingDirectory(TestRoot);
+
+  StringRef OuterFile = "dir/outer.rsp";
+  StringRef OuterFileContents = "@inner.rsp";
+  FS.addFile(OuterFile, 0, MemoryBuffer::getMemBuffer(OuterFileContents));
+
+  StringRef InnerFile = "dir/inner.rsp";
+  StringRef InnerFileContents = "-flag";
+  FS.addFile(InnerFile, 0, MemoryBuffer::getMemBuffer(InnerFileContents));
+
+  SmallVector<const char *, 2> Argv = {"test/test", "@dir/outer.rsp"};
+
+  BumpPtrAllocator A;
+  StringSaver Saver(A);
+  ASSERT_TRUE(cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv,
+                                      false, true, FS,
+                                      /*CurrentDir=*/StringRef(TestRoot)));
+  EXPECT_THAT(Argv,
+              testing::Pointwise(StringEquality(), {"test/test", "-flag"}));
+}
+
 TEST(CommandLineTest, SetDefautValue) {
   cl::ResetCommandLineParser();
 
@@ -1653,4 +1672,124 @@
   EXPECT_TRUE(Errs.empty()); Errs.clear();
   cl::ResetAllOptionOccurrences();
 }
-}  // anonymous namespace
+
+TEST(CommandLineTest, OptionErrorMessage) {
+  // When there is an error, we expect some error message like:
+  //   prog: for the -a option: [...]
+  //
+  // Test whether the "for the -a option"-part is correctly formatted.
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptA("a", cl::desc("Some option"));
+  StackOption<bool> OptLong("long", cl::desc("Some long option"));
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  OptA.error("custom error", OS);
+  OS.flush();
+  EXPECT_FALSE(Errs.find("for the -a option:") == std::string::npos);
+  Errs.clear();
+
+  OptLong.error("custom error", OS);
+  OS.flush();
+  EXPECT_FALSE(Errs.find("for the --long option:") == std::string::npos);
+  Errs.clear();
+
+  cl::ResetAllOptionOccurrences();
+}
+
+TEST(CommandLineTest, OptionErrorMessageSuggest) {
+  // When there is an error, and the edit-distance is not very large,
+  // we expect some error message like:
+  //   prog: did you mean '--option'?
+  //
+  // Test whether this message is well-formatted.
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptLong("aluminium", cl::desc("Some long option"));
+
+  const char *args[] = {"prog", "--aluminum"};
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, StringRef(), &OS));
+  OS.flush();
+  EXPECT_FALSE(Errs.find("prog: Did you mean '--aluminium'?\n") ==
+               std::string::npos);
+  Errs.clear();
+
+  cl::ResetAllOptionOccurrences();
+}
+
+TEST(CommandLineTest, Callback) {
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptA("a", cl::desc("option a"));
+  StackOption<bool> OptB(
+      "b", cl::desc("option b -- This option turns on option a"),
+      cl::callback([&](const bool &) { OptA = true; }));
+  StackOption<bool> OptC(
+      "c", cl::desc("option c -- This option turns on options a and b"),
+      cl::callback([&](const bool &) { OptB = true; }));
+  StackOption<std::string, cl::list<std::string>> List(
+      "list",
+      cl::desc("option list -- This option turns on options a, b, and c when "
+               "'foo' is included in list"),
+      cl::CommaSeparated,
+      cl::callback([&](const std::string &Str) {
+        if (Str == "foo")
+          OptC = true;
+      }));
+
+  const char *args1[] = {"prog", "-a"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args1));
+  EXPECT_TRUE(OptA);
+  EXPECT_FALSE(OptB);
+  EXPECT_FALSE(OptC);
+  EXPECT_TRUE(List.size() == 0);
+  cl::ResetAllOptionOccurrences();
+
+  const char *args2[] = {"prog", "-b"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args2));
+  EXPECT_TRUE(OptA);
+  EXPECT_TRUE(OptB);
+  EXPECT_FALSE(OptC);
+  EXPECT_TRUE(List.size() == 0);
+  cl::ResetAllOptionOccurrences();
+
+  const char *args3[] = {"prog", "-c"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args3));
+  EXPECT_TRUE(OptA);
+  EXPECT_TRUE(OptB);
+  EXPECT_TRUE(OptC);
+  EXPECT_TRUE(List.size() == 0);
+  cl::ResetAllOptionOccurrences();
+
+  const char *args4[] = {"prog", "--list=foo,bar"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args4));
+  EXPECT_TRUE(OptA);
+  EXPECT_TRUE(OptB);
+  EXPECT_TRUE(OptC);
+  EXPECT_TRUE(List.size() == 2);
+  cl::ResetAllOptionOccurrences();
+
+  const char *args5[] = {"prog", "--list=bar"};
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args5));
+  EXPECT_FALSE(OptA);
+  EXPECT_FALSE(OptB);
+  EXPECT_FALSE(OptC);
+  EXPECT_TRUE(List.size() == 1);
+
+  cl::ResetAllOptionOccurrences();
+}
+
+enum Enum { Val1, Val2 };
+static cl::bits<Enum> ExampleBits(
+    cl::desc("An example cl::bits to ensure it compiles"),
+    cl::values(
+      clEnumValN(Val1, "bits-val1", "The Val1 value"),
+      clEnumValN(Val1, "bits-val2", "The Val2 value")));
+
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
index d863dd0..798ed20 100644
--- a/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/CrashRecoveryTest.cpp
@@ -8,6 +8,8 @@
 
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Signals.h"
 #include "gtest/gtest.h"
 
 #ifdef _WIN32
@@ -23,6 +25,7 @@
 static void nullDeref() { *(volatile int *)0x10 = 0; }
 static void incrementGlobal() { ++GlobalInt; }
 static void llvmTrap() { LLVM_BUILTIN_TRAP; }
+static void incrementGlobalWithParam(void *) { ++GlobalInt; }
 
 TEST(CrashRecoveryTest, Basic) {
   llvm::CrashRecoveryContext::Enable();
@@ -58,6 +61,33 @@
     EXPECT_FALSE(CRC.RunSafely(nullDeref));
   } // run cleanups
   EXPECT_EQ(1, GlobalInt);
+  llvm::CrashRecoveryContext::Disable();
+}
+
+TEST(CrashRecoveryTest, DumpStackCleanup) {
+  SmallString<128> Filename;
+  std::error_code EC = sys::fs::createTemporaryFile("crash", "test", Filename);
+  EXPECT_FALSE(EC);
+  sys::RemoveFileOnSignal(Filename);
+  llvm::sys::AddSignalHandler(incrementGlobalWithParam, nullptr);
+  GlobalInt = 0;
+  llvm::CrashRecoveryContext::Enable();
+  {
+    CrashRecoveryContext CRC;
+    CRC.DumpStackAndCleanupOnFailure = true;
+    EXPECT_TRUE(CRC.RunSafely(noop));
+  }
+  EXPECT_TRUE(sys::fs::exists(Filename));
+  EXPECT_EQ(GlobalInt, 0);
+  {
+    CrashRecoveryContext CRC;
+    CRC.DumpStackAndCleanupOnFailure = true;
+    EXPECT_FALSE(CRC.RunSafely(nullDeref));
+    EXPECT_NE(CRC.RetCode, 0);
+  }
+  EXPECT_FALSE(sys::fs::exists(Filename));
+  EXPECT_EQ(GlobalInt, 1);
+  llvm::CrashRecoveryContext::Disable();
 }
 
 #ifdef _WIN32
diff --git a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
index 9726a74..cdb8bfd 100644
--- a/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/DataExtractorTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/DataExtractor.h"
+#include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 using namespace llvm;
 
@@ -24,7 +25,7 @@
 
 TEST(DataExtractorTest, UnsignedNumbers) {
   DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
-  uint32_t offset = 0;
+  uint64_t offset = 0;
 
   EXPECT_EQ(0x80U, DE.getU8(&offset));
   EXPECT_EQ(1U, offset);
@@ -72,7 +73,7 @@
 
 TEST(DataExtractorTest, SignedNumbers) {
   DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
-  uint32_t offset = 0;
+  uint64_t offset = 0;
 
   EXPECT_EQ(-128, DE.getSigned(&offset, 1));
   EXPECT_EQ(1U, offset);
@@ -89,7 +90,7 @@
 
 TEST(DataExtractorTest, Strings) {
   DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8);
-  uint32_t offset = 0;
+  uint64_t offset = 0;
 
   EXPECT_EQ(stringData, DE.getCStr(&offset));
   EXPECT_EQ(11U, offset);
@@ -99,7 +100,7 @@
 
 TEST(DataExtractorTest, LEB128) {
   DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8);
-  uint32_t offset = 0;
+  uint64_t offset = 0;
 
   EXPECT_EQ(9382ULL, DE.getULEB128(&offset));
   EXPECT_EQ(2U, offset);
@@ -118,7 +119,7 @@
 
 TEST(DataExtractorTest, LEB128_error) {
   DataExtractor DE(StringRef("\x81"), false, 8);
-  uint32_t Offset = 0;
+  uint64_t Offset = 0;
   EXPECT_EQ(0U, DE.getULEB128(&Offset));
   EXPECT_EQ(0U, Offset);
 
@@ -126,4 +127,155 @@
   EXPECT_EQ(0U, DE.getSLEB128(&Offset));
   EXPECT_EQ(0U, Offset);
 }
+
+TEST(DataExtractorTest, Cursor_tell) {
+  DataExtractor DE(StringRef("AB"), false, 8);
+  DataExtractor::Cursor C(0);
+  // A successful read operation advances the cursor
+  EXPECT_EQ('A', DE.getU8(C));
+  EXPECT_EQ(1u, C.tell());
+
+  // An unsuccessful one doesn't.
+  EXPECT_EQ(0u, DE.getU16(C));
+  EXPECT_EQ(1u, C.tell());
+
+  // And neither do any subsequent operations.
+  EXPECT_EQ(0, DE.getU8(C));
+  EXPECT_EQ(1u, C.tell());
+
+  consumeError(C.takeError());
+}
+
+TEST(DataExtractorTest, Cursor_takeError) {
+  DataExtractor DE(StringRef("AB"), false, 8);
+  DataExtractor::Cursor C(0);
+  // Initially, the cursor is in the "success" state.
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+
+  // It remains "success" after a successful read.
+  EXPECT_EQ('A', DE.getU8(C));
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+
+  // An unsuccessful read sets the error state.
+  EXPECT_EQ(0u, DE.getU32(C));
+  EXPECT_THAT_ERROR(C.takeError(), Failed());
+
+  // Once set the error sticks until explicitly cleared.
+  EXPECT_EQ(0u, DE.getU32(C));
+  EXPECT_EQ(0, DE.getU8(C));
+  EXPECT_THAT_ERROR(C.takeError(), Failed());
+
+  // At which point reads can be succeed again.
+  EXPECT_EQ('B', DE.getU8(C));
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+}
+
+TEST(DataExtractorTest, Cursor_chaining) {
+  DataExtractor DE(StringRef("ABCD"), false, 8);
+  DataExtractor::Cursor C(0);
+
+  // Multiple reads can be chained without trigerring any assertions.
+  EXPECT_EQ('A', DE.getU8(C));
+  EXPECT_EQ('B', DE.getU8(C));
+  EXPECT_EQ('C', DE.getU8(C));
+  EXPECT_EQ('D', DE.getU8(C));
+  // And the error checked at the end.
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+}
+
+#if defined(GTEST_HAS_DEATH_TEST) && defined(_DEBUG)
+TEST(DataExtractorDeathTest, Cursor) {
+  DataExtractor DE(StringRef("AB"), false, 8);
+
+  // Even an unused cursor must be checked for errors:
+  EXPECT_DEATH(DataExtractor::Cursor(0),
+               "Success values must still be checked prior to being destroyed");
+
+  {
+    auto C = std::make_unique<DataExtractor::Cursor>(0);
+    EXPECT_EQ(0u, DE.getU32(*C));
+    // It must also be checked after an unsuccessful operation.
+    // destruction.
+    EXPECT_DEATH(C.reset(), "unexpected end of data");
+    EXPECT_THAT_ERROR(C->takeError(), Failed());
+  }
+  {
+    auto C = std::make_unique<DataExtractor::Cursor>(0);
+    EXPECT_EQ('A', DE.getU8(*C));
+    // Same goes for a successful one.
+    EXPECT_DEATH(
+        C.reset(),
+        "Success values must still be checked prior to being destroyed");
+    EXPECT_THAT_ERROR(C->takeError(), Succeeded());
+  }
+  {
+    auto C = std::make_unique<DataExtractor::Cursor>(0);
+    EXPECT_EQ('A', DE.getU8(*C));
+    EXPECT_EQ(0u, DE.getU32(*C));
+    // Even if a successful operation is followed by an unsuccessful one.
+    EXPECT_DEATH(C.reset(), "unexpected end of data");
+    EXPECT_THAT_ERROR(C->takeError(), Failed());
+  }
+  {
+    auto C = std::make_unique<DataExtractor::Cursor>(0);
+    EXPECT_EQ(0u, DE.getU32(*C));
+    EXPECT_EQ(0, DE.getU8(*C));
+    // Even if an unsuccessful operation is followed by one that would normally
+    // succeed.
+    EXPECT_DEATH(C.reset(), "unexpected end of data");
+    EXPECT_THAT_ERROR(C->takeError(), Failed());
+  }
+}
+#endif
+
+TEST(DataExtractorTest, getU8_vector) {
+  DataExtractor DE(StringRef("AB"), false, 8);
+  DataExtractor::Cursor C(0);
+  SmallVector<uint8_t, 2> S;
+
+  DE.getU8(C, S, 4);
+  EXPECT_THAT_ERROR(C.takeError(), Failed());
+  EXPECT_EQ("", toStringRef(S));
+
+  DE.getU8(C, S, 2);
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+  EXPECT_EQ("AB", toStringRef(S));
+}
+
+TEST(DataExtractorTest, skip) {
+  DataExtractor DE(StringRef("AB"), false, 8);
+  DataExtractor::Cursor C(0);
+
+  DE.skip(C, 4);
+  EXPECT_THAT_ERROR(C.takeError(), Failed());
+  EXPECT_EQ(0u, C.tell());
+
+  DE.skip(C, 2);
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+  EXPECT_EQ(2u, C.tell());
+}
+
+TEST(DataExtractorTest, eof) {
+  DataExtractor DE(StringRef("A"), false, 8);
+  DataExtractor::Cursor C(0);
+
+  EXPECT_FALSE(DE.eof(C));
+
+  EXPECT_EQ(0, DE.getU16(C));
+  EXPECT_FALSE(DE.eof(C));
+  EXPECT_THAT_ERROR(C.takeError(), Failed());
+
+  EXPECT_EQ('A', DE.getU8(C));
+  EXPECT_TRUE(DE.eof(C));
+  EXPECT_THAT_ERROR(C.takeError(), Succeeded());
+}
+
+TEST(DataExtractorTest, size) {
+  uint8_t Data[] = {'A', 'B', 'C', 'D'};
+  DataExtractor DE1(StringRef(reinterpret_cast<char *>(Data), sizeof(Data)),
+                    false, 8);
+  EXPECT_EQ(DE1.size(), sizeof(Data));
+  DataExtractor DE2(ArrayRef<uint8_t>(Data), false, 8);
+  EXPECT_EQ(DE2.size(), sizeof(Data));
+}
 }
diff --git a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
index c4a9f3e..2cac94d 100644
--- a/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ErrorTest.cpp
@@ -390,7 +390,8 @@
   };
 
   EXPECT_DEATH(FailToHandle(),
-               "Failure value returned from cantFail wrapped call")
+               "Failure value returned from cantFail wrapped call\n"
+               "CustomError \\{7\\}")
       << "Unhandled Error in handleAllErrors call did not cause an "
          "abort()";
 }
@@ -409,7 +410,8 @@
   };
 
   EXPECT_DEATH(ReturnErrorFromHandler(),
-               "Failure value returned from cantFail wrapped call")
+               "Failure value returned from cantFail wrapped call\n"
+               "CustomError \\{7\\}")
       << " Error returned from handler in handleAllErrors call did not "
          "cause abort()";
 }
@@ -510,11 +512,12 @@
 // 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(cantFail(make_error<StringError>("Original error message",
+                                                inconvertibleErrorCode()),
+                        "Cantfail call failed"),
+               "Cantfail call failed\n"
+               "Original error message")
+      << "cantFail(Error) did not cause an abort for failure value";
 
   EXPECT_DEATH(
       {
diff --git a/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp b/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
index 2275d72..8ca0af7 100644
--- a/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/FileCheckTest.cpp
@@ -7,25 +7,27 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/FileCheck.h"
+#include "../lib/Support/FileCheckImpl.h"
 #include "gtest/gtest.h"
 #include <unordered_set>
 
 using namespace llvm;
+
 namespace {
 
 class FileCheckTest : public ::testing::Test {};
 
 TEST_F(FileCheckTest, Literal) {
   // Eval returns the literal's value.
-  FileCheckExpressionLiteral Ten(10);
+  ExpressionLiteral Ten(10);
   Expected<uint64_t> Value = Ten.eval();
-  EXPECT_TRUE(bool(Value));
+  ASSERT_TRUE(bool(Value));
   EXPECT_EQ(10U, *Value);
 
   // Max value can be correctly represented.
-  FileCheckExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
+  ExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
   Value = Max.eval();
-  EXPECT_TRUE(bool(Value));
+  ASSERT_TRUE(bool(Value));
   EXPECT_EQ(std::numeric_limits<uint64_t>::max(), *Value);
 }
 
@@ -43,91 +45,91 @@
 static void
 expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
                   Error Err) {
-  handleAllErrors(std::move(Err), [&](const FileCheckUndefVarError &E) {
+  handleAllErrors(std::move(Err), [&](const UndefVarError &E) {
     ExpectedUndefVarNames.erase(E.getVarName());
   });
   EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
 }
 
+// Return whether Err contains any UndefVarError whose associated name is not
+// ExpectedUndefVarName.
 static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
   expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
 }
 
+uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
+
 TEST_F(FileCheckTest, NumericVariable) {
   // Undefined variable: getValue and eval fail, error returned by eval holds
-  // the name of the undefined variable and setValue does not trigger assert.
-  FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO", 1);
+  // the name of the undefined variable.
+  NumericVariable FooVar("FOO", 1);
   EXPECT_EQ("FOO", FooVar.getName());
-  FileCheckNumericVariableUse FooVarUse =
-      FileCheckNumericVariableUse("FOO", &FooVar);
+  NumericVariableUse FooVarUse("FOO", &FooVar);
   EXPECT_FALSE(FooVar.getValue());
   Expected<uint64_t> EvalResult = FooVarUse.eval();
-  EXPECT_FALSE(EvalResult);
+  ASSERT_FALSE(EvalResult);
   expectUndefError("FOO", EvalResult.takeError());
+
   FooVar.setValue(42);
 
   // Defined variable: getValue and eval return value set.
   Optional<uint64_t> Value = FooVar.getValue();
-  EXPECT_TRUE(bool(Value));
+  ASSERT_TRUE(bool(Value));
   EXPECT_EQ(42U, *Value);
   EvalResult = FooVarUse.eval();
-  EXPECT_TRUE(bool(EvalResult));
+  ASSERT_TRUE(bool(EvalResult));
   EXPECT_EQ(42U, *EvalResult);
 
   // Clearing variable: getValue and eval fail. Error returned by eval holds
   // the name of the cleared variable.
   FooVar.clearValue();
-  Value = FooVar.getValue();
-  EXPECT_FALSE(Value);
+  EXPECT_FALSE(FooVar.getValue());
   EvalResult = FooVarUse.eval();
-  EXPECT_FALSE(EvalResult);
+  ASSERT_FALSE(EvalResult);
   expectUndefError("FOO", EvalResult.takeError());
 }
 
-uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
-
 TEST_F(FileCheckTest, Binop) {
-  FileCheckNumericVariable FooVar = FileCheckNumericVariable("FOO");
+  NumericVariable FooVar("FOO", 1);
   FooVar.setValue(42);
-  std::unique_ptr<FileCheckNumericVariableUse> FooVarUse =
-      llvm::make_unique<FileCheckNumericVariableUse>("FOO", &FooVar);
-  FileCheckNumericVariable BarVar = FileCheckNumericVariable("BAR");
+  std::unique_ptr<NumericVariableUse> FooVarUse =
+      std::make_unique<NumericVariableUse>("FOO", &FooVar);
+  NumericVariable BarVar("BAR", 2);
   BarVar.setValue(18);
-  std::unique_ptr<FileCheckNumericVariableUse> BarVarUse =
-      llvm::make_unique<FileCheckNumericVariableUse>("BAR", &BarVar);
-  FileCheckASTBinop Binop =
-      FileCheckASTBinop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
+  std::unique_ptr<NumericVariableUse> BarVarUse =
+      std::make_unique<NumericVariableUse>("BAR", &BarVar);
+  BinaryOperation Binop(doAdd, std::move(FooVarUse), std::move(BarVarUse));
 
   // Defined variable: eval returns right value.
   Expected<uint64_t> Value = Binop.eval();
-  EXPECT_TRUE(bool(Value));
+  ASSERT_TRUE(bool(Value));
   EXPECT_EQ(60U, *Value);
 
   // 1 undefined variable: eval fails, error contains name of undefined
   // variable.
   FooVar.clearValue();
   Value = Binop.eval();
-  EXPECT_FALSE(Value);
+  ASSERT_FALSE(Value);
   expectUndefError("FOO", Value.takeError());
 
   // 2 undefined variables: eval fails, error contains names of all undefined
   // variables.
   BarVar.clearValue();
   Value = Binop.eval();
-  EXPECT_FALSE(Value);
+  ASSERT_FALSE(Value);
   expectUndefErrors({"FOO", "BAR"}, Value.takeError());
 }
 
 TEST_F(FileCheckTest, ValidVarNameStart) {
-  EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('a'));
-  EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('G'));
-  EXPECT_TRUE(FileCheckPattern::isValidVarNameStart('_'));
-  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('2'));
-  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('$'));
-  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('@'));
-  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('+'));
-  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart('-'));
-  EXPECT_FALSE(FileCheckPattern::isValidVarNameStart(':'));
+  EXPECT_TRUE(Pattern::isValidVarNameStart('a'));
+  EXPECT_TRUE(Pattern::isValidVarNameStart('G'));
+  EXPECT_TRUE(Pattern::isValidVarNameStart('_'));
+  EXPECT_FALSE(Pattern::isValidVarNameStart('2'));
+  EXPECT_FALSE(Pattern::isValidVarNameStart('$'));
+  EXPECT_FALSE(Pattern::isValidVarNameStart('@'));
+  EXPECT_FALSE(Pattern::isValidVarNameStart('+'));
+  EXPECT_FALSE(Pattern::isValidVarNameStart('-'));
+  EXPECT_FALSE(Pattern::isValidVarNameStart(':'));
 }
 
 static StringRef bufferize(SourceMgr &SM, StringRef Str) {
@@ -142,66 +144,66 @@
   SourceMgr SM;
   StringRef OrigVarName = bufferize(SM, "GoodVar42");
   StringRef VarName = OrigVarName;
-  Expected<FileCheckPattern::VariableProperties> ParsedVarResult =
-      FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  Expected<Pattern::VariableProperties> ParsedVarResult =
+      Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
   EXPECT_TRUE(VarName.empty());
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
   EXPECT_TRUE(VarName.empty());
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
   EXPECT_TRUE(VarName.empty());
   EXPECT_TRUE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "42BadVar");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
   EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
 
   VarName = bufferize(SM, "$@");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
   EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
 
   VarName = OrigVarName = bufferize(SM, "B@dVar");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(VarName, OrigVarName.substr(1));
   EXPECT_EQ(ParsedVarResult->Name, "B");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = OrigVarName = bufferize(SM, "B$dVar");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(VarName, OrigVarName.substr(1));
   EXPECT_EQ(ParsedVarResult->Name, "B");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "BadVar+");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(VarName, "+");
   EXPECT_EQ(ParsedVarResult->Name, "BadVar");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "BadVar-");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(VarName, "-");
   EXPECT_EQ(ParsedVarResult->Name, "BadVar");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "BadVar:");
-  ParsedVarResult = FileCheckPattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(bool(ParsedVarResult));
+  ParsedVarResult = Pattern::parseVariable(VarName, SM);
+  ASSERT_TRUE(bool(ParsedVarResult));
   EXPECT_EQ(VarName, ":");
   EXPECT_EQ(ParsedVarResult->Name, "BadVar");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
@@ -213,14 +215,15 @@
   SourceMgr SM;
   FileCheckRequest Req;
   FileCheckPatternContext Context;
-  FileCheckPattern P =
-      FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
+  Pattern P{Check::CheckPlain, &Context, LineNumber++};
 
 public:
   PatternTester() {
     std::vector<std::string> GlobalDefines;
     GlobalDefines.emplace_back(std::string("#FOO=42"));
     GlobalDefines.emplace_back(std::string("BAR=BAZ"));
+    // An ASSERT_FALSE would make more sense but cannot be used in a
+    // constructor.
     EXPECT_FALSE(
         errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
     Context.createLineVariable();
@@ -233,22 +236,16 @@
   }
 
   void initNextPattern() {
-    P = FileCheckPattern(Check::CheckPlain, &Context, LineNumber++);
-  }
-
-  bool parseNumVarDefExpect(StringRef Expr) {
-    StringRef ExprBufferRef = bufferize(SM, Expr);
-    return errorToBool(FileCheckPattern::parseNumericVariableDefinition(
-                           ExprBufferRef, &Context, LineNumber, SM)
-                           .takeError());
+    P = Pattern(Check::CheckPlain, &Context, LineNumber++);
   }
 
   bool parseSubstExpect(StringRef Expr) {
     StringRef ExprBufferRef = bufferize(SM, Expr);
-    Optional<FileCheckNumericVariable *> DefinedNumericVariable;
-    return errorToBool(P.parseNumericSubstitutionBlock(
-                            ExprBufferRef, DefinedNumericVariable, false, SM)
-                           .takeError());
+    Optional<NumericVariable *> DefinedNumericVariable;
+    return errorToBool(
+        P.parseNumericSubstitutionBlock(ExprBufferRef, DefinedNumericVariable,
+                                        false, LineNumber - 1, &Context, SM)
+            .takeError());
   }
 
   bool parsePatternExpect(StringRef Pattern) {
@@ -263,19 +260,6 @@
   }
 };
 
-TEST_F(FileCheckTest, ParseNumericVariableDefinition) {
-  PatternTester Tester;
-
-  // Invalid definition of pseudo.
-  EXPECT_TRUE(Tester.parseNumVarDefExpect("@LINE"));
-
-  // Conflict with pattern variable.
-  EXPECT_TRUE(Tester.parseNumVarDefExpect("BAR"));
-
-  // Defined variable.
-  EXPECT_FALSE(Tester.parseNumVarDefExpect("FOO"));
-}
-
 TEST_F(FileCheckTest, ParseExpr) {
   PatternTester Tester;
 
@@ -286,17 +270,18 @@
   EXPECT_TRUE(Tester.parseSubstExpect("@FOO:"));
   EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
 
+  // Conflict with pattern variable.
+  EXPECT_TRUE(Tester.parseSubstExpect("BAR:"));
+
   // Garbage after name of variable being defined.
   EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
 
-  // Variable defined to numeric expression.
-  EXPECT_TRUE(Tester.parseSubstExpect("VAR1: FOO"));
-
   // Acceptable variable definition.
   EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
   EXPECT_FALSE(Tester.parseSubstExpect("  VAR2:"));
   EXPECT_FALSE(Tester.parseSubstExpect("VAR3  :"));
   EXPECT_FALSE(Tester.parseSubstExpect("VAR3:  "));
+  EXPECT_FALSE(Tester.parsePatternExpect("[[#FOOBAR: FOO+1]]"));
 
   // Numeric expression.
 
@@ -309,10 +294,22 @@
   EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
   EXPECT_FALSE(Tester.parseSubstExpect("UNDEF"));
 
-  // Use variable defined on same line.
-  EXPECT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:]]"));
+  // Valid empty expression.
+  EXPECT_FALSE(Tester.parseSubstExpect(""));
+
+  // Invalid use of variable defined on the same line from expression. Note
+  // that the same pattern object is used for the parsePatternExpect and
+  // parseSubstExpect since no initNextPattern is called, thus appearing as
+  // being on the same line from the pattern's point of view.
+  ASSERT_FALSE(Tester.parsePatternExpect("[[#LINE1VAR:FOO+1]]"));
   EXPECT_TRUE(Tester.parseSubstExpect("LINE1VAR"));
 
+  // Invalid use of variable defined on same line from input. As above, the
+  // absence of a call to initNextPattern makes it appear to be on the same
+  // line from the pattern's point of view.
+  ASSERT_FALSE(Tester.parsePatternExpect("[[#LINE2VAR:]]"));
+  EXPECT_TRUE(Tester.parseSubstExpect("LINE2VAR"));
+
   // Unsupported operator.
   EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
 
@@ -323,6 +320,8 @@
   EXPECT_FALSE(Tester.parseSubstExpect("@LINE+5"));
   EXPECT_FALSE(Tester.parseSubstExpect("FOO+4"));
   Tester.initNextPattern();
+  EXPECT_FALSE(Tester.parseSubstExpect("FOOBAR"));
+  EXPECT_FALSE(Tester.parseSubstExpect("LINE1VAR"));
   EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+FOO]]"));
   EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO+3-FOO]]"));
 }
@@ -353,7 +352,6 @@
   EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
   EXPECT_TRUE(Tester.parsePatternExpect("[[#@FOO]]"));
   EXPECT_TRUE(Tester.parsePatternExpect("[[#@LINE/2]]"));
-  EXPECT_TRUE(Tester.parsePatternExpect("[[#YUP:@LINE]]"));
 
   // Valid numeric expressions and numeric variable definition.
   EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
@@ -364,9 +362,16 @@
 TEST_F(FileCheckTest, Match) {
   PatternTester Tester;
 
+  // Check matching an empty expression only matches a number.
+  Tester.parsePatternExpect("[[#]]");
+  EXPECT_TRUE(Tester.matchExpect("FAIL"));
+  EXPECT_FALSE(Tester.matchExpect("18"));
+
   // Check matching a definition only matches a number.
+  Tester.initNextPattern();
   Tester.parsePatternExpect("[[#NUMVAR:]]");
   EXPECT_TRUE(Tester.matchExpect("FAIL"));
+  EXPECT_TRUE(Tester.matchExpect(""));
   EXPECT_FALSE(Tester.matchExpect("18"));
 
   // Check matching the variable defined matches the correct number only
@@ -380,16 +385,16 @@
   // the correct value for @LINE.
   Tester.initNextPattern();
   EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
-  // Ok, @LINE is 4 now.
-  EXPECT_FALSE(Tester.matchExpect("4"));
+  // Ok, @LINE is 5 now.
+  EXPECT_FALSE(Tester.matchExpect("5"));
   Tester.initNextPattern();
-  // @LINE is now 5, match with substitution failure.
+  // @LINE is now 6, match with substitution failure.
   EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
   EXPECT_TRUE(Tester.matchExpect("FOO"));
   Tester.initNextPattern();
-  // Check that @LINE is 6 as expected.
+  // Check that @LINE is 7 as expected.
   EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
-  EXPECT_FALSE(Tester.matchExpect("6"));
+  EXPECT_FALSE(Tester.matchExpect("7"));
 }
 
 TEST_F(FileCheckTest, Substitution) {
@@ -401,53 +406,50 @@
 
   // Substitution of an undefined string variable fails and error holds that
   // variable's name.
-  FileCheckStringSubstitution StringSubstitution =
-      FileCheckStringSubstitution(&Context, "VAR404", 42);
+  StringSubstitution StringSubstitution(&Context, "VAR404", 42);
   Expected<std::string> SubstValue = StringSubstitution.getResult();
-  EXPECT_FALSE(bool(SubstValue));
+  ASSERT_FALSE(bool(SubstValue));
   expectUndefError("VAR404", SubstValue.takeError());
 
   // Substitutions of defined pseudo and non-pseudo numeric variables return
   // the right value.
-  FileCheckNumericVariable LineVar = FileCheckNumericVariable("@LINE");
+  NumericVariable LineVar("@LINE", 1);
+  NumericVariable NVar("N", 1);
   LineVar.setValue(42);
-  FileCheckNumericVariable NVar = FileCheckNumericVariable("N");
   NVar.setValue(10);
-  auto LineVarUse =
-      llvm::make_unique<FileCheckNumericVariableUse>("@LINE", &LineVar);
-  auto NVarUse = llvm::make_unique<FileCheckNumericVariableUse>("N", &NVar);
-  FileCheckNumericSubstitution SubstitutionLine = FileCheckNumericSubstitution(
-      &Context, "@LINE", std::move(LineVarUse), 12);
-  FileCheckNumericSubstitution SubstitutionN =
-      FileCheckNumericSubstitution(&Context, "N", std::move(NVarUse), 30);
+  auto LineVarUse = std::make_unique<NumericVariableUse>("@LINE", &LineVar);
+  auto NVarUse = std::make_unique<NumericVariableUse>("N", &NVar);
+  NumericSubstitution SubstitutionLine(&Context, "@LINE", std::move(LineVarUse),
+                                       12);
+  NumericSubstitution SubstitutionN(&Context, "N", std::move(NVarUse), 30);
   SubstValue = SubstitutionLine.getResult();
-  EXPECT_TRUE(bool(SubstValue));
+  ASSERT_TRUE(bool(SubstValue));
   EXPECT_EQ("42", *SubstValue);
   SubstValue = SubstitutionN.getResult();
-  EXPECT_TRUE(bool(SubstValue));
+  ASSERT_TRUE(bool(SubstValue));
   EXPECT_EQ("10", *SubstValue);
 
   // Substitution of an undefined numeric variable fails, error holds name of
   // undefined variable.
   LineVar.clearValue();
   SubstValue = SubstitutionLine.getResult();
-  EXPECT_FALSE(bool(SubstValue));
+  ASSERT_FALSE(bool(SubstValue));
   expectUndefError("@LINE", SubstValue.takeError());
   NVar.clearValue();
   SubstValue = SubstitutionN.getResult();
-  EXPECT_FALSE(bool(SubstValue));
+  ASSERT_FALSE(bool(SubstValue));
   expectUndefError("N", SubstValue.takeError());
 
   // Substitution of a defined string variable returns the right value.
-  FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Context, 1);
-  StringSubstitution = FileCheckStringSubstitution(&Context, "FOO", 42);
+  Pattern P(Check::CheckPlain, &Context, 1);
+  StringSubstitution = llvm::StringSubstitution(&Context, "FOO", 42);
   SubstValue = StringSubstitution.getResult();
-  EXPECT_TRUE(bool(SubstValue));
+  ASSERT_TRUE(bool(SubstValue));
   EXPECT_EQ("BAR", *SubstValue);
 }
 
 TEST_F(FileCheckTest, FileCheckContext) {
-  FileCheckPatternContext Cxt = FileCheckPatternContext();
+  FileCheckPatternContext Cxt;
   std::vector<std::string> GlobalDefines;
   SourceMgr SM;
 
@@ -493,31 +495,46 @@
 
   // Define local variables from command-line.
   GlobalDefines.clear();
+  // Clear local variables to remove dummy numeric variable x that
+  // parseNumericSubstitutionBlock would have created and stored in
+  // GlobalNumericVariableTable.
+  Cxt.clearLocalVars();
   GlobalDefines.emplace_back(std::string("LocalVar=FOO"));
   GlobalDefines.emplace_back(std::string("EmptyVar="));
-  GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
-  EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  GlobalDefines.emplace_back(std::string("#LocalNumVar1=18"));
+  GlobalDefines.emplace_back(std::string("#LocalNumVar2=LocalNumVar1+2"));
+  ASSERT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
 
   // Check defined variables are present and undefined is absent.
   StringRef LocalVarStr = "LocalVar";
-  StringRef LocalNumVarRef = bufferize(SM, "LocalNumVar");
+  StringRef LocalNumVar1Ref = bufferize(SM, "LocalNumVar1");
+  StringRef LocalNumVar2Ref = bufferize(SM, "LocalNumVar2");
   StringRef EmptyVarStr = "EmptyVar";
   StringRef UnknownVarStr = "UnknownVar";
   Expected<StringRef> LocalVar = Cxt.getPatternVarValue(LocalVarStr);
-  FileCheckPattern P = FileCheckPattern(Check::CheckPlain, &Cxt, 1);
-  Optional<FileCheckNumericVariable *> DefinedNumericVariable;
-  Expected<std::unique_ptr<FileCheckExpressionAST>> ExpressionAST =
-      P.parseNumericSubstitutionBlock(LocalNumVarRef, DefinedNumericVariable,
-                                      /*IsLegacyLineExpr=*/false, SM);
-  EXPECT_TRUE(bool(LocalVar));
+  Pattern P(Check::CheckPlain, &Cxt, 1);
+  Optional<NumericVariable *> DefinedNumericVariable;
+  Expected<std::unique_ptr<ExpressionAST>> ExpressionASTPointer =
+      P.parseNumericSubstitutionBlock(LocalNumVar1Ref, DefinedNumericVariable,
+                                      /*IsLegacyLineExpr=*/false,
+                                      /*LineNumber=*/1, &Cxt, SM);
+  ASSERT_TRUE(bool(LocalVar));
   EXPECT_EQ(*LocalVar, "FOO");
   Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
   Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
-  EXPECT_TRUE(bool(ExpressionAST));
-  Expected<uint64_t> ExpressionVal = (*ExpressionAST)->eval();
-  EXPECT_TRUE(bool(ExpressionVal));
+  ASSERT_TRUE(bool(ExpressionASTPointer));
+  Expected<uint64_t> ExpressionVal = (*ExpressionASTPointer)->eval();
+  ASSERT_TRUE(bool(ExpressionVal));
   EXPECT_EQ(*ExpressionVal, 18U);
-  EXPECT_TRUE(bool(EmptyVar));
+  ExpressionASTPointer =
+      P.parseNumericSubstitutionBlock(LocalNumVar2Ref, DefinedNumericVariable,
+                                      /*IsLegacyLineExpr=*/false,
+                                      /*LineNumber=*/1, &Cxt, SM);
+  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ExpressionVal = (*ExpressionASTPointer)->eval();
+  ASSERT_TRUE(bool(ExpressionVal));
+  EXPECT_EQ(*ExpressionVal, 20U);
+  ASSERT_TRUE(bool(EmptyVar));
   EXPECT_EQ(*EmptyVar, "");
   EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
 
@@ -529,12 +546,19 @@
   // local variables, if it was created before. This is important because local
   // variable clearing due to --enable-var-scope happens after numeric
   // expressions are linked to the numeric variables they use.
-  EXPECT_TRUE(errorToBool((*ExpressionAST)->eval().takeError()));
-  P = FileCheckPattern(Check::CheckPlain, &Cxt, 2);
-  ExpressionAST = P.parseNumericSubstitutionBlock(
-      LocalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
-  EXPECT_TRUE(bool(ExpressionAST));
-  ExpressionVal = (*ExpressionAST)->eval();
+  EXPECT_TRUE(errorToBool((*ExpressionASTPointer)->eval().takeError()));
+  P = Pattern(Check::CheckPlain, &Cxt, 2);
+  ExpressionASTPointer = P.parseNumericSubstitutionBlock(
+      LocalNumVar1Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+      /*LineNumber=*/2, &Cxt, SM);
+  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ExpressionVal = (*ExpressionASTPointer)->eval();
+  EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
+  ExpressionASTPointer = P.parseNumericSubstitutionBlock(
+      LocalNumVar2Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+      /*LineNumber=*/2, &Cxt, SM);
+  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ExpressionVal = (*ExpressionASTPointer)->eval();
   EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
   EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
   EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
@@ -545,29 +569,31 @@
   // Redefine global variables and check variables are defined again.
   GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
   GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36"));
-  EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  ASSERT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
   StringRef GlobalVarStr = "$GlobalVar";
   StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar");
   Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
-  EXPECT_TRUE(bool(GlobalVar));
+  ASSERT_TRUE(bool(GlobalVar));
   EXPECT_EQ(*GlobalVar, "BAR");
-  P = FileCheckPattern(Check::CheckPlain, &Cxt, 3);
-  ExpressionAST = P.parseNumericSubstitutionBlock(
-      GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
-  EXPECT_TRUE(bool(ExpressionAST));
-  ExpressionVal = (*ExpressionAST)->eval();
-  EXPECT_TRUE(bool(ExpressionVal));
+  P = Pattern(Check::CheckPlain, &Cxt, 3);
+  ExpressionASTPointer = P.parseNumericSubstitutionBlock(
+      GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+      /*LineNumber=*/3, &Cxt, SM);
+  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ExpressionVal = (*ExpressionASTPointer)->eval();
+  ASSERT_TRUE(bool(ExpressionVal));
   EXPECT_EQ(*ExpressionVal, 36U);
 
   // Clear local variables and check global variables remain defined.
   Cxt.clearLocalVars();
   EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
-  P = FileCheckPattern(Check::CheckPlain, &Cxt, 4);
-  ExpressionAST = P.parseNumericSubstitutionBlock(
-      GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false, SM);
-  EXPECT_TRUE(bool(ExpressionAST));
-  ExpressionVal = (*ExpressionAST)->eval();
-  EXPECT_TRUE(bool(ExpressionVal));
+  P = Pattern(Check::CheckPlain, &Cxt, 4);
+  ExpressionASTPointer = P.parseNumericSubstitutionBlock(
+      GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
+      /*LineNumber=*/4, &Cxt, SM);
+  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ExpressionVal = (*ExpressionASTPointer)->eval();
+  ASSERT_TRUE(bool(ExpressionVal));
   EXPECT_EQ(*ExpressionVal, 36U);
 }
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/FileCollectorTest.cpp b/src/llvm-project/llvm/unittests/Support/FileCollectorTest.cpp
new file mode 100644
index 0000000..c6aeedd
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/FileCollectorTest.cpp
@@ -0,0 +1,299 @@
+//===-- FileCollectorTest.cpp -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+#include "llvm/Support/FileCollector.h"
+#include "llvm/Support/FileSystem.h"
+
+using namespace llvm;
+
+namespace llvm {
+namespace vfs {
+inline bool operator==(const llvm::vfs::YAMLVFSEntry &LHS,
+                       const llvm::vfs::YAMLVFSEntry &RHS) {
+  return LHS.VPath == RHS.VPath && LHS.RPath == RHS.RPath;
+}
+} // namespace vfs
+} // namespace llvm
+
+namespace {
+class TestingFileCollector : public FileCollector {
+public:
+  using FileCollector::FileCollector;
+  using FileCollector::Root;
+  using FileCollector::Seen;
+  using FileCollector::SymlinkMap;
+  using FileCollector::VFSWriter;
+
+  bool hasSeen(StringRef fs) {
+    return Seen.find(fs) != Seen.end();
+  }
+};
+
+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);
+    // Ensure the path is the real path so tests can use it to compare against
+    // realpath output.
+    SmallString<128> RealPath;
+    if (!llvm::sys::fs::real_path(Path, RealPath))
+      Path.swap(RealPath);
+  }
+  ~ScopedDir() {
+    if (Path != "") {
+      EXPECT_FALSE(llvm::sys::fs::remove_directories(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(); }
+};
+
+struct ScopedFile {
+  SmallString<128> Path;
+  ScopedFile(const Twine &Name) {
+    std::error_code EC;
+    EC = llvm::sys::fs::createUniqueFile(Name, Path);
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedFile() {
+    if (Path != "") {
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+    }
+  }
+  operator StringRef() { return Path.str(); }
+};
+} // end anonymous namespace
+
+TEST(FileCollectorTest, addFile) {
+  ScopedDir root("add_file_root", true);
+  std::string root_fs = root.Path.str();
+  TestingFileCollector FileCollector(root_fs, root_fs);
+
+  FileCollector.addFile("/path/to/a");
+  FileCollector.addFile("/path/to/b");
+  FileCollector.addFile("/path/to/c");
+
+  // Make sure the root is correct.
+  EXPECT_EQ(FileCollector.Root, root_fs);
+
+  // Make sure we've seen all the added files.
+  EXPECT_TRUE(FileCollector.hasSeen("/path/to/a"));
+  EXPECT_TRUE(FileCollector.hasSeen("/path/to/b"));
+  EXPECT_TRUE(FileCollector.hasSeen("/path/to/c"));
+
+  // Make sure we've only seen the added files.
+  EXPECT_FALSE(FileCollector.hasSeen("/path/to/d"));
+}
+
+TEST(FileCollectorTest, copyFiles) {
+  ScopedDir file_root("file_root", true);
+  ScopedFile a(file_root + "/aaa");
+  ScopedFile b(file_root + "/bbb");
+  ScopedFile c(file_root + "/ccc");
+
+  // Create file collector and add files.
+  ScopedDir root("copy_files_root", true);
+  std::string root_fs = root.Path.str();
+  TestingFileCollector FileCollector(root_fs, root_fs);
+  FileCollector.addFile(a.Path);
+  FileCollector.addFile(b.Path);
+  FileCollector.addFile(c.Path);
+
+  // Make sure we can copy the files.
+  std::error_code ec = FileCollector.copyFiles(true);
+  EXPECT_FALSE(ec);
+
+  // Now add a bogus file and make sure we error out.
+  FileCollector.addFile("/some/bogus/file");
+  ec = FileCollector.copyFiles(true);
+  EXPECT_TRUE(ec);
+
+  // However, if stop_on_error is true the copy should still succeed.
+  ec = FileCollector.copyFiles(false);
+  EXPECT_FALSE(ec);
+}
+
+TEST(FileCollectorTest, recordAndConstructDirectory) {
+  ScopedDir file_root("dir_root", true);
+  ScopedDir subdir(file_root + "/subdir");
+  ScopedDir subdir2(file_root + "/subdir2");
+  ScopedFile a(subdir2 + "/a");
+
+  // Create file collector and add files.
+  ScopedDir root("copy_files_root", true);
+  std::string root_fs = root.Path.str();
+  TestingFileCollector FileCollector(root_fs, root_fs);
+  FileCollector.addFile(a.Path);
+
+  // The empty directory isn't seen until we add it.
+  EXPECT_TRUE(FileCollector.hasSeen(a.Path));
+  EXPECT_FALSE(FileCollector.hasSeen(subdir.Path));
+
+  FileCollector.addFile(subdir.Path);
+  EXPECT_TRUE(FileCollector.hasSeen(subdir.Path));
+
+  // Make sure we can construct the directory.
+  std::error_code ec = FileCollector.copyFiles(true);
+  EXPECT_FALSE(ec);
+  bool IsDirectory = false;
+  llvm::SmallString<128> SubdirInRoot = root.Path;
+  llvm::sys::path::append(SubdirInRoot,
+                          llvm::sys::path::relative_path(subdir.Path));
+  ec = sys::fs::is_directory(SubdirInRoot, IsDirectory);
+  EXPECT_FALSE(ec);
+  ASSERT_TRUE(IsDirectory);
+}
+
+TEST(FileCollectorTest, recordVFSAccesses) {
+  ScopedDir file_root("dir_root", true);
+  ScopedDir subdir(file_root + "/subdir");
+  ScopedDir subdir2(file_root + "/subdir2");
+  ScopedFile a(subdir2 + "/a");
+  ScopedFile b(file_root + "/b");
+  ScopedDir subdir3(file_root + "/subdir3");
+  ScopedFile subdir3a(subdir3 + "/aa");
+  ScopedDir subdir3b(subdir3 + "/subdirb");
+  {
+    ScopedFile subdir3fileremoved(subdir3 + "/removed");
+  }
+
+  // Create file collector and add files.
+  ScopedDir root("copy_files_root", true);
+  std::string root_fs = root.Path.str();
+  auto Collector = std::make_shared<TestingFileCollector>(root_fs, root_fs);
+  auto VFS =
+      FileCollector::createCollectorVFS(vfs::getRealFileSystem(), Collector);
+  VFS->status(a.Path);
+  EXPECT_TRUE(Collector->hasSeen(a.Path));
+
+  VFS->openFileForRead(b.Path);
+  EXPECT_TRUE(Collector->hasSeen(b.Path));
+
+  VFS->status(subdir.Path);
+  EXPECT_TRUE(Collector->hasSeen(subdir.Path));
+
+#ifndef _WIN32
+  std::error_code EC;
+  auto It = VFS->dir_begin(subdir3.Path, EC);
+  EXPECT_FALSE(EC);
+  EXPECT_TRUE(Collector->hasSeen(subdir3.Path));
+  EXPECT_TRUE(Collector->hasSeen(subdir3a.Path));
+  EXPECT_TRUE(Collector->hasSeen(subdir3b.Path));
+  std::string RemovedFileName = (Twine(subdir3.Path) + "/removed").str();
+  EXPECT_FALSE(Collector->hasSeen(RemovedFileName));
+#endif
+}
+
+#ifndef _WIN32
+TEST(FileCollectorTest, Symlinks) {
+  // Root where the original files live.
+  ScopedDir file_root("file_root", true);
+
+  // Create some files in the file root.
+  ScopedFile a(file_root + "/aaa");
+  ScopedFile b(file_root + "/bbb");
+  ScopedFile c(file_root + "/ccc");
+
+  // Create a directory foo with file ddd.
+  ScopedDir foo(file_root + "/foo");
+  ScopedFile d(foo + "/ddd");
+
+  // Create a file eee in the foo's parent directory.
+  ScopedFile e(foo + "/../eee");
+
+  // Create a symlink bar pointing to foo.
+  ScopedLink symlink(file_root + "/foo", file_root + "/bar");
+
+  // Root where files are copied to.
+  ScopedDir reproducer_root("reproducer_root", true);
+  std::string root_fs = reproducer_root.Path.str();
+  TestingFileCollector FileCollector(root_fs, root_fs);
+
+  // Add all the files to the collector.
+  FileCollector.addFile(a.Path);
+  FileCollector.addFile(b.Path);
+  FileCollector.addFile(c.Path);
+  FileCollector.addFile(d.Path);
+  FileCollector.addFile(e.Path);
+  FileCollector.addFile(file_root + "/bar/ddd");
+
+  auto mapping = FileCollector.VFSWriter.getMappings();
+
+  {
+    // Make sure the common case works.
+    std::string vpath = (file_root + "/aaa").str();
+    std::string rpath = (reproducer_root.Path + file_root.Path + "/aaa").str();
+    printf("%s -> %s\n", vpath.c_str(), rpath.c_str());
+    EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath)));
+  }
+
+  {
+    // Make sure the virtual path points to the real source path.
+    std::string vpath = (file_root + "/bar/ddd").str();
+    std::string rpath =
+        (reproducer_root.Path + file_root.Path + "/foo/ddd").str();
+    printf("%s -> %s\n", vpath.c_str(), rpath.c_str());
+    EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath)));
+  }
+
+  {
+    // Make sure that .. is removed from the source path.
+    std::string vpath = (file_root + "/eee").str();
+    std::string rpath = (reproducer_root.Path + file_root.Path + "/eee").str();
+    printf("%s -> %s\n", vpath.c_str(), rpath.c_str());
+    EXPECT_THAT(mapping, testing::Contains(vfs::YAMLVFSEntry(vpath, rpath)));
+  }
+}
+
+TEST(FileCollectorTest, recordVFSSymlinkAccesses) {
+  ScopedDir file_root("dir_root", true);
+  ScopedFile a(file_root + "/a");
+  ScopedLink symlink(file_root + "/a", file_root + "/b");
+
+  // Create file collector and add files.
+  ScopedDir root("copy_files_root", true);
+  std::string root_fs = root.Path.str();
+  auto Collector = std::make_shared<TestingFileCollector>(root_fs, root_fs);
+  auto VFS =
+      FileCollector::createCollectorVFS(vfs::getRealFileSystem(), Collector);
+  SmallString<256> Output;
+  VFS->getRealPath(symlink.Path, Output);
+  EXPECT_TRUE(Collector->hasSeen(a.Path));
+  EXPECT_TRUE(Collector->hasSeen(symlink.Path));
+}
+#endif
diff --git a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
index 8afc212..6b6196f 100644
--- a/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/FileOutputBufferTest.cpp
@@ -118,6 +118,28 @@
   EXPECT_TRUE(IsExecutable);
   ASSERT_NO_ERROR(fs::remove(File4.str()));
 
+  // TEST 5: In-memory buffer works as expected.
+  SmallString<128> File5(TestDirectory);
+  File5.append("/file5");
+  {
+    Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+        FileOutputBuffer::create(File5, 8000, FileOutputBuffer::F_no_mmap);
+    ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
+    std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
+    // Start buffer with special header.
+    memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
+    ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
+    // 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 File5Size;
+  ASSERT_NO_ERROR(fs::file_size(Twine(File5), File5Size));
+  ASSERT_EQ(File5Size, 8000ULL);
+  ASSERT_NO_ERROR(fs::remove(File5.str()));
   // Clean up.
   ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
 }
diff --git a/src/llvm-project/llvm/unittests/Support/FileUtilitiesTest.cpp b/src/llvm-project/llvm/unittests/Support/FileUtilitiesTest.cpp
new file mode 100644
index 0000000..2bf9dc5
--- /dev/null
+++ b/src/llvm-project/llvm/unittests/Support/FileUtilitiesTest.cpp
@@ -0,0 +1,52 @@
+//===- llvm/unittest/Support/FileUtilitiesTest.cpp - unit tests -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FileUtilities.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 "gtest/gtest.h"
+#include <fstream>
+
+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(writeFileAtomicallyTest, Test) {
+  // Create unique temporary directory for these tests
+  SmallString<128> RootTestDirectory;
+  ASSERT_NO_ERROR(
+    fs::createUniqueDirectory("writeFileAtomicallyTest", RootTestDirectory));
+
+  SmallString<128> FinalTestfilePath(RootTestDirectory);
+  sys::path::append(FinalTestfilePath, "foo.txt");
+  const std::string TempUniqTestFileModel = FinalTestfilePath.str().str() + "-%%%%%%%%";
+  const std::string TestfileContent = "fooFOOfoo";
+
+  llvm::Error Err = llvm::writeFileAtomically(TempUniqTestFileModel, FinalTestfilePath, TestfileContent);
+  ASSERT_FALSE(static_cast<bool>(Err));
+
+  std::ifstream FinalFileStream(FinalTestfilePath.str());
+  std::string FinalFileContent;
+  FinalFileStream >> FinalFileContent;
+  ASSERT_EQ(FinalFileContent, TestfileContent);
+}
+} // anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
index 113b20e..17d60b2 100644
--- a/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/GlobPatternTest.cpp
@@ -14,57 +14,115 @@
 
 class GlobPatternTest : public ::testing::Test {};
 
-TEST_F(GlobPatternTest, Basics) {
+TEST_F(GlobPatternTest, Empty) {
   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");
+TEST_F(GlobPatternTest, Glob) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("ab*c*def");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("abcdef"));
+  EXPECT_TRUE(Pat1->match("abxcxdef"));
+  EXPECT_FALSE(Pat1->match(""));
+  EXPECT_FALSE(Pat1->match("xabcdef"));
+  EXPECT_FALSE(Pat1->match("abcdefx"));
+}
+
+TEST_F(GlobPatternTest, Wildcard) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("a??c");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("axxc"));
+  EXPECT_FALSE(Pat1->match("axxx"));
+  EXPECT_FALSE(Pat1->match(""));
+}
+
+TEST_F(GlobPatternTest, Escape) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("\\*");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("*"));
+  EXPECT_FALSE(Pat1->match("\\*"));
+  EXPECT_FALSE(Pat1->match("a"));
+
+  Expected<GlobPattern> Pat2 = GlobPattern::create("a?\\?c");
   EXPECT_TRUE((bool)Pat2);
-  EXPECT_TRUE(Pat2->match("abcdef"));
-  EXPECT_TRUE(Pat2->match("abxcxdef"));
+  EXPECT_TRUE(Pat2->match("ax?c"));
+  EXPECT_FALSE(Pat2->match("axxc"));
   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(""));
+TEST_F(GlobPatternTest, BasicCharacterClass) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("[abc-fy-z]");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("a"));
+  EXPECT_TRUE(Pat1->match("b"));
+  EXPECT_TRUE(Pat1->match("c"));
+  EXPECT_TRUE(Pat1->match("d"));
+  EXPECT_TRUE(Pat1->match("e"));
+  EXPECT_TRUE(Pat1->match("f"));
+  EXPECT_TRUE(Pat1->match("y"));
+  EXPECT_TRUE(Pat1->match("z"));
+  EXPECT_FALSE(Pat1->match("g"));
+  EXPECT_FALSE(Pat1->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(""));
+TEST_F(GlobPatternTest, NegatedCharacterClass) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("[^abc-fy-z]");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("g"));
+  EXPECT_FALSE(Pat1->match("a"));
+  EXPECT_FALSE(Pat1->match("b"));
+  EXPECT_FALSE(Pat1->match("c"));
+  EXPECT_FALSE(Pat1->match("d"));
+  EXPECT_FALSE(Pat1->match("e"));
+  EXPECT_FALSE(Pat1->match("f"));
+  EXPECT_FALSE(Pat1->match("y"));
+  EXPECT_FALSE(Pat1->match("z"));
+  EXPECT_FALSE(Pat1->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(""));
+  Expected<GlobPattern> Pat2 = GlobPattern::create("[!abc-fy-z]");
+  EXPECT_TRUE((bool)Pat2);
+  EXPECT_TRUE(Pat2->match("g"));
+  EXPECT_FALSE(Pat2->match("a"));
+  EXPECT_FALSE(Pat2->match("b"));
+  EXPECT_FALSE(Pat2->match("c"));
+  EXPECT_FALSE(Pat2->match("d"));
+  EXPECT_FALSE(Pat2->match("e"));
+  EXPECT_FALSE(Pat2->match("f"));
+  EXPECT_FALSE(Pat2->match("y"));
+  EXPECT_FALSE(Pat2->match("z"));
+  EXPECT_FALSE(Pat2->match(""));
+}
+
+TEST_F(GlobPatternTest, BracketFrontOfCharacterClass) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("[]a]x");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("]x"));
+  EXPECT_TRUE(Pat1->match("ax"));
+  EXPECT_FALSE(Pat1->match("a]x"));
+  EXPECT_FALSE(Pat1->match(""));
+}
+
+TEST_F(GlobPatternTest, SpecialCharsInCharacterClass) {
+  Expected<GlobPattern> Pat1 = GlobPattern::create("[*?^]");
+  EXPECT_TRUE((bool)Pat1);
+  EXPECT_TRUE(Pat1->match("*"));
+  EXPECT_TRUE(Pat1->match("?"));
+  EXPECT_TRUE(Pat1->match("^"));
+  EXPECT_FALSE(Pat1->match("*?^"));
+  EXPECT_FALSE(Pat1->match(""));
 }
 
 TEST_F(GlobPatternTest, Invalid) {
   Expected<GlobPattern> Pat1 = GlobPattern::create("[");
   EXPECT_FALSE((bool)Pat1);
   handleAllErrors(Pat1.takeError(), [&](ErrorInfoBase &EIB) {});
+
+  Expected<GlobPattern> Pat2 = GlobPattern::create("[]");
+  EXPECT_FALSE((bool)Pat2);
+  handleAllErrors(Pat2.takeError(), [&](ErrorInfoBase &EIB) {});
 }
 
 TEST_F(GlobPatternTest, ExtSym) {
diff --git a/src/llvm-project/llvm/unittests/Support/Host.cpp b/src/llvm-project/llvm/unittests/Support/Host.cpp
index ec9dd95..2c17a50 100644
--- a/src/llvm-project/llvm/unittests/Support/Host.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Host.cpp
@@ -147,7 +147,7 @@
 CPU implementer : 0x41
 CPU architecture: 8
 CPU variant     : 0x0
-CPU part        : 0xd03
+CPU part        : 0xd05
 
 processor       : 1
 Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
@@ -159,17 +159,17 @@
   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
                                               "CPU variant     : 0xc\n"
                                               "CPU part        : 0xafe"),
-            "exynos-m1");
-  // Verify Exynos M1.
+            "exynos-m3");
+  // Verify Exynos M3.
   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
                                               "CPU variant     : 0x1\n"
-                                              "CPU part        : 0x001"),
-            "exynos-m1");
-  // Verify Exynos M2.
+                                              "CPU part        : 0x002"),
+            "exynos-m3");
+  // Verify Exynos M4.
   EXPECT_EQ(sys::detail::getHostCPUNameForARM(ExynosProcCpuInfo +
-                                              "CPU variant     : 0x4\n"
-                                              "CPU part        : 0x001"),
-            "exynos-m2");
+                                              "CPU variant     : 0x1\n"
+                                              "CPU part        : 0x003"),
+            "exynos-m4");
 
   const std::string ThunderX2T99ProcCpuInfo = R"(
 processor	: 0
@@ -273,7 +273,7 @@
     Size = ::lseek(FD, 0, SEEK_END);
     ASSERT_NE(-1, Size);
     ::lseek(FD, 0, SEEK_SET);
-    Buffer = llvm::make_unique<char[]>(Size);
+    Buffer = std::make_unique<char[]>(Size);
     ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
     ::close(FD);
 
diff --git a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
index 9143289..b20cdcf 100644
--- a/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp
@@ -249,6 +249,19 @@
         {"_Z1fRA1_i"}, {"_Z1fRA_f"},
       }
     },
+
+    // Unmangled names can be remapped as complete encodings.
+    {
+      {
+        {FragmentKind::Encoding, "3foo", "3bar"},
+      },
+      {
+        // foo == bar
+        {"foo", "bar"},
+        // void f<foo>() == void f<bar>()
+        {"_Z1fIL_Z3fooEEvv", "_Z1fIL_Z3barEEvv"},
+      }
+    },
   };
 }
 
@@ -343,7 +356,7 @@
             EquivalenceError::InvalidSecondMangling);
   EXPECT_EQ(Canonicalizer.canonicalize("_Z3fooE"),
             llvm::ItaniumManglingCanonicalizer::Key());
-  EXPECT_EQ(Canonicalizer.canonicalize("foo"),
+  EXPECT_EQ(Canonicalizer.canonicalize("_Zfoo"),
             llvm::ItaniumManglingCanonicalizer::Key());
 
   // A reference to a template parameter ('T_' etc) cannot appear in a <name>,
diff --git a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
index 14c11b1..93efcf2 100644
--- a/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/JSONTest.cpp
@@ -71,7 +71,7 @@
 }
 
 TEST(JSONTest, Escaping) {
-  std::string test = {
+  std::string Test = {
       0,                    // Strings may contain nulls.
       '\b',   '\f',         // Have mnemonics, but we escape numerically.
       '\r',   '\n',   '\t', // Escaped with mnemonics.
@@ -80,17 +80,17 @@
       '\xce', '\x94',       // Non-ASCII UTF-8 is not escaped.
   };
 
-  std::string teststring = R"("\u0000\u0008\u000c\r\n\tS\"\\)"
+  std::string TestString = R"("\u0000\u0008\u000c\r\n\tS\"\\)"
                            "\x7f\xCE\x94\"";
 
-  EXPECT_EQ(teststring, s(test));
+  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"({
+  const char Str[] = R"({
   "empty_array": [],
   "empty_object": {},
   "full_array": [
@@ -106,7 +106,7 @@
   }
 })";
 
-  EXPECT_EQ(str, sp(Object{
+  EXPECT_EQ(Str, sp(Object{
                      {"empty_object", Object{}},
                      {"empty_array", {}},
                      {"full_array", {1, nullptr}},
@@ -120,6 +120,33 @@
                  }));
 }
 
+TEST(JSONTest, Array) {
+  Array A{1, 2};
+  A.emplace_back(3);
+  A.emplace(++A.begin(), 0);
+  A.push_back(4);
+  A.insert(++++A.begin(), 99);
+
+  EXPECT_EQ(A.size(), 6u);
+  EXPECT_EQ(R"([1,0,99,2,3,4])", s(std::move(A)));
+}
+
+TEST(JSONTest, Object) {
+  Object O{{"a", 1}, {"b", 2}, {"c", 3}};
+  EXPECT_TRUE(O.try_emplace("d", 4).second);
+  EXPECT_FALSE(O.try_emplace("a", 4).second);
+
+  auto D = O.find("d");
+  EXPECT_FALSE(D == O.end());
+  auto E = O.find("e");
+  EXPECT_TRUE(E == O.end());
+
+  O.erase("b");
+  O.erase(D);
+  EXPECT_EQ(O.size(), 2u);
+  EXPECT_EQ(R"({"a":1,"c":3})", s(std::move(O)));
+}
+
 TEST(JSONTest, Parse) {
   auto Compare = [](llvm::StringRef S, Value Expected) {
     if (auto E = parse(S)) {
diff --git a/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp b/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
index c2b3b12..372521d 100644
--- a/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp
@@ -127,4 +127,18 @@
   TestAddSubExhaustive(false);
 }
 
+TEST(KnownBitsTest, GetMinMaxVal) {
+  unsigned Bits = 4;
+  ForeachKnownBits(Bits, [&](const KnownBits &Known) {
+    APInt Min = APInt::getMaxValue(Bits);
+    APInt Max = APInt::getMinValue(Bits);
+    ForeachNumInKnownBits(Known, [&](const APInt &N) {
+      Min = APIntOps::umin(Min, N);
+      Max = APIntOps::umax(Max, N);
+    });
+    EXPECT_EQ(Min, Known.getMinValue());
+    EXPECT_EQ(Max, Known.getMaxValue());
+  });
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
index de87714..e910d83 100644
--- a/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MathExtrasTest.cpp
@@ -203,6 +203,25 @@
   EXPECT_EQ(4U, PowerOf2Floor(7U));
 }
 
+TEST(MathExtras, CTLog2) {
+  EXPECT_EQ(CTLog2<1ULL << 0>(), 0U);
+  EXPECT_EQ(CTLog2<1ULL << 1>(), 1U);
+  EXPECT_EQ(CTLog2<1ULL << 2>(), 2U);
+  EXPECT_EQ(CTLog2<1ULL << 3>(), 3U);
+  EXPECT_EQ(CTLog2<1ULL << 4>(), 4U);
+  EXPECT_EQ(CTLog2<1ULL << 5>(), 5U);
+  EXPECT_EQ(CTLog2<1ULL << 6>(), 6U);
+  EXPECT_EQ(CTLog2<1ULL << 7>(), 7U);
+  EXPECT_EQ(CTLog2<1ULL << 8>(), 8U);
+  EXPECT_EQ(CTLog2<1ULL << 9>(), 9U);
+  EXPECT_EQ(CTLog2<1ULL << 10>(), 10U);
+  EXPECT_EQ(CTLog2<1ULL << 11>(), 11U);
+  EXPECT_EQ(CTLog2<1ULL << 12>(), 12U);
+  EXPECT_EQ(CTLog2<1ULL << 13>(), 13U);
+  EXPECT_EQ(CTLog2<1ULL << 14>(), 14U);
+  EXPECT_EQ(CTLog2<1ULL << 15>(), 15U);
+}
+
 TEST(MathExtras, ByteSwap_32) {
   EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344));
   EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD));
@@ -468,4 +487,131 @@
   EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15)));
 }
 
+template <typename T>
+class OverflowTest : public ::testing::Test { };
+
+using OverflowTestTypes = ::testing::Types<signed char, short, int, long,
+                                           long long>;
+
+TYPED_TEST_CASE(OverflowTest, OverflowTestTypes);
+
+TYPED_TEST(OverflowTest, AddNoOverflow) {
+  TypeParam Result;
+  EXPECT_FALSE(AddOverflow<TypeParam>(1, 2, Result));
+  EXPECT_EQ(Result, TypeParam(3));
+}
+
+TYPED_TEST(OverflowTest, AddOverflowToNegative) {
+  TypeParam Result;
+  auto MaxValue = std::numeric_limits<TypeParam>::max();
+  EXPECT_TRUE(AddOverflow<TypeParam>(MaxValue, MaxValue, Result));
+  EXPECT_EQ(Result, TypeParam(-2));
+}
+
+TYPED_TEST(OverflowTest, AddOverflowToMin) {
+  TypeParam Result;
+  auto MaxValue = std::numeric_limits<TypeParam>::max();
+  EXPECT_TRUE(AddOverflow<TypeParam>(MaxValue, TypeParam(1), Result));
+  EXPECT_EQ(Result, std::numeric_limits<TypeParam>::min());
+}
+
+TYPED_TEST(OverflowTest, AddOverflowToZero) {
+  TypeParam Result;
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(AddOverflow<TypeParam>(MinValue, MinValue, Result));
+  EXPECT_EQ(Result, TypeParam(0));
+}
+
+TYPED_TEST(OverflowTest, AddOverflowToMax) {
+  TypeParam Result;
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(AddOverflow<TypeParam>(MinValue, TypeParam(-1), Result));
+  EXPECT_EQ(Result, std::numeric_limits<TypeParam>::max());
+}
+
+TYPED_TEST(OverflowTest, SubNoOverflow) {
+  TypeParam Result;
+  EXPECT_FALSE(SubOverflow<TypeParam>(1, 2, Result));
+  EXPECT_EQ(Result, TypeParam(-1));
+}
+
+TYPED_TEST(OverflowTest, SubOverflowToMax) {
+  TypeParam Result;
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(SubOverflow<TypeParam>(0, MinValue, Result));
+  EXPECT_EQ(Result, MinValue);
+}
+
+TYPED_TEST(OverflowTest, SubOverflowToMin) {
+  TypeParam Result;
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(SubOverflow<TypeParam>(0, MinValue, Result));
+  EXPECT_EQ(Result, MinValue);
+}
+
+TYPED_TEST(OverflowTest, SubOverflowToNegative) {
+  TypeParam Result;
+  auto MaxValue = std::numeric_limits<TypeParam>::max();
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(SubOverflow<TypeParam>(MaxValue, MinValue, Result));
+  EXPECT_EQ(Result, TypeParam(-1));
+}
+
+TYPED_TEST(OverflowTest, SubOverflowToPositive) {
+  TypeParam Result;
+  auto MaxValue = std::numeric_limits<TypeParam>::max();
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(SubOverflow<TypeParam>(MinValue, MaxValue, Result));
+  EXPECT_EQ(Result, TypeParam(1));
+}
+
+TYPED_TEST(OverflowTest, MulNoOverflow) {
+  TypeParam Result;
+  EXPECT_FALSE(MulOverflow<TypeParam>(1, 2, Result));
+  EXPECT_EQ(Result, 2);
+  EXPECT_FALSE(MulOverflow<TypeParam>(-1, 3, Result));
+  EXPECT_EQ(Result, -3);
+  EXPECT_FALSE(MulOverflow<TypeParam>(4, -2, Result));
+  EXPECT_EQ(Result, -8);
+  EXPECT_FALSE(MulOverflow<TypeParam>(-6, -5, Result));
+  EXPECT_EQ(Result, 30);
+}
+
+TYPED_TEST(OverflowTest, MulNoOverflowToMax) {
+  TypeParam Result;
+  auto MaxValue = std::numeric_limits<TypeParam>::max();
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_FALSE(MulOverflow<TypeParam>(MinValue + 1, -1, Result));
+  EXPECT_EQ(Result, MaxValue);
+}
+
+TYPED_TEST(OverflowTest, MulOverflowToMin) {
+  TypeParam Result;
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  EXPECT_TRUE(MulOverflow<TypeParam>(MinValue, -1, Result));
+  EXPECT_EQ(Result, MinValue);
+}
+
+TYPED_TEST(OverflowTest, MulOverflowMax) {
+  TypeParam Result;
+  auto MinValue = std::numeric_limits<TypeParam>::min();
+  auto MaxValue = std::numeric_limits<TypeParam>::max();
+  EXPECT_TRUE(MulOverflow<TypeParam>(MinValue, MinValue, Result));
+  EXPECT_EQ(Result, 0);
+  EXPECT_TRUE(MulOverflow<TypeParam>(MaxValue, MaxValue, Result));
+  EXPECT_EQ(Result, 1);
+}
+
+TYPED_TEST(OverflowTest, MulResultZero) {
+  TypeParam Result;
+  EXPECT_FALSE(MulOverflow<TypeParam>(4, 0, Result));
+  EXPECT_EQ(Result, TypeParam(0));
+  EXPECT_FALSE(MulOverflow<TypeParam>(-5, 0, Result));
+  EXPECT_EQ(Result, TypeParam(0));
+  EXPECT_FALSE(MulOverflow<TypeParam>(0, 5, Result));
+  EXPECT_EQ(Result, TypeParam(0));
+  EXPECT_FALSE(MulOverflow<TypeParam>(0, -5, Result));
+  EXPECT_EQ(Result, TypeParam(0));
+}
+
 } // namespace
diff --git a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
index 2f96643..1b72aad 100644
--- a/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/MemoryBufferTest.cpp
@@ -11,14 +11,43 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/ScopeExit.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"
+#if LLVM_ENABLE_THREADS
+#include <thread>
+#endif
+#if LLVM_ON_UNIX
+#include <unistd.h>
+#endif
+#if _WIN32
+#include <windows.h>
+#endif
 
 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 {                                                                     \
+  }
+
+#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 {
 
 class MemoryBufferTest : public testing::Test {
@@ -65,6 +94,37 @@
   EXPECT_EQ("this is some data", data);
 }
 
+TEST_F(MemoryBufferTest, getOpenFile) {
+  int FD;
+  SmallString<64> TestPath;
+  ASSERT_EQ(sys::fs::createTemporaryFile("MemoryBufferTest_getOpenFile", "temp",
+                                         FD, TestPath),
+            std::error_code());
+
+  FileRemover Cleanup(TestPath);
+  raw_fd_ostream OF(FD, /*shouldClose*/ true);
+  OF << "12345678";
+  OF.close();
+
+  {
+    Expected<sys::fs::file_t> File = sys::fs::openNativeFileForRead(TestPath);
+    ASSERT_THAT_EXPECTED(File, Succeeded());
+    auto OnExit =
+        make_scope_exit([&] { ASSERT_NO_ERROR(sys::fs::closeFile(*File)); });
+    ErrorOr<OwningBuffer> MB = MemoryBuffer::getOpenFile(*File, TestPath, 6);
+    ASSERT_NO_ERROR(MB.getError());
+    EXPECT_EQ("123456", MB.get()->getBuffer());
+  }
+  {
+    Expected<sys::fs::file_t> File = sys::fs::openNativeFileForWrite(
+        TestPath, sys::fs::CD_OpenExisting, sys::fs::OF_None);
+    ASSERT_THAT_EXPECTED(File, Succeeded());
+    auto OnExit =
+        make_scope_exit([&] { ASSERT_NO_ERROR(sys::fs::closeFile(*File)); });
+    ASSERT_ERROR(MemoryBuffer::getOpenFile(*File, TestPath, 6).getError());
+  }
+}
+
 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.
@@ -101,6 +161,38 @@
   EXPECT_NE(MBC1->getBufferStart(), MBC2->getBufferStart());
 }
 
+#if LLVM_ENABLE_THREADS
+TEST_F(MemoryBufferTest, createFromPipe) {
+  sys::fs::file_t pipes[2];
+#if LLVM_ON_UNIX
+  ASSERT_EQ(::pipe(pipes), 0) << strerror(errno);
+#else
+  ASSERT_TRUE(::CreatePipe(&pipes[0], &pipes[1], nullptr, 0))
+      << ::GetLastError();
+#endif
+  auto ReadCloser = make_scope_exit([&] { sys::fs::closeFile(pipes[0]); });
+  std::thread Writer([&] {
+    auto WriteCloser = make_scope_exit([&] { sys::fs::closeFile(pipes[1]); });
+    for (unsigned i = 0; i < 5; ++i) {
+      std::this_thread::sleep_for(std::chrono::milliseconds(10));
+#if LLVM_ON_UNIX
+      ASSERT_EQ(::write(pipes[1], "foo", 3), 3) << strerror(errno);
+#else
+      DWORD Written;
+      ASSERT_TRUE(::WriteFile(pipes[1], "foo", 3, &Written, nullptr))
+          << ::GetLastError();
+      ASSERT_EQ(Written, 3u);
+#endif
+    }
+  });
+  ErrorOr<OwningBuffer> MB =
+      MemoryBuffer::getOpenFile(pipes[0], "pipe", /*FileSize*/ -1);
+  Writer.join();
+  ASSERT_NO_ERROR(MB.getError());
+  EXPECT_EQ(MB.get()->getBuffer(), "foofoofoofoofoo");
+}
+#endif
+
 TEST_F(MemoryBufferTest, make_new) {
   // 0-sized buffer
   OwningBuffer Zero(WritableMemoryBuffer::getNewUninitMemBuffer(0));
diff --git a/src/llvm-project/llvm/unittests/Support/Path.cpp b/src/llvm-project/llvm/unittests/Support/Path.cpp
index ccd72d7..b143ea6 100644
--- a/src/llvm-project/llvm/unittests/Support/Path.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Path.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Support/Path.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/BinaryFormat/Magic.h"
@@ -20,8 +21,9 @@
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "gtest/gtest.h"
+#include "llvm/Testing/Support/Error.h"
 #include "gmock/gmock.h"
+#include "gtest/gtest.h"
 
 #ifdef _WIN32
 #include "llvm/ADT/ArrayRef.h"
@@ -185,10 +187,19 @@
     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);
+  {
+    SmallString<32> Relative("foo.cpp");
+    sys::fs::make_absolute("/root", Relative);
+    Relative[5] = '/'; // Fix up windows paths.
+    ASSERT_EQ("/root/foo.cpp", Relative);
+  }
+
+  {
+    SmallString<32> Relative("foo.cpp");
+    sys::fs::make_absolute("//root", Relative);
+    Relative[6] = '/'; // Fix up windows paths.
+    ASSERT_EQ("//root/foo.cpp", Relative);
+  }
 }
 
 TEST(Support, FilenameParent) {
@@ -1021,7 +1032,7 @@
   path::append(FilePathname, "test");
 
   {
-    raw_fd_ostream File(FilePathname, EC, sys::fs::F_Text);
+    raw_fd_ostream File(FilePathname, EC, sys::fs::OF_Text);
     ASSERT_NO_ERROR(EC);
     File << '\n';
   }
@@ -1032,7 +1043,7 @@
   }
 
   {
-    raw_fd_ostream File(FilePathname, EC, sys::fs::F_None);
+    raw_fd_ostream File(FilePathname, EC, sys::fs::OF_None);
     ASSERT_NO_ERROR(EC);
     File << '\n';
   }
@@ -1219,7 +1230,9 @@
 TEST(Support, ReplacePathPrefix) {
   SmallString<64> Path1("/foo");
   SmallString<64> Path2("/old/foo");
+  SmallString<64> Path3("/oldnew/foo");
   SmallString<64> OldPrefix("/old");
+  SmallString<64> OldPrefixSep("/old/");
   SmallString<64> NewPrefix("/new");
   SmallString<64> NewPrefix2("/longernew");
   SmallString<64> EmptyPrefix("");
@@ -1239,6 +1252,39 @@
   Path = Path2;
   path::replace_path_prefix(Path, OldPrefix, EmptyPrefix);
   EXPECT_EQ(Path, "/foo");
+  Path = Path2;
+  path::replace_path_prefix(Path, OldPrefix, EmptyPrefix, path::Style::native,
+                            true);
+  EXPECT_EQ(Path, "foo");
+  Path = Path3;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix, path::Style::native,
+                            false);
+  EXPECT_EQ(Path, "/newnew/foo");
+  Path = Path3;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix, path::Style::native,
+                            true);
+  EXPECT_EQ(Path, "/oldnew/foo");
+  Path = Path3;
+  path::replace_path_prefix(Path, OldPrefixSep, NewPrefix, path::Style::native,
+                            true);
+  EXPECT_EQ(Path, "/oldnew/foo");
+  Path = Path1;
+  path::replace_path_prefix(Path, EmptyPrefix, NewPrefix);
+  EXPECT_EQ(Path, "/new/foo");
+  Path = OldPrefix;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix);
+  EXPECT_EQ(Path, "/new");
+  Path = OldPrefixSep;
+  path::replace_path_prefix(Path, OldPrefix, NewPrefix);
+  EXPECT_EQ(Path, "/new/");
+  Path = OldPrefix;
+  path::replace_path_prefix(Path, OldPrefixSep, NewPrefix, path::Style::native,
+                            false);
+  EXPECT_EQ(Path, "/old");
+  Path = OldPrefix;
+  path::replace_path_prefix(Path, OldPrefixSep, NewPrefix, path::Style::native,
+                            true);
+  EXPECT_EQ(Path, "/new");
 }
 
 TEST_F(FileSystemTest, OpenFileForRead) {
@@ -1418,7 +1464,7 @@
                                      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
+  // hack that shouldn't work, but is left for compatibility.  OF_Append
   // overrides
   // the specified disposition.
   for (fs::CreationDisposition Disp : Disps) {
@@ -1504,6 +1550,49 @@
   verifyWrite(FD, "Buzz", true);
 }
 
+TEST_F(FileSystemTest, readNativeFile) {
+  createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "01234");
+  FileRemover Cleanup(NonExistantFile);
+  const auto &Read = [&](size_t ToRead) -> Expected<std::string> {
+    std::string Buf(ToRead, '?');
+    Expected<fs::file_t> FD = fs::openNativeFileForRead(NonExistantFile);
+    if (!FD)
+      return FD.takeError();
+    auto Close = make_scope_exit([&] { fs::closeFile(*FD); });
+    if (Expected<size_t> BytesRead = fs::readNativeFile(
+            *FD, makeMutableArrayRef(&*Buf.begin(), Buf.size())))
+      return Buf.substr(0, *BytesRead);
+    else
+      return BytesRead.takeError();
+  };
+  EXPECT_THAT_EXPECTED(Read(5), HasValue("01234"));
+  EXPECT_THAT_EXPECTED(Read(3), HasValue("012"));
+  EXPECT_THAT_EXPECTED(Read(6), HasValue("01234"));
+}
+
+TEST_F(FileSystemTest, readNativeFileSlice) {
+  createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "01234");
+  FileRemover Cleanup(NonExistantFile);
+  Expected<fs::file_t> FD = fs::openNativeFileForRead(NonExistantFile);
+  ASSERT_THAT_EXPECTED(FD, Succeeded());
+  auto Close = make_scope_exit([&] { fs::closeFile(*FD); });
+  const auto &Read = [&](size_t Offset,
+                         size_t ToRead) -> Expected<std::string> {
+    std::string Buf(ToRead, '?');
+    if (Expected<size_t> BytesRead = fs::readNativeFileSlice(
+            *FD, makeMutableArrayRef(&*Buf.begin(), Buf.size()), Offset))
+      return Buf.substr(0, *BytesRead);
+    else
+      return BytesRead.takeError();
+  };
+  EXPECT_THAT_EXPECTED(Read(0, 5), HasValue("01234"));
+  EXPECT_THAT_EXPECTED(Read(0, 3), HasValue("012"));
+  EXPECT_THAT_EXPECTED(Read(2, 3), HasValue("234"));
+  EXPECT_THAT_EXPECTED(Read(0, 6), HasValue("01234"));
+  EXPECT_THAT_EXPECTED(Read(2, 6), HasValue("234"));
+  EXPECT_THAT_EXPECTED(Read(5, 5), HasValue(""));
+}
+
 TEST_F(FileSystemTest, is_local) {
   bool TestDirectoryIsLocal;
   ASSERT_NO_ERROR(fs::is_local(TestDirectory, TestDirectoryIsLocal));
diff --git a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
index dbfaf8e..83be3a9 100644
--- a/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ProcessTest.cpp
@@ -6,6 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Host.h"
 #include "llvm/Support/Process.h"
 #include "gtest/gtest.h"
 
@@ -61,4 +64,39 @@
 }
 #endif
 
+class PageSizeTest : public testing::Test {
+  Triple Host;
+
+protected:
+  PageSizeTest() : Host(Triple::normalize(sys::getProcessTriple())) {}
+
+  bool isSupported() const {
+    // For now just on X86-64 and Aarch64. This can be expanded in the future.
+    return (Host.getArch() == Triple::x86_64 ||
+            Host.getArch() == Triple::aarch64) &&
+           Host.getOS() == Triple::Linux;
+  }
+
+  bool pageSizeAsExpected(unsigned PageSize) const {
+    switch (Host.getArch()) {
+    case Triple::x86_64:
+      return PageSize == 4096;
+    case Triple::aarch64:
+      // supported granule sizes are 4k, 16k and 64k
+      return PageSize == 4096 || PageSize == 16384 || PageSize == 65536;
+    default:
+      llvm_unreachable("unexpected arch!");
+    }
+  }
+};
+
+TEST_F(PageSizeTest, PageSize) {
+  if (!isSupported())
+    return;
+
+  llvm::Expected<unsigned> Result = llvm::sys::Process::getPageSize();
+  ASSERT_FALSE(!Result);
+  ASSERT_TRUE(pageSizeAsExpected(*Result));
+}
+
 } // end anonymous namespace
diff --git a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
index 05804e6..6573682 100644
--- a/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ReverseIterationTest.cpp
@@ -45,7 +45,7 @@
   int IterKeys[] = { 2, 4, 1, 3 };
 
   // Check that the DenseMap is iterated in the expected order.
-  for (const auto &Tuple : zip(Map, IterKeys))
+  for (auto Tuple : zip(Map, IterKeys))
     ASSERT_EQ(std::get<0>(Tuple).first, std::get<1>(Tuple));
 
   // Check operator++ (post-increment).
@@ -99,7 +99,7 @@
     std::reverse(&Keys[0], &Keys[4]);
 
   // Check that the DenseMap is iterated in the expected order.
-  for (const auto &Tuple : zip(Map, Keys))
+  for (auto Tuple : zip(Map, Keys))
     ASSERT_EQ(std::get<0>(Tuple).second, std::get<1>(Tuple)->value);
 
   // Check operator++ (post-increment).
diff --git a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
index 2245588..de1f058 100644
--- a/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -9,6 +9,7 @@
 #include "llvm/Support/SpecialCaseList.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -161,7 +162,8 @@
   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(nullptr,
+            SpecialCaseList::create(Files, *vfs::getRealFileSystem(), Error));
   EXPECT_EQ(0U, Error.find("can't open file 'unexisting':"));
 }
 
@@ -177,7 +179,7 @@
                                           "src:ban=init\n"));
   Files.push_back(makeSpecialCaseListFile("src:baz\n"
                                           "src:*fog*\n"));
-  auto SCL = SpecialCaseList::createOrDie(Files);
+  auto SCL = SpecialCaseList::createOrDie(Files, *vfs::getRealFileSystem());
   EXPECT_TRUE(SCL->inSection("", "src", "bar"));
   EXPECT_TRUE(SCL->inSection("", "src", "baz"));
   EXPECT_FALSE(SCL->inSection("", "src", "ban"));
diff --git a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
index 04ee379..32d0924 100644
--- a/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TargetParserTest.cpp
@@ -44,7 +44,6 @@
     pass &= ((ExtKind ^ ARM::AEK_NONE) == ExpectedFlags);
   else
     pass &= (ExtKind == ExpectedFlags);
-
   pass &= ARM::getCPUAttr(AK).equals(CPUAttr);
 
   return pass;
@@ -257,21 +256,17 @@
                          ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_FP16 |
                          ARM::AEK_RAS | ARM::AEK_DOTPROD,
                          "8.2-A"));
+  EXPECT_TRUE(testARMCPU("neoverse-n1", "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 |
@@ -304,7 +299,7 @@
                          "7-S"));
 }
 
-static constexpr unsigned NumARMCPUArchs = 86;
+static constexpr unsigned NumARMCPUArchs = 85;
 
 TEST(TargetParserTest, testARMCPUArchList) {
   SmallVector<StringRef, NumARMCPUArchs> List;
@@ -327,10 +322,11 @@
 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);
+  bool Result = (AK != ARM::ArchKind::INVALID);
+  Result &= ARM::getDefaultCPU(Arch).equals(DefaultCPU);
+  Result &= ARM::getSubArch(AK).equals(SubArch);
+  Result &= (ARM::getArchAttr(AK) == ArchAttr);
+  return Result;
 }
 
 TEST(TargetParserTest, testARMArch) {
@@ -782,6 +778,20 @@
       AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
       AArch64::AEK_SIMD, "8-A"));
   EXPECT_TRUE(testAArch64CPU(
+      "cortex-a65", "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_RCPC | AArch64::AEK_RDM |
+      AArch64::AEK_SIMD | AArch64::AEK_SSBS,
+      "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "cortex-a65ae", "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_RCPC | AArch64::AEK_RDM |
+      AArch64::AEK_SIMD | AArch64::AEK_SSBS,
+      "8.2-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"));
@@ -811,13 +821,50 @@
       "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"));
+      "apple-a7", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
   EXPECT_TRUE(testAArch64CPU(
-      "exynos-m2", "armv8-a", "crypto-neon-fp-armv8",
+      "apple-a8", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "apple-a9", "armv8-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD, "8-A"));
+  EXPECT_TRUE(testAArch64CPU("apple-a10", "armv8-a", "crypto-neon-fp-armv8",
+                             AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
+                                 AArch64::AEK_FP | AArch64::AEK_RDM |
+                                 AArch64::AEK_SIMD,
+                             "8-A"));
+  EXPECT_TRUE(testAArch64CPU("apple-a11", "armv8.2-a", "crypto-neon-fp-armv8",
+                             AArch64::AEK_CRC | AArch64::AEK_CRYPTO |
+                                 AArch64::AEK_FP | AArch64::AEK_LSE |
+                                 AArch64::AEK_RAS | AArch64::AEK_RDM |
+                                 AArch64::AEK_SIMD,
+                             "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "apple-a12", "armv8.3-a", "crypto-neon-fp-armv8",
       AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
-      AArch64::AEK_SIMD, "8-A"));
+          AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_RAS |
+          AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_FP16,
+      "8.3-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "apple-a13", "armv8.4-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+          AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_RAS |
+          AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+          AArch64::AEK_FP16 | AArch64::AEK_FP16FML,
+      "8.4-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "apple-s4", "armv8.3-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+          AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_RAS |
+          AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_FP16,
+      "8.3-A"));
+  EXPECT_TRUE(testAArch64CPU(
+      "apple-s5", "armv8.3-a", "crypto-neon-fp-armv8",
+      AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
+          AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_RAS |
+          AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_FP16,
+      "8.3-A"));
   EXPECT_TRUE(testAArch64CPU(
       "exynos-m3", "armv8-a", "crypto-neon-fp-armv8",
       AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
@@ -843,6 +890,20 @@
       AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
       AArch64::AEK_SIMD, "8-A"));
   EXPECT_TRUE(testAArch64CPU(
+     "neoverse-e1", "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_RCPC | AArch64::AEK_RDM |
+      AArch64::AEK_SIMD | AArch64::AEK_SSBS,
+     "8.2-A"));
+  EXPECT_TRUE(testAArch64CPU(
+     "neoverse-n1", "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_PROFILE | AArch64::AEK_RAS | AArch64::AEK_RCPC |
+      AArch64::AEK_RDM | AArch64::AEK_SIMD | AArch64::AEK_SSBS,
+     "8.2-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"));
@@ -875,7 +936,7 @@
       "8.2-A"));
 }
 
-static constexpr unsigned NumAArch64CPUArchs = 24;
+static constexpr unsigned NumAArch64CPUArchs = 35;
 
 TEST(TargetParserTest, testAArch64CPUArchList) {
   SmallVector<StringRef, NumAArch64CPUArchs> List;
@@ -936,10 +997,6 @@
                                     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",
@@ -1120,6 +1177,7 @@
                               {"rcpc", "norcpc", "+rcpc", "-rcpc" },
                               {"rng", "norng", "+rand", "-rand"},
                               {"memtag", "nomemtag", "+mte", "-mte"},
+                              {"tme", "notme", "+tme", "-tme"},
                               {"ssbs", "nossbs", "+ssbs", "-ssbs"},
                               {"sb", "nosb", "+sb", "-sb"},
                               {"predres", "nopredres", "+predres", "-predres"}
diff --git a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
index 4755b52..a16adbb 100644
--- a/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
+++ b/src/llvm-project/llvm/unittests/Support/ThreadPool.cpp
@@ -71,8 +71,7 @@
 
   std::condition_variable WaitMainThread;
   std::mutex WaitMainThreadMutex;
-  bool MainThreadReady;
-
+  bool MainThreadReady = false;
 };
 
 #define CHECK_UNSUPPORTED() \
diff --git a/src/llvm-project/llvm/unittests/Support/Threading.cpp b/src/llvm-project/llvm/unittests/Support/Threading.cpp
index 01f1c51..183c9aa 100644
--- a/src/llvm-project/llvm/unittests/Support/Threading.cpp
+++ b/src/llvm-project/llvm/unittests/Support/Threading.cpp
@@ -10,6 +10,9 @@
 #include "llvm/Support/thread.h"
 #include "gtest/gtest.h"
 
+#include <atomic>
+#include <condition_variable>
+
 using namespace llvm;
 
 namespace {
@@ -21,4 +24,57 @@
   ASSERT_LE(Num, thread::hardware_concurrency());
 }
 
+#if LLVM_ENABLE_THREADS
+
+class Notification {
+public:
+  void notify() {
+    {
+      std::lock_guard<std::mutex> Lock(M);
+      Notified = true;
+      // Broadcast with the lock held, so it's safe to destroy the Notification
+      // after wait() returns.
+      CV.notify_all();
+    }
+  }
+
+  bool wait() {
+    std::unique_lock<std::mutex> Lock(M);
+    using steady_clock = std::chrono::steady_clock;
+    auto Deadline = steady_clock::now() +
+                    std::chrono::duration_cast<steady_clock::duration>(
+                        std::chrono::duration<double>(5));
+    return CV.wait_until(Lock, Deadline, [this] { return Notified; });
+  }
+
+private:
+  bool Notified = false;
+  mutable std::condition_variable CV;
+  mutable std::mutex M;
+};
+
+TEST(Threading, RunOnThreadSyncAsync) {
+  Notification ThreadStarted, ThreadAdvanced, ThreadFinished;
+
+  auto ThreadFunc = [&] {
+    ThreadStarted.notify();
+    ASSERT_TRUE(ThreadAdvanced.wait());
+    ThreadFinished.notify();
+  };
+
+  llvm::llvm_execute_on_thread_async(ThreadFunc);
+  ASSERT_TRUE(ThreadStarted.wait());
+  ThreadAdvanced.notify();
+  ASSERT_TRUE(ThreadFinished.wait());
+}
+
+TEST(Threading, RunOnThreadSync) {
+  std::atomic_bool Executed(false);
+  llvm::llvm_execute_on_thread(
+      [](void *Arg) { *static_cast<std::atomic_bool *>(Arg) = true; },
+      &Executed);
+  ASSERT_EQ(Executed, true);
+}
+#endif
+
 } // end anon namespace
diff --git a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
index 967f6f6..e2656b2 100644
--- a/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TrailingObjectsTest.cpp
@@ -232,7 +232,7 @@
   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))));
+                reinterpret_cast<char *>(C + 1) + 1, Align::Of<long>())));
 }
 }
 
diff --git a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
index 9b10daa..42b3fcd 100644
--- a/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/TrigramIndexTest.cpp
@@ -22,7 +22,7 @@
   std::unique_ptr<TrigramIndex> makeTrigramIndex(
       std::vector<std::string> Rules) {
     std::unique_ptr<TrigramIndex> TI =
-        make_unique<TrigramIndex>();
+        std::make_unique<TrigramIndex>();
     for (auto &Rule : Rules)
       TI->insert(Rule);
     return TI;
diff --git a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
index a867bc5..d61652b 100644
--- a/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -41,7 +41,9 @@
 class DummyFileSystem : public vfs::FileSystem {
   int FSID;   // used to produce UniqueIDs
   int FileID; // used to produce UniqueIDs
+  std::string WorkingDirectory;
   std::map<std::string, vfs::Status> FilesAndDirs;
+  typedef std::map<std::string, vfs::Status>::const_iterator const_iterator;
 
   static int getNextFSID() {
     static int Count = 0;
@@ -52,8 +54,7 @@
   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());
+    auto I = findEntry(Path);
     if (I == FilesAndDirs.end())
       return make_error_code(llvm::errc::no_such_file_or_directory);
     return I->second;
@@ -66,15 +67,16 @@
     return S.getError();
   }
   llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
-    return std::string();
+    return WorkingDirectory;
   }
   std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
+    WorkingDirectory = Path.str();
     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());
+    auto I = findEntry(Path);
     if (I == FilesAndDirs.end())
       return make_error_code(llvm::errc::no_such_file_or_directory);
     if (I->second.isSymlink()) {
@@ -136,6 +138,15 @@
     FilesAndDirs[Path] = Status;
   }
 
+  const_iterator findEntry(const Twine &Path) const {
+    SmallString<128> P;
+    Path.toVector(P);
+    std::error_code EC = makeAbsolute(P);
+    assert(!EC);
+    (void)EC;
+    return FilesAndDirs.find(P.str());
+  }
+
   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,
@@ -158,6 +169,12 @@
   }
 };
 
+class ErrorDummyFileSystem : public DummyFileSystem {
+  std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
+    return llvm::errc::no_such_file_or_directory;
+  }
+};
+
 /// Replace back-slashes by front-slashes.
 std::string getPosixPath(std::string S) {
   SmallString<128> Result;
@@ -1994,3 +2011,181 @@
   EXPECT_EQ(FS->getRealPath("/non_existing", RealPath),
             errc::no_such_file_or_directory);
 }
+
+TEST_F(VFSFromYAMLTest, WorkingDirectory) {
+  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/bar',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'a',\n"
+      "                  'external-contents': '//root/foo/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+  std::error_code EC = FS->setCurrentWorkingDirectory("//root/bar");
+  ASSERT_FALSE(EC);
+
+  llvm::ErrorOr<std::string> WorkingDir = FS->getCurrentWorkingDirectory();
+  ASSERT_TRUE(WorkingDir);
+  EXPECT_EQ(*WorkingDir, "//root/bar");
+
+  llvm::ErrorOr<vfs::Status> Status = FS->status("./a");
+  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());
+
+  EC = FS->setCurrentWorkingDirectory("bogus");
+  ASSERT_TRUE(EC);
+  WorkingDir = FS->getCurrentWorkingDirectory();
+  ASSERT_TRUE(WorkingDir);
+  EXPECT_EQ(*WorkingDir, "//root/bar");
+
+  EC = FS->setCurrentWorkingDirectory("//root/");
+  ASSERT_FALSE(EC);
+  WorkingDir = FS->getCurrentWorkingDirectory();
+  ASSERT_TRUE(WorkingDir);
+  EXPECT_EQ(*WorkingDir, "//root/");
+
+  EC = FS->setCurrentWorkingDirectory("bar");
+  ASSERT_FALSE(EC);
+  WorkingDir = FS->getCurrentWorkingDirectory();
+  ASSERT_TRUE(WorkingDir);
+  EXPECT_EQ(*WorkingDir, "//root/bar");
+}
+
+TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthrough) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addDirectory("//root/foo");
+  Lower->addRegularFile("//root/foo/a");
+  Lower->addRegularFile("//root/foo/b");
+  Lower->addRegularFile("//root/c");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/bar',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'a',\n"
+      "                  'external-contents': '//root/foo/a'\n"
+      "                }\n"
+      "              ]\n"
+      "},\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/bar/baz',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'a',\n"
+      "                  'external-contents': '//root/foo/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+  std::error_code EC = FS->setCurrentWorkingDirectory("//root/");
+  ASSERT_FALSE(EC);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  llvm::ErrorOr<vfs::Status> Status = FS->status("bar/a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+  Status = FS->status("foo/a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+  EC = FS->setCurrentWorkingDirectory("//root/bar");
+  ASSERT_FALSE(EC);
+
+  Status = FS->status("./a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+  Status = FS->status("./b");
+  ASSERT_TRUE(Status.getError());
+
+  Status = FS->status("./c");
+  ASSERT_TRUE(Status.getError());
+
+  EC = FS->setCurrentWorkingDirectory("//root/");
+  ASSERT_FALSE(EC);
+
+  Status = FS->status("c");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+  Status = FS->status("./bar/baz/a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+  EC = FS->setCurrentWorkingDirectory("//root/bar");
+  ASSERT_FALSE(EC);
+
+  Status = FS->status("./baz/a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+#if !defined(_WIN32)
+  Status = FS->status("../bar/baz/a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+#endif
+}
+
+TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthroughInvalid) {
+  IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addDirectory("//root/foo");
+  Lower->addRegularFile("//root/foo/a");
+  Lower->addRegularFile("//root/foo/b");
+  Lower->addRegularFile("//root/c");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "{\n"
+      "  'type': 'directory',\n"
+      "  'name': '//root/bar',\n"
+      "  'contents': [ {\n"
+      "                  'type': 'file',\n"
+      "                  'name': 'a',\n"
+      "                  'external-contents': '//root/foo/a'\n"
+      "                }\n"
+      "              ]\n"
+      "}\n"
+      "]\n"
+      "}",
+      Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+  std::error_code EC = FS->setCurrentWorkingDirectory("//root/");
+  ASSERT_FALSE(EC);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  llvm::ErrorOr<vfs::Status> Status = FS->status("bar/a");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->exists());
+
+  Status = FS->status("foo/a");
+  ASSERT_TRUE(Status.getError());
+}
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
index e02f68f..df111e7 100644
--- a/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/YAMLIOTest.cpp
@@ -2189,7 +2189,6 @@
 //
 // Test error handling reading built-in Hex8 type
 //
-LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8)
 TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
   std::vector<Hex8> seq;
   Input yin("---\n"
@@ -2200,15 +2199,26 @@
             /*Ctxt=*/nullptr,
             suppressErrorMessages);
   yin >> seq;
-
   EXPECT_TRUE(!!yin.error());
+
+  std::vector<Hex8> seq2;
+  Input yin2("---\n"
+             "[ 0x12, 0xFE, 0x123 ]\n"
+             "...\n",
+             /*Ctxt=*/nullptr, suppressErrorMessages);
+  yin2 >> seq2;
+  EXPECT_TRUE(!!yin2.error());
+
+  EXPECT_TRUE(seq.size() == 3);
+  EXPECT_TRUE(seq.size() == seq2.size());
+  for (size_t i = 0; i < seq.size(); ++i)
+    EXPECT_TRUE(seq[i] == seq2[i]);
 }
 
 
 //
 // Test error handling reading built-in Hex16 type
 //
-LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16)
 TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
   std::vector<Hex16> seq;
   Input yin("---\n"
@@ -2219,14 +2229,25 @@
             /*Ctxt=*/nullptr,
             suppressErrorMessages);
   yin >> seq;
-
   EXPECT_TRUE(!!yin.error());
+
+  std::vector<Hex16> seq2;
+  Input yin2("---\n"
+             "[ 0x0012, 0xFEFF, 0x12345 ]\n"
+             "...\n",
+             /*Ctxt=*/nullptr, suppressErrorMessages);
+  yin2 >> seq2;
+  EXPECT_TRUE(!!yin2.error());
+
+  EXPECT_TRUE(seq.size() == 3);
+  EXPECT_TRUE(seq.size() == seq2.size());
+  for (size_t i = 0; i < seq.size(); ++i)
+    EXPECT_TRUE(seq[i] == seq2[i]);
 }
 
 //
 // Test error handling reading built-in Hex32 type
 //
-LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32)
 TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
   std::vector<Hex32> seq;
   Input yin("---\n"
@@ -2239,12 +2260,24 @@
   yin >> seq;
 
   EXPECT_TRUE(!!yin.error());
+
+  std::vector<Hex32> seq2;
+  Input yin2("---\n"
+             "[ 0x0012, 0xFEFF0000, 0x1234556789 ]\n"
+             "...\n",
+             /*Ctxt=*/nullptr, suppressErrorMessages);
+  yin2 >> seq2;
+  EXPECT_TRUE(!!yin2.error());
+
+  EXPECT_TRUE(seq.size() == 3);
+  EXPECT_TRUE(seq.size() == seq2.size());
+  for (size_t i = 0; i < seq.size(); ++i)
+    EXPECT_TRUE(seq[i] == seq2[i]);
 }
 
 //
 // Test error handling reading built-in Hex64 type
 //
-LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64)
 TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
   std::vector<Hex64> seq;
   Input yin("---\n"
@@ -2255,8 +2288,20 @@
             /*Ctxt=*/nullptr,
             suppressErrorMessages);
   yin >> seq;
-
   EXPECT_TRUE(!!yin.error());
+
+  std::vector<Hex64> seq2;
+  Input yin2("---\n"
+             "[ 0x0012, 0xFFEEDDCCBBAA9988, 0x12345567890ABCDEF0 ]\n"
+             "...\n",
+             /*Ctxt=*/nullptr, suppressErrorMessages);
+  yin2 >> seq2;
+  EXPECT_TRUE(!!yin2.error());
+
+  EXPECT_TRUE(seq.size() == 3);
+  EXPECT_TRUE(seq.size() == seq2.size());
+  for (size_t i = 0; i < seq.size(); ++i)
+    EXPECT_TRUE(seq[i] == seq2[i]);
 }
 
 TEST(YAMLIO, TestMalformedMapFailsGracefully) {
@@ -2841,19 +2886,19 @@
 
   static Scalar &getAsScalar(std::unique_ptr<Poly> &N) {
     if (!N || !isa<Scalar>(*N))
-      N = llvm::make_unique<Scalar>();
+      N = std::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>();
+      N = std::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>();
+      N = std::make_unique<Map>();
     return *cast<Map>(N.get());
   }
 };
@@ -2932,7 +2977,7 @@
 
 TEST(YAMLIO, TestReadWritePolymorphicScalar) {
   std::string intermediate;
-  std::unique_ptr<Poly> node = llvm::make_unique<Scalar>(true);
+  std::unique_ptr<Poly> node = std::make_unique<Scalar>(true);
 
   llvm::raw_string_ostream ostr(intermediate);
   Output yout(ostr);
@@ -2946,9 +2991,9 @@
 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 seq = std::make_unique<Seq>();
+    seq->push_back(std::make_unique<Scalar>(true));
+    seq->push_back(std::make_unique<Scalar>(1.0));
     auto node = llvm::unique_dyn_cast<Poly>(seq);
 
     llvm::raw_string_ostream ostr(intermediate);
@@ -2978,9 +3023,9 @@
 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);
+    auto map = std::make_unique<Map>();
+    (*map)["foo"] = std::make_unique<Scalar>(false);
+    (*map)["bar"] = std::make_unique<Scalar>(2.0);
     std::unique_ptr<Poly> node = llvm::unique_dyn_cast<Poly>(map);
 
     llvm::raw_string_ostream ostr(intermediate);
@@ -3005,3 +3050,55 @@
     EXPECT_EQ(bar->DoubleValue, 2.0);
   }
 }
+
+TEST(YAMLIO, TestAnchorMapError) {
+  Input yin("& & &: ");
+  yin.setCurrentDocument();
+  EXPECT_TRUE(yin.error());
+}
+
+TEST(YAMLIO, TestFlowSequenceTokenErrors) {
+  Input yin(",");
+  EXPECT_FALSE(yin.setCurrentDocument());
+  EXPECT_TRUE(yin.error());
+
+  Input yin2("]");
+  EXPECT_FALSE(yin2.setCurrentDocument());
+  EXPECT_TRUE(yin2.error());
+
+  Input yin3("}");
+  EXPECT_FALSE(yin3.setCurrentDocument());
+  EXPECT_TRUE(yin3.error());
+}
+
+TEST(YAMLIO, TestDirectiveMappingNoValue) {
+  Input yin("%YAML\n{5:");
+  EXPECT_FALSE(yin.setCurrentDocument());
+  EXPECT_TRUE(yin.error());
+
+  Input yin2("%TAG\n'\x98!< :\n");
+  yin2.setCurrentDocument();
+  EXPECT_TRUE(yin2.error());
+}
+
+TEST(YAMLIO, TestUnescapeInfiniteLoop) {
+  Input yin("\"\\u\\^#\\\\\"");
+  yin.setCurrentDocument();
+  EXPECT_TRUE(yin.error());
+}
+
+TEST(YAMLIO, TestScannerUnexpectedCharacter) {
+  Input yin("!<$\x9F.");
+  EXPECT_FALSE(yin.setCurrentDocument());
+  EXPECT_TRUE(yin.error());
+}
+
+TEST(YAMLIO, TestUnknownDirective) {
+  Input yin("%");
+  EXPECT_FALSE(yin.setCurrentDocument());
+  EXPECT_TRUE(yin.error());
+
+  Input yin2("%)");
+  EXPECT_FALSE(yin2.setCurrentDocument());
+  EXPECT_TRUE(yin2.error());
+}
diff --git a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
index 06d4b0e..938a6ab 100644
--- a/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
+++ b/src/llvm-project/llvm/unittests/Support/YAMLParserTest.cpp
@@ -331,4 +331,15 @@
   EXPECT_TRUE(End == AnotherEnd);
 }
 
+TEST(YAMLParser, FlowSequenceTokensOutsideFlowSequence) {
+  auto FlowSequenceStrs = {",", "]", "}"};
+  SourceMgr SM;
+
+  for (auto &Str : FlowSequenceStrs) {
+    yaml::Stream Stream(Str, SM);
+    yaml::Document &Doc = *Stream.begin();
+    EXPECT_FALSE(Doc.skip());
+  }
+}
+
 } // end namespace llvm
diff --git a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
index 4ce4917..0e56464 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_ostream_test.cpp
@@ -18,8 +18,7 @@
 
 template<typename T> std::string printToString(const T &Value) {
   std::string res;
-  llvm::raw_string_ostream(res) << Value;
-  return res;    
+  return (llvm::raw_string_ostream(res) << Value).str();
 }
 
 /// printToString - Print the given value to a stream which only has \arg
@@ -47,6 +46,10 @@
   return res;
 }
 
+struct X {};
+
+raw_ostream &operator<<(raw_ostream &OS, const X &) { return OS << 'X'; }
+
 TEST(raw_ostreamTest, Types_Buffered) {
   // Char
   EXPECT_EQ("c", printToString('c'));
@@ -76,6 +79,9 @@
   // Min and max.
   EXPECT_EQ("18446744073709551615", printToString(UINT64_MAX));
   EXPECT_EQ("-9223372036854775808", printToString(INT64_MIN));
+
+  // X, checking free operator<<().
+  EXPECT_EQ("X", printToString(X{}));
 }
 
 TEST(raw_ostreamTest, Types_Unbuffered) {  
@@ -107,6 +113,9 @@
   // Min and max.
   EXPECT_EQ("18446744073709551615", printToStringUnbuffered(UINT64_MAX));
   EXPECT_EQ("-9223372036854775808", printToStringUnbuffered(INT64_MIN));
+
+  // X, checking free operator<<().
+  EXPECT_EQ("X", printToString(X{}));
 }
 
 TEST(raw_ostreamTest, BufferEdge) {  
@@ -339,7 +348,7 @@
 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); }
+  { raw_fd_ostream("-", EC, sys::fs::OpenFlags::OF_None); }
+  { raw_fd_ostream("-", EC, sys::fs::OpenFlags::OF_None); }
 }
 }
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
index be03536..3238d0d 100644
--- a/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
+++ b/src/llvm-project/llvm/unittests/Support/raw_sha1_ostream_test.cpp
@@ -43,6 +43,22 @@
   ASSERT_EQ("2EF7BDE608CE5404E97D5F042F95F89F1C232871", Hash);
 }
 
+TEST(sha1_hash_test, Update) {
+  SHA1 sha1;
+  std::string Input = "123456789012345678901234567890";
+  ASSERT_EQ(Input.size(), 30UL);
+  // 3 short updates.
+  sha1.update(Input);
+  sha1.update(Input);
+  sha1.update(Input);
+  // Long update that gets into the optimized loop with prefix/suffix.
+  sha1.update(Input + Input + Input + Input);
+  // 18 bytes buffered now.
+
+  std::string Hash = toHex(sha1.final());
+  ASSERT_EQ("3E4A614101AD84985AB0FE54DC12A6D71551E5AE", Hash);
+}
+
 // Check that getting the intermediate hash in the middle of the stream does
 // not invalidate the final result.
 TEST(raw_sha1_ostreamTest, Intermediate) {