diff --git a/linux-x64/clang/include/llvm/ADT/APFloat.h b/linux-x64/clang/include/llvm/ADT/APFloat.h
index 6255823..a9648d3 100644
--- a/linux-x64/clang/include/llvm/ADT/APFloat.h
+++ b/linux-x64/clang/include/llvm/ADT/APFloat.h
@@ -147,6 +147,17 @@
 
   /// \name Floating Point Semantics.
   /// @{
+  enum Semantics {
+    S_IEEEhalf,
+    S_IEEEsingle,
+    S_IEEEdouble,
+    S_x87DoubleExtended,
+    S_IEEEquad,
+    S_PPCDoubleDouble
+  };
+
+  static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+  static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
 
   static const fltSemantics &IEEEhalf() LLVM_READNONE;
   static const fltSemantics &IEEEsingle() LLVM_READNONE;
diff --git a/linux-x64/clang/include/llvm/ADT/APInt.h b/linux-x64/clang/include/llvm/ADT/APInt.h
index 0f27dbf..2381b75 100644
--- a/linux-x64/clang/include/llvm/ADT/APInt.h
+++ b/linux-x64/clang/include/llvm/ADT/APInt.h
@@ -2212,6 +2212,15 @@
 // See friend declaration above. This additional declaration is required in
 // order to compile LLVM with IBM xlC compiler.
 hash_code hash_value(const APInt &Arg);
-} // End of llvm namespace
+
+/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
+/// with the integer held in IntVal.
+void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
+
+/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
+/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
+void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes);
+
+} // namespace llvm
 
 #endif
diff --git a/linux-x64/clang/include/llvm/ADT/APSInt.h b/linux-x64/clang/include/llvm/ADT/APSInt.h
index be36611..0f99182 100644
--- a/linux-x64/clang/include/llvm/ADT/APSInt.h
+++ b/linux-x64/clang/include/llvm/ADT/APSInt.h
@@ -42,6 +42,24 @@
   /// \param Str the string to be interpreted.
   explicit APSInt(StringRef Str);
 
+  /// Determine sign of this APSInt.
+  ///
+  /// \returns true if this APSInt is negative, false otherwise
+  bool isNegative() const { return isSigned() && APInt::isNegative(); }
+
+  /// Determine if this APSInt Value is non-negative (>= 0)
+  ///
+  /// \returns true if this APSInt is non-negative, false otherwise
+  bool isNonNegative() const { return !isNegative(); }
+
+  /// Determine if this APSInt Value is positive.
+  ///
+  /// This tests if the value of this APSInt is positive (> 0). Note
+  /// that 0 is not a positive value.
+  ///
+  /// \returns true if this APSInt is positive.
+  bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
+
   APSInt &operator=(APInt RHS) {
     // Retain our current sign.
     APInt::operator=(std::move(RHS));
diff --git a/linux-x64/clang/include/llvm/ADT/ArrayRef.h b/linux-x64/clang/include/llvm/ADT/ArrayRef.h
index 75bb7d6..773c88f 100644
--- a/linux-x64/clang/include/llvm/ADT/ArrayRef.h
+++ b/linux-x64/clang/include/llvm/ADT/ArrayRef.h
@@ -430,7 +430,7 @@
       std::copy(Data.begin(), Data.end(), this->begin());
     }
 
-    OwningArrayRef(OwningArrayRef &&Other) { *this = Other; }
+    OwningArrayRef(OwningArrayRef &&Other) { *this = std::move(Other); }
 
     OwningArrayRef &operator=(OwningArrayRef &&Other) {
       delete[] this->data();
diff --git a/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h b/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h
index cc6c860..e97d766 100644
--- a/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h
+++ b/linux-x64/clang/include/llvm/ADT/BreadthFirstIterator.h
@@ -124,7 +124,7 @@
 
   const NodeRef &operator*() const { return VisitQueue.front()->first; }
 
-  // This is a nonstandard operator-> that dereferenfces the pointer an extra
+  // This is a nonstandard operator-> that dereferences the pointer an extra
   // time so that you can actually call methods on the node, because the
   // contained type is a pointer.
   NodeRef operator->() const { return **this; }
diff --git a/linux-x64/clang/include/llvm/ADT/DenseMap.h b/linux-x64/clang/include/llvm/ADT/DenseMap.h
index e7cd370..a05cf81 100644
--- a/linux-x64/clang/include/llvm/ADT/DenseMap.h
+++ b/linux-x64/clang/include/llvm/ADT/DenseMap.h
@@ -63,7 +63,7 @@
   template <typename AltPairT>
   DenseMapPair(AltPairT &&AltPair,
                typename std::enable_if<std::is_convertible<
-                   AltPairT, std::pair<KeyT, ValueT>>::value>::type * = 0)
+                   AltPairT, std::pair<KeyT, ValueT>>::value>::type * = nullptr)
       : std::pair<KeyT, ValueT>(std::forward<AltPairT>(AltPair)) {}
 
   KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
diff --git a/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h b/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h
index 18d6dff..5ef6f3a 100644
--- a/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h
+++ b/linux-x64/clang/include/llvm/ADT/DenseMapInfo.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/ScalableSize.h"
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
@@ -268,6 +269,21 @@
   static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
 };
 
