]> granicus.if.org Git - llvm/commitdiff
Revert rL368939 "Remove LVALUE / RVALUE workarounds"
authorRussell Gallop <russell.gallop@gmail.com>
Thu, 15 Aug 2019 10:12:11 +0000 (10:12 +0000)
committerRussell Gallop <russell.gallop@gmail.com>
Thu, 15 Aug 2019 10:12:11 +0000 (10:12 +0000)
This reverts commit cad8356d699b36c73abb267f65db575ddacbd652.

To unbreak Windows bots

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368985 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/Optional.h
include/llvm/Support/Compiler.h
unittests/ADT/OptionalTest.cpp

index 420f21b0d64ae35ef5180aea6c8cc835280c26a2..b45a74002e10c9d6b6bd7aac8456b2e3dca029bb 100644 (file)
@@ -69,18 +69,20 @@ public:
 
   bool hasValue() const noexcept { return hasVal; }
 
-  T &getValue() & noexcept {
+  T &getValue() LLVM_LVALUE_FUNCTION noexcept {
     assert(hasVal);
     return value;
   }
-  T const &getValue() const & noexcept {
+  T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
     assert(hasVal);
     return value;
   }
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
   T &&getValue() && noexcept {
     assert(hasVal);
     return std::move(value);
   }
+#endif
 
   template <class... Args> void emplace(Args &&... args) {
     reset();
@@ -167,19 +169,20 @@ public:
 
   bool hasValue() const noexcept { return hasVal; }
 
-  T &getValue() & noexcept {
+  T &getValue() LLVM_LVALUE_FUNCTION noexcept {
     assert(hasVal);
     return value;
   }
-  T const &getValue() const & noexcept {
+  T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
     assert(hasVal);
     return value;
   }
-
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
   T &&getValue() && noexcept {
     assert(hasVal);
     return std::move(value);
   }
+#endif
 
   template <class... Args> void emplace(Args &&... args) {
     reset();
@@ -249,21 +252,22 @@ public:
 
   const T *getPointer() const { return &Storage.getValue(); }
   T *getPointer() { return &Storage.getValue(); }
-  const T &getValue() const & { return Storage.getValue(); }
-  T &getValue() & { return Storage.getValue(); }
+  const T &getValue() const LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
+  T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
 
   explicit operator bool() const { return hasValue(); }
   bool hasValue() const { return Storage.hasValue(); }
   const T *operator->() const { return getPointer(); }
   T *operator->() { return getPointer(); }
-  const T &operator*() const & { return getValue(); }
-  T &operator*() & { return getValue(); }
+  const T &operator*() const LLVM_LVALUE_FUNCTION { return getValue(); }
+  T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); }
 
   template <typename U>
-  constexpr T getValueOr(U &&value) const & {
+  constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
     return hasValue() ? getValue() : std::forward<U>(value);
   }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
   T &&getValue() && { return std::move(Storage.getValue()); }
   T &&operator*() && { return std::move(Storage.getValue()); }
 
@@ -271,6 +275,7 @@ public:
   T getValueOr(U &&value) && {
     return hasValue() ? std::move(getValue()) : std::forward<U>(value);
   }
+#endif
 };
 
 template <typename T, typename U>
index 8f54db7c826bc6f6c7dde36e15aeb428a0ec5920..43114ad3a43c0e1e74fc38a94c3311dfd1803478 100644 (file)
 #define LLVM_MSC_PREREQ(version) 0
 #endif
 
+/// Does the compiler support ref-qualifiers for *this?
+///
+/// Sadly, this is separate from just rvalue reference support because GCC
+/// and MSVC implemented this later than everything else.
+#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
+#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
+#else
+#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
+#endif
+
+/// Expands to '&' if ref-qualifiers for *this are supported.
+///
+/// This can be used to provide lvalue/rvalue overrides of member functions.
+/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+#define LLVM_LVALUE_FUNCTION &
+#else
+#define LLVM_LVALUE_FUNCTION
+#endif
+
 /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
 /// into a shared library, then the class should be private to the library and
 /// not accessible from outside it.  Can also be used to mark variables and
index 3b58abf57d72c5fd0c3ea0ea5233df808362a292..1f26c101183a0fe6cc06730c128f987a6bf54a96 100644 (file)
@@ -382,6 +382,8 @@ TEST_F(OptionalTest, ImmovableEmplace) {
   EXPECT_EQ(0u, Immovable::Destructions);
 }
 
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+
 TEST_F(OptionalTest, MoveGetValueOr) {
   Optional<MoveOnly> A;
 
@@ -399,6 +401,8 @@ TEST_F(OptionalTest, MoveGetValueOr) {
   EXPECT_EQ(2u, MoveOnly::Destructions);
 }
 
+#endif // LLVM_HAS_RVALUE_REFERENCE_THIS
+
 struct EqualTo {
   template <typename T, typename U> static bool apply(const T &X, const U &Y) {
     return X == Y;