[libcxx-commits] [libcxx] 2d0f1fa - [libc++] Header inclusion tests.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 6 12:32:10 PDT 2021


Author: Arthur O'Dwyer
Date: 2021-04-06T15:31:56-04:00
New Revision: 2d0f1fa472a99dbb46735623363fe918feeda795

URL: https://github.com/llvm/llvm-project/commit/2d0f1fa472a99dbb46735623363fe918feeda795
DIFF: https://github.com/llvm/llvm-project/commit/2d0f1fa472a99dbb46735623363fe918feeda795.diff

LOG: [libc++] Header inclusion tests.

As mandated by the Standard's various synopses, e.g. [iterator.synopsis].
Searching the TeX source for '#include' is a good way to find all of these
mandates.

The new tests are all autogenerated by utils/generate_header_inclusion_tests.py.
I was SHOCKED by how many mandates there are, and how many of them
libc++ wasn't conforming with.

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

Added: 
    libcxx/test/libcxx/inclusions/algorithm.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/array.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/bitset.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/chrono.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/cinttypes.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/complex.h.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/deque.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/filesystem.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/forward_list.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/ios.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/iostream.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/iterator.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/list.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/map.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/memory.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/optional.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/queue.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/random.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/regex.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/set.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/stack.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/string.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/string_view.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/system_error.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/tgmath.h.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/thread.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/tuple.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/typeindex.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/unordered_map.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/unordered_set.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/utility.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/valarray.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/variant.inclusions.compile.pass.cpp
    libcxx/test/libcxx/inclusions/vector.inclusions.compile.pass.cpp
    libcxx/utils/generate_header_inclusion_tests.py

Modified: 
    libcxx/docs/Contributing.rst
    libcxx/include/chrono
    libcxx/include/deque
    libcxx/include/filesystem
    libcxx/include/iterator
    libcxx/include/map
    libcxx/include/memory
    libcxx/include/optional
    libcxx/include/queue
    libcxx/include/regex
    libcxx/include/set
    libcxx/include/string
    libcxx/include/string_view
    libcxx/include/system_error
    libcxx/include/tuple
    libcxx/include/typeindex
    libcxx/include/unordered_map
    libcxx/include/unordered_set
    libcxx/include/utility
    libcxx/include/variant
    libcxx/include/vector

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Contributing.rst b/libcxx/docs/Contributing.rst
index 20b614f177bc6..de71c7efa0753 100644
--- a/libcxx/docs/Contributing.rst
+++ b/libcxx/docs/Contributing.rst
@@ -45,9 +45,10 @@ Adding a new header TODO
 When adding a new header to libc++:
 
 1. Add a test under ``test/libcxx`` that the new header defines ``_LIBCPP_VERSION``. See ``test/libcxx/algorithms/version.pass.cpp`` for an example.
-2. Run ``python utils/generate_header_tests.py``, verify and commit the modifications.
-3. Create a submodule in ``include/module.modulemap`` for the new header.
-4. Update the ``include/CMakeLists.txt`` file to include the new header.
+2. Run ``python utils/generate_header_tests.py``; verify and commit the changes.
+3. Modify ``python utils/generate_header_inclusion_tests.py``; run it; verify and commit the changes.
+4. Create a submodule in ``include/module.modulemap`` for the new header.
+5. Update the ``include/CMakeLists.txt`` file to include the new header.
 
 Exporting new symbols from the library
 ======================================