+template <> struct DenseMapInfo<ElementCount> {
+  static inline ElementCount getEmptyKey() { return {~0U, true}; }
+  static inline ElementCount getTombstoneKey() { return {~0U - 1, false}; }
+  static unsigned getHashValue(const ElementCount& EltCnt) {
+    if (EltCnt.Scalable)
+      return (EltCnt.Min * 37U) - 1U;
+
+    return EltCnt.Min * 37U;
+  }
+
+  static bool isEqual(const ElementCount& LHS, const ElementCount& RHS) {
+    return LHS == RHS;
+  }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_ADT_DENSEMAPINFO_H
diff --git a/linux-x64/clang/include/llvm/ADT/DenseSet.h b/linux-x64/clang/include/llvm/ADT/DenseSet.h
index 5eaaf27..9afb715 100644
--- a/linux-x64/clang/include/llvm/ADT/DenseSet.h
+++ b/linux-x64/clang/include/llvm/ADT/DenseSet.h
@@ -130,7 +130,7 @@
 
   class ConstIterator {
     typename MapTy::const_iterator I;
-    friend class DenseSet;
+    friend class DenseSetImpl;
     friend class Iterator;
 
   public:
diff --git a/linux-x64/clang/include/llvm/ADT/Optional.h b/linux-x64/clang/include/llvm/ADT/Optional.h
index 25a3185..b45a740 100644
--- a/linux-x64/clang/include/llvm/ADT/Optional.h
+++ b/linux-x64/clang/include/llvm/ADT/Optional.h
@@ -16,11 +16,10 @@
 #define LLVM_ADT_OPTIONAL_H
 
 #include "llvm/ADT/None.h"
-#include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/type_traits.h"
-#include <algorithm>
 #include <cassert>
+#include <memory>
 #include <new>
 #include <utility>
 
@@ -29,83 +28,185 @@
 class raw_ostream;
 
 namespace optional_detail {
+
+struct in_place_t {};
+
 /// Storage for any type.
-template <typename T, bool = is_trivially_copyable<T>::value> struct OptionalStorage {
-  AlignedCharArrayUnion<T> storage;
-  bool hasVal = false;
+template <typename T, bool = is_trivially_copyable<T>::value>
+class OptionalStorage {
+  union {
+    char empty;
+    T value;
+  };
+  bool hasVal;
 
-  OptionalStorage() = default;
-
-  OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
-  OptionalStorage(const OptionalStorage &O) : hasVal(O.hasVal) {
-    if (hasVal)
-      new (storage.buffer) T(*O.getPointer());
-  }
-  OptionalStorage(T &&y) : hasVal(true) {
-    new (storage.buffer) T(std::forward<T>(y));
-  }
-  OptionalStorage(OptionalStorage &&O) : hasVal(O.hasVal) {
-    if (O.hasVal) {
-      new (storage.buffer) T(std::move(*O.getPointer()));
-    }
-  }
-
-  OptionalStorage &operator=(T &&y) {
-    if (hasVal)
-      *getPointer() = std::move(y);
-    else {
-      new (storage.buffer) T(std::move(y));
-      hasVal = true;
-    }
-    return *this;
-  }
-  OptionalStorage &operator=(OptionalStorage &&O) {
-    if (!O.hasVal)
-      reset();
-    else {
-      *this = std::move(*O.getPointer());
-    }
-    return *this;
-  }
-
-  // FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
-  // could be made more efficient by passing by value, possibly unifying them
-  // with the rvalue versions above - but this could place a different set of
-  // requirements (notably: the existence of a default ctor) when implemented
-  // in that way. Careful SFINAE to avoid such pitfalls would be required.
-  OptionalStorage &operator=(const T &y) {
-    if (hasVal)
-      *getPointer() = y;
-    else {
-      new (storage.buffer) T(y);
-      hasVal = true;
-    }
-    return *this;
-  }
-  OptionalStorage &operator=(const OptionalStorage &O) {
-    if (!O.hasVal)
-      reset();
-    else
-      *this = *O.getPointer();
-    return *this;
-  }
-
+public:
   ~OptionalStorage() { reset(); }
 
-  void reset() {
+  OptionalStorage() noexcept : empty(), hasVal(false) {}
+
+  OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
+    if (other.hasValue()) {
+      emplace(other.value);
+    }
+  }
+  OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
+    if (other.hasValue()) {
+      emplace(std::move(other.value));
+    }
+  }
+
+  template <class... Args>
+  explicit OptionalStorage(in_place_t, Args &&... args)
+      : value(std::forward<Args>(args)...), hasVal(true) {}
+
+  void reset() noexcept {
     if (hasVal) {
-      (*getPointer()).~T();
+      value.~T();
       hasVal = false;
     }
   }
 
-  T *getPointer() {
+  bool hasValue() const noexcept { return hasVal; }
+
+  T &getValue() LLVM_LVALUE_FUNCTION noexcept {
     assert(hasVal);
-    return reinterpret_cast<T *>(storage.buffer);
+    return value;
   }
-  const T *getPointer() const {
+  T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
     assert(hasVal);
-    return reinterpret_cast<const T *>(storage.buffer);
+    return value;
+  }
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  T &&getValue() && noexcept {
+    assert(hasVal);
+    return std::move(value);
+  }
+#endif
+
+  template <class... Args> void emplace(Args &&... args) {
+    reset();
+    ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
+    hasVal = true;
+  }
+
+  OptionalStorage &operator=(T const &y) {
+    if (hasValue()) {
+      value = y;
+    } else {
+      ::new ((void *)std::addressof(value)) T(y);
+      hasVal = true;
+    }
+    return *this;
+  }
+  OptionalStorage &operator=(T &&y) {
+    if (hasValue()) {
+      value = std::move(y);
+    } else {
+      ::new ((void *)std::addressof(value)) T(std::move(y));
+      hasVal = true;
+    }
+    return *this;
+  }
+
+  OptionalStorage &operator=(OptionalStorage const &other) {
+    if (other.hasValue()) {
+      if (hasValue()) {
+        value = other.value;
+      } else {
+        ::new ((void *)std::addressof(value)) T(other.value);
+        hasVal = true;
+      }
+    } else {
+      reset();
+    }
+    return *this;
+  }
+
+  OptionalStorage &operator=(OptionalStorage &&other) {
+    if (other.hasValue()) {
+      if (hasValue()) {
+        value = std::move(other.value);
+      } else {
+        ::new ((void *)std::addressof(value)) T(std::move(other.value));
+        hasVal = true;
+      }
+    } else {
+      reset();
+    }
+    return *this;
+  }
+};
+
+template <typename T> class OptionalStorage<T, true> {
+  union {
+    char empty;
+    T value;
+  };
+  bool hasVal = false;
+
+public:
+  ~OptionalStorage() = default;
+
+  OptionalStorage() noexcept : empty{} {}
+
+  OptionalStorage(OptionalStorage const &other) = default;
+  OptionalStorage(OptionalStorage &&other) = default;
+
+  OptionalStorage &operator=(OptionalStorage const &other) = default;
+  OptionalStorage &operator=(OptionalStorage &&other) = default;
+
+  template <class... Args>
+  explicit OptionalStorage(in_place_t, Args &&... args)
+      : value(std::forward<Args>(args)...), hasVal(true) {}
+
+  void reset() noexcept {
+    if (hasVal) {
+      value.~T();
+      hasVal = false;
+    }
+  }
+
+  bool hasValue() const noexcept { return hasVal; }
+
+  T &getValue() LLVM_LVALUE_FUNCTION noexcept {
+    assert(hasVal);
+    return value;
+  }
+  T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
+    assert(hasVal);
+    return value;
+  }
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+  T &&getValue() && noexcept {
+    assert(hasVal);
+    return std::move(value);
+  }
+#endif
+
+  template <class... Args> void emplace(Args &&... args) {
+    reset();
+    ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...);
+    hasVal = true;
+  }
+
+  OptionalStorage &operator=(T const &y) {
+    if (hasValue()) {
+      value = y;
+    } else {
+      ::new ((void *)std::addressof(value)) T(y);
+      hasVal = true;
+    }
+    return *this;
+  }
+  OptionalStorage &operator=(T &&y) {
+    if (hasValue()) {
+      value = std::move(y);
+    } else {
+      ::new ((void *)std::addressof(value)) T(std::move(y));
+      hasVal = true;
+    }
+    return *this;
   }
 };
 
@@ -120,10 +221,10 @@
   constexpr Optional() {}
   constexpr Optional(NoneType) {}
 
-  Optional(const T &y) : Storage(y) {}
+  Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {}
   Optional(const Optional &O) = default;
 
-  Optional(T &&y) : Storage(std::forward<T>(y)) {}
+  Optional(T &&y) : Storage(optional_detail::in_place_t{}, std::move(y)) {}
   Optional(Optional &&O) = default;
 
   Optional &operator=(T &&y) {
@@ -134,9 +235,7 @@
 
   /// Create a new object by constructing it in place with the given arguments.
   template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
-    reset();
-    Storage.hasVal = true;
-    new (getPointer()) T(std::forward<ArgTypes>(Args)...);
+    Storage.emplace(std::forward<ArgTypes>(Args)...);
   }
 
   static inline Optional create(const T *y) {
@@ -151,23 +250,17 @@
 
   void reset() { Storage.reset(); }
 
-  const T *getPointer() const {
-    assert(Storage.hasVal);
-    return reinterpret_cast<const T *>(Storage.storage.buffer);
-  }
-  T *getPointer() {
-    assert(Storage.hasVal);
-    return reinterpret_cast<T *>(Storage.storage.buffer);
-  }
-  const T &getValue() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
-  T &getValue() LLVM_LVALUE_FUNCTION { return *getPointer(); }
+  const T *getPointer() const { return &Storage.getValue(); }
+  T *getPointer() { return &Storage.getValue(); }
+  const T &getValue() const LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
+  T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
 
-  explicit operator bool() const { return Storage.hasVal; }
-  bool hasValue() const { return Storage.hasVal; }
+  explicit operator bool() const { return hasValue(); }
+  bool hasValue() const { return Storage.hasValue(); }
   const T *operator->() const { return getPointer(); }
   T *operator->() { return getPointer(); }
-  const T &operator*() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
-  T &operator*() LLVM_LVALUE_FUNCTION { return *getPointer(); }
+  const T &operator*() const LLVM_LVALUE_FUNCTION { return getValue(); }
+  T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); }
 
   template <typename U>
   constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
@@ -175,8 +268,8 @@
   }
 
 #if LLVM_HAS_RVALUE_REFERENCE_THIS
