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