File indexing completed on 2026-05-10 08:44:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_SUPPORT_ERROR_H
0014 #define LLVM_SUPPORT_ERROR_H
0015
0016 #include "llvm-c/Error.h"
0017 #include "llvm/ADT/Twine.h"
0018 #include "llvm/Config/abi-breaking.h"
0019 #include "llvm/Support/AlignOf.h"
0020 #include "llvm/Support/Compiler.h"
0021 #include "llvm/Support/Debug.h"
0022 #include "llvm/Support/ErrorHandling.h"
0023 #include "llvm/Support/ErrorOr.h"
0024 #include "llvm/Support/Format.h"
0025 #include "llvm/Support/raw_ostream.h"
0026 #include <cassert>
0027 #include <cstdint>
0028 #include <cstdlib>
0029 #include <functional>
0030 #include <memory>
0031 #include <new>
0032 #include <optional>
0033 #include <string>
0034 #include <system_error>
0035 #include <type_traits>
0036 #include <utility>
0037 #include <vector>
0038
0039 namespace llvm {
0040
0041 class ErrorSuccess;
0042
0043
0044
0045 class ErrorInfoBase {
0046 public:
0047 virtual ~ErrorInfoBase() = default;
0048
0049
0050 virtual void log(raw_ostream &OS) const = 0;
0051
0052
0053 virtual std::string message() const {
0054 std::string Msg;
0055 raw_string_ostream OS(Msg);
0056 log(OS);
0057 return Msg;
0058 }
0059
0060
0061
0062
0063
0064 virtual std::error_code convertToErrorCode() const = 0;
0065
0066
0067 static const void *classID() { return &ID; }
0068
0069
0070 virtual const void *dynamicClassID() const = 0;
0071
0072
0073
0074 virtual bool isA(const void *const ClassID) const {
0075 return ClassID == classID();
0076 }
0077
0078
0079 template <typename ErrorInfoT> bool isA() const {
0080 return isA(ErrorInfoT::classID());
0081 }
0082
0083 private:
0084 virtual void anchor();
0085
0086 static char ID;
0087 };
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 class [[nodiscard]] Error {
0161
0162
0163
0164 friend class ErrorList;
0165
0166
0167 template <typename... HandlerTs>
0168 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
0169
0170 template <typename HandlerT>
0171 friend void visitErrors(const Error &E, HandlerT H);
0172
0173
0174
0175 template <typename T> friend class Expected;
0176
0177
0178 friend LLVMErrorRef wrap(Error);
0179
0180 protected:
0181
0182 Error() {
0183 setPtr(nullptr);
0184 setChecked(false);
0185 }
0186
0187 public:
0188
0189 static ErrorSuccess success();
0190
0191
0192 Error(const Error &Other) = delete;
0193
0194
0195
0196
0197 Error(Error &&Other) {
0198 setChecked(true);
0199 *this = std::move(Other);
0200 }
0201
0202
0203
0204 Error(std::unique_ptr<ErrorInfoBase> Payload) {
0205 setPtr(Payload.release());
0206 setChecked(false);
0207 }
0208
0209
0210 Error &operator=(const Error &Other) = delete;
0211
0212
0213
0214
0215
0216 Error &operator=(Error &&Other) {
0217
0218 assertIsChecked();
0219 setPtr(Other.getPtr());
0220
0221
0222 setChecked(false);
0223
0224
0225 Other.setPtr(nullptr);
0226 Other.setChecked(true);
0227
0228 return *this;
0229 }
0230
0231
0232
0233 ~Error() {
0234 assertIsChecked();
0235 delete getPtr();
0236 }
0237
0238
0239
0240
0241 explicit operator bool() {
0242 setChecked(getPtr() == nullptr);
0243 return getPtr() != nullptr;
0244 }
0245
0246
0247 template <typename ErrT> bool isA() const {
0248 return getPtr() && getPtr()->isA(ErrT::classID());
0249 }
0250
0251
0252
0253 const void* dynamicClassID() const {
0254 if (!getPtr())
0255 return nullptr;
0256 return getPtr()->dynamicClassID();
0257 }
0258
0259 private:
0260 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0261
0262
0263
0264
0265
0266 [[noreturn]] void fatalUncheckedError() const;
0267 #endif
0268
0269 void assertIsChecked() {
0270 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0271 if (LLVM_UNLIKELY(!getChecked() || getPtr()))
0272 fatalUncheckedError();
0273 #endif
0274 }
0275
0276 ErrorInfoBase *getPtr() const {
0277 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0278 return reinterpret_cast<ErrorInfoBase*>(
0279 reinterpret_cast<uintptr_t>(Payload) &
0280 ~static_cast<uintptr_t>(0x1));
0281 #else
0282 return Payload;
0283 #endif
0284 }
0285
0286 void setPtr(ErrorInfoBase *EI) {
0287 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0288 Payload = reinterpret_cast<ErrorInfoBase*>(
0289 (reinterpret_cast<uintptr_t>(EI) &
0290 ~static_cast<uintptr_t>(0x1)) |
0291 (reinterpret_cast<uintptr_t>(Payload) & 0x1));
0292 #else
0293 Payload = EI;
0294 #endif
0295 }
0296
0297 bool getChecked() const {
0298 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0299 return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0;
0300 #else
0301 return true;
0302 #endif
0303 }
0304
0305 void setChecked(bool V) {
0306 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0307 Payload = reinterpret_cast<ErrorInfoBase*>(
0308 (reinterpret_cast<uintptr_t>(Payload) &
0309 ~static_cast<uintptr_t>(0x1)) |
0310 (V ? 0 : 1));
0311 #endif
0312 }
0313
0314 std::unique_ptr<ErrorInfoBase> takePayload() {
0315 std::unique_ptr<ErrorInfoBase> Tmp(getPtr());
0316 setPtr(nullptr);
0317 setChecked(true);
0318 return Tmp;
0319 }
0320
0321 friend raw_ostream &operator<<(raw_ostream &OS, const Error &E) {
0322 if (auto *P = E.getPtr())
0323 P->log(OS);
0324 else
0325 OS << "success";
0326 return OS;
0327 }
0328
0329 ErrorInfoBase *Payload = nullptr;
0330 };
0331
0332
0333
0334
0335 class ErrorSuccess final : public Error {};
0336
0337 inline ErrorSuccess Error::success() { return ErrorSuccess(); }
0338
0339
0340
0341 template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
0342 return Error(std::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
0343 }
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
0355 class ErrorInfo : public ParentErrT {
0356 public:
0357 using ParentErrT::ParentErrT;
0358
0359 static const void *classID() { return &ThisErrT::ID; }
0360
0361 const void *dynamicClassID() const override { return &ThisErrT::ID; }
0362
0363 bool isA(const void *const ClassID) const override {
0364 return ClassID == classID() || ParentErrT::isA(ClassID);
0365 }
0366 };
0367
0368
0369
0370 class ErrorList final : public ErrorInfo<ErrorList> {
0371
0372
0373 template <typename... HandlerTs>
0374 friend Error handleErrors(Error E, HandlerTs &&... Handlers);
0375
0376
0377 template <typename HandlerT>
0378 friend void visitErrors(const Error &E, HandlerT H);
0379
0380
0381 friend Error joinErrors(Error, Error);
0382
0383 public:
0384 void log(raw_ostream &OS) const override {
0385 OS << "Multiple errors:\n";
0386 for (const auto &ErrPayload : Payloads) {
0387 ErrPayload->log(OS);
0388 OS << "\n";
0389 }
0390 }
0391
0392 std::error_code convertToErrorCode() const override;
0393
0394
0395 static char ID;
0396
0397 private:
0398 ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
0399 std::unique_ptr<ErrorInfoBase> Payload2) {
0400 assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&
0401 "ErrorList constructor payloads should be singleton errors");
0402 Payloads.push_back(std::move(Payload1));
0403 Payloads.push_back(std::move(Payload2));
0404 }
0405
0406 static Error join(Error E1, Error E2) {
0407 if (!E1)
0408 return E2;
0409 if (!E2)
0410 return E1;
0411 if (E1.isA<ErrorList>()) {
0412 auto &E1List = static_cast<ErrorList &>(*E1.getPtr());
0413 if (E2.isA<ErrorList>()) {
0414 auto E2Payload = E2.takePayload();
0415 auto &E2List = static_cast<ErrorList &>(*E2Payload);
0416 for (auto &Payload : E2List.Payloads)
0417 E1List.Payloads.push_back(std::move(Payload));
0418 } else
0419 E1List.Payloads.push_back(E2.takePayload());
0420
0421 return E1;
0422 }
0423 if (E2.isA<ErrorList>()) {
0424 auto &E2List = static_cast<ErrorList &>(*E2.getPtr());
0425 E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
0426 return E2;
0427 }
0428 return Error(std::unique_ptr<ErrorList>(
0429 new ErrorList(E1.takePayload(), E2.takePayload())));
0430 }
0431
0432 std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
0433 };
0434
0435
0436
0437
0438 inline Error joinErrors(Error E1, Error E2) {
0439 return ErrorList::join(std::move(E1), std::move(E2));
0440 }
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481 template <class T> class [[nodiscard]] Expected {
0482 template <class T1> friend class ExpectedAsOutParameter;
0483 template <class OtherT> friend class Expected;
0484
0485 static constexpr bool isRef = std::is_reference_v<T>;
0486
0487 using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
0488
0489 using error_type = std::unique_ptr<ErrorInfoBase>;
0490
0491 public:
0492 using storage_type = std::conditional_t<isRef, wrap, T>;
0493 using value_type = T;
0494
0495 private:
0496 using reference = std::remove_reference_t<T> &;
0497 using const_reference = const std::remove_reference_t<T> &;
0498 using pointer = std::remove_reference_t<T> *;
0499 using const_pointer = const std::remove_reference_t<T> *;
0500
0501 public:
0502
0503 Expected(Error &&Err)
0504 : HasError(true)
0505 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0506
0507 , Unchecked(true)
0508 #endif
0509 {
0510 assert(Err && "Cannot create Expected<T> from Error success value.");
0511 new (getErrorStorage()) error_type(Err.takePayload());
0512 }
0513
0514
0515
0516
0517 Expected(ErrorSuccess) = delete;
0518
0519
0520
0521 template <typename OtherT>
0522 Expected(OtherT &&Val,
0523 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
0524 : HasError(false)
0525 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0526
0527 ,
0528 Unchecked(true)
0529 #endif
0530 {
0531 new (getStorage()) storage_type(std::forward<OtherT>(Val));
0532 }
0533
0534
0535 Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
0536
0537
0538
0539 template <class OtherT>
0540 Expected(Expected<OtherT> &&Other,
0541 std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {
0542 moveConstruct(std::move(Other));
0543 }
0544
0545
0546
0547 template <class OtherT>
0548 explicit Expected(
0549 Expected<OtherT> &&Other,
0550 std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr) {
0551 moveConstruct(std::move(Other));
0552 }
0553
0554
0555 Expected &operator=(Expected &&Other) {
0556 moveAssign(std::move(Other));
0557 return *this;
0558 }
0559
0560
0561 ~Expected() {
0562 assertIsChecked();
0563 if (!HasError)
0564 getStorage()->~storage_type();
0565 else
0566 getErrorStorage()->~error_type();
0567 }
0568
0569
0570 explicit operator bool() {
0571 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0572 Unchecked = HasError;
0573 #endif
0574 return !HasError;
0575 }
0576
0577
0578 reference get() {
0579 assertIsChecked();
0580 return *getStorage();
0581 }
0582
0583
0584 const_reference get() const {
0585 assertIsChecked();
0586 return const_cast<Expected<T> *>(this)->get();
0587 }
0588
0589
0590 template <class OtherT>
0591 Error moveInto(
0592 OtherT &Value,
0593 std::enable_if_t<std::is_assignable_v<OtherT &, T &&>> * = nullptr) && {
0594 if (*this)
0595 Value = std::move(get());
0596 return takeError();
0597 }
0598
0599
0600 template <typename ErrT> bool errorIsA() const {
0601 return HasError && (*getErrorStorage())->template isA<ErrT>();
0602 }
0603
0604
0605
0606
0607
0608 Error takeError() {
0609 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0610 Unchecked = false;
0611 #endif
0612 return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
0613 }
0614
0615
0616 pointer operator->() {
0617 assertIsChecked();
0618 return toPointer(getStorage());
0619 }
0620
0621
0622 const_pointer operator->() const {
0623 assertIsChecked();
0624 return toPointer(getStorage());
0625 }
0626
0627
0628 reference operator*() {
0629 assertIsChecked();
0630 return *getStorage();
0631 }
0632
0633
0634 const_reference operator*() const {
0635 assertIsChecked();
0636 return *getStorage();
0637 }
0638
0639 private:
0640 template <class T1>
0641 static bool compareThisIfSameType(const T1 &a, const T1 &b) {
0642 return &a == &b;
0643 }
0644
0645 template <class T1, class T2>
0646 static bool compareThisIfSameType(const T1 &, const T2 &) {
0647 return false;
0648 }
0649
0650 template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
0651 HasError = Other.HasError;
0652 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0653 Unchecked = true;
0654 Other.Unchecked = false;
0655 #endif
0656
0657 if (!HasError)
0658 new (getStorage()) storage_type(std::move(*Other.getStorage()));
0659 else
0660 new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
0661 }
0662
0663 template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
0664 assertIsChecked();
0665
0666 if (compareThisIfSameType(*this, Other))
0667 return;
0668
0669 this->~Expected();
0670 new (this) Expected(std::move(Other));
0671 }
0672
0673 pointer toPointer(pointer Val) { return Val; }
0674
0675 const_pointer toPointer(const_pointer Val) const { return Val; }
0676
0677 pointer toPointer(wrap *Val) { return &Val->get(); }
0678
0679 const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
0680
0681 storage_type *getStorage() {
0682 assert(!HasError && "Cannot get value when an error exists!");
0683 return reinterpret_cast<storage_type *>(&TStorage);
0684 }
0685
0686 const storage_type *getStorage() const {
0687 assert(!HasError && "Cannot get value when an error exists!");
0688 return reinterpret_cast<const storage_type *>(&TStorage);
0689 }
0690
0691 error_type *getErrorStorage() {
0692 assert(HasError && "Cannot get error when a value exists!");
0693 return reinterpret_cast<error_type *>(&ErrorStorage);
0694 }
0695
0696 const error_type *getErrorStorage() const {
0697 assert(HasError && "Cannot get error when a value exists!");
0698 return reinterpret_cast<const error_type *>(&ErrorStorage);
0699 }
0700
0701
0702 void setUnchecked() {
0703 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0704 Unchecked = true;
0705 #endif
0706 }
0707
0708 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0709 [[noreturn]] LLVM_ATTRIBUTE_NOINLINE void fatalUncheckedExpected() const {
0710 dbgs() << "Expected<T> must be checked before access or destruction.\n";
0711 if (HasError) {
0712 dbgs() << "Unchecked Expected<T> contained error:\n";
0713 (*getErrorStorage())->log(dbgs());
0714 } else
0715 dbgs() << "Expected<T> value was in success state. (Note: Expected<T> "
0716 "values in success mode must still be checked prior to being "
0717 "destroyed).\n";
0718 abort();
0719 }
0720 #endif
0721
0722 void assertIsChecked() const {
0723 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0724 if (LLVM_UNLIKELY(Unchecked))
0725 fatalUncheckedExpected();
0726 #endif
0727 }
0728
0729 union {
0730 AlignedCharArrayUnion<storage_type> TStorage;
0731 AlignedCharArrayUnion<error_type> ErrorStorage;
0732 };
0733 bool HasError : 1;
0734 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0735 bool Unchecked : 1;
0736 #endif
0737 };
0738
0739
0740
0741 [[noreturn]] void report_fatal_error(Error Err, bool gen_crash_diag = true);
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756 inline void cantFail(Error Err, const char *Msg = nullptr) {
0757 if (Err) {
0758 if (!Msg)
0759 Msg = "Failure value returned from cantFail wrapped call";
0760 #ifndef NDEBUG
0761 std::string Str;
0762 raw_string_ostream OS(Str);
0763 OS << Msg << "\n" << Err;
0764 Msg = Str.c_str();
0765 #endif
0766 llvm_unreachable(Msg);
0767 }
0768 }
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 template <typename T>
0784 T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) {
0785 if (ValOrErr)
0786 return std::move(*ValOrErr);
0787 else {
0788 if (!Msg)
0789 Msg = "Failure value returned from cantFail wrapped call";
0790 #ifndef NDEBUG
0791 std::string Str;
0792 raw_string_ostream OS(Str);
0793 auto E = ValOrErr.takeError();
0794 OS << Msg << "\n" << E;
0795 Msg = Str.c_str();
0796 #endif
0797 llvm_unreachable(Msg);
0798 }
0799 }
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814 template <typename T>
0815 T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) {
0816 if (ValOrErr)
0817 return *ValOrErr;
0818 else {
0819 if (!Msg)
0820 Msg = "Failure value returned from cantFail wrapped call";
0821 #ifndef NDEBUG
0822 std::string Str;
0823 raw_string_ostream OS(Str);
0824 auto E = ValOrErr.takeError();
0825 OS << Msg << "\n" << E;
0826 Msg = Str.c_str();
0827 #endif
0828 llvm_unreachable(Msg);
0829 }
0830 }
0831
0832
0833
0834 template <typename HandlerT>
0835 class ErrorHandlerTraits
0836 : public ErrorHandlerTraits<
0837 decltype(&std::remove_reference_t<HandlerT>::operator())> {};
0838
0839
0840 template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
0841 public:
0842 static bool appliesTo(const ErrorInfoBase &E) {
0843 return E.template isA<ErrT>();
0844 }
0845
0846 template <typename HandlerT>
0847 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
0848 assert(appliesTo(*E) && "Applying incorrect handler");
0849 return H(static_cast<ErrT &>(*E));
0850 }
0851 };
0852
0853
0854 template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
0855 public:
0856 static bool appliesTo(const ErrorInfoBase &E) {
0857 return E.template isA<ErrT>();
0858 }
0859
0860 template <typename HandlerT>
0861 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
0862 assert(appliesTo(*E) && "Applying incorrect handler");
0863 H(static_cast<ErrT &>(*E));
0864 return Error::success();
0865 }
0866 };
0867
0868
0869 template <typename ErrT>
0870 class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
0871 public:
0872 static bool appliesTo(const ErrorInfoBase &E) {
0873 return E.template isA<ErrT>();
0874 }
0875
0876 template <typename HandlerT>
0877 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
0878 assert(appliesTo(*E) && "Applying incorrect handler");
0879 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
0880 return H(std::move(SubE));
0881 }
0882 };
0883
0884
0885 template <typename ErrT>
0886 class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
0887 public:
0888 static bool appliesTo(const ErrorInfoBase &E) {
0889 return E.template isA<ErrT>();
0890 }
0891
0892 template <typename HandlerT>
0893 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
0894 assert(appliesTo(*E) && "Applying incorrect handler");
0895 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
0896 H(std::move(SubE));
0897 return Error::success();
0898 }
0899 };
0900
0901
0902 template <typename C, typename RetT, typename ErrT>
0903 class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
0904 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
0905
0906
0907 template <typename C, typename RetT, typename ErrT>
0908 class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
0909 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
0910
0911
0912 template <typename C, typename RetT, typename ErrT>
0913 class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
0914 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
0915
0916
0917 template <typename C, typename RetT, typename ErrT>
0918 class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
0919 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
0920
0921
0922
0923 template <typename C, typename RetT, typename ErrT>
0924 class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
0925 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
0926
0927
0928
0929 template <typename C, typename RetT, typename ErrT>
0930 class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
0931 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
0932
0933 inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
0934 return Error(std::move(Payload));
0935 }
0936
0937 template <typename HandlerT, typename... HandlerTs>
0938 Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
0939 HandlerT &&Handler, HandlerTs &&... Handlers) {
0940 if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
0941 return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
0942 std::move(Payload));
0943 return handleErrorImpl(std::move(Payload),
0944 std::forward<HandlerTs>(Handlers)...);
0945 }
0946
0947
0948
0949
0950
0951
0952
0953 template <typename... HandlerTs>
0954 Error handleErrors(Error E, HandlerTs &&... Hs) {
0955 if (!E)
0956 return Error::success();
0957
0958 std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
0959
0960 if (Payload->isA<ErrorList>()) {
0961 ErrorList &List = static_cast<ErrorList &>(*Payload);
0962 Error R;
0963 for (auto &P : List.Payloads)
0964 R = ErrorList::join(
0965 std::move(R),
0966 handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
0967 return R;
0968 }
0969
0970 return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...);
0971 }
0972
0973
0974
0975
0976 template <typename... HandlerTs>
0977 void handleAllErrors(Error E, HandlerTs &&... Handlers) {
0978 cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...));
0979 }
0980
0981
0982
0983 inline void handleAllErrors(Error E) {
0984 cantFail(std::move(E));
0985 }
0986
0987
0988
0989 template <typename HandlerT> void visitErrors(const Error &E, HandlerT H) {
0990 const ErrorInfoBase *Payload = E.getPtr();
0991 if (!Payload)
0992 return;
0993
0994 if (Payload->isA<ErrorList>()) {
0995 const ErrorList &List = static_cast<const ErrorList &>(*Payload);
0996 for (const auto &P : List.Payloads)
0997 H(*P);
0998 return;
0999 }
1000
1001 return H(*Payload);
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 template <typename T, typename RecoveryFtor, typename... HandlerTs>
1029 Expected<T> handleExpected(Expected<T> ValOrErr, RecoveryFtor &&RecoveryPath,
1030 HandlerTs &&... Handlers) {
1031 if (ValOrErr)
1032 return ValOrErr;
1033
1034 if (auto Err = handleErrors(ValOrErr.takeError(),
1035 std::forward<HandlerTs>(Handlers)...))
1036 return std::move(Err);
1037
1038 return RecoveryPath();
1039 }
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052 void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner = {});
1053
1054
1055
1056 std::string toString(Error E);
1057
1058
1059
1060 std::string toStringWithoutConsuming(const Error &E);
1061
1062
1063
1064
1065
1066
1067
1068
1069 inline void consumeError(Error Err) {
1070 handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
1071 }
1072
1073
1074
1075
1076
1077
1078
1079
1080 template <typename T> std::optional<T> expectedToOptional(Expected<T> &&E) {
1081 if (E)
1082 return std::move(*E);
1083 consumeError(E.takeError());
1084 return std::nullopt;
1085 }
1086
1087 template <typename T> std::optional<T> expectedToStdOptional(Expected<T> &&E) {
1088 if (E)
1089 return std::move(*E);
1090 consumeError(E.takeError());
1091 return std::nullopt;
1092 }
1093
1094
1095
1096
1097
1098
1099 inline bool errorToBool(Error Err) {
1100 bool IsError = static_cast<bool>(Err);
1101 if (IsError)
1102 consumeError(std::move(Err));
1103 return IsError;
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 class ErrorAsOutParameter {
1131 public:
1132
1133 ErrorAsOutParameter(Error *Err) : Err(Err) {
1134
1135 if (Err)
1136 (void)!!*Err;
1137 }
1138
1139 ErrorAsOutParameter(Error &Err) : Err(&Err) {
1140 (void)!!Err;
1141 }
1142
1143 ~ErrorAsOutParameter() {
1144
1145 if (Err && !*Err)
1146 *Err = Error::success();
1147 }
1148
1149 private:
1150 Error *Err;
1151 };
1152
1153
1154
1155
1156 template <typename T>
1157 class ExpectedAsOutParameter {
1158 public:
1159 ExpectedAsOutParameter(Expected<T> *ValOrErr)
1160 : ValOrErr(ValOrErr) {
1161 if (ValOrErr)
1162 (void)!!*ValOrErr;
1163 }
1164
1165 ~ExpectedAsOutParameter() {
1166 if (ValOrErr)
1167 ValOrErr->setUnchecked();
1168 }
1169
1170 private:
1171 Expected<T> *ValOrErr;
1172 };
1173
1174
1175
1176
1177
1178
1179 class ECError : public ErrorInfo<ECError> {
1180 friend Error errorCodeToError(std::error_code);
1181
1182 void anchor() override;
1183
1184 public:
1185 void setErrorCode(std::error_code EC) { this->EC = EC; }
1186 std::error_code convertToErrorCode() const override { return EC; }
1187 void log(raw_ostream &OS) const override { OS << EC.message(); }
1188
1189
1190 static char ID;
1191
1192 protected:
1193 ECError() = default;
1194 ECError(std::error_code EC) : EC(EC) {}
1195
1196 std::error_code EC;
1197 };
1198
1199
1200
1201
1202
1203
1204
1205 std::error_code inconvertibleErrorCode();
1206
1207
1208 Error errorCodeToError(std::error_code EC);
1209
1210
1211
1212
1213
1214 std::error_code errorToErrorCode(Error Err);
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 inline std::error_code errnoAsErrorCode() {
1227 return std::error_code(errno, std::generic_category());
1228 }
1229
1230
1231 template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
1232 if (auto EC = EO.getError())
1233 return errorCodeToError(EC);
1234 return std::move(*EO);
1235 }
1236
1237
1238 template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
1239 if (auto Err = E.takeError())
1240 return errorToErrorCode(std::move(Err));
1241 return std::move(*E);
1242 }
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268 class StringError : public ErrorInfo<StringError> {
1269 public:
1270 static char ID;
1271
1272 StringError(std::string &&S, std::error_code EC, bool PrintMsgOnly);
1273
1274 StringError(std::error_code EC, const Twine &S = Twine());
1275
1276 StringError(const Twine &S, std::error_code EC);
1277
1278 void log(raw_ostream &OS) const override;
1279 std::error_code convertToErrorCode() const override;
1280
1281 const std::string &getMessage() const { return Msg; }
1282
1283 private:
1284 std::string Msg;
1285 std::error_code EC;
1286 const bool PrintMsgOnly = false;
1287 };
1288
1289
1290 template <typename... Ts>
1291 inline Error createStringError(std::error_code EC, char const *Fmt,
1292 const Ts &... Vals) {
1293 std::string Buffer;
1294 raw_string_ostream(Buffer) << format(Fmt, Vals...);
1295 return make_error<StringError>(Buffer, EC);
1296 }
1297
1298 Error createStringError(std::string &&Msg, std::error_code EC);
1299
1300 inline Error createStringError(std::error_code EC, const char *S) {
1301 return createStringError(std::string(S), EC);
1302 }
1303
1304 inline Error createStringError(std::error_code EC, const Twine &S) {
1305 return createStringError(S.str(), EC);
1306 }
1307
1308
1309 inline Error createStringError(const Twine &S) {
1310 return createStringError(llvm::inconvertibleErrorCode(), S);
1311 }
1312
1313 template <typename... Ts>
1314 inline Error createStringError(char const *Fmt, const Ts &...Vals) {
1315 return createStringError(llvm::inconvertibleErrorCode(), Fmt, Vals...);
1316 }
1317
1318 template <typename... Ts>
1319 inline Error createStringError(std::errc EC, char const *Fmt,
1320 const Ts &... Vals) {
1321 return createStringError(std::make_error_code(EC), Fmt, Vals...);
1322 }
1323
1324
1325
1326
1327
1328 class FileError final : public ErrorInfo<FileError> {
1329
1330 friend Error createFileError(const Twine &, Error);
1331 friend Error createFileError(const Twine &, size_t, Error);
1332
1333 public:
1334 void log(raw_ostream &OS) const override {
1335 assert(Err && "Trying to log after takeError().");
1336 OS << "'" << FileName << "': ";
1337 if (Line)
1338 OS << "line " << *Line << ": ";
1339 Err->log(OS);
1340 }
1341
1342 std::string messageWithoutFileInfo() const {
1343 std::string Msg;
1344 raw_string_ostream OS(Msg);
1345 Err->log(OS);
1346 return Msg;
1347 }
1348
1349 StringRef getFileName() const { return FileName; }
1350
1351 Error takeError() { return Error(std::move(Err)); }
1352
1353 std::error_code convertToErrorCode() const override;
1354
1355
1356 static char ID;
1357
1358 private:
1359 FileError(const Twine &F, std::optional<size_t> LineNum,
1360 std::unique_ptr<ErrorInfoBase> E) {
1361 assert(E && "Cannot create FileError from Error success value.");
1362 FileName = F.str();
1363 Err = std::move(E);
1364 Line = std::move(LineNum);
1365 }
1366
1367 static Error build(const Twine &F, std::optional<size_t> Line, Error E) {
1368 std::unique_ptr<ErrorInfoBase> Payload;
1369 handleAllErrors(std::move(E),
1370 [&](std::unique_ptr<ErrorInfoBase> EIB) -> Error {
1371 Payload = std::move(EIB);
1372 return Error::success();
1373 });
1374 return Error(
1375 std::unique_ptr<FileError>(new FileError(F, Line, std::move(Payload))));
1376 }
1377
1378 std::string FileName;
1379 std::optional<size_t> Line;
1380 std::unique_ptr<ErrorInfoBase> Err;
1381 };
1382
1383
1384
1385 inline Error createFileError(const Twine &F, Error E) {
1386 return FileError::build(F, std::optional<size_t>(), std::move(E));
1387 }
1388
1389
1390
1391 inline Error createFileError(const Twine &F, size_t Line, Error E) {
1392 return FileError::build(F, std::optional<size_t>(Line), std::move(E));
1393 }
1394
1395
1396
1397 inline Error createFileError(const Twine &F, std::error_code EC) {
1398 return createFileError(F, errorCodeToError(EC));
1399 }
1400
1401
1402
1403 inline Error createFileError(const Twine &F, size_t Line, std::error_code EC) {
1404 return createFileError(F, Line, errorCodeToError(EC));
1405 }
1406
1407
1408
1409 inline Error createFileError(const Twine &F, std::error_code EC,
1410 const Twine &S) {
1411 Error E = createStringError(EC, S);
1412 return createFileError(F, std::move(E));
1413 }
1414
1415
1416
1417 template <typename... Ts>
1418 inline Error createFileError(const Twine &F, std::error_code EC,
1419 char const *Fmt, const Ts &...Vals) {
1420 Error E = createStringError(EC, Fmt, Vals...);
1421 return createFileError(F, std::move(E));
1422 }
1423
1424 Error createFileError(const Twine &F, ErrorSuccess) = delete;
1425
1426
1427
1428
1429
1430 class ExitOnError {
1431 public:
1432
1433 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
1434 : Banner(std::move(Banner)),
1435 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
1436
1437
1438 void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
1439
1440
1441 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
1442 this->GetExitCode = std::move(GetExitCode);
1443 }
1444
1445
1446 void operator()(Error Err) const { checkError(std::move(Err)); }
1447
1448
1449
1450 template <typename T> T operator()(Expected<T> &&E) const {
1451 checkError(E.takeError());
1452 return std::move(*E);
1453 }
1454
1455
1456
1457 template <typename T> T& operator()(Expected<T&> &&E) const {
1458 checkError(E.takeError());
1459 return *E;
1460 }
1461
1462 private:
1463 void checkError(Error Err) const {
1464 if (Err) {
1465 int ExitCode = GetExitCode(Err);
1466 logAllUnhandledErrors(std::move(Err), errs(), Banner);
1467 exit(ExitCode);
1468 }
1469 }
1470
1471 std::string Banner;
1472 std::function<int(const Error &)> GetExitCode;
1473 };
1474
1475
1476 inline LLVMErrorRef wrap(Error Err) {
1477 return reinterpret_cast<LLVMErrorRef>(Err.takePayload().release());
1478 }
1479
1480
1481 inline Error unwrap(LLVMErrorRef ErrRef) {
1482 return Error(std::unique_ptr<ErrorInfoBase>(
1483 reinterpret_cast<ErrorInfoBase *>(ErrRef)));
1484 }
1485
1486 }
1487
1488 #endif