-  T &&getValue() && { return std::move(*getPointer()); }
-  T &&operator*() && { return std::move(*getPointer()); }
+  T &&getValue() && { return std::move(Storage.getValue()); }
+  T &&operator*() && { return std::move(Storage.getValue()); }
 
   template <typename U>
   T getValueOr(U &&value) && {
diff --git a/linux-x64/clang/include/llvm/ADT/PointerUnion.h b/linux-x64/clang/include/llvm/ADT/PointerUnion.h
index 0605429..2bcdf54 100644
--- a/linux-x64/clang/include/llvm/ADT/PointerUnion.h
+++ b/linux-x64/clang/include/llvm/ADT/PointerUnion.h
@@ -53,22 +53,98 @@
       typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return;
 };
 
-/// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
-/// for the two template arguments.
-template <typename PT1, typename PT2> class PointerUnionUIntTraits {
-public:
-  static inline void *getAsVoidPointer(void *P) { return P; }
-  static inline void *getFromVoidPointer(void *P) { return P; }
+namespace pointer_union_detail {
+  constexpr int constexprMin(int a, int b) { return a < b ? a : b; }
+  /// Determine the number of bits required to store integers with values < n.
+  /// This is ceil(log2(n)).
+  constexpr int bitsRequired(unsigned n) {
+    return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0;
+  }
 
-  enum {
-    PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
-    PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
-    NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
+  // FIXME: In C++14, replace this with
+  //   std::min({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...})
+  template <typename T> constexpr int lowBitsAvailable() {
+    return PointerLikeTypeTraits<T>::NumLowBitsAvailable;
+  }
+  template <typename T1, typename T2, typename... Ts>
+  constexpr int lowBitsAvailable() {
+    return constexprMin(lowBitsAvailable<T1>(), lowBitsAvailable<T2, Ts...>());
+  }
+
+  /// Find the index of a type in a list of types. TypeIndex<T, Us...>::Index
+  /// is the index of T in Us, or sizeof...(Us) if T does not appear in the
+  /// list.
+  template <typename T, typename ...Us> struct TypeIndex;
+  template <typename T, typename ...Us> struct TypeIndex<T, T, Us...> {
+    static constexpr int Index = 0;
   };
-};
+  template <typename T, typename U, typename... Us>
+  struct TypeIndex<T, U, Us...> {
+    static constexpr int Index = 1 + TypeIndex<T, Us...>::Index;
+  };
+  template <typename T> struct TypeIndex<T> {
+    static constexpr int Index = 0;
+  };
 
-/// A discriminated union of two pointer types, with the discriminator in the
-/// low bit of the pointer.
+  /// Find the first type in a list of types.
+  template <typename T, typename...> struct GetFirstType {
+    using type = T;
+  };
+
+  /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
+  /// for the template arguments.
+  template <typename ...PTs> class PointerUnionUIntTraits {
+  public:
+    static inline void *getAsVoidPointer(void *P) { return P; }
+    static inline void *getFromVoidPointer(void *P) { return P; }
+    static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>();
+  };
+
+  /// Implement assigment in terms of construction.
+  template <typename Derived, typename T> struct AssignableFrom {
+    Derived &operator=(T t) {
+      return static_cast<Derived &>(*this) = Derived(t);
+    }
+  };
+
+  template <typename Derived, typename ValTy, int I, typename ...Types>
+  class PointerUnionMembers;
+
+  template <typename Derived, typename ValTy, int I>
+  class PointerUnionMembers<Derived, ValTy, I> {
+  protected:
+    ValTy Val;
+    PointerUnionMembers() = default;
+    PointerUnionMembers(ValTy Val) : Val(Val) {}
+
+    friend struct PointerLikeTypeTraits<Derived>;
+  };
+
+  template <typename Derived, typename ValTy, int I, typename Type,
+            typename ...Types>
+  class PointerUnionMembers<Derived, ValTy, I, Type, Types...>
+      : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> {
+    using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>;
+  public:
+    using Base::Base;
+    PointerUnionMembers() = default;
+    PointerUnionMembers(Type V)
+        : Base(ValTy(const_cast<void *>(
+                         PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
+                     I)) {}
+
+    using Base::operator=;
+    Derived &operator=(Type V) {
+      this->Val = ValTy(
+          const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
+          I);
+      return static_cast<Derived &>(*this);
+    };
+  };
+}
+
+/// A discriminated union of two or more pointer types, with the discriminator
+/// in the low bit of the pointer.
 ///
 /// This implementation is extremely efficient in space due to leveraging the
 /// low bits of the pointer, while exposing a natural and type-safe API.
@@ -83,49 +159,44 @@
 ///    P = (float*)0;
 ///    Y = P.get<float*>();   // ok.
 ///    X = P.get<int*>();     // runtime assertion failure.
-template <typename PT1, typename PT2> class PointerUnion {
-public:
-  using ValTy =
-      PointerIntPair<void *, 1, bool, PointerUnionUIntTraits<PT1, PT2>>;
-
-private:
-  ValTy Val;
-
-  struct IsPT1 {
-    static const int Num = 0;
-  };
-  struct IsPT2 {
-    static const int Num = 1;
-  };
-  template <typename T> struct UNION_DOESNT_CONTAIN_TYPE {};
+template <typename... PTs>
+class PointerUnion
+    : public pointer_union_detail::PointerUnionMembers<
+          PointerUnion<PTs...>,
+          PointerIntPair<
+              void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int,
+              pointer_union_detail::PointerUnionUIntTraits<PTs...>>,
+          0, PTs...> {
+  // The first type is special in some ways, but we don't want PointerUnion to
+  // be a 'template <typename First, typename ...Rest>' because it's much more
+  // convenient to have a name for the whole pack. So split off the first type
+  // here.
+  using First = typename pointer_union_detail::GetFirstType<PTs...>::type;
+  using Base = typename PointerUnion::PointerUnionMembers;
 
 public:
   PointerUnion() = default;
-  PointerUnion(PT1 V)
-      : Val(const_cast<void *>(
-            PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {}
-  PointerUnion(PT2 V)
-      : Val(const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)),
-            1) {}
+
+  PointerUnion(std::nullptr_t) : PointerUnion() {}
+  using Base::Base;
 
   /// Test if the pointer held in the union is null, regardless of
   /// which type it is.
   bool isNull() const {
     // Convert from the void* to one of the pointer types, to make sure that
     // we recursively strip off low bits if we have a nested PointerUnion.
-    return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer());
+    return !PointerLikeTypeTraits<First>::getFromVoidPointer(
+        this->Val.getPointer());
   }
 
   explicit operator bool() const { return !isNull(); }
 
   /// Test if the Union currently holds the type matching T.
   template <typename T> int is() const {
-    using Ty = typename ::llvm::PointerUnionTypeSelector<
-        PT1, T, IsPT1,
-        ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
-                                         UNION_DOESNT_CONTAIN_TYPE<T>>>::Return;
-    int TyNo = Ty::Num;
-    return static_cast<int>(Val.getInt()) == TyNo;
+    constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index;
+    static_assert(Index < sizeof...(PTs),
+                  "PointerUnion::is<T> given type not in the union");
+    return this->Val.getInt() == Index;
   }
 
   /// Returns the value of the specified pointer type.
@@ -133,7 +204,7 @@
   /// If the specified pointer type is incorrect, assert.
   template <typename T> T get() const {
     assert(is<T>() && "Invalid accessor called");
-    return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
+    return PointerLikeTypeTraits<T>::getFromVoidPointer(this->Val.getPointer());
   }
 
   /// Returns the current pointer if it is of the specified pointer type,
@@ -146,342 +217,100 @@
 
   /// If the union is set to the first pointer type get an address pointing to
   /// it.
-  PT1 const *getAddrOfPtr1() const {
+  First const *getAddrOfPtr1() const {
     return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
   }
 
   /// If the union is set to the first pointer type get an address pointing to
   /// it.
-  PT1 *getAddrOfPtr1() {
-    assert(is<PT1>() && "Val is not the first pointer");
+  First *getAddrOfPtr1() {
+    assert(is<First>() && "Val is not the first pointer");
     assert(
-        get<PT1>() == Val.getPointer() &&
+        get<First>() == this->Val.getPointer() &&
         "Can't get the address because PointerLikeTypeTraits changes the ptr");
-    return const_cast<PT1 *>(
-        reinterpret_cast<const PT1 *>(Val.getAddrOfPointer()));
+    return const_cast<First *>(
+        reinterpret_cast<const First *>(this->Val.getAddrOfPointer()));
   }
 
   /// Assignment from nullptr which just clears the union.
   const PointerUnion &operator=(std::nullptr_t) {
-    Val.initWithPointer(nullptr);
+    this->Val.initWithPointer(nullptr);
     return *this;
   }
 
-  /// Assignment operators - Allow assigning into this union from either
-  /// pointer type, setting the discriminator to remember what it came from.
-  const PointerUnion &operator=(const PT1 &RHS) {
-    Val.initWithPointer(
-        const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
-    return *this;
-  }
-  const PointerUnion &operator=(const PT2 &RHS) {
-    Val.setPointerAndInt(
-        const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
-        1);
-    return *this;
-  }
+  /// Assignment from elements of the union.
+  using Base::operator=;
 
-  void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+  void *getOpaqueValue() const { return this->Val.getOpaqueValue(); }
   static inline PointerUnion getFromOpaqueValue(void *VP) {
     PointerUnion V;
-    V.Val = ValTy::getFromOpaqueValue(VP);
+    V.Val = decltype(V.Val)::getFromOpaqueValue(VP);
     return V;
   }
 };
 
-template <typename PT1, typename PT2>
-bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+template <typename ...PTs>
+bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
   return lhs.getOpaqueValue() == rhs.getOpaqueValue();
 }
 
-template <typename PT1, typename PT2>
-bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+template <typename ...PTs>
+bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
   return lhs.getOpaqueValue() != rhs.getOpaqueValue();
 }
 
-template <typename PT1, typename PT2>
-bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+template <typename ...PTs>
+bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
   return lhs.getOpaqueValue() < rhs.getOpaqueValue();
 }
 
 // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
 // # low bits available = min(PT1bits,PT2bits)-1.
-template <typename PT1, typename PT2>
-struct PointerLikeTypeTraits<PointerUnion<PT1, PT2>> {
-  static inline void *getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
+template <typename ...PTs>
+struct PointerLikeTypeTraits<PointerUnion<PTs...>> {
+  static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) {
     return P.getOpaqueValue();
   }
 
-  static inline PointerUnion<PT1, PT2> getFromVoidPointer(void *P) {
-    return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+  static inline PointerUnion<PTs...> getFromVoidPointer(void *P) {
+    return PointerUnion<PTs...>::getFromOpaqueValue(P);
   }
 
-  // The number of bits available are the min of the two pointer types.
-  enum {
-    NumLowBitsAvailable = PointerLikeTypeTraits<
-        typename PointerUnion<PT1, PT2>::ValTy>::NumLowBitsAvailable
-  };
+  // The number of bits available are the min of the pointer types minus the
+  // bits needed for the discriminator.
+  static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype(
+      PointerUnion<PTs...>::Val)>::NumLowBitsAvailable;
 };
 
 /// A pointer union of three pointer types. See documentation for PointerUnion
 /// for usage.
-template <typename PT1, typename PT2, typename PT3> class PointerUnion3 {
-public:
-  using InnerUnion = PointerUnion<PT1, PT2>;
-  using ValTy = PointerUnion<InnerUnion, PT3>;
-
-private:
-  ValTy Val;
-
-  struct IsInnerUnion {
-    ValTy Val;
-
-    IsInnerUnion(ValTy val) : Val(val) {}
-
-    template <typename T> int is() const {
-      return Val.template is<InnerUnion>() &&
-             Val.template get<InnerUnion>().template is<T>();
-    }
-
-    template <typename T> T get() const {
-      return Val.template get<InnerUnion>().template get<T>();
-    }
-  };
-
-  struct IsPT3 {
-    ValTy Val;
-
-    IsPT3(ValTy val) : Val(val) {}
-
-    template <typename T> int is() const { return Val.template is<T>(); }
-    template <typename T> T get() const { return Val.template get<T>(); }
-  };
-
-public:
-  PointerUnion3() = default;
-  PointerUnion3(PT1 V) { Val = InnerUnion(V); }
-  PointerUnion3(PT2 V) { Val = InnerUnion(V); }
-  PointerUnion3(PT3 V) { Val = V; }
-
-  /// Test if the pointer held in the union is null, regardless of
-  /// which type it is.
-  bool isNull() const { return Val.isNull(); }
-  explicit operator bool() const { return !isNull(); }
-
-  /// Test if the Union currently holds the type matching T.
-  template <typename T> int is() const {
-    // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
-    using Ty = typename ::llvm::PointerUnionTypeSelector<
-        PT1, T, IsInnerUnion,
-        ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return;
-    return Ty(Val).template is<T>();
-  }
-
-  /// Returns the value of the specified pointer type.
-  ///
-  /// If the specified pointer type is incorrect, assert.
-  template <typename T> T get() const {
-    assert(is<T>() && "Invalid accessor called");
-    // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
-    using Ty = typename ::llvm::PointerUnionTypeSelector<
-        PT1, T, IsInnerUnion,
-        ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return;
-    return Ty(Val).template get<T>();
-  }
-
-  /// Returns the current pointer if it is of the specified pointer type,
-  /// otherwises returns null.
-  template <typename T> T dyn_cast() const {
-    if (is<T>())
-      return get<T>();
-    return T();
-  }
-
-  /// Assignment from nullptr which just clears the union.
-  const PointerUnion3 &operator=(std::nullptr_t) {
-    Val = nullptr;
-    return *this;
-  }
-
-  /// Assignment operators - Allow assigning into this union from either
-  /// pointer type, setting the discriminator to remember what it came from.
-  const PointerUnion3 &operator=(const PT1 &RHS) {
-    Val = InnerUnion(RHS);
-    return *this;
-  }
-  const PointerUnion3 &operator=(const PT2 &RHS) {
-    Val = InnerUnion(RHS);
-    return *this;
-  }
-  const PointerUnion3 &operator=(const PT3 &RHS) {
-    Val = RHS;
-    return *this;
-  }
-
-  void *getOpaqueValue() const { return Val.getOpaqueValue(); }
-  static inline PointerUnion3 getFromOpaqueValue(void *VP) {
-    PointerUnion3 V;
-    V.Val = ValTy::getFromOpaqueValue(VP);
-    return V;
-  }
-};
-
-// Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
-// # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
 template <typename PT1, typename PT2, typename PT3>
-struct PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> {
-  static inline void *getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
-    return P.getOpaqueValue();
-  }
-
-  static inline PointerUnion3<PT1, PT2, PT3> getFromVoidPointer(void *P) {
-    return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
-  }
-
-  // The number of bits available are the min of the two pointer types.
-  enum {
-    NumLowBitsAvailable = PointerLikeTypeTraits<
-        typename PointerUnion3<PT1, PT2, PT3>::ValTy>::NumLowBitsAvailable
-  };
-};
-
-template <typename PT1, typename PT2, typename PT3>
-bool operator<(PointerUnion3<PT1, PT2, PT3> lhs,
-               PointerUnion3<PT1, PT2, PT3> rhs) {
-  return lhs.getOpaqueValue() < rhs.getOpaqueValue();
-}
+using PointerUnion3 = PointerUnion<PT1, PT2, PT3>;
 
 /// A pointer union of four pointer types. See documentation for PointerUnion
 /// for usage.
 template <typename PT1, typename PT2, typename PT3, typename PT4>
-class PointerUnion4 {
-public:
-  using InnerUnion1 = PointerUnion<PT1, PT2>;
-  using InnerUnion2 = PointerUnion<PT3, PT4>;
-  using ValTy = PointerUnion<InnerUnion1, InnerUnion2>;
-
-private:
-  ValTy Val;
-
-public:
-  PointerUnion4() = default;
-  PointerUnion4(PT1 V) { Val = InnerUnion1(V); }
-  PointerUnion4(PT2 V) { Val = InnerUnion1(V); }
-  PointerUnion4(PT3 V) { Val = InnerUnion2(V); }
-  PointerUnion4(PT4 V) { Val = InnerUnion2(V); }
-
-  /// Test if the pointer held in the union is null, regardless of
-  /// which type it is.
-  bool isNull() const { return Val.isNull(); }
-  explicit operator bool() const { return !isNull(); }
-
-  /// Test if the Union currently holds the type matching T.
-  template <typename T> int is() const {
-    // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
-    using Ty = typename ::llvm::PointerUnionTypeSelector<
-        PT1, T, InnerUnion1,
-        ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1,
-                                         InnerUnion2>>::Return;
-    return Val.template is<Ty>() && Val.template get<Ty>().template is<T>();
-  }
-
-  /// Returns the value of the specified pointer type.
-  ///
-  /// If the specified pointer type is incorrect, assert.
-  template <typename T> T get() const {
-    assert(is<T>() && "Invalid accessor called");
-    // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
-    using Ty = typename ::llvm::PointerUnionTypeSelector<
-        PT1, T, InnerUnion1,
-        ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1,
-                                         InnerUnion2>>::Return;
-    return Val.template get<Ty>().template get<T>();
-  }
-
-  /// Returns the current pointer if it is of the specified pointer type,
-  /// otherwises returns null.
-  template <typename T> T dyn_cast() const {
-    if (is<T>())
-      return get<T>();
-    return T();
-  }
-
-  /// Assignment from nullptr which just clears the union.
-  const PointerUnion4 &operator=(std::nullptr_t) {
-    Val = nullptr;
-    return *this;
-  }
-
-  /// Assignment operators - Allow assigning into this union from either
-  /// pointer type, setting the discriminator to remember what it came from.
-  const PointerUnion4 &operator=(const PT1 &RHS) {
-    Val = InnerUnion1(RHS);
-    return *this;
-  }
-  const PointerUnion4 &operator=(const PT2 &RHS) {
-    Val = InnerUnion1(RHS);
-    return *this;
-  }
-  const PointerUnion4 &operator=(const PT3 &RHS) {
-    Val = InnerUnion2(RHS);
-    return *this;
-  }
-  const PointerUnion4 &operator=(const PT4 &RHS) {
-    Val = InnerUnion2(RHS);
-    return *this;
-  }
-
-  void *getOpaqueValue() const { return Val.getOpaqueValue(); }
-  static inline PointerUnion4 getFromOpaqueValue(void *VP) {
-    PointerUnion4 V;
-    V.Val = ValTy::getFromOpaqueValue(VP);
-    return V;
-  }
-};
-
-// Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
-// # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
-template <typename PT1, typename PT2, typename PT3, typename PT4>
-struct PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4>> {
-  static inline void *
-  getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
-    return P.getOpaqueValue();
-  }
-
-  static inline PointerUnion4<PT1, PT2, PT3, PT4> getFromVoidPointer(void *P) {
-    return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
-  }
-
-  // The number of bits available are the min of the two pointer types.
-  enum {
-    NumLowBitsAvailable = PointerLikeTypeTraits<
-        typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>::NumLowBitsAvailable
-  };
-};
+using PointerUnion4 = PointerUnion<PT1, PT2, PT3, PT4>;
 
 // Teach DenseMap how to use PointerUnions as keys.
-template <typename T, typename U> struct DenseMapInfo<PointerUnion<T, U>> {
-  using Pair = PointerUnion<T, U>;
-  using FirstInfo = DenseMapInfo<T>;
-  using SecondInfo = DenseMapInfo<U>;
+template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> {
+  using Union = PointerUnion<PTs...>;
+  using FirstInfo =
+      DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>;
 
-  static inline Pair getEmptyKey() { return Pair(FirstInfo::getEmptyKey()); }
+  static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); }
 
-  static inline Pair getTombstoneKey() {
-    return Pair(FirstInfo::getTombstoneKey());
+  static inline Union getTombstoneKey() {
+    return Union(FirstInfo::getTombstoneKey());
   }
 
-  static unsigned getHashValue(const Pair &PairVal) {
-    intptr_t key = (intptr_t)PairVal.getOpaqueValue();
+  static unsigned getHashValue(const Union &UnionVal) {
+    intptr_t key = (intptr_t)UnionVal.getOpaqueValue();
     return DenseMapInfo<intptr_t>::getHashValue(key);
   }
 
-  static bool isEqual(const Pair &LHS, const Pair &RHS) {
-    return LHS.template is<T>() == RHS.template is<T>() &&
-           (LHS.template is<T>() ? FirstInfo::isEqual(LHS.template get<T>(),
-                                                      RHS.template get<T>())
-                                 : SecondInfo::isEqual(LHS.template get<U>(),
-                                                       RHS.template get<U>()));
+  static bool isEqual(const Union &LHS, const Union &RHS) {
+    return LHS == RHS;
   }
 };
 
diff --git a/linux-x64/clang/include/llvm/ADT/STLExtras.h b/linux-x64/clang/include/llvm/ADT/STLExtras.h
index 9a891d1..81dce01 100644
--- a/linux-x64/clang/include/llvm/ADT/STLExtras.h
+++ b/linux-x64/clang/include/llvm/ADT/STLExtras.h
@@ -240,6 +240,13 @@
   return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F));
 }
 
