[libcxx-commits] [libcxx] 6fd5a94 - [libc++] Add a script to automatize updating test for a new header.

Marek Kurdej via libcxx-commits libcxx-commits at lists.llvm.org
Wed Dec 9 23:37:56 PST 2020


Author: Marek Kurdej
Date: 2020-12-10T08:37:50+01:00
New Revision: 6fd5a94eeb9acca783549df26b2e6319df8ab0a8

URL: https://github.com/llvm/llvm-project/commit/6fd5a94eeb9acca783549df26b2e6319df8ab0a8
DIFF: https://github.com/llvm/llvm-project/commit/6fd5a94eeb9acca783549df26b2e6319df8ab0a8.diff

LOG: [libc++] Add a script to automatize updating test for a new header.

Idea from D92525.
This script globs include/ directory and updates the tests in test/libcxx.
This patch does not generate module.modulemap nor CMakeLists.txt.

Reviewed By: ldionne, #libc

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

Added: 
    libcxx/utils/generate_header_tests.py

Modified: 
    libcxx/docs/Contributing.rst
    libcxx/test/libcxx/double_include.sh.cpp
    libcxx/test/libcxx/min_max_macros.compile.pass.cpp
    libcxx/test/libcxx/no_assert_include.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Contributing.rst b/libcxx/docs/Contributing.rst
index abbf91fdd702..f397f4ce8831 100644
--- a/libcxx/docs/Contributing.rst
+++ b/libcxx/docs/Contributing.rst
@@ -23,18 +23,19 @@ After branching for an LLVM release:
 2. Update the ``include/__libcpp_version`` file
 3. Update the version number in ``docs/conf.py``
 
+Modifying feature test macros
+=============================
+
+When adding or updating feature test macros, you should update the corresponding tests.
+To do that, modify ``feature_test_macros`` table in the script ``utils/generate_feature_test_macro_components.py``, run it, and commit updated files.
+
 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. Update the following test files to include the new header:
-
-  * ``test/libcxx/double_include.sh.cpp``
-  * ``test/libcxx/min_max_macros.compile.pass.cpp``
-  * ``test/libcxx/no_assert_include.compile.pass.cpp``
-
+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.
 

