diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -105,6 +105,11 @@ the shared library they shipped should turn this on and see `include/__availability` for more details." OFF) option(LIBCXX_ENABLE_CLANG_TIDY "Whether to compile and run clang-tidy checks" OFF) +option(LIBCXX_ENABLE_STD_MODULE + "Whether to enable the building the C++23 `std` module. This feature is + experimental and has additional dependencies. Only enable this when + interested in testing or developing this module. See + https://libcxx.llvm.org/Modules.html for more information." OFF) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(LIBCXX_DEFAULT_TEST_CONFIG "llvm-libc++-shared-gcc.cfg.in") @@ -418,6 +423,7 @@ if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_MODULE_DIR "${LLVM_BINARY_DIR}/modules/c++/v1") set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LLVM_BINARY_DIR}/include/${LLVM_DEFAULT_TARGET_TRIPLE}/c++/v1") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH "Path where built libc++ libraries should be installed.") @@ -431,9 +437,11 @@ if(LLVM_LIBRARY_OUTPUT_INTDIR) set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_MODULE_DIR "${LLVM_BINARY_DIR}/modules/c++/v1") else() set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1") + set(LIBCXX_GENERATED_MODULE_DIR "${CMAKE_BINARY_DIR}/modules/c++/v1") endif() set(LIBCXX_GENERATED_INCLUDE_TARGET_DIR "${LIBCXX_GENERATED_INCLUDE_DIR}") set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX} CACHE PATH @@ -865,6 +873,9 @@ add_subdirectory(include) add_subdirectory(src) add_subdirectory(utils) +if (LIBCXX_ENABLE_STD_MODULE) + add_subdirectory(modules) +endif() set(LIBCXX_TEST_DEPS "cxx_experimental") @@ -876,6 +887,10 @@ list(APPEND LIBCXX_TEST_DEPS cxx-tidy) endif() +if (LIBCXX_ENABLE_STD_MODULE) + list(APPEND LIBCXX_TEST_DEPS generate-cxx-modules) +endif() + if (LIBCXX_INCLUDE_BENCHMARKS) add_subdirectory(benchmarks) endif() diff --git a/libcxx/cmake/caches/Generic-module-std-cxx23.cmake b/libcxx/cmake/caches/Generic-module-std-cxx23.cmake new file mode 100644 --- /dev/null +++ b/libcxx/cmake/caches/Generic-module-std-cxx23.cmake @@ -0,0 +1,4 @@ +set(LIBCXX_ENABLE_STD_MODULE ON CACHE BOOL "") +set(LIBCXX_TEST_PARAMS "enable_modules=std;std=c++23" CACHE STRING "") +set(LIBCXXABI_TEST_PARAMS "${LIBCXX_TEST_PARAMS}" CACHE STRING "") + diff --git a/libcxx/docs/Contributing.rst b/libcxx/docs/Contributing.rst --- a/libcxx/docs/Contributing.rst +++ b/libcxx/docs/Contributing.rst @@ -35,6 +35,7 @@ - Did you update the synopsis of the relevant headers? - Did you update the relevant files to track implementation status (in ``docs/Status/``)? - Did you mark all functions and type declarations with the :ref:`proper visibility macro `? +- Did you add all new named declarations to the ``std`` module? - If you added a header: - Did you add it to ``include/module.modulemap.in``? diff --git a/libcxx/docs/Modules.rst b/libcxx/docs/Modules.rst new file mode 100644 --- /dev/null +++ b/libcxx/docs/Modules.rst @@ -0,0 +1,221 @@ +.. _ModulesInLibcxx: + +================= +Modules in libc++ +================= + +.. warning:: Modules are an experimental feature. It has additional build + requirements and not all libc++ configurations are supported yet. + + The work is still in an early developement state and not + considered stable nor complete + +This page contains information regarding C++23 module support in libc++. +There are two kinds of modules available in Clang + + * `Clang specific modules `_ + * `C++ modules `_ + +This page mainly discusses the C++ modules. In C++20 there are also header units, +these are not part of this document. + +Overview +======== + +The module sources are stored in ``.cppm`` files. Modules need to be available +as BMIs, which are ``.pcm`` files for Clang. BMIs are not portable, they depend +on the compiler used and its compilation flags. Therefore there needs to be a +way to distribute the ``.cppm`` files to the user and offer a way for them to +build and use the ``.pcm`` files. It is expected this will be done by build +systems in the future. To aid early adaptor and build system vendors libc++ +currently ships a CMake project to aid building modules. + +.. note:: This CMake file is intended to be a temporary solution and will + be removed in the future. The timeline for the removal depends + on the availability of build systems with proper module support. + +What works +~~~~~~~~~~ + + * Building BMIs + * Running tests using the ``std`` module + * Using the ``std`` module in external projects + * The following "parts disabled" configuration options are supported + + * ``LIBCXX_ENABLE_LOCALIZATION`` + * ``LIBCXX_ENABLE_WIDE_CHARACTERS`` + +Some of the current limitations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * There is no official build system support, libc++ has experimental CMake support + * Requires CMake 3.26 + * Requires Ninja 1.11 + * Requires a recent Clang 17 + * The path to the compiler may not be a symlink, ``clang-scan-deps`` does + not handle that case properly + * Only C++23 is tested + * The libc++ is not tested with modules instead of headers + * The module ``.cppm`` files are not installed + * The experimental ``PSTL`` library is not supported + * Clang: + * Including headers after importing the ``std`` module may fail. This is + hard to solve and there is a work-around by first including all headers + `bug report `__. + +Blockers +~~~~~~~~ + + * libc++ + + * Currently the tests only test with modules enabled, but not module is + imported. When converting tests to using modules there are still + failures. These are under investigation. + + * It has not been determined how to fully test libc++ with modules instead + of headers. + + * Clang + + * Some concepts do not work properly + `bug report `__. + + +Using in external projects +========================== + +Users need to be able to build their own BMI files. + +.. note:: The requirements for users to build their own BMI files will remain + true for the forseeable future. For now this needs to be done manually. + Once libc++'s implementation is more mature we will reach out to build + system vendors, with the goal that the building of the BMI files will be + done by the build system. + +Currently this requires a local build of libc++ with modules enabled. Since +modules are not part of the installation yet, they are used from the build +directory. First libc++ needs to be build with module support enabled. + +.. code-block:: bash + + $ git clone https://github.com/llvm/llvm-project.git + $ cd llvm-project + $ mkdir build + $ cmake -G Ninja -S runtimes -B build -DLIBCXX_ENABLE_STD_MODULE=ON -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" + $ ninja -C build + +The above ``build`` directory will be referred to as ```` in the other +rest of these instructions. + +This is a small sample program that uses the module ``std``. It consists of a +``CMakeLists.txt`` and a ``main.cpp`` file. + +.. code-block:: cpp + + import std; + + int main() { std::cout << "Hello modular world\n"; } + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR) + project("module" + LANGUAGES CXX + ) + + # + # Set language version used + # + + # At the moment only C++23 is tested. + set(CMAKE_CXX_STANDARD 23) + set(CMAKE_CXX_STANDARD_REQUIRED YES) + # Clang doesn't support compiler extensions for modules. + set(CMAKE_CXX_EXTENSIONS OFF) + + # + # Enable modules in CMake + # + + # This is required to write your own modules in your project. + set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) + + # + # Import the modules from libc++ + # + + include(FetchContent) + FetchContent_Declare( + std + URL "file://${LIBCXX_BUILD}/modules/c++/v1/" + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + FetchContent_GetProperties(std) + if(NOT std_POPULATED) + FetchContent_Populate(std) + add_subdirectory(${std_SOURCE_DIR} ${std_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() + + # + # Adjust project compiler flags + # + + # Implicit paths are not allowed in the future. + add_compile_options($<$:-fprebuilt-module-path=${CMAKE_BINARY_DIR}/_deps/std-build/CMakeFiles/std.dir/>) + add_compile_options($<$:-nostdinc++>) + # The include path needs to be set to be able to use macros from headers. + # For example from, the headers and . + add_compile_options($<$:-isystem>) + add_compile_options($<$:${LIBCXX_BUILD}/include/c++/v1>) + + # + # Adjust project linker flags + # + + add_link_options($<$:-nostdlib++>) + add_link_options($<$:-L${LIBCXX_BUILD}/lib>) + add_link_options($<$:-Wl,-rpath,${LIBCXX_BUILD}/lib>) + # Linking against std is required for CMake to get the proper dependencies + link_libraries(std c++) + + # + # Add the project + # + + add_executable(main) + target_sources(main + PRIVATE + main.cpp + ) + +Building this project is done with the following steps, assuming the files +``main.cpp`` and ``CMakeLists.txt`` are copied in the current directory. + +.. code-block:: bash + + $ mkdir build + $ cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER= -DLIBCXX_BUILD= + $ ninja -C build + $ build/main + +.. warning:: ```` should point point to the real binary and + not to a symlink. + +.. warning:: When using these examples in your own projects make sure the + compilation flags are the same for the ``std`` module and your + project. Some flags will affect the generated code, when these + are different the module cannot be used. For example using + ``-pthread`` in your project and not in the module will give + errors like + + ``error: POSIX thread support was disabled in PCH file but is currently enabled`` + + ``error: module file _deps/std-build/CMakeFiles/std.dir/std.pcm cannot be loaded due to a configuration mismatch with the current compilation [-Wmodule-file-config-mismatch]`` + +If you have questions about modules free free to ask them in the ``#libcxx`` +channel on `LLVM's Discord server `__. + +If you think you've found a bug please it using the `LLVM bug tracker +`_. Please make sure the issue +you found is not one of the known bugs or limitations on this page. diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -35,6 +35,9 @@ What's New in Libc++ 17.0.0? ============================ +There is an experimental implementation of the C++23 ``std`` module. See +:ref:`ModulesInLibcxx` for more information. + Implemented Papers ------------------ - P2520R0 - ``move_iterator`` should be a random access iterator @@ -108,6 +111,14 @@ - The classes ``strstreambuf`` , ``istrstream``, ``ostrstream``, and ``strstream`` have been deprecated. They have been deprecated in the Standard since C++98, but were never marked as deprecated in libc++. +- The lit test parameter ``enable_modules`` changed from a Boolean to an enum. The changes are + + - ``False`` became ``none``. This option does not test with modules enabled. + - ``True`` became ``clang``. This option tests using Clang modules. + - ``std`` is a new optional and tests with the experimental C++23 ``std`` module. + + The old values still work but will be removed in the LLVM-18. + Upcoming Deprecations and Removals ---------------------------------- @@ -133,6 +144,8 @@ and ```` will be removed in LLVM 18, as all their contents will have been implemented in namespace ``std`` for at least two releases. +- The lit test parameter ``enable_modules`` will no longer support ``True`` and ``False`` as valid input. + API Changes ----------- diff --git a/libcxx/docs/index.rst b/libcxx/docs/index.rst --- a/libcxx/docs/index.rst +++ b/libcxx/docs/index.rst @@ -39,6 +39,7 @@ BuildingLibcxx TestingLibcxx Contributing + Modules ReleaseProcedure Status/Cxx14 Status/Cxx17 @@ -111,12 +112,17 @@ ============ =============== ========================== ===================== Compiler Versions Restrictions Support policy ============ =============== ========================== ===================== -Clang 15, 16, 17-git latest two stable releases per `LLVM's release page `_ and the development version +Clang 15, 16, 17-git [#note-modules]_ latest two stable releases per `LLVM's release page `_ and the development version AppleClang 14 latest stable release per `Xcode's release page `_ Open XL 17.1 (AIX) latest stable release per `Open XL's documentation page `_ GCC 12 In C++11 or later only latest stable release per `GCC's release page `_ ============ =============== ========================== ===================== +.. note:: + + .. [#note-modules] The C++23 ``std`` module has additional requirement. + This is an optional feature, see :ref:`ModulesInLibcxx`. + Libc++ also supports common platforms and architectures: =============== ========================= ============================ diff --git a/libcxx/modules/.clang-format b/libcxx/modules/.clang-format new file mode 100644 --- /dev/null +++ b/libcxx/modules/.clang-format @@ -0,0 +1,3 @@ +BasedOnStyle: InheritParentConfig + +NamespaceIndentation: All diff --git a/libcxx/modules/CMakeLists.txt b/libcxx/modules/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libcxx/modules/CMakeLists.txt @@ -0,0 +1,146 @@ +if (CMAKE_VERSION VERSION_LESS 3.26) + message(WARNING "The libc++ modules won't be available because the version of CMake is too old to support them.") + return() +endif() + +# The headers of Table 24: C++ library headers [tab:headers.cpp] +# and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c] +set(LIBCXX_SOURCES_MODULE_STD + std.cppm + std/algorithm.cppm + std/any.cppm + std/array.cppm + std/atomic.cppm + std/barrier.cppm + std/bit.cppm + std/bitset.cppm + std/cassert.cppm + std/cctype.cppm + std/cerrno.cppm + std/cfenv.cppm + std/cfloat.cppm + std/charconv.cppm + std/chrono.cppm + std/cinttypes.cppm + std/climits.cppm + std/clocale.cppm + std/cmath.cppm + std/codecvt.cppm + std/compare.cppm + std/complex.cppm + std/concepts.cppm + std/condition_variable.cppm + std/coroutine.cppm + std/csetjmp.cppm + std/csignal.cppm + std/cstdarg.cppm + std/cstddef.cppm + std/cstdint.cppm + std/cstdio.cppm + std/cstdlib.cppm + std/cstring.cppm + std/ctime.cppm + std/cuchar.cppm + std/cwchar.cppm + std/cwctype.cppm + std/deque.cppm + std/exception.cppm + std/execution.cppm + std/expected.cppm + std/filesystem.cppm + std/flat_map.cppm + std/flat_set.cppm + std/format.cppm + std/forward_list.cppm + std/fstream.cppm + std/functional.cppm + std/future.cppm + std/generator.cppm + std/initializer_list.cppm + std/iomanip.cppm + std/ios.cppm + std/iosfwd.cppm + std/iostream.cppm + std/iostream.cppm + std/istream.cppm + std/iterator.cppm + std/latch.cppm + std/limits.cppm + std/list.cppm + std/locale.cppm + std/map.cppm + std/mdspan.cppm + std/memory.cppm + std/memory_resource.cppm + std/mutex.cppm + std/new.cppm + std/numbers.cppm + std/numeric.cppm + std/optional.cppm + std/ostream.cppm + std/print.cppm + std/queue.cppm + std/random.cppm + std/ranges.cppm + std/ratio.cppm + std/regex.cppm + std/scoped_allocator.cppm + std/semaphore.cppm + std/set.cppm + std/shared_mutex.cppm + std/source_location.cppm + std/span.cppm + std/spanstream.cppm + std/sstream.cppm + std/stack.cppm + std/stacktrace.cppm + std/stdexcept.cppm + std/stdexcept.cppm + std/stdfloat.cppm + std/stop_token.cppm + std/streambuf.cppm + std/string.cppm + std/string_view.cppm + std/strstream.cppm + std/syncstream.cppm + std/system_error.cppm + std/thread.cppm + std/tuple.cppm + std/type_traits.cppm + std/typeindex.cppm + std/typeinfo.cppm + std/unordered_map.cppm + std/unordered_set.cppm + std/utility.cppm + std/valarray.cppm + std/variant.cppm + std/vector.cppm + std/version.cppm +) + +# TODO MODULES the CMakeLists.txt in the install directory is only temporary +# When that is removed the configured file can use the substitution +# LIBCXX_GENERATED_INCLUDE_TARGET_DIR avoiding this set. +# Also clean up the parts needed to generate the install version. +set(LIBCXX_CONFIGURED_INCLUDE_DIR ${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}) +configure_file( + "CMakeLists.txt.in" + "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt" + @ONLY +) + +set(_all_modules "${LIBCXX_GENERATED_MODULE_DIR}/CMakeLists.txt") +foreach(file ${LIBCXX_SOURCES_MODULE_STD}) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${file}") + set(dst "${LIBCXX_GENERATED_MODULE_DIR}/${file}") + add_custom_command(OUTPUT ${dst} + DEPENDS ${src} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} + COMMENT "Copying CXX module ${file}") + list(APPEND _all_modules "${dst}") +endforeach() + +add_custom_target(generate-cxx-modules + ALL DEPENDS + ${_all_modules} +) diff --git a/libcxx/modules/CMakeLists.txt.in b/libcxx/modules/CMakeLists.txt.in new file mode 100644 --- /dev/null +++ b/libcxx/modules/CMakeLists.txt.in @@ -0,0 +1,68 @@ +# CMake 3.25 has modules support, but that does not work properly. +cmake_minimum_required(VERSION 3.26) + +project(libc++-modules LANGUAGES CXX) + +# Enable CMake's module support +set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") +set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) + +# Default to C++ extensions being off. Clang's modules support have trouble +# with extensions right now. +set(CMAKE_CXX_EXTENSIONS OFF) + +# Propagates the CMake options to the modules. +# +# This uses the std module hard-coded since the std.compat module does not +# depend on these flags. +macro(compile_define_if_not condition def) + if (NOT ${condition}) + target_compile_definitions(std PRIVATE ${def}) + endif() +endmacro() +macro(compile_define_if condition def) + if (${condition}) + target_compile_definitions(std PRIVATE ${def}) + endif() +endmacro() + +if(NOT @LIBCXX_ENABLE_THREADS@ OR NOT @LIBCXXABI_ENABLE_THREADS@ OR NOT @LIBCXX_ENABLE_MONOTONIC_CLOCK@) + message(FATAL_ERROR "Modules without thread support is not yet implemented.") +endif() +if(NOT @LIBCXX_ENABLE_FILESYSTEM@) + message(FATAL_ERROR "Modules without filesystem support is not yet implemented.") +endif() +if(NOT @LIBCXX_ENABLE_RANDOM_DEVICE@) + message(FATAL_ERROR "Modules without randome device support is not yet implemented.") +endif() +if(NOT @LIBCXX_ENABLE_FSTREAM@) + message(FATAL_ERROR "Modules without fstream support is not yet implemented.") +endif() +if(NOT @LIBCXX_ENABLE_UNICODE@) + message(FATAL_ERROR "Modules without Unicode support is not yet implemented.") +endif() +if(NOT @LIBCXX_ENABLE_EXCEPTIONS@ OR NOT @LIBCXXABI_ENABLE_EXCEPTIONS@) + message(FATAL_ERROR "Modules without exception support is not yet implemented.") +endif() + +add_library(std) +target_sources(std + PUBLIC FILE_SET cxx_modules TYPE CXX_MODULES FILES + @LIBCXX_SOURCES_MODULE_STD@ +) + +target_compile_definitions(std PRIVATE _LIBCPP_ENABLE_EXPERIMENTAL) +target_include_directories(std SYSTEM PRIVATE @LIBCXX_CONFIGURED_INCLUDE_DIR@) + +target_compile_options(std + PUBLIC + -nostdinc++ + -Wno-reserved-module-identifier + -Wno-reserved-user-defined-literal + #-Werror + @LIBCXX_COMPILE_FLAGS@ +) +set_target_properties(std + PROPERTIES + OUTPUT_NAME "c++std" +) diff --git a/libcxx/modules/std/iosfwd.cppm b/libcxx/modules/std/iosfwd.cppm --- a/libcxx/modules/std/iosfwd.cppm +++ b/libcxx/modules/std/iosfwd.cppm @@ -12,5 +12,16 @@ export module std:iosfwd; export namespace std { - // All symbols are exported by other modules. + using std::streampos; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + using std::wstreampos; +#endif + using std::u16streampos; + using std::u32streampos; + using std::u8streampos; + + using std::istreambuf_iterator; + using std::ostreambuf_iterator; + + using std::fpos; } // namespace std diff --git a/libcxx/modules/std/set.cppm b/libcxx/modules/std/set.cppm --- a/libcxx/modules/std/set.cppm +++ b/libcxx/modules/std/set.cppm @@ -16,15 +16,7 @@ using std::set; using std::operator==; -#if 0 // P1614 using std::operator<=>; -#else - using std::operator!=; - using std::operator<; - using std::operator>; - using std::operator<=; - using std::operator>=; -#endif using std::swap; diff --git a/libcxx/modules/std/string.cppm b/libcxx/modules/std/string.cppm --- a/libcxx/modules/std/string.cppm +++ b/libcxx/modules/std/string.cppm @@ -71,10 +71,15 @@ // [basic.string.hash], hash support using std::hash; + // TODO MODULES is this a bug? +#if 1 + using std::operator""s; +#else inline namespace literals { inline namespace string_literals { // [basic.string.literals], suffix for basic_string literals using std::literals::string_literals::operator""s; } // namespace string_literals } // namespace literals +#endif } // namespace std diff --git a/libcxx/test/configs/cmake-bridge.cfg.in b/libcxx/test/configs/cmake-bridge.cfg.in --- a/libcxx/test/configs/cmake-bridge.cfg.in +++ b/libcxx/test/configs/cmake-bridge.cfg.in @@ -31,3 +31,10 @@ config.substitutions.append(('%{lib}', '@LIBCXX_LIBRARY_DIR@')) config.substitutions.append(('%{executor}', '@LIBCXX_EXECUTOR@')) config.substitutions.append(('%{test-tools}', '@LIBCXX_TEST_TOOLS_PATH@')) + +# The substitutions needed for building the modules. +# TODO MODULES look at a way to do this without changing the bridge. +config.substitutions.append(('%{module}', '@LIBCXX_GENERATED_MODULE_DIR@')) +config.substitutions.append(('%{cmake}', '@CMAKE_COMMAND@')) +config.substitutions.append(('%{make}', '@CMAKE_MAKE_PROGRAM@')) +config.substitutions.append(('%{generator}', '@CMAKE_GENERATOR@')) diff --git a/libcxx/test/libcxx/module_std.sh.cpp b/libcxx/test/libcxx/module_std.sh.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/module_std.sh.cpp @@ -0,0 +1,862 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// REQUIRES: has-clang-tidy +// REQUIRES: use_module_std + +// The GCC compiler flags are not always compatible with clang-tidy. +// UNSUPPORTED: gcc + +// RUN %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} +// should the headers list just be a list of regexes where symbols from are available... + +/* +BEGIN-SCRIPT + +# Used because the sequence of tokens RUN : can't appear anywhere or it'll confuse Lit. +RUN = "RUN" + +### Remove the headers that have no module associated with them + +# Note all C-headers using .h are filtered in the loop. + +# These headers are not available in C++23, but in older language Standards. +toplevel_headers.remove('ccomplex') +toplevel_headers.remove('ciso646') +toplevel_headers.remove('cstdbool') +toplevel_headers.remove('ctgmath') + +# Ignore several declarations found in the includes. +# +# Part of these items are bugs other are not yet implemented features. +SkipDeclarations = dict() + +# See comment in the header. +SkipDeclarations['cuchar'] = "std::mbstate_t std::size_t" + +# Not in the synopsis. +SkipDeclarations['cwchar'] = "std::FILE" + +# The operators are added for private types like __iom_t10. +SkipDeclarations['iomanip'] = "std::operator<< std::operator>>" + +SkipDeclarations['iosfwd'] = "std::ios_base std::vector" + +# This header also provides declarations in the namespace that might be an error +SkipDeclarations['filesystem'] = "std::filesystem::operator== std::filesystem::operator!=" + +# This is a specialization for a private type +SkipDeclarations['iterator'] = "std::pointer_traits" + +# TODO MODULES +# This definition is declared in string and defined in isteam +# This declaration should be part of string +SkipDeclarations['istream'] = "std::getline" + +# P1614 (at many places) and LWG3519 too. +SkipDeclarations['random'] = "std::operator!=" +# LWG3519 makes these hidden friends. Note the older versions had the requirement of these operations but not in the synopsis. +SkipDeclarations['random'] = SkipDeclarations['random'] + " std::operator<< std::operator>> std::operator==" + +# Declared in the forward header since std::string uses std::allocator +SkipDeclarations['string'] = "std::allocator" +# TODO MODULES remove zombie names +# https://libcxx.llvm.org/Status/Cxx20.html#note-p0619 +SkipDeclarations['memory'] = "std::return_temporary_buffer std::get_temporary_buffer" + +# TODO MODULES this should be part of ios instead +SkipDeclarations['streambuf'] = "std::basic_ios" + +# include/__type_traits/is_swappable.h +SkipDeclarations['type_traits'] = "std::swap" +# TODO MODULES gotten through __functional/unwrap_ref.h +SkipDeclarations['type_traits'] = SkipDeclarations['type_traits'] + " std::reference_wrapper" + +# Add delarations in headers. +# +# Some headers have their defines in a different header, which may have additional declarations +ExtraDeclarations = dict() +# This declaration is in the ostream header. +ExtraDeclarations['system_error'] = "std::operator<<" + +# Adds an extra header file to scan +# +# +ExtraHeader = dict() +# locale has a file and not a subdirectory +ExtraHeader['locale'] = "v1/__locale$" +ExtraHeader['thread'] = "v1/__threading_support$" +ExtraHeader['ranges'] = "v1/__fwd/subrange.h$" + +# The extra header is needed since two headers are required to provide the same definition. +ExtraHeader['functional'] = "v1/__compare/compare_three_way.h$" + +# Create empty file with all parts. +print(f"// {RUN}: echo -n > %t.parts") + +# Validate all module parts. +for i, header in enumerate(toplevel_headers): + if header.endswith('.h'): # Skip C compatibility headers + continue + + # Dump the information as found in the module's cppm file. + print(f"// {RUN}: %{{clang-tidy}} %{{module}}/std/{header}.cppm --checks='-*,libcpp-header-exportable-declarations' " + "-config='{CheckOptions: [ " + f"{{key: libcpp-header-exportable-declarations.Filename, value: {header}.cppm}}, " + "{key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, " + "]}' " + f"--load=%{{test-tools}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} " + f"| sort > %t.{header}.module") + print(f"// {RUN}: cat %t.{header}.module >> %t.parts") + + # Dump the information as found in the module by using the header file(s). + skip_declarations = SkipDeclarations.get(header, "") + if len(skip_declarations): + skip_declarations = f", {{key: libcpp-header-exportable-declarations.SkipDeclarations, value: \"{skip_declarations}\"}}" + + extra_declarations = ExtraDeclarations.get(header, "") + if len(extra_declarations): + extra_declarations = f", {{key: libcpp-header-exportable-declarations.ExtraDeclarations, value: \"{extra_declarations}\"}}" + + extra_header = ExtraHeader.get(header, "") + if len(extra_header): + extra_header = f", {{key: libcpp-header-exportable-declarations.ExtraHeader, value: \"{extra_header}\"}}" + + print(f"// {RUN}: %{{clang-tidy}} %s --checks='-*,libcpp-header-exportable-declarations' " + "-config='{CheckOptions: [ " + f"{{key: libcpp-header-exportable-declarations.Filename, value: {header}}}, " + "{key: libcpp-header-exportable-declarations.FileType, value: Header}, " + f"{skip_declarations} {extra_declarations} {extra_header}, " + "]}' " + f"--load=%{{test-tools}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{compile_flags}} -DTEST_{i} " + f"| sort > %t.{header}.include") + + # Compare the cppm and header file(s) return the same results. + print(f"// {RUN}: diff -u %t.{header}.module %t.{header}.include") + + # The actual include script. + print(f"#if defined(TEST_{i})") + print(f"#include <{header}>") + print("#endif") + +# Validate the module parts against the main module. + +# Merge the data of the parts +print(f"// {RUN}: sort -u -o %t.parts %t.parts") + +# Dump the information as found in std.cppm. +print(f"// {RUN}: %{{clang-tidy}} %{{module}}/std.cppm --checks='-*,libcpp-header-exportable-declarations' " + "-config='{CheckOptions: [ " + "{key: libcpp-header-exportable-declarations.Header, value: std.cppm}, " + "{key: libcpp-header-exportable-declarations.FileType, value: Module}, " + "]}' " + f"--load=%{{test-tools}}/clang_tidy_checks/libcxx-tidy.plugin -- %{{flags}} %{{compile_flags}} " + "| sort > %t.module") + + +# Compare the sum of the parts with the main module. +print(f"// {RUN}: diff -u %t.parts %t.module") + +END-SCRIPT +*/ + +// DO NOT MANUALLY EDIT ANYTHING BETWEEN THE MARKERS BELOW +// GENERATED-MARKER +// RUN: echo -n > %t.parts +// RUN: %{clang-tidy} %{module}/std/algorithm.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: algorithm.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.algorithm.module +// RUN: cat %t.algorithm.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: algorithm}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_0 | sort > %t.algorithm.include +// RUN: diff -u %t.algorithm.module %t.algorithm.include +#if defined(TEST_0) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/any.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: any.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.any.module +// RUN: cat %t.any.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: any}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_1 | sort > %t.any.include +// RUN: diff -u %t.any.module %t.any.include +#if defined(TEST_1) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/array.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: array.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.array.module +// RUN: cat %t.array.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: array}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_2 | sort > %t.array.include +// RUN: diff -u %t.array.module %t.array.include +#if defined(TEST_2) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/atomic.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: atomic.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.atomic.module +// RUN: cat %t.atomic.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: atomic}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_3 | sort > %t.atomic.include +// RUN: diff -u %t.atomic.module %t.atomic.include +#if defined(TEST_3) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/barrier.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: barrier.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.barrier.module +// RUN: cat %t.barrier.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: barrier}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_4 | sort > %t.barrier.include +// RUN: diff -u %t.barrier.module %t.barrier.include +#if defined(TEST_4) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/bit.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: bit.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.bit.module +// RUN: cat %t.bit.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: bit}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_5 | sort > %t.bit.include +// RUN: diff -u %t.bit.module %t.bit.include +#if defined(TEST_5) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/bitset.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: bitset.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.bitset.module +// RUN: cat %t.bitset.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: bitset}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_6 | sort > %t.bitset.include +// RUN: diff -u %t.bitset.module %t.bitset.include +#if defined(TEST_6) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cassert.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cassert.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cassert.module +// RUN: cat %t.cassert.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cassert}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_7 | sort > %t.cassert.include +// RUN: diff -u %t.cassert.module %t.cassert.include +#if defined(TEST_7) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cctype.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cctype.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cctype.module +// RUN: cat %t.cctype.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cctype}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_8 | sort > %t.cctype.include +// RUN: diff -u %t.cctype.module %t.cctype.include +#if defined(TEST_8) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cerrno.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cerrno.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cerrno.module +// RUN: cat %t.cerrno.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cerrno}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_9 | sort > %t.cerrno.include +// RUN: diff -u %t.cerrno.module %t.cerrno.include +#if defined(TEST_9) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cfenv.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cfenv.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cfenv.module +// RUN: cat %t.cfenv.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cfenv}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_10 | sort > %t.cfenv.include +// RUN: diff -u %t.cfenv.module %t.cfenv.include +#if defined(TEST_10) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cfloat.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cfloat.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cfloat.module +// RUN: cat %t.cfloat.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cfloat}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_11 | sort > %t.cfloat.include +// RUN: diff -u %t.cfloat.module %t.cfloat.include +#if defined(TEST_11) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/charconv.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: charconv.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.charconv.module +// RUN: cat %t.charconv.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: charconv}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_12 | sort > %t.charconv.include +// RUN: diff -u %t.charconv.module %t.charconv.include +#if defined(TEST_12) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/chrono.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: chrono.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.chrono.module +// RUN: cat %t.chrono.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: chrono}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_13 | sort > %t.chrono.include +// RUN: diff -u %t.chrono.module %t.chrono.include +#if defined(TEST_13) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cinttypes.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cinttypes.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cinttypes.module +// RUN: cat %t.cinttypes.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cinttypes}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_14 | sort > %t.cinttypes.include +// RUN: diff -u %t.cinttypes.module %t.cinttypes.include +#if defined(TEST_14) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/climits.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: climits.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.climits.module +// RUN: cat %t.climits.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: climits}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_15 | sort > %t.climits.include +// RUN: diff -u %t.climits.module %t.climits.include +#if defined(TEST_15) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/clocale.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: clocale.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.clocale.module +// RUN: cat %t.clocale.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: clocale}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_16 | sort > %t.clocale.include +// RUN: diff -u %t.clocale.module %t.clocale.include +#if defined(TEST_16) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cmath.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cmath.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cmath.module +// RUN: cat %t.cmath.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cmath}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_17 | sort > %t.cmath.include +// RUN: diff -u %t.cmath.module %t.cmath.include +#if defined(TEST_17) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/codecvt.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: codecvt.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.codecvt.module +// RUN: cat %t.codecvt.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: codecvt}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_18 | sort > %t.codecvt.include +// RUN: diff -u %t.codecvt.module %t.codecvt.include +#if defined(TEST_18) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/compare.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: compare.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.compare.module +// RUN: cat %t.compare.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: compare}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_19 | sort > %t.compare.include +// RUN: diff -u %t.compare.module %t.compare.include +#if defined(TEST_19) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/complex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: complex.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.complex.module +// RUN: cat %t.complex.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: complex}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_20 | sort > %t.complex.include +// RUN: diff -u %t.complex.module %t.complex.include +#if defined(TEST_20) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/concepts.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: concepts.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.concepts.module +// RUN: cat %t.concepts.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: concepts}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_22 | sort > %t.concepts.include +// RUN: diff -u %t.concepts.module %t.concepts.include +#if defined(TEST_22) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/condition_variable.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: condition_variable.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.condition_variable.module +// RUN: cat %t.condition_variable.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: condition_variable}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_23 | sort > %t.condition_variable.include +// RUN: diff -u %t.condition_variable.module %t.condition_variable.include +#if defined(TEST_23) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/coroutine.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: coroutine.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.coroutine.module +// RUN: cat %t.coroutine.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: coroutine}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_24 | sort > %t.coroutine.include +// RUN: diff -u %t.coroutine.module %t.coroutine.include +#if defined(TEST_24) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/csetjmp.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: csetjmp.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.csetjmp.module +// RUN: cat %t.csetjmp.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: csetjmp}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_25 | sort > %t.csetjmp.include +// RUN: diff -u %t.csetjmp.module %t.csetjmp.include +#if defined(TEST_25) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/csignal.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: csignal.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.csignal.module +// RUN: cat %t.csignal.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: csignal}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_26 | sort > %t.csignal.include +// RUN: diff -u %t.csignal.module %t.csignal.include +#if defined(TEST_26) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cstdarg.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdarg.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdarg.module +// RUN: cat %t.cstdarg.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdarg}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_27 | sort > %t.cstdarg.include +// RUN: diff -u %t.cstdarg.module %t.cstdarg.include +#if defined(TEST_27) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cstddef.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstddef.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstddef.module +// RUN: cat %t.cstddef.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstddef}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_28 | sort > %t.cstddef.include +// RUN: diff -u %t.cstddef.module %t.cstddef.include +#if defined(TEST_28) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cstdint.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdint.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdint.module +// RUN: cat %t.cstdint.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdint}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_29 | sort > %t.cstdint.include +// RUN: diff -u %t.cstdint.module %t.cstdint.include +#if defined(TEST_29) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cstdio.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdio.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdio.module +// RUN: cat %t.cstdio.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdio}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_30 | sort > %t.cstdio.include +// RUN: diff -u %t.cstdio.module %t.cstdio.include +#if defined(TEST_30) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cstdlib.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdlib.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstdlib.module +// RUN: cat %t.cstdlib.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstdlib}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_31 | sort > %t.cstdlib.include +// RUN: diff -u %t.cstdlib.module %t.cstdlib.include +#if defined(TEST_31) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cstring.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstring.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cstring.module +// RUN: cat %t.cstring.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cstring}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_32 | sort > %t.cstring.include +// RUN: diff -u %t.cstring.module %t.cstring.include +#if defined(TEST_32) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/ctime.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ctime.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ctime.module +// RUN: cat %t.ctime.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ctime}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_33 | sort > %t.ctime.include +// RUN: diff -u %t.ctime.module %t.ctime.include +#if defined(TEST_33) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cuchar.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cuchar.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cuchar.module +// RUN: cat %t.cuchar.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cuchar}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::mbstate_t std::size_t"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_35 | sort > %t.cuchar.include +// RUN: diff -u %t.cuchar.module %t.cuchar.include +#if defined(TEST_35) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cwchar.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cwchar.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cwchar.module +// RUN: cat %t.cwchar.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cwchar}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::FILE"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_36 | sort > %t.cwchar.include +// RUN: diff -u %t.cwchar.module %t.cwchar.include +#if defined(TEST_36) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/cwctype.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cwctype.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.cwctype.module +// RUN: cat %t.cwctype.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: cwctype}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_37 | sort > %t.cwctype.include +// RUN: diff -u %t.cwctype.module %t.cwctype.include +#if defined(TEST_37) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/deque.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: deque.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.deque.module +// RUN: cat %t.deque.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: deque}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_38 | sort > %t.deque.include +// RUN: diff -u %t.deque.module %t.deque.include +#if defined(TEST_38) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/exception.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: exception.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.exception.module +// RUN: cat %t.exception.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: exception}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_40 | sort > %t.exception.include +// RUN: diff -u %t.exception.module %t.exception.include +#if defined(TEST_40) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/execution.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: execution.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.execution.module +// RUN: cat %t.execution.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: execution}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_41 | sort > %t.execution.include +// RUN: diff -u %t.execution.module %t.execution.include +#if defined(TEST_41) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/expected.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: expected.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.expected.module +// RUN: cat %t.expected.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: expected}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_42 | sort > %t.expected.include +// RUN: diff -u %t.expected.module %t.expected.include +#if defined(TEST_42) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/filesystem.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: filesystem.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.filesystem.module +// RUN: cat %t.filesystem.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: filesystem}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::filesystem::operator== std::filesystem::operator!="} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_44 | sort > %t.filesystem.include +// RUN: diff -u %t.filesystem.module %t.filesystem.include +#if defined(TEST_44) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/format.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: format.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.format.module +// RUN: cat %t.format.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: format}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_46 | sort > %t.format.include +// RUN: diff -u %t.format.module %t.format.include +#if defined(TEST_46) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/forward_list.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: forward_list.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.forward_list.module +// RUN: cat %t.forward_list.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: forward_list}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_47 | sort > %t.forward_list.include +// RUN: diff -u %t.forward_list.module %t.forward_list.include +#if defined(TEST_47) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/fstream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: fstream.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.fstream.module +// RUN: cat %t.fstream.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: fstream}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_48 | sort > %t.fstream.include +// RUN: diff -u %t.fstream.module %t.fstream.include +#if defined(TEST_48) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/functional.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: functional.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.functional.module +// RUN: cat %t.functional.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: functional}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.ExtraHeader, value: "v1/__compare/compare_three_way.h$"}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_49 | sort > %t.functional.include +// RUN: diff -u %t.functional.module %t.functional.include +#if defined(TEST_49) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/future.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: future.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.future.module +// RUN: cat %t.future.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: future}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_50 | sort > %t.future.include +// RUN: diff -u %t.future.module %t.future.include +#if defined(TEST_50) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/initializer_list.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: initializer_list.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.initializer_list.module +// RUN: cat %t.initializer_list.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: initializer_list}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_51 | sort > %t.initializer_list.include +// RUN: diff -u %t.initializer_list.module %t.initializer_list.include +#if defined(TEST_51) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/iomanip.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iomanip.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.iomanip.module +// RUN: cat %t.iomanip.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iomanip}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::operator<< std::operator>>"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_53 | sort > %t.iomanip.include +// RUN: diff -u %t.iomanip.module %t.iomanip.include +#if defined(TEST_53) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/ios.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ios.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ios.module +// RUN: cat %t.ios.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ios}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_54 | sort > %t.ios.include +// RUN: diff -u %t.ios.module %t.ios.include +#if defined(TEST_54) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/iosfwd.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iosfwd.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.iosfwd.module +// RUN: cat %t.iosfwd.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iosfwd}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::ios_base std::vector"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_55 | sort > %t.iosfwd.include +// RUN: diff -u %t.iosfwd.module %t.iosfwd.include +#if defined(TEST_55) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/iostream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iostream.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.iostream.module +// RUN: cat %t.iostream.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iostream}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_56 | sort > %t.iostream.include +// RUN: diff -u %t.iostream.module %t.iostream.include +#if defined(TEST_56) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/istream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: istream.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.istream.module +// RUN: cat %t.istream.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: istream}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::getline"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_57 | sort > %t.istream.include +// RUN: diff -u %t.istream.module %t.istream.include +#if defined(TEST_57) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/iterator.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iterator.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.iterator.module +// RUN: cat %t.iterator.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: iterator}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::pointer_traits"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_58 | sort > %t.iterator.include +// RUN: diff -u %t.iterator.module %t.iterator.include +#if defined(TEST_58) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/latch.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: latch.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.latch.module +// RUN: cat %t.latch.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: latch}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_59 | sort > %t.latch.include +// RUN: diff -u %t.latch.module %t.latch.include +#if defined(TEST_59) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/limits.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: limits.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.limits.module +// RUN: cat %t.limits.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: limits}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_60 | sort > %t.limits.include +// RUN: diff -u %t.limits.module %t.limits.include +#if defined(TEST_60) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/list.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: list.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.list.module +// RUN: cat %t.list.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: list}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_62 | sort > %t.list.include +// RUN: diff -u %t.list.module %t.list.include +#if defined(TEST_62) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/locale.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: locale.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.locale.module +// RUN: cat %t.locale.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: locale}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.ExtraHeader, value: "v1/__locale$"}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_63 | sort > %t.locale.include +// RUN: diff -u %t.locale.module %t.locale.include +#if defined(TEST_63) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/map.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: map.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.map.module +// RUN: cat %t.map.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: map}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_65 | sort > %t.map.include +// RUN: diff -u %t.map.module %t.map.include +#if defined(TEST_65) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/mdspan.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: mdspan.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.mdspan.module +// RUN: cat %t.mdspan.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: mdspan}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_67 | sort > %t.mdspan.include +// RUN: diff -u %t.mdspan.module %t.mdspan.include +#if defined(TEST_67) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/memory.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: memory.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.memory.module +// RUN: cat %t.memory.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: memory}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::return_temporary_buffer std::get_temporary_buffer"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_68 | sort > %t.memory.include +// RUN: diff -u %t.memory.module %t.memory.include +#if defined(TEST_68) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/memory_resource.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: memory_resource.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.memory_resource.module +// RUN: cat %t.memory_resource.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: memory_resource}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_69 | sort > %t.memory_resource.include +// RUN: diff -u %t.memory_resource.module %t.memory_resource.include +#if defined(TEST_69) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/mutex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: mutex.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.mutex.module +// RUN: cat %t.mutex.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: mutex}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_70 | sort > %t.mutex.include +// RUN: diff -u %t.mutex.module %t.mutex.include +#if defined(TEST_70) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/new.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: new.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.new.module +// RUN: cat %t.new.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: new}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_71 | sort > %t.new.include +// RUN: diff -u %t.new.module %t.new.include +#if defined(TEST_71) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/numbers.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: numbers.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.numbers.module +// RUN: cat %t.numbers.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: numbers}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_72 | sort > %t.numbers.include +// RUN: diff -u %t.numbers.module %t.numbers.include +#if defined(TEST_72) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/numeric.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: numeric.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.numeric.module +// RUN: cat %t.numeric.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: numeric}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_73 | sort > %t.numeric.include +// RUN: diff -u %t.numeric.module %t.numeric.include +#if defined(TEST_73) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/optional.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: optional.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.optional.module +// RUN: cat %t.optional.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: optional}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_74 | sort > %t.optional.include +// RUN: diff -u %t.optional.module %t.optional.include +#if defined(TEST_74) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/ostream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ostream.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ostream.module +// RUN: cat %t.ostream.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ostream}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_75 | sort > %t.ostream.include +// RUN: diff -u %t.ostream.module %t.ostream.include +#if defined(TEST_75) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/queue.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: queue.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.queue.module +// RUN: cat %t.queue.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: queue}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_76 | sort > %t.queue.include +// RUN: diff -u %t.queue.module %t.queue.include +#if defined(TEST_76) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/random.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: random.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.random.module +// RUN: cat %t.random.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: random}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::operator!= std::operator<< std::operator>> std::operator=="} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_77 | sort > %t.random.include +// RUN: diff -u %t.random.module %t.random.include +#if defined(TEST_77) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/ranges.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ranges.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ranges.module +// RUN: cat %t.ranges.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ranges}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.ExtraHeader, value: "v1/__fwd/subrange.h$"}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_78 | sort > %t.ranges.include +// RUN: diff -u %t.ranges.module %t.ranges.include +#if defined(TEST_78) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/ratio.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ratio.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.ratio.module +// RUN: cat %t.ratio.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: ratio}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_79 | sort > %t.ratio.include +// RUN: diff -u %t.ratio.module %t.ratio.include +#if defined(TEST_79) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/regex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: regex.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.regex.module +// RUN: cat %t.regex.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: regex}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_80 | sort > %t.regex.include +// RUN: diff -u %t.regex.module %t.regex.include +#if defined(TEST_80) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/scoped_allocator.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: scoped_allocator.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.scoped_allocator.module +// RUN: cat %t.scoped_allocator.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: scoped_allocator}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_81 | sort > %t.scoped_allocator.include +// RUN: diff -u %t.scoped_allocator.module %t.scoped_allocator.include +#if defined(TEST_81) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/semaphore.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: semaphore.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.semaphore.module +// RUN: cat %t.semaphore.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: semaphore}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_82 | sort > %t.semaphore.include +// RUN: diff -u %t.semaphore.module %t.semaphore.include +#if defined(TEST_82) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/set.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: set.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.set.module +// RUN: cat %t.set.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: set}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_83 | sort > %t.set.include +// RUN: diff -u %t.set.module %t.set.include +#if defined(TEST_83) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/shared_mutex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: shared_mutex.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.shared_mutex.module +// RUN: cat %t.shared_mutex.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: shared_mutex}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_85 | sort > %t.shared_mutex.include +// RUN: diff -u %t.shared_mutex.module %t.shared_mutex.include +#if defined(TEST_85) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/source_location.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: source_location.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.source_location.module +// RUN: cat %t.source_location.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: source_location}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_86 | sort > %t.source_location.include +// RUN: diff -u %t.source_location.module %t.source_location.include +#if defined(TEST_86) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/span.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: span.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.span.module +// RUN: cat %t.span.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: span}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_87 | sort > %t.span.include +// RUN: diff -u %t.span.module %t.span.include +#if defined(TEST_87) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/sstream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: sstream.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.sstream.module +// RUN: cat %t.sstream.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: sstream}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_88 | sort > %t.sstream.include +// RUN: diff -u %t.sstream.module %t.sstream.include +#if defined(TEST_88) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/stack.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: stack.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.stack.module +// RUN: cat %t.stack.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: stack}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_89 | sort > %t.stack.include +// RUN: diff -u %t.stack.module %t.stack.include +#if defined(TEST_89) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/stdexcept.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: stdexcept.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.stdexcept.module +// RUN: cat %t.stdexcept.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: stdexcept}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_93 | sort > %t.stdexcept.include +// RUN: diff -u %t.stdexcept.module %t.stdexcept.include +#if defined(TEST_93) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/streambuf.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: streambuf.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.streambuf.module +// RUN: cat %t.streambuf.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: streambuf}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::basic_ios"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_97 | sort > %t.streambuf.include +// RUN: diff -u %t.streambuf.module %t.streambuf.include +#if defined(TEST_97) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/string.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: string.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.string.module +// RUN: cat %t.string.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: string}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::allocator"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_98 | sort > %t.string.include +// RUN: diff -u %t.string.module %t.string.include +#if defined(TEST_98) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/string_view.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: string_view.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.string_view.module +// RUN: cat %t.string_view.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: string_view}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_100 | sort > %t.string_view.include +// RUN: diff -u %t.string_view.module %t.string_view.include +#if defined(TEST_100) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/strstream.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: strstream.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.strstream.module +// RUN: cat %t.strstream.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: strstream}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_101 | sort > %t.strstream.include +// RUN: diff -u %t.strstream.module %t.strstream.include +#if defined(TEST_101) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/system_error.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: system_error.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.system_error.module +// RUN: cat %t.system_error.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: system_error}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.ExtraDeclarations, value: "std::operator<<"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_102 | sort > %t.system_error.include +// RUN: diff -u %t.system_error.module %t.system_error.include +#if defined(TEST_102) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/thread.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: thread.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.thread.module +// RUN: cat %t.thread.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: thread}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.ExtraHeader, value: "v1/__threading_support$"}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_104 | sort > %t.thread.include +// RUN: diff -u %t.thread.module %t.thread.include +#if defined(TEST_104) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/tuple.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: tuple.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.tuple.module +// RUN: cat %t.tuple.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: tuple}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_105 | sort > %t.tuple.include +// RUN: diff -u %t.tuple.module %t.tuple.include +#if defined(TEST_105) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/type_traits.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: type_traits.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.type_traits.module +// RUN: cat %t.type_traits.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: type_traits}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , {key: libcpp-header-exportable-declarations.SkipDeclarations, value: "std::swap std::reference_wrapper"} , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_106 | sort > %t.type_traits.include +// RUN: diff -u %t.type_traits.module %t.type_traits.include +#if defined(TEST_106) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/typeindex.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: typeindex.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.typeindex.module +// RUN: cat %t.typeindex.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: typeindex}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_107 | sort > %t.typeindex.include +// RUN: diff -u %t.typeindex.module %t.typeindex.include +#if defined(TEST_107) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/typeinfo.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: typeinfo.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.typeinfo.module +// RUN: cat %t.typeinfo.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: typeinfo}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_108 | sort > %t.typeinfo.include +// RUN: diff -u %t.typeinfo.module %t.typeinfo.include +#if defined(TEST_108) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/unordered_map.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: unordered_map.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.unordered_map.module +// RUN: cat %t.unordered_map.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: unordered_map}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_110 | sort > %t.unordered_map.include +// RUN: diff -u %t.unordered_map.module %t.unordered_map.include +#if defined(TEST_110) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/unordered_set.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: unordered_set.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.unordered_set.module +// RUN: cat %t.unordered_set.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: unordered_set}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_111 | sort > %t.unordered_set.include +// RUN: diff -u %t.unordered_set.module %t.unordered_set.include +#if defined(TEST_111) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/utility.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: utility.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.utility.module +// RUN: cat %t.utility.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: utility}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_112 | sort > %t.utility.include +// RUN: diff -u %t.utility.module %t.utility.include +#if defined(TEST_112) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/valarray.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: valarray.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.valarray.module +// RUN: cat %t.valarray.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: valarray}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_113 | sort > %t.valarray.include +// RUN: diff -u %t.valarray.module %t.valarray.include +#if defined(TEST_113) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/variant.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: variant.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.variant.module +// RUN: cat %t.variant.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: variant}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_114 | sort > %t.variant.include +// RUN: diff -u %t.variant.module %t.variant.include +#if defined(TEST_114) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/vector.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: vector.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.vector.module +// RUN: cat %t.vector.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: vector}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_115 | sort > %t.vector.include +// RUN: diff -u %t.vector.module %t.vector.include +#if defined(TEST_115) +#include +#endif +// RUN: %{clang-tidy} %{module}/std/version.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: version.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: ModulePartition}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} | sort > %t.version.module +// RUN: cat %t.version.module >> %t.parts +// RUN: %{clang-tidy} %s --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Filename, value: version}, {key: libcpp-header-exportable-declarations.FileType, value: Header}, , ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{compile_flags} -DTEST_116 | sort > %t.version.include +// RUN: diff -u %t.version.module %t.version.include +#if defined(TEST_116) +#include +#endif +// RUN: sort -u -o %t.parts %t.parts +// RUN: %{clang-tidy} %{module}/std.cppm --checks='-*,libcpp-header-exportable-declarations' -config='{CheckOptions: [ {key: libcpp-header-exportable-declarations.Header, value: std.cppm}, {key: libcpp-header-exportable-declarations.FileType, value: Module}, ]}' --load=%{test-tools}/clang_tidy_checks/libcxx-tidy.plugin -- %{flags} %{compile_flags} | sort > %t.module +// RUN: diff -u %t.parts %t.module +// GENERATED-MARKER diff --git a/libcxx/test/libcxx/modules_include.sh.cpp b/libcxx/test/libcxx/modules_include.sh.cpp --- a/libcxx/test/libcxx/modules_include.sh.cpp +++ b/libcxx/test/libcxx/modules_include.sh.cpp @@ -10,6 +10,9 @@ // This is important notably because the LLDB data formatters use // libc++ headers with modules enabled. +// Doesn't work with the std module +// UNSUPPORTED: use_module_std + // GCC doesn't support -fcxx-modules // UNSUPPORTED: gcc diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt --- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt @@ -16,6 +16,7 @@ set(SOURCES abi_tag_on_virtual.cpp + header_exportable_declarations.cpp hide_from_abi.cpp proper_version_checks.cpp qualify_declval.cpp diff --git a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.hpp b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.hpp new file mode 100644 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.hpp @@ -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 +// +//===----------------------------------------------------------------------===// + +#include "clang-tidy/ClangTidyCheck.h" + +#include + +namespace libcpp { +class header_exportable_declarations : public clang::tidy::ClangTidyCheck { +public: + header_exportable_declarations(llvm::StringRef, clang::tidy::ClangTidyContext*); + void registerMatchers(clang::ast_matchers::MatchFinder*) override; + void check(const clang::ast_matchers::MatchFinder::MatchResult&) override; + + enum class FileType { Header, ModulePartition, Module, Unknown }; + +private: + llvm::StringRef filename_; + FileType file_type_; + llvm::StringRef extra_header_; + std::set decls_; +}; +} // namespace libcpp diff --git a/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/tools/clang_tidy_checks/header_exportable_declarations.cpp @@ -0,0 +1,214 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "clang-tidy/ClangTidyCheck.h" +#include "clang-tidy/ClangTidyModuleRegistry.h" + +#include "clang/Basic/Module.h" + +#include "header_exportable_declarations.hpp" + +#include +#include +#include +#include + +template <> +struct clang::tidy::OptionEnumMapping { + static llvm::ArrayRef< std::pair> + getEnumMapping() { + static constexpr std::pair Mapping[] = { + {libcpp::header_exportable_declarations::FileType::Header, "Header"}, + {libcpp::header_exportable_declarations::FileType::ModulePartition, "ModulePartition"}, + {libcpp::header_exportable_declarations::FileType::Module, "Module"}}; + return ArrayRef(Mapping); + } +}; + +namespace libcpp { +header_exportable_declarations::header_exportable_declarations( + llvm::StringRef name, clang::tidy::ClangTidyContext* context) + : clang::tidy::ClangTidyCheck(name, context), + filename_(Options.get("Filename", "")), + file_type_(Options.get("FileType", header_exportable_declarations::FileType::Unknown)), + extra_header_(Options.get("ExtraHeader", "")) { + if (filename_.empty()) + llvm::errs() << "No filename is provided.\n"; + + switch (file_type_) { + case header_exportable_declarations::FileType::Module: + case header_exportable_declarations::FileType::ModulePartition: + if (!extra_header_.empty()) + llvm::errs() << "Extra headers are not allowed for modules.\n"; + if (Options.get("SkipDeclarations")) + llvm::errs() << "Modules may not skip declarations.\n"; + if (Options.get("ExtraDeclarations")) + llvm::errs() << "Modules may not have extra declarations.\n"; + break; + case header_exportable_declarations::FileType::Unknown: + llvm::errs() << "No file type is provided.\n"; + break; + } + + std::optional list = Options.get("SkipDeclarations"); + if (list) { + std::string_view s = *list; + auto b = s.begin(); + auto e = std::find(b, s.end(), ' '); + while (b != e) { + decls_.emplace(b, e); + if (e == s.end()) + break; + b = e + 1; + e = std::find(b, s.end(), ' '); + } + } + + list = Options.get("ExtraDeclarations"); + if (list) { + std::string_view s = *list; + auto b = s.begin(); + auto e = std::find(b, s.end(), ' '); + while (b != e) { + std::cout << "using " << std::string_view{b, e} << ";\n"; + if (e == s.end()) + break; + b = e + 1; + e = std::find(b, s.end(), ' '); + } + } +} + +void header_exportable_declarations::registerMatchers(clang::ast_matchers::MatchFinder* finder) { + // there are no public names in the Standard starting with an underscore, so + // no need to check the strict rules. + using namespace clang::ast_matchers; + + switch (file_type_) { + case FileType::Header: + + finder->addMatcher( + namedDecl( + // Looks at the common locations where headers store their data + // * header + // * __header/*.h + // * __fwd/header.h + anyOf(isExpansionInFileMatching(("v1/__" + filename_ + "/").str()), + isExpansionInFileMatching(extra_header_), + isExpansionInFileMatching(("v1/__fwd/" + filename_ + "\\.h$").str()), + isExpansionInFileMatching(("v1/" + filename_ + "$").str())), + unless(hasAncestor(friendDecl()))) + .bind("header_exportable_declarations"), + this); + break; + case FileType::ModulePartition: + finder->addMatcher(namedDecl(isExpansionInFileMatching(filename_)).bind("header_exportable_declarations"), this); + break; + case FileType::Module: + finder->addMatcher(namedDecl().bind("header_exportable_declarations"), this); + break; + } +} + +/// Returns the qualified name of a declaration. +/// +/// There is a small issue with qualified names. Typically the name returned is +/// in the namespace \c std instead of the namespace \c std::__1. Except when a +/// name is declared both in the namespace \c std and in the namespace +/// \c std::__1. In that case the returned value will adjust the name to use +/// the namespace \c std. +/// +/// The reason this happens is due to some parts of libc++ using +/// \code namespace std \endcode instead of +/// \code _LIBCPP_BEGIN_NAMESPACE_STD \endcode +/// Some examples +/// * cstddef has bitwise operators for the type \c byte +/// * exception has equality operators for the type \c exception_ptr +/// * initializer_list has the functions \c begin and \c end +/// +/// TODO is this an issue in libc++? +static std::string get_qualified_name(const clang::NamedDecl& decl) { + std::string result = decl.getQualifiedNameAsString(); + + if (result.starts_with("std::__1::")) + result.erase(5, 5); + + return result; +} + +static bool is_viable_declaration(const clang::NamedDecl* decl) { + // Declarations nested in records are automatically exported with the record itself. + if (!decl->getDeclContext()->isNamespace()) + return false; + + // Declarations that are a subobject of a friend Declaration are automatically exported with the record itself. + if (decl->getFriendObjectKind() != clang::Decl::FOK_None) + return false; + + // *** Function declarations *** + + if (clang::CXXMethodDecl::classof(decl)) + return false; + + if (clang::CXXDeductionGuideDecl::classof(decl)) + return false; + + if (clang::FunctionDecl::classof(decl)) + return true; + + if (clang::CXXConstructorDecl::classof(decl)) + return false; + + // implicit constructors disallowed + if (const auto* r = llvm::dyn_cast_or_null(decl)) + return !r->isLambda() && !r->isImplicit(); + + // *** Unconditionally accepted declarations *** + return llvm::isa(decl); +} + +/// Returns the name is a reserved name. +/// +/// This test misses 2 candidates which are not used in libc++ +/// * any identifier with two underscores not at the start +/// * a name with a leading underscore in the global namespace +bool is_reserved_name(const std::string& name) { + std::size_t pos = name.find("::_"); + if (pos == std::string::npos) + return false; + + if (pos + 3 > name.size()) + return false; + + return name[pos + 3] == '_' || std::isupper(name[pos + 3]); +} + +void header_exportable_declarations::check(const clang::ast_matchers::MatchFinder::MatchResult& result) { + if (const auto* decl = result.Nodes.getNodeAs("header_exportable_declarations"); decl != nullptr) { + if (!is_viable_declaration(decl)) + return; + + std::string name = get_qualified_name(*decl); + if (is_reserved_name(name)) + return; + + // For modules (std, std.compat) only take the declarations exported from the partitions. + // Making sure no declatations of headers are compared. + if (file_type_ == FileType::Module) + if (clang::Module* M = decl->getOwningModule(); M && M->Kind != clang::Module::ModulePartitionInterface) + return; + + if (decls_.contains(name)) + return; + + std::cout << "using " << std::string{name} << ";\n"; + decls_.insert(name); + } +} + +} // namespace libcpp diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp --- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp +++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp @@ -10,6 +10,7 @@ #include "clang-tidy/ClangTidyModuleRegistry.h" #include "abi_tag_on_virtual.hpp" +#include "header_exportable_declarations.hpp" #include "hide_from_abi.hpp" #include "proper_version_checks.hpp" #include "qualify_declval.hpp" @@ -21,6 +22,7 @@ public: void addCheckFactories(clang::tidy::ClangTidyCheckFactories& check_factories) override { check_factories.registerCheck("libcpp-avoid-abi-tag-on-virtual"); + check_factories.registerCheck("libcpp-header-exportable-declarations"); check_factories.registerCheck("libcpp-hide-from-abi"); check_factories.registerCheck("libcpp-cpp-version-check"); check_factories.registerCheck("libcpp-robust-against-adl"); diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -146,6 +146,26 @@ limit: 2 timeout_in_minutes: 120 + - label: "Module std C++23" + command: "libcxx/utils/ci/run-buildbot generic-module-std-cxx23" + artifact_paths: + - "**/test-results.xml" + - "**/*.abilist" + env: + # Note modules require and absolute path for clang-scan-deps + # https://github.com/llvm/llvm-project/issues/61006 + CC: "/usr/lib/llvm-${LLVM_HEAD_VERSION}/bin/clang" + CXX: "/usr/lib/llvm-${LLVM_HEAD_VERSION}/bin/clang++" + ENABLE_CLANG_TIDY: "On" + agents: + queue: "libcxx-builders" + os: "linux" + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + timeout_in_minutes: 120 + - label: "C++11" command: "libcxx/utils/ci/run-buildbot generic-cxx11" artifact_paths: diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -89,7 +89,8 @@ # version will generally work with the Clang shipped in Xcode (e.g. if Clang # knows about -std=c++20, the CMake bundled in Xcode will probably know about # that flag too). -if xcrun --find ninja &>/dev/null; then NINJA="$(xcrun --find ninja)"; else NINJA="ninja"; fi +# TODO MODULES Use ninja without a path when using a newer Ubuntu. +if xcrun --find ninja &>/dev/null; then NINJA="$(xcrun --find ninja)"; else NINJA="/usr/local/bin/ninja"; fi if xcrun --find cmake &>/dev/null; then CMAKE="$(xcrun --find cmake)"; else CMAKE="cmake"; fi function clean() { @@ -187,8 +188,8 @@ fi ${GIT_CLANG_FORMAT} \ --diff \ - --extensions ',h,hpp,c,cpp,inc,ipp' HEAD~1 \ - -- $(find libcxx/{benchmarks,include,src}/ -type f | grep -vf libcxx/utils/data/ignore_format.txt) \ + --extensions ',h,hpp,c,cpp,cppm,inc,ipp' HEAD~1 \ + -- $(find libcxx/{benchmarks,include,modules,src}/ -type f | grep -vf libcxx/utils/data/ignore_format.txt) \ | tee ${BUILD_DIR}/clang-format.patch # Check if the diff is empty, fail otherwise. ! grep -q '^--- a' ${BUILD_DIR}/clang-format.patch @@ -386,6 +387,9 @@ generate-cmake -DLIBCXXABI_USE_LLVM_UNWINDER=ON check-runtimes ;; +# +# Module builds +# generic-modules) clean generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-modules.cmake" @@ -398,6 +402,14 @@ check-runtimes check-abi-list ;; +generic-module-std-cxx23) + clean + # TODO MODULES Remove manual version selection. + export CMAKE=/opt/bin/cmake + generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-module-std-cxx23.cmake" + check-runtimes + check-abi-list +;; # # Parts removed # diff --git a/libcxx/utils/generate_header_tests.py b/libcxx/utils/generate_header_tests.py --- a/libcxx/utils/generate_header_tests.py +++ b/libcxx/utils/generate_header_tests.py @@ -81,6 +81,7 @@ produce(test.joinpath("libcxx/double_include.sh.cpp"), libcxx.test.header_information.variables) produce(test.joinpath("libcxx/min_max_macros.compile.pass.cpp"), libcxx.test.header_information.variables) produce(test.joinpath("libcxx/modules_include.sh.cpp"), libcxx.test.header_information.variables) + produce(test.joinpath("libcxx/module_std.sh.cpp"), libcxx.test.header_information.variables) produce(test.joinpath("libcxx/nasty_macros.compile.pass.cpp"), libcxx.test.header_information.variables) produce(test.joinpath("libcxx/no_assert_include.compile.pass.cpp"), libcxx.test.header_information.variables) produce(test.joinpath("libcxx/private_headers.verify.cpp"), libcxx.test.header_information.variables) diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py --- a/libcxx/utils/libcxx/test/dsl.py +++ b/libcxx/utils/libcxx/test/dsl.py @@ -12,6 +12,7 @@ import platform import re import shutil +import subprocess import tempfile import libcxx.test.format @@ -338,6 +339,12 @@ } +def _getSubstitution(substitution, config): + for (orig, replacement) in config.substitutions: + if orig == substitution: + return replacement + raise ValueError('Substitution {} is not in the config.'.format(substitution)) + def _appendToSubstitution(substitutions, key, value): return [(k, v + " " + value) if k == key else (k, v) for (k, v) in substitutions] @@ -430,6 +437,42 @@ def pretty(self, config, litParams): return "add {} to %{{flags}}".format(self._getFlag(config)) +class AddModule(ConfigAction): + def applyTo(self, config): + build = os.path.join(config.test_exec_root, '__config_module__') + + cxx = _getSubstitution('%{cxx}', config) + std = _getSubstitution('%{cxx_std}', config) + if std == 'cxx2c' or std == 'cxx26': + std = '17' # TODO MODULES Investigate why this fails + elif std == 'cxx2b' or std == 'cxx23': + std = '23' + else: + std = '17' # Not allowed for modules + + flags = _getSubstitution('%{flags}', config) + source = _getSubstitution('%{module}', config) + + cmake = _getSubstitution('%{cmake}', config) + make = _getSubstitution('%{make}', config) + generator = _getSubstitution('%{generator}', config) + + subprocess.check_call([cmake, + "-G" + generator, + "-DCMAKE_MAKE_PROGRAM=" + make, + "-B" + build, + "-H" + source, + "-DCMAKE_CXX_COMPILER_WORKS=TRUE", # The compiler test fails, but forcing this works + "-DCMAKE_CXX_COMPILER=" + cxx, + "-DCMAKE_CXX_STANDARD=" + std, + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", + f"-DCMAKE_CXX_FLAGS={flags}", + ], env={}) + + subprocess.check_call([cmake, "--build", build], env={}) + + def pretty(self, config, litParams): + pass class AddFlagIfSupported(ConfigAction): """ diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -25,6 +25,7 @@ "-Wno-noexcept-type", "-Wno-aligned-allocation-unavailable", "-Wno-atomic-alignment", + "-Wno-reserved-module-identifier", # GCC warns about places where we might want to add sized allocation/deallocation # functions, but we know better what we're doing/testing in the test suite. "-Wno-sized-deallocation", @@ -70,6 +71,24 @@ return None +_allModules = ["none", "clang", "std"] + + +def getModuleFlag(cfg, enable_modules): + # Originaly the flag was a Boolean, this maps the original Boolean values + # to the new enumerate values. + # TODO(LLVM-18) Remove this backwards compatibility. + fallbacks = { + "none": "False", + "clang": "True", + } + if enable_modules in _allModules: + return enable_modules + if enable_modules in fallbacks: + return fallbacks[enable_modules] + return None + + DEFAULT_PARAMETERS = [ Parameter( name="target_triple", @@ -101,18 +120,39 @@ ), Parameter( name="enable_modules", - choices=[True, False], - type=bool, - default=False, - help="Whether to build the test suite with Clang modules enabled.", - actions=lambda modules: [ + choices=_allModules + ["True", "False"], + type=str, + help="Whether to build the test suite with modules enabled. Select " + "`clang` for Clang modules and `std` for C++23 std module", + default=lambda cfg: next(s for s in _allModules if getModuleFlag(cfg, s)), + actions=lambda enable_modules: [ AddFeature("modules-build"), AddCompileFlag("-fmodules"), AddCompileFlag( "-fcxx-modules" ), # AppleClang disregards -fmodules entirely when compiling C++. This enables modules for C++. + # TODO(LLVM-18) Remove the True backwards compatibility. + ] + if enable_modules == "clang" or enable_modules == "True" + else [ + AddFeature("use_module_std"), + AddCompileFlag("-DTEST_USE_MODULE"), + AddCompileFlag("-DTEST_USE_MODULE_STD"), + AddCompileFlag( + lambda cfg: "-fprebuilt-module-path=" + + os.path.join( + cfg.test_exec_root, "__config_module__/CMakeFiles/std.dir" + ) + ), + AddSubstitution( + "%{link_flag}", + lambda cfg: os.path.join( + cfg.test_exec_root, "__config_module__/libc++std.a" + ), + ), + AddModule(), ] - if modules + if enable_modules == "std" else [], ), Parameter(