• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, pathlib
10
11header_restrictions = {
12    # headers with #error directives
13    "atomic": "!defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)",
14    "stdatomic.h": "!defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)",
15
16    # headers with #error directives
17    "ios": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
18    "locale.h": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
19    # transitive includers of the above headers
20    "clocale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
21    "codecvt": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
22    "fstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
23    "iomanip": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
24    "iostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
25    "istream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
26    "locale": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
27    "ostream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
28    "regex": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
29    "sstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
30    "streambuf": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
31    "strstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
32    "syncstream": "!defined(_LIBCPP_HAS_NO_LOCALIZATION)",
33
34    # headers with #error directives
35    "barrier": "!defined(_LIBCPP_HAS_NO_THREADS)",
36    "future": "!defined(_LIBCPP_HAS_NO_THREADS)",
37    "latch": "!defined(_LIBCPP_HAS_NO_THREADS)",
38    "semaphore": "!defined(_LIBCPP_HAS_NO_THREADS)",
39    "shared_mutex": "!defined(_LIBCPP_HAS_NO_THREADS)",
40    "stop_token": "!defined(_LIBCPP_HAS_NO_THREADS)",
41    "thread": "!defined(_LIBCPP_HAS_NO_THREADS)",
42
43    # headers with #error directives
44    "wchar.h": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
45    "wctype.h": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
46    # transitive includers of the above headers
47    "cwchar": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
48    "cwctype": "!defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)",
49}
50
51lit_header_restrictions = {
52    "barrier": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
53    "clocale": "// UNSUPPORTED: no-localization",
54    "codecvt": "// UNSUPPORTED: no-localization",
55    "coroutine": "// UNSUPPORTED: c++03, c++11, c++14, c++17",
56    "cwchar": "// UNSUPPORTED: no-wide-characters",
57    "cwctype": "// UNSUPPORTED: no-wide-characters",
58    "experimental/iterator": "// UNSUPPORTED: c++03",
59    "experimental/propagate_const": "// UNSUPPORTED: c++03",
60    "experimental/simd": "// UNSUPPORTED: c++03",
61    "experimental/type_traits": "// UNSUPPORTED: c++03",
62    "experimental/utility": "// UNSUPPORTED: c++03",
63    "filesystem": "// UNSUPPORTED: no-filesystem, c++03, c++11, c++14",
64    "fstream": "// UNSUPPORTED: no-localization, no-filesystem",
65    "future": "// UNSUPPORTED: no-threads, c++03",
66    "iomanip": "// UNSUPPORTED: no-localization",
67    "ios": "// UNSUPPORTED: no-localization",
68    "iostream": "// UNSUPPORTED: no-localization",
69    "istream": "// UNSUPPORTED: no-localization",
70    "latch": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
71    "locale": "// UNSUPPORTED: no-localization",
72    "locale.h": "// UNSUPPORTED: no-localization",
73    "mutex": "// UNSUPPORTED: no-threads, c++03",
74    "ostream": "// UNSUPPORTED: no-localization",
75    "print": "// UNSUPPORTED: no-filesystem, c++03, c++11, c++14, c++17, c++20, availability-fp_to_chars-missing", # TODO PRINT investigate
76    "regex": "// UNSUPPORTED: no-localization",
77    "semaphore": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
78    "shared_mutex": "// UNSUPPORTED: no-threads, c++03, c++11",
79    "sstream": "// UNSUPPORTED: no-localization",
80    "stdatomic.h": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17, c++20",
81    "stop_token": "// UNSUPPORTED: no-threads, c++03, c++11, c++14, c++17",
82    "streambuf": "// UNSUPPORTED: no-localization",
83    "strstream": "// UNSUPPORTED: no-localization",
84    "syncstream": "// UNSUPPORTED: no-localization",
85    "thread": "// UNSUPPORTED: no-threads, c++03",
86    "wchar.h": "// UNSUPPORTED: no-wide-characters",
87    "wctype.h": "// UNSUPPORTED: no-wide-characters",
88}
89
90# This table was produced manually, by grepping the TeX source of the Standard's
91# library clauses for the string "#include". Each header's synopsis contains
92# explicit "#include" directives for its mandatory inclusions.
93# For example, [algorithm.syn] contains "#include <initializer_list>".
94mandatory_inclusions = {
95    "algorithm": ["initializer_list"],
96    "array": ["compare", "initializer_list"],
97    "bitset": ["iosfwd", "string"],
98    "chrono": ["compare"],
99    "cinttypes": ["cstdint"],
100    "complex.h": ["complex"],
101    "coroutine": ["compare"],
102    "deque": ["compare", "initializer_list"],
103    "filesystem": ["compare"],
104    "forward_list": ["compare", "initializer_list"],
105    "ios": ["iosfwd"],
106    "iostream": ["ios", "istream", "ostream", "streambuf"],
107    "iterator": ["compare", "concepts"],
108    "list": ["compare", "initializer_list"],
109    "map": ["compare", "initializer_list"],
110    "memory": ["compare"],
111    "optional": ["compare"],
112    "queue": ["compare", "initializer_list"],
113    "random": ["initializer_list"],
114    "ranges": ["compare", "initializer_list", "iterator"],
115    "regex": ["compare", "initializer_list"],
116    "set": ["compare", "initializer_list"],
117    "stack": ["compare", "initializer_list"],
118    "string_view": ["compare"],
119    "string": ["compare", "initializer_list"],
120    "syncstream": ["ostream"],
121    "system_error": ["compare"],
122    "tgmath.h": ["cmath", "complex"],
123    "thread": ["compare"],
124    "tuple": ["compare"],
125    "typeindex": ["compare"],
126    "unordered_map": ["compare", "initializer_list"],
127    "unordered_set": ["compare", "initializer_list"],
128    "utility": ["compare", "initializer_list"],
129    "valarray": ["initializer_list"],
130    "variant": ["compare"],
131    "vector": ["compare", "initializer_list"],
132}
133
134
135# These headers are not yet implemented in libc++
136#
137# These headers are required by the latest (draft) Standard but have not been
138# implemented yet. They are used in the generated module input. The C++23 standard
139# modules will fail to build if a header is added but this list is not updated.
140headers_not_available = [
141    "debugging",
142    "flat_map",
143    "flat_set",
144    "generator",
145    "hazard_pointer",
146    "linalg",
147    "rcu",
148    "spanstream",
149    "stacktrace",
150    "stdfloat",
151    "text_encoding",
152]
153
154
155def is_header(file):
156    """Returns whether the given file is a header (i.e. not a directory or the modulemap file)."""
157    return not file.is_dir() and not file.name in [
158        "module.modulemap.in",
159        "module.modulemap",
160        "CMakeLists.txt",
161        "libcxx.imp",
162    ]
163
164
165def is_modulemap_header(header):
166    """Returns whether a header should be listed in the modulemap"""
167    # TODO: Should `__config_site` be in the modulemap?
168    if header == "__config_site":
169        return False
170
171    # exclude libc++abi files
172    if header in ["cxxabi.h", "__cxxabi_config.h"]:
173        return False
174
175    # exclude headers in __support/ - these aren't supposed to work everywhere,
176    # so they shouldn't be included in general
177    if header.startswith("__support/"):
178        return False
179
180    # exclude ext/ headers - these are non-standard extensions and are barely
181    # maintained. People should migrate away from these and we don't need to
182    # burden ourself with maintaining them in any way.
183    if header.startswith("ext/"):
184        return False
185    return True
186
187libcxx_root = pathlib.Path(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
188include = pathlib.Path(os.path.join(libcxx_root, "include"))
189test = pathlib.Path(os.path.join(libcxx_root, "test"))
190assert libcxx_root.exists()
191
192toplevel_headers = sorted(
193    p.relative_to(include).as_posix() for p in include.glob("[a-z]*") if is_header(p)
194)
195experimental_headers = sorted(
196    p.relative_to(include).as_posix()
197    for p in include.glob("experimental/[a-z]*")
198    if is_header(p)
199)
200public_headers = toplevel_headers + experimental_headers
201
202# The headers used in the std and std.compat modules.
203#
204# This is the set of all C++23-and-later headers, excluding C compatibility headers.
205module_headers = [
206    header
207    for header in toplevel_headers
208    if not header.endswith(".h")
209    # These headers have been removed in C++20 so are never part of a module.
210    and not header in ["ccomplex", "ciso646", "cstdbool", "ctgmath"]
211]
212