diff --git a/libcxx/include/__std_clang_module b/libcxx/include/__std_clang_module --- a/libcxx/include/__std_clang_module +++ b/libcxx/include/__std_clang_module @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// WARNING, this entire header is generated by +// utils/generate_std_clang_module_header.py +// DO NOT MODIFY! + // This header should not be directly included, it's exclusively to import all // of the libc++ public clang modules for the `std` clang module to export. In // other words, it's to facilitate `@import std;` in Objective-C++ and `import std` @@ -17,7 +21,6 @@ # error "Do not include this header directly, include individual headers instead" #endif -#include <__availability> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,52 +30,109 @@ #include #include #include -#include #include #include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include #include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include #include #include +#include #include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include +#include +#include #include +#include +#include +#include +#include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -81,132 +141,43 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER +# include +# include +#endif #ifndef _LIBCPP_HAS_NO_LOCALIZATION +# include # include -# ifndef _LIBCPP_HAS_NO_FILESYSTEM -# include -# endif +# include +# include # include # include # include # include +# include # include # include # include # include # include # include +#endif -# include - -# include +#ifndef _LIBCPP_HAS_NO_THREADS +# include +# include +# include +# include +# include +# include +# include #endif #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS # include # include - # include # include #endif -#ifdef _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT -# include -#endif - -#ifndef _LIBCPP_CXX03_LANG -# ifndef _LIBCPP_HAS_NO_THREADS -# include -# include -# include -# endif - -# include -# include -# include -# include -# include -# include -# include -# ifndef _LIBCPP_HAS_NO_LOCALIZATION -# include -# endif -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#if _LIBCPP_STD_VER >= 14 -# ifndef _LIBCPP_HAS_NO_THREADS -# include -# endif -#endif - -#if _LIBCPP_STD_VER >= 17 -# ifndef _LIBCPP_HAS_NO_FILESYSTEM -# include -# endif -#endif - -#if _LIBCPP_STD_VER >= 20 -# include - -# ifndef _LIBCPP_HAS_NO_THREADS -# include -# include -# include -# include -# endif -#endif - -#if _LIBCPP_STD_VER >= 23 -# ifndef _LIBCPP_HAS_NO_THREADS -# include -# endif -#endif diff --git a/libcxx/test/libcxx/modules_include.gen.py b/libcxx/test/libcxx/modules_include.gen.py --- a/libcxx/test/libcxx/modules_include.gen.py +++ b/libcxx/test/libcxx/modules_include.gen.py @@ -16,8 +16,9 @@ sys.path.append(sys.argv[1]) from libcxx.header_information import lit_header_restrictions, public_headers +BLOCKLIT = '' # block Lit from interpreting a RUN/XFAIL/etc inside the generation script + for header in public_headers: - BLOCKLIT = '' # block Lit from interpreting a RUN/XFAIL/etc inside the generation script print(f"""\ //--- {header}.compile.pass.cpp // RUN{BLOCKLIT}: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only @@ -45,7 +46,7 @@ #include <{header}> """) -print(f""" +print(f"""\ //--- __std_clang_module.compile.pass.mm // RUN{BLOCKLIT}: %{{cxx}} %s %{{flags}} %{{compile_flags}} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only @@ -68,10 +69,6 @@ // TODO: Investigate this failure // UNSUPPORTED{BLOCKLIT}: LIBCXX-FREEBSD-FIXME -// Lit seems to compile this twice: once with the default flags and once with with -// the flags specified in the RUN directive. Guard the first compile from failing. -#if __has_feature(modules) @import std; -#endif """) diff --git a/libcxx/utils/CMakeLists.txt b/libcxx/utils/CMakeLists.txt --- a/libcxx/utils/CMakeLists.txt +++ b/libcxx/utils/CMakeLists.txt @@ -2,6 +2,10 @@ COMMAND "${Python3_EXECUTABLE}" "${LIBCXX_SOURCE_DIR}/utils/generate_feature_test_macro_components.py" COMMENT "Generate the header and tests for feature test macros.") +add_custom_target(libcxx-generate-std-clang-module-header + COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/generate_std_clang_module_header.py" + COMMENT "Generate the <__std_clang_module> header") + add_custom_target(libcxx-generate-extended-grapheme-cluster-tables COMMAND "${Python3_EXECUTABLE}" @@ -38,6 +42,7 @@ add_custom_target(libcxx-generate-files DEPENDS libcxx-generate-feature-test-macros + libcxx-generate-std-clang-module-header libcxx-generate-extended-grapheme-cluster-tables libcxx-generate-extended-grapheme-cluster-tests libcxx-generate-escaped-output-table diff --git a/libcxx/utils/generate_std_clang_module_header.py b/libcxx/utils/generate_std_clang_module_header.py new file mode 100644 --- /dev/null +++ b/libcxx/utils/generate_std_clang_module_header.py @@ -0,0 +1,82 @@ +# ===----------------------------------------------------------------------===## +# +# 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 +# +# ===----------------------------------------------------------------------===## + +import operator +import os.path + +import libcxx.header_information + +public_headers = libcxx.header_information.public_headers +header_include_requirements = libcxx.header_information.header_include_requirements +always_available_headers = frozenset(public_headers).difference( + *header_include_requirements.values() +) + +libcxx_include_directory = os.path.join( + os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "include" +) +with open( + os.path.join(libcxx_include_directory, "__std_clang_module"), "w" +) as std_clang_module_header: + std_clang_module_header.write( + """\ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_std_clang_module_header.py +// DO NOT MODIFY! + +// This header should not be directly included, it's exclusively to import all +// of the libc++ public clang modules for the `std` clang module to export. In +// other words, it's to facilitate `@import std;` in Objective-C++ and `import std` +// in Swift to expose all of the libc++ interfaces. This is generally not +// recommended, however there are some clients that need to import all of libc++ +// without knowing what "all" is. +#if !__building_module(std) +# error "Do not include this header directly, include individual headers instead" +#endif + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +""" + ) + # Include the angle brackets in sorting so that sorts before + # like check-format wants. + for include in sorted([f"<{header}>" for header in always_available_headers]): + std_clang_module_header.write(f"#include {include}\n") + std_clang_module_header.write("\n") + + for requirements, headers in sorted( + header_include_requirements.items(), key=operator.itemgetter(0) + ): + if len(requirements) == 1: + std_clang_module_header.write("#ifndef ") + std_clang_module_header.write(requirements[0]) + else: + std_clang_module_header.write("#if") + for index, requirement in enumerate(requirements): + if index > 0: + std_clang_module_header.write(" &&") + std_clang_module_header.write(f" !defined({requirement})") + std_clang_module_header.write("\n") + + for include in sorted([f"<{header}>" for header in headers]): + std_clang_module_header.write(f"# include {include}\n") + + std_clang_module_header.write("#endif\n\n") diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py --- a/libcxx/utils/libcxx/header_information.py +++ b/libcxx/utils/libcxx/header_information.py @@ -57,6 +57,52 @@ "wctype.h": "// UNSUPPORTED: no-wide-characters", } +header_include_requirements = { + ("_LIBCPP_HAS_NO_ATOMIC_HEADER",): ( + # headers with #error directives + "atomic", + # transitive includers of the above headers + "stdatomic.h", + ), + ("_LIBCPP_HAS_NO_LOCALIZATION",): ( + # headers with #error directives + "ios", + "locale.h", + # transitive includers of the above headers + "clocale", + "codecvt", + "experimental/regex", + "fstream", + "iomanip", + "iostream", + "istream", + "locale", + "ostream", + "regex", + "sstream", + "streambuf", + "strstream", + ), + ("_LIBCPP_HAS_NO_THREADS",): ( + # headers with #error directives + "barrier", + "future", + "latch", + "semaphore", + "shared_mutex", + "stop_token", + "thread", + ), + ("_LIBCPP_HAS_NO_WIDE_CHARACTERS",): ( + # headers with #error directives + "wchar.h", + "wctype.h", + # transitive includers of the above headers + "cwchar", + "cwctype", + ), +} + # This table was produced manually, by grepping the TeX source of the Standard's # library clauses for the string "#include". Each header's synopsis contains # explicit "#include" directives for its mandatory inclusions.