diff  --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp
index 39851cc379d4..072b78899b36 100644
--- a/libcxx/test/libcxx/double_include.sh.cpp
+++ b/libcxx/test/libcxx/double_include.sh.cpp
@@ -1,195 +1,235 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// Test that we can include each header in two TU's and link them together.
-
-// RUN: %{cxx} -c %s -o %t.first.o %{flags} %{compile_flags}
-// RUN: %{cxx} -c %s -o %t.second.o -DWITH_MAIN %{flags} %{compile_flags}
-// RUN: %{cxx} -o %t.exe %t.first.o %t.second.o %{flags} %{link_flags}
-// RUN: %{run}
-
-// GCC 5 pretends it supports C++17 features, but some features like static_assert
-// without a message are not actually supported. This causes some headers to fail
-// when included.
-// UNSUPPORTED: gcc-5 && c++17
-
-// Prevent <ext/hash_map> from generating deprecated warnings for this test.
-#if defined(__DEPRECATED)
-#undef __DEPRECATED
-#endif
-
-// Top level headers
-#include <algorithm>
-#include <any>
-#include <array>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <atomic>
-#endif
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <barrier>
-#endif
-#include <bit>
-#include <bitset>
-#include <cassert>
-#include <ccomplex>
-#include <cctype>
-#include <cerrno>
-#include <cfenv>
-#include <cfloat>
-#include <charconv>
-#include <chrono>
-#include <cinttypes>
-#include <ciso646>
-#include <climits>
-#include <cmath>
-#include <compare>
-#include <complex>
-#include <complex.h>
-#include <concepts>
-#include <condition_variable>
-#include <csetjmp>
-#include <csignal>
-#include <cstdarg>
-#include <cstdbool>
-#include <cstddef>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <ctgmath>
-#include <ctime>
-#include <ctype.h>
-#include <cwchar>
-#include <cwctype>
-#include <deque>
-#include <errno.h>
-#include <exception>
-#include <execution>
-#include <fenv.h>
-#include <filesystem>
-#include <float.h>
-#include <forward_list>
-#include <functional>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <future>
-#endif
-#include <initializer_list>
-#include <inttypes.h>
-#include <iosfwd>
-#include <iterator>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <latch>
-#endif
-#include <limits>
-#include <limits.h>
-#include <list>
-#include <map>
-#include <math.h>
-#include <memory>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <mutex>
-#endif
-#include <new>
-#include <numbers>
-#include <numeric>
-#include <optional>
-#include <queue>
-#include <random>
-#include <ratio>
-#include <scoped_allocator>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <semaphore>
-#endif
-#include <set>
-#include <setjmp.h>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <shared_mutex>
-#endif
-#include <span>
-#include <stack>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdexcept>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include <string.h>
-#include <string_view>
-#include <system_error>
-#include <tgmath.h>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <thread>
-#endif
-#include <tuple>
-#include <typeindex>
-#include <typeinfo>
-#include <type_traits>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <valarray>
-#include <variant>
-#include <vector>
-#include <version>
-#include <wchar.h>
-#include <wctype.h>
-
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
-#   include <clocale>
-#   include <codecvt>
-#   include <fstream>
-#   include <iomanip>
-#   include <ios>
-#   include <iostream>
-#   include <istream>
-#   include <locale.h>
-#   include <locale>
-#   include <ostream>
-#   include <regex>
-#   include <sstream>
-#   include <streambuf>
-#   include <strstream>
-#   if __cplusplus >= 201103L
-#       include <experimental/regex>
-#   endif
-#endif
-
-// experimental headers
-#if __cplusplus >= 201103L
-#include <experimental/algorithm>
-#if defined(__cpp_coroutines)
-#include <experimental/coroutine>
-#endif
-#include <experimental/deque>
-#include <experimental/filesystem>
-#include <experimental/forward_list>
-#include <experimental/functional>
-#include <experimental/iterator>
-#include <experimental/list>
-#include <experimental/map>
-#include <experimental/memory_resource>
-#include <experimental/propagate_const>
-#include <experimental/set>
-#include <experimental/simd>
-#include <experimental/string>
-#include <experimental/type_traits>
-#include <experimental/unordered_map>
-#include <experimental/unordered_set>
-#include <experimental/utility>
-#include <experimental/vector>
-#endif // __cplusplus >= 201103L
-
-// extended headers
-#include <ext/hash_map>
-#include <ext/hash_set>
-
-#if defined(WITH_MAIN)
-int main(int, char**) { return 0; }
-#endif
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that we can include each header in two TU's and link them together.
+
+// RUN: %{cxx} -c %s -o %t.first.o %{flags} %{compile_flags}
+// RUN: %{cxx} -c %s -o %t.second.o -DWITH_MAIN %{flags} %{compile_flags}
+// RUN: %{cxx} -o %t.exe %t.first.o %t.second.o %{flags} %{link_flags}
+// RUN: %{run}
+
+// GCC 5 pretends it supports C++17 features, but some features like static_assert
+// without a message are not actually supported. This causes some headers to fail
+// when included.
+// UNSUPPORTED: gcc-5 && c++17
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+#if defined(__DEPRECATED)
+#    undef __DEPRECATED
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// BEGIN-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+
+// clang-format off
+
+// WARNING: This test was generated by generate_header_tests.py
+// and should not be edited manually.
+
+// Top level headers
+#include <algorithm>
+#include <any>
+#include <array>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <atomic>
+#endif
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <barrier>
+#endif
+#include <bit>
+#include <bitset>
+#include <cassert>
+#include <ccomplex>
+#include <cctype>
+#include <cerrno>
+#include <cfenv>
+#include <cfloat>
+#include <charconv>
+#include <chrono>
+#include <cinttypes>
+#include <ciso646>
+#include <climits>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <clocale>
+#endif
+#include <cmath>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <codecvt>
+#endif
+#include <compare>
+#include <complex>
+#include <complex.h>
+#include <concepts>
+#include <condition_variable>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstdbool>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctgmath>
+#include <ctime>
+#include <ctype.h>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <errno.h>
+#include <exception>
+#include <execution>
+#include <fenv.h>
+#include <filesystem>
+#include <float.h>
+#include <forward_list>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <fstream>
+#endif
+#include <functional>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <future>
+#endif
+#include <initializer_list>
+#include <inttypes.h>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <iomanip>
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <ios>
+#endif
+#include <iosfwd>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <iostream>
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <istream>
+#endif
+#include <iterator>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <latch>
+#endif
+#include <limits>
+#include <limits.h>
+#include <list>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <locale>
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <locale.h>
+#endif
+#include <map>
+#include <math.h>
+#include <memory>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <mutex>
+#endif
+#include <new>
+#include <numbers>
+#include <numeric>
+#include <optional>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <ostream>
+#endif
+#include <queue>
+#include <random>
+#include <ratio>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <regex>
+#endif
+#include <scoped_allocator>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <semaphore>
+#endif
+#include <set>
+#include <setjmp.h>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <shared_mutex>
+#endif
+#include <span>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <sstream>
+#endif
+#include <stack>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdexcept>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <streambuf>
+#endif
+#include <string>
+#include <string.h>
+#include <string_view>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <strstream>
+#endif
+#include <system_error>
+#include <tgmath.h>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <thread>
+#endif
+#include <tuple>
+#include <typeindex>
+#include <typeinfo>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <variant>
+#include <vector>
+#include <version>
+#include <wchar.h>
+#include <wctype.h>
+
+// experimental headers
+#if __cplusplus >= 201103L
+#    include <experimental/algorithm>
+#    if defined(__cpp_coroutines)
+#        include <experimental/coroutine>
+#    endif
+#    include <experimental/deque>
+#    include <experimental/filesystem>
+#    include <experimental/forward_list>
+#    include <experimental/functional>
+#    include <experimental/iterator>
+#    include <experimental/list>
+#    include <experimental/map>
+#    include <experimental/memory_resource>
+#    include <experimental/propagate_const>
+#    ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#        include <experimental/regex>
+#    endif
+#    include <experimental/set>
+#    include <experimental/simd>
+#    include <experimental/string>
+#    include <experimental/type_traits>
+#    include <experimental/unordered_map>
+#    include <experimental/unordered_set>
+#    include <experimental/utility>
+#    include <experimental/vector>
+#endif // __cplusplus >= 201103L
+
+// extended headers
+#include <ext/hash_map>
+#include <ext/hash_set>
+
+// clang-format on
+
+////////////////////////////////////////////////////////////////////////////////
+// END-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(WITH_MAIN)
+int main(int, char**) { return 0; }
+#endif

