10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_ABI_MICROSOFT
110b57cec5SDimitry Andric#  error this header can only be used when targeting the MSVC ABI
120b57cec5SDimitry Andric#endif
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric#include <stdio.h>
150b57cec5SDimitry Andric#include <stdlib.h>
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricextern "C" {
180b57cec5SDimitry Andrictypedef void(__cdecl* terminate_handler)();
19cb14a3feSDimitry Andric_LIBCPP_CRT_FUNC terminate_handler __cdecl set_terminate(terminate_handler _NewTerminateHandler) throw();
200b57cec5SDimitry Andric_LIBCPP_CRT_FUNC terminate_handler __cdecl _get_terminate();
210b57cec5SDimitry Andric
220b57cec5SDimitry Andrictypedef void(__cdecl* unexpected_handler)();
23cb14a3feSDimitry Andricunexpected_handler __cdecl set_unexpected(unexpected_handler _NewUnexpectedHandler) throw();
240b57cec5SDimitry Andricunexpected_handler __cdecl _get_unexpected();
250b57cec5SDimitry Andric
260b57cec5SDimitry Andricint __cdecl __uncaught_exceptions();
270b57cec5SDimitry Andric}
280b57cec5SDimitry Andric
290b57cec5SDimitry Andricnamespace std {
300b57cec5SDimitry Andric
31cb14a3feSDimitry Andricunexpected_handler set_unexpected(unexpected_handler func) noexcept { return ::set_unexpected(func); }
320b57cec5SDimitry Andric
33cb14a3feSDimitry Andricunexpected_handler get_unexpected() noexcept { return ::_get_unexpected(); }
340b57cec5SDimitry Andric
35cb14a3feSDimitry Andric_LIBCPP_NORETURN void unexpected() {
360b57cec5SDimitry Andric  (*get_unexpected())();
370b57cec5SDimitry Andric  // unexpected handler should not return
380b57cec5SDimitry Andric  terminate();
390b57cec5SDimitry Andric}
400b57cec5SDimitry Andric
41cb14a3feSDimitry Andricterminate_handler set_terminate(terminate_handler func) noexcept { return ::set_terminate(func); }
420b57cec5SDimitry Andric
43cb14a3feSDimitry Andricterminate_handler get_terminate() noexcept { return ::_get_terminate(); }
440b57cec5SDimitry Andric
45cb14a3feSDimitry Andric_LIBCPP_NORETURN void terminate() noexcept {
4606c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
47cb14a3feSDimitry Andric  try {
4806c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
490b57cec5SDimitry Andric    (*get_terminate())();
500b57cec5SDimitry Andric    // handler should not return
510b57cec5SDimitry Andric    fprintf(stderr, "terminate_handler unexpectedly returned\n");
520b57cec5SDimitry Andric    ::abort();
5306c3fb27SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
54cb14a3feSDimitry Andric  } catch (...) {
550b57cec5SDimitry Andric    // handler should not throw exception
560b57cec5SDimitry Andric    fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
570b57cec5SDimitry Andric    ::abort();
580b57cec5SDimitry Andric  }
5906c3fb27SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
600b57cec5SDimitry Andric}
610b57cec5SDimitry Andric
62fe6060f1SDimitry Andricbool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
630b57cec5SDimitry Andric
64cb14a3feSDimitry Andricint uncaught_exceptions() noexcept { return __uncaught_exceptions(); }
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric#if !defined(_LIBCPP_ABI_VCRUNTIME)
67cb14a3feSDimitry Andricbad_cast::bad_cast() noexcept {}
680b57cec5SDimitry Andric
69cb14a3feSDimitry Andricbad_cast::~bad_cast() noexcept {}
700b57cec5SDimitry Andric
71cb14a3feSDimitry Andricconst char* bad_cast::what() const noexcept { return "std::bad_cast"; }
720b57cec5SDimitry Andric
73cb14a3feSDimitry Andricbad_typeid::bad_typeid() noexcept {}
740b57cec5SDimitry Andric
75cb14a3feSDimitry Andricbad_typeid::~bad_typeid() noexcept {}
760b57cec5SDimitry Andric
77cb14a3feSDimitry Andricconst char* bad_typeid::what() const noexcept { return "std::bad_typeid"; }
780b57cec5SDimitry Andric
79cb14a3feSDimitry Andricexception::~exception() noexcept {}
800b57cec5SDimitry Andric
81cb14a3feSDimitry Andricconst char* exception::what() const noexcept { return "std::exception"; }
820b57cec5SDimitry Andric
83cb14a3feSDimitry Andricbad_exception::~bad_exception() noexcept {}
840b57cec5SDimitry Andric
85cb14a3feSDimitry Andricconst char* bad_exception::what() const noexcept { return "std::bad_exception"; }
860b57cec5SDimitry Andric
87cb14a3feSDimitry Andricbad_alloc::bad_alloc() noexcept {}
880b57cec5SDimitry Andric
89cb14a3feSDimitry Andricbad_alloc::~bad_alloc() noexcept {}
900b57cec5SDimitry Andric
91cb14a3feSDimitry Andricconst char* bad_alloc::what() const noexcept { return "std::bad_alloc"; }
920b57cec5SDimitry Andric
93cb14a3feSDimitry Andricbad_array_new_length::bad_array_new_length() noexcept {}
940b57cec5SDimitry Andric
95cb14a3feSDimitry Andricbad_array_new_length::~bad_array_new_length() noexcept {}
960b57cec5SDimitry Andric
97cb14a3feSDimitry Andricconst char* bad_array_new_length::what() const noexcept { return "bad_array_new_length"; }
980b57cec5SDimitry Andric#endif // !_LIBCPP_ABI_VCRUNTIME
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric} // namespace std
101