+template <class ContainerTy, class FuncTy>
+auto map_range(ContainerTy &&C, FuncTy F)
+    -> decltype(make_range(map_iterator(C.begin(), F),
+                           map_iterator(C.end(), F))) {
+  return make_range(map_iterator(C.begin(), F), map_iterator(C.end(), F));
+}
+
 /// Helper to determine if type T has a member called rbegin().
 template <typename Ty> class has_rbegin_impl {
   using yes = char[1];
@@ -1277,29 +1284,52 @@
 
 /// Provide wrappers to std::lower_bound which take ranges instead of having to
 /// pass begin/end explicitly.
-template <typename R, typename ForwardIt>
-auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
-  return std::lower_bound(adl_begin(Range), adl_end(Range), I);
+template <typename R, typename T>
+auto lower_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
+  return std::lower_bound(adl_begin(Range), adl_end(Range),
+                          std::forward<T>(Value));
 }
 
-template <typename R, typename ForwardIt, typename Compare>
-auto lower_bound(R &&Range, ForwardIt I, Compare C)
+template <typename R, typename T, typename Compare>
+auto lower_bound(R &&Range, T &&Value, Compare C)
     -> decltype(adl_begin(Range)) {
-  return std::lower_bound(adl_begin(Range), adl_end(Range), I, C);
+  return std::lower_bound(adl_begin(Range), adl_end(Range),
+                          std::forward<T>(Value), C);
 }
 
 /// Provide wrappers to std::upper_bound which take ranges instead of having to
 /// pass begin/end explicitly.
