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#include <cstdio>
11
12namespace std {
13
14static constinit std::terminate_handler  __terminate_handler = nullptr;
15static constinit std::unexpected_handler __unexpected_handler = nullptr;
16
17// libcxxrt provides implementations of these functions itself.
18unexpected_handler
19set_unexpected(unexpected_handler func) noexcept
20{
21  return __libcpp_atomic_exchange(&__unexpected_handler, func);
22}
23
24unexpected_handler
25get_unexpected() noexcept
26{
27  return __libcpp_atomic_load(&__unexpected_handler);
28}
29
30_LIBCPP_NORETURN
31void unexpected()
32{
33    (*get_unexpected())();
34    // unexpected handler should not return
35    terminate();
36}
37
38terminate_handler
39set_terminate(terminate_handler func) noexcept
40{
41  return __libcpp_atomic_exchange(&__terminate_handler, func);
42}
43
44terminate_handler
45get_terminate() noexcept
46{
47  return __libcpp_atomic_load(&__terminate_handler);
48}
49
50_LIBCPP_NORETURN
51void
52terminate() noexcept
53{
54#ifndef _LIBCPP_NO_EXCEPTIONS
55    try
56    {
57#endif // _LIBCPP_NO_EXCEPTIONS
58        (*get_terminate())();
59        // handler should not return
60        fprintf(stderr, "terminate_handler unexpectedly returned\n");
61        ::abort();
62#ifndef _LIBCPP_NO_EXCEPTIONS
63    }
64    catch (...)
65    {
66        // handler should not throw exception
67        fprintf(stderr, "terminate_handler unexpectedly threw an exception\n");
68        ::abort();
69    }
70#endif // _LIBCPP_NO_EXCEPTIONS
71}
72
73bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; }
74
75int uncaught_exceptions() noexcept
76{
77#warning uncaught_exception not yet implemented
78  fprintf(stderr, "uncaught_exceptions not yet implemented\n");
79  ::abort();
80}
81
82
83exception::~exception() noexcept
84{
85}
86
87const char* exception::what() const noexcept
88{
89  return "std::exception";
90}
91
92bad_exception::~bad_exception() noexcept
93{
94}
95
96const char* bad_exception::what() const noexcept
97{
98  return "std::bad_exception";
99}
100
101
102bad_alloc::bad_alloc() noexcept
103{
104}
105
106bad_alloc::~bad_alloc() noexcept
107{
108}
109
110const char*
111bad_alloc::what() const noexcept
112{
113    return "std::bad_alloc";
114}
115
116bad_array_new_length::bad_array_new_length() noexcept
117{
118}
119
120bad_array_new_length::~bad_array_new_length() noexcept
121{
122}
123
124const char*
125bad_array_new_length::what() const noexcept
126{
127    return "bad_array_new_length";
128}
129
130bad_cast::bad_cast() noexcept
131{
132}
133
134bad_typeid::bad_typeid() noexcept
135{
136}
137
138bad_cast::~bad_cast() noexcept
139{
140}
141
142const char*
143bad_cast::what() const noexcept
144{
145  return "std::bad_cast";
146}
147
148bad_typeid::~bad_typeid() noexcept
149{
150}
151
152const char*
153bad_typeid::what() const noexcept
154{
155  return "std::bad_typeid";
156}
157
158} // namespace std
159