diff options
Diffstat (limited to 'third_party/llvm-project/Error.cpp')
-rw-r--r-- | third_party/llvm-project/Error.cpp | 168 |
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); +} |