-template <typename R, typename ForwardIt>
-auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
-  return std::upper_bound(adl_begin(Range), adl_end(Range), I);
+template <typename R, typename T>
+auto upper_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
+  return std::upper_bound(adl_begin(Range), adl_end(Range),
+                          std::forward<T>(Value));
 }
 
-template <typename R, typename ForwardIt, typename Compare>
-auto upper_bound(R &&Range, ForwardIt I, Compare C)
+template <typename R, typename T, typename Compare>
+auto upper_bound(R &&Range, T &&Value, Compare C)
     -> decltype(adl_begin(Range)) {
-  return std::upper_bound(adl_begin(Range), adl_end(Range), I, C);
+  return std::upper_bound(adl_begin(Range), adl_end(Range),
+                          std::forward<T>(Value), C);
 }
+
+template <typename R>
+void stable_sort(R &&Range) {
+  std::stable_sort(adl_begin(Range), adl_end(Range));
+}
+
+template <typename R, typename Compare>
+void stable_sort(R &&Range, Compare C) {
+  std::stable_sort(adl_begin(Range), adl_end(Range), C);
+}
+
+/// Binary search for the first iterator in a range where a predicate is false.
+/// Requires that C is always true below some limit, and always false above it.
+template <typename R, typename Predicate,
+          typename Val = decltype(*adl_begin(std::declval<R>()))>
+auto partition_point(R &&Range, Predicate P) -> decltype(adl_begin(Range)) {
+  return std::partition_point(adl_begin(Range), adl_end(Range), P);
+}
+
 /// Wrapper function around std::equal to detect if all elements
 /// in a container are same.
 template <typename R>
