Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 4ed5b9a

Browse files
committed
Revert rL368939 "Remove LVALUE / RVALUE workarounds"
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
1 parent c996b8c commit 4ed5b9a

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

include/llvm/ADT/Optional.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,20 @@ class OptionalStorage {
6969

7070
bool hasValue() const noexcept { return hasVal; }
7171

72-
T &getValue() & noexcept {
72+
T &getValue() LLVM_LVALUE_FUNCTION noexcept {
7373
assert(hasVal);
7474
return value;
7575
}
76-
T const &getValue() const & noexcept {
76+
T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
7777
assert(hasVal);
7878
return value;
7979
}
80+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
8081
T &&getValue() && noexcept {
8182
assert(hasVal);
8283
return std::move(value);
8384
}
85+
#endif
8486

8587
template <class... Args> void emplace(Args &&... args) {
8688
reset();
@@ -167,19 +169,20 @@ template <typename T> class OptionalStorage<T, true> {
167169

168170
bool hasValue() const noexcept { return hasVal; }
169171

170-
T &getValue() & noexcept {
172+
T &getValue() LLVM_LVALUE_FUNCTION noexcept {
171173
assert(hasVal);
172174
return value;
173175
}
174-
T const &getValue() const & noexcept {
176+
T const &getValue() const LLVM_LVALUE_FUNCTION noexcept {
175177
assert(hasVal);
176178
return value;
177179
}
178-
180+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
179181
T &&getValue() && noexcept {
180182
assert(hasVal);
181183
return std::move(value);
182184
}
185+
#endif
183186

184187
template <class... Args> void emplace(Args &&... args) {
185188
reset();
@@ -249,28 +252,30 @@ template <typename T> class Optional {
249252

250253
const T *getPointer() const { return &Storage.getValue(); }
251254
T *getPointer() { return &Storage.getValue(); }
252-
const T &getValue() const & { return Storage.getValue(); }
253-
T &getValue() & { return Storage.getValue(); }
255+
const T &getValue() const LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
256+
T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); }
254257

255258
explicit operator bool() const { return hasValue(); }
256259
bool hasValue() const { return Storage.hasValue(); }
257260
const T *operator->() const { return getPointer(); }
258261
T *operator->() { return getPointer(); }
259-
const T &operator*() const & { return getValue(); }
260-
T &operator*() & { return getValue(); }
262+
const T &operator*() const LLVM_LVALUE_FUNCTION { return getValue(); }
263+
T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); }
261264

262265
template <typename U>
263-
constexpr T getValueOr(U &&value) const & {
266+
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
264267
return hasValue() ? getValue() : std::forward<U>(value);
265268
}
266269

270+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
267271
T &&getValue() && { return std::move(Storage.getValue()); }
268272
T &&operator*() && { return std::move(Storage.getValue()); }
269273

270274
template <typename U>
271275
T getValueOr(U &&value) && {
272276
return hasValue() ? std::move(getValue()) : std::forward<U>(value);
273277
}
278+
#endif
274279
};
275280

276281
template <typename T, typename U>

include/llvm/Support/Compiler.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,26 @@
8383
#define LLVM_MSC_PREREQ(version) 0
8484
#endif
8585

86+
/// Does the compiler support ref-qualifiers for *this?
87+
///
88+
/// Sadly, this is separate from just rvalue reference support because GCC
89+
/// and MSVC implemented this later than everything else.
90+
#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
91+
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
92+
#else
93+
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
94+
#endif
95+
96+
/// Expands to '&' if ref-qualifiers for *this are supported.
97+
///
98+
/// This can be used to provide lvalue/rvalue overrides of member functions.
99+
/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
100+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
101+
#define LLVM_LVALUE_FUNCTION &
102+
#else
103+
#define LLVM_LVALUE_FUNCTION
104+
#endif
105+
86106
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
87107
/// into a shared library, then the class should be private to the library and
88108
/// not accessible from outside it. Can also be used to mark variables and

unittests/ADT/OptionalTest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ TEST_F(OptionalTest, ImmovableEmplace) {
382382
EXPECT_EQ(0u, Immovable::Destructions);
383383
}
384384

385+
#if LLVM_HAS_RVALUE_REFERENCE_THIS
386+
385387
TEST_F(OptionalTest, MoveGetValueOr) {
386388
Optional<MoveOnly> A;
387389

@@ -399,6 +401,8 @@ TEST_F(OptionalTest, MoveGetValueOr) {
399401
EXPECT_EQ(2u, MoveOnly::Destructions);
400402
}
401403

404+
#endif // LLVM_HAS_RVALUE_REFERENCE_THIS
405+
402406
struct EqualTo {
403407
template <typename T, typename U> static bool apply(const T &X, const U &Y) {
404408
return X == Y;

0 commit comments

Comments
 (0)