[Support] Add a StringError convenience class to Error.h

StringError can be used to represent Errors that aren't recoverable based on
the error type, but that have a useful error message that can be reported to
the user or logged.

llvm-svn: 270948
diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp
index 564b763..6a81895 100644
--- a/llvm/lib/Support/Error.cpp
+++ b/llvm/lib/Support/Error.cpp
@@ -8,15 +8,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Error.h"
+
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
 
+
 using namespace llvm;
 
 namespace {
 
-  enum class ErrorErrorCode {
-    MultipleErrors
+  enum class ErrorErrorCode : int {
+    MultipleErrors = 1,
+    UnconvertibleError
   };
 
   // FIXME: This class is only here to support the transition to llvm::Error. It
@@ -30,21 +34,61 @@
       switch (static_cast<ErrorErrorCode>(condition)) {
       case ErrorErrorCode::MultipleErrors:
         return "Multiple errors";
-      };
+      case ErrorErrorCode::UnconvertibleError:
+        return "Unconvertible error value. An error has occurred that could "
+               "not be converted to a known std::error_code. Please file a "
+               "bug.";
+      }
       llvm_unreachable("Unhandled error code");
     }
   };
 
 }
 
+static ManagedStatic<ErrorErrorCategory> ErrorErrorCat;
+
+namespace llvm {
+
 void ErrorInfoBase::anchor() {}
 char ErrorInfoBase::ID = 0;
 char ErrorList::ID = 0;
 char ECError::ID = 0;
+char StringError::ID = 0;
 
-static ManagedStatic<ErrorErrorCategory> ErrorErrorCat;
 
 std::error_code ErrorList::convertToErrorCode() const {
   return std::error_code(static_cast<int>(ErrorErrorCode::MultipleErrors),
                          *ErrorErrorCat);
 }
+
+std::error_code unconvertibleErrorCode() {
+  return std::error_code(static_cast<int>(ErrorErrorCode::UnconvertibleError),
+                         *ErrorErrorCat);
+}
+
+Error errorCodeToError(std::error_code EC) {
+  if (!EC)
+    return Error::success();
+  return Error(llvm::make_unique<ECError>(ECError(EC)));
+}
+
+std::error_code errorToErrorCode(Error Err) {
+  std::error_code EC;
+  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
+    EC = EI.convertToErrorCode();
+  });
+  if (EC == unconvertibleErrorCode())
+    report_fatal_error(EC.message());
+  return EC;
+}
+
+StringError::StringError(const Twine &S, std::error_code EC)
+    : Msg(S.str()), EC(EC) {}
+
+void StringError::log(raw_ostream &OS) const { OS << Msg; }
+
+std::error_code StringError::convertToErrorCode() const {
+  return EC;
+}
+
+}