@@ -1330,6 +1360,33 @@
   C.erase(remove_if(C, P), C.end());
 }
 
+/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
+/// the range [ValIt, ValEnd) (which is not from the same container).
+template<typename Container, typename RandomAccessIterator>
+void replace(Container &Cont, typename Container::iterator ContIt,
+             typename Container::iterator ContEnd, RandomAccessIterator ValIt,
+             RandomAccessIterator ValEnd) {
+  while (true) {
+    if (ValIt == ValEnd) {
+      Cont.erase(ContIt, ContEnd);
+      return;
+    } else if (ContIt == ContEnd) {
+      Cont.insert(ContIt, ValIt, ValEnd);
+      return;
+    }
+    *ContIt++ = *ValIt++;
+  }
+}
+
+/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with
+/// the range R.
+template<typename Container, typename Range = std::initializer_list<
+                                 typename Container::value_type>>
+void replace(Container &Cont, typename Container::iterator ContIt,
+             typename Container::iterator ContEnd, Range R) {
+  replace(Cont, ContIt, ContEnd, R.begin(), R.end());
+}
+
 //===----------------------------------------------------------------------===//
 //     Extra additions to <memory>
 //===----------------------------------------------------------------------===//
@@ -1417,6 +1474,9 @@
 template <typename R> class enumerator_iter;
 
 template <typename R> struct result_pair {
+  using value_reference =
+      typename std::iterator_traits<IterOfRange<R>>::reference;
+
   friend class enumerator_iter<R>;
 
   result_pair() = default;
@@ -1430,8 +1490,8 @@
   }
 
   std::size_t index() const { return Index; }
