[libcxx-commits] [libcxx] 4356228 - [libc++] Granularize <exception>

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Mar 12 14:19:47 PDT 2023


Author: Nikolas Klauser
Date: 2023-03-12T22:19:41+01:00
New Revision: 43562287a816c74be390478d32adc0cb4c4abca4

URL: https://github.com/llvm/llvm-project/commit/43562287a816c74be390478d32adc0cb4c4abca4
DIFF: https://github.com/llvm/llvm-project/commit/43562287a816c74be390478d32adc0cb4c4abca4.diff

LOG: [libc++] Granularize <exception>

This patch also updates the moved code to the new style (i.e. formatted, replaced marcos and typedefs)

Reviewed By: ldionne, #libc

Spies: arichardson, libcxx-commits

Differential Revision: https://reviews.llvm.org/D145095

Added: 
    libcxx/include/__exception/exception.h
    libcxx/include/__exception/exception_ptr.h
    libcxx/include/__exception/nested_exception.h
    libcxx/include/__exception/operations.h
    libcxx/include/__exception/terminate.h

Modified: 
    libcxx/include/CMakeLists.txt
    libcxx/include/__format/formatter_integral.h
    libcxx/include/__iterator/common_iterator.h
    libcxx/include/__memory/allocator.h
    libcxx/include/__memory/shared_ptr.h
    libcxx/include/__tree
    libcxx/include/any
    libcxx/include/deque
    libcxx/include/exception
    libcxx/include/istream
    libcxx/include/libcxx.imp
    libcxx/include/module.modulemap.in
    libcxx/include/optional
    libcxx/include/ostream
    libcxx/include/span
    libcxx/include/string
    libcxx/include/string_view
    libcxx/include/valarray
    libcxx/include/variant
    libcxx/include/vector
    libcxx/test/libcxx/private_headers.verify.cpp
    libcxx/test/std/containers/sequences/array/contiguous.pass.cpp
    libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
    libcxx/utils/data/ignore_format.txt

Removed: 
    


