LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/Support - Error.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 0.0 % 57 0
Test Date: 2026-07-03 19:57:34 Functions: 0.0 % 18 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 24 0

             Branch data     Line data    Source code
       1                 :             : //===- llvm/Support/Error.h - Recoverable error handling --------*- C++ -*-===//
       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                 :             : // This file defines an API used to report recoverable errors.
      10                 :             : //
      11                 :             : //===----------------------------------------------------------------------===//
      12                 :             : 
      13                 :             : #ifndef LLVM_SUPPORT_ERROR_H
      14                 :             : #define LLVM_SUPPORT_ERROR_H
      15                 :             : 
      16                 :             : #include "llvm-c/Error.h"
      17                 :             : #include "llvm/ADT/Twine.h"
      18                 :             : #include "llvm/Config/abi-breaking.h"
      19                 :             : #include "llvm/Support/AlignOf.h"
      20                 :             : #include "llvm/Support/Compiler.h"
      21                 :             : #include "llvm/Support/Debug.h"
      22                 :             : #include "llvm/Support/ErrorHandling.h"
      23                 :             : #include "llvm/Support/ErrorOr.h"
      24                 :             : #include "llvm/Support/Format.h"
      25                 :             : #include "llvm/Support/raw_ostream.h"
      26                 :             : #include <cassert>
      27                 :             : #include <cstdint>
      28                 :             : #include <cstdlib>
      29                 :             : #include <functional>
      30                 :             : #include <memory>
      31                 :             : #include <new>
      32                 :             : #include <optional>
      33                 :             : #include <string>
      34                 :             : #include <system_error>
      35                 :             : #include <type_traits>
      36                 :             : #include <utility>
      37                 :             : #include <vector>
      38                 :             : 
      39                 :             : namespace llvm {
      40                 :             : 
      41                 :             : class ErrorSuccess;
      42                 :             : 
      43                 :             : /// Base class for error info classes. Do not extend this directly: Extend
      44                 :             : /// the ErrorInfo template subclass instead.
      45                 :             : class ErrorInfoBase {
      46                 :             : public:
      47                 :             :   virtual ~ErrorInfoBase() = default;
      48                 :             : 
      49                 :             :   /// Print an error message to an output stream.
      50                 :             :   virtual void log(raw_ostream &OS) const = 0;
      51                 :             : 
      52                 :             :   /// Return the error message as a string.
      53                 :             :   virtual std::string message() const {
      54                 :             :     std::string Msg;
      55                 :             :     raw_string_ostream OS(Msg);
      56                 :             :     log(OS);
      57                 :             :     return Msg;
      58                 :             :   }
      59                 :             : 
      60                 :             :   /// Convert this error to a std::error_code.
      61                 :             :   ///
      62                 :             :   /// This is a temporary crutch to enable interaction with code still
      63                 :             :   /// using std::error_code. It will be removed in the future.
      64                 :             :   virtual std::error_code convertToErrorCode() const = 0;
      65                 :             : 
      66                 :             :   // Returns the class ID for this type.
      67                 :             :   static const void *classID() { return &ID; }
      68                 :             : 
      69                 :             :   // Returns the class ID for the dynamic type of this ErrorInfoBase instance.
      70                 :             :   virtual const void *dynamicClassID() const = 0;
      71                 :             : 
      72                 :             :   // Check whether this instance is a subclass of the class identified by
      73                 :             :   // ClassID.
      74                 :             :   virtual bool isA(const void *const ClassID) const {
      75                 :             :     return ClassID == classID();
      76                 :             :   }
      77                 :             : 
      78                 :             :   // Check whether this instance is a subclass of ErrorInfoT.
      79                 :             :   template <typename ErrorInfoT> bool isA() const {
      80                 :             :     return isA(ErrorInfoT::classID());
      81                 :             :   }
      82                 :             : 
      83                 :             : private:
      84                 :             :   virtual void anchor();
      85                 :             : 
      86                 :             :   static char ID;
      87                 :             : };
      88                 :             : 
      89                 :             : /// Lightweight error class with error context and mandatory checking.
      90                 :             : ///
      91                 :             : /// Instances of this class wrap a ErrorInfoBase pointer. Failure states
      92                 :             : /// are represented by setting the pointer to a ErrorInfoBase subclass
      93                 :             : /// instance containing information describing the failure. Success is
      94                 :             : /// represented by a null pointer value.
      95                 :             : ///
      96                 :             : /// Instances of Error also contains a 'Checked' flag, which must be set
      97                 :             : /// before the destructor is called, otherwise the destructor will trigger a
      98                 :             : /// runtime error. This enforces at runtime the requirement that all Error
      99                 :             : /// instances be checked or returned to the caller.
     100                 :             : ///
     101                 :             : /// There are two ways to set the checked flag, depending on what state the
     102                 :             : /// Error instance is in. For Error instances indicating success, it
     103                 :             : /// is sufficient to invoke the boolean conversion operator. E.g.:
     104                 :             : ///
     105                 :             : ///   @code{.cpp}
     106                 :             : ///   Error foo(<...>);
     107                 :             : ///
     108                 :             : ///   if (auto E = foo(<...>))
     109                 :             : ///     return E; // <- Return E if it is in the error state.
     110                 :             : ///   // We have verified that E was in the success state. It can now be safely
     111                 :             : ///   // destroyed.
     112                 :             : ///   @endcode
     113                 :             : ///
     114                 :             : /// A success value *can not* be dropped. For example, just calling 'foo(<...>)'
     115                 :             : /// without testing the return value will raise a runtime error, even if foo
     116                 :             : /// returns success.
     117                 :             : ///
     118                 :             : /// For Error instances representing failure, you must use either the
     119                 :             : /// handleErrors or handleAllErrors function with a typed handler. E.g.:
     120                 :             : ///
     121                 :             : ///   @code{.cpp}
     122                 :             : ///   class MyErrorInfo : public ErrorInfo<MyErrorInfo> {
     123                 :             : ///     // Custom error info.
     124                 :             : ///   };
     125                 :             : ///
     126                 :             : ///   Error foo(<...>) { return make_error<MyErrorInfo>(...); }
     127                 :             : ///
     128                 :             : ///   auto E = foo(<...>); // <- foo returns failure with MyErrorInfo.
     129                 :             : ///   auto NewE =
     130                 :             : ///     handleErrors(std::move(E),
     131                 :             : ///       [](const MyErrorInfo &M) {
     132                 :             : ///         // Deal with the error.
     133                 :             : ///       },
     134                 :             : ///       [](std::unique_ptr<OtherError> M) -> Error {
     135                 :             : ///         if (canHandle(*M)) {
     136                 :             : ///           // handle error.
     137                 :             : ///           return Error::success();
     138                 :             : ///         }
     139                 :             : ///         // Couldn't handle this error instance. Pass it up the stack.
     140                 :             : ///         return Error(std::move(M));
     141                 :             : ///     });
     142                 :             : ///   // Note - The error passed to handleErrors will be marked as checked. If
     143                 :             : ///   // there is no matched handler, a new error with the same payload is
     144                 :             : ///   // created and returned.
     145                 :             : ///   // The handlers take the error checked by handleErrors as an argument,
     146                 :             : ///   // which can be used to retrieve more information. If a new error is
     147                 :             : ///   // created by a handler, it will be passed back to the caller of
     148                 :             : ///   // handleErrors and needs to be checked or return up to the stack.
     149                 :             : ///   // Otherwise, the passed-in error is considered consumed.
     150                 :             : ///   @endcode
     151                 :             : ///
     152                 :             : /// The handleAllErrors function is identical to handleErrors, except
     153                 :             : /// that it has a void return type, and requires all errors to be handled and
     154                 :             : /// no new errors be returned. It prevents errors (assuming they can all be
     155                 :             : /// handled) from having to be bubbled all the way to the top-level.
     156                 :             : ///
     157                 :             : /// *All* Error instances must be checked before destruction, even if
     158                 :             : /// they're moved-assigned or constructed from Success values that have already
     159                 :             : /// been checked. This enforces checking through all levels of the call stack.
     160                 :             : class [[nodiscard]] Error {
     161                 :             :   // ErrorList needs to be able to yank ErrorInfoBase pointers out of Errors
     162                 :             :   // to add to the error list. It can't rely on handleErrors for this, since
     163                 :             :   // handleErrors does not support ErrorList handlers.
     164                 :             :   friend class ErrorList;
     165                 :             : 
     166                 :             :   // handleErrors needs to be able to set the Checked flag.
     167                 :             :   template <typename... HandlerTs>
     168                 :             :   friend Error handleErrors(Error E, HandlerTs &&... Handlers);
     169                 :             :   // visitErrors needs direct access to the payload.
     170                 :             :   template <typename HandlerT>
     171                 :             :   friend void visitErrors(const Error &E, HandlerT H);
     172                 :             : 
     173                 :             :   // Expected<T> needs to be able to steal the payload when constructed from an
     174                 :             :   // error.
     175                 :             :   template <typename T> friend class Expected;
     176                 :             : 
     177                 :             :   // wrap needs to be able to steal the payload.
     178                 :             :   friend LLVMErrorRef wrap(Error);
     179                 :             : 
     180                 :             : protected:
     181                 :             :   /// Create a success value. Prefer using 'Error::success()' for readability
     182                 :           0 :   Error() {
     183                 :           0 :     setPtr(nullptr);
     184                 :           0 :     setChecked(false);
     185                 :           0 :   }
     186                 :             : 
     187                 :             : public:
     188                 :             :   /// Create a success value.
     189                 :             :   static ErrorSuccess success();
     190                 :             : 
     191                 :             :   // Errors are not copy-constructable.
     192                 :             :   Error(const Error &Other) = delete;
     193                 :             : 
     194                 :             :   /// Move-construct an error value. The newly constructed error is considered
     195                 :             :   /// unchecked, even if the source error had been checked. The original error
     196                 :             :   /// becomes a checked Success value, regardless of its original state.
     197                 :           0 :   Error(Error &&Other) {
     198                 :           0 :     setChecked(true);
     199                 :           0 :     *this = std::move(Other);
     200                 :           0 :   }
     201                 :             : 
     202                 :             :   /// Create an error value. Prefer using the 'make_error' function, but
     203                 :             :   /// this constructor can be useful when "re-throwing" errors from handlers.
     204                 :           0 :   Error(std::unique_ptr<ErrorInfoBase> Payload) {
     205                 :           0 :     setPtr(Payload.release());
     206                 :           0 :     setChecked(false);
     207                 :           0 :   }
     208                 :             : 
     209                 :             :   // Errors are not copy-assignable.
     210                 :             :   Error &operator=(const Error &Other) = delete;
     211                 :             : 
     212                 :             :   /// Move-assign an error value. The current error must represent success, you
     213                 :             :   /// you cannot overwrite an unhandled error. The current error is then
     214                 :             :   /// considered unchecked. The source error becomes a checked success value,
     215                 :             :   /// regardless of its original state.
     216                 :           0 :   Error &operator=(Error &&Other) {
     217                 :             :     // Don't allow overwriting of unchecked values.
     218                 :           0 :     assertIsChecked();
     219                 :           0 :     setPtr(Other.getPtr());
     220                 :             : 
     221                 :             :     // This Error is unchecked, even if the source error was checked.
     222                 :           0 :     setChecked(false);
     223                 :             : 
     224                 :             :     // Null out Other's payload and set its checked bit.
     225                 :           0 :     Other.setPtr(nullptr);
     226                 :           0 :     Other.setChecked(true);
     227                 :             : 
     228                 :           0 :     return *this;
     229                 :             :   }
     230                 :             : 
     231                 :             :   /// Destroy a Error. Fails with a call to abort() if the error is
     232                 :             :   /// unchecked.
     233                 :           0 :   ~Error() {
     234                 :           0 :     assertIsChecked();
     235         [ #  # ]:           0 :     delete getPtr();
     236                 :           0 :   }
     237                 :             : 
     238                 :             :   /// Bool conversion. Returns true if this Error is in a failure state,
     239                 :             :   /// and false if it is in an accept state. If the error is in a Success state
     240                 :             :   /// it will be considered checked.
     241                 :           0 :   explicit operator bool() {
     242                 :           0 :     setChecked(getPtr() == nullptr);
     243                 :           0 :     return getPtr() != nullptr;
     244                 :             :   }
     245                 :             : 
     246                 :             :   /// Check whether one error is a subclass of another.
     247                 :             :   template <typename ErrT> bool isA() const {
     248                 :             :     return getPtr() && getPtr()->isA(ErrT::classID());
     249                 :             :   }
     250                 :             : 
     251                 :             :   /// Returns the dynamic class id of this error, or null if this is a success
     252                 :             :   /// value.
     253                 :             :   const void* dynamicClassID() const {
     254                 :             :     if (!getPtr())
     255                 :             :       return nullptr;
     256                 :             :     return getPtr()->dynamicClassID();
     257                 :             :   }
     258                 :             : 
     259                 :             : private:
     260                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     261                 :             :   // assertIsChecked() happens very frequently, but under normal circumstances
     262                 :             :   // is supposed to be a no-op.  So we want it to be inlined, but having a bunch
     263                 :             :   // of debug prints can cause the function to be too large for inlining.  So
     264                 :             :   // it's important that we define this function out of line so that it can't be
     265                 :             :   // inlined.
     266                 :             :   [[noreturn]] void fatalUncheckedError() const;
     267                 :             : #endif
     268                 :             : 
     269                 :           0 :   void assertIsChecked() {
     270                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     271                 :             :     if (LLVM_UNLIKELY(!getChecked() || getPtr()))
     272                 :             :       fatalUncheckedError();
     273                 :             : #endif
     274                 :           0 :   }
     275                 :             : 
     276                 :           0 :   ErrorInfoBase *getPtr() const {
     277                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     278                 :             :     return reinterpret_cast<ErrorInfoBase*>(
     279                 :             :              reinterpret_cast<uintptr_t>(Payload) &
     280                 :             :              ~static_cast<uintptr_t>(0x1));
     281                 :             : #else
     282                 :           0 :     return Payload;
     283                 :             : #endif
     284                 :             :   }
     285                 :             : 
     286                 :           0 :   void setPtr(ErrorInfoBase *EI) {
     287                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     288                 :             :     Payload = reinterpret_cast<ErrorInfoBase*>(
     289                 :             :                 (reinterpret_cast<uintptr_t>(EI) &
     290                 :             :                  ~static_cast<uintptr_t>(0x1)) |
     291                 :             :                 (reinterpret_cast<uintptr_t>(Payload) & 0x1));
     292                 :             : #else
     293                 :           0 :     Payload = EI;
     294                 :             : #endif
     295                 :           0 :   }
     296                 :             : 
     297                 :             :   bool getChecked() const {
     298                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     299                 :             :     return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0;
     300                 :             : #else
     301                 :             :     return true;
     302                 :             : #endif
     303                 :             :   }
     304                 :             : 
     305                 :           0 :   void setChecked(bool V) {
     306                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     307                 :             :     Payload = reinterpret_cast<ErrorInfoBase*>(
     308                 :             :                 (reinterpret_cast<uintptr_t>(Payload) &
     309                 :             :                   ~static_cast<uintptr_t>(0x1)) |
     310                 :             :                   (V ? 0 : 1));
     311                 :             : #endif
     312                 :           0 :   }
     313                 :             : 
     314                 :             :   std::unique_ptr<ErrorInfoBase> takePayload() {
     315                 :             :     std::unique_ptr<ErrorInfoBase> Tmp(getPtr());
     316                 :             :     setPtr(nullptr);
     317                 :             :     setChecked(true);
     318                 :             :     return Tmp;
     319                 :             :   }
     320                 :             : 
     321                 :             :   friend raw_ostream &operator<<(raw_ostream &OS, const Error &E) {
     322                 :             :     if (auto *P = E.getPtr())
     323                 :             :       P->log(OS);
     324                 :             :     else
     325                 :             :       OS << "success";
     326                 :             :     return OS;
     327                 :             :   }
     328                 :             : 
     329                 :             :   ErrorInfoBase *Payload = nullptr;
     330                 :             : };
     331                 :             : 
     332                 :             : /// Subclass of Error for the sole purpose of identifying the success path in
     333                 :             : /// the type system. This allows to catch invalid conversion to Expected<T> at
     334                 :             : /// compile time.
     335                 :             : class ErrorSuccess final : public Error {};
     336                 :             : 
     337                 :           0 : inline ErrorSuccess Error::success() { return ErrorSuccess(); }
     338                 :             : 
     339                 :             : /// Make a Error instance representing failure using the given error info
     340                 :             : /// type.
     341                 :             : template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) {
     342                 :             :   return Error(std::make_unique<ErrT>(std::forward<ArgTs>(Args)...));
     343                 :             : }
     344                 :             : 
     345                 :             : /// Base class for user error types. Users should declare their error types
     346                 :             : /// like:
     347                 :             : ///
     348                 :             : /// class MyError : public ErrorInfo<MyError> {
     349                 :             : ///   ....
     350                 :             : /// };
     351                 :             : ///
     352                 :             : /// This class provides an implementation of the ErrorInfoBase::kind
     353                 :             : /// method, which is used by the Error RTTI system.
     354                 :             : template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
     355                 :             : class ErrorInfo : public ParentErrT {
     356                 :             : public:
     357                 :             :   using ParentErrT::ParentErrT; // inherit constructors
     358                 :             : 
     359                 :             :   static const void *classID() { return &ThisErrT::ID; }
     360                 :             : 
     361                 :             :   const void *dynamicClassID() const override { return &ThisErrT::ID; }
     362                 :             : 
     363                 :             :   bool isA(const void *const ClassID) const override {
     364                 :             :     return ClassID == classID() || ParentErrT::isA(ClassID);
     365                 :             :   }
     366                 :             : };
     367                 :             : 
     368                 :             : /// Special ErrorInfo subclass representing a list of ErrorInfos.
     369                 :             : /// Instances of this class are constructed by joinError.
     370                 :             : class ErrorList final : public ErrorInfo<ErrorList> {
     371                 :             :   // handleErrors needs to be able to iterate the payload list of an
     372                 :             :   // ErrorList.
     373                 :             :   template <typename... HandlerTs>
     374                 :             :   friend Error handleErrors(Error E, HandlerTs &&... Handlers);
     375                 :             :   // visitErrors needs to be able to iterate the payload list of an
     376                 :             :   // ErrorList.
     377                 :             :   template <typename HandlerT>
     378                 :             :   friend void visitErrors(const Error &E, HandlerT H);
     379                 :             : 
     380                 :             :   // joinErrors is implemented in terms of join.
     381                 :             :   friend Error joinErrors(Error, Error);
     382                 :             : 
     383                 :             : public:
     384                 :             :   void log(raw_ostream &OS) const override {
     385                 :             :     OS << "Multiple errors:\n";
     386                 :             :     for (const auto &ErrPayload : Payloads) {
     387                 :             :       ErrPayload->log(OS);
     388                 :             :       OS << "\n";
     389                 :             :     }
     390                 :             :   }
     391                 :             : 
     392                 :             :   std::error_code convertToErrorCode() const override;
     393                 :             : 
     394                 :             :   // Used by ErrorInfo::classID.
     395                 :             :   static char ID;
     396                 :             : 
     397                 :             : private:
     398                 :             :   ErrorList(std::unique_ptr<ErrorInfoBase> Payload1,
     399                 :             :             std::unique_ptr<ErrorInfoBase> Payload2) {
     400                 :             :     assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() &&
     401                 :             :            "ErrorList constructor payloads should be singleton errors");
     402                 :             :     Payloads.push_back(std::move(Payload1));
     403                 :             :     Payloads.push_back(std::move(Payload2));
     404                 :             :   }
     405                 :             : 
     406                 :             :   static Error join(Error E1, Error E2) {
     407                 :             :     if (!E1)
     408                 :             :       return E2;
     409                 :             :     if (!E2)
     410                 :             :       return E1;
     411                 :             :     if (E1.isA<ErrorList>()) {
     412                 :             :       auto &E1List = static_cast<ErrorList &>(*E1.getPtr());
     413                 :             :       if (E2.isA<ErrorList>()) {
     414                 :             :         auto E2Payload = E2.takePayload();
     415                 :             :         auto &E2List = static_cast<ErrorList &>(*E2Payload);
     416                 :             :         for (auto &Payload : E2List.Payloads)
     417                 :             :           E1List.Payloads.push_back(std::move(Payload));
     418                 :             :       } else
     419                 :             :         E1List.Payloads.push_back(E2.takePayload());
     420                 :             : 
     421                 :             :       return E1;
     422                 :             :     }
     423                 :             :     if (E2.isA<ErrorList>()) {
     424                 :             :       auto &E2List = static_cast<ErrorList &>(*E2.getPtr());
     425                 :             :       E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload());
     426                 :             :       return E2;
     427                 :             :     }
     428                 :             :     return Error(std::unique_ptr<ErrorList>(
     429                 :             :         new ErrorList(E1.takePayload(), E2.takePayload())));
     430                 :             :   }
     431                 :             : 
     432                 :             :   std::vector<std::unique_ptr<ErrorInfoBase>> Payloads;
     433                 :             : };
     434                 :             : 
     435                 :             : /// Concatenate errors. The resulting Error is unchecked, and contains the
     436                 :             : /// ErrorInfo(s), if any, contained in E1, followed by the
     437                 :             : /// ErrorInfo(s), if any, contained in E2.
     438                 :             : inline Error joinErrors(Error E1, Error E2) {
     439                 :             :   return ErrorList::join(std::move(E1), std::move(E2));
     440                 :             : }
     441                 :             : 
     442                 :             : /// Tagged union holding either a T or a Error.
     443                 :             : ///
     444                 :             : /// This class parallels ErrorOr, but replaces error_code with Error. Since
     445                 :             : /// Error cannot be copied, this class replaces getError() with
     446                 :             : /// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the
     447                 :             : /// error class type.
     448                 :             : ///
     449                 :             : /// Example usage of 'Expected<T>' as a function return type:
     450                 :             : ///
     451                 :             : ///   @code{.cpp}
     452                 :             : ///     Expected<int> myDivide(int A, int B) {
     453                 :             : ///       if (B == 0) {
     454                 :             : ///         // return an Error
     455                 :             : ///         return createStringError(inconvertibleErrorCode(),
     456                 :             : ///                                  "B must not be zero!");
     457                 :             : ///       }
     458                 :             : ///       // return an integer
     459                 :             : ///       return A / B;
     460                 :             : ///     }
     461                 :             : ///   @endcode
     462                 :             : ///
     463                 :             : ///   Checking the results of to a function returning 'Expected<T>':
     464                 :             : ///   @code{.cpp}
     465                 :             : ///     if (auto E = Result.takeError()) {
     466                 :             : ///       // We must consume the error. Typically one of:
     467                 :             : ///       // - return the error to our caller
     468                 :             : ///       // - toString(), when logging
     469                 :             : ///       // - consumeError(), to silently swallow the error
     470                 :             : ///       // - handleErrors(), to distinguish error types
     471                 :             : ///       errs() << "Problem with division " << toString(std::move(E)) << "\n";
     472                 :             : ///       return;
     473                 :             : ///     }
     474                 :             : ///     // use the result
     475                 :             : ///     outs() << "The answer is " << *Result << "\n";
     476                 :             : ///   @endcode
     477                 :             : ///
     478                 :             : ///  For unit-testing a function returning an 'Expected<T>', see the
     479                 :             : ///  'EXPECT_THAT_EXPECTED' macros in llvm/Testing/Support/Error.h
     480                 :             : 
     481                 :             : template <class T> class [[nodiscard]] Expected {
     482                 :             :   template <class T1> friend class ExpectedAsOutParameter;
     483                 :             :   template <class OtherT> friend class Expected;
     484                 :             : 
     485                 :             :   static constexpr bool isRef = std::is_reference_v<T>;
     486                 :             : 
     487                 :             :   using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
     488                 :             : 
     489                 :             :   using error_type = std::unique_ptr<ErrorInfoBase>;
     490                 :             : 
     491                 :             : public:
     492                 :             :   using storage_type = std::conditional_t<isRef, wrap, T>;
     493                 :             :   using value_type = T;
     494                 :             : 
     495                 :             : private:
     496                 :             :   using reference = std::remove_reference_t<T> &;
     497                 :             :   using const_reference = const std::remove_reference_t<T> &;
     498                 :             :   using pointer = std::remove_reference_t<T> *;
     499                 :             :   using const_pointer = const std::remove_reference_t<T> *;
     500                 :             : 
     501                 :             : public:
     502                 :             :   /// Create an Expected<T> error value from the given Error.
     503                 :             :   Expected(Error &&Err)
     504                 :             :       : HasError(true)
     505                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     506                 :             :         // Expected is unchecked upon construction in Debug builds.
     507                 :             :         , Unchecked(true)
     508                 :             : #endif
     509                 :             :   {
     510                 :             :     assert(Err && "Cannot create Expected<T> from Error success value.");
     511                 :             :     new (getErrorStorage()) error_type(Err.takePayload());
     512                 :             :   }
     513                 :             : 
     514                 :             :   /// Forbid to convert from Error::success() implicitly, this avoids having
     515                 :             :   /// Expected<T> foo() { return Error::success(); } which compiles otherwise
     516                 :             :   /// but triggers the assertion above.
     517                 :             :   Expected(ErrorSuccess) = delete;
     518                 :             : 
     519                 :             :   /// Create an Expected<T> success value from the given OtherT value, which
     520                 :             :   /// must be convertible to T.
     521                 :             :   template <typename OtherT>
     522                 :             :   Expected(OtherT &&Val,
     523                 :             :            std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr)
     524                 :             :       : HasError(false)
     525                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     526                 :             :         // Expected is unchecked upon construction in Debug builds.
     527                 :             :         ,
     528                 :             :         Unchecked(true)
     529                 :             : #endif
     530                 :             :   {
     531                 :             :     new (getStorage()) storage_type(std::forward<OtherT>(Val));
     532                 :             :   }
     533                 :             : 
     534                 :             :   /// Move construct an Expected<T> value.
     535                 :             :   Expected(Expected &&Other) { moveConstruct(std::move(Other)); }
     536                 :             : 
     537                 :             :   /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
     538                 :             :   /// must be convertible to T.
     539                 :             :   template <class OtherT>
     540                 :             :   Expected(Expected<OtherT> &&Other,
     541                 :             :            std::enable_if_t<std::is_convertible_v<OtherT, T>> * = nullptr) {
     542                 :             :     moveConstruct(std::move(Other));
     543                 :             :   }
     544                 :             : 
     545                 :             :   /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
     546                 :             :   /// isn't convertible to T.
     547                 :             :   template <class OtherT>
     548                 :             :   explicit Expected(
     549                 :             :       Expected<OtherT> &&Other,
     550                 :             :       std::enable_if_t<!std::is_convertible_v<OtherT, T>> * = nullptr) {
     551                 :             :     moveConstruct(std::move(Other));
     552                 :             :   }
     553                 :             : 
     554                 :             :   /// Move-assign from another Expected<T>.
     555                 :             :   Expected &operator=(Expected &&Other) {
     556                 :             :     moveAssign(std::move(Other));
     557                 :             :     return *this;
     558                 :             :   }
     559                 :             : 
     560                 :             :   /// Destroy an Expected<T>.
     561                 :           0 :   ~Expected() {
     562                 :           0 :     assertIsChecked();
     563         [ #  # ]:           0 :     if (!HasError)
     564                 :           0 :       getStorage()->~storage_type();
     565                 :             :     else
     566                 :           0 :       getErrorStorage()->~error_type();
     567                 :           0 :   }
     568                 :             : 
     569                 :             :   /// Return false if there is an error.
     570                 :           0 :   explicit operator bool() {
     571                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     572                 :             :     Unchecked = HasError;
     573                 :             : #endif
     574                 :           0 :     return !HasError;
     575                 :             :   }
     576                 :             : 
     577                 :             :   /// Returns a reference to the stored T value.
     578                 :           0 :   reference get() {
     579                 :           0 :     assertIsChecked();
     580                 :           0 :     return *getStorage();
     581                 :             :   }
     582                 :             : 
     583                 :             :   /// Returns a const reference to the stored T value.
     584                 :             :   const_reference get() const {
     585                 :             :     assertIsChecked();
     586                 :             :     return const_cast<Expected<T> *>(this)->get();
     587                 :             :   }
     588                 :             : 
     589                 :             :   /// Returns \a takeError() after moving the held T (if any) into \p V.
     590                 :             :   template <class OtherT>
     591                 :             :   Error moveInto(
     592                 :             :       OtherT &Value,
     593                 :             :       std::enable_if_t<std::is_assignable_v<OtherT &, T &&>> * = nullptr) && {
     594                 :             :     if (*this)
     595                 :             :       Value = std::move(get());
     596                 :             :     return takeError();
     597                 :             :   }
     598                 :             : 
     599                 :             :   /// Check that this Expected<T> is an error of type ErrT.
     600                 :             :   template <typename ErrT> bool errorIsA() const {
     601                 :             :     return HasError && (*getErrorStorage())->template isA<ErrT>();
     602                 :             :   }
     603                 :             : 
     604                 :             :   /// Take ownership of the stored error.
     605                 :             :   /// After calling this the Expected<T> is in an indeterminate state that can
     606                 :             :   /// only be safely destructed. No further calls (beside the destructor) should
     607                 :             :   /// be made on the Expected<T> value.
     608                 :           0 :   Error takeError() {
     609                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     610                 :             :     Unchecked = false;
     611                 :             : #endif
     612   [ #  #  #  #  :           0 :     return HasError ? Error(std::move(*getErrorStorage())) : Error::success();
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     613                 :             :   }
     614                 :             : 
     615                 :             :   /// Returns a pointer to the stored T value.
     616                 :             :   pointer operator->() {
     617                 :             :     assertIsChecked();
     618                 :             :     return toPointer(getStorage());
     619                 :             :   }
     620                 :             : 
     621                 :             :   /// Returns a const pointer to the stored T value.
     622                 :             :   const_pointer operator->() const {
     623                 :             :     assertIsChecked();
     624                 :             :     return toPointer(getStorage());
     625                 :             :   }
     626                 :             : 
     627                 :             :   /// Returns a reference to the stored T value.
     628                 :             :   reference operator*() {
     629                 :             :     assertIsChecked();
     630                 :             :     return *getStorage();
     631                 :             :   }
     632                 :             : 
     633                 :             :   /// Returns a const reference to the stored T value.
     634                 :             :   const_reference operator*() const {
     635                 :             :     assertIsChecked();
     636                 :             :     return *getStorage();
     637                 :             :   }
     638                 :             : 
     639                 :             : private:
     640                 :             :   template <class T1>
     641                 :             :   static bool compareThisIfSameType(const T1 &a, const T1 &b) {
     642                 :             :     return &a == &b;
     643                 :             :   }
     644                 :             : 
     645                 :             :   template <class T1, class T2>
     646                 :             :   static bool compareThisIfSameType(const T1 &, const T2 &) {
     647                 :             :     return false;
     648                 :             :   }
     649                 :             : 
     650                 :             :   template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) {
     651                 :             :     HasError = Other.HasError;
     652                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     653                 :             :     Unchecked = true;
     654                 :             :     Other.Unchecked = false;
     655                 :             : #endif
     656                 :             : 
     657                 :             :     if (!HasError)
     658                 :             :       new (getStorage()) storage_type(std::move(*Other.getStorage()));
     659                 :             :     else
     660                 :             :       new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage()));
     661                 :             :   }
     662                 :             : 
     663                 :             :   template <class OtherT> void moveAssign(Expected<OtherT> &&Other) {
     664                 :             :     assertIsChecked();
     665                 :             : 
     666                 :             :     if (compareThisIfSameType(*this, Other))
     667                 :             :       return;
     668                 :             : 
     669                 :             :     this->~Expected();
     670                 :             :     new (this) Expected(std::move(Other));
     671                 :             :   }
     672                 :             : 
     673                 :             :   pointer toPointer(pointer Val) { return Val; }
     674                 :             : 
     675                 :             :   const_pointer toPointer(const_pointer Val) const { return Val; }
     676                 :             : 
     677                 :             :   pointer toPointer(wrap *Val) { return &Val->get(); }
     678                 :             : 
     679                 :             :   const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
     680                 :             : 
     681                 :           0 :   storage_type *getStorage() {
     682         [ #  # ]:           0 :     assert(!HasError && "Cannot get value when an error exists!");
     683                 :           0 :     return reinterpret_cast<storage_type *>(&TStorage);
     684                 :             :   }
     685                 :             : 
     686                 :             :   const storage_type *getStorage() const {
     687                 :             :     assert(!HasError && "Cannot get value when an error exists!");
     688                 :             :     return reinterpret_cast<const storage_type *>(&TStorage);
     689                 :             :   }
     690                 :             : 
     691                 :           0 :   error_type *getErrorStorage() {
     692         [ #  # ]:           0 :     assert(HasError && "Cannot get error when a value exists!");
     693                 :           0 :     return reinterpret_cast<error_type *>(&ErrorStorage);
     694                 :             :   }
     695                 :             : 
     696                 :             :   const error_type *getErrorStorage() const {
     697                 :             :     assert(HasError && "Cannot get error when a value exists!");
     698                 :             :     return reinterpret_cast<const error_type *>(&ErrorStorage);
     699                 :             :   }
     700                 :             : 
     701                 :             :   // Used by ExpectedAsOutParameter to reset the checked flag.
     702                 :             :   void setUnchecked() {
     703                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     704                 :             :     Unchecked = true;
     705                 :             : #endif
     706                 :             :   }
     707                 :             : 
     708                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     709                 :             :   [[noreturn]] LLVM_ATTRIBUTE_NOINLINE void fatalUncheckedExpected() const {
     710                 :             :     dbgs() << "Expected<T> must be checked before access or destruction.\n";
     711                 :             :     if (HasError) {
     712                 :             :       dbgs() << "Unchecked Expected<T> contained error:\n";
     713                 :             :       (*getErrorStorage())->log(dbgs());
     714                 :             :     } else
     715                 :             :       dbgs() << "Expected<T> value was in success state. (Note: Expected<T> "
     716                 :             :                 "values in success mode must still be checked prior to being "
     717                 :             :                 "destroyed).\n";
     718                 :             :     abort();
     719                 :             :   }
     720                 :             : #endif
     721                 :             : 
     722                 :           0 :   void assertIsChecked() const {
     723                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     724                 :             :     if (LLVM_UNLIKELY(Unchecked))
     725                 :             :       fatalUncheckedExpected();
     726                 :             : #endif
     727                 :           0 :   }
     728                 :             : 
     729                 :             :   union {
     730                 :             :     AlignedCharArrayUnion<storage_type> TStorage;
     731                 :             :     AlignedCharArrayUnion<error_type> ErrorStorage;
     732                 :             :   };
     733                 :             :   bool HasError : 1;
     734                 :             : #if LLVM_ENABLE_ABI_BREAKING_CHECKS
     735                 :             :   bool Unchecked : 1;
     736                 :             : #endif
     737                 :             : };
     738                 :             : 
     739                 :             : /// Report a serious error, calling any installed error handler. See
     740                 :             : /// ErrorHandling.h.
     741                 :             : [[noreturn]] void report_fatal_error(Error Err, bool gen_crash_diag = true);
     742                 :             : 
     743                 :             : /// Report a fatal error if Err is a failure value.
     744                 :             : ///
     745                 :             : /// This function can be used to wrap calls to fallible functions ONLY when it
     746                 :             : /// is known that the Error will always be a success value. E.g.
     747                 :             : ///
     748                 :             : ///   @code{.cpp}
     749                 :             : ///   // foo only attempts the fallible operation if DoFallibleOperation is
     750                 :             : ///   // true. If DoFallibleOperation is false then foo always returns
     751                 :             : ///   // Error::success().
     752                 :             : ///   Error foo(bool DoFallibleOperation);
     753                 :             : ///
     754                 :             : ///   cantFail(foo(false));
     755                 :             : ///   @endcode
     756                 :             : inline void cantFail(Error Err, const char *Msg = nullptr) {
     757                 :             :   if (Err) {
     758                 :             :     if (!Msg)
     759                 :             :       Msg = "Failure value returned from cantFail wrapped call";
     760                 :             : #ifndef NDEBUG
     761                 :             :     std::string Str;
     762                 :             :     raw_string_ostream OS(Str);
     763                 :             :     OS << Msg << "\n" << Err;
     764                 :             :     Msg = Str.c_str();
     765                 :             : #endif
     766                 :             :     llvm_unreachable(Msg);
     767                 :             :   }
     768                 :             : }
     769                 :             : 
     770                 :             : /// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
     771                 :             : /// returns the contained value.
     772                 :             : ///
     773                 :             : /// This function can be used to wrap calls to fallible functions ONLY when it
     774                 :             : /// is known that the Error will always be a success value. E.g.
     775                 :             : ///
     776                 :             : ///   @code{.cpp}
     777                 :             : ///   // foo only attempts the fallible operation if DoFallibleOperation is
     778                 :             : ///   // true. If DoFallibleOperation is false then foo always returns an int.
     779                 :             : ///   Expected<int> foo(bool DoFallibleOperation);
     780                 :             : ///
     781                 :             : ///   int X = cantFail(foo(false));
     782                 :             : ///   @endcode
     783                 :             : template <typename T>
     784                 :             : T cantFail(Expected<T> ValOrErr, const char *Msg = nullptr) {
     785                 :             :   if (ValOrErr)
     786                 :             :     return std::move(*ValOrErr);
     787                 :             :   else {
     788                 :             :     if (!Msg)
     789                 :             :       Msg = "Failure value returned from cantFail wrapped call";
     790                 :             : #ifndef NDEBUG
     791                 :             :     std::string Str;
     792                 :             :     raw_string_ostream OS(Str);
     793                 :             :     auto E = ValOrErr.takeError();
     794                 :             :     OS << Msg << "\n" << E;
     795                 :             :     Msg = Str.c_str();
     796                 :             : #endif
     797                 :             :     llvm_unreachable(Msg);
     798                 :             :   }
     799                 :             : }
     800                 :             : 
     801                 :             : /// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and
     802                 :             : /// returns the contained reference.
     803                 :             : ///
     804                 :             : /// This function can be used to wrap calls to fallible functions ONLY when it
     805                 :             : /// is known that the Error will always be a success value. E.g.
     806                 :             : ///
     807                 :             : ///   @code{.cpp}
     808                 :             : ///   // foo only attempts the fallible operation if DoFallibleOperation is
     809                 :             : ///   // true. If DoFallibleOperation is false then foo always returns a Bar&.
     810                 :             : ///   Expected<Bar&> foo(bool DoFallibleOperation);
     811                 :             : ///
     812                 :             : ///   Bar &X = cantFail(foo(false));
     813                 :             : ///   @endcode
     814                 :             : template <typename T>
     815                 :             : T& cantFail(Expected<T&> ValOrErr, const char *Msg = nullptr) {
     816                 :             :   if (ValOrErr)
     817                 :             :     return *ValOrErr;
     818                 :             :   else {
     819                 :             :     if (!Msg)
     820                 :             :       Msg = "Failure value returned from cantFail wrapped call";
     821                 :             : #ifndef NDEBUG
     822                 :             :     std::string Str;
     823                 :             :     raw_string_ostream OS(Str);
     824                 :             :     auto E = ValOrErr.takeError();
     825                 :             :     OS << Msg << "\n" << E;
     826                 :             :     Msg = Str.c_str();
     827                 :             : #endif
     828                 :             :     llvm_unreachable(Msg);
     829                 :             :   }
     830                 :             : }
     831                 :             : 
     832                 :             : /// Helper for testing applicability of, and applying, handlers for
     833                 :             : /// ErrorInfo types.
     834                 :             : template <typename HandlerT>
     835                 :             : class ErrorHandlerTraits
     836                 :             :     : public ErrorHandlerTraits<
     837                 :             :           decltype(&std::remove_reference_t<HandlerT>::operator())> {};
     838                 :             : 
     839                 :             : // Specialization functions of the form 'Error (const ErrT&)'.
     840                 :             : template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> {
     841                 :             : public:
     842                 :             :   static bool appliesTo(const ErrorInfoBase &E) {
     843                 :             :     return E.template isA<ErrT>();
     844                 :             :   }
     845                 :             : 
     846                 :             :   template <typename HandlerT>
     847                 :             :   static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
     848                 :             :     assert(appliesTo(*E) && "Applying incorrect handler");
     849                 :             :     return H(static_cast<ErrT &>(*E));
     850                 :             :   }
     851                 :             : };
     852                 :             : 
     853                 :             : // Specialization functions of the form 'void (const ErrT&)'.
     854                 :             : template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> {
     855                 :             : public:
     856                 :             :   static bool appliesTo(const ErrorInfoBase &E) {
     857                 :             :     return E.template isA<ErrT>();
     858                 :             :   }
     859                 :             : 
     860                 :             :   template <typename HandlerT>
     861                 :             :   static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
     862                 :             :     assert(appliesTo(*E) && "Applying incorrect handler");
     863                 :             :     H(static_cast<ErrT &>(*E));
     864                 :             :     return Error::success();
     865                 :             :   }
     866                 :             : };
     867                 :             : 
     868                 :             : /// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'.
     869                 :             : template <typename ErrT>
     870                 :             : class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {
     871                 :             : public:
     872                 :             :   static bool appliesTo(const ErrorInfoBase &E) {
     873                 :             :     return E.template isA<ErrT>();
     874                 :             :   }
     875                 :             : 
     876                 :             :   template <typename HandlerT>
     877                 :             :   static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
     878                 :             :     assert(appliesTo(*E) && "Applying incorrect handler");
     879                 :             :     std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
     880                 :             :     return H(std::move(SubE));
     881                 :             :   }
     882                 :             : };
     883                 :             : 
     884                 :             : /// Specialization for functions of the form 'void (std::unique_ptr<ErrT>)'.
     885                 :             : template <typename ErrT>
     886                 :             : class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> {
     887                 :             : public:
     888                 :             :   static bool appliesTo(const ErrorInfoBase &E) {
     889                 :             :     return E.template isA<ErrT>();
     890                 :             :   }
     891                 :             : 
     892                 :             :   template <typename HandlerT>
     893                 :             :   static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) {
     894                 :             :     assert(appliesTo(*E) && "Applying incorrect handler");
     895                 :             :     std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release()));
     896                 :             :     H(std::move(SubE));
     897                 :             :     return Error::success();
     898                 :             :   }
     899                 :             : };
     900                 :             : 
     901                 :             : // Specialization for member functions of the form 'RetT (const ErrT&)'.
     902                 :             : template <typename C, typename RetT, typename ErrT>
     903                 :             : class ErrorHandlerTraits<RetT (C::*)(ErrT &)>
     904                 :             :     : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
     905                 :             : 
     906                 :             : // Specialization for member functions of the form 'RetT (const ErrT&) const'.
     907                 :             : template <typename C, typename RetT, typename ErrT>
     908                 :             : class ErrorHandlerTraits<RetT (C::*)(ErrT &) const>
     909                 :             :     : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
     910                 :             : 
     911                 :             : // Specialization for member functions of the form 'RetT (const ErrT&)'.
     912                 :             : template <typename C, typename RetT, typename ErrT>
     913                 :             : class ErrorHandlerTraits<RetT (C::*)(const ErrT &)>
     914                 :             :     : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
     915                 :             : 
     916                 :             : // Specialization for member functions of the form 'RetT (const ErrT&) const'.
     917                 :             : template <typename C, typename RetT, typename ErrT>
     918                 :             : class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const>
     919                 :             :     : public ErrorHandlerTraits<RetT (&)(ErrT &)> {};
     920                 :             : 
     921                 :             : /// Specialization for member functions of the form
     922                 :             : /// 'RetT (std::unique_ptr<ErrT>)'.
     923                 :             : template <typename C, typename RetT, typename ErrT>
     924                 :             : class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)>
     925                 :             :     : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
     926                 :             : 
     927                 :             : /// Specialization for member functions of the form
     928                 :             : /// 'RetT (std::unique_ptr<ErrT>) const'.
     929                 :             : template <typename C, typename RetT, typename ErrT>
     930                 :             : class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const>
     931                 :             :     : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {};
     932                 :             : 
     933                 :             : inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) {
     934                 :             :   return Error(std::move(Payload));
     935                 :             : }
     936                 :             : 
     937                 :             : template <typename HandlerT, typename... HandlerTs>
     938                 :             : Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload,
     939                 :             :                       HandlerT &&Handler, HandlerTs &&... Handlers) {
     940                 :             :   if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload))
     941                 :             :     return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler),
     942                 :             :                                                std::move(Payload));
     943                 :             :   return handleErrorImpl(std::move(Payload),
     944                 :             :                          std::forward<HandlerTs>(Handlers)...);
     945                 :             : }
     946                 :             : 
     947                 :             : /// Pass the ErrorInfo(s) contained in E to their respective handlers. Any
     948                 :             : /// unhandled errors (or Errors returned by handlers) are re-concatenated and
     949                 :             : /// returned.
     950                 :             : /// Because this function returns an error, its result must also be checked
     951                 :             : /// or returned. If you intend to handle all errors use handleAllErrors
     952                 :             : /// (which returns void, and will abort() on unhandled errors) instead.
     953                 :             : template <typename... HandlerTs>
     954                 :             : Error handleErrors(Error E, HandlerTs &&... Hs) {
     955                 :             :   if (!E)
     956                 :             :     return Error::success();
     957                 :             : 
     958                 :             :   std::unique_ptr<ErrorInfoBase> Payload = E.takePayload();
     959                 :             : 
     960                 :             :   if (Payload->isA<ErrorList>()) {
     961                 :             :     ErrorList &List = static_cast<ErrorList &>(*Payload);
     962                 :             :     Error R;
     963                 :             :     for (auto &P : List.Payloads)
     964                 :             :       R = ErrorList::join(
     965                 :             :           std::move(R),
     966                 :             :           handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...));
     967                 :             :     return R;
     968                 :             :   }
     969                 :             : 
     970                 :             :   return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...);
     971                 :             : }
     972                 :             : 
     973                 :             : /// Behaves the same as handleErrors, except that by contract all errors
     974                 :             : /// *must* be handled by the given handlers (i.e. there must be no remaining
     975                 :             : /// errors after running the handlers, or llvm_unreachable is called).
     976                 :             : template <typename... HandlerTs>
     977                 :             : void handleAllErrors(Error E, HandlerTs &&... Handlers) {
     978                 :             :   cantFail(handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...));
     979                 :             : }
     980                 :             : 
     981                 :             : /// Check that E is a non-error, then drop it.
     982                 :             : /// If E is an error, llvm_unreachable will be called.
     983                 :             : inline void handleAllErrors(Error E) {
     984                 :             :   cantFail(std::move(E));
     985                 :             : }
     986                 :             : 
     987                 :             : /// Visit all the ErrorInfo(s) contained in E by passing them to the respective
     988                 :             : /// handler, without consuming the error.
     989                 :             : template <typename HandlerT> void visitErrors(const Error &E, HandlerT H) {
     990                 :             :   const ErrorInfoBase *Payload = E.getPtr();
     991                 :             :   if (!Payload)
     992                 :             :     return;
     993                 :             : 
     994                 :             :   if (Payload->isA<ErrorList>()) {
     995                 :             :     const ErrorList &List = static_cast<const ErrorList &>(*Payload);
     996                 :             :     for (const auto &P : List.Payloads)
     997                 :             :       H(*P);
     998                 :             :     return;
     999                 :             :   }
    1000                 :             : 
    1001                 :             :   return H(*Payload);
    1002                 :             : }
    1003                 :             : 
    1004                 :             : /// Handle any errors (if present) in an Expected<T>, then try a recovery path.
    1005                 :             : ///
    1006                 :             : /// If the incoming value is a success value it is returned unmodified. If it
    1007                 :             : /// is a failure value then it the contained error is passed to handleErrors.
    1008                 :             : /// If handleErrors is able to handle the error then the RecoveryPath functor
    1009                 :             : /// is called to supply the final result. If handleErrors is not able to
    1010                 :             : /// handle all errors then the unhandled errors are returned.
    1011                 :             : ///
    1012                 :             : /// This utility enables the follow pattern:
    1013                 :             : ///
    1014                 :             : ///   @code{.cpp}
    1015                 :             : ///   enum FooStrategy { Aggressive, Conservative };
    1016                 :             : ///   Expected<Foo> foo(FooStrategy S);
    1017                 :             : ///
    1018                 :             : ///   auto ResultOrErr =
    1019                 :             : ///     handleExpected(
    1020                 :             : ///       foo(Aggressive),
    1021                 :             : ///       []() { return foo(Conservative); },
    1022                 :             : ///       [](AggressiveStrategyError&) {
    1023                 :             : ///         // Implicitly conusme this - we'll recover by using a conservative
    1024                 :             : ///         // strategy.
    1025                 :             : ///       });
    1026                 :             : ///
    1027                 :             : ///   @endcode
    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                 :             : /// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner
    1042                 :             : /// will be printed before the first one is logged. A newline will be printed
    1043                 :             : /// after each error.
    1044                 :             : ///
    1045                 :             : /// This function is compatible with the helpers from Support/WithColor.h. You
    1046                 :             : /// can pass any of them as the OS. Please consider using them instead of
    1047                 :             : /// including 'error: ' in the ErrorBanner.
    1048                 :             : ///
    1049                 :             : /// This is useful in the base level of your program to allow clean termination
    1050                 :             : /// (allowing clean deallocation of resources, etc.), while reporting error
    1051                 :             : /// information to the user.
    1052                 :             : void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner = {});
    1053                 :             : 
    1054                 :             : /// Write all error messages (if any) in E to a string. The newline character
    1055                 :             : /// is used to separate error messages.
    1056                 :             : std::string toString(Error E);
    1057                 :             : 
    1058                 :             : /// Like toString(), but does not consume the error. This can be used to print
    1059                 :             : /// a warning while retaining the original error object.
    1060                 :             : std::string toStringWithoutConsuming(const Error &E);
    1061                 :             : 
    1062                 :             : /// Consume a Error without doing anything. This method should be used
    1063                 :             : /// only where an error can be considered a reasonable and expected return
    1064                 :             : /// value.
    1065                 :             : ///
    1066                 :             : /// Uses of this method are potentially indicative of design problems: If it's
    1067                 :             : /// legitimate to do nothing while processing an "error", the error-producer
    1068                 :             : /// might be more clearly refactored to return an std::optional<T>.
    1069                 :             : inline void consumeError(Error Err) {
    1070                 :             :   handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {});
    1071                 :             : }
    1072                 :             : 
    1073                 :             : /// Convert an Expected to an Optional without doing anything. This method
    1074                 :             : /// should be used only where an error can be considered a reasonable and
    1075                 :             : /// expected return value.
    1076                 :             : ///
    1077                 :             : /// Uses of this method are potentially indicative of problems: perhaps the
    1078                 :             : /// error should be propagated further, or the error-producer should just
    1079                 :             : /// return an Optional in the first place.
    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                 :             : /// Helper for converting an Error to a bool.
    1095                 :             : ///
    1096                 :             : /// This method returns true if Err is in an error state, or false if it is
    1097                 :             : /// in a success state.  Puts Err in a checked state in both cases (unlike
    1098                 :             : /// Error::operator bool(), which only does this for success states).
    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                 :             : /// Helper for Errors used as out-parameters.
    1107                 :             : ///
    1108                 :             : /// This helper is for use with the Error-as-out-parameter idiom, where an error
    1109                 :             : /// is passed to a function or method by reference, rather than being returned.
    1110                 :             : /// In such cases it is helpful to set the checked bit on entry to the function
    1111                 :             : /// so that the error can be written to (unchecked Errors abort on assignment)
    1112                 :             : /// and clear the checked bit on exit so that clients cannot accidentally forget
    1113                 :             : /// to check the result. This helper performs these actions automatically using
    1114                 :             : /// RAII:
    1115                 :             : ///
    1116                 :             : ///   @code{.cpp}
    1117                 :             : ///   Result foo(Error &Err) {
    1118                 :             : ///     ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set
    1119                 :             : ///     // <body of foo>
    1120                 :             : ///     // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed.
    1121                 :             : ///   }
    1122                 :             : ///   @endcode
    1123                 :             : ///
    1124                 :             : /// ErrorAsOutParameter takes an Error* rather than Error& so that it can be
    1125                 :             : /// used with optional Errors (Error pointers that are allowed to be null). If
    1126                 :             : /// ErrorAsOutParameter took an Error reference, an instance would have to be
    1127                 :             : /// created inside every condition that verified that Error was non-null. By
    1128                 :             : /// taking an Error pointer we can just create one instance at the top of the
    1129                 :             : /// function.
    1130                 :             : class ErrorAsOutParameter {
    1131                 :             : public:
    1132                 :             :   ErrorAsOutParameter(Error *Err) : Err(Err) {
    1133                 :             :     // Raise the checked bit if Err is success.
    1134                 :             :     if (Err)
    1135                 :             :       (void)!!*Err;
    1136                 :             :   }
    1137                 :             : 
    1138                 :             :   ~ErrorAsOutParameter() {
    1139                 :             :     // Clear the checked bit.
    1140                 :             :     if (Err && !*Err)
    1141                 :             :       *Err = Error::success();
    1142                 :             :   }
    1143                 :             : 
    1144                 :             : private:
    1145                 :             :   Error *Err;
    1146                 :             : };
    1147                 :             : 
    1148                 :             : /// Helper for Expected<T>s used as out-parameters.
    1149                 :             : ///
    1150                 :             : /// See ErrorAsOutParameter.
    1151                 :             : template <typename T>
    1152                 :             : class ExpectedAsOutParameter {
    1153                 :             : public:
    1154                 :             :   ExpectedAsOutParameter(Expected<T> *ValOrErr)
    1155                 :             :     : ValOrErr(ValOrErr) {
    1156                 :             :     if (ValOrErr)
    1157                 :             :       (void)!!*ValOrErr;
    1158                 :             :   }
    1159                 :             : 
    1160                 :             :   ~ExpectedAsOutParameter() {
    1161                 :             :     if (ValOrErr)
    1162                 :             :       ValOrErr->setUnchecked();
    1163                 :             :   }
    1164                 :             : 
    1165                 :             : private:
    1166                 :             :   Expected<T> *ValOrErr;
    1167                 :             : };
    1168                 :             : 
    1169                 :             : /// This class wraps a std::error_code in a Error.
    1170                 :             : ///
    1171                 :             : /// This is useful if you're writing an interface that returns a Error
    1172                 :             : /// (or Expected) and you want to call code that still returns
    1173                 :             : /// std::error_codes.
    1174                 :             : class ECError : public ErrorInfo<ECError> {
    1175                 :             :   friend Error errorCodeToError(std::error_code);
    1176                 :             : 
    1177                 :             :   void anchor() override;
    1178                 :             : 
    1179                 :             : public:
    1180                 :             :   void setErrorCode(std::error_code EC) { this->EC = EC; }
    1181                 :             :   std::error_code convertToErrorCode() const override { return EC; }
    1182                 :             :   void log(raw_ostream &OS) const override { OS << EC.message(); }
    1183                 :             : 
    1184                 :             :   // Used by ErrorInfo::classID.
    1185                 :             :   static char ID;
    1186                 :             : 
    1187                 :             : protected:
    1188                 :             :   ECError() = default;
    1189                 :             :   ECError(std::error_code EC) : EC(EC) {}
    1190                 :             : 
    1191                 :             :   std::error_code EC;
    1192                 :             : };
    1193                 :             : 
    1194                 :             : /// The value returned by this function can be returned from convertToErrorCode
    1195                 :             : /// for Error values where no sensible translation to std::error_code exists.
    1196                 :             : /// It should only be used in this situation, and should never be used where a
    1197                 :             : /// sensible conversion to std::error_code is available, as attempts to convert
    1198                 :             : /// to/from this error will result in a fatal error. (i.e. it is a programmatic
    1199                 :             : /// error to try to convert such a value).
    1200                 :             : std::error_code inconvertibleErrorCode();
    1201                 :             : 
    1202                 :             : /// Helper for converting an std::error_code to a Error.
    1203                 :             : Error errorCodeToError(std::error_code EC);
    1204                 :             : 
    1205                 :             : /// Helper for converting an ECError to a std::error_code.
    1206                 :             : ///
    1207                 :             : /// This method requires that Err be Error() or an ECError, otherwise it
    1208                 :             : /// will trigger a call to abort().
    1209                 :             : std::error_code errorToErrorCode(Error Err);
    1210                 :             : 
    1211                 :             : /// Helper to get errno as an std::error_code.
    1212                 :             : ///
    1213                 :             : /// errno should always be represented using the generic category as that's what
    1214                 :             : /// both libc++ and libstdc++ do. On POSIX systems you can also represent them
    1215                 :             : /// using the system category, however this makes them compare differently for
    1216                 :             : /// values outside of those used by `std::errc` if one is generic and the other
    1217                 :             : /// is system.
    1218                 :             : ///
    1219                 :             : /// See the libc++ and libstdc++ implementations of `default_error_condition` on
    1220                 :             : /// the system category for more details on what the difference is.
    1221                 :             : inline std::error_code errnoAsErrorCode() {
    1222                 :             :   return std::error_code(errno, std::generic_category());
    1223                 :             : }
    1224                 :             : 
    1225                 :             : /// Convert an ErrorOr<T> to an Expected<T>.
    1226                 :             : template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) {
    1227                 :             :   if (auto EC = EO.getError())
    1228                 :             :     return errorCodeToError(EC);
    1229                 :             :   return std::move(*EO);
    1230                 :             : }
    1231                 :             : 
    1232                 :             : /// Convert an Expected<T> to an ErrorOr<T>.
    1233                 :             : template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) {
    1234                 :             :   if (auto Err = E.takeError())
    1235                 :             :     return errorToErrorCode(std::move(Err));
    1236                 :             :   return std::move(*E);
    1237                 :             : }
    1238                 :             : 
    1239                 :             : /// This class wraps a string in an Error.
    1240                 :             : ///
    1241                 :             : /// StringError is useful in cases where the client is not expected to be able
    1242                 :             : /// to consume the specific error message programmatically (for example, if the
    1243                 :             : /// error message is to be presented to the user).
    1244                 :             : ///
    1245                 :             : /// StringError can also be used when additional information is to be printed
    1246                 :             : /// along with a error_code message. Depending on the constructor called, this
    1247                 :             : /// class can either display:
    1248                 :             : ///    1. the error_code message (ECError behavior)
    1249                 :             : ///    2. a string
    1250                 :             : ///    3. the error_code message and a string
    1251                 :             : ///
    1252                 :             : /// These behaviors are useful when subtyping is required; for example, when a
    1253                 :             : /// specific library needs an explicit error type. In the example below,
    1254                 :             : /// PDBError is derived from StringError:
    1255                 :             : ///
    1256                 :             : ///   @code{.cpp}
    1257                 :             : ///   Expected<int> foo() {
    1258                 :             : ///      return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading,
    1259                 :             : ///                                        "Additional information");
    1260                 :             : ///   }
    1261                 :             : ///   @endcode
    1262                 :             : ///
    1263                 :             : class StringError : public ErrorInfo<StringError> {
    1264                 :             : public:
    1265                 :             :   static char ID;
    1266                 :             : 
    1267                 :             :   StringError(std::string &&S, std::error_code EC, bool PrintMsgOnly);
    1268                 :             :   /// Prints EC + S and converts to EC.
    1269                 :             :   StringError(std::error_code EC, const Twine &S = Twine());
    1270                 :             :   /// Prints S and converts to EC.
    1271                 :             :   StringError(const Twine &S, std::error_code EC);
    1272                 :             : 
    1273                 :             :   void log(raw_ostream &OS) const override;
    1274                 :             :   std::error_code convertToErrorCode() const override;
    1275                 :             : 
    1276                 :             :   const std::string &getMessage() const { return Msg; }
    1277                 :             : 
    1278                 :             : private:
    1279                 :             :   std::string Msg;
    1280                 :             :   std::error_code EC;
    1281                 :             :   const bool PrintMsgOnly = false;
    1282                 :             : };
    1283                 :             : 
    1284                 :             : /// Create formatted StringError object.
    1285                 :             : template <typename... Ts>
    1286                 :             : inline Error createStringError(std::error_code EC, char const *Fmt,
    1287                 :             :                                const Ts &... Vals) {
    1288                 :             :   std::string Buffer;
    1289                 :             :   raw_string_ostream(Buffer) << format(Fmt, Vals...);
    1290                 :             :   return make_error<StringError>(Buffer, EC);
    1291                 :             : }
    1292                 :             : 
    1293                 :             : Error createStringError(std::string &&Msg, std::error_code EC);
    1294                 :             : 
    1295                 :             : inline Error createStringError(std::error_code EC, const char *S) {
    1296                 :             :   return createStringError(std::string(S), EC);
    1297                 :             : }
    1298                 :             : 
    1299                 :             : inline Error createStringError(std::error_code EC, const Twine &S) {
    1300                 :             :   return createStringError(S.str(), EC);
    1301                 :             : }
    1302                 :             : 
    1303                 :             : /// Create a StringError with an inconvertible error code.
    1304                 :             : inline Error createStringError(const Twine &S) {
    1305                 :             :   return createStringError(llvm::inconvertibleErrorCode(), S);
    1306                 :             : }
    1307                 :             : 
    1308                 :             : template <typename... Ts>
    1309                 :             : inline Error createStringError(char const *Fmt, const Ts &...Vals) {
    1310                 :             :   return createStringError(llvm::inconvertibleErrorCode(), Fmt, Vals...);
    1311                 :             : }
    1312                 :             : 
    1313                 :             : template <typename... Ts>
    1314                 :             : inline Error createStringError(std::errc EC, char const *Fmt,
    1315                 :             :                                const Ts &... Vals) {
    1316                 :             :   return createStringError(std::make_error_code(EC), Fmt, Vals...);
    1317                 :             : }
    1318                 :             : 
    1319                 :             : /// This class wraps a filename and another Error.
    1320                 :             : ///
    1321                 :             : /// In some cases, an error needs to live along a 'source' name, in order to
    1322                 :             : /// show more detailed information to the user.
    1323                 :             : class FileError final : public ErrorInfo<FileError> {
    1324                 :             : 
    1325                 :             :   friend Error createFileError(const Twine &, Error);
    1326                 :             :   friend Error createFileError(const Twine &, size_t, Error);
    1327                 :             : 
    1328                 :             : public:
    1329                 :             :   void log(raw_ostream &OS) const override {
    1330                 :             :     assert(Err && "Trying to log after takeError().");
    1331                 :             :     OS << "'" << FileName << "': ";
    1332                 :             :     if (Line)
    1333                 :             :       OS << "line " << *Line << ": ";
    1334                 :             :     Err->log(OS);
    1335                 :             :   }
    1336                 :             : 
    1337                 :             :   std::string messageWithoutFileInfo() const {
    1338                 :             :     std::string Msg;
    1339                 :             :     raw_string_ostream OS(Msg);
    1340                 :             :     Err->log(OS);
    1341                 :             :     return Msg;
    1342                 :             :   }
    1343                 :             : 
    1344                 :             :   StringRef getFileName() const { return FileName; }
    1345                 :             : 
    1346                 :             :   Error takeError() { return Error(std::move(Err)); }
    1347                 :             : 
    1348                 :             :   std::error_code convertToErrorCode() const override;
    1349                 :             : 
    1350                 :             :   // Used by ErrorInfo::classID.
    1351                 :             :   static char ID;
    1352                 :             : 
    1353                 :             : private:
    1354                 :             :   FileError(const Twine &F, std::optional<size_t> LineNum,
    1355                 :             :             std::unique_ptr<ErrorInfoBase> E) {
    1356                 :             :     assert(E && "Cannot create FileError from Error success value.");
    1357                 :             :     FileName = F.str();
    1358                 :             :     Err = std::move(E);
    1359                 :             :     Line = std::move(LineNum);
    1360                 :             :   }
    1361                 :             : 
    1362                 :             :   static Error build(const Twine &F, std::optional<size_t> Line, Error E) {
    1363                 :             :     std::unique_ptr<ErrorInfoBase> Payload;
    1364                 :             :     handleAllErrors(std::move(E),
    1365                 :             :                     [&](std::unique_ptr<ErrorInfoBase> EIB) -> Error {
    1366                 :             :                       Payload = std::move(EIB);
    1367                 :             :                       return Error::success();
    1368                 :             :                     });
    1369                 :             :     return Error(
    1370                 :             :         std::unique_ptr<FileError>(new FileError(F, Line, std::move(Payload))));
    1371                 :             :   }
    1372                 :             : 
    1373                 :             :   std::string FileName;
    1374                 :             :   std::optional<size_t> Line;
    1375                 :             :   std::unique_ptr<ErrorInfoBase> Err;
    1376                 :             : };
    1377                 :             : 
    1378                 :             : /// Concatenate a source file path and/or name with an Error. The resulting
    1379                 :             : /// Error is unchecked.
    1380                 :             : inline Error createFileError(const Twine &F, Error E) {
    1381                 :             :   return FileError::build(F, std::optional<size_t>(), std::move(E));
    1382                 :             : }
    1383                 :             : 
    1384                 :             : /// Concatenate a source file path and/or name with line number and an Error.
    1385                 :             : /// The resulting Error is unchecked.
    1386                 :             : inline Error createFileError(const Twine &F, size_t Line, Error E) {
    1387                 :             :   return FileError::build(F, std::optional<size_t>(Line), std::move(E));
    1388                 :             : }
    1389                 :             : 
    1390                 :             : /// Concatenate a source file path and/or name with a std::error_code 
    1391                 :             : /// to form an Error object.
    1392                 :             : inline Error createFileError(const Twine &F, std::error_code EC) {
    1393                 :             :   return createFileError(F, errorCodeToError(EC));
    1394                 :             : }
    1395                 :             : 
    1396                 :             : /// Concatenate a source file path and/or name with line number and
    1397                 :             : /// std::error_code to form an Error object.
    1398                 :             : inline Error createFileError(const Twine &F, size_t Line, std::error_code EC) {
    1399                 :             :   return createFileError(F, Line, errorCodeToError(EC));
    1400                 :             : }
    1401                 :             : 
    1402                 :             : Error createFileError(const Twine &F, ErrorSuccess) = delete;
    1403                 :             : 
    1404                 :             : /// Helper for check-and-exit error handling.
    1405                 :             : ///
    1406                 :             : /// For tool use only. NOT FOR USE IN LIBRARY CODE.
    1407                 :             : ///
    1408                 :             : class ExitOnError {
    1409                 :             : public:
    1410                 :             :   /// Create an error on exit helper.
    1411                 :             :   ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1)
    1412                 :             :       : Banner(std::move(Banner)),
    1413                 :             :         GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {}
    1414                 :             : 
    1415                 :             :   /// Set the banner string for any errors caught by operator().
    1416                 :             :   void setBanner(std::string Banner) { this->Banner = std::move(Banner); }
    1417                 :             : 
    1418                 :             :   /// Set the exit-code mapper function.
    1419                 :             :   void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) {
    1420                 :             :     this->GetExitCode = std::move(GetExitCode);
    1421                 :             :   }
    1422                 :             : 
    1423                 :             :   /// Check Err. If it's in a failure state log the error(s) and exit.
    1424                 :             :   void operator()(Error Err) const { checkError(std::move(Err)); }
    1425                 :             : 
    1426                 :             :   /// Check E. If it's in a success state then return the contained value. If
    1427                 :             :   /// it's in a failure state log the error(s) and exit.
    1428                 :             :   template <typename T> T operator()(Expected<T> &&E) const {
    1429                 :             :     checkError(E.takeError());
    1430                 :             :     return std::move(*E);
    1431                 :             :   }
    1432                 :             : 
    1433                 :             :   /// Check E. If it's in a success state then return the contained reference. If
    1434                 :             :   /// it's in a failure state log the error(s) and exit.
    1435                 :             :   template <typename T> T& operator()(Expected<T&> &&E) const {
    1436                 :             :     checkError(E.takeError());
    1437                 :             :     return *E;
    1438                 :             :   }
    1439                 :             : 
    1440                 :             : private:
    1441                 :             :   void checkError(Error Err) const {
    1442                 :             :     if (Err) {
    1443                 :             :       int ExitCode = GetExitCode(Err);
    1444                 :             :       logAllUnhandledErrors(std::move(Err), errs(), Banner);
    1445                 :             :       exit(ExitCode);
    1446                 :             :     }
    1447                 :             :   }
    1448                 :             : 
    1449                 :             :   std::string Banner;
    1450                 :             :   std::function<int(const Error &)> GetExitCode;
    1451                 :             : };
    1452                 :             : 
    1453                 :             : /// Conversion from Error to LLVMErrorRef for C error bindings.
    1454                 :             : inline LLVMErrorRef wrap(Error Err) {
    1455                 :             :   return reinterpret_cast<LLVMErrorRef>(Err.takePayload().release());
    1456                 :             : }
    1457                 :             : 
    1458                 :             : /// Conversion from LLVMErrorRef to Error for C error bindings.
    1459                 :             : inline Error unwrap(LLVMErrorRef ErrRef) {
    1460                 :             :   return Error(std::unique_ptr<ErrorInfoBase>(
    1461                 :             :       reinterpret_cast<ErrorInfoBase *>(ErrRef)));
    1462                 :             : }
    1463                 :             : 
    1464                 :             : } // end namespace llvm
    1465                 :             : 
    1466                 :             : #endif // LLVM_SUPPORT_ERROR_H
        

Generated by: LCOV version 2.0-1