-  const ValueOfRange<R> &value() const { return *Iter; }
-  ValueOfRange<R> &value() { return *Iter; }
+  const value_reference value() const { return *Iter; }
+  value_reference value() { return *Iter; }
 
 private:
   std::size_t Index = std::numeric_limits<std::size_t>::max();
@@ -1576,6 +1636,19 @@
   return true;
 }
 
+/// Returns a raw pointer that represents the same address as the argument.
+///
+/// The late bound return should be removed once we move to C++14 to better
+/// align with the C++20 declaration. Also, this implementation can be removed
+/// once we move to C++20 where it's defined as std::to_addres()
+///
+/// The std::pointer_traits<>::to_address(p) variations of these overloads has
+/// not been implemented.
+template <class Ptr> auto to_address(const Ptr &P) -> decltype(P.operator->()) {
+  return P.operator->();
+}
+template <class T> constexpr T *to_address(T *P) { return P; }
+
 } // end namespace llvm
 
 #endif // LLVM_ADT_STLEXTRAS_H
diff --git a/linux-x64/clang/include/llvm/ADT/SmallVector.h b/linux-x64/clang/include/llvm/ADT/SmallVector.h
index e3bfb90..1758690 100644
--- a/linux-x64/clang/include/llvm/ADT/SmallVector.h
+++ b/linux-x64/clang/include/llvm/ADT/SmallVector.h
@@ -41,8 +41,8 @@
   unsigned Size = 0, Capacity;
 
   SmallVectorBase() = delete;
-  SmallVectorBase(void *FirstEl, size_t Capacity)
-      : BeginX(FirstEl), Capacity(Capacity) {}
+  SmallVectorBase(void *FirstEl, size_t TotalCapacity)
+      : BeginX(FirstEl), Capacity(TotalCapacity) {}
 
   /// This is an implementation of the grow() method which only works
   /// on POD-like data types and is out of line to reduce code duplication.
@@ -63,9 +63,9 @@
   /// of the buffer when they know that more elements are available, and only
   /// update the size later. This avoids the cost of value initializing elements
   /// which will only be overwritten.
-  void set_size(size_t Size) {
-    assert(Size <= capacity());
-    this->Size = Size;
+  void set_size(size_t N) {
+    assert(N <= capacity());
+    Size = N;
   }
 };
 
@@ -318,6 +318,7 @@
 public:
   using iterator = typename SuperClass::iterator;
   using const_iterator = typename SuperClass::const_iterator;
+  using reference = typename SuperClass::reference;
   using size_type = typename SuperClass::size_type;
 
 protected:
@@ -385,22 +386,18 @@
                 std::input_iterator_tag>::value>::type>
   void append(in_iter in_start, in_iter in_end) {
     size_type NumInputs = std::distance(in_start, in_end);
-    // Grow allocated space if needed.
     if (NumInputs > this->capacity() - this->size())
       this->grow(this->size()+NumInputs);
 
-    // Copy the new elements over.
     this->uninitialized_copy(in_start, in_end, this->end());
     this->set_size(this->size() + NumInputs);
   }
 
-  /// Add the specified range to the end of the SmallVector.
+  /// Append \p NumInputs copies of \p Elt to the end.
   void append(size_type NumInputs, const T &Elt) {
-    // Grow allocated space if needed.
     if (NumInputs > this->capacity() - this->size())
       this->grow(this->size()+NumInputs);
 
-    // Copy the new elements over.
     std::uninitialized_fill_n(this->end(), NumInputs, Elt);
     this->set_size(this->size() + NumInputs);
   }
@@ -641,11 +638,12 @@
     insert(I, IL.begin(), IL.end());
   }
 
