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", 159 "CMakeLists.txt", 160 "libcxx.imp", 161 ] 162 163 164def is_modulemap_header(header): 165 """Returns whether a header should be listed in the modulemap""" 166 # TODO: Should `__config_site` be in the modulemap? 167 if header == "__config_site": 168 return False 169 170 if header == "__assertion_handler": 171 return False 172 173 # exclude libc++abi files 174 if header in ["cxxabi.h", "__cxxabi_config.h"]: 175 return False 176 177 # exclude headers in __support/ - these aren't supposed to work everywhere, 178 # so they shouldn't be included in general 179 if header.startswith("__support/"): 180 return False 181 182 # exclude ext/ headers - these are non-standard extensions and are barely 183 # maintained. People should migrate away from these and we don't need to 184 # burden ourself with maintaining them in any way. 185 if header.startswith("ext/"): 186 return False 187 return True 188 189libcxx_root = pathlib.Path(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 190include = pathlib.Path(os.path.join(libcxx_root, "include")) 191test = pathlib.Path(os.path.join(libcxx_root, "test")) 192assert libcxx_root.exists() 193 194all_headers = sorted( 195 p.relative_to(include).as_posix() for p in include.rglob("[a-z]*") if is_header(p) 196) 197toplevel_headers = sorted( 198 p.relative_to(include).as_posix() for p in include.glob("[a-z]*") if is_header(p) 199) 200experimental_headers = sorted( 201 p.relative_to(include).as_posix() 202 for p in include.glob("experimental/[a-z]*") 203 if is_header(p) 204) 205public_headers = toplevel_headers + experimental_headers 206 207# The headers used in the std and std.compat modules. 208# 209# This is the set of all C++23-and-later headers, excluding C compatibility headers. 210module_headers = [ 211 header 212 for header in toplevel_headers 213 if not header.endswith(".h") 214 # These headers have been removed in C++20 so are never part of a module. 215 and not header in ["ccomplex", "ciso646", "cstdbool", "ctgmath"] 216] 217 218# The C headers used in the std and std.compat modules. 219module_c_headers = [ 220 "cassert", 221 "cctype", 222 "cerrno", 223 "cfenv", 224 "cfloat", 225 "cinttypes", 226 "climits", 227 "clocale", 228 "cmath", 229 "csetjmp", 230 "csignal", 231 "cstdarg", 232 "cstddef", 233 "cstdint", 234 "cstdio", 235 "cstdlib", 236 "cstring", 237 "ctime", 238 "cuchar", 239 "cwchar", 240 "cwctype", 241] 242