Error.h revision 309124
1//===----- llvm/Support/Error.h - Recoverable error handling ----*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an API used to report recoverable errors. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SUPPORT_ERROR_H 15#define LLVM_SUPPORT_ERROR_H 16 17#include "llvm/ADT/PointerIntPair.h" 18#include "llvm/ADT/STLExtras.h" 19#include "llvm/ADT/StringExtras.h" 20#include "llvm/ADT/Twine.h" 21#include "llvm/Support/Debug.h" 22#include "llvm/Support/ErrorOr.h" 23#include "llvm/Support/raw_ostream.h" 24#include <vector> 25 26namespace llvm { 27 28class Error; 29class ErrorList; 30 31/// Base class for error info classes. Do not extend this directly: Extend 32/// the ErrorInfo template subclass instead. 33class ErrorInfoBase { 34public: 35 virtual ~ErrorInfoBase() {} 36 37 /// Print an error message to an output stream. 38 virtual void log(raw_ostream &OS) const = 0; 39 40 /// Return the error message as a string. 41 virtual std::string message() const { 42 std::string Msg; 43 raw_string_ostream OS(Msg); 44 log(OS); 45 return OS.str(); 46 } 47 48 /// Convert this error to a std::error_code. 49 /// 50 /// This is a temporary crutch to enable interaction with code still 51 /// using std::error_code. It will be removed in the future. 52 virtual std::error_code convertToErrorCode() const = 0; 53 54 // Check whether this instance is a subclass of the class identified by 55 // ClassID. 56 virtual bool isA(const void *const ClassID) const { 57 return ClassID == classID(); 58 } 59 60 // Check whether this instance is a subclass of ErrorInfoT. 61 template <typename ErrorInfoT> bool isA() const { 62 return isA(ErrorInfoT::classID()); 63 } 64 65 // Returns the class ID for this type. 66 static const void *classID() { return &ID; } 67 68private: 69 virtual void anchor(); 70 static char ID; 71}; 72 73/// Lightweight error class with error context and mandatory checking. 74/// 75/// Instances of this class wrap a ErrorInfoBase pointer. Failure states 76/// are represented by setting the pointer to a ErrorInfoBase subclass 77/// instance containing information describing the failure. Success is 78/// represented by a null pointer value. 79/// 80/// Instances of Error also contains a 'Checked' flag, which must be set 81/// before the destructor is called, otherwise the destructor will trigger a 82/// runtime error. This enforces at runtime the requirement that all Error 83/// instances be checked or returned to the caller. 84/// 85/// There are two ways to set the checked flag, depending on what state the 86/// Error instance is in. For Error instances indicating success, it 87/// is sufficient to invoke the boolean conversion operator. E.g.: 88/// 89/// Error foo(<...>); 90/// 91/// if (auto E = foo(<...>)) 92/// return E; // <- Return E if it is in the error state. 93/// // We have verified that E was in the success state. It can now be safely 94/// // destroyed. 95/// 96/// A success value *can not* be dropped. For example, just calling 'foo(<...>)' 97/// without testing the return value will raise a runtime error, even if foo 98/// returns success. 99/// 100/// For Error instances representing failure, you must use either the 101/// handleErrors or handleAllErrors function with a typed handler. E.g.: 102/// 103/// class MyErrorInfo : public ErrorInfo<MyErrorInfo> { 104/// // Custom error info. 105/// }; 106/// 107/// Error foo(<...>) { return make_error<MyErrorInfo>(...); } 108/// 109/// auto E = foo(<...>); // <- foo returns failure with MyErrorInfo. 110/// auto NewE = 111/// handleErrors(E, 112/// [](const MyErrorInfo &M) { 113/// // Deal with the error. 114/// }, 115/// [](std::unique_ptr<OtherError> M) -> Error { 116/// if (canHandle(*M)) { 117/// // handle error. 118/// return Error::success(); 119/// } 120/// // Couldn't handle this error instance. Pass it up the stack. 121/// return Error(std::move(M)); 122/// ); 123/// // Note - we must check or return NewE in case any of the handlers 124/// // returned a new error. 125/// 126/// The handleAllErrors function is identical to handleErrors, except 127/// that it has a void return type, and requires all errors to be handled and 128/// no new errors be returned. It prevents errors (assuming they can all be 129/// handled) from having to be bubbled all the way to the top-level. 130/// 131/// *All* Error instances must be checked before destruction, even if 132/// they're moved-assigned or constructed from Success values that have already 133/// been checked. This enforces checking through all levels of the call stack. 134class Error { 135 136 // ErrorList needs to be able to yank ErrorInfoBase pointers out of this 137 // class to add to the error list. 138 friend class ErrorList; 139 140 // handleErrors needs to be able to set the Checked flag. 141 template <typename... HandlerTs> 142 friend Error handleErrors(Error E, HandlerTs &&... Handlers); 143 144 // Expected<T> needs to be able to steal the payload when constructed from an 145 // error. 146 template <typename T> class Expected; 147 148public: 149 /// Create a success value. Prefer using 'Error::success()' for readability 150 /// where possible. 151 Error() { 152 setPtr(nullptr); 153 setChecked(false); 154 } 155 156 /// Create a success value. This is equivalent to calling the default 157 /// constructor, but should be preferred for readability where possible. 158 static Error success() { return Error(); } 159 160 // Errors are not copy-constructable. 161 Error(const Error &Other) = delete; 162 163 /// Move-construct an error value. The newly constructed error is considered 164 /// unchecked, even if the source error had been checked. The original error 165 /// becomes a checked Success value, regardless of its original state. 166 Error(Error &&Other) { 167 setChecked(true); 168 *this = std::move(Other); 169 } 170 171 /// Create an error value. Prefer using the 'make_error' function, but 172 /// this constructor can be useful when "re-throwing" errors from handlers. 173 Error(std::unique_ptr<ErrorInfoBase> Payload) { 174 setPtr(Payload.release()); 175 setChecked(false); 176 } 177 178 // Errors are not copy-assignable. 179 Error &operator=(const Error &Other) = delete; 180 181 /// Move-assign an error value. The current error must represent success, you 182 /// you cannot overwrite an unhandled error. The current error is then 183 /// considered unchecked. The source error becomes a checked success value, 184 /// regardless of its original state. 185 Error &operator=(Error &&Other) { 186 // Don't allow overwriting of unchecked values. 187 assertIsChecked(); 188 setPtr(Other.getPtr()); 189 190 // This Error is unchecked, even if the source error was checked. 191 setChecked(false); 192 193 // Null out Other's payload and set its checked bit. 194 Other.setPtr(nullptr); 195 Other.setChecked(true); 196 197 return *this; 198 } 199 200 /// Destroy a Error. Fails with a call to abort() if the error is 201 /// unchecked. 202 ~Error() { 203 assertIsChecked(); 204 delete getPtr(); 205 } 206 207 /// Bool conversion. Returns true if this Error is in a failure state, 208 /// and false if it is in an accept state. If the error is in a Success state 209 /// it will be considered checked. 210 explicit operator bool() { 211 setChecked(getPtr() == nullptr); 212 return getPtr() != nullptr; 213 } 214 215 /// Check whether one error is a subclass of another. 216 template <typename ErrT> bool isA() const { 217 return getPtr() && getPtr()->isA(ErrT::classID()); 218 } 219 220private: 221 void assertIsChecked() { 222#ifndef NDEBUG 223 if (!getChecked() || getPtr()) { 224 dbgs() << "Program aborted due to an unhandled Error:\n"; 225 if (getPtr()) 226 getPtr()->log(dbgs()); 227 else 228 dbgs() 229 << "Error value was Success. (Note: Success values must still be " 230 "checked prior to being destroyed).\n"; 231 abort(); 232 } 233#endif 234 } 235 236 ErrorInfoBase *getPtr() const { 237#ifndef NDEBUG 238 return PayloadAndCheckedBit.getPointer(); 239#else 240 return Payload; 241#endif 242 } 243 244 void setPtr(ErrorInfoBase *EI) { 245#ifndef NDEBUG 246 PayloadAndCheckedBit.setPointer(EI); 247#else 248 Payload = EI; 249#endif 250 } 251 252 bool getChecked() const { 253#ifndef NDEBUG 254 return PayloadAndCheckedBit.getInt(); 255#else 256 return true; 257#endif 258 } 259 260 void setChecked(bool V) { 261#ifndef NDEBUG 262 PayloadAndCheckedBit.setInt(V); 263#endif 264 } 265 266 std::unique_ptr<ErrorInfoBase> takePayload() { 267 std::unique_ptr<ErrorInfoBase> Tmp(getPtr()); 268 setPtr(nullptr); 269 setChecked(true); 270 return Tmp; 271 } 272 273#ifndef NDEBUG 274 PointerIntPair<ErrorInfoBase *, 1> PayloadAndCheckedBit; 275#else 276 ErrorInfoBase *Payload; 277#endif 278}; 279 280/// Make a Error instance representing failure using the given error info 281/// type. 282template <typename ErrT, typename... ArgTs> Error make_error(ArgTs &&... Args) { 283 return Error(llvm::make_unique<ErrT>(std::forward<ArgTs>(Args)...)); 284} 285 286/// Base class for user error types. Users should declare their error types 287/// like: 288/// 289/// class MyError : public ErrorInfo<MyError> { 290/// .... 291/// }; 292/// 293/// This class provides an implementation of the ErrorInfoBase::kind 294/// method, which is used by the Error RTTI system. 295template <typename ThisErrT, typename ParentErrT = ErrorInfoBase> 296class ErrorInfo : public ParentErrT { 297public: 298 bool isA(const void *const ClassID) const override { 299 return ClassID == classID() || ParentErrT::isA(ClassID); 300 } 301 302 static const void *classID() { return &ThisErrT::ID; } 303}; 304 305/// Special ErrorInfo subclass representing a list of ErrorInfos. 306/// Instances of this class are constructed by joinError. 307class ErrorList final : public ErrorInfo<ErrorList> { 308 309 // handleErrors needs to be able to iterate the payload list of an 310 // ErrorList. 311 template <typename... HandlerTs> 312 friend Error handleErrors(Error E, HandlerTs &&... Handlers); 313 314 // joinErrors is implemented in terms of join. 315 friend Error joinErrors(Error, Error); 316 317public: 318 void log(raw_ostream &OS) const override { 319 OS << "Multiple errors:\n"; 320 for (auto &ErrPayload : Payloads) { 321 ErrPayload->log(OS); 322 OS << "\n"; 323 } 324 } 325 326 std::error_code convertToErrorCode() const override; 327 328 // Used by ErrorInfo::classID. 329 static char ID; 330 331private: 332 ErrorList(std::unique_ptr<ErrorInfoBase> Payload1, 333 std::unique_ptr<ErrorInfoBase> Payload2) { 334 assert(!Payload1->isA<ErrorList>() && !Payload2->isA<ErrorList>() && 335 "ErrorList constructor payloads should be singleton errors"); 336 Payloads.push_back(std::move(Payload1)); 337 Payloads.push_back(std::move(Payload2)); 338 } 339 340 static Error join(Error E1, Error E2) { 341 if (!E1) 342 return E2; 343 if (!E2) 344 return E1; 345 if (E1.isA<ErrorList>()) { 346 auto &E1List = static_cast<ErrorList &>(*E1.getPtr()); 347 if (E2.isA<ErrorList>()) { 348 auto E2Payload = E2.takePayload(); 349 auto &E2List = static_cast<ErrorList &>(*E2Payload); 350 for (auto &Payload : E2List.Payloads) 351 E1List.Payloads.push_back(std::move(Payload)); 352 } else 353 E1List.Payloads.push_back(E2.takePayload()); 354 355 return E1; 356 } 357 if (E2.isA<ErrorList>()) { 358 auto &E2List = static_cast<ErrorList &>(*E2.getPtr()); 359 E2List.Payloads.insert(E2List.Payloads.begin(), E1.takePayload()); 360 return E2; 361 } 362 return Error(std::unique_ptr<ErrorList>( 363 new ErrorList(E1.takePayload(), E2.takePayload()))); 364 } 365 366 std::vector<std::unique_ptr<ErrorInfoBase>> Payloads; 367}; 368 369/// Concatenate errors. The resulting Error is unchecked, and contains the 370/// ErrorInfo(s), if any, contained in E1, followed by the 371/// ErrorInfo(s), if any, contained in E2. 372inline Error joinErrors(Error E1, Error E2) { 373 return ErrorList::join(std::move(E1), std::move(E2)); 374} 375 376/// Helper for testing applicability of, and applying, handlers for 377/// ErrorInfo types. 378template <typename HandlerT> 379class ErrorHandlerTraits 380 : public ErrorHandlerTraits<decltype( 381 &std::remove_reference<HandlerT>::type::operator())> {}; 382 383// Specialization functions of the form 'Error (const ErrT&)'. 384template <typename ErrT> class ErrorHandlerTraits<Error (&)(ErrT &)> { 385public: 386 static bool appliesTo(const ErrorInfoBase &E) { 387 return E.template isA<ErrT>(); 388 } 389 390 template <typename HandlerT> 391 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 392 assert(appliesTo(*E) && "Applying incorrect handler"); 393 return H(static_cast<ErrT &>(*E)); 394 } 395}; 396 397// Specialization functions of the form 'void (const ErrT&)'. 398template <typename ErrT> class ErrorHandlerTraits<void (&)(ErrT &)> { 399public: 400 static bool appliesTo(const ErrorInfoBase &E) { 401 return E.template isA<ErrT>(); 402 } 403 404 template <typename HandlerT> 405 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 406 assert(appliesTo(*E) && "Applying incorrect handler"); 407 H(static_cast<ErrT &>(*E)); 408 return Error::success(); 409 } 410}; 411 412/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'. 413template <typename ErrT> 414class ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> { 415public: 416 static bool appliesTo(const ErrorInfoBase &E) { 417 return E.template isA<ErrT>(); 418 } 419 420 template <typename HandlerT> 421 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 422 assert(appliesTo(*E) && "Applying incorrect handler"); 423 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release())); 424 return H(std::move(SubE)); 425 } 426}; 427 428/// Specialization for functions of the form 'Error (std::unique_ptr<ErrT>)'. 429template <typename ErrT> 430class ErrorHandlerTraits<void (&)(std::unique_ptr<ErrT>)> { 431public: 432 static bool appliesTo(const ErrorInfoBase &E) { 433 return E.template isA<ErrT>(); 434 } 435 436 template <typename HandlerT> 437 static Error apply(HandlerT &&H, std::unique_ptr<ErrorInfoBase> E) { 438 assert(appliesTo(*E) && "Applying incorrect handler"); 439 std::unique_ptr<ErrT> SubE(static_cast<ErrT *>(E.release())); 440 H(std::move(SubE)); 441 return Error::success(); 442 } 443}; 444 445// Specialization for member functions of the form 'RetT (const ErrT&)'. 446template <typename C, typename RetT, typename ErrT> 447class ErrorHandlerTraits<RetT (C::*)(ErrT &)> 448 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 449 450// Specialization for member functions of the form 'RetT (const ErrT&) const'. 451template <typename C, typename RetT, typename ErrT> 452class ErrorHandlerTraits<RetT (C::*)(ErrT &) const> 453 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 454 455// Specialization for member functions of the form 'RetT (const ErrT&)'. 456template <typename C, typename RetT, typename ErrT> 457class ErrorHandlerTraits<RetT (C::*)(const ErrT &)> 458 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 459 460// Specialization for member functions of the form 'RetT (const ErrT&) const'. 461template <typename C, typename RetT, typename ErrT> 462class ErrorHandlerTraits<RetT (C::*)(const ErrT &) const> 463 : public ErrorHandlerTraits<RetT (&)(ErrT &)> {}; 464 465/// Specialization for member functions of the form 466/// 'RetT (std::unique_ptr<ErrT>) const'. 467template <typename C, typename RetT, typename ErrT> 468class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>)> 469 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {}; 470 471/// Specialization for member functions of the form 472/// 'RetT (std::unique_ptr<ErrT>) const'. 473template <typename C, typename RetT, typename ErrT> 474class ErrorHandlerTraits<RetT (C::*)(std::unique_ptr<ErrT>) const> 475 : public ErrorHandlerTraits<RetT (&)(std::unique_ptr<ErrT>)> {}; 476 477inline Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload) { 478 return Error(std::move(Payload)); 479} 480 481template <typename HandlerT, typename... HandlerTs> 482Error handleErrorImpl(std::unique_ptr<ErrorInfoBase> Payload, 483 HandlerT &&Handler, HandlerTs &&... Handlers) { 484 if (ErrorHandlerTraits<HandlerT>::appliesTo(*Payload)) 485 return ErrorHandlerTraits<HandlerT>::apply(std::forward<HandlerT>(Handler), 486 std::move(Payload)); 487 return handleErrorImpl(std::move(Payload), 488 std::forward<HandlerTs>(Handlers)...); 489} 490 491/// Pass the ErrorInfo(s) contained in E to their respective handlers. Any 492/// unhandled errors (or Errors returned by handlers) are re-concatenated and 493/// returned. 494/// Because this function returns an error, its result must also be checked 495/// or returned. If you intend to handle all errors use handleAllErrors 496/// (which returns void, and will abort() on unhandled errors) instead. 497template <typename... HandlerTs> 498Error handleErrors(Error E, HandlerTs &&... Hs) { 499 if (!E) 500 return Error::success(); 501 502 std::unique_ptr<ErrorInfoBase> Payload = E.takePayload(); 503 504 if (Payload->isA<ErrorList>()) { 505 ErrorList &List = static_cast<ErrorList &>(*Payload); 506 Error R; 507 for (auto &P : List.Payloads) 508 R = ErrorList::join( 509 std::move(R), 510 handleErrorImpl(std::move(P), std::forward<HandlerTs>(Hs)...)); 511 return R; 512 } 513 514 return handleErrorImpl(std::move(Payload), std::forward<HandlerTs>(Hs)...); 515} 516 517/// Behaves the same as handleErrors, except that it requires that all 518/// errors be handled by the given handlers. If any unhandled error remains 519/// after the handlers have run, abort() will be called. 520template <typename... HandlerTs> 521void handleAllErrors(Error E, HandlerTs &&... Handlers) { 522 auto F = handleErrors(std::move(E), std::forward<HandlerTs>(Handlers)...); 523 // Cast 'F' to bool to set the 'Checked' flag if it's a success value: 524 (void)!F; 525} 526 527/// Check that E is a non-error, then drop it. 528inline void handleAllErrors(Error E) { 529 // Cast 'E' to a bool to set the 'Checked' flag if it's a success value: 530 (void)!E; 531} 532 533/// Log all errors (if any) in E to OS. If there are any errors, ErrorBanner 534/// will be printed before the first one is logged. A newline will be printed 535/// after each error. 536/// 537/// This is useful in the base level of your program to allow clean termination 538/// (allowing clean deallocation of resources, etc.), while reporting error 539/// information to the user. 540void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner); 541 542/// Write all error messages (if any) in E to a string. The newline character 543/// is used to separate error messages. 544inline std::string toString(Error E) { 545 SmallVector<std::string, 2> Errors; 546 handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) { 547 Errors.push_back(EI.message()); 548 }); 549 return join(Errors.begin(), Errors.end(), "\n"); 550} 551 552/// Consume a Error without doing anything. This method should be used 553/// only where an error can be considered a reasonable and expected return 554/// value. 555/// 556/// Uses of this method are potentially indicative of design problems: If it's 557/// legitimate to do nothing while processing an "error", the error-producer 558/// might be more clearly refactored to return an Optional<T>. 559inline void consumeError(Error Err) { 560 handleAllErrors(std::move(Err), [](const ErrorInfoBase &) {}); 561} 562 563/// Helper for Errors used as out-parameters. 564/// 565/// This helper is for use with the Error-as-out-parameter idiom, where an error 566/// is passed to a function or method by reference, rather than being returned. 567/// In such cases it is helpful to set the checked bit on entry to the function 568/// so that the error can be written to (unchecked Errors abort on assignment) 569/// and clear the checked bit on exit so that clients cannot accidentally forget 570/// to check the result. This helper performs these actions automatically using 571/// RAII: 572/// 573/// Result foo(Error &Err) { 574/// ErrorAsOutParameter ErrAsOutParam(Err); // 'Checked' flag set 575/// // <body of foo> 576/// // <- 'Checked' flag auto-cleared when ErrAsOutParam is destructed. 577/// } 578class ErrorAsOutParameter { 579public: 580 ErrorAsOutParameter(Error &Err) : Err(Err) { 581 // Raise the checked bit if Err is success. 582 (void)!!Err; 583 } 584 ~ErrorAsOutParameter() { 585 // Clear the checked bit. 586 if (!Err) 587 Err = Error::success(); 588 } 589 590private: 591 Error &Err; 592}; 593 594/// Tagged union holding either a T or a Error. 595/// 596/// This class parallels ErrorOr, but replaces error_code with Error. Since 597/// Error cannot be copied, this class replaces getError() with 598/// takeError(). It also adds an bool errorIsA<ErrT>() method for testing the 599/// error class type. 600template <class T> class Expected { 601 template <class OtherT> friend class Expected; 602 static const bool isRef = std::is_reference<T>::value; 603 typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap; 604 605 typedef std::unique_ptr<ErrorInfoBase> error_type; 606 607public: 608 typedef typename std::conditional<isRef, wrap, T>::type storage_type; 609 typedef T value_type; 610 611private: 612 typedef typename std::remove_reference<T>::type &reference; 613 typedef const typename std::remove_reference<T>::type &const_reference; 614 typedef typename std::remove_reference<T>::type *pointer; 615 typedef const typename std::remove_reference<T>::type *const_pointer; 616 617public: 618 /// Create an Expected<T> error value from the given Error. 619 Expected(Error Err) 620 : HasError(true) 621#ifndef NDEBUG 622 , 623 Checked(false) 624#endif 625 { 626 assert(Err && "Cannot create Expected<T> from Error success value."); 627 new (getErrorStorage()) Error(std::move(Err)); 628 } 629 630 /// Create an Expected<T> success value from the given OtherT value, which 631 /// must be convertible to T. 632 template <typename OtherT> 633 Expected(OtherT &&Val, 634 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type 635 * = nullptr) 636 : HasError(false) 637#ifndef NDEBUG 638 , 639 Checked(false) 640#endif 641 { 642 new (getStorage()) storage_type(std::forward<OtherT>(Val)); 643 } 644 645 /// Move construct an Expected<T> value. 646 Expected(Expected &&Other) { moveConstruct(std::move(Other)); } 647 648 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT 649 /// must be convertible to T. 650 template <class OtherT> 651 Expected(Expected<OtherT> &&Other, 652 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type 653 * = nullptr) { 654 moveConstruct(std::move(Other)); 655 } 656 657 /// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT 658 /// isn't convertible to T. 659 template <class OtherT> 660 explicit Expected( 661 Expected<OtherT> &&Other, 662 typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * = 663 nullptr) { 664 moveConstruct(std::move(Other)); 665 } 666 667 /// Move-assign from another Expected<T>. 668 Expected &operator=(Expected &&Other) { 669 moveAssign(std::move(Other)); 670 return *this; 671 } 672 673 /// Destroy an Expected<T>. 674 ~Expected() { 675 assertIsChecked(); 676 if (!HasError) 677 getStorage()->~storage_type(); 678 else 679 getErrorStorage()->~error_type(); 680 } 681 682 /// \brief Return false if there is an error. 683 explicit operator bool() { 684#ifndef NDEBUG 685 Checked = !HasError; 686#endif 687 return !HasError; 688 } 689 690 /// \brief Returns a reference to the stored T value. 691 reference get() { 692 assertIsChecked(); 693 return *getStorage(); 694 } 695 696 /// \brief Returns a const reference to the stored T value. 697 const_reference get() const { 698 assertIsChecked(); 699 return const_cast<Expected<T> *>(this)->get(); 700 } 701 702 /// \brief Check that this Expected<T> is an error of type ErrT. 703 template <typename ErrT> bool errorIsA() const { 704 return HasError && getErrorStorage()->template isA<ErrT>(); 705 } 706 707 /// \brief Take ownership of the stored error. 708 /// After calling this the Expected<T> is in an indeterminate state that can 709 /// only be safely destructed. No further calls (beside the destructor) should 710 /// be made on the Expected<T> vaule. 711 Error takeError() { 712#ifndef NDEBUG 713 Checked = true; 714#endif 715 return HasError ? Error(std::move(*getErrorStorage())) : Error::success(); 716 } 717 718 /// \brief Returns a pointer to the stored T value. 719 pointer operator->() { 720 assertIsChecked(); 721 return toPointer(getStorage()); 722 } 723 724 /// \brief Returns a const pointer to the stored T value. 725 const_pointer operator->() const { 726 assertIsChecked(); 727 return toPointer(getStorage()); 728 } 729 730 /// \brief Returns a reference to the stored T value. 731 reference operator*() { 732 assertIsChecked(); 733 return *getStorage(); 734 } 735 736 /// \brief Returns a const reference to the stored T value. 737 const_reference operator*() const { 738 assertIsChecked(); 739 return *getStorage(); 740 } 741 742private: 743 template <class T1> 744 static bool compareThisIfSameType(const T1 &a, const T1 &b) { 745 return &a == &b; 746 } 747 748 template <class T1, class T2> 749 static bool compareThisIfSameType(const T1 &a, const T2 &b) { 750 return false; 751 } 752 753 template <class OtherT> void moveConstruct(Expected<OtherT> &&Other) { 754 HasError = Other.HasError; 755 756#ifndef NDEBUG 757 Checked = false; 758 Other.Checked = true; 759#endif 760 761 if (!HasError) 762 new (getStorage()) storage_type(std::move(*Other.getStorage())); 763 else 764 new (getErrorStorage()) error_type(std::move(*Other.getErrorStorage())); 765 } 766 767 template <class OtherT> void moveAssign(Expected<OtherT> &&Other) { 768 assertIsChecked(); 769 770 if (compareThisIfSameType(*this, Other)) 771 return; 772 773 this->~Expected(); 774 new (this) Expected(std::move(Other)); 775 } 776 777 pointer toPointer(pointer Val) { return Val; } 778 779 const_pointer toPointer(const_pointer Val) const { return Val; } 780 781 pointer toPointer(wrap *Val) { return &Val->get(); } 782 783 const_pointer toPointer(const wrap *Val) const { return &Val->get(); } 784 785 storage_type *getStorage() { 786 assert(!HasError && "Cannot get value when an error exists!"); 787 return reinterpret_cast<storage_type *>(TStorage.buffer); 788 } 789 790 const storage_type *getStorage() const { 791 assert(!HasError && "Cannot get value when an error exists!"); 792 return reinterpret_cast<const storage_type *>(TStorage.buffer); 793 } 794 795 error_type *getErrorStorage() { 796 assert(HasError && "Cannot get error when a value exists!"); 797 return reinterpret_cast<error_type *>(ErrorStorage.buffer); 798 } 799 800 void assertIsChecked() { 801#ifndef NDEBUG 802 if (!Checked) { 803 dbgs() << "Expected<T> must be checked before access or destruction.\n"; 804 if (HasError) { 805 dbgs() << "Unchecked Expected<T> contained error:\n"; 806 (*getErrorStorage())->log(dbgs()); 807 } else 808 dbgs() << "Expected<T> value was in success state. (Note: Expected<T> " 809 "values in success mode must still be checked prior to being " 810 "destroyed).\n"; 811 abort(); 812 } 813#endif 814 } 815 816 union { 817 AlignedCharArrayUnion<storage_type> TStorage; 818 AlignedCharArrayUnion<error_type> ErrorStorage; 819 }; 820 bool HasError : 1; 821#ifndef NDEBUG 822 bool Checked : 1; 823#endif 824}; 825 826/// This class wraps a std::error_code in a Error. 827/// 828/// This is useful if you're writing an interface that returns a Error 829/// (or Expected) and you want to call code that still returns 830/// std::error_codes. 831class ECError : public ErrorInfo<ECError> { 832 friend Error errorCodeToError(std::error_code); 833public: 834 void setErrorCode(std::error_code EC) { this->EC = EC; } 835 std::error_code convertToErrorCode() const override { return EC; } 836 void log(raw_ostream &OS) const override { OS << EC.message(); } 837 838 // Used by ErrorInfo::classID. 839 static char ID; 840 841protected: 842 ECError() = default; 843 ECError(std::error_code EC) : EC(EC) {} 844 std::error_code EC; 845}; 846 847/// The value returned by this function can be returned from convertToErrorCode 848/// for Error values where no sensible translation to std::error_code exists. 849/// It should only be used in this situation, and should never be used where a 850/// sensible conversion to std::error_code is available, as attempts to convert 851/// to/from this error will result in a fatal error. (i.e. it is a programmatic 852///error to try to convert such a value). 853std::error_code inconvertibleErrorCode(); 854 855/// Helper for converting an std::error_code to a Error. 856Error errorCodeToError(std::error_code EC); 857 858/// Helper for converting an ECError to a std::error_code. 859/// 860/// This method requires that Err be Error() or an ECError, otherwise it 861/// will trigger a call to abort(). 862std::error_code errorToErrorCode(Error Err); 863 864/// Convert an ErrorOr<T> to an Expected<T>. 865template <typename T> Expected<T> errorOrToExpected(ErrorOr<T> &&EO) { 866 if (auto EC = EO.getError()) 867 return errorCodeToError(EC); 868 return std::move(*EO); 869} 870 871/// Convert an Expected<T> to an ErrorOr<T>. 872template <typename T> ErrorOr<T> expectedToErrorOr(Expected<T> &&E) { 873 if (auto Err = E.takeError()) 874 return errorToErrorCode(std::move(Err)); 875 return std::move(*E); 876} 877 878/// This class wraps a string in an Error. 879/// 880/// StringError is useful in cases where the client is not expected to be able 881/// to consume the specific error message programmatically (for example, if the 882/// error message is to be presented to the user). 883class StringError : public ErrorInfo<StringError> { 884public: 885 static char ID; 886 StringError(const Twine &S, std::error_code EC); 887 void log(raw_ostream &OS) const override; 888 std::error_code convertToErrorCode() const override; 889private: 890 std::string Msg; 891 std::error_code EC; 892}; 893 894/// Helper for check-and-exit error handling. 895/// 896/// For tool use only. NOT FOR USE IN LIBRARY CODE. 897/// 898class ExitOnError { 899public: 900 /// Create an error on exit helper. 901 ExitOnError(std::string Banner = "", int DefaultErrorExitCode = 1) 902 : Banner(std::move(Banner)), 903 GetExitCode([=](const Error &) { return DefaultErrorExitCode; }) {} 904 905 /// Set the banner string for any errors caught by operator(). 906 void setBanner(std::string Banner) { this->Banner = std::move(Banner); } 907 908 /// Set the exit-code mapper function. 909 void setExitCodeMapper(std::function<int(const Error &)> GetExitCode) { 910 this->GetExitCode = std::move(GetExitCode); 911 } 912 913 /// Check Err. If it's in a failure state log the error(s) and exit. 914 void operator()(Error Err) const { checkError(std::move(Err)); } 915 916 /// Check E. If it's in a success state then return the contained value. If 917 /// it's in a failure state log the error(s) and exit. 918 template <typename T> T operator()(Expected<T> &&E) const { 919 checkError(E.takeError()); 920 return std::move(*E); 921 } 922 923 /// Check E. If it's in a success state then return the contained reference. If 924 /// it's in a failure state log the error(s) and exit. 925 template <typename T> T& operator()(Expected<T&> &&E) const { 926 checkError(E.takeError()); 927 return *E; 928 } 929 930private: 931 void checkError(Error Err) const { 932 if (Err) { 933 int ExitCode = GetExitCode(Err); 934 logAllUnhandledErrors(std::move(Err), errs(), Banner); 935 exit(ExitCode); 936 } 937 } 938 939 std::string Banner; 940 std::function<int(const Error &)> GetExitCode; 941}; 942 943/// Report a serious error, calling any installed error handler. See 944/// ErrorHandling.h. 945LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, 946 bool gen_crash_diag = true); 947 948} // namespace llvm 949 950#endif // LLVM_SUPPORT_ERROR_H 951