[flang-commits] [flang] 2916b99 - [ADT] Alias llvm::Optional to std::optional
Benjamin Kramer via flang-commits
flang-commits at lists.llvm.org
Mon Dec 19 16:02:12 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 flang-commits
mailing list