xref: /llvm-project/libcxx/utils/generate_libcxx_cppm_in.py (revision d6e714b10e102eb32e64e04bf177226dbe16d0e7)
1# ===----------------------------------------------------------------------===##
2#
3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6#
7# ===----------------------------------------------------------------------===##
8
9import os.path
10import sys
11
12from libcxx.header_information import module_c_headers, module_headers, header_restrictions, headers_not_available, libcxx_root
13
14
15def write_file(module):
16    with open(libcxx_root / "modules" / f"{module}.cppm.in", "w") as module_cpp_in:
17        module_cpp_in.write(
18            """\
19// -*- C++ -*-
20//===----------------------------------------------------------------------===//
21//
22// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
23// See https://llvm.org/LICENSE.txt for license information.
24// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
25//
26//===----------------------------------------------------------------------===//
27
28// WARNING, this entire header is generated by
29// utils/generate_libcxx_cppm_in.py
30// DO NOT MODIFY!
31
32module;
33
34#include <__config>
35
36// The headers of Table 24: C++ library headers [tab:headers.cpp]
37// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c]
38"""
39        )
40        for header in sorted(module_headers if module == "std" else module_c_headers):
41            if header in header_restrictions:
42                module_cpp_in.write(
43                    f"""\
44#if {header_restrictions[header]}
45#  include <{header}>
46#endif
47"""
48                )
49            else:
50                module_cpp_in.write(f"#include <{header}>\n")
51
52        module_cpp_in.write(
53            """
54// *** Headers not yet available ***
55//
56// This validation is mainly to catch when a new header is added but adding the
57// corresponding .inc file is forgotten. However, the check based on __has_include
58// alone doesn't work on Windows because the Windows SDK is on the include path,
59// and that means the MSVC STL headers can be found as well, tricking __has_include
60// into thinking that libc++ provides the header.
61//
62#ifndef _WIN32
63"""
64        )
65        for header in sorted(headers_not_available):
66            module_cpp_in.write(
67                f"""\
68#  if __has_include(<{header}>)
69#    error "please update the header information for <{header}> in headers_not_available in utils/libcxx/header_information.py"
70#  endif // __has_include(<{header}>)
71"""
72            )
73
74        module_cpp_in.write(
75            f"""#endif // _WIN32
76
77export module {module};
78{'export import std;' if module == 'std.compat' else ''}
79
80{'@LIBCXX_MODULE_STD_INCLUDE_SOURCES@' if module == 'std' else ''}
81{'@LIBCXX_MODULE_STD_COMPAT_INCLUDE_SOURCES@' if module == 'std.compat' else ''}"""
82        )
83
84
85if __name__ == "__main__":
86    if len(sys.argv) != 2 or (sys.argv[1] != "std" and sys.argv[1] != "std.compat"):
87        sys.stderr.write(
88            f"""\
89Usage:
90{os.path.basename(__file__)} (std|std.compat)
91"""
92        )
93        sys.exit(1)
94
95    write_file(sys.argv[1])
96