[llvm] 2916b99 - [ADT] Alias llvm::Optional to std::optional

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 19 16:02:15 PST 2022


Author: Benjamin Kramer
Date: 2022-12-20T01:01:46+01:00
New Revision: 2916b99182752b1aece8cc4479d8d6a20b5e02da

URL: https://github.com/llvm/llvm-project/commit/2916b99182752b1aece8cc4479d8d6a20b5e02da
DIFF: https://github.com/llvm/llvm-project/commit/2916b99182752b1aece8cc4479d8d6a20b5e02da.diff

LOG: [ADT] Alias llvm::Optional to std::optional

This avoids the continuous API churn when upgrading things to use
std::optional and makes trivial string replace upgrades possible.

I tested this with GCC 7.5, the oldest supported GCC I had around.

Differential Revision: https://reviews.llvm.org/D140332

Added: 
    

Modified: 
    clang/include/clang/Basic/LLVM.h
    clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
    flang/include/flang/Lower/Runtime.h
    lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
    lldb/source/Symbol/Type.cpp
    llvm/include/llvm/ADT/Optional.h
    llvm/include/llvm/ADT/STLForwardCompat.h
    llvm/include/llvm/Support/raw_ostream.h
    llvm/include/llvm/Testing/Support/SupportHelpers.h
    llvm/lib/CodeGen/RegAllocGreedy.h
    llvm/unittests/ADT/CMakeLists.txt
    llvm/unittests/Support/TypeTraitsTest.cpp
    mlir/include/mlir/Bindings/Python/PybindAdaptors.h
    mlir/include/mlir/Support/LLVM.h
    mlir/lib/Bindings/Python/PybindUtils.h
    mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp

Removed: 
    llvm/unittests/ADT/OptionalTest.cpp


