llvm-project/libcxx/test/libcxx/transitive_includes.gen.py
Louis Dionne 7d2b9fafab [libc++] Use Lit annotations for all .gen.py tests
Instead of guarding header tests using #ifdefs inside the tests,
use Lit markup to mark all the tests as unsupported. This is simpler
but also provides better feedback about which tests are being run
when running the test suite.

Differential Revision: https://reviews.llvm.org/D151893
2023-06-06 13:28:09 -07:00

91 lines
4.0 KiB
Python

#===----------------------------------------------------------------------===##
#
# 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}/utils
import sys
sys.path.append(sys.argv[1])
from libcxx.test.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 ${path_to_this_file}; done
regenerate_expected_results = False
BLOCKLIT = '' # block Lit from interpreting a RUN/XFAIL/etc inside the generation script
if regenerate_expected_results:
print(f"""\
//--- generate-transitive-includes.sh.cpp
// RUN{BLOCKLIT}: mkdir %t
""")
all_traces = []
for header in sorted(public_headers):
if header.endswith('.h'): # Skip C compatibility or detail headers
continue
normalized_header = re.sub('/', '_', header)
print(f"""\
// RUN{BLOCKLIT}: 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{BLOCKLIT}: %{{python}} %{{libcxx}}/test/libcxx/transitive_includes_to_csv.py {' '.join(all_traces)} > %{{libcxx}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv
""")
else:
for header in public_headers:
if header.endswith('.h'): # Skip C compatibility or detail headers
continue
# Escape slashes for the awk command below
escaped_header = header.replace('/', '\/')
print(f"""\
//--- {header}.sh.cpp
{lit_header_restrictions.get(header, '')}
// TODO: Fix this test to make it work with filesystem, localization or wide characters disabled
// UNSUPPORTED{BLOCKLIT}: no-filesystem, no-localization, no-wide-characters
// When built with modules, this test doesn't work because --trace-includes doesn't
// report the stack of includes correctly.
// UNSUPPORTED{BLOCKLIT}: modules-build
// This test uses --trace-includes, which is not supported by GCC.
// UNSUPPORTED{BLOCKLIT}: 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{BLOCKLIT}: transitive-includes-disabled
// TODO: Figure out why <stdatomic.h> doesn't work on FreeBSD
// UNSUPPORTED{BLOCKLIT}: LIBCXX-FREEBSD-FIXME
// RUN{BLOCKLIT}: mkdir %t
// RUN{BLOCKLIT}: %{{cxx}} %s %{{flags}} %{{compile_flags}} --trace-includes -fshow-skipped-includes --preprocess > /dev/null 2> %t/trace-includes.txt
// RUN{BLOCKLIT}: %{{python}} %{{libcxx}}/test/libcxx/transitive_includes_to_csv.py %t/trace-includes.txt > %t/actual_transitive_includes.csv
// RUN{BLOCKLIT}: cat %{{libcxx}}/test/libcxx/transitive_includes/%{{cxx_std}}.csv | awk '/^{escaped_header} / {{ print }}' > %t/expected_transitive_includes.csv
// RUN{BLOCKLIT}: diff -w %t/expected_transitive_includes.csv %t/actual_transitive_includes.csv
#include <{header}>
""")