xref: /llvm-project/libcxx/include/__cxx03/__exception/exception.h (revision ce7771902dc50d900de639d499a60486b83f70e0)
1e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===//
2e78f53d1SNikolas Klauser //
3e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e78f53d1SNikolas Klauser //
7e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===//
8e78f53d1SNikolas Klauser 
9*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03___EXCEPTION_EXCEPTION_H
10*ce777190SNikolas Klauser #define _LIBCPP___CXX03___EXCEPTION_EXCEPTION_H
11e78f53d1SNikolas Klauser 
1273fbae83SNikolas Klauser #include <__cxx03/__config>
13e78f53d1SNikolas Klauser 
14e78f53d1SNikolas Klauser // <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
15e78f53d1SNikolas Klauser // which we use in order to be ABI-compatible with other STLs on Windows.
16e78f53d1SNikolas Klauser #if defined(_LIBCPP_ABI_VCRUNTIME)
1773fbae83SNikolas Klauser #  include <__cxx03/vcruntime_exception.h>
18e78f53d1SNikolas Klauser #endif
19e78f53d1SNikolas Klauser 
20e78f53d1SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21e78f53d1SNikolas Klauser #  pragma GCC system_header
22e78f53d1SNikolas Klauser #endif
23e78f53d1SNikolas Klauser 
24e78f53d1SNikolas Klauser namespace std { // purposefully not using versioning namespace
25e78f53d1SNikolas Klauser 
26e78f53d1SNikolas Klauser #if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
27e78f53d1SNikolas Klauser // The std::exception class was already included above, but we're explicit about this condition here for clarity.
28e78f53d1SNikolas Klauser 
29e78f53d1SNikolas Klauser #elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
30e78f53d1SNikolas Klauser // However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
31e78f53d1SNikolas Klauser // when _HAS_EXCEPTIONS == 0.
32e78f53d1SNikolas Klauser //
33e78f53d1SNikolas Klauser // Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
34e78f53d1SNikolas Klauser // (after all those are simply types like any other), we define an ABI-compatible version
35e78f53d1SNikolas Klauser // of the VCRuntime std::exception and std::bad_exception types in that mode.
36e78f53d1SNikolas Klauser 
37e78f53d1SNikolas Klauser struct __std_exception_data {
38e78f53d1SNikolas Klauser   char const* _What;
39e78f53d1SNikolas Klauser   bool _DoFree;
40e78f53d1SNikolas Klauser };
41e78f53d1SNikolas Klauser 
42e78f53d1SNikolas Klauser class exception { // base of all library exceptions
43e78f53d1SNikolas Klauser public:
44e78f53d1SNikolas Klauser   exception() _NOEXCEPT : __data_() {}
45e78f53d1SNikolas Klauser 
46e78f53d1SNikolas Klauser   explicit exception(char const* __message) _NOEXCEPT : __data_() {
47e78f53d1SNikolas Klauser     __data_._What   = __message;
48e78f53d1SNikolas Klauser     __data_._DoFree = true;
49e78f53d1SNikolas Klauser   }
50e78f53d1SNikolas Klauser 
51e78f53d1SNikolas Klauser   exception(exception const&) _NOEXCEPT {}
52e78f53d1SNikolas Klauser 
53e78f53d1SNikolas Klauser   exception& operator=(exception const&) _NOEXCEPT { return *this; }
54e78f53d1SNikolas Klauser 
55e78f53d1SNikolas Klauser   virtual ~exception() _NOEXCEPT {}
56e78f53d1SNikolas Klauser 
57e78f53d1SNikolas Klauser   virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
58e78f53d1SNikolas Klauser 
59e78f53d1SNikolas Klauser private:
60e78f53d1SNikolas Klauser   __std_exception_data __data_;
61e78f53d1SNikolas Klauser };
62e78f53d1SNikolas Klauser 
63e78f53d1SNikolas Klauser class bad_exception : public exception {
64e78f53d1SNikolas Klauser public:
65e78f53d1SNikolas Klauser   bad_exception() _NOEXCEPT : exception("bad exception") {}
66e78f53d1SNikolas Klauser };
67e78f53d1SNikolas Klauser 
68e78f53d1SNikolas Klauser #else  // !defined(_LIBCPP_ABI_VCRUNTIME)
69e78f53d1SNikolas Klauser // On all other platforms, we define our own std::exception and std::bad_exception types
70e78f53d1SNikolas Klauser // regardless of whether exceptions are turned on as a language feature.
71e78f53d1SNikolas Klauser 
72e78f53d1SNikolas Klauser class _LIBCPP_EXPORTED_FROM_ABI exception {
73e78f53d1SNikolas Klauser public:
74e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {}
75e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT            = default;
76e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default;
77e78f53d1SNikolas Klauser 
78e78f53d1SNikolas Klauser   virtual ~exception() _NOEXCEPT;
79e78f53d1SNikolas Klauser   virtual const char* what() const _NOEXCEPT;
80e78f53d1SNikolas Klauser };
81e78f53d1SNikolas Klauser 
82e78f53d1SNikolas Klauser class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception {
83e78f53d1SNikolas Klauser public:
84e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {}
85e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT            = default;
86e78f53d1SNikolas Klauser   _LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default;
87e78f53d1SNikolas Klauser   ~bad_exception() _NOEXCEPT override;
88e78f53d1SNikolas Klauser   const char* what() const _NOEXCEPT override;
89e78f53d1SNikolas Klauser };
90e78f53d1SNikolas Klauser #endif // !_LIBCPP_ABI_VCRUNTIME
91e78f53d1SNikolas Klauser 
92e78f53d1SNikolas Klauser } // namespace std
93e78f53d1SNikolas Klauser 
94*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03___EXCEPTION_EXCEPTION_H
95