diff options
Diffstat (limited to 'include/llvm/Support/Error.h')
-rw-r--r-- | include/llvm/Support/Error.h | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/include/llvm/Support/Error.h b/include/llvm/Support/Error.h index 8567af392fb0..8015cab45a06 100644 --- a/include/llvm/Support/Error.h +++ b/include/llvm/Support/Error.h @@ -24,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -302,6 +303,14 @@ private: return Tmp; } + friend raw_ostream &operator<<(raw_ostream &OS, const Error &E) { + if (auto P = E.getPtr()) + P->log(OS); + else + OS << "success"; + return OS; + } + ErrorInfoBase *Payload = nullptr; }; @@ -421,7 +430,7 @@ template <class T> class LLVM_NODISCARD Expected { static const bool isRef = std::is_reference<T>::value; - using wrap = ReferenceStorage<typename std::remove_reference<T>::type>; + using wrap = std::reference_wrapper<typename std::remove_reference<T>::type>; using error_type = std::unique_ptr<ErrorInfoBase>; @@ -505,7 +514,7 @@ public: getErrorStorage()->~error_type(); } - /// \brief Return false if there is an error. + /// Return false if there is an error. explicit operator bool() { #if LLVM_ENABLE_ABI_BREAKING_CHECKS Unchecked = HasError; @@ -513,24 +522,24 @@ public: return !HasError; } - /// \brief Returns a reference to the stored T value. + /// Returns a reference to the stored T value. reference get() { assertIsChecked(); return *getStorage(); } - /// \brief Returns a const reference to the stored T value. + /// Returns a const reference to the stored T value. const_reference get() const { assertIsChecked(); return const_cast<Expected<T> *>(this)->get(); } - /// \brief Check that this Expected<T> is an error of type ErrT. + /// Check that this Expected<T> is an error of type ErrT. template <typename ErrT> bool errorIsA() const { return HasError && (*getErrorStorage())->template isA<ErrT>(); } - /// \brief Take ownership of the stored error. + /// Take ownership of the stored error. /// After calling this the Expected<T> is in an indeterminate state that can /// only be safely destructed. No further calls (beside the destructor) should /// be made on the Expected<T> vaule. @@ -541,25 +550,25 @@ public: return HasError ? Error(std::move(*getErrorStorage())) : Error::success(); } - /// \brief Returns a pointer to the stored T value. + /// Returns a pointer to the stored T value. pointer operator->() { assertIsChecked(); return toPointer(getStorage()); } - /// \brief Returns a const pointer to the stored T value. + /// Returns a const pointer to the stored T value. const_pointer operator->() const { assertIsChecked(); return toPointer(getStorage()); } - /// \brief Returns a reference to the stored T value. + /// Returns a reference to the stored T value. reference operator*() { assertIsChecked(); return *getStorage(); } - /// \brief Returns a const reference to the stored T value. + /// Returns a const reference to the stored T value. const_reference operator*() const { assertIsChecked(); return *getStorage(); @@ -882,16 +891,16 @@ Error handleErrors(Error E, HandlerTs &&... Hs) { return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...); } -/// Behaves the same as handleErrors, except that it requires that all -/// errors be handled by the given handlers. If any unhandled error remains -/// after the handlers have run, report_fatal_error() will be called. +/// Behaves the same as handleErrors, except that by contract all errors +/// *must* be handled by the given handlers (i.e. there must be no remaining +/// errors after running the handlers, or llvm_unreachable is called). template <typename... HandlerTs> void handleAllErrors(Error E, HandlerTs &&... Handlers) { cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...)); } /// Check that E is a non-error, then drop it. -/// If E is an error report_fatal_error will be called. +/// If E is an error, llvm_unreachable will be called. inline void handleAllErrors(Error E) { cantFail(std::move(E)); } @@ -963,6 +972,18 @@ inline void consumeError(Error Err) { handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {}); } +/// Helper for converting an Error to a bool. +/// +/// This method returns true if Err is in an error state, or false if it is +/// in a success state. Puts Err in a checked state in both cases (unlike +/// Error::operator bool(), which only does this for success states). +inline bool errorToBool(Error Err) { + bool IsError = static_cast<bool>(Err); + if (IsError) + consumeError(std::move(Err)); + return IsError; +} + /// Helper for Errors used as out-parameters. /// /// This helper is for use with the Error-as-out-parameter idiom, where an error @@ -1101,6 +1122,18 @@ private: std::error_code EC; }; +/// Create formatted StringError object. +template <typename... Ts> +Error createStringError(std::error_code EC, char const *Fmt, + const Ts &... Vals) { + std::string Buffer; + raw_string_ostream Stream(Buffer); + Stream << format(Fmt, Vals...); + return make_error<StringError>(Stream.str(), EC); +} + +Error createStringError(std::error_code EC, char const *Msg); + /// Helper for check-and-exit error handling. /// /// For tool use only. NOT FOR USE IN LIBRARY CODE. |