LLVM 17.0.0git
Error.cpp
Go to the documentation of this file.
1//===----- lib/Support/Error.cpp - Error and associated utilities ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/Twine.h"
12#include <system_error>
13
14using namespace llvm;
15
16namespace {
17
18 enum class ErrorErrorCode : int {
19 MultipleErrors = 1,
21 InconvertibleError
22 };
23
24 // FIXME: This class is only here to support the transition to llvm::Error. It
25 // will be removed once this transition is complete. Clients should prefer to
26 // deal with the Error value directly, rather than converting to error_code.
27 class ErrorErrorCategory : public std::error_category {
28 public:
29 const char *name() const noexcept override { return "Error"; }
30
31 std::string message(int condition) const override {
32 switch (static_cast<ErrorErrorCode>(condition)) {
33 case ErrorErrorCode::MultipleErrors:
34 return "Multiple errors";
35 case ErrorErrorCode::InconvertibleError:
36 return "Inconvertible error value. An error has occurred that could "
37 "not be converted to a known std::error_code. Please file a "
38 "bug.";
39 case ErrorErrorCode::FileError:
40 return "A file error occurred.";
41 }
42 llvm_unreachable("Unhandled error code");
43 }
44 };
45
46}
47
48ErrorErrorCategory &getErrorErrorCat() {
49 static ErrorErrorCategory ErrorErrorCat;
50 return ErrorErrorCat;
51}
52
53namespace llvm {
54
55void ErrorInfoBase::anchor() {}
56char ErrorInfoBase::ID = 0;
57char ErrorList::ID = 0;
58void ECError::anchor() {}
59char ECError::ID = 0;
60char StringError::ID = 0;
61char FileError::ID = 0;
62
63void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner) {
64 if (!E)
65 return;
66 OS << ErrorBanner;
67 handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
68 EI.log(OS);
69 OS << "\n";
70 });
71}
72
73
74std::error_code ErrorList::convertToErrorCode() const {
75 return std::error_code(static_cast<int>(ErrorErrorCode::MultipleErrors),
77}
78
79std::error_code inconvertibleErrorCode() {
80 return std::error_code(static_cast<int>(ErrorErrorCode::InconvertibleError),
82}
83
84std::error_code FileError::convertToErrorCode() const {
85 std::error_code NestedEC = Err->convertToErrorCode();
86 if (NestedEC == inconvertibleErrorCode())
87 return std::error_code(static_cast<int>(ErrorErrorCode::FileError),
89 return NestedEC;
90}
91
92Error errorCodeToError(std::error_code EC) {
93 if (!EC)
94 return Error::success();
95 return Error(std::make_unique<ECError>(ECError(EC)));
96}
97
98std::error_code errorToErrorCode(Error Err) {
99 std::error_code EC;
100 handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
101 EC = EI.convertToErrorCode();
102 });
103 if (EC == inconvertibleErrorCode())
104 report_fatal_error(Twine(EC.message()));
105 return EC;
106}
107
108#if LLVM_ENABLE_ABI_BREAKING_CHECKS
109void Error::fatalUncheckedError() const {
110 dbgs() << "Program aborted due to an unhandled Error:\n";
111 if (getPtr()) {
112 getPtr()->log(dbgs());
113 dbgs() << "\n";
114 }else
115 dbgs() << "Error value was Success. (Note: Success values must still be "
116 "checked prior to being destroyed).\n";
117 abort();
118}
119#endif
120
121StringError::StringError(std::error_code EC, const Twine &S)
122 : Msg(S.str()), EC(EC) {}
123
124StringError::StringError(const Twine &S, std::error_code EC)
125 : Msg(S.str()), EC(EC), PrintMsgOnly(true) {}
126
127void StringError::log(raw_ostream &OS) const {
128 if (PrintMsgOnly) {
129 OS << Msg;
130 } else {
131 OS << EC.message();
132 if (!Msg.empty())
133 OS << (" " + Msg);
134 }
135}
136
137std::error_code StringError::convertToErrorCode() const {
138 return EC;
139}
140
141Error createStringError(std::error_code EC, char const *Msg) {
142 return make_error<StringError>(Msg, EC);
143}
144
145void report_fatal_error(Error Err, bool GenCrashDiag) {
146 assert(Err && "report_fatal_error called with success value");
147 std::string ErrMsg;
148 {
149 raw_string_ostream ErrStream(ErrMsg);
150 logAllUnhandledErrors(std::move(Err), ErrStream);
151 }
152 report_fatal_error(Twine(ErrMsg), GenCrashDiag);
153}
154
155} // end namespace llvm
156
158 return reinterpret_cast<ErrorInfoBase *>(Err)->dynamicClassID();
159}
160
162
164 std::string Tmp = toString(unwrap(Err));
165 char *ErrMsg = new char[Tmp.size() + 1];
166 memcpy(ErrMsg, Tmp.data(), Tmp.size());
167 ErrMsg[Tmp.size()] = '\0';
168 return ErrMsg;
169}
170
171void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; }
172
174 return reinterpret_cast<void *>(&StringError::ID);
175}
176
177LLVMErrorRef LLVMCreateStringError(const char *ErrMsg) {
178 return wrap(make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
179}
aarch64 promote const
basic Basic Alias true
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static LLVMTargetMachineRef wrap(const TargetMachine *P)
static const char * toString(MIToken::TokenKind TokenKind)
Definition: MIParser.cpp:614
OwningBinary< ObjectFile > * unwrap(LLVMObjectFileRef OF)
Definition: Object.cpp:24
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
raw_pwrite_stream & OS
ErrorErrorCategory & getErrorErrorCat()
Definition: Error.cpp:48
This class wraps a std::error_code in a Error.
Definition: Error.h:1148
static char ID
Definition: Error.h:1159
Base class for error info classes.
Definition: Error.h:47
virtual std::error_code convertToErrorCode() const =0
Convert this error to a std::error_code.
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:74
static char ID
Definition: Error.h:384
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
This class wraps a filename and another Error.
Definition: Error.h:1270
static char ID
Definition: Error.h:1298
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:84
StringError(std::error_code EC, const Twine &S=Twine())
Definition: Error.cpp:121
static char ID
Definition: Error.h:1225
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
char * LLVMGetErrorMessage(LLVMErrorRef Err)
Returns the given string's error message.
Definition: Error.cpp:163
LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err)
Returns the type id for the given error instance, which must be a failure value (i....
Definition: Error.cpp:157
LLVMErrorTypeId LLVMGetStringErrorTypeId(void)
Returns the type id for llvm StringError.
Definition: Error.cpp:173
void LLVMDisposeErrorMessage(char *ErrMsg)
Dispose of the given error message.
Definition: Error.cpp:171
const void * LLVMErrorTypeId
Error type identifier.
Definition: Error.h:38
struct LLVMOpaqueError * LLVMErrorRef
Opaque reference to an error instance.
Definition: Error.h:33
LLVMErrorRef LLVMCreateStringError(const char *ErrMsg)
Create a StringError.
Definition: Error.cpp:177
void LLVMConsumeError(LLVMErrorRef Err)
Dispose of the given error without handling it.
Definition: Error.cpp:161
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const CustomOperand< const MCSubtargetInfo & > Msg[]
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:63
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:966
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1246
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:92
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition: Error.cpp:98
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043