[llvm] r311631 - [Support] Rewrite handleAllErrors in terms of cantFail.

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 23 22:35:27 PDT 2017


Author: lhames
Date: Wed Aug 23 22:35:27 2017
New Revision: 311631

URL: http://llvm.org/viewvc/llvm-project?rev=311631&view=rev
Log:
[Support] Rewrite handleAllErrors in terms of cantFail.

This just switches handleAllErrors from using custom assertions that all errors
have been handled to using cantFail. This change involves moving some of the
class and function definitions around though.

Modified:
    llvm/trunk/include/llvm/Support/Error.h
    llvm/trunk/unittests/Support/ErrorTest.cpp

Modified: llvm/trunk/include/llvm/Support/Error.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Error.h?rev=311631&r1=311630&r2=311631&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Error.h (original)
+++ llvm/trunk/include/llvm/Support/Error.h Wed Aug 23 22:35:27 2017
@@ -407,235 +407,6 @@ inline Error joinErrors(Error E1, Error
   return ErrorList::join(std::move(E1), std::move(E2));
 }
 
-/// Helper for testing applicability of, and applying, handlers for
-/// ErrorInfo types.
-template <typename HandlerT>
-class ErrorHandlerTraits
-    : public ErrorHandlerTraits<decltype(
-          &std::remove_reference<HandlerT>::type::operator())> {};
-
-// Specialization functions of the form 'Error (const ErrT&)'.
-template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
-public:
-  static bool appliesTo(const ErrorInfoBase &E) {
-    return E.template isA<ErrT>();
-  }
-
-  template <typename HandlerT>
-  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
-    assert(appliesTo(*E) && "Applying incorrect handler");
-    return H(static_cast<ErrT &>(*E));
-  }
-};
-
-// Specialization functions of the form 'void (const ErrT&)'.
-template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
-public:
-  static bool appliesTo(const ErrorInfoBase &E) {
-    return E.template isA<ErrT>();
-  }
-
-  template <typename HandlerT>
-  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
-    assert(appliesTo(*E) && "Applying incorrect handler");
-    H(static_cast<ErrT &>(*E));
-    return Error::success();
-  }
-};
-
-/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
-template <typename ErrT>
-class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
-public:
-  static bool appliesTo(const ErrorInfoBase &E) {
-    return E.template isA<ErrT>();
-  }
-
-  template <typename HandlerT>
-  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
-    assert(appliesTo(*E) && "Applying incorrect handler");
-    std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
-    return H(std::move(SubE));
-  }
-};
-
-/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
-template <typename ErrT>
-class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
-public:
-  static bool appliesTo(const ErrorInfoBase &E) {
-    return E.template isA<ErrT>();
-  }
-
-  template <typename HandlerT>
-  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
-    assert(appliesTo(*E) && "Applying incorrect handler");
-    std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
-    H(std::move(SubE));
-    return Error::success();
-  }
-};
-
-// Specialization for member functions of the form 'RetT (const ErrT&)'.
-template <typename C, typename RetT, typename ErrT>
-class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
-    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
-
-// Specialization for member functions of the form 'RetT (const ErrT&) const'.
-template <typename C, typename RetT, typename ErrT>
-class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
-    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
-
-// Specialization for member functions of the form 'RetT (const ErrT&)'.
-template <typename C, typename RetT, typename ErrT>
-class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
-    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
-
-// Specialization for member functions of the form 'RetT (const ErrT&) const'.
-template <typename C, typename RetT, typename ErrT>
-class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
-    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
-
-/// Specialization for member functions of the form
-/// 'RetT (std::unique_ptr<ErrT>) const'.
-template <typename C, typename RetT, typename ErrT>
-class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
-    : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
-
-/// Specialization for member functions of the form
-/// 'RetT (std::unique_ptr<ErrT>) const'.
-template <typename C, typename RetT, typename ErrT>
-class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
-    : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
-
-inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
-  return Error(std::move(Payload));
-}
-
-template <typename HandlerT, typename... HandlerTs>
-Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
-                      HandlerT &&Handler, HandlerTs &&... Handlers) {
-  if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
-    return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
-                                               std::move(Payload));
-  return handleErrorImpl(std::move(Payload),
-                         std::forward<HandlerTs>(Handlers)...);
-}
-
-/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
-/// unhandled errors (or Errors returned by handlers) are re-concatenated and
-/// returned.
-/// Because this function returns an error, its result must also be checked
-/// or returned. If you intend to handle all errors use handleAllErrors
-/// (which returns void, and will abort() on unhandled errors) instead.
-template <typename... HandlerTs>
-Error handleErrors(Error E, HandlerTs &&... Hs) {
-  if (!E)
-    return Error::success();
-
-  std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
-
-  if (Payload->isA<ErrorList>()) {
-    ErrorList &List = static_cast<ErrorList &>(*Payload);
-    Error R;
-    for (auto &P : List.Payloads)
-      R = ErrorList::join(
-          std::move(R),
-          handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
-    return R;
-  }
-
-  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, abort() will be called.
-template <typename... HandlerTs>
-void handleAllErrors(Error E, HandlerTs &&... Handlers) {
-  auto F = handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...);
-  // Cast 'F' to bool to set the 'Checked' flag if it's a success value:
-  (void)!F;
-}
-
-/// Check that E is a non-error, then drop it.
-inline void handleAllErrors(Error E) {
-  // Cast 'E' to a bool to set the 'Checked' flag if it's a success value:
-  (void)!E;
-}
-
-/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
-/// will be printed before the first one is logged. A newline will be printed
-/// after each error.
-///
-/// This is useful in the base level of your program to allow clean termination
-/// (allowing clean deallocation of resources, etc.), while reporting error
-/// information to the user.
-void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner);
-
-/// Write all error messages (if any) in E to a string. The newline character
-/// is used to separate error messages.
-inline std::string toString(Error E) {
-  SmallVector<std::string, 2> Errors;
-  handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) {
-    Errors.push_back(EI.message());
-  });
-  return join(Errors.begin(), Errors.end(), "\n");
-}
-
-/// Consume a Error without doing anything. This method should be used
-/// only where an error can be considered a reasonable and expected return
-/// value.
-///
-/// Uses of this method are potentially indicative of design problems: If it's
-/// legitimate to do nothing while processing an "error", the error-producer
-/// might be more clearly refactored to return an Optional<T>.
-inline void consumeError(Error Err) {
-  handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
-}
-
-/// Helper for Errors used as out-parameters.
-///
-/// This helper is for use with the Error-as-out-parameter idiom, where an error
-/// is passed to a function or method by reference, rather than being returned.
-/// In such cases it is helpful to set the checked bit on entry to the function
-/// so that the error can be written to (unchecked Errors abort on assignment)
-/// and clear the checked bit on exit so that clients cannot accidentally forget
-/// to check the result. This helper performs these actions automatically using
-/// RAII:
-///
-///   @code{.cpp}
-///   Result foo(Error &Err) {
-///     ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
-///     // <body of foo>
-///     // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
-///   }
-///   @endcode
-///
-/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
-/// used with optional Errors (Error pointers that are allowed to be null). If
-/// ErrorAsOutParameter took an Error reference, an instance would have to be
-/// created inside every condition that verified that Error was non-null. By
-/// taking an Error pointer we can just create one instance at the top of the
-/// function.
-class ErrorAsOutParameter {
-public:
-  ErrorAsOutParameter(Error *Err) : Err(Err) {
-    // Raise the checked bit if Err is success.
-    if (Err)
-      (void)!!*Err;
-  }
-
-  ~ErrorAsOutParameter() {
-    // Clear the checked bit.
-    if (Err && !*Err)
-      *Err = Error::success();
-  }
-
-private:
-  Error *Err;
-};
-
 /// Tagged union holding either a T or a Error.
 ///
 /// This class parallels ErrorOr, but replaces error_code with Error. Since
