13e519524SHoward Hinnant// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 33e519524SHoward Hinnant// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 73e519524SHoward Hinnant// 83e519524SHoward Hinnant//===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 103e519524SHoward Hinnant#ifndef _LIBCPP_EXCEPTION 113e519524SHoward Hinnant#define _LIBCPP_EXCEPTION 123e519524SHoward Hinnant 133e519524SHoward Hinnant/* 143e519524SHoward Hinnant exception synopsis 153e519524SHoward Hinnant 163e519524SHoward Hinnantnamespace std 173e519524SHoward Hinnant{ 183e519524SHoward Hinnant 193e519524SHoward Hinnantclass exception 203e519524SHoward Hinnant{ 213e519524SHoward Hinnantpublic: 22fafca58cSHoward Hinnant exception() noexcept; 23fafca58cSHoward Hinnant exception(const exception&) noexcept; 24fafca58cSHoward Hinnant exception& operator=(const exception&) noexcept; 25fafca58cSHoward Hinnant virtual ~exception() noexcept; 26fafca58cSHoward Hinnant virtual const char* what() const noexcept; 273e519524SHoward Hinnant}; 283e519524SHoward Hinnant 293e519524SHoward Hinnantclass bad_exception 303e519524SHoward Hinnant : public exception 313e519524SHoward Hinnant{ 323e519524SHoward Hinnantpublic: 33fafca58cSHoward Hinnant bad_exception() noexcept; 34fafca58cSHoward Hinnant bad_exception(const bad_exception&) noexcept; 35fafca58cSHoward Hinnant bad_exception& operator=(const bad_exception&) noexcept; 36fafca58cSHoward Hinnant virtual ~bad_exception() noexcept; 37fafca58cSHoward Hinnant virtual const char* what() const noexcept; 383e519524SHoward Hinnant}; 393e519524SHoward Hinnant 403e519524SHoward Hinnanttypedef void (*unexpected_handler)(); 41fafca58cSHoward Hinnantunexpected_handler set_unexpected(unexpected_handler f ) noexcept; 42fafca58cSHoward Hinnantunexpected_handler get_unexpected() noexcept; 43fafca58cSHoward Hinnant[[noreturn]] void unexpected(); 443e519524SHoward Hinnant 453e519524SHoward Hinnanttypedef void (*terminate_handler)(); 46fafca58cSHoward Hinnantterminate_handler set_terminate(terminate_handler f ) noexcept; 47fafca58cSHoward Hinnantterminate_handler get_terminate() noexcept; 48fafca58cSHoward Hinnant[[noreturn]] void terminate() noexcept; 493e519524SHoward Hinnant 50fafca58cSHoward Hinnantbool uncaught_exception() noexcept; 5189102f0fSMarshall Clowint uncaught_exceptions() noexcept; // C++17 523e519524SHoward Hinnant 533e519524SHoward Hinnanttypedef unspecified exception_ptr; 543e519524SHoward Hinnant 55fafca58cSHoward Hinnantexception_ptr current_exception() noexcept; 563e519524SHoward Hinnantvoid rethrow_exception [[noreturn]] (exception_ptr p); 57fafca58cSHoward Hinnanttemplate<class E> exception_ptr make_exception_ptr(E e) noexcept; 583e519524SHoward Hinnant 593e519524SHoward Hinnantclass nested_exception 603e519524SHoward Hinnant{ 613e519524SHoward Hinnantpublic: 62fafca58cSHoward Hinnant nested_exception() noexcept; 63fafca58cSHoward Hinnant nested_exception(const nested_exception&) noexcept = default; 64fafca58cSHoward Hinnant nested_exception& operator=(const nested_exception&) noexcept = default; 653e519524SHoward Hinnant virtual ~nested_exception() = default; 663e519524SHoward Hinnant 673e519524SHoward Hinnant // access functions 68fafca58cSHoward Hinnant [[noreturn]] void rethrow_nested() const; 69fafca58cSHoward Hinnant exception_ptr nested_ptr() const noexcept; 703e519524SHoward Hinnant}; 713e519524SHoward Hinnant 72fafca58cSHoward Hinnanttemplate <class T> [[noreturn]] void throw_with_nested(T&& t); 733e519524SHoward Hinnanttemplate <class E> void rethrow_if_nested(const E& e); 743e519524SHoward Hinnant 753e519524SHoward Hinnant} // std 763e519524SHoward Hinnant 773e519524SHoward Hinnant*/ 783e519524SHoward Hinnant 79385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 802eadbc86SLouis Dionne#include <__availability> 81bfbd73f8SArthur O'Dwyer#include <__config> 82f992cfbaSLouis Dionne#include <__memory/addressof.h> 833e519524SHoward Hinnant#include <cstddef> 84613dc646SEric Fiselier#include <cstdlib> 85019fe4b8SHoward Hinnant#include <type_traits> 86f56972e2SMarshall Clow#include <version> 873e519524SHoward Hinnant 88e69290dcSEric Fiselier#if defined(_LIBCPP_ABI_VCRUNTIME) 89d22c9dc4SEric Fiselier#include <vcruntime_exception.h> 90d22c9dc4SEric Fiselier#endif 91d22c9dc4SEric Fiselier 92073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 933e519524SHoward Hinnant# pragma GCC system_header 94073458b1SHoward Hinnant#endif 953e519524SHoward Hinnant 963e519524SHoward Hinnantnamespace std // purposefully not using versioning namespace 973e519524SHoward Hinnant{ 983e519524SHoward Hinnant 99e69290dcSEric Fiselier#if !defined(_LIBCPP_ABI_VCRUNTIME) 1003e519524SHoward Hinnantclass _LIBCPP_EXCEPTION_ABI exception 1013e519524SHoward Hinnant{ 1023e519524SHoward Hinnantpublic: 103fafca58cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} 104585a3cc3SDimitry Andric _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default; 105585a3cc3SDimitry Andric 106fafca58cSHoward Hinnant virtual ~exception() _NOEXCEPT; 107fafca58cSHoward Hinnant virtual const char* what() const _NOEXCEPT; 1083e519524SHoward Hinnant}; 1093e519524SHoward Hinnant 1103e519524SHoward Hinnantclass _LIBCPP_EXCEPTION_ABI bad_exception 1113e519524SHoward Hinnant : public exception 1123e519524SHoward Hinnant{ 1133e519524SHoward Hinnantpublic: 114fafca58cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} 115fafca58cSHoward Hinnant virtual ~bad_exception() _NOEXCEPT; 116fafca58cSHoward Hinnant virtual const char* what() const _NOEXCEPT; 1173e519524SHoward Hinnant}; 118e69290dcSEric Fiselier#endif // !_LIBCPP_ABI_VCRUNTIME 1193e519524SHoward Hinnant 1202a1bfa98SEric Fiselier#if _LIBCPP_STD_VER <= 14 \ 1212a1bfa98SEric Fiselier || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \ 1222a1bfa98SEric Fiselier || defined(_LIBCPP_BUILDING_LIBRARY) 1233e519524SHoward Hinnanttypedef void (*unexpected_handler)(); 1246e41256fSHoward Hinnant_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; 1256e41256fSHoward Hinnant_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; 1266e41256fSHoward Hinnant_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); 1272a1bfa98SEric Fiselier#endif 1283e519524SHoward Hinnant 1293e519524SHoward Hinnanttypedef void (*terminate_handler)(); 1306e41256fSHoward Hinnant_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; 1316e41256fSHoward Hinnant_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; 1326e41256fSHoward Hinnant_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; 1333e519524SHoward Hinnant 1346e41256fSHoward Hinnant_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; 135e9c66ad9SMehdi Amini_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT; 1363e519524SHoward Hinnant 1376e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS exception_ptr; 1383e519524SHoward Hinnant 139f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 140f0544c20SHoward Hinnant_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 1413e519524SHoward Hinnant 1423e254a6eSEric Fiselier#ifndef _LIBCPP_ABI_MICROSOFT 1433e254a6eSEric Fiselier 1446e41256fSHoward Hinnantclass _LIBCPP_TYPE_VIS exception_ptr 1453e519524SHoward Hinnant{ 1463e519524SHoward Hinnant void* __ptr_; 1473e519524SHoward Hinnantpublic: 148fafca58cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} 149fafca58cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} 1503e254a6eSEric Fiselier 151fafca58cSHoward Hinnant exception_ptr(const exception_ptr&) _NOEXCEPT; 152fafca58cSHoward Hinnant exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; 153fafca58cSHoward Hinnant ~exception_ptr() _NOEXCEPT; 1543e519524SHoward Hinnant 155317e92a3SArthur O'Dwyer _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT 1563e254a6eSEric Fiselier {return __ptr_ != nullptr;} 1573e519524SHoward Hinnant 158fb100021SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 159fafca58cSHoward Hinnant bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 1603e519524SHoward Hinnant {return __x.__ptr_ == __y.__ptr_;} 1613e254a6eSEric Fiselier 162fb100021SHoward Hinnant friend _LIBCPP_INLINE_VISIBILITY 163fafca58cSHoward Hinnant bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 1643e519524SHoward Hinnant {return !(__x == __y);} 1653e519524SHoward Hinnant 166f0544c20SHoward Hinnant friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 167f0544c20SHoward Hinnant friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 1683e519524SHoward Hinnant}; 1693e519524SHoward Hinnant 170c003db1fSHoward Hinnanttemplate<class _Ep> 171352adb65SLouis Dionne_LIBCPP_INLINE_VISIBILITY exception_ptr 172c003db1fSHoward Hinnantmake_exception_ptr(_Ep __e) _NOEXCEPT 1733e519524SHoward Hinnant{ 17454b409fdSHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 1753e519524SHoward Hinnant try 1763e519524SHoward Hinnant { 1773e519524SHoward Hinnant throw __e; 1783e519524SHoward Hinnant } 1793e519524SHoward Hinnant catch (...) 1803e519524SHoward Hinnant { 1813e519524SHoward Hinnant return current_exception(); 1823e519524SHoward Hinnant } 183613dc646SEric Fiselier#else 184fd838227SEric Fiselier ((void)__e); 185613dc646SEric Fiselier _VSTD::abort(); 186613dc646SEric Fiselier#endif 1873e519524SHoward Hinnant} 1883e519524SHoward Hinnant 1893e254a6eSEric Fiselier#else // _LIBCPP_ABI_MICROSOFT 1903e254a6eSEric Fiselier 1913e254a6eSEric Fiselierclass _LIBCPP_TYPE_VIS exception_ptr 1923e254a6eSEric Fiselier{ 193a7c2a628SNikolas Klauser_LIBCPP_DIAGNOSTIC_PUSH 194a7c2a628SNikolas Klauser_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field") 1953e254a6eSEric Fiselier void* __ptr1_; 1963e254a6eSEric Fiselier void* __ptr2_; 197a7c2a628SNikolas Klauser_LIBCPP_DIAGNOSTIC_POP 1983e254a6eSEric Fiselierpublic: 1993e254a6eSEric Fiselier exception_ptr() _NOEXCEPT; 2003e254a6eSEric Fiselier exception_ptr(nullptr_t) _NOEXCEPT; 2013e254a6eSEric Fiselier exception_ptr(const exception_ptr& __other) _NOEXCEPT; 2023e254a6eSEric Fiselier exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT; 2033e254a6eSEric Fiselier exception_ptr& operator=(nullptr_t) _NOEXCEPT; 2043e254a6eSEric Fiselier ~exception_ptr() _NOEXCEPT; 205317e92a3SArthur O'Dwyer explicit operator bool() const _NOEXCEPT; 2063e254a6eSEric Fiselier}; 2073e254a6eSEric Fiselier 2083e254a6eSEric Fiselier_LIBCPP_FUNC_VIS 2093e254a6eSEric Fiselierbool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; 2103e254a6eSEric Fiselier 2113e254a6eSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY 2123e254a6eSEric Fiselierbool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT 2133e254a6eSEric Fiselier {return !(__x == __y);} 2143e254a6eSEric Fiselier 2153e254a6eSEric Fiselier_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; 2163e254a6eSEric Fiselier 2173e254a6eSEric Fiselier_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr); 2183e254a6eSEric Fiselier_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; 219*b48c5010SNikolas Klauser_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); 2203e254a6eSEric Fiselier 2213e254a6eSEric Fiselier// This is a built-in template function which automagically extracts the required 2223e254a6eSEric Fiselier// information. 2233e254a6eSEric Fiseliertemplate <class _E> void *__GetExceptionInfo(_E); 2243e254a6eSEric Fiselier 2253e254a6eSEric Fiseliertemplate<class _Ep> 226352adb65SLouis Dionne_LIBCPP_INLINE_VISIBILITY exception_ptr 2273e254a6eSEric Fiseliermake_exception_ptr(_Ep __e) _NOEXCEPT 2283e254a6eSEric Fiselier{ 2293e254a6eSEric Fiselier return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e)); 2303e254a6eSEric Fiselier} 2313e254a6eSEric Fiselier 2323e254a6eSEric Fiselier#endif // _LIBCPP_ABI_MICROSOFT 233019fe4b8SHoward Hinnant// nested_exception 234019fe4b8SHoward Hinnant 235019fe4b8SHoward Hinnantclass _LIBCPP_EXCEPTION_ABI nested_exception 236019fe4b8SHoward Hinnant{ 237019fe4b8SHoward Hinnant exception_ptr __ptr_; 238019fe4b8SHoward Hinnantpublic: 239fafca58cSHoward Hinnant nested_exception() _NOEXCEPT; 240fafca58cSHoward Hinnant// nested_exception(const nested_exception&) noexcept = default; 241fafca58cSHoward Hinnant// nested_exception& operator=(const nested_exception&) noexcept = default; 242fafca58cSHoward Hinnant virtual ~nested_exception() _NOEXCEPT; 243019fe4b8SHoward Hinnant 244019fe4b8SHoward Hinnant // access functions 245535a86c3SRichard Smith _LIBCPP_NORETURN void rethrow_nested() const; 246fafca58cSHoward Hinnant _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} 247019fe4b8SHoward Hinnant}; 248019fe4b8SHoward Hinnant 249019fe4b8SHoward Hinnanttemplate <class _Tp> 250019fe4b8SHoward Hinnantstruct __nested 251019fe4b8SHoward Hinnant : public _Tp, 252019fe4b8SHoward Hinnant public nested_exception 253019fe4b8SHoward Hinnant{ 254fb100021SHoward Hinnant _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} 255019fe4b8SHoward Hinnant}; 256019fe4b8SHoward Hinnant 257e9ca2bb8SMarshall Clow#ifndef _LIBCPP_NO_EXCEPTIONS 258e9ca2bb8SMarshall Clowtemplate <class _Tp, class _Up, bool> 259e9ca2bb8SMarshall Clowstruct __throw_with_nested; 260e9ca2bb8SMarshall Clow 261e9ca2bb8SMarshall Clowtemplate <class _Tp, class _Up> 262e9ca2bb8SMarshall Clowstruct __throw_with_nested<_Tp, _Up, true> { 263dc7200b4SLouis Dionne _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void 264e9ca2bb8SMarshall Clow __do_throw(_Tp&& __t) 265019fe4b8SHoward Hinnant { 2666adbc83eSChristopher Di Bella throw __nested<_Up>(static_cast<_Tp&&>(__t)); 267019fe4b8SHoward Hinnant } 268e9ca2bb8SMarshall Clow}; 269e9ca2bb8SMarshall Clow 270e9ca2bb8SMarshall Clowtemplate <class _Tp, class _Up> 271e9ca2bb8SMarshall Clowstruct __throw_with_nested<_Tp, _Up, false> { 272dc7200b4SLouis Dionne _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void 2736ded58e2SEric Fiselier#ifndef _LIBCPP_CXX03_LANG 274e9ca2bb8SMarshall Clow __do_throw(_Tp&& __t) 275e9ca2bb8SMarshall Clow#else 276e9ca2bb8SMarshall Clow __do_throw (_Tp& __t) 2776ded58e2SEric Fiselier#endif // _LIBCPP_CXX03_LANG 278e9ca2bb8SMarshall Clow { 2796adbc83eSChristopher Di Bella throw static_cast<_Tp&&>(__t); 280e9ca2bb8SMarshall Clow } 281e9ca2bb8SMarshall Clow}; 282e9ca2bb8SMarshall Clow#endif 283019fe4b8SHoward Hinnant 284019fe4b8SHoward Hinnanttemplate <class _Tp> 285535a86c3SRichard Smith_LIBCPP_NORETURN 286019fe4b8SHoward Hinnantvoid 287e9ca2bb8SMarshall Clowthrow_with_nested(_Tp&& __t) 288019fe4b8SHoward Hinnant{ 28954b409fdSHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS 2905948e392SMarshall Clow typedef typename decay<_Tp>::type _Up; 2915948e392SMarshall Clow static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible"); 292e9ca2bb8SMarshall Clow __throw_with_nested<_Tp, _Up, 293e9ca2bb8SMarshall Clow is_class<_Up>::value && 294e9ca2bb8SMarshall Clow !is_base_of<nested_exception, _Up>::value && 295e9ca2bb8SMarshall Clow !__libcpp_is_final<_Up>::value>:: 2966adbc83eSChristopher Di Bella __do_throw(static_cast<_Tp&&>(__t)); 297fd838227SEric Fiselier#else 298fd838227SEric Fiselier ((void)__t); 299fd838227SEric Fiselier // FIXME: Make this abort 30054b409fdSHoward Hinnant#endif 301019fe4b8SHoward Hinnant} 302019fe4b8SHoward Hinnant 30355cfe4c1SMarshall Clowtemplate <class _From, class _To> 304f900f702SLouis Dionnestruct __can_dynamic_cast : _BoolConstant< 30555cfe4c1SMarshall Clow is_polymorphic<_From>::value && 30655cfe4c1SMarshall Clow (!is_base_of<_To, _From>::value || 307f900f702SLouis Dionne is_convertible<const _From*, const _To*>::value)> {}; 30855cfe4c1SMarshall Clow 309c003db1fSHoward Hinnanttemplate <class _Ep> 310fb100021SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 311019fe4b8SHoward Hinnantvoid 31255cfe4c1SMarshall Clowrethrow_if_nested(const _Ep& __e, 3134887d047SNikolas Klauser __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) 314019fe4b8SHoward Hinnant{ 31594b5bc42SMarshall Clow const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e)); 316a391bc13SHoward Hinnant if (__nep) 317a391bc13SHoward Hinnant __nep->rethrow_nested(); 318019fe4b8SHoward Hinnant} 319019fe4b8SHoward Hinnant 320c003db1fSHoward Hinnanttemplate <class _Ep> 321fb100021SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 322019fe4b8SHoward Hinnantvoid 32355cfe4c1SMarshall Clowrethrow_if_nested(const _Ep&, 3244887d047SNikolas Klauser __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) 325019fe4b8SHoward Hinnant{ 326019fe4b8SHoward Hinnant} 327019fe4b8SHoward Hinnant 328d2b0df35SNikolas Klauser} // namespace std 3293e519524SHoward Hinnant 3303e519524SHoward Hinnant#endif // _LIBCPP_EXCEPTION 331