Skip to content

[libc++][modules] Modularize <cstddef> #107254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Sep 4, 2024

Many headers include <cstddef> just for size_t, and pulling in additional content (e.g. the traits used for std::byte) is unnecessary. To solve this problem, this patch splits up <cstddef> into subcomponents so that headers can include only the parts that they actually require.

This has the added benefit of making the modules build a lot stricter with respect to IWYU, and also providing a canonical location where we define std::size_t and friends (which were previously defined in multiple headers like <cstddef> and <ctime>).

After this patch, there's still many places in the codebase where we include <cstddef> when <__cstddef/size_t.h> would be sufficient. This patch focuses on removing <cstddef> includes from __type_traits to make these headers non-circular with <cstddef>. Additional refactorings can be tackled separately.

@ldionne ldionne requested a review from a team as a code owner September 4, 2024 15:15
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 4, 2024
@ldionne ldionne changed the title [libc++] Modularize <cstddef> [libc++][modules] Modularize <cstddef> Sep 4, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 4, 2024

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

Many headers include <cstddef> just for size_t, and pulling in additional content (e.g. the traits used for std::byte) is unnecessary. To solve this problem, this patch splits up &lt;cstddef&gt; into subcomponents so that headers can include only the parts that they actually require.

This has the added benefit of making the modules build a lot stricter with respect to IWYU, and also providing a canonical location where we define std::size_t and friends (which were previously defined in multiple headers like <cstddef> and <ctime>).

After this patch, there's still many places in the codebase where we include <cstddef> when <__cstddef/size_t.h> would be sufficient. This patch focuses on removing <cstddef> includes from __type_traits to make these headers non-circular with <cstddef>. Additional refactorings can be tackled separately.


Patch is 40.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/107254.diff

