143562287SNikolas Klauser //===----------------------------------------------------------------------===// 243562287SNikolas Klauser // 343562287SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 443562287SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 543562287SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 643562287SNikolas Klauser // 743562287SNikolas Klauser //===----------------------------------------------------------------------===// 843562287SNikolas Klauser 943562287SNikolas Klauser #ifndef _LIBCPP___EXCEPTION_EXCEPTION_H 1043562287SNikolas Klauser #define _LIBCPP___EXCEPTION_EXCEPTION_H 1143562287SNikolas Klauser 1243562287SNikolas Klauser #include <__config> 1343562287SNikolas Klauser 1443562287SNikolas Klauser // <vcruntime_exception.h> defines its own std::exception and std::bad_exception types, 1543562287SNikolas Klauser // which we use in order to be ABI-compatible with other STLs on Windows. 1643562287SNikolas Klauser #if defined(_LIBCPP_ABI_VCRUNTIME) 1743562287SNikolas Klauser # include <vcruntime_exception.h> 1843562287SNikolas Klauser #endif 1943562287SNikolas Klauser 2043562287SNikolas Klauser #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2143562287SNikolas Klauser # pragma GCC system_header 2243562287SNikolas Klauser #endif 2343562287SNikolas Klauser 2443562287SNikolas Klauser namespace std { // purposefully not using versioning namespace 2543562287SNikolas Klauser 2643562287SNikolas Klauser #if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0) 2743562287SNikolas Klauser // The std::exception class was already included above, but we're explicit about this condition here for clarity. 2843562287SNikolas Klauser 2943562287SNikolas Klauser #elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 3043562287SNikolas Klauser // However, <vcruntime_exception.h> does not define std::exception and std::bad_exception 3143562287SNikolas Klauser // when _HAS_EXCEPTIONS == 0. 3243562287SNikolas Klauser // 3343562287SNikolas Klauser // Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0 3443562287SNikolas Klauser // (after all those are simply types like any other), we define an ABI-compatible version 3543562287SNikolas Klauser // of the VCRuntime std::exception and std::bad_exception types in that mode. 3643562287SNikolas Klauser 3743562287SNikolas Klauser struct __std_exception_data { 3843562287SNikolas Klauser char const* _What; 3943562287SNikolas Klauser bool _DoFree; 4043562287SNikolas Klauser }; 4143562287SNikolas Klauser 4243562287SNikolas Klauser class exception { // base of all library exceptions 4343562287SNikolas Klauser public: 4443562287SNikolas Klauser exception() _NOEXCEPT : __data_() {} 4543562287SNikolas Klauser 4643562287SNikolas Klauser explicit exception(char const* __message) _NOEXCEPT : __data_() { 4743562287SNikolas Klauser __data_._What = __message; 4843562287SNikolas Klauser __data_._DoFree = true; 4943562287SNikolas Klauser } 5043562287SNikolas Klauser 5143562287SNikolas Klauser exception(exception const&) _NOEXCEPT {} 5243562287SNikolas Klauser 5343562287SNikolas Klauser exception& operator=(exception const&) _NOEXCEPT { return *this; } 5443562287SNikolas Klauser 5543562287SNikolas Klauser virtual ~exception() _NOEXCEPT {} 5643562287SNikolas Klauser 5743562287SNikolas Klauser virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; } 5843562287SNikolas Klauser 5943562287SNikolas Klauser private: 6043562287SNikolas Klauser __std_exception_data __data_; 6143562287SNikolas Klauser }; 6243562287SNikolas Klauser 6343562287SNikolas Klauser class bad_exception : public exception { 6443562287SNikolas Klauser public: 6543562287SNikolas Klauser bad_exception() _NOEXCEPT : exception("bad exception") {} 6643562287SNikolas Klauser }; 6743562287SNikolas Klauser 6843562287SNikolas Klauser #else // !defined(_LIBCPP_ABI_VCRUNTIME) 6943562287SNikolas Klauser // On all other platforms, we define our own std::exception and std::bad_exception types 7043562287SNikolas Klauser // regardless of whether exceptions are turned on as a language feature. 7143562287SNikolas Klauser 72f1ea0b11SNikolas Klauser class _LIBCPP_EXPORTED_FROM_ABI exception { 7343562287SNikolas Klauser public: 7443562287SNikolas Klauser _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {} 7543562287SNikolas Klauser _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default; 76*70248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default; 7743562287SNikolas Klauser 7843562287SNikolas Klauser virtual ~exception() _NOEXCEPT; 7943562287SNikolas Klauser virtual const char* what() const _NOEXCEPT; 8043562287SNikolas Klauser }; 8143562287SNikolas Klauser 82f1ea0b11SNikolas Klauser class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception { 8343562287SNikolas Klauser public: 8443562287SNikolas Klauser _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {} 85*70248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default; 86*70248920SIgor Zhukov _LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default; 8743562287SNikolas Klauser ~bad_exception() _NOEXCEPT override; 8843562287SNikolas Klauser const char* what() const _NOEXCEPT override; 8943562287SNikolas Klauser }; 9043562287SNikolas Klauser #endif // !_LIBCPP_ABI_VCRUNTIME 9143562287SNikolas Klauser 9243562287SNikolas Klauser } // namespace std 9343562287SNikolas Klauser 9443562287SNikolas Klauser #endif // _LIBCPP___EXCEPTION_EXCEPTION_H 95