LLVM  9.0.0svn
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  return std::error_code(static_cast<int>(ErrorErrorCode::FileError),
84  *ErrorErrorCat);
85 }
86 
87 Error errorCodeToError(std::error_code EC) {
88  if (!EC)
89  return Error::success();
90  return Error(llvm::make_unique<ECError>(ECError(EC)));
91 }
92 
93 std::error_code errorToErrorCode(Error Err) {
94  std::error_code EC;
95  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
96  EC = EI.convertToErrorCode();
97  });
98  if (EC == inconvertibleErrorCode())
99  report_fatal_error(EC.message());
100  return EC;
101 }
102 
103 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
104 void Error::fatalUncheckedError() const {
105  dbgs() << "Program aborted due to an unhandled Error:\n";
106  if (getPtr())
107  getPtr()->log(dbgs());
108  else
109  dbgs() << "Error value was Success. (Note: Success values must still be "
110  "checked prior to being destroyed).\n";
111  abort();
112 }
113 #endif
114 
115 StringError::StringError(std::error_code EC, const Twine &S)
116  : Msg(S.str()), EC(EC) {}
117 
118 StringError::StringError(const Twine &S, std::error_code EC)
119  : Msg(S.str()), EC(EC), PrintMsgOnly(true) {}
120 
121 void StringError::log(raw_ostream &OS) const {
122  if (PrintMsgOnly) {
123  OS << Msg;
124  } else {
125  OS << EC.message();
126  if (!Msg.empty())
127  OS << (" " + Msg);
128  }
129 }
130 
131 std::error_code StringError::convertToErrorCode() const {
132  return EC;
133 }
134 
135 Error createStringError(std::error_code EC, char const *Msg) {
136  return make_error<StringError>(Msg, EC);
137 }
138 
139 void report_fatal_error(Error Err, bool GenCrashDiag) {
140  assert(Err && "report_fatal_error called with success value");
141  std::string ErrMsg;
142  {
143  raw_string_ostream ErrStream(ErrMsg);
144  logAllUnhandledErrors(std::move(Err), ErrStream);
145  }
146  report_fatal_error(ErrMsg);
147 }
148 
149 } // end namespace llvm
150 
152  return reinterpret_cast<ErrorInfoBase *>(Err)->dynamicClassID();
153 }
154 
156 
158  std::string Tmp = toString(unwrap(Err));
159  char *ErrMsg = new char[Tmp.size() + 1];
160  memcpy(ErrMsg, Tmp.data(), Tmp.size());
161  ErrMsg[Tmp.size()] = '\0';
162  return ErrMsg;
163 }
164 
165 void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; }
166 
168  return reinterpret_cast<void *>(&StringError::ID);
169 }
170 
171 #ifndef _MSC_VER
172 namespace llvm {
173 
174 // One of these two variables will be referenced by a symbol defined in
175 // llvm-config.h. We provide a link-time (or load time for DSO) failure when
176 // there is a mismatch in the build configuration of the API client and LLVM.
177 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
178 int EnableABIBreakingChecks;
179 #else
181 #endif
182 
183 } // end namespace llvm
184 #endif
int DisableABIBreakingChecks
Definition: Error.cpp:180
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static const char * getPtr(const MachOObjectFile &O, size_t Offset)
StringError(std::error_code EC, const Twine &S=Twine())
Definition: Error.cpp:115
block Block Frequency true
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:72
ErrorErrorCode
Definition: Error.cpp:19
Base class for error info classes.
Definition: Error.h:48
This class wraps a filename and another Error.
Definition: Error.h:1177
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:966
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
Attribute unwrap(LLVMAttributeRef Attr)
Definition: Attributes.h:194
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: Error.cpp:121
static char ID
Definition: Error.h:380
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:82
struct LLVMOpaqueError * LLVMErrorRef
Opaque reference to an error instance.
Definition: Error.h:26
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
static ManagedStatic< _object_error_category > error_category
Definition: Error.cpp:74
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:981
const void * LLVMErrorTypeId
Error type identifier.
Definition: Error.h:31
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:61
static ManagedStatic< ErrorErrorCategory > ErrorErrorCat
Definition: Error.cpp:49
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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:904
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
LLVMErrorTypeId LLVMGetErrorTypeId(LLVMErrorRef Err)
Returns the type id for the given error instance, which must be a failure value (i.e.
Definition: Error.cpp:151
static char ID
Definition: Error.h:1076
virtual std::error_code convertToErrorCode() const =0
Convert this error to a std::error_code.
void LLVMConsumeError(LLVMErrorRef Err)
Dispose of the given error without handling it.
Definition: Error.cpp:155
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
LLVMErrorTypeId LLVMGetStringErrorTypeId()
Returns the type id for llvm StringError.
Definition: Error.cpp:167
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: Error.cpp:131
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
aarch64 promote const
static const char * name
char * LLVMGetErrorMessage(LLVMErrorRef Err)
Returns the given string&#39;s error message.
Definition: Error.cpp:157
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
This class wraps a std::error_code in a Error.
Definition: Error.h:1065
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
Definition: ManagedStatic.h:83
void LLVMDisposeErrorMessage(char *ErrMsg)
Dispose of the given error message.
Definition: Error.cpp:165
static char ID
Definition: Error.h:1142
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition: Error.cpp:93
static char ID
Definition: Error.h:1193
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1163
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77