62 Files Affected:

  • (modified) libcxx/include/CMakeLists.txt (+5)
  • (modified) libcxx/include/__algorithm/ranges_minmax.h (+1)
  • (modified) libcxx/include/__atomic/atomic.h (+2)
  • (modified) libcxx/include/__charconv/to_chars_integral.h (+1)
  • (added) libcxx/include/__cstddef/byte.h (+84)
  • (added) libcxx/include/__cstddef/max_align_t.h (+27)
  • (added) libcxx/include/__cstddef/nullptr_t.h (+25)
  • (added) libcxx/include/__cstddef/ptrdiff_t.h (+25)
  • (added) libcxx/include/__cstddef/size_t.h (+25)
  • (modified) libcxx/include/__exception/nested_exception.h (+2)
  • (modified) libcxx/include/__fwd/array.h (+2-1)
  • (modified) libcxx/include/__fwd/complex.h (+1-1)
  • (modified) libcxx/include/__fwd/pair.h (+1-1)
  • (modified) libcxx/include/__fwd/span.h (+1-1)
  • (modified) libcxx/include/__fwd/subrange.h (+1-1)
  • (modified) libcxx/include/__fwd/tuple.h (+1-1)
  • (modified) libcxx/include/__iterator/iterator_traits.h (+1)
  • (modified) libcxx/include/__mdspan/layout_stride.h (+1)
  • (modified) libcxx/include/__memory/pointer_traits.h (+1)
  • (modified) libcxx/include/__memory/shared_ptr.h (+2)
  • (modified) libcxx/include/__memory/unique_ptr.h (+1)
  • (modified) libcxx/include/__memory/uses_allocator.h (+1)
  • (modified) libcxx/include/__random/mersenne_twister_engine.h (+1)
  • (modified) libcxx/include/__random/seed_seq.h (+2)
  • (modified) libcxx/include/__random/subtract_with_carry_engine.h (+1)
  • (modified) libcxx/include/__ranges/subrange.h (+1)
  • (modified) libcxx/include/__string/constexpr_c_functions.h (+2)
  • (modified) libcxx/include/__tuple/tuple_size.h (+2)
  • (modified) libcxx/include/__type_traits/aligned_storage.h (+1-1)
  • (modified) libcxx/include/__type_traits/aligned_union.h (+1-1)
  • (modified) libcxx/include/__type_traits/alignment_of.h (+1-1)
  • (modified) libcxx/include/__type_traits/extent.h (+1-1)
  • (modified) libcxx/include/__type_traits/is_allocator.h (+1-1)
  • (modified) libcxx/include/__type_traits/is_array.h (+1-1)
  • (modified) libcxx/include/__type_traits/is_bounded_array.h (+1-1)
  • (modified) libcxx/include/__type_traits/is_nothrow_destructible.h (+1-1)
  • (modified) libcxx/include/__type_traits/is_null_pointer.h (+1-1)
  • (modified) libcxx/include/__type_traits/is_swappable.h (+1-1)
  • (modified) libcxx/include/__type_traits/rank.h (+1-1)
  • (modified) libcxx/include/__type_traits/remove_all_extents.h (+1-1)
  • (modified) libcxx/include/__type_traits/remove_extent.h (+1-1)
  • (modified) libcxx/include/__type_traits/type_list.h (+1-1)
  • (modified) libcxx/include/__utility/in_place.h (+1)
  • (modified) libcxx/include/__utility/pair.h (+1)
  • (modified) libcxx/include/__utility/swap.h (+1)
  • (modified) libcxx/include/any (+1)
  • (modified) libcxx/include/cstddef (+5-78)
  • (modified) libcxx/include/cstdio (+1-1)
  • (modified) libcxx/include/cstdlib (+1-1)
  • (modified) libcxx/include/cstring (+1-1)
  • (modified) libcxx/include/ctime (+1-1)
  • (modified) libcxx/include/cuchar (+1-1)
  • (modified) libcxx/include/cwchar (+1-1)
  • (modified) libcxx/include/experimental/__simd/reference.h (+1)
  • (modified) libcxx/include/experimental/__simd/scalar.h (+1)
  • (modified) libcxx/include/experimental/__simd/simd.h (+1)
  • (modified) libcxx/include/experimental/__simd/simd_mask.h (+1)
  • (modified) libcxx/include/experimental/__simd/vec_ext.h (+1)
  • (modified) libcxx/include/module.modulemap (+9-1)
  • (modified) libcxx/include/typeinfo (+1)
  • (modified) libcxx/include/unordered_map (+2)
  • (modified) libcxx/include/unordered_set (+2)
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 32579272858a8e..1f8ff29e2e2cfb 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -324,6 +324,11 @@ set(files
   __coroutine/coroutine_traits.h
   __coroutine/noop_coroutine_handle.h
   __coroutine/trivial_awaitables.h
+  __cstddef/byte.h
+  __cstddef/max_align_t.h
+  __cstddef/nullptr_t.h
+  __cstddef/ptrdiff_t.h
+  __cstddef/size_t.h
   __debug_utils/randomize_range.h
   __debug_utils/sanitizers.h
   __debug_utils/strict_weak_ordering_check.h
diff --git a/libcxx/include/__algorithm/ranges_minmax.h b/libcxx/include/__algorithm/ranges_minmax.h
index 1b43b1e19cdec9..5f2e5cb2a1eeab 100644
--- a/libcxx/include/__algorithm/ranges_minmax.h
+++ b/libcxx/include/__algorithm/ranges_minmax.h
@@ -24,6 +24,7 @@
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
 #include <__type_traits/desugars_to.h>
+#include <__type_traits/is_integral.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/is_trivially_copyable.h>
 #include <__type_traits/remove_cvref.h>
diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index bcea21f5ce2e17..af6d12b5e4ce91 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -16,8 +16,10 @@
 #include <__config>
 #include <__functional/operations.h>
 #include <__memory/addressof.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/is_floating_point.h>
 #include <__type_traits/is_function.h>
+#include <__type_traits/is_integral.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/remove_const.h>
 #include <__type_traits/remove_pointer.h>
diff --git a/libcxx/include/__charconv/to_chars_integral.h b/libcxx/include/__charconv/to_chars_integral.h
index 0369f4dfb9bda6..ccb5856df17993 100644
--- a/libcxx/include/__charconv/to_chars_integral.h
+++ b/libcxx/include/__charconv/to_chars_integral.h
@@ -21,6 +21,7 @@
 #include <__system_error/errc.h>
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
+#include <__type_traits/is_integral.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/make_32_64_or_128_bit.h>
 #include <__type_traits/make_unsigned.h>
diff --git a/libcxx/include/__cstddef/byte.h b/libcxx/include/__cstddef/byte.h
new file mode 100644
index 00000000000000..b8cfe5e8d1c7ef
--- /dev/null
+++ b/libcxx/include/__cstddef/byte.h
@@ -0,0 +1,84 @@
+//===---------------------------------------------------------------------===//
+//
+// 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___CSTDDEF_BYTE_H
+#define _LIBCPP___CSTDDEF_BYTE_H
+
+#include <__config>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_integral.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 17
+namespace std { // purposefully not versioned
+
+enum class byte : unsigned char {};
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte operator|(byte __lhs, byte __rhs) noexcept {
+  return static_cast<byte>(
+      static_cast<unsigned char>(static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs)));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept {
+  return __lhs = __lhs | __rhs;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte operator&(byte __lhs, byte __rhs) noexcept {
+  return static_cast<byte>(
+      static_cast<unsigned char>(static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs)));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept {
+  return __lhs = __lhs & __rhs;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte operator^(byte __lhs, byte __rhs) noexcept {
+  return static_cast<byte>(
+      static_cast<unsigned char>(static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs)));
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept {
+  return __lhs = __lhs ^ __rhs;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr byte operator~(byte __b) noexcept {
+  return static_cast<byte>(static_cast<unsigned char>(~static_cast<unsigned int>(__b)));
+}
+
+template <class _Integer, __enable_if_t<is_integral<_Integer>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI constexpr byte& operator<<=(byte& __lhs, _Integer __shift) noexcept {
+  return __lhs = __lhs << __shift;
+}
+
+template <class _Integer, __enable_if_t<is_integral<_Integer>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI constexpr byte operator<<(byte __lhs, _Integer __shift) noexcept {
+  return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) << __shift));
+}
+
+template <class _Integer, __enable_if_t<is_integral<_Integer>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI constexpr byte& operator>>=(byte& __lhs, _Integer __shift) noexcept {
+  return __lhs = __lhs >> __shift;
+}
+
+template <class _Integer, __enable_if_t<is_integral<_Integer>::value, int> = 0>
+_LIBCPP_HIDE_FROM_ABI constexpr byte operator>>(byte __lhs, _Integer __shift) noexcept {
+  return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift));
+}
+
+template <class _Integer, __enable_if_t<is_integral<_Integer>::value, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Integer to_integer(byte __b) noexcept {
+  return static_cast<_Integer>(__b);
+}
+
+} // namespace std
+#endif // _LIBCPP_STD_VER >= 17
+
+#endif // _LIBCPP___CSTDDEF_BYTE_H
diff --git a/libcxx/include/__cstddef/max_align_t.h b/libcxx/include/__cstddef/max_align_t.h
new file mode 100644
index 00000000000000..7c09c7e7f30172
--- /dev/null
+++ b/libcxx/include/__cstddef/max_align_t.h
@@ -0,0 +1,27 @@
+//===---------------------------------------------------------------------===//
+//
+// 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___CSTDDEF_MAX_ALIGN_T_H
+#define _LIBCPP___CSTDDEF_MAX_ALIGN_T_H
+
+#include <__config>
+#include <stddef.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_CXX03_LANG)
+using ::max_align_t _LIBCPP_USING_IF_EXISTS;
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CSTDDEF_MAX_ALIGN_T_H
diff --git a/libcxx/include/__cstddef/nullptr_t.h b/libcxx/include/__cstddef/nullptr_t.h
new file mode 100644
index 00000000000000..de3f7d4ab5fa75
--- /dev/null
+++ b/libcxx/include/__cstddef/nullptr_t.h
@@ -0,0 +1,25 @@
+//===---------------------------------------------------------------------===//
+//
+// 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___CSTDDEF_NULLPTR_T_H
+#define _LIBCPP___CSTDDEF_NULLPTR_T_H
+
+#include <__config>
+#include <stddef.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::nullptr_t;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CSTDDEF_NULLPTR_T_H
diff --git a/libcxx/include/__cstddef/ptrdiff_t.h b/libcxx/include/__cstddef/ptrdiff_t.h
new file mode 100644
index 00000000000000..f8b5cdaaff01c9
--- /dev/null
+++ b/libcxx/include/__cstddef/ptrdiff_t.h
@@ -0,0 +1,25 @@
+//===---------------------------------------------------------------------===//
+//
+// 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___CSTDDEF_PTRDIFF_T_H
+#define _LIBCPP___CSTDDEF_PTRDIFF_T_H
+
+#include <__config>
+#include <stddef.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::ptrdiff_t _LIBCPP_USING_IF_EXISTS;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CSTDDEF_PTRDIFF_T_H
diff --git a/libcxx/include/__cstddef/size_t.h b/libcxx/include/__cstddef/size_t.h
new file mode 100644
index 00000000000000..91abbf01318953
--- /dev/null
+++ b/libcxx/include/__cstddef/size_t.h
@@ -0,0 +1,25 @@
+//===---------------------------------------------------------------------===//
+//
+// 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___CSTDDEF_SIZE_T_H
+#define _LIBCPP___CSTDDEF_SIZE_T_H
+
+#include <__config>
+#include <stddef.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+using ::size_t _LIBCPP_USING_IF_EXISTS;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___CSTDDEF_SIZE_T_H
diff --git a/libcxx/include/__exception/nested_exception.h b/libcxx/include/__exception/nested_exception.h
index feb489f87f62f5..4c7970d167ffa5 100644
--- a/libcxx/include/__exception/nested_exception.h
+++ b/libcxx/include/__exception/nested_exception.h
@@ -13,6 +13,8 @@
 #include <__exception/exception_ptr.h>
 #include <__memory/addressof.h>
 #include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_base_of.h>
 #include <__type_traits/is_class.h>
 #include <__type_traits/is_constructible.h>
