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
18#if !defined(_ACRTIMP)
19#define _ACRTIMP __declspec(dllimport)
20#endif
21
22#if !defined(_VCRTIMP)
23#define _VCRTIMP __declspec(dllimport)
24#endif
25
26#if !defined(__CRTDECL)
27#define __CRTDECL __cdecl
28#endif
29
30extern "C" {
31typedef void (__CRTDECL* terminate_handler)();
32_ACRTIMP terminate_handler __cdecl set_terminate(
33    terminate_handler _NewTerminateHandler) throw();
34_ACRTIMP terminate_handler __cdecl _get_terminate();
35
36typedef void (__CRTDECL* unexpected_handler)();
37_VCRTIMP unexpected_handler __cdecl set_unexpected(
38    unexpected_handler _NewUnexpectedHandler) throw();
39_VCRTIMP unexpected_handler __cdecl _get_unexpected();
40
41_VCRTIMP int __cdecl __uncaught_exceptions();
42}
43
44namespace std {
45
46unexpected_handler
47set_unexpected(unexpected_handler func) _NOEXCEPT {
48  return ::set_unexpected(func);
49}
50
51unexpected_handler get_unexpected() _NOEXCEPT {
52  return ::_get_unexpected();
53}
54
55_LIBCPP_NORETURN
56void unexpected() {
57    (*get_unexpected())();
58    // unexpected handler should not return
59    terminate();
60}
61
62terminate_handler set_terminate(terminate_handler func) _NOEXCEPT {
63  return ::set_terminate(func);
64}
65
66terminate_handler get_terminate() _NOEXCEPT {
67  return ::_get_terminate();
68}
69
70_LIBCPP_NORETURN
71void terminate() _NOEXCEPT
72{
73#ifndef _LIBCPP_NO_EXCEPTIONS
74    try
75    {
76#endif  // _LIBCPP_NO_EXCEPTIONS
77        (*get_terminate())();
78        // handler should not return
79        fprintf(stderr, "terminate_handler unexpectedly returned\n");
80        ::abort();
81#ifndef _LIBCPP_NO_EXCEPTIONS
82    }
83    catch (...)
84    {
85        // handler should not throw exception
86        fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
87        ::abort();
88    }
89#endif  // _LIBCPP_NO_EXCEPTIONS
90}
91
92bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
93
94int uncaught_exceptions() _NOEXCEPT {
95    return __uncaught_exceptions();
96}
97
98bad_array_length::bad_array_length() _NOEXCEPT
99{
100}
101
102bad_array_length::~bad_array_length() _NOEXCEPT
103{
104}
105
106const char*
107bad_array_length::what() const _NOEXCEPT
108{
109    return "bad_array_length";
110}
111
112bad_cast::bad_cast() _NOEXCEPT
113{
114}
115
116bad_cast::~bad_cast() _NOEXCEPT
117{
118}
119
120const char *
121bad_cast::what() const _NOEXCEPT
122{
123  return "std::bad_cast";
124}
125
126bad_typeid::bad_typeid() _NOEXCEPT
127{
128}
129
130bad_typeid::~bad_typeid() _NOEXCEPT
131{
132}
133
134const char *
135bad_typeid::what() const _NOEXCEPT
136{
137  return "std::bad_typeid";
138}
139
140#if defined(_LIBCPP_NO_VCRUNTIME)
141exception::~exception() _NOEXCEPT
142{
143}
144
145const char* exception::what() const _NOEXCEPT
146{
147  return "std::exception";
148}
149
150
151bad_exception::~bad_exception() _NOEXCEPT
152{
153}
154
155const char* bad_exception::what() const _NOEXCEPT
156{
157  return "std::bad_exception";
158}
159
160
161bad_alloc::bad_alloc() _NOEXCEPT
162{
163}
164
165bad_alloc::~bad_alloc() _NOEXCEPT
166{
167}
168
169const char*
170bad_alloc::what() const _NOEXCEPT
171{
172    return "std::bad_alloc";
173}
174
175bad_array_new_length::bad_array_new_length() _NOEXCEPT
176{
177}
178
179bad_array_new_length::~bad_array_new_length() _NOEXCEPT
180{
181}
182
183const char*
184bad_array_new_length::what() const _NOEXCEPT
185{
186    return "bad_array_new_length";
187}
188#endif // _LIBCPP_NO_VCRUNTIME
189
190} // namespace std
191