################################################################################
diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 34932dee692ed..f8b00e9918e22 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -297,6 +297,11 @@ set(files
   __debug
   __debug_utils/randomize_range.h
   __errc
+  __exception/exception.h
+  __exception/exception_ptr.h
+  __exception/nested_exception.h
+  __exception/operations.h
+  __exception/terminate.h
   __expected/bad_expected_access.h
   __expected/expected.h
   __expected/unexpect.h

diff  --git a/libcxx/include/__exception/exception.h b/libcxx/include/__exception/exception.h
new file mode 100644
index 0000000000000..49a58dd16999a
--- /dev/null
+++ b/libcxx/include/__exception/exception.h
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___EXCEPTION_EXCEPTION_H
+#define _LIBCPP___EXCEPTION_EXCEPTION_H
+
+#include <__config>
+
+// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
+// which we use in order to be ABI-compatible with other STLs on Windows.
+#if defined(_LIBCPP_ABI_VCRUNTIME)
+#  include <vcruntime_exception.h>
+#endif
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+
+#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
+// The std::exception class was already included above, but we're explicit about this condition here for clarity.
+
+#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
+// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
+// when _HAS_EXCEPTIONS == 0.
+//
+// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
+// (after all those are simply types like any other), we define an ABI-compatible version
+// of the VCRuntime std::exception and std::bad_exception types in that mode.
+
+struct __std_exception_data {
+  char const* _What;
+  bool _DoFree;
+};
+
+class exception { // base of all library exceptions
+public:
+  exception() _NOEXCEPT : __data_() {}
+
+  explicit exception(char const* __message) _NOEXCEPT : __data_() {
+    __data_._What   = __message;
+    __data_._DoFree = true;
+  }
+
+  exception(exception const&) _NOEXCEPT {}
+
+  exception& operator=(exception const&) _NOEXCEPT { return *this; }
+
+  virtual ~exception() _NOEXCEPT {}
+
+  virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
+
+private:
+  __std_exception_data __data_;
+};
+
+class bad_exception : public exception {
+public:
+  bad_exception() _NOEXCEPT : exception("bad exception") {}
+};
+
+#else  // !defined(_LIBCPP_ABI_VCRUNTIME)
+// On all other platforms, we define our own std::exception and std::bad_exception types
+// regardless of whether exceptions are turned on as a language feature.
+
+class _LIBCPP_EXCEPTION_ABI exception {
+public:
+  _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {}
+  _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default;
+
+  virtual ~exception() _NOEXCEPT;
+  virtual const char* what() const _NOEXCEPT;
+};
+
+class _LIBCPP_EXCEPTION_ABI bad_exception : public exception {
+public:
+  _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {}
+  ~bad_exception() _NOEXCEPT override;
+  const char* what() const _NOEXCEPT override;
+};
+#endif // !_LIBCPP_ABI_VCRUNTIME
+
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_EXCEPTION_H

diff  --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h
new file mode 100644
index 0000000000000..9c77ebf74d515
--- /dev/null
+++ b/libcxx/include/__exception/exception_ptr.h
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
+#define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H
+
+#include <__config>
+#include <__exception/operations.h>
+#include <cstddef>
+#include <cstdlib>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+
+#ifndef _LIBCPP_ABI_MICROSOFT
+
+class _LIBCPP_TYPE_VIS exception_ptr {
+  void* __ptr_;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
+  _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
+
+  exception_ptr(const exception_ptr&) _NOEXCEPT;
+  exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
+  ~exception_ptr() _NOEXCEPT;
+
+  _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; }
+
+  friend _LIBCPP_HIDE_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+    return __x.__ptr_ == __y.__ptr_;
+  }
+
+  friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+    return !(__x == __y);
+  }
+
+  friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+  friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
+};
+
+template <class _Ep>
+_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
+#  ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  try {
+    throw __e;
+  } catch (...) {
+    return current_exception();
+  }
+#  else
+  ((void)__e);
+  std::abort();
+#  endif
+}
+
+#else  // _LIBCPP_ABI_MICROSOFT
+
+class _LIBCPP_TYPE_VIS exception_ptr {
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
+  void* __ptr1_;
+  void* __ptr2_;
+  _LIBCPP_DIAGNOSTIC_POP
+
+public:
+  exception_ptr() _NOEXCEPT;
+  exception_ptr(nullptr_t) _NOEXCEPT;
+  exception_ptr(const exception_ptr& __other) _NOEXCEPT;
+  exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
+  exception_ptr& operator=(nullptr_t) _NOEXCEPT;
+  ~exception_ptr() _NOEXCEPT;
+  explicit operator bool() const _NOEXCEPT;
+};
+
+_LIBCPP_FUNC_VIS bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
+
+inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
+  return !(__x == __y);
+}
+
+_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void* __except, const void* __ptr);
+_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
+
+// This is a built-in template function which automagically extracts the required
+// information.
+template <class _E>
+void* __GetExceptionInfo(_E);
+
+template <class _Ep>
+_LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT {
+  return __copy_exception_ptr(std::addressof(__e), __GetExceptionInfo(__e));
+}
+
+#endif // _LIBCPP_ABI_MICROSOFT
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H

