1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is dual licensed under the MIT and the University of Illinois Open
7// Source Licenses. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_ABI_MICROSOFT
12#error this header can only be used when targeting the MSVC ABI
13#endif
14
15#include <stdio.h>
16#include <stdlib.h>
17
18extern "C" {
19typedef void (__cdecl* terminate_handler)();
20_LIBCPP_CRT_FUNC terminate_handler __cdecl set_terminate(
21    terminate_handler _NewTerminateHandler) throw();
22_LIBCPP_CRT_FUNC terminate_handler __cdecl _get_terminate();
23
24typedef void (__cdecl* unexpected_handler)();
25unexpected_handler __cdecl set_unexpected(
26    unexpected_handler _NewUnexpectedHandler) throw();
27unexpected_handler __cdecl _get_unexpected();
28
29int __cdecl __uncaught_exceptions();
30}
31
32namespace std {
33
34unexpected_handler
35set_unexpected(unexpected_handler func) _NOEXCEPT {
36  return ::set_unexpected(func);
37}
38
39unexpected_handler get_unexpected() _NOEXCEPT {
40  return ::_get_unexpected();
41}
42
43_LIBCPP_NORETURN
44void unexpected() {
45    (*get_unexpected())();
46    // unexpected handler should not return
47    terminate();
48}
49
50terminate_handler set_terminate(terminate_handler func) _NOEXCEPT {
51  return ::set_terminate(func);
52}
53
54terminate_handler get_terminate() _NOEXCEPT {
55  return ::_get_terminate();
56}
57
58_LIBCPP_NORETURN
59void terminate() _NOEXCEPT
60{
61#ifndef _LIBCPP_NO_EXCEPTIONS
62    try
63    {
64#endif  // _LIBCPP_NO_EXCEPTIONS
65        (*get_terminate())();
66        // handler should not return
67        fprintf(stderr, "terminate_handler unexpectedly returned\n");
68        ::abort();
69#ifndef _LIBCPP_NO_EXCEPTIONS
70    }
71    catch (...)
72    {
73        // handler should not throw exception
74        fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
75        ::abort();
76    }
77#endif  // _LIBCPP_NO_EXCEPTIONS
78}
79
80bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
81
82int uncaught_exceptions() _NOEXCEPT {
83    return __uncaught_exceptions();
84}
85
86bad_array_length::bad_array_length() _NOEXCEPT
87{
88}
89
90bad_array_length::~bad_array_length() _NOEXCEPT
91{
92}
93
94const char*
95bad_array_length::what() const _NOEXCEPT
96{
97    return "bad_array_length";
98}
99
100#if defined(_LIBCPP_NO_VCRUNTIME)
101bad_cast::bad_cast() _NOEXCEPT
102{
103}
104
105bad_cast::~bad_cast() _NOEXCEPT
106{
107}
108
109const char *
110bad_cast::what() const _NOEXCEPT
111{
112  return "std::bad_cast";
113}
114
115bad_typeid::bad_typeid() _NOEXCEPT
116{
117}
118
119bad_typeid::~bad_typeid() _NOEXCEPT
120{
121}
122
123const char *
124bad_typeid::what() const _NOEXCEPT
125{
126  return "std::bad_typeid";
127}
128
129exception::~exception() _NOEXCEPT
130{
131}
132
133const char* exception::what() const _NOEXCEPT
134{
135  return "std::exception";
136}
137
138
139bad_exception::~bad_exception() _NOEXCEPT
140{
141}
142
143const char* bad_exception::what() const _NOEXCEPT
144{
145  return "std::bad_exception";
146}
147
148
149bad_alloc::bad_alloc() _NOEXCEPT
150{
151}
152
153bad_alloc::~bad_alloc() _NOEXCEPT
154{
155}
156
157const char*
158bad_alloc::what() const _NOEXCEPT
159{
160    return "std::bad_alloc";
161}
162
163bad_array_new_length::bad_array_new_length() _NOEXCEPT
164{
165}
166
167bad_array_new_length::~bad_array_new_length() _NOEXCEPT
168{
169}
170
171const char*
172bad_array_new_length::what() const _NOEXCEPT
173{
174    return "bad_array_new_length";
175}
176#endif // _LIBCPP_NO_VCRUNTIME
177
178} // namespace std
179