diff --git a/libcxx/include/__fwd/array.h b/libcxx/include/__fwd/array.h
index b429d0c5a95427..d7ca6c738a7d0c 100644
--- a/libcxx/include/__fwd/array.h
+++ b/libcxx/include/__fwd/array.h
@@ -10,7 +10,8 @@
 #define _LIBCPP___FWD_ARRAY_H
 
 #include <__config>
-#include <cstddef>
+#include <__cstddef/size_t.h>
+#include <__type_traits/integral_constant.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__fwd/complex.h b/libcxx/include/__fwd/complex.h
index 22c78c5cc3c77a..092d2e10b12b5b 100644
--- a/libcxx/include/__fwd/complex.h
+++ b/libcxx/include/__fwd/complex.h
@@ -10,7 +10,7 @@
 #define _LIBCPP___FWD_COMPLEX_H
 
 #include <__config>
-#include <cstddef>
+#include <__cstddef/size_t.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__fwd/pair.h b/libcxx/include/__fwd/pair.h
index af32628fe1e0d0..b8ba2b7e923241 100644
--- a/libcxx/include/__fwd/pair.h
+++ b/libcxx/include/__fwd/pair.h
@@ -10,8 +10,8 @@
 #define _LIBCPP___FWD_PAIR_H
 
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__fwd/tuple.h>
-#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__fwd/span.h b/libcxx/include/__fwd/span.h
index 8dafa742c19df5..5d473ee51c6b74 100644
--- a/libcxx/include/__fwd/span.h
+++ b/libcxx/include/__fwd/span.h
@@ -11,7 +11,7 @@
 #define _LIBCPP___FWD_SPAN_H
 
 #include <__config>
