Go to the documentation of this file.
13 #ifndef LLVM_SUPPORT_ERROR_H
14 #define LLVM_SUPPORT_ERROR_H
20 #include "llvm/Config/abi-breaking.h"
35 #include <system_error>
36 #include <type_traits>
75 virtual bool isA(
const void *
const ClassID)
const {
80 template <
typename ErrorInfoT>
bool isA()
const {
81 return isA(ErrorInfoT::classID());
85 virtual void anchor();
162 template <
typename... HandlerTs>
196 Error(std::unique_ptr<ErrorInfoBase> Payload) {
197 setPtr(Payload.release());
211 setPtr(
Other.getPtr());
217 Other.setPtr(
nullptr);
218 Other.setChecked(
true);
233 explicit operator bool() {
234 setChecked(
getPtr() ==
nullptr);
235 return getPtr() !=
nullptr;
239 template <
typename ErrT>
bool isA()
const {
248 return getPtr()->dynamicClassID();
252 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
258 [[noreturn]]
void fatalUncheckedError()
const;
261 void assertIsChecked() {
262 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
264 fatalUncheckedError();
268 ErrorInfoBase *
getPtr()
const {
269 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
270 return reinterpret_cast<ErrorInfoBase*
>(
271 reinterpret_cast<uintptr_t
>(Payload) &
272 ~
static_cast<uintptr_t
>(0x1));
278 void setPtr(ErrorInfoBase *EI) {
279 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
280 Payload =
reinterpret_cast<ErrorInfoBase*
>(
281 (
reinterpret_cast<uintptr_t
>(EI) &
282 ~
static_cast<uintptr_t
>(0x1)) |
283 (
reinterpret_cast<uintptr_t
>(Payload) & 0x1));
289 bool getChecked()
const {
290 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
291 return (
reinterpret_cast<uintptr_t
>(Payload) & 0x1) == 0;
297 void setChecked(
bool V) {
298 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
299 Payload =
reinterpret_cast<ErrorInfoBase*
>(
300 (
reinterpret_cast<uintptr_t
>(Payload) &
301 ~
static_cast<uintptr_t
>(0x1)) |
306 std::unique_ptr<ErrorInfoBase> takePayload() {
307 std::unique_ptr<ErrorInfoBase> Tmp(
getPtr());
314 if (
auto *
P =
E.getPtr())
334 return Error(std::make_unique<ErrT>(std::forward<ArgTs>(
Args)...));
346 template <
typename ThisErrT,
typename ParentErrT = ErrorInfoBase>
349 using ParentErrT::ParentErrT;
355 bool isA(
const void *
const ClassID)
const override {
356 return ClassID ==
classID() || ParentErrT::isA(ClassID);
365 template <
typename... HandlerTs>
373 OS <<
"Multiple errors:\n";
374 for (
const auto &ErrPayload : Payloads) {
386 ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
387 std::unique_ptr<ErrorInfoBase> Payload2) {
389 "ErrorList constructor payloads should be singleton errors");
400 auto &E1List =
static_cast<ErrorList &
>(*E1.getPtr());
402 auto E2Payload = E2.takePayload();
403 auto &E2List =
static_cast<ErrorList &
>(*E2Payload);
404 for (
auto &Payload : E2List.Payloads)
405 E1List.Payloads.push_back(
std::move(Payload));
407 E1List.Payloads.push_back(E2.takePayload());
411 if (E2.
isA<ErrorList>()) {
412 auto &E2List =
static_cast<ErrorList &
>(*E2.getPtr());
413 E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
416 return Error(std::unique_ptr<ErrorList>(
417 new ErrorList(E1.takePayload(), E2.takePayload())));
420 std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
473 static constexpr
bool isRef = std::is_reference<T>::value;
475 using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
477 using error_type = std::unique_ptr<ErrorInfoBase>;
484 using reference = std::remove_reference_t<T> &;
485 using const_reference =
const std::remove_reference_t<T> &;
486 using pointer = std::remove_reference_t<T> *;
487 using const_pointer =
const std::remove_reference_t<T> *;
493 #
if LLVM_ENABLE_ABI_BREAKING_CHECKS
498 assert(Err &&
"Cannot create Expected<T> from Error success value.");
499 new (getErrorStorage()) error_type(Err.takePayload());
509 template <
typename OtherT>
511 std::enable_if_t<std::is_convertible<OtherT, T>::value> * =
nullptr)
513 #
if LLVM_ENABLE_ABI_BREAKING_CHECKS
519 new (getStorage())
storage_type(std::forward<OtherT>(Val));
527 template <
class OtherT>
530 std::enable_if_t<std::is_convertible<OtherT, T>::value> * =
nullptr) {
536 template <
class OtherT>
539 std::enable_if_t<!std::is_convertible<OtherT, T>::value> * =
nullptr) {
553 getStorage()->~storage_type();
555 getErrorStorage()->~error_type();
559 explicit operator bool() {
560 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
561 Unchecked = HasError;
569 return *getStorage();
573 const_reference
get()
const {
579 template <
class OtherT>
581 std::enable_if_t<std::is_assignable<OtherT &, T &&>::value> * =
590 return HasError && (*getErrorStorage())->
template isA<ErrT>();
598 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
607 return toPointer(getStorage());
613 return toPointer(getStorage());
619 return *getStorage();
625 return *getStorage();
630 static bool compareThisIfSameType(
const T1 &
a,
const T1 &
b) {
634 template <
class T1,
class T2>
635 static bool compareThisIfSameType(
const T1 &,
const T2 &) {
639 template <
class OtherT>
void moveConstruct(Expected<OtherT> &&
Other) {
640 HasError =
Other.HasError;
641 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
643 Other.Unchecked =
false;
649 new (getErrorStorage()) error_type(
std::move(*
Other.getErrorStorage()));
652 template <
class OtherT>
void moveAssign(Expected<OtherT> &&
Other) {
655 if (compareThisIfSameType(*
this,
Other))
664 const_pointer toPointer(const_pointer Val)
const {
return Val; }
666 pointer toPointer(
wrap *Val) {
return &Val->get(); }
668 const_pointer toPointer(
const wrap *Val)
const {
return &Val->get(); }
670 storage_type *getStorage() {
671 assert(!HasError &&
"Cannot get value when an error exists!");
672 return reinterpret_cast<storage_type *
>(&TStorage);
675 const storage_type *getStorage()
const {
676 assert(!HasError &&
"Cannot get value when an error exists!");
677 return reinterpret_cast<const storage_type *
>(&TStorage);
680 error_type *getErrorStorage() {
681 assert(HasError &&
"Cannot get error when a value exists!");
682 return reinterpret_cast<error_type *
>(&ErrorStorage);
685 const error_type *getErrorStorage()
const {
686 assert(HasError &&
"Cannot get error when a value exists!");
687 return reinterpret_cast<const error_type *
>(&ErrorStorage);
691 void setUnchecked() {
692 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
697 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
699 dbgs() <<
"Expected<T> must be checked before access or destruction.\n";
701 dbgs() <<
"Unchecked Expected<T> contained error:\n";
702 (*getErrorStorage())->log(
dbgs());
704 dbgs() <<
"Expected<T> value was in success state. (Note: Expected<T> "
705 "values in success mode must still be checked prior to being "
711 void assertIsChecked()
const {
712 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
714 fatalUncheckedExpected();
723 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
748 Msg =
"Failure value returned from cantFail wrapped call";
752 OS <<
Msg <<
"\n" << Err;
772 template <
typename T>
778 Msg =
"Failure value returned from cantFail wrapped call";
782 auto E = ValOrErr.takeError();
783 OS <<
Msg <<
"\n" <<
E;
803 template <
typename T>
809 Msg =
"Failure value returned from cantFail wrapped call";
813 auto E = ValOrErr.takeError();
814 OS <<
Msg <<
"\n" <<
E;
823 template <
typename HandlerT>
826 &std::remove_reference<HandlerT>::type::operator())> {};
832 return E.template isA<ErrT>();
835 template <
typename HandlerT>
837 assert(appliesTo(*
E) &&
"Applying incorrect handler");
838 return H(
static_cast<ErrT &
>(*
E));
846 return E.template isA<ErrT>();
849 template <
typename HandlerT>
851 assert(appliesTo(*
E) &&
"Applying incorrect handler");
852 H(
static_cast<ErrT &
>(*
E));
858 template <
typename ErrT>
862 return E.template isA<ErrT>();
865 template <
typename HandlerT>
867 assert(appliesTo(*
E) &&
"Applying incorrect handler");
868 std::unique_ptr<ErrT> SubE(
static_cast<ErrT *
>(
E.release()));
874 template <
typename ErrT>
878 return E.template isA<ErrT>();
881 template <
typename HandlerT>
883 assert(appliesTo(*
E) &&
"Applying incorrect handler");
884 std::unique_ptr<ErrT> SubE(
static_cast<ErrT *
>(
E.release()));
891 template <
typename C,
typename RetT,
typename ErrT>
896 template <
typename C,
typename RetT,
typename ErrT>
901 template <
typename C,
typename RetT,
typename ErrT>
906 template <
typename C,
typename RetT,
typename ErrT>
912 template <
typename C,
typename RetT,
typename ErrT>
918 template <
typename C,
typename RetT,
typename ErrT>
926 template <
typename HandlerT,
typename... HandlerTs>
928 HandlerT &&Handler, HandlerTs &&... Handlers) {
933 std::forward<HandlerTs>(Handlers)...);
942 template <
typename... HandlerTs>
947 std::unique_ptr<ErrorInfoBase> Payload =
E.takePayload();
952 for (
auto &
P :
List.Payloads)
965 template <
typename... HandlerTs>
1000 template <
typename T,
typename RecoveryFtor,
typename... HandlerTs>
1002 HandlerTs &&... Handlers) {
1007 std::forward<HandlerTs>(Handlers)...))
1010 return RecoveryPath();
1031 Errors.push_back(EI.
message());
1033 return join(Errors.begin(), Errors.end(),
"\n");
1067 bool IsError =
static_cast<bool>(Err);
1118 template <
typename T>
1122 : ValOrErr(ValOrErr) {
1129 ValOrErr->setUnchecked();
1144 virtual void anchor()
override;
1180 if (
auto EC = EO.getError())
1187 if (
auto Err =
E.takeError())
1234 const bool PrintMsgOnly =
false;
1238 template <
typename... Ts>
1240 const Ts &... Vals) {
1243 Stream <<
format(Fmt, Vals...);
1244 return make_error<StringError>(Stream.str(), EC);
1253 template <
typename... Ts>
1255 const Ts &... Vals) {
1270 assert(Err &&
"Trying to log after takeError().");
1271 OS <<
"'" << FileName <<
"': ";
1273 OS <<
"line " << Line.
getValue() <<
": ";
1295 std::unique_ptr<ErrorInfoBase>
E) {
1296 assert(
E &&
"Cannot create FileError from Error success value.");
1303 std::unique_ptr<ErrorInfoBase> Payload;
1305 [&](std::unique_ptr<ErrorInfoBase> EIB) ->
Error {
1310 std::unique_ptr<FileError>(
new FileError(
F, Line,
std::move(Payload))));
1313 std::string FileName;
1314 Optional<size_t> Line;
1315 std::unique_ptr<ErrorInfoBase> Err;
1353 GetExitCode([=](
const Error &) {
return DefaultErrorExitCode; }) {}
1360 this->GetExitCode =
std::move(GetExitCode);
1369 checkError(
E.takeError());
1376 checkError(
E.takeError());
1381 void checkError(
Error Err)
const {
1383 int ExitCode = GetExitCode(Err);
1395 return reinterpret_cast<LLVMErrorRef>(Err.takePayload().release());
1400 return Error(std::unique_ptr<ErrorInfoBase>(
1406 #endif // LLVM_SUPPORT_ERROR_H
T operator()(Expected< T > &&E) const
Check E.
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
static const char * getPtr(const MachOObjectFile &O, size_t Offset)
Class representing a numeric value.
static Error apply(HandlerT &&H, std::unique_ptr< ErrorInfoBase > E)
static Error apply(HandlerT &&H, std::unique_ptr< ErrorInfoBase > E)
This is an optimization pass for GlobalISel generic memory operations.
static bool appliesTo(const ErrorInfoBase &E)
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
~Expected()
Destroy an Expected<T>.
std::string messageWithoutFileInfo() const
Special ErrorInfo subclass representing a list of ErrorInfos.
friend Error errorCodeToError(std::error_code)
Helper for converting an std::error_code to a Error.
Expected & operator=(Expected &&Other)
Move-assign from another Expected<T>.
Error(Error &&Other)
Move-construct an error value.
Replace within non kernel function use of LDS with pointer
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
static bool appliesTo(const ErrorInfoBase &E)
A raw_ostream that writes to an std::string.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static ErrorSuccess success()
Create a success value.
ExitOnError(std::string Banner="", int DefaultErrorExitCode=1)
Create an error on exit helper.
void operator()(Error Err) const
Check Err. If it's in a failure state log the error(s) and exit.
This class wraps a filename and another Error.
Helper for check-and-exit error handling.
static bool appliesTo(const ErrorInfoBase &E)
void log(raw_ostream &OS) const override
Print an error message to an output stream.
static Error apply(HandlerT &&H, std::unique_ptr< ErrorInfoBase > E)
const_reference operator*() const
Returns a const reference to the stored T value.
ExpectedAsOutParameter(Expected< T > *ValOrErr)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Tagged union holding either a T or a Error.
std::error_code make_error_code(object_error e)
This class wraps a std::error_code in a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
__FakeVCSRevision h endif() endif() set(generated_files "$
=0.0 ? 0.0 :(a > 0.0 ? 1.0 :-1.0) a
pointer operator->()
Returns a pointer to the stored T value.
constexpr bool hasValue() const
static const void * classID()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Expected(Expected< OtherT > &&Other, std::enable_if_t< std::is_convertible< OtherT, T >::value > *=nullptr)
Move construct an Expected<T> value from an Expected<OtherT>, where OtherT must be convertible to T.
reference operator*()
Returns a reference to the stored T value.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
const_pointer operator->() const
Returns a const pointer to the stored T value.
virtual bool isA(const void *const ClassID) const
class LLVM_NODISCARD Expected
ECError(std::error_code EC)
bool isA() const
Check whether one error is a subclass of another.
void apply(Opt *O, const Mod &M, const Mods &... Ms)
void log(raw_ostream &OS) const override
Print an error message to an output stream.
const void * dynamicClassID() const
Returns the dynamic class id of this error, or null if this is a success value.
Helper for testing applicability of, and applying, handlers for ErrorInfo types.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
(vector float) vec_cmpeq(*A, *B) C
Expected(Expected &&Other)
Move construct an Expected<T> value.
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
Error moveInto(OtherT &Value, std::enable_if_t< std::is_assignable< OtherT &, T && >::value > *=nullptr) &&
Returns takeError() after moving the held T (if any) into V.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void setBanner(std::string Banner)
Set the banner string for any errors caught by operator().
~ExpectedAsOutParameter()
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
Expected(Expected< OtherT > &&Other, std::enable_if_t<!std::is_convertible< OtherT, T >::value > *=nullptr)
Move construct an Expected<T> value from an Expected<OtherT>, where OtherT isn't convertible to T.
friend Error handleErrors(Error E, HandlerTs &&... Handlers)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Attribute unwrap(LLVMAttributeRef Attr)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class implements an extremely fast bulk output stream that can only output to a stream.
Helper for Errors used as out-parameters.
Helper for Expected<T>s used as out-parameters.
virtual ~ErrorInfoBase()=default
virtual std::error_code convertToErrorCode() const =0
Convert this error to a std::error_code.
StringRef getFileName() const
Base class for error info classes.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
virtual std::string message() const
Return the error message as a string.
Expected(Error Err)
Create an Expected<T> error value from the given Error.
void setErrorCode(std::error_code EC)
friend raw_ostream & operator<<(raw_ostream &OS, const Error &E)
Expected< T > handleExpected(Expected< T > ValOrErr, RecoveryFtor &&RecoveryPath, HandlerTs &&... Handlers)
Handle any errors (if present) in an Expected<T>, then try a recovery path.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Error handleErrorImpl(std::unique_ptr< ErrorInfoBase > Payload)
const_reference get() const
Returns a const reference to the stored T value.
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
Error()
Create a success value. Prefer using 'Error::success()' for readability.
bool isA(const void *const ClassID) const override
Expected(OtherT &&Val, std::enable_if_t< std::is_convertible< OtherT, T >::value > *=nullptr)
Create an Expected<T> success value from the given OtherT value, which must be convertible to T.
Subclass of Error for the sole purpose of identifying the success path in the type system.
static bool appliesTo(const ErrorInfoBase &E)
Error joinErrors(Error E1, Error E2)
Concatenate errors.
friend Error createFileError(const Twine &, Error)
Concatenate a source file path and/or name with an Error.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
constexpr const T & getValue() const &
print Print MemDeps of function
Optional< T > expectedToOptional(Expected< T > &&E)
Convert an Expected to an Optional without doing anything.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
This class wraps a string in an Error.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Base class for user error types.
std::conditional_t< isRef, wrap, ExpressionValue > storage_type
static Error apply(HandlerT &&H, std::unique_ptr< ErrorInfoBase > E)
const std::string & getMessage() const
LLVMAttributeRef wrap(Attribute Attr)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
if(llvm_vc STREQUAL "") set(fake_version_inc "$
reference get()
Returns a reference to the stored T value.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
ErrorAsOutParameter(Error *Err)
Error(std::unique_ptr< ErrorInfoBase > Payload)
Create an error value.
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
static const void * classID()
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error & operator=(Error &&Other)
Move-assign an error value.
void setExitCodeMapper(std::function< int(const Error &)> GetExitCode)
Set the exit-code mapper function.
bool errorIsA() const
Check that this Expected<T> is an error of type ErrT.
const CustomOperand< const MCSubtargetInfo & > Msg[]
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Should compile to something r4 addze r3 instead we get
const char * toString(DWARFSectionKind Kind)
Lightweight error class with error context and mandatory checking.
AlignedCharArrayUnion< error_type > ErrorStorage
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
AlignedCharArrayUnion< storage_type > TStorage
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
Error takeError()
Take ownership of the stored error.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
declare void exit(i32) noreturn nounwind This compiles into
struct LLVMOpaqueError * LLVMErrorRef
Opaque reference to an error instance.
Represents either an error or a value T.
virtual const void * dynamicClassID() const =0
StringError(std::error_code EC, const Twine &S=Twine())
T & operator()(Expected< T & > &&E) const
Check E.
const void * dynamicClassID() const override
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
ErrorOr< T > expectedToErrorOr(Expected< T > &&E)
Convert an Expected<T> to an ErrorOr<T>.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
*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)
#define LLVM_UNLIKELY(EXPR)
std::string & str()
Returns the string's reference.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
LLVM Value Representation.
Optional< std::vector< StOtherPiece > > Other
friend Error joinErrors(Error, Error)
Concatenate errors.