diff  --git a/libcxx/include/chrono b/libcxx/include/chrono
index c8aab5d963236..d6a0de87a1a54 100644
--- a/libcxx/include/chrono
+++ b/libcxx/include/chrono
@@ -825,6 +825,7 @@ constexpr chrono::year                                  operator ""y(unsigned lo
 
 #include <__config>
 #include <__availability>
+#include <compare>
 #include <ctime>
 #include <type_traits>
 #include <ratio>

diff  --git a/libcxx/include/deque b/libcxx/include/deque
index 429dcabeacd7e..607611c378fc7 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -162,6 +162,7 @@ template <class T, class Allocator, class Predicate>
 
 #include <__config>
 #include <__split_buffer>
+#include <compare>
 #include <type_traits>
 #include <initializer_list>
 #include <iterator>

diff  --git a/libcxx/include/filesystem b/libcxx/include/filesystem
index dc4ac6d30db1d..fcfc63798b302 100644
--- a/libcxx/include/filesystem
+++ b/libcxx/include/filesystem
@@ -234,6 +234,7 @@
 #include <cstddef>
 #include <cstdlib>
 #include <chrono>
+#include <compare>
 #include <iterator>
 #include <iosfwd>
 #include <memory>

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index c02f5232880d3..54ea2aab1325f 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -418,6 +418,8 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 #include <iosfwd> // for forward declarations of vector and string.
 #include <__functional_base>
 #include <type_traits>
+#include <compare>
+#include <concepts>
 #include <cstddef>
 #include <initializer_list>
 #include <__memory/base.h>

diff  --git a/libcxx/include/map b/libcxx/include/map
index 9c3e5e64a0985..ddb596f8f6317 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -480,6 +480,8 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20
 #include <__config>
 #include <__tree>
 #include <__node_handle>
+#include <compare>
+#include <initializer_list>
 #include <iterator> // __libcpp_erase_if_container
 #include <memory>
 #include <utility>

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 3fa0f2c4ca34a..484dafe7677c9 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -668,6 +668,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 #include <__availability>
 #include <type_traits>
 #include <typeinfo>
+#include <compare>
 #include <cstddef>
 #include <cstdint>
 #include <new>

diff  --git a/libcxx/include/optional b/libcxx/include/optional
index 97a0bbe66ca97..1de9c8a07802d 100644
--- a/libcxx/include/optional
+++ b/libcxx/include/optional
@@ -150,6 +150,7 @@ template<class T>
 #include <__availability>
 #include <__debug>
 #include <__functional_base>
+#include <compare>
 #include <functional>
 #include <initializer_list>
 #include <new>

diff  --git a/libcxx/include/queue b/libcxx/include/queue
index 05cc2466baa40..5091f67b84437 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -179,6 +179,7 @@ template <class T, class Container, class Compare>
 */
 
 #include <__config>
+#include <compare>
 #include <deque>
 #include <vector>
 #include <functional>

diff  --git a/libcxx/include/regex b/libcxx/include/regex
index d78e4888a6197..466146d6d141e 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -765,6 +765,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
 #include <__config>
 #include <stdexcept>
 #include <__locale>
+#include <compare>
 #include <initializer_list>
 #include <utility>
 #include <iterator>

diff  --git a/libcxx/include/set b/libcxx/include/set
index a5cf39995f2da..11991affb66e0 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -428,7 +428,9 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);  // C++20
 #include <__config>
 #include <__tree>
 #include <__node_handle>
+#include <compare>
 #include <functional>
+#include <initializer_list>
 #include <iterator> // __libcpp_erase_if_container
 #include <version>
 

diff  --git a/libcxx/include/string b/libcxx/include/string
index 5f49b4774e8b2..336922ebefb15 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -514,6 +514,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1
 */
 
 #include <__config>