-#include <cstddef>
+#include <__cstddef/size_t.h>
 #include <limits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
diff --git a/libcxx/include/__fwd/subrange.h b/libcxx/include/__fwd/subrange.h
index 60a41da23dd44e..5b3a07e55348a6 100644
--- a/libcxx/include/__fwd/subrange.h
+++ b/libcxx/include/__fwd/subrange.h
@@ -11,8 +11,8 @@
 
 #include <__concepts/copyable.h>
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__iterator/concepts.h>
-#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__fwd/tuple.h b/libcxx/include/__fwd/tuple.h
index 902770c29555ed..2ed32bc0df4e14 100644
--- a/libcxx/include/__fwd/tuple.h
+++ b/libcxx/include/__fwd/tuple.h
@@ -10,7 +10,7 @@
 #define _LIBCPP___FWD_TUPLE_H
 
 #include <__config>
-#include <cstddef>
+#include <__cstddef/size_t.h>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h
index 11af9e301842cf..35e4cc6f10efdb 100644
--- a/libcxx/include/__iterator/iterator_traits.h
+++ b/libcxx/include/__iterator/iterator_traits.h
@@ -24,6 +24,7 @@
 #include <__type_traits/common_reference.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/disjunction.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/is_convertible.h>
 #include <__type_traits/is_object.h>
 #include <__type_traits/is_primary_template.h>
