blob: c2ebd124d452bf47ac0c14cb8cd3136347a851d4 [file] [log] [blame]
James Kuszmaulcf324122023-01-14 14:07:17 -08001#!/usr/bin/env python3
2
3import os
4import shutil
5
6from upstream_utils import (
7 get_repo_root,
8 clone_repo,
9 comment_out_invalid_includes,
10 walk_cwd_and_copy_if,
11 git_am,
12)
13
14
15def run_global_replacements(wpiutil_llvm_files):
16
17 for wpi_file in wpiutil_llvm_files:
18 with open(wpi_file) as f:
19 content = f.read()
20
21 # Rename namespace from llvm to wpi
22 content = content.replace("namespace llvm", "namespace wpi")
23 content = content.replace("llvm::", "wpi::")
24
25 # Fix #includes
26 content = content.replace('include "llvm/ADT', 'include "wpi')
27 content = content.replace('include "llvm/Config', 'include "wpi')
28 content = content.replace('include "llvm/Support', 'include "wpi')
29
30 # Fix uses of span
31 content = content.replace("span", "std::span")
32 content = content.replace('include "wpi/std::span.h"', "include <span>")
33 if wpi_file.endswith("ConvertUTFWrapper.cpp"):
34 content = content.replace(
35 "const UTF16 *Src = reinterpret_cast<const UTF16 *>(SrcBytes.begin());",
36 "const UTF16 *Src = reinterpret_cast<const UTF16 *>(&*SrcBytes.begin());",
37 )
38 content = content.replace(
39 "const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(SrcBytes.end());",
40 "const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(&*SrcBytes.begin() + SrcBytes.size());",
41 )
42
43 # Remove unused headers
44 content = content.replace('#include "llvm-c/ErrorHandling.h"\n', "")
45 content = content.replace('#include "wpi/Debug.h"\n', "")
46 content = content.replace('#include "wpi/Error.h"\n', "")
47 content = content.replace('#include "wpi/Format.h"\n', "")
48 content = content.replace('#include "wpi/FormatVariadic.h"\n', "")
49 content = content.replace('#include "wpi/NativeFormatting.h"\n', "")
50 content = content.replace('#include "wpi/Threading.h"\n', "")
51 content = content.replace('#include "wpi/DataTypes.h"\n', "")
52 content = content.replace('#include "wpi/llvm-config.h"\n', "")
53 content = content.replace('#include "wpi/abi-breaking.h"\n', "")
54 content = content.replace('#include "wpi/config.h"\n', "")
55 content = content.replace('#include "wpi/Signals.h"\n', "")
56 content = content.replace('#include "wpi/Process.h"\n', "")
57 content = content.replace('#include "wpi/Path.h"\n', "")
58 content = content.replace('#include "wpi/Program.h"\n', "")
59
60 # Fix include guards
61 content = content.replace("LLVM_ADT_", "WPIUTIL_WPI_")
62 content = content.replace("LLVM_SUPPORT_", "WPIUTIL_WPI_")
63 content = content.replace("LLVM_DEFINED_HAS_FEATURE", "WPI_DEFINED_HAS_FEATURE")
64
65 content = content.replace("const std::string_view &", "std::string_view ")
66 content = content.replace("sys::fs::openFileForRead", "fs::OpenFileForRead")
67 content = content.replace("sys::fs::closeFile", "fs::CloseFile")
68 content = content.replace("sys::fs::", "fs::")
69
70 # Replace wpi/FileSystem.h with wpi/fs.h
71 content = content.replace('include "wpi/FileSystem.h"', 'include "wpi/fs.h"')
72
73 # Replace llvm_unreachable() with wpi_unreachable()
74 content = content.replace("llvm_unreachable", "wpi_unreachable")
75
76 content = content.replace("llvm_is_multithreaded()", "1")
77
78 # Revert message in copyright header
79 content = content.replace("/// Defines the wpi::", "/// Defines the llvm::")
80 content = content.replace("// end llvm namespace", "// end wpi namespace")
81 content = content.replace("// end namespace llvm", "// end namespace wpi")
82 content = content.replace("// End llvm namespace", "// End wpi namespace")
83
84 content = content.replace("fs::openFileForRead", "fs::OpenFileForRead")
85
86 with open(wpi_file, "w") as f:
87 f.write(content)
88
89
90def flattened_llvm_files(llvm, dirs_to_keep):
91 file_lookup = {}
92
93 for dir_to_keep in dirs_to_keep:
94 dir_to_crawl = os.path.join(llvm, dir_to_keep)
95 for root, _, files in os.walk(dir_to_crawl):
96 for f in files:
97 file_lookup[f] = os.path.join(root, f)
98
99 return file_lookup
100
101
102def find_wpiutil_llvm_files(wpiutil_root, subfolder):
103
104 # These files have substantial changes, not worth managing with the patching process
105 ignore_list = [
106 "StringExtras.h",
107 "StringExtras.cpp",
108 "MemoryBuffer.cpp",
109 "MemoryBuffer.h",
110 "SmallVectorMemoryBuffer.h",
111 ]
112
113 wpiutil_files = []
114 for root, _, files in os.walk(os.path.join(wpiutil_root, subfolder)):
115 for f in files:
116 if f not in ignore_list:
117 full_file = os.path.join(root, f)
118 wpiutil_files.append(full_file)
119
120 return wpiutil_files
121
122
123def overwrite_files(wpiutil_files, llvm_files):
124 # Very sparse rips from LLVM sources. Not worth tyring to make match upstream
125 unmatched_files_whitelist = ["fs.h", "fs.cpp", "function_ref.h"]
126
127 for wpi_file in wpiutil_files:
128 wpi_base_name = os.path.basename(wpi_file)
129 if wpi_base_name in llvm_files:
130 shutil.copyfile(llvm_files[wpi_base_name], wpi_file)
131
132 elif wpi_base_name not in unmatched_files_whitelist:
133 print(f"No file match for {wpi_file}, check if LLVM deleted it")
134
135
136def overwrite_source(wpiutil_root, llvm_root):
137 llvm_files = flattened_llvm_files(
138 llvm_root,
139 [
140 "llvm/include/llvm/ADT/",
141 "llvm/include/llvm/Config",
142 "llvm/include/llvm/Support/",
143 "llvm/lib/Support/",
144 ],
145 )
146 wpi_files = find_wpiutil_llvm_files(
147 wpiutil_root, "src/main/native/thirdparty/llvm/include/wpi"
148 ) + find_wpiutil_llvm_files(
149 wpiutil_root, "src/main/native/thirdparty/llvm/cpp/llvm"
150 )
151
152 overwrite_files(wpi_files, llvm_files)
153 run_global_replacements(wpi_files)
154
155
156def overwrite_tests(wpiutil_root, llvm_root):
157 llvm_files = flattened_llvm_files(
158 llvm_root,
159 ["llvm/unittests/ADT/", "llvm/unittests/Config", "llvm/unittests/Support/"],
160 )
161 wpi_files = find_wpiutil_llvm_files(wpiutil_root, "src/test/native/cpp/llvm")
162
163 overwrite_files(wpi_files, llvm_files)
164 run_global_replacements(wpi_files)
165
166
167def main():
168 upstream_root = clone_repo("https://github.com/llvm/llvm-project", "llvmorg-14.0.6")
169 wpilib_root = get_repo_root()
170 wpiutil = os.path.join(wpilib_root, "wpiutil")
171
172 # Apply patches to upstream Git repo
173 os.chdir(upstream_root)
174 for f in [
175 "0001-Fix-spelling-language-errors.patch",
176 "0002-Remove-StringRef-ArrayRef-and-Optional.patch",
177 "0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch",
178 "0004-Change-unique_function-storage-size.patch",
179 "0005-Threading-updates.patch",
180 "0006-ifdef-guard-safety.patch",
181 "0007-Explicitly-use-std.patch",
182 "0008-Remove-format_provider.patch",
183 "0009-Add-compiler-warning-pragmas.patch",
184 "0010-Remove-unused-functions.patch",
185 "0011-Detemplatize-SmallVectorBase.patch",
186 "0012-Add-vectors-to-raw_ostream.patch",
187 "0013-Extra-collections-features.patch",
188 "0014-EpochTracker-ABI-macro.patch",
189 "0015-Delete-numbers-from-MathExtras.patch",
190 "0016-Add-lerp-and-sgn.patch",
191 "0017-Fixup-includes.patch",
192 "0018-Use-std-is_trivially_copy_constructible.patch",
193 "0019-Windows-support.patch",
194 "0020-Prefer-fmtlib.patch",
195 "0021-Prefer-wpi-s-fs.h.patch",
196 "0022-Remove-unused-functions.patch",
197 "0023-OS-specific-changes.patch",
198 "0024-Use-SmallVector-for-UTF-conversion.patch",
199 "0025-Prefer-to-use-static-pointers-in-raw_ostream.patch",
200 "0026-constexpr-endian-byte-swap.patch",
201 "0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch",
202 "0028-Remove-StringMap-test-for-llvm-sort.patch",
203 ]:
204 git_am(
205 os.path.join(wpilib_root, "upstream_utils/llvm_patches", f),
206 use_threeway=True,
207 )
208
209 overwrite_source(wpiutil, upstream_root)
210 overwrite_tests(wpiutil, upstream_root)
211
212
213if __name__ == "__main__":
214 main()