1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_ABI_MICROSOFT 11# error this header can only be used when targeting the MSVC ABI 12#endif 13 14#include <__verbose_abort> 15 16extern "C" { 17typedef void(__cdecl* terminate_handler)(); 18_LIBCPP_CRT_FUNC terminate_handler __cdecl set_terminate(terminate_handler _NewTerminateHandler) throw(); 19_LIBCPP_CRT_FUNC terminate_handler __cdecl _get_terminate(); 20 21typedef void(__cdecl* unexpected_handler)(); 22unexpected_handler __cdecl set_unexpected(unexpected_handler _NewUnexpectedHandler) throw(); 23unexpected_handler __cdecl _get_unexpected(); 24 25int __cdecl __uncaught_exceptions(); 26} 27 28namespace std { 29 30unexpected_handler set_unexpected(unexpected_handler func) noexcept { return ::set_unexpected(func); } 31 32unexpected_handler get_unexpected() noexcept { return ::_get_unexpected(); } 33 34[[noreturn]] void unexpected() { 35 (*get_unexpected())(); 36 // unexpected handler should not return 37 terminate(); 38} 39 40terminate_handler set_terminate(terminate_handler func) noexcept { return ::set_terminate(func); } 41 42terminate_handler get_terminate() noexcept { return ::_get_terminate(); } 43 44[[noreturn]] void terminate() noexcept { 45#if _LIBCPP_HAS_EXCEPTIONS 46 try { 47#endif // _LIBCPP_HAS_EXCEPTIONS 48 (*get_terminate())(); 49 // handler should not return 50 __libcpp_verbose_abort("terminate_handler unexpectedly returned\n"); 51#if _LIBCPP_HAS_EXCEPTIONS 52 } catch (...) { 53 // handler should not throw exception 54 __libcpp_verbose_abort("terminate_handler unexpectedly threw an exception\n"); 55 } 56#endif // _LIBCPP_HAS_EXCEPTIONS 57} 58 59bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; } 60 61int uncaught_exceptions() noexcept { return __uncaught_exceptions(); } 62 63#if !defined(_LIBCPP_ABI_VCRUNTIME) 64bad_cast::bad_cast() noexcept {} 65 66bad_cast::~bad_cast() noexcept {} 67 68const char* bad_cast::what() const noexcept { return "std::bad_cast"; } 69 70bad_typeid::bad_typeid() noexcept {} 71 72bad_typeid::~bad_typeid() noexcept {} 73 74const char* bad_typeid::what() const noexcept { return "std::bad_typeid"; } 75 76exception::~exception() noexcept {} 77 78const char* exception::what() const noexcept { return "std::exception"; } 79 80bad_exception::~bad_exception() noexcept {} 81 82const char* bad_exception::what() const noexcept { return "std::bad_exception"; } 83 84bad_alloc::bad_alloc() noexcept {} 85 86bad_alloc::~bad_alloc() noexcept {} 87 88const char* bad_alloc::what() const noexcept { return "std::bad_alloc"; } 89 90bad_array_new_length::bad_array_new_length() noexcept {} 91 92bad_array_new_length::~bad_array_new_length() noexcept {} 93 94const char* bad_array_new_length::what() const noexcept { return "bad_array_new_length"; } 95#endif // !_LIBCPP_ABI_VCRUNTIME 96 97} // namespace std 98