diff --git a/libcxx/include/__mdspan/layout_stride.h b/libcxx/include/__mdspan/layout_stride.h
index 86148ac849eca5..c386ab81251cd0 100644
--- a/libcxx/include/__mdspan/layout_stride.h
+++ b/libcxx/include/__mdspan/layout_stride.h
@@ -23,6 +23,7 @@
 #include <__mdspan/extents.h>
 #include <__type_traits/is_constructible.h>
 #include <__type_traits/is_convertible.h>
+#include <__type_traits/is_integral.h>
 #include <__type_traits/is_nothrow_constructible.h>
 #include <__utility/as_const.h>
 #include <__utility/integer_sequence.h>
diff --git a/libcxx/include/__memory/pointer_traits.h b/libcxx/include/__memory/pointer_traits.h
index 0914aceb318b74..8e08eb74413ee5 100644
--- a/libcxx/include/__memory/pointer_traits.h
+++ b/libcxx/include/__memory/pointer_traits.h
@@ -15,6 +15,7 @@
 #include <__type_traits/conditional.h>
 #include <__type_traits/conjunction.h>
 #include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/is_class.h>
 #include <__type_traits/is_function.h>
 #include <__type_traits/is_void.h>
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index d487e4fbe3a953..4dd8022822d223 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -34,6 +34,8 @@
 #include <__type_traits/conditional.h>
 #include <__type_traits/conjunction.h>
 #include <__type_traits/disjunction.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_array.h>
 #include <__type_traits/is_bounded_array.h>
 #include <__type_traits/is_constructible.h>
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 7f5e0ea243c956..392cf421378214 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -23,6 +23,7 @@
 #include <__type_traits/common_type.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/dependent_type.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_array.h>
 #include <__type_traits/is_assignable.h>
diff --git a/libcxx/include/__memory/uses_allocator.h b/libcxx/include/__memory/uses_allocator.h
index 84310c3fa56739..16504e8b2a9989 100644
--- a/libcxx/include/__memory/uses_allocator.h
+++ b/libcxx/include/__memory/uses_allocator.h
@@ -11,6 +11,7 @@
 #define _LIBCPP___MEMORY_USES_ALLOCATOR_H
 
 #include <__config>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_convertible.h>
 #include <cstddef>
 
