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