-  template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
+  template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
     if (LLVM_UNLIKELY(this->size() >= this->capacity()))
       this->grow();
     ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
     this->set_size(this->size() + 1);
+    return this->back();
   }
 
   SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
diff --git a/linux-x64/clang/include/llvm/ADT/StringMap.h b/linux-x64/clang/include/llvm/ADT/StringMap.h
index d94e483..8a586fc 100644
--- a/linux-x64/clang/include/llvm/ADT/StringMap.h
+++ b/linux-x64/clang/include/llvm/ADT/StringMap.h
@@ -359,6 +359,11 @@
     return find(Key) == end() ? 0 : 1;
   }
 
+  template <typename InputTy>
+  size_type count(const StringMapEntry<InputTy> &MapEntry) const {
+    return count(MapEntry.getKey());
+  }
+
   /// insert - Insert the specified key/value pair into the map.  If the key
   /// already exists in the map, return false and ignore the request, otherwise
   /// insert it and return true.
diff --git a/linux-x64/clang/include/llvm/ADT/StringSet.h b/linux-x64/clang/include/llvm/ADT/StringSet.h
index fcf9519..af3a44a 100644
--- a/linux-x64/clang/include/llvm/ADT/StringSet.h
+++ b/linux-x64/clang/include/llvm/ADT/StringSet.h
@@ -33,6 +33,7 @@
       for (StringRef X : S)
         insert(X);
     }
+    explicit StringSet(AllocatorTy A) : base(A) {}
 
     std::pair<typename base::iterator, bool> insert(StringRef Key) {
       assert(!Key.empty());
@@ -44,6 +45,12 @@
       for (auto It = Begin; It != End; ++It)
         base::insert(std::make_pair(*It, '\0'));
     }
+
+    template <typename ValueTy>
+    std::pair<typename base::iterator, bool>
+    insert(const StringMapEntry<ValueTy> &MapEntry) {
+      return insert(MapEntry.getKey());
+    }
   };
 
 } // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/ADT/Triple.h b/linux-x64/clang/include/llvm/ADT/Triple.h
index 70d8879..edeb31e 100644
--- a/linux-x64/clang/include/llvm/ADT/Triple.h
+++ b/linux-x64/clang/include/llvm/ADT/Triple.h
@@ -49,6 +49,7 @@
     armeb,          // ARM (big endian): armeb
     aarch64,        // AArch64 (little endian): aarch64
     aarch64_be,     // AArch64 (big endian): aarch64_be
+    aarch64_32,     // AArch64 (little endian) ILP32: aarch64_32
     arc,            // ARC: Synopsys ARC
     avr,            // AVR: Atmel AVR microcontroller
     bpfel,          // eBPF or extended BPF or 64-bit BPF (little endian)
@@ -108,6 +109,7 @@
     ARMSubArch_v8r,
     ARMSubArch_v8m_baseline,
     ARMSubArch_v8m_mainline,
+    ARMSubArch_v8_1m_mainline,
     ARMSubArch_v7,
     ARMSubArch_v7em,
     ARMSubArch_v7m,
@@ -186,7 +188,8 @@
     HermitCore, // HermitCore Unikernel/Multikernel
     Hurd,       // GNU/Hurd
     WASI,       // Experimental WebAssembly OS
-    LastOSType = WASI
+    Emscripten,
+    LastOSType = Emscripten
   };
   enum EnvironmentType {
     UnknownEnvironment,
@@ -200,6 +203,8 @@
     CODE16,
     EABI,
     EABIHF,
+    ELFv1,
+    ELFv2,
     Android,
     Musl,
     MuslEABI,
@@ -209,8 +214,9 @@
     Itanium,
     Cygnus,
     CoreCLR,
-    Simulator,  // Simulator variants of other systems, e.g., Apple's iOS
-    LastEnvironmentType = Simulator
+    Simulator, // Simulator variants of other systems, e.g., Apple's iOS
+    MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
+    LastEnvironmentType = MacABI
   };
   enum ObjectFormatType {
     UnknownObjectFormat,
@@ -219,6 +225,7 @@
     ELF,
     MachO,
     Wasm,
+    XCOFF,
   };
 
 private:
@@ -479,6 +486,10 @@
     return getEnvironment() == Triple::Simulator;
   }
 
+  bool isMacCatalystEnvironment() const {
+    return getEnvironment() == Triple::MacABI;
+  }
+
   bool isOSNetBSD() const {
     return getOS() == Triple::NetBSD;
   }
@@ -591,6 +602,11 @@
     return getOS() == Triple::WASI;
   }
 
+  /// Tests whether the OS is Emscripten.
+  bool isOSEmscripten() const {
+    return getOS() == Triple::Emscripten;
+  }
+
   /// Tests whether the OS uses glibc.
   bool isOSGlibc() const {
     return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD ||
@@ -598,6 +614,11 @@
            !isAndroid();
   }
 
+  /// Tests whether the OS is AIX.
+  bool isOSAIX() const {
+    return getOS() == Triple::AIX;
+  }
+
   /// Tests whether the OS uses the ELF binary format.
   bool isOSBinFormatELF() const {
     return getObjectFormat() == Triple::ELF;
@@ -618,6 +639,11 @@
     return getObjectFormat() == Triple::Wasm;
   }
 
+  /// Tests whether the OS uses the XCOFF binary format.
+  bool isOSBinFormatXCOFF() const {
+    return getObjectFormat() == Triple::XCOFF;
+  }
+
   /// Tests whether the target is the PS4 CPU
   bool isPS4CPU() const {
     return getArch() == Triple::x86_64 &&
@@ -654,6 +680,11 @@
            getEnvironment() == Triple::MuslEABIHF;
   }
 
+  /// Tests whether the target is SPIR (32- or 64-bit).
+  bool isSPIR() const {
+    return getArch() == Triple::spir || getArch() == Triple::spir64;
+  }
+
   /// Tests whether the target is NVPTX (32- or 64-bit).
   bool isNVPTX() const {
     return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
@@ -689,6 +720,16 @@
     return isMIPS32() || isMIPS64();
   }
 
+  /// Tests whether the target is 64-bit PowerPC (little and big endian).
+  bool isPPC64() const {
+    return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le;
+  }
+
+  /// Tests whether the target is RISC-V (32- and 64-bit).
+  bool isRISCV() const {
+    return getArch() == Triple::riscv32 || getArch() == Triple::riscv64;
+  }
+
   /// Tests whether the target supports comdat
   bool supportsCOMDAT() const {
     return !isOSBinFormatMachO();