diff --git a/libcxx/include/__random/mersenne_twister_engine.h b/libcxx/include/__random/mersenne_twister_engine.h
index 65280d7c5505f7..1f50e608ce8d4e 100644
--- a/libcxx/include/__random/mersenne_twister_engine.h
+++ b/libcxx/include/__random/mersenne_twister_engine.h
@@ -13,6 +13,7 @@
 #include <__algorithm/min.h>
 #include <__config>
 #include <__random/is_seed_sequence.h>
+#include <__type_traits/enable_if.h>
 #include <cstddef>
 #include <cstdint>
 #include <iosfwd>
diff --git a/libcxx/include/__random/seed_seq.h b/libcxx/include/__random/seed_seq.h
index 5cf84aeb8a72b3..c1a320a75c88aa 100644
--- a/libcxx/include/__random/seed_seq.h
+++ b/libcxx/include/__random/seed_seq.h
@@ -14,6 +14,8 @@
 #include <__algorithm/max.h>
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/is_integral.h>
 #include <__type_traits/is_unsigned.h>
 #include <cstdint>
 #include <initializer_list>
diff --git a/libcxx/include/__random/subtract_with_carry_engine.h b/libcxx/include/__random/subtract_with_carry_engine.h
index ec25fed49f9498..926333cdda45ee 100644
--- a/libcxx/include/__random/subtract_with_carry_engine.h
+++ b/libcxx/include/__random/subtract_with_carry_engine.h
@@ -14,6 +14,7 @@
 #include <__config>
 #include <__random/is_seed_sequence.h>
 #include <__random/linear_congruential_engine.h>
+#include <__type_traits/enable_if.h>
 #include <cstddef>
 #include <cstdint>
 #include <iosfwd>
diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h
index aba584ef933542..144746babb325f 100644
--- a/libcxx/include/__ranges/subrange.h
+++ b/libcxx/include/__ranges/subrange.h
@@ -33,6 +33,7 @@
 #include <__tuple/tuple_size.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/decay.h>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_pointer.h>
 #include <__type_traits/is_reference.h>
 #include <__type_traits/make_unsigned.h>
diff --git a/libcxx/include/__string/constexpr_c_functions.h b/libcxx/include/__string/constexpr_c_functions.h
index 32fc06e121b362..9b8871e2e71a38 100644
--- a/libcxx/include/__string/constexpr_c_functions.h
+++ b/libcxx/include/__string/constexpr_c_functions.h
@@ -13,11 +13,13 @@
 #include <__memory/addressof.h>
 #include <__memory/construct_at.h>
 #include <__type_traits/datasizeof.h>
+#include <__type_traits/enable_if.h>
 #include <__type_traits/is_always_bitcastable.h>
 #include <__type_traits/is_assignable.h>
 #include <__type_traits/is_constant_evaluated.h>
 #include <__type_traits/is_constructible.h>
 #include <__type_traits/is_equality_comparable.h>
+#include <__type_traits/is_integral.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/is_trivially_copyable.h>
 #include <__type_traits/is_trivially_lexicographically_comparable.h>
diff --git a/libcxx/include/__tuple/tuple_size.h b/libcxx/include/__tuple/tuple_size.h
index 18a17fd4d58780..21c9811abeee7b 100644
--- a/libcxx/include/__tuple/tuple_size.h
+++ b/libcxx/include/__tuple/tuple_size.h
@@ -12,6 +12,8 @@
 #include <__config>
 #include <__fwd/tuple.h>
 #include <__tuple/tuple_types.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
 #include <__type_traits/is_const.h>
 #include <__type_traits/is_volatile.h>
 #include <cstddef>