@@ -887,36 +658,328 @@ private:
 #endif
 };
 
-/// Helper for Expected<T>s used as out-parameters.
-///
-/// See ErrorAsOutParameter.
-template <typename T>
-class ExpectedAsOutParameter {
-public:
-  ExpectedAsOutParameter(Expected<T> *ValOrErr)
-    : ValOrErr(ValOrErr) {
-    if (ValOrErr)
-      (void)!!*ValOrErr;
-  }
-
-  ~ExpectedAsOutParameter() {
-    if (ValOrErr)
-      ValOrErr->setUnchecked();
-  }
-
-private:
-  Expected<T> *ValOrErr;
-};
+/// Report a serious error, calling any installed error handler. See
+/// ErrorHandling.h.
+LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err,
+                                                bool gen_crash_diag = true);
 
-/// This class wraps a std::error_code in a Error.
+/// Report a fatal error if Err is a failure value.
 ///
-/// This is useful if you're writing an interface that returns a Error
-/// (or Expected) and you want to call code that still returns
-/// std::error_codes.
-class ECError : public ErrorInfo<ECError> {
-  friend Error errorCodeToError(std::error_code);
-
-public:
+/// This function can be used to wrap calls to fallible functions ONLY when it
+/// is known that the Error will always be a success value. E.g.
+///
+///   @code{.cpp}
+///   // foo only attempts the fallible operation if DoFallibleOperation is
+///   // true. If DoFallibleOperation is false then foo always returns
+///   // Error::success().
+///   Error foo(bool DoFallibleOperation);
+///
+///   cantFail(foo(false));
+///   @endcode
+inline void cantFail(Error Err) {
+  if (Err)
+    llvm_unreachable("Failure value returned from cantFail wrapped call");
+}
+
+/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
+/// returns the contained value.
+///
+/// This function can be used to wrap calls to fallible functions ONLY when it
+/// is known that the Error will always be a success value. E.g.
+///
+///   @code{.cpp}
+///   // foo only attempts the fallible operation if DoFallibleOperation is
+///   // true. If DoFallibleOperation is false then foo always returns an int.
+///   Expected<int> foo(bool DoFallibleOperation);
+///
+///   int X = cantFail(foo(false));
+///   @endcode
+template <typename T>
+T cantFail(Expected<T> ValOrErr) {
+  if (ValOrErr)
+    return std::move(*ValOrErr);
+  else
+    llvm_unreachable("Failure value returned from cantFail wrapped call");
+}
+
+/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
+/// returns the contained reference.
+///
+/// This function can be used to wrap calls to fallible functions ONLY when it
+/// is known that the Error will always be a success value. E.g.
+///
+///   @code{.cpp}
+///   // foo only attempts the fallible operation if DoFallibleOperation is
+///   // true. If DoFallibleOperation is false then foo always returns a Bar&.
+///   Expected<Bar&> foo(bool DoFallibleOperation);
+///
+///   Bar &X = cantFail(foo(false));
+///   @endcode
+template <typename T>
+T& cantFail(Expected<T&> ValOrErr) {
+  if (ValOrErr)
+    return *ValOrErr;
+  else
+    llvm_unreachable("Failure value returned from cantFail wrapped call");
+}
+
+/// Helper for testing applicability of, and applying, handlers for
+/// ErrorInfo types.
+template <typename HandlerT>
+class ErrorHandlerTraits
+    : public ErrorHandlerTraits<decltype(
+          &std::remove_reference<HandlerT>::type::operator())> {};
+
+// Specialization functions of the form 'Error (const ErrT&)'.
+template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
+public:
+  static bool appliesTo(const ErrorInfoBase &E) {
+    return E.template isA<ErrT>();
+  }
+
+  template <typename HandlerT>
+  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+    assert(appliesTo(*E) && "Applying incorrect handler");
+    return H(static_cast<ErrT &>(*E));
+  }
+};
+
+// Specialization functions of the form 'void (const ErrT&)'.
+template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
+public:
+  static bool appliesTo(const ErrorInfoBase &E) {
+    return E.template isA<ErrT>();
+  }
+
+  template <typename HandlerT>
+  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+    assert(appliesTo(*E) && "Applying incorrect handler");
+    H(static_cast<ErrT &>(*E));
+    return Error::success();
+  }
+};
+
+/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
+template <typename ErrT>
+class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
+public:
+  static bool appliesTo(const ErrorInfoBase &E) {
+    return E.template isA<ErrT>();
+  }
+
+  template <typename HandlerT>
+  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+    assert(appliesTo(*E) && "Applying incorrect handler");
+    std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
+    return H(std::move(SubE));
+  }
+};
+
+/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
+template <typename ErrT>
+class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
+public:
+  static bool appliesTo(const ErrorInfoBase &E) {
+    return E.template isA<ErrT>();
+  }
+
+  template <typename HandlerT>
+  static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
+    assert(appliesTo(*E) && "Applying incorrect handler");
+    std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
+    H(std::move(SubE));
+    return Error::success();
+  }
+};
+
+// Specialization for member functions of the form 'RetT (const ErrT&)'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
+    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'RetT (const ErrT&) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
+    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'RetT (const ErrT&)'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
+    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'RetT (const ErrT&) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
+    : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
+
+/// Specialization for member functions of the form
+/// 'RetT (std::unique_ptr<ErrT>) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
+    : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
+
+/// Specialization for member functions of the form
+/// 'RetT (std::unique_ptr<ErrT>) const'.
+template <typename C, typename RetT, typename ErrT>
+class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
+    : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
+
+inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
+  return Error(std::move(Payload));
+}
+
+template <typename HandlerT, typename... HandlerTs>
+Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
+                      HandlerT &&Handler, HandlerTs &&... Handlers) {
+  if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
+    return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
+                                               std::move(Payload));
+  return handleErrorImpl(std::move(Payload),
+                         std::forward<HandlerTs>(Handlers)...);
+}
+
+/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
+/// unhandled errors (or Errors returned by handlers) are re-concatenated and
+/// returned.
+/// Because this function returns an error, its result must also be checked
+/// or returned. If you intend to handle all errors use handleAllErrors
+/// (which returns void, and will abort() on unhandled errors) instead.
+template <typename... HandlerTs>
+Error handleErrors(Error E, HandlerTs &&... Hs) {
+  if (!E)
+    return Error::success();
+
+  std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
+
+  if (Payload->isA<ErrorList>()) {
+    ErrorList &List = static_cast<ErrorList &>(*Payload);
+    Error R;
+    for (auto &P : List.Payloads)
+      R = ErrorList::join(
+          std::move(R),
+          handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
+    return R;
+  }
+
+  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.
+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.
+inline void handleAllErrors(Error E) {
+  cantFail(std::move(E));
+}
+
+/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
+/// will be printed before the first one is logged. A newline will be printed
+/// after each error.
+///
+/// This is useful in the base level of your program to allow clean termination
+/// (allowing clean deallocation of resources, etc.), while reporting error
+/// information to the user.
+void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner);
+
+/// Write all error messages (if any) in E to a string. The newline character
+/// is used to separate error messages.
+inline std::string toString(Error E) {
+  SmallVector<std::string, 2> Errors;
+  handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) {
+    Errors.push_back(EI.message());
+  });
+  return join(Errors.begin(), Errors.end(), "\n");
+}
+
+/// Consume a Error without doing anything. This method should be used
+/// only where an error can be considered a reasonable and expected return
+/// value.
+///
+/// Uses of this method are potentially indicative of design problems: If it's
+/// legitimate to do nothing while processing an "error", the error-producer
+/// might be more clearly refactored to return an Optional<T>.
+inline void consumeError(Error Err) {
+  handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
+}
+
+/// Helper for Errors used as out-parameters.
+///
+/// This helper is for use with the Error-as-out-parameter idiom, where an error
+/// is passed to a function or method by reference, rather than being returned.
+/// In such cases it is helpful to set the checked bit on entry to the function
+/// so that the error can be written to (unchecked Errors abort on assignment)
+/// and clear the checked bit on exit so that clients cannot accidentally forget
+/// to check the result. This helper performs these actions automatically using
+/// RAII:
+///
+///   @code{.cpp}
+///   Result foo(Error &Err) {
+///     ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
+///     // <body of foo>
+///     // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
+///   }
+///   @endcode
+///
+/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
+/// used with optional Errors (Error pointers that are allowed to be null). If
+/// ErrorAsOutParameter took an Error reference, an instance would have to be
+/// created inside every condition that verified that Error was non-null. By
+/// taking an Error pointer we can just create one instance at the top of the
+/// function.
+class ErrorAsOutParameter {
+public:
+  ErrorAsOutParameter(Error *Err) : Err(Err) {
+    // Raise the checked bit if Err is success.
+    if (Err)
+      (void)!!*Err;
+  }
+
+  ~ErrorAsOutParameter() {
+    // Clear the checked bit.
+    if (Err && !*Err)
+      *Err = Error::success();
+  }
+
+private:
+  Error *Err;
+};
+
+/// Helper for Expected<T>s used as out-parameters.
+///
+/// See ErrorAsOutParameter.
+template <typename T>
+class ExpectedAsOutParameter {
+public:
+  ExpectedAsOutParameter(Expected<T> *ValOrErr)
+    : ValOrErr(ValOrErr) {
+    if (ValOrErr)
+      (void)!!*ValOrErr;
+  }
+
+  ~ExpectedAsOutParameter() {
+    if (ValOrErr)
+      ValOrErr->setUnchecked();
+  }
+
+private:
+  Expected<T> *ValOrErr;
+};
+
+/// This class wraps a std::error_code in a Error.
+///
+/// This is useful if you're writing an interface that returns a Error
+/// (or Expected) and you want to call code that still returns
+/// std::error_codes.
+class ECError : public ErrorInfo<ECError> {
+  friend Error errorCodeToError(std::error_code);
+
+public:
   void setErrorCode(std::error_code EC) { this->EC = EC; }
   std::error_code convertToErrorCode() const override { return EC; }
   void log(raw_ostream &OS) const override { OS << EC.message(); }
@@ -1032,71 +1095,6 @@ private:
   std::function<int(const Error &)> GetExitCode;
 };
 