diff  --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
index da7e857fc6ff..21f70d7a888e 100644
--- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
+++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp
@@ -1,324 +1,364 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// Test that headers are not tripped up by the surrounding code defining the
-// min() and max() macros.
-
-// GCC 5 has incomplete support for C++17, so some headers fail when included.
-// UNSUPPORTED: gcc-5 && c++17
-
-// Prevent <ext/hash_map> from generating deprecated warnings for this test.
-#if defined(__DEPRECATED)
-#undef __DEPRECATED
-#endif
-
-#define TEST_MACROS() static_assert(min() == true && max() == true, "")
-#define min() true
-#define max() true
-
-// Top level headers
-#include <algorithm>
-TEST_MACROS();
-#include <any>
-TEST_MACROS();
-#include <array>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <atomic>
-TEST_MACROS();
-#endif
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <barrier>
-TEST_MACROS();
-#endif
-#include <bit>
-TEST_MACROS();
-#include <bitset>
-TEST_MACROS();
-#include <cassert>
-TEST_MACROS();
-#include <ccomplex>
-TEST_MACROS();
-#include <cctype>
-TEST_MACROS();
-#include <cerrno>
-TEST_MACROS();
-#include <cfenv>
-TEST_MACROS();
-#include <cfloat>
-TEST_MACROS();
-#include <charconv>
-TEST_MACROS();
-#include <chrono>
-TEST_MACROS();
-#include <cinttypes>
-TEST_MACROS();
-#include <ciso646>
-TEST_MACROS();
-#include <climits>
-TEST_MACROS();
-#include <cmath>
-TEST_MACROS();
-#include <compare>
-TEST_MACROS();
-#include <complex>
-TEST_MACROS();
-#include <complex.h>
-TEST_MACROS();
-#include <concepts>
-TEST_MACROS();
-#include <condition_variable>
-TEST_MACROS();
-#include <csetjmp>
-TEST_MACROS();
-#include <csignal>
-TEST_MACROS();
-#include <cstdarg>
-TEST_MACROS();
-#include <cstdbool>
-TEST_MACROS();
-#include <cstddef>
-TEST_MACROS();
-#include <cstdint>
-TEST_MACROS();
-#include <cstdio>
-TEST_MACROS();
-#include <cstdlib>
-TEST_MACROS();
-#include <cstring>
-TEST_MACROS();
-#include <ctgmath>
-TEST_MACROS();
-#include <ctime>
-TEST_MACROS();
-#include <ctype.h>
-TEST_MACROS();
-#include <cwchar>
-TEST_MACROS();
-#include <cwctype>
-TEST_MACROS();
-#include <deque>
-TEST_MACROS();
-#include <errno.h>
-TEST_MACROS();
-#include <exception>
-TEST_MACROS();
-#include <execution>
-TEST_MACROS();
-#include <fenv.h>
-TEST_MACROS();
-#include <filesystem>
-TEST_MACROS();
-#include <float.h>
-TEST_MACROS();
-#include <forward_list>
-TEST_MACROS();
-#include <functional>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <future>
-TEST_MACROS();
-#endif
-#include <initializer_list>
-TEST_MACROS();
-#include <inttypes.h>
-TEST_MACROS();
-#include <iosfwd>
-TEST_MACROS();
-#include <iterator>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <latch>
-TEST_MACROS();
-#endif
-#include <limits>
-TEST_MACROS();
-#include <limits.h>
-TEST_MACROS();
-#include <list>
-TEST_MACROS();
-#include <map>
-TEST_MACROS();
-#include <math.h>
-TEST_MACROS();
-#include <memory>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <mutex>
-TEST_MACROS();
-#endif
-#include <new>
-TEST_MACROS();
-#include <numbers>
-TEST_MACROS();
-#include <numeric>
-TEST_MACROS();
-#include <optional>
-TEST_MACROS();
-#include <queue>
-TEST_MACROS();
-#include <random>
-TEST_MACROS();
-#include <ratio>
-TEST_MACROS();
-#include <scoped_allocator>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <semaphore>
-TEST_MACROS();
-#endif
-#include <set>
-TEST_MACROS();
-#include <setjmp.h>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <shared_mutex>
-TEST_MACROS();
-#endif
-#include <span>
-TEST_MACROS();
-#include <stack>
-TEST_MACROS();
-#include <stdbool.h>
-TEST_MACROS();
-#include <stddef.h>
-TEST_MACROS();
-#include <stdexcept>
-TEST_MACROS();
-#include <stdint.h>
-TEST_MACROS();
-#include <stdio.h>
-TEST_MACROS();
-#include <stdlib.h>
-TEST_MACROS();
-#include <string>
-TEST_MACROS();
-#include <string.h>
-TEST_MACROS();
-#include <string_view>
-TEST_MACROS();
-#include <system_error>
-TEST_MACROS();
-#include <tgmath.h>
-TEST_MACROS();
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <thread>
-TEST_MACROS();
-#endif
-#include <tuple>
-TEST_MACROS();
-#include <typeindex>
-TEST_MACROS();
-#include <typeinfo>
-TEST_MACROS();
-#include <type_traits>
-TEST_MACROS();
-#include <unordered_map>
-TEST_MACROS();
-#include <unordered_set>
-TEST_MACROS();
-#include <utility>
-TEST_MACROS();
-#include <valarray>
-TEST_MACROS();
-#include <variant>
-TEST_MACROS();
-#include <vector>
-TEST_MACROS();
-#include <version>
-TEST_MACROS();
-#include <wchar.h>
-TEST_MACROS();
-#include <wctype.h>
-TEST_MACROS();
-
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
-#   include <clocale>
-    TEST_MACROS();
-#   include <codecvt>
-    TEST_MACROS();
-#   include <fstream>
-    TEST_MACROS();
-#   include <iomanip>
-    TEST_MACROS();
-#   include <ios>
-    TEST_MACROS();
-#   include <iostream>
-    TEST_MACROS();
-#   include <istream>
-    TEST_MACROS();
-#   include <locale>
-    TEST_MACROS();
-#   include <locale.h>
-    TEST_MACROS();
-#   include <ostream>
-    TEST_MACROS();
-#   include <regex>
-    TEST_MACROS();
-#   include <sstream>
-    TEST_MACROS();
-#   include <streambuf>
-    TEST_MACROS();
-#   include <strstream>
-    TEST_MACROS();
-#   if __cplusplus >= 201103L
-#       include <experimental/regex>
-        TEST_MACROS();
-#   endif
-#endif
-
-// experimental headers
-#if __cplusplus >= 201103L
-#include <experimental/algorithm>
-TEST_MACROS();
-#if defined(__cpp_coroutines)
-#include <experimental/coroutine>
-TEST_MACROS();
-#endif
-#include <experimental/deque>
-TEST_MACROS();
-#include <experimental/filesystem>
-TEST_MACROS();
-#include <experimental/forward_list>
-TEST_MACROS();
-#include <experimental/functional>
-TEST_MACROS();
-#include <experimental/iterator>
-TEST_MACROS();
-#include <experimental/list>
-TEST_MACROS();
-#include <experimental/map>
-TEST_MACROS();
-#include <experimental/memory_resource>
-TEST_MACROS();
-#include <experimental/propagate_const>
-TEST_MACROS();
-#include <experimental/set>
-TEST_MACROS();
-#include <experimental/simd>
-TEST_MACROS();
-#include <experimental/string>
-TEST_MACROS();
-#include <experimental/type_traits>
-TEST_MACROS();
-#include <experimental/unordered_map>
-TEST_MACROS();
-#include <experimental/unordered_set>
-TEST_MACROS();
-#include <experimental/utility>
-TEST_MACROS();
-#include <experimental/vector>
-TEST_MACROS();
-#endif // __cplusplus >= 201103L
-
-// extended headers
-#include <ext/hash_map>
-TEST_MACROS();
-#include <ext/hash_set>
-TEST_MACROS();
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test that headers are not tripped up by the surrounding code defining the
+// min() and max() macros.
+
+// GCC 5 has incomplete support for C++17, so some headers fail when included.
+// UNSUPPORTED: gcc-5 && c++17
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+#if defined(__DEPRECATED)
+#    undef __DEPRECATED
+#endif
+
+#define TEST_MACROS() static_assert(min() == true && max() == true, "")
+#define min() true
+#define max() true
+
+////////////////////////////////////////////////////////////////////////////////
+// BEGIN-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+
+// clang-format off
+
+// WARNING: This test was generated by generate_header_tests.py
+// and should not be edited manually.
+
+// Top level headers
+#include <algorithm>
+TEST_MACROS();
+#include <any>
+TEST_MACROS();
+#include <array>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <atomic>
+TEST_MACROS();
+#endif
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <barrier>
+TEST_MACROS();
+#endif
+#include <bit>
+TEST_MACROS();
+#include <bitset>
+TEST_MACROS();
+#include <cassert>
+TEST_MACROS();
+#include <ccomplex>
+TEST_MACROS();
+#include <cctype>
+TEST_MACROS();
+#include <cerrno>
+TEST_MACROS();
+#include <cfenv>
+TEST_MACROS();
+#include <cfloat>
+TEST_MACROS();
+#include <charconv>
+TEST_MACROS();
+#include <chrono>
+TEST_MACROS();
+#include <cinttypes>
+TEST_MACROS();
+#include <ciso646>
+TEST_MACROS();
+#include <climits>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <clocale>
+TEST_MACROS();
+#endif
+#include <cmath>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <codecvt>
+TEST_MACROS();
+#endif
+#include <compare>
+TEST_MACROS();
+#include <complex>
+TEST_MACROS();
+#include <complex.h>
+TEST_MACROS();
+#include <concepts>
+TEST_MACROS();
+#include <condition_variable>
+TEST_MACROS();
+#include <csetjmp>
+TEST_MACROS();
+#include <csignal>
+TEST_MACROS();
+#include <cstdarg>
+TEST_MACROS();
+#include <cstdbool>
+TEST_MACROS();
+#include <cstddef>
+TEST_MACROS();
+#include <cstdint>
+TEST_MACROS();
+#include <cstdio>
+TEST_MACROS();
+#include <cstdlib>
+TEST_MACROS();
+#include <cstring>
+TEST_MACROS();
+#include <ctgmath>
+TEST_MACROS();
+#include <ctime>
+TEST_MACROS();
+#include <ctype.h>
+TEST_MACROS();
+#include <cwchar>
+TEST_MACROS();
+#include <cwctype>
+TEST_MACROS();
+#include <deque>
+TEST_MACROS();
+#include <errno.h>
+TEST_MACROS();
+#include <exception>
+TEST_MACROS();
+#include <execution>
+TEST_MACROS();
+#include <fenv.h>
+TEST_MACROS();
+#include <filesystem>
+TEST_MACROS();
+#include <float.h>
+TEST_MACROS();
+#include <forward_list>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <fstream>
+TEST_MACROS();
+#endif
+#include <functional>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <future>
+TEST_MACROS();
+#endif
+#include <initializer_list>
+TEST_MACROS();
+#include <inttypes.h>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <iomanip>
+TEST_MACROS();
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <ios>
+TEST_MACROS();
+#endif
+#include <iosfwd>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <iostream>
+TEST_MACROS();
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <istream>
+TEST_MACROS();
+#endif
+#include <iterator>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <latch>
+TEST_MACROS();
+#endif
+#include <limits>
+TEST_MACROS();
+#include <limits.h>
+TEST_MACROS();
+#include <list>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <locale>
+TEST_MACROS();
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <locale.h>
+TEST_MACROS();
+#endif
+#include <map>
+TEST_MACROS();
+#include <math.h>
+TEST_MACROS();
+#include <memory>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <mutex>
+TEST_MACROS();
+#endif
+#include <new>
+TEST_MACROS();
+#include <numbers>
+TEST_MACROS();
+#include <numeric>
+TEST_MACROS();
+#include <optional>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <ostream>
+TEST_MACROS();
+#endif
+#include <queue>
+TEST_MACROS();
+#include <random>
+TEST_MACROS();
+#include <ratio>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <regex>
+TEST_MACROS();
+#endif
+#include <scoped_allocator>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <semaphore>
+TEST_MACROS();
+#endif
+#include <set>
+TEST_MACROS();
+#include <setjmp.h>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <shared_mutex>
+TEST_MACROS();
+#endif
+#include <span>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <sstream>
+TEST_MACROS();
+#endif
+#include <stack>
+TEST_MACROS();
+#include <stdbool.h>
+TEST_MACROS();
+#include <stddef.h>
+TEST_MACROS();
+#include <stdexcept>
+TEST_MACROS();
+#include <stdint.h>
+TEST_MACROS();
+#include <stdio.h>
+TEST_MACROS();
+#include <stdlib.h>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <streambuf>
+TEST_MACROS();
+#endif
+#include <string>
+TEST_MACROS();
+#include <string.h>
+TEST_MACROS();
+#include <string_view>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <strstream>
+TEST_MACROS();
+#endif
+#include <system_error>
+TEST_MACROS();
+#include <tgmath.h>
+TEST_MACROS();
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <thread>
+TEST_MACROS();
+#endif
+#include <tuple>
+TEST_MACROS();
+#include <typeindex>
+TEST_MACROS();
+#include <typeinfo>
+TEST_MACROS();
+#include <type_traits>
+TEST_MACROS();
+#include <unordered_map>
+TEST_MACROS();
+#include <unordered_set>
+TEST_MACROS();
+#include <utility>
+TEST_MACROS();
+#include <valarray>
+TEST_MACROS();
+#include <variant>
+TEST_MACROS();
+#include <vector>
+TEST_MACROS();
+#include <version>
+TEST_MACROS();
+#include <wchar.h>
+TEST_MACROS();
+#include <wctype.h>
+TEST_MACROS();
+
+// experimental headers
+#if __cplusplus >= 201103L
+#    include <experimental/algorithm>
+TEST_MACROS();
+#    if defined(__cpp_coroutines)
+#        include <experimental/coroutine>
+TEST_MACROS();
+#    endif
+#    include <experimental/deque>
+TEST_MACROS();
+#    include <experimental/filesystem>
+TEST_MACROS();
+#    include <experimental/forward_list>
+TEST_MACROS();
+#    include <experimental/functional>
+TEST_MACROS();
+#    include <experimental/iterator>
+TEST_MACROS();
+#    include <experimental/list>
+TEST_MACROS();
+#    include <experimental/map>
+TEST_MACROS();
+#    include <experimental/memory_resource>
+TEST_MACROS();
+#    include <experimental/propagate_const>
+TEST_MACROS();
+#    ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#        include <experimental/regex>
+TEST_MACROS();
+#    endif
+#    include <experimental/set>
+TEST_MACROS();
+#    include <experimental/simd>
+TEST_MACROS();
+#    include <experimental/string>
+TEST_MACROS();
+#    include <experimental/type_traits>
+TEST_MACROS();
+#    include <experimental/unordered_map>
+TEST_MACROS();
+#    include <experimental/unordered_set>
+TEST_MACROS();
+#    include <experimental/utility>
+TEST_MACROS();
+#    include <experimental/vector>
+TEST_MACROS();
+#endif // __cplusplus >= 201103L
+
+// extended headers
+#include <ext/hash_map>
+TEST_MACROS();
+#include <ext/hash_set>
+TEST_MACROS();
+
+// clang-format on
+
+////////////////////////////////////////////////////////////////////////////////
+// END-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////

diff  --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
index 71842dcc5038..435cc2f9988f 100644
--- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
+++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp
@@ -1,188 +1,228 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// Ensure that none of the standard C++ headers implicitly include cassert or
-// assert.h (because assert() is implemented as a macro).
-
-// GCC 5 has incomplete support for C++17, so some headers fail when included.
-// UNSUPPORTED: gcc-5 && c++17
-
-// Prevent <ext/hash_map> from generating deprecated warnings for this test.
-#if defined(__DEPRECATED)
-#undef __DEPRECATED
-#endif
-
-// Top level headers
-#include <algorithm>
-#include <any>
-#include <array>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <atomic>
-#endif
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <barrier>
-#endif
-#include <bit>
-#include <bitset>
-#include <ccomplex>
-#include <cctype>
-#include <cerrno>
-#include <cfenv>
-#include <cfloat>
-#include <charconv>
-#include <chrono>
-#include <cinttypes>
-#include <ciso646>
-#include <climits>
-#include <cmath>
-#include <compare>
-#include <complex>
-#include <complex.h>
-#include <concepts>
-#include <condition_variable>
-#include <csetjmp>
-#include <csignal>
-#include <cstdarg>
-#include <cstdbool>
-#include <cstddef>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <ctgmath>
-#include <ctime>
-#include <ctype.h>
-#include <cwchar>
-#include <cwctype>
-#include <deque>
-#include <errno.h>
-#include <exception>
-#include <execution>
-#include <fenv.h>
-#include <filesystem>
-#include <float.h>
-#include <forward_list>
-#include <functional>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <future>
-#endif
-#include <initializer_list>
-#include <inttypes.h>
-#include <iosfwd>
-#include <iterator>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <latch>
-#endif
-#include <limits>
-#include <limits.h>
-#include <list>
-#include <map>
-#include <math.h>
-#include <memory>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <mutex>
-#endif
-#include <new>
-#include <numbers>
-#include <numeric>
-#include <optional>
-#include <queue>
-#include <random>
-#include <ratio>
-#include <scoped_allocator>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <semaphore>
-#endif
-#include <set>
-#include <setjmp.h>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <shared_mutex>
-#endif
-#include <span>
-#include <stack>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdexcept>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include <string.h>
-#include <string_view>
-#include <system_error>
-#include <tgmath.h>
-#ifndef _LIBCPP_HAS_NO_THREADS
-#include <thread>
-#endif
-#include <tuple>
-#include <typeindex>
-#include <typeinfo>
-#include <type_traits>
-#include <unordered_map>
-#include <unordered_set>
-#include <utility>
-#include <valarray>
-#include <variant>
-#include <vector>
-#include <version>
-#include <wchar.h>
-#include <wctype.h>
-
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
-#   include <clocale>
-#   include <codecvt>
-#   include <fstream>
-#   include <iomanip>
-#   include <ios>
-#   include <iostream>
-#   include <istream>
-#   include <locale>
-#   include <locale.h>
-#   include <ostream>
-#   include <regex>
-#   include <sstream>
-#   include <streambuf>
-#   include <strstream>
-#   if __cplusplus >= 201103L
-#       include <experimental/regex>
-#   endif
-#endif
-
-// experimental headers
-#if __cplusplus >= 201103L
-#include <experimental/algorithm>
-#if defined(__cpp_coroutines)
-#include <experimental/coroutine>
-#endif
-#include <experimental/deque>
-#include <experimental/filesystem>
-#include <experimental/forward_list>
-#include <experimental/functional>
-#include <experimental/iterator>
-#include <experimental/list>
-#include <experimental/map>
-#include <experimental/memory_resource>
-#include <experimental/propagate_const>
-#include <experimental/set>
-#include <experimental/simd>
-#include <experimental/string>
-#include <experimental/type_traits>
-#include <experimental/unordered_map>
-#include <experimental/unordered_set>
-#include <experimental/utility>
-#include <experimental/vector>
-#endif // __cplusplus >= 201103L
-
-// extended headers
-#include <ext/hash_map>
-#include <ext/hash_set>
-
-#ifdef assert
-#error "Do not include cassert or assert.h in standard header files"
-#endif
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Ensure that none of the standard C++ headers implicitly include cassert or
+// assert.h (because assert() is implemented as a macro).
+
+// GCC 5 has incomplete support for C++17, so some headers fail when included.
+// UNSUPPORTED: gcc-5 && c++17
+
+// Prevent <ext/hash_map> from generating deprecated warnings for this test.
+#if defined(__DEPRECATED)
+#    undef __DEPRECATED
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// BEGIN-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+
+// clang-format off
+
+// WARNING: This test was generated by generate_header_tests.py
+// and should not be edited manually.
+
+// Top level headers
+#include <algorithm>
+#include <any>
+#include <array>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <atomic>
+#endif
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <barrier>
+#endif
+#include <bit>
+#include <bitset>
+#include <ccomplex>
+#include <cctype>
+#include <cerrno>
+#include <cfenv>
+#include <cfloat>
+#include <charconv>
+#include <chrono>
+#include <cinttypes>
+#include <ciso646>
+#include <climits>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <clocale>
+#endif
+#include <cmath>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <codecvt>
+#endif
+#include <compare>
+#include <complex>
+#include <complex.h>
+#include <concepts>
+#include <condition_variable>
+#include <csetjmp>
+#include <csignal>
+#include <cstdarg>
+#include <cstdbool>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctgmath>
+#include <ctime>
+#include <ctype.h>
+#include <cwchar>
+#include <cwctype>
+#include <deque>
+#include <errno.h>
+#include <exception>
+#include <execution>
+#include <fenv.h>
+#include <filesystem>
+#include <float.h>
+#include <forward_list>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <fstream>
+#endif
+#include <functional>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <future>
+#endif
+#include <initializer_list>
+#include <inttypes.h>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <iomanip>
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <ios>
+#endif
+#include <iosfwd>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <iostream>
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <istream>
+#endif
+#include <iterator>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <latch>
+#endif
+#include <limits>
+#include <limits.h>
+#include <list>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <locale>
+#endif
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <locale.h>
+#endif
+#include <map>
+#include <math.h>
+#include <memory>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <mutex>
+#endif
+#include <new>
+#include <numbers>
+#include <numeric>
+#include <optional>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <ostream>
+#endif
+#include <queue>
+#include <random>
+#include <ratio>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <regex>
+#endif
+#include <scoped_allocator>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <semaphore>
+#endif
+#include <set>
+#include <setjmp.h>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <shared_mutex>
+#endif
+#include <span>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <sstream>
+#endif
+#include <stack>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdexcept>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <streambuf>
+#endif
+#include <string>
+#include <string.h>
+#include <string_view>
+#ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#    include <strstream>
+#endif
+#include <system_error>
+#include <tgmath.h>
+#ifndef _LIBCPP_HAS_NO_THREADS
+#    include <thread>
+#endif
+#include <tuple>
+#include <typeindex>
+#include <typeinfo>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <valarray>
+#include <variant>
+#include <vector>
+#include <version>
+#include <wchar.h>
+#include <wctype.h>
+
+// experimental headers
+#if __cplusplus >= 201103L
+#    include <experimental/algorithm>
+#    if defined(__cpp_coroutines)
+#        include <experimental/coroutine>
+#    endif
+#    include <experimental/deque>
+#    include <experimental/filesystem>
+#    include <experimental/forward_list>
+#    include <experimental/functional>
+#    include <experimental/iterator>
+#    include <experimental/list>
+#    include <experimental/map>
+#    include <experimental/memory_resource>
+#    include <experimental/propagate_const>
+#    ifndef _LIBCPP_HAS_NO_LOCALIZATION
+#        include <experimental/regex>
+#    endif
+#    include <experimental/set>
+#    include <experimental/simd>
+#    include <experimental/string>
+#    include <experimental/type_traits>
+#    include <experimental/unordered_map>
+#    include <experimental/unordered_set>
+#    include <experimental/utility>
+#    include <experimental/vector>
+#endif // __cplusplus >= 201103L
+
+// extended headers
+#include <ext/hash_map>
+#include <ext/hash_set>
+
+// clang-format on
+
+////////////////////////////////////////////////////////////////////////////////
+// END-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef assert
+#error "Do not include cassert or assert.h in standard header files"
+#endif

diff  --git a/libcxx/utils/generate_header_tests.py b/libcxx/utils/generate_header_tests.py
new file mode 100644
index 000000000000..961e0fb81a1d
--- /dev/null
+++ b/libcxx/utils/generate_header_tests.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python
+
+import glob
+import os
+import posixpath
+import re
+
+
+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)
+    include_path = os.path.join(src_root, 'include')
+    assert os.path.exists(include_path)
+    libcxx_test_path = os.path.join(src_root, 'test', 'libcxx')
+    assert os.path.exists(libcxx_test_path)
+    return script_name, src_root, include_path, libcxx_test_path
+
+
+script_name, source_root, include_path, libcxx_test_path = get_libcxx_paths()
+
+header_markup = {
+    "atomic": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "barrier": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "future": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "latch": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "mutex": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "shared_mutex": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "semaphore": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+    "thread": ["ifndef _LIBCPP_HAS_NO_THREADS"],
+
+    "clocale": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "codecvt": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "fstream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "iomanip": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "ios": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "iostream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "istream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "locale": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "locale.h": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "ostream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "regex": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "sstream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "streambuf": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+    "strstream": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+
+    "experimental/coroutine": ["if defined(__cpp_coroutines)"],
+    "experimental/regex": ["ifndef _LIBCPP_HAS_NO_LOCALIZATION"],
+}
+
+allowed_extensions = ['', '.h']
+indent_width = 4
+
+
+begin_pattern = """\
+////////////////////////////////////////////////////////////////////////////////
+// BEGIN-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+"""
+
+warning_note = """\
+// WARNING: This test was generated by {script_name}
+// and should not be edited manually.
+
+""".format(script_name=script_name)
+
+end_pattern = """\
+////////////////////////////////////////////////////////////////////////////////
+// END-GENERATED-HEADERS
+////////////////////////////////////////////////////////////////////////////////
+"""
+
+generated_part_pattern = re.compile(re.escape(begin_pattern) + ".*" + re.escape(end_pattern),
+                                    re.MULTILINE | re.DOTALL)
+
+headers_template = """\
+// Top level headers
+{top_level_headers}
+
+// experimental headers
+#if __cplusplus >= 201103L
+{experimental_headers}
+#endif // __cplusplus >= 201103L
+
+// extended headers
+{extended_headers}
+"""
+
+
+def should_keep_header(p, exclusions=None):
+    if os.path.isdir(p):
+        return False
+
+    if exclusions:
+        relpath = os.path.relpath(p, include_path)
+        relpath = posixpath.join(*os.path.split(relpath))
+        if relpath in exclusions:
+            print('Excluded file:', relpath)
+            return False
+
+    return os.path.splitext(p)[1] in allowed_extensions
+
+
+def produce_include(relpath, indent_level, post_include=None):
+    relpath = posixpath.join(*os.path.split(relpath))
+    template = "{preambule}#{indentation}include <{include}>{post_include}{postambule}"
+
+    base_indentation = ' '*(indent_width * indent_level)
+    next_indentation = base_indentation + ' '*(indent_width)
+    post_include = "\n{}".format(post_include) if post_include else ''
+
+    markup = header_markup.get(relpath, None)
+    if markup:
+        preambule = '#{indentation}{directive}\n'.format(
+            directive=markup[0],
+            indentation=base_indentation,
+        )
+        postambule = '\n#{indentation}endif'.format(
+            indentation=base_indentation,
+        )
+        indentation = next_indentation
+    else:
+        preambule = ''
+        postambule = ''
+        indentation = base_indentation
+
+    return template.format(
+        include=relpath,
+        post_include=post_include,
+        preambule=preambule,
+        postambule=postambule,
+        indentation=indentation,
+    )
+
+
+def produce_headers(path_parts, indent_level, post_include=None, exclusions=None):
+    pattern = os.path.join(*path_parts, '[a-z]*')
+
+    include_headers = glob.glob(pattern, recursive=False)
+
+    include_headers = [
+        produce_include(os.path.relpath(p, include_path),
+                        indent_level, post_include=post_include)
+        for p in include_headers
+        if should_keep_header(p, exclusions)]
+
+    return '\n'.join(include_headers)
+
+
+def produce_top_level_headers(post_include=None, exclusions=None):
+    return produce_headers([include_path], 0, post_include=post_include, exclusions=exclusions)
+
+
+def produce_experimental_headers(post_include=None, exclusions=None):
+    return produce_headers([include_path, 'experimental'], 1, post_include=post_include, exclusions=exclusions)
+
+
+def produce_extended_headers(post_include=None, exclusions=None):
+    return produce_headers([include_path, 'ext'], 0, post_include=post_include, exclusions=exclusions)
+
+
+def replace_generated_headers(test_path, test_str):
+    with open(test_path, 'r') as f:
+        content = f.read()
+
+    preambule = begin_pattern + '\n// clang-format off\n\n' + warning_note
+    postambule = '\n// clang-format on\n\n' + end_pattern
+    content = generated_part_pattern.sub(
+        preambule + test_str + postambule, content)
+
+    with open(test_path, 'w') as f:
+        f.write(content)
+
+
+def produce_test(test_filename, exclusions=None, post_include=None):
+    test_str = headers_template.format(
+        top_level_headers=produce_top_level_headers(
+            post_include=post_include,
+            exclusions=exclusions,
+        ),
+        experimental_headers=produce_experimental_headers(
+            post_include=post_include,
+        ),
+        extended_headers=produce_extended_headers(
+            post_include=post_include,
+        ),
+    )
+
+    replace_generated_headers(os.path.join(
+        libcxx_test_path, test_filename), test_str)
+
+
+def main():
+    produce_test('double_include.sh.cpp')
+    produce_test('min_max_macros.compile.pass.cpp',
+                 post_include='TEST_MACROS();')
+    produce_test('no_assert_include.compile.pass.cpp',
+                 exclusions=['cassert'])
+
+
+if __name__ == '__main__':
+    main()


        


More information about the libcxx-commits mailing list