|  | # ===----------------------------------------------------------------------===## | 
|  | # | 
|  | # 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 os.path | 
|  | import sys | 
|  |  | 
|  | from libcxx.header_information import module_c_headers | 
|  | from libcxx.header_information import module_headers | 
|  | from libcxx.header_information import header_restrictions | 
|  | from libcxx.header_information import headers_not_available | 
|  |  | 
|  |  | 
|  | def write_file(module): | 
|  | libcxx_module_directory = os.path.join( | 
|  | os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "modules" | 
|  | ) | 
|  | with open( | 
|  | os.path.join(libcxx_module_directory, f"{module}.cppm.in"), "w" | 
|  | ) as module_cpp_in: | 
|  | module_cpp_in.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_libcxx_cppm_in.py | 
|  | // DO NOT MODIFY! | 
|  |  | 
|  | module; | 
|  |  | 
|  | #include <__config> | 
|  |  | 
|  | // 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] | 
|  | """ | 
|  | ) | 
|  | for header in module_headers if module == "std" else module_c_headers: | 
|  | if header in header_restrictions: | 
|  | module_cpp_in.write( | 
|  | f"""\ | 
|  | #if {header_restrictions[header]} | 
|  | #  include <{header}> | 
|  | #endif | 
|  | """ | 
|  | ) | 
|  | else: | 
|  | module_cpp_in.write(f"#include <{header}>\n") | 
|  |  | 
|  | module_cpp_in.write( | 
|  | """ | 
|  | // *** Headers not yet available *** | 
|  | // | 
|  | // This validation is mainly to catch when a new header is added but adding the | 
|  | // corresponding .inc file is forgotten. However, the check based on __has_include | 
|  | // alone doesn't work on Windows because the Windows SDK is on the include path, | 
|  | // and that means the MSVC STL headers can be found as well, tricking __has_include | 
|  | // into thinking that libc++ provides the header. | 
|  | // | 
|  | #ifndef _WIN32 | 
|  | """ | 
|  | ) | 
|  | for header in sorted(headers_not_available): | 
|  | module_cpp_in.write( | 
|  | f"""\ | 
|  | #  if __has_include(<{header}>) | 
|  | #    error "please update the header information for <{header}> in headers_not_available in utils/libcxx/header_information.py" | 
|  | #  endif // __has_include(<{header}>) | 
|  | """ | 
|  | ) | 
|  |  | 
|  | module_cpp_in.write( | 
|  | f"""#endif // _WIN32 | 
|  |  | 
|  | export module {module}; | 
|  | {'export import std;' if module == 'std.compat' else ''} | 
|  |  | 
|  | {'@LIBCXX_MODULE_STD_INCLUDE_SOURCES@' if module == 'std' else ''} | 
|  | {'@LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES@' if module == 'std.compat' else ''}""" | 
|  | ) | 
|  |  | 
|  |  | 
|  | if __name__ == "__main__": | 
|  | if len(sys.argv) != 2 or (sys.argv[1] != "std" and sys.argv[1] != "std.compat"): | 
|  | sys.stderr.write( | 
|  | f"""\ | 
|  | Usage: | 
|  | {os.path.basename(__file__)} (std|std.compat) | 
|  | """ | 
|  | ) | 
|  | sys.exit(1) | 
|  |  | 
|  | write_file(sys.argv[1]) |