-/// Report a serious error, calling any installed error handler. See
-/// ErrorHandling.h.
-LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err,
-                                                bool gen_crash_diag = true);
-
-/// Report a fatal error if Err is a failure value.
-///
-/// This function can be used to wrap calls to fallible functions ONLY when it
-/// is known that the Error will always be a success value. E.g.
-///
-///   @code{.cpp}
-///   // foo only attempts the fallible operation if DoFallibleOperation is
-///   // true. If DoFallibleOperation is false then foo always returns
-///   // Error::success().
-///   Error foo(bool DoFallibleOperation);
-///
-///   cantFail(foo(false));
-///   @endcode
-inline void cantFail(Error Err) {
-  if (Err)
-    llvm_unreachable("Failure value returned from cantFail wrapped call");
-}
-
-/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
-/// returns the contained value.
-///
-/// This function can be used to wrap calls to fallible functions ONLY when it
-/// is known that the Error will always be a success value. E.g.
-///
-///   @code{.cpp}
-///   // foo only attempts the fallible operation if DoFallibleOperation is
-///   // true. If DoFallibleOperation is false then foo always returns an int.
-///   Expected<int> foo(bool DoFallibleOperation);
-///
-///   int X = cantFail(foo(false));
-///   @endcode
-template <typename T>
-T cantFail(Expected<T> ValOrErr) {
-  if (ValOrErr)
-    return std::move(*ValOrErr);
-  else
-    llvm_unreachable("Failure value returned from cantFail wrapped call");
-}
-
-/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
-/// returns the contained reference.
-///
-/// This function can be used to wrap calls to fallible functions ONLY when it
-/// is known that the Error will always be a success value. E.g.
-///
-///   @code{.cpp}
-///   // foo only attempts the fallible operation if DoFallibleOperation is
-///   // true. If DoFallibleOperation is false then foo always returns a Bar&.
-///   Expected<Bar&> foo(bool DoFallibleOperation);
-///
-///   Bar &X = cantFail(foo(false));
-///   @endcode
-template <typename T>
-T& cantFail(Expected<T&> ValOrErr) {
-  if (ValOrErr)
-    return *ValOrErr;
-  else
-    llvm_unreachable("Failure value returned from cantFail wrapped call");
-}
-
 } // end namespace llvm
 
 #endif // LLVM_SUPPORT_ERROR_H

Modified: llvm/trunk/unittests/Support/ErrorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/ErrorTest.cpp?rev=311631&r1=311630&r2=311631&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/ErrorTest.cpp (original)
+++ llvm/trunk/unittests/Support/ErrorTest.cpp Wed Aug 23 22:35:27 2017
@@ -386,7 +386,8 @@ TEST(Error, FailureToHandle) {
     });
   };
 
-  EXPECT_DEATH(FailToHandle(), "Program aborted due to an unhandled Error:")
+  EXPECT_DEATH(FailToHandle(),
+               "Failure value returned from cantFail wrapped call")
       << "Unhandled Error in handleAllErrors call did not cause an "
          "abort()";
 }
@@ -405,7 +406,7 @@ TEST(Error, FailureFromHandler) {
   };
 
   EXPECT_DEATH(ReturnErrorFromHandler(),
-               "Program aborted due to an unhandled Error:")
+               "Failure value returned from cantFail wrapped call")
       << " Error returned from handler in handleAllErrors call did not "
          "cause abort()";
 }




More information about the llvm-commits mailing list