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