LLVM  14.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 
9 #include "llvm/Support/Error.h"
10 #include "llvm/ADT/Twine.h"
13 #include <system_error>
14 
15 using namespace llvm;
16 
17 namespace {
18 
19  enum class ErrorErrorCode : int {
20  MultipleErrors = 1,
21  FileError,
22  InconvertibleError
23  };
24 
25  // FIXME: This class is only here to support the transition to llvm::Error. It
26  // will be removed once this transition is complete. Clients should prefer to
27  // deal with the Error value directly, rather than converting to error_code.
28  class ErrorErrorCategory : public std::error_category {
29  public:
30  const char *name() const noexcept override { return "Error"; }
31 
32  std::string message(int condition) const override {
33  switch (static_cast<ErrorErrorCode>(condition)) {
34  case ErrorErrorCode::MultipleErrors:
35  return "Multiple errors";
36  case ErrorErrorCode::InconvertibleError:
37  return "Inconvertible error value. An error has occurred that could "
38  "not be converted to a known std::error_code. Please file a "
39  "bug.";
40  case ErrorErrorCode::FileError:
41  return "A file error occurred.";
42  }
43  llvm_unreachable("Unhandled error code");
44  }
45  };
46 
47 }
48 
50 
51 namespace llvm {
52 
53 void ErrorInfoBase::anchor() {}
54 char ErrorInfoBase::ID = 0;
55 char ErrorList::ID = 0;
56 void ECError::anchor() {}
57 char ECError::ID = 0;
58 char StringError::ID = 0;
59 char FileError::ID = 0;
60 
61 void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner) {
62  if (!E)
63  return;
64  OS << ErrorBanner;
65  handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
66  EI.log(OS);
67  OS << "\n";
68  });
69 }
70 
71 
72 std::error_code ErrorList::convertToErrorCode() const {
73  return std::error_code(static_cast<int>(ErrorErrorCode::MultipleErrors),
74  *ErrorErrorCat);
75 }
76 
77 std::error_code inconvertibleErrorCode() {
78  return std::error_code(static_cast<int>(ErrorErrorCode::InconvertibleError),
79  *ErrorErrorCat);
80 }
81 
82 std::error_code FileError::convertToErrorCode() const {
83  std::error_code NestedEC = Err->convertToErrorCode();
84  if (NestedEC == inconvertibleErrorCode())
85  return std::error_code(static_cast<int>(ErrorErrorCode::FileError),
86  *ErrorErrorCat);
87  return NestedEC;
88 }
89 
90 Error errorCodeToError(std::error_code EC) {
91  if (!EC)
92  return Error::success();
93  return Error(std::make_unique<ECError>(ECError(EC)));
94 }
95 
96 std::error_code errorToErrorCode(Error Err) {
97  std::error_code EC;
98  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
99  EC = EI.convertToErrorCode();
100  });
101  if (EC == inconvertibleErrorCode())
102  report_fatal_error(Twine(EC.message()));
103  return EC;
104 }
105 
106 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
107 void Error::fatalUncheckedError() const {
108  dbgs() << "Program aborted due to an unhandled Error:\n";
109  if (getPtr()) {
110  getPtr()->log(dbgs());
111  dbgs() << "\n";
112  }else
113  dbgs() << "Error value was Success. (Note: Success values must still be "
114  "checked prior to being destroyed).\n";
115  abort();
116 }
117 #endif
118 
119 StringError::StringError(std::error_code EC, const Twine &S)
120  : Msg(S.str()), EC(EC) {}
121 
122 StringError::StringError(const Twine &S, std::error_code EC)
123  : Msg(S.str()), EC(EC), PrintMsgOnly(true) {}
124 
125 void StringError::log(raw_ostream &OS) const {
126  if (PrintMsgOnly) {
127  OS << Msg;
128  } else {
129  OS << EC.message();
130  if (!Msg.empty())
131  OS << (" " + Msg);
132  }
133 }
134 
135 std::error_code StringError::convertToErrorCode() const {
136  return EC;
137 }
138 
139 Error createStringError(std::error_code EC, char const *Msg) {
140  return make_error<StringError>(Msg, EC);
141 }
142 
143 void report_fatal_error(Error Err, bool GenCrashDiag) {
144  assert(Err && "report_fatal_error called with success value");
145  std::string ErrMsg;
146  {
147  raw_string_ostream ErrStream(ErrMsg);
148  logAllUnhandledErrors(std::move(Err), ErrStream);
149  }
150  report_fatal_error(Twine(ErrMsg));
151 }
152 
153 } // end namespace llvm
154 
156  return reinterpret_cast<ErrorInfoBase *>(Err)->dynamicClassID();
157 }
158 
160 
162  std::string Tmp = toString(unwrap(Err));
163  char *ErrMsg = new char[Tmp.size() + 1];
164  memcpy(ErrMsg, Tmp.data(), Tmp.size());
165  ErrMsg[Tmp.size()] = '\0';
166  return ErrMsg;
167 }
168 
169 void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; }
170 
172  return reinterpret_cast<void *>(&StringError::ID);
173 }
174 
175 LLVMErrorRef LLVMCreateStringError(const char *ErrMsg) {
176  return wrap(make_error<StringError>(ErrMsg, inconvertibleErrorCode()));
177 }
llvm::ErrorInfoBase::log
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
llvm::StringError::ID
static char ID
Definition: Error.h:1220
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
LLVMCreateStringError
LLVMErrorRef LLVMCreateStringError(const char *ErrMsg)
Create a StringError.
Definition: Error.cpp:175
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:625
ErrorHandling.h
ManagedStatic.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
LLVMErrorTypeId
const typedef void * LLVMErrorTypeId
Error type identifier.
Definition: Error.h:38
Error.h
llvm::ErrorList::ID
static char ID
Definition: Error.h:385
llvm::FileError
This class wraps a filename and another Error.
Definition: Error.h:1265
llvm::FileError::ID
static char ID
Definition: Error.h:1293
llvm::ECError
This class wraps a std::error_code in a Error.
Definition: Error.h:1143
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1045
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::ECError::ID
static char ID
Definition: Error.h:1154
llvm::ErrorList::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:72
llvm::StringError::log
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Error.cpp:125
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVMGetStringErrorTypeId
LLVMErrorTypeId LLVMGetStringErrorTypeId()
Returns the type id for llvm StringError.
Definition: Error.cpp:171
Twine.h
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:90
llvm::ManagedStatic
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
llvm::unwrap
Attribute unwrap(LLVMAttributeRef Attr)
Definition: Attributes.h:256
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::ErrorInfoBase::convertToErrorCode
virtual std::error_code convertToErrorCode() const =0
Convert this error to a std::error_code.
LLVMConsumeError
void LLVMConsumeError(LLVMErrorRef Err)
Dispose of the given error without handling it.
Definition: Error.cpp:159
llvm::ErrorInfoBase
Base class for error info classes.
Definition: Error.h:48
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
message
message(STATUS "Targeting ${t}") add_subdirectory($
Definition: CMakeLists.txt:33
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::StringError::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:135
llvm::wrap
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:251
llvm::wasm::toString
std::string toString(WasmSymbolType type)
Definition: Wasm.cpp:11
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::logAllUnhandledErrors
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:61
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:78
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1241
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
LLVMGetErrorTypeId
LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err)
Returns the type id for the given error instance, which must be a failure value (i....
Definition: Error.cpp:155
LLVMGetErrorMessage
char * LLVMGetErrorMessage(LLVMErrorRef Err)
Returns the given string's error message.
Definition: Error.cpp:161
ErrorErrorCat
static ManagedStatic< ErrorErrorCategory > ErrorErrorCat
Definition: Error.cpp:49
llvm::errorToErrorCode
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition: Error.cpp:96
LLVMErrorRef
struct LLVMOpaqueError * LLVMErrorRef
Opaque reference to an error instance.
Definition: Error.h:33
llvm::StringError::StringError
StringError(std::error_code EC, const Twine &S=Twine())
Definition: Error.cpp:119
llvm::FileError::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:82
abort
*Add support for compiling functions in both ARM and Thumb then taking the smallest *Add support for compiling individual basic blocks in thumb when in a larger ARM function This can be used for presumed cold like paths to abort(failure path of asserts)
error_category
static ManagedStatic< _object_error_category > error_category
Definition: Error.cpp:76
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1883
LLVMDisposeErrorMessage
void LLVMDisposeErrorMessage(char *ErrMsg)
Dispose of the given error message.
Definition: Error.cpp:169
llvm::handleAllErrors
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:968
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38