diff  --git a/libcxx/include/__exception/nested_exception.h b/libcxx/include/__exception/nested_exception.h
new file mode 100644
index 0000000000000..b842dde03e16a
--- /dev/null
+++ b/libcxx/include/__exception/nested_exception.h
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
+#define _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H
+
+#include <__config>
+#include <__exception/exception_ptr.h>
+#include <__memory/addressof.h>
+#include <__type_traits/decay.h>
+#include <__type_traits/is_base_of.h>
+#include <__type_traits/is_class.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/is_copy_constructible.h>
+#include <__type_traits/is_final.h>
+#include <__type_traits/is_polymorphic.h>
+#include <__utility/forward.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+
+class _LIBCPP_EXCEPTION_ABI nested_exception {
+  exception_ptr __ptr_;
+
+public:
+  nested_exception() _NOEXCEPT;
+  //     nested_exception(const nested_exception&) noexcept = default;
+  //     nested_exception& operator=(const nested_exception&) noexcept = default;
+  virtual ~nested_exception() _NOEXCEPT;
+
+  // access functions
+  _LIBCPP_NORETURN void rethrow_nested() const;
+  _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; }
+};
+
+template <class _Tp>
+struct __nested : public _Tp, public nested_exception {
+  _LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {}
+};
+
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+template <class _Tp, class _Up, bool>
+struct __throw_with_nested;
+
+template <class _Tp, class _Up>
+struct __throw_with_nested<_Tp, _Up, true> {
+  _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) {
+    throw __nested<_Up>(std::forward<_Tp>(__t));
+  }
+};
+
+template <class _Tp, class _Up>
+struct __throw_with_nested<_Tp, _Up, false> {
+  _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); }
+};
+#endif
+
+template <class _Tp>
+_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) {
+#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
+  typedef typename decay<_Tp>::type _Up;
+  static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
+  __throw_with_nested<_Tp,
+                      _Up,
+                      is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value &&
+                          !__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t));
+#else
+  ((void)__t);
+  // FIXME: Make this abort
+#endif
+}
+
+template <class _From, class _To>
+struct __can_dynamic_cast
+    : _BoolConstant< is_polymorphic<_From>::value &&
+                     (!is_base_of<_To, _From>::value || is_convertible<const _From*, const _To*>::value)> {};
+
+template <class _Ep>
+inline _LIBCPP_HIDE_FROM_ABI void
+rethrow_if_nested(const _Ep& __e, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {
+  const nested_exception* __nep = dynamic_cast<const nested_exception*>(std::addressof(__e));
+  if (__nep)
+    __nep->rethrow_nested();
+}
+
+template <class _Ep>
+inline _LIBCPP_HIDE_FROM_ABI void
+rethrow_if_nested(const _Ep&, __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {}
+
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H

diff  --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h
new file mode 100644
index 0000000000000..e8c5ba61ee0e2
--- /dev/null
+++ b/libcxx/include/__exception/operations.h
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___EXCEPTION_OPERATIONS_H
+#define _LIBCPP___EXCEPTION_OPERATIONS_H
+
+#include <__availability>
+#include <__config>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) ||                             \
+    defined(_LIBCPP_BUILDING_LIBRARY)
+using unexpected_handler = void (*)();
+_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
+_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
+#endif
+
+using terminate_handler = void (*)();
+_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
+_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
+
+_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
+_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
+
+class _LIBCPP_TYPE_VIS exception_ptr;
+
+_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_OPERATIONS_H

diff  --git a/libcxx/include/__exception/terminate.h b/libcxx/include/__exception/terminate.h
new file mode 100644
index 0000000000000..d8dd9642b88d1
--- /dev/null
+++ b/libcxx/include/__exception/terminate.h
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___EXCEPTION_TERMINATE_H
+#define _LIBCPP___EXCEPTION_TERMINATE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+namespace std { // purposefully not using versioning namespace
+_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
+} // namespace std
+
+#endif // _LIBCPP___EXCEPTION_TERMINATE_H

diff  --git a/libcxx/include/__format/formatter_integral.h b/libcxx/include/__format/formatter_integral.h
index 8a18049618846..8cc21e43749db 100644
--- a/libcxx/include/__format/formatter_integral.h
+++ b/libcxx/include/__format/formatter_integral.h
@@ -22,6 +22,7 @@
 #include <charconv>
 #include <limits>
 #include <string>
+#include <string_view>
 
 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
 #  include <locale>

diff  --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h
index 3c8eb1c00e11c..aab04ce49717f 100644
--- a/libcxx/include/__iterator/common_iterator.h
+++ b/libcxx/include/__iterator/common_iterator.h
@@ -25,6 +25,7 @@
 #include <__iterator/iter_swap.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/readable_traits.h>
+#include <__memory/addressof.h>
 #include <__type_traits/is_pointer.h>
 #include <__utility/declval.h>
 #include <variant>

diff  --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h
index de94cfb6a2353..244013cef7b64 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___MEMORY_ALLOCATOR_H
 
 #include <__config>
+#include <__memory/addressof.h>
 #include <__memory/allocate_at_least.h>
 #include <__memory/allocator_traits.h>
 #include <__type_traits/is_constant_evaluated.h>

diff  --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index c5089f3f8686d..c88ced2c5bbe5 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -35,6 +35,7 @@
 #include <__type_traits/disjunction.h>
 #include <__type_traits/is_array.h>
 #include <__type_traits/is_bounded_array.h>
+#include <__type_traits/is_convertible.h>
 #include <__type_traits/is_move_constructible.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/is_unbounded_array.h>

diff  --git a/libcxx/include/__tree b/libcxx/include/__tree
index 672b92c7796ea..8b2965ae9b51c 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -18,6 +18,7 @@
 #include <__iterator/distance.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/next.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator_traits.h>
 #include <__memory/compressed_pair.h>
 #include <__memory/pointer_traits.h>

diff  --git a/libcxx/include/any b/libcxx/include/any
index e44ec7a45b2d8..addd6d4285c0b 100644
--- a/libcxx/include/any
+++ b/libcxx/include/any
@@ -92,7 +92,9 @@ namespace std {
 #include <__type_traits/aligned_storage.h>
 #include <__type_traits/alignment_of.h>
 #include <__type_traits/conditional.h>
+#include <__type_traits/decay.h>
 #include <__type_traits/is_constructible.h>
+#include <__type_traits/is_copy_constructible.h>
 #include <__type_traits/is_function.h>
 #include <__type_traits/is_nothrow_move_constructible.h>
 #include <__type_traits/is_reference.h>

diff  --git a/libcxx/include/deque b/libcxx/include/deque
index 4ce261f2f8aa6..166a75c843fd1 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -181,6 +181,7 @@ template <class T, class Allocator, class Predicate>
 #include <__iterator/prev.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/segmented_iterator.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator_destructor.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/temp_value.h>
@@ -188,6 +189,7 @@ template <class T, class Allocator, class Predicate>
 #include <__memory_resource/polymorphic_allocator.h>
 #include <__split_buffer>
 #include <__type_traits/is_allocator.h>
+#include <__type_traits/is_convertible.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/type_identity.h>
 #include <__utility/forward.h>

diff  --git a/libcxx/include/exception b/libcxx/include/exception
index 2b5cfd52ae186..97fee977690d0 100644
--- a/libcxx/include/exception
+++ b/libcxx/include/exception
@@ -77,304 +77,20 @@ template <class E> void rethrow_if_nested(const E& e);
 */
 
 #include <__assert> // all public C++ headers provide the assertion handler
-#include <__availability>
 #include <__config>
-#include <__memory/addressof.h>
-#include <__type_traits/decay.h>
-#include <__type_traits/is_base_of.h>
-#include <__type_traits/is_class.h>
-#include <__type_traits/is_convertible.h>
-#include <__type_traits/is_copy_constructible.h>
-#include <__type_traits/is_final.h>
-#include <__type_traits/is_polymorphic.h>
-#include <__utility/forward.h>
-#include <cstddef>
-#include <cstdlib>
+#include <__exception/exception.h>
+#include <__exception/exception_ptr.h>
+#include <__exception/nested_exception.h>
+#include <__exception/operations.h>
+#include <__exception/terminate.h>
 #include <version>
 
-// <vcruntime_exception.h> defines its own std::exception and std::bad_exception types,
-// which we use in order to be ABI-compatible with other STLs on Windows.
-#if defined(_LIBCPP_ABI_VCRUNTIME)
-#  include <vcruntime_exception.h>
-#endif
-
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif
 
-namespace std  // purposefully not using versioning namespace
-{
-
-#if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0)
-// The std::exception class was already included above, but we're explicit about this condition here for clarity.
-
-#elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0
-// However, <vcruntime_exception.h> does not define std::exception and std::bad_exception
-// when _HAS_EXCEPTIONS == 0.
-//
-// Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0
-// (after all those are simply types like any other), we define an ABI-compatible version
-// of the VCRuntime std::exception and std::bad_exception types in that mode.
-
-struct __std_exception_data {
-  char const* _What;
-  bool _DoFree;
-};
-
-class exception { // base of all library exceptions
-public:
-  exception() _NOEXCEPT : __data_() {}
-
-  explicit exception(char const* __message) _NOEXCEPT : __data_() {
-    __data_._What = __message;
-    __data_._DoFree = true;
-  }
-
-  exception(exception const&) _NOEXCEPT {}
-
-  exception& operator=(exception const&) _NOEXCEPT { return *this; }
-
-  virtual ~exception() _NOEXCEPT {}
-
-  virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; }
-
-private:
-  __std_exception_data __data_;
-};
-
-class bad_exception : public exception {
-public:
-  bad_exception() _NOEXCEPT : exception("bad exception") {}
-};
-
-#else // !defined(_LIBCPP_ABI_VCRUNTIME)
-// On all other platforms, we define our own std::exception and std::bad_exception types
-// regardless of whether exceptions are turned on as a language feature.
-
-class _LIBCPP_EXCEPTION_ABI exception {
-public:
-  _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
-  _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default;
-
-  virtual ~exception() _NOEXCEPT;
-  virtual const char* what() const _NOEXCEPT;
-};
-
-class _LIBCPP_EXCEPTION_ABI bad_exception : public exception {
-public:
-  _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}
-  ~bad_exception() _NOEXCEPT override;
-  const char* what() const _NOEXCEPT override;
-};
-#endif // !_LIBCPP_ABI_VCRUNTIME
-
-#if _LIBCPP_STD_VER <= 14 \
-    || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \
-    || defined(_LIBCPP_BUILDING_LIBRARY)
-typedef void (*unexpected_handler)();
-_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
-_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
-#endif
-
-typedef void (*terminate_handler)();
-_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
-_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
-
-_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
-_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
-
-class _LIBCPP_TYPE_VIS exception_ptr;
-
-_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
-
-#ifndef _LIBCPP_ABI_MICROSOFT
-
-class _LIBCPP_TYPE_VIS exception_ptr
-{
-    void* __ptr_;
-public:
-    _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
-    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
-
-    exception_ptr(const exception_ptr&) _NOEXCEPT;
-    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
-    ~exception_ptr() _NOEXCEPT;
-
-    _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT
-    {return __ptr_ != nullptr;}
-
-    friend _LIBCPP_INLINE_VISIBILITY
-    bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
-        {return __x.__ptr_ == __y.__ptr_;}
-
-    friend _LIBCPP_INLINE_VISIBILITY
-    bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
-        {return !(__x == __y);}
-
-    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
-};
-
-template<class _Ep>
-_LIBCPP_INLINE_VISIBILITY exception_ptr
-make_exception_ptr(_Ep __e) _NOEXCEPT
-{
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
-    try
-    {
-        throw __e;
-    }
-    catch (...)
-    {
-        return current_exception();
-    }
-#else
-    ((void)__e);
-    _VSTD::abort();
-#endif
-}
-
-#else // _LIBCPP_ABI_MICROSOFT
-
-class _LIBCPP_TYPE_VIS exception_ptr
-{
-_LIBCPP_DIAGNOSTIC_PUSH
-_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field")
-    void* __ptr1_;
-    void* __ptr2_;
-_LIBCPP_DIAGNOSTIC_POP
-public:
-    exception_ptr() _NOEXCEPT;
-    exception_ptr(nullptr_t) _NOEXCEPT;
-    exception_ptr(const exception_ptr& __other) _NOEXCEPT;
-    exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
-    exception_ptr& operator=(nullptr_t) _NOEXCEPT;
-    ~exception_ptr() _NOEXCEPT;
-    explicit operator bool() const _NOEXCEPT;
-};
-
-_LIBCPP_FUNC_VIS
-bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
-
-inline _LIBCPP_INLINE_VISIBILITY
-bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
-    {return !(__x == __y);}
-
-_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
-
-_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
-_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
-_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
-
-// This is a built-in template function which automagically extracts the required
-// information.
-template <class _E> void *__GetExceptionInfo(_E);
-
-template<class _Ep>
-_LIBCPP_INLINE_VISIBILITY exception_ptr
-make_exception_ptr(_Ep __e) _NOEXCEPT
-{
-  return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
-}
-
-#endif // _LIBCPP_ABI_MICROSOFT
-// nested_exception
-
-class _LIBCPP_EXCEPTION_ABI nested_exception
-{
-    exception_ptr __ptr_;
-public:
-    nested_exception() _NOEXCEPT;
-//     nested_exception(const nested_exception&) noexcept = default;
-//     nested_exception& operator=(const nested_exception&) noexcept = default;
-    virtual ~nested_exception() _NOEXCEPT;
-
-    // access functions
-    _LIBCPP_NORETURN void rethrow_nested() const;
-    _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}
-};
-
-template <class _Tp>
-struct __nested
-    : public _Tp,
-      public nested_exception
-{
-    _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}
-};
-
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
-template <class _Tp, class _Up, bool>
-struct __throw_with_nested;
-
-template <class _Tp, class _Up>
-struct __throw_with_nested<_Tp, _Up, true> {
-    _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
-    __do_throw(_Tp&& __t)
-    {
-        throw __nested<_Up>(std::forward<_Tp>(__t));
-    }
-};
-
-template <class _Tp, class _Up>
-struct __throw_with_nested<_Tp, _Up, false> {
-    _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void
-    __do_throw(_Tp&& __t)
-    {
-        throw std::forward<_Tp>(__t);
-    }
-};
-#endif
-
-template <class _Tp>
-_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI
-void
-throw_with_nested(_Tp&& __t)
-{
-#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
-    typedef typename decay<_Tp>::type _Up;
-    static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible");
-    __throw_with_nested<_Tp, _Up,
-        is_class<_Up>::value &&
-        !is_base_of<nested_exception, _Up>::value &&
-        !__libcpp_is_final<_Up>::value>::
-            __do_throw(std::forward<_Tp>(__t));
-#else
-    ((void)__t);
-    // FIXME: Make this abort
-#endif
-}
-
-template <class _From, class _To>
-struct __can_dynamic_cast : _BoolConstant<
-              is_polymorphic<_From>::value &&
-                 (!is_base_of<_To, _From>::value ||
-                   is_convertible<const _From*, const _To*>::value)> {};
-
-template <class _Ep>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-rethrow_if_nested(const _Ep& __e,
-                  __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
-{
-    const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e));
-    if (__nep)
-        __nep->rethrow_nested();
-}
-
-template <class _Ep>
-inline _LIBCPP_INLINE_VISIBILITY
-void
-rethrow_if_nested(const _Ep&,
-                  __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0)
-{
-}
-
-} // namespace std
-
 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