################################################################################
diff  --git a/clang/include/clang/Basic/LLVM.h b/clang/include/clang/Basic/LLVM.h
index 5d4d72630970b..7ffc4c403473b 100644
--- a/clang/include/clang/Basic/LLVM.h
+++ b/clang/include/clang/Basic/LLVM.h
@@ -37,7 +37,7 @@ namespace llvm {
   template<unsigned InternalLen> class SmallString;
   template<typename T, unsigned N> class SmallVector;
   template<typename T> class SmallVectorImpl;
-  template <typename T> class Optional;
+  template <typename T> using Optional = std::optional<T>;
   template <class T> class Expected;
 
   template<typename T>

diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 7ced94a7dc371..f9e76d85efdde 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -481,7 +481,7 @@ Optional<unsigned> ExprEngine::getPendingInitLoop(ProgramStateRef State,
                                                   const CXXConstructExpr *E,
                                                   const LocationContext *LCtx) {
   const unsigned *V = State->get<PendingInitLoop>({E, LCtx->getStackFrame()});
-  return V ? Optional(*V) : std::nullopt;
+  return V ? std::make_optional(*V) : std::nullopt;
 }
 
 ProgramStateRef ExprEngine::removePendingInitLoop(ProgramStateRef State,
@@ -510,7 +510,7 @@ ExprEngine::getIndexOfElementToConstruct(ProgramStateRef State,
                                          const LocationContext *LCtx) {
   const unsigned *V =
       State->get<IndexOfElementToConstruct>({E, LCtx->getStackFrame()});
-  return V ? Optional(*V) : std::nullopt;
+  return V ? std::make_optional(*V) : std::nullopt;
 }
 
 ProgramStateRef
@@ -530,7 +530,7 @@ ExprEngine::getPendingArrayDestruction(ProgramStateRef State,
 
   const unsigned *V =
       State->get<PendingArrayDestruction>(LCtx->getStackFrame());
-  return V ? Optional(*V) : std::nullopt;
+  return V ? std::make_optional(*V) : std::nullopt;
 }
 
 ProgramStateRef ExprEngine::setPendingArrayDestruction(
@@ -600,7 +600,7 @@ ExprEngine::getObjectUnderConstruction(ProgramStateRef State,
                                        const LocationContext *LC) {
   ConstructedObjectKey Key(Item, LC->getStackFrame());
   const SVal *V = State->get<ObjectsUnderConstruction>(Key);
-  return V ? Optional(*V) : std::nullopt;
+  return V ? std::make_optional(*V) : std::nullopt;
 }
 
 ProgramStateRef

diff  --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h
index 64e9a16fd7988..da01d1a87cccd 100644
--- a/flang/include/flang/Lower/Runtime.h
+++ b/flang/include/flang/Lower/Runtime.h
@@ -16,9 +16,10 @@
 #ifndef FORTRAN_LOWER_RUNTIME_H
 #define FORTRAN_LOWER_RUNTIME_H
 
+#include <optional>
+
 namespace llvm {
-template <typename T>
-class Optional;
+template <typename T> using Optional = std::optional<T>;
 }
 
 namespace mlir {

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 4efb5a2029e85..32960c2102eda 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -190,7 +190,7 @@ static FormSize g_form_sizes[] = {
 llvm::Optional<uint8_t>
 DWARFFormValue::GetFixedSize(dw_form_t form, const DWARFUnit *u) {
   if (form <= DW_FORM_ref_sig8 && g_form_sizes[form].valid)
-    return g_form_sizes[form].size;
+    return static_cast<uint8_t>(g_form_sizes[form].size);
   if (form == DW_FORM_addr && u)
     return u->GetAddressByteSize();
   return std::nullopt;

diff  --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index da9eeadc0ecd2..048e37fb1db2f 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -343,7 +343,7 @@ Type *Type::GetEncodingType() {
 
 llvm::Optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
   if (m_byte_size_has_value)
-    return m_byte_size;
+    return static_cast<uint64_t>(m_byte_size);
 
   switch (m_encoding_uid_type) {
   case eEncodingInvalid:
@@ -360,14 +360,14 @@ llvm::Optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
       if (llvm::Optional<uint64_t> size = encoding_type->GetByteSize(exe_scope)) {
         m_byte_size = *size;
         m_byte_size_has_value = true;
-        return m_byte_size;
+        return static_cast<uint64_t>(m_byte_size);
       }
 
     if (llvm::Optional<uint64_t> size =
             GetLayoutCompilerType().GetByteSize(exe_scope)) {
       m_byte_size = *size;
       m_byte_size_has_value = true;
-        return m_byte_size;
+      return static_cast<uint64_t>(m_byte_size);
     }
   } break;
 
@@ -378,7 +378,7 @@ llvm::Optional<uint64_t> Type::GetByteSize(ExecutionContextScope *exe_scope) {
       if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) {
         m_byte_size = arch.GetAddressByteSize();
         m_byte_size_has_value = true;
-        return m_byte_size;
+        return static_cast<uint64_t>(m_byte_size);
       }
     } break;
   }

diff  --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h
index a458ccf61c717..c3382837c0aea 100644
--- a/llvm/include/llvm/ADT/Optional.h
+++ b/llvm/include/llvm/ADT/Optional.h
@@ -16,446 +16,12 @@
 #ifndef LLVM_ADT_OPTIONAL_H
 #define LLVM_ADT_OPTIONAL_H
 
-#include "llvm/ADT/Hashing.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/type_traits.h"
-#include <cassert>
-#include <new>
-#include <utility>
+#include <optional>
 
 namespace llvm {
-
-namespace optional_detail {
-
-/// Storage for any type.
-//
-// The specialization condition intentionally uses
-// llvm::is_trivially_{copy/move}_constructible instead of
-// std::is_trivially_{copy/move}_constructible. GCC versions prior to 7.4 may
-// instantiate the copy/move constructor of `T` when
-// std::is_trivially_{copy/move}_constructible is instantiated.  This causes
-// compilation to fail if we query the trivially copy/move constructible
-// property of a class which is not copy/move constructible.
-//
-// The current implementation of OptionalStorage insists that in order to use
-// the trivial specialization, the value_type must be trivially copy
-// constructible and trivially copy assignable due to =default implementations
-// of the copy/move constructor/assignment.  It does not follow that this is
-// necessarily the case std::is_trivially_copyable is true (hence the expanded
-// specialization condition).
-//
-// The move constructible / assignable conditions emulate the remaining behavior
-// of std::is_trivially_copyable.
-template <typename T,
-          bool = (llvm::is_trivially_copy_constructible<T>::value &&
-                  std::is_trivially_copy_assignable<T>::value &&
-                  (llvm::is_trivially_move_constructible<T>::value ||
-                   !std::is_move_constructible<T>::value) &&
-                  (std::is_trivially_move_assignable<T>::value ||
-                   !std::is_move_assignable<T>::value))>
-class OptionalStorage {
-  union {
-    char empty;
-    T val;
-  };
-  bool hasVal = false;
-
-public:
-  ~OptionalStorage() { reset(); }
-
-  constexpr OptionalStorage() noexcept : empty() {}
-
-  constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() {
-    if (other.has_value()) {
-      emplace(other.val);
-    }
-  }
-  constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() {
-    if (other.has_value()) {
-      emplace(std::move(other.val));
-    }
-  }
-
-  template <class... Args>
-  constexpr explicit OptionalStorage(std::in_place_t, Args &&...args)
-      : val(std::forward<Args>(args)...), hasVal(true) {}
-
-  void reset() noexcept {
-    if (hasVal) {
-      val.~T();
-      hasVal = false;
-    }
-  }
-
-  constexpr bool has_value() const noexcept { return hasVal; }
-
-  T &value() &noexcept {
-    assert(hasVal);
-    return val;
-  }
-  constexpr T const &value() const &noexcept {
-    assert(hasVal);
-    return val;
-  }
-  T &&value() &&noexcept {
-    assert(hasVal);
-    return std::move(val);
-  }
-
-  template <class... Args> void emplace(Args &&...args) {
-    reset();
-    ::new ((void *)std::addressof(val)) T(std::forward<Args>(args)...);
-    hasVal = true;
-  }
-
-  OptionalStorage &operator=(T const &y) {
-    if (has_value()) {
-      val = y;
-    } else {
-      ::new ((void *)std::addressof(val)) T(y);
-      hasVal = true;
-    }
-    return *this;
-  }
-  OptionalStorage &operator=(T &&y) {
-    if (has_value()) {
-      val = std::move(y);
-    } else {
-      ::new ((void *)std::addressof(val)) T(std::move(y));
-      hasVal = true;
-    }
-    return *this;
-  }
-
-  OptionalStorage &operator=(OptionalStorage const &other) {
-    if (other.has_value()) {
-      if (has_value()) {
-        val = other.val;
-      } else {
-        ::new ((void *)std::addressof(val)) T(other.val);
-        hasVal = true;
-      }
-    } else {
-      reset();
-    }
-    return *this;
-  }
-
-  OptionalStorage &operator=(OptionalStorage &&other) {
-    if (other.has_value()) {
-      if (has_value()) {
-        val = std::move(other.val);
-      } else {
-        ::new ((void *)std::addressof(val)) T(std::move(other.val));
-        hasVal = true;
-      }
-    } else {
-      reset();
-    }
-    return *this;
-  }
-};
-
-template <typename T> class OptionalStorage<T, true> {
-  union {
-    char empty;
-    T val;
-  };
-  bool hasVal = false;
-
-public:
-  ~OptionalStorage() = default;
-
-  constexpr OptionalStorage() noexcept : empty{} {}
-
-  constexpr OptionalStorage(OptionalStorage const &other) = default;
-  constexpr OptionalStorage(OptionalStorage &&other) = default;
-
-  OptionalStorage &operator=(OptionalStorage const &other) = default;
-  OptionalStorage &operator=(OptionalStorage &&other) = default;
-
-  template <class... Args>
-  constexpr explicit OptionalStorage(std::in_place_t, Args &&...args)
-      : val(std::forward<Args>(args)...), hasVal(true) {}
-
-  void reset() noexcept {
-    if (hasVal) {
-      val.~T();
-      hasVal = false;
-    }
-  }
-
-  constexpr bool has_value() const noexcept { return hasVal; }
-
-  T &value() &noexcept {
-    assert(hasVal);
-    return val;
-  }
-  constexpr T const &value() const &noexcept {
-    assert(hasVal);
-    return val;
-  }
-  T &&value() &&noexcept {
-    assert(hasVal);
-    return std::move(val);
-  }
-
-  template <class... Args> void emplace(Args &&...args) {
-    reset();
-    ::new ((void *)std::addressof(val)) T(std::forward<Args>(args)...);
-    hasVal = true;
-  }
-
-  OptionalStorage &operator=(T const &y) {
-    if (has_value()) {
-      val = y;
-    } else {
-      ::new ((void *)std::addressof(val)) T(y);
-      hasVal = true;
-    }
-    return *this;
-  }
-  OptionalStorage &operator=(T &&y) {
-    if (has_value()) {
-      val = std::move(y);
-    } else {
-      ::new ((void *)std::addressof(val)) T(std::move(y));
-      hasVal = true;
-    }
-    return *this;
-  }
-};
-
-} // namespace optional_detail
-
-template <typename T> class Optional {
-  optional_detail::OptionalStorage<T> Storage;
-
-public:
-  using value_type = T;
-
-  constexpr Optional() = default;
-  constexpr Optional(std::nullopt_t) {}
-
-  constexpr Optional(const T &y) : Storage(std::in_place, y) {}
-  constexpr Optional(const Optional &O) = default;
-
-  constexpr Optional(T &&y) : Storage(std::in_place, std::move(y)) {}
-  constexpr Optional(Optional &&O) = default;
-
-  template <typename... ArgTypes>
-  constexpr Optional(std::in_place_t, ArgTypes &&...Args)
-      : Storage(std::in_place, std::forward<ArgTypes>(Args)...) {}
-
-  Optional &operator=(T &&y) {
-    Storage = std::move(y);
-    return *this;
-  }
-  Optional &operator=(Optional &&O) = default;
-
-  /// Create a new object by constructing it in place with the given arguments.
-  template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
-    Storage.emplace(std::forward<ArgTypes>(Args)...);
-  }
-
-  Optional &operator=(const T &y) {
-    Storage = y;
-    return *this;
-  }
-  Optional &operator=(const Optional &O) = default;
-
-  void reset() { Storage.reset(); }
-
-  LLVM_DEPRECATED("Use &*X instead.", "&*X")
-  constexpr const T *getPointer() const { return &Storage.value(); }
-  LLVM_DEPRECATED("Use &*X instead.", "&*X")
-  T *getPointer() { return &Storage.value(); }
-  LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
-  constexpr const T &value() const & { return Storage.value(); }
-  LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
-  T &value() & { return Storage.value(); }
-
-  constexpr explicit operator bool() const { return has_value(); }
-  constexpr bool has_value() const { return Storage.has_value(); }
-  constexpr const T *operator->() const { return &Storage.value(); }
-  T *operator->() { return &Storage.value(); }
-  constexpr const T &operator*() const & { return Storage.value(); }
-  T &operator*() & { return Storage.value(); }
-
-  template <typename U> constexpr T value_or(U &&alt) const & {
-    return has_value() ? operator*() : std::forward<U>(alt);
-  }
-
-  LLVM_DEPRECATED("std::optional::value is throwing. Use *X instead", "*X")
-  T &&value() && { return std::move(Storage.value()); }
-  T &&operator*() && { return std::move(Storage.value()); }
-
-  template <typename U> T value_or(U &&alt) && {
-    return has_value() ? std::move(operator*()) : std::forward<U>(alt);
-  }
-};
-
-template<typename T>
-Optional(const T&) -> Optional<T>;
-
-template <class T> llvm::hash_code hash_value(const Optional<T> &O) {
-  return O ? hash_combine(true, *O) : hash_value(false);
-}
-
-template <typename T, typename U>
-constexpr bool operator==(const Optional<T> &X, const Optional<U> &Y) {
-  if (X && Y)
-    return *X == *Y;
-  return X.has_value() == Y.has_value();
-}
-
-template <typename T, typename U>
-constexpr bool operator!=(const Optional<T> &X, const Optional<U> &Y) {
-  return !(X == Y);
-}
-
-template <typename T, typename U>
-constexpr bool operator<(const Optional<T> &X, const Optional<U> &Y) {
-  if (X && Y)
-    return *X < *Y;
-  return X.has_value() < Y.has_value();
-}
-
-template <typename T, typename U>
-constexpr bool operator<=(const Optional<T> &X, const Optional<U> &Y) {
-  return !(Y < X);
-}
-
-template <typename T, typename U>
-constexpr bool operator>(const Optional<T> &X, const Optional<U> &Y) {
-  return Y < X;
-}
-
-template <typename T, typename U>
-constexpr bool operator>=(const Optional<T> &X, const Optional<U> &Y) {
-  return !(X < Y);
-}
-
-template <typename T>
-constexpr bool operator==(const Optional<T> &X, std::nullopt_t) {
-  return !X;
-}
-
-template <typename T>
-constexpr bool operator==(std::nullopt_t, const Optional<T> &X) {
-  return X == std::nullopt;
-}
-
-template <typename T>
-constexpr bool operator!=(const Optional<T> &X, std::nullopt_t) {
-  return !(X == std::nullopt);
-}
-
-template <typename T>
-constexpr bool operator!=(std::nullopt_t, const Optional<T> &X) {
-  return X != std::nullopt;
-}
-
-template <typename T>
-constexpr bool operator<(const Optional<T> &, std::nullopt_t) {
-  return false;
-}
-
-template <typename T>
-constexpr bool operator<(std::nullopt_t, const Optional<T> &X) {
-  return X.has_value();
-}
-
-template <typename T>
-constexpr bool operator<=(const Optional<T> &X, std::nullopt_t) {
-  return !(std::nullopt < X);
-}
-
-template <typename T>
-constexpr bool operator<=(std::nullopt_t, const Optional<T> &X) {
-  return !(X < std::nullopt);
-}
-
-template <typename T>
-constexpr bool operator>(const Optional<T> &X, std::nullopt_t) {
-  return std::nullopt < X;
-}
-
-template <typename T>
-constexpr bool operator>(std::nullopt_t, const Optional<T> &X) {
-  return X < std::nullopt;
-}
-
-template <typename T>
-constexpr bool operator>=(const Optional<T> &X, std::nullopt_t) {
-  return std::nullopt <= X;
-}
-
-template <typename T>
-constexpr bool operator>=(std::nullopt_t, const Optional<T> &X) {
-  return X <= std::nullopt;
-}
-
-template <typename T>
-constexpr bool operator==(const Optional<T> &X, const T &Y) {
-  return X && *X == Y;
-}
-
-template <typename T>
-constexpr bool operator==(const T &X, const Optional<T> &Y) {
-  return Y && X == *Y;
-}
-
-template <typename T>
-constexpr bool operator!=(const Optional<T> &X, const T &Y) {
-  return !(X == Y);
-}
-
-template <typename T>
-constexpr bool operator!=(const T &X, const Optional<T> &Y) {
-  return !(X == Y);
-}
-
-template <typename T>
-constexpr bool operator<(const Optional<T> &X, const T &Y) {
-  return !X || *X < Y;
-}
-
-template <typename T>
-constexpr bool operator<(const T &X, const Optional<T> &Y) {
-  return Y && X < *Y;
-}
-
-template <typename T>
-constexpr bool operator<=(const Optional<T> &X, const T &Y) {
-  return !(Y < X);
-}
-
-template <typename T>
-constexpr bool operator<=(const T &X, const Optional<T> &Y) {
-  return !(Y < X);
-}
-
-template <typename T>
-constexpr bool operator>(const Optional<T> &X, const T &Y) {
-  return Y < X;
-}
-
-template <typename T>
-constexpr bool operator>(const T &X, const Optional<T> &Y) {
-  return Y < X;
-}
-
-template <typename T>
-constexpr bool operator>=(const Optional<T> &X, const T &Y) {
-  return !(X < Y);
-}
-
-template <typename T>
-constexpr bool operator>=(const T &X, const Optional<T> &Y) {
-  return !(X < Y);
-}
-
-} // end namespace llvm
+// Legacy alias of llvm::Optional to std::optional.
+// FIXME: Remove this after LLVM 16.
+template <class T> using Optional = std::optional<T>;
+} // namespace llvm
 
 #endif // LLVM_ADT_OPTIONAL_H

diff  --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h
index 51748c7c0ea28..b2fe9bc753f63 100644
--- a/llvm/include/llvm/ADT/STLForwardCompat.h
+++ b/llvm/include/llvm/ADT/STLForwardCompat.h
@@ -61,26 +61,6 @@ auto transformOptional(std::optional<T> &&O, const Function &F)
   return std::nullopt;
 }
 
-// TODO: Remove this once the migration from llvm::Optional to std::optional is
-// complete.
-template <typename T, typename Function>
-auto transformOptional(const Optional<T> &O, const Function &F)
-    -> Optional<decltype(F(*O))> {
-  if (O)
-    return F(*O);
-  return std::nullopt;
-}
-
-// TODO: Remove this once the migration from llvm::Optional to std::optional is
-// complete.
-template <typename T, typename Function>
-auto transformOptional(Optional<T> &&O, const Function &F)
-    -> Optional<decltype(F(*std::move(O)))> {
-  if (O)
-    return F(*std::move(O));
-  return std::nullopt;
-}
-
 } // namespace llvm
 
 #endif // LLVM_ADT_STLFORWARDCOMPAT_H

diff  --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
index b5c3e463d69dc..73c703c7f8732 100644
--- a/llvm/include/llvm/Support/raw_ostream.h
+++ b/llvm/include/llvm/Support/raw_ostream.h
@@ -743,16 +743,6 @@ Error writeToOutput(StringRef OutputFileName,
 
 raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);
 
-template <typename T, typename = decltype(std::declval<raw_ostream &>()
-                                          << std::declval<const T &>())>
-raw_ostream &operator<<(raw_ostream &OS, const Optional<T> &O) {
-  if (O)
-    OS << *O;
-  else
-    OS << std::nullopt;
-  return OS;
-}
-
 template <typename T, typename = decltype(std::declval<raw_ostream &>()
                                           << std::declval<const T &>())>
 raw_ostream &operator<<(raw_ostream &OS, const std::optional<T> &O) {

diff  --git a/llvm/include/llvm/Testing/Support/SupportHelpers.h b/llvm/include/llvm/Testing/Support/SupportHelpers.h
index afcad6f9ba307..f9aa136f7a0ac 100644
--- a/llvm/include/llvm/Testing/Support/SupportHelpers.h
+++ b/llvm/include/llvm/Testing/Support/SupportHelpers.h
@@ -69,12 +69,6 @@ template <class InnerMatcher> class ValueIsMatcher {
         new Impl<T>(::testing::SafeMatcherCast<T>(ValueMatcher)));
   }
 
-  template <class T>
-  operator ::testing::Matcher<const Optional<T> &>() const {
-    return ::testing::MakeMatcher(
-        new Impl<T, Optional<T>>(::testing::SafeMatcherCast<T>(ValueMatcher)));
-  }
-
   template <class T, class O = std::optional<T>>
   class Impl : public ::testing::MatcherInterface<const O &> {
   public:

diff  --git a/llvm/lib/CodeGen/RegAllocGreedy.h b/llvm/lib/CodeGen/RegAllocGreedy.h
index e199772b14069..188cc5664d5d9 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.h
+++ b/llvm/lib/CodeGen/RegAllocGreedy.h
@@ -80,7 +80,7 @@ class LLVM_LIBRARY_VISIBILITY RAGreedy : public MachineFunctionPass,
     unsigned NextCascade = 1;
 
   public:
-    ExtraRegInfo() = default;
+    ExtraRegInfo() {}
     ExtraRegInfo(const ExtraRegInfo &) = delete;
 
     LiveRangeStage getStage(Register Reg) const { return Info[Reg].Stage; }

diff  --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt
index 8cddaa50341f8..5a918892ff8e4 100644
--- a/llvm/unittests/ADT/CMakeLists.txt
+++ b/llvm/unittests/ADT/CMakeLists.txt
@@ -49,7 +49,6 @@ add_llvm_unittest(ADTTests
   MappedIteratorTest.cpp
   MapVectorTest.cpp
   MoveOnly.cpp
-  OptionalTest.cpp
   PackedVectorTest.cpp
   PointerEmbeddedIntTest.cpp
   PointerIntPairTest.cpp

diff  --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp
deleted file mode 100644
index af4cf2ec46610..0000000000000
--- a/llvm/unittests/ADT/OptionalTest.cpp
+++ /dev/null
@@ -1,803 +0,0 @@
-//===- llvm/unittest/ADT/OptionalTest.cpp - Optional 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/ADT/Optional.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/raw_ostream.h"
-#include "MoveOnly.h"
-#include "gtest/gtest-spi.h"
-#include "gtest/gtest.h"
-
-#include <array>
-#include <utility>
-
-using namespace llvm;
-
-static_assert(std::is_trivially_copyable_v<Optional<int>>,
-              "trivially copyable");
-
-static_assert(std::is_trivially_copyable_v<Optional<std::array<int, 3>>>,
-              "trivially copyable");
-
-void OptionalWorksInConstexpr() {
-  constexpr auto x1 = Optional<int>();
-  constexpr Optional<int> x2{};
-  static_assert(!x1.has_value() && !x2.has_value(),
-                "Default construction and hasValue() are contexpr");
-  static_assert(!x1.has_value() && !x2.has_value(),
-                "Default construction and hasValue() are contexpr");
-  constexpr auto y1 = Optional<int>(3);
-  constexpr Optional<int> y2{3};
-  static_assert(*y1 == *y2 && *y1 == 3,
-                "Construction with value and getValue() are constexpr");
-  static_assert(*y1 == *y2 && *y1 == 3,
-                "Construction with value and getValue() are constexpr");
-  static_assert(Optional<int>{3} >= 2 && Optional<int>{1} < Optional<int>{2},
-                "Comparisons work in constexpr");
-}
-
-namespace {
-
-struct NonDefaultConstructible {
-  static unsigned CopyConstructions;
-  static unsigned Destructions;
-  static unsigned CopyAssignments;
-  explicit NonDefaultConstructible(int) {
-  }
-  NonDefaultConstructible(const NonDefaultConstructible&) {
-    ++CopyConstructions;
-  }
-  NonDefaultConstructible &operator=(const NonDefaultConstructible&) {
-    ++CopyAssignments;
-    return *this;
-  }
-  ~NonDefaultConstructible() {
-    ++Destructions;
-  }
-  static void ResetCounts() {
-    CopyConstructions = 0;
-    Destructions = 0;
-    CopyAssignments = 0;
-  }
-};
-
-unsigned NonDefaultConstructible::CopyConstructions = 0;
-unsigned NonDefaultConstructible::Destructions = 0;
-unsigned NonDefaultConstructible::CopyAssignments = 0;
-
-static_assert(!std::is_trivially_copyable_v<Optional<NonDefaultConstructible>>,
-              "not trivially copyable");
-
-TEST(OptionalTest, NonDefaultConstructibleTest) {
-  Optional<NonDefaultConstructible> O;
-  EXPECT_FALSE(O);
-}
-
-TEST(OptionalTest, ResetTest) {
-  NonDefaultConstructible::ResetCounts();
-  Optional<NonDefaultConstructible> O(NonDefaultConstructible(3));
-  EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-  NonDefaultConstructible::ResetCounts();
-  O.reset();
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, InitializationLeakTest) {
-  NonDefaultConstructible::ResetCounts();
-  Optional<NonDefaultConstructible>(NonDefaultConstructible(3));
-  EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, CopyConstructionTest) {
-  NonDefaultConstructible::ResetCounts();
-  {
-    Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
-    EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-    Optional<NonDefaultConstructible> B(A);
-    EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-  }
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, ConstructingCopyAssignmentTest) {
-  NonDefaultConstructible::ResetCounts();
-  {
-    Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
-    Optional<NonDefaultConstructible> B;
-    EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-    B = A;
-    EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-  }
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, CopyingCopyAssignmentTest) {
-  NonDefaultConstructible::ResetCounts();
-  {
-    Optional<NonDefaultConstructible> A(NonDefaultConstructible(3));
-    Optional<NonDefaultConstructible> B(NonDefaultConstructible(4));
-    EXPECT_EQ(2u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-    B = A;
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(1u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-  }
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(2u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, DeletingCopyAssignmentTest) {
-  NonDefaultConstructible::ResetCounts();
-  {
-    Optional<NonDefaultConstructible> A;
-    Optional<NonDefaultConstructible> B(NonDefaultConstructible(3));
-    EXPECT_EQ(1u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-    B = A;
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-  }
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, NullCopyConstructionTest) {
-  NonDefaultConstructible::ResetCounts();
-  {
-    Optional<NonDefaultConstructible> A;
-    Optional<NonDefaultConstructible> B;
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-    B = A;
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-    EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-    EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-    NonDefaultConstructible::ResetCounts();
-  }
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) {
-  NonDefaultConstructible::ResetCounts();
-  { Optional<NonDefaultConstructible> A{std::in_place, 1}; }
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
-  EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
-  EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
-}
-
-TEST(OptionalTest, GetValueOr) {
-  Optional<int> A;
-  EXPECT_EQ(42, A.value_or(42));
-
-  A = 5;
-  EXPECT_EQ(5, A.value_or(42));
-}
-
-struct MultiArgConstructor {
-  int x, y;
-  MultiArgConstructor(int x, int y) : x(x), y(y) {}
-  explicit MultiArgConstructor(int x, bool positive)
-    : x(x), y(positive ? x : -x) {}
-
-  MultiArgConstructor(const MultiArgConstructor &) = delete;
-  MultiArgConstructor(MultiArgConstructor &&) = delete;
-  MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
-  MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
-
-  friend bool operator==(const MultiArgConstructor &LHS,
-                         const MultiArgConstructor &RHS) {
-    return LHS.x == RHS.x && LHS.y == RHS.y;
-  }
-
-  static unsigned Destructions;
-  ~MultiArgConstructor() {
-    ++Destructions;
-  }
-  static void ResetCounts() {
-    Destructions = 0;
-  }
-};
-unsigned MultiArgConstructor::Destructions = 0;
-
-static_assert(!std::is_trivially_copyable_v<Optional<MultiArgConstructor>>,
-              "not trivially copyable");
-
-TEST(OptionalTest, Emplace) {
-  MultiArgConstructor::ResetCounts();
-  Optional<MultiArgConstructor> A;
-
-  A.emplace(1, 2);
-  EXPECT_TRUE(A.has_value());
-  EXPECT_TRUE(A.has_value());
-  EXPECT_EQ(1, A->x);
-  EXPECT_EQ(2, A->y);
-  EXPECT_EQ(0u, MultiArgConstructor::Destructions);
-
-  A.emplace(5, false);
-  EXPECT_TRUE(A.has_value());
-  EXPECT_TRUE(A.has_value());
-  EXPECT_EQ(5, A->x);
-  EXPECT_EQ(-5, A->y);
-  EXPECT_EQ(1u, MultiArgConstructor::Destructions);
-}
-
-TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) {
-  MultiArgConstructor::ResetCounts();
-  {
-    Optional<MultiArgConstructor> A{std::in_place, 1, 2};
-    EXPECT_TRUE(A.has_value());
-    EXPECT_TRUE(A.has_value());
-    EXPECT_EQ(1, A->x);
-    EXPECT_EQ(2, A->y);
-    Optional<MultiArgConstructor> B{std::in_place, 5, false};
-    EXPECT_TRUE(B.has_value());
-    EXPECT_TRUE(B.has_value());
-    EXPECT_EQ(5, B->x);
-    EXPECT_EQ(-5, B->y);
-    EXPECT_EQ(0u, MultiArgConstructor::Destructions);
-  }
-  EXPECT_EQ(2u, MultiArgConstructor::Destructions);
-}
-
-TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) {
-  MultiArgConstructor::ResetCounts();
-  {
-    Optional<MultiArgConstructor> A{std::in_place, 1, 2};
-    Optional<MultiArgConstructor> B;
-    B.emplace(1, 2);
-    EXPECT_EQ(0u, MultiArgConstructor::Destructions);
-    ASSERT_EQ(A, B);
-  }
-  EXPECT_EQ(2u, MultiArgConstructor::Destructions);
-}
-
-static_assert(!std::is_trivially_copyable_v<Optional<MoveOnly>>,
-              "not trivially copyable");
-
-TEST(OptionalTest, MoveOnlyNull) {
-  MoveOnly::ResetCounts();
-  Optional<MoveOnly> O;
-  EXPECT_EQ(0u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(0u, MoveOnly::Destructions);
-}
-
-TEST(OptionalTest, MoveOnlyConstruction) {
-  MoveOnly::ResetCounts();
-  Optional<MoveOnly> O(MoveOnly(3));
-  EXPECT_TRUE((bool)O);
-  EXPECT_EQ(3, O->val);
-  EXPECT_EQ(1u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(1u, MoveOnly::Destructions);
-}
-
-TEST(OptionalTest, MoveOnlyMoveConstruction) {
-  Optional<MoveOnly> A(MoveOnly(3));
-  MoveOnly::ResetCounts();
-  Optional<MoveOnly> B(std::move(A));
-  EXPECT_TRUE((bool)A);
-  EXPECT_TRUE((bool)B);
-  EXPECT_EQ(3, B->val);
-  EXPECT_EQ(1u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(0u, MoveOnly::Destructions);
-}
-
-TEST(OptionalTest, MoveOnlyAssignment) {
-  MoveOnly::ResetCounts();
-  Optional<MoveOnly> O;
-  O = MoveOnly(3);
-  EXPECT_TRUE((bool)O);
-  EXPECT_EQ(3, O->val);
-  EXPECT_EQ(1u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(1u, MoveOnly::Destructions);
-}
-
-TEST(OptionalTest, MoveOnlyInitializingAssignment) {
-  Optional<MoveOnly> A(MoveOnly(3));
-  Optional<MoveOnly> B;
-  MoveOnly::ResetCounts();
-  B = std::move(A);
-  EXPECT_TRUE((bool)A);
-  EXPECT_TRUE((bool)B);
-  EXPECT_EQ(3, B->val);
-  EXPECT_EQ(1u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(0u, MoveOnly::Destructions);
-}
-
-TEST(OptionalTest, MoveOnlyNullingAssignment) {
-  Optional<MoveOnly> A;
-  Optional<MoveOnly> B(MoveOnly(3));
-  MoveOnly::ResetCounts();
-  B = std::move(A);
-  EXPECT_FALSE((bool)A);
-  EXPECT_FALSE((bool)B);
-  EXPECT_EQ(0u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(1u, MoveOnly::Destructions);
-}
-
-TEST(OptionalTest, MoveOnlyAssigningAssignment) {
-  Optional<MoveOnly> A(MoveOnly(3));
-  Optional<MoveOnly> B(MoveOnly(4));
-  MoveOnly::ResetCounts();
-  B = std::move(A);
-  EXPECT_TRUE((bool)A);
-  EXPECT_TRUE((bool)B);
-  EXPECT_EQ(3, B->val);
-  EXPECT_EQ(0u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(1u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(0u, MoveOnly::Destructions);
-}
-
-struct Immovable {
-  static unsigned Constructions;
-  static unsigned Destructions;
-  int val;
-  explicit Immovable(int val) : val(val) {
-    ++Constructions;
-  }
-  ~Immovable() {
-    ++Destructions;
-  }
-  static void ResetCounts() {
-    Constructions = 0;
-    Destructions = 0;
-  }
-private:
-  // This should disable all move/copy operations.
-  Immovable(Immovable&& other) = delete;
-};
-
-unsigned Immovable::Constructions = 0;
-unsigned Immovable::Destructions = 0;
-
-static_assert(!std::is_trivially_copyable_v<Optional<Immovable>>,
-              "not trivially copyable");
-
-TEST(OptionalTest, ImmovableEmplace) {
-  Optional<Immovable> A;
-  Immovable::ResetCounts();
-  A.emplace(4);
-  EXPECT_TRUE((bool)A);
-  EXPECT_EQ(4, A->val);
-  EXPECT_EQ(1u, Immovable::Constructions);
-  EXPECT_EQ(0u, Immovable::Destructions);
-}
-
-TEST(OptionalTest, ImmovableInPlaceConstruction) {
-  Immovable::ResetCounts();
-  Optional<Immovable> A{std::in_place, 4};
-  EXPECT_TRUE((bool)A);
-  EXPECT_EQ(4, A->val);
-  EXPECT_EQ(1u, Immovable::Constructions);
-  EXPECT_EQ(0u, Immovable::Destructions);
-}
-
-// Craft a class which is_trivially_copyable, but not
-// is_trivially_copy_constructible.
-struct NonTCopy {
-  NonTCopy() = default;
-
-  // Delete the volatile copy constructor to engage the "rule of 3" and delete
-  // any unspecified copy assignment or constructor.
-  NonTCopy(volatile NonTCopy const &) = delete;
-
-  // Leave the non-volatile default copy constructor unspecified (deleted by
-  // rule of 3)
-
-  // This template can serve as the copy constructor, but isn't chosen
-  // by =default in a class with a 'NonTCopy' member.
-  template <typename Self = NonTCopy>
-  NonTCopy(Self const &Other) : Val(Other.Val) {}
-
-  NonTCopy &operator=(NonTCopy const &) = default;
-
-  int Val{0};
-};
-
-#if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
-// Currently only true on recent MSVC releases.
-static_assert(std::is_trivially_copyable<NonTCopy>::value,
-              "Expect NonTCopy to be trivially copyable");
-
-static_assert(!std::is_trivially_copy_constructible<NonTCopy>::value,
-              "Expect NonTCopy not to be trivially copy constructible.");
-#endif // defined(_MSC_VER) && _MSC_VER >= 1927
-
-TEST(OptionalTest, DeletedCopyConstructor) {
-
-  // Expect compile to fail if 'trivial' version of
-  // optional_detail::OptionalStorage is chosen.
-  using NonTCopyOptT = Optional<NonTCopy>;
-  NonTCopyOptT NonTCopy1;
-
-  // Check that the Optional can be copy constructed.
-  NonTCopyOptT NonTCopy2{NonTCopy1};
-
-  // Check that the Optional can be copy assigned.
-  NonTCopy1 = NonTCopy2;
-}
-
-// Craft a class which is_trivially_copyable, but not
-// is_trivially_copy_assignable.
-class NonTAssign {
-public:
-  NonTAssign() = default;
-  NonTAssign(NonTAssign const &) = default;
-
-  // Delete the volatile copy assignment to engage the "rule of 3" and delete
-  // any unspecified copy assignment or constructor.
-  NonTAssign &operator=(volatile NonTAssign const &) = delete;
-
-  // Leave the non-volatile default copy assignment unspecified (deleted by rule
-  // of 3).
-
-  // This template can serve as the copy assignment, but isn't chosen
-  // by =default in a class with a 'NonTAssign' member.
-  template <typename Self = NonTAssign>
-  NonTAssign &operator=(Self const &Other) {
-    A = Other.A;
-    return *this;
-  }
-
-  int A{0};
-};
-
-#if defined(_MSC_VER) && _MSC_VER >= 1927 && !defined(__clang__)
-// Currently only true on recent MSVC releases.
-static_assert(std::is_trivially_copyable<NonTAssign>::value,
-              "Expect NonTAssign to be trivially copyable");
-
-static_assert(!std::is_trivially_copy_assignable<NonTAssign>::value,
-              "Expect NonTAssign not to be trivially assignable.");
-#endif // defined(_MSC_VER) && _MSC_VER >= 1927
-
-TEST(OptionalTest, DeletedCopyAssignment) {
-
-  // Expect compile to fail if 'trivial' version of
-  // optional_detail::OptionalStorage is chosen.
-  using NonTAssignOptT = Optional<NonTAssign>;
-  NonTAssignOptT NonTAssign1;
-
-  // Check that the Optional can be copy constructed.
-  NonTAssignOptT NonTAssign2{NonTAssign1};
-
-  // Check that the Optional can be copy assigned.
-  NonTAssign1 = NonTAssign2;
-}
-
-struct NoTMove {
-  NoTMove() = default;
-  NoTMove(NoTMove const &) = default;
-  NoTMove &operator=(NoTMove const &) = default;
-
-  // Delete move constructor / assignment.  Compiler should fall-back to the
-  // trivial copy constructor / assignment in the trivial OptionalStorage
-  // specialization.
-  NoTMove(NoTMove &&) = delete;
-  NoTMove &operator=(NoTMove &&) = delete;
-
-  int Val{0};
-};
-
-TEST(OptionalTest, DeletedMoveConstructor) {
-  using NoTMoveOptT = Optional<NoTMove>;
-
-  NoTMoveOptT NonTMove1;
-  NoTMoveOptT NonTMove2{std::move(NonTMove1)};
-
-  NonTMove1 = std::move(NonTMove2);
-
-  static_assert(
-      std::is_trivially_copyable_v<NoTMoveOptT>,
-      "Expect Optional<NoTMove> to still use the trivial specialization "
-      "of OptionalStorage despite the deleted move constructor / assignment.");
-}
-
-class NoCopyStringMap {
-public:
-  NoCopyStringMap() = default;
-
-private:
-  llvm::StringMap<std::unique_ptr<int>> Map;
-};
-
-TEST(OptionalTest, DeletedCopyStringMap) {
-  // Old versions of gcc (7.3 and prior) instantiate the copy constructor when
-  // std::is_trivially_copyable is instantiated.  This test will fail
-  // compilation if std::is_trivially_copyable is used in the OptionalStorage
-  // specialization condition by gcc <= 7.3.
-  Optional<NoCopyStringMap> TestInstantiation;
-}
-
-TEST(OptionalTest, MoveValueOr) {
-  Optional<MoveOnly> A;
-
-  MoveOnly::ResetCounts();
-  EXPECT_EQ(42, std::move(A).value_or(MoveOnly(42)).val);
-  EXPECT_EQ(1u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(2u, MoveOnly::Destructions);
-
-  A = MoveOnly(5);
-  MoveOnly::ResetCounts();
-  EXPECT_EQ(5, std::move(A).value_or(MoveOnly(42)).val);
-  EXPECT_EQ(1u, MoveOnly::MoveConstructions);
-  EXPECT_EQ(0u, MoveOnly::MoveAssignments);
-  EXPECT_EQ(2u, MoveOnly::Destructions);
-}
-
-struct EqualTo {
-  template <typename T, typename U> static bool apply(const T &X, const U &Y) {
-    return X == Y;
-  }
-};
-
-struct NotEqualTo {
-  template <typename T, typename U> static bool apply(const T &X, const U &Y) {
-    return X != Y;
-  }
-};
-
-struct Less {
-  template <typename T, typename U> static bool apply(const T &X, const U &Y) {
-    return X < Y;
-  }
-};
-
-struct Greater {
-  template <typename T, typename U> static bool apply(const T &X, const U &Y) {
-    return X > Y;
-  }
-};
-
-struct LessEqual {
-  template <typename T, typename U> static bool apply(const T &X, const U &Y) {
-    return X <= Y;
-  }
-};
-
-struct GreaterEqual {
-  template <typename T, typename U> static bool apply(const T &X, const U &Y) {
-    return X >= Y;
-  }
-};
-
-template <typename OperatorT, typename T>
-void CheckRelation(const Optional<T> &Lhs, const Optional<T> &Rhs,
-                   bool Expected) {
-  EXPECT_EQ(Expected, OperatorT::apply(Lhs, Rhs));
-
-  if (Lhs)
-    EXPECT_EQ(Expected, OperatorT::apply(*Lhs, Rhs));
-  else
-    EXPECT_EQ(Expected, OperatorT::apply(std::nullopt, Rhs));
-
-  if (Rhs)
-    EXPECT_EQ(Expected, OperatorT::apply(Lhs, *Rhs));
-  else
-    EXPECT_EQ(Expected, OperatorT::apply(Lhs, std::nullopt));
-}
-
-struct EqualityMock {};
-const Optional<EqualityMock> NoneEq, EqualityLhs((EqualityMock())),
-    EqualityRhs((EqualityMock()));
-bool IsEqual;
-
-bool operator==(const EqualityMock &Lhs, const EqualityMock &Rhs) {
-  EXPECT_EQ(&*EqualityLhs, &Lhs);
-  EXPECT_EQ(&*EqualityRhs, &Rhs);
-  return IsEqual;
-}
-
-TEST(OptionalTest, OperatorEqual) {
-  CheckRelation<EqualTo>(NoneEq, NoneEq, true);
-  CheckRelation<EqualTo>(NoneEq, EqualityRhs, false);
-  CheckRelation<EqualTo>(EqualityLhs, NoneEq, false);
-
-  IsEqual = false;
-  CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
-  IsEqual = true;
-  CheckRelation<EqualTo>(EqualityLhs, EqualityRhs, IsEqual);
-}
-
-TEST(OptionalTest, OperatorNotEqual) {
-  CheckRelation<NotEqualTo>(NoneEq, NoneEq, false);
-  CheckRelation<NotEqualTo>(NoneEq, EqualityRhs, true);
-  CheckRelation<NotEqualTo>(EqualityLhs, NoneEq, true);
-
-  IsEqual = false;
-  CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
-  IsEqual = true;
-  CheckRelation<NotEqualTo>(EqualityLhs, EqualityRhs, !IsEqual);
-}
-
-struct InequalityMock {};
-const Optional<InequalityMock> NoneIneq, InequalityLhs((InequalityMock())),
-    InequalityRhs((InequalityMock()));
-bool IsLess;
-
-bool operator<(const InequalityMock &Lhs, const InequalityMock &Rhs) {
-  EXPECT_EQ(&*InequalityLhs, &Lhs);
-  EXPECT_EQ(&*InequalityRhs, &Rhs);
-  return IsLess;
-}
-
-TEST(OptionalTest, OperatorLess) {
-  CheckRelation<Less>(NoneIneq, NoneIneq, false);
-  CheckRelation<Less>(NoneIneq, InequalityRhs, true);
-  CheckRelation<Less>(InequalityLhs, NoneIneq, false);
-
-  IsLess = false;
-  CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
-  IsLess = true;
-  CheckRelation<Less>(InequalityLhs, InequalityRhs, IsLess);
-}
-
-TEST(OptionalTest, OperatorGreater) {
-  CheckRelation<Greater>(NoneIneq, NoneIneq, false);
-  CheckRelation<Greater>(NoneIneq, InequalityRhs, false);
-  CheckRelation<Greater>(InequalityLhs, NoneIneq, true);
-
-  IsLess = false;
-  CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
-  IsLess = true;
-  CheckRelation<Greater>(InequalityRhs, InequalityLhs, IsLess);
-}
-
-TEST(OptionalTest, OperatorLessEqual) {
-  CheckRelation<LessEqual>(NoneIneq, NoneIneq, true);
-  CheckRelation<LessEqual>(NoneIneq, InequalityRhs, true);
-  CheckRelation<LessEqual>(InequalityLhs, NoneIneq, false);
-
-  IsLess = false;
-  CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
-  IsLess = true;
-  CheckRelation<LessEqual>(InequalityRhs, InequalityLhs, !IsLess);
-}
-
-TEST(OptionalTest, OperatorGreaterEqual) {
-  CheckRelation<GreaterEqual>(NoneIneq, NoneIneq, true);
-  CheckRelation<GreaterEqual>(NoneIneq, InequalityRhs, false);
-  CheckRelation<GreaterEqual>(InequalityLhs, NoneIneq, true);
-
-  IsLess = false;
-  CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
-  IsLess = true;
-  CheckRelation<GreaterEqual>(InequalityLhs, InequalityRhs, !IsLess);
-}
-
-struct ComparableAndStreamable {
-  friend bool operator==(ComparableAndStreamable,
-                         ComparableAndStreamable) LLVM_ATTRIBUTE_USED {
-    return true;
-  }
-
-  friend raw_ostream &operator<<(raw_ostream &OS, ComparableAndStreamable) {
-    return OS << "ComparableAndStreamable";
-  }
-
-  static Optional<ComparableAndStreamable> get() {
-    return ComparableAndStreamable();
-  }
-};
-
-TEST(OptionalTest, StreamOperator) {
-  auto to_string = [](Optional<ComparableAndStreamable> O) {
-    SmallString<16> S;
-    raw_svector_ostream OS(S);
-    OS << O;
-    return S;
-  };
-  EXPECT_EQ("ComparableAndStreamable",
-            to_string(ComparableAndStreamable::get()));
-  EXPECT_EQ("None", to_string(std::nullopt));
-}
-
-struct Comparable {
-  friend bool operator==(Comparable, Comparable) LLVM_ATTRIBUTE_USED {
-    return true;
-  }
-  static Optional<Comparable> get() { return Comparable(); }
-};
-
-TEST(OptionalTest, UseInUnitTests) {
-  // Test that we invoke the streaming operators when pretty-printing values in
-  // EXPECT macros.
-  EXPECT_NONFATAL_FAILURE(
-      EXPECT_EQ(std::nullopt, ComparableAndStreamable::get()),
-      "Expected equality of these values:\n"
-      "  std::nullopt\n"
-      "    Which is: None\n"
-      "  ComparableAndStreamable::get()\n"
-      "    Which is: ComparableAndStreamable");
-
-  // Test that it is still possible to compare objects which do not have a
-  // custom streaming operator.
-  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(std::nullopt, Comparable::get()), "object");
-}
-
-TEST(OptionalTest, HashValue) {
-  // Check that None, false, and true all hash 
diff erently.
-  Optional<bool> B, B0 = false, B1 = true;
-  EXPECT_NE(hash_value(B0), hash_value(B));
-  EXPECT_NE(hash_value(B1), hash_value(B));
-  EXPECT_NE(hash_value(B1), hash_value(B0));
-
-  // Check that None, 0, and 1 all hash 
diff erently.
-  Optional<int> I, I0 = 0, I1 = 1;
-  EXPECT_NE(hash_value(I0), hash_value(I));
-  EXPECT_NE(hash_value(I1), hash_value(I));
-  EXPECT_NE(hash_value(I1), hash_value(I0));
-
-  // Check None hash the same way regardless of type.
-  EXPECT_EQ(hash_value(B), hash_value(I));
-}
-
-struct NotTriviallyCopyable {
-  NotTriviallyCopyable(); // Constructor out-of-line.
-  virtual ~NotTriviallyCopyable() = default;
-  Optional<MoveOnly> MO;
-};
-
-TEST(OptionalTest, GCCIsTriviallyMoveConstructibleCompat) {
-  Optional<NotTriviallyCopyable> V;
-  EXPECT_FALSE(V);
-}
-
-TEST(OptionalTest, DeductionGuide) {
-  Optional V = MoveOnly(1);
-  EXPECT_TRUE(V);
-  EXPECT_EQ(V->val, 1);
-}
-
-static_assert(
-    std::is_same_v<Optional<MoveOnly>, decltype(Optional(MoveOnly(1)))>);
-
-} // end anonymous namespace

diff  --git a/llvm/unittests/Support/TypeTraitsTest.cpp b/llvm/unittests/Support/TypeTraitsTest.cpp
index 734e50afa2db3..845c38d21182b 100644
--- a/llvm/unittests/Support/TypeTraitsTest.cpp
+++ b/llvm/unittests/Support/TypeTraitsTest.cpp
@@ -118,7 +118,10 @@ TEST(Triviality, ADT) {
   TrivialityTester<llvm::StringRef, true, true>();
   TrivialityTester<llvm::ArrayRef<int>, true, true>();
   TrivialityTester<llvm::PointerIntPair<int *, 2>, true, true>();
+#if defined(_LIBCPP_VERSION) ||                                                \
+    (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 8)
   TrivialityTester<llvm::Optional<int>, true, true>();
+#endif
 }
 
 } // namespace triviality

diff  --git a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
index 564425b9beb2c..38c547078bfcd 100644
--- a/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/PybindAdaptors.h
@@ -35,9 +35,6 @@ namespace py = pybind11;
 namespace pybind11 {
 namespace detail {
 
-template <typename T>
-struct type_caster<llvm::Optional<T>> : optional_caster<llvm::Optional<T>> {};
-
 /// Helper to convert a presumed MLIR API object to a capsule, accepting either
 /// an explicit Capsule (which can happen when two C APIs are communicating
 /// directly via Python) or indirectly by querying the MLIR_PYTHON_CAPI_PTR_ATTR

diff  --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h
index a389392301a00..7acf97b5a2531 100644
--- a/mlir/include/mlir/Support/LLVM.h
+++ b/mlir/include/mlir/Support/LLVM.h
@@ -58,8 +58,7 @@ class DenseSet;
 class MallocAllocator;
 template <typename T>
 class MutableArrayRef;
-template <typename T>
-class Optional;
+template <typename T> using Optional = std::optional<T>;
 template <typename... PT>
 class PointerUnion;
 template <typename T, typename Vector, typename Set>

diff  --git a/mlir/lib/Bindings/Python/PybindUtils.h b/mlir/lib/Bindings/Python/PybindUtils.h
index 5356cbd54ff48..d039a8acdca39 100644
--- a/mlir/lib/Bindings/Python/PybindUtils.h
+++ b/mlir/lib/Bindings/Python/PybindUtils.h
@@ -94,9 +94,6 @@ struct MlirDefaultingCaster {
     return pybind11::cast(src, policy);
   }
 };
-
-template <typename T>
-struct type_caster<llvm::Optional<T>> : optional_caster<llvm::Optional<T>> {};
 } // namespace detail
 } // namespace pybind11
 

diff  --git a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
index 860d5d7d60800..692c1e8fb3bf4 100644
--- a/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
+++ b/mlir/lib/Dialect/GPU/Transforms/SerializeToHsaco.cpp
@@ -179,7 +179,7 @@ SerializeToHsacoPass::loadLibraries(SmallVectorImpl<char> &path,
     ret.push_back(std::move(library));
   }
 
-  return ret;
+  return std::move(ret);
 }
 
 std::unique_ptr<llvm::Module>


        


More information about the llvm-commits mailing list