aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Gallop <russell.gallop@gmail.com>2019-08-15 10:12:11 +0000
committerRussell Gallop <russell.gallop@gmail.com>2019-08-15 10:12:11 +0000
commit2601cdd3aed5d90b574e4a681462667b25577bcd (patch)
tree1b5ffad88a2028661db19ec0580ac0dcd7d6f095
parent0096d1938ef7656f4eb30c8d3cd6999b146eaa14 (diff)
downloadllvm-2601cdd3aed5d90b574e4a681462667b25577bcd.zip
llvm-2601cdd3aed5d90b574e4a681462667b25577bcd.tar.gz
llvm-2601cdd3aed5d90b574e4a681462667b25577bcd.tar.bz2
Revert rL368939 "Remove LVALUE / RVALUE workarounds"
This reverts commit cad8356d699b36c73abb267f65db575ddacbd652. To unbreak Windows bots llvm-svn: 368985
-rw-r--r--clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h2
-rw-r--r--llvm/include/llvm/ADT/Optional.h25
-rw-r--r--llvm/include/llvm/Support/Compiler.h20
-rw-r--r--llvm/unittests/ADT/OptionalTest.cpp4
4 files changed, 40 insertions, 11 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 07fb937..598e2f6 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -167,7 +167,7 @@ public:
const ProgramStateRef &getState() const { return State; }
template <typename T>
- Optional<T> getLocationAs() const & {
+ Optional<T> getLocationAs() const LLVM_LVALUE_FUNCTION {
return Location.getAs<T>();
}
diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h
index 420f21b..b45a740 100644
--- a/llvm/include/llvm/ADT/Optional.h
+++ b/llvm/include/llvm/ADT/Optional.h
@@ -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>
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 8f54db7..43114ad 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -83,6 +83,26 @@
#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
diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp
index 3b58abf..1f26c10 100644
--- a/llvm/unittests/ADT/OptionalTest.cpp
+++ b/llvm/unittests/ADT/OptionalTest.cpp
@@ -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;