+#  include <cstdlib>
 #  include <type_traits>
 #endif
 

diff  --git a/libcxx/include/istream b/libcxx/include/istream
index 1fb45fadf236a..7350e11fe129d 100644
--- a/libcxx/include/istream
+++ b/libcxx/include/istream
@@ -161,6 +161,9 @@ template <class Stream, class T>
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__iterator/istreambuf_iterator.h>
+#include <__type_traits/conjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_base_of.h>
 #include <__utility/declval.h>
 #include <__utility/forward.h>
 #include <ostream>

diff  --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp
index 8e897c9bb66e1..d85ae36953a1e 100644
--- a/libcxx/include/libcxx.imp
+++ b/libcxx/include/libcxx.imp
@@ -24,6 +24,7 @@
   { include: [ "@<__concepts/.*>", "private", "<concepts>", "public" ] },
   { include: [ "@<__coroutine/.*>", "private", "<coroutine>", "public" ] },
   { include: [ "@<__debug_utils/.*>", "private", "<debug_utils>", "public" ] },
+  { include: [ "@<__exception/.*>", "private", "<exception>", "public" ] },
   { include: [ "@<__expected/.*>", "private", "<expected>", "public" ] },
   { include: [ "@<__filesystem/.*>", "private", "<filesystem>", "public" ] },
   { include: [ "@<__format/.*>", "private", "<format>", "public" ] },

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 5f874d0d0de0c..4f8159fd07ee2 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -829,6 +829,14 @@ module std [system] {
   module exception {
     header "exception"
     export *
+
+    module __exception {
+      module exception        { private header "__exception/exception.h" }
+      module exception_ptr    { private header "__exception/exception_ptr.h" }
+      module nested_exception { private header "__exception/nested_exception.h" }
+      module operations       { private header "__exception/operations.h" }
+      module terminate        { private header "__exception/terminate.h" }
+    }
   }
   module execution {
     header "execution"
@@ -1623,7 +1631,10 @@ module std [system] {
 
     module __utility {
       module as_const            { private header "__utility/as_const.h" }
-      module auto_cast           { private header "__utility/auto_cast.h" }
+      module auto_cast           {
+        private header "__utility/auto_cast.h"
+        export type_traits.decay
+      }
       module cmp                 { private header "__utility/cmp.h" }
       module convert_to_integral { private header "__utility/convert_to_integral.h" }
       module declval             { private header "__utility/declval.h" }

diff  --git a/libcxx/include/optional b/libcxx/include/optional
index e548c47268611..641745b7bda94 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -165,6 +165,7 @@ template<class T>
 #include <__functional/hash.h>
 #include <__functional/invoke.h>
 #include <__functional/unary_function.h>
+#include <__memory/addressof.h>
 #include <__memory/construct_at.h>
 #include <__tuple_dir/sfinae_helpers.h>
 #include <__type_traits/conjunction.h>

diff  --git a/libcxx/include/ostream b/libcxx/include/ostream
index 6db0e889ce457..60f111ce6aa86 100644
--- a/libcxx/include/ostream
+++ b/libcxx/include/ostream
@@ -168,6 +168,8 @@ basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, cons
 #include <__memory/shared_ptr.h>
 #include <__memory/unique_ptr.h>
 #include <__type_traits/conjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_base_of.h>
 #include <__type_traits/void_t.h>
 #include <__utility/declval.h>
 #include <bitset>

diff  --git a/libcxx/include/span b/libcxx/include/span
index 661ae0dbec20a..2ef1ea69d9587 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -141,6 +141,7 @@ template<class R>
 #include <__ranges/enable_borrowed_range.h>
 #include <__ranges/enable_view.h>
 #include <__ranges/size.h>
+#include <__type_traits/is_convertible.h>
 #include <__type_traits/remove_cvref.h>
 #include <__type_traits/remove_reference.h>
 #include <__type_traits/type_identity.h>

diff  --git a/libcxx/include/string b/libcxx/include/string
index 3217361d00f6a..9a84440555aa8 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -550,6 +550,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/wrap_iter.h>
+#include <__memory/addressof.h>
 #include <__memory/allocate_at_least.h>
 #include <__memory/allocator.h>
 #include <__memory/allocator_traits.h>
@@ -562,6 +563,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len );
 #include <__string/extern_template_lists.h>
 #include <__type_traits/is_allocator.h>
 #include <__type_traits/is_array.h>
+#include <__type_traits/is_convertible.h>
 #include <__type_traits/is_nothrow_default_constructible.h>
 #include <__type_traits/is_nothrow_move_assignable.h>
 #include <__type_traits/is_same.h>

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index d5629b706d839..b61ca9e9d5363 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -220,6 +220,7 @@ namespace std {
 #include <__ranges/size.h>
 #include <__string/char_traits.h>
 #include <__type_traits/is_array.h>
+#include <__type_traits/is_convertible.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_standard_layout.h>
 #include <__type_traits/is_trivial.h>

diff  --git a/libcxx/include/valarray b/libcxx/include/valarray
index a52fc1088e467..f305bac8bc764 100644
--- a/libcxx/include/valarray
+++ b/libcxx/include/valarray
@@ -351,8 +351,10 @@ template <class T> unspecified2 end(const valarray<T>& v);
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <__functional/operations.h>
+#include <__memory/addressof.h>
 #include <__memory/allocator.h>
 #include <__memory/uninitialized_algorithms.h>
+#include <__type_traits/decay.h>
 #include <__type_traits/remove_reference.h>
 #include <__utility/move.h>
 #include <__utility/swap.h>

diff  --git a/libcxx/include/variant b/libcxx/include/variant
index 0f4600eea49b1..88f63dd5610ab 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -214,6 +214,7 @@ namespace std {
 #include <__functional/invoke.h>
 #include <__functional/operations.h>
 #include <__functional/unary_function.h>
+#include <__memory/addressof.h>
 #include <__type_traits/add_const.h>
 #include <__type_traits/add_cv.h>
 #include <__type_traits/add_pointer.h>

diff  --git a/libcxx/include/vector b/libcxx/include/vector
index 6c25e5de718a0..980af582558be 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -299,6 +299,7 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++
 #include <__iterator/iterator_traits.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/wrap_iter.h>
+#include <__memory/addressof.h>
 #include <__memory/allocate_at_least.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/swap_allocator.h>

diff  --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index 0f611ce5eec75..7ec1762874625 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -329,6 +329,11 @@ END-SCRIPT
 #include <__coroutine/trivial_awaitables.h> // expected-error@*:* {{use of private header from outside its module: '__coroutine/trivial_awaitables.h'}}
 #include <__debug_utils/randomize_range.h> // expected-error@*:* {{use of private header from outside its module: '__debug_utils/randomize_range.h'}}
 #include <__errc> // expected-error@*:* {{use of private header from outside its module: '__errc'}}
+#include <__exception/exception.h> // expected-error@*:* {{use of private header from outside its module: '__exception/exception.h'}}
+#include <__exception/exception_ptr.h> // expected-error@*:* {{use of private header from outside its module: '__exception/exception_ptr.h'}}
+#include <__exception/nested_exception.h> // expected-error@*:* {{use of private header from outside its module: '__exception/nested_exception.h'}}
+#include <__exception/operations.h> // expected-error@*:* {{use of private header from outside its module: '__exception/operations.h'}}
+#include <__exception/terminate.h> // expected-error@*:* {{use of private header from outside its module: '__exception/terminate.h'}}
 #include <__expected/bad_expected_access.h> // expected-error@*:* {{use of private header from outside its module: '__expected/bad_expected_access.h'}}
 #include <__expected/expected.h> // expected-error@*:* {{use of private header from outside its module: '__expected/expected.h'}}
 #include <__expected/unexpect.h> // expected-error@*:* {{use of private header from outside its module: '__expected/unexpect.h'}}

diff  --git a/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp b/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp
index 9589e63643941..fec48b325e90e 100644
--- a/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <array>
 #include <cassert>
+#include <memory>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
index dc52cb8635937..5d200a4bf808f 100644
--- a/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
+++ b/libcxx/test/std/utilities/memory/allocator.uses/allocator.uses.trait/uses_allocator.pass.cpp
@@ -12,6 +12,7 @@
 
 #include <memory>
 #include <vector>
+#include <type_traits>
 
 #include "test_macros.h"
 

diff  --git a/libcxx/utils/data/ignore_format.txt b/libcxx/utils/data/ignore_format.txt
index 387f4c5f36d49..945af7ebd1fc8 100644
--- a/libcxx/utils/data/ignore_format.txt
+++ b/libcxx/utils/data/ignore_format.txt
@@ -317,7 +317,6 @@ libcxx/include/__debug_utils/randomize_range.h
 libcxx/include/deque
 libcxx/include/__errc
 libcxx/include/errno.h
-libcxx/include/exception
 libcxx/include/execution
 libcxx/include/expected
 libcxx/include/__expected/expected.h


        


More information about the libcxx-commits mailing list