mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 00:56:06 +00:00

We need a forward-declaration so that we can know about std::byte from some type traits without having to include std::byte's definition, which (circularly) depends back on type traits.
93 lines
3.1 KiB
Python
93 lines
3.1 KiB
Python
#!/usr/bin/env python
|
|
|
|
import argparse
|
|
import libcxx.header_information
|
|
import os
|
|
import pathlib
|
|
import re
|
|
import sys
|
|
import typing
|
|
|
|
def IWYU_mapping(header: str) -> typing.Optional[typing.List[str]]:
|
|
ignore = [
|
|
"__debug_utils/.+",
|
|
"__fwd/get[.]h",
|
|
"__pstl/.+",
|
|
"__support/.+",
|
|
"__utility/private_constructor_tag.h",
|
|
]
|
|
if any(re.match(pattern, header) for pattern in ignore):
|
|
return None
|
|
elif header == "__bits":
|
|
return ["bits"]
|
|
elif header in ("__bit_reference", "__fwd/bit_reference.h"):
|
|
return ["bitset", "vector"]
|
|
elif re.match("__configuration/.+", header) or header == "__config":
|
|
return ["version"]
|
|
elif header == "__hash_table":
|
|
return ["unordered_map", "unordered_set"]
|
|
elif header == "__locale":
|
|
return ["locale"]
|
|
elif re.match("__locale_dir/.+", header):
|
|
return ["locale"]
|
|
elif re.match("__math/.+", header):
|
|
return ["cmath"]
|
|
elif header == "__node_handle":
|
|
return ["map", "set", "unordered_map", "unordered_set"]
|
|
elif header == "__split_buffer":
|
|
return ["deque", "vector"]
|
|
elif re.match("(__thread/support[.]h)|(__thread/support/.+)", header):
|
|
return ["atomic", "mutex", "semaphore", "thread"]
|
|
elif header == "__tree":
|
|
return ["map", "set"]
|
|
elif header == "__fwd/byte.h":
|
|
return ["cstddef"]
|
|
elif header == "__fwd/pair.h":
|
|
return ["utility"]
|
|
elif header == "__fwd/subrange.h":
|
|
return ["ranges"]
|
|
elif re.match("__fwd/(fstream|ios|istream|ostream|sstream|streambuf)[.]h", header):
|
|
return ["iosfwd"]
|
|
# Handle remaining forward declaration headers
|
|
elif re.match("__fwd/(.+)[.]h", header):
|
|
return [re.match("__fwd/(.+)[.]h", header).group(1)]
|
|
# Handle detail headers for things like <__algorithm/foo.h>
|
|
elif re.match("__(.+?)/.+", header):
|
|
return [re.match("__(.+?)/.+", header).group(1)]
|
|
else:
|
|
return None
|
|
|
|
|
|
def main(argv: typing.List[str]):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"-o",
|
|
help="File to output the IWYU mappings into",
|
|
type=argparse.FileType("w"),
|
|
required=True,
|
|
dest="output",
|
|
)
|
|
args = parser.parse_args(argv)
|
|
|
|
mappings = [] # Pairs of (header, public_header)
|
|
for header in libcxx.header_information.all_headers:
|
|
public_headers = IWYU_mapping(header)
|
|
if public_headers is not None:
|
|
mappings.extend((header, public) for public in public_headers)
|
|
|
|
# Validate that we only have valid public header names -- otherwise the mapping above
|
|
# needs to be updated.
|
|
for header, public in mappings:
|
|
if public not in libcxx.header_information.public_headers:
|
|
raise RuntimeError(f"{header}: Header {public} is not a valid header")
|
|
|
|
args.output.write("[\n")
|
|
for header, public in sorted(mappings):
|
|
args.output.write(
|
|
f' {{ include: [ "<{header}>", "private", "<{public}>", "public" ] }},\n'
|
|
)
|
|
args.output.write("]\n")
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1:])
|