+#include <compare>
 #include <string_view>
 #include <iosfwd>
 #include <cstring>

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index bc92dd5b1cb2e..3177fcd778316 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -182,6 +182,7 @@ namespace std {
 #include <__string>
 #include <iosfwd>
 #include <algorithm>
+#include <compare>
 #include <iterator>
 #include <limits>
 #include <stdexcept>

diff  --git a/libcxx/include/system_error b/libcxx/include/system_error
index 784adccbec023..9f3d8acdcb896 100644
--- a/libcxx/include/system_error
+++ b/libcxx/include/system_error
@@ -145,6 +145,7 @@ template <> struct hash<std::error_condition>;
 #include <__config>
 #include <__errc>
 #include <__functional_base> // unary_function
+#include <compare>
 #include <stdexcept>
 #include <string>
 #include <type_traits>

diff  --git a/libcxx/include/tuple b/libcxx/include/tuple
index 6e07892f94791..61ff2125623f7 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -151,6 +151,7 @@ template <class... Types>
 
 #include <__config>
 #include <__tuple>
+#include <compare>
 #include <cstddef>
 #include <type_traits>
 #include <__functional_base>

diff  --git a/libcxx/include/typeindex b/libcxx/include/typeindex
index bff1e65af9446..a8d582e4f7097 100644
--- a/libcxx/include/typeindex
+++ b/libcxx/include/typeindex
@@ -47,6 +47,7 @@ struct hash<type_index>
 #include <__config>
 #include <typeinfo>
 #include <__functional_base>
+#include <compare>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header

diff  --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index fc10c8b9c2a2b..d061e527560cf 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -434,6 +434,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
 #include <__config>
 #include <__hash_table>
 #include <__node_handle>
+#include <compare>
 #include <functional>
 #include <iterator> // __libcpp_erase_if_container
 #include <stdexcept>

diff  --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 726e37389ff12..99943f355a6e2 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -389,6 +389,7 @@ template <class Value, class Hash, class Pred, class Alloc>
 #include <__config>
 #include <__hash_table>
 #include <__node_handle>
+#include <compare>
 #include <functional>
 #include <iterator> // __libcpp_erase_if_container
 #include <version>

diff  --git a/libcxx/include/utility b/libcxx/include/utility
index e81fcbe1b870c..bfde01c587e22 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -201,6 +201,7 @@ template <class T>
 
 #include <__config>
 #include <__tuple>
+#include <compare>
 #include <type_traits>
 #include <initializer_list>
 #include <cstddef>

diff  --git a/libcxx/include/variant b/libcxx/include/variant
index 4e3db1f7afbc7..43b6aa77fae6f 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -203,6 +203,7 @@ namespace std {
 #include <__availability>
 #include <__tuple>
 #include <array>
+#include <compare>
 #include <exception>
 #include <functional>
 #include <initializer_list>

diff  --git a/libcxx/include/vector b/libcxx/include/vector
index 4e1a46af2f4bb..2cd243ae87df4 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -276,6 +276,7 @@ erase_if(vector<T, Allocator>& c, Predicate pred);    // C++20
 #include <__bit_reference>
 #include <type_traits>
 #include <climits>
+#include <compare>
 #include <limits>
 #include <initializer_list>
 #include <memory>

diff  --git a/libcxx/test/libcxx/inclusions/algorithm.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/algorithm.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..d2fde39d33128
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/algorithm.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <algorithm>
+
+// Test that <algorithm> includes all the other headers it's supposed to.
+
+#include <algorithm>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_ALGORITHM)
+ #   error "<algorithm> was expected to define _LIBCPP_ALGORITHM"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<algorithm> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/array.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/array.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..7ec19fb0e23ea
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/array.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <array>
+
+// Test that <array> includes all the other headers it's supposed to.
+
+#include <array>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_ARRAY)
+ #   error "<array> was expected to define _LIBCPP_ARRAY"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<array> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<array> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/bitset.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/bitset.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..c8d413c1d57f7
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/bitset.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <bitset>
+
+// Test that <bitset> includes all the other headers it's supposed to.
+
+#include <bitset>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_BITSET)
+ #   error "<bitset> was expected to define _LIBCPP_BITSET"
+#endif
+#if !defined(_LIBCPP_IOSFWD)
+ #   error "<bitset> should include <iosfwd> in C++03 and later"
+#endif
+#if !defined(_LIBCPP_STRING)
+ #   error "<bitset> should include <string> in C++03 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/chrono.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/chrono.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..ffcaeed4e728f
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/chrono.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03
+
+// <chrono>
+
+// Test that <chrono> includes all the other headers it's supposed to.
+
+#include <chrono>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_CHRONO)
+ #   error "<chrono> was expected to define _LIBCPP_CHRONO"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<chrono> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/cinttypes.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/cinttypes.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..61c0797a8074a
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/cinttypes.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <cinttypes>
+
+// Test that <cinttypes> includes all the other headers it's supposed to.
+
+#include <cinttypes>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_CINTTYPES)
+ #   error "<cinttypes> was expected to define _LIBCPP_CINTTYPES"
+#endif
+#if !defined(_LIBCPP_CSTDINT)
+ #   error "<cinttypes> should include <cstdint> in C++03 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/complex.h.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/complex.h.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..5d2e943e6285a
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/complex.h.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <complex.h>
+
+// Test that <complex.h> includes all the other headers it's supposed to.
+
+#include <complex.h>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_COMPLEX_H)
+ #   error "<complex.h> was expected to define _LIBCPP_COMPLEX_H"
+#endif
+#if !defined(_LIBCPP_COMPLEX)
+ #   error "<complex.h> should include <complex> in C++03 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/deque.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/deque.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..d1563de00e05e
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/deque.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <deque>
+
+// Test that <deque> includes all the other headers it's supposed to.
+
+#include <deque>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_DEQUE)
+ #   error "<deque> was expected to define _LIBCPP_DEQUE"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<deque> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<deque> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/filesystem.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/filesystem.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..6112320697000
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/filesystem.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: libcpp-has-no-filesystem-library
+
+// <filesystem>
+
+// Test that <filesystem> includes all the other headers it's supposed to.
+
+#include <filesystem>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_FILESYSTEM)
+ #   error "<filesystem> was expected to define _LIBCPP_FILESYSTEM"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<filesystem> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/forward_list.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/forward_list.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..62ea06ef7d4e2
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/forward_list.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <forward_list>
+
+// Test that <forward_list> includes all the other headers it's supposed to.
+
+#include <forward_list>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_FORWARD_LIST)
+ #   error "<forward_list> was expected to define _LIBCPP_FORWARD_LIST"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<forward_list> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<forward_list> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/ios.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/ios.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..52fb9ee034dd5
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/ios.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: libcpp-has-no-localization
+
+// <ios>
+
+// Test that <ios> includes all the other headers it's supposed to.
+
+#include <ios>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_IOS)
+ #   error "<ios> was expected to define _LIBCPP_IOS"
+#endif
+#if !defined(_LIBCPP_IOSFWD)
+ #   error "<ios> should include <iosfwd> in C++03 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/iostream.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/iostream.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..4d1b448ef69b2
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/iostream.inclusions.compile.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: libcpp-has-no-localization
+
+// <iostream>
+
+// Test that <iostream> includes all the other headers it's supposed to.
+
+#include <iostream>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_IOSTREAM)
+ #   error "<iostream> was expected to define _LIBCPP_IOSTREAM"
+#endif
+#if !defined(_LIBCPP_IOS)
+ #   error "<iostream> should include <ios> in C++03 and later"
+#endif
+#if !defined(_LIBCPP_ISTREAM)
+ #   error "<iostream> should include <istream> in C++03 and later"
+#endif
+#if !defined(_LIBCPP_OSTREAM)
+ #   error "<iostream> should include <ostream> in C++03 and later"
+#endif
+#if !defined(_LIBCPP_STREAMBUF)
+ #   error "<iostream> should include <streambuf> in C++03 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/iterator.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/iterator.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..11dfb74e45981
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/iterator.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <iterator>
+
+// Test that <iterator> includes all the other headers it's supposed to.
+
+#include <iterator>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_ITERATOR)
+ #   error "<iterator> was expected to define _LIBCPP_ITERATOR"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<iterator> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_CONCEPTS)
+ #   error "<iterator> should include <concepts> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/list.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/list.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..76cb06d78132d
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/list.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <list>
+
+// Test that <list> includes all the other headers it's supposed to.
+
+#include <list>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_LIST)
+ #   error "<list> was expected to define _LIBCPP_LIST"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<list> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<list> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/map.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/map.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..319ee462a41b2
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/map.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <map>
+
+// Test that <map> includes all the other headers it's supposed to.
+
+#include <map>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_MAP)
+ #   error "<map> was expected to define _LIBCPP_MAP"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<map> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<map> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/memory.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/memory.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..6b1cd84b19b25
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/memory.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <memory>
+
+// Test that <memory> includes all the other headers it's supposed to.
+
+#include <memory>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_MEMORY)
+ #   error "<memory> was expected to define _LIBCPP_MEMORY"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<memory> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/optional.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/optional.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..7a6ff343e0b5e
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/optional.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <optional>
+
+// Test that <optional> includes all the other headers it's supposed to.
+
+#include <optional>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_OPTIONAL)
+ #   error "<optional> was expected to define _LIBCPP_OPTIONAL"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<optional> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/queue.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/queue.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..f0bf7fb649831
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/queue.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <queue>
+
+// Test that <queue> includes all the other headers it's supposed to.
+
+#include <queue>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_QUEUE)
+ #   error "<queue> was expected to define _LIBCPP_QUEUE"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<queue> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<queue> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/random.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/random.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..68da450ca86b4
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/random.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <random>
+
+// Test that <random> includes all the other headers it's supposed to.
+
+#include <random>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_RANDOM)
+ #   error "<random> was expected to define _LIBCPP_RANDOM"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<random> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/regex.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/regex.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..a2a66f4be6b0f
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/regex.inclusions.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: libcpp-has-no-localization
+
+// <regex>
+
+// Test that <regex> includes all the other headers it's supposed to.
+
+#include <regex>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_REGEX)
+ #   error "<regex> was expected to define _LIBCPP_REGEX"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<regex> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<regex> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/set.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/set.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..68350f5369a9f
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/set.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <set>
+
+// Test that <set> includes all the other headers it's supposed to.
+
+#include <set>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_SET)
+ #   error "<set> was expected to define _LIBCPP_SET"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<set> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<set> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/stack.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/stack.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..323abc2f63a0c
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/stack.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <stack>
+
+// Test that <stack> includes all the other headers it's supposed to.
+
+#include <stack>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_STACK)
+ #   error "<stack> was expected to define _LIBCPP_STACK"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<stack> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<stack> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/string.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/string.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..d77ee0ecffa55
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/string.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <string>
+
+// Test that <string> includes all the other headers it's supposed to.
+
+#include <string>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_STRING)
+ #   error "<string> was expected to define _LIBCPP_STRING"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<string> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<string> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/string_view.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/string_view.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..a4b999e2c680a
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/string_view.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <string_view>
+
+// Test that <string_view> includes all the other headers it's supposed to.
+
+#include <string_view>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_STRING_VIEW)
+ #   error "<string_view> was expected to define _LIBCPP_STRING_VIEW"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<string_view> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/system_error.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/system_error.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..5c7f485219975
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/system_error.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03
+
+// <system_error>
+
+// Test that <system_error> includes all the other headers it's supposed to.
+
+#include <system_error>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_SYSTEM_ERROR)
+ #   error "<system_error> was expected to define _LIBCPP_SYSTEM_ERROR"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<system_error> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/tgmath.h.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/tgmath.h.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..25bc00de39576
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/tgmath.h.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <tgmath.h>
+
+// Test that <tgmath.h> includes all the other headers it's supposed to.
+
+#include <tgmath.h>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_TGMATH_H)
+ #   error "<tgmath.h> was expected to define _LIBCPP_TGMATH_H"
+#endif
+#if !defined(_LIBCPP_CMATH)
+ #   error "<tgmath.h> should include <cmath> in C++03 and later"
+#endif
+#if !defined(_LIBCPP_COMPLEX)
+ #   error "<tgmath.h> should include <complex> in C++03 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/thread.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/thread.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..fc5467423efde
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/thread.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <thread>
+
+// Test that <thread> includes all the other headers it's supposed to.
+
+#include <thread>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_THREAD)
+ #   error "<thread> was expected to define _LIBCPP_THREAD"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<thread> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/tuple.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/tuple.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..58f05b1b9ece0
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/tuple.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03
+
+// <tuple>
+
+// Test that <tuple> includes all the other headers it's supposed to.
+
+#include <tuple>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_TUPLE)
+ #   error "<tuple> was expected to define _LIBCPP_TUPLE"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<tuple> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/typeindex.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/typeindex.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..1cecb54101490
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/typeindex.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <typeindex>
+
+// Test that <typeindex> includes all the other headers it's supposed to.
+
+#include <typeindex>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_TYPEINDEX)
+ #   error "<typeindex> was expected to define _LIBCPP_TYPEINDEX"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<typeindex> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/unordered_map.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/unordered_map.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..2abddcfcf13c7
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/unordered_map.inclusions.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03
+
+// <unordered_map>
+
+// Test that <unordered_map> includes all the other headers it's supposed to.
+
+#include <unordered_map>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_UNORDERED_MAP)
+ #   error "<unordered_map> was expected to define _LIBCPP_UNORDERED_MAP"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<unordered_map> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<unordered_map> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/unordered_set.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/unordered_set.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..58bf21507993f
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/unordered_set.inclusions.compile.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03
+
+// <unordered_set>
+
+// Test that <unordered_set> includes all the other headers it's supposed to.
+
+#include <unordered_set>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_UNORDERED_SET)
+ #   error "<unordered_set> was expected to define _LIBCPP_UNORDERED_SET"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<unordered_set> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<unordered_set> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/utility.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/utility.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..b0e2163bcf365
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/utility.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <utility>
+
+// Test that <utility> includes all the other headers it's supposed to.
+
+#include <utility>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_UTILITY)
+ #   error "<utility> was expected to define _LIBCPP_UTILITY"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<utility> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<utility> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/valarray.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/valarray.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..3d3bf9187db53
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/valarray.inclusions.compile.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <valarray>
+
+// Test that <valarray> includes all the other headers it's supposed to.
+
+#include <valarray>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_VALARRAY)
+ #   error "<valarray> was expected to define _LIBCPP_VALARRAY"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<valarray> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/variant.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/variant.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..96adb1907746d
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/variant.inclusions.compile.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// <variant>
+
+// Test that <variant> includes all the other headers it's supposed to.
+
+#include <variant>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_VARIANT)
+ #   error "<variant> was expected to define _LIBCPP_VARIANT"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<variant> should include <compare> in C++20 and later"
+#endif

diff  --git a/libcxx/test/libcxx/inclusions/vector.inclusions.compile.pass.cpp b/libcxx/test/libcxx/inclusions/vector.inclusions.compile.pass.cpp
new file mode 100644
index 0000000000000..2e6b36ea4f607
--- /dev/null
+++ b/libcxx/test/libcxx/inclusions/vector.inclusions.compile.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_header_inclusion_tests.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <vector>
+
+// Test that <vector> includes all the other headers it's supposed to.
+
+#include <vector>
+#include "test_macros.h"
+
+#if !defined(_LIBCPP_VECTOR)
+ #   error "<vector> was expected to define _LIBCPP_VECTOR"
+#endif
+#if TEST_STD_VER > 17 && !defined(_LIBCPP_COMPARE)
+ #   error "<vector> should include <compare> in C++20 and later"
+#endif
+#if TEST_STD_VER > 03 && !defined(_LIBCPP_INITIALIZER_LIST)
+ #   error "<vector> should include <initializer_list> in C++11 and later"
+#endif

diff  --git a/libcxx/utils/generate_header_inclusion_tests.py b/libcxx/utils/generate_header_inclusion_tests.py
new file mode 100755
index 0000000000000..0bf318ea440e8
--- /dev/null
+++ b/libcxx/utils/generate_header_inclusion_tests.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python
+
+import os
+
+
+def get_libcxx_paths():
+    utils_path = os.path.dirname(os.path.abspath(__file__))
+    script_name = os.path.basename(__file__)
+    assert os.path.exists(utils_path)
+    src_root = os.path.dirname(utils_path)
+    test_path = os.path.join(src_root, 'test', 'libcxx', 'inclusions')
+    assert os.path.exists(test_path)
+    assert os.path.exists(os.path.join(test_path, 'algorithm.inclusions.compile.pass.cpp'))
+    return script_name, src_root, test_path
+
+
+script_name, source_root, test_path = get_libcxx_paths()
+
+
+# This table was produced manually, by grepping the TeX source of the Standard's
+# library clauses for the string "#include". Each header's synopsis contains
+# explicit "#include" directives for its mandatory inclusions.
+# For example, [algorithm.syn] contains "#include <initializer_list>".
+#
+mandatory_inclusions = {
+    "algorithm": ["initializer_list"],
+    "array": ["compare", "initializer_list"],
+    "bitset": ["iosfwd", "string"],
+    "chrono": ["compare"],
+    "cinttypes": ["cstdint"],
+    "complex.h": ["complex"],
+    # TODO "coroutine": ["compare"],
+    "deque": ["compare", "initializer_list"],
+    "filesystem": ["compare"],
+    "forward_list": ["compare", "initializer_list"],
+    "ios": ["iosfwd"],
+    "iostream": ["ios", "istream", "ostream", "streambuf"],
+    "iterator": ["compare", "concepts"],
+    "list": ["compare", "initializer_list"],
+    "map": ["compare", "initializer_list"],
+    "memory": ["compare"],
+    "optional": ["compare"],
+    "queue": ["compare", "initializer_list"],
+    "random": ["initializer_list"],
+    # TODO "ranges": ["compare", "initializer_list", "iterator"],
+    "regex": ["compare", "initializer_list"],
+    "set": ["compare", "initializer_list"],
+    "stack": ["compare", "initializer_list"],
+    "string": ["compare", "initializer_list"],
+    "string_view": ["compare"],
+    # TODO "syncstream": ["ostream"],
+    "system_error": ["compare"],
+    "tgmath.h": ["cmath", "complex"],
+    "thread": ["compare"],
+    "tuple": ["compare"],
+    "typeindex": ["compare"],
+    "unordered_map": ["compare", "initializer_list"],
+    "unordered_set": ["compare", "initializer_list"],
+    "utility": ["compare", "initializer_list"],
+    "valarray": ["initializer_list"],
+    "variant": ["compare"],
+    "vector": ["compare", "initializer_list"],
+}
+
+new_in_version = {
+    "chrono": "11",
+    "compare": "20",
+    "concepts": "20",
+    "coroutine": "20",
+    "filesystem": "17",
+    "initializer_list": "11",
+    "optional": "17",
+    "system_error": "11",
+    "thread": "11",
+    "tuple": "11",
+    "unordered_map": "11",
+    "unordered_set": "11",
+    "string_view": "17",
+    "ranges": "20",
+    "syncstream": "20",
+    "variant": "17",
+}
+
+assert all(v == sorted(v) for k, v in mandatory_inclusions.items())
+
+# Map from each header to the Lit annotations that should be used for
+# tests that include that header.
+#
+# For example, when threads are not supported, any test
+# that includes <thread> should be marked as UNSUPPORTED, because including
+# <thread> is a hard error in that case.
+lit_markup = {
+  "atomic": ["UNSUPPORTED: libcpp-has-no-threads"],
+  "barrier": ["UNSUPPORTED: libcpp-has-no-threads"],
+  "filesystem": ["UNSUPPORTED: libcpp-has-no-filesystem-library"],
+  "iomanip": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "istream": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "ios": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "iostream": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "latch": ["UNSUPPORTED: libcpp-has-no-threads"],
+  "locale": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "ostream": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "regex": ["UNSUPPORTED: libcpp-has-no-localization"],
+  "semaphore": ["UNSUPPORTED: libcpp-has-no-threads"],
+  "shared_mutex": ["UNSUPPORTED: libcpp-has-no-threads"],
+  "thread": ["UNSUPPORTED: libcpp-has-no-threads"],
+}
+
+
+def get_std_ver_test(includee):
+    v = new_in_version.get(includee, "03")
+    if v == "03":
+        return ''
+    versions = ["03", "11", "14", "17", "20"]
+    return 'TEST_STD_VER > {} && '.format(max(i for i in versions if i < v))
+
+
+def get_unsupported_line(includee):
+    v = new_in_version.get(includee, "03")
+    return {
+        "03": [],
+        "11": ['UNSUPPORTED: c++03'],
+        "14": ['UNSUPPORTED: c++03, c++11'],
+        "17": ['UNSUPPORTED: c++03, c++11, c++14'],
+        "20": ['UNSUPPORTED: c++03, c++11, c++14, c++17'],
+        "2b": ['UNSUPPORTED: c++03, c++11, c++14, c++17, c++20'],
+    }[v]
+
+
+def get_libcpp_header_symbol(header_name):
+    return '_LIBCPP_' + header_name.upper().replace('.', '_')
+
+
+def get_includer_symbol_test(includer):
+    symbol = get_libcpp_header_symbol(includer)
+    return """
+#if !defined({symbol})
+ #   error "{message}"
+#endif
+    """.strip().format(
+        symbol=symbol,
+        message="<{}> was expected to define {}".format(includer, symbol),
+    )
+
+
+def get_ifdef(includer, includee):
+    version = max(new_in_version.get(h, "03") for h in [includer, includee])
+    symbol = get_libcpp_header_symbol(includee)
+    return """
+#if {includee_test}!defined({symbol})
+ #   error "{message}"
+#endif
+    """.strip().format(
+        includee_test=get_std_ver_test(includee),
+        symbol=symbol,
+        message="<{}> should include <{}> in C++{} and later".format(includer, includee, version)
+    )
+
+
+test_body_template = """
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by {script_name}
+// and should not be edited manually.
+//
+// clang-format off
+{markup}
+// <{header}>
+
+// Test that <{header}> includes all the other headers it's supposed to.
+
+#include <{header}>
+#include "test_macros.h"
+
+{test_includers_symbol}
+{test_per_includee}
+""".strip()
+
+
+def produce_tests():
+    for includer, includees in mandatory_inclusions.items():
+        markup_tags = get_unsupported_line(includer) + lit_markup.get(includer, [])
+        test_body = test_body_template.format(
+            script_name=script_name,
+            header=includer,
+            markup=('\n' + '\n'.join('// ' + m for m in markup_tags) + '\n') if markup_tags else '',
+            test_includers_symbol=get_includer_symbol_test(includer),
+            test_per_includee='\n'.join(get_ifdef(includer, includee) for includee in includees),
+        )
+        test_name = "{header}.inclusions.compile.pass.cpp".format(header=includer)
+        out_path = os.path.join(test_path, test_name)
+        with open(out_path, 'w', newline='\n') as f:
+            f.write(test_body + '\n')
+
+
+if __name__ == '__main__':
+    produce_tests()


        


More information about the libcxx-commits mailing list