summaryrefslogtreecommitdiff
path: root/third_party/llvm-project/Error.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/llvm-project/Error.cpp')
-rw-r--r--third_party/llvm-project/Error.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/third_party/llvm-project/Error.cpp b/third_party/llvm-project/Error.cpp
new file mode 100644
index 000000000..bb13c836d
--- /dev/null
+++ b/third_party/llvm-project/Error.cpp
@@ -0,0 +1,168 @@
+//===----- lib/Support/Error.cpp - Error and associated utilities ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Error.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+#include <system_error>
+
+using namespace llvm;
+
+namespace {
+
+ enum class ErrorErrorCode : int {
+ MultipleErrors = 1,
+ FileError,
+ InconvertibleError
+ };
+
+ // FIXME: This class is only here to support the transition to llvm::Error. It
+ // will be removed once this transition is complete. Clients should prefer to
+ // deal with the Error value directly, rather than converting to error_code.
+ class ErrorErrorCategory : public std::error_category {
+ public:
+ const char *name() const noexcept override { return "Error"; }
+
+ std::string message(int condition) const override {
+ switch (static_cast<ErrorErrorCode>(condition)) {
+ case ErrorErrorCode::MultipleErrors:
+ return "Multiple errors";
+ case ErrorErrorCode::InconvertibleError:
+ return "Inconvertible error value. An error has occurred that could "
+ "not be converted to a known std::error_code. Please file a "
+ "bug.";
+ case ErrorErrorCode::FileError:
+ return "A file error occurred.";
+ }
+ llvm_unreachable("Unhandled error code");
+ }
+ };
+
+}
+
+#if 0 // XXX BINARYEN
+static ManagedStatic<ErrorErrorCategory> ErrorErrorCat;
+#endif
+
+namespace llvm {
+
+void ErrorInfoBase::anchor() {}
+char ErrorInfoBase::ID = 0;
+char ErrorList::ID = 0;
+void ECError::anchor() {}
+char ECError::ID = 0;
+char StringError::ID = 0;
+char FileError::ID = 0;
+
+void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner) {
+ if (!E)
+ return;
+ OS << ErrorBanner;
+ handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
+ EI.log(OS);
+ OS << "\n";
+ });
+}
+
+
+std::error_code ErrorList::convertToErrorCode() const {
+ llvm_unreachable("convert error code");
+}
+
+std::error_code inconvertibleErrorCode() {
+ llvm_unreachable("inconvertible error code");
+}
+
+std::error_code FileError::convertToErrorCode() const {
+ llvm_unreachable("(file) convert error code");
+}
+
+Error errorCodeToError(std::error_code EC) {
+ if (!EC)
+ return Error::success();
+ return Error(std::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 == inconvertibleErrorCode())
+ report_fatal_error(EC.message());
+ return EC;
+}
+
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+void Error::fatalUncheckedError() const {
+ dbgs() << "Program aborted due to an unhandled Error:\n";
+ if (getPtr())
+ getPtr()->log(dbgs());
+ else
+ dbgs() << "Error value was Success. (Note: Success values must still be "
+ "checked prior to being destroyed).\n";
+ abort();
+}
+#endif
+
+StringError::StringError(std::error_code EC, const Twine &S)
+ : Msg(S.str()), EC(EC) {}
+
+StringError::StringError(const Twine &S, std::error_code EC)
+ : Msg(S.str()), EC(EC), PrintMsgOnly(true) {}
+
+void StringError::log(raw_ostream &OS) const {
+ if (PrintMsgOnly) {
+ OS << Msg;
+ } else {
+ OS << EC.message();
+ if (!Msg.empty())
+ OS << (" " + Msg);
+ }
+}
+
+std::error_code StringError::convertToErrorCode() const {
+ return EC;
+}
+
+Error createStringError(std::error_code EC, char const *Msg) {
+ return make_error<StringError>(Msg, EC);
+}
+
+void report_fatal_error(Error Err, bool GenCrashDiag) {
+ assert(Err && "report_fatal_error called with success value");
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrStream(ErrMsg);
+ logAllUnhandledErrors(std::move(Err), ErrStream);
+ }
+ report_fatal_error(ErrMsg);
+}
+
+} // end namespace llvm
+
+LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err) {
+ return reinterpret_cast<ErrorInfoBase *>(Err)->dynamicClassID();
+}
+
+void LLVMConsumeError(LLVMErrorRef Err) { consumeError(unwrap(Err)); }
+
+char *LLVMGetErrorMessage(LLVMErrorRef Err) {
+ std::string Tmp = toString(unwrap(Err));
+ char *ErrMsg = new char[Tmp.size() + 1];
+ memcpy(ErrMsg, Tmp.data(), Tmp.size());
+ ErrMsg[Tmp.size()] = '\0';
+ return ErrMsg;
+}
+
+void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; }
+
+LLVMErrorTypeId LLVMGetStringErrorTypeId() {
+ return reinterpret_cast<void *>(&StringError::ID);
+}