summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Support/ErrorOr.h219
-rw-r--r--unittests/Support/ErrorOrTest.cpp38
2 files changed, 5 insertions, 252 deletions
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
index 6832e3df2f..148494c5d8 100644
--- a/include/llvm/Support/ErrorOr.h
+++ b/include/llvm/Support/ErrorOr.h
@@ -27,38 +27,6 @@
#endif
namespace llvm {
-struct ErrorHolderBase {
- error_code Error;
- uint16_t RefCount;
- bool HasUserData;
-
- ErrorHolderBase() : RefCount(1) {}
-
- void acquire() {
- ++RefCount;
- }
-
- void release() {
- if (--RefCount == 0)
- delete this;
- }
-
-protected:
- virtual ~ErrorHolderBase() {}
-};
-
-template<class T>
-struct ErrorHolder : ErrorHolderBase {
-#if LLVM_HAS_RVALUE_REFERENCES
- ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {}
-#else
- ErrorHolder(T &UD) : UserData(UD) {}
-#endif
- T UserData;
-};
-
-template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type {};
-
#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES
template<class T, class V>
typename std::enable_if< std::is_constructible<T, V>::value
@@ -111,44 +79,6 @@ public:
/// buffer->write("adena");
/// \endcode
///
-/// ErrorOr<T> also supports user defined data for specific error_codes. To use
-/// this feature you must first add a template specialization of
-/// ErrorOrUserDataTraits derived from std::true_type for your type in the lld
-/// namespace. This specialization must have a static error_code error()
-/// function that returns the error_code this data is used with.
-///
-/// getError<UserData>() may be called to get either the stored user data, or
-/// a default constructed UserData if none was stored.
-///
-/// Example:
-/// \code
-/// struct InvalidArgError {
-/// InvalidArgError() {}
-/// InvalidArgError(std::string S) : ArgName(S) {}
-/// std::string ArgName;
-/// };
-///
-/// namespace llvm {
-/// template<>
-/// struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type {
-/// static error_code error() {
-/// return make_error_code(errc::invalid_argument);
-/// }
-/// };
-/// } // end namespace llvm
-///
-/// using namespace llvm;
-///
-/// ErrorOr<int> foo() {
-/// return InvalidArgError("adena");
-/// }
-///
-/// int main() {
-/// auto a = foo();
-/// if (!a && error_code(a) == errc::invalid_argument)
-/// llvm::errs() << a.getError<InvalidArgError>().ArgName << "\n";
-/// }
-/// \endcode
///
/// An implicit conversion to bool provides a way to check if there was an
/// error. The unary * and -> operators provide pointer like access to the
@@ -185,24 +115,11 @@ public:
is_error_condition_enum<E>::value,
void *>::type = 0)
: HasError(true), IsValid(true) {
- Error = new ErrorHolderBase;
- Error->Error = make_error_code(ErrorCode);
- Error->HasUserData = false;
+ Error = make_error_code(ErrorCode);
}
ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {
- Error = new ErrorHolderBase;
- Error->Error = EC;
- Error->HasUserData = false;
- }
-
- template<class UserDataT>
- ErrorOr(UserDataT UD, typename
- enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
- : HasError(true), IsValid(true) {
- Error = new ErrorHolder<UserDataT>(llvm_move(UD));
- Error->Error = ErrorOrUserDataTraits<UserDataT>::error();
- Error->HasUserData = true;
+ Error = EC;
}
ErrorOr(T Val) : HasError(false), IsValid(true) {
@@ -254,23 +171,10 @@ public:
~ErrorOr() {
if (!IsValid)
return;
- if (HasError)
- Error->release();
- else
+ if (!HasError)
get()->~storage_type();
}
- template<class ET>
- ET getError() const {
- assert(IsValid && "Cannot get the error of a default constructed ErrorOr!");
- assert(HasError && "Cannot get an error if none exists!");
- assert(ErrorOrUserDataTraits<ET>::error() == Error->Error &&
- "Incorrect user error data type for error!");
- if (!Error->HasUserData)
- return ET();
- return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData;
- }
-
typedef void (*unspecified_bool_type)();
static void unspecified_bool_true() {}
@@ -282,7 +186,7 @@ public:
operator llvm::error_code() const {
assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
- return HasError ? Error->Error : llvm::error_code::success();
+ return HasError ? Error : llvm::error_code::success();
}
pointer operator ->() {
@@ -308,7 +212,6 @@ private:
// Get other's error.
Error = Other.Error;
HasError = true;
- Error->acquire();
}
}
@@ -385,124 +288,12 @@ private:
union {
AlignedCharArrayUnion<storage_type> TStorage;
- ErrorHolderBase *Error;
+ error_code Error;
};
bool HasError : 1;
bool IsValid : 1;
};
-// ErrorOr specialization for void.
-template <>
-class ErrorOr<void> {
-public:
- ErrorOr() : Error(0, 0) {}
-
- template <class E>
- ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value ||
- is_error_condition_enum<E>::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);
- return;
- }
- ErrorHolderBase *E = new ErrorHolderBase;
- E->Error = EC;
- E->HasUserData = false;
- Error.setPointer(E);
- }
-
- template<class UserDataT>
- ErrorOr(UserDataT UD, typename
- enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
- : Error(0, 0) {
- ErrorHolderBase *E = new ErrorHolder<UserDataT>(llvm_move(UD));
- E->Error = ErrorOrUserDataTraits<UserDataT>::error();
- E->HasUserData = true;
- Error.setPointer(E);
- }
-
- ErrorOr(const ErrorOr &Other) : Error(0, 0) {
- Error = Other.Error;
- if (Other.Error.getPointer()->Error) {
- Error.getPointer()->acquire();
- }
- }
-
- 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(0) {
- // Get other's error.
- Error = Other.Error;
- // Tell other not to do any destruction.
- Other.Error.setPointer(0);
- }
-
- 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<class ET>
- ET getError() const {
- assert(ErrorOrUserDataTraits<ET>::error() == *this &&
- "Incorrect user error data type for error!");
- if (!Error.getPointer()->HasUserData)
- return ET();
- return reinterpret_cast<const ErrorHolder<ET> *>(
- 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<ErrorHolderBase *, 1> Error;
-};
-
template<class T, class E>
typename enable_if_c<is_error_code_enum<E>::value ||
is_error_condition_enum<E>::value, bool>::type
diff --git a/unittests/Support/ErrorOrTest.cpp b/unittests/Support/ErrorOrTest.cpp
index 4853426c94..feb6a086e1 100644
--- a/unittests/Support/ErrorOrTest.cpp
+++ b/unittests/Support/ErrorOrTest.cpp
@@ -45,9 +45,6 @@ TEST(ErrorOr, Types) {
*a = 42;
EXPECT_EQ(42, x);
- EXPECT_FALSE(ErrorOr<void>(errc::broken_pipe));
- EXPECT_TRUE(ErrorOr<void>(errc::success));
-
#if LLVM_HAS_CXX11_STDLIB
// Move only types.
EXPECT_EQ(3, **t3());
@@ -67,38 +64,3 @@ TEST(ErrorOr, Covariant) {
#endif
}
} // end anon namespace
-
-struct InvalidArgError {
- InvalidArgError() {}
- InvalidArgError(std::string S) : ArgName(S) {}
- std::string ArgName;
-};
-
-namespace llvm {
-template<>
-struct ErrorOrUserDataTraits<InvalidArgError> : true_type {
- static error_code error() {
- return make_error_code(errc::invalid_argument);
- }
-};
-} // end namespace llvm
-
-ErrorOr<int> t4() {
- return InvalidArgError("adena");
-}
-
-ErrorOr<void> t5() {
- return InvalidArgError("pie");
-}
-
-namespace {
-TEST(ErrorOr, UserErrorData) {
- ErrorOr<int> a = t4();
- EXPECT_EQ(errc::invalid_argument, a);
- EXPECT_EQ("adena", t4().getError<InvalidArgError>().ArgName);
-
- ErrorOr<void> b = t5();
- EXPECT_EQ(errc::invalid_argument, b);
- EXPECT_EQ("pie", b.getError<InvalidArgError>().ArgName);
-}
-} // end anon namespace