diff --git a/libcxx/include/__type_traits/aligned_storage.h b/libcxx/include/__type_traits/aligned_storage.h
index 46aae12832f867..49b4e971bbb675 100644
--- a/libcxx/include/__type_traits/aligned_storage.h
+++ b/libcxx/include/__type_traits/aligned_storage.h
@@ -10,11 +10,11 @@
 #define _LIBCPP___TYPE_TRAITS_ALIGNED_STORAGE_H
 
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/nat.h>
 #include <__type_traits/type_list.h>
-#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__type_traits/aligned_union.h b/libcxx/include/__type_traits/aligned_union.h
index 005ed9a096ea8e..de62a4b1c2a331 100644
--- a/libcxx/include/__type_traits/aligned_union.h
+++ b/libcxx/include/__type_traits/aligned_union.h
@@ -10,9 +10,9 @@
 #define _LIBCPP___TYPE_TRAITS_ALIGNED_UNION_H
 
 #include <__config>
+#include <__cstddef/size_t.h>
 #include <__type_traits/aligned_storage.h>
 #include <__type_traits/integral_constant.h>
-#include <cstddef>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
diff --git a/libcxx/include/__type_traits/alignment_of.h b/libcxx/include/__type_traits/alignment_of.h
index f2d069bf2488f7..8871c8ce110d67 100644
--- a/libcxx/include/_...
[truncated]

@philnik777
Copy link
Contributor

Is there a reason we wouldn't instead just include <stddef.h> instread of <cstddef>?

@ldionne
Copy link
Member Author

ldionne commented Sep 4, 2024

Is there a reason we wouldn't instead just include <stddef.h> instread of <cstddef>?

Because that defines ::size_t, not std::size_t. We still need a canonical place to define std::size_t and that's also a problem that __cstddef/size_t.h solves. Additionally, this patch provides a path towards defining std::size_t in libc++ itself without relying on stddef.h in the future, which could be nice to reduce our dependency on a base C standard library.

@ldionne ldionne force-pushed the review/modularization-introduce-stddef-module branch from 9f8fae4 to 6a2351d Compare September 4, 2024 17:11
Many headers include <cstddef> just for size_t, and pulling in additional
content (e.g. the traits used for std::byte) is unnecessary. To solve
this problem, this patch splits up `<cstddef>` into subcomponents so
that headers can include only the parts that they actually require.

This has the added benefit of making the modules build a lot stricter
with respect to IWYU, and also providing a canonical location where
we define `std::size_t` and friends (which were previously defined in
multiple headers like <cstddef> and <ctime>).

After this patch, there's still many places in the codebase where we
include <cstddef> when <__cstddef/size_t.h> would be sufficient. This
patch focuses on removing <cstddef> includes from __type_traits to make
these headers non-circular with <cstddef>. Additional refactorings can
be tackled separately.
@ldionne ldionne force-pushed the review/modularization-introduce-stddef-module branch from 9f919cd to c10c1ad Compare September 4, 2024 20:51
@philnik777
Copy link
Contributor

That makes sense. I feel these headers a bit too granular though. Maybe we could just have __cstddef/aliases.h and __cstddef/byte.h? Having four headers for four aliases seems a bit overkill.

@ldionne
Copy link
Member Author

ldionne commented Sep 5, 2024

That makes sense. I feel these headers a bit too granular though. Maybe we could just have __cstddef/aliases.h and __cstddef/byte.h? Having four headers for four aliases seems a bit overkill.

Some headers like <cstdio> want to redeclare std::size_t but not e.g. std::nullptr_t or std::ptrdiff_t. We could technically have __cstddef/byte.h, __cstddef/size_t.h and __cstddef/others.h but IMO it's better to be consistent than save 1-2 headers.

@ldionne ldionne merged commit d6832a6 into llvm:main Sep 5, 2024
62 of 64 checks passed
@ldionne ldionne deleted the review/modularization-introduce-stddef-module branch September 5, 2024 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants