summaryrefslogtreecommitdiff
path: root/libcxx/test/libcxx-03/transitive_includes.gen.py
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/test/libcxx-03/transitive_includes.gen.py')
-rw-r--r--libcxx/test/libcxx-03/transitive_includes.gen.py102
1 files changed, 102 insertions, 0 deletions
diff --git a/libcxx/test/libcxx-03/transitive_includes.gen.py b/libcxx/test/libcxx-03/transitive_includes.gen.py
new file mode 100644
index 000000000000..6f9924043663
--- /dev/null
+++ b/libcxx/test/libcxx-03/transitive_includes.gen.py
@@ -0,0 +1,102 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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 don't remove transitive includes of public C++ headers in the library accidentally.
+# When we remove a transitive public include, clients tend to break because they don't always
+# properly include what they use. Note that we don't check which system (C) headers are
+# included transitively, because that is too unstable across platforms, and hence difficult
+# to test for.
+#
+# This is not meant to block libc++ from removing unused transitive includes
+# forever, however we do try to group removals for a couple of releases
+# to avoid breaking users at every release.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+
+# block Lit from interpreting a RUN/XFAIL/etc inside the generation script
+# END.
+
+import sys
+sys.path.append(sys.argv[1])
+from libcxx.header_information import lit_header_restrictions, public_headers
+
+import re
+
+# To re-generate the list of expected headers, temporarily set this to True, and run this test.
+# Note that this needs to be done for all supported language versions of libc++:
+# for std in c++03 c++11 c++14 c++17 c++20 c++23 c++26; do <build>/bin/llvm-lit --param std=$std libcxx/test/libcxx/transitive_includes.gen.py; done
+regenerate_expected_results = False
+
+if regenerate_expected_results:
+ print(
+ f"""\
+//--- generate-transitive-includes.sh.cpp
+// RUN: mkdir %t
+"""
+ )
+
+ all_traces = []
+ for header in sorted(public_headers):
+ if header.is_C_compatibility() or header.is_internal():
+ continue
+
+ normalized_header = re.sub("/", "_", str(header))
+ print(
+ f"""\
+// RUN: echo "#include <{header}>" | %{{cxx}} -xc++ - %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.{normalized_header}.txt
+"""
+ )
+ all_traces.append(f"%t/trace-includes.{normalized_header}.txt")
+
+ print(
+ f"""\
+// RUN: %{{python}} %{{libcxx-dir}}/test/libcxx/transitive_includes/to_csv.py {' '.join(all_traces)} > %{{libcxx-dir}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv
+"""
+ )
+
+else:
+ for header in public_headers:
+ if header.is_C_compatibility() or header.is_internal():
+ continue
+
+ # Escape slashes for the awk command below
+ escaped_header = str(header).replace("/", "\\/")
+
+ print(
+ f"""\
+//--- {header}.sh.cpp
+{lit_header_restrictions.get(header, '')}
+
+// TODO: Fix this test to make it work with localization or wide characters disabled
+// UNSUPPORTED: no-localization, no-wide-characters, no-threads, no-filesystem, libcpp-has-no-experimental-tzdb
+
+// When built with modules, this test doesn't work because --trace-includes doesn't
+// report the stack of includes correctly.
+// UNSUPPORTED: clang-modules-build
+
+// This test uses --trace-includes, which is not supported by GCC.
+// UNSUPPORTED: gcc
+
+// This test is not supported when we remove the transitive includes provided for backwards
+// compatibility. When we bulk-remove them, we'll adjust the includes that are expected by
+// this test instead.
+// UNSUPPORTED: transitive-includes-disabled
+
+// TODO: Figure out why <stdatomic.h> doesn't work on FreeBSD
+// UNSUPPORTED: LIBCXX-FREEBSD-FIXME
+
+// UNSUPPORTED: FROZEN-CXX03-HEADERS-FIXME
+
+// RUN: mkdir %t
+// RUN: %{{cxx}} %s %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt
+// RUN: %{{python}} %{{libcxx-dir}}/test/libcxx/transitive_includes/to_csv.py %t/trace-includes.txt > %t/actual_transitive_includes.csv
+// RUN: cat %{{libcxx-dir}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv | awk '/^{escaped_header} / {{ print }}' > %t/expected_transitive_includes.csv
+// RUN: diff -w %t/expected_transitive_includes.csv %t/actual_transitive_includes.csv
+#include <{header}>
+"""
+ )