17ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----- llvm/Support/Error.h - Recoverable error handling ----*- C++ -*-===// 27ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 37ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// The LLVM Compiler Infrastructure 47ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 57ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// This file is distributed under the University of Illinois Open Source 67ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// License. See LICENSE.TXT for details. 77ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 87ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 97ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// This file defines an API used to report recoverable errors. 117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#ifndef LLVM_SUPPORT_ERROR_H 157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#define LLVM_SUPPORT_ERROR_H 167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 172df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include "llvm/ADT/SmallVector.h" 187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/ADT/STLExtras.h" 197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/ADT/StringExtras.h" 207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/ADT/Twine.h" 212df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include "llvm/Config/abi-breaking.h" 222df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include "llvm/Support/AlignOf.h" 232df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include "llvm/Support/Compiler.h" 247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/Support/Debug.h" 257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/Support/ErrorOr.h" 267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/Support/raw_ostream.h" 272df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <algorithm> 282df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <cassert> 292df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <cstdint> 302df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <cstdlib> 312df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <functional> 322df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <memory> 332df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <new> 342df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <string> 352df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <system_error> 362df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <type_traits> 372df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <utility> 387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <vector> 397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensnamespace llvm { 417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 422df178997d17474042e8c3704cc93ab2db6619bfNicolas Capensclass ErrorSuccess; 437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Base class for error info classes. Do not extend this directly: Extend 457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// the ErrorInfo template subclass instead. 467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorInfoBase { 477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 482df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens virtual ~ErrorInfoBase() = default; 497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Print an error message to an output stream. 517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens virtual void log(raw_ostream &OS) const = 0; 527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Return the error message as a string. 547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens virtual std::string message() const { 557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::string Msg; 567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens raw_string_ostream OS(Msg); 577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens log(OS); 587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return OS.str(); 597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Convert this error to a std::error_code. 627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// 637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// This is a temporary crutch to enable interaction with code still 647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// using std::error_code. It will be removed in the future. 657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens virtual std::error_code convertToErrorCode() const = 0; 667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Check whether this instance is a subclass of the class identified by 687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // ClassID. 697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens virtual bool isA(const void *const ClassID) const { 707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ClassID == classID(); 717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Check whether this instance is a subclass of ErrorInfoT. 747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename ErrorInfoT> bool isA() const { 757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return isA(ErrorInfoT::classID()); 767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Returns the class ID for this type. 797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static const void *classID() { return &ID; } 807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens virtual void anchor(); 832df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static char ID; 857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Lightweight error class with error context and mandatory checking. 887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Instances of this class wrap a ErrorInfoBase pointer. Failure states 907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// are represented by setting the pointer to a ErrorInfoBase subclass 917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// instance containing information describing the failure. Success is 927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// represented by a null pointer value. 937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Instances of Error also contains a 'Checked' flag, which must be set 957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// before the destructor is called, otherwise the destructor will trigger a 967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// runtime error. This enforces at runtime the requirement that all Error 977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// instances be checked or returned to the caller. 987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// There are two ways to set the checked flag, depending on what state the 1007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Error instance is in. For Error instances indicating success, it 1017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// is sufficient to invoke the boolean conversion operator. E.g.: 1027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// @code{.cpp} 1047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Error foo(<...>); 1057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// if (auto E = foo(<...>)) 1077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// return E; // <- Return E if it is in the error state. 1087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // We have verified that E was in the success state. It can now be safely 1097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // destroyed. 1107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// @endcode 1117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// A success value *can not* be dropped. For example, just calling 'foo(<...>)' 1137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// without testing the return value will raise a runtime error, even if foo 1147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// returns success. 1157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// For Error instances representing failure, you must use either the 1177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// handleErrors or handleAllErrors function with a typed handler. E.g.: 1187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// @code{.cpp} 1207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// class MyErrorInfo : public ErrorInfo<MyErrorInfo> { 1217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // Custom error info. 1227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// }; 1237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Error foo(<...>) { return make_error<MyErrorInfo>(...); } 1257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo. 1277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// auto NewE = 1287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// handleErrors(E, 1297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// [](const MyErrorInfo &M) { 1307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // Deal with the error. 1317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// }, 1327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// [](std::unique_ptr<OtherError> M) -> Error { 1337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// if (canHandle(*M)) { 1347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // handle error. 1357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// return Error::success(); 1367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// } 1377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // Couldn't handle this error instance. Pass it up the stack. 1387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// return Error(std::move(M)); 1397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ); 1407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // Note - we must check or return NewE in case any of the handlers 1417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // returned a new error. 1427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// @endcode 1437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// The handleAllErrors function is identical to handleErrors, except 1457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// that it has a void return type, and requires all errors to be handled and 1467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// no new errors be returned. It prevents errors (assuming they can all be 1477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// handled) from having to be bubbled all the way to the top-level. 1487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 1497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// *All* Error instances must be checked before destruction, even if 1507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// they're moved-assigned or constructed from Success values that have already 1517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// been checked. This enforces checking through all levels of the call stack. 1522df178997d17474042e8c3704cc93ab2db6619bfNicolas Capensclass LLVM_NODISCARD Error { 1537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // ErrorList needs to be able to yank ErrorInfoBase pointers out of this 1547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // class to add to the error list. 1557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens friend class ErrorList; 1567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // handleErrors needs to be able to set the Checked flag. 1587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename... HandlerTs> 1597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens friend Error handleErrors(Error E, HandlerTs &&... Handlers); 1607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Expected<T> needs to be able to steal the payload when constructed from an 1627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // error. 1632df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens template <typename T> friend class Expected; 1647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1652df178997d17474042e8c3704cc93ab2db6619bfNicolas Capensprotected: 1667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Create a success value. Prefer using 'Error::success()' for readability 1672df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Error() : Payload(nullptr) { 1687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setPtr(nullptr); 1697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setChecked(false); 1707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1722df178997d17474042e8c3704cc93ab2db6619bfNicolas Capenspublic: 1732df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// Create a success value. 1742df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens static ErrorSuccess success(); 1757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Errors are not copy-constructable. 1777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error(const Error &Other) = delete; 1787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Move-construct an error value. The newly constructed error is considered 1807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// unchecked, even if the source error had been checked. The original error 1817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// becomes a checked Success value, regardless of its original state. 1822df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Error(Error &&Other) : Payload(nullptr) { 1837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setChecked(true); 1847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens *this = std::move(Other); 1857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Create an error value. Prefer using the 'make_error' function, but 1887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// this constructor can be useful when "re-throwing" errors from handlers. 1897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error(std::unique_ptr<ErrorInfoBase> Payload) { 1907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setPtr(Payload.release()); 1917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setChecked(false); 1927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Errors are not copy-assignable. 1957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error &operator=(const Error &Other) = delete; 1967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Move-assign an error value. The current error must represent success, you 1987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// you cannot overwrite an unhandled error. The current error is then 1997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// considered unchecked. The source error becomes a checked success value, 2007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// regardless of its original state. 2017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error &operator=(Error &&Other) { 2027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Don't allow overwriting of unchecked values. 2037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 2047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setPtr(Other.getPtr()); 2057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // This Error is unchecked, even if the source error was checked. 2077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setChecked(false); 2087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Null out Other's payload and set its checked bit. 2107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Other.setPtr(nullptr); 2117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Other.setChecked(true); 2127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 2147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Destroy a Error. Fails with a call to abort() if the error is 2177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// unchecked. 2187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ~Error() { 2197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 2207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens delete getPtr(); 2217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Bool conversion. Returns true if this Error is in a failure state, 2247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// and false if it is in an accept state. If the error is in a Success state 2257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// it will be considered checked. 2267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens explicit operator bool() { 2277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setChecked(getPtr() == nullptr); 2287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return getPtr() != nullptr; 2297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Check whether one error is a subclass of another. 2327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename ErrT> bool isA() const { 2337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return getPtr() && getPtr()->isA(ErrT::classID()); 2347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 2377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void assertIsChecked() { 2382df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 2397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!getChecked() || getPtr()) { 2407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens dbgs() << "Program aborted due to an unhandled Error:\n"; 2417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (getPtr()) 2427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens getPtr()->log(dbgs()); 2437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens else 2447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens dbgs() 2457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens << "Error value was Success. (Note: Success values must still be " 2467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens "checked prior to being destroyed).\n"; 2477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens abort(); 2487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 2507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ErrorInfoBase *getPtr() const { 2532df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return reinterpret_cast<ErrorInfoBase*>( 2542df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens reinterpret_cast<uintptr_t>(Payload) & 2552df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens ~static_cast<uintptr_t>(0x1)); 2567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void setPtr(ErrorInfoBase *EI) { 2592df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 2602df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Payload = reinterpret_cast<ErrorInfoBase*>( 2612df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens (reinterpret_cast<uintptr_t>(EI) & 2622df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens ~static_cast<uintptr_t>(0x1)) | 2632df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens (reinterpret_cast<uintptr_t>(Payload) & 0x1)); 2647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#else 2657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Payload = EI; 2667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 2677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool getChecked() const { 2702df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 2712df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens return (reinterpret_cast<uintptr_t>(Payload) & 0x1) == 0; 2727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#else 2737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return true; 2747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 2757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void setChecked(bool V) { 2782df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Payload = reinterpret_cast<ErrorInfoBase*>( 2792df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens (reinterpret_cast<uintptr_t>(Payload) & 2802df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens ~static_cast<uintptr_t>(0x1)) | 2812df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens (V ? 0 : 1)); 2827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::unique_ptr<ErrorInfoBase> takePayload() { 2857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::unique_ptr<ErrorInfoBase> Tmp(getPtr()); 2867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setPtr(nullptr); 2877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens setChecked(true); 2887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Tmp; 2897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 2907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ErrorInfoBase *Payload; 2927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 2937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 2942df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens/// Subclass of Error for the sole purpose of identifying the success path in 2952df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens/// the type system. This allows to catch invalid conversion to Expected<T> at 2962df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens/// compile time. 2972df178997d17474042e8c3704cc93ab2db6619bfNicolas Capensclass ErrorSuccess : public Error {}; 2982df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 2992df178997d17474042e8c3704cc93ab2db6619bfNicolas Capensinline ErrorSuccess Error::success() { return ErrorSuccess(); } 3002df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 3017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Make a Error instance representing failure using the given error info 3027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// type. 3037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) { 3047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...)); 3057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 3067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Base class for user error types. Users should declare their error types 3087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// like: 3097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 3107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// class MyError : public ErrorInfo<MyError> { 3117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// .... 3127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// }; 3137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 3147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This class provides an implementation of the ErrorInfoBase::kind 3157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// method, which is used by the Error RTTI system. 3167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename ThisErrT, typename ParentErrT = ErrorInfoBase> 3177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorInfo : public ParentErrT { 3187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 3197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool isA(const void *const ClassID) const override { 3207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ClassID == classID() || ParentErrT::isA(ClassID); 3217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static const void *classID() { return &ThisErrT::ID; } 3247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 3257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Special ErrorInfo subclass representing a list of ErrorInfos. 3277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Instances of this class are constructed by joinError. 3287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorList final : public ErrorInfo<ErrorList> { 3297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // handleErrors needs to be able to iterate the payload list of an 3307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // ErrorList. 3317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename... HandlerTs> 3327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens friend Error handleErrors(Error E, HandlerTs &&... Handlers); 3337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // joinErrors is implemented in terms of join. 3357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens friend Error joinErrors(Error, Error); 3367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 3387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void log(raw_ostream &OS) const override { 3397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens OS << "Multiple errors:\n"; 3407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens for (auto &ErrPayload : Payloads) { 3417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ErrPayload->log(OS); 3427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens OS << "\n"; 3437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::error_code convertToErrorCode() const override; 3477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Used by ErrorInfo::classID. 3497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static char ID; 3507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 3527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ErrorList(std::unique_ptr<ErrorInfoBase> Payload1, 3537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::unique_ptr<ErrorInfoBase> Payload2) { 3547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && 3557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens "ErrorList constructor payloads should be singleton errors"); 3567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Payloads.push_back(std::move(Payload1)); 3577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Payloads.push_back(std::move(Payload2)); 3587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static Error join(Error E1, Error E2) { 3617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!E1) 3627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E2; 3637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!E2) 3647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E1; 3657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (E1.isA<ErrorList>()) { 3667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens auto &E1List = static_cast<ErrorList &>(*E1.getPtr()); 3677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (E2.isA<ErrorList>()) { 3687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens auto E2Payload = E2.takePayload(); 3697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens auto &E2List = static_cast<ErrorList &>(*E2Payload); 3707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens for (auto &Payload : E2List.Payloads) 3717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens E1List.Payloads.push_back(std::move(Payload)); 3727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } else 3737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens E1List.Payloads.push_back(E2.takePayload()); 3747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E1; 3767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (E2.isA<ErrorList>()) { 3787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens auto &E2List = static_cast<ErrorList &>(*E2.getPtr()); 3797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload()); 3807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E2; 3817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Error(std::unique_ptr<ErrorList>( 3837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens new ErrorList(E1.takePayload(), E2.takePayload()))); 3847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 3857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::vector<std::unique_ptr<ErrorInfoBase>> Payloads; 3877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 3887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Concatenate errors. The resulting Error is unchecked, and contains the 3907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorInfo(s), if any, contained in E1, followed by the 3917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorInfo(s), if any, contained in E2. 3927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline Error joinErrors(Error E1, Error E2) { 3937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ErrorList::join(std::move(E1), std::move(E2)); 3947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 3957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 3967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Helper for testing applicability of, and applying, handlers for 3977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorInfo types. 3987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename HandlerT> 3997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits 4007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<decltype( 4017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens &std::remove_reference<HandlerT>::type::operator())> {}; 4027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Specialization functions of the form 'Error (const ErrT&)'. 4047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> { 4057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 4067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool appliesTo(const ErrorInfoBase &E) { 4077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E.template isA<ErrT>(); 4087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename HandlerT> 4117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 4127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(appliesTo(*E) && "Applying incorrect handler"); 4137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return H(static_cast<ErrT &>(*E)); 4147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 4167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Specialization functions of the form 'void (const ErrT&)'. 4187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> { 4197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 4207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool appliesTo(const ErrorInfoBase &E) { 4217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E.template isA<ErrT>(); 4227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename HandlerT> 4257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 4267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(appliesTo(*E) && "Applying incorrect handler"); 4277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens H(static_cast<ErrT &>(*E)); 4287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Error::success(); 4297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 4317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'. 4337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename ErrT> 4347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> { 4357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 4367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool appliesTo(const ErrorInfoBase &E) { 4377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E.template isA<ErrT>(); 4387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename HandlerT> 4417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 4427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(appliesTo(*E) && "Applying incorrect handler"); 4437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release())); 4447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return H(std::move(SubE)); 4457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 4477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'. 4497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename ErrT> 4507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> { 4517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 4527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool appliesTo(const ErrorInfoBase &E) { 4537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return E.template isA<ErrT>(); 4547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename HandlerT> 4577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 4587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(appliesTo(*E) && "Applying incorrect handler"); 4597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release())); 4607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens H(std::move(SubE)); 4617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Error::success(); 4627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 4637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 4647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Specialization for member functions of the form 'RetT (const ErrT&)'. 4667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename C, typename RetT, typename ErrT> 4677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<RetT (C::*)(ErrT &)> 4687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 4697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Specialization for member functions of the form 'RetT (const ErrT&) const'. 4717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename C, typename RetT, typename ErrT> 4727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<RetT (C::*)(ErrT &) const> 4737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 4747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Specialization for member functions of the form 'RetT (const ErrT&)'. 4767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename C, typename RetT, typename ErrT> 4777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<RetT (C::*)(const ErrT &)> 4787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 4797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Specialization for member functions of the form 'RetT (const ErrT&) const'. 4817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename C, typename RetT, typename ErrT> 4827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<RetT (C::*)(const ErrT &) const> 4837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 4847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Specialization for member functions of the form 4867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 'RetT (std::unique_ptr<ErrT>) const'. 4877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename C, typename RetT, typename ErrT> 4887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)> 4897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {}; 4907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Specialization for member functions of the form 4927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 'RetT (std::unique_ptr<ErrT>) const'. 4937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename C, typename RetT, typename ErrT> 4947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const> 4957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {}; 4967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 4977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) { 4987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Error(std::move(Payload)); 4997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename HandlerT, typename... HandlerTs> 5027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensError handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload, 5037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens HandlerT &&Handler, HandlerTs &&... Handlers) { 5047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload)) 5057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler), 5067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::move(Payload)); 5077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return handleErrorImpl(std::move(Payload), 5087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::forward<HandlerTs>(Handlers)...); 5097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any 5127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// unhandled errors (or Errors returned by handlers) are re-concatenated and 5137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// returned. 5147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Because this function returns an error, its result must also be checked 5157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// or returned. If you intend to handle all errors use handleAllErrors 5167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// (which returns void, and will abort() on unhandled errors) instead. 5177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename... HandlerTs> 5187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensError handleErrors(Error E, HandlerTs &&... Hs) { 5197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!E) 5207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return Error::success(); 5217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::unique_ptr<ErrorInfoBase> Payload = E.takePayload(); 5237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (Payload->isA<ErrorList>()) { 5257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ErrorList &List = static_cast<ErrorList &>(*Payload); 5267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error R; 5277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens for (auto &P : List.Payloads) 5287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens R = ErrorList::join( 5297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::move(R), 5307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...)); 5317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return R; 5327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 5337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...); 5357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Behaves the same as handleErrors, except that it requires that all 5387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// errors be handled by the given handlers. If any unhandled error remains 5397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// after the handlers have run, abort() will be called. 5407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename... HandlerTs> 5417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid handleAllErrors(Error E, HandlerTs &&... Handlers) { 5427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens auto F = handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...); 5437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Cast 'F' to bool to set the 'Checked' flag if it's a success value: 5447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens (void)!F; 5457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Check that E is a non-error, then drop it. 5487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline void handleAllErrors(Error E) { 5497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Cast 'E' to a bool to set the 'Checked' flag if it's a success value: 5507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens (void)!E; 5517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner 5547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// will be printed before the first one is logged. A newline will be printed 5557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// after each error. 5567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 5577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This is useful in the base level of your program to allow clean termination 5587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// (allowing clean deallocation of resources, etc.), while reporting error 5597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// information to the user. 5607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner); 5617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Write all error messages (if any) in E to a string. The newline character 5637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// is used to separate error messages. 5647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline std::string toString(Error E) { 5657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens SmallVector<std::string, 2> Errors; 5667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) { 5677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Errors.push_back(EI.message()); 5687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens }); 5697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return join(Errors.begin(), Errors.end(), "\n"); 5707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Consume a Error without doing anything. This method should be used 5737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// only where an error can be considered a reasonable and expected return 5747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// value. 5757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 5767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Uses of this method are potentially indicative of design problems: If it's 5777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// legitimate to do nothing while processing an "error", the error-producer 5787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// might be more clearly refactored to return an Optional<T>. 5797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensinline void consumeError(Error Err) { 5807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {}); 5817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 5827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 5837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Helper for Errors used as out-parameters. 5847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 5857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This helper is for use with the Error-as-out-parameter idiom, where an error 5867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// is passed to a function or method by reference, rather than being returned. 5877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// In such cases it is helpful to set the checked bit on entry to the function 5887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// so that the error can be written to (unchecked Errors abort on assignment) 5897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// and clear the checked bit on exit so that clients cannot accidentally forget 5907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// to check the result. This helper performs these actions automatically using 5917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// RAII: 5927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 5937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// @code{.cpp} 5947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Result foo(Error &Err) { 5957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorAsOutParameter ErrAsOutParam(&Err); // 'Checked' flag set 5967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // <body of foo> 5977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed. 5987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// } 5997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// @endcode 6007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 6017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorAsOutParameter takes an Error* rather than Error& so that it can be 6027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// used with optional Errors (Error pointers that are allowed to be null). If 6037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorAsOutParameter took an Error reference, an instance would have to be 6047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// created inside every condition that verified that Error was non-null. By 6057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// taking an Error pointer we can just create one instance at the top of the 6067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// function. 6077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ErrorAsOutParameter { 6087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 6097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ErrorAsOutParameter(Error *Err) : Err(Err) { 6107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Raise the checked bit if Err is success. 6117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (Err) 6127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens (void)!!*Err; 6137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 6142df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 6157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ~ErrorAsOutParameter() { 6167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Clear the checked bit. 6177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (Err && !*Err) 6187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens *Err = Error::success(); 6197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 6207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 6227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error *Err; 6237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 6247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Tagged union holding either a T or a Error. 6267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 6277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This class parallels ErrorOr, but replaces error_code with Error. Since 6287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Error cannot be copied, this class replaces getError() with 6297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the 6307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// error class type. 6312df178997d17474042e8c3704cc93ab2db6619bfNicolas Capenstemplate <class T> class LLVM_NODISCARD Expected { 6327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class OtherT> friend class Expected; 6337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static const bool isRef = std::is_reference<T>::value; 6347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap; 6357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef std::unique_ptr<ErrorInfoBase> error_type; 6377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 6397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename std::conditional<isRef, wrap, T>::type storage_type; 6407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef T value_type; 6417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 6437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename std::remove_reference<T>::type &reference; 6447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const typename std::remove_reference<T>::type &const_reference; 6457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef typename std::remove_reference<T>::type *pointer; 6467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef const typename std::remove_reference<T>::type *const_pointer; 6477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 6497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Create an Expected<T> error value from the given Error. 6507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Expected(Error Err) 6517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : HasError(true) 6522df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 6532df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens // Expected is unchecked upon construction in Debug builds. 6542df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens , Unchecked(true) 6557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 6567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens { 6577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(Err && "Cannot create Expected<T> from Error success value."); 6582df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens new (getErrorStorage()) error_type(Err.takePayload()); 6597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 6607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6612df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// Forbid to convert from Error::success() implicitly, this avoids having 6622df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// Expected<T> foo() { return Error::success(); } which compiles otherwise 6632df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens /// but triggers the assertion above. 6642df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Expected(ErrorSuccess) = delete; 6652df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 6667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Create an Expected<T> success value from the given OtherT value, which 6677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// must be convertible to T. 6687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename OtherT> 6697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Expected(OtherT &&Val, 6707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename std::enable_if<std::is_convertible<OtherT, T>::value>::type 6717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * = nullptr) 6727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : HasError(false) 6732df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 6742df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens // Expected is unchecked upon construction in Debug builds. 6752df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens , Unchecked(true) 6767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 6777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens { 6787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens new (getStorage()) storage_type(std::forward<OtherT>(Val)); 6797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 6807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Move construct an Expected<T> value. 6827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Expected(Expected &&Other) { moveConstruct(std::move(Other)); } 6837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT 6857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// must be convertible to T. 6867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class OtherT> 6877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Expected(Expected<OtherT> &&Other, 6887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename std::enable_if<std::is_convertible<OtherT, T>::value>::type 6897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * = nullptr) { 6907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens moveConstruct(std::move(Other)); 6917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 6927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 6937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT 6947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// isn't convertible to T. 6957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class OtherT> 6967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens explicit Expected( 6977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Expected<OtherT> &&Other, 6987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * = 6997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens nullptr) { 7007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens moveConstruct(std::move(Other)); 7017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Move-assign from another Expected<T>. 7047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Expected &operator=(Expected &&Other) { 7057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens moveAssign(std::move(Other)); 7067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 7077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Destroy an Expected<T>. 7107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ~Expected() { 7117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!HasError) 7137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens getStorage()->~storage_type(); 7147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens else 7157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens getErrorStorage()->~error_type(); 7167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Return false if there is an error. 7197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens explicit operator bool() { 7202df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 7212df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Unchecked = HasError; 7227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 7237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return !HasError; 7247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Returns a reference to the stored T value. 7277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens reference get() { 7287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *getStorage(); 7307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Returns a const reference to the stored T value. 7337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const_reference get() const { 7347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return const_cast<Expected<T> *>(this)->get(); 7367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Check that this Expected<T> is an error of type ErrT. 7397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename ErrT> bool errorIsA() const { 7407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return HasError && getErrorStorage()->template isA<ErrT>(); 7417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Take ownership of the stored error. 7447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// After calling this the Expected<T> is in an indeterminate state that can 7457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// only be safely destructed. No further calls (beside the destructor) should 7467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// be made on the Expected<T> vaule. 7477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Error takeError() { 7482df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 7492df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Unchecked = false; 7507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 7517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return HasError ? Error(std::move(*getErrorStorage())) : Error::success(); 7527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Returns a pointer to the stored T value. 7557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens pointer operator->() { 7567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return toPointer(getStorage()); 7587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Returns a const pointer to the stored T value. 7617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const_pointer operator->() const { 7627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return toPointer(getStorage()); 7647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Returns a reference to the stored T value. 7677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens reference operator*() { 7687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *getStorage(); 7707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Returns a const reference to the stored T value. 7737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const_reference operator*() const { 7747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 7757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *getStorage(); 7767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 7797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class T1> 7807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool compareThisIfSameType(const T1 &a, const T1 &b) { 7817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return &a == &b; 7827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class T1, class T2> 7857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static bool compareThisIfSameType(const T1 &a, const T2 &b) { 7867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return false; 7877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 7887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) { 7907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens HasError = Other.HasError; 7912df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 7922df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Unchecked = true; 7932df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens Other.Unchecked = false; 7947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 7957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 7967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (!HasError) 7977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens new (getStorage()) storage_type(std::move(*Other.getStorage())); 7987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens else 7997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage())); 8007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <class OtherT> void moveAssign(Expected<OtherT> &&Other) { 8037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assertIsChecked(); 8047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (compareThisIfSameType(*this, Other)) 8067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return; 8077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens this->~Expected(); 8097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens new (this) Expected(std::move(Other)); 8107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens pointer toPointer(pointer Val) { return Val; } 8137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const_pointer toPointer(const_pointer Val) const { return Val; } 8157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens pointer toPointer(wrap *Val) { return &Val->get(); } 8177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const_pointer toPointer(const wrap *Val) const { return &Val->get(); } 8197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens storage_type *getStorage() { 8217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!HasError && "Cannot get value when an error exists!"); 8227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return reinterpret_cast<storage_type *>(TStorage.buffer); 8237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens const storage_type *getStorage() const { 8267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(!HasError && "Cannot get value when an error exists!"); 8277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return reinterpret_cast<const storage_type *>(TStorage.buffer); 8287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens error_type *getErrorStorage() { 8317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(HasError && "Cannot get error when a value exists!"); 8327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return reinterpret_cast<error_type *>(ErrorStorage.buffer); 8337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void assertIsChecked() { 8362df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 8372df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens if (Unchecked) { 8387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens dbgs() << "Expected<T> must be checked before access or destruction.\n"; 8397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (HasError) { 8407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens dbgs() << "Unchecked Expected<T> contained error:\n"; 8417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens (*getErrorStorage())->log(dbgs()); 8427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } else 8437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens dbgs() << "Expected<T> value was in success state. (Note: Expected<T> " 8447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens "values in success mode must still be checked prior to being " 8457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens "destroyed).\n"; 8467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens abort(); 8477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 8497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 8507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens union { 8527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens AlignedCharArrayUnion<storage_type> TStorage; 8537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens AlignedCharArrayUnion<error_type> ErrorStorage; 8547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens }; 8557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool HasError : 1; 8562df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#if LLVM_ENABLE_ABI_BREAKING_CHECKS 8572df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens bool Unchecked : 1; 8587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 8597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 8607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This class wraps a std::error_code in a Error. 8627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 8637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This is useful if you're writing an interface that returns a Error 8647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// (or Expected) and you want to call code that still returns 8657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// std::error_codes. 8667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ECError : public ErrorInfo<ECError> { 8677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens friend Error errorCodeToError(std::error_code); 8682df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 8697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 8707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void setErrorCode(std::error_code EC) { this->EC = EC; } 8717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::error_code convertToErrorCode() const override { return EC; } 8727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void log(raw_ostream &OS) const override { OS << EC.message(); } 8737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens // Used by ErrorInfo::classID. 8757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static char ID; 8767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprotected: 8787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ECError() = default; 8797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ECError(std::error_code EC) : EC(EC) {} 8802df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 8817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::error_code EC; 8827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 8837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// The value returned by this function can be returned from convertToErrorCode 8857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// for Error values where no sensible translation to std::error_code exists. 8867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// It should only be used in this situation, and should never be used where a 8877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// sensible conversion to std::error_code is available, as attempts to convert 8887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// to/from this error will result in a fatal error. (i.e. it is a programmatic 8897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens///error to try to convert such a value). 8907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstd::error_code inconvertibleErrorCode(); 8917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Helper for converting an std::error_code to a Error. 8937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensError errorCodeToError(std::error_code EC); 8947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 8957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Helper for converting an ECError to a std::error_code. 8967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 8977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This method requires that Err be Error() or an ECError, otherwise it 8987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// will trigger a call to abort(). 8997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstd::error_code errorToErrorCode(Error Err); 9007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Convert an ErrorOr<T> to an Expected<T>. 9027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) { 9037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (auto EC = EO.getError()) 9047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return errorCodeToError(EC); 9057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return std::move(*EO); 9067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 9077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Convert an Expected<T> to an ErrorOr<T>. 9097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) { 9107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (auto Err = E.takeError()) 9117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return errorToErrorCode(std::move(Err)); 9127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return std::move(*E); 9137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} 9147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This class wraps a string in an Error. 9167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 9177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// StringError is useful in cases where the client is not expected to be able 9187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// to consume the specific error message programmatically (for example, if the 9197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// error message is to be presented to the user). 9207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass StringError : public ErrorInfo<StringError> { 9217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 9227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static char ID; 9232df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 9247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens StringError(const Twine &S, std::error_code EC); 9252df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 9267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void log(raw_ostream &OS) const override; 9277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::error_code convertToErrorCode() const override; 9282df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens 9297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 9307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::string Msg; 9317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::error_code EC; 9327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 9337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Helper for check-and-exit error handling. 9357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 9367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// For tool use only. NOT FOR USE IN LIBRARY CODE. 9377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 9387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass ExitOnError { 9397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 9407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Create an error on exit helper. 9417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1) 9427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens : Banner(std::move(Banner)), 9437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {} 9447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Set the banner string for any errors caught by operator(). 9467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void setBanner(std::string Banner) { this->Banner = std::move(Banner); } 9477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Set the exit-code mapper function. 9497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) { 9507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens this->GetExitCode = std::move(GetExitCode); 9517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 9527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Check Err. If it's in a failure state log the error(s) and exit. 9547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void operator()(Error Err) const { checkError(std::move(Err)); } 9557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Check E. If it's in a success state then return the contained value. If 9577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// it's in a failure state log the error(s) and exit. 9587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> T operator()(Expected<T> &&E) const { 9597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens checkError(E.takeError()); 9607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return std::move(*E); 9617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 9627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// Check E. If it's in a success state then return the contained reference. If 9647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// it's in a failure state log the error(s) and exit. 9657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens template <typename T> T& operator()(Expected<T&> &&E) const { 9667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens checkError(E.takeError()); 9677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *E; 9687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 9697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 9717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void checkError(Error Err) const { 9727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (Err) { 9737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens int ExitCode = GetExitCode(Err); 9747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens logAllUnhandledErrors(std::move(Err), errs(), Banner); 9757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens exit(ExitCode); 9767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 9777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 9787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::string Banner; 9807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens std::function<int(const Error &)> GetExitCode; 9817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 9827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Report a serious error, calling any installed error handler. See 9847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// ErrorHandling.h. 9857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensLLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, 9867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool gen_crash_diag = true); 9877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9882df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens} // end namespace llvm 9897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 9907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif // LLVM_SUPPORT_ERROR_H 991