1804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik//===------------------------ exception.cpp -------------------------------===//
2804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik//
3804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik//                     The LLVM Compiler Infrastructure
4804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik//
5b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6b64f8b07c104c6cc986570ac8ee0ed16a9f23976Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik//
8804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik//===----------------------------------------------------------------------===//
9804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik#include <stdlib.h>
10ed14a76beba8f2a0e30f5c66d327d60f87a75921Howard Hinnant#include <stdio.h>
11804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
12804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik#include "exception"
13ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#include "new"
14804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
15591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith#ifndef __has_include
16591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith#define __has_include(inc) 0
17591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith#endif
18591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith
197112dae6acac544a0271a85d95342c583441e2d1Dan Albert#if defined(__APPLE__) && !defined(LIBCXXRT)
20804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik  #include <cxxabi.h>
21dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant
22804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik  using namespace __cxxabiv1;
23c512df1950baf9466843b2943855356c031fec08David Chisnall  #define HAVE_DEPENDENT_EH_ABI 1
24dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant  #ifndef _LIBCPPABI_VERSION
25dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant    using namespace __cxxabiapple;
26dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant    // On Darwin, there are two STL shared libraries and a lower level ABI
27a46a0ad9e516eefff7d2240dd652bdcbe60645c7Marshall Clow    // shared library.  The globals holding the current terminate handler and
28dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant    // current unexpected handler are in the ABI library.
29dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant    #define __terminate_handler  __cxxabiapple::__cxa_terminate_handler
30dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant    #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler
31dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant  #endif  // _LIBCPPABI_VERSION
32591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith#elif defined(LIBCXXRT) || __has_include(<cxxabi.h>)
33c512df1950baf9466843b2943855356c031fec08David Chisnall  #include <cxxabi.h>
34c512df1950baf9466843b2943855356c031fec08David Chisnall  using namespace __cxxabiv1;
35591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith  #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION)
36591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith    #define HAVE_DEPENDENT_EH_ABI 1
37591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith  #endif
38e0f0bfb5e6348e9d912809cd882c4076bd738fa8Howard Hinnant#elif !defined(__GLIBCXX__) // __has_include(<cxxabi.h>)
39804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik  static std::terminate_handler  __terminate_handler;
40804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik  static std::unexpected_handler __unexpected_handler;
41591e32d624295ff8a8a33bcfa4e82ca33980be42Richard Smith#endif // __has_include(<cxxabi.h>)
42804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
431e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallnamespace std
441e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall{
451e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall
46a358fbe504cec211a5742d9c984aed9b25f9ff4aMichael J. Spencer#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
47dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant
48c512df1950baf9466843b2943855356c031fec08David Chisnall// libcxxrt provides implementations of these functions itself.
491e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallunexpected_handler
501e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallset_unexpected(unexpected_handler func) _NOEXCEPT
51804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
52a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant    return __sync_lock_test_and_set(&__unexpected_handler, func);
53a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant}
54a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant
551e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallunexpected_handler
561e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallget_unexpected() _NOEXCEPT
57a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant{
581e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall    return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0);
59804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
60804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
610405cc4ae0b74bab1f30830aa7bb03077b8280a6Richard Smith_LIBCPP_NORETURN
62804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzikvoid
631e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallunexpected()
64804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
651e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall    (*get_unexpected())();
66d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    // unexpected handler should not return
671e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall    terminate();
68804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
69804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
701e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallterminate_handler
711e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallset_terminate(terminate_handler func) _NOEXCEPT
72804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
73a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant    return __sync_lock_test_and_set(&__terminate_handler, func);
74a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant}
75a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant
761e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallterminate_handler
771e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallget_terminate() _NOEXCEPT
78a445151f4a1a9abf852cd7b84d6328687bb3294cHoward Hinnant{
791e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall    return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0);
80804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
81804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
822ccffefaffc4558adcfa64bec7dc71ade2235937Marshall Clow#ifndef __EMSCRIPTEN__ // We provide this in JS
830405cc4ae0b74bab1f30830aa7bb03077b8280a6Richard Smith_LIBCPP_NORETURN
84804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzikvoid
851e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallterminate() _NOEXCEPT
86804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
87d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
88d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant    try
89d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant    {
9016e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
911e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall        (*get_terminate())();
92804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik        // handler should not return
934a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne        printf("terminate_handler unexpectedly returned\n");
944a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne        ::abort();
95d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
9616e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant    }
97d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant    catch (...)
98d444470d6cd1cad554139c4ba7f3c4f3fe921a5dHoward Hinnant    {
99804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik        // handler should not throw exception
1004a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne        printf("terminate_handler unexpectedly threw an exception\n");
1014a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne        ::abort();
102804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik    }
10316e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
104804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
1052ccffefaffc4558adcfa64bec7dc71ade2235937Marshall Clow#endif // !__EMSCRIPTEN__
106dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION)
107804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
1082ccffefaffc4558adcfa64bec7dc71ade2235937Marshall Clow#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__)
1091e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallbool uncaught_exception() _NOEXCEPT
110804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
111dece7fe6706591d80e4694a986446f756611733cMarshall Clow#if defined(__APPLE__) || defined(_LIBCPPABI_VERSION)
112d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    // on Darwin, there is a helper function so __cxa_get_globals is private
113dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant    return __cxa_uncaught_exception();
114d0ed21e94ddbc12cbec3cea0aab89d470adfbd57Howard Hinnant#else  // __APPLE__
115f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   if defined(_MSC_VER) && ! defined(__clang__)
116f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant        _LIBCPP_WARNING("uncaught_exception not yet implemented")
117f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   else
118f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#       warning uncaught_exception not yet implemented
119f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   endif
1204a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    printf("uncaught_exception not yet implemented\n");
1214a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    ::abort();
12216e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant#endif  // __APPLE__
123804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
124804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
125f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant
126dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant#ifndef _LIBCPPABI_VERSION
127dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant
128ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantexception::~exception() _NOEXCEPT
12916e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant{
130804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
131804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
13221a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnallconst char* exception::what() const _NOEXCEPT
13316e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant{
13421a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnall  return "std::exception";
135804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
136804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
13721a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnall#endif  // _LIBCPPABI_VERSION
13821a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnall#endif //LIBCXXRT
139a358fbe504cec211a5742d9c984aed9b25f9ff4aMichael J. Spencer#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)
14021a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnall
14121a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnallbad_exception::~bad_exception() _NOEXCEPT
142804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
143804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
144804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
145ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantconst char* bad_exception::what() const _NOEXCEPT
146804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
147804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik  return "std::bad_exception";
148804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
149804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
15021a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnall#endif
15121a84cfb8fbbf6333baf8b59aa5c9a34aa5430abDavid Chisnall
152ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#if defined(__GLIBCXX__)
153ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
154ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// libsupc++ does not implement the dependent EH ABI and the functionality
155ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// it uses to implement std::exception_ptr (which it declares as an alias of
156ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// std::__exception_ptr::exception_ptr) is not directly exported to clients. So
157ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// we have little choice but to hijack std::__exception_ptr::exception_ptr's
158ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// (which fortunately has the same layout as our std::exception_ptr) copy
159ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// constructor, assignment operator and destructor (which are part of its
160ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr)
161ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne// function.
162ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
163ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbournenamespace __exception_ptr
164ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne{
165ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
166ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbournestruct exception_ptr
167ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne{
168ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    void* __ptr_;
169ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
170ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    exception_ptr(const exception_ptr&) _NOEXCEPT;
171ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
172ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    ~exception_ptr() _NOEXCEPT;
173ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne};
174ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
175ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne}
176ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
177ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr);
178ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
179ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif
180dea7f39af1ae5a71adfc0434b111962345193ef2Howard Hinnant
181ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantexception_ptr::~exception_ptr() _NOEXCEPT
182804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
183c512df1950baf9466843b2943855356c031fec08David Chisnall#if HAVE_DEPENDENT_EH_ABI
184c512df1950baf9466843b2943855356c031fec08David Chisnall    __cxa_decrement_exception_refcount(__ptr_);
185ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#elif defined(__GLIBCXX__)
186ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr();
187804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik#else
188f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   if defined(_MSC_VER) && ! defined(__clang__)
189f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant        _LIBCPP_WARNING("exception_ptr not yet implemented")
190f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   else
191f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#       warning exception_ptr not yet implemented
192f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   endif
1934a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    printf("exception_ptr not yet implemented\n");
1944a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    ::abort();
195ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif
196804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
197804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
198ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantexception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT
199804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik    : __ptr_(other.__ptr_)
200804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
201c512df1950baf9466843b2943855356c031fec08David Chisnall#if HAVE_DEPENDENT_EH_ABI
202c512df1950baf9466843b2943855356c031fec08David Chisnall    __cxa_increment_exception_refcount(__ptr_);
203ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#elif defined(__GLIBCXX__)
204ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr(
205ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne        reinterpret_cast<const __exception_ptr::exception_ptr&>(other));
206804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik#else
207f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   if defined(_MSC_VER) && ! defined(__clang__)
208f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant        _LIBCPP_WARNING("exception_ptr not yet implemented")
209f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   else
210f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#       warning exception_ptr not yet implemented
211f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   endif
2124a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    printf("exception_ptr not yet implemented\n");
2134a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    ::abort();
214ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif
215804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
216804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
217ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantexception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT
218804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
219c512df1950baf9466843b2943855356c031fec08David Chisnall#if HAVE_DEPENDENT_EH_ABI
220804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik    if (__ptr_ != other.__ptr_)
221804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik    {
222c512df1950baf9466843b2943855356c031fec08David Chisnall        __cxa_increment_exception_refcount(other.__ptr_);
223c512df1950baf9466843b2943855356c031fec08David Chisnall        __cxa_decrement_exception_refcount(__ptr_);
224d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant        __ptr_ = other.__ptr_;
225d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    }
226804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik    return *this;
227ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#elif defined(__GLIBCXX__)
228ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    *reinterpret_cast<__exception_ptr::exception_ptr*>(this) =
229ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne        reinterpret_cast<const __exception_ptr::exception_ptr&>(other);
230ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    return *this;
231ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#else
232f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   if defined(_MSC_VER) && ! defined(__clang__)
233f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant        _LIBCPP_WARNING("exception_ptr not yet implemented")
234f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   else
235f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#       warning exception_ptr not yet implemented
236f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   endif
2374a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    printf("exception_ptr not yet implemented\n");
2384a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    ::abort();
239ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif
240804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
241804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
242ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantnested_exception::nested_exception() _NOEXCEPT
243ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant    : __ptr_(current_exception())
244ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant{
245ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant}
246ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant
24740455c65da679c5789c14b2081417c432cd1173cPeter Collingbourne#if !defined(__GLIBCXX__)
24840455c65da679c5789c14b2081417c432cd1173cPeter Collingbourne
249ed56921d6e491eb96f489cedf24fed393fdfc0bfHoward Hinnantnested_exception::~nested_exception() _NOEXCEPT
250ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant{
251ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant}
252ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant
25340455c65da679c5789c14b2081417c432cd1173cPeter Collingbourne#endif
25440455c65da679c5789c14b2081417c432cd1173cPeter Collingbourne
2550405cc4ae0b74bab1f30830aa7bb03077b8280a6Richard Smith_LIBCPP_NORETURN
256ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnantvoid
2574b7a43da34a986ad356993d9ccea8c99a45a958aHoward Hinnantnested_exception::rethrow_nested() const
258ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant{
259ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant    if (__ptr_ == nullptr)
260ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant        terminate();
261ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant    rethrow_exception(__ptr_);
262ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant}
263ed2c2916b218361524764b6da427db2f2cb249f6Howard Hinnant
264ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#if !defined(__GLIBCXX__)
265804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
2661e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallexception_ptr current_exception() _NOEXCEPT
267804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
268c512df1950baf9466843b2943855356c031fec08David Chisnall#if HAVE_DEPENDENT_EH_ABI
269d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    // be nicer if there was a constructor that took a ptr, then
270d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    // this whole function would be just:
271d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    //    return exception_ptr(__cxa_current_primary_exception());
2721e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall    exception_ptr ptr;
273c512df1950baf9466843b2943855356c031fec08David Chisnall    ptr.__ptr_ = __cxa_current_primary_exception();
274d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    return ptr;
275ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#else
276f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   if defined(_MSC_VER) && ! defined(__clang__)
277f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant        _LIBCPP_WARNING( "exception_ptr not yet implemented" )
278f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   else
279f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#       warning exception_ptr not yet implemented
280f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   endif
2814a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    printf("exception_ptr not yet implemented\n");
2824a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    ::abort();
283ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif
284804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
285804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik
286ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif  // !__GLIBCXX__
287ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne
2880405cc4ae0b74bab1f30830aa7bb03077b8280a6Richard Smith_LIBCPP_NORETURN
2891e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnallvoid rethrow_exception(exception_ptr p)
290804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik{
291c512df1950baf9466843b2943855356c031fec08David Chisnall#if HAVE_DEPENDENT_EH_ABI
292c512df1950baf9466843b2943855356c031fec08David Chisnall    __cxa_rethrow_primary_exception(p.__ptr_);
293d510977c4dccbc249dff951e73ea0651d1fa59d7Howard Hinnant    // if p.__ptr_ is NULL, above returns so we terminate
29416e6e1d72fd6a10fc165eba4ca4ed2fa7c45df78Howard Hinnant    terminate();
295ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#elif defined(__GLIBCXX__)
296ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne    rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p));
297ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#else
298f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   if defined(_MSC_VER) && ! defined(__clang__)
299f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant        _LIBCPP_WARNING("exception_ptr not yet implemented")
300f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   else
301f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#       warning exception_ptr not yet implemented
302f7555069ab8b7eaf73970a1d325a51bedf2cb250Howard Hinnant#   endif
3034a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    printf("exception_ptr not yet implemented\n");
3044a0555a9d4d59dc2b0827f0841f8ab3a65322f01Peter Collingbourne    ::abort();
305ece95914ac8f29d62137f7452b42056a1cd9c45fPeter Collingbourne#endif
306804b6e73d41fc61cae5be513276183c69a4530b5Nick Kledzik}
3071e8b3f96c015e7e4a190eec7444b90d47be95540David Chisnall} // std
308