From e7aad357a95be22a91d4d7d4131fb5fcf49f50ca Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 23 Mar 2016 23:57:28 +0000 Subject: [PATCH] [Support] Make all Errors convertible to std::error_code. This is a temporary crutch to enable code that currently uses std::error_code to be incrementally moved over to Error. Requiring all Error instances be convertible enables clients to call errorToErrorCode on any error (not just ECErrors created by conversion *from* an error_code). This patch also moves code for Error from ErrorHandling.cpp into a new Error.cpp file. llvm-svn: 264221 --- llvm/include/llvm/Support/Error.h | 15 ++++++++++-- llvm/lib/Support/CMakeLists.txt | 1 + llvm/lib/Support/Error.cpp | 45 ++++++++++++++++++++++++++++++++++++ llvm/lib/Support/ErrorHandling.cpp | 3 --- llvm/unittests/Support/ErrorTest.cpp | 9 ++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 llvm/lib/Support/Error.cpp diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h index a05dae1..f1eccf8 100644 --- a/llvm/include/llvm/Support/Error.h +++ b/llvm/include/llvm/Support/Error.h @@ -35,6 +35,12 @@ public: /// Print an error message to an output stream. virtual void log(raw_ostream &OS) const = 0; + /// Convert this error to a std::error_code. + /// + /// This is a temporary crutch to enable interaction with code still + /// using std::error_code. It will be removed in the future. + virtual std::error_code convertToErrorCode() const = 0; + // Check whether this instance is a subclass of the class identified by // ClassID. virtual bool isA(const void *const ClassID) const { @@ -309,6 +315,8 @@ public: } } + std::error_code convertToErrorCode() const override; + private: ErrorList(std::unique_ptr Payload1, std::unique_ptr Payload2) { @@ -717,7 +725,8 @@ class ECError : public ErrorInfo { public: ECError() = default; ECError(std::error_code EC) : EC(EC) {} - std::error_code getErrorCode() const { return EC; } + 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(); } protected: @@ -738,7 +747,9 @@ inline Error errorCodeToError(std::error_code EC) { inline std::error_code errorToErrorCode(Error Err) { std::error_code EC; handleAllErrors(std::move(Err), - [&](const ECError &ECE) { EC = ECE.getErrorCode(); }); + [&](const ErrorInfoBase &EI) { + EC = EI.convertToErrorCode(); + }); return EC; } diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index d14d7d3..98108e5 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -48,6 +48,7 @@ add_llvm_library(LLVMSupport DeltaAlgorithm.cpp DAGDeltaAlgorithm.cpp Dwarf.cpp + Error.cpp ErrorHandling.cpp FileUtilities.cpp FileOutputBuffer.cpp diff --git a/llvm/lib/Support/Error.cpp b/llvm/lib/Support/Error.cpp new file mode 100644 index 0000000..0cf5015 --- /dev/null +++ b/llvm/lib/Support/Error.cpp @@ -0,0 +1,45 @@ +//===----- lib/Support/Error.cpp - Error and associated utilities ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ManagedStatic.h" + +using namespace llvm; + +namespace { + + enum class ErrorErrorCode { + MultipleErrors + }; + + class ErrorErrorCategory : public std::error_category { + public: + const char *name() const LLVM_NOEXCEPT override { return "Error"; } + + std::string message(int condition) const override { + switch (static_cast(condition)) { + case ErrorErrorCode::MultipleErrors: + return "Multiple errors"; + }; + llvm_unreachable("Unhandled error code"); + } + }; + +}; + +void ErrorInfoBase::anchor() {} +char ErrorInfoBase::ID = 0; + +static ManagedStatic ErrorErrorCat; + +std::error_code ErrorList::convertToErrorCode() const { + return std::error_code(static_cast(ErrorErrorCode::MultipleErrors), + *ErrorErrorCat); +} diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp index c743d38..a7d3a18 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -139,9 +139,6 @@ void LLVMResetFatalErrorHandler() { remove_fatal_error_handler(); } -void ErrorInfoBase::anchor() {} -char ErrorInfoBase::ID = 0; - #ifdef LLVM_ON_WIN32 #include diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp index 788dcd3..1807547 100644 --- a/llvm/unittests/Support/ErrorTest.cpp +++ b/llvm/unittests/Support/ErrorTest.cpp @@ -9,6 +9,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/ErrorHandling.h" #include "gtest/gtest.h" #include @@ -30,6 +31,10 @@ public: OS << "CustomError { " << getInfo() << "}"; } + std::error_code convertToErrorCode() const override { + llvm_unreachable("CustomError doesn't support ECError conversion"); + } + protected: // This error is subclassed below, but we can't use inheriting constructors // yet, so we can't propagate the constructors through ErrorInfo. Instead @@ -57,6 +62,10 @@ public: OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}"; } + std::error_code convertToErrorCode() const override { + llvm_unreachable("CustomSubError doesn't support ECError conversion"); + } + protected: int ExtraInfo; }; -- 2.7.4