diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h index 47bd90bb1bad..5b72a4a54dda 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/include/llvm/ExecutionEngine/Orc/RPCUtils.h @@ -207,73 +207,6 @@ class RPCFunctionIdAllocator< namespace detail { -// FIXME: Remove MSVCPError/MSVCPExpected once MSVC's future implementation -// supports classes without default constructors. -#ifdef _MSC_VER - -namespace msvc_hacks { - -// Work around MSVC's future implementation's use of default constructors: -// A default constructed value in the promise will be overwritten when the -// real error is set - so the default constructed Error has to be checked -// already. -class MSVCPError : public Error { -public: - MSVCPError() { (void)!!*this; } - - MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {} - - MSVCPError &operator=(MSVCPError Other) { - Error::operator=(std::move(Other)); - return *this; - } - - MSVCPError(Error Err) : Error(std::move(Err)) {} -}; - -// Work around MSVC's future implementation, similar to MSVCPError. -template class MSVCPExpected : public Expected { -public: - MSVCPExpected() - : Expected(make_error("", inconvertibleErrorCode())) { - consumeError(this->takeError()); - } - - MSVCPExpected(MSVCPExpected &&Other) : Expected(std::move(Other)) {} - - MSVCPExpected &operator=(MSVCPExpected &&Other) { - Expected::operator=(std::move(Other)); - return *this; - } - - MSVCPExpected(Error Err) : Expected(std::move(Err)) {} - - template - MSVCPExpected( - OtherT &&Val, - typename std::enable_if::value>::type * = - nullptr) - : Expected(std::move(Val)) {} - - template - MSVCPExpected( - Expected &&Other, - typename std::enable_if::value>::type * = - nullptr) - : Expected(std::move(Other)) {} - - template - explicit MSVCPExpected( - Expected &&Other, - typename std::enable_if::value>::type * = - nullptr) - : Expected(std::move(Other)) {} -}; - -} // end namespace msvc_hacks - -#endif // _MSC_VER - /// Provides a typedef for a tuple containing the decayed argument types. template class FunctionArgsTuple; @@ -293,10 +226,10 @@ template class ResultTraits { #ifdef _MSC_VER // The ErrorReturnType wrapped in a std::promise. - using ReturnPromiseType = std::promise>; + using ReturnPromiseType = std::promise>; // The ErrorReturnType wrapped in a std::future. - using ReturnFutureType = std::future>; + using ReturnFutureType = std::future>; #else // The ErrorReturnType wrapped in a std::promise. using ReturnPromiseType = std::promise; @@ -325,10 +258,10 @@ template <> class ResultTraits { #ifdef _MSC_VER // The ErrorReturnType wrapped in a std::promise. - using ReturnPromiseType = std::promise; + using ReturnPromiseType = std::promise; // The ErrorReturnType wrapped in a std::future. - using ReturnFutureType = std::future; + using ReturnFutureType = std::future; #else // The ErrorReturnType wrapped in a std::promise. using ReturnPromiseType = std::promise; diff --git a/include/llvm/Support/MSVCErrorWorkarounds.h b/include/llvm/Support/MSVCErrorWorkarounds.h new file mode 100644 index 000000000000..13c78358e5cd --- /dev/null +++ b/include/llvm/Support/MSVCErrorWorkarounds.h @@ -0,0 +1,86 @@ +//===--- MSVCErrorWorkarounds.h - Enable future in MSVC --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// MSVC's promise/future implementation requires types to be default +// constructible, so this header provides analogues of Error an Expected +// that are default constructed in a safely destructible state. +// +// FIXME: Kill off this header and migrate all users to Error/Expected once we +// move to MSVC versions that support non-default-constructible types. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H +#define LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H + +#include "llvm/Support/Error.h" + +namespace llvm { +namespace orc { + +// A default-constructible llvm::Error that is suitable for use with MSVC's +// std::future implementation which requires default constructible types. +class MSVCPError : public Error { +public: + MSVCPError() { (void)!!*this; } + + MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {} + + MSVCPError &operator=(MSVCPError Other) { + Error::operator=(std::move(Other)); + return *this; + } + + MSVCPError(Error Err) : Error(std::move(Err)) {} +}; + +// A default-constructible llvm::Expected that is suitable for use with MSVC's +// std::future implementation, which requires default constructible types. +template class MSVCPExpected : public Expected { +public: + MSVCPExpected() + : Expected(make_error("", inconvertibleErrorCode())) { + consumeError(this->takeError()); + } + + MSVCPExpected(MSVCPExpected &&Other) : Expected(std::move(Other)) {} + + MSVCPExpected &operator=(MSVCPExpected &&Other) { + Expected::operator=(std::move(Other)); + return *this; + } + + MSVCPExpected(Error Err) : Expected(std::move(Err)) {} + + template + MSVCPExpected( + OtherT &&Val, + typename std::enable_if::value>::type * = + nullptr) + : Expected(std::move(Val)) {} + + template + MSVCPExpected( + Expected &&Other, + typename std::enable_if::value>::type * = + nullptr) + : Expected(std::move(Other)) {} + + template + explicit MSVCPExpected( + Expected &&Other, + typename std::enable_if::value>::type * = + nullptr) + : Expected(std::move(Other)) {} +}; + +} // end namespace orc +} // end namespace llvm + +#endif // LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H