From 01812bebcc345b09ce261317b6fdefde8f097642 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Sun, 20 Jan 2013 20:32:30 +0000 Subject: [Support] Port ErrorOr from lld to C++03. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172991 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Support/ErrorOrTest.cpp | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 unittests/Support/ErrorOrTest.cpp (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp new file mode 100644 index 0000000000..1f80aa0cdf --- /dev/null +++ b/unittests/Support/ErrorOrTest.cpp @@ -0,0 +1,78 @@ +//===- unittests/ErrorOrTest.cpp - ErrorOr.h tests ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ErrorOr.h" + +#include "gtest/gtest.h" + +#include + +using namespace llvm; + +namespace { + +ErrorOr t1() {return 1;} +ErrorOr t2() {return make_error_code(errc::invalid_argument);} + +TEST(ErrorOr, SimpleValue) { + ErrorOr a = t1(); + EXPECT_TRUE(a); + EXPECT_EQ(1, *a); + + a = t2(); + EXPECT_FALSE(a); + EXPECT_EQ(errc::invalid_argument, a); + EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists"); +} + +#if LLVM_HAS_CXX11_STDLIB +ErrorOr > t3() { + return std::unique_ptr(new int(3)); +} +#endif + +TEST(ErrorOr, Types) { + int x; + ErrorOr a(x); + *a = 42; + EXPECT_EQ(42, x); + +#if LLVM_HAS_CXX11_STDLIB + // Move only types. + EXPECT_EQ(3, **t3()); +#endif +} +} // end anon namespace + +struct InvalidArgError { + InvalidArgError() {} + InvalidArgError(std::string S) : ArgName(S) {} + std::string ArgName; +}; + +namespace llvm { +template<> +struct ErrorOrUserDataTraits : std::true_type { + static error_code error() { + return make_error_code(errc::invalid_argument); + } +}; +} // end namespace lld + +ErrorOr t4() { + return InvalidArgError("adena"); +} + +namespace { +TEST(ErrorOr, UserErrorData) { + ErrorOr a = t4(); + EXPECT_EQ(errc::invalid_argument, a); + EXPECT_EQ("adena", t4().getError().ArgName); +} +} // end anon namespace -- cgit v1.2.3-70-g09d2 From c052d5b047312195d2722c13af5fdf6d2ebe6bae Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 20 Jan 2013 21:52:27 +0000 Subject: Disable test that fails due to lack of std::true_type in C++03. Michael, can this test be ported to C++03? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172996 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Support/ErrorOrTest.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index 1f80aa0cdf..8ce7160ba3 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -56,6 +56,7 @@ struct InvalidArgError { std::string ArgName; }; +#if LLVM_HAS_CXX11_STDLIB namespace llvm { template<> struct ErrorOrUserDataTraits : std::true_type { @@ -76,3 +77,4 @@ TEST(ErrorOr, UserErrorData) { EXPECT_EQ("adena", t4().getError().ArgName); } } // end anon namespace +#endif -- cgit v1.2.3-70-g09d2 From 7babd25ae44fd96805edaa4fe99bc638740dd164 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Mon, 21 Jan 2013 05:39:07 +0000 Subject: [Support] Make test C++03. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173004 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Support/ErrorOrTest.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index 8ce7160ba3..3181b4fc4b 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -56,15 +56,14 @@ struct InvalidArgError { std::string ArgName; }; -#if LLVM_HAS_CXX11_STDLIB namespace llvm { template<> -struct ErrorOrUserDataTraits : std::true_type { +struct ErrorOrUserDataTraits : true_type { static error_code error() { return make_error_code(errc::invalid_argument); } }; -} // end namespace lld +} // end namespace llvm ErrorOr t4() { return InvalidArgError("adena"); @@ -77,4 +76,3 @@ TEST(ErrorOr, UserErrorData) { EXPECT_EQ("adena", t4().getError().ArgName); } } // end anon namespace -#endif -- cgit v1.2.3-70-g09d2 From 93d61374f3a12251aa6cc24bea0e0829ad23cdd0 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 22 Jan 2013 04:02:41 +0000 Subject: ErrorOrTest.cpp: Check existence of EXPECT_DEBUG_DEATH. It is not always available. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173123 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Support/ErrorOrTest.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index 3181b4fc4b..b30895cdbd 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -28,7 +28,9 @@ TEST(ErrorOr, SimpleValue) { a = t2(); EXPECT_FALSE(a); EXPECT_EQ(errc::invalid_argument, a); +#ifdef EXPECT_DEBUG_DEATH EXPECT_DEBUG_DEATH(*a, "Cannot get value when an error exists"); +#endif } #if LLVM_HAS_CXX11_STDLIB -- cgit v1.2.3-70-g09d2 From bdd4e1311830bea92c8b8c09f0644cba15421241 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Wed, 23 Jan 2013 00:18:31 +0000 Subject: [Support][ErrorOr] Add optimized specialization of ErrorOr. ErrorOr represents an operation that returns nothing, but can still fail. It should be used in cases where you need the aditional user data that ErrorOr provides over error_code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173209 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ErrorOr.h | 99 ++++++++++++++++++++++++++++++++++++++- unittests/Support/ErrorOrTest.cpp | 11 +++++ 2 files changed, 109 insertions(+), 1 deletion(-) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index bc708a2af4..13705c887e 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -16,6 +16,7 @@ #ifndef LLVM_SUPPORT_ERROR_OR_H #define LLVM_SUPPORT_ERROR_OR_H +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/system_error.h" #include "llvm/Support/type_traits.h" @@ -257,6 +258,7 @@ public: return *this; } +#endif ~ErrorOr() { if (!IsValid) @@ -266,7 +268,6 @@ public: else get()->~storage_type(); } -#endif template ET getError() const { @@ -331,6 +332,102 @@ protected: bool IsValid : 1; }; +// ErrorOr specialization for void. +template <> +class ErrorOr { +public: + ErrorOr() : Error(nullptr, 0) {} + + ErrorOr(llvm::error_code EC) : Error(nullptr, 0) { + if (EC == errc::success) { + Error.setInt(1); + return; + } + ErrorHolderBase *E = new ErrorHolderBase; + E->Error = EC; + E->HasUserData = false; + Error.setPointer(E); + } + + template + ErrorOr(UserDataT UD, typename + enable_if_c::value>::type* = 0) + : Error(nullptr, 0) { + ErrorHolderBase *E = new ErrorHolder(llvm_move(UD)); + E->Error = ErrorOrUserDataTraits::error(); + E->HasUserData = true; + Error.setPointer(E); + } + + ErrorOr(const ErrorOr &Other) : Error(nullptr, 0) { + Error = Other.Error; + if (Other.Error.getPointer()->Error) { + Error.getPointer()->aquire(); + } + } + + ErrorOr &operator =(const ErrorOr &Other) { + if (this == &Other) + return *this; + + this->~ErrorOr(); + new (this) ErrorOr(Other); + + return *this; + } + +#if LLVM_HAS_RVALUE_REFERENCES + ErrorOr(ErrorOr &&Other) : Error(nullptr) { + // Get other's error. + Error = Other.Error; + // Tell other not to do any destruction. + Other.Error.setPointer(nullptr); + } + + ErrorOr &operator =(ErrorOr &&Other) { + if (this == &Other) + return *this; + + this->~ErrorOr(); + new (this) ErrorOr(std::move(Other)); + + return *this; + } +#endif + + ~ErrorOr() { + if (Error.getPointer()) + Error.getPointer()->release(); + } + + template + ET getError() const { + assert(ErrorOrUserDataTraits::error() == *this && + "Incorrect user error data type for error!"); + if (!Error.getPointer()->HasUserData) + return ET(); + return reinterpret_cast *>( + Error.getPointer())->UserData; + } + + typedef void (*unspecified_bool_type)(); + static void unspecified_bool_true() {} + + /// \brief Return false if there is an error. + operator unspecified_bool_type() const { + return Error.getInt() ? unspecified_bool_true : 0; + } + + operator llvm::error_code() const { + return Error.getInt() ? make_error_code(errc::success) + : Error.getPointer()->Error; + } + +private: + // If the bit is 1, the error is success. + llvm::PointerIntPair Error; +}; + template typename enable_if_c::value || is_error_condition_enum::value, bool>::type diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index b30895cdbd..a8608860b8 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -45,6 +45,9 @@ TEST(ErrorOr, Types) { *a = 42; EXPECT_EQ(42, x); + EXPECT_FALSE(ErrorOr(make_error_code(errc::broken_pipe))); + EXPECT_TRUE(ErrorOr(make_error_code(errc::success))); + #if LLVM_HAS_CXX11_STDLIB // Move only types. EXPECT_EQ(3, **t3()); @@ -71,10 +74,18 @@ ErrorOr t4() { return InvalidArgError("adena"); } +ErrorOr t5() { + return InvalidArgError("pie"); +} + namespace { TEST(ErrorOr, UserErrorData) { ErrorOr a = t4(); EXPECT_EQ(errc::invalid_argument, a); EXPECT_EQ("adena", t4().getError().ArgName); + + ErrorOr b = t5(); + EXPECT_EQ(errc::invalid_argument, b); + EXPECT_EQ("pie", b.getError().ArgName); } } // end anon namespace -- cgit v1.2.3-70-g09d2 From a33e1fafac7fedb1b080ef07ddf9ad6ddff3a830 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Tue, 5 Feb 2013 08:22:27 +0000 Subject: [Support][ErrorOr] Add support for convertable types. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174357 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ErrorOr.h | 8 +++++--- unittests/Support/ErrorOrTest.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index 452d85ceec..653b9e5c88 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -162,6 +162,7 @@ public: /// T cannot be a rvalue reference. template class ErrorOr { + template friend class ErrorOr; static const bool isRef = is_reference::value; typedef ReferenceStorage::type> wrap; @@ -198,7 +199,8 @@ public: new (get()) storage_type(moveIfMoveConstructible(Val)); } - ErrorOr(const ErrorOr &Other) : IsValid(false) { + template + ErrorOr(ErrorOr &Other) : IsValid(false) { // Construct an invalid ErrorOr if other is invalid. if (!Other.IsValid) return; @@ -227,7 +229,8 @@ public: } #if LLVM_HAS_RVALUE_REFERENCES - ErrorOr(ErrorOr &&Other) : IsValid(false) { + template + ErrorOr(ErrorOr &&Other) : IsValid(false) { // Construct an invalid ErrorOr if other is invalid. if (!Other.IsValid) return; @@ -311,7 +314,6 @@ private: return &Val->get(); } -protected: storage_type *get() { assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); assert(!HasError && "Cannot get value when an error exists!"); diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index a8608860b8..6cef4fc212 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -53,6 +53,17 @@ TEST(ErrorOr, Types) { EXPECT_EQ(3, **t3()); #endif } + +struct B {}; +struct D : B {}; + +TEST(ErrorOr, Covariant) { + ErrorOr b(ErrorOr(0)); + +#if LLVM_HAS_CXX11_STDLIB + ErrorOr > b1(ErrorOr >(0)); +#endif +} } // end anon namespace struct InvalidArgError { -- cgit v1.2.3-70-g09d2 From 2a78bb961ad99cfc9ae4e8a05a9a5a6bf84e41f3 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 5 Feb 2013 22:50:20 +0000 Subject: Revert "[Support][ErrorOr] Add support for convertable types." This reverts commit a33e1fafac7fedb1b080ef07ddf9ad6ddff3a830. This unit test crashes on Darwon. It needs to be temporarily reverted to unblock the test infrastructure. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174458 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ErrorOr.h | 8 +++----- unittests/Support/ErrorOrTest.cpp | 11 ----------- 2 files changed, 3 insertions(+), 16 deletions(-) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index c22c3ca84f..828d77b852 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -162,7 +162,6 @@ public: /// T cannot be a rvalue reference. template class ErrorOr { - template friend class ErrorOr; static const bool isRef = is_reference::value; typedef ReferenceStorage::type> wrap; @@ -199,8 +198,7 @@ public: new (get()) storage_type(moveIfMoveConstructible(Val)); } - template - ErrorOr(ErrorOr &Other) : IsValid(false) { + ErrorOr(const ErrorOr &Other) : IsValid(false) { // Construct an invalid ErrorOr if other is invalid. if (!Other.IsValid) return; @@ -228,8 +226,7 @@ public: } #if LLVM_HAS_RVALUE_REFERENCES - template - ErrorOr(ErrorOr &&Other) : IsValid(false) { + ErrorOr(ErrorOr &&Other) : IsValid(false) { // Construct an invalid ErrorOr if other is invalid. if (!Other.IsValid) return; @@ -311,6 +308,7 @@ private: return &Val->get(); } +protected: storage_type *get() { assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); assert(!HasError && "Cannot get value when an error exists!"); diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index 6cef4fc212..a8608860b8 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -53,17 +53,6 @@ TEST(ErrorOr, Types) { EXPECT_EQ(3, **t3()); #endif } - -struct B {}; -struct D : B {}; - -TEST(ErrorOr, Covariant) { - ErrorOr b(ErrorOr(0)); - -#if LLVM_HAS_CXX11_STDLIB - ErrorOr > b1(ErrorOr >(0)); -#endif -} } // end anon namespace struct InvalidArgError { -- cgit v1.2.3-70-g09d2 From 780e9004c85ee33a0bdd592aebe9b959f29c4fb2 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Wed, 6 Feb 2013 22:28:53 +0000 Subject: [Support][ErrorOr] Add support for convertable types. Thanks to Andrew, David, and Aaron for helping fix this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174552 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ErrorOr.h | 136 ++++++++++++++++++++++++++------------ unittests/Support/ErrorOrTest.cpp | 13 ++++ 2 files changed, 107 insertions(+), 42 deletions(-) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index 828d77b852..ceec33d185 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -162,6 +162,7 @@ public: /// T cannot be a rvalue reference. template class ErrorOr { + template friend class ErrorOr; static const bool isRef = is_reference::value; typedef ReferenceStorage::type> wrap; @@ -199,60 +200,43 @@ public: } ErrorOr(const ErrorOr &Other) : IsValid(false) { - // Construct an invalid ErrorOr if other is invalid. - if (!Other.IsValid) - return; - IsValid = true; - if (!Other.HasError) { - // Get the other value. - HasError = false; - new (get()) storage_type(*Other.get()); - } else { - // Get other's error. - Error = Other.Error; - HasError = true; - Error->aquire(); - } + copyConstruct(Other); } - ErrorOr &operator =(const ErrorOr &Other) { - if (this == &Other) - return *this; + template + ErrorOr(const ErrorOr &Other) : IsValid(false) { + copyConstruct(Other); + } - this->~ErrorOr(); - new (this) ErrorOr(Other); + ErrorOr &operator =(const ErrorOr &Other) { + copyAssign(Other); + return *this; + } + template + ErrorOr &operator =(const ErrorOr &Other) { + copyAssign(Other); return *this; } #if LLVM_HAS_RVALUE_REFERENCES ErrorOr(ErrorOr &&Other) : IsValid(false) { - // Construct an invalid ErrorOr if other is invalid. - if (!Other.IsValid) - return; - IsValid = true; - if (!Other.HasError) { - // Get the other value. - HasError = false; - new (get()) storage_type(std::move(*Other.get())); - // Tell other not to do any destruction. - Other.IsValid = false; - } else { - // Get other's error. - Error = Other.Error; - HasError = true; - // Tell other not to do any destruction. - Other.IsValid = false; - } + moveConstruct(std::move(Other)); } - ErrorOr &operator =(ErrorOr &&Other) { - if (this == &Other) - return *this; + template + ErrorOr(ErrorOr &&Other) : IsValid(false) { + moveConstruct(std::move(Other)); + } - this->~ErrorOr(); - new (this) ErrorOr(std::move(Other)); + ErrorOr &operator =(ErrorOr &&Other) { + moveAssign(std::move(Other)); + return *this; + } + template + ErrorOr &operator =(ErrorOr &&Other) { + moveAssign(std::move(Other)); return *this; } #endif @@ -300,6 +284,75 @@ public: } private: + template + void copyConstruct(const ErrorOr &Other) { + // Construct an invalid ErrorOr if other is invalid. + if (!Other.IsValid) + return; + IsValid = true; + if (!Other.HasError) { + // Get the other value. + HasError = false; + new (get()) storage_type(*Other.get()); + } else { + // Get other's error. + Error = Other.Error; + HasError = true; + Error->aquire(); + } + } + + template + static bool compareThisIfSameType(const T1 &a, const T1 &b) { + return &a == &b; + } + + template + static bool compareThisIfSameType(const T1 &a, const T2 &b) { + return false; + } + + template + void copyAssign(const ErrorOr &Other) { + if (compareThisIfSameType(*this, Other)) + return; + + this->~ErrorOr(); + new (this) ErrorOr(Other); + } + +#if LLVM_HAS_RVALUE_REFERENCES + template + void moveConstruct(ErrorOr &&Other) { + // Construct an invalid ErrorOr if other is invalid. + if (!Other.IsValid) + return; + IsValid = true; + if (!Other.HasError) { + // Get the other value. + HasError = false; + new (get()) storage_type(std::move(*Other.get())); + // Tell other not to do any destruction. + Other.IsValid = false; + } else { + // Get other's error. + Error = Other.Error; + HasError = true; + // Tell other not to do any destruction. + Other.IsValid = false; + } + } + + template + void moveAssign(ErrorOr &&Other) { + if (compareThisIfSameType(*this, Other)) + return; + + this->~ErrorOr(); + new (this) ErrorOr(std::move(Other)); + } +#endif + pointer toPointer(pointer Val) { return Val; } @@ -308,7 +361,6 @@ private: return &Val->get(); } -protected: storage_type *get() { assert(IsValid && "Can't do anything on a default constructed ErrorOr!"); assert(!HasError && "Cannot get value when an error exists!"); diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index a8608860b8..aa0ddd5e79 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -53,6 +53,19 @@ TEST(ErrorOr, Types) { EXPECT_EQ(3, **t3()); #endif } + +struct B {}; +struct D : B {}; + +TEST(ErrorOr, Covariant) { + ErrorOr b(ErrorOr(0)); + b = ErrorOr(0); + +#if LLVM_HAS_CXX11_STDLIB + ErrorOr > b1(ErrorOr >(0)); + b1 = ErrorOr >(0); +#endif +} } // end anon namespace struct InvalidArgError { -- cgit v1.2.3-70-g09d2 From 9b4886ee55c4d13cf0f663fe0ee5e0cfacb39667 Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Thu, 28 Feb 2013 01:44:26 +0000 Subject: [Support][ErrorOr] Add support for implicit conversion from error code/condition enums. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176228 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ErrorOr.h | 26 ++++++++++++++++++++++++++ unittests/Support/ErrorOrTest.cpp | 6 +++--- 2 files changed, 29 insertions(+), 3 deletions(-) (limited to 'unittests/Support/ErrorOrTest.cpp') diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index ceec33d185..f3ac305fe7 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -180,6 +180,16 @@ private: public: ErrorOr() : IsValid(false) {} + template + ErrorOr(E ErrorCode, typename enable_if_c::value || + is_error_condition_enum::value, + void *>::type = 0) + : HasError(true), IsValid(true) { + Error = new ErrorHolderBase; + Error->Error = make_error_code(ErrorCode); + Error->HasUserData = false; + } + ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) { Error = new ErrorHolderBase; Error->Error = EC; @@ -387,6 +397,22 @@ class ErrorOr { public: ErrorOr() : Error(0, 0) {} + template + ErrorOr(E ErrorCode, typename enable_if_c::value || + is_error_condition_enum::value, + void *> ::type = 0) + : Error(0, 0) { + error_code EC = make_error_code(ErrorCode); + if (EC == errc::success) { + Error.setInt(1); + return; + } + ErrorHolderBase *EHB = new ErrorHolderBase; + EHB->Error = EC; + EHB->HasUserData = false; + Error.setPointer(EHB); + } + ErrorOr(llvm::error_code EC) : Error(0, 0) { if (EC == errc::success) { Error.setInt(1); diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp index aa0ddd5e79..4853426c94 100644 --- a/unittests/Support/ErrorOrTest.cpp +++ b/unittests/Support/ErrorOrTest.cpp @@ -18,7 +18,7 @@ using namespace llvm; namespace { ErrorOr t1() {return 1;} -ErrorOr t2() {return make_error_code(errc::invalid_argument);} +ErrorOr t2() { return errc::invalid_argument; } TEST(ErrorOr, SimpleValue) { ErrorOr a = t1(); @@ -45,8 +45,8 @@ TEST(ErrorOr, Types) { *a = 42; EXPECT_EQ(42, x); - EXPECT_FALSE(ErrorOr(make_error_code(errc::broken_pipe))); - EXPECT_TRUE(ErrorOr(make_error_code(errc::success))); + EXPECT_FALSE(ErrorOr(errc::broken_pipe)); + EXPECT_TRUE(ErrorOr(errc::success)); #if LLVM_HAS_CXX11_STDLIB // Move only types. -- cgit v1.2.3-70-g09d2