Squashed 'third_party/allwpilib/' changes from e4b91005cf..83f1860047

83f1860047 [wpilib] Add/update documentation to PneumaticBase and subclasses (NFC) (#4881)
9872e676d8 [commands] Make Subsystem destructor virtual (#4892)
25db20e49d [hal] Fix segfault in various HAL functions (#4891)
b0c6724eed [glass] Add hamburger menu icon to titlebars (#4874)
f0fa8205ac Add missing compiler flags and fix warnings (#4889)
42fc4cb6bc [wpiutil] SafeThread: Provide start/stop hooks (#4880)
cc166c98d2 [templates] Add Command-based skeleton template (#4861)
3f51f10ad3 [build] Update to 2023v3 image (#4886)
1562eae74a [ntcore] Refactor meta-topic decoding from glass (#4809)
b632b288a3 Fix usages of std::min and std::max to be windows safe (#4887)
c11bd2720f [wpilibc] Add internal function to reset Shuffleboard instance (#4884)
f1151d375f [ntcore] Add method to get server time offset (#4847)
fe1b62647f [hal,wpilib] Update documentation for getComments (NFC) (#4879)
c49a45abbd [build] Fix examples linking in incorrect jni library (#4873)
bc3d01a721 [build] Add platform check to doxygen plugin (#4862)
bc473240ae Add Jetbrains Fleet folder to .gitignore (#4872)
2121bd5fb8 [wpimath] Remove RKF45 (#4870)
835f8470d6 [build] Fix roborio cross-compiler on arm hosts (#4864)
6cfe5de00d [ntcore] Don't deadlock server on early destroy (#4863)
2ac41f3edc [hal, wpilib] Add RobotController.getComments()  (#4463)
26bdbf3d41 Java optimization and formatting fixes (#4857)
92149efa11 Spelling and grammar cleanups (#4849)
176fddeb4c [commands] Add functions to HID classes to allow use of axes as BooleanEvents/Triggers (#4762)
87a34af367 [templates] Add bindings to command-based template (#4838)
4534e75787 [examples] Remove redundant MotorControl example (#4837)
1cbebaa2f7 [commands] Remove final semicolon from test macro definition (#4859)
6efb9ee405 [commands] Add constructor for SwerveControllerCommand that takes a HolonomicDriveController (#4785)
1e7fcd5637 [cscore] Change run loop functions to not be mac specific (#4854)
1f940e2b60 [apriltag] Add C++ wrappers, rewrite Java/JNI to match (#4842)
a6d127aedf [build] Add missing task dependency in wpilibjExamples (#4852)
b893b3d6d3 [cscore] Add support for USB cameras on macOS (#4846)
1696a490fa [glass] Add support for alternate NT ports (#4848)
40a22d69bc [glass] Add support for alternate NT ports (#4848)
e84dbfede0 [wpilib] GenericHID: Add rumble both option (#4843)
8aa9dbfa90 [examples] Link apriltag package in examples build.gradle (#4845)
eda2fa8a17 [build] Update Spotless (#4840)
d20594db0d Fix typos (#4839)
dd8ecfdd54 [commands] Fix typo in waitUntil docs (NFC) (#4841)
17ceebfff4 [apriltag] Clean up apriltag JNI (#4823)
8b74ab389d [examples] RapidReactCommandBot: Fix array indices (#4833)
1aad3489c2 [sim] Implement PD total current and power (#4830)
2744991771 [wpimath] Fix docs in SwerveModulePosition (#4825)
ffbf6a1fa2 [commands] Disable regularly failing unit test (#4824)
fbabd0ef15 [commands] Enhance Command Sendable implementations (#4822)
7713f68772 [hal] Use atomic rather then mutex for DS Data updates (#4787)
701995d6cc [examples] Update Command-based starter project (#4778)
bf7068ac27 [wpilibc] Add missing PPS implementation for C++ (#4821)
aae0f52ca6 [ntcore] NetworkTable: fix visibility of get/set value (#4820)
ee02fb7ba7 [hal] Add support for Pulse-Per-Second signal (#4819)
518916ba02 [wpilib] Fix DS mode thread event being manual reset accidentally (#4818)
3997c6635b [hal] Update to new image, use new TCP notify callback and new duty cycle API (#4774)
cc8675a4e5 [examples] Add comment on how to view elevator sim (NFC) (#4482)
fb2c170b6e [ntcore] Simplify local startup (#4803)
7ba8a9ee1f [wpimath] ProfiledPIDController: Add to SendableRegistry (#4656)
c569d8e523 [wpilib] Joystick.getMagnitude(): use hypot() function (#4816)
2a5e89fa97 [apriltag] Improve description of pose coordinates (NFC) (#4810)
cc003c6c38 [apriltag] Fix AprilTagFieldLayout JSON name (#4814)
5522916123 [commands] CommandXBoxController bumper documentation fix (NFC) (#4815)
967b30de3a [glass] Fix NT view UpdateClients() bug (#4808)
3270d4fc86 [wpimath] Rewrite pose estimator docs (#4807)
be39678447 [apriltag] Add test to ensure apriltagjni loads (#4805)
61c75deb2a [commands] Test no-op behavior of scheduling a scheduled command (#4806)
a865f48e96 [ntcore] Pass pub/sub options as a unified PubSubOptions struct (#4794)
f66a667321 [commands] Fix incorrect Trigger docs (NFC) (#4792)
f8d4e9866e [ntcore] Clean up ntcore_test.h (#4804)
7e84ea891f [wpimath] Fix ComputerVisionUtil transform example in parameter docs (NFC) (#4800)
da3ec1be10 [wpimath] Change terminology for ArmFeedforward gravity gain (NFC) (#4791)
944dd7265d [wpilibc] Add C++ Notifier error handling, update java notifier error message (#4795)
6948cea67a [wpiutil] Fix MemoryBuffer initialization (#4797)
a31459bce6 [wpiutil] Fix UnescapeCString overflow when inputSize < 2 (#4796)
4a0ad6b48c [wpimath] Rotation2d: Add reference to angleModulus in docs (NFC) (#4786)
e6552d272e [ntcore] Remove table multi-subscriber (#4789)
bde383f763 [hal] Replace const char* with std::string_view in Driver Station sim functions (#4532)
5a52b51443 [hal] Add RobotController.getSerialNumber() (#4783)
69a66ec5ec [wpilib] Fix multiple motor safety issues (#4784)
989c9fb29a [wpimath] Revert Rotation2D change that limits angles (#4781)
0f5b08ec69 [wpigui] Update imgui to 1.89.1+ (#4780)
fba191099c [examples] AddressableLED: Add unit test (#4779)
b390cad095 [wpilibj] Consistently use ErrorMessages.requireNonNullParam (#4776)
b9772214d9 [wpilib] Sendable: Don't call setter for getter changes
342c375a71 [ntcore] Add subscriber option to exclude single publisher
b0e4053087 [ntcore] Use int for options instead of double
f3e666b7bb [cscore] Convert YUYV and UYVY directly to grayscale (#4777)
b300518bd1 [hal] Add CAN Stream API to Java through JNI bindings (#4193)
be27171236 [wpilibj] Shuffleboard: Check for null sendable (#4772)
4bbdbdfb48 [commands] Move GroupedCommands to CommandScheduler (#4728)
f18fd41ac3 [wpimath] Remove broken and obsoleted ComputerVisionUtil functions (#4775)
2d0faecf4f [glass] DataSource: Add spinlock to protect value (#4771)
348bd107fc [hal] Add CANManufacturer for The Thrifty Bot (#4773)
3149dc64b8 [examples] HatchbotInlined: Use Subsystem factories (#4765)
8618dd4160 [glass, wpilib] Replace remaining references to Speed Controller with Motor Controller (#4769)
72e21a1ed1 [apriltag] Use wpilibsuite fork of apriltag (#4764)
eab0d929e6 [commands] CommandGenericHID POV methods: Fix docs (NFC) (#4760)
6789869663 [wpilib] Call set(0) rather than disable for stopMotor (#4763)
c9dea2968d [cscore] Emit warning that USB Camera isn't supported on OSX (#4766)
8f402645f5 [commands] Fix PIDSubsystem setSetpoint behavior (#4759)
f24ad1d715 [build] Upgrade to googletest 1.12.1 (#4752)
ff88756864 [wpimath] Add new DCMotor functions for alternative calculations and reduction calculation (#4749)
f58873db8e [wpimath] Remove extra terms in matrix for pose estimator docs (#4756)
37e969b41a [wpimath] Add constructors to pose estimators with default standard deviations (#4754)
13cdc29382 [ci] Rename comment command from "/wpiformat" to "/format" (#4755)
6e23985ae6 [examples] Add main include directory to test builds (#4751)
66bb0ffb2c [examples] Add unit testing infrastructure (#4646)
74cc86c4c5 [wpimath] Make transform tests use pose/transform equality operators (#4675)
e22d8cc343 [wpimath] Use Odometry for internal state in Pose Estimation (#4668)
68dba92630 [ci] Update mac and windows builds to Java 17 (#4750)
23bfc2d9ab [sim] Remove unmaintained Gazebo support (#4736)
1f1461e254 [wpilib] Add method to enable/disable LiveWindow in test mode (#4678)
eae68fc165 [wpimath] Add tolerance for Rotation3d rotation matrix special orthogonality (#4744)
4c4545fb4b [apriltag] Suppress warning (#4743)
16ffaa754d [docs] Generate docs for apriltag subproject (#4745)
5e74ff26d8 [apriltag, build] Update native utils, add apriltag impl and JNI (#4733)
53875419a1 [hal] Allow overriding stderr printing by HAL_SendError (#4742)
aa6499e920 [ntcore] Fix special topic multi-subscriber handling (#4740)
df70351107 [build] Fix cmake install of thirdparty includes (#4741)
e9bd50ff9b [glass] NT view: clear meta-topic info on disconnect (#4732)
9b319fd56b [ntcore] Add sub option for local vs remote changes (#4731)
18d28ec5e3 [ntcore] Remove duplicate value checking from ClientImpl
bdfb625211 [ntcore] Send duplicate values to network if necessary
21003e34eb [commands] Update Subsystem factories and example to return CommandBase (#4729)
70080457d5 [commands] Refactor ProxyScheduleCommand, SelectCommand into ProxyCommand (#4534)
e82cd5147b [wpilib] Tweak Color HSV formula and use in AddressableLED (#4724)
ec124bb662 [commands] Allow unsetting a subsystem's default command (#4621)
2b2aa8eef7 [examples] Update all examples to use NWU coordinate conventions (#4725)
cb38bacfe8 [commands] Revert to original Trigger implementation (#4673)
15561338d5 [commands] Remove one more default command isFinished check (#4727)
ca35a2e097 Add simgui files to .gitignore (#4726)
20dbae0cee [examples] Renovate command-based examples (#4409)
1a59737f40 [commands] Add convenience factories (#4460)
42b6d4e3f7 Use defaulted comparison operators in C++ (#4723)
135c13958f [wpigui] Add FontAwesome (#4713)
ffbfc61532 [ntcore] Add NetworkTable table-specific listeners (#4640)
8958b2a4da [commands] Add property tests for command compositions (#4715)
e4ac09077c [wpilib] Add link to MotorSafety article (#4720)
f40de0c120 [commands] Add C++ factory templates (#4686)
51fa3e851f [build] cmake: Use FetchContent instead of ExternalProject (#4714)
1da84b2255 [wpigui] Reload fonts to scale rather than preloading (#4712)
e43e2fbc84 [wpiutil] StringExtras: Add UnescapeCString (#4707)
5804d8fa84 [ntcore] Server: Properly handle multiple subscribers (#4717)
169ef5fabf [glass] Update NT view for topicsOnly and sendAll changes (#4718)
148759ef54 [examples] CANPDP: Expand properties shown (#4687)
58ed112b51 [commands] RepeatCommand: restart on following iteration (#4706)
dd1da77d20 [readme] Fix broken CI badge (#4710)
7cda85df20 [build] Check Gradle plugin repo last to fix CI (#4711)
7ed9b13277 [build] Bump version plugin to fix null tag (#4705)
6b4f26225d [apriltag] Fix pluralization of apriltag artifacts (#4671)
b2d2924b72 [cscore] Add Y16 image support (#4702)
34ec89c041 [wpilibc] Shuffleboard SimpleWidget: Return pointer instead of reference (#4703)
e15200068d [ci] Disable HW testbench runs (#4704)
d5200db6cd [wpimath] Rename HolonomicDriveController.calculate params (#4683)
2ee3d86de4 [wpimath] Clarify Rotation3d roll-pitch-yaw direction (#4699)
9f0a8b930f [cscore] Use MFVideoFormat_L8 for Gray on Windows (#4701)
2bca43779e [cscore] Add UYVY image support (#4700)
4307d0ee8b [glass] Plot: allow for more than 11 plots (#4685)
3fe8d355a1 [examples] StateSpaceDifferentialDriveSimulation: Use encoder reversed constants (#4682)
b44034dadc [ntcore] Allow duplicate client IDs on server (#4676)
52d2c53888 [commands] Rename Java factory wait() to waitSeconds() (#4684)
76e918f71e [build] Fix JNI artifacts linking to incorrect libraries (#4680)
0bee875aff [commands] Change C++ CommandPtr to use CommandBase (#4677)
98e922313b [glass] Don't check IsConnected for NT widgets (#4674)
9a36373b8f [apriltag] Switch 2022 apriltag layout length and width values (#4670)
cf8faa9e67 [wpilib] Update values on controllable sendables (#4667)
5ec067c1f8 [ntcore] Implement keep duplicates pub/sub flag (#4666)
e962fd2916 [ntcore] Allow numeric-compatible value sets (#4620)
88bd67e7de [ci] Update clang repositories to jammy (#4665)
902e8686d3 [wpimath] Rework odometry APIs to improve feature parity (#4645)
e2d49181da Update to native utils 2023.8.0 (#4664)
149bac55b1 [cscore] Add Arducam OV9281 exposure quirk (#4663)
88f7a3ccb9 [wpimath] Fix Pose relativeTo documentation (#4661)
8acce443f0 [examples] Fix swerve examples to use getDistance for turning encoder (#4652)
295a1f8f3b [ntcore] Fix WaitForListenerQueue (#4662)
388e7a4265 [ntcore] Provide mechanism to reset internals of NT instance (#4653)
13aceea8dc [apriltag] Fix FieldDimensions argument order (#4659)
c203f3f0a9 [apriltag] Fix documentation for AprilTagFieldLayout (#4657)
f54d495c90 Fix non initialized hal functionality during motor safety init (#4658)
e6392a1570 [cmd] Change factories return type to CommandBase (#4655)
53904e7cf4 [apriltag] Split AprilTag functionality to a separate library (#4578)
2e88a496c2 [wpimath] Add support for swerve joystick normalization (#4516)
ce4c45df13 [wpimath] Rework function signatures for Pose Estimation / Odometry (#4642)
0401597d3b [readme] Add wpinet to MavenArtifacts.md (#4651)
2e5f9e45bb [wpimath] Remove encoder reset comments on Swerve, Mecanum Odometry and Pose Estimation (#4643)
e4b5795fc7 [docs] Disable Doxygen for memory to fix search (#4636)
03d0ea188c [build] cmake: Add missing wpinet to installed config file (#4637)
3082bd236b [build] Move version file to its own source set (#4638)
b7ca860417 [build] Use build cache for sign step (#4635)
64838e6367 [commands] Remove unsafe default command isFinished check (#4411)
1269d2b901 [myRobot] Disable spotbugs (#4565)
14d8506b72 [wpimath] Fix units docs for LinearSystemId::IdentifyDrivetrainSystem() (#4600)
d1d458db2b [wpimath] Constrain Rotation2d range to -pi to pi (#4611)
f656e99245 [readme] Add links to development build documentation (#4481)
6dd937cef7 [commands] Fix Trigger API docs (NFC) (#4599)
49047c85b9 [commands] Report error on C++ CommandPtr use-after-move (#4575)
d07267fed1 [ci] Upgrade containers to Ubuntu 22.04 and remove libclang installation (#4633)
b53ce1d3f0 [build, wpiutil] Switch macos to universal binaries (#4628)
5a320c326b [upstream_util, wpiutil] Refactor python scripts (#4614)
c4e526d315 [glass] Fix NT Mechanism2D (#4626)
d122e4254f [ci] Run spotlessApply after wpiformat in comment command (#4623)
5a1e7ea036 [wpilibj] FieldObject2d: Add null check to close() (#4619)
179f569113 [ntcore] Notify locally on SetDefault (#4617)
b0f6dc199d [wpilibc] ShuffleboardComponent.WithProperties: Update type (#4615)
7836f661cd [wpimath] Add missing open curly brace to units/base.h (#4613)
dbcc1de37f [wpimath] Add DifferentialDriveFeedforward classes which wrap LinearPlantInversionFeedforward (#4598)
93890c528b [wpimath] Add additional angular acceleration units (#4610)
3d8d5936f9 [wpimath] Add macro for disabling units fmt support (#4609)
2b04159dec [wpimath] Update units/base.h license header (#4608)
2764004fad [wpinet] Fix incorrect jni definitions (#4605)
85f1bb8f2b [wpiutil] Reenable jni check task (#4606)
231ae2c353 [glass] Plot: Fix Y-axis not being saved (#4594)
e92b6dd5f9 [wpilib] Fix AprilTagFieldLayout JSON property name typos (#4597)
2a8e0e1cc8 Update all dependencies that use grgit (#4596)
7d06e517e9 [commands] Move SelectCommand factory impl to header (#4581)
323524fed6 [wpimath] Remove deprecated units/units.h header (#4572)
d426873ed1 [commands] Add missing PS4 triangle methods (#4576)
5be5869b2f [apriltags] Use map as internal data model (#4577)
b1b4c1e9e7 [wpimath] Fix Pose3d transformBy rotation type (#4545)
a4054d702f [commands] Allow composing two triggers directly (#4580)
0190301e09 [wpilibc] Explicitly mark EventLoop as non-copyable/non-movable (#4579)
9d1ce6a6d9 [ntcore] Catch file open error when saving preferences (#4571)
5005e2ca04 [ntcore] Change Java event mask to EnumSet (#4564)
fa44a07938 [upstream-utils][mpack] Add upstream util for mpack (#4500)
4ba16db645 [ntcore] Various fixes and cleanups (#4544)
837415abfd [hal] Fix joysticks either crashing or returning 0 (#4570)
2c20fd0d09 [wpilib] SingleJointedArmSim: Check angle equals limit on wouldHit (#4567)
64a7136e08 [wpimath] SwerveDrivePoseEstimator: Restore comment about encoder reset (#4569)
b2b473b24a [wpilib] Add AprilTag and AprilTagFieldLayout (#4421)
7aab8fa93a [build] Update to Native Utils 2023.6.0 (#4563)
12c2851856 [commands] WrapperCommand: inherit from CommandBase (#4561)
0da169dd84 [wpimath] Remove template argument from ElevatorFeedforward (#4554)
2416827c25 [wpimath] Fix docs for pose estimator local measurement models (#4558)
1177a3522e [wpilib] Fix Xbox/PS4 POV sim for port number constructors (#4548)
102344e27a [commands] HID classes: Add missing methods, tweak return types (#4557)
1831ef3e19 [wpilib] Fix Shuffleboard SuppliedValueWidget (#4559)
a9606ce870 [wpilib] Fix Xbox/PS4 POV sim (#4546)
6c80d5eab3 [wpimath] Remove unused SymbolExports.h include from units/base.h (#4541)
b114006543 [ntcore] Unify listeners (#4536)
32fbfb7da6 [build] cmake: Install ntcore generated include files (#4540)
02465920fb [build] Update native utils to 2023.4.0 (#4539)
3a5a376465 [wpimath] Increase constexpr support in geometry data types (#4231)
1c3c86e9f1 [ntcore] Cache GetEntry(name) values (#4531)
dcda09f90a [command] Rename trigger methods (#4210)
66157397c1 [wpilib] Make drive classes follow NWU axes convention (#4079)
9e22ffbebf [ntcore] Fix null deref in NT3 client (#4530)
648ab6115c [wpigui,dlt,glass,ov] Support arm in GUI tools (#4527)
8bc3b04f5b [wpimath] Make ComputerVisionUtil use 3D geometry classes (#4528)
cfb84a6083 [wpilibc] Don't hang waiting for NT server to start (#4524)
02c47726e1 [wpimath] Remove unused odometry instance from DifferentialDrivePoseEstimator test (#4522)
b2a0093294 [ci] Revert upgrade of github-pages-deploy-action (#4521)
2a98d6b5d7 [wpimath] PIDController: Add getters for position & velocity tolerances (#4458)
9f36301dc8 [ci] Write wpiformat patch to job summary (#4519)
901fc555f4 [wpimath] Position Delta Odometry for Mecanum (#4514)
4170ec6107 [wpimath] Position Delta Odometry for Swerve (#4493)
fe400f68c5 [docs] Add wpinet to docs build (#4517)
794669b346 [ntcore] Revamp listeners (#4511)
dcfa85a5d5 [ci] Build sanitizers with clang-14 (#4518)
15ad855f1d [ntcore] Add UnitTopic<T> (C++ only) (#4497)
11244a49d9 [wpilib] Add IsConnected function to all gyros (#4465)
1d2e8eb153 [build] Update myRobot deployment (#4515)
ad53fb19b4 [hal] Use new HMB api for addressable LED (#4479)
ba850bac3b [hal] Add more shutdown checks and motor safety shutdown (#4510)
023a5989f8 [ntcore] Fix typo in NetworkServer client connect message (#4512)
c970011ccc [docs] Add Doxygen aliases used by Foonathan memory (#4509)
07a43c3d9a [readme] Document clang-format version and /wpiformat (#4503)
a05b212b04 [ci] Revert changes to wpiformat task from #4501 (#4508)
09faf31b67 [commands] Replace Command HID inheritance with delegation (#4470)
9e1f9c1133 [commands] Add command factories (#4476)
f19d2b9b84 [ci] Add NUMBER environment variable to comment command commit script (#4507)
a28f93863c [ci] Push comment command commit directly to PR (#4506)
c9f61669b8 [ci] Fix comment command commit push (#4505)
dcce5ad3b3 [ci] Update github-script API usage (#4504)
6836e5923d [wpilibc] Restore get duty cycle scale factor (#4502)
335188c652 [dlt] Add deselect/select all buttons to download view (#4499)
60a29dcb99 [glass] Field2D: Add "hidden" option for objects (#4498)
b55d5b3034 [ci] Update deprecated github actions (#4501)
10ed4b3969 [ntcore] Various NT4 fixes (#4474)
4a401b89d7 [hal, wpilib] New DS thread model and implementation (#3787)
c195b4fc46 [wpimath] Clean up PoseEstimator nominal dt docs (#4496)
8f2e34c6a3 [build] Remove wpilib prefix from CMake flat install (#4492)
150d692df7 [wpimath] Remove unused private PoseEstimator function (#4495)
3e5bfff1b5 [wpimath] FromFieldRelativeSpeeds: Add ChassisSpeeds overload (#4494)
9c7e66a27d [commands] C++: Add CommandPtr overload for SetDefaultCommand (#4488)
0ca274866b [build] Fix CMake system library opt-ins (#4487)
dc037f8d41 [commands] Remove EndlessCommand (#4483)
16cdc741cf [wpimath] Add Pose3d(Pose2d) constructor (#4485)
9d5055176d [build] cmake: Allow disabling ntcore build (#4486)
d1e66e1296 [build] Compile all java code with inline string concatenation (#4490)
1fc098e696 Enable log macros to work with no args (#4475)
878cc8defb [wpilib] LiveWindow: Add enableAllTelemetry() (#4480)
8153911160 [build] Fix MSVC runtime archiver to grab default runtime (#4478)
fbdc810887 Upgrade to C++20 (#4239)
396143004c [ntcore] Add ntcoreffi binary (#4471)
1f45732700 [build] Update to 2023.2.4 native-utils and new dependencies (#4473)
574cb41c18 [ntcore] Various fixes (#4469)
d9d6c425e7 [build] Force Java 11 source compatibility (#4472)
58b6484dbe Switch away from NI interrupt manager to custom implementation (#3705)
ca43fe2798 [wpimath] Use Units conversions in ComputerVisionUtil docs (NFC) (#4464)
87a64ccedc [hal] Convert DutyCycle Raw output to be a high time measurement (#4466)
89a3d00297 [commands] Add FinallyDo and HandleInterrupt decorators (#4412)
1497665f96 [commands] Add C++ versions of Java-only decorators (#4457)
27b173374e [wpimath] Add minLinearAccel parameter to DifferentialDriveAccelerationLimiter (#4422)
2a13dba8ac [wpilib] TrajectoryUtil: Fix ambiguous documentation (NFC) (#4461)
77301b126c [ntcore] NetworkTables 4 (#3217)
90cfa00115 [build] cmake: Fix libssh include directory order (#4459)
5cf961edb9 [commands] Refactor lambda-based commands to inherit FunctionalCommand (#4451)
b2276e47de [wpimath] Enable continuous angle input for HolonomicDriveController (#4453)
893b46139a [fieldImages] Add utilities to simplify loading of fields (#4456)
60e29627c0 [commands] C++ unique_ptr migration (#4319)
3b81cf6c35 [wpilib] Improve Color.toString (#4450)
5c067d30a0 [wpinet] WebSocket: Add SendFrames() (#4445)
ceaf493811 [wpiutil] MakeJByteArray: Use span<uint8> instead of string_view (#4446)
10e04e2b13 [examples] FrisbeeBot: Fix reference capture (#4449)
726f67c64b [build] Add exeSplitSetup (#4444)
c7b7624c1c [wpiutil] Add MessagePack utility functions (#4448)
d600529ec0 [wpinet] uv::Async: Add UnsafeSend() (#4447)
b53b3526a2 [wpimath] Add CoordinateSystem conversion for Transform3d (#4443)
38bb23eb18 [wpimath] Add scalar multiply and divide operators to all geometry classes (#4438)
3937ff8221 [wpilib] Remove deprecated Controller class (#4440)
abbfe244b5 [wpilib] Improve Color FromHSV (#4439)
4ddb8aa0dd [sim] Provide function that resets all simulation data (#4016)
a791470de7 Clean up Java warning suppressions (#4433)
17f504f548 [hal,wpilib] Fix SPI Mode Setting (#4434)
773198537c [wpiutil] Add wpi::scope_exit (#4432)
5ac658c8f0 [wpiutil] Logger: Conditionalize around WPI_LOG (#4431)
8767e4a941 [wpiutil] DataLog: Fix SetMetadata output (#4430)
8c4af073f4 [wpiutil] Synchronization: shutdown race protection (#4429)
c79f38584a [build] Fix Java integration tests (#4428)
36c08dd97c [build] Fix cmake install of fmtlib (#4426)
69b7b3dd7d [ci] Remove the Windows cmake job (#4425)
738c75fed8 [readme] Fix formatting/linting link (#4423)
4eb1d03fb3 [wpimath] Document C++ LinearFilter exception (#4417)
ba4ec6c967 [build] Fix clang-tidy false positive on Linux (#4406)
97836f0e55 [commands] Fix ProfiledPIDSubsystem setGoal behavior (#4414)
fdfb85f695 [wpimath] Remove Java LQR constructor that takes a controller gain matrix (#4419)
ab1baf4832 [wpimath] Add rotation matrix constructor to Rotation3d (#4413)
9730032866 [wpimath] Document LQR and KalmanFilter exceptions (#4418)
5b656eecf6 [wpimath] Fix HTML5 entity (#4420)
9ae38eaa7c [commands] Add owning overload to ProxyScheduleCommand (#4405)
cb33bd71df [commands] deprecate withInterrupt decorator (#4407)
d9b4e7b8bf [commands] Revert "Change grouping decorator impl to flatten nested group structures (#3335)" (#4402)
0389bf5214 [hal] REVPH: Improve handling of disconnected CAN Bus (#4169)
4267fa08d1 [wpilibc] ADIS IMUs: Fix memory leak (#4170)
65c8fbd452 [wpilib] MotorControllerGroup: Override setVoltage (#4403)
f36162fddc [wpimath] Improve Discretization internal docs (#4400)
5149f7d894 [wpimath] Add two-vector Rotation3d constructor (#4398)
20b5bed1cb [wpimath] Clean up Java Quaternion class (#4399)
f18dd1905d [build] Include all thirdparty sources in distribution (#4397)
aa9d7f1cdc [wpiutil] Import foonathan memory (#4306)
2742662254 [ci] Remove a couple of obsolete clang-tidy checks (#4396)
a5df391166 [hal, wpilib] Fix up DIO pulse API (#4387)
59e6706b75 [glass] Turn on docking by default
8461bb1e03 [glass] Add support for saving docking info
b873e208b4 [wpigui] Add support for imgui config flags
873e72df8c [build] Update imgui to 1.88 docking branch
c8bd6fc5b4 [ci] Fix comment-command (take 2) (#4395)
fed68b83b4 [ci] Fix comment-command action not running runners (#4393)
0ef8a4e1df [wpimath] Support formatting more Eigen types (#4391)
c393b3b367 [build] Update to native utils 2023.1.0 and Gradle 7.5.1 (#4392)
b5a17f762c [wpimath] Add direction to slew rate limiter (#4377)
fafc81ed1a [wpiutil] Upgrade to fmt 9.1.0 (#4389)
cc56bdc787 [wpiutil] SafeThread: Add Synchronization object variant (#4382)
4254438d8d [commands] Mark command group lifecycle methods as final (#4385)
97c15af238 [wpimath] LinearSystemId: Fix docs, move C++ impls out of header (#4388)
d22ff8a158 [wpiutil] Add JNI access to C++ stderr (#4381)
fdb5a2791f [wpiutil] jni_util: Add Mac-friendly MakeJLongArray/JArrayRef (#4383)
c3a93fb995 [commands] Revamp Interruptible (#4192)
f2a8d38d2a [commands] Rename Command.repeat to repeatedly (#4379)
9e24c6eac0 [wpiutil] Logger: paren-protect instance usage in macro (#4384)
fe4d12ce22 [wpimath] Add LTV controller derivations and make enums private (#4380)
eb08486039 [build] Fix MacOS binary rpath generation (#4376)
ccf83c634a [build] Use native-utils platform names instead of raw strings (#4375)
3fd69749e7 [docs] Upgrade to doxygen 1.9.4 (#4370)
594df5fc08 [wpinet] uv/util.h: Pull in ws2_32.lib on Windows for ntohs (#4371)
539070820d [ci] Enable asan for wpinet and wpiutil (#4369)
564a56d99b [wpinet] Fix memory leak in WorkerThreadTest (#4368)
5adf50d93c [upstream_utils] Refactor upstream_utils scripts (#4367)
d80e8039d7 [wpiutil] Suppress fmtlib clang-tidy warning in C++20 consteval contexts (#4364)
0e6d67b23b [upstream_utils] Remove yapf format disable comment (#4366)
be5270697a [build] Suppress enum-enum deprecation warning in OpenCV (#4365)
8d28851263 Add Rosetta install command to build requirements (#4363)
3d2115c93e [wpinet] include-what-you-use in MulticastTest (#4360)
91002ae3cc [wpimath] Upgrade to Drake 1.6.0 (#4361)
148c18e658 [wpinet] Upgrade to libuv 1.44.2 (#4362)
a2a5c926b6 Fix clang-tidy warnings (#4359)
ea6b1d8449 [wpiutil] Remove unused ManagedStatic class (#4358)
ac9be78e27 Use stricter C++ type conversions (#4357)
151dabb2af [wpiutil] Upgrade to fmt 9.0.0 (#4337)
340465c929 [ci] Upgrade to clang-format and clang-tidy 14 (NFC) (#4347)
d45bcddd15 [examples] Add comments to StateSpaceDifferentialDrive (#4341)
0e0786331a Update LLVM libraries to 14.0.6 (#4350)
c5db23f296 [wpimath] Add Eigen sparse matrix and iterative solver support (#4349)
44abc8dfa6 [upstream_utils] Remove git version from upstream patches (#4351)
3fdb2f767d [wpimath] Add comments with Ramsete equations (#4348)
0485f05da9 [wpilibjExamples] Upgrade jacoco to match allwpilib (#4346)
0a5eb65231 [wpinet] Handle empty txt block for mdns announcer (#4072)
19ffebaf3e [wpilib] Add reference to I2C Lockup to API Docs (NFC) (#4340)
ce1a90d639 [hal] Replace SerialHelper "goto done" with continue (#4342)
d25af48797 [ci] Make upstream_utils CI fail on untracked files (#4339)
ebb836dacb [examples] Fix negations in event loop examples (#4334)
d83e202f00 [upstream_utils] Update paths in update_fmt.py (#4338)
3ccf806064 [wpimath] Remove redundant LinearFilter.finiteDifference() argument (#4335)
6f1e01f8bd [wpimath] Document example of online filtering for LinearFilter.finiteDifference() (#4336)
1023c34b1c [readme] Update location of ni-libraries (#4333)
faa29d596c [wpilib] Improve Notifier docs (NFC) (#4326)
add00a96ed [wpimath] Improve DifferentialDriveAccelerationLimiter docs (NFC) (#4323)
82fac41244 [wpimath] Better document trackwidth parameters (NFC) (#4324)
5eb44e22a9 Format Python scripts with black (NFC) (#4325)
2e09fa7325 [build] Fix mpack cmake (#4322)
fe3c24b1ee [command] Add ignoringDisable decorator (#4305)
aa221597bc [build] Add M1 builds, change arm name, update to 2023 deps (#4315)
579a8ee229 [ci] Use one worker for Windows release Gradle build (#4318)
5105c5eab6 [wpilibj] Change "final" to "exit" in the IterativeRobotBase JavaDoc (NFC) (#4317)
787fe6e7a5 [wpiutil] Separate third party libraries (#4190)
6671f8d099 [wpigui] Update portable file dialogs (#4316)
9ac9b69aa2 [command] Reorder Scheduler operations (#4261)
e61028cb18 [build] halsim_gui: Add wpinet dependency (#4313)
661d23eaf5 [glass] Add precision setting for NetworkTable view (#4311)
666040e3e5 [hal] Throw exceptions for invalid sizes in I2C and SPI JNI (#4312)
aebc272449 [build] Upgrade to spotbugs Gradle plugin 5.0.8 (#4310)
fd884581e4 [wpilib] Add BooleanEvent/Trigger factories on HID classes (#4247)
9b1bf5c7f1 [wpimath] Move Drake and Eigen to thirdparty folders (#4307)
c9e620a920 [wpilibc] Change EventLoop data structure to vector (#4304)
41d40dd62f [wpinet] Fix libuv unused variable warning on Mac (#4299)
30f5b68264 [wpinet] Fix JNI loading error (#4295)
f7b3f4b90e [examples] Getting Started: Change Joystick to XboxController (#4194)
a99c11c14c [wpimath] Replace UKF implementation with square root form (#4168)
45b7fc445b [wpilib] Add EventLoop (#4104)
16a4888c52 [wpilib] Default off LiveWindow telemetry (#4301)
17752f1337 [ci] Split debug and release Windows builds (#4277)
abb45a68db [commands] Remove custom test wrappers (#4296)
1280a54ef3 [upstream_utils]: Make work with Python 3.8 (#4298)
f2d243fa68 [build] Change defaults for Java lints (#4300)
a4787130f4 Update using development build to work with 2023 gradlerio (#4294)
af7985e46c [wpiutil] Use invoke_result_t instead of result_of in future.h (#4293)
e9d1b5c2d0 [hal] Remove deprecated SimDevice functions (#4209)
45b598d236 [wpilibj] Add toString() methods to Color and Color8Bit (#4286)
fc37265da5 [wpimath] Add angle measurement convention to ArmFeedforward docs (NFC) (#4285)
a4ec13eb0e [wpilibjexamples] Remove unnecessary voltage desaturation
2fa52007af [wpilibc] Use GetBatteryVoltage() in MotorController::SetVoltage
d9f9cd1140 [wpimath] Reset prev_time on pose estimator reset (#4283)
8b6df88783 [wpilibj] Tachometer.getFrequency(): Fix bug (#4281)
345cff08c0 [wpiutil] Make wpi::array constexpr (#4278)
57428112ac [wpimath] Upgrade to Drake v1.3.0 (#4279)
a18d4ff154 [build] Fix tools not being copied when built with -Ponly* (#4276)
d1cd07b9f3 [wpigui] Add OpenURL (#4273)
e67f8e917a [glass] Use glfwSetKeyCallback for Enter key remap (#4275)
be2fedfe50 [wpimath] Add stdexcept include for std::invalid_argument (IWYU) (#4274)
7ad2be172e [build] Update native-utils to 2023.0.1 (#4272)
abc605c9c9 [ci] Update workflows to 20.04 base image (#4271)
3e94805220 [wpiutil] Reduce llvm collections patches (#4268)
db2e1d170e [upstream_utils] Document how to update thirdparty libraries (#4253)
96ebdcaf16 [wpimath] Remove unused Eigen AutoDiff module (#4267)
553b2a3b12 [upstream_utils] Fix stackwalker (#4265)
3e13ef42eb [wpilibc] Add missing std::array #include (include-what-you-use) (#4266)
d651a1fcec Fix internal deprecation warnings (#4257)
b193b318c1 [commands] Add unless() decorator (#4244)
ef3714223b [commands] Remove docs reference to obsolete interrupted() method (NFC) (#4262)
3d8dbbbac3 [readme] Add quickstart (#4225)
013efdde25 [wpinet] Wrap a number of newer libuv features (#4260)
816aa4e465 [wpilib] Add Pneumatics sim classes (#4033)
046c2c8972 [wpilibc] Rename SpeedControllerGroupTest.cpp (#4258)
d80e9cdf64 [upstream_utils] Use shallow clones for thirdparty repos (#4255)
7576136b4a [upstream_utils] Make update_llvm.py executable (#4254)
c3b223ce60 [wpiutil] Vendor llvm and update to 13.0.0 (#4224)
5aa67f56e6 [wpimath] Clean up math comments (#4252)
fff4d1f44e [wpimath] Extend Eigen warning suppression to GCC 12 (#4251)
0d9956273c [wpimath] Add CoordinateSystem.convert() translation and rotation overloads (#4227)
3fada4e0b4 [wpinet] Update to libuv 1.44.1 (#4232)
65b23ac45e [wpilibc] Fix return value of DriverStation::GetJoystickAxisType() (#4230)
4ac34c0141 [upstream_utils] Cleanup update_libuv.py (#4249)
8bd614bb1e [upstream_utils] Use "git am" instead of "git apply" for patches (#4248)
4253d6d5f0 [upstream_utils] Apply "git am" patches individually (#4250)
6a4752dcdc Fix GCC 12.1 warning false positives (#4246)
5876b40f08 [wpimath] Memoize CoordinateSystem and CoordinateAxis statics (#4241)
5983434a70 [cameraserver] Replace IterativeRobot in comment sample code with TimedRobot (#4238)
a3d44a1e69 [wpimath] Add Translation2d.getAngle() (#4217)
d364bbd5a7 [upstream_utils] Give vendor update scripts execute permissions (#4226)
f341e1b2be [wpimath] Document standard coordinate systems better (NFC) (#4228)
9af389b200 [wpinet] AddrToName: Initialize name (#4229)
2ae4adf2d7 [ci] Add wpiformat command to PRs (#4223)
178b2a1e88 Contributing.md: Correct version of clang-format used (#4222)
18db343cdc [wpiutil, wpinet] Vendor libuv, stack walker (#4219)
f0c821282a [build] Use artifactory mirror (#4220)
d673ead481 [wpinet] Move network portions of wpiutil into new wpinet library (#4077)
b33715db15 [wpimath] Add CoordinateSystem class (#4214)
99424ad562 [sim] Allow creating a PWMSim object from a PWMMotorController (#4039)
dc6f641fd2 [wpimath] PIDController: Reset position and velocity error when reset() is called. (#4064)
f20a20f3f1 [wpimath] Add 3D geometry classes (#4175)
708a4bc3bc [wpimath] Conserve previously calculated swerve module angles when updating states for stationary ChassisSpeeds (#4208)
ef7ed21a9d [wpimath] Improve accuracy of ComputerVisionUtil.calculateDistanceToTarget() (#4215)
b1abf455c1 [wpimath] LTVUnicycleController: Use LUT, provide default hyperparameters (#4213)
d5456cf278 [wpimath] LTVDifferentialDriveController: Remove unused variable (#4212)
99343d40ba [command] Remove old command-based framework (#4211)
ee03a7ad3b Remove most 2022 deprecations (#4205)
ce1a7d698a [wpimath] Refactor WheelVoltages inner class to a separate file (#4203)
87bf70fa8e [wpimath] Add LTV controllers (#4094)
ebd2a303bf [wpimath] Remove deprecated MakeMatrix() function (#4202)
e28776d361 [wpimath] LinearSystemLoop: Add extern templates for common cases
dac1429aa9 [wpimath] LQR: Use extern template instead of Impl class
e767605e94 [wpimath] Add typedefs for common types
97c493241f [wpimath] UnscentedKalmanFilter: Move implementation out-of-line
8ea90d8bc9 [wpimath] ExtendedKalmanFilter: Move implementation out-of-line
ae7b1851ec [wpimath] KalmanFilter: Use extern template instead of Impl class
e3d62c22d3 [wpimath] Add extern templates for common cases
7200c4951d [wpiutil] SymbolExports: Add WPILIB_IMPORTS for dllimport
84056c9347 [wpiutil] SymbolExports: Add EXPORT_TEMPLATE_DECLARE/DEFINE
09cf6eeecb [wpimath] ApplyDeadband: add a scale param (#3865)
03230fc842 [build,ci] Enable artifactory build cache (#4200)
63cf3aaa3f [examples] Don't square ArcadeDrive inputs in auto (#4201)
18ff694f02 [wpimath] Add Rotation2d.fromRadians factory (#4178)
4f79ceedd9 [wpilibc] Add missing #include (#4198)
f7ca72fb41 [command] Rename PerpetualCommand to EndlessCommand (#4177)
a06b3f0307 [hal] Correct documentation on updateNotifierAlarm (#4156)
d926dd1610 [wpimath] Fix pose estimator performance (#4111)
51bc893bc5 [wpiutil] CircularBuffer: Change Java package-private methods to public (#4181)
fbe761f7f6 [build] Increase Gradle JVM heap size (#4172)
5ebe911933 [wpimath] Add DifferentialDriveAccelerationLimiter (#4091)
3919250da2 [wpilibj] Remove finalizers (#4158)
b3aee28388 [commands] Allow BooleanSupplier for Trigger operations (#4103)
9d20ab3024 [wpilib] Allow disabling ElevatorSim gravity (#4145)
aaa69f6717 [ci] Remove 32-bit Windows builds (#4078)
355a11a414 Update Java linters and fix new PMD errors (#4157)
ffc69d406c [examples] Reduce suggested acceleration in Ramsete example (#4171)
922d50079a [wpimath] Units: fix comment in degreesToRotations (NFC) (#4159)
dd163b62ae [wpimath] Rotation2d: Add factory method that uses rotations (#4166)
bd80e220b9 [ci] Upgrade CMake actions (#4161)
aef4b16d4c [wpimath] Remove unnecessary NOLINT in LinearPlantInversionFeedforward (NFC) (#4155)
975171609e [wpilib] Compressor: Rename enabled to isEnabled (#4147)
5bf46a9093 [wpimath] Add ComputerVisionUtil (#4124)
f27a1f9bfb [commands] Fix JoystickButton.getAsBoolean (#4131)
1b26e2d5da [commands] Add RepeatCommand (#4009)
88222daa3d [hal] Fix misspelling in AnalogInput/Output docs (NFC) (#4153)
81c5b41ce1 [wpilibj] Document MechanismLigament2d angle unit (NFC) (#4142)
9650e6733e [wpiutil] DataLog: Document finish and thread safety (NFC) (#4140)
c8905ec29a [wpimath] Remove ImplicitModelFollower dt argument (#4119)
b4620f01f9 [wpimath] Fix Rotation2d interpolation in Java (#4125)
2e462a19d3 [wpimath] Constexprify units unary operators (#4138)
069f932e59 [build] Fix gl3w cmake build (#4139)
126e3de91a [wpilibc] Remove unused SetPriority() call from Ultrasonic (#4123)
ba0dccaae4 [wpimath] Fix reference to Rotation2d.fromRadians() (#4118)
e1b6e5f212 [wpilib] Improve MotorSafety documentation (NFC) (#4120)
8d79dc8738 [wpimath] Add ImplicitModelFollower (#4056)
78108c2aba [wpimath] Fix PIDController having incorrect error after calling SetSetpoint() (#4070)
cdafc723fb [examples] Remove unused LinearPlantInversionFeedforward includes (#4069)
0d70884dce [wpimath] Add InterpolatedTreeMap (#4073)
765efa325e [wpimath] Remove redundant column index from vectors (#4116)
89ffcbbe41 [wpimath] Update TrapezoidProfile class name in comment (NFC) (#4107)
95ae23b0e7 [wpimath] Improve EKF numerical stability (#4093)
d5cb6fed67 [wpimath] Support zero cost entries in MakeCostMatrix() (#4100)
d0fef18378 [wpimath] Remove redundant `this.` from ExtendedKalmanFilter.java (#4115)
d640c0f41f [wpimath] Fix pose estimator local measurement standard deviation docs (NFC) (#4113)
a2fa5e3ff7 [wpilibc] BatterySim: Provide non-initializer list versions of Calculate (#4076)
a3eea9958e [hal] Add link to FRC CAN Spec (NFC) (#4086)
db27331d7b [wpilib] Update DifferentialDrive docs (NFC) (#4085)
fdfb31f164 [dlt] Export boolean[] values (#4082)
f93c3331b3 [wpigui] disable changing directory when initializing on MacOS (#4092)
ab7ac4fbb9 [build] Fix various warnings in cmake builds (#4081)
bc39a1a293 [wpilibc] Fix moved pneumatics objects not destructing properly (#4068)
2668130e70 [wpimath] Remove SwerveDrivePoseEstimator encoder reset warning (#4066)
d27ed3722b [ci] Set actions workflow concurrency (#4060)
dae18308c9 [wpimath] Minor fixes to Rotation2d docs (NFC) (#4055)
d66555e42f [datalogtool] Add datalogtool
9f52d8a3b1 [wpilib] DriverStation: Add DataLog support for modes and joystick data
757ea91932 [wpilib] Add DataLogManager
02a804f1c5 [ntcore] Add DataLog support
9b500df0d9 [wpiutil] Add high speed data logging
5a89575b3a [wpiutil] Import customized LLVM MemoryBuffer
b8c4d7527b [wpiutil] Add MappedFileRegion
ac5d46cfa7 [wpilibc] Fix ProfiledPID SetTolerance default velocity value (#4054)
bc9e96e86f [wpilib] Absolute Encoder API and behavior fixes (#4052)
f88c435dd0 [hal] Add mechanism to cancel all periodic callbacks (#4049)

Change-Id: I49aa5b08abbefc7a045e99e19d48ce2cd8fc4d1b
git-subtree-dir: third_party/allwpilib
git-subtree-split: 83f1860047c86aa3330fcb41caf3b2047e074804
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/upstream_utils/README.md b/upstream_utils/README.md
new file mode 100644
index 0000000..587fc9e
--- /dev/null
+++ b/upstream_utils/README.md
@@ -0,0 +1,67 @@
+# Upstream utils
+
+## Layout
+
+Each thirdparty library has a Python script for updating it. They generally:
+
+1. Check out a thirdparty Git repository to a specific commit or tag
+2. Apply patch files to the thirdparty repo to fix things specific to our build
+3. Copy a subset of the thirdparty files into our repo
+4. Comment out any header includes that were invalidated, if needed
+
+`upstream_utils.py` contains utilities common to these update scripts.
+
+Patches are generated in the thirdparty repo with
+`git format-patch --no-signature` so they can be applied as individual commits
+and easily rebased onto newer versions. Each library has its own patch directory
+(e.g., `lib_patches`).
+
+## Updating thirdparty library version
+
+The example below will update a hypothetical library called `lib` to the tag
+`2.0`.
+
+Start in the `upstream_utils` folder. Restore the original repo.
+```bash
+./update_lib.py
+```
+
+Navigate to the repo.
+```bash
+cd /tmp/lib
+```
+
+Fetch the desired version using one of the following methods.
+```bash
+# Fetch a full branch or tag
+git fetch origin 2.0
+
+# Fetch just a tag (useful for expensive-to-clone repos)
+git fetch --depth 1 origin tag 2.0
+```
+
+Rebase any patches onto the new version.
+```bash
+git rebase 2.0
+```
+
+Generate patch files for the new version.
+```bash
+git format-patch 2.0..HEAD
+```
+
+Move the patch files to `upstream_utils`.
+```
+mv *.patch allwpilib/upstream_utils/lib_patches
+```
+
+Navigate back to `upstream_utils`
+```bash
+cd allwpilib/upstream_utils
+```
+
+Modify the version number in the call to `setup_upstream_repo()` in
+`update_lib.py`, then  rerun `update_lib.py` to reimport the thirdparty files.
+```bash
+./update_lib.py
+```
diff --git a/upstream_utils/drake-replace-dense-with-core.patch b/upstream_utils/drake-replace-dense-with-core.patch
deleted file mode 100644
index d225597..0000000
--- a/upstream_utils/drake-replace-dense-with-core.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-diff --git b/wpimath/src/main/native/include/drake/common/is_approx_equal_abstol.h a/wpimath/src/main/native/include/drake/common/is_approx_equal_abstol.h
-index 9af0c4525..b3f369ca0 100644
---- b/wpimath/src/main/native/include/drake/common/is_approx_equal_abstol.h
-+++ a/wpimath/src/main/native/include/drake/common/is_approx_equal_abstol.h
-@@ -2,7 +2,7 @@
- 
- #include <vector>
- 
--#include <Eigen/Dense>
-+#include <Eigen/Core>
- 
- namespace drake {
- 
-diff --git a/wpimath/src/main/native/cpp/drake/math/discrete_algebraic_riccati_equation.cpp b/wpimath/src/main/native/cpp/drake/math/discrete_algebraic_riccati_equation.cpp
-index 9585c4dae..49c2fefe7 100644
---- a/wpimath/src/main/native/cpp/drake/math/discrete_algebraic_riccati_equation.cpp
-+++ b/wpimath/src/main/native/cpp/drake/math/discrete_algebraic_riccati_equation.cpp
-@@ -1,5 +1,8 @@
- #include "drake/math/discrete_algebraic_riccati_equation.h"
- 
-+#include <Eigen/Eigenvalues>
-+#include <Eigen/QR>
-+
- #include "drake/common/drake_assert.h"
- #include "drake/common/drake_throw.h"
- #include "drake/common/is_approx_equal_abstol.h"
-diff --git b/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h a/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h
-index b64bfe75e..fc5efb313 100644
---- b/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h
-+++ a/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h
-@@ -3,7 +3,7 @@
- #include <cmath>
- #include <cstdlib>
- 
--#include <Eigen/Dense>
-+#include <Eigen/Core>
- 
- namespace drake {
- namespace math {
- 
-diff --git b/wpimath/src/test/native/cpp/drake/discrete_algebraic_riccati_equation_test.cpp a/wpimath/src/test/native/cpp/drake/discrete_algebraic_riccati_equation_test.cpp
-index 74aa4b23d..2deb039a0 100644
---- b/wpimath/src/test/native/cpp/drake/discrete_algebraic_riccati_equation_test.cpp
-+++ a/wpimath/src/test/native/cpp/drake/discrete_algebraic_riccati_equation_test.cpp
-@@ -1,5 +1,6 @@
- #include "drake/math/discrete_algebraic_riccati_equation.h"
- 
-+#include <Eigen/Eigenvalues>
- #include <gtest/gtest.h>
- 
- #include "drake/common/test_utilities/eigen_matrix_compare.h"
-diff --git b/wpimath/src/test/native/include/drake/common/test_utilities/eigen_matrix_compare.h a/wpimath/src/test/native/include/drake/common/test_utilities/eigen_matrix_compare.h
-index e3bd85349..d6bcbb8ec 100644
---- b/wpimath/src/test/native/include/drake/common/test_utilities/eigen_matrix_compare.h
-+++ a/wpimath/src/test/native/include/drake/common/test_utilities/eigen_matrix_compare.h
-@@ -4,7 +4,7 @@
- #include <cmath>
- #include <limits>
- 
--#include <Eigen/Dense>
-+#include <Eigen/Core>
- #include <gtest/gtest.h>
- 
- // #include "drake/common/text_logging.h"
diff --git a/upstream_utils/drake_patches/0001-Replace-Eigen-Dense-with-Eigen-Core.patch b/upstream_utils/drake_patches/0001-Replace-Eigen-Dense-with-Eigen-Core.patch
new file mode 100644
index 0000000..dcd2e8f
--- /dev/null
+++ b/upstream_utils/drake_patches/0001-Replace-Eigen-Dense-with-Eigen-Core.patch
@@ -0,0 +1,76 @@
+From 02d023c7cdfdfb72ccdbccbac0883b4a1f6ec6d5 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Wed, 18 May 2022 11:13:21 -0700
+Subject: [PATCH 1/2] Replace <Eigen/Dense> with <Eigen/Core>
+
+---
+ common/is_approx_equal_abstol.h                       | 2 +-
+ common/test_utilities/eigen_matrix_compare.h          | 2 +-
+ math/discrete_algebraic_riccati_equation.cc           | 3 +++
+ math/discrete_algebraic_riccati_equation.h            | 2 +-
+ math/test/discrete_algebraic_riccati_equation_test.cc | 1 +
+ 5 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/common/is_approx_equal_abstol.h b/common/is_approx_equal_abstol.h
+index 9af0c45..b3f369c 100644
+--- a/common/is_approx_equal_abstol.h
++++ b/common/is_approx_equal_abstol.h
+@@ -2,7 +2,7 @@
+ 
+ #include <vector>
+ 
+-#include <Eigen/Dense>
++#include <Eigen/Core>
+ 
+ namespace drake {
+ 
+diff --git a/common/test_utilities/eigen_matrix_compare.h b/common/test_utilities/eigen_matrix_compare.h
+index a595da9..c22567d 100644
+--- a/common/test_utilities/eigen_matrix_compare.h
++++ b/common/test_utilities/eigen_matrix_compare.h
+@@ -4,7 +4,7 @@
+ #include <cmath>
+ #include <limits>
+ 
+-#include <Eigen/Dense>
++#include <Eigen/Core>
+ #include <gtest/gtest.h>
+ 
+ #include "drake/common/text_logging.h"
+diff --git a/math/discrete_algebraic_riccati_equation.cc b/math/discrete_algebraic_riccati_equation.cc
+index 901f2ef..20ea2b7 100644
+--- a/math/discrete_algebraic_riccati_equation.cc
++++ b/math/discrete_algebraic_riccati_equation.cc
+@@ -1,5 +1,8 @@
+ #include "drake/math/discrete_algebraic_riccati_equation.h"
+ 
++#include <Eigen/Eigenvalues>
++#include <Eigen/QR>
++
+ #include "drake/common/drake_assert.h"
+ #include "drake/common/drake_throw.h"
+ #include "drake/common/is_approx_equal_abstol.h"
+diff --git a/math/discrete_algebraic_riccati_equation.h b/math/discrete_algebraic_riccati_equation.h
+index 891373f..df7a58b 100644
+--- a/math/discrete_algebraic_riccati_equation.h
++++ b/math/discrete_algebraic_riccati_equation.h
+@@ -3,7 +3,7 @@
+ #include <cmath>
+ #include <cstdlib>
+ 
+-#include <Eigen/Dense>
++#include <Eigen/Core>
+ 
+ namespace drake {
+ namespace math {
+diff --git a/math/test/discrete_algebraic_riccati_equation_test.cc b/math/test/discrete_algebraic_riccati_equation_test.cc
+index 533ced1..e4ecfd2 100644
+--- a/math/test/discrete_algebraic_riccati_equation_test.cc
++++ b/math/test/discrete_algebraic_riccati_equation_test.cc
+@@ -1,5 +1,6 @@
+ #include "drake/math/discrete_algebraic_riccati_equation.h"
+ 
++#include <Eigen/Eigenvalues>
+ #include <gtest/gtest.h>
+ 
+ #include "drake/common/test_utilities/eigen_matrix_compare.h"
diff --git a/upstream_utils/drake-dllexport-dare.patch b/upstream_utils/drake_patches/0002-Add-WPILIB_DLLEXPORT-to-DARE-function-declarations.patch
similarity index 61%
rename from upstream_utils/drake-dllexport-dare.patch
rename to upstream_utils/drake_patches/0002-Add-WPILIB_DLLEXPORT-to-DARE-function-declarations.patch
index a37dacd..1c7b469 100644
--- a/upstream_utils/drake-dllexport-dare.patch
+++ b/upstream_utils/drake_patches/0002-Add-WPILIB_DLLEXPORT-to-DARE-function-declarations.patch
@@ -1,7 +1,16 @@
-diff --git b/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h a/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h
-index df7a58b2b..55b8442bf 100644
---- b/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h
-+++ a/wpimath/src/main/native/include/drake/math/discrete_algebraic_riccati_equation.h
+From b208372a18b37f6cbc49dd45d15adf63c9b60755 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Wed, 18 May 2022 11:15:27 -0700
+Subject: [PATCH 2/2] Add WPILIB_DLLEXPORT to DARE function declarations
+
+---
+ math/discrete_algebraic_riccati_equation.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/math/discrete_algebraic_riccati_equation.h b/math/discrete_algebraic_riccati_equation.h
+index df7a58b..55b8442 100644
+--- a/math/discrete_algebraic_riccati_equation.h
++++ b/math/discrete_algebraic_riccati_equation.h
 @@ -4,6 +4,7 @@
  #include <cstdlib>
  
diff --git a/upstream_utils/eigen-maybe-uninitialized.patch b/upstream_utils/eigen-maybe-uninitialized.patch
deleted file mode 100644
index 27144de..0000000
--- a/upstream_utils/eigen-maybe-uninitialized.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/wpimath/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h b/wpimath/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h
-index 74f74cc42..5fe86fa0d 100644
---- a/wpimath/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h
-+++ b/wpimath/src/main/native/eigeninclude/Eigen/src/Core/util/DisableStupidWarnings.h
-@@ -61,6 +61,10 @@
-     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325
-     #pragma GCC diagnostic ignored "-Wattributes"
-   #endif
-+  #if __GNUC__==11
-+    // This warning is a false positive
-+    #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-+  #endif
- #endif
- 
- #if defined __NVCC__
diff --git a/upstream_utils/eigen_patches/0001-Disable-warnings.patch b/upstream_utils/eigen_patches/0001-Disable-warnings.patch
new file mode 100644
index 0000000..78a5922
--- /dev/null
+++ b/upstream_utils/eigen_patches/0001-Disable-warnings.patch
@@ -0,0 +1,31 @@
+From 3bfc3d1e3cbc9d7032446cc4aa6246d1c7750901 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Wed, 18 May 2022 09:14:24 -0700
+Subject: [PATCH] Disable warnings
+
+---
+ Eigen/src/Core/util/DisableStupidWarnings.h | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/Eigen/src/Core/util/DisableStupidWarnings.h b/Eigen/src/Core/util/DisableStupidWarnings.h
+index fe0cfec..d973255 100755
+--- a/Eigen/src/Core/util/DisableStupidWarnings.h
++++ b/Eigen/src/Core/util/DisableStupidWarnings.h
+@@ -71,6 +71,17 @@
+     // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325
+     #pragma GCC diagnostic ignored "-Wattributes"
+   #endif
++  #if __GNUC__>=8
++    #pragma GCC diagnostic ignored "-Wclass-memaccess"
++  #endif
++  #if __GNUC__>=11
++    // This warning is a false positive
++    #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
++  #endif
++  #if __GNUC__==12
++    // This warning is a false positive
++    #pragma GCC diagnostic ignored "-Warray-bounds"
++  #endif
+ #endif
+ 
+ #if defined __NVCC__
diff --git a/upstream_utils/fmt-dont-throw-on-write-failure.patch b/upstream_utils/fmt-dont-throw-on-write-failure.patch
deleted file mode 100644
index 6be3639..0000000
--- a/upstream_utils/fmt-dont-throw-on-write-failure.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-diff --git a/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h b/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
-index 2c51c50ae..cc89abdd3 100644
---- a/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
-+++ b/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
-@@ -92,8 +92,7 @@ FMT_FUNC void report_error(format_func func, int error_code,
- // A wrapper around fwrite that throws on error.
- inline void fwrite_fully(const void* ptr, size_t size, size_t count,
-                          FILE* stream) {
--  size_t written = std::fwrite(ptr, size, count, stream);
--  if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
-+  std::fwrite(ptr, size, count, stream);
- }
- 
- #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
-diff --git a/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h b/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
-index 55825077f..9acb893fa 100644
---- a/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
-+++ b/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
-@@ -207,8 +207,7 @@ inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
-   wmemory_buffer buffer;
-   detail::vformat_to(buffer, fmt, args);
-   buffer.push_back(L'\0');
--  if (std::fputws(buffer.data(), f) == -1)
--    FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
-+  std::fputws(buffer.data(), f);
- }
- 
- inline void vprint(wstring_view fmt, wformat_args args) {
-diff --git a/wpiutil/src/main/native/fmtlib/src/os.cpp b/wpiutil/src/main/native/fmtlib/src/os.cpp
-index 04b4dc506..4eb3e1fdd 100644
---- a/wpiutil/src/main/native/fmtlib/src/os.cpp
-+++ b/wpiutil/src/main/native/fmtlib/src/os.cpp
-@@ -277,8 +277,7 @@ std::size_t file::read(void* buffer, std::size_t count) {
- std::size_t file::write(const void* buffer, std::size_t count) {
-   rwresult result = 0;
-   FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
--  if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
--  return detail::to_unsigned(result);
-+  return count;
- }
- 
- file file::dup(int fd) {
diff --git a/upstream_utils/fmt_patches/0001-Don-t-throw-on-write-failure.patch b/upstream_utils/fmt_patches/0001-Don-t-throw-on-write-failure.patch
new file mode 100644
index 0000000..edaf575
--- /dev/null
+++ b/upstream_utils/fmt_patches/0001-Don-t-throw-on-write-failure.patch
@@ -0,0 +1,54 @@
+From e685209746aabbbed0a9db54694b8ea1ca504163 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Wed, 18 May 2022 10:21:49 -0700
+Subject: [PATCH 1/2] Don't throw on write failure
+
+---
+ include/fmt/format-inl.h | 4 +---
+ include/fmt/xchar.h      | 3 +--
+ src/os.cc                | 3 +--
+ 3 files changed, 3 insertions(+), 7 deletions(-)
+
+diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h
+index 22b1ec8..abe4ff1 100644
+--- a/include/fmt/format-inl.h
++++ b/include/fmt/format-inl.h
+@@ -79,9 +79,7 @@ FMT_FUNC void report_error(format_func func, int error_code,
+ // A wrapper around fwrite that throws on error.
+ inline void fwrite_fully(const void* ptr, size_t size, size_t count,
+                          FILE* stream) {
+-  size_t written = std::fwrite(ptr, size, count, stream);
+-  if (written < count)
+-    FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
++  std::fwrite(ptr, size, count, stream);
+ }
+ 
+ #ifndef FMT_STATIC_THOUSANDS_SEPARATOR
+diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h
+index 3b5bc15..fc3c67f 100644
+--- a/include/fmt/xchar.h
++++ b/include/fmt/xchar.h
+@@ -200,8 +200,7 @@ inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
+   wmemory_buffer buffer;
+   detail::vformat_to(buffer, fmt, args);
+   buffer.push_back(L'\0');
+-  if (std::fputws(buffer.data(), f) == -1)
+-    FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
++  std::fputws(buffer.data(), f);
+ }
+ 
+ inline void vprint(wstring_view fmt, wformat_args args) {
+diff --git a/src/os.cc b/src/os.cc
+index f388ead..2c49951 100644
+--- a/src/os.cc
++++ b/src/os.cc
+@@ -277,8 +277,7 @@ std::size_t file::read(void* buffer, std::size_t count) {
+ std::size_t file::write(const void* buffer, std::size_t count) {
+   rwresult result = 0;
+   FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
+-  if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
+-  return detail::to_unsigned(result);
++  return count;
+ }
+ 
+ file file::dup(int fd) {
diff --git a/upstream_utils/fmt_patches/0002-Suppress-C-20-clang-tidy-warning-false-positive.patch b/upstream_utils/fmt_patches/0002-Suppress-C-20-clang-tidy-warning-false-positive.patch
new file mode 100644
index 0000000..7e25fc0
--- /dev/null
+++ b/upstream_utils/fmt_patches/0002-Suppress-C-20-clang-tidy-warning-false-positive.patch
@@ -0,0 +1,22 @@
+From 1d8e07241d380d13383a6ff479f3895ef49ce514 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Fri, 2 Sep 2022 15:12:54 -0700
+Subject: [PATCH 2/2] Suppress C++20 clang-tidy warning false positive
+
+---
+ include/fmt/core.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/fmt/core.h b/include/fmt/core.h
+index f6a37af..5c210bc 100644
+--- a/include/fmt/core.h
++++ b/include/fmt/core.h
+@@ -2952,7 +2952,7 @@ class format_string_checker {
+       basic_string_view<Char> format_str, ErrorHandler eh)
+       : context_(format_str, num_args, types_, eh),
+         parse_funcs_{&parse_format_specs<Args, parse_context_type>...},
+-        types_{
++        types_{  // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
+             mapped_type_constant<Args,
+                                  basic_format_context<Char*, Char>>::value...} {
+   }
diff --git a/upstream_utils/libuv_patches/0001-Fix-missing-casts.patch b/upstream_utils/libuv_patches/0001-Fix-missing-casts.patch
new file mode 100644
index 0000000..6965d0d
--- /dev/null
+++ b/upstream_utils/libuv_patches/0001-Fix-missing-casts.patch
@@ -0,0 +1,1533 @@
+From d5613423f057b088f6b3753f49162947d5559ad9 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 26 Apr 2022 15:01:25 -0400
+Subject: [PATCH 1/9] Fix missing casts
+
+---
+ include/uv/unix.h              |  2 +-
+ src/fs-poll.c                  | 10 ++++-----
+ src/inet.c                     | 11 +++++-----
+ src/strscpy.c                  |  2 +-
+ src/threadpool.c               |  2 +-
+ src/unix/bsd-ifaddrs.c         |  2 +-
+ src/unix/core.c                | 12 +++++-----
+ src/unix/darwin-proctitle.c    |  5 +++--
+ src/unix/darwin.c              |  2 +-
+ src/unix/epoll.c               |  2 +-
+ src/unix/freebsd.c             |  4 ++--
+ src/unix/fs.c                  | 20 ++++++++---------
+ src/unix/fsevents.c            | 40 +++++++++++++++++-----------------
+ src/unix/getaddrinfo.c         |  8 +++----
+ src/unix/ibmi.c                |  2 +-
+ src/unix/kqueue.c              |  6 ++---
+ src/unix/linux-core.c          |  5 ++---
+ src/unix/linux-inotify.c       |  4 ++--
+ src/unix/loop.c                |  2 +-
+ src/unix/netbsd.c              |  4 ++--
+ src/unix/openbsd.c             |  4 ++--
+ src/unix/pipe.c                |  4 ++--
+ src/unix/poll.c                |  2 +-
+ src/unix/posix-poll.c          |  2 +-
+ src/unix/process.c             |  4 ++--
+ src/unix/proctitle.c           |  2 +-
+ src/unix/random-sysctl-linux.c |  2 +-
+ src/unix/stream.c              | 35 ++++++++++++++---------------
+ src/unix/thread.c              |  7 +++---
+ src/unix/udp.c                 |  8 +++----
+ src/uv-common.c                | 16 +++++++-------
+ src/win/core.c                 |  8 ++++---
+ src/win/fs-event.c             |  4 ++--
+ src/win/fs-fd-hash-inl.h       |  2 +-
+ src/win/fs.c                   | 26 +++++++++++-----------
+ src/win/pipe.c                 | 10 ++++-----
+ src/win/process.c              | 12 +++++-----
+ src/win/tcp.c                  |  2 +-
+ src/win/thread.c               |  4 ++--
+ src/win/util.c                 | 29 ++++++++++++------------
+ 40 files changed, 166 insertions(+), 162 deletions(-)
+
+diff --git a/include/uv/unix.h b/include/uv/unix.h
+index ea37d787..420be86c 100644
+--- a/include/uv/unix.h
++++ b/include/uv/unix.h
+@@ -223,7 +223,7 @@ typedef struct {
+   int backend_fd;                                                             \
+   void* pending_queue[2];                                                     \
+   void* watcher_queue[2];                                                     \
+-  uv__io_t** watchers;                                                        \
++  void** watchers;                                                            \
+   unsigned int nwatchers;                                                     \
+   unsigned int nfds;                                                          \
+   void* wq[2];                                                                \
+diff --git a/src/fs-poll.c b/src/fs-poll.c
+index 1bac1c56..5a39daed 100644
+--- a/src/fs-poll.c
++++ b/src/fs-poll.c
+@@ -77,7 +77,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
+ 
+   loop = handle->loop;
+   len = strlen(path);
+-  ctx = uv__calloc(1, sizeof(*ctx) + len);
++  ctx = (struct poll_ctx*)uv__calloc(1, sizeof(*ctx) + len);
+ 
+   if (ctx == NULL)
+     return UV_ENOMEM;
+@@ -101,7 +101,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
+     goto error;
+ 
+   if (handle->poll_ctx != NULL)
+-    ctx->previous = handle->poll_ctx;
++    ctx->previous = (struct poll_ctx*)handle->poll_ctx;
+   handle->poll_ctx = ctx;
+   uv__handle_start(handle);
+ 
+@@ -119,7 +119,7 @@ int uv_fs_poll_stop(uv_fs_poll_t* handle) {
+   if (!uv_is_active((uv_handle_t*)handle))
+     return 0;
+ 
+-  ctx = handle->poll_ctx;
++  ctx = (struct poll_ctx*)handle->poll_ctx;
+   assert(ctx != NULL);
+   assert(ctx->parent_handle == handle);
+ 
+@@ -144,7 +144,7 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
+     return UV_EINVAL;
+   }
+ 
+-  ctx = handle->poll_ctx;
++  ctx = (struct poll_ctx*)handle->poll_ctx;
+   assert(ctx != NULL);
+ 
+   required_len = strlen(ctx->path);
+@@ -244,7 +244,7 @@ static void timer_close_cb(uv_handle_t* timer) {
+     if (handle->poll_ctx == NULL && uv__is_closing(handle))
+       uv__make_close_pending((uv_handle_t*)handle);
+   } else {
+-    for (last = handle->poll_ctx, it = last->previous;
++    for (last = (struct poll_ctx*)handle->poll_ctx, it = last->previous;
+          it != ctx;
+          last = it, it = it->previous) {
+       assert(last->previous != NULL);
+diff --git a/src/inet.c b/src/inet.c
+index ddabf22f..ca8b6ac8 100644
+--- a/src/inet.c
++++ b/src/inet.c
+@@ -40,9 +40,9 @@ static int inet_pton6(const char *src, unsigned char *dst);
+ int uv_inet_ntop(int af, const void* src, char* dst, size_t size) {
+   switch (af) {
+   case AF_INET:
+-    return (inet_ntop4(src, dst, size));
++    return (inet_ntop4((const unsigned char*)src, dst, size));
+   case AF_INET6:
+-    return (inet_ntop6(src, dst, size));
++    return (inet_ntop6((const unsigned char*)src, dst, size));
+   default:
+     return UV_EAFNOSUPPORT;
+   }
+@@ -154,10 +154,11 @@ int uv_inet_pton(int af, const char* src, void* dst) {
+ 
+   switch (af) {
+   case AF_INET:
+-    return (inet_pton4(src, dst));
++    return (inet_pton4(src, (unsigned char*)dst));
+   case AF_INET6: {
+     int len;
+-    char tmp[UV__INET6_ADDRSTRLEN], *s, *p;
++    char tmp[UV__INET6_ADDRSTRLEN], *s;
++    const char *p;
+     s = (char*) src;
+     p = strchr(src, '%');
+     if (p != NULL) {
+@@ -168,7 +169,7 @@ int uv_inet_pton(int af, const char* src, void* dst) {
+       memcpy(s, src, len);
+       s[len] = '\0';
+     }
+-    return inet_pton6(s, dst);
++    return inet_pton6(s, (unsigned char*)dst);
+   }
+   default:
+     return UV_EAFNOSUPPORT;
+diff --git a/src/strscpy.c b/src/strscpy.c
+index 20df6fcb..6b4cc3bc 100644
+--- a/src/strscpy.c
++++ b/src/strscpy.c
+@@ -27,7 +27,7 @@ ssize_t uv__strscpy(char* d, const char* s, size_t n) {
+ 
+   for (i = 0; i < n; i++)
+     if ('\0' == (d[i] = s[i]))
+-      return i > SSIZE_MAX ? UV_E2BIG : (ssize_t) i;
++      return i > SSIZE_MAX ? (ssize_t) UV_E2BIG : (ssize_t) i;
+ 
+   if (i == 0)
+     return 0;
+diff --git a/src/threadpool.c b/src/threadpool.c
+index e804c7c4..1241ace1 100644
+--- a/src/threadpool.c
++++ b/src/threadpool.c
+@@ -206,7 +206,7 @@ static void init_threads(void) {
+ 
+   threads = default_threads;
+   if (nthreads > ARRAY_SIZE(default_threads)) {
+-    threads = uv__malloc(nthreads * sizeof(threads[0]));
++    threads = (uv_thread_t*)uv__malloc(nthreads * sizeof(threads[0]));
+     if (threads == NULL) {
+       nthreads = ARRAY_SIZE(default_threads);
+       threads = default_threads;
+diff --git a/src/unix/bsd-ifaddrs.c b/src/unix/bsd-ifaddrs.c
+index 11ca9559..c3dd71a1 100644
+--- a/src/unix/bsd-ifaddrs.c
++++ b/src/unix/bsd-ifaddrs.c
+@@ -92,7 +92,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+   }
+ 
+   /* Make sure the memory is initiallized to zero using calloc() */
+-  *addresses = uv__calloc(*count, sizeof(**addresses));
++  *addresses = (uv_interface_address_t*)uv__calloc(*count, sizeof(**addresses));
+ 
+   if (*addresses == NULL) {
+     freeifaddrs(addrs);
+diff --git a/src/unix/core.c b/src/unix/core.c
+index 54c769f3..6353b0e3 100644
+--- a/src/unix/core.c
++++ b/src/unix/core.c
+@@ -824,7 +824,7 @@ static unsigned int next_power_of_two(unsigned int val) {
+ }
+ 
+ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
+-  uv__io_t** watchers;
++  void** watchers;
+   void* fake_watcher_list;
+   void* fake_watcher_count;
+   unsigned int nwatchers;
+@@ -843,8 +843,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
+   }
+ 
+   nwatchers = next_power_of_two(len + 2) - 2;
+-  watchers = uv__reallocf(loop->watchers,
+-                          (nwatchers + 2) * sizeof(loop->watchers[0]));
++  watchers = (void**)
++      uv__reallocf(loop->watchers, (nwatchers + 2) * sizeof(loop->watchers[0]));
+ 
+   if (watchers == NULL)
+     abort();
+@@ -1184,7 +1184,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
+    * is frequently 1024 or 4096, so we can just use that directly. The pwent
+    * will not usually be large. */
+   for (bufsize = 2000;; bufsize *= 2) {
+-    buf = uv__malloc(bufsize);
++    buf = (char*)uv__malloc(bufsize);
+ 
+     if (buf == NULL)
+       return UV_ENOMEM;
+@@ -1210,7 +1210,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
+   name_size = strlen(pw.pw_name) + 1;
+   homedir_size = strlen(pw.pw_dir) + 1;
+   shell_size = strlen(pw.pw_shell) + 1;
+-  pwd->username = uv__malloc(name_size + homedir_size + shell_size);
++  pwd->username = (char*)uv__malloc(name_size + homedir_size + shell_size);
+ 
+   if (pwd->username == NULL) {
+     uv__free(buf);
+@@ -1274,7 +1274,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
+ 
+   for (i = 0; environ[i] != NULL; i++);
+ 
+-  *envitems = uv__calloc(i, sizeof(**envitems));
++  *envitems = (uv_env_item_s*)uv__calloc(i, sizeof(**envitems));
+ 
+   if (*envitems == NULL)
+     return UV_ENOMEM;
+diff --git a/src/unix/darwin-proctitle.c b/src/unix/darwin-proctitle.c
+index 5288083e..9bd55dd7 100644
+--- a/src/unix/darwin-proctitle.c
++++ b/src/unix/darwin-proctitle.c
+@@ -128,8 +128,9 @@ int uv__set_process_title(const char* title) {
+   if (pLSSetApplicationInformationItem == NULL)
+     goto out;
+ 
+-  display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle,
+-                                                    S("_kLSDisplayNameKey"));
++  display_name_key = (CFStringRef*)
++      pCFBundleGetDataPointerForName(launch_services_bundle,
++                                     S("_kLSDisplayNameKey"));
+ 
+   if (display_name_key == NULL || *display_name_key == NULL)
+     goto out;
+diff --git a/src/unix/darwin.c b/src/unix/darwin.c
+index 62f04d31..5fbf7342 100644
+--- a/src/unix/darwin.c
++++ b/src/unix/darwin.c
+@@ -353,7 +353,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+     return UV_EINVAL;  /* FIXME(bnoordhuis) Translate error. */
+   }
+ 
+-  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
++  *cpu_infos = (uv_cpu_info_t*)uv__malloc(numcpus * sizeof(**cpu_infos));
+   if (!(*cpu_infos)) {
+     vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
+     return UV_ENOMEM;
+diff --git a/src/unix/epoll.c b/src/unix/epoll.c
+index 97348e25..4c057fb3 100644
+--- a/src/unix/epoll.c
++++ b/src/unix/epoll.c
+@@ -325,7 +325,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
+       assert(fd >= 0);
+       assert((unsigned) fd < loop->nwatchers);
+ 
+-      w = loop->watchers[fd];
++      w = (uv__io_t*)loop->watchers[fd];
+ 
+       if (w == NULL) {
+         /* File descriptor that we've stopped watching, disarm it.
+diff --git a/src/unix/freebsd.c b/src/unix/freebsd.c
+index 658ff262..6700ff61 100644
+--- a/src/unix/freebsd.c
++++ b/src/unix/freebsd.c
+@@ -215,7 +215,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+   if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
+     return UV__ERR(errno);
+ 
+-  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
++  *cpu_infos = (uv_cpu_info_t*)uv__malloc(numcpus * sizeof(**cpu_infos));
+   if (!(*cpu_infos))
+     return UV_ENOMEM;
+ 
+@@ -232,7 +232,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ 
+   size = maxcpus * CPUSTATES * sizeof(long);
+ 
+-  cp_times = uv__malloc(size);
++  cp_times = (long*)uv__malloc(size);
+   if (cp_times == NULL) {
+     uv__free(*cpu_infos);
+     return UV_ENOMEM;
+diff --git a/src/unix/fs.c b/src/unix/fs.c
+index 933c9c0d..1a615244 100644
+--- a/src/unix/fs.c
++++ b/src/unix/fs.c
+@@ -137,7 +137,7 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
+       size_t new_path_len;                                                    \
+       path_len = strlen(path) + 1;                                            \
+       new_path_len = strlen(new_path) + 1;                                    \
+-      req->path = uv__malloc(path_len + new_path_len);                        \
++      req->path = (char*)uv__malloc(path_len + new_path_len);                 \
+       if (req->path == NULL)                                                  \
+         return UV_ENOMEM;                                                     \
+       req->new_path = req->path + path_len;                                   \
+@@ -572,7 +572,7 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) {
+ static int uv__fs_opendir(uv_fs_t* req) {
+   uv_dir_t* dir;
+ 
+-  dir = uv__malloc(sizeof(*dir));
++  dir = (uv_dir_t*)uv__malloc(sizeof(*dir));
+   if (dir == NULL)
+     goto error;
+ 
+@@ -596,7 +596,7 @@ static int uv__fs_readdir(uv_fs_t* req) {
+   unsigned int dirent_idx;
+   unsigned int i;
+ 
+-  dir = req->ptr;
++  dir = (uv_dir_t*)req->ptr;
+   dirent_idx = 0;
+ 
+   while (dirent_idx < dir->nentries) {
+@@ -638,7 +638,7 @@ error:
+ static int uv__fs_closedir(uv_fs_t* req) {
+   uv_dir_t* dir;
+ 
+-  dir = req->ptr;
++  dir = (uv_dir_t*)req->ptr;
+ 
+   if (dir->dir != NULL) {
+     closedir(dir->dir);
+@@ -667,7 +667,7 @@ static int uv__fs_statfs(uv_fs_t* req) {
+ #endif /* defined(__sun) */
+     return -1;
+ 
+-  stat_fs = uv__malloc(sizeof(*stat_fs));
++  stat_fs = (uv_statfs_t*)uv__malloc(sizeof(*stat_fs));
+   if (stat_fs == NULL) {
+     errno = ENOMEM;
+     return -1;
+@@ -731,7 +731,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
+     maxlen = uv__fs_pathmax_size(req->path);
+ #endif
+ 
+-  buf = uv__malloc(maxlen);
++  buf = (char*)uv__malloc(maxlen);
+ 
+   if (buf == NULL) {
+     errno = ENOMEM;
+@@ -751,7 +751,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
+ 
+   /* Uncommon case: resize to make room for the trailing nul byte. */
+   if (len == maxlen) {
+-    buf = uv__reallocf(buf, len + 1);
++    buf = (char*)uv__reallocf(buf, len + 1);
+ 
+     if (buf == NULL)
+       return -1;
+@@ -774,7 +774,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) {
+   ssize_t len;
+ 
+   len = uv__fs_pathmax_size(req->path);
+-  buf = uv__malloc(len + 1);
++  buf = (char*)uv__malloc(len + 1);
+ 
+   if (buf == NULL) {
+     errno = ENOMEM;
+@@ -2010,7 +2010,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
+   req->nbufs = nbufs;
+   req->bufs = req->bufsml;
+   if (nbufs > ARRAY_SIZE(req->bufsml))
+-    req->bufs = uv__malloc(nbufs * sizeof(*bufs));
++    req->bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(*bufs));
+ 
+   if (req->bufs == NULL)
+     return UV_ENOMEM;
+@@ -2180,7 +2180,7 @@ int uv_fs_write(uv_loop_t* loop,
+   req->nbufs = nbufs;
+   req->bufs = req->bufsml;
+   if (nbufs > ARRAY_SIZE(req->bufsml))
+-    req->bufs = uv__malloc(nbufs * sizeof(*bufs));
++    req->bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(*bufs));
+ 
+   if (req->bufs == NULL)
+     return UV_ENOMEM;
+diff --git a/src/unix/fsevents.c b/src/unix/fsevents.c
+index bf4f1f6a..648c8a98 100644
+--- a/src/unix/fsevents.c
++++ b/src/unix/fsevents.c
+@@ -185,7 +185,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef);
+ static void uv__fsevents_cb(uv_async_t* cb) {
+   uv_fs_event_t* handle;
+ 
+-  handle = cb->data;
++  handle = (uv_fs_event_t*)cb->data;
+ 
+   UV__FSEVENTS_PROCESS(handle, {
+     handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0);
+@@ -233,10 +233,10 @@ static void uv__fsevents_event_cb(const FSEventStreamRef streamRef,
+   FSEventStreamEventFlags flags;
+   QUEUE head;
+ 
+-  loop = info;
+-  state = loop->cf_state;
++  loop = (uv_loop_t*)info;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+   assert(state != NULL);
+-  paths = eventPaths;
++  paths = (char**)eventPaths;
+ 
+   /* For each handle */
+   uv_mutex_lock(&state->fsevent_mutex);
+@@ -306,7 +306,7 @@ static void uv__fsevents_event_cb(const FSEventStreamRef streamRef,
+           continue;
+       }
+ 
+-      event = uv__malloc(sizeof(*event) + len);
++      event = (uv__fsevents_event_t*)uv__malloc(sizeof(*event) + len);
+       if (event == NULL)
+         break;
+ 
+@@ -373,7 +373,7 @@ static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
+                              flags);
+   assert(ref != NULL);
+ 
+-  state = loop->cf_state;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+   pFSEventStreamScheduleWithRunLoop(ref,
+                                     state->loop,
+                                     *pkCFRunLoopDefaultMode);
+@@ -392,7 +392,7 @@ static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
+ static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
+   uv__cf_loop_state_t* state;
+ 
+-  state = loop->cf_state;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+ 
+   if (state->fsevent_stream == NULL)
+     return;
+@@ -419,7 +419,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle,
+   int err;
+   unsigned int path_count;
+ 
+-  state = handle->loop->cf_state;
++  state = (uv__cf_loop_state_t*)handle->loop->cf_state;
+   paths = NULL;
+   cf_paths = NULL;
+   err = 0;
+@@ -447,7 +447,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle,
+   uv_mutex_lock(&state->fsevent_mutex);
+   path_count = state->fsevent_handle_count;
+   if (path_count != 0) {
+-    paths = uv__malloc(sizeof(*paths) * path_count);
++    paths = (CFStringRef*)uv__malloc(sizeof(*paths) * path_count);
+     if (paths == NULL) {
+       uv_mutex_unlock(&state->fsevent_mutex);
+       goto final;
+@@ -605,7 +605,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
+   if (err)
+     return err;
+ 
+-  state = uv__calloc(1, sizeof(*state));
++  state = (uv__cf_loop_state_t*)uv__calloc(1, sizeof(*state));
+   if (state == NULL)
+     return UV_ENOMEM;
+ 
+@@ -707,7 +707,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
+   }
+ 
+   /* Destroy state */
+-  state = loop->cf_state;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+   uv_sem_destroy(&state->fsevent_sem);
+   uv_mutex_destroy(&state->fsevent_mutex);
+   pCFRelease(state->signal_source);
+@@ -721,8 +721,8 @@ static void* uv__cf_loop_runner(void* arg) {
+   uv_loop_t* loop;
+   uv__cf_loop_state_t* state;
+ 
+-  loop = arg;
+-  state = loop->cf_state;
++  loop = (uv_loop_t*)arg;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+   state->loop = pCFRunLoopGetCurrent();
+ 
+   pCFRunLoopAddSource(state->loop,
+@@ -750,8 +750,8 @@ static void uv__cf_loop_cb(void* arg) {
+   QUEUE split_head;
+   uv__cf_loop_signal_t* s;
+ 
+-  loop = arg;
+-  state = loop->cf_state;
++  loop = (uv_loop_t*)arg;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+ 
+   uv_mutex_lock(&loop->cf_mutex);
+   QUEUE_MOVE(&loop->cf_signals, &split_head);
+@@ -781,7 +781,7 @@ int uv__cf_loop_signal(uv_loop_t* loop,
+   uv__cf_loop_signal_t* item;
+   uv__cf_loop_state_t* state;
+ 
+-  item = uv__malloc(sizeof(*item));
++  item = (uv__cf_loop_signal_t*)uv__malloc(sizeof(*item));
+   if (item == NULL)
+     return UV_ENOMEM;
+ 
+@@ -791,7 +791,7 @@ int uv__cf_loop_signal(uv_loop_t* loop,
+   uv_mutex_lock(&loop->cf_mutex);
+   QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
+ 
+-  state = loop->cf_state;
++  state = (uv__cf_loop_state_t*)loop->cf_state;
+   assert(state != NULL);
+   pCFRunLoopSourceSignal(state->signal_source);
+   pCFRunLoopWakeUp(state->loop);
+@@ -825,7 +825,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
+    * Events will occur in other thread.
+    * Initialize callback for getting them back into event loop's thread
+    */
+-  handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb));
++  handle->cf_cb = (uv_async_t*)uv__malloc(sizeof(*handle->cf_cb));
+   if (handle->cf_cb == NULL) {
+     err = UV_ENOMEM;
+     goto fail_cf_cb_malloc;
+@@ -841,7 +841,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
+     goto fail_cf_mutex_init;
+ 
+   /* Insert handle into the list */
+-  state = handle->loop->cf_state;
++  state = (uv__cf_loop_state_t*)handle->loop->cf_state;
+   uv_mutex_lock(&state->fsevent_mutex);
+   QUEUE_INSERT_TAIL(&state->fsevent_handles, &handle->cf_member);
+   state->fsevent_handle_count++;
+@@ -881,7 +881,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
+     return UV_EINVAL;
+ 
+   /* Remove handle from  the list */
+-  state = handle->loop->cf_state;
++  state = (uv__cf_loop_state_t*)handle->loop->cf_state;
+   uv_mutex_lock(&state->fsevent_mutex);
+   QUEUE_REMOVE(&handle->cf_member);
+   state->fsevent_handle_count--;
+diff --git a/src/unix/getaddrinfo.c b/src/unix/getaddrinfo.c
+index 77337ace..41dc3909 100644
+--- a/src/unix/getaddrinfo.c
++++ b/src/unix/getaddrinfo.c
+@@ -172,7 +172,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
+   hostname_len = hostname ? strlen(hostname) + 1 : 0;
+   service_len = service ? strlen(service) + 1 : 0;
+   hints_len = hints ? sizeof(*hints) : 0;
+-  buf = uv__malloc(hostname_len + service_len + hints_len);
++  buf = (char*)uv__malloc(hostname_len + service_len + hints_len);
+ 
+   if (buf == NULL)
+     return UV_ENOMEM;
+@@ -190,17 +190,17 @@ int uv_getaddrinfo(uv_loop_t* loop,
+   len = 0;
+ 
+   if (hints) {
+-    req->hints = memcpy(buf + len, hints, sizeof(*hints));
++    req->hints = (struct addrinfo*)memcpy(buf + len, hints, sizeof(*hints));
+     len += sizeof(*hints);
+   }
+ 
+   if (service) {
+-    req->service = memcpy(buf + len, service, service_len);
++    req->service = (char*)memcpy(buf + len, service, service_len);
+     len += service_len;
+   }
+ 
+   if (hostname)
+-    req->hostname = memcpy(buf + len, hostname, hostname_len);
++    req->hostname = (char*)memcpy(buf + len, hostname, hostname_len);
+ 
+   if (cb) {
+     uv__work_submit(loop,
+diff --git a/src/unix/ibmi.c b/src/unix/ibmi.c
+index 8c6ae636..56af31e9 100644
+--- a/src/unix/ibmi.c
++++ b/src/unix/ibmi.c
+@@ -288,7 +288,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ 
+   numcpus = sysconf(_SC_NPROCESSORS_ONLN);
+ 
+-  *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t));
++  *cpu_infos = (uv_cpu_info_t*)uv__malloc(numcpus * sizeof(uv_cpu_info_t));
+   if (!*cpu_infos) {
+     return UV_ENOMEM;
+   }
+diff --git a/src/unix/kqueue.c b/src/unix/kqueue.c
+index 5dac76ae..86eb529b 100644
+--- a/src/unix/kqueue.c
++++ b/src/unix/kqueue.c
+@@ -281,8 +281,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
+     nevents = 0;
+ 
+     assert(loop->watchers != NULL);
+-    loop->watchers[loop->nwatchers] = (void*) events;
+-    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
++    loop->watchers[loop->nwatchers] = (uv__io_t*) events;
++    loop->watchers[loop->nwatchers + 1] = (uv__io_t*) (uintptr_t) nfds;
+     for (i = 0; i < nfds; i++) {
+       ev = events + i;
+       fd = ev->ident;
+@@ -304,7 +304,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
+       /* Skip invalidated events, see uv__platform_invalidate_fd */
+       if (fd == -1)
+         continue;
+-      w = loop->watchers[fd];
++      w = (uv__io_t*)loop->watchers[fd];
+ 
+       if (w == NULL) {
+         /* File descriptor that we've stopped watching, disarm it.
+diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c
+index 23a7dafe..85f3fc01 100644
+--- a/src/unix/linux-core.c
++++ b/src/unix/linux-core.c
+@@ -117,7 +117,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
+ }
+ 
+ 
+-
+ uint64_t uv__hrtime(uv_clocktype_t type) {
+   static clock_t fast_clock_id = -1;
+   struct timespec t;
+@@ -283,7 +282,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+     goto out;
+ 
+   err = UV_ENOMEM;
+-  ci = uv__calloc(numcpus, sizeof(*ci));
++  ci = (uv_cpu_info_t*)uv__calloc(numcpus, sizeof(*ci));
+   if (ci == NULL)
+     goto out;
+ 
+@@ -663,7 +662,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+   }
+ 
+   /* Make sure the memory is initiallized to zero using calloc() */
+-  *addresses = uv__calloc(*count, sizeof(**addresses));
++  *addresses = (uv_interface_address_t*)uv__calloc(*count, sizeof(**addresses));
+   if (!(*addresses)) {
+     freeifaddrs(addrs);
+     return UV_ENOMEM;
+diff --git a/src/unix/linux-inotify.c b/src/unix/linux-inotify.c
+index c1bd260e..f5366e96 100644
+--- a/src/unix/linux-inotify.c
++++ b/src/unix/linux-inotify.c
+@@ -281,12 +281,12 @@ int uv_fs_event_start(uv_fs_event_t* handle,
+     goto no_insert;
+ 
+   len = strlen(path) + 1;
+-  w = uv__malloc(sizeof(*w) + len);
++  w = (watcher_list*)uv__malloc(sizeof(*w) + len);
+   if (w == NULL)
+     return UV_ENOMEM;
+ 
+   w->wd = wd;
+-  w->path = memcpy(w + 1, path, len);
++  w->path = (char*)memcpy(w + 1, path, len);
+   QUEUE_INIT(&w->watchers);
+   w->iterating = 0;
+   RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w);
+diff --git a/src/unix/loop.c b/src/unix/loop.c
+index a88e71c3..2e819cdd 100644
+--- a/src/unix/loop.c
++++ b/src/unix/loop.c
+@@ -148,7 +148,7 @@ int uv_loop_fork(uv_loop_t* loop) {
+ 
+   /* Rearm all the watchers that aren't re-queued by the above. */
+   for (i = 0; i < loop->nwatchers; i++) {
+-    w = loop->watchers[i];
++    w = (uv__io_t*)loop->watchers[i];
+     if (w == NULL)
+       continue;
+ 
+diff --git a/src/unix/netbsd.c b/src/unix/netbsd.c
+index c66333f5..b6886a1c 100644
+--- a/src/unix/netbsd.c
++++ b/src/unix/netbsd.c
+@@ -206,14 +206,14 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+     cpuspeed = 0;
+ 
+   size = numcpus * CPUSTATES * sizeof(*cp_times);
+-  cp_times = uv__malloc(size);
++  cp_times = (u_int64_t*)uv__malloc(size);
+   if (cp_times == NULL)
+     return UV_ENOMEM;
+ 
+   if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0))
+     return UV__ERR(errno);
+ 
+-  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
++  *cpu_infos = (uv_cpu_info_t*)uv__malloc(numcpus * sizeof(**cpu_infos));
+   if (!(*cpu_infos)) {
+     uv__free(cp_times);
+     uv__free(*cpu_infos);
+diff --git a/src/unix/openbsd.c b/src/unix/openbsd.c
+index f32a94df..62740f73 100644
+--- a/src/unix/openbsd.c
++++ b/src/unix/openbsd.c
+@@ -72,7 +72,7 @@ int uv_exepath(char* buffer, size_t* size) {
+   mypid = getpid();
+   for (;;) {
+     err = UV_ENOMEM;
+-    argsbuf = uv__reallocf(argsbuf, argsbuf_size);
++    argsbuf = (char**)uv__reallocf(argsbuf, argsbuf_size);
+     if (argsbuf == NULL)
+       goto out;
+     mib[0] = CTL_KERN;
+@@ -197,7 +197,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+   if (sysctl(which, ARRAY_SIZE(which), &numcpus, &size, NULL, 0))
+     return UV__ERR(errno);
+ 
+-  *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
++  *cpu_infos = (uv_cpu_info_t*)uv__malloc(numcpus * sizeof(**cpu_infos));
+   if (!(*cpu_infos))
+     return UV_ENOMEM;
+ 
+diff --git a/src/unix/pipe.c b/src/unix/pipe.c
+index e8cfa148..c8ba31da 100644
+--- a/src/unix/pipe.c
++++ b/src/unix/pipe.c
+@@ -309,7 +309,7 @@ int uv_pipe_pending_count(uv_pipe_t* handle) {
+   if (handle->queued_fds == NULL)
+     return 1;
+ 
+-  queued_fds = handle->queued_fds;
++  queued_fds = (uv__stream_queued_fds_t*)(handle->queued_fds);
+   return queued_fds->offset + 1;
+ }
+ 
+@@ -346,7 +346,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
+   if (r != UV_ENOBUFS)
+     return r;
+ 
+-  name_buffer = uv__malloc(name_len);
++  name_buffer = (char*)uv__malloc(name_len);
+   if (name_buffer == NULL)
+     return UV_ENOMEM;
+ 
+diff --git a/src/unix/poll.c b/src/unix/poll.c
+index 7a12e2d1..73647317 100644
+--- a/src/unix/poll.c
++++ b/src/unix/poll.c
+@@ -117,7 +117,7 @@ int uv_poll_stop(uv_poll_t* handle) {
+ 
+ 
+ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
+-  uv__io_t** watchers;
++  void** watchers;
+   uv__io_t* w;
+   int events;
+ 
+diff --git a/src/unix/posix-poll.c b/src/unix/posix-poll.c
+index 0f4bf938..8da038d1 100644
+--- a/src/unix/posix-poll.c
++++ b/src/unix/posix-poll.c
+@@ -61,7 +61,7 @@ static void uv__pollfds_maybe_resize(uv_loop_t* loop) {
+     return;
+ 
+   n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64;
+-  p = uv__reallocf(loop->poll_fds, n * sizeof(*loop->poll_fds));
++  p = (struct pollfd*)uv__reallocf(loop->poll_fds, n * sizeof(*loop->poll_fds));
+   if (p == NULL)
+     abort();
+ 
+diff --git a/src/unix/process.c b/src/unix/process.c
+index f8415368..0916aa45 100644
+--- a/src/unix/process.c
++++ b/src/unix/process.c
+@@ -403,7 +403,7 @@ static int posix_spawn_can_use_setsid;
+ static void uv__spawn_init_posix_spawn_fncs(void) {
+   /* Try to locate all non-portable functions at runtime */
+   posix_spawn_fncs.file_actions.addchdir_np =
+-    dlsym(RTLD_DEFAULT, "posix_spawn_file_actions_addchdir_np");
++    (int (*)(void* const*, const char*)) dlsym(RTLD_DEFAULT, "posix_spawn_file_actions_addchdir_np");
+ }
+ 
+ 
+@@ -967,7 +967,7 @@ int uv_spawn(uv_loop_t* loop,
+   err = UV_ENOMEM;
+   pipes = pipes_storage;
+   if (stdio_count > (int) ARRAY_SIZE(pipes_storage))
+-    pipes = uv__malloc(stdio_count * sizeof(*pipes));
++    pipes = (int (*)[2])uv__malloc(stdio_count * sizeof(*pipes));
+ 
+   if (pipes == NULL)
+     goto error;
+diff --git a/src/unix/proctitle.c b/src/unix/proctitle.c
+index 9d1f00dd..8cdec753 100644
+--- a/src/unix/proctitle.c
++++ b/src/unix/proctitle.c
+@@ -65,7 +65,7 @@ char** uv_setup_args(int argc, char** argv) {
+   /* Add space for the argv pointers. */
+   size += (argc + 1) * sizeof(char*);
+ 
+-  new_argv = uv__malloc(size);
++  new_argv = (char**)uv__malloc(size);
+   if (new_argv == NULL)
+     return argv;
+ 
+diff --git a/src/unix/random-sysctl-linux.c b/src/unix/random-sysctl-linux.c
+index 66ba8d74..9ef18df0 100644
+--- a/src/unix/random-sysctl-linux.c
++++ b/src/unix/random-sysctl-linux.c
+@@ -48,7 +48,7 @@ int uv__random_sysctl(void* buf, size_t buflen) {
+   char* pe;
+   size_t n;
+ 
+-  p = buf;
++  p = (char*)buf;
+   pe = p + buflen;
+ 
+   while (p < pe) {
+diff --git a/src/unix/stream.c b/src/unix/stream.c
+index b1f6359e..c6cc50e7 100644
+--- a/src/unix/stream.c
++++ b/src/unix/stream.c
+@@ -113,7 +113,7 @@ static void uv__stream_osx_interrupt_select(uv_stream_t* stream) {
+   uv__stream_select_t* s;
+   int r;
+ 
+-  s = stream->select;
++  s = (uv__stream_select_t*)stream->select;
+   if (s == NULL)
+     return;
+ 
+@@ -142,8 +142,8 @@ static void uv__stream_osx_select(void* arg) {
+   int r;
+   int max_fd;
+ 
+-  stream = arg;
+-  s = stream->select;
++  stream = (uv_stream_t*)arg;
++  s = (uv__stream_select_t*)stream->select;
+   fd = s->fd;
+ 
+   if (fd > s->int_fd)
+@@ -320,7 +320,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
+   sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY;
+   swrite_sz = sread_sz;
+ 
+-  s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz);
++  s = (uv__stream_select_t*)uv__malloc(sizeof(*s) + sread_sz + swrite_sz);
+   if (s == NULL) {
+     err = UV_ENOMEM;
+     goto failed_malloc;
+@@ -605,7 +605,7 @@ done:
+   if (server->queued_fds != NULL) {
+     uv__stream_queued_fds_t* queued_fds;
+ 
+-    queued_fds = server->queued_fds;
++    queued_fds = (uv__stream_queued_fds_t*)(server->queued_fds);
+ 
+     /* Read first */
+     server->accepted_fd = queued_fds->fds[0];
+@@ -844,7 +844,7 @@ static int uv__try_write(uv_stream_t* stream,
+     /* silence aliasing warning */
+     {
+       void* pv = CMSG_DATA(cmsg);
+-      int* pi = pv;
++      int* pi = (int*)pv;
+       *pi = fd_to_send;
+     }
+ 
+@@ -975,11 +975,12 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
+   uv__stream_queued_fds_t* queued_fds;
+   unsigned int queue_size;
+ 
+-  queued_fds = stream->queued_fds;
++  queued_fds = (uv__stream_queued_fds_t*)stream->queued_fds;
+   if (queued_fds == NULL) {
+     queue_size = 8;
+-    queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
+-                            sizeof(*queued_fds));
++    queued_fds = (uv__stream_queued_fds_t*)
++        uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) +
++                   sizeof(*queued_fds));
+     if (queued_fds == NULL)
+       return UV_ENOMEM;
+     queued_fds->size = queue_size;
+@@ -989,9 +990,9 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) {
+     /* Grow */
+   } else if (queued_fds->size == queued_fds->offset) {
+     queue_size = queued_fds->size + 8;
+-    queued_fds = uv__realloc(queued_fds,
+-                             (queue_size - 1) * sizeof(*queued_fds->fds) +
+-                              sizeof(*queued_fds));
++    queued_fds = (uv__stream_queued_fds_t*)
++        uv__realloc(queued_fds, (queue_size - 1) * sizeof(*queued_fds->fds) +
++                    sizeof(*queued_fds));
+ 
+     /*
+      * Allocation failure, report back.
+@@ -1039,7 +1040,7 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
+ 
+     /* silence aliasing warning */
+     pv = CMSG_DATA(cmsg);
+-    pi = pv;
++    pi = (int*)pv;
+ 
+     /* Count available fds */
+     start = (char*) cmsg;
+@@ -1423,7 +1424,7 @@ int uv_write2(uv_write_t* req,
+ 
+   req->bufs = req->bufsml;
+   if (nbufs > ARRAY_SIZE(req->bufsml))
+-    req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
++    req->bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(bufs[0]));
+ 
+   if (req->bufs == NULL)
+     return UV_ENOMEM;
+@@ -1557,7 +1558,7 @@ int uv___stream_fd(const uv_stream_t* handle) {
+          handle->type == UV_TTY ||
+          handle->type == UV_NAMED_PIPE);
+ 
+-  s = handle->select;
++  s = (const uv__stream_select_t*)handle->select;
+   if (s != NULL)
+     return s->fd;
+ 
+@@ -1575,7 +1576,7 @@ void uv__stream_close(uv_stream_t* handle) {
+   if (handle->select != NULL) {
+     uv__stream_select_t* s;
+ 
+-    s = handle->select;
++    s = (uv__stream_select_t*)handle->select;
+ 
+     uv_sem_post(&s->close_sem);
+     uv_sem_post(&s->async_sem);
+@@ -1610,7 +1611,7 @@ void uv__stream_close(uv_stream_t* handle) {
+ 
+   /* Close all queued fds */
+   if (handle->queued_fds != NULL) {
+-    queued_fds = handle->queued_fds;
++    queued_fds = (uv__stream_queued_fds_t*)(handle->queued_fds);
+     for (i = 0; i < queued_fds->offset; i++)
+       uv__close(queued_fds->fds[i]);
+     uv__free(handle->queued_fds);
+diff --git a/src/unix/thread.c b/src/unix/thread.c
+index d89e5cd1..759cd0c2 100644
+--- a/src/unix/thread.c
++++ b/src/unix/thread.c
+@@ -59,7 +59,7 @@ int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+   if (barrier == NULL || count == 0)
+     return UV_EINVAL;
+ 
+-  b = uv__malloc(sizeof(*b));
++  b = (_uv_barrier*)uv__malloc(sizeof(*b));
+   if (b == NULL)
+     return UV_ENOMEM;
+ 
+@@ -275,8 +275,7 @@ int uv_thread_create_ex(uv_thread_t* tid,
+       abort();
+   }
+ 
+-  f.in = entry;
+-  err = pthread_create(tid, attr, f.out, arg);
++  err = pthread_create(tid, attr, (void*(*)(void*)) (void(*)(void)) entry, arg);
+ 
+   if (attr != NULL)
+     pthread_attr_destroy(attr);
+@@ -547,7 +546,7 @@ static int uv__custom_sem_init(uv_sem_t* sem_, unsigned int value) {
+   int err;
+   uv_semaphore_t* sem;
+ 
+-  sem = uv__malloc(sizeof(*sem));
++  sem = (uv_semaphore_t*)uv__malloc(sizeof(*sem));
+   if (sem == NULL)
+     return UV_ENOMEM;
+ 
+diff --git a/src/unix/udp.c b/src/unix/udp.c
+index 4d985b88..a130aeaa 100644
+--- a/src/unix/udp.c
++++ b/src/unix/udp.c
+@@ -227,11 +227,11 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
+       if (msgs[k].msg_hdr.msg_flags & MSG_TRUNC)
+         flags |= UV_UDP_PARTIAL;
+ 
+-      chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len);
++      chunk_buf = uv_buf_init((char*) iov[k].iov_base, iov[k].iov_len);
+       handle->recv_cb(handle,
+                       msgs[k].msg_len,
+                       &chunk_buf,
+-                      msgs[k].msg_hdr.msg_name,
++                      (const sockaddr*) msgs[k].msg_hdr.msg_name,
+                       flags);
+     }
+ 
+@@ -281,7 +281,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
+     memset(&peer, 0, sizeof(peer));
+     h.msg_name = &peer;
+     h.msg_namelen = sizeof(peer);
+-    h.msg_iov = (void*) &buf;
++    h.msg_iov = (iovec*) &buf;
+     h.msg_iovlen = 1;
+ 
+     do {
+@@ -765,7 +765,7 @@ int uv__udp_send(uv_udp_send_t* req,
+ 
+   req->bufs = req->bufsml;
+   if (nbufs > ARRAY_SIZE(req->bufsml))
+-    req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
++    req->bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(bufs[0]));
+ 
+   if (req->bufs == NULL) {
+     uv__req_unregister(handle->loop, req);
+diff --git a/src/uv-common.c b/src/uv-common.c
+index efc9eb50..dfb606e3 100644
+--- a/src/uv-common.c
++++ b/src/uv-common.c
+@@ -54,10 +54,10 @@ static uv__allocator_t uv__allocator = {
+ 
+ char* uv__strdup(const char* s) {
+   size_t len = strlen(s) + 1;
+-  char* m = uv__malloc(len);
++  char* m = (char*)uv__malloc(len);
+   if (m == NULL)
+     return NULL;
+-  return memcpy(m, s, len);
++  return (char*)memcpy(m, s, len);
+ }
+ 
+ char* uv__strndup(const char* s, size_t n) {
+@@ -65,11 +65,11 @@ char* uv__strndup(const char* s, size_t n) {
+   size_t len = strlen(s);
+   if (n < len)
+     len = n;
+-  m = uv__malloc(len + 1);
++  m = (char*)uv__malloc(len + 1);
+   if (m == NULL)
+     return NULL;
+   m[len] = '\0';
+-  return memcpy(m, s, len);
++  return (char*)memcpy(m, s, len);
+ }
+ 
+ void* uv__malloc(size_t size) {
+@@ -653,7 +653,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req) {
+ 
+   unsigned int* nbufs = uv__get_nbufs(req);
+ 
+-  dents = req->ptr;
++  dents = (uv__dirent_t**)(req->ptr);
+   if (*nbufs > 0 && *nbufs != (unsigned int) req->result)
+     (*nbufs)--;
+   for (; *nbufs < (unsigned int) req->result; (*nbufs)++)
+@@ -680,7 +680,7 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
+   nbufs = uv__get_nbufs(req);
+   assert(nbufs);
+ 
+-  dents = req->ptr;
++  dents = (uv__dirent_t**)(req->ptr);
+ 
+   /* Free previous entity */
+   if (*nbufs > 0)
+@@ -745,7 +745,7 @@ void uv__fs_readdir_cleanup(uv_fs_t* req) {
+   if (req->ptr == NULL)
+     return;
+ 
+-  dir = req->ptr;
++  dir = (uv_dir_t*)req->ptr;
+   dirents = dir->dirents;
+   req->ptr = NULL;
+ 
+@@ -791,7 +791,7 @@ uv_loop_t* uv_default_loop(void) {
+ uv_loop_t* uv_loop_new(void) {
+   uv_loop_t* loop;
+ 
+-  loop = uv__malloc(sizeof(*loop));
++  loop = (uv_loop_t*)uv__malloc(sizeof(*loop));
+   if (loop == NULL)
+     return NULL;
+ 
+diff --git a/src/win/core.c b/src/win/core.c
+index 67af93e6..0752edff 100644
+--- a/src/win/core.c
++++ b/src/win/core.c
+@@ -98,7 +98,8 @@ static int uv__loops_add(uv_loop_t* loop) {
+ 
+   if (uv__loops_size == uv__loops_capacity) {
+     new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE;
+-    new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity);
++    new_loops = (uv_loop_t**)
++        uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity);
+     if (!new_loops)
+       goto failed_loops_realloc;
+     uv__loops = new_loops;
+@@ -152,7 +153,8 @@ static void uv__loops_remove(uv_loop_t* loop) {
+   smaller_capacity = uv__loops_capacity / 2;
+   if (uv__loops_size >= smaller_capacity)
+     goto loop_removed;
+-  new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity);
++  new_loops = (uv_loop_t**)
++      uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity);
+   if (!new_loops)
+     goto loop_removed;
+   uv__loops = new_loops;
+@@ -261,7 +263,7 @@ int uv_loop_init(uv_loop_t* loop) {
+ 
+   loop->endgame_handles = NULL;
+ 
+-  loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
++  loop->timer_heap = timer_heap = (heap*)uv__malloc(sizeof(*timer_heap));
+   if (timer_heap == NULL) {
+     err = UV_ENOMEM;
+     goto fail_timers_alloc;
+diff --git a/src/win/fs-event.c b/src/win/fs-event.c
+index 6758c7c7..15046731 100644
+--- a/src/win/fs-event.c
++++ b/src/win/fs-event.c
+@@ -73,7 +73,7 @@ static void uv__relative_path(const WCHAR* filename,
+   if (dirlen > 0 && dir[dirlen - 1] == '\\')
+     dirlen--;
+   relpathlen = filenamelen - dirlen - 1;
+-  *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR));
++  *relpath = (WCHAR*)uv__malloc((relpathlen + 1) * sizeof(WCHAR));
+   if (!*relpath)
+     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+   wcsncpy(*relpath, filename + dirlen + 1, relpathlen);
+@@ -242,7 +242,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
+     if (short_path_buffer_len == 0) {
+       goto short_path_done;
+     }
+-    short_path_buffer = uv__malloc(short_path_buffer_len * sizeof(WCHAR));
++    short_path_buffer = (WCHAR*)uv__malloc(short_path_buffer_len * sizeof(WCHAR));
+     if (short_path_buffer == NULL) {
+       goto short_path_done;
+     }
+diff --git a/src/win/fs-fd-hash-inl.h b/src/win/fs-fd-hash-inl.h
+index 0b532af1..703a8d8f 100644
+--- a/src/win/fs-fd-hash-inl.h
++++ b/src/win/fs-fd-hash-inl.h
+@@ -146,7 +146,7 @@ INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
+ 
+     if (bucket_ptr->size != 0 && i == 0) {
+       struct uv__fd_hash_entry_group_s* new_group_ptr =
+-        uv__malloc(sizeof(*new_group_ptr));
++        (struct uv__fd_hash_entry_group_s*)uv__malloc(sizeof(*new_group_ptr));
+       if (new_group_ptr == NULL) {
+         uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+       }
+diff --git a/src/win/fs.c b/src/win/fs.c
+index 79230799..8374012f 100644
+--- a/src/win/fs.c
++++ b/src/win/fs.c
+@@ -285,7 +285,7 @@ static int fs__wide_to_utf8(WCHAR* w_source_ptr,
+     return 0;
+   }
+ 
+-  target = uv__malloc(target_len + 1);
++  target = (char*)uv__malloc(target_len + 1);
+   if (target == NULL) {
+     SetLastError(ERROR_OUTOFMEMORY);
+     return -1;
+@@ -1464,7 +1464,7 @@ void fs__scandir(uv_fs_t* req) {
+       if (dirents_used >= dirents_size) {
+         size_t new_dirents_size =
+             dirents_size == 0 ? dirents_initial_size : dirents_size << 1;
+-        uv__dirent_t** new_dirents =
++        uv__dirent_t** new_dirents = (uv__dirent_t**)
+             uv__realloc(dirents, new_dirents_size * sizeof *dirents);
+ 
+         if (new_dirents == NULL)
+@@ -1478,7 +1478,7 @@ void fs__scandir(uv_fs_t* req) {
+        * includes room for the first character of the filename, but `utf8_len`
+        * doesn't count the NULL terminator at this point.
+        */
+-      dirent = uv__malloc(sizeof *dirent + utf8_len);
++      dirent = (uv__dirent_t*)uv__malloc(sizeof *dirent + utf8_len);
+       if (dirent == NULL)
+         goto out_of_memory_error;
+ 
+@@ -1589,7 +1589,7 @@ void fs__opendir(uv_fs_t* req) {
+     goto error;
+   }
+ 
+-  dir = uv__malloc(sizeof(*dir));
++  dir = (uv_dir_t*)uv__malloc(sizeof(*dir));
+   if (dir == NULL) {
+     SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+     goto error;
+@@ -1604,7 +1604,7 @@ void fs__opendir(uv_fs_t* req) {
+   else
+     fmt = L"%s\\*";
+ 
+-  find_path = uv__malloc(sizeof(WCHAR) * (len + 4));
++  find_path = (WCHAR*)uv__malloc(sizeof(WCHAR) * (len + 4));
+   if (find_path == NULL) {
+     SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+     goto error;
+@@ -1641,7 +1641,7 @@ void fs__readdir(uv_fs_t* req) {
+   int r;
+ 
+   req->flags |= UV_FS_FREE_PTR;
+-  dir = req->ptr;
++  dir = (uv_dir_t*)req->ptr;
+   dirents = dir->dirents;
+   memset(dirents, 0, dir->nentries * sizeof(*dir->dirents));
+   find_data = &dir->find_data;
+@@ -1698,7 +1698,7 @@ error:
+ void fs__closedir(uv_fs_t* req) {
+   uv_dir_t* dir;
+ 
+-  dir = req->ptr;
++  dir = (uv_dir_t*)req->ptr;
+   FindClose(dir->dir_handle);
+   uv__free(req->ptr);
+   SET_REQ_RESULT(req, 0);
+@@ -2627,7 +2627,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
+     return -1;
+   }
+ 
+-  w_realpath_buf = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
++  w_realpath_buf = (WCHAR*)uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
+   if (w_realpath_buf == NULL) {
+     SetLastError(ERROR_OUTOFMEMORY);
+     return -1;
+@@ -2738,7 +2738,7 @@ retry_get_disk_free_space:
+     }
+ 
+     len = MAX_PATH + 1;
+-    pathw = uv__malloc(len * sizeof(*pathw));
++    pathw = (WCHAR*)uv__malloc(len * sizeof(*pathw));
+     if (pathw == NULL) {
+       SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+       return;
+@@ -2754,7 +2754,7 @@ retry_get_full_path_name:
+       return;
+     } else if (ret > len) {
+       len = ret;
+-      pathw = uv__reallocf(pathw, len * sizeof(*pathw));
++      pathw = (WCHAR*)uv__reallocf(pathw, len * sizeof(*pathw));
+       if (pathw == NULL) {
+         SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+         return;
+@@ -2770,7 +2770,7 @@ retry_get_full_path_name:
+     uv__free(pathw);
+   }
+ 
+-  stat_fs = uv__malloc(sizeof(*stat_fs));
++  stat_fs = (uv_statfs_t*)uv__malloc(sizeof(*stat_fs));
+   if (stat_fs == NULL) {
+     SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+     return;
+@@ -2929,7 +2929,7 @@ int uv_fs_read(uv_loop_t* loop,
+   req->fs.info.nbufs = nbufs;
+   req->fs.info.bufs = req->fs.info.bufsml;
+   if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
+-    req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
++    req->fs.info.bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(*bufs));
+ 
+   if (req->fs.info.bufs == NULL) {
+     SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+@@ -2962,7 +2962,7 @@ int uv_fs_write(uv_loop_t* loop,
+   req->fs.info.nbufs = nbufs;
+   req->fs.info.bufs = req->fs.info.bufsml;
+   if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
+-    req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
++    req->fs.info.bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(*bufs));
+ 
+   if (req->fs.info.bufs == NULL) {
+     SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+diff --git a/src/win/pipe.c b/src/win/pipe.c
+index 99846181..cd77061a 100644
+--- a/src/win/pipe.c
++++ b/src/win/pipe.c
+@@ -728,7 +728,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
+ 
+   /* Convert name to UTF16. */
+   nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
+-  handle->name = uv__malloc(nameSize);
++  handle->name = (WCHAR*)uv__malloc(nameSize);
+   if (!handle->name) {
+     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+   }
+@@ -841,7 +841,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+ 
+   /* Convert name to UTF16. */
+   nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
+-  handle->name = uv__malloc(nameSize);
++  handle->name = (WCHAR*)uv__malloc(nameSize);
+   if (!handle->name) {
+     uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+   }
+@@ -1453,7 +1453,7 @@ static int uv__build_coalesced_write_req(uv_write_t* user_req,
+                        data_length;                  /* (c) */
+ 
+   /* Allocate buffer. */
+-  heap_buffer = uv__malloc(heap_buffer_length);
++  heap_buffer = (char*)uv__malloc(heap_buffer_length);
+   if (heap_buffer == NULL)
+     return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */
+ 
+@@ -1698,7 +1698,7 @@ int uv__pipe_write_ipc(uv_loop_t* loop,
+     bufs = stack_bufs;
+   } else {
+     /* Use heap-allocated buffer array. */
+-    bufs = uv__calloc(buf_count, sizeof(uv_buf_t));
++    bufs = (uv_buf_t*)uv__calloc(buf_count, sizeof(uv_buf_t));
+     if (bufs == NULL)
+       return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */
+   }
+@@ -2430,7 +2430,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
+                                       FileNameInformation);
+   if (nt_status == STATUS_BUFFER_OVERFLOW) {
+     name_size = sizeof(*name_info) + tmp_name_info.FileNameLength;
+-    name_info = uv__malloc(name_size);
++    name_info = (FILE_NAME_INFORMATION*)uv__malloc(name_size);
+     if (!name_info) {
+       *size = 0;
+       err = UV_ENOMEM;
+diff --git a/src/win/process.c b/src/win/process.c
+index 24c63339..e857db3e 100644
+--- a/src/win/process.c
++++ b/src/win/process.c
+@@ -616,8 +616,8 @@ error:
+ 
+ 
+ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) {
+-  wchar_t* a_eq;
+-  wchar_t* b_eq;
++  const wchar_t* a_eq;
++  const wchar_t* b_eq;
+   wchar_t* A;
+   wchar_t* B;
+   int nb;
+@@ -634,8 +634,8 @@ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) {
+   assert(b_eq);
+   nb = b_eq - b;
+ 
+-  A = alloca((na+1) * sizeof(wchar_t));
+-  B = alloca((nb+1) * sizeof(wchar_t));
++  A = (wchar_t*)alloca((na+1) * sizeof(wchar_t));
++  B = (wchar_t*)alloca((nb+1) * sizeof(wchar_t));
+ 
+   r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na);
+   assert(r==na);
+@@ -718,7 +718,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
+   if (dst_copy == NULL && env_len > 0) {
+     return ERROR_OUTOFMEMORY;
+   }
+-  env_copy = alloca(env_block_count * sizeof(WCHAR*));
++  env_copy = (WCHAR**)alloca(env_block_count * sizeof(WCHAR*));
+ 
+   ptr = dst_copy;
+   ptr_copy = env_copy;
+@@ -772,7 +772,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
+   }
+ 
+   /* final pass: copy, in sort order, and inserting required variables */
+-  dst = uv__malloc((1+env_len) * sizeof(WCHAR));
++  dst = (WCHAR*)uv__malloc((1+env_len) * sizeof(WCHAR));
+   if (!dst) {
+     uv__free(dst_copy);
+     return ERROR_OUTOFMEMORY;
+diff --git a/src/win/tcp.c b/src/win/tcp.c
+index b6aa4c51..4cccee42 100644
+--- a/src/win/tcp.c
++++ b/src/win/tcp.c
+@@ -612,7 +612,7 @@ int uv__tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
+ 
+   if (handle->tcp.serv.accept_reqs == NULL) {
+     handle->tcp.serv.accept_reqs =
+-      uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
++      (uv_tcp_accept_t*)uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
+     if (!handle->tcp.serv.accept_reqs) {
+       uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+     }
+diff --git a/src/win/thread.c b/src/win/thread.c
+index d3b1c96b..9ad60c91 100644
+--- a/src/win/thread.c
++++ b/src/win/thread.c
+@@ -98,7 +98,7 @@ static UINT __stdcall uv__thread_start(void* arg) {
+   struct thread_ctx *ctx_p;
+   struct thread_ctx ctx;
+ 
+-  ctx_p = arg;
++  ctx_p = (struct thread_ctx*)arg;
+   ctx = *ctx_p;
+   uv__free(ctx_p);
+ 
+@@ -141,7 +141,7 @@ int uv_thread_create_ex(uv_thread_t* tid,
+       return UV_EINVAL;
+   }
+ 
+-  ctx = uv__malloc(sizeof(*ctx));
++  ctx = (struct thread_ctx*)uv__malloc(sizeof(*ctx));
+   if (ctx == NULL)
+     return UV_ENOMEM;
+ 
+diff --git a/src/win/util.c b/src/win/util.c
+index 99432053..c655f532 100644
+--- a/src/win/util.c
++++ b/src/win/util.c
+@@ -164,7 +164,7 @@ int uv_cwd(char* buffer, size_t* size) {
+   if (utf16_len == 0) {
+     return uv_translate_sys_error(GetLastError());
+   }
+-  utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
++  utf16_buffer = (WCHAR*)uv__malloc(utf16_len * sizeof(WCHAR));
+   if (utf16_buffer == NULL) {
+     return UV_ENOMEM;
+   }
+@@ -242,7 +242,7 @@ int uv_chdir(const char* dir) {
+   if (utf16_len == 0) {
+     return uv_translate_sys_error(GetLastError());
+   }
+-  utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
++  utf16_buffer = (WCHAR*)uv__malloc(utf16_len * sizeof(WCHAR));
+   if (utf16_buffer == NULL) {
+     return UV_ENOMEM;
+   }
+@@ -268,7 +268,7 @@ int uv_chdir(const char* dir) {
+   new_utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
+   if (new_utf16_len > utf16_len ) {
+     uv__free(utf16_buffer);
+-    utf16_buffer = uv__malloc(new_utf16_len * sizeof(WCHAR));
++    utf16_buffer = (WCHAR*)uv__malloc(new_utf16_len * sizeof(WCHAR));
+     if (utf16_buffer == NULL) {
+       /* When updating the environment variable fails, return UV_OK anyway.
+        * We did successfully change current working directory, only updating
+@@ -573,14 +573,14 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
+   GetSystemInfo(&system_info);
+   cpu_count = system_info.dwNumberOfProcessors;
+ 
+-  cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos);
++  cpu_infos = (uv_cpu_info_t*)uv__calloc(cpu_count, sizeof *cpu_infos);
+   if (cpu_infos == NULL) {
+     err = ERROR_OUTOFMEMORY;
+     goto error;
+   }
+ 
+   sppi_size = cpu_count * sizeof(*sppi);
+-  sppi = uv__malloc(sppi_size);
++  sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)uv__malloc(sppi_size);
+   if (sppi == NULL) {
+     err = ERROR_OUTOFMEMORY;
+     goto error;
+@@ -802,7 +802,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
+       case ERROR_BUFFER_OVERFLOW:
+         /* This happens when win_address_buf is NULL or too small to hold all
+          * adapters. */
+-        win_address_buf = uv__malloc(win_address_buf_size);
++        win_address_buf =
++            (IP_ADAPTER_ADDRESSES*)uv__malloc(win_address_buf_size);
+         if (win_address_buf == NULL)
+           return UV_ENOMEM;
+ 
+@@ -810,7 +811,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
+ 
+       case ERROR_NO_DATA: {
+         /* No adapters were found. */
+-        uv_address_buf = uv__malloc(1);
++        uv_address_buf = (uv_interface_address_t*)uv__malloc(1);
+         if (uv_address_buf == NULL)
+           return UV_ENOMEM;
+ 
+@@ -887,7 +888,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
+   }
+ 
+   /* Allocate space to store interface data plus adapter names. */
+-  uv_address_buf = uv__malloc(uv_address_buf_size);
++  uv_address_buf = (uv_interface_address_t*)uv__malloc(uv_address_buf_size);
+   if (uv_address_buf == NULL) {
+     uv__free(win_address_buf);
+     return UV_ENOMEM;
+@@ -1131,7 +1132,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
+   }
+   /* Include space for terminating null char. */
+   len += 1;
+-  path = uv__malloc(len * sizeof(wchar_t));
++  path = (wchar_t*)uv__malloc(len * sizeof(wchar_t));
+   if (path == NULL) {
+     return UV_ENOMEM;
+   }
+@@ -1221,7 +1222,7 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
+   /* Allocate the destination buffer adding an extra byte for the terminating
+    * NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so
+    * we do it ourselves always, just in case. */
+-  *utf8 = uv__malloc(bufsize + 1);
++  *utf8 = (char*)uv__malloc(bufsize + 1);
+ 
+   if (*utf8 == NULL)
+     return UV_ENOMEM;
+@@ -1269,7 +1270,7 @@ int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
+   /* Allocate the destination buffer adding an extra byte for the terminating
+    * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so
+    * we do it ourselves always, just in case. */
+-  *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1));
++  *utf16 = (WCHAR*)uv__malloc(sizeof(WCHAR) * (bufsize + 1));
+ 
+   if (*utf16 == NULL)
+     return UV_ENOMEM;
+@@ -1310,7 +1311,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
+     return uv_translate_sys_error(r);
+   }
+ 
+-  path = uv__malloc(bufsize * sizeof(wchar_t));
++  path = (wchar_t*)uv__malloc(bufsize * sizeof(wchar_t));
+   if (path == NULL) {
+     CloseHandle(token);
+     return UV_ENOMEM;
+@@ -1381,7 +1382,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
+ 
+   for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);
+ 
+-  *envitems = uv__calloc(i, sizeof(**envitems));
++  *envitems = (uv_env_item_t*)uv__calloc(i, sizeof(**envitems));
+   if (*envitems == NULL) {
+     FreeEnvironmentStringsW(env);
+     return UV_ENOMEM;
+@@ -1471,7 +1472,7 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
+       uv__free(var);
+ 
+     varlen = 1 + len;
+-    var = uv__malloc(varlen * sizeof(*var));
++    var = (wchar_t*)uv__malloc(varlen * sizeof(*var));
+ 
+     if (var == NULL) {
+       r = UV_ENOMEM;
diff --git a/upstream_utils/libuv_patches/0002-Fix-warnings.patch b/upstream_utils/libuv_patches/0002-Fix-warnings.patch
new file mode 100644
index 0000000..fedaea0
--- /dev/null
+++ b/upstream_utils/libuv_patches/0002-Fix-warnings.patch
@@ -0,0 +1,365 @@
+From f7b4492d37b35a64a3a6c5bbbdb375494095b6ff Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 26 Apr 2022 15:09:43 -0400
+Subject: [PATCH 2/9] Fix warnings
+
+---
+ include/uv/win.h    |   5 +++
+ src/idna.c          |   2 +-
+ src/inet.c          |   4 ++
+ src/threadpool.c    |   4 ++
+ src/unix/core.c     |  12 ++++-
+ src/unix/darwin.c   | 106 +++++++++++++++++++++++---------------------
+ src/unix/internal.h |   4 +-
+ src/unix/thread.c   |   6 ---
+ src/uv-common.c     |   8 ++++
+ src/win/fs-event.c  |   2 +
+ src/win/fs.c        |   2 +
+ src/win/pipe.c      |   2 +
+ src/win/process.c   |   2 +
+ src/win/tty.c       |   2 +
+ 14 files changed, 99 insertions(+), 62 deletions(-)
+
+diff --git a/include/uv/win.h b/include/uv/win.h
+index 56a4cf11..10d5e8f1 100644
+--- a/include/uv/win.h
++++ b/include/uv/win.h
+@@ -201,11 +201,16 @@ typedef int (WSAAPI* LPFN_WSARECVFROM)
+              LPWSAOVERLAPPED overlapped,
+              LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+ 
++#pragma warning(push)
++#pragma warning(disable : 28251)
++
+ #ifndef _NTDEF_
+   typedef LONG NTSTATUS;
+   typedef NTSTATUS *PNTSTATUS;
+ #endif
+ 
++#pragma warning(pop)
++
+ #ifndef RTL_CONDITION_VARIABLE_INIT
+   typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+ #endif
+diff --git a/src/idna.c b/src/idna.c
+index 93d982ca..36a39a08 100644
+--- a/src/idna.c
++++ b/src/idna.c
+@@ -106,7 +106,7 @@ static int uv__idna_toascii_label(const char* s, const char* se,
+                                   char** d, char* de) {
+   static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
+   const char* ss;
+-  unsigned c;
++  unsigned c = 0;
+   unsigned h;
+   unsigned k;
+   unsigned n;
+diff --git a/src/inet.c b/src/inet.c
+index ca8b6ac8..1b190255 100644
+--- a/src/inet.c
++++ b/src/inet.c
+@@ -27,6 +27,10 @@
+ #include "uv.h"
+ #include "uv-common.h"
+ 
++#ifdef _WIN32
++#pragma warning(disable : 6001)
++#endif
++
+ #define UV__INET_ADDRSTRLEN         16
+ #define UV__INET6_ADDRSTRLEN        46
+ 
+diff --git a/src/threadpool.c b/src/threadpool.c
+index 1241ace1..718972c3 100644
+--- a/src/threadpool.c
++++ b/src/threadpool.c
+@@ -27,6 +27,10 @@
+ 
+ #include <stdlib.h>
+ 
++#ifdef _WIN32
++#pragma warning(disable: 6001 6011)
++#endif
++
+ #define MAX_THREADPOOL_SIZE 1024
+ 
+ static uv_once_t once = UV_ONCE_INIT;
+diff --git a/src/unix/core.c b/src/unix/core.c
+index 6353b0e3..223c5513 100644
+--- a/src/unix/core.c
++++ b/src/unix/core.c
+@@ -544,6 +544,16 @@ int uv__accept(int sockfd) {
+   return peerfd;
+ }
+ 
++#if defined(__APPLE__)
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
++#if defined(__LP64__)
++  extern "C" int close$NOCANCEL(int);
++#else
++  extern "C" int close$NOCANCEL$UNIX2003(int);
++#endif
++#pragma GCC diagnostic pop
++#endif
+ 
+ /* close() on macos has the "interesting" quirk that it fails with EINTR
+  * without closing the file descriptor when a thread is in the cancel state.
+@@ -558,10 +568,8 @@ int uv__close_nocancel(int fd) {
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
+ #if defined(__LP64__) || TARGET_OS_IPHONE
+-  extern int close$NOCANCEL(int);
+   return close$NOCANCEL(fd);
+ #else
+-  extern int close$NOCANCEL$UNIX2003(int);
+   return close$NOCANCEL$UNIX2003(fd);
+ #endif
+ #pragma GCC diagnostic pop
+diff --git a/src/unix/darwin.c b/src/unix/darwin.c
+index 5fbf7342..eeb35720 100644
+--- a/src/unix/darwin.c
++++ b/src/unix/darwin.c
+@@ -253,64 +253,68 @@ static int uv__get_cpu_speed(uint64_t* speed) {
+ 
+ #define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
+ 
+-  kr = pIOMasterPort(MACH_PORT_NULL, &mach_port);
+-  assert(kr == KERN_SUCCESS);
+-  CFMutableDictionaryRef classes_to_match
+-      = pIOServiceMatching("IOPlatformDevice");
+-  kr = pIOServiceGetMatchingServices(mach_port, classes_to_match, &it);
+-  assert(kr == KERN_SUCCESS);
+-  service = pIOIteratorNext(it);
+-
+-  CFStringRef device_type_str = S("device_type");
+-  CFStringRef clock_frequency_str = S("clock-frequency");
+-
+-  while (service != 0) {
+-    CFDataRef data;
+-    data = pIORegistryEntryCreateCFProperty(service,
+-                                            device_type_str,
+-                                            NULL,
+-                                            0);
+-    if (data) {
+-      const UInt8* raw = pCFDataGetBytePtr(data);
+-      if (strncmp((char*)raw, "cpu", 3) == 0 ||
+-          strncmp((char*)raw, "processor", 9) == 0) {
+-        CFDataRef freq_ref;
+-        freq_ref = pIORegistryEntryCreateCFProperty(service,
+-                                                    clock_frequency_str,
+-                                                    NULL,
+-                                                    0);
+-        if (freq_ref) {
+-          const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref);
+-          CFIndex len = pCFDataGetLength(freq_ref);
+-          if (len == 8)
+-            memcpy(speed, freq_ref_ptr, 8);
+-          else if (len == 4) {
+-            uint32_t v;
+-            memcpy(&v, freq_ref_ptr, 4);
+-            *speed = v;
+-          } else {
+-            *speed = 0;
+-          }
++  // Braces ensure goto doesn't jump into device_type_str's and
++  // clock_frequency_str's lifetimes after their initialization
++  {
++    kr = pIOMasterPort(MACH_PORT_NULL, &mach_port);
++    assert(kr == KERN_SUCCESS);
++    CFMutableDictionaryRef classes_to_match
++        = pIOServiceMatching("IOPlatformDevice");
++    kr = pIOServiceGetMatchingServices(mach_port, classes_to_match, &it);
++    assert(kr == KERN_SUCCESS);
++    service = pIOIteratorNext(it);
+ 
+-          pCFRelease(freq_ref);
+-          pCFRelease(data);
+-          break;
++    CFStringRef device_type_str = S("device_type");
++    CFStringRef clock_frequency_str = S("clock-frequency");
++
++    while (service != 0) {
++      CFDataRef data;
++      data = pIORegistryEntryCreateCFProperty(service,
++                                              device_type_str,
++                                              NULL,
++                                              0);
++      if (data) {
++        const UInt8* raw = pCFDataGetBytePtr(data);
++        if (strncmp((char*)raw, "cpu", 3) == 0 ||
++            strncmp((char*)raw, "processor", 9) == 0) {
++          CFDataRef freq_ref;
++          freq_ref = pIORegistryEntryCreateCFProperty(service,
++                                                      clock_frequency_str,
++                                                      NULL,
++                                                      0);
++          if (freq_ref) {
++            const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref);
++            CFIndex len = pCFDataGetLength(freq_ref);
++            if (len == 8)
++              memcpy(speed, freq_ref_ptr, 8);
++            else if (len == 4) {
++              uint32_t v;
++              memcpy(&v, freq_ref_ptr, 4);
++              *speed = v;
++            } else {
++              *speed = 0;
++            }
++
++            pCFRelease(freq_ref);
++            pCFRelease(data);
++            break;
++          }
+         }
++        pCFRelease(data);
+       }
+-      pCFRelease(data);
+-    }
+ 
+-    service = pIOIteratorNext(it);
+-  }
++      service = pIOIteratorNext(it);
++    }
+ 
+-  pIOObjectRelease(it);
++    pIOObjectRelease(it);
+ 
+-  err = 0;
++    err = 0;
+ 
+-  if (device_type_str != NULL)
+-    pCFRelease(device_type_str);
+-  if (clock_frequency_str != NULL)
+-    pCFRelease(clock_frequency_str);
++    if (device_type_str != NULL)
++      pCFRelease(device_type_str);
++    if (clock_frequency_str != NULL)
++      pCFRelease(clock_frequency_str);
++  }
+ 
+ out:
+   if (core_foundation_handle != NULL)
+diff --git a/src/unix/internal.h b/src/unix/internal.h
+index cee35c21..f9d1666d 100644
+--- a/src/unix/internal.h
++++ b/src/unix/internal.h
+@@ -312,8 +312,8 @@ UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
+   loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
+ }
+ 
+-UV_UNUSED(static char* uv__basename_r(const char* path)) {
+-  char* s;
++UV_UNUSED(static const char* uv__basename_r(const char* path)) {
++  const char* s;
+ 
+   s = strrchr(path, '/');
+   if (s == NULL)
+diff --git a/src/unix/thread.c b/src/unix/thread.c
+index 759cd0c2..64726bd6 100644
+--- a/src/unix/thread.c
++++ b/src/unix/thread.c
+@@ -244,12 +244,6 @@ int uv_thread_create_ex(uv_thread_t* tid,
+   size_t stack_size;
+   size_t min_stack_size;
+ 
+-  /* Used to squelch a -Wcast-function-type warning. */
+-  union {
+-    void (*in)(void*);
+-    void* (*out)(void*);
+-  } f;
+-
+   stack_size =
+       params->flags & UV_THREAD_HAS_STACK_SIZE ? params->stack_size : 0;
+ 
+diff --git a/src/uv-common.c b/src/uv-common.c
+index dfb606e3..49026c03 100644
+--- a/src/uv-common.c
++++ b/src/uv-common.c
+@@ -758,6 +758,10 @@ void uv__fs_readdir_cleanup(uv_fs_t* req) {
+   }
+ }
+ 
++#ifdef __clang__
++# pragma clang diagnostic push
++# pragma clang diagnostic ignored "-Wvarargs"
++#endif
+ 
+ int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
+   va_list ap;
+@@ -771,6 +775,10 @@ int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
+   return err;
+ }
+ 
++#ifdef __clang__
++# pragma clang diagnostic pop
++#endif
++
+ 
+ static uv_loop_t default_loop_struct;
+ static uv_loop_t* default_loop_ptr;
+diff --git a/src/win/fs-event.c b/src/win/fs-event.c
+index 15046731..3244a4e4 100644
+--- a/src/win/fs-event.c
++++ b/src/win/fs-event.c
+@@ -19,6 +19,8 @@
+  * IN THE SOFTWARE.
+  */
+ 
++#define _CRT_NONSTDC_NO_WARNINGS
++
+ #include <assert.h>
+ #include <errno.h>
+ #include <stdio.h>
+diff --git a/src/win/fs.c b/src/win/fs.c
+index 8374012f..f71b3c04 100644
+--- a/src/win/fs.c
++++ b/src/win/fs.c
+@@ -19,6 +19,8 @@
+  * IN THE SOFTWARE.
+  */
+ 
++#define _CRT_NONSTDC_NO_WARNINGS
++
+ #include <assert.h>
+ #include <stdlib.h>
+ #include <direct.h>
+diff --git a/src/win/pipe.c b/src/win/pipe.c
+index cd77061a..f413a72d 100644
+--- a/src/win/pipe.c
++++ b/src/win/pipe.c
+@@ -19,6 +19,8 @@
+  * IN THE SOFTWARE.
+  */
+ 
++#define _CRT_NONSTDC_NO_WARNINGS
++
+ #include <assert.h>
+ #include <io.h>
+ #include <stdio.h>
+diff --git a/src/win/process.c b/src/win/process.c
+index e857db3e..a49016f6 100644
+--- a/src/win/process.c
++++ b/src/win/process.c
+@@ -19,6 +19,8 @@
+  * IN THE SOFTWARE.
+  */
+ 
++#define _CRT_NONSTDC_NO_WARNINGS
++
+ #include <assert.h>
+ #include <io.h>
+ #include <stdio.h>
+diff --git a/src/win/tty.c b/src/win/tty.c
+index 267ca645..d7522668 100644
+--- a/src/win/tty.c
++++ b/src/win/tty.c
+@@ -19,6 +19,8 @@
+  * IN THE SOFTWARE.
+  */
+ 
++#define _CRT_NONSTDC_NO_WARNINGS
++
+ #include <assert.h>
+ #include <io.h>
+ #include <string.h>
diff --git a/upstream_utils/libuv_patches/0003-Preprocessor-cleanup.patch b/upstream_utils/libuv_patches/0003-Preprocessor-cleanup.patch
new file mode 100644
index 0000000..f55f5cc
--- /dev/null
+++ b/upstream_utils/libuv_patches/0003-Preprocessor-cleanup.patch
@@ -0,0 +1,179 @@
+From dec4f95751a103f132e9674adf184188ec69176f Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 26 Apr 2022 15:19:14 -0400
+Subject: [PATCH 3/9] Preprocessor cleanup
+
+---
+ include/uv.h        | 18 +-----------------
+ include/uv/unix.h   |  8 --------
+ include/uv/win.h    |  6 +-----
+ src/unix/internal.h |  2 ++
+ src/win/fs.c        |  1 +
+ src/win/tty.c       |  2 ++
+ src/win/util.c      |  8 ++++++++
+ src/win/winsock.c   |  1 +
+ 8 files changed, 16 insertions(+), 30 deletions(-)
+
+diff --git a/include/uv.h b/include/uv.h
+index ee1c94cc..dbaeb1e9 100644
+--- a/include/uv.h
++++ b/include/uv.h
+@@ -23,9 +23,6 @@
+ 
+ #ifndef UV_H
+ #define UV_H
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+ 
+ #if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED)
+ #error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both."
+@@ -56,11 +53,7 @@ extern "C" {
+ #include <stddef.h>
+ #include <stdio.h>
+ 
+-#if defined(_MSC_VER) && _MSC_VER < 1600
+-# include "uv/stdint-msvc2008.h"
+-#else
+-# include <stdint.h>
+-#endif
++#include <stdint.h>
+ 
+ #if defined(_WIN32)
+ # include "uv/win.h"
+@@ -767,16 +760,10 @@ UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
+ UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state);
+ UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state);
+ 
+-#ifdef __cplusplus
+-extern "C++" {
+-
+ inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
+   return uv_tty_set_mode(handle, static_cast<uv_tty_mode_t>(mode));
+ }
+ 
+-}
+-#endif
+-
+ UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
+ 
+ /*
+@@ -1844,7 +1831,4 @@ UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data);
+ #undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
+ #undef UV__ERR
+ 
+-#ifdef __cplusplus
+-}
+-#endif
+ #endif /* UV_H */
+diff --git a/include/uv/unix.h b/include/uv/unix.h
+index 420be86c..256fef37 100644
+--- a/include/uv/unix.h
++++ b/include/uv/unix.h
+@@ -47,14 +47,6 @@
+ 
+ #if defined(__linux__)
+ # include "uv/linux.h"
+-#elif defined (__MVS__)
+-# include "uv/os390.h"
+-#elif defined(__PASE__)  /* __PASE__ and _AIX are both defined on IBM i */
+-# include "uv/posix.h"  /* IBM i needs uv/posix.h, not uv/aix.h */
+-#elif defined(_AIX)
+-# include "uv/aix.h"
+-#elif defined(__sun)
+-# include "uv/sunos.h"
+ #elif defined(__APPLE__)
+ # include "uv/darwin.h"
+ #elif defined(__DragonFly__)       || \
+diff --git a/include/uv/win.h b/include/uv/win.h
+index 10d5e8f1..0a33366f 100644
+--- a/include/uv/win.h
++++ b/include/uv/win.h
+@@ -60,11 +60,7 @@ typedef struct pollfd {
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ 
+-#if defined(_MSC_VER) && _MSC_VER < 1600
+-# include "uv/stdint-msvc2008.h"
+-#else
+-# include <stdint.h>
+-#endif
++#include <stdint.h>
+ 
+ #include "uv/tree.h"
+ #include "uv/threadpool.h"
+diff --git a/src/unix/internal.h b/src/unix/internal.h
+index f9d1666d..2b654157 100644
+--- a/src/unix/internal.h
++++ b/src/unix/internal.h
+@@ -192,6 +192,8 @@ struct uv__stream_queued_fds_s {
+ #if defined(__linux__) && O_NDELAY != O_NONBLOCK
+ #undef uv__nonblock
+ #define uv__nonblock uv__nonblock_fcntl
++#undef UV__NONBLOCK_IS_IOCTL
++#define UV__NONBLOCK_IS_FCNTL
+ #endif
+ 
+ /* core */
+diff --git a/src/win/fs.c b/src/win/fs.c
+index f71b3c04..71c9b169 100644
+--- a/src/win/fs.c
++++ b/src/win/fs.c
+@@ -38,6 +38,7 @@
+ #include "handle-inl.h"
+ #include "fs-fd-hash-inl.h"
+ 
++#pragma comment(lib, "Advapi32.lib")
+ 
+ #define UV_FS_FREE_PATHS         0x0002
+ #define UV_FS_FREE_PTR           0x0008
+diff --git a/src/win/tty.c b/src/win/tty.c
+index d7522668..9753784d 100644
+--- a/src/win/tty.c
++++ b/src/win/tty.c
+@@ -42,6 +42,8 @@
+ #include "stream-inl.h"
+ #include "req-inl.h"
+ 
++#pragma comment(lib, "User32.lib")
++
+ #ifndef InterlockedOr
+ # define InterlockedOr _InterlockedOr
+ #endif
+diff --git a/src/win/util.c b/src/win/util.c
+index c655f532..7a5dd2ef 100644
+--- a/src/win/util.c
++++ b/src/win/util.c
+@@ -63,12 +63,20 @@
+ 
+ 
+ /* A RtlGenRandom() by any other name... */
++extern "C" {
+ extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
++}
+ 
+ /* Cached copy of the process title, plus a mutex guarding it. */
+ static char *process_title;
+ static CRITICAL_SECTION process_title_lock;
+ 
++#pragma comment(lib, "Advapi32.lib")
++#pragma comment(lib, "IPHLPAPI.lib")
++#pragma comment(lib, "Psapi.lib")
++#pragma comment(lib, "Userenv.lib")
++#pragma comment(lib, "kernel32.lib")
++
+ /* Frequency of the high-resolution clock. */
+ static uint64_t hrtime_frequency_ = 0;
+ 
+diff --git a/src/win/winsock.c b/src/win/winsock.c
+index a68b0953..7843e9f1 100644
+--- a/src/win/winsock.c
++++ b/src/win/winsock.c
+@@ -25,6 +25,7 @@
+ #include "uv.h"
+ #include "internal.h"
+ 
++#pragma comment(lib, "Ws2_32.lib")
+ 
+ /* Whether there are any non-IFS LSPs stacked on TCP */
+ int uv_tcp_non_ifs_lsp_ipv4;
diff --git a/upstream_utils/libuv_patches/0004-Cleanup-problematic-language.patch b/upstream_utils/libuv_patches/0004-Cleanup-problematic-language.patch
new file mode 100644
index 0000000..a29043b
--- /dev/null
+++ b/upstream_utils/libuv_patches/0004-Cleanup-problematic-language.patch
@@ -0,0 +1,61 @@
+From 2d06f216dec3abbeaaabb465b945e09856d1b687 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 26 Apr 2022 15:24:47 -0400
+Subject: [PATCH 4/9] Cleanup problematic language
+
+---
+ src/unix/tty.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/src/unix/tty.c b/src/unix/tty.c
+index b4150525..ed81e26a 100644
+--- a/src/unix/tty.c
++++ b/src/unix/tty.c
+@@ -79,7 +79,7 @@ int uv__tcsetattr(int fd, int how, const struct termios *term) {
+   return 0;
+ }
+ 
+-static int uv__tty_is_slave(const int fd) {
++static int uv__tty_is_peripheral(const int fd) {
+   int result;
+ #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+   int dummy;
+@@ -91,15 +91,16 @@ static int uv__tty_is_slave(const int fd) {
+   result = ioctl(fd, TIOCPTYGNAME, &dummy) != 0;
+ #elif defined(__NetBSD__)
+   /*
+-   * NetBSD as an extension returns with ptsname(3) and ptsname_r(3) the slave
+-   * device name for both descriptors, the master one and slave one.
++   * NetBSD as an extension returns with ptsname(3) and ptsname_r(3) the
++   * peripheral device name for both descriptors, the controller one and
++   * peripheral one.
+    *
+    * Implement function to compare major device number with pts devices.
+    *
+    * The major numbers are machine-dependent, on NetBSD/amd64 they are
+    * respectively:
+-   *  - master tty: ptc - major 6
+-   *  - slave tty:  pts - major 5
++   *  - controller tty: ptc - major 6
++   *  - peripheral tty:  pts - major 5
+    */
+ 
+   struct stat sb;
+@@ -174,12 +175,12 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) {
+    * other processes.
+    */
+   if (type == UV_TTY) {
+-    /* Reopening a pty in master mode won't work either because the reopened
+-     * pty will be in slave mode (*BSD) or reopening will allocate a new
+-     * master/slave pair (Linux). Therefore check if the fd points to a
+-     * slave device.
++    /* Reopening a pty in controller mode won't work either because the reopened
++     * pty will be in peripheral mode (*BSD) or reopening will allocate a new
++     * controller/peripheral pair (Linux). Therefore check if the fd points to a
++     * peripheral device.
+      */
+-    if (uv__tty_is_slave(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
++    if (uv__tty_is_peripheral(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
+       r = uv__open_cloexec(path, mode | O_NOCTTY);
+     else
+       r = -1;
diff --git a/upstream_utils/libuv_patches/0005-Use-roborio-time.patch b/upstream_utils/libuv_patches/0005-Use-roborio-time.patch
new file mode 100644
index 0000000..46cc46f
--- /dev/null
+++ b/upstream_utils/libuv_patches/0005-Use-roborio-time.patch
@@ -0,0 +1,42 @@
+From 690d487df2e60a01ab811aba34587466a38caead Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 26 Apr 2022 15:26:03 -0400
+Subject: [PATCH 5/9] Use roborio time
+
+---
+ src/unix/linux-core.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c
+index 85f3fc01..12ed7ff1 100644
+--- a/src/unix/linux-core.c
++++ b/src/unix/linux-core.c
+@@ -67,6 +67,10 @@
+ # define CLOCK_MONOTONIC_COARSE 6
+ #endif
+ 
++#ifdef __FRC_ROBORIO__
++#include "wpi/timestamp.h"
++#endif
++
+ /* This is rather annoying: CLOCK_BOOTTIME lives in <linux/time.h> but we can't
+  * include that file because it conflicts with <time.h>. We'll just have to
+  * define it ourselves.
+@@ -118,6 +122,9 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
+ 
+ 
+ uint64_t uv__hrtime(uv_clocktype_t type) {
++#ifdef __FRC_ROBORIO__
++  return wpi::Now() * 1000u;
++#else
+   static clock_t fast_clock_id = -1;
+   struct timespec t;
+   clock_t clock_id;
+@@ -151,6 +158,7 @@ done:
+     return 0;  /* Not really possible. */
+ 
+   return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec;
++#endif
+ }
+ 
+ 
diff --git a/upstream_utils/libuv_patches/0006-Style-comments-cleanup.patch b/upstream_utils/libuv_patches/0006-Style-comments-cleanup.patch
new file mode 100644
index 0000000..964d944
--- /dev/null
+++ b/upstream_utils/libuv_patches/0006-Style-comments-cleanup.patch
@@ -0,0 +1,102 @@
+From ad60aa8e1c03cc5f0c88159d37f63b0c063927c7 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 26 Apr 2022 15:28:52 -0400
+Subject: [PATCH 6/9] Style / comments cleanup
+
+---
+ src/fs-poll.c     | 1 +
+ src/unix/core.c   | 1 +
+ src/unix/thread.c | 3 +--
+ src/uv-common.c   | 1 +
+ src/win/process.c | 1 -
+ src/win/winsock.c | 1 +
+ 6 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/fs-poll.c b/src/fs-poll.c
+index 5a39daed..1a7ca70d 100644
+--- a/src/fs-poll.c
++++ b/src/fs-poll.c
+@@ -34,6 +34,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ 
++
+ struct poll_ctx {
+   uv_fs_poll_t* parent_handle;
+   int busy_polling;
+diff --git a/src/unix/core.c b/src/unix/core.c
+index 223c5513..4c23f608 100644
+--- a/src/unix/core.c
++++ b/src/unix/core.c
+@@ -544,6 +544,7 @@ int uv__accept(int sockfd) {
+   return peerfd;
+ }
+ 
++
+ #if defined(__APPLE__)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
+diff --git a/src/unix/thread.c b/src/unix/thread.c
+index 64726bd6..392a0715 100644
+--- a/src/unix/thread.c
++++ b/src/unix/thread.c
+@@ -85,7 +85,6 @@ error2:
+   return rc;
+ }
+ 
+-
+ int uv_barrier_wait(uv_barrier_t* barrier) {
+   struct _uv_barrier* b;
+   int last;
+@@ -94,6 +93,7 @@ int uv_barrier_wait(uv_barrier_t* barrier) {
+     return UV_EINVAL;
+ 
+   b = barrier->b;
++  /* Lock the mutex*/
+   uv_mutex_lock(&b->mutex);
+ 
+   if (++b->in == b->threshold) {
+@@ -113,7 +113,6 @@ int uv_barrier_wait(uv_barrier_t* barrier) {
+   return last;
+ }
+ 
+-
+ void uv_barrier_destroy(uv_barrier_t* barrier) {
+   struct _uv_barrier* b;
+ 
+diff --git a/src/uv-common.c b/src/uv-common.c
+index 49026c03..c9a32c03 100644
+--- a/src/uv-common.c
++++ b/src/uv-common.c
+@@ -758,6 +758,7 @@ void uv__fs_readdir_cleanup(uv_fs_t* req) {
+   }
+ }
+ 
++
+ #ifdef __clang__
+ # pragma clang diagnostic push
+ # pragma clang diagnostic ignored "-Wvarargs"
+diff --git a/src/win/process.c b/src/win/process.c
+index a49016f6..8e7835a5 100644
+--- a/src/win/process.c
++++ b/src/win/process.c
+@@ -35,7 +35,6 @@
+ #include "handle-inl.h"
+ #include "req-inl.h"
+ 
+-
+ #define SIGKILL         9
+ 
+ 
+diff --git a/src/win/winsock.c b/src/win/winsock.c
+index 7843e9f1..cda82bc3 100644
+--- a/src/win/winsock.c
++++ b/src/win/winsock.c
+@@ -25,6 +25,7 @@
+ #include "uv.h"
+ #include "internal.h"
+ 
++
+ #pragma comment(lib, "Ws2_32.lib")
+ 
+ /* Whether there are any non-IFS LSPs stacked on TCP */
diff --git a/upstream_utils/libuv_patches/0007-Squelch-GCC-12.1-warnings.patch b/upstream_utils/libuv_patches/0007-Squelch-GCC-12.1-warnings.patch
new file mode 100644
index 0000000..92032da
--- /dev/null
+++ b/upstream_utils/libuv_patches/0007-Squelch-GCC-12.1-warnings.patch
@@ -0,0 +1,52 @@
+From ee8a72764f602928cc08d16d661602c0aefde050 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Tue, 17 May 2022 21:36:57 -0700
+Subject: [PATCH 7/9] Squelch GCC 12.1 warnings
+
+---
+ src/unix/stream.c | 9 +++++++++
+ src/uv-common.c   | 9 +++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/src/unix/stream.c b/src/unix/stream.c
+index c6cc50e7..fa25812a 100644
+--- a/src/unix/stream.c
++++ b/src/unix/stream.c
+@@ -938,7 +938,16 @@ static void uv__write_callbacks(uv_stream_t* stream) {
+   if (QUEUE_EMPTY(&stream->write_completed_queue))
+     return;
+ 
++// FIXME: GCC 12.1 gives a possibly real warning, but we don't know how to fix
++// it
++#if __GNUC__ >= 12
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wdangling-pointer="
++#endif  // __GNUC__ >= 12
+   QUEUE_MOVE(&stream->write_completed_queue, &pq);
++#if __GNUC__ >= 12
++#pragma GCC diagnostic pop
++#endif  // __GNUC__ >= 12
+ 
+   while (!QUEUE_EMPTY(&pq)) {
+     /* Pop a req off write_completed_queue. */
+diff --git a/src/uv-common.c b/src/uv-common.c
+index c9a32c03..8ab600df 100644
+--- a/src/uv-common.c
++++ b/src/uv-common.c
+@@ -504,7 +504,16 @@ void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
+   QUEUE* q;
+   uv_handle_t* h;
+ 
++// FIXME: GCC 12.1 gives a possibly real warning, but we don't know how to fix
++// it
++#if __GNUC__ >= 12
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wdangling-pointer="
++#endif  // __GNUC__ >= 12
+   QUEUE_MOVE(&loop->handle_queue, &queue);
++#if __GNUC__ >= 12
++#pragma GCC diagnostic pop
++#endif  // __GNUC__ >= 12
+   while (!QUEUE_EMPTY(&queue)) {
+     q = QUEUE_HEAD(&queue);
+     h = QUEUE_DATA(q, uv_handle_t, handle_queue);
diff --git a/upstream_utils/libuv_patches/0008-Fix-Win32-warning-suppression-pragma.patch b/upstream_utils/libuv_patches/0008-Fix-Win32-warning-suppression-pragma.patch
new file mode 100644
index 0000000..bdc5f61
--- /dev/null
+++ b/upstream_utils/libuv_patches/0008-Fix-Win32-warning-suppression-pragma.patch
@@ -0,0 +1,22 @@
+From 49d5945dde1d182fd2d75cdf550120951796cb1f Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Sat, 21 May 2022 22:58:06 -0700
+Subject: [PATCH 8/9] Fix Win32 warning suppression pragma
+
+---
+ src/win/util.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/win/util.c b/src/win/util.c
+index 7a5dd2ef..d9888aec 100644
+--- a/src/win/util.c
++++ b/src/win/util.c
+@@ -1750,7 +1750,7 @@ int uv_os_uname(uv_utsname_t* buffer) {
+   } else {
+     /* Silence GetVersionEx() deprecation warning. */
+     #ifdef _MSC_VER
+-    #pragma warning(suppress : 4996)
++    #pragma warning(disable : 4996)
+     #endif
+     if (GetVersionExW(&os_info) == 0) {
+       r = uv_translate_sys_error(GetLastError());
diff --git a/upstream_utils/libuv_patches/0009-Avoid-unused-variable-warning-on-Mac.patch b/upstream_utils/libuv_patches/0009-Avoid-unused-variable-warning-on-Mac.patch
new file mode 100644
index 0000000..8db2deb
--- /dev/null
+++ b/upstream_utils/libuv_patches/0009-Avoid-unused-variable-warning-on-Mac.patch
@@ -0,0 +1,21 @@
+From d83eaeff1f53bc3dede8a46a05cdb3ca94d1aac4 Mon Sep 17 00:00:00 2001
+From: Peter Johnson <johnson.peter@gmail.com>
+Date: Sun, 5 Jun 2022 15:40:35 -0700
+Subject: [PATCH 9/9] Avoid unused variable warning on Mac
+
+---
+ src/unix/darwin.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/unix/darwin.c b/src/unix/darwin.c
+index eeb35720..ed51a6ad 100644
+--- a/src/unix/darwin.c
++++ b/src/unix/darwin.c
+@@ -257,6 +257,7 @@ static int uv__get_cpu_speed(uint64_t* speed) {
+   // clock_frequency_str's lifetimes after their initialization
+   {
+     kr = pIOMasterPort(MACH_PORT_NULL, &mach_port);
++    (void) kr;
+     assert(kr == KERN_SUCCESS);
+     CFMutableDictionaryRef classes_to_match
+         = pIOServiceMatching("IOPlatformDevice");
diff --git a/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch b/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch
new file mode 100644
index 0000000..5d6916d
--- /dev/null
+++ b/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch
@@ -0,0 +1,22 @@
+From 3d09b3d7b78ffc037a32725cc4002976b908d965 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 20:50:26 -0400
+Subject: [PATCH 01/28] Fix spelling/language errors
+
+---
+ llvm/include/llvm/Support/ErrorHandling.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
+index f980510d3..6791df6be 100644
+--- a/llvm/include/llvm/Support/ErrorHandling.h
++++ b/llvm/include/llvm/Support/ErrorHandling.h
+@@ -44,7 +44,7 @@ namespace llvm {
+   void install_fatal_error_handler(fatal_error_handler_t handler,
+                                    void *user_data = nullptr);
+ 
+-  /// Restores default error handling behaviour.
++  /// Restores default error handling behavior.
+   void remove_fatal_error_handler();
+ 
+   /// ScopedFatalErrorHandler - This is a simple helper class which just
diff --git a/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch b/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch
new file mode 100644
index 0000000..eb5b759
--- /dev/null
+++ b/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch
@@ -0,0 +1,1894 @@
+From afca62cd2f1616bcf2e648dc121a057d59168424 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:09:18 -0400
+Subject: [PATCH 02/28] Remove StringRef, ArrayRef, and Optional
+
+---
+ llvm/include/llvm/ADT/PointerUnion.h          |  1 -
+ llvm/include/llvm/ADT/SmallSet.h              | 13 ++--
+ llvm/include/llvm/ADT/SmallString.h           | 77 ++++++++++---------
+ llvm/include/llvm/ADT/StringMap.h             | 34 ++++----
+ llvm/include/llvm/ADT/StringMapEntry.h        | 25 +++---
+ llvm/include/llvm/Support/Chrono.h            | 10 +--
+ llvm/include/llvm/Support/Compiler.h          |  2 +-
+ llvm/include/llvm/Support/ConvertUTF.h        | 28 ++++---
+ llvm/include/llvm/Support/DJB.h               |  6 +-
+ llvm/include/llvm/Support/ErrorHandling.h     |  9 +--
+ .../llvm/Support/SmallVectorMemoryBuffer.h    |  6 +-
+ llvm/include/llvm/Support/VersionTuple.h      | 20 ++---
+ .../llvm/Support/Windows/WindowsSupport.h     |  4 +-
+ llvm/include/llvm/Support/raw_ostream.h       | 51 ++++++------
+ llvm/lib/Support/ConvertUTFWrapper.cpp        | 32 ++++----
+ llvm/lib/Support/ErrorHandling.cpp            | 13 ++--
+ llvm/lib/Support/SmallVector.cpp              |  5 +-
+ llvm/lib/Support/StringMap.cpp                | 12 +--
+ llvm/lib/Support/raw_ostream.cpp              | 25 +++---
+ llvm/unittests/ADT/DenseMapTest.cpp           | 25 ------
+ llvm/unittests/ADT/FunctionExtrasTest.cpp     | 12 +--
+ llvm/unittests/ADT/HashingTest.cpp            |  2 +-
+ llvm/unittests/ADT/SmallPtrSetTest.cpp        |  1 -
+ llvm/unittests/ADT/SmallStringTest.cpp        | 50 ++++++------
+ llvm/unittests/ADT/SmallVectorTest.cpp        | 20 +----
+ llvm/unittests/ADT/StringMapTest.cpp          | 32 ++++----
+ llvm/unittests/Support/ConvertUTFTest.cpp     | 37 +++++----
+ 27 files changed, 248 insertions(+), 304 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h
+index 04d566bbc..1d4cc747c 100644
+--- a/llvm/include/llvm/ADT/PointerUnion.h
++++ b/llvm/include/llvm/ADT/PointerUnion.h
+@@ -17,7 +17,6 @@
+ 
+ #include "llvm/ADT/DenseMapInfo.h"
+ #include "llvm/ADT/PointerIntPair.h"
+-#include "llvm/ADT/STLExtras.h"
+ #include "llvm/Support/PointerLikeTypeTraits.h"
+ #include <algorithm>
+ #include <cassert>
+diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h
+index 0eed85449..bfe93e997 100644
+--- a/llvm/include/llvm/ADT/SmallSet.h
++++ b/llvm/include/llvm/ADT/SmallSet.h
+@@ -14,15 +14,14 @@
+ #ifndef LLVM_ADT_SMALLSET_H
+ #define LLVM_ADT_SMALLSET_H
+ 
+-#include "llvm/ADT/None.h"
+ #include "llvm/ADT/SmallPtrSet.h"
+ #include "llvm/ADT/SmallVector.h"
+-#include "llvm/ADT/STLExtras.h"
+ #include "llvm/ADT/iterator.h"
+ #include "llvm/Support/Compiler.h"
+ #include "llvm/Support/type_traits.h"
+ #include <cstddef>
+ #include <functional>
++#include <optional>
+ #include <set>
+ #include <type_traits>
+ #include <utility>
+@@ -179,16 +178,16 @@ public:
+   /// concept.
+   // FIXME: Add iterators that abstract over the small and large form, and then
+   // return those here.
+-  std::pair<NoneType, bool> insert(const T &V) {
++  std::pair<std::nullopt_t, bool> insert(const T &V) {
+     if (!isSmall())
+-      return std::make_pair(None, Set.insert(V).second);
++      return std::make_pair(std::nullopt, Set.insert(V).second);
+ 
+     VIterator I = vfind(V);
+     if (I != Vector.end())    // Don't reinsert if it already exists.
+-      return std::make_pair(None, false);
++      return std::make_pair(std::nullopt, false);
+     if (Vector.size() < N) {
+       Vector.push_back(V);
+-      return std::make_pair(None, true);
++      return std::make_pair(std::nullopt, true);
+     }
+ 
+     // Otherwise, grow from vector to set.
+@@ -197,7 +196,7 @@ public:
+       Vector.pop_back();
+     }
+     Set.insert(V);
+-    return std::make_pair(None, true);
++    return std::make_pair(std::nullopt, true);
+   }
+ 
+   template <typename IterT>
+diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h
+index 874968f0a..50cbdade4 100644
+--- a/llvm/include/llvm/ADT/SmallString.h
++++ b/llvm/include/llvm/ADT/SmallString.h
+@@ -15,8 +15,9 @@
+ #define LLVM_ADT_SMALLSTRING_H
+ 
+ #include "llvm/ADT/SmallVector.h"
+-#include "llvm/ADT/StringRef.h"
+ #include <cstddef>
++#include <string>
++#include <string_view>
+ 
+ namespace llvm {
+ 
+@@ -28,11 +29,11 @@ public:
+   /// Default ctor - Initialize to empty.
+   SmallString() = default;
+ 
+-  /// Initialize from a StringRef.
+-  SmallString(StringRef S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
++  /// Initialize from a std::string_view.
++  SmallString(std::string_view S) : SmallVector<char, InternalLen>(S.begin(), S.end()) {}
+ 
+-  /// Initialize by concatenating a list of StringRefs.
+-  SmallString(std::initializer_list<StringRef> Refs)
++  /// Initialize by concatenating a list of std::string_views.
++  SmallString(std::initializer_list<std::string_view> Refs)
+       : SmallVector<char, InternalLen>() {
+     this->append(Refs);
+   }
+@@ -47,13 +48,13 @@ public:
+ 
+   using SmallVector<char, InternalLen>::assign;
+ 
+-  /// Assign from a StringRef.
+-  void assign(StringRef RHS) {
++  /// Assign from a std::string_view.
++  void assign(std::string_view RHS) {
+     SmallVectorImpl<char>::assign(RHS.begin(), RHS.end());
+   }
+ 
+-  /// Assign from a list of StringRefs.
+-  void assign(std::initializer_list<StringRef> Refs) {
++  /// Assign from a list of std::string_views.
++  void assign(std::initializer_list<std::string_view> Refs) {
+     this->clear();
+     append(Refs);
+   }
+@@ -64,19 +65,19 @@ public:
+ 
+   using SmallVector<char, InternalLen>::append;
+ 
+-  /// Append from a StringRef.
+-  void append(StringRef RHS) {
++  /// Append from a std::string_view.
++  void append(std::string_view RHS) {
+     SmallVectorImpl<char>::append(RHS.begin(), RHS.end());
+   }
+ 
+-  /// Append from a list of StringRefs.
+-  void append(std::initializer_list<StringRef> Refs) {
++  /// Append from a list of std::string_views.
++  void append(std::initializer_list<std::string_view> Refs) {
+     size_t CurrentSize = this->size();
+     size_t SizeNeeded = CurrentSize;
+-    for (const StringRef &Ref : Refs)
++    for (const std::string_view &Ref : Refs)
+       SizeNeeded += Ref.size();
+     this->resize_for_overwrite(SizeNeeded);
+-    for (const StringRef &Ref : Refs) {
++    for (const std::string_view &Ref : Refs) {
+       std::copy(Ref.begin(), Ref.end(), this->begin() + CurrentSize);
+       CurrentSize += Ref.size();
+     }
+@@ -89,29 +90,29 @@ public:
+ 
+   /// Check for string equality.  This is more efficient than compare() when
+   /// the relative ordering of inequal strings isn't needed.
+-  bool equals(StringRef RHS) const {
++  bool equals(std::string_view RHS) const {
+     return str().equals(RHS);
+   }
+ 
+   /// Check for string equality, ignoring case.
+-  bool equals_insensitive(StringRef RHS) const {
++  bool equals_insensitive(std::string_view RHS) const {
+     return str().equals_insensitive(RHS);
+   }
+ 
+   /// Compare two strings; the result is -1, 0, or 1 if this string is
+   /// lexicographically less than, equal to, or greater than the \p RHS.
+-  int compare(StringRef RHS) const {
++  int compare(std::string_view RHS) const {
+     return str().compare(RHS);
+   }
+ 
+   /// compare_insensitive - Compare two strings, ignoring case.
+-  int compare_insensitive(StringRef RHS) const {
++  int compare_insensitive(std::string_view RHS) const {
+     return str().compare_insensitive(RHS);
+   }
+ 
+   /// compare_numeric - Compare two strings, treating sequences of digits as
+   /// numbers.
+-  int compare_numeric(StringRef RHS) const {
++  int compare_numeric(std::string_view RHS) const {
+     return str().compare_numeric(RHS);
+   }
+ 
+@@ -120,12 +121,12 @@ public:
+   /// @{
+ 
+   /// startswith - Check if this string starts with the given \p Prefix.
+-  bool startswith(StringRef Prefix) const {
++  bool startswith(std::string_view Prefix) const {
+     return str().startswith(Prefix);
+   }
+ 
+   /// endswith - Check if this string ends with the given \p Suffix.
+-  bool endswith(StringRef Suffix) const {
++  bool endswith(std::string_view Suffix) const {
+     return str().endswith(Suffix);
+   }
+ 
+@@ -145,7 +146,7 @@ public:
+   ///
+   /// \returns The index of the first occurrence of \p Str, or npos if not
+   /// found.
+-  size_t find(StringRef Str, size_t From = 0) const {
++  size_t find(std::string_view Str, size_t From = 0) const {
+     return str().find(Str, From);
+   }
+ 
+@@ -153,7 +154,7 @@ public:
+   ///
+   /// \returns The index of the last occurrence of \p C, or npos if not
+   /// found.
+-  size_t rfind(char C, size_t From = StringRef::npos) const {
++  size_t rfind(char C, size_t From = std::string_view::npos) const {
+     return str().rfind(C, From);
+   }
+ 
+@@ -161,7 +162,7 @@ public:
+   ///
+   /// \returns The index of the last occurrence of \p Str, or npos if not
+   /// found.
+-  size_t rfind(StringRef Str) const {
++  size_t rfind(std::string_view Str) const {
+     return str().rfind(Str);
+   }
+ 
+@@ -175,7 +176,7 @@ public:
+   /// not found.
+   ///
+   /// Complexity: O(size() + Chars.size())
+-  size_t find_first_of(StringRef Chars, size_t From = 0) const {
++  size_t find_first_of(std::string_view Chars, size_t From = 0) const {
+     return str().find_first_of(Chars, From);
+   }
+ 
+@@ -189,13 +190,13 @@ public:
+   /// \p Chars, or npos if not found.
+   ///
+   /// Complexity: O(size() + Chars.size())
+-  size_t find_first_not_of(StringRef Chars, size_t From = 0) const {
++  size_t find_first_not_of(std::string_view Chars, size_t From = 0) const {
+     return str().find_first_not_of(Chars, From);
+   }
+ 
+   /// Find the last character in the string that is \p C, or npos if not
+   /// found.
+-  size_t find_last_of(char C, size_t From = StringRef::npos) const {
++  size_t find_last_of(char C, size_t From = std::string_view::npos) const {
+     return str().find_last_of(C, From);
+   }
+ 
+@@ -204,7 +205,7 @@ public:
+   ///
+   /// Complexity: O(size() + Chars.size())
+   size_t find_last_of(
+-      StringRef Chars, size_t From = StringRef::npos) const {
++      std::string_view Chars, size_t From = std::string_view::npos) const {
+     return str().find_last_of(Chars, From);
+   }
+ 
+@@ -219,7 +220,7 @@ public:
+ 
+   /// Return the number of non-overlapped occurrences of \p Str in the
+   /// string.
+-  size_t count(StringRef Str) const {
++  size_t count(std::string_view Str) const {
+     return str().count(Str);
+   }
+ 
+@@ -236,7 +237,7 @@ public:
+   /// \param N The number of characters to included in the substring. If \p N
+   /// exceeds the number of characters remaining in the string, the string
+   /// suffix (starting with \p Start) will be returned.
+-  StringRef substr(size_t Start, size_t N = StringRef::npos) const {
++  std::string_view substr(size_t Start, size_t N = std::string_view::npos) const {
+     return str().substr(Start, N);
+   }
+ 
+@@ -250,14 +251,14 @@ public:
+   /// substring. If this is npos, or less than \p Start, or exceeds the
+   /// number of characters remaining in the string, the string suffix
+   /// (starting with \p Start) will be returned.
+-  StringRef slice(size_t Start, size_t End) const {
++  std::string_view slice(size_t Start, size_t End) const {
+     return str().slice(Start, End);
+   }
+ 
+   // Extra methods.
+ 
+-  /// Explicit conversion to StringRef.
+-  StringRef str() const { return StringRef(this->data(), this->size()); }
++  /// Explicit conversion to std::string_view.
++  std::string_view str() const { return std::string_view(this->begin(), this->size()); }
+ 
+   // TODO: Make this const, if it's safe...
+   const char* c_str() {
+@@ -266,20 +267,20 @@ public:
+     return this->data();
+   }
+ 
+-  /// Implicit conversion to StringRef.
+-  operator StringRef() const { return str(); }
++  /// Implicit conversion to std::string_view.
++  operator std::string_view() const { return str(); }
+ 
+   explicit operator std::string() const {
+     return std::string(this->data(), this->size());
+   }
+ 
+   // Extra operators.
+-  SmallString &operator=(StringRef RHS) {
++  SmallString &operator=(std::string_view RHS) {
+     this->assign(RHS);
+     return *this;
+   }
+ 
+-  SmallString &operator+=(StringRef RHS) {
++  SmallString &operator+=(std::string_view RHS) {
+     this->append(RHS.begin(), RHS.end());
+     return *this;
+   }
+diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
+index 23248093c..8747cdb35 100644
+--- a/llvm/include/llvm/ADT/StringMap.h
++++ b/llvm/include/llvm/ADT/StringMap.h
+@@ -60,12 +60,12 @@ protected:
+   /// specified bucket will be non-null.  Otherwise, it will be null.  In either
+   /// case, the FullHashValue field of the bucket will be set to the hash value
+   /// of the string.
+-  unsigned LookupBucketFor(StringRef Key);
++  unsigned LookupBucketFor(std::string_view Key);
+ 
+   /// FindKey - Look up the bucket that contains the specified key. If it exists
+   /// in the map, return the bucket number of the key.  Otherwise return -1.
+   /// This does not modify the map.
+-  int FindKey(StringRef Key) const;
++  int FindKey(std::string_view Key) const;
+ 
+   /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+   /// delete it.  This aborts if the value isn't in the table.
+@@ -73,7 +73,7 @@ protected:
+ 
+   /// RemoveKey - Remove the StringMapEntry for the specified key from the
+   /// table, returning it.  If the key is not in the table, this returns null.
+-  StringMapEntryBase *RemoveKey(StringRef Key);
++  StringMapEntryBase *RemoveKey(std::string_view Key);
+ 
+   /// Allocate the table with the specified number of buckets and otherwise
+   /// setup the map as empty.
+@@ -126,7 +126,7 @@ public:
+       : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
+         Allocator(A) {}
+ 
+-  StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
++  StringMap(std::initializer_list<std::pair<std::string_view, ValueTy>> List)
+       : StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
+     insert(List);
+   }
+@@ -215,14 +215,14 @@ public:
+                       StringMapKeyIterator<ValueTy>(end()));
+   }
+ 
+-  iterator find(StringRef Key) {
++  iterator find(std::string_view Key) {
+     int Bucket = FindKey(Key);
+     if (Bucket == -1)
+       return end();
+     return iterator(TheTable + Bucket, true);
+   }
+ 
+-  const_iterator find(StringRef Key) const {
++  const_iterator find(std::string_view Key) const {
+     int Bucket = FindKey(Key);
+     if (Bucket == -1)
+       return end();
+@@ -231,7 +231,7 @@ public:
+ 
+   /// lookup - Return the entry for the specified key, or a default
+   /// constructed value if no such entry exists.
+-  ValueTy lookup(StringRef Key) const {
++  ValueTy lookup(std::string_view Key) const {
+     const_iterator it = find(Key);
+     if (it != end())
+       return it->second;
+@@ -240,10 +240,10 @@ public:
+ 
+   /// Lookup the ValueTy for the \p Key, or create a default constructed value
+   /// if the key is not in the map.
+-  ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }
++  ValueTy &operator[](std::string_view Key) { return try_emplace(Key).first->second; }
+ 
+   /// count - Return 1 if the element is in the map, 0 otherwise.
+-  size_type count(StringRef Key) const { return find(Key) == end() ? 0 : 1; }
++  size_type count(std::string_view Key) const { return find(Key) == end() ? 0 : 1; }
+ 
+   template <typename InputTy>
+   size_type count(const StringMapEntry<InputTy> &MapEntry) const {
+@@ -293,7 +293,7 @@ public:
+   /// isn't already in the map. The bool component of the returned pair is true
+   /// if and only if the insertion takes place, and the iterator component of
+   /// the pair points to the element with key equivalent to the key of the pair.
+-  std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
++  std::pair<iterator, bool> insert(std::pair<std::string_view, ValueTy> KV) {
+     return try_emplace(KV.first, std::move(KV.second));
+   }
+ 
+@@ -308,14 +308,14 @@ public:
+   ///  Inserts elements from initializer list ilist. If multiple elements in
+   /// the range have keys that compare equivalent, it is unspecified which
+   /// element is inserted
+-  void insert(std::initializer_list<std::pair<StringRef, ValueTy>> List) {
++  void insert(std::initializer_list<std::pair<std::string_view, ValueTy>> List) {
+     insert(List.begin(), List.end());
+   }
+ 
+   /// Inserts an element or assigns to the current element if the key already
+   /// exists. The return type is the same as try_emplace.
+   template <typename V>
+-  std::pair<iterator, bool> insert_or_assign(StringRef Key, V &&Val) {
++  std::pair<iterator, bool> insert_or_assign(std::string_view Key, V &&Val) {
+     auto Ret = try_emplace(Key, std::forward<V>(Val));
+     if (!Ret.second)
+       Ret.first->second = std::forward<V>(Val);
+@@ -327,7 +327,7 @@ public:
+   /// if and only if the insertion takes place, and the iterator component of
+   /// the pair points to the element with key equivalent to the key of the pair.
+   template <typename... ArgsTy>
+-  std::pair<iterator, bool> try_emplace(StringRef Key, ArgsTy &&... Args) {
++  std::pair<iterator, bool> try_emplace(std::string_view Key, ArgsTy &&... Args) {
+     unsigned BucketNo = LookupBucketFor(Key);
+     StringMapEntryBase *&Bucket = TheTable[BucketNo];
+     if (Bucket && Bucket != getTombstoneVal())
+@@ -373,7 +373,7 @@ public:
+     V.Destroy(Allocator);
+   }
+ 
+-  bool erase(StringRef Key) {
++  bool erase(std::string_view Key) {
+     iterator I = find(Key);
+     if (I == end())
+       return false;
+@@ -470,17 +470,17 @@ template <typename ValueTy>
+ class StringMapKeyIterator
+     : public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
+                                    StringMapConstIterator<ValueTy>,
+-                                   std::forward_iterator_tag, StringRef> {
++                                   std::forward_iterator_tag, std::string_view> {
+   using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
+                                      StringMapConstIterator<ValueTy>,
+-                                     std::forward_iterator_tag, StringRef>;
++                                     std::forward_iterator_tag, std::string_view>;
+ 
+ public:
+   StringMapKeyIterator() = default;
+   explicit StringMapKeyIterator(StringMapConstIterator<ValueTy> Iter)
+       : base(std::move(Iter)) {}
+ 
+-  StringRef operator*() const { return this->wrapped()->getKey(); }
++  std::string_view operator*() const { return this->wrapped()->getKey(); }
+ };
+ 
+ } // end namespace llvm
+diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
+index 6e13c8618..39976a02b 100644
+--- a/llvm/include/llvm/ADT/StringMapEntry.h
++++ b/llvm/include/llvm/ADT/StringMapEntry.h
+@@ -16,9 +16,8 @@
+ #ifndef LLVM_ADT_STRINGMAPENTRY_H
+ #define LLVM_ADT_STRINGMAPENTRY_H
+ 
+-#include "llvm/ADT/None.h"
+-#include "llvm/ADT/StringRef.h"
+-#include "llvm/ADT/STLFunctionalExtras.h"
++#include <optional>
++#include <string_view>
+ 
+ namespace llvm {
+ 
+@@ -37,13 +36,13 @@ protected:
+   /// type-erase the allocator and put it in a source file.
+   template <typename AllocatorTy>
+   static void *allocateWithKey(size_t EntrySize, size_t EntryAlign,
+-                               StringRef Key, AllocatorTy &Allocator);
++                               std::string_view Key, AllocatorTy &Allocator);
+ };
+ 
+ // Define out-of-line to dissuade inlining.
+ template <typename AllocatorTy>
+ void *StringMapEntryBase::allocateWithKey(size_t EntrySize, size_t EntryAlign,
+-                                          StringRef Key,
++                                          std::string_view Key,
+                                           AllocatorTy &Allocator) {
+   size_t KeyLength = Key.size();
+ 
+@@ -85,13 +84,13 @@ public:
+   void setValue(const ValueTy &V) { second = V; }
+ };
+ 
+-template <> class StringMapEntryStorage<NoneType> : public StringMapEntryBase {
++template <> class StringMapEntryStorage<std::nullopt_t> : public StringMapEntryBase {
+ public:
+-  explicit StringMapEntryStorage(size_t keyLength, NoneType = None)
++  explicit StringMapEntryStorage(size_t keyLength, std::nullopt_t = std::nullopt)
+       : StringMapEntryBase(keyLength) {}
+   StringMapEntryStorage(StringMapEntryStorage &entry) = delete;
+ 
+-  NoneType getValue() const { return None; }
++  std::nullopt_t getValue() const { return std::nullopt; }
+ };
+ 
+ /// StringMapEntry - This is used to represent one value that is inserted into
+@@ -102,8 +101,8 @@ class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
+ public:
+   using StringMapEntryStorage<ValueTy>::StringMapEntryStorage;
+ 
+-  StringRef getKey() const {
+-    return StringRef(getKeyData(), this->getKeyLength());
++  std::string_view getKey() const {
++    return std::string_view(getKeyData(), this->getKeyLength());
+   }
+ 
+   /// getKeyData - Return the start of the string data that is the key for this
+@@ -113,14 +112,14 @@ public:
+     return reinterpret_cast<const char *>(this + 1);
+   }
+ 
+-  StringRef first() const {
+-    return StringRef(getKeyData(), this->getKeyLength());
++  std::string_view first() const {
++    return std::string_view(getKeyData(), this->getKeyLength());
+   }
+ 
+   /// Create a StringMapEntry for the specified key construct the value using
+   /// \p InitiVals.
+   template <typename AllocatorTy, typename... InitTy>
+-  static StringMapEntry *Create(StringRef key, AllocatorTy &allocator,
++  static StringMapEntry *Create(std::string_view key, AllocatorTy &allocator,
+                                 InitTy &&... initVals) {
+     return new (StringMapEntryBase::allocateWithKey(
+         sizeof(StringMapEntry), alignof(StringMapEntry), key, allocator))
+diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h
+index 9c2bd45d2..a7dea19d9 100644
+--- a/llvm/include/llvm/Support/Chrono.h
++++ b/llvm/include/llvm/Support/Chrono.h
+@@ -70,7 +70,7 @@ raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);
+ template <>
+ struct format_provider<sys::TimePoint<>> {
+   static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS,
+-                     StringRef Style);
++                     std::string_view Style);
+ };
+ 
+ namespace detail {
+@@ -122,7 +122,7 @@ private:
+     return duration_cast<duration<InternalRep, AsPeriod>>(D).count();
+   }
+ 
+-  static std::pair<InternalRep, StringRef> consumeUnit(StringRef &Style,
++  static std::pair<InternalRep, std::string_view> consumeUnit(std::string_view &Style,
+                                                         const Dur &D) {
+     using namespace std::chrono;
+     if (Style.consume_front("ns"))
+@@ -140,7 +140,7 @@ private:
+     return {D.count(), detail::unit<Period>::value};
+   }
+ 
+-  static bool consumeShowUnit(StringRef &Style) {
++  static bool consumeShowUnit(std::string_view &Style) {
+     if (Style.empty())
+       return true;
+     if (Style.consume_front("-"))
+@@ -152,9 +152,9 @@ private:
+   }
+ 
+ public:
+-  static void format(const Dur &D, llvm::raw_ostream &Stream, StringRef Style) {
++  static void format(const Dur &D, llvm::raw_ostream &Stream, std::string_view Style) {
+     InternalRep count;
+-    StringRef unit;
++    std::string_view unit;
+     std::tie(count, unit) = consumeUnit(Style, D);
+     bool show_unit = consumeShowUnit(Style);
+ 
+diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
+index 80b2dfaec..f5d726ec8 100644
+--- a/llvm/include/llvm/Support/Compiler.h
++++ b/llvm/include/llvm/Support/Compiler.h
+@@ -312,7 +312,7 @@
+ #endif
+ 
+ /// LLVM_GSL_POINTER - Apply this to non-owning classes like
+-/// StringRef to enable lifetime warnings.
++/// std::string_view to enable lifetime warnings.
+ #if LLVM_HAS_CPP_ATTRIBUTE(gsl::Pointer)
+ #define LLVM_GSL_POINTER [[gsl::Pointer]]
+ #else
+diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h
+index 374cdb907..7f1527f51 100644
+--- a/llvm/include/llvm/Support/ConvertUTF.h
++++ b/llvm/include/llvm/Support/ConvertUTF.h
+@@ -89,12 +89,12 @@
+ #ifndef LLVM_SUPPORT_CONVERTUTF_H
+ #define LLVM_SUPPORT_CONVERTUTF_H
+ 
++#include "wpi/span.h"
++
+ #include <cstddef>
+ #include <string>
+-
+-#if defined(_WIN32)
++#include <string_view>
+ #include <system_error>
+-#endif
+ 
+ // Wrap everything in namespace llvm so that programs can link with llvm and
+ // their own version of the unicode libraries.
+@@ -183,12 +183,10 @@ unsigned getNumBytesForUTF8(UTF8 firstByte);
+ /*************************************************************************/
+ /* Below are LLVM-specific wrappers of the functions above. */
+ 
+-template <typename T> class ArrayRef;
+ template <typename T> class SmallVectorImpl;
+-class StringRef;
+ 
+ /**
+- * Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
++ * Convert an UTF8 string_view to UTF8, UTF16, or UTF32 depending on
+  * WideCharWidth. The converted data is written to ResultPtr, which needs to
+  * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
+  * ResultPtr will point one after the end of the copied string. On failure,
+@@ -196,14 +194,14 @@ class StringRef;
+  * the first character which could not be converted.
+  * \return true on success.
+  */
+-bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
++bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source,
+                        char *&ResultPtr, const UTF8 *&ErrorPtr);
+ 
+ /**
+-* Converts a UTF-8 StringRef to a std::wstring.
++* Converts a UTF-8 string_view to a std::wstring.
+ * \return true on success.
+ */
+-bool ConvertUTF8toWide(llvm::StringRef Source, std::wstring &Result);
++bool ConvertUTF8toWide(std::string_view Source, std::wstring &Result);
+ 
+ /**
+ * Converts a UTF-8 C-string to a std::wstring.
+@@ -261,7 +259,7 @@ inline ConversionResult convertUTF8Sequence(const UTF8 **source,
+  * Returns true if a blob of text starts with a UTF-16 big or little endian byte
+  * order mark.
+  */
+-bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
++bool hasUTF16ByteOrderMark(span<const char> SrcBytes);
+ 
+ /**
+  * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
+@@ -270,7 +268,7 @@ bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
+  * \param [out] Out Converted UTF-8 is stored here on success.
+  * \returns true on success
+  */
+-bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
++bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out);
+ 
+ /**
+ * Converts a UTF16 string into a UTF8 std::string.
+@@ -279,22 +277,22 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+-bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out);
++bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out);
+ 
+ /**
+  * Converts a UTF-8 string into a UTF-16 string with native endianness.
+  *
+  * \returns true on success
+  */
+-bool convertUTF8ToUTF16String(StringRef SrcUTF8,
++bool convertUTF8ToUTF16String(std::string_view SrcUTF8,
+                               SmallVectorImpl<UTF16> &DstUTF16);
+ 
+ #if defined(_WIN32)
+ namespace sys {
+ namespace windows {
+-std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
++std::error_code UTF8ToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
+ /// Convert to UTF16 from the current code page used in the system
+-std::error_code CurCPToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
++std::error_code CurCPToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
+ std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
+                             SmallVectorImpl<char> &utf8);
+ /// Convert from UTF16 to the current code page used in the system
+diff --git a/llvm/include/llvm/Support/DJB.h b/llvm/include/llvm/Support/DJB.h
+index 8a04a324a..8737cd144 100644
+--- a/llvm/include/llvm/Support/DJB.h
++++ b/llvm/include/llvm/Support/DJB.h
+@@ -13,13 +13,13 @@
+ #ifndef LLVM_SUPPORT_DJB_H
+ #define LLVM_SUPPORT_DJB_H
+ 
+-#include "llvm/ADT/StringRef.h"
++#include <string_view>
+ 
+ namespace llvm {
+ 
+ /// The Bernstein hash function used by the DWARF accelerator tables.
+-inline uint32_t djbHash(StringRef Buffer, uint32_t H = 5381) {
+-  for (unsigned char C : Buffer.bytes())
++inline uint32_t djbHash(std::string_view Buffer, uint32_t H = 5381) {
++  for (unsigned char C : Buffer)
+     H = (H << 5) + H + C;
+   return H;
+ }
+diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h
+index 6791df6be..3f726d40b 100644
+--- a/llvm/include/llvm/Support/ErrorHandling.h
++++ b/llvm/include/llvm/Support/ErrorHandling.h
+@@ -15,10 +15,10 @@
+ #define LLVM_SUPPORT_ERRORHANDLING_H
+ 
+ #include "llvm/Support/Compiler.h"
++#include <string>
++#include <string_view>
+ 
+ namespace llvm {
+-  class StringRef;
+-  class Twine;
+ 
+   /// An error handler callback.
+   typedef void (*fatal_error_handler_t)(void *user_data,
+@@ -67,12 +67,11 @@ namespace llvm {
+ /// standard error, followed by a newline.
+ /// After the error handler is called this function will call abort(), it
+ /// does not return.
+-/// NOTE: The std::string variant was removed to avoid a <string> dependency.
+ [[noreturn]] void report_fatal_error(const char *reason,
+                                      bool gen_crash_diag = true);
+-[[noreturn]] void report_fatal_error(StringRef reason,
++[[noreturn]] void report_fatal_error(const std::string &reason,
+                                      bool gen_crash_diag = true);
+-[[noreturn]] void report_fatal_error(const Twine &reason,
++[[noreturn]] void report_fatal_error(std::string_view reason,
+                                      bool gen_crash_diag = true);
+ 
+ /// Installs a new bad alloc error handler that should be used whenever a
+diff --git a/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h b/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
+index f7f2d4e54..b5e321b5f 100644
+--- a/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
++++ b/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
+@@ -35,8 +35,8 @@ public:
+                                 RequiresNullTerminator) {}
+ 
+   /// Construct a named SmallVectorMemoryBuffer from the given SmallVector
+-  /// r-value and StringRef.
+-  SmallVectorMemoryBuffer(SmallVectorImpl<char> &&SV, StringRef Name,
++  /// r-value and std::string_view.
++  SmallVectorMemoryBuffer(SmallVectorImpl<char> &&SV, std::string_view Name,
+                           bool RequiresNullTerminator = true)
+       : SV(std::move(SV)), BufferName(std::string(Name)) {
+     if (RequiresNullTerminator) {
+@@ -49,7 +49,7 @@ public:
+   // Key function.
+   ~SmallVectorMemoryBuffer() override;
+ 
+-  StringRef getBufferIdentifier() const override { return BufferName; }
++  std::string_view getBufferIdentifier() const override { return BufferName; }
+ 
+   BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
+ 
+diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h
+index 1a1072d22..3d6573bf5 100644
+--- a/llvm/include/llvm/Support/VersionTuple.h
++++ b/llvm/include/llvm/Support/VersionTuple.h
+@@ -16,14 +16,13 @@
+ 
+ #include "llvm/ADT/DenseMapInfo.h"
+ #include "llvm/ADT/Hashing.h"
+-#include "llvm/ADT/Optional.h"
+ #include "llvm/Support/HashBuilder.h"
++#include <optional>
+ #include <string>
+ #include <tuple>
+ 
+ namespace llvm {
+ class raw_ostream;
+-class StringRef;
+ 
+ /// Represents a version number in the form major[.minor[.subminor[.build]]].
+ class VersionTuple {
+@@ -70,23 +69,23 @@ public:
+   unsigned getMajor() const { return Major; }
+ 
+   /// Retrieve the minor version number, if provided.
+-  Optional<unsigned> getMinor() const {
++  std::optional<unsigned> getMinor() const {
+     if (!HasMinor)
+-      return None;
++      return std::nullopt;
+     return Minor;
+   }
+ 
+   /// Retrieve the subminor version number, if provided.
+-  Optional<unsigned> getSubminor() const {
++  std::optional<unsigned> getSubminor() const {
+     if (!HasSubminor)
+-      return None;
++      return std::nullopt;
+     return Subminor;
+   }
+ 
+   /// Retrieve the build version number, if provided.
+-  Optional<unsigned> getBuild() const {
++  std::optional<unsigned> getBuild() const {
+     if (!HasBuild)
+-      return None;
++      return std::nullopt;
+     return Build;
+   }
+ 
+@@ -173,11 +172,6 @@ public:
+ 
+   /// Retrieve a string representation of the version number.
+   std::string getAsString() const;
+-
+-  /// Try to parse the given string as a version number.
+-  /// \returns \c true if the string does not match the regular expression
+-  ///   [0-9]+(\.[0-9]+){0,3}
+-  bool tryParse(StringRef string);
+ };
+ 
+ /// Print a version number.
+diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
+index 917822678..180803fbd 100644
+--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
++++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
+@@ -35,8 +35,6 @@
+ 
+ #include "llvm/ADT/SmallVector.h"
+ #include "llvm/ADT/StringExtras.h"
+-#include "llvm/ADT/StringRef.h"
+-#include "llvm/ADT/Twine.h"
+ #include "llvm/Config/llvm-config.h" // Get build system configuration settings
+ #include "llvm/Support/Allocator.h"
+ #include "llvm/Support/Chrono.h"
+@@ -71,7 +69,7 @@ bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
+ [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) {
+   std::string ErrMsg;
+   MakeErrMsg(&ErrMsg, Msg);
+-  llvm::report_fatal_error(Twine(ErrMsg));
++  llvm::report_fatal_error(ErrMsg);
+ }
+ 
+ template <typename HandleTraits>
+diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
+index 58adb41cb..9a1dd7a60 100644
+--- a/llvm/include/llvm/Support/raw_ostream.h
++++ b/llvm/include/llvm/Support/raw_ostream.h
+@@ -14,9 +14,7 @@
+ #define LLVM_SUPPORT_RAW_OSTREAM_H
+ 
+ #include "llvm/ADT/SmallVector.h"
+-#include "llvm/ADT/StringRef.h"
+-#include "llvm/ADT/Optional.h"
+-#include "llvm/Support/DataTypes.h"
++#include "llvm/ADT/span.h"
+ #include <cassert>
+ #include <cstddef>
+ #include <cstdint>
+@@ -210,7 +208,22 @@ public:
+     return *this;
+   }
+ 
+-  raw_ostream &operator<<(StringRef Str) {
++  raw_ostream &operator<<(span<const uint8_t> Arr) {
++    // Inline fast path, particularly for arrays with a known length.
++    size_t Size = Arr.size();
++
++    // Make sure we can use the fast path.
++    if (Size > (size_t)(OutBufEnd - OutBufCur))
++      return write(Arr.data(), Size);
++
++    if (Size) {
++      memcpy(OutBufCur, Arr.data(), Size);
++      OutBufCur += Size;
++    }
++    return *this;
++  }
++
++  raw_ostream &operator<<(std::string_view Str) {
+     // Inline fast path, particularly for strings with a known length.
+     size_t Size = Str.size();
+ 
+@@ -229,7 +242,7 @@ public:
+     // Inline fast path, particularly for constant strings where a sufficiently
+     // smart compiler will simplify strlen.
+ 
+-    return this->operator<<(StringRef(Str));
++    return this->operator<<(std::string_view(Str));
+   }
+ 
+   raw_ostream &operator<<(const std::string &Str) {
+@@ -237,12 +250,6 @@ public:
+     return write(Str.data(), Str.length());
+   }
+ 
+-#if __cplusplus > 201402L
+-  raw_ostream &operator<<(const std::string_view &Str) {
+-    return write(Str.data(), Str.length());
+-  }
+-#endif
+-
+   raw_ostream &operator<<(const SmallVectorImpl<char> &Str) {
+     return write(Str.data(), Str.size());
+   }
+@@ -275,7 +282,7 @@ public:
+ 
+   /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
+   /// satisfy llvm::isPrint into an escape sequence.
+-  raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
++  raw_ostream &write_escaped(std::string_view Str, bool UseHexEscapes = false);
+ 
+   raw_ostream &write(unsigned char C);
+   raw_ostream &write(const char *Ptr, size_t Size);
+@@ -446,7 +453,7 @@ class raw_fd_ostream : public raw_pwrite_stream {
+   bool ShouldClose;
+   bool SupportsSeeking = false;
+   bool IsRegularFile = false;
+-  mutable Optional<bool> HasColors;
++  mutable std::optional<bool> HasColors;
+ 
+ #ifdef _WIN32
+   /// True if this fd refers to a Windows console device. Mintty and other
+@@ -491,14 +498,14 @@ public:
+   /// As a special case, if Filename is "-", then the stream will use
+   /// STDOUT_FILENO instead of opening a file. This will not close the stdout
+   /// descriptor.
+-  raw_fd_ostream(StringRef Filename, std::error_code &EC);
+-  raw_fd_ostream(StringRef Filename, std::error_code &EC,
++  raw_fd_ostream(std::string_view Filename, std::error_code &EC);
++  raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                  sys::fs::CreationDisposition Disp);
+-  raw_fd_ostream(StringRef Filename, std::error_code &EC,
++  raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                  sys::fs::FileAccess Access);
+-  raw_fd_ostream(StringRef Filename, std::error_code &EC,
++  raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                  sys::fs::OpenFlags Flags);
+-  raw_fd_ostream(StringRef Filename, std::error_code &EC,
++  raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                  sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
+                  sys::fs::OpenFlags Flags);
+ 
+@@ -603,7 +610,7 @@ public:
+   /// Open the specified file for reading/writing/seeking. If an error occurs,
+   /// information about the error is put into EC, and the stream should be
+   /// immediately destroyed.
+-  raw_fd_stream(StringRef Filename, std::error_code &EC);
++  raw_fd_stream(std::string_view Filename, std::error_code &EC);
+ 
+   /// This reads the \p Size bytes into a buffer pointed by \p Ptr.
+   ///
+@@ -683,8 +690,8 @@ public:
+ 
+   void flush() = delete;
+ 
+-  /// Return a StringRef for the vector contents.
+-  StringRef str() const { return StringRef(OS.data(), OS.size()); }
++  /// Return a std::string_view for the vector contents.
++  std::string_view str() const { return std::string_view(OS.data(), OS.size()); }
+ 
+   void reserveExtraSpace(uint64_t ExtraSize) override {
+     OS.reserve(tell() + ExtraSize);
+@@ -741,7 +748,7 @@ class Error;
+ /// for other names. For raw_fd_ostream instances, the stream writes to
+ /// a temporary file. The final output file is atomically replaced with the
+ /// temporary file after the \p Write function is finished.
+-Error writeToOutput(StringRef OutputFileName,
++Error writeToOutput(std::string_view OutputFileName,
+                     std::function<Error(raw_ostream &)> Write);
+ 
+ } // end namespace llvm
+diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp
+index 392c4c489..396ab0c65 100644
+--- a/llvm/lib/Support/ConvertUTFWrapper.cpp
++++ b/llvm/lib/Support/ConvertUTFWrapper.cpp
+@@ -6,24 +6,24 @@
+ //
+ //===----------------------------------------------------------------------===//
+ 
+-#include "llvm/ADT/ArrayRef.h"
+-#include "llvm/ADT/StringRef.h"
++#include "llvm/ADT/span.h"
+ #include "llvm/Support/ConvertUTF.h"
+ #include "llvm/Support/ErrorHandling.h"
+ #include "llvm/Support/SwapByteOrder.h"
+ #include <string>
++#include <string_view>
+ #include <vector>
+ 
+ namespace llvm {
+ 
+-bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
++bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source,
+                        char *&ResultPtr, const UTF8 *&ErrorPtr) {
+   assert(WideCharWidth == 1 || WideCharWidth == 2 || WideCharWidth == 4);
+   ConversionResult result = conversionOK;
+   // Copy the character span over.
+   if (WideCharWidth == 1) {
+-    const UTF8 *Pos = reinterpret_cast<const UTF8*>(Source.begin());
+-    if (!isLegalUTF8String(&Pos, reinterpret_cast<const UTF8*>(Source.end()))) {
++    const UTF8 *Pos = reinterpret_cast<const UTF8*>(Source.data());
++    if (!isLegalUTF8String(&Pos, reinterpret_cast<const UTF8*>(Source.data() + Source.size()))) {
+       result = sourceIllegal;
+       ErrorPtr = Pos;
+     } else {
+@@ -77,13 +77,13 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) {
+   return true;
+ }
+ 
+-bool hasUTF16ByteOrderMark(ArrayRef<char> S) {
++bool hasUTF16ByteOrderMark(span<const char> S) {
+   return (S.size() >= 2 &&
+           ((S[0] == '\xff' && S[1] == '\xfe') ||
+            (S[0] == '\xfe' && S[1] == '\xff')));
+ }
+ 
+-bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
++bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out) {
+   assert(Out.empty());
+ 
+   // Error out on an uneven byte count.
+@@ -134,14 +134,14 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
+   return true;
+ }
+ 
+-bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out)
++bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out)
+ {
+   return convertUTF16ToUTF8String(
+-      llvm::ArrayRef<char>(reinterpret_cast<const char *>(Src.data()),
++      span<const char>(reinterpret_cast<const char *>(Src.data()),
+       Src.size() * sizeof(UTF16)), Out);
+ }
+ 
+-bool convertUTF8ToUTF16String(StringRef SrcUTF8,
++bool convertUTF8ToUTF16String(std::string_view SrcUTF8,
+                               SmallVectorImpl<UTF16> &DstUTF16) {
+   assert(DstUTF16.empty());
+ 
+@@ -152,8 +152,8 @@ bool convertUTF8ToUTF16String(StringRef SrcUTF8,
+     return true;
+   }
+ 
+-  const UTF8 *Src = reinterpret_cast<const UTF8 *>(SrcUTF8.begin());
+-  const UTF8 *SrcEnd = reinterpret_cast<const UTF8 *>(SrcUTF8.end());
++  const UTF8 *Src = reinterpret_cast<const UTF8 *>(SrcUTF8.data());
++  const UTF8 *SrcEnd = reinterpret_cast<const UTF8 *>(SrcUTF8.data() + SrcUTF8.size());
+ 
+   // Allocate the same number of UTF-16 code units as UTF-8 code units. Encoding
+   // as UTF-16 should always require the same amount or less code units than the
+@@ -184,7 +184,7 @@ static_assert(sizeof(wchar_t) == 1 || sizeof(wchar_t) == 2 ||
+               "Expected wchar_t to be 1, 2, or 4 bytes");
+ 
+ template <typename TResult>
+-static inline bool ConvertUTF8toWideInternal(llvm::StringRef Source,
++static inline bool ConvertUTF8toWideInternal(std::string_view Source,
+                                              TResult &Result) {
+   // Even in the case of UTF-16, the number of bytes in a UTF-8 string is
+   // at least as large as the number of elements in the resulting wide
+@@ -200,7 +200,7 @@ static inline bool ConvertUTF8toWideInternal(llvm::StringRef Source,
+   return true;
+ }
+ 
+-bool ConvertUTF8toWide(llvm::StringRef Source, std::wstring &Result) {
++bool ConvertUTF8toWide(std::string_view Source, std::wstring &Result) {
+   return ConvertUTF8toWideInternal(Source, Result);
+ }
+ 
+@@ -209,7 +209,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) {
+     Result.clear();
+     return true;
+   }
+-  return ConvertUTF8toWide(llvm::StringRef(Source), Result);
++  return ConvertUTF8toWide(std::string_view(Source), Result);
+ }
+ 
+ bool convertWideToUTF8(const std::wstring &Source, std::string &Result) {
+@@ -224,7 +224,7 @@ bool convertWideToUTF8(const std::wstring &Source, std::string &Result) {
+     return true;
+   } else if (sizeof(wchar_t) == 2) {
+     return convertUTF16ToUTF8String(
+-        llvm::ArrayRef<UTF16>(reinterpret_cast<const UTF16 *>(Source.data()),
++        span<const UTF16>(reinterpret_cast<const UTF16 *>(Source.data()),
+                               Source.size()),
+         Result);
+   } else if (sizeof(wchar_t) == 4) {
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index 80c0e0043..8ae8fb8b4 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -14,7 +14,6 @@
+ #include "llvm/Support/ErrorHandling.h"
+ #include "llvm-c/ErrorHandling.h"
+ #include "llvm/ADT/SmallVector.h"
+-#include "llvm/ADT/Twine.h"
+ #include "llvm/Config/config.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/Support/Errc.h"
+@@ -80,14 +79,14 @@ void llvm::remove_fatal_error_handler() {
+ }
+ 
+ void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) {
+-  report_fatal_error(Twine(Reason), GenCrashDiag);
++  report_fatal_error(std::string_view(Reason), GenCrashDiag);
+ }
+ 
+-void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) {
+-  report_fatal_error(Twine(Reason), GenCrashDiag);
++void llvm::report_fatal_error(const std::string &Reason, bool GenCrashDiag) {
++  report_fatal_error(std::string_view(Reason), GenCrashDiag);
+ }
+ 
+-void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
++void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
+   llvm::fatal_error_handler_t handler = nullptr;
+   void* handlerData = nullptr;
+   {
+@@ -101,7 +100,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
+   }
+ 
+   if (handler) {
+-    handler(handlerData, Reason.str().c_str(), GenCrashDiag);
++    handler(handlerData, std::string{Reason}.c_str(), GenCrashDiag);
+   } else {
+     // Blast the result out to stderr.  We don't try hard to make sure this
+     // succeeds (e.g. handling EINTR) and we can't use errs() here because
+@@ -109,7 +108,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
+     SmallVector<char, 64> Buffer;
+     raw_svector_ostream OS(Buffer);
+     OS << "LLVM ERROR: " << Reason << "\n";
+-    StringRef MessageStr = OS.str();
++    std::string_view MessageStr = OS.str();
+     ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
+     (void)written; // If something went wrong, we deliberately just give up.
+   }
+diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
+index 8cafbc7fa..8bad715e4 100644
+--- a/llvm/lib/Support/SmallVector.cpp
++++ b/llvm/lib/Support/SmallVector.cpp
+@@ -11,7 +11,6 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/ADT/SmallVector.h"
+-#include "llvm/ADT/Twine.h"
+ #include "llvm/Support/MemAlloc.h"
+ #include <cstdint>
+ #ifdef LLVM_ENABLE_EXCEPTIONS
+@@ -67,7 +66,7 @@ static void report_size_overflow(size_t MinSize, size_t MaxSize) {
+ #ifdef LLVM_ENABLE_EXCEPTIONS
+   throw std::length_error(Reason);
+ #else
+-  report_fatal_error(Twine(Reason));
++  report_fatal_error(Reason);
+ #endif
+ }
+ 
+@@ -81,7 +80,7 @@ static void report_at_maximum_capacity(size_t MaxSize) {
+ #ifdef LLVM_ENABLE_EXCEPTIONS
+   throw std::length_error(Reason);
+ #else
+-  report_fatal_error(Twine(Reason));
++  report_fatal_error(Reason);
+ #endif
+ }
+ 
+diff --git a/llvm/lib/Support/StringMap.cpp b/llvm/lib/Support/StringMap.cpp
+index 012c785b4..317f4ee43 100644
+--- a/llvm/lib/Support/StringMap.cpp
++++ b/llvm/lib/Support/StringMap.cpp
+@@ -70,7 +70,7 @@ void StringMapImpl::init(unsigned InitSize) {
+ /// specified bucket will be non-null.  Otherwise, it will be null.  In either
+ /// case, the FullHashValue field of the bucket will be set to the hash value
+ /// of the string.
+-unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
++unsigned StringMapImpl::LookupBucketFor(std::string_view Name) {
+   unsigned HTSize = NumBuckets;
+   if (HTSize == 0) { // Hash table unallocated so far?
+     init(16);
+@@ -110,7 +110,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
+       // Do the comparison like this because Name isn't necessarily
+       // null-terminated!
+       char *ItemStr = (char *)BucketItem + ItemSize;
+-      if (Name == StringRef(ItemStr, BucketItem->getKeyLength())) {
++      if (Name == std::string_view(ItemStr, BucketItem->getKeyLength())) {
+         // We found a match!
+         return BucketNo;
+       }
+@@ -128,7 +128,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
+ /// FindKey - Look up the bucket that contains the specified key. If it exists
+ /// in the map, return the bucket number of the key.  Otherwise return -1.
+ /// This does not modify the map.
+-int StringMapImpl::FindKey(StringRef Key) const {
++int StringMapImpl::FindKey(std::string_view Key) const {
+   unsigned HTSize = NumBuckets;
+   if (HTSize == 0)
+     return -1; // Really empty table?
+@@ -154,7 +154,7 @@ int StringMapImpl::FindKey(StringRef Key) const {
+       // Do the comparison like this because NameStart isn't necessarily
+       // null-terminated!
+       char *ItemStr = (char *)BucketItem + ItemSize;
+-      if (Key == StringRef(ItemStr, BucketItem->getKeyLength())) {
++      if (Key == std::string_view(ItemStr, BucketItem->getKeyLength())) {
+         // We found a match!
+         return BucketNo;
+       }
+@@ -173,14 +173,14 @@ int StringMapImpl::FindKey(StringRef Key) const {
+ /// delete it.  This aborts if the value isn't in the table.
+ void StringMapImpl::RemoveKey(StringMapEntryBase *V) {
+   const char *VStr = (char *)V + ItemSize;
+-  StringMapEntryBase *V2 = RemoveKey(StringRef(VStr, V->getKeyLength()));
++  StringMapEntryBase *V2 = RemoveKey(std::string_view(VStr, V->getKeyLength()));
+   (void)V2;
+   assert(V == V2 && "Didn't find key?");
+ }
+ 
+ /// RemoveKey - Remove the StringMapEntry for the specified key from the
+ /// table, returning it.  If the key is not in the table, this returns null.
+-StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
++StringMapEntryBase *StringMapImpl::RemoveKey(std::string_view Key) {
+   int Bucket = FindKey(Key);
+   if (Bucket == -1)
+     return nullptr;
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index 69d4fe96b..e4c318eb8 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -159,7 +159,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
+ }
+ 
+ 
+-raw_ostream &raw_ostream::write_escaped(StringRef Str,
++raw_ostream &raw_ostream::write_escaped(std::string_view Str,
+                                         bool UseHexEscapes) {
+   for (unsigned char c : Str) {
+     switch (c) {
+@@ -563,7 +563,7 @@ void format_object_base::home() {
+ //  raw_fd_ostream
+ //===----------------------------------------------------------------------===//
+ 
+-static int getFD(StringRef Filename, std::error_code &EC,
++static int getFD(std::string_view Filename, std::error_code &EC,
+                  sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
+                  sys::fs::OpenFlags Flags) {
+   assert((Access & sys::fs::FA_Write) &&
+@@ -589,25 +589,25 @@ static int getFD(StringRef Filename, std::error_code &EC,
+   return FD;
+ }
+ 
+-raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
++raw_fd_ostream::raw_fd_ostream(std::string_view Filename, std::error_code &EC)
+     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
+                      sys::fs::OF_None) {}
+ 
+-raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
++raw_fd_ostream::raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                                sys::fs::CreationDisposition Disp)
+     : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
+ 
+-raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
++raw_fd_ostream::raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                                sys::fs::FileAccess Access)
+     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
+                      sys::fs::OF_None) {}
+ 
+-raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
++raw_fd_ostream::raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                                sys::fs::OpenFlags Flags)
+     : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
+                      Flags) {}
+ 
+-raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
++raw_fd_ostream::raw_fd_ostream(std::string_view Filename, std::error_code &EC,
+                                sys::fs::CreationDisposition Disp,
+                                sys::fs::FileAccess Access,
+                                sys::fs::OpenFlags Flags)
+@@ -679,8 +679,7 @@ raw_fd_ostream::~raw_fd_ostream() {
+   // has_error() and clear the error flag with clear_error() before
+   // destructing raw_ostream objects which may have errors.
+   if (has_error())
+-    report_fatal_error(Twine("IO failure on output stream: ") +
+-                           error().message(),
++    report_fatal_error("IO failure on output stream: " + error().message(),
+                        /*gen_crash_diag=*/false);
+ }
+ 
+@@ -699,7 +698,7 @@ raw_fd_ostream::~raw_fd_ostream() {
+ // the input is UTF-8 or transcode from the local codepage to UTF-8 before
+ // quoting it. If they don't, this may mess up the encoding, but this is still
+ // probably the best compromise we can make.
+-static bool write_console_impl(int FD, StringRef Data) {
++static bool write_console_impl(int FD, std::string_view Data) {
+   SmallVector<wchar_t, 256> WideText;
+ 
+   // Fall back to ::write if it wasn't valid UTF-8.
+@@ -742,7 +741,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
+   // If this is a Windows console device, try re-encoding from UTF-8 to UTF-16
+   // and using WriteConsoleW. If that fails, fall back to plain write().
+   if (IsWindowsConsole)
+-    if (write_console_impl(FD, StringRef(Ptr, Size)))
++    if (write_console_impl(FD, std::string_view(Ptr, Size)))
+       return;
+ #endif
+ 
+@@ -906,7 +905,7 @@ raw_ostream &llvm::nulls() {
+ // File Streams
+ //===----------------------------------------------------------------------===//
+ 
+-raw_fd_stream::raw_fd_stream(StringRef Filename, std::error_code &EC)
++raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC)
+     : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways,
+                            sys::fs::FA_Write | sys::fs::FA_Read,
+                            sys::fs::OF_None),
+@@ -984,7 +983,7 @@ void buffer_ostream::anchor() {}
+ 
+ void buffer_unique_ostream::anchor() {}
+ 
+-Error llvm::writeToOutput(StringRef OutputFileName,
++Error llvm::writeToOutput(std::string_view OutputFileName,
+                           std::function<Error(raw_ostream &)> Write) {
+   if (OutputFileName == "-")
+     return Write(outs());
+diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
+index 4dd314c5c..e505b1907 100644
+--- a/llvm/unittests/ADT/DenseMapTest.cpp
++++ b/llvm/unittests/ADT/DenseMapTest.cpp
+@@ -481,31 +481,6 @@ TEST(DenseMapCustomTest, ReserveTest) {
+   }
+ }
+ 
+-// Make sure DenseMap works with StringRef keys.
+-TEST(DenseMapCustomTest, StringRefTest) {
+-  DenseMap<StringRef, int> M;
+-
+-  M["a"] = 1;
+-  M["b"] = 2;
+-  M["c"] = 3;
+-
+-  EXPECT_EQ(3u, M.size());
+-  EXPECT_EQ(1, M.lookup("a"));
+-  EXPECT_EQ(2, M.lookup("b"));
+-  EXPECT_EQ(3, M.lookup("c"));
+-
+-  EXPECT_EQ(0, M.lookup("q"));
+-
+-  // Test the empty string, spelled various ways.
+-  EXPECT_EQ(0, M.lookup(""));
+-  EXPECT_EQ(0, M.lookup(StringRef()));
+-  EXPECT_EQ(0, M.lookup(StringRef("a", 0)));
+-  M[""] = 42;
+-  EXPECT_EQ(42, M.lookup(""));
+-  EXPECT_EQ(42, M.lookup(StringRef()));
+-  EXPECT_EQ(42, M.lookup(StringRef("a", 0)));
+-}
+-
+ // Key traits that allows lookup with either an unsigned or char* key;
+ // In the latter case, "a" == 0, "b" == 1 and so on.
+ struct TestDenseMapInfo {
+diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp
+index fc856a976..aff9d61c7 100644
+--- a/llvm/unittests/ADT/FunctionExtrasTest.cpp
++++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp
+@@ -249,23 +249,23 @@ TEST(UniqueFunctionTest, Const) {
+ 
+   // Overloaded call operator correctly resolved.
+   struct ChooseCorrectOverload {
+-    StringRef operator()() { return "non-const"; }
+-    StringRef operator()() const { return "const"; }
++    std::string_view operator()() { return "non-const"; }
++    std::string_view operator()() const { return "const"; }
+   };
+-  unique_function<StringRef()> ChooseMutable = ChooseCorrectOverload();
++  unique_function<std::string_view()> ChooseMutable = ChooseCorrectOverload();
+   ChooseCorrectOverload A;
+   EXPECT_EQ("non-const", ChooseMutable());
+   EXPECT_EQ("non-const", A());
+-  unique_function<StringRef() const> ChooseConst = ChooseCorrectOverload();
++  unique_function<std::string_view() const> ChooseConst = ChooseCorrectOverload();
+   const ChooseCorrectOverload &X = A;
+   EXPECT_EQ("const", ChooseConst());
+   EXPECT_EQ("const", X());
+ }
+ 
+ // Test that overloads on unique_functions are resolved as expected.
+-std::string returns(StringRef) { return "not a function"; }
++std::string returns(std::string_view) { return "not a function"; }
+ std::string returns(unique_function<double()> F) { return "number"; }
+-std::string returns(unique_function<StringRef()> F) { return "string"; }
++std::string returns(unique_function<std::string_view()> F) { return "string"; }
+ 
+ TEST(UniqueFunctionTest, SFINAE) {
+   EXPECT_EQ("not a function", returns("boo!"));
+diff --git a/llvm/unittests/ADT/HashingTest.cpp b/llvm/unittests/ADT/HashingTest.cpp
+index bb19a5699..0634767a4 100644
+--- a/llvm/unittests/ADT/HashingTest.cpp
++++ b/llvm/unittests/ADT/HashingTest.cpp
+@@ -277,7 +277,7 @@ TEST(HashingTest, HashCombineRangeGoldenTest) {
+ #endif
+   };
+   for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
+-    StringRef str = golden_data[i].s;
++    std::string_view str = golden_data[i].s;
+     hash_code hash = hash_combine_range(str.begin(), str.end());
+ #if 0 // Enable this to generate paste-able text for the above structure.
+     std::string member_str = "\"" + str.str() + "\",";
+diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp
+index 414298c4e..6f3c94eed 100644
+--- a/llvm/unittests/ADT/SmallPtrSetTest.cpp
++++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp
+@@ -12,7 +12,6 @@
+ 
+ #include "llvm/ADT/SmallPtrSet.h"
+ #include "llvm/ADT/PointerIntPair.h"
+-#include "llvm/ADT/STLExtras.h"
+ #include "llvm/Support/PointerLikeTypeTraits.h"
+ #include "gtest/gtest.h"
+ 
+diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp
+index b207f582e..bee3875d1 100644
+--- a/llvm/unittests/ADT/SmallStringTest.cpp
++++ b/llvm/unittests/ADT/SmallStringTest.cpp
+@@ -50,43 +50,43 @@ TEST_F(SmallStringTest, AssignRepeated) {
+ }
+ 
+ TEST_F(SmallStringTest, AssignIterPair) {
+-  StringRef abc = "abc";
++  std::string_view abc = "abc";
+   theString.assign(abc.begin(), abc.end());
+   EXPECT_EQ(3u, theString.size());
+   EXPECT_STREQ("abc", theString.c_str());
+ }
+ 
+-TEST_F(SmallStringTest, AssignStringRef) {
+-  StringRef abc = "abc";
++TEST_F(SmallStringTest, AssignStringView) {
++  std::string_view abc = "abc";
+   theString.assign(abc);
+   EXPECT_EQ(3u, theString.size());
+   EXPECT_STREQ("abc", theString.c_str());
+ }
+ 
+ TEST_F(SmallStringTest, AssignSmallVector) {
+-  StringRef abc = "abc";
++  std::string_view abc = "abc";
+   SmallVector<char, 10> abcVec(abc.begin(), abc.end());
+   theString.assign(abcVec);
+   EXPECT_EQ(3u, theString.size());
+   EXPECT_STREQ("abc", theString.c_str());
+ }
+ 
+-TEST_F(SmallStringTest, AssignStringRefs) {
++TEST_F(SmallStringTest, AssignStringViews) {
+   theString.assign({"abc", "def", "ghi"});
+   EXPECT_EQ(9u, theString.size());
+   EXPECT_STREQ("abcdefghi", theString.c_str());
+ }
+ 
+ TEST_F(SmallStringTest, AppendIterPair) {
+-  StringRef abc = "abc";
++  std::string_view abc = "abc";
+   theString.append(abc.begin(), abc.end());
+   theString.append(abc.begin(), abc.end());
+   EXPECT_EQ(6u, theString.size());
+   EXPECT_STREQ("abcabc", theString.c_str());
+ }
+ 
+-TEST_F(SmallStringTest, AppendStringRef) {
+-  StringRef abc = "abc";
++TEST_F(SmallStringTest, AppendStringView) {
++  std::string_view abc = "abc";
+   theString.append(abc);
+   theString.append(abc);
+   EXPECT_EQ(6u, theString.size());
+@@ -94,7 +94,7 @@ TEST_F(SmallStringTest, AppendStringRef) {
+ }
+ 
+ TEST_F(SmallStringTest, AppendSmallVector) {
+-  StringRef abc = "abc";
++  std::string_view abc = "abc";
+   SmallVector<char, 10> abcVec(abc.begin(), abc.end());
+   theString.append(abcVec);
+   theString.append(abcVec);
+@@ -102,11 +102,11 @@ TEST_F(SmallStringTest, AppendSmallVector) {
+   EXPECT_STREQ("abcabc", theString.c_str());
+ }
+ 
+-TEST_F(SmallStringTest, AppendStringRefs) {
++TEST_F(SmallStringTest, AppendStringViews) {
+   theString.append({"abc", "def", "ghi"});
+   EXPECT_EQ(9u, theString.size());
+   EXPECT_STREQ("abcdefghi", theString.c_str());
+-  StringRef Jkl = "jkl";
++  std::string_view Jkl = "jkl";
+   std::string Mno = "mno";
+   SmallString<4> Pqr("pqr");
+   const char *Stu = "stu";
+@@ -115,15 +115,15 @@ TEST_F(SmallStringTest, AppendStringRefs) {
+   EXPECT_STREQ("abcdefghijklmnopqrstu", theString.c_str());
+ }
+ 
+-TEST_F(SmallStringTest, StringRefConversion) {
+-  StringRef abc = "abc";
++TEST_F(SmallStringTest, StringViewConversion) {
++  std::string_view abc = "abc";
+   theString.assign(abc.begin(), abc.end());
+-  StringRef theStringRef = theString;
+-  EXPECT_EQ("abc", theStringRef);
++  std::string_view theStringView = theString;
++  EXPECT_EQ("abc", theStringView);
+ }
+ 
+ TEST_F(SmallStringTest, StdStringConversion) {
+-  StringRef abc = "abc";
++  std::string_view abc = "abc";
+   theString.assign(abc.begin(), abc.end());
+   std::string theStdString = std::string(theString);
+   EXPECT_EQ("abc", theStdString);
+@@ -149,29 +149,29 @@ TEST_F(SmallStringTest, Slice) {
+ TEST_F(SmallStringTest, Find) {
+   theString = "hello";
+   EXPECT_EQ(2U, theString.find('l'));
+-  EXPECT_EQ(StringRef::npos, theString.find('z'));
+-  EXPECT_EQ(StringRef::npos, theString.find("helloworld"));
++  EXPECT_EQ(std::string_view::npos, theString.find('z'));
++  EXPECT_EQ(std::string_view::npos, theString.find("helloworld"));
+   EXPECT_EQ(0U, theString.find("hello"));
+   EXPECT_EQ(1U, theString.find("ello"));
+-  EXPECT_EQ(StringRef::npos, theString.find("zz"));
++  EXPECT_EQ(std::string_view::npos, theString.find("zz"));
+   EXPECT_EQ(2U, theString.find("ll", 2));
+-  EXPECT_EQ(StringRef::npos, theString.find("ll", 3));
++  EXPECT_EQ(std::string_view::npos, theString.find("ll", 3));
+   EXPECT_EQ(0U, theString.find(""));
+ 
+   EXPECT_EQ(3U, theString.rfind('l'));
+-  EXPECT_EQ(StringRef::npos, theString.rfind('z'));
+-  EXPECT_EQ(StringRef::npos, theString.rfind("helloworld"));
++  EXPECT_EQ(std::string_view::npos, theString.rfind('z'));
++  EXPECT_EQ(std::string_view::npos, theString.rfind("helloworld"));
+   EXPECT_EQ(0U, theString.rfind("hello"));
+   EXPECT_EQ(1U, theString.rfind("ello"));
+-  EXPECT_EQ(StringRef::npos, theString.rfind("zz"));
++  EXPECT_EQ(std::string_view::npos, theString.rfind("zz"));
+ 
+   EXPECT_EQ(2U, theString.find_first_of('l'));
+   EXPECT_EQ(1U, theString.find_first_of("el"));
+-  EXPECT_EQ(StringRef::npos, theString.find_first_of("xyz"));
++  EXPECT_EQ(std::string_view::npos, theString.find_first_of("xyz"));
+ 
+   EXPECT_EQ(1U, theString.find_first_not_of('h'));
+   EXPECT_EQ(4U, theString.find_first_not_of("hel"));
+-  EXPECT_EQ(StringRef::npos, theString.find_first_not_of("hello"));
++  EXPECT_EQ(std::string_view::npos, theString.find_first_not_of("hello"));
+ 
+   theString = "hellx xello hell ello world foo bar hello";
+   EXPECT_EQ(36U, theString.find("hello"));
+diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp
+index 3fbea5299..fe827546a 100644
+--- a/llvm/unittests/ADT/SmallVectorTest.cpp
++++ b/llvm/unittests/ADT/SmallVectorTest.cpp
+@@ -11,7 +11,7 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/ADT/SmallVector.h"
+-#include "llvm/ADT/ArrayRef.h"
++#include "llvm/ADT/span.h"
+ #include "llvm/Support/Compiler.h"
+ #include "gtest/gtest.h"
+ #include <list>
+@@ -1070,24 +1070,6 @@ TEST(SmallVectorTest, DefaultInlinedElements) {
+   EXPECT_EQ(NestedV[0][0][0], 42);
+ }
+ 
+-TEST(SmallVectorTest, InitializerList) {
+-  SmallVector<int, 2> V1 = {};
+-  EXPECT_TRUE(V1.empty());
+-  V1 = {0, 0};
+-  EXPECT_TRUE(makeArrayRef(V1).equals({0, 0}));
+-  V1 = {-1, -1};
+-  EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1}));
+-
+-  SmallVector<int, 2> V2 = {1, 2, 3, 4};
+-  EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4}));
+-  V2.assign({4});
+-  EXPECT_TRUE(makeArrayRef(V2).equals({4}));
+-  V2.append({3, 2});
+-  EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2}));
+-  V2.insert(V2.begin() + 1, 5);
+-  EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2}));
+-}
+-
+ template <class VectorT>
+ class SmallVectorReferenceInvalidationTest : public SmallVectorTestBase {
+ protected:
+diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
+index 817fec6c3..86907ab61 100644
+--- a/llvm/unittests/ADT/StringMapTest.cpp
++++ b/llvm/unittests/ADT/StringMapTest.cpp
+@@ -7,8 +7,6 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/ADT/StringMap.h"
+-#include "llvm/ADT/STLExtras.h"
+-#include "llvm/ADT/Twine.h"
+ #include "llvm/Support/DataTypes.h"
+ #include "gtest/gtest.h"
+ #include <limits>
+@@ -38,10 +36,10 @@ protected:
+ 
+     // Lookup tests
+     EXPECT_EQ(0u, testMap.count(testKey));
+-    EXPECT_EQ(0u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
++    EXPECT_EQ(0u, testMap.count(std::string_view(testKeyFirst, testKeyLength)));
+     EXPECT_EQ(0u, testMap.count(testKeyStr));
+     EXPECT_TRUE(testMap.find(testKey) == testMap.end());
+-    EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) == 
++    EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == 
+                 testMap.end());
+     EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
+   }
+@@ -61,10 +59,10 @@ protected:
+ 
+     // Lookup tests
+     EXPECT_EQ(1u, testMap.count(testKey));
+-    EXPECT_EQ(1u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
++    EXPECT_EQ(1u, testMap.count(std::string_view(testKeyFirst, testKeyLength)));
+     EXPECT_EQ(1u, testMap.count(testKeyStr));
+     EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
+-    EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) == 
++    EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == 
+                 testMap.begin());
+     EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
+   }
+@@ -104,10 +102,10 @@ TEST_F(StringMapTest, ConstEmptyMapTest) {
+ 
+   // Lookup tests
+   EXPECT_EQ(0u, constTestMap.count(testKey));
+-  EXPECT_EQ(0u, constTestMap.count(StringRef(testKeyFirst, testKeyLength)));
++  EXPECT_EQ(0u, constTestMap.count(std::string_view(testKeyFirst, testKeyLength)));
+   EXPECT_EQ(0u, constTestMap.count(testKeyStr));
+   EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end());
+-  EXPECT_TRUE(constTestMap.find(StringRef(testKeyFirst, testKeyLength)) ==
++  EXPECT_TRUE(constTestMap.find(std::string_view(testKeyFirst, testKeyLength)) ==
+               constTestMap.end());
+   EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end());
+ }
+@@ -235,7 +233,7 @@ TEST_F(StringMapTest, StringMapEntryTest) {
+   MallocAllocator Allocator;
+   StringMap<uint32_t>::value_type *entry =
+       StringMap<uint32_t>::value_type::Create(
+-          StringRef(testKeyFirst, testKeyLength), Allocator, 1u);
++          std::string_view(testKeyFirst, testKeyLength), Allocator, 1u);
+   EXPECT_STREQ(testKey, entry->first().data());
+   EXPECT_EQ(1u, entry->second);
+   entry->Destroy(Allocator);
+@@ -246,7 +244,7 @@ TEST_F(StringMapTest, InsertTest) {
+   SCOPED_TRACE("InsertTest");
+   testMap.insert(
+       StringMap<uint32_t>::value_type::Create(
+-          StringRef(testKeyFirst, testKeyLength),
++          std::string_view(testKeyFirst, testKeyLength),
+           testMap.getAllocator(), 1u));
+   assertSingleItemMap();
+ }
+@@ -316,10 +314,10 @@ TEST_F(StringMapTest, IterMapKeysVector) {
+   Map["C"] = 3;
+   Map["D"] = 3;
+ 
+-  std::vector<StringRef> Keys{Map.keys().begin(), Map.keys().end()};
++  std::vector<std::string_view> Keys{Map.keys().begin(), Map.keys().end()};
+   llvm::sort(Keys);
+ 
+-  std::vector<StringRef> Expected{{"A", "B", "C", "D"}};
++  std::vector<std::string_view> Expected{{"A", "B", "C", "D"}};
+   EXPECT_EQ(Expected, Keys);
+ }
+ 
+@@ -333,7 +331,7 @@ TEST_F(StringMapTest, IterMapKeysSmallVector) {
+   auto Keys = to_vector<4>(Map.keys());
+   llvm::sort(Keys);
+ 
+-  SmallVector<StringRef, 4> Expected = {"A", "B", "C", "D"};
++  SmallVector<std::string_view, 4> Expected = {"A", "B", "C", "D"};
+   EXPECT_EQ(Expected, Keys);
+ }
+ 
+@@ -375,13 +373,13 @@ private:
+ TEST_F(StringMapTest, MoveOnly) {
+   StringMap<MoveOnly> t;
+   t.insert(std::make_pair("Test", MoveOnly(42)));
+-  StringRef Key = "Test";
++  std::string_view Key = "Test";
+   StringMapEntry<MoveOnly>::Create(Key, t.getAllocator(), MoveOnly(42))
+       ->Destroy(t.getAllocator());
+ }
+ 
+ TEST_F(StringMapTest, CtorArg) {
+-  StringRef Key = "Test";
++  std::string_view Key = "Test";
+   MallocAllocator Allocator;
+   StringMapEntry<MoveOnly>::Create(Key, Allocator, Immovable())
+       ->Destroy(Allocator);
+@@ -556,7 +554,7 @@ TEST(StringMapCustomTest, InitialSizeTest) {
+     CountCtorCopyAndMove::Copy = 0;
+     for (int i = 0; i < Size; ++i)
+       Map.insert(std::pair<std::string, CountCtorCopyAndMove>(
+-          std::piecewise_construct, std::forward_as_tuple(Twine(i).str()),
++          std::piecewise_construct, std::forward_as_tuple(std::to_string(i)),
+           std::forward_as_tuple(i)));
+     // After the initial move, the map will move the Elts in the Entry.
+     EXPECT_EQ((unsigned)Size * 2, CountCtorCopyAndMove::Move);
+@@ -625,7 +623,7 @@ TEST(StringMapCustomTest, StringMapEntrySize) {
+   else
+     LargeValue = std::numeric_limits<unsigned>::max() + 1ULL;
+   StringMapEntry<int> LargeEntry(LargeValue);
+-  StringRef Key = LargeEntry.getKey();
++  std::string_view Key = LargeEntry.getKey();
+   EXPECT_EQ(LargeValue, Key.size());
+ 
+   // Test that the entry can hold at least max size_t.
+diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp
+index 7bda6ea28..9c798437a 100644
+--- a/llvm/unittests/Support/ConvertUTFTest.cpp
++++ b/llvm/unittests/Support/ConvertUTFTest.cpp
+@@ -7,7 +7,6 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/Support/ConvertUTF.h"
+-#include "llvm/ADT/ArrayRef.h"
+ #include "gtest/gtest.h"
+ #include <string>
+ #include <vector>
+@@ -17,7 +16,7 @@ using namespace llvm;
+ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) {
+   // Src is the look of disapproval.
+   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+-  ArrayRef<char> Ref(Src, sizeof(Src) - 1);
++  span<const char> Ref(Src, sizeof(Src) - 1);
+   std::string Result;
+   bool Success = convertUTF16ToUTF8String(Ref, Result);
+   EXPECT_TRUE(Success);
+@@ -28,7 +27,7 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) {
+ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
+   // Src is the look of disapproval.
+   alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+-  ArrayRef<char> Ref(Src, sizeof(Src) - 1);
++  span<const char> Ref(Src, sizeof(Src) - 1);
+   std::string Result;
+   bool Success = convertUTF16ToUTF8String(Ref, Result);
+   EXPECT_TRUE(Success);
+@@ -39,7 +38,7 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
+ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
+   // Src is the look of disapproval.
+   static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0";
+-  StringRef Ref(Src, sizeof(Src) - 1);
++  std::string_view Ref(Src, sizeof(Src) - 1);
+   SmallVector<UTF16, 5> Result;
+   bool Success = convertUTF8ToUTF16String(Ref, Result);
+   EXPECT_TRUE(Success);
+@@ -51,37 +50,37 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
+ 
+ TEST(ConvertUTFTest, OddLengthInput) {
+   std::string Result;
+-  bool Success = convertUTF16ToUTF8String(makeArrayRef("xxxxx", 5), Result);
++  bool Success = convertUTF16ToUTF8String(span<const char>("xxxxx", 5), Result);
+   EXPECT_FALSE(Success);
+ }
+ 
+ TEST(ConvertUTFTest, Empty) {
+   std::string Result;
+-  bool Success = convertUTF16ToUTF8String(llvm::ArrayRef<char>(None), Result);
++  bool Success = convertUTF16ToUTF8String(span<const char>(), Result);
+   EXPECT_TRUE(Success);
+   EXPECT_TRUE(Result.empty());
+ }
+ 
+ TEST(ConvertUTFTest, HasUTF16BOM) {
+-  bool HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xff\xfe", 2));
++  bool HasBOM = hasUTF16ByteOrderMark("\xff\xfe");
+   EXPECT_TRUE(HasBOM);
+-  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff", 2));
++  HasBOM = hasUTF16ByteOrderMark("\xfe\xff");
+   EXPECT_TRUE(HasBOM);
+-  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff ", 3));
++  HasBOM = hasUTF16ByteOrderMark("\xfe\xff ");
+   EXPECT_TRUE(HasBOM); // Don't care about odd lengths.
+-  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff\x00asdf", 6));
++  HasBOM = hasUTF16ByteOrderMark("\xfe\xff\x00asdf");
+   EXPECT_TRUE(HasBOM);
+ 
+-  HasBOM = hasUTF16ByteOrderMark(None);
++  HasBOM = hasUTF16ByteOrderMark("");
+   EXPECT_FALSE(HasBOM);
+-  HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe", 1));
++  HasBOM = hasUTF16ByteOrderMark("\xfe");
+   EXPECT_FALSE(HasBOM);
+ }
+ 
+ TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
+   // Src is the look of disapproval.
+   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+-  ArrayRef<UTF16> SrcRef = makeArrayRef((const UTF16 *)Src, 4);
++  span<const UTF16> SrcRef((const UTF16 *)Src, 4);
+   std::string Result;
+   bool Success = convertUTF16ToUTF8String(SrcRef, Result);
+   EXPECT_TRUE(Success);
+@@ -98,7 +97,7 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) {
+   std::wstring Expected(L"\x0ca0_\x0ca0");
+   EXPECT_EQ(Expected, Result);
+   Result.clear();
+-  Success = ConvertUTF8toWide(StringRef(Src, 7), Result);
++  Success = ConvertUTF8toWide(Src, Result);
+   EXPECT_TRUE(Success);
+   EXPECT_EQ(Expected, Result);
+ }
+@@ -147,7 +146,7 @@ struct ConvertUTFResultContainer {
+ };
+ 
+ std::pair<ConversionResult, std::vector<unsigned>>
+-ConvertUTF8ToUnicodeScalarsLenient(StringRef S) {
++ConvertUTF8ToUnicodeScalarsLenient(std::string_view S) {
+   const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+ 
+   const UTF8 *SourceNext = SourceStart;
+@@ -164,7 +163,7 @@ ConvertUTF8ToUnicodeScalarsLenient(StringRef S) {
+ }
+ 
+ std::pair<ConversionResult, std::vector<unsigned>>
+-ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) {
++ConvertUTF8ToUnicodeScalarsPartialLenient(std::string_view S) {
+   const UTF8 *SourceStart = reinterpret_cast<const UTF8 *>(S.data());
+ 
+   const UTF8 *SourceNext = SourceStart;
+@@ -182,7 +181,7 @@ ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) {
+ 
+ ::testing::AssertionResult
+ CheckConvertUTF8ToUnicodeScalars(ConvertUTFResultContainer Expected,
+-                                 StringRef S, bool Partial = false) {
++                                 std::string_view S, bool Partial = false) {
+   ConversionResult ErrorCode;
+   std::vector<unsigned> Decoded;
+   if (!Partial)
+@@ -277,7 +276,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
+   // U+0000 NULL
+   EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+       ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
+-      StringRef("\x00", 1)));
++      std::string_view("\x00", 1)));
+ 
+   // U+0080 PADDING CHARACTER
+   EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+@@ -1051,7 +1050,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) {
+   // U+0000 NULL
+   EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
+       ConvertUTFResultContainer(conversionOK).withScalars(0x0000),
+-      StringRef("\x00", 1)));
++      std::string_view("\x00", 1)));
+ 
+   // Overlong sequences of the above.
+   EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars(
diff --git a/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch b/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch
new file mode 100644
index 0000000..a67e326
--- /dev/null
+++ b/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch
@@ -0,0 +1,208 @@
+From 5fccde024bea117d90d215390f09c7d779195ea5 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:12:41 -0400
+Subject: [PATCH 03/28] Wrap std::min/max calls in parens, for Windows warnings
+
+---
+ llvm/include/llvm/ADT/DenseMap.h       |  4 ++--
+ llvm/include/llvm/ADT/SmallVector.h    | 12 ++++++------
+ llvm/include/llvm/Support/ConvertUTF.h |  2 +-
+ llvm/include/llvm/Support/MathExtras.h | 22 +++++++++++-----------
+ llvm/lib/Support/SmallVector.cpp       |  2 +-
+ 5 files changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
+index 7673b66ca..975c3b97e 100644
+--- a/llvm/include/llvm/ADT/DenseMap.h
++++ b/llvm/include/llvm/ADT/DenseMap.h
+@@ -390,7 +390,7 @@ protected:
+       return 0;
+     // +1 is required because of the strict equality.
+     // For example if NumEntries is 48, we need to return 401.
+-    return NextPowerOf2(NumEntries * 4 / 3 + 1);
++    return static_cast<unsigned>(NextPowerOf2(NumEntries * 4 / 3 + 1));
+   }
+ 
+   void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
+@@ -826,7 +826,7 @@ public:
+     // Reduce the number of buckets.
+     unsigned NewNumBuckets = 0;
+     if (OldNumEntries)
+-      NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
++      NewNumBuckets = (std::max)(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
+     if (NewNumBuckets == NumBuckets) {
+       this->BaseT::initEmpty();
+       return;
+diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
+index a4a790323..8686f7bb5 100644
+--- a/llvm/include/llvm/ADT/SmallVector.h
++++ b/llvm/include/llvm/ADT/SmallVector.h
+@@ -49,12 +49,12 @@ protected:
+ 
+   /// The maximum value of the Size_T used.
+   static constexpr size_t SizeTypeMax() {
+-    return std::numeric_limits<Size_T>::max();
++    return (std::numeric_limits<Size_T>::max)();
+   }
+ 
+   SmallVectorBase() = delete;
+   SmallVectorBase(void *FirstEl, size_t TotalCapacity)
+-      : BeginX(FirstEl), Capacity(TotalCapacity) {}
++      : BeginX(FirstEl), Capacity(static_cast<unsigned>(TotalCapacity)) {}
+ 
+   /// This is a helper for \a grow() that's out of line to reduce code
+   /// duplication.  This function will report a fatal error if it can't grow at
+@@ -79,7 +79,7 @@ protected:
+   /// This does not construct or destroy any elements in the vector.
+   void set_size(size_t N) {
+     assert(N <= capacity());
+-    Size = N;
++    Size = static_cast<unsigned>(N);
+   }
+ };
+ 
+@@ -259,7 +259,7 @@ public:
+ 
+   size_type size_in_bytes() const { return size() * sizeof(T); }
+   size_type max_size() const {
+-    return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
++    return (std::min)(this->SizeTypeMax(), size_type(-1) / sizeof(T));
+   }
+ 
+   size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
+@@ -444,7 +444,7 @@ void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow(
+     free(this->begin());
+ 
+   this->BeginX = NewElts;
+-  this->Capacity = NewCapacity;
++  this->Capacity = static_cast<unsigned>(NewCapacity);
+ }
+ 
+ /// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
+@@ -693,7 +693,7 @@ public:
+     }
+ 
+     // Assign over existing elements.
+-    std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
++    std::fill_n(this->begin(), (std::min)(NumElts, this->size()), Elt);
+     if (NumElts > this->size())
+       std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
+     else if (NumElts < this->size())
+diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h
+index 7f1527f51..b085c8a17 100644
+--- a/llvm/include/llvm/Support/ConvertUTF.h
++++ b/llvm/include/llvm/Support/ConvertUTF.h
+@@ -112,7 +112,7 @@ namespace llvm {
+ typedef unsigned int    UTF32;  /* at least 32 bits */
+ typedef unsigned short  UTF16;  /* at least 16 bits */
+ typedef unsigned char   UTF8;   /* typically 8 bits */
+-typedef unsigned char   Boolean; /* 0 or 1 */
++typedef bool   Boolean; /* 0 or 1 */
+ 
+ /* Some fundamental constants */
+ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
+index 753b1998c..db9fbc148 100644
+--- a/llvm/include/llvm/Support/MathExtras.h
++++ b/llvm/include/llvm/Support/MathExtras.h
+@@ -97,7 +97,7 @@ template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
+     // Bisection method.
+     unsigned ZeroBits = 0;
+     T Shift = std::numeric_limits<T>::digits >> 1;
+-    T Mask = std::numeric_limits<T>::max() >> Shift;
++    T Mask = (std::numeric_limits<T>::max)() >> Shift;
+     while (Shift) {
+       if ((Val & Mask) == 0) {
+         Val >>= Shift;
+@@ -238,7 +238,7 @@ unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) {
+ ///   valid arguments.
+ template <typename T> T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) {
+   if (ZB == ZB_Max && Val == 0)
+-    return std::numeric_limits<T>::max();
++    return (std::numeric_limits<T>::max)();
+ 
+   return countTrailingZeros(Val, ZB_Undefined);
+ }
+@@ -279,7 +279,7 @@ template <typename T> T maskLeadingZeros(unsigned N) {
+ ///   valid arguments.
+ template <typename T> T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) {
+   if (ZB == ZB_Max && Val == 0)
+-    return std::numeric_limits<T>::max();
++    return (std::numeric_limits<T>::max)();
+ 
+   // Use ^ instead of - because both gcc and llvm can remove the associated ^
+   // in the __builtin_clz intrinsic on x86.
+@@ -594,26 +594,26 @@ inline double Log2(double Value) {
+ /// (32 bit edition.)
+ /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+ inline unsigned Log2_32(uint32_t Value) {
+-  return 31 - countLeadingZeros(Value);
++  return static_cast<unsigned>(31 - countLeadingZeros(Value));
+ }
+ 
+ /// Return the floor log base 2 of the specified value, -1 if the value is zero.
+ /// (64 bit edition.)
+ inline unsigned Log2_64(uint64_t Value) {
+-  return 63 - countLeadingZeros(Value);
++  return static_cast<unsigned>(63 - countLeadingZeros(Value));
+ }
+ 
+ /// Return the ceil log base 2 of the specified value, 32 if the value is zero.
+ /// (32 bit edition).
+ /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+ inline unsigned Log2_32_Ceil(uint32_t Value) {
+-  return 32 - countLeadingZeros(Value - 1);
++  return static_cast<unsigned>(32 - countLeadingZeros(Value - 1));
+ }
+ 
+ /// Return the ceil log base 2 of the specified value, 64 if the value is zero.
+ /// (64 bit edition.)
+ inline unsigned Log2_64_Ceil(uint64_t Value) {
+-  return 64 - countLeadingZeros(Value - 1);
++  return static_cast<unsigned>(64 - countLeadingZeros(Value - 1));
+ }
+ 
+ /// Return the greatest common divisor of the values using Euclid's algorithm.
+@@ -807,7 +807,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
+   T Z = X + Y;
+   Overflowed = (Z < X || Z < Y);
+   if (Overflowed)
+-    return std::numeric_limits<T>::max();
++    return (std::numeric_limits<T>::max)();
+   else
+     return Z;
+ }
+@@ -832,7 +832,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
+   // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z
+   // will necessarily be less than Log2Max as desired.
+   int Log2Z = Log2_64(X) + Log2_64(Y);
+-  const T Max = std::numeric_limits<T>::max();
++  const T Max = (std::numeric_limits<T>::max)();
+   int Log2Max = Log2_64(Max);
+   if (Log2Z < Log2Max) {
+     return X * Y;
+@@ -952,9 +952,9 @@ std::enable_if_t<std::is_signed<T>::value, T> MulOverflow(T X, T Y, T &Result) {
+   // Check how the max allowed absolute value (2^n for negative, 2^(n-1) for
+   // positive) divided by an argument compares to the other.
+   if (IsNegative)
+-    return UX > (static_cast<U>(std::numeric_limits<T>::max()) + U(1)) / UY;
++    return UX > (static_cast<U>((std::numeric_limits<T>::max)()) + U(1)) / UY;
+   else
+-    return UX > (static_cast<U>(std::numeric_limits<T>::max())) / UY;
++    return UX > (static_cast<U>((std::numeric_limits<T>::max)())) / UY;
+ }
+ 
+ } // End llvm namespace
+diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
+index 8bad715e4..a2b4899e1 100644
+--- a/llvm/lib/Support/SmallVector.cpp
++++ b/llvm/lib/Support/SmallVector.cpp
+@@ -104,7 +104,7 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
+   // In theory 2*capacity can overflow if the capacity is 64 bit, but the
+   // original capacity would never be large enough for this to be a problem.
+   size_t NewCapacity = 2 * OldCapacity + 1; // Always grow.
+-  return std::min(std::max(NewCapacity, MinSize), MaxSize);
++  return (std::min)((std::max)(NewCapacity, MinSize), MaxSize);
+ }
+ 
+ // Note: Moving this function into the header may cause performance regression.
diff --git a/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch b/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch
new file mode 100644
index 0000000..6e57262
--- /dev/null
+++ b/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch
@@ -0,0 +1,31 @@
+From 376285281b6173ee3d6650d71148bc173e4a9f7a Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:13:55 -0400
+Subject: [PATCH 04/28] Change unique_function storage size
+
+---
+ llvm/include/llvm/ADT/FunctionExtras.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h
+index 5a37417dd..8a9d78f41 100644
+--- a/llvm/include/llvm/ADT/FunctionExtras.h
++++ b/llvm/include/llvm/ADT/FunctionExtras.h
+@@ -78,7 +78,7 @@ using EnableIfCallable = std::enable_if_t<llvm::disjunction<
+ 
+ template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
+ protected:
+-  static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
++  static constexpr size_t InlineStorageSize = sizeof(void *) * 4;
+ 
+   template <typename T, class = void>
+   struct IsSizeLessThanThresholdT : std::false_type {};
+@@ -157,7 +157,7 @@ protected:
+         "Should always use all of the out-of-line storage for inline storage!");
+ 
+     // For in-line storage, we just provide an aligned character buffer. We
+-    // provide three pointers worth of storage here.
++    // provide four pointers worth of storage here.
+     // This is mutable as an inlined `const unique_function<void() const>` may
+     // still modify its own mutable members.
+     mutable
diff --git a/upstream_utils/llvm_patches/0005-Threading-updates.patch b/upstream_utils/llvm_patches/0005-Threading-updates.patch
new file mode 100644
index 0000000..1ccd217
--- /dev/null
+++ b/upstream_utils/llvm_patches/0005-Threading-updates.patch
@@ -0,0 +1,185 @@
+From bc86b62f72cbb76a0911996f4b1c6ce476cd1fac Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:17:19 -0400
+Subject: [PATCH 05/28] Threading updates
+
+- Remove guards for threads and exception
+- Prefer scope gaurd over lock gaurd
+---
+ llvm/include/llvm/Support/Compiler.h |  6 -----
+ llvm/lib/Support/ErrorHandling.cpp   | 38 +++++-----------------------
+ llvm/lib/Support/ManagedStatic.cpp   | 10 ++++----
+ 3 files changed, 11 insertions(+), 43 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
+index f5d726ec8..ede1cb172 100644
+--- a/llvm/include/llvm/Support/Compiler.h
++++ b/llvm/include/llvm/Support/Compiler.h
+@@ -540,7 +540,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
+ /// initialize to some constant value. In almost all circumstances this is most
+ /// appropriate for use with a pointer, integer, or small aggregation of
+ /// pointers and integers.
+-#if LLVM_ENABLE_THREADS
+ #if __has_feature(cxx_thread_local) || defined(_MSC_VER)
+ #define LLVM_THREAD_LOCAL thread_local
+ #else
+@@ -548,11 +547,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
+ // we only need the restricted functionality that provides.
+ #define LLVM_THREAD_LOCAL __thread
+ #endif
+-#else // !LLVM_ENABLE_THREADS
+-// If threading is disabled entirely, this compiles to nothing and you get
+-// a normal global variable.
+-#define LLVM_THREAD_LOCAL
+-#endif
+ 
+ /// \macro LLVM_ENABLE_EXCEPTIONS
+ /// Whether LLVM is built with exception support.
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index 8ae8fb8b4..89440b5ab 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -44,7 +44,6 @@ static void *ErrorHandlerUserData = nullptr;
+ static fatal_error_handler_t BadAllocErrorHandler = nullptr;
+ static void *BadAllocErrorHandlerUserData = nullptr;
+ 
+-#if LLVM_ENABLE_THREADS == 1
+ // Mutexes to synchronize installing error handlers and calling error handlers.
+ // Do not use ManagedStatic, or that may allocate memory while attempting to
+ // report an OOM.
+@@ -58,22 +57,17 @@ static void *BadAllocErrorHandlerUserData = nullptr;
+ // builds. We can remove these ifdefs if that script goes away.
+ static std::mutex ErrorHandlerMutex;
+ static std::mutex BadAllocErrorHandlerMutex;
+-#endif
+ 
+ void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
+                                        void *user_data) {
+-#if LLVM_ENABLE_THREADS == 1
+-  std::lock_guard<std::mutex> Lock(ErrorHandlerMutex);
+-#endif
++  std::scoped_lock Lock(ErrorHandlerMutex);
+   assert(!ErrorHandler && "Error handler already registered!\n");
+   ErrorHandler = handler;
+   ErrorHandlerUserData = user_data;
+ }
+ 
+ void llvm::remove_fatal_error_handler() {
+-#if LLVM_ENABLE_THREADS == 1
+-  std::lock_guard<std::mutex> Lock(ErrorHandlerMutex);
+-#endif
++  std::scoped_lock Lock(ErrorHandlerMutex);
+   ErrorHandler = nullptr;
+   ErrorHandlerUserData = nullptr;
+ }
+@@ -92,9 +86,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
+   {
+     // Only acquire the mutex while reading the handler, so as not to invoke a
+     // user-supplied callback under a lock.
+-#if LLVM_ENABLE_THREADS == 1
+-    std::lock_guard<std::mutex> Lock(ErrorHandlerMutex);
+-#endif
++    std::scoped_lock Lock(ErrorHandlerMutex);
+     handler = ErrorHandler;
+     handlerData = ErrorHandlerUserData;
+   }
+@@ -123,18 +115,14 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
+ 
+ void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
+                                            void *user_data) {
+-#if LLVM_ENABLE_THREADS == 1
+-  std::lock_guard<std::mutex> Lock(BadAllocErrorHandlerMutex);
+-#endif
++  std::scoped_lock Lock(BadAllocErrorHandlerMutex);
+   assert(!ErrorHandler && "Bad alloc error handler already registered!\n");
+   BadAllocErrorHandler = handler;
+   BadAllocErrorHandlerUserData = user_data;
+ }
+ 
+ void llvm::remove_bad_alloc_error_handler() {
+-#if LLVM_ENABLE_THREADS == 1
+-  std::lock_guard<std::mutex> Lock(BadAllocErrorHandlerMutex);
+-#endif
++  std::scoped_lock Lock(BadAllocErrorHandlerMutex);
+   BadAllocErrorHandler = nullptr;
+   BadAllocErrorHandlerUserData = nullptr;
+ }
+@@ -145,9 +133,7 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
+   {
+     // Only acquire the mutex while reading the handler, so as not to invoke a
+     // user-supplied callback under a lock.
+-#if LLVM_ENABLE_THREADS == 1
+-    std::lock_guard<std::mutex> Lock(BadAllocErrorHandlerMutex);
+-#endif
++    std::scoped_lock Lock(BadAllocErrorHandlerMutex);
+     Handler = BadAllocErrorHandler;
+     HandlerData = BadAllocErrorHandlerUserData;
+   }
+@@ -157,10 +143,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
+     llvm_unreachable("bad alloc handler should not return");
+   }
+ 
+-#ifdef LLVM_ENABLE_EXCEPTIONS
+-  // If exceptions are enabled, make OOM in malloc look like OOM in new.
+-  throw std::bad_alloc();
+-#else
+   // Don't call the normal error handler. It may allocate memory. Directly write
+   // an OOM to stderr and abort.
+   const char *OOMMessage = "LLVM ERROR: out of memory\n";
+@@ -169,15 +151,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
+   (void)!::write(2, Reason, strlen(Reason));
+   (void)!::write(2, Newline, strlen(Newline));
+   abort();
+-#endif
+ }
+ 
+-#ifdef LLVM_ENABLE_EXCEPTIONS
+-// Do not set custom new handler if exceptions are enabled. In this case OOM
+-// errors are handled by throwing 'std::bad_alloc'.
+-void llvm::install_out_of_memory_new_handler() {
+-}
+-#else
+ // Causes crash on allocation failure. It is called prior to the handler set by
+ // 'install_bad_alloc_error_handler'.
+ static void out_of_memory_new_handler() {
+@@ -192,7 +167,6 @@ void llvm::install_out_of_memory_new_handler() {
+   assert((old == nullptr || old == out_of_memory_new_handler) &&
+          "new-handler already installed");
+ }
+-#endif
+ 
+ void llvm::llvm_unreachable_internal(const char *msg, const char *file,
+                                      unsigned line) {
+diff --git a/llvm/lib/Support/ManagedStatic.cpp b/llvm/lib/Support/ManagedStatic.cpp
+index a6ae67066..fc798b7ec 100644
+--- a/llvm/lib/Support/ManagedStatic.cpp
++++ b/llvm/lib/Support/ManagedStatic.cpp
+@@ -12,23 +12,23 @@
+ 
+ #include "llvm/Support/ManagedStatic.h"
+ #include "llvm/Config/config.h"
+-#include "llvm/Support/Threading.h"
++#include "llvm/Support/mutex.h"
+ #include <cassert>
+ #include <mutex>
+ using namespace llvm;
+ 
+ static const ManagedStaticBase *StaticList = nullptr;
+ 
+-static std::recursive_mutex *getManagedStaticMutex() {
+-  static std::recursive_mutex m;
++static llvm::mutex *getManagedStaticMutex() {
++  static llvm::mutex m;
+   return &m;
+ }
+ 
+ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
+                                               void (*Deleter)(void*)) const {
+   assert(Creator);
+-  if (llvm_is_multithreaded()) {
+-    std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex());
++  if (1) {
++    std::scoped_lock Lock(*getManagedStaticMutex());
+ 
+     if (!Ptr.load(std::memory_order_relaxed)) {
+       void *Tmp = Creator();
diff --git a/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch b/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch
new file mode 100644
index 0000000..bcb4950
--- /dev/null
+++ b/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch
@@ -0,0 +1,341 @@
+From 008e921f77933f475174d74a6b70309c6fbe0771 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:28:13 -0400
+Subject: [PATCH 06/28] \#ifdef guard safety
+
+Prevents redefinition if someone is pulling in real LLVM, since the macros are in global namespace
+---
+ llvm/include/llvm/Support/Compiler.h | 50 ++++++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
+index ede1cb172..8b8260b50 100644
+--- a/llvm/include/llvm/Support/Compiler.h
++++ b/llvm/include/llvm/Support/Compiler.h
+@@ -86,6 +86,7 @@
+ /// * 1928: VS2019, version 16.8 + 16.9
+ /// * 1929: VS2019, version 16.10 + 16.11
+ /// * 1930: VS2022, version 17.0
++#ifndef LLVM_MSC_PREREQ
+ #ifdef _MSC_VER
+ #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version))
+ 
+@@ -99,6 +100,7 @@
+ #else
+ #define LLVM_MSC_PREREQ(version) 0
+ #endif
++#endif
+ 
+ /// Does the compiler support ref-qualifiers for *this?
+ ///
+@@ -112,11 +114,13 @@
+ ///
+ /// This can be used to provide lvalue/rvalue overrides of member functions.
+ /// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS
++#ifndef LLVM_LVALUE_FUNCTION
+ #if LLVM_HAS_RVALUE_REFERENCE_THIS
+ #define LLVM_LVALUE_FUNCTION &
+ #else
+ #define LLVM_LVALUE_FUNCTION
+ #endif
++#endif
+ 
+ /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
+ /// into a shared library, then the class should be private to the library and
+@@ -140,21 +144,26 @@
+ #define LLVM_EXTERNAL_VISIBILITY
+ #endif
+ 
++#ifndef LLVM_PREFETCH
+ #if defined(__GNUC__)
+ #define LLVM_PREFETCH(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
+ #else
+ #define LLVM_PREFETCH(addr, rw, locality)
+ #endif
++#endif
+ 
++#ifndef LLVM_ATTRIBUTE_USED
+ #if __has_attribute(used)
+ #define LLVM_ATTRIBUTE_USED __attribute__((__used__))
+ #else
+ #define LLVM_ATTRIBUTE_USED
+ #endif
++#endif
+ 
+ /// LLVM_NODISCARD - Warn if a type or return value is discarded.
+ 
+ // Use the 'nodiscard' attribute in C++17 or newer mode.
++#ifndef LLVM_NODISCARD
+ #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard)
+ #define LLVM_NODISCARD [[nodiscard]]
+ #elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result)
+@@ -168,6 +177,7 @@
+ #else
+ #define LLVM_NODISCARD
+ #endif
++#endif
+ 
+ // Indicate that a non-static, non-const C++ member function reinitializes
+ // the entire object to a known state, independent of the previous state of
+@@ -190,11 +200,13 @@
+ // more portable solution:
+ //   (void)unused_var_name;
+ // Prefer cast-to-void wherever it is sufficient.
++#ifndef LLVM_ATTRIBUTE_UNUSED
+ #if __has_attribute(unused)
+ #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__))
+ #else
+ #define LLVM_ATTRIBUTE_UNUSED
+ #endif
++#endif
+ 
+ // FIXME: Provide this for PE/COFF targets.
+ #if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) &&  \
+@@ -204,6 +216,7 @@
+ #define LLVM_ATTRIBUTE_WEAK
+ #endif
+ 
++#ifndef LLVM_READNONE
+ // Prior to clang 3.2, clang did not accept any spelling of
+ // __has_attribute(const), so assume it is supported.
+ #if defined(__clang__) || defined(__GNUC__)
+@@ -212,13 +225,16 @@
+ #else
+ #define LLVM_READNONE
+ #endif
++#endif
+ 
++#ifndef LLVM_READONLY
+ #if __has_attribute(pure) || defined(__GNUC__)
+ // aka 'PURE' but following LLVM Conventions.
+ #define LLVM_READONLY __attribute__((__pure__))
+ #else
+ #define LLVM_READONLY
+ #endif
++#endif
+ 
+ #if __has_attribute(minsize)
+ #define LLVM_ATTRIBUTE_MINSIZE __attribute__((minsize))
+@@ -226,6 +242,7 @@
+ #define LLVM_ATTRIBUTE_MINSIZE
+ #endif
+ 
++#ifndef LLVM_LIKELY
+ #if __has_builtin(__builtin_expect) || defined(__GNUC__)
+ #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true)
+ #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false)
+@@ -233,9 +250,11 @@
+ #define LLVM_LIKELY(EXPR) (EXPR)
+ #define LLVM_UNLIKELY(EXPR) (EXPR)
+ #endif
++#endif
+ 
+ /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so,
+ /// mark a method "not for inlining".
++#ifndef LLVM_ATTRIBUTE_NOINLINE
+ #if __has_attribute(noinline)
+ #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline))
+ #elif defined(_MSC_VER)
+@@ -243,9 +262,11 @@
+ #else
+ #define LLVM_ATTRIBUTE_NOINLINE
+ #endif
++#endif
+ 
+ /// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do
+ /// so, mark a method "always inline" because it is performance sensitive.
++#ifndef LLVM_ATTRIBUTE_ALWAYS_INLINE
+ #if __has_attribute(always_inline)
+ #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
+ #elif defined(_MSC_VER)
+@@ -253,6 +274,7 @@
+ #else
+ #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline
+ #endif
++#endif
+ 
+ /// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do
+ /// so, mark a method "no debug" because debug info makes the debugger
+@@ -263,6 +285,7 @@
+ #define LLVM_ATTRIBUTE_NODEBUG
+ #endif
+ 
++#ifndef LLVM_ATTRIBUTE_RETURNS_NONNULL
+ #if __has_attribute(returns_nonnull)
+ #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull))
+ #elif defined(_MSC_VER)
+@@ -270,9 +293,11 @@
+ #else
+ #define LLVM_ATTRIBUTE_RETURNS_NONNULL
+ #endif
++#endif
+ 
+ /// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a
+ /// pointer that does not alias any other valid pointer.
++#ifndef LLVM_ATTRIBUTE_RETURNS_NOALIAS
+ #ifdef __GNUC__
+ #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__))
+ #elif defined(_MSC_VER)
+@@ -280,8 +305,10 @@
+ #else
+ #define LLVM_ATTRIBUTE_RETURNS_NOALIAS
+ #endif
++#endif
+ 
+ /// LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
++#ifndef LLVM_FALLTHROUGH
+ #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough)
+ #define LLVM_FALLTHROUGH [[fallthrough]]
+ #elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
+@@ -293,6 +320,7 @@
+ #else
+ #define LLVM_FALLTHROUGH
+ #endif
++#endif
+ 
+ /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that
+ /// they are constant initialized.
+@@ -321,20 +349,25 @@
+ 
+ /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
+ /// pedantic diagnostics.
++#ifndef LLVM_EXTENSION
+ #ifdef __GNUC__
+ #define LLVM_EXTENSION __extension__
+ #else
+ #define LLVM_EXTENSION
+ #endif
++#endif
+ 
+ // LLVM_ATTRIBUTE_DEPRECATED(decl, "message")
+ // This macro will be removed.
+ // Use C++14's attribute instead: [[deprecated("message")]]
++#ifndef LLVM_ATTRIBUTE_DEPRECATED
+ #define LLVM_ATTRIBUTE_DEPRECATED(decl, message) [[deprecated(message)]] decl
++#endif
+ 
+ /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands
+ /// to an expression which states that it is undefined behavior for the
+ /// compiler to reach this point.  Otherwise is not defined.
++#ifndef LLVM_BUILTIN_UNREACHABLE
+ #if __has_builtin(__builtin_unreachable) || defined(__GNUC__)
+ # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable()
+ #elif defined(_MSC_VER)
+@@ -342,9 +375,11 @@
+ #else
+ # define LLVM_BUILTIN_UNREACHABLE
+ #endif
++#endif
+ 
+ /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression
+ /// which causes the program to exit abnormally.
++#ifndef LLVM_BUILTIN_TRAP
+ #if __has_builtin(__builtin_trap) || defined(__GNUC__)
+ # define LLVM_BUILTIN_TRAP __builtin_trap()
+ #elif defined(_MSC_VER)
+@@ -356,10 +391,12 @@
+ #else
+ # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0
+ #endif
++#endif
+ 
+ /// LLVM_BUILTIN_DEBUGTRAP - On compilers which support it, expands to
+ /// an expression which causes the program to break while running
+ /// under a debugger.
++#ifndef LLVM_BUILTIN_DEBUGTRAP
+ #if __has_builtin(__builtin_debugtrap)
+ # define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap()
+ #elif defined(_MSC_VER)
+@@ -373,9 +410,11 @@
+ // program to abort if encountered.
+ # define LLVM_BUILTIN_DEBUGTRAP
+ #endif
++#endif
+ 
+ /// \macro LLVM_ASSUME_ALIGNED
+ /// Returns a pointer with an assumed alignment.
++#ifndef LLVM_ASSUME_ALIGNED
+ #if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__)
+ # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
+ #elif defined(LLVM_BUILTIN_UNREACHABLE)
+@@ -384,6 +423,7 @@
+ #else
+ # define LLVM_ASSUME_ALIGNED(p, a) (p)
+ #endif
++#endif
+ 
+ /// \macro LLVM_PACKED
+ /// Used to specify a packed structure.
+@@ -403,6 +443,7 @@
+ ///   long long l;
+ /// };
+ /// LLVM_PACKED_END
++#ifndef LLVM_PACKED
+ #ifdef _MSC_VER
+ # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
+ # define LLVM_PACKED_START __pragma(pack(push, 1))
+@@ -412,11 +453,13 @@
+ # define LLVM_PACKED_START _Pragma("pack(push, 1)")
+ # define LLVM_PACKED_END   _Pragma("pack(pop)")
+ #endif
++#endif
+ 
+ /// \macro LLVM_PTR_SIZE
+ /// A constant integer equivalent to the value of sizeof(void*).
+ /// Generally used in combination with alignas or when doing computation in the
+ /// preprocessor.
++#ifndef LLVM_PTR_SIZE
+ #ifdef __SIZEOF_POINTER__
+ # define LLVM_PTR_SIZE __SIZEOF_POINTER__
+ #elif defined(_WIN64)
+@@ -428,6 +471,7 @@
+ #else
+ # define LLVM_PTR_SIZE sizeof(void *)
+ #endif
++#endif
+ 
+ /// \macro LLVM_MEMORY_SANITIZER_BUILD
+ /// Whether LLVM itself is built with MemorySanitizer instrumentation.
+@@ -498,11 +542,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
+ 
+ /// \macro LLVM_NO_SANITIZE
+ /// Disable a particular sanitizer for a function.
++#ifndef LLVM_NO_SANITIZE
+ #if __has_attribute(no_sanitize)
+ #define LLVM_NO_SANITIZE(KIND) __attribute__((no_sanitize(KIND)))
+ #else
+ #define LLVM_NO_SANITIZE(KIND)
+ #endif
++#endif
+ 
+ /// Mark debug helper function definitions like dump() that should not be
+ /// stripped from debug builds.
+@@ -510,17 +556,20 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
+ /// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always
+ /// get stripped in release builds.
+ // FIXME: Move this to a private config.h as it's not usable in public headers.
++#ifndef LLVM_DUMP_METHOD
+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED
+ #else
+ #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE
+ #endif
++#endif
+ 
+ /// \macro LLVM_PRETTY_FUNCTION
+ /// Gets a user-friendly looking function signature for the current scope
+ /// using the best available method on each platform.  The exact format of the
+ /// resulting string is implementation specific and non-portable, so this should
+ /// only be used, for example, for logging or diagnostics.
++#ifndef LLVM_PRETTY_FUNCTION
+ #if defined(_MSC_VER)
+ #define LLVM_PRETTY_FUNCTION __FUNCSIG__
+ #elif defined(__GNUC__) || defined(__clang__)
+@@ -528,6 +577,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
+ #else
+ #define LLVM_PRETTY_FUNCTION __func__
+ #endif
++#endif
+ 
+ /// \macro LLVM_THREAD_LOCAL
+ /// A thread-local storage specifier which can be used with globals,
diff --git a/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch b/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch
new file mode 100644
index 0000000..cfbe9a1
--- /dev/null
+++ b/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch
@@ -0,0 +1,78 @@
+From c26562caae6a685716a8785ad8689833c9996549 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:37:34 -0400
+Subject: [PATCH 07/28] Explicitly use std::
+
+---
+ llvm/include/llvm/ADT/SmallSet.h       | 2 +-
+ llvm/include/llvm/Support/MathExtras.h | 2 +-
+ llvm/lib/Support/ErrorHandling.cpp     | 2 +-
+ llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 +-
+ llvm/unittests/ADT/StringMapTest.cpp   | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h
+index bfe93e997..403e108fd 100644
+--- a/llvm/include/llvm/ADT/SmallSet.h
++++ b/llvm/include/llvm/ADT/SmallSet.h
+@@ -270,7 +270,7 @@ bool operator==(const SmallSet<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
+     return false;
+ 
+   // All elements in LHS must also be in RHS
+-  return all_of(LHS, [&RHS](const T &E) { return RHS.count(E); });
++  return std::all_of(LHS.begin(), LHS.end(), [&RHS](const T &E) { return RHS.count(E); });
+ }
+ 
+ /// Inequality comparison for SmallSet.
+diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
+index db9fbc148..da843ef79 100644
+--- a/llvm/include/llvm/Support/MathExtras.h
++++ b/llvm/include/llvm/Support/MathExtras.h
+@@ -586,7 +586,7 @@ inline double Log2(double Value) {
+ #if defined(__ANDROID_API__) && __ANDROID_API__ < 18
+   return __builtin_log(Value) / __builtin_log(2.0);
+ #else
+-  return log2(Value);
++  return std::log2(Value);
+ #endif
+ }
+ 
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index 89440b5ab..f80e28e87 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -210,7 +210,7 @@ void LLVMResetFatalErrorHandler() {
+ // I'd rather not double the line count of the following.
+ #define MAP_ERR_TO_COND(x, y)                                                  \
+   case x:                                                                      \
+-    return make_error_code(errc::y)
++    return std::make_error_code(std::errc::y)
+ 
+ std::error_code llvm::mapWindowsError(unsigned EV) {
+   switch (EV) {
+diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp
+index 6f3c94eed..531f81ab5 100644
+--- a/llvm/unittests/ADT/SmallPtrSetTest.cpp
++++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp
+@@ -298,7 +298,7 @@ TEST(SmallPtrSetTest, dereferenceAndIterate) {
+ 
+   // Sort.  We should hit the first element just once and the final element N
+   // times.
+-  llvm::sort(std::begin(Found), std::end(Found));
++  std::sort(std::begin(Found), std::end(Found));
+   for (auto F = std::begin(Found), E = std::end(Found); F != E; ++F)
+     EXPECT_EQ(F - Found + 1, *F);
+ }
+diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
+index 86907ab61..6d0c0942c 100644
+--- a/llvm/unittests/ADT/StringMapTest.cpp
++++ b/llvm/unittests/ADT/StringMapTest.cpp
+@@ -329,7 +329,7 @@ TEST_F(StringMapTest, IterMapKeysSmallVector) {
+   Map["D"] = 3;
+ 
+   auto Keys = to_vector<4>(Map.keys());
+-  llvm::sort(Keys);
++  std::sort(Keys.begin(), Keys.end());
+ 
+   SmallVector<std::string_view, 4> Expected = {"A", "B", "C", "D"};
+   EXPECT_EQ(Expected, Keys);
diff --git a/upstream_utils/llvm_patches/0008-Remove-format_provider.patch b/upstream_utils/llvm_patches/0008-Remove-format_provider.patch
new file mode 100644
index 0000000..1e43a8b
--- /dev/null
+++ b/upstream_utils/llvm_patches/0008-Remove-format_provider.patch
@@ -0,0 +1,232 @@
+From f35fcb2c40caceed14437e65131e9fe1cf94deac Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 7 May 2022 22:53:50 -0400
+Subject: [PATCH 08/28] Remove format_provider
+
+---
+ llvm/include/llvm/Support/Chrono.h      | 109 ------------------------
+ llvm/include/llvm/Support/raw_ostream.h |   6 --
+ llvm/unittests/Support/Chrono.cpp       |  61 -------------
+ 3 files changed, 176 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h
+index a7dea19d9..9f9a2b5ca 100644
+--- a/llvm/include/llvm/Support/Chrono.h
++++ b/llvm/include/llvm/Support/Chrono.h
+@@ -10,7 +10,6 @@
+ #define LLVM_SUPPORT_CHRONO_H
+ 
+ #include "llvm/Support/Compiler.h"
+-#include "llvm/Support/FormatProviders.h"
+ 
+ #include <chrono>
+ #include <ctime>
+@@ -59,114 +58,6 @@ toTimePoint(std::time_t T, uint32_t nsec) {
+ 
+ raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP);
+ 
+-/// Format provider for TimePoint<>
+-///
+-/// The options string is a strftime format string, with extensions:
+-///   - %L is millis: 000-999
+-///   - %f is micros: 000000-999999
+-///   - %N is nanos: 000000000 - 999999999
+-///
+-/// If no options are given, the default format is "%Y-%m-%d %H:%M:%S.%N".
+-template <>
+-struct format_provider<sys::TimePoint<>> {
+-  static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS,
+-                     std::string_view Style);
+-};
+-
+-namespace detail {
+-template <typename Period> struct unit { static const char value[]; };
+-template <typename Period> const char unit<Period>::value[] = "";
+-
+-template <> struct unit<std::ratio<3600>> { static const char value[]; };
+-template <> struct unit<std::ratio<60>> { static const char value[]; };
+-template <> struct unit<std::ratio<1>> { static const char value[]; };
+-template <> struct unit<std::milli> { static const char value[]; };
+-template <> struct unit<std::micro> { static const char value[]; };
+-template <> struct unit<std::nano> { static const char value[]; };
+-} // namespace detail
+-
+-/// Implementation of format_provider<T> for duration types.
+-///
+-/// The options string of a duration type has the grammar:
+-///
+-///   duration_options  ::= [unit][show_unit [number_options]]
+-///   unit              ::= `h`|`m`|`s`|`ms|`us`|`ns`
+-///   show_unit         ::= `+` | `-`
+-///   number_options    ::= options string for a integral or floating point type
+-///
+-///   Examples
+-///   =================================
+-///   |  options  | Input | Output    |
+-///   =================================
+-///   | ""        | 1s    | 1 s       |
+-///   | "ms"      | 1s    | 1000 ms   |
+-///   | "ms-"     | 1s    | 1000      |
+-///   | "ms-n"    | 1s    | 1,000     |
+-///   | ""        | 1.0s  | 1.00 s    |
+-///   =================================
+-///
+-///  If the unit of the duration type is not one of the units specified above,
+-///  it is still possible to format it, provided you explicitly request a
+-///  display unit or you request that the unit is not displayed.
+-
+-template <typename Rep, typename Period>
+-struct format_provider<std::chrono::duration<Rep, Period>> {
+-private:
+-  typedef std::chrono::duration<Rep, Period> Dur;
+-  typedef std::conditional_t<std::chrono::treat_as_floating_point<Rep>::value,
+-                             double, intmax_t>
+-      InternalRep;
+-
+-  template <typename AsPeriod> static InternalRep getAs(const Dur &D) {
+-    using namespace std::chrono;
+-    return duration_cast<duration<InternalRep, AsPeriod>>(D).count();
+-  }
+-
+-  static std::pair<InternalRep, std::string_view> consumeUnit(std::string_view &Style,
+-                                                        const Dur &D) {
+-    using namespace std::chrono;
+-    if (Style.consume_front("ns"))
+-      return {getAs<std::nano>(D), "ns"};
+-    if (Style.consume_front("us"))
+-      return {getAs<std::micro>(D), "us"};
+-    if (Style.consume_front("ms"))
+-      return {getAs<std::milli>(D), "ms"};
+-    if (Style.consume_front("s"))
+-      return {getAs<std::ratio<1>>(D), "s"};
+-    if (Style.consume_front("m"))
+-      return {getAs<std::ratio<60>>(D), "m"};
+-    if (Style.consume_front("h"))
+-      return {getAs<std::ratio<3600>>(D), "h"};
+-    return {D.count(), detail::unit<Period>::value};
+-  }
+-
+-  static bool consumeShowUnit(std::string_view &Style) {
+-    if (Style.empty())
+-      return true;
+-    if (Style.consume_front("-"))
+-      return false;
+-    if (Style.consume_front("+"))
+-      return true;
+-    assert(0 && "Unrecognised duration format");
+-    return true;
+-  }
+-
+-public:
+-  static void format(const Dur &D, llvm::raw_ostream &Stream, std::string_view Style) {
+-    InternalRep count;
+-    std::string_view unit;
+-    std::tie(count, unit) = consumeUnit(Style, D);
+-    bool show_unit = consumeShowUnit(Style);
+-
+-    format_provider<InternalRep>::format(count, Stream, Style);
+-
+-    if (show_unit) {
+-      assert(!unit.empty());
+-      Stream << " " << unit;
+-    }
+-  }
+-};
+-
+ } // namespace llvm
+ 
+ #endif // LLVM_SUPPORT_CHRONO_H
+diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
+index 9a1dd7a60..a25ca5b7b 100644
+--- a/llvm/include/llvm/Support/raw_ostream.h
++++ b/llvm/include/llvm/Support/raw_ostream.h
+@@ -28,12 +28,6 @@
+ 
+ namespace llvm {
+ 
+-class Duration;
+-class formatv_object_base;
+-class format_object_base;
+-class FormattedString;
+-class FormattedNumber;
+-class FormattedBytes;
+ template <class T> class LLVM_NODISCARD Expected;
+ 
+ namespace sys {
+diff --git a/llvm/unittests/Support/Chrono.cpp b/llvm/unittests/Support/Chrono.cpp
+index 9a08a5c1b..3c049de18 100644
+--- a/llvm/unittests/Support/Chrono.cpp
++++ b/llvm/unittests/Support/Chrono.cpp
+@@ -30,37 +30,6 @@ TEST(Chrono, TimeTConversion) {
+   EXPECT_EQ(TP, toTimePoint(toTimeT(TP)));
+ }
+ 
+-TEST(Chrono, TimePointFormat) {
+-  using namespace std::chrono;
+-  struct tm TM {};
+-  TM.tm_year = 106;
+-  TM.tm_mon = 0;
+-  TM.tm_mday = 2;
+-  TM.tm_hour = 15;
+-  TM.tm_min = 4;
+-  TM.tm_sec = 5;
+-  TM.tm_isdst = -1;
+-  TimePoint<> T =
+-      system_clock::from_time_t(mktime(&TM)) + nanoseconds(123456789);
+-
+-  // operator<< uses the format YYYY-MM-DD HH:MM:SS.NNNNNNNNN
+-  std::string S;
+-  raw_string_ostream OS(S);
+-  OS << T;
+-  EXPECT_EQ("2006-01-02 15:04:05.123456789", OS.str());
+-
+-  // formatv default style matches operator<<.
+-  EXPECT_EQ("2006-01-02 15:04:05.123456789", formatv("{0}", T).str());
+-  // formatv supports strftime-style format strings.
+-  EXPECT_EQ("15:04:05", formatv("{0:%H:%M:%S}", T).str());
+-  // formatv supports our strftime extensions for sub-second precision.
+-  EXPECT_EQ("123", formatv("{0:%L}", T).str());
+-  EXPECT_EQ("123456", formatv("{0:%f}", T).str());
+-  EXPECT_EQ("123456789", formatv("{0:%N}", T).str());
+-  // our extensions don't interfere with %% escaping.
+-  EXPECT_EQ("%foo", formatv("{0:%%foo}", T).str());
+-}
+-
+ // Test that toTimePoint and toTimeT can be called with a arguments with varying
+ // precisions.
+ TEST(Chrono, ImplicitConversions) {
+@@ -78,34 +47,4 @@ TEST(Chrono, ImplicitConversions) {
+   EXPECT_EQ(TimeT, toTimeT(Nano));
+ }
+ 
+-TEST(Chrono, DurationFormat) {
+-  EXPECT_EQ("1 h", formatv("{0}", hours(1)).str());
+-  EXPECT_EQ("1 m", formatv("{0}", minutes(1)).str());
+-  EXPECT_EQ("1 s", formatv("{0}", seconds(1)).str());
+-  EXPECT_EQ("1 ms", formatv("{0}", milliseconds(1)).str());
+-  EXPECT_EQ("1 us", formatv("{0}", microseconds(1)).str());
+-  EXPECT_EQ("1 ns", formatv("{0}", nanoseconds(1)).str());
+-
+-  EXPECT_EQ("1 s", formatv("{0:+}", seconds(1)).str());
+-  EXPECT_EQ("1", formatv("{0:-}", seconds(1)).str());
+-
+-  EXPECT_EQ("1000 ms", formatv("{0:ms}", seconds(1)).str());
+-  EXPECT_EQ("1000000 us", formatv("{0:us}", seconds(1)).str());
+-  EXPECT_EQ("1000", formatv("{0:ms-}", seconds(1)).str());
+-
+-  EXPECT_EQ("1,000 ms", formatv("{0:+n}", milliseconds(1000)).str());
+-  EXPECT_EQ("0x3e8", formatv("{0:-x}", milliseconds(1000)).str());
+-  EXPECT_EQ("010", formatv("{0:-3}", milliseconds(10)).str());
+-  EXPECT_EQ("10,000", formatv("{0:ms-n}", seconds(10)).str());
+-
+-  EXPECT_EQ("1.00 s", formatv("{0}", duration<float>(1)).str());
+-  EXPECT_EQ("0.123 s", formatv("{0:+3}", duration<float>(0.123f)).str());
+-  EXPECT_EQ("1.230e-01 s", formatv("{0:+e3}", duration<float>(0.123f)).str());
+-
+-  typedef duration<float, std::ratio<60 * 60 * 24 * 14, 1000000>>
+-      microfortnights;
+-  EXPECT_EQ("1.00", formatv("{0:-}", microfortnights(1)).str());
+-  EXPECT_EQ("1209.60 ms", formatv("{0:ms}", microfortnights(1)).str());
+-}
+-
+ } // anonymous namespace
diff --git a/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch b/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch
new file mode 100644
index 0000000..2255dd1
--- /dev/null
+++ b/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch
@@ -0,0 +1,228 @@
+From 2c53d8ac36f378fda347f36ef2bc7fbc2038cb93 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 13:34:07 -0400
+Subject: [PATCH 09/28] Add compiler warning pragmas
+
+---
+ llvm/include/llvm/ADT/FunctionExtras.h | 11 +++++++++++
+ llvm/include/llvm/ADT/Hashing.h        |  9 +++++++++
+ llvm/include/llvm/ADT/SmallVector.h    |  8 ++++++++
+ llvm/include/llvm/Support/MathExtras.h |  9 +++++++++
+ llvm/include/llvm/Support/MemAlloc.h   | 13 +++++++++++++
+ llvm/lib/Support/raw_ostream.cpp       |  4 ++++
+ llvm/unittests/ADT/DenseMapTest.cpp    |  4 ++++
+ llvm/unittests/ADT/MapVectorTest.cpp   |  7 +++++++
+ llvm/unittests/ADT/SmallVectorTest.cpp |  4 ++++
+ llvm/unittests/Support/AlignOfTest.cpp |  7 +++----
+ 10 files changed, 72 insertions(+), 4 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h
+index 8a9d78f41..3efa73587 100644
+--- a/llvm/include/llvm/ADT/FunctionExtras.h
++++ b/llvm/include/llvm/ADT/FunctionExtras.h
+@@ -55,6 +55,13 @@ namespace llvm {
+ ///   It can hold functions with a non-const operator(), like mutable lambdas.
+ template <typename FunctionT> class unique_function;
+ 
++// GCC warns on OutOfLineStorage
++#if defined(__GNUC__) && !defined(__clang__)
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Warray-bounds"
++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
++#endif
++
+ namespace detail {
+ 
+ template <typename T>
+@@ -411,6 +418,10 @@ public:
+   }
+ };
+ 
++#if defined(__GNUC__) && !defined(__clang__)
++#pragma GCC diagnostic pop
++#endif
++
+ } // end namespace llvm
+ 
+ #endif // LLVM_ADT_FUNCTIONEXTRAS_H
+diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h
+index 74a87a3d8..47ff1b2bc 100644
+--- a/llvm/include/llvm/ADT/Hashing.h
++++ b/llvm/include/llvm/ADT/Hashing.h
+@@ -55,6 +55,11 @@
+ #include <tuple>
+ #include <utility>
+ 
++#ifdef _WIN32
++#pragma warning(push)
++#pragma warning(disable : 26495)
++#endif
++
+ namespace llvm {
+ template <typename T, typename Enable> struct DenseMapInfo;
+ 
+@@ -687,4 +692,8 @@ template <> struct DenseMapInfo<hash_code, void> {
+ 
+ } // namespace llvm
+ 
++#ifdef _WIN32
++#pragma warning(pop)
++#endif
++
+ #endif
+diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
+index 8686f7bb5..1e311ea56 100644
+--- a/llvm/include/llvm/ADT/SmallVector.h
++++ b/llvm/include/llvm/ADT/SmallVector.h
+@@ -14,6 +14,14 @@
+ #ifndef LLVM_ADT_SMALLVECTOR_H
+ #define LLVM_ADT_SMALLVECTOR_H
+ 
++// This file uses std::memcpy() to copy std::pair<unsigned int, unsigned int>.
++// That type is POD, but the standard doesn't guarantee that. GCC doesn't treat
++// the type as POD so it throws a warning. We want to consider this a warning
++// instead of an error.
++#if __GNUC__ >= 8
++#pragma GCC diagnostic warning "-Wclass-memaccess"
++#endif
++
+ #include "llvm/Support/Compiler.h"
+ #include "llvm/Support/type_traits.h"
+ #include <algorithm>
+diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
+index da843ef79..fac12dd0e 100644
+--- a/llvm/include/llvm/Support/MathExtras.h
++++ b/llvm/include/llvm/Support/MathExtras.h
+@@ -435,6 +435,11 @@ inline uint64_t maxUIntN(uint64_t N) {
+   return UINT64_MAX >> (64 - N);
+ }
+ 
++#ifdef _WIN32
++#pragma warning(push)
++#pragma warning(disable : 4146)
++#endif
++
+ /// Gets the minimum value for a N-bit signed integer.
+ inline int64_t minIntN(int64_t N) {
+   assert(N > 0 && N <= 64 && "integer width out of range");
+@@ -442,6 +447,10 @@ inline int64_t minIntN(int64_t N) {
+   return UINT64_C(1) + ~(UINT64_C(1) << (N - 1));
+ }
+ 
++#ifdef _WIN32
++#pragma warning(pop)
++#endif
++
+ /// Gets the maximum value for a N-bit signed integer.
+ inline int64_t maxIntN(int64_t N) {
+   assert(N > 0 && N <= 64 && "integer width out of range");
+diff --git a/llvm/include/llvm/Support/MemAlloc.h b/llvm/include/llvm/Support/MemAlloc.h
+index d6012bd5a..01007deb8 100644
+--- a/llvm/include/llvm/Support/MemAlloc.h
++++ b/llvm/include/llvm/Support/MemAlloc.h
+@@ -22,6 +22,14 @@
+ 
+ namespace llvm {
+ 
++#ifdef _WIN32
++#pragma warning(push)
++// Warning on NONNULL, report is not known to abort
++#pragma warning(disable : 6387)
++#pragma warning(disable : 28196)
++#pragma warning(disable : 28183)
++#endif
++
+ LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_malloc(size_t Sz) {
+   void *Result = std::malloc(Sz);
+   if (Result == nullptr) {
+@@ -84,4 +92,9 @@ allocate_buffer(size_t Size, size_t Alignment);
+ void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment);
+ 
+ } // namespace llvm
++
++#ifdef _WIN32
++#pragma warning(pop)
++#endif
++
+ #endif
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index e4c318eb8..ee01a9522 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -10,6 +10,10 @@
+ //
+ //===----------------------------------------------------------------------===//
+ 
++#ifdef _WIN32
++#define _CRT_NONSTDC_NO_WARNINGS
++#endif
++
+ #include "llvm/Support/raw_ostream.h"
+ #include "llvm/ADT/STLArrayExtras.h"
+ #include "llvm/ADT/StringExtras.h"
+diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
+index e505b1907..9fe83a45d 100644
+--- a/llvm/unittests/ADT/DenseMapTest.cpp
++++ b/llvm/unittests/ADT/DenseMapTest.cpp
+@@ -6,6 +6,10 @@
+ //
+ //===----------------------------------------------------------------------===//
+ 
++#if defined(__GNUC__) && !defined(__clang__)
++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
++#endif
++
+ #include "llvm/ADT/DenseMap.h"
+ #include "gtest/gtest.h"
+ #include <map>
+diff --git a/llvm/unittests/ADT/MapVectorTest.cpp b/llvm/unittests/ADT/MapVectorTest.cpp
+index 552f9956b..20ebcd753 100644
+--- a/llvm/unittests/ADT/MapVectorTest.cpp
++++ b/llvm/unittests/ADT/MapVectorTest.cpp
+@@ -6,6 +6,13 @@
+ //
+ //===----------------------------------------------------------------------===//
+ 
++#if defined(__GNUC__)
++#pragma GCC diagnostic ignored "-Wpedantic"
++#if !defined(__clang__)
++#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
++#endif
++#endif
++
+ #include "llvm/ADT/MapVector.h"
+ #include "llvm/ADT/iterator_range.h"
+ #include "gtest/gtest.h"
+diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp
+index fe827546a..0e68bad6c 100644
+--- a/llvm/unittests/ADT/SmallVectorTest.cpp
++++ b/llvm/unittests/ADT/SmallVectorTest.cpp
+@@ -17,6 +17,10 @@
+ #include <list>
+ #include <stdarg.h>
+ 
++#if defined(__GNUC__)
++#pragma GCC diagnostic ignored "-Wpedantic"
++#endif
++
+ using namespace llvm;
+ 
+ namespace {
+diff --git a/llvm/unittests/Support/AlignOfTest.cpp b/llvm/unittests/Support/AlignOfTest.cpp
+index f84895c18..6a50205b1 100644
+--- a/llvm/unittests/Support/AlignOfTest.cpp
++++ b/llvm/unittests/Support/AlignOfTest.cpp
+@@ -31,10 +31,9 @@ namespace {
+ #pragma clang diagnostic ignored "-Wunknown-pragmas"
+ #pragma clang diagnostic ignored "-Winaccessible-base"
+ #elif ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
+-// Pragma based warning suppression was introduced in GGC 4.2.  Additionally
+-// this warning is "enabled by default".  The warning still appears if -Wall is
+-// suppressed.  Apparently GCC suppresses it when -w is specifed, which is odd.
+-#pragma GCC diagnostic warning "-w"
++#pragma GCC diagnostic warning "-Wunknown-pragmas"
++#pragma GCC diagnostic warning "-Winaccessible-base"
++#pragma GCC diagnostic warning "-Wunused-function"
+ #endif
+ 
+ // Define some fixed alignment types to use in these tests.
diff --git a/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch b/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch
new file mode 100644
index 0000000..50f5300
--- /dev/null
+++ b/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch
@@ -0,0 +1,762 @@
+From df2dc9fdb3d57e01423104a71a6a1d1d6382644a Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 13:43:50 -0400
+Subject: [PATCH 10/28] Remove unused functions
+
+---
+ llvm/include/llvm/ADT/SmallString.h      |  80 ------
+ llvm/include/llvm/Support/Errno.h        |   9 -
+ llvm/include/llvm/Support/VersionTuple.h |  40 ---
+ llvm/include/llvm/Support/raw_ostream.h  | 115 +-------
+ llvm/lib/Support/raw_ostream.cpp         | 328 -----------------------
+ 5 files changed, 8 insertions(+), 564 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h
+index 50cbdade4..bfa965fd6 100644
+--- a/llvm/include/llvm/ADT/SmallString.h
++++ b/llvm/include/llvm/ADT/SmallString.h
+@@ -88,48 +88,12 @@ public:
+   /// @name String Comparison
+   /// @{
+ 
+-  /// Check for string equality.  This is more efficient than compare() when
+-  /// the relative ordering of inequal strings isn't needed.
+-  bool equals(std::string_view RHS) const {
+-    return str().equals(RHS);
+-  }
+-
+-  /// Check for string equality, ignoring case.
+-  bool equals_insensitive(std::string_view RHS) const {
+-    return str().equals_insensitive(RHS);
+-  }
+-
+   /// Compare two strings; the result is -1, 0, or 1 if this string is
+   /// lexicographically less than, equal to, or greater than the \p RHS.
+   int compare(std::string_view RHS) const {
+     return str().compare(RHS);
+   }
+ 
+-  /// compare_insensitive - Compare two strings, ignoring case.
+-  int compare_insensitive(std::string_view RHS) const {
+-    return str().compare_insensitive(RHS);
+-  }
+-
+-  /// compare_numeric - Compare two strings, treating sequences of digits as
+-  /// numbers.
+-  int compare_numeric(std::string_view RHS) const {
+-    return str().compare_numeric(RHS);
+-  }
+-
+-  /// @}
+-  /// @name String Predicates
+-  /// @{
+-
+-  /// startswith - Check if this string starts with the given \p Prefix.
+-  bool startswith(std::string_view Prefix) const {
+-    return str().startswith(Prefix);
+-  }
+-
+-  /// endswith - Check if this string ends with the given \p Suffix.
+-  bool endswith(std::string_view Suffix) const {
+-    return str().endswith(Suffix);
+-  }
+-
+   /// @}
+   /// @name String Searching
+   /// @{
+@@ -210,50 +174,6 @@ public:
+   }
+ 
+   /// @}
+-  /// @name Helpful Algorithms
+-  /// @{
+-
+-  /// Return the number of occurrences of \p C in the string.
+-  size_t count(char C) const {
+-    return str().count(C);
+-  }
+-
+-  /// Return the number of non-overlapped occurrences of \p Str in the
+-  /// string.
+-  size_t count(std::string_view Str) const {
+-    return str().count(Str);
+-  }
+-
+-  /// @}
+-  /// @name Substring Operations
+-  /// @{
+-
+-  /// Return a reference to the substring from [Start, Start + N).
+-  ///
+-  /// \param Start The index of the starting character in the substring; if
+-  /// the index is npos or greater than the length of the string then the
+-  /// empty substring will be returned.
+-  ///
+-  /// \param N The number of characters to included in the substring. If \p N
+-  /// exceeds the number of characters remaining in the string, the string
+-  /// suffix (starting with \p Start) will be returned.
+-  std::string_view substr(size_t Start, size_t N = std::string_view::npos) const {
+-    return str().substr(Start, N);
+-  }
+-
+-  /// Return a reference to the substring from [Start, End).
+-  ///
+-  /// \param Start The index of the starting character in the substring; if
+-  /// the index is npos or greater than the length of the string then the
+-  /// empty substring will be returned.
+-  ///
+-  /// \param End The index following the last character to include in the
+-  /// substring. If this is npos, or less than \p Start, or exceeds the
+-  /// number of characters remaining in the string, the string suffix
+-  /// (starting with \p Start) will be returned.
+-  std::string_view slice(size_t Start, size_t End) const {
+-    return str().slice(Start, End);
+-  }
+ 
+   // Extra methods.
+ 
+diff --git a/llvm/include/llvm/Support/Errno.h b/llvm/include/llvm/Support/Errno.h
+index 07df6765d..d9bf68bb3 100644
+--- a/llvm/include/llvm/Support/Errno.h
++++ b/llvm/include/llvm/Support/Errno.h
+@@ -20,15 +20,6 @@
+ namespace llvm {
+ namespace sys {
+ 
+-/// Returns a string representation of the errno value, using whatever
+-/// thread-safe variant of strerror() is available.  Be sure to call this
+-/// immediately after the function that set errno, or errno may have been
+-/// overwritten by an intervening call.
+-std::string StrError();
+-
+-/// Like the no-argument version above, but uses \p errnum instead of errno.
+-std::string StrError(int errnum);
+-
+ template <typename FailT, typename Fun, typename... Args>
+ inline decltype(auto) RetryAfterSignal(const FailT &Fail, const Fun &F,
+                                        const Args &... As) {
+diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h
+index 3d6573bf5..a28e12adc 100644
+--- a/llvm/include/llvm/Support/VersionTuple.h
++++ b/llvm/include/llvm/Support/VersionTuple.h
+@@ -16,7 +16,6 @@
+ 
+ #include "llvm/ADT/DenseMapInfo.h"
+ #include "llvm/ADT/Hashing.h"
+-#include "llvm/Support/HashBuilder.h"
+ #include <optional>
+ #include <string>
+ #include <tuple>
+@@ -159,45 +158,6 @@ public:
+   friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) {
+     return !(X < Y);
+   }
+-
+-  friend llvm::hash_code hash_value(const VersionTuple &VT) {
+-    return llvm::hash_combine(VT.Major, VT.Minor, VT.Subminor, VT.Build);
+-  }
+-
+-  template <typename HasherT, llvm::support::endianness Endianness>
+-  friend void addHash(HashBuilderImpl<HasherT, Endianness> &HBuilder,
+-                      const VersionTuple &VT) {
+-    HBuilder.add(VT.Major, VT.Minor, VT.Subminor, VT.Build);
+-  }
+-
+-  /// Retrieve a string representation of the version number.
+-  std::string getAsString() const;
+-};
+-
+-/// Print a version number.
+-raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V);
+-
+-// Provide DenseMapInfo for version tuples.
+-template <> struct DenseMapInfo<VersionTuple> {
+-  static inline VersionTuple getEmptyKey() { return VersionTuple(0x7FFFFFFF); }
+-  static inline VersionTuple getTombstoneKey() {
+-    return VersionTuple(0x7FFFFFFE);
+-  }
+-  static unsigned getHashValue(const VersionTuple &Value) {
+-    unsigned Result = Value.getMajor();
+-    if (auto Minor = Value.getMinor())
+-      Result = detail::combineHashValue(Result, *Minor);
+-    if (auto Subminor = Value.getSubminor())
+-      Result = detail::combineHashValue(Result, *Subminor);
+-    if (auto Build = Value.getBuild())
+-      Result = detail::combineHashValue(Result, *Build);
+-
+-    return Result;
+-  }
+-
+-  static bool isEqual(const VersionTuple &LHS, const VersionTuple &RHS) {
+-    return LHS == RHS;
+-  }
+ };
+ 
+ } // end namespace llvm
+diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
+index a25ca5b7b..d4521c8e2 100644
+--- a/llvm/include/llvm/Support/raw_ostream.h
++++ b/llvm/include/llvm/Support/raw_ostream.h
+@@ -248,32 +248,6 @@ public:
+     return write(Str.data(), Str.size());
+   }
+ 
+-  raw_ostream &operator<<(unsigned long N);
+-  raw_ostream &operator<<(long N);
+-  raw_ostream &operator<<(unsigned long long N);
+-  raw_ostream &operator<<(long long N);
+-  raw_ostream &operator<<(const void *P);
+-
+-  raw_ostream &operator<<(unsigned int N) {
+-    return this->operator<<(static_cast<unsigned long>(N));
+-  }
+-
+-  raw_ostream &operator<<(int N) {
+-    return this->operator<<(static_cast<long>(N));
+-  }
+-
+-  raw_ostream &operator<<(double N);
+-
+-  /// Output \p N in hexadecimal, without any prefix or padding.
+-  raw_ostream &write_hex(unsigned long long N);
+-
+-  // Change the foreground color of text.
+-  raw_ostream &operator<<(Colors C);
+-
+-  /// Output a formatted UUID with dash separators.
+-  using uuid_t = uint8_t[16];
+-  raw_ostream &write_uuid(const uuid_t UUID);
+-
+   /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
+   /// satisfy llvm::isPrint into an escape sequence.
+   raw_ostream &write_escaped(std::string_view Str, bool UseHexEscapes = false);
+@@ -281,21 +255,6 @@ public:
+   raw_ostream &write(unsigned char C);
+   raw_ostream &write(const char *Ptr, size_t Size);
+ 
+-  // Formatted output, see the format() function in Support/Format.h.
+-  raw_ostream &operator<<(const format_object_base &Fmt);
+-
+-  // Formatted output, see the leftJustify() function in Support/Format.h.
+-  raw_ostream &operator<<(const FormattedString &);
+-
+-  // Formatted output, see the formatHex() function in Support/Format.h.
+-  raw_ostream &operator<<(const FormattedNumber &);
+-
+-  // Formatted output, see the formatv() function in Support/FormatVariadic.h.
+-  raw_ostream &operator<<(const formatv_object_base &);
+-
+-  // Formatted output, see the format_bytes() function in Support/Format.h.
+-  raw_ostream &operator<<(const FormattedBytes &);
+-
+   /// indent - Insert 'NumSpaces' spaces.
+   raw_ostream &indent(unsigned NumSpaces);
+ 
+@@ -310,14 +269,19 @@ public:
+   /// @param BG if true change the background, default: change foreground
+   /// @returns itself so it can be used within << invocations
+   virtual raw_ostream &changeColor(enum Colors Color, bool Bold = false,
+-                                   bool BG = false);
++                                   bool BG = false)  {
++    (void)Color;
++    (void)Bold;
++    (void)BG;
++    return *this;
++  }
+ 
+   /// Resets the colors to terminal defaults. Call this when you are done
+   /// outputting colored text, or before program exit.
+-  virtual raw_ostream &resetColor();
++  virtual raw_ostream &resetColor() { return *this; }
+ 
+   /// Reverses the foreground and background colors.
+-  virtual raw_ostream &reverseColor();
++  virtual raw_ostream &reverseColor() { return *this; }
+ 
+   /// This function determines if this stream is connected to a "tty" or
+   /// "console" window. That is, the output would be displayed to the user
+@@ -392,10 +356,6 @@ private:
+   /// unused bytes in the buffer.
+   void copy_to_buffer(const char *Ptr, size_t Size);
+ 
+-  /// Compute whether colors should be used and do the necessary work such as
+-  /// flushing. The result is affected by calls to enable_color().
+-  bool prepare_colors();
+-
+   /// Flush the tied-to stream (if present) and then write the required data.
+   void flush_tied_then_write(const char *Ptr, size_t Size);
+ 
+@@ -447,7 +407,6 @@ class raw_fd_ostream : public raw_pwrite_stream {
+   bool ShouldClose;
+   bool SupportsSeeking = false;
+   bool IsRegularFile = false;
+-  mutable std::optional<bool> HasColors;
+ 
+ #ifdef _WIN32
+   /// True if this fd refers to a Windows console device. Mintty and other
+@@ -523,10 +482,6 @@ public:
+   /// to the offset specified from the beginning of the file.
+   uint64_t seek(uint64_t off);
+ 
+-  bool is_displayed() const override;
+-
+-  bool has_colors() const override;
+-
+   std::error_code error() const { return EC; }
+ 
+   /// Return the value of the flag in this raw_fd_ostream indicating whether an
+@@ -545,38 +500,6 @@ public:
+   ///      - from The Zen of Python, by Tim Peters
+   ///
+   void clear_error() { EC = std::error_code(); }
+-
+-  /// Locks the underlying file.
+-  ///
+-  /// @returns RAII object that releases the lock upon leaving the scope, if the
+-  ///          locking was successful. Otherwise returns corresponding
+-  ///          error code.
+-  ///
+-  /// The function blocks the current thread until the lock become available or
+-  /// error occurs.
+-  ///
+-  /// Possible use of this function may be as follows:
+-  ///
+-  ///   @code{.cpp}
+-  ///   if (auto L = stream.lock()) {
+-  ///     // ... do action that require file to be locked.
+-  ///   } else {
+-  ///     handleAllErrors(std::move(L.takeError()), [&](ErrorInfoBase &EIB) {
+-  ///       // ... handle lock error.
+-  ///     });
+-  ///   }
+-  ///   @endcode
+-  LLVM_NODISCARD Expected<sys::fs::FileLocker> lock();
+-
+-  /// Tries to lock the underlying file within the specified period.
+-  ///
+-  /// @returns RAII object that releases the lock upon leaving the scope, if the
+-  ///          locking was successful. Otherwise returns corresponding
+-  ///          error code.
+-  ///
+-  /// It is used as @ref lock.
+-  LLVM_NODISCARD
+-  Expected<sys::fs::FileLocker> tryLockFor(Duration const& Timeout);
+ };
+ 
+ /// This returns a reference to a raw_fd_ostream for standard output. Use it
+@@ -606,17 +529,6 @@ public:
+   /// immediately destroyed.
+   raw_fd_stream(std::string_view Filename, std::error_code &EC);
+ 
+-  /// This reads the \p Size bytes into a buffer pointed by \p Ptr.
+-  ///
+-  /// \param Ptr The start of the buffer to hold data to be read.
+-  ///
+-  /// \param Size The number of bytes to be read.
+-  ///
+-  /// On success, the number of bytes read is returned, and the file position is
+-  /// advanced by this number. On error, -1 is returned, use error() to get the
+-  /// error code.
+-  ssize_t read(char *Ptr, size_t Size);
+-
+   /// Check if \p OS is a pointer of type raw_fd_stream*.
+   static bool classof(const raw_ostream *OS);
+ };
+@@ -734,17 +646,6 @@ public:
+   ~buffer_unique_ostream() override { *OS << str(); }
+ };
+ 
+-class Error;
+-
+-/// This helper creates an output stream and then passes it to \p Write.
+-/// The stream created is based on the specified \p OutputFileName:
+-/// llvm::outs for "-", raw_null_ostream for "/dev/null", and raw_fd_ostream
+-/// for other names. For raw_fd_ostream instances, the stream writes to
+-/// a temporary file. The final output file is atomically replaced with the
+-/// temporary file after the \p Write function is finished.
+-Error writeToOutput(std::string_view OutputFileName,
+-                    std::function<Error(raw_ostream &)> Write);
+-
+ } // end namespace llvm
+ 
+ #endif // LLVM_SUPPORT_RAW_OSTREAM_H
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index ee01a9522..875eda7ba 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -19,7 +19,6 @@
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/Config/config.h"
+ #include "llvm/Support/Compiler.h"
+-#include "llvm/Support/Duration.h"
+ #include "llvm/Support/ErrorHandling.h"
+ #include "llvm/Support/FileSystem.h"
+ #include "llvm/Support/Format.h"
+@@ -120,49 +119,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
+   assert(OutBufStart <= OutBufEnd && "Invalid size!");
+ }
+ 
+-raw_ostream &raw_ostream::operator<<(unsigned long N) {
+-  write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(long N) {
+-  write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(unsigned long long N) {
+-  write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(long long N) {
+-  write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::write_hex(unsigned long long N) {
+-  llvm::write_hex(*this, N, HexPrintStyle::Lower);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(Colors C) {
+-  if (C == Colors::RESET)
+-    resetColor();
+-  else
+-    changeColor(C);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) {
+-  for (int Idx = 0; Idx < 16; ++Idx) {
+-    *this << format("%02" PRIX32, UUID[Idx]);
+-    if (Idx == 3 || Idx == 5 || Idx == 7 || Idx == 9)
+-      *this << "-";
+-  }
+-  return *this;
+-}
+-
+-
+ raw_ostream &raw_ostream::write_escaped(std::string_view Str,
+                                         bool UseHexEscapes) {
+   for (unsigned char c : Str) {
+@@ -308,172 +264,6 @@ void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) {
+   write_impl(Ptr, Size);
+ }
+ 
+-// Formatted output.
+-raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
+-  // If we have more than a few bytes left in our output buffer, try
+-  // formatting directly onto its end.
+-  size_t NextBufferSize = 127;
+-  size_t BufferBytesLeft = OutBufEnd - OutBufCur;
+-  if (BufferBytesLeft > 3) {
+-    size_t BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
+-
+-    // Common case is that we have plenty of space.
+-    if (BytesUsed <= BufferBytesLeft) {
+-      OutBufCur += BytesUsed;
+-      return *this;
+-    }
+-
+-    // Otherwise, we overflowed and the return value tells us the size to try
+-    // again with.
+-    NextBufferSize = BytesUsed;
+-  }
+-
+-  // If we got here, we didn't have enough space in the output buffer for the
+-  // string.  Try printing into a SmallVector that is resized to have enough
+-  // space.  Iterate until we win.
+-  SmallVector<char, 128> V;
+-
+-  while (true) {
+-    V.resize(NextBufferSize);
+-
+-    // Try formatting into the SmallVector.
+-    size_t BytesUsed = Fmt.print(V.data(), NextBufferSize);
+-
+-    // If BytesUsed fit into the vector, we win.
+-    if (BytesUsed <= NextBufferSize)
+-      return write(V.data(), BytesUsed);
+-
+-    // Otherwise, try again with a new size.
+-    assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
+-    NextBufferSize = BytesUsed;
+-  }
+-}
+-
+-raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
+-  Obj.format(*this);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
+-  unsigned LeftIndent = 0;
+-  unsigned RightIndent = 0;
+-  const ssize_t Difference = FS.Width - FS.Str.size();
+-  if (Difference > 0) {
+-    switch (FS.Justify) {
+-    case FormattedString::JustifyNone:
+-      break;
+-    case FormattedString::JustifyLeft:
+-      RightIndent = Difference;
+-      break;
+-    case FormattedString::JustifyRight:
+-      LeftIndent = Difference;
+-      break;
+-    case FormattedString::JustifyCenter:
+-      LeftIndent = Difference / 2;
+-      RightIndent = Difference - LeftIndent;
+-      break;
+-    }
+-  }
+-  indent(LeftIndent);
+-  (*this) << FS.Str;
+-  indent(RightIndent);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
+-  if (FN.Hex) {
+-    HexPrintStyle Style;
+-    if (FN.Upper && FN.HexPrefix)
+-      Style = HexPrintStyle::PrefixUpper;
+-    else if (FN.Upper && !FN.HexPrefix)
+-      Style = HexPrintStyle::Upper;
+-    else if (!FN.Upper && FN.HexPrefix)
+-      Style = HexPrintStyle::PrefixLower;
+-    else
+-      Style = HexPrintStyle::Lower;
+-    llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
+-  } else {
+-    llvm::SmallString<16> Buffer;
+-    llvm::raw_svector_ostream Stream(Buffer);
+-    llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
+-    if (Buffer.size() < FN.Width)
+-      indent(FN.Width - Buffer.size());
+-    (*this) << Buffer;
+-  }
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(const FormattedBytes &FB) {
+-  if (FB.Bytes.empty())
+-    return *this;
+-
+-  size_t LineIndex = 0;
+-  auto Bytes = FB.Bytes;
+-  const size_t Size = Bytes.size();
+-  HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
+-  uint64_t OffsetWidth = 0;
+-  if (FB.FirstByteOffset.hasValue()) {
+-    // Figure out how many nibbles are needed to print the largest offset
+-    // represented by this data set, so that we can align the offset field
+-    // to the right width.
+-    size_t Lines = Size / FB.NumPerLine;
+-    uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
+-    unsigned Power = 0;
+-    if (MaxOffset > 0)
+-      Power = llvm::Log2_64_Ceil(MaxOffset);
+-    OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
+-  }
+-
+-  // The width of a block of data including all spaces for group separators.
+-  unsigned NumByteGroups =
+-      alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
+-  unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
+-
+-  while (!Bytes.empty()) {
+-    indent(FB.IndentLevel);
+-
+-    if (FB.FirstByteOffset.hasValue()) {
+-      uint64_t Offset = FB.FirstByteOffset.getValue();
+-      llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
+-      *this << ": ";
+-    }
+-
+-    auto Line = Bytes.take_front(FB.NumPerLine);
+-
+-    size_t CharsPrinted = 0;
+-    // Print the hex bytes for this line in groups
+-    for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
+-      if (I && (I % FB.ByteGroupSize) == 0) {
+-        ++CharsPrinted;
+-        *this << " ";
+-      }
+-      llvm::write_hex(*this, Line[I], HPS, 2);
+-    }
+-
+-    if (FB.ASCII) {
+-      // Print any spaces needed for any bytes that we didn't print on this
+-      // line so that the ASCII bytes are correctly aligned.
+-      assert(BlockCharWidth >= CharsPrinted);
+-      indent(BlockCharWidth - CharsPrinted + 2);
+-      *this << "|";
+-
+-      // Print the ASCII char values for each byte on this line
+-      for (uint8_t Byte : Line) {
+-        if (isPrint(Byte))
+-          *this << static_cast<char>(Byte);
+-        else
+-          *this << '.';
+-      }
+-      *this << '|';
+-    }
+-
+-    Bytes = Bytes.drop_front(Line.size());
+-    LineIndex += Line.size();
+-    if (LineIndex < Size)
+-      *this << '\n';
+-  }
+-  return *this;
+-}
+ 
+ template <char C>
+ static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) {
+@@ -506,63 +296,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) {
+   return write_padding<'\0'>(*this, NumZeros);
+ }
+ 
+-bool raw_ostream::prepare_colors() {
+-  // Colors were explicitly disabled.
+-  if (!ColorEnabled)
+-    return false;
+-
+-  // Colors require changing the terminal but this stream is not going to a
+-  // terminal.
+-  if (sys::Process::ColorNeedsFlush() && !is_displayed())
+-    return false;
+-
+-  if (sys::Process::ColorNeedsFlush())
+-    flush();
+-
+-  return true;
+-}
+-
+-raw_ostream &raw_ostream::changeColor(enum Colors colors, bool bold, bool bg) {
+-  if (!prepare_colors())
+-    return *this;
+-
+-  const char *colorcode =
+-      (colors == SAVEDCOLOR)
+-          ? sys::Process::OutputBold(bg)
+-          : sys::Process::OutputColor(static_cast<char>(colors), bold, bg);
+-  if (colorcode)
+-    write(colorcode, strlen(colorcode));
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::resetColor() {
+-  if (!prepare_colors())
+-    return *this;
+-
+-  if (const char *colorcode = sys::Process::ResetColor())
+-    write(colorcode, strlen(colorcode));
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::reverseColor() {
+-  if (!prepare_colors())
+-    return *this;
+-
+-  if (const char *colorcode = sys::Process::OutputReverse())
+-    write(colorcode, strlen(colorcode));
+-  return *this;
+-}
+-
+ void raw_ostream::anchor() {}
+ 
+-//===----------------------------------------------------------------------===//
+-//  Formatted Output
+-//===----------------------------------------------------------------------===//
+-
+-// Out of line virtual method.
+-void format_object_base::home() {
+-}
+-
+ //===----------------------------------------------------------------------===//
+ //  raw_fd_ostream
+ //===----------------------------------------------------------------------===//
+@@ -854,31 +589,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const {
+ #endif
+ }
+ 
+-bool raw_fd_ostream::is_displayed() const {
+-  return sys::Process::FileDescriptorIsDisplayed(FD);
+-}
+-
+-bool raw_fd_ostream::has_colors() const {
+-  if (!HasColors)
+-    HasColors = sys::Process::FileDescriptorHasColors(FD);
+-  return *HasColors;
+-}
+-
+-Expected<sys::fs::FileLocker> raw_fd_ostream::lock() {
+-  std::error_code EC = sys::fs::lockFile(FD);
+-  if (!EC)
+-    return sys::fs::FileLocker(FD);
+-  return errorCodeToError(EC);
+-}
+-
+-Expected<sys::fs::FileLocker>
+-raw_fd_ostream::tryLockFor(Duration const& Timeout) {
+-  std::error_code EC = sys::fs::tryLockFile(FD, Timeout.getDuration());
+-  if (!EC)
+-    return sys::fs::FileLocker(FD);
+-  return errorCodeToError(EC);
+-}
+-
+ void raw_fd_ostream::anchor() {}
+ 
+ //===----------------------------------------------------------------------===//
+@@ -921,16 +631,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC)
+     EC = std::make_error_code(std::errc::invalid_argument);
+ }
+ 
+-ssize_t raw_fd_stream::read(char *Ptr, size_t Size) {
+-  assert(get_fd() >= 0 && "File already closed.");
+-  ssize_t Ret = ::read(get_fd(), (void *)Ptr, Size);
+-  if (Ret >= 0)
+-    inc_pos(Ret);
+-  else
+-    error_detected(std::error_code(errno, std::generic_category()));
+-  return Ret;
+-}
+-
+ bool raw_fd_stream::classof(const raw_ostream *OS) {
+   return OS->get_kind() == OStreamKind::OK_FDStream;
+ }
+@@ -986,31 +686,3 @@ void raw_pwrite_stream::anchor() {}
+ void buffer_ostream::anchor() {}
+ 
+ void buffer_unique_ostream::anchor() {}
+-
+-Error llvm::writeToOutput(std::string_view OutputFileName,
+-                          std::function<Error(raw_ostream &)> Write) {
+-  if (OutputFileName == "-")
+-    return Write(outs());
+-
+-  if (OutputFileName == "/dev/null") {
+-    raw_null_ostream Out;
+-    return Write(Out);
+-  }
+-
+-  unsigned Mode = sys::fs::all_read | sys::fs::all_write | sys::fs::all_exe;
+-  Expected<sys::fs::TempFile> Temp =
+-      sys::fs::TempFile::create(OutputFileName + ".temp-stream-%%%%%%", Mode);
+-  if (!Temp)
+-    return createFileError(OutputFileName, Temp.takeError());
+-
+-  raw_fd_ostream Out(Temp->FD, false);
+-
+-  if (Error E = Write(Out)) {
+-    if (Error DiscardError = Temp->discard())
+-      return joinErrors(std::move(E), std::move(DiscardError));
+-    return E;
+-  }
+-  Out.flush();
+-
+-  return Temp->keep(OutputFileName);
+-}
diff --git a/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch b/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch
new file mode 100644
index 0000000..320e500
--- /dev/null
+++ b/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch
@@ -0,0 +1,140 @@
+From ef26f059859d3a0d08b06a70519928bcd5f9bb79 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Thu, 5 May 2022 23:18:34 -0400
+Subject: [PATCH 11/28] Detemplatize SmallVectorBase
+
+---
+ llvm/include/llvm/ADT/SmallVector.h | 21 +++++++-----------
+ llvm/lib/Support/SmallVector.cpp    | 34 +++++------------------------
+ 2 files changed, 13 insertions(+), 42 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
+index 1e311ea56..4b6bbdeb2 100644
+--- a/llvm/include/llvm/ADT/SmallVector.h
++++ b/llvm/include/llvm/ADT/SmallVector.h
+@@ -50,14 +50,14 @@ template <typename IteratorT> class iterator_range;
+ /// Using 64 bit size is desirable for cases like SmallVector<char>, where a
+ /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
+ /// buffering bitcode output - which can exceed 4GB.
+-template <class Size_T> class SmallVectorBase {
++class SmallVectorBase {
+ protected:
+   void *BeginX;
+-  Size_T Size = 0, Capacity;
++  unsigned Size = 0, Capacity;
+ 
+   /// The maximum value of the Size_T used.
+   static constexpr size_t SizeTypeMax() {
+-    return (std::numeric_limits<Size_T>::max)();
++    return (std::numeric_limits<unsigned>::max)();
+   }
+ 
+   SmallVectorBase() = delete;
+@@ -91,15 +91,10 @@ protected:
+   }
+ };
+ 
+-template <class T>
+-using SmallVectorSizeType =
+-    typename std::conditional<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
+-                              uint32_t>::type;
+-
+ /// Figure out the offset of the first element.
+ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
+-  alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
+-      SmallVectorBase<SmallVectorSizeType<T>>)];
++  alignas(SmallVectorBase) char Base[sizeof(
++      SmallVectorBase)];
+   alignas(T) char FirstEl[sizeof(T)];
+ };
+ 
+@@ -108,8 +103,8 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
+ /// to avoid unnecessarily requiring T to be complete.
+ template <typename T, typename = void>
+ class SmallVectorTemplateCommon
+-    : public SmallVectorBase<SmallVectorSizeType<T>> {
+-  using Base = SmallVectorBase<SmallVectorSizeType<T>>;
++    : public SmallVectorBase {
++  using Base = SmallVectorBase;
+ 
+   /// Find the address of the first element.  For this pointer math to be valid
+   /// with small-size of 0 for T with lots of alignment, it's important that
+@@ -356,7 +351,7 @@ protected:
+   /// in \p NewCapacity. This is the first section of \a grow().
+   T *mallocForGrow(size_t MinSize, size_t &NewCapacity) {
+     return static_cast<T *>(
+-        SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow(
++        SmallVectorBase::mallocForGrow(
+             MinSize, sizeof(T), NewCapacity));
+   }
+ 
+diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp
+index a2b4899e1..bdfc963d7 100644
+--- a/llvm/lib/Support/SmallVector.cpp
++++ b/llvm/lib/Support/SmallVector.cpp
+@@ -51,10 +51,6 @@ static_assert(sizeof(SmallVector<void *, 1>) ==
+                   sizeof(unsigned) * 2 + sizeof(void *) * 2,
+               "wasted space in SmallVector size 1");
+ 
+-static_assert(sizeof(SmallVector<char, 0>) ==
+-                  sizeof(void *) * 2 + sizeof(void *),
+-              "1 byte elements have word-sized type for size and capacity");
+-
+ /// Report that MinSize doesn't fit into this vector's size type. Throws
+ /// std::length_error or calls report_fatal_error.
+ [[noreturn]] static void report_size_overflow(size_t MinSize, size_t MaxSize);
+@@ -85,9 +81,8 @@ static void report_at_maximum_capacity(size_t MaxSize) {
+ }
+ 
+ // Note: Moving this function into the header may cause performance regression.
+-template <class Size_T>
+ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
+-  constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
++  constexpr size_t MaxSize = std::numeric_limits<unsigned>::max();
+ 
+   // Ensure we can fit the new capacity.
+   // This is only going to be applicable when the capacity is 32 bit.
+@@ -108,18 +103,16 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) {
+ }
+ 
+ // Note: Moving this function into the header may cause performance regression.
+-template <class Size_T>
+-void *SmallVectorBase<Size_T>::mallocForGrow(size_t MinSize, size_t TSize,
++void *SmallVectorBase::mallocForGrow(size_t MinSize, size_t TSize,
+                                              size_t &NewCapacity) {
+-  NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
++  NewCapacity = getNewCapacity(MinSize, TSize, this->capacity());
+   return llvm::safe_malloc(NewCapacity * TSize);
+ }
+ 
+ // Note: Moving this function into the header may cause performance regression.
+-template <class Size_T>
+-void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
++void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize,
+                                        size_t TSize) {
+-  size_t NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
++  size_t NewCapacity = getNewCapacity(MinSize, TSize, this->capacity());
+   void *NewElts;
+   if (BeginX == FirstEl) {
+     NewElts = safe_malloc(NewCapacity * TSize);
+@@ -134,20 +127,3 @@ void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize,
+   this->BeginX = NewElts;
+   this->Capacity = NewCapacity;
+ }
+-
+-template class llvm::SmallVectorBase<uint32_t>;
+-
+-// Disable the uint64_t instantiation for 32-bit builds.
+-// Both uint32_t and uint64_t instantiations are needed for 64-bit builds.
+-// This instantiation will never be used in 32-bit builds, and will cause
+-// warnings when sizeof(Size_T) > sizeof(size_t).
+-#if SIZE_MAX > UINT32_MAX
+-template class llvm::SmallVectorBase<uint64_t>;
+-
+-// Assertions to ensure this #if stays in sync with SmallVectorSizeType.
+-static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint64_t),
+-              "Expected SmallVectorBase<uint64_t> variant to be in use.");
+-#else
+-static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t),
+-              "Expected SmallVectorBase<uint32_t> variant to be in use.");
+-#endif
diff --git a/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch b/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch
new file mode 100644
index 0000000..cc0bd5d
--- /dev/null
+++ b/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch
@@ -0,0 +1,214 @@
+From 342ebd445bb3dae8b0c119a6126a318ad378a377 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 13:48:59 -0400
+Subject: [PATCH 12/28] Add vectors to raw_ostream
+
+---
+ llvm/include/llvm/Support/raw_ostream.h | 115 ++++++++++++++++++++++++
+ llvm/lib/Support/raw_ostream.cpp        |  47 ++++++++++
+ 2 files changed, 162 insertions(+)
+
+diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
+index d4521c8e2..bf5630ab5 100644
+--- a/llvm/include/llvm/Support/raw_ostream.h
++++ b/llvm/include/llvm/Support/raw_ostream.h
+@@ -25,6 +25,7 @@
+ #endif
+ #include <system_error>
+ #include <type_traits>
++#include <vector>
+ 
+ namespace llvm {
+ 
+@@ -248,12 +249,24 @@ public:
+     return write(Str.data(), Str.size());
+   }
+ 
++  raw_ostream &operator<<(const std::vector<uint8_t> &Arr) {
++    // Avoid the fast path, it would only increase code size for a marginal win.
++    return write(Arr.data(), Arr.size());
++  }
++
++  raw_ostream &operator<<(const SmallVectorImpl<uint8_t> &Arr) {
++    return write(Arr.data(), Arr.size());
++  }
++
+   /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
+   /// satisfy llvm::isPrint into an escape sequence.
+   raw_ostream &write_escaped(std::string_view Str, bool UseHexEscapes = false);
+ 
+   raw_ostream &write(unsigned char C);
+   raw_ostream &write(const char *Ptr, size_t Size);
++  raw_ostream &write(const uint8_t *Ptr, size_t Size) {
++    return write(reinterpret_cast<const char *>(Ptr), Size);
++  }
+ 
+   /// indent - Insert 'NumSpaces' spaces.
+   raw_ostream &indent(unsigned NumSpaces);
+@@ -604,6 +617,108 @@ public:
+   }
+ };
+ 
++/// A raw_ostream that writes to a vector.  This is a
++/// simple adaptor class. This class does not encounter output errors.
++/// raw_vector_ostream operates without a buffer, delegating all memory
++/// management to the vector. Thus the vector is always up-to-date,
++/// may be used directly and there is no need to call flush().
++class raw_vector_ostream : public raw_pwrite_stream {
++  std::vector<char> &OS;
++
++  /// See raw_ostream::write_impl.
++  void write_impl(const char *Ptr, size_t Size) override;
++
++  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
++
++  /// Return the current position within the stream.
++  uint64_t current_pos() const override;
++
++public:
++  /// Construct a new raw_svector_ostream.
++  ///
++  /// \param O The vector to write to; this should generally have at least 128
++  /// bytes free to avoid any extraneous memory overhead.
++  explicit raw_vector_ostream(std::vector<char> &O) : OS(O) {
++    SetUnbuffered();
++  }
++
++  ~raw_vector_ostream() override = default;
++
++  void flush() = delete;
++
++  /// Return a std::string_view for the vector contents.
++  std::string_view str() { return std::string_view(OS.data(), OS.size()); }
++};
++
++/// A raw_ostream that writes to an SmallVector or SmallString.  This is a
++/// simple adaptor class. This class does not encounter output errors.
++/// raw_svector_ostream operates without a buffer, delegating all memory
++/// management to the SmallString. Thus the SmallString is always up-to-date,
++/// may be used directly and there is no need to call flush().
++class raw_usvector_ostream : public raw_pwrite_stream {
++  SmallVectorImpl<uint8_t> &OS;
++
++  /// See raw_ostream::write_impl.
++  void write_impl(const char *Ptr, size_t Size) override;
++
++  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
++
++  /// Return the current position within the stream.
++  uint64_t current_pos() const override;
++
++public:
++  /// Construct a new raw_svector_ostream.
++  ///
++  /// \param O The vector to write to; this should generally have at least 128
++  /// bytes free to avoid any extraneous memory overhead.
++  explicit raw_usvector_ostream(SmallVectorImpl<uint8_t> &O) : OS(O) {
++    SetUnbuffered();
++  }
++
++  ~raw_usvector_ostream() override = default;
++
++  void flush() = delete;
++
++  /// Return an span for the vector contents.
++  span<uint8_t> array() { return {OS.data(), OS.size()}; }
++  span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
++};
++
++/// A raw_ostream that writes to a vector.  This is a
++/// simple adaptor class. This class does not encounter output errors.
++/// raw_vector_ostream operates without a buffer, delegating all memory
++/// management to the vector. Thus the vector is always up-to-date,
++/// may be used directly and there is no need to call flush().
++class raw_uvector_ostream : public raw_pwrite_stream {
++  std::vector<uint8_t> &OS;
++
++  /// See raw_ostream::write_impl.
++  void write_impl(const char *Ptr, size_t Size) override;
++
++  void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
++
++  /// Return the current position within the stream.
++  uint64_t current_pos() const override;
++
++public:
++  /// Construct a new raw_svector_ostream.
++  ///
++  /// \param O The vector to write to; this should generally have at least 128
++  /// bytes free to avoid any extraneous memory overhead.
++  explicit raw_uvector_ostream(std::vector<uint8_t> &O) : OS(O) {
++    SetUnbuffered();
++  }
++
++  ~raw_uvector_ostream() override = default;
++
++  void flush() = delete;
++
++  /// Return a span for the vector contents.
++  span<uint8_t> array() { return {OS.data(), OS.size()}; }
++  span<const uint8_t> array() const { return {OS.data(), OS.size()}; }
++};
++
++
+ /// A raw_ostream that discards all output.
+ class raw_null_ostream : public raw_pwrite_stream {
+   /// See raw_ostream::write_impl.
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index 875eda7ba..36faf744c 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -658,6 +658,53 @@ void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size,
+   memcpy(OS.data() + Offset, Ptr, Size);
+ }
+ 
++//===----------------------------------------------------------------------===//
++//  raw_vector_ostream
++//===----------------------------------------------------------------------===//
++
++uint64_t raw_vector_ostream::current_pos() const { return OS.size(); }
++
++void raw_vector_ostream::write_impl(const char *Ptr, size_t Size) {
++  OS.insert(OS.end(), Ptr, Ptr + Size);
++}
++
++void raw_vector_ostream::pwrite_impl(const char *Ptr, size_t Size,
++                                     uint64_t Offset) {
++  memcpy(OS.data() + Offset, Ptr, Size);
++}
++
++//===----------------------------------------------------------------------===//
++//  raw_usvector_ostream
++//===----------------------------------------------------------------------===//
++
++uint64_t raw_usvector_ostream::current_pos() const { return OS.size(); }
++
++void raw_usvector_ostream::write_impl(const char *Ptr, size_t Size) {
++  OS.append(reinterpret_cast<const uint8_t *>(Ptr),
++            reinterpret_cast<const uint8_t *>(Ptr) + Size);
++}
++
++void raw_usvector_ostream::pwrite_impl(const char *Ptr, size_t Size,
++                                       uint64_t Offset) {
++  memcpy(OS.data() + Offset, Ptr, Size);
++}
++
++//===----------------------------------------------------------------------===//
++//  raw_uvector_ostream
++//===----------------------------------------------------------------------===//
++
++uint64_t raw_uvector_ostream::current_pos() const { return OS.size(); }
++
++void raw_uvector_ostream::write_impl(const char *Ptr, size_t Size) {
++  OS.insert(OS.end(), reinterpret_cast<const uint8_t *>(Ptr),
++            reinterpret_cast<const uint8_t *>(Ptr) + Size);
++}
++
++void raw_uvector_ostream::pwrite_impl(const char *Ptr, size_t Size,
++                                      uint64_t Offset) {
++  memcpy(OS.data() + Offset, Ptr, Size);
++}
++
+ //===----------------------------------------------------------------------===//
+ //  raw_null_ostream
+ //===----------------------------------------------------------------------===//
diff --git a/upstream_utils/llvm_patches/0013-Extra-collections-features.patch b/upstream_utils/llvm_patches/0013-Extra-collections-features.patch
new file mode 100644
index 0000000..19aef1a
--- /dev/null
+++ b/upstream_utils/llvm_patches/0013-Extra-collections-features.patch
@@ -0,0 +1,162 @@
+From 5db7e9f9370a5e04949846cc68eeb13e2c1db187 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 3 May 2022 22:16:10 -0400
+Subject: [PATCH 13/28] Extra collections features
+
+---
+ llvm/include/llvm/ADT/StringMap.h | 103 +++++++++++++++++++++++++++++-
+ llvm/lib/Support/raw_ostream.cpp  |   8 +++
+ 2 files changed, 110 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
+index 8747cdb35..16f13f048 100644
+--- a/llvm/include/llvm/ADT/StringMap.h
++++ b/llvm/include/llvm/ADT/StringMap.h
+@@ -42,7 +42,7 @@ protected:
+ 
+ protected:
+   explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {}
+-  StringMapImpl(StringMapImpl &&RHS)
++  StringMapImpl(StringMapImpl &&RHS) noexcept
+       : TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
+         NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
+         ItemSize(RHS.ItemSize) {
+@@ -420,11 +420,27 @@ public:
+     return Tmp;
+   }
+ 
++  DerivedTy &operator--() { // Predecrement
++    --Ptr;
++    ReversePastEmptyBuckets();
++    return static_cast<DerivedTy &>(*this);
++  }
++
++  DerivedTy operator--(int) { // Post-decrement
++    DerivedTy Tmp(Ptr);
++    --*this;
++    return Tmp;
++  }
++
+ private:
+   void AdvancePastEmptyBuckets() {
+     while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
+       ++Ptr;
+   }
++  void ReversePastEmptyBuckets() {
++    while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
++      --Ptr;
++  }
+ };
+ 
+ template <typename ValueTy>
+@@ -483,6 +499,91 @@ public:
+   std::string_view operator*() const { return this->wrapped()->getKey(); }
+ };
+ 
++template <typename ValueTy>
++bool operator==(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
++  // same instance?
++  if (&lhs == &rhs) return true;
++
++  // first check that sizes are identical
++  if (lhs.size() != rhs.size()) return false;
++
++  // copy into vectors and sort by key
++  SmallVector<StringMapConstIterator<ValueTy>, 16> lhs_items;
++  lhs_items.reserve(lhs.size());
++  for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
++    lhs_items.push_back(i);
++  std::sort(lhs_items.begin(), lhs_items.end(),
++            [](const StringMapConstIterator<ValueTy>& a,
++               const StringMapConstIterator<ValueTy>& b) {
++              return a->getKey() < b->getKey();
++            });
++
++  SmallVector<StringMapConstIterator<ValueTy>, 16> rhs_items;
++  rhs_items.reserve(rhs.size());
++  for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
++    rhs_items.push_back(i);
++  std::sort(rhs_items.begin(), rhs_items.end(),
++            [](const StringMapConstIterator<ValueTy>& a,
++               const StringMapConstIterator<ValueTy>& b) {
++              return a->getKey() < b->getKey();
++            });
++
++  // compare vector keys and values
++  for (auto a = lhs_items.begin(), b = rhs_items.begin(),
++            aend = lhs_items.end(), bend = rhs_items.end();
++       a != aend && b != bend; ++a, ++b) {
++    if ((*a)->first() != (*b)->first() || (*a)->second != (*b)->second)
++      return false;
++  }
++  return true;
++}
++
++template <typename ValueTy>
++inline bool operator!=(const StringMap<ValueTy>& lhs,
++                       const StringMap<ValueTy>& rhs) {
++  return !(lhs == rhs);
++}
++
++template <typename ValueTy>
++bool operator<(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
++  // same instance?
++  if (&lhs == &rhs) return false;
++
++  // copy into vectors and sort by key
++  SmallVector<std::string_view, 16> lhs_keys;
++  lhs_keys.reserve(lhs.size());
++  for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
++    lhs_keys.push_back(i->getKey());
++  std::sort(lhs_keys.begin(), lhs_keys.end());
++
++  SmallVector<std::string_view, 16> rhs_keys;
++  rhs_keys.reserve(rhs.size());
++  for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
++    rhs_keys.push_back(i->getKey());
++  std::sort(rhs_keys.begin(), rhs_keys.end());
++
++  // use std::vector comparison
++  return lhs_keys < rhs_keys;
++}
++
++template <typename ValueTy>
++inline bool operator<=(const StringMap<ValueTy>& lhs,
++                       const StringMap<ValueTy>& rhs) {
++  return !(rhs < lhs);
++}
++
++template <typename ValueTy>
++inline bool operator>(const StringMap<ValueTy>& lhs,
++                      const StringMap<ValueTy>& rhs) {
++  return !(lhs <= rhs);
++}
++
++template <typename ValueTy>
++inline bool operator>=(const StringMap<ValueTy>& lhs,
++                       const StringMap<ValueTy>& rhs) {
++  return !(lhs < rhs);
++}
++
+ } // end namespace llvm
+ 
+ #endif // LLVM_ADT_STRINGMAP_H
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index 36faf744c..95152849c 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -76,6 +76,14 @@ constexpr raw_ostream::Colors raw_ostream::WHITE;
+ constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR;
+ constexpr raw_ostream::Colors raw_ostream::RESET;
+ 
++namespace {
++// Find the length of an array.
++template <class T, std::size_t N>
++constexpr inline size_t array_lengthof(T (&)[N]) {
++  return N;
++}
++}  // namespace
++
+ raw_ostream::~raw_ostream() {
+   // raw_ostream's subclasses should take care to flush the buffer
+   // in their destructors.
diff --git a/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch b/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch
new file mode 100644
index 0000000..1049911
--- /dev/null
+++ b/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch
@@ -0,0 +1,22 @@
+From 9951c4b3fea6b2dbe7141070444de8df6ae4ce9b Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Wed, 4 May 2022 00:01:00 -0400
+Subject: [PATCH 14/28] EpochTracker ABI macro
+
+---
+ llvm/include/llvm/ADT/EpochTracker.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/llvm/include/llvm/ADT/EpochTracker.h b/llvm/include/llvm/ADT/EpochTracker.h
+index b06888494..f35461d1c 100644
+--- a/llvm/include/llvm/ADT/EpochTracker.h
++++ b/llvm/include/llvm/ADT/EpochTracker.h
+@@ -22,7 +22,7 @@
+ 
+ namespace llvm {
+ 
+-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
++#ifndef NDEBUG //ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS
+ 
+ /// A base class for data structure classes wishing to make iterators
+ /// ("handles") pointing into themselves fail-fast.  When building without
diff --git a/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch b/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch
new file mode 100644
index 0000000..5578739
--- /dev/null
+++ b/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch
@@ -0,0 +1,56 @@
+From 907608f09061ab272b0a127330b1b24e28d50a9f Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Thu, 5 May 2022 18:09:45 -0400
+Subject: [PATCH 15/28] Delete numbers from MathExtras
+
+---
+ llvm/include/llvm/Support/MathExtras.h | 36 --------------------------
+ 1 file changed, 36 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
+index fac12dd0e..e8f1f2aca 100644
+--- a/llvm/include/llvm/Support/MathExtras.h
++++ b/llvm/include/llvm/Support/MathExtras.h
+@@ -50,42 +50,6 @@ enum ZeroBehavior {
+   ZB_Width
+ };
+ 
+-/// Mathematical constants.
+-namespace numbers {
+-// TODO: Track C++20 std::numbers.
+-// TODO: Favor using the hexadecimal FP constants (requires C++17).
+-constexpr double e          = 2.7182818284590452354, // (0x1.5bf0a8b145749P+1) https://oeis.org/A001113
+-                 egamma     = .57721566490153286061, // (0x1.2788cfc6fb619P-1) https://oeis.org/A001620
+-                 ln2        = .69314718055994530942, // (0x1.62e42fefa39efP-1) https://oeis.org/A002162
+-                 ln10       = 2.3025850929940456840, // (0x1.24bb1bbb55516P+1) https://oeis.org/A002392
+-                 log2e      = 1.4426950408889634074, // (0x1.71547652b82feP+0)
+-                 log10e     = .43429448190325182765, // (0x1.bcb7b1526e50eP-2)
+-                 pi         = 3.1415926535897932385, // (0x1.921fb54442d18P+1) https://oeis.org/A000796
+-                 inv_pi     = .31830988618379067154, // (0x1.45f306bc9c883P-2) https://oeis.org/A049541
+-                 sqrtpi     = 1.7724538509055160273, // (0x1.c5bf891b4ef6bP+0) https://oeis.org/A002161
+-                 inv_sqrtpi = .56418958354775628695, // (0x1.20dd750429b6dP-1) https://oeis.org/A087197
+-                 sqrt2      = 1.4142135623730950488, // (0x1.6a09e667f3bcdP+0) https://oeis.org/A00219
+-                 inv_sqrt2  = .70710678118654752440, // (0x1.6a09e667f3bcdP-1)
+-                 sqrt3      = 1.7320508075688772935, // (0x1.bb67ae8584caaP+0) https://oeis.org/A002194
+-                 inv_sqrt3  = .57735026918962576451, // (0x1.279a74590331cP-1)
+-                 phi        = 1.6180339887498948482; // (0x1.9e3779b97f4a8P+0) https://oeis.org/A001622
+-constexpr float ef          = 2.71828183F, // (0x1.5bf0a8P+1) https://oeis.org/A001113
+-                egammaf     = .577215665F, // (0x1.2788d0P-1) https://oeis.org/A001620
+-                ln2f        = .693147181F, // (0x1.62e430P-1) https://oeis.org/A002162
+-                ln10f       = 2.30258509F, // (0x1.26bb1cP+1) https://oeis.org/A002392
+-                log2ef      = 1.44269504F, // (0x1.715476P+0)
+-                log10ef     = .434294482F, // (0x1.bcb7b2P-2)
+-                pif         = 3.14159265F, // (0x1.921fb6P+1) https://oeis.org/A000796
+-                inv_pif     = .318309886F, // (0x1.45f306P-2) https://oeis.org/A049541
+-                sqrtpif     = 1.77245385F, // (0x1.c5bf8aP+0) https://oeis.org/A002161
+-                inv_sqrtpif = .564189584F, // (0x1.20dd76P-1) https://oeis.org/A087197
+-                sqrt2f      = 1.41421356F, // (0x1.6a09e6P+0) https://oeis.org/A002193
+-                inv_sqrt2f  = .707106781F, // (0x1.6a09e6P-1)
+-                sqrt3f      = 1.73205081F, // (0x1.bb67aeP+0) https://oeis.org/A002194
+-                inv_sqrt3f  = .577350269F, // (0x1.279a74P-1)
+-                phif        = 1.61803399F; // (0x1.9e377aP+0) https://oeis.org/A001622
+-} // namespace numbers
+-
+ namespace detail {
+ template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
+   static unsigned count(T Val, ZeroBehavior) {
diff --git a/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch b/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch
new file mode 100644
index 0000000..8dcc9c7
--- /dev/null
+++ b/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch
@@ -0,0 +1,40 @@
+From 9ef10e5b331d00d7d5822afdb70c1f2d9981d772 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 3 May 2022 22:50:24 -0400
+Subject: [PATCH 16/28] Add lerp and sgn
+
+---
+ llvm/include/llvm/Support/MathExtras.h | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
+index e8f1f2aca..8116c58bd 100644
+--- a/llvm/include/llvm/Support/MathExtras.h
++++ b/llvm/include/llvm/Support/MathExtras.h
+@@ -930,6 +930,26 @@ std::enable_if_t<std::is_signed<T>::value, T> MulOverflow(T X, T Y, T &Result) {
+     return UX > (static_cast<U>((std::numeric_limits<T>::max)())) / UY;
+ }
+ 
++// Typesafe implementation of the signum function.
++// Returns -1 if negative, 1 if positive, 0 if 0.
++template <typename T>
++constexpr int sgn(T val) {
++  return (T(0) < val) - (val < T(0));
++}
++
++/**
++ * Linearly interpolates between two values.
++ *
++ * @param startValue The start value.
++ * @param endValue The end value.
++ * @param t The fraction for interpolation.
++ *
++ * @return The interpolated value.
++ */
++template <typename T>
++constexpr T Lerp(const T& startValue, const T& endValue, double t) {
++  return startValue + (endValue - startValue) * t;
++}
+ } // End llvm namespace
+ 
+ #endif
diff --git a/upstream_utils/llvm_patches/0017-Fixup-includes.patch b/upstream_utils/llvm_patches/0017-Fixup-includes.patch
new file mode 100644
index 0000000..f247db0
--- /dev/null
+++ b/upstream_utils/llvm_patches/0017-Fixup-includes.patch
@@ -0,0 +1,168 @@
+From aa30b80d86cb0774efc094646339b54694ab8398 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 16:38:11 -0400
+Subject: [PATCH 17/28] Fixup includes
+
+---
+ llvm/include/llvm/ADT/StringMap.h                 |  4 ++++
+ llvm/include/llvm/ADT/StringMapEntry.h            |  4 ++++
+ llvm/include/llvm/Support/PointerLikeTypeTraits.h |  1 +
+ llvm/lib/Support/ConvertUTFWrapper.cpp            |  1 +
+ llvm/lib/Support/ErrorHandling.cpp                |  7 +++----
+ llvm/lib/Support/raw_ostream.cpp                  | 12 ++++++------
+ llvm/unittests/ADT/SmallPtrSetTest.cpp            |  2 ++
+ llvm/unittests/ADT/StringMapTest.cpp              |  1 +
+ llvm/unittests/Support/ConvertUTFTest.cpp         |  2 ++
+ 9 files changed, 24 insertions(+), 10 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
+index 16f13f048..6ae0e39a1 100644
+--- a/llvm/include/llvm/ADT/StringMap.h
++++ b/llvm/include/llvm/ADT/StringMap.h
+@@ -17,6 +17,10 @@
+ #include "llvm/ADT/StringMapEntry.h"
+ #include "llvm/ADT/iterator.h"
+ #include "llvm/Support/AllocatorBase.h"
++#include "llvm/Support/MemAlloc.h"
++#include "llvm/Support/SmallVector.h"
++#include "llvm/Support/iterator.h"
++#include "llvm/Support/iterator_range.h"
+ #include "llvm/Support/PointerLikeTypeTraits.h"
+ #include <initializer_list>
+ #include <iterator>
+diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h
+index 39976a02b..cdefc5449 100644
+--- a/llvm/include/llvm/ADT/StringMapEntry.h
++++ b/llvm/include/llvm/ADT/StringMapEntry.h
+@@ -16,6 +16,10 @@
+ #ifndef LLVM_ADT_STRINGMAPENTRY_H
+ #define LLVM_ADT_STRINGMAPENTRY_H
+ 
++#include "wpi/MemAlloc.h"
++
++#include <cassert>
++#include <cstring>
+ #include <optional>
+ #include <string_view>
+ 
+diff --git a/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/llvm/include/llvm/Support/PointerLikeTypeTraits.h
+index 1b15f930b..acadd5e89 100644
+--- a/llvm/include/llvm/Support/PointerLikeTypeTraits.h
++++ b/llvm/include/llvm/Support/PointerLikeTypeTraits.h
+@@ -16,6 +16,7 @@
+ 
+ #include "llvm/Support/DataTypes.h"
+ #include <cassert>
++#include <cstdint>
+ #include <type_traits>
+ 
+ namespace llvm {
+diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp
+index 396ab0c65..cff30f16c 100644
+--- a/llvm/lib/Support/ConvertUTFWrapper.cpp
++++ b/llvm/lib/Support/ConvertUTFWrapper.cpp
+@@ -8,6 +8,7 @@
+ 
+ #include "llvm/ADT/span.h"
+ #include "llvm/Support/ConvertUTF.h"
++#include "llvm/Support/SmallVector.h"
+ #include "llvm/Support/ErrorHandling.h"
+ #include "llvm/Support/SwapByteOrder.h"
+ #include <string>
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index f80e28e87..ec1a1633a 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -28,12 +28,11 @@
+ #include <mutex>
+ #include <new>
+ 
+-#if defined(HAVE_UNISTD_H)
+-# include <unistd.h>
++#ifndef _WIN32
++#include <unistd.h>
+ #endif
+ #if defined(_MSC_VER)
+-# include <io.h>
+-# include <fcntl.h>
++#include <io.h>
+ #endif
+ 
+ using namespace llvm;
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index 95152849c..878a3a5e9 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -15,7 +15,8 @@
+ #endif
+ 
+ #include "llvm/Support/raw_ostream.h"
+-#include "llvm/ADT/STLArrayExtras.h"
++#include "wpi/SmallString.h"
++#include "wpi/SmallVector.h"
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/Config/config.h"
+ #include "llvm/Support/Compiler.h"
+@@ -33,12 +34,11 @@
+ #include <sys/stat.h>
+ 
+ // <fcntl.h> may provide O_BINARY.
+-#if defined(HAVE_FCNTL_H)
+ # include <fcntl.h>
+-#endif
+ 
+-#if defined(HAVE_UNISTD_H)
+-# include <unistd.h>
++#ifndef _WIN32
++#include <unistd.h>
++#include <sys/uio.h>
+ #endif
+ 
+ #if defined(__CYGWIN__)
+@@ -60,7 +60,7 @@
+ 
+ #ifdef _WIN32
+ #include "llvm/Support/ConvertUTF.h"
+-#include "llvm/Support/Windows/WindowsSupport.h"
++#include "Windows/WindowsSupport.h"
+ #endif
+ 
+ using namespace llvm;
+diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp
+index 531f81ab5..3db8b6e37 100644
+--- a/llvm/unittests/ADT/SmallPtrSetTest.cpp
++++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp
+@@ -15,6 +15,8 @@
+ #include "llvm/Support/PointerLikeTypeTraits.h"
+ #include "gtest/gtest.h"
+ 
++#include <algorithm>
++
+ using namespace llvm;
+ 
+ TEST(SmallPtrSetTest, Assignment) {
+diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
+index 6d0c0942c..de6daf3da 100644
+--- a/llvm/unittests/ADT/StringMapTest.cpp
++++ b/llvm/unittests/ADT/StringMapTest.cpp
+@@ -9,6 +9,7 @@
+ #include "llvm/ADT/StringMap.h"
+ #include "llvm/Support/DataTypes.h"
+ #include "gtest/gtest.h"
++#include <algorithm>
+ #include <limits>
+ #include <tuple>
+ using namespace llvm;
+diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp
+index 9c798437a..2fee8ad5c 100644
+--- a/llvm/unittests/Support/ConvertUTFTest.cpp
++++ b/llvm/unittests/Support/ConvertUTFTest.cpp
+@@ -7,6 +7,8 @@
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/Support/ConvertUTF.h"
++#include "llvm/Support/SmallString.h"
++#include "llvm/Support/SmallVector.h"
+ #include "gtest/gtest.h"
+ #include <string>
+ #include <vector>
diff --git a/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch b/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch
new file mode 100644
index 0000000..4e2650e
--- /dev/null
+++ b/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch
@@ -0,0 +1,138 @@
+From 1c3e8a6ff8d8b6c054141503c7318d69319d8d41 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 16:42:09 -0400
+Subject: [PATCH 18/28] Use std::is_trivially_copy_constructible
+
+---
+ llvm/include/llvm/ADT/PointerIntPair.h  | 12 ----
+ llvm/include/llvm/Support/type_traits.h | 91 +------------------------
+ 2 files changed, 2 insertions(+), 101 deletions(-)
+
+diff --git a/llvm/include/llvm/ADT/PointerIntPair.h b/llvm/include/llvm/ADT/PointerIntPair.h
+index b7ddf8855..a48fb904b 100644
+--- a/llvm/include/llvm/ADT/PointerIntPair.h
++++ b/llvm/include/llvm/ADT/PointerIntPair.h
+@@ -128,18 +128,6 @@ public:
+   }
+ };
+ 
+-// Specialize is_trivially_copyable to avoid limitation of llvm::is_trivially_copyable
+-// when compiled with gcc 4.9.
+-template <typename PointerTy, unsigned IntBits, typename IntType,
+-          typename PtrTraits,
+-          typename Info>
+-struct is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>> : std::true_type {
+-#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
+-  static_assert(std::is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>::value,
+-                "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
+-#endif
+-};
+-
+ 
+ template <typename PointerT, unsigned IntBits, typename PtrTraits>
+ struct PointerIntPairInfo {
+diff --git a/llvm/include/llvm/Support/type_traits.h b/llvm/include/llvm/Support/type_traits.h
+index 7b7d5d991..72a2e84ad 100644
+--- a/llvm/include/llvm/Support/type_traits.h
++++ b/llvm/include/llvm/Support/type_traits.h
+@@ -92,98 +92,11 @@ union trivial_helper {
+ 
+ } // end namespace detail
+ 
+-/// An implementation of `std::is_trivially_copy_constructible` since we have
+-/// users with STLs that don't yet include it.
+ template <typename T>
+-struct is_trivially_copy_constructible
+-    : std::is_copy_constructible<
+-          ::llvm::detail::copy_construction_triviality_helper<T>> {};
+-template <typename T>
+-struct is_trivially_copy_constructible<T &> : std::true_type {};
+-template <typename T>
+-struct is_trivially_copy_constructible<T &&> : std::false_type {};
++using is_trivially_move_constructible = std::is_trivially_move_constructible<T>;
+ 
+-/// An implementation of `std::is_trivially_move_constructible` since we have
+-/// users with STLs that don't yet include it.
+-template <typename T>
+-struct is_trivially_move_constructible
+-    : std::is_move_constructible<
+-          ::llvm::detail::move_construction_triviality_helper<T>> {};
+ template <typename T>
+-struct is_trivially_move_constructible<T &> : std::true_type {};
+-template <typename T>
+-struct is_trivially_move_constructible<T &&> : std::true_type {};
+-
+-
+-template <typename T>
+-struct is_copy_assignable {
+-  template<class F>
+-    static auto get(F*) -> decltype(std::declval<F &>() = std::declval<const F &>(), std::true_type{});
+-    static std::false_type get(...);
+-    static constexpr bool value = decltype(get((T*)nullptr))::value;
+-};
+-
+-template <typename T>
+-struct is_move_assignable {
+-  template<class F>
+-    static auto get(F*) -> decltype(std::declval<F &>() = std::declval<F &&>(), std::true_type{});
+-    static std::false_type get(...);
+-    static constexpr bool value = decltype(get((T*)nullptr))::value;
+-};
+-
+-
+-// An implementation of `std::is_trivially_copyable` since STL version
+-// is not equally supported by all compilers, especially GCC 4.9.
+-// Uniform implementation of this trait is important for ABI compatibility
+-// as it has an impact on SmallVector's ABI (among others).
+-template <typename T>
+-class is_trivially_copyable {
+-
+-  // copy constructors
+-  static constexpr bool has_trivial_copy_constructor =
+-      std::is_copy_constructible<detail::trivial_helper<T>>::value;
+-  static constexpr bool has_deleted_copy_constructor =
+-      !std::is_copy_constructible<T>::value;
+-
+-  // move constructors
+-  static constexpr bool has_trivial_move_constructor =
+-      std::is_move_constructible<detail::trivial_helper<T>>::value;
+-  static constexpr bool has_deleted_move_constructor =
+-      !std::is_move_constructible<T>::value;
+-
+-  // copy assign
+-  static constexpr bool has_trivial_copy_assign =
+-      is_copy_assignable<detail::trivial_helper<T>>::value;
+-  static constexpr bool has_deleted_copy_assign =
+-      !is_copy_assignable<T>::value;
+-
+-  // move assign
+-  static constexpr bool has_trivial_move_assign =
+-      is_move_assignable<detail::trivial_helper<T>>::value;
+-  static constexpr bool has_deleted_move_assign =
+-      !is_move_assignable<T>::value;
+-
+-  // destructor
+-  static constexpr bool has_trivial_destructor =
+-      std::is_destructible<detail::trivial_helper<T>>::value;
+-
+-  public:
+-
+-  static constexpr bool value =
+-      has_trivial_destructor &&
+-      (has_deleted_move_assign || has_trivial_move_assign) &&
+-      (has_deleted_move_constructor || has_trivial_move_constructor) &&
+-      (has_deleted_copy_assign || has_trivial_copy_assign) &&
+-      (has_deleted_copy_constructor || has_trivial_copy_constructor);
+-
+-#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
+-  static_assert(value == std::is_trivially_copyable<T>::value,
+-                "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
+-#endif
+-};
+-template <typename T>
+-class is_trivially_copyable<T*> : public std::true_type {
+-};
++using is_trivially_copy_constructible = std::is_trivially_copy_constructible<T>;
+ 
+ 
+ } // end namespace llvm
diff --git a/upstream_utils/llvm_patches/0019-Windows-support.patch b/upstream_utils/llvm_patches/0019-Windows-support.patch
new file mode 100644
index 0000000..07d973b
--- /dev/null
+++ b/upstream_utils/llvm_patches/0019-Windows-support.patch
@@ -0,0 +1,204 @@
+From 36f7f08e257f2b58b2894f165a38ff2a831aed8f Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 3 May 2022 20:22:38 -0400
+Subject: [PATCH 19/28] Windows support
+
+---
+ .../llvm/Support/Windows/WindowsSupport.h     | 45 +++++----
+ llvm/lib/Support/ConvertUTF.cpp               | 95 +++++++++++++++++++
+ 2 files changed, 124 insertions(+), 16 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h
+index 180803fbd..31120cfa0 100644
+--- a/llvm/include/llvm/Support/Windows/WindowsSupport.h
++++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h
+@@ -35,8 +35,6 @@
+ 
+ #include "llvm/ADT/SmallVector.h"
+ #include "llvm/ADT/StringExtras.h"
+-#include "llvm/Config/llvm-config.h" // Get build system configuration settings
+-#include "llvm/Support/Allocator.h"
+ #include "llvm/Support/Chrono.h"
+ #include "llvm/Support/Compiler.h"
+ #include "llvm/Support/ErrorHandling.h"
+@@ -44,18 +42,46 @@
+ #include <cassert>
+ #include <string>
+ #include <system_error>
++#define WIN32_NO_STATUS
+ #include <windows.h>
++#undef WIN32_NO_STATUS
++#include <winternl.h>
++#include <ntstatus.h>
+ 
+ // Must be included after windows.h
+ #include <wincrypt.h>
+ 
+ namespace llvm {
+ 
++/// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
++/// RtlGetVersion or GetVersionEx under the hood depending on what is available.
++/// GetVersionEx is deprecated, but this API exposes the build number which can
++/// be useful for working around certain kernel bugs.
++inline llvm::VersionTuple GetWindowsOSVersion() {
++  typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
++  HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
++  if (hMod) {
++    auto getVer = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
++    if (getVer) {
++      RTL_OSVERSIONINFOEXW info{};
++      info.dwOSVersionInfoSize = sizeof(info);
++      if (getVer((PRTL_OSVERSIONINFOW)&info) == ((NTSTATUS)0x00000000L)) {
++        return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion, 0,
++                                  info.dwBuildNumber);
++      }
++    }
++  }
++  return llvm::VersionTuple(0, 0, 0, 0);
++}
++
+ /// Determines if the program is running on Windows 8 or newer. This
+ /// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
+ /// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
+ /// yet have VersionHelpers.h, so we have our own helper.
+-bool RunningWindows8OrGreater();
++inline bool RunningWindows8OrGreater() {
++  // Windows 8 is version 6.2, service pack 0.
++  return GetWindowsOSVersion() >= llvm::VersionTuple(6, 2, 0, 0);
++}
+ 
+ /// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
+ /// RtlGetVersion or GetVersionEx under the hood depending on what is available.
+@@ -228,19 +254,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) {
+   return Time;
+ }
+ 
+-namespace windows {
+-// Returns command line arguments. Unlike arguments given to main(),
+-// this function guarantees that the returned arguments are encoded in
+-// UTF-8 regardless of the current code page setting.
+-std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
+-                                        BumpPtrAllocator &Alloc);
+-
+-/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
+-/// File API.
+-std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
+-                          size_t MaxPathLen = MAX_PATH);
+-
+-} // end namespace windows
+ } // end namespace sys
+ } // end namespace llvm.
+ 
+diff --git a/llvm/lib/Support/ConvertUTF.cpp b/llvm/lib/Support/ConvertUTF.cpp
+index e24a918c5..c906ded91 100644
+--- a/llvm/lib/Support/ConvertUTF.cpp
++++ b/llvm/lib/Support/ConvertUTF.cpp
+@@ -51,6 +51,11 @@
+ #endif
+ #include <assert.h>
+ 
++#ifdef _WIN32
++#include "wpi/WindowsError.h"
++#include "Windows/WindowsSupport.h"
++#endif
++
+ /*
+  * This code extensively uses fall-through switches.
+  * Keep the compiler from warning about that.
+@@ -733,6 +738,96 @@ ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart,
+ 
+    --------------------------------------------------------------------- */
+ 
++#ifdef _WIN32
++
++namespace sys {
++namespace windows {
++std::error_code CodePageToUTF16(unsigned codepage,
++                                std::string_view original,
++                                wpi::SmallVectorImpl<wchar_t> &utf16) {
++  if (!original.empty()) {
++    int len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.data(),
++                                    original.size(), utf16.begin(), 0);
++
++    if (len == 0) {
++      return mapWindowsError(::GetLastError());
++    }
++
++    utf16.reserve(len + 1);
++    utf16.resize_for_overwrite(len);
++
++    len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.data(),
++                                original.size(), utf16.begin(), utf16.size());
++
++    if (len == 0) {
++      return mapWindowsError(::GetLastError());
++    }
++  }
++
++  // Make utf16 null terminated.
++  utf16.push_back(0);
++  utf16.pop_back();
++
++  return std::error_code();
++}
++
++std::error_code UTF8ToUTF16(std::string_view utf8,
++                            wpi::SmallVectorImpl<wchar_t> &utf16) {
++  return CodePageToUTF16(CP_UTF8, utf8, utf16);
++}
++
++std::error_code CurCPToUTF16(std::string_view curcp,
++                            wpi::SmallVectorImpl<wchar_t> &utf16) {
++  return CodePageToUTF16(CP_ACP, curcp, utf16);
++}
++
++static
++std::error_code UTF16ToCodePage(unsigned codepage, const wchar_t *utf16,
++                                size_t utf16_len,
++                                wpi::SmallVectorImpl<char> &converted) {
++  if (utf16_len) {
++    // Get length.
++    int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.begin(),
++                                    0, NULL, NULL);
++
++    if (len == 0) {
++      return mapWindowsError(::GetLastError());
++    }
++
++    converted.reserve(len);
++    converted.resize_for_overwrite(len);
++
++    // Now do the actual conversion.
++    len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.data(),
++                                converted.size(), NULL, NULL);
++
++    if (len == 0) {
++      return mapWindowsError(::GetLastError());
++    }
++  }
++
++  // Make the new string null terminated.
++  converted.push_back(0);
++  converted.pop_back();
++
++  return std::error_code();
++}
++
++std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
++                            wpi::SmallVectorImpl<char> &utf8) {
++  return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
++}
++
++std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
++                             wpi::SmallVectorImpl<char> &curcp) {
++  return UTF16ToCodePage(CP_ACP, utf16, utf16_len, curcp);
++}
++
++} // end namespace windows
++} // end namespace sys
++
++#endif  // _WIN32
++
+ } // namespace llvm
+ 
+ ConvertUTF_RESTORE_WARNINGS
diff --git a/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch b/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch
new file mode 100644
index 0000000..4315754
--- /dev/null
+++ b/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch
@@ -0,0 +1,55 @@
+From 8834260a9ee172311cc08d0b4e4e958bf36a260f Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 16:46:20 -0400
+Subject: [PATCH 20/28] Prefer fmtlib
+
+---
+ llvm/lib/Support/ErrorHandling.cpp | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index ec1a1633a..8de7b726d 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -22,7 +22,7 @@
+ #include "llvm/Support/Signals.h"
+ #include "llvm/Support/Threading.h"
+ #include "llvm/Support/WindowsError.h"
+-#include "llvm/Support/raw_ostream.h"
++#include "fmt/format.h"
+ #include <cassert>
+ #include <cstdlib>
+ #include <mutex>
+@@ -93,15 +93,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
+   if (handler) {
+     handler(handlerData, std::string{Reason}.c_str(), GenCrashDiag);
+   } else {
+-    // Blast the result out to stderr.  We don't try hard to make sure this
+-    // succeeds (e.g. handling EINTR) and we can't use errs() here because
+-    // raw ostreams can call report_fatal_error.
+-    SmallVector<char, 64> Buffer;
+-    raw_svector_ostream OS(Buffer);
+-    OS << "LLVM ERROR: " << Reason << "\n";
+-    std::string_view MessageStr = OS.str();
+-    ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
+-    (void)written; // If something went wrong, we deliberately just give up.
++    fmt::print(stderr, "LLVM ERROR: {}\n", Reason);
+   }
+ 
+   // If we reached here, we are failing ungracefully. Run the interrupt handlers
+@@ -173,11 +165,11 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file,
+   // llvm_unreachable is intended to be used to indicate "impossible"
+   // situations, and not legitimate runtime errors.
+   if (msg)
+-    dbgs() << msg << "\n";
+-  dbgs() << "UNREACHABLE executed";
++    fmt::print(stderr, "{}\n", msg);
++  std::fputs("UNREACHABLE executed", stderr);
+   if (file)
+-    dbgs() << " at " << file << ":" << line;
+-  dbgs() << "!\n";
++    fmt::print(stderr, " at {}:{}", file, line);
++  fmt::print(stderr, "!\n");
+   abort();
+ #ifdef LLVM_BUILTIN_UNREACHABLE
+   // Windows systems and possibly others don't declare abort() to be noreturn,
diff --git a/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch b/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch
new file mode 100644
index 0000000..2f246a0
--- /dev/null
+++ b/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch
@@ -0,0 +1,34 @@
+From 7943842aea1a05a1dd2c2c753378af569c24293b Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 16:49:36 -0400
+Subject: [PATCH 21/28] Prefer wpi's fs.h
+
+---
+ llvm/include/llvm/Support/raw_ostream.h | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
+index bf5630ab5..256bcec25 100644
+--- a/llvm/include/llvm/Support/raw_ostream.h
++++ b/llvm/include/llvm/Support/raw_ostream.h
+@@ -27,18 +27,15 @@
+ #include <type_traits>
+ #include <vector>
+ 
+-namespace llvm {
+-
+-template <class T> class LLVM_NODISCARD Expected;
+ 
+-namespace sys {
+ namespace fs {
+ enum FileAccess : unsigned;
+ enum OpenFlags : unsigned;
+ enum CreationDisposition : unsigned;
+ class FileLocker;
+ } // end namespace fs
+-} // end namespace sys
++
++namespace llvm {
+ 
+ /// This class implements an extremely fast bulk output stream that can *only*
+ /// output to a stream.  It does not support seeking, reopening, rewinding, line
diff --git a/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch b/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch
new file mode 100644
index 0000000..244148e
--- /dev/null
+++ b/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch
@@ -0,0 +1,283 @@
+From a172c93df929ac6c9f783fd5af1e4df3604c4c66 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 19:16:51 -0400
+Subject: [PATCH 22/28] Remove unused functions
+
+---
+ llvm/include/llvm/Support/DJB.h         |  3 -
+ llvm/include/llvm/Support/raw_ostream.h |  5 +-
+ llvm/lib/Support/ErrorHandling.cpp      | 16 -----
+ llvm/lib/Support/raw_ostream.cpp        | 49 +++++++--------
+ llvm/unittests/ADT/SmallStringTest.cpp  | 81 -------------------------
+ 5 files changed, 23 insertions(+), 131 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/DJB.h b/llvm/include/llvm/Support/DJB.h
+index 8737cd144..67b0ae91b 100644
+--- a/llvm/include/llvm/Support/DJB.h
++++ b/llvm/include/llvm/Support/DJB.h
+@@ -24,9 +24,6 @@ inline uint32_t djbHash(std::string_view Buffer, uint32_t H = 5381) {
+   return H;
+ }
+ 
+-/// Computes the Bernstein hash after folding the input according to the Dwarf 5
+-/// standard case folding rules.
+-uint32_t caseFoldingDjbHash(StringRef Buffer, uint32_t H = 5381);
+ } // namespace llvm
+ 
+ #endif // LLVM_SUPPORT_DJB_H
+diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h
+index 256bcec25..9b3a87e1b 100644
+--- a/llvm/include/llvm/Support/raw_ostream.h
++++ b/llvm/include/llvm/Support/raw_ostream.h
+@@ -71,7 +71,6 @@ private:
+   /// for a \see write_impl() call to handle the data which has been put into
+   /// this buffer.
+   char *OutBufStart, *OutBufEnd, *OutBufCur;
+-  bool ColorEnabled = false;
+ 
+   /// Optional stream this stream is tied to. If this stream is written to, the
+   /// tied-to stream will be flushed first.
+@@ -304,9 +303,9 @@ public:
+ 
+   // Enable or disable colors. Once enable_colors(false) is called,
+   // changeColor() has no effect until enable_colors(true) is called.
+-  virtual void enable_colors(bool enable) { ColorEnabled = enable; }
++  virtual void enable_colors(bool /*enable*/) {}
+ 
+-  bool colors_enabled() const { return ColorEnabled; }
++  bool colors_enabled() const { return false; }
+ 
+   /// Tie this stream to the specified stream. Replaces any existing tied-to
+   /// stream. Specifying a nullptr unties the stream.
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index 8de7b726d..bc08199a1 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -178,22 +178,6 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file,
+ #endif
+ }
+ 
+-static void bindingsErrorHandler(void *user_data, const char *reason,
+-                                 bool gen_crash_diag) {
+-  LLVMFatalErrorHandler handler =
+-      LLVM_EXTENSION reinterpret_cast<LLVMFatalErrorHandler>(user_data);
+-  handler(reason);
+-}
+-
+-void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler) {
+-  install_fatal_error_handler(bindingsErrorHandler,
+-                              LLVM_EXTENSION reinterpret_cast<void *>(Handler));
+-}
+-
+-void LLVMResetFatalErrorHandler() {
+-  remove_fatal_error_handler();
+-}
+-
+ #ifdef _WIN32
+ 
+ #include <winerror.h>
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index 878a3a5e9..632b52235 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -167,16 +167,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str,
+   return *this;
+ }
+ 
+-raw_ostream &raw_ostream::operator<<(const void *P) {
+-  llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
+-  return *this;
+-}
+-
+-raw_ostream &raw_ostream::operator<<(double N) {
+-  llvm::write_double(*this, N, FloatStyle::Exponent);
+-  return *this;
+-}
+-
+ void raw_ostream::flush_nonempty() {
+   assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
+   size_t Length = OutBufCur - OutBufStart;
+@@ -321,15 +311,22 @@ static int getFD(std::string_view Filename, std::error_code &EC,
+   if (Filename == "-") {
+     EC = std::error_code();
+     // Change stdout's text/binary mode based on the Flags.
+-    sys::ChangeStdoutMode(Flags);
++    if (!(Flags & fs::OF_Text)) {
++#if defined(_WIN32)
++      _setmode(_fileno(stdout), _O_BINARY);
++#endif
++    }
+     return STDOUT_FILENO;
+   }
+ 
+-  int FD;
+-  if (Access & sys::fs::FA_Read)
+-    EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
++  fs::file_t F;
++  if (Access & fs::FA_Read)
++    F = fs::OpenFileForReadWrite(fs::path{std::string_view{Filename.data(), Filename.size()}}, EC, Disp, Flags);
+   else
+-    EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
++    F = fs::OpenFileForWrite(fs::path{std::string_view{Filename.data(), Filename.size()}}, EC, Disp, Flags);
++  if (EC)
++    return -1;
++  int FD = fs::FileToFd(F, EC, Flags);
+   if (EC)
+     return -1;
+ 
+@@ -389,12 +386,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
+ 
+   // Get the starting position.
+   off_t loc = ::lseek(FD, 0, SEEK_CUR);
+-  sys::fs::file_status Status;
+-  std::error_code EC = status(FD, Status);
+-  IsRegularFile = Status.type() == sys::fs::file_type::regular_file;
+ #ifdef _WIN32
+-  // MSVCRT's _lseek(SEEK_CUR) doesn't return -1 for pipes.
+-  SupportsSeeking = !EC && IsRegularFile;
++  SupportsSeeking = loc != (off_t)-1 && ::GetFileType(reinterpret_cast<HANDLE>(::_get_osfhandle(FD))) != FILE_TYPE_PIPE;
+ #else
+   SupportsSeeking = !EC && loc != (off_t)-1;
+ #endif
+@@ -407,10 +400,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered,
+ raw_fd_ostream::~raw_fd_ostream() {
+   if (FD >= 0) {
+     flush();
+-    if (ShouldClose) {
+-      if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
+-        error_detected(EC);
+-    }
++    if (ShouldClose && ::close(FD) < 0)
++      error_detected(std::error_code(errno, std::generic_category()));
+   }
+ 
+ #ifdef __MINGW32__
+@@ -505,7 +496,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
+ 
+   do {
+     size_t ChunkSize = std::min(Size, MaxWriteSize);
++#ifdef _WIN32
++    int ret = ::_write(FD, Ptr, ChunkSize);
++#else
+     ssize_t ret = ::write(FD, Ptr, ChunkSize);
++#endif
+ 
+     if (ret < 0) {
+       // If it's a recoverable error, swallow it and retry the write.
+@@ -540,8 +535,8 @@ void raw_fd_ostream::close() {
+   assert(ShouldClose);
+   ShouldClose = false;
+   flush();
+-  if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
+-    error_detected(EC);
++  if (::close(FD) < 0)
++    error_detected(std::error_code(errno, std::generic_category()));
+   FD = -1;
+ }
+ 
+@@ -550,8 +545,6 @@ uint64_t raw_fd_ostream::seek(uint64_t off) {
+   flush();
+ #ifdef _WIN32
+   pos = ::_lseeki64(FD, off, SEEK_SET);
+-#elif defined(HAVE_LSEEK64)
+-  pos = ::lseek64(FD, off, SEEK_SET);
+ #else
+   pos = ::lseek(FD, off, SEEK_SET);
+ #endif
+diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp
+index bee3875d1..87600ea47 100644
+--- a/llvm/unittests/ADT/SmallStringTest.cpp
++++ b/llvm/unittests/ADT/SmallStringTest.cpp
+@@ -129,23 +129,6 @@ TEST_F(SmallStringTest, StdStringConversion) {
+   EXPECT_EQ("abc", theStdString);
+ }
+ 
+-TEST_F(SmallStringTest, Substr) {
+-  theString = "hello";
+-  EXPECT_EQ("lo", theString.substr(3));
+-  EXPECT_EQ("", theString.substr(100));
+-  EXPECT_EQ("hello", theString.substr(0, 100));
+-  EXPECT_EQ("o", theString.substr(4, 10));
+-}
+-
+-TEST_F(SmallStringTest, Slice) {
+-  theString = "hello";
+-  EXPECT_EQ("l", theString.slice(2, 3));
+-  EXPECT_EQ("ell", theString.slice(1, 4));
+-  EXPECT_EQ("llo", theString.slice(2, 100));
+-  EXPECT_EQ("", theString.slice(2, 1));
+-  EXPECT_EQ("", theString.slice(10, 20));
+-}
+-
+ TEST_F(SmallStringTest, Find) {
+   theString = "hello";
+   EXPECT_EQ(2U, theString.find('l'));
+@@ -180,68 +163,4 @@ TEST_F(SmallStringTest, Find) {
+   EXPECT_EQ(0U, theString.find(""));
+ }
+ 
+-TEST_F(SmallStringTest, Count) {
+-  theString = "hello";
+-  EXPECT_EQ(2U, theString.count('l'));
+-  EXPECT_EQ(1U, theString.count('o'));
+-  EXPECT_EQ(0U, theString.count('z'));
+-  EXPECT_EQ(0U, theString.count("helloworld"));
+-  EXPECT_EQ(1U, theString.count("hello"));
+-  EXPECT_EQ(1U, theString.count("ello"));
+-  EXPECT_EQ(0U, theString.count("zz"));
+-}
+-
+-TEST_F(SmallStringTest, Realloc) {
+-  theString = "abcd";
+-  theString.reserve(100);
+-  EXPECT_EQ("abcd", theString);
+-  unsigned const N = 100000;
+-  theString.reserve(N);
+-  for (unsigned i = 0; i < N - 4; ++i)
+-    theString.push_back('y');
+-  EXPECT_EQ("abcdyyy", theString.slice(0, 7));
+-}
+-
+-TEST_F(SmallStringTest, Comparisons) {
+-  EXPECT_EQ(-1, SmallString<10>("aab").compare("aad"));
+-  EXPECT_EQ( 0, SmallString<10>("aab").compare("aab"));
+-  EXPECT_EQ( 1, SmallString<10>("aab").compare("aaa"));
+-  EXPECT_EQ(-1, SmallString<10>("aab").compare("aabb"));
+-  EXPECT_EQ( 1, SmallString<10>("aab").compare("aa"));
+-  EXPECT_EQ( 1, SmallString<10>("\xFF").compare("\1"));
+-
+-  EXPECT_EQ(-1, SmallString<10>("AaB").compare_insensitive("aAd"));
+-  EXPECT_EQ( 0, SmallString<10>("AaB").compare_insensitive("aab"));
+-  EXPECT_EQ( 1, SmallString<10>("AaB").compare_insensitive("AAA"));
+-  EXPECT_EQ(-1, SmallString<10>("AaB").compare_insensitive("aaBb"));
+-  EXPECT_EQ( 1, SmallString<10>("AaB").compare_insensitive("aA"));
+-  EXPECT_EQ( 1, SmallString<10>("\xFF").compare_insensitive("\1"));
+-
+-  EXPECT_EQ(-1, SmallString<10>("aab").compare_numeric("aad"));
+-  EXPECT_EQ( 0, SmallString<10>("aab").compare_numeric("aab"));
+-  EXPECT_EQ( 1, SmallString<10>("aab").compare_numeric("aaa"));
+-  EXPECT_EQ(-1, SmallString<10>("aab").compare_numeric("aabb"));
+-  EXPECT_EQ( 1, SmallString<10>("aab").compare_numeric("aa"));
+-  EXPECT_EQ(-1, SmallString<10>("1").compare_numeric("10"));
+-  EXPECT_EQ( 0, SmallString<10>("10").compare_numeric("10"));
+-  EXPECT_EQ( 0, SmallString<10>("10a").compare_numeric("10a"));
+-  EXPECT_EQ( 1, SmallString<10>("2").compare_numeric("1"));
+-  EXPECT_EQ( 0, SmallString<10>("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty"));
+-  EXPECT_EQ( 1, SmallString<10>("\xFF").compare_numeric("\1"));
+-  EXPECT_EQ( 1, SmallString<10>("V16").compare_numeric("V1_q0"));
+-  EXPECT_EQ(-1, SmallString<10>("V1_q0").compare_numeric("V16"));
+-  EXPECT_EQ(-1, SmallString<10>("V8_q0").compare_numeric("V16"));
+-  EXPECT_EQ( 1, SmallString<10>("V16").compare_numeric("V8_q0"));
+-  EXPECT_EQ(-1, SmallString<10>("V1_q0").compare_numeric("V8_q0"));
+-  EXPECT_EQ( 1, SmallString<10>("V8_q0").compare_numeric("V1_q0"));
+-}
+-
+-// Check gtest prints SmallString as a string instead of a container of chars.
+-// The code is in utils/unittest/googletest/internal/custom/gtest-printers.h
+-TEST_F(SmallStringTest, GTestPrinter) {
+-  EXPECT_EQ(R"("foo")", ::testing::PrintToString(SmallString<1>("foo")));
+-  const SmallVectorImpl<char> &ErasedSmallString = SmallString<1>("foo");
+-  EXPECT_EQ(R"("foo")", ::testing::PrintToString(ErasedSmallString));
+-}
+-
+ } // namespace
diff --git a/upstream_utils/llvm_patches/0023-OS-specific-changes.patch b/upstream_utils/llvm_patches/0023-OS-specific-changes.patch
new file mode 100644
index 0000000..ed58dac
--- /dev/null
+++ b/upstream_utils/llvm_patches/0023-OS-specific-changes.patch
@@ -0,0 +1,43 @@
+From ae08bb29b4d2a8ea15a4b82b909c0f4aee5e9060 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 8 May 2022 19:30:43 -0400
+Subject: [PATCH 23/28] OS-specific changes
+
+---
+ llvm/lib/Support/ErrorHandling.cpp | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp
+index bc08199a1..839819094 100644
+--- a/llvm/lib/Support/ErrorHandling.cpp
++++ b/llvm/lib/Support/ErrorHandling.cpp
+@@ -96,12 +96,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) {
+     fmt::print(stderr, "LLVM ERROR: {}\n", Reason);
+   }
+ 
+-  // If we reached here, we are failing ungracefully. Run the interrupt handlers
+-  // to make sure any special cleanups get done, in particular that we remove
+-  // files registered with RemoveFileOnSignal.
+-  sys::RunInterruptHandlers();
+-
+-  abort();
++  exit(1);
+ }
+ 
+ void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler,
+@@ -138,9 +133,15 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) {
+   // an OOM to stderr and abort.
+   const char *OOMMessage = "LLVM ERROR: out of memory\n";
+   const char *Newline = "\n";
++#ifdef _WIN32
++  (void)!::_write(2, OOMMessage, strlen(OOMMessage));
++  (void)!::_write(2, Reason, strlen(Reason));
++  (void)!::_write(2, Newline, strlen(Newline));
++#else
+   (void)!::write(2, OOMMessage, strlen(OOMMessage));
+   (void)!::write(2, Reason, strlen(Reason));
+   (void)!::write(2, Newline, strlen(Newline));
++#endif
+   abort();
+ }
+ 
diff --git a/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch b/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch
new file mode 100644
index 0000000..96088d2
--- /dev/null
+++ b/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch
@@ -0,0 +1,152 @@
+From f58b9bad86f61c35cc530ff113ccbb13415261c8 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Mon, 9 May 2022 00:04:30 -0400
+Subject: [PATCH 24/28] Use SmallVector for UTF conversion
+
+---
+ llvm/include/llvm/Support/ConvertUTF.h    |  6 +++---
+ llvm/lib/Support/ConvertUTFWrapper.cpp    |  6 +++---
+ llvm/unittests/Support/ConvertUTFTest.cpp | 22 +++++++++++-----------
+ 3 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h
+index b085c8a17..c82947006 100644
+--- a/llvm/include/llvm/Support/ConvertUTF.h
++++ b/llvm/include/llvm/Support/ConvertUTF.h
+@@ -213,7 +213,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result);
+ * Converts a std::wstring to a UTF-8 encoded std::string.
+ * \return true on success.
+ */
+-bool convertWideToUTF8(const std::wstring &Source, std::string &Result);
++bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl<char> &Result);
+ 
+ 
+ /**
+@@ -268,7 +268,7 @@ bool hasUTF16ByteOrderMark(span<const char> SrcBytes);
+  * \param [out] Out Converted UTF-8 is stored here on success.
+  * \returns true on success
+  */
+-bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out);
++bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &Out);
+ 
+ /**
+ * Converts a UTF16 string into a UTF8 std::string.
+@@ -277,7 +277,7 @@ bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out);
+ * \param [out] Out Converted UTF-8 is stored here on success.
+ * \returns true on success
+ */
+-bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out);
++bool convertUTF16ToUTF8String(span<const UTF16> Src, SmallVectorImpl<char> &Out);
+ 
+ /**
+  * Converts a UTF-8 string into a UTF-16 string with native endianness.
+diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp
+index cff30f16c..d3689d92a 100644
+--- a/llvm/lib/Support/ConvertUTFWrapper.cpp
++++ b/llvm/lib/Support/ConvertUTFWrapper.cpp
+@@ -84,7 +84,7 @@ bool hasUTF16ByteOrderMark(span<const char> S) {
+            (S[0] == '\xfe' && S[1] == '\xff')));
+ }
+ 
+-bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out) {
++bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &Out) {
+   assert(Out.empty());
+ 
+   // Error out on an uneven byte count.
+@@ -135,7 +135,7 @@ bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out) {
+   return true;
+ }
+ 
+-bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out)
++bool convertUTF16ToUTF8String(span<const UTF16> Src, SmallVectorImpl<char> &Out)
+ {
+   return convertUTF16ToUTF8String(
+       span<const char>(reinterpret_cast<const char *>(Src.data()),
+@@ -213,7 +213,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) {
+   return ConvertUTF8toWide(std::string_view(Source), Result);
+ }
+ 
+-bool convertWideToUTF8(const std::wstring &Source, std::string &Result) {
++bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl<char> &Result) {
+   if (sizeof(wchar_t) == 1) {
+     const UTF8 *Start = reinterpret_cast<const UTF8 *>(Source.data());
+     const UTF8 *End =
+diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp
+index 2fee8ad5c..7d7650b1c 100644
+--- a/llvm/unittests/Support/ConvertUTFTest.cpp
++++ b/llvm/unittests/Support/ConvertUTFTest.cpp
+@@ -19,22 +19,22 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) {
+   // Src is the look of disapproval.
+   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+   span<const char> Ref(Src, sizeof(Src) - 1);
+-  std::string Result;
++  SmallString<20> Result;
+   bool Success = convertUTF16ToUTF8String(Ref, Result);
+   EXPECT_TRUE(Success);
+   std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+-  EXPECT_EQ(Expected, Result);
++  EXPECT_EQ(Expected, std::string{Result});
+ }
+ 
+ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) {
+   // Src is the look of disapproval.
+   alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0";
+   span<const char> Ref(Src, sizeof(Src) - 1);
+-  std::string Result;
++  SmallString<20> Result;
+   bool Success = convertUTF16ToUTF8String(Ref, Result);
+   EXPECT_TRUE(Success);
+   std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+-  EXPECT_EQ(Expected, Result);
++  EXPECT_EQ(Expected, std::string{Result});
+ }
+ 
+ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
+@@ -51,16 +51,16 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) {
+ }
+ 
+ TEST(ConvertUTFTest, OddLengthInput) {
+-  std::string Result;
++  SmallString<20> Result;
+   bool Success = convertUTF16ToUTF8String(span<const char>("xxxxx", 5), Result);
+   EXPECT_FALSE(Success);
+ }
+ 
+ TEST(ConvertUTFTest, Empty) {
+-  std::string Result;
++  SmallString<20> Result;
+   bool Success = convertUTF16ToUTF8String(span<const char>(), Result);
+   EXPECT_TRUE(Success);
+-  EXPECT_TRUE(Result.empty());
++  EXPECT_TRUE(std::string{Result}.empty());
+ }
+ 
+ TEST(ConvertUTFTest, HasUTF16BOM) {
+@@ -83,11 +83,11 @@ TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) {
+   // Src is the look of disapproval.
+   alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c";
+   span<const UTF16> SrcRef((const UTF16 *)Src, 4);
+-  std::string Result;
++  SmallString<20> Result;
+   bool Success = convertUTF16ToUTF8String(SrcRef, Result);
+   EXPECT_TRUE(Success);
+   std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+-  EXPECT_EQ(Expected, Result);
++  EXPECT_EQ(Expected, std::string{Result});
+ }
+ 
+ TEST(ConvertUTFTest, ConvertUTF8toWide) {
+@@ -107,11 +107,11 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) {
+ TEST(ConvertUTFTest, convertWideToUTF8) {
+   // Src is the look of disapproval.
+   static const wchar_t Src[] = L"\x0ca0_\x0ca0";
+-  std::string Result;
++  SmallString<20> Result;
+   bool Success = convertWideToUTF8(Src, Result);
+   EXPECT_TRUE(Success);
+   std::string Expected("\xe0\xb2\xa0_\xe0\xb2\xa0");
+-  EXPECT_EQ(Expected, Result);
++  EXPECT_EQ(Expected, std::string{Result});
+ }
+ 
+ struct ConvertUTFResultContainer {
diff --git a/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch b/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch
new file mode 100644
index 0000000..36a884c
--- /dev/null
+++ b/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch
@@ -0,0 +1,34 @@
+From 35b1a8382240732065790c88a0c515701c1a2beb Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Thu, 19 May 2022 00:58:36 -0400
+Subject: [PATCH 25/28] Prefer to use static pointers in raw_ostream
+
+See #1401
+---
+ llvm/lib/Support/raw_ostream.cpp | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
+index 632b52235..a703a75ed 100644
+--- a/llvm/lib/Support/raw_ostream.cpp
++++ b/llvm/lib/Support/raw_ostream.cpp
+@@ -599,15 +599,15 @@ void raw_fd_ostream::anchor() {}
+ raw_fd_ostream &llvm::outs() {
+   // Set buffer settings to model stdout behavior.
+   std::error_code EC;
+-  static raw_fd_ostream S("-", EC, sys::fs::OF_None);
++  static raw_fd_ostream* S = new raw_fd_ostream("-", EC, sys::fs::OF_None);
+   assert(!EC);
+-  return S;
++  return *S;
+ }
+ 
+ raw_fd_ostream &llvm::errs() {
+   // Set standard error to be unbuffered and tied to outs() by default.
+-  static raw_fd_ostream S(STDERR_FILENO, false, true);
+-  return S;
++  static raw_fd_ostream* S = new raw_fd_ostream(STDERR_FILENO, false, true);
++  return *S;
+ }
+ 
+ /// nulls() - This returns a reference to a raw_ostream which discards output.
diff --git a/upstream_utils/llvm_patches/0026-constexpr-endian-byte-swap.patch b/upstream_utils/llvm_patches/0026-constexpr-endian-byte-swap.patch
new file mode 100644
index 0000000..79e0e7d
--- /dev/null
+++ b/upstream_utils/llvm_patches/0026-constexpr-endian-byte-swap.patch
@@ -0,0 +1,24 @@
+From 34f44d312c918b3b5dd69fc689ec0b628dc712f9 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Thu, 19 May 2022 01:12:41 -0400
+Subject: [PATCH 26/28] constexpr endian byte swap
+
+---
+ llvm/include/llvm/Support/Endian.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/llvm/include/llvm/Support/Endian.h b/llvm/include/llvm/Support/Endian.h
+index 5e7c1e961..2e883ff05 100644
+--- a/llvm/include/llvm/Support/Endian.h
++++ b/llvm/include/llvm/Support/Endian.h
+@@ -55,7 +55,9 @@ inline value_type byte_swap(value_type value, endianness endian) {
+ /// Swap the bytes of value to match the given endianness.
+ template<typename value_type, endianness endian>
+ inline value_type byte_swap(value_type value) {
+-  return byte_swap(value, endian);
++  if constexpr ((endian != native) && (endian != system_endianness()))
++    sys::swapByteOrder(value);
++  return value;
+ }
+ 
+ /// Read a value of a particular endianness from memory.
diff --git a/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch b/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch
new file mode 100644
index 0000000..9f192a1
--- /dev/null
+++ b/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch
@@ -0,0 +1,69 @@
+From 8f51777a3117a7b010a4cfb2ded1f5d226466f34 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Wed, 10 Aug 2022 17:07:52 -0700
+Subject: [PATCH 27/28] Copy type traits from STLExtras.h into PointerUnion.h
+
+---
+ llvm/include/llvm/ADT/PointerUnion.h | 46 ++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h
+index 1d4cc747c..7d090da59 100644
+--- a/llvm/include/llvm/ADT/PointerUnion.h
++++ b/llvm/include/llvm/ADT/PointerUnion.h
+@@ -22,9 +22,55 @@
+ #include <cassert>
+ #include <cstddef>
+ #include <cstdint>
++#include <type_traits>
+ 
+ namespace llvm {
+ 
++namespace detail {
++template <typename T, typename... Us> struct TypesAreDistinct;
++template <typename T, typename... Us>
++struct TypesAreDistinct
++    : std::integral_constant<bool, !std::disjunction_v<std::is_same<T, Us>...> &&
++                                       TypesAreDistinct<Us...>::value> {};
++template <typename T> struct TypesAreDistinct<T> : std::true_type {};
++} // namespace detail
++
++/// Determine if all types in Ts are distinct.
++///
++/// Useful to statically assert when Ts is intended to describe a non-multi set
++/// of types.
++///
++/// Expensive (currently quadratic in sizeof(Ts...)), and so should only be
++/// asserted once per instantiation of a type which requires it.
++template <typename... Ts> struct TypesAreDistinct;
++template <> struct TypesAreDistinct<> : std::true_type {};
++template <typename... Ts>
++struct TypesAreDistinct
++    : std::integral_constant<bool, detail::TypesAreDistinct<Ts...>::value> {};
++
++/// Find the first index where a type appears in a list of types.
++///
++/// FirstIndexOfType<T, Us...>::value is the first index of T in Us.
++///
++/// Typically only meaningful when it is otherwise statically known that the
++/// type pack has no duplicate types. This should be guaranteed explicitly with
++/// static_assert(TypesAreDistinct<Us...>::value).
++///
++/// It is a compile-time error to instantiate when T is not present in Us, i.e.
++/// if is_one_of<T, Us...>::value is false.
++template <typename T, typename... Us> struct FirstIndexOfType;
++template <typename T, typename U, typename... Us>
++struct FirstIndexOfType<T, U, Us...>
++    : std::integral_constant<size_t, 1 + FirstIndexOfType<T, Us...>::value> {};
++template <typename T, typename... Us>
++struct FirstIndexOfType<T, T, Us...> : std::integral_constant<size_t, 0> {};
++
++/// Find the type at a given index in a list of types.
++///
++/// TypeAtIndex<I, Ts...> is the type at index I in Ts.
++template <size_t I, typename... Ts>
++using TypeAtIndex = std::tuple_element_t<I, std::tuple<Ts...>>;
++
+ namespace pointer_union_detail {
+   /// Determine the number of bits required to store integers with values < n.
+   /// This is ceil(log2(n)).
diff --git a/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch b/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch
new file mode 100644
index 0000000..5c847e1
--- /dev/null
+++ b/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch
@@ -0,0 +1,34 @@
+From 498e56e09e8f264978831519ff9c8afa701bf208 Mon Sep 17 00:00:00 2001
+From: Tyler Veness <calcmogul@gmail.com>
+Date: Wed, 10 Aug 2022 22:35:00 -0700
+Subject: [PATCH 28/28] Remove StringMap test for llvm::sort()
+
+---
+ llvm/unittests/ADT/StringMapTest.cpp | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp
+index de6daf3da..ca41631cc 100644
+--- a/llvm/unittests/ADT/StringMapTest.cpp
++++ b/llvm/unittests/ADT/StringMapTest.cpp
+@@ -308,20 +308,6 @@ TEST_F(StringMapTest, InsertOrAssignTest) {
+   EXPECT_EQ(0, try1.first->second.copy);
+ }
+ 
+-TEST_F(StringMapTest, IterMapKeysVector) {
+-  StringMap<int> Map;
+-  Map["A"] = 1;
+-  Map["B"] = 2;
+-  Map["C"] = 3;
+-  Map["D"] = 3;
+-
+-  std::vector<std::string_view> Keys{Map.keys().begin(), Map.keys().end()};
+-  llvm::sort(Keys);
+-
+-  std::vector<std::string_view> Expected{{"A", "B", "C", "D"}};
+-  EXPECT_EQ(Expected, Keys);
+-}
+-
+ TEST_F(StringMapTest, IterMapKeysSmallVector) {
+   StringMap<int> Map;
+   Map["A"] = 1;
diff --git a/upstream_utils/memory_files/config_impl.hpp b/upstream_utils/memory_files/config_impl.hpp
new file mode 100644
index 0000000..1f72375
--- /dev/null
+++ b/upstream_utils/memory_files/config_impl.hpp
@@ -0,0 +1,34 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+// Copyright (C) 2015-2020 Jonathan Müller <jonathanmueller.dev@gmail.com>
+// This file is subject to the license terms in the LICENSE file
+// found in the top-level directory of this distribution.
+
+#pragma once
+
+#include <cstddef>
+
+//=== options ===//
+#define WPI_MEMORY_CHECK_ALLOCATION_SIZE 1
+#define WPI_MEMORY_IMPL_DEFAULT_ALLOCATOR heap_allocator
+#ifdef NDEBUG
+#define WPI_MEMORY_DEBUG_ASSERT 0
+#define WPI_MEMORY_DEBUG_FILL 0
+#define WPI_MEMORY_DEBUG_FENCE 0
+#define WPI_MEMORY_DEBUG_LEAK_CHECK 0
+#define WPI_MEMORY_DEBUG_POINTER_CHECK 0
+#define WPI_MEMORY_DEBUG_DOUBLE_DEALLOC_CHECK 0
+#else
+#define WPI_MEMORY_DEBUG_ASSERT 1
+#define WPI_MEMORY_DEBUG_FILL 1
+#define WPI_MEMORY_DEBUG_FENCE 8
+#define WPI_MEMORY_DEBUG_LEAK_CHECK 1
+#define WPI_MEMORY_DEBUG_POINTER_CHECK 1
+#define WPI_MEMORY_DEBUG_DOUBLE_DEALLOC_CHECK 1
+#endif
+#define WPI_MEMORY_EXTERN_TEMPLATE 1
+#define WPI_MEMORY_TEMPORARY_STACK_MODE 2
+
+#define WPI_MEMORY_NO_NODE_SIZE 1
diff --git a/upstream_utils/mpack_patches/0001-Don-t-emit-inline-defs.patch b/upstream_utils/mpack_patches/0001-Don-t-emit-inline-defs.patch
new file mode 100644
index 0000000..a899a5e
--- /dev/null
+++ b/upstream_utils/mpack_patches/0001-Don-t-emit-inline-defs.patch
@@ -0,0 +1,22 @@
+From 05864e768ca1458c1e24f433d091306a7d47562b Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 29 Oct 2022 12:09:03 -0400
+Subject: [PATCH 1/3] Don't emit inline defs
+
+---
+ src/mpack/mpack-platform.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/mpack/mpack-platform.c b/src/mpack/mpack-platform.c
+index 6599e1f..d4a2fa3 100644
+--- a/src/mpack/mpack-platform.c
++++ b/src/mpack/mpack-platform.c
+@@ -24,7 +24,7 @@
+ // standalone definitions of all (non-static) inline functions in MPack.
+ 
+ #define MPACK_INTERNAL 1
+-#define MPACK_EMIT_INLINE_DEFS 1
++#define MPACK_EMIT_INLINE_DEFS 0
+ 
+ #include "mpack-platform.h"
+ #include "mpack.h"
diff --git a/upstream_utils/mpack_patches/0002-Update-amalgamation-script.patch b/upstream_utils/mpack_patches/0002-Update-amalgamation-script.patch
new file mode 100644
index 0000000..eabf154
--- /dev/null
+++ b/upstream_utils/mpack_patches/0002-Update-amalgamation-script.patch
@@ -0,0 +1,24 @@
+From d4d045c843d4b4de747d800e570c32cff3759a80 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 29 Oct 2022 12:16:36 -0400
+Subject: [PATCH 2/3] Update amalgamation script
+
+---
+ tools/amalgamate.sh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/amalgamate.sh b/tools/amalgamate.sh
+index 2e24e27..4dfe999 100755
+--- a/tools/amalgamate.sh
++++ b/tools/amalgamate.sh
+@@ -74,8 +74,8 @@ echo -e "#endif\n" >> $HEADER
+ 
+ # assemble source
+ echo -e "#define MPACK_INTERNAL 1" >> $SOURCE
+-echo -e "#define MPACK_EMIT_INLINE_DEFS 1\n" >> $SOURCE
+-echo -e "#include \"mpack.h\"\n" >> $SOURCE
++echo -e "#define MPACK_EMIT_INLINE_DEFS 0\n" >> $SOURCE
++echo -e "#include \"wpi/mpack.h\"\n" >> $SOURCE
+ for f in $SOURCES; do
+     echo -e "\n/* $f.c */" >> $SOURCE
+     sed -e 's@^#include ".*@/* & */@' -e '0,/^ \*\/$/d' src/$f >> $SOURCE
diff --git a/upstream_utils/mpack_patches/0003-Use-namespace-for-C.patch b/upstream_utils/mpack_patches/0003-Use-namespace-for-C.patch
new file mode 100644
index 0000000..4adb7f8
--- /dev/null
+++ b/upstream_utils/mpack_patches/0003-Use-namespace-for-C.patch
@@ -0,0 +1,158 @@
+From 37854ea8a4a4b387940719c40bd32792f1e6e027 Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sat, 29 Oct 2022 12:22:50 -0400
+Subject: [PATCH 3/3] Use namespace for C++
+
+---
+ src/mpack/mpack-common.c   | 2 ++
+ src/mpack/mpack-expect.c   | 2 ++
+ src/mpack/mpack-node.c     | 2 ++
+ src/mpack/mpack-platform.c | 2 ++
+ src/mpack/mpack-platform.h | 2 +-
+ src/mpack/mpack-reader.c   | 2 ++
+ src/mpack/mpack-writer.c   | 2 ++
+ src/mpack/mpack-writer.h   | 3 ++-
+ 8 files changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/src/mpack/mpack-common.c b/src/mpack/mpack-common.c
+index 2c133a3..dc7207f 100644
+--- a/src/mpack/mpack-common.c
++++ b/src/mpack/mpack-common.c
+@@ -24,6 +24,7 @@
+ #include "mpack-common.h"
+ 
+ MPACK_SILENCE_WARNINGS_BEGIN
++namespace mpack {
+ 
+ const char* mpack_error_to_string(mpack_error_t error) {
+     #if MPACK_STRINGS
+@@ -748,4 +749,5 @@ void mpack_print_file_callback(void* context, const char* data, size_t count) {
+ }
+ #endif
+ 
++}  // namespace mpack
+ MPACK_SILENCE_WARNINGS_END
+diff --git a/src/mpack/mpack-expect.c b/src/mpack/mpack-expect.c
+index 81576d1..6232a67 100644
+--- a/src/mpack/mpack-expect.c
++++ b/src/mpack/mpack-expect.c
+@@ -24,6 +24,7 @@
+ #include "mpack-expect.h"
+ 
+ MPACK_SILENCE_WARNINGS_BEGIN
++namespace mpack {
+ 
+ #if MPACK_EXPECT
+ 
+@@ -880,4 +881,5 @@ size_t mpack_expect_key_cstr(mpack_reader_t* reader, const char* keys[], bool fo
+ 
+ #endif
+ 
++}  // namespace mpack
+ MPACK_SILENCE_WARNINGS_END
+diff --git a/src/mpack/mpack-node.c b/src/mpack/mpack-node.c
+index 3d4b0f4..aba9897 100644
+--- a/src/mpack/mpack-node.c
++++ b/src/mpack/mpack-node.c
+@@ -24,6 +24,7 @@
+ #include "mpack-node.h"
+ 
+ MPACK_SILENCE_WARNINGS_BEGIN
++namespace mpack {
+ 
+ #if MPACK_NODE
+ 
+@@ -2401,4 +2402,5 @@ mpack_node_t mpack_node_map_value_at(mpack_node_t node, size_t index) {
+ 
+ #endif
+ 
++}  // namespace mpack
+ MPACK_SILENCE_WARNINGS_END
+diff --git a/src/mpack/mpack-platform.c b/src/mpack/mpack-platform.c
+index d4a2fa3..75d2de3 100644
+--- a/src/mpack/mpack-platform.c
++++ b/src/mpack/mpack-platform.c
+@@ -30,6 +30,7 @@
+ #include "mpack.h"
+ 
+ MPACK_SILENCE_WARNINGS_BEGIN
++namespace mpack {
+ 
+ #if MPACK_DEBUG
+ 
+@@ -218,4 +219,5 @@ void* mpack_realloc(void* old_ptr, size_t used_size, size_t new_size) {
+ }
+ #endif
+ 
++}  // namespace mpack
+ MPACK_SILENCE_WARNINGS_END
+diff --git a/src/mpack/mpack-platform.h b/src/mpack/mpack-platform.h
+index 79604c9..27a2f9e 100644
+--- a/src/mpack/mpack-platform.h
++++ b/src/mpack/mpack-platform.h
+@@ -1043,7 +1043,7 @@ void mpack_assert_fail(const char* message);
+  */
+ 
+ #ifdef __cplusplus
+-    #define MPACK_EXTERN_C_BEGIN extern "C" {
++    #define MPACK_EXTERN_C_BEGIN namespace mpack {
+     #define MPACK_EXTERN_C_END   }
+ #else
+     #define MPACK_EXTERN_C_BEGIN /*nothing*/
+diff --git a/src/mpack/mpack-reader.c b/src/mpack/mpack-reader.c
+index c6d2223..a135879 100644
+--- a/src/mpack/mpack-reader.c
++++ b/src/mpack/mpack-reader.c
+@@ -24,6 +24,7 @@
+ #include "mpack-reader.h"
+ 
+ MPACK_SILENCE_WARNINGS_BEGIN
++namespace mpack {
+ 
+ #if MPACK_READER
+ 
+@@ -1284,4 +1285,5 @@ void mpack_print_stdfile_to_callback(FILE* file, mpack_print_callback_t callback
+ 
+ #endif
+ 
++}  // namespace mpack
+ MPACK_SILENCE_WARNINGS_END
+diff --git a/src/mpack/mpack-writer.c b/src/mpack/mpack-writer.c
+index 4d052b1..9630d9e 100644
+--- a/src/mpack/mpack-writer.c
++++ b/src/mpack/mpack-writer.c
+@@ -24,6 +24,7 @@
+ #include "mpack-writer.h"
+ 
+ MPACK_SILENCE_WARNINGS_BEGIN
++namespace mpack {
+ 
+ #if MPACK_WRITER
+ 
+@@ -1772,4 +1773,5 @@ void mpack_complete_array(mpack_writer_t* writer) {
+ #endif // MPACK_BUILDER
+ #endif // MPACK_WRITER
+ 
++}  // namespace mpack
+ MPACK_SILENCE_WARNINGS_END
+diff --git a/src/mpack/mpack-writer.h b/src/mpack/mpack-writer.h
+index c239ee6..abeee1a 100644
+--- a/src/mpack/mpack-writer.h
++++ b/src/mpack/mpack-writer.h
+@@ -1168,6 +1168,7 @@ MPACK_EXTERN_C_END
+ 
+ #if defined(__cplusplus) || defined(MPACK_DOXYGEN)
+ 
++namespace mpack {
+ /**
+  * @name C++ write overloads
+  * @{
+@@ -1304,7 +1305,7 @@ MPACK_INLINE void mpack_write_kv(mpack_writer_t* writer, const char *key, const
+ /**
+  * @}
+  */
+-
++}  // namespace mpack
+ #endif /* __cplusplus */
+ 
+ /**
diff --git a/upstream_utils/stack_walker_patches/0001-Apply-PR-35.patch b/upstream_utils/stack_walker_patches/0001-Apply-PR-35.patch
new file mode 100644
index 0000000..8fe466e
--- /dev/null
+++ b/upstream_utils/stack_walker_patches/0001-Apply-PR-35.patch
@@ -0,0 +1,1353 @@
+From 6e2f70b7bb7c59fe99b7469bf3e3a257876403dc Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Sun, 22 May 2022 23:58:57 -0400
+Subject: [PATCH 1/3] Apply PR #35
+
+---
+ .gitignore                              |   9 +
+ Main/StackWalker/StackWalker.cpp        | 642 ++++++++++--------------
+ Main/StackWalker/StackWalker.h          |  40 +-
+ Main/StackWalker/StackWalker_VC2017.sln |  16 +-
+ Main/StackWalker/main.cpp               |   2 +-
+ 5 files changed, 306 insertions(+), 403 deletions(-)
+ create mode 100644 .gitignore
+
+diff --git a/.gitignore b/.gitignore
+new file mode 100644
+index 0000000..5d102c5
+--- /dev/null
++++ b/.gitignore
+@@ -0,0 +1,9 @@
++################################################################################
++# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
++################################################################################
++
++*.suo
++*.db
++*.sqlite
++/Main/StackWalker/_ReSharper.Caches/*
++/.vs/*
+diff --git a/Main/StackWalker/StackWalker.cpp b/Main/StackWalker/StackWalker.cpp
+index 7008ac6..48c7c57 100644
+--- a/Main/StackWalker/StackWalker.cpp
++++ b/Main/StackWalker/StackWalker.cpp
+@@ -1,4 +1,4 @@
+-/**********************************************************************
++/**********************************************************************
+  *
+  * StackWalker.cpp
+  * https://github.com/JochenKalmbach/StackWalker
+@@ -87,162 +87,36 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <tchar.h>
+-#include <windows.h>
+ #pragma comment(lib, "version.lib") // for "VerQueryValue"
+ #pragma warning(disable : 4826)
+ 
++#ifdef UNICODE
++  #define DBGHELP_TRANSLATE_TCHAR
+ 
+-// If VC7 and later, then use the shipped 'dbghelp.h'-file
++#endif
+ #pragma pack(push, 8)
+-#if _MSC_VER >= 1300
+ #include <dbghelp.h>
+-#else
+-// inline the important dbghelp.h-declarations...
+-typedef enum
+-{
+-  SymNone = 0,
+-  SymCoff,
+-  SymCv,
+-  SymPdb,
+-  SymExport,
+-  SymDeferred,
+-  SymSym,
+-  SymDia,
+-  SymVirtual,
+-  NumSymTypes
+-} SYM_TYPE;
+-typedef struct _IMAGEHLP_LINE64
+-{
+-  DWORD   SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
+-  PVOID   Key;          // internal
+-  DWORD   LineNumber;   // line number in file
+-  PCHAR   FileName;     // full filename
+-  DWORD64 Address;      // first instruction of line
+-} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
+-typedef struct _IMAGEHLP_MODULE64
+-{
+-  DWORD    SizeOfStruct;         // set to sizeof(IMAGEHLP_MODULE64)
+-  DWORD64  BaseOfImage;          // base load address of module
+-  DWORD    ImageSize;            // virtual size of the loaded module
+-  DWORD    TimeDateStamp;        // date/time stamp from pe header
+-  DWORD    CheckSum;             // checksum from the pe header
+-  DWORD    NumSyms;              // number of symbols in the symbol table
+-  SYM_TYPE SymType;              // type of symbols loaded
+-  CHAR     ModuleName[32];       // module name
+-  CHAR     ImageName[256];       // image name
+-  CHAR     LoadedImageName[256]; // symbol file name
+-} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
+-typedef struct _IMAGEHLP_SYMBOL64
+-{
+-  DWORD   SizeOfStruct;  // set to sizeof(IMAGEHLP_SYMBOL64)
+-  DWORD64 Address;       // virtual address including dll base address
+-  DWORD   Size;          // estimated size of symbol, can be zero
+-  DWORD   Flags;         // info about the symbols, see the SYMF defines
+-  DWORD   MaxNameLength; // maximum size of symbol name in 'Name'
+-  CHAR    Name[1];       // symbol name (null terminated string)
+-} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
+-typedef enum
+-{
+-  AddrMode1616,
+-  AddrMode1632,
+-  AddrModeReal,
+-  AddrModeFlat
+-} ADDRESS_MODE;
+-typedef struct _tagADDRESS64
+-{
+-  DWORD64      Offset;
+-  WORD         Segment;
+-  ADDRESS_MODE Mode;
+-} ADDRESS64, *LPADDRESS64;
+-typedef struct _KDHELP64
+-{
+-  DWORD64 Thread;
+-  DWORD   ThCallbackStack;
+-  DWORD   ThCallbackBStore;
+-  DWORD   NextCallback;
+-  DWORD   FramePointer;
+-  DWORD64 KiCallUserMode;
+-  DWORD64 KeUserCallbackDispatcher;
+-  DWORD64 SystemRangeStart;
+-  DWORD64 Reserved[8];
+-} KDHELP64, *PKDHELP64;
+-typedef struct _tagSTACKFRAME64
+-{
+-  ADDRESS64 AddrPC;         // program counter
+-  ADDRESS64 AddrReturn;     // return address
+-  ADDRESS64 AddrFrame;      // frame pointer
+-  ADDRESS64 AddrStack;      // stack pointer
+-  ADDRESS64 AddrBStore;     // backing store pointer
+-  PVOID     FuncTableEntry; // pointer to pdata/fpo or NULL
+-  DWORD64   Params[4];      // possible arguments to the function
+-  BOOL      Far;            // WOW far call
+-  BOOL      Virtual;        // is this a virtual frame?
+-  DWORD64   Reserved[3];
+-  KDHELP64  KdHelp;
+-} STACKFRAME64, *LPSTACKFRAME64;
+-typedef BOOL(__stdcall* PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE  hProcess,
+-                                                        DWORD64 qwBaseAddress,
+-                                                        PVOID   lpBuffer,
+-                                                        DWORD   nSize,
+-                                                        LPDWORD lpNumberOfBytesRead);
+-typedef PVOID(__stdcall* PFUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE hProcess, DWORD64 AddrBase);
+-typedef DWORD64(__stdcall* PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address);
+-typedef DWORD64(__stdcall* PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE      hProcess,
+-                                                         HANDLE      hThread,
+-                                                         LPADDRESS64 lpaddr);
+-
+-// clang-format off
+-#define SYMOPT_CASE_INSENSITIVE         0x00000001
+-#define SYMOPT_UNDNAME                  0x00000002
+-#define SYMOPT_DEFERRED_LOADS           0x00000004
+-#define SYMOPT_NO_CPP                   0x00000008
+-#define SYMOPT_LOAD_LINES               0x00000010
+-#define SYMOPT_OMAP_FIND_NEAREST        0x00000020
+-#define SYMOPT_LOAD_ANYTHING            0x00000040
+-#define SYMOPT_IGNORE_CVREC             0x00000080
+-#define SYMOPT_NO_UNQUALIFIED_LOADS     0x00000100
+-#define SYMOPT_FAIL_CRITICAL_ERRORS     0x00000200
+-#define SYMOPT_EXACT_SYMBOLS            0x00000400
+-#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS   0x00000800
+-#define SYMOPT_IGNORE_NT_SYMPATH        0x00001000
+-#define SYMOPT_INCLUDE_32BIT_MODULES    0x00002000
+-#define SYMOPT_PUBLICS_ONLY             0x00004000
+-#define SYMOPT_NO_PUBLICS               0x00008000
+-#define SYMOPT_AUTO_PUBLICS             0x00010000
+-#define SYMOPT_NO_IMAGE_SEARCH          0x00020000
+-#define SYMOPT_SECURE                   0x00040000
+-#define SYMOPT_DEBUG                    0x80000000
+-#define UNDNAME_COMPLETE                 (0x0000) // Enable full undecoration
+-#define UNDNAME_NAME_ONLY                (0x1000) // Crack only the name for primary declaration;
+-// clang-format on
+-
+-#endif // _MSC_VER < 1300
+ #pragma pack(pop)
+ 
+-// Some missing defines (for VC5/6):
+-#ifndef INVALID_FILE_ATTRIBUTES
+-#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+-#endif
+ 
+-// secure-CRT_functions are only available starting with VC8
+-#if _MSC_VER < 1400
+-#define strcpy_s(dst, len, src) strcpy(dst, src)
+-#define strncpy_s(dst, len, src, maxLen) strncpy(dst, len, src)
+-#define strcat_s(dst, len, src) strcat(dst, src)
+-#define _snprintf_s _snprintf
+-#define _tcscat_s _tcscat
+-#endif
+-
+-static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
++static void MyStrCpy(TCHAR* szDest, size_t nMaxDestSize, const TCHAR* szSrc)
+ {
+   if (nMaxDestSize <= 0)
+     return;
+-  strncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE);
++  _tcsncpy_s(szDest, nMaxDestSize, szSrc, _TRUNCATE);
+   // INFO: _TRUNCATE will ensure that it is null-terminated;
+   // but with older compilers (<1400) it uses "strncpy" and this does not!)
+   szDest[nMaxDestSize - 1] = 0;
+ } // MyStrCpy
+ 
++#ifdef _UNICODE
++  typedef SYMBOL_INFOW   tSymbolInfo;
++  typedef IMAGEHLP_LINEW64  tImageHelperLine;
++#else
++  typedef SYMBOL_INFO   tSymbolInfo;
++  typedef IMAGEHLP_LINE64  tImageHelperLine;
++#endif
++
+ // Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
+ #define USED_CONTEXT_FLAGS CONTEXT_FULL
+ 
+@@ -253,26 +127,26 @@ public:
+   {
+     m_parent = parent;
+     m_hDbhHelp = NULL;
+-    pSC = NULL;
++    symCleanup = NULL;
+     m_hProcess = hProcess;
+     m_szSymPath = NULL;
+-    pSFTA = NULL;
+-    pSGLFA = NULL;
+-    pSGMB = NULL;
+-    pSGMI = NULL;
+-    pSGO = NULL;
+-    pSGSFA = NULL;
+-    pSI = NULL;
+-    pSLM = NULL;
+-    pSSO = NULL;
+-    pSW = NULL;
+-    pUDSN = NULL;
+-    pSGSP = NULL;
++    symFunctionTableAccess64 = NULL;
++    symGetLineFromAddr64 = NULL;
++    symGetModuleBase64 = NULL;
++    symGetModuleInfo64 = NULL;
++    symGetOptions = NULL;
++    symFromAddr = NULL;
++    symInitialize = NULL;
++    symLoadModuleEx = NULL;
++    symSetOptions = NULL;
++    stackWalk64 = NULL;
++    unDecorateSymbolName = NULL;
++    symGetSearchPath = NULL;
+   }
+   ~StackWalkerInternal()
+   {
+-    if (pSC != NULL)
+-      pSC(m_hProcess); // SymCleanup
++    if (symCleanup != NULL)
++      symCleanup(m_hProcess); // SymCleanup
+     if (m_hDbhHelp != NULL)
+       FreeLibrary(m_hDbhHelp);
+     m_hDbhHelp = NULL;
+@@ -281,7 +155,7 @@ public:
+       free(m_szSymPath);
+     m_szSymPath = NULL;
+   }
+-  BOOL Init(LPCSTR szSymPath)
++  BOOL Init(LPCTSTR szSymPath)
+   {
+     if (m_parent == NULL)
+       return FALSE;
+@@ -354,54 +228,72 @@ public:
+       m_hDbhHelp = LoadLibrary(_T("dbghelp.dll"));
+     if (m_hDbhHelp == NULL)
+       return FALSE;
+-    pSI = (tSI)GetProcAddress(m_hDbhHelp, "SymInitialize");
+-    pSC = (tSC)GetProcAddress(m_hDbhHelp, "SymCleanup");
+-
+-    pSW = (tSW)GetProcAddress(m_hDbhHelp, "StackWalk64");
+-    pSGO = (tSGO)GetProcAddress(m_hDbhHelp, "SymGetOptions");
+-    pSSO = (tSSO)GetProcAddress(m_hDbhHelp, "SymSetOptions");
+-
+-    pSFTA = (tSFTA)GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64");
+-    pSGLFA = (tSGLFA)GetProcAddress(m_hDbhHelp, "SymGetLineFromAddr64");
+-    pSGMB = (tSGMB)GetProcAddress(m_hDbhHelp, "SymGetModuleBase64");
+-    pSGMI = (tSGMI)GetProcAddress(m_hDbhHelp, "SymGetModuleInfo64");
+-    pSGSFA = (tSGSFA)GetProcAddress(m_hDbhHelp, "SymGetSymFromAddr64");
+-    pUDSN = (tUDSN)GetProcAddress(m_hDbhHelp, "UnDecorateSymbolName");
+-    pSLM = (tSLM)GetProcAddress(m_hDbhHelp, "SymLoadModule64");
+-    pSGSP = (tSGSP)GetProcAddress(m_hDbhHelp, "SymGetSearchPath");
+-
+-    if (pSC == NULL || pSFTA == NULL || pSGMB == NULL || pSGMI == NULL || pSGO == NULL ||
+-        pSGSFA == NULL || pSI == NULL || pSSO == NULL || pSW == NULL || pUDSN == NULL ||
+-        pSLM == NULL)
++
++#ifdef _UNICODE
++    static const char strSymInitialize[] = "SymInitializeW";
++    static const char strUnDecorateSymbolName[] = "UnDecorateSymbolNameW";
++    static const char strSymGetSearchPath[] = "SymGetSearchPathW";
++    static const char strSymLoadModuleEx[] = "SymLoadModuleExW";
++    static const char strSymGetLineFromAddr64[] = "SymGetLineFromAddrW64";
++    static const char strSymGetModuleInfo64[] = "SymGetModuleInfoW64";
++    static const char strSymFromAddr[] = "SymFromAddrW";
++#else
++    static const char strSymInitialize[] = "SymInitialize";
++    static const char strUnDecorateSymbolName[] = "UnDecorateSymbolName";
++    static const char strSymGetSearchPath[] = "SymGetSearchPath";
++    static const char strSymLoadModuleEx[] = "SymLoadModuleEx";
++    static const char strSymGetLineFromAddr64[] = "SymGetLineFromAddr64";
++    static const char strSymGetModuleInfo64[] = "SymGetModuleInfo64";
++    static const char strSymFromAddr[] = "SymFromAddr";
++#endif
++    symInitialize = (tSI)GetProcAddress(m_hDbhHelp, strSymInitialize);
++    symCleanup = (tSC)GetProcAddress(m_hDbhHelp, "SymCleanup");
++
++    stackWalk64 = (tSW)GetProcAddress(m_hDbhHelp, "StackWalk64");
++    symGetOptions = (tSGO)GetProcAddress(m_hDbhHelp, "SymGetOptions");
++    symSetOptions = (tSSO)GetProcAddress(m_hDbhHelp, "SymSetOptions");
++
++    symFunctionTableAccess64 = (tSFTA)GetProcAddress(m_hDbhHelp, "SymFunctionTableAccess64");
++    symGetLineFromAddr64 = (tSGLFA)GetProcAddress(m_hDbhHelp, strSymGetLineFromAddr64);
++    symGetModuleBase64 = (tSGMB)GetProcAddress(m_hDbhHelp, "SymGetModuleBase64");
++    symGetModuleInfo64 = (tSGMI)GetProcAddress(m_hDbhHelp, strSymGetModuleInfo64);
++    symFromAddr = (tSFA)GetProcAddress(m_hDbhHelp, strSymFromAddr);
++    unDecorateSymbolName = (tUDSN)GetProcAddress(m_hDbhHelp, strUnDecorateSymbolName);
++    symLoadModuleEx = (tSLM)GetProcAddress(m_hDbhHelp, strSymLoadModuleEx);
++    symGetSearchPath = (tSGSP)GetProcAddress(m_hDbhHelp, strSymGetSearchPath);
++
++    if (symCleanup == NULL || symFunctionTableAccess64 == NULL || symGetModuleBase64 == NULL || symGetModuleInfo64 == NULL || symGetOptions == NULL ||
++        symFromAddr == NULL || symInitialize == NULL || symSetOptions == NULL || stackWalk64 == NULL || unDecorateSymbolName == NULL ||
++        symLoadModuleEx == NULL)
+     {
+       FreeLibrary(m_hDbhHelp);
+       m_hDbhHelp = NULL;
+-      pSC = NULL;
++      symCleanup = NULL;
+       return FALSE;
+     }
+ 
+     // SymInitialize
+     if (szSymPath != NULL)
+-      m_szSymPath = _strdup(szSymPath);
+-    if (this->pSI(m_hProcess, m_szSymPath, FALSE) == FALSE)
+-      this->m_parent->OnDbgHelpErr("SymInitialize", GetLastError(), 0);
++      m_szSymPath = _tcsdup(szSymPath);
++    if (this->symInitialize(m_hProcess, m_szSymPath, FALSE) == FALSE)
++      this->m_parent->OnDbgHelpErr(_T("SymInitialize"), GetLastError(), 0);
+ 
+-    DWORD symOptions = this->pSGO(); // SymGetOptions
++    DWORD symOptions = this->symGetOptions(); // SymGetOptions
+     symOptions |= SYMOPT_LOAD_LINES;
+     symOptions |= SYMOPT_FAIL_CRITICAL_ERRORS;
+     //symOptions |= SYMOPT_NO_PROMPTS;
+     // SymSetOptions
+-    symOptions = this->pSSO(symOptions);
++    symOptions = this->symSetOptions(symOptions);
+ 
+-    char buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
+-    if (this->pSGSP != NULL)
++    TCHAR buf[StackWalker::STACKWALK_MAX_NAMELEN] = {0};
++    if (this->symGetSearchPath != NULL)
+     {
+-      if (this->pSGSP(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE)
+-        this->m_parent->OnDbgHelpErr("SymGetSearchPath", GetLastError(), 0);
++      if (this->symGetSearchPath(m_hProcess, buf, StackWalker::STACKWALK_MAX_NAMELEN) == FALSE)
++        this->m_parent->OnDbgHelpErr(_T("SymGetSearchPath"), GetLastError(), 0);
+     }
+-    char  szUserName[1024] = {0};
++    TCHAR  szUserName[1024] = {0};
+     DWORD dwSize = 1024;
+-    GetUserNameA(szUserName, &dwSize);
++    GetUserName(szUserName, &dwSize);
+     this->m_parent->OnSymInit(buf, symOptions, szUserName);
+ 
+     return TRUE;
+@@ -411,7 +303,7 @@ public:
+ 
+   HMODULE m_hDbhHelp;
+   HANDLE  m_hProcess;
+-  LPSTR   m_szSymPath;
++  LPTSTR   m_szSymPath;
+ 
+ #pragma pack(push, 8)
+   typedef struct IMAGEHLP_MODULE64_V3
+@@ -423,13 +315,13 @@ public:
+     DWORD    CheckSum;             // checksum from the pe header
+     DWORD    NumSyms;              // number of symbols in the symbol table
+     SYM_TYPE SymType;              // type of symbols loaded
+-    CHAR     ModuleName[32];       // module name
+-    CHAR     ImageName[256];       // image name
+-    CHAR     LoadedImageName[256]; // symbol file name
++    TCHAR     ModuleName[32];       // module name
++    TCHAR     ImageName[256];       // image name
++    TCHAR     LoadedImageName[256]; // symbol file name
+     // new elements: 07-Jun-2002
+-    CHAR  LoadedPdbName[256];   // pdb file name
++    TCHAR  LoadedPdbName[256];   // pdb file name
+     DWORD CVSig;                // Signature of the CV record in the debug directories
+-    CHAR  CVData[MAX_PATH * 3]; // Contents of the CV record
++    TCHAR  CVData[MAX_PATH * 3]; // Contents of the CV record
+     DWORD PdbSig;               // Signature of PDB
+     GUID  PdbSig70;             // Signature of PDB (VC 7 and up)
+     DWORD PdbAge;               // DBI age of pdb
+@@ -460,56 +352,59 @@ public:
+ 
+   // SymCleanup()
+   typedef BOOL(__stdcall* tSC)(IN HANDLE hProcess);
+-  tSC pSC;
++  tSC symCleanup;
+ 
+   // SymFunctionTableAccess64()
+   typedef PVOID(__stdcall* tSFTA)(HANDLE hProcess, DWORD64 AddrBase);
+-  tSFTA pSFTA;
++  tSFTA symFunctionTableAccess64;
+ 
+   // SymGetLineFromAddr64()
+   typedef BOOL(__stdcall* tSGLFA)(IN HANDLE hProcess,
+                                   IN DWORD64 dwAddr,
+                                   OUT PDWORD pdwDisplacement,
+-                                  OUT PIMAGEHLP_LINE64 Line);
+-  tSGLFA pSGLFA;
++                                  OUT tImageHelperLine* Line);
++  tSGLFA symGetLineFromAddr64;
+ 
+   // SymGetModuleBase64()
+   typedef DWORD64(__stdcall* tSGMB)(IN HANDLE hProcess, IN DWORD64 dwAddr);
+-  tSGMB pSGMB;
++  tSGMB symGetModuleBase64;
+ 
+   // SymGetModuleInfo64()
+   typedef BOOL(__stdcall* tSGMI)(IN HANDLE hProcess,
+                                  IN DWORD64 dwAddr,
+                                  OUT IMAGEHLP_MODULE64_V3* ModuleInfo);
+-  tSGMI pSGMI;
++  tSGMI symGetModuleInfo64;
+ 
+   // SymGetOptions()
+   typedef DWORD(__stdcall* tSGO)(VOID);
+-  tSGO pSGO;
++  tSGO symGetOptions;
++
+ 
+   // SymGetSymFromAddr64()
+-  typedef BOOL(__stdcall* tSGSFA)(IN HANDLE hProcess,
+-                                  IN DWORD64 dwAddr,
++  typedef BOOL(__stdcall* tSFA)(IN HANDLE hProcess,
++                                  IN DWORD64 Address,
+                                   OUT PDWORD64 pdwDisplacement,
+-                                  OUT PIMAGEHLP_SYMBOL64 Symbol);
+-  tSGSFA pSGSFA;
++                                  OUT tSymbolInfo* Symbol);
++  tSFA symFromAddr;
+ 
+   // SymInitialize()
+-  typedef BOOL(__stdcall* tSI)(IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess);
+-  tSI pSI;
++  typedef BOOL(__stdcall* tSI)(IN HANDLE hProcess, IN PTSTR UserSearchPath, IN BOOL fInvadeProcess);
++  tSI symInitialize;
+ 
+   // SymLoadModule64()
+   typedef DWORD64(__stdcall* tSLM)(IN HANDLE hProcess,
+                                    IN HANDLE hFile,
+-                                   IN PSTR ImageName,
+-                                   IN PSTR ModuleName,
++                                   IN PTSTR ImageName,
++                                   IN PTSTR ModuleName,
+                                    IN DWORD64 BaseOfDll,
+-                                   IN DWORD SizeOfDll);
+-  tSLM pSLM;
++                                   IN DWORD SizeOfDll,
++                                   IN PMODLOAD_DATA Data,
++                                   IN DWORD         Flags);
++  tSLM symLoadModuleEx;
+ 
+   // SymSetOptions()
+   typedef DWORD(__stdcall* tSSO)(IN DWORD SymOptions);
+-  tSSO pSSO;
++  tSSO symSetOptions;
+ 
+   // StackWalk64()
+   typedef BOOL(__stdcall* tSW)(DWORD                            MachineType,
+@@ -521,17 +416,17 @@ public:
+                                PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
+                                PGET_MODULE_BASE_ROUTINE64       GetModuleBaseRoutine,
+                                PTRANSLATE_ADDRESS_ROUTINE64     TranslateAddress);
+-  tSW pSW;
++  tSW stackWalk64;
+ 
+   // UnDecorateSymbolName()
+-  typedef DWORD(__stdcall WINAPI* tUDSN)(PCSTR DecoratedName,
+-                                         PSTR  UnDecoratedName,
++  typedef DWORD(__stdcall WINAPI* tUDSN)(PCTSTR DecoratedName,
++                                         PTSTR  UnDecoratedName,
+                                          DWORD UndecoratedLength,
+                                          DWORD Flags);
+-  tUDSN pUDSN;
++  tUDSN unDecorateSymbolName;
+ 
+-  typedef BOOL(__stdcall WINAPI* tSGSP)(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength);
+-  tSGSP pSGSP;
++  typedef BOOL(__stdcall WINAPI* tSGSP)(HANDLE hProcess, PTSTR SearchPath, DWORD SearchPathLength);
++  tSGSP symGetSearchPath;
+ 
+ private:
+ // **************************************** ToolHelp32 ************************
+@@ -548,8 +443,8 @@ private:
+     BYTE*   modBaseAddr;   // Base address of module in th32ProcessID's context
+     DWORD   modBaseSize;   // Size in bytes of module starting at modBaseAddr
+     HMODULE hModule;       // The hModule of this module in th32ProcessID's context
+-    char    szModule[MAX_MODULE_NAME32 + 1];
+-    char    szExePath[MAX_PATH];
++    TCHAR   szModule[MAX_MODULE_NAME32 + 1];
++    TCHAR   szExePath[MAX_PATH];
+   } MODULEENTRY32;
+   typedef MODULEENTRY32* PMODULEENTRY32;
+   typedef MODULEENTRY32* LPMODULEENTRY32;
+@@ -567,25 +462,31 @@ private:
+     // try both dlls...
+     const TCHAR* dllname[] = {_T("kernel32.dll"), _T("tlhelp32.dll")};
+     HINSTANCE    hToolhelp = NULL;
+-    tCT32S       pCT32S = NULL;
+-    tM32F        pM32F = NULL;
+-    tM32N        pM32N = NULL;
++    tCT32S       createToolhelp32Snapshot = NULL;
++    tM32F        module32First = NULL;
++    tM32N        module32Next = NULL;
+ 
+     HANDLE        hSnap;
+-    MODULEENTRY32 me;
+-    me.dwSize = sizeof(me);
++    MODULEENTRY32 moduleEntry32;
++    moduleEntry32.dwSize = sizeof(moduleEntry32);
+     BOOL   keepGoing;
+-    size_t i;
+ 
+-    for (i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
++#ifdef _UNICODE
++    static const char strModule32First[] = "Module32FirstW";
++    static const char strModule32Next[] = "Module32NextW";
++ #else
++    static const char strModule32First[] = "Module32First";
++    static const char strModule32Next[] = "Module32Next";
++#endif
++    for (size_t i = 0; i < (sizeof(dllname) / sizeof(dllname[0])); i++)
+     {
+       hToolhelp = LoadLibrary(dllname[i]);
+       if (hToolhelp == NULL)
+         continue;
+-      pCT32S = (tCT32S)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
+-      pM32F = (tM32F)GetProcAddress(hToolhelp, "Module32First");
+-      pM32N = (tM32N)GetProcAddress(hToolhelp, "Module32Next");
+-      if ((pCT32S != NULL) && (pM32F != NULL) && (pM32N != NULL))
++      createToolhelp32Snapshot = (tCT32S)GetProcAddress(hToolhelp, "CreateToolhelp32Snapshot");
++      module32First = (tM32F)GetProcAddress(hToolhelp, strModule32First);  
++      module32Next = (tM32N)GetProcAddress(hToolhelp, strModule32Next); 
++      if ((createToolhelp32Snapshot != NULL) && (module32First != NULL) && (module32Next != NULL))
+         break; // found the functions!
+       FreeLibrary(hToolhelp);
+       hToolhelp = NULL;
+@@ -594,21 +495,21 @@ private:
+     if (hToolhelp == NULL)
+       return FALSE;
+ 
+-    hSnap = pCT32S(TH32CS_SNAPMODULE, pid);
++    hSnap = createToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
+     if (hSnap == (HANDLE)-1)
+     {
+       FreeLibrary(hToolhelp);
+       return FALSE;
+     }
+ 
+-    keepGoing = !!pM32F(hSnap, &me);
++    keepGoing = !!module32First(hSnap, &moduleEntry32);
+     int cnt = 0;
+     while (keepGoing)
+     {
+-      this->LoadModule(hProcess, me.szExePath, me.szModule, (DWORD64)me.modBaseAddr,
+-                       me.modBaseSize);
++      this->LoadModule(hProcess, moduleEntry32.szExePath, moduleEntry32.szModule, (DWORD64)moduleEntry32.modBaseAddr,
++                       moduleEntry32.modBaseSize);
+       cnt++;
+-      keepGoing = !!pM32N(hSnap, &me);
++      keepGoing = !!module32Next(hSnap, &moduleEntry32);
+     }
+     CloseHandle(hSnap);
+     FreeLibrary(hToolhelp);
+@@ -631,39 +532,41 @@ private:
+     typedef BOOL(__stdcall * tEPM)(HANDLE hProcess, HMODULE * lphModule, DWORD cb,
+                                    LPDWORD lpcbNeeded);
+     // GetModuleFileNameEx()
+-    typedef DWORD(__stdcall * tGMFNE)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename,
++    typedef DWORD(__stdcall * tGMFNE)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename,
+                                       DWORD nSize);
+     // GetModuleBaseName()
+-    typedef DWORD(__stdcall * tGMBN)(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename,
++    typedef DWORD(__stdcall * tGMBN)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename,
+                                      DWORD nSize);
+     // GetModuleInformation()
+     typedef BOOL(__stdcall * tGMI)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO pmi, DWORD nSize);
+ 
+-    HINSTANCE hPsapi;
+-    tEPM      pEPM;
+-    tGMFNE    pGMFNE;
+-    tGMBN     pGMBN;
+-    tGMI      pGMI;
+-
+-    DWORD i;
+-    //ModuleEntry e;
++      //ModuleEntry e;
+     DWORD        cbNeeded;
+     MODULEINFO   mi;
+     HMODULE*     hMods = 0;
+-    char*        tt = NULL;
+-    char*        tt2 = NULL;
++    TCHAR*        tt = NULL;
++    TCHAR*        tt2 = NULL;
+     const SIZE_T TTBUFLEN = 8096;
+     int          cnt = 0;
+ 
+-    hPsapi = LoadLibrary(_T("psapi.dll"));
++    HINSTANCE hPsapi = LoadLibrary(_T("psapi.dll"));
+     if (hPsapi == NULL)
+       return FALSE;
+ 
+-    pEPM = (tEPM)GetProcAddress(hPsapi, "EnumProcessModules");
+-    pGMFNE = (tGMFNE)GetProcAddress(hPsapi, "GetModuleFileNameExA");
+-    pGMBN = (tGMFNE)GetProcAddress(hPsapi, "GetModuleBaseNameA");
+-    pGMI = (tGMI)GetProcAddress(hPsapi, "GetModuleInformation");
+-    if ((pEPM == NULL) || (pGMFNE == NULL) || (pGMBN == NULL) || (pGMI == NULL))
++#ifdef _UNICODE
++    static const char strGetModuleFileName[] = "GetModuleFileNameExW";
++    static const char strGetModuleBaseName[] = "GetModuleBaseNameW";
++#else
++    static const char strGetModuleFileName[] = "GetModulefileNameExA";
++    static const char strGetModuleBaseName[] = "GetModuleBaseNameA";
++#endif
++
++    tEPM   enumProcessModules = (tEPM)GetProcAddress(hPsapi, "EnumProcessModules");
++    tGMFNE getModuleFileNameEx = (tGMFNE)GetProcAddress(hPsapi, strGetModuleFileName);
++    tGMBN  getModuleBaseName = (tGMFNE)GetProcAddress(hPsapi, strGetModuleBaseName);
++    tGMI   getModuleInformation = (tGMI)GetProcAddress(hPsapi, "GetModuleInformation");
++    if ((enumProcessModules == NULL) || (getModuleFileNameEx == NULL) ||
++        (getModuleBaseName == NULL) || (getModuleInformation == NULL))
+     {
+       // we couldn't find all functions
+       FreeLibrary(hPsapi);
+@@ -671,12 +574,12 @@ private:
+     }
+ 
+     hMods = (HMODULE*)malloc(sizeof(HMODULE) * (TTBUFLEN / sizeof(HMODULE)));
+-    tt = (char*)malloc(sizeof(char) * TTBUFLEN);
+-    tt2 = (char*)malloc(sizeof(char) * TTBUFLEN);
++    tt = (TCHAR*)malloc(sizeof(TCHAR) * TTBUFLEN);
++    tt2 = (TCHAR*)malloc(sizeof(TCHAR) * TTBUFLEN);
+     if ((hMods == NULL) || (tt == NULL) || (tt2 == NULL))
+       goto cleanup;
+ 
+-    if (!pEPM(hProcess, hMods, TTBUFLEN, &cbNeeded))
++    if (!enumProcessModules(hProcess, hMods, TTBUFLEN, &cbNeeded))
+     {
+       //_ftprintf(fLogFile, _T("%lu: EPM failed, GetLastError = %lu\n"), g_dwShowCount, gle );
+       goto cleanup;
+@@ -688,20 +591,20 @@ private:
+       goto cleanup;
+     }
+ 
+-    for (i = 0; i < cbNeeded / sizeof(hMods[0]); i++)
++    for (DWORD i = 0; i < cbNeeded / sizeof(hMods[0]); i++)
+     {
+       // base address, size
+-      pGMI(hProcess, hMods[i], &mi, sizeof(mi));
++      getModuleInformation(hProcess, hMods[i], &mi, sizeof(mi));
+       // image file name
+       tt[0] = 0;
+-      pGMFNE(hProcess, hMods[i], tt, TTBUFLEN);
++      getModuleFileNameEx(hProcess, hMods[i], tt, TTBUFLEN);
+       // module name
+       tt2[0] = 0;
+-      pGMBN(hProcess, hMods[i], tt2, TTBUFLEN);
++      getModuleBaseName(hProcess, hMods[i], tt2, TTBUFLEN);
+ 
+       DWORD dwRes = this->LoadModule(hProcess, tt, tt2, (DWORD64)mi.lpBaseOfDll, mi.SizeOfImage);
+       if (dwRes != ERROR_SUCCESS)
+-        this->m_parent->OnDbgHelpErr("LoadModule", dwRes, 0);
++        this->m_parent->OnDbgHelpErr(_T("LoadModule"), dwRes, 0);
+       cnt++;
+     }
+ 
+@@ -718,16 +621,16 @@ private:
+     return cnt != 0;
+   } // GetModuleListPSAPI
+ 
+-  DWORD LoadModule(HANDLE hProcess, LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size)
++  DWORD LoadModule(HANDLE hProcess, LPCTSTR img, LPCTSTR mod, DWORD64 baseAddr, DWORD size)
+   {
+-    CHAR* szImg = _strdup(img);
+-    CHAR* szMod = _strdup(mod);
++    TCHAR* szImg = _tcsdup(img);
++    TCHAR* szMod = _tcsdup(mod);
+     DWORD result = ERROR_SUCCESS;
+     if ((szImg == NULL) || (szMod == NULL))
+       result = ERROR_NOT_ENOUGH_MEMORY;
+     else
+     {
+-      if (pSLM(hProcess, 0, szImg, szMod, baseAddr, size) == 0)
++      if (symLoadModuleEx(hProcess, 0, szImg, szMod, baseAddr, size, 0, 0) == 0)
+         result = GetLastError();
+     }
+     ULONGLONG fileVersion = 0;
+@@ -738,13 +641,13 @@ private:
+       {
+         VS_FIXEDFILEINFO* fInfo = NULL;
+         DWORD             dwHandle;
+-        DWORD             dwSize = GetFileVersionInfoSizeA(szImg, &dwHandle);
++        DWORD             dwSize = GetFileVersionInfoSize(szImg, &dwHandle);
+         if (dwSize > 0)
+         {
+           LPVOID vData = malloc(dwSize);
+           if (vData != NULL)
+           {
+-            if (GetFileVersionInfoA(szImg, dwHandle, dwSize, vData) != 0)
++            if (GetFileVersionInfo(szImg, dwHandle, dwSize, vData) != 0)
+             {
+               UINT  len;
+               TCHAR szSubBlock[] = _T("\\");
+@@ -763,41 +666,41 @@ private:
+ 
+       // Retrieve some additional-infos about the module
+       IMAGEHLP_MODULE64_V3 Module;
+-      const char*          szSymType = "-unknown-";
++      const TCHAR*          szSymType = _T("-unknown-");
+       if (this->GetModuleInfo(hProcess, baseAddr, &Module) != FALSE)
+       {
+         switch (Module.SymType)
+         {
+           case SymNone:
+-            szSymType = "-nosymbols-";
++            szSymType = _T("-nosymbols-");
+             break;
+           case SymCoff: // 1
+-            szSymType = "COFF";
++            szSymType = _T("COFF");
+             break;
+           case SymCv: // 2
+-            szSymType = "CV";
++            szSymType = _T("CV");
+             break;
+           case SymPdb: // 3
+-            szSymType = "PDB";
++            szSymType = _T("PDB");
+             break;
+           case SymExport: // 4
+-            szSymType = "-exported-";
++            szSymType = _T("-exported-");
+             break;
+           case SymDeferred: // 5
+-            szSymType = "-deferred-";
++            szSymType = _T("-deferred-");
+             break;
+           case SymSym: // 6
+-            szSymType = "SYM";
++            szSymType = _T("SYM");
+             break;
+           case 7: // SymDia:
+-            szSymType = "DIA";
++            szSymType = _T("DIA");
+             break;
+           case 8: //SymVirtual:
+-            szSymType = "Virtual";
++            szSymType = _T("Virtual");
+             break;
+         }
+       }
+-      LPCSTR pdbName = Module.LoadedImageName;
++      LPCTSTR pdbName = Module.LoadedImageName;
+       if (Module.LoadedPdbName[0] != 0)
+         pdbName = Module.LoadedPdbName;
+       this->m_parent->OnLoadModule(img, mod, baseAddr, size, result, szSymType, pdbName,
+@@ -823,7 +726,7 @@ public:
+   BOOL GetModuleInfo(HANDLE hProcess, DWORD64 baseAddr, IMAGEHLP_MODULE64_V3* pModuleInfo)
+   {
+     memset(pModuleInfo, 0, sizeof(IMAGEHLP_MODULE64_V3));
+-    if (this->pSGMI == NULL)
++    if (this->symGetModuleInfo64 == NULL)
+     {
+       SetLastError(ERROR_DLL_INIT_FAILED);
+       return FALSE;
+@@ -841,7 +744,7 @@ public:
+     static bool s_useV3Version = true;
+     if (s_useV3Version)
+     {
+-      if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
++      if (this->symGetModuleInfo64(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
+       {
+         // only copy as much memory as is reserved...
+         memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V3));
+@@ -855,7 +758,7 @@ public:
+     // could not retrieve the bigger structure, try with the smaller one (as defined in VC7.1)...
+     pModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2);
+     memcpy(pData, pModuleInfo, sizeof(IMAGEHLP_MODULE64_V2));
+-    if (this->pSGMI(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
++    if (this->symGetModuleInfo64(hProcess, baseAddr, (IMAGEHLP_MODULE64_V3*)pData) != FALSE)
+     {
+       // only copy as much memory as is reserved...
+       memcpy(pModuleInfo, pData, sizeof(IMAGEHLP_MODULE64_V2));
+@@ -880,7 +783,7 @@ StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess)
+   this->m_szSymPath = NULL;
+   this->m_MaxRecursionCount = 1000;
+ }
+-StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
++StackWalker::StackWalker(int options, LPCTSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
+ {
+   this->m_options = options;
+   this->m_modulesLoaded = FALSE;
+@@ -889,7 +792,7 @@ StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDL
+   this->m_dwProcessId = dwProcessId;
+   if (szSymPath != NULL)
+   {
+-    this->m_szSymPath = _strdup(szSymPath);
++    this->m_szSymPath = _tcsdup(szSymPath);
+     this->m_options |= SymBuildPath;
+   }
+   else
+@@ -918,11 +821,11 @@ BOOL StackWalker::LoadModules()
+     return TRUE;
+ 
+   // Build the sym-path:
+-  char* szSymPath = NULL;
++  TCHAR* szSymPath = NULL;
+   if ((this->m_options & SymBuildPath) != 0)
+   {
+     const size_t nSymPathLen = 4096;
+-    szSymPath = (char*)malloc(nSymPathLen);
++    szSymPath = (TCHAR*)malloc(nSymPathLen * sizeof(TCHAR));
+     if (szSymPath == NULL)
+     {
+       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+@@ -932,27 +835,27 @@ BOOL StackWalker::LoadModules()
+     // Now first add the (optional) provided sympath:
+     if (this->m_szSymPath != NULL)
+     {
+-      strcat_s(szSymPath, nSymPathLen, this->m_szSymPath);
+-      strcat_s(szSymPath, nSymPathLen, ";");
++      _tcscat_s(szSymPath, nSymPathLen, this->m_szSymPath);
++      _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+     }
+ 
+-    strcat_s(szSymPath, nSymPathLen, ".;");
++    _tcscat_s(szSymPath, nSymPathLen, _T(".;"));
+ 
+     const size_t nTempLen = 1024;
+-    char         szTemp[nTempLen];
++    TCHAR         szTemp[nTempLen];
+     // Now add the current directory:
+-    if (GetCurrentDirectoryA(nTempLen, szTemp) > 0)
++    if (GetCurrentDirectory(nTempLen, szTemp) > 0)
+     {
+       szTemp[nTempLen - 1] = 0;
+-      strcat_s(szSymPath, nSymPathLen, szTemp);
+-      strcat_s(szSymPath, nSymPathLen, ";");
++      _tcscat_s(szSymPath, nSymPathLen, szTemp);
++      _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+     }
+ 
+     // Now add the path for the main-module:
+-    if (GetModuleFileNameA(NULL, szTemp, nTempLen) > 0)
++    if (GetModuleFileName(NULL, szTemp, nTempLen) > 0)
+     {
+       szTemp[nTempLen - 1] = 0;
+-      for (char* p = (szTemp + strlen(szTemp) - 1); p >= szTemp; --p)
++      for (TCHAR* p = (szTemp + _tcslen(szTemp) - 1); p >= szTemp; --p)
+       {
+         // locate the rightmost path separator
+         if ((*p == '\\') || (*p == '/') || (*p == ':'))
+@@ -961,48 +864,48 @@ BOOL StackWalker::LoadModules()
+           break;
+         }
+       } // for (search for path separator...)
+-      if (strlen(szTemp) > 0)
++      if (_tcslen(szTemp) > 0)
+       {
+-        strcat_s(szSymPath, nSymPathLen, szTemp);
+-        strcat_s(szSymPath, nSymPathLen, ";");
++        _tcscat_s(szSymPath, nSymPathLen, szTemp);
++        _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+       }
+     }
+-    if (GetEnvironmentVariableA("_NT_SYMBOL_PATH", szTemp, nTempLen) > 0)
++    if (GetEnvironmentVariable(_T("_NT_SYMBOL_PATH"), szTemp, nTempLen) > 0)
+     {
+       szTemp[nTempLen - 1] = 0;
+-      strcat_s(szSymPath, nSymPathLen, szTemp);
+-      strcat_s(szSymPath, nSymPathLen, ";");
++      _tcscat_s(szSymPath, nSymPathLen, szTemp);
++      _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+     }
+-    if (GetEnvironmentVariableA("_NT_ALTERNATE_SYMBOL_PATH", szTemp, nTempLen) > 0)
++    if (GetEnvironmentVariable(_T("_NT_ALTERNATE_SYMBOL_PATH"), szTemp, nTempLen) > 0)
+     {
+       szTemp[nTempLen - 1] = 0;
+-      strcat_s(szSymPath, nSymPathLen, szTemp);
+-      strcat_s(szSymPath, nSymPathLen, ";");
++      _tcscat_s(szSymPath, nSymPathLen, szTemp);
++      _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+     }
+-    if (GetEnvironmentVariableA("SYSTEMROOT", szTemp, nTempLen) > 0)
++    if (GetEnvironmentVariable(_T("SYSTEMROOT"), szTemp, nTempLen) > 0)
+     {
+       szTemp[nTempLen - 1] = 0;
+-      strcat_s(szSymPath, nSymPathLen, szTemp);
+-      strcat_s(szSymPath, nSymPathLen, ";");
++      _tcscat_s(szSymPath, nSymPathLen, szTemp);
++      _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+       // also add the "system32"-directory:
+-      strcat_s(szTemp, nTempLen, "\\system32");
+-      strcat_s(szSymPath, nSymPathLen, szTemp);
+-      strcat_s(szSymPath, nSymPathLen, ";");
++      _tcscat_s(szTemp, nTempLen, _T("\\system32"));
++      _tcscat_s(szSymPath, nSymPathLen, szTemp);
++      _tcscat_s(szSymPath, nSymPathLen, _T(";"));
+     }
+ 
+     if ((this->m_options & SymUseSymSrv) != 0)
+     {
+-      if (GetEnvironmentVariableA("SYSTEMDRIVE", szTemp, nTempLen) > 0)
++      if (GetEnvironmentVariable(_T("SYSTEMDRIVE"), szTemp, nTempLen) > 0)
+       {
+         szTemp[nTempLen - 1] = 0;
+-        strcat_s(szSymPath, nSymPathLen, "SRV*");
+-        strcat_s(szSymPath, nSymPathLen, szTemp);
+-        strcat_s(szSymPath, nSymPathLen, "\\websymbols");
+-        strcat_s(szSymPath, nSymPathLen, "*http://msdl.microsoft.com/download/symbols;");
++        _tcscat_s(szSymPath, nSymPathLen, _T("SRV*"));
++        _tcscat_s(szSymPath, nSymPathLen, szTemp);
++        _tcscat_s(szSymPath, nSymPathLen, _T("\\websymbols"));
++        _tcscat_s(szSymPath, nSymPathLen, _T("*http://msdl.microsoft.com/download/symbols;"));
+       }
+       else
+-        strcat_s(szSymPath, nSymPathLen,
+-                 "SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;");
++        _tcscat_s(szSymPath, nSymPathLen,
++                 _T("SRV*c:\\websymbols*http://msdl.microsoft.com/download/symbols;"));
+     }
+   } // if SymBuildPath
+ 
+@@ -1013,7 +916,7 @@ BOOL StackWalker::LoadModules()
+   szSymPath = NULL;
+   if (bRet == FALSE)
+   {
+-    this->OnDbgHelpErr("Error while initializing dbghelp.dll", 0, 0);
++    this->OnDbgHelpErr(_T("Error while initializing dbghelp.dll"), 0, 0);
+     SetLastError(ERROR_DLL_INIT_FAILED);
+     return FALSE;
+   }
+@@ -1038,9 +941,10 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+ {
+   CONTEXT                                   c;
+   CallstackEntry                            csEntry;
+-  IMAGEHLP_SYMBOL64*                        pSym = NULL;
++
++  tSymbolInfo* pSym = NULL;
+   StackWalkerInternal::IMAGEHLP_MODULE64_V3 Module;
+-  IMAGEHLP_LINE64                           Line;
++  tImageHelperLine                           Line;
+   int                                       frameNum;
+   bool                                      bLastEntryCalled = true;
+   int                                       curRecursionCount = 0;
+@@ -1125,12 +1029,12 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+ #error "Platform not supported!"
+ #endif
+ 
+-  pSym = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
++  pSym = (tSymbolInfo*)malloc(sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
+   if (!pSym)
+     goto cleanup; // not enough memory...
+-  memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
+-  pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+-  pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
++  memset(pSym, 0, sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
++  pSym->SizeOfStruct = sizeof(tSymbolInfo);
++  pSym->MaxNameLen = STACKWALK_MAX_NAMELEN;
+ 
+   memset(&Line, 0, sizeof(Line));
+   Line.SizeOfStruct = sizeof(Line);
+@@ -1145,11 +1049,11 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+     // assume that either you are done, or that the stack is so hosed that the next
+     // deeper frame could not be found.
+     // CONTEXT need not to be supplied if imageTyp is IMAGE_FILE_MACHINE_I386!
+-    if (!this->m_sw->pSW(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem,
+-                         this->m_sw->pSFTA, this->m_sw->pSGMB, NULL))
++    if (!this->m_sw->stackWalk64(imageType, this->m_hProcess, hThread, &s, &c, myReadProcMem,
++                         this->m_sw->symFunctionTableAccess64, this->m_sw->symGetModuleBase64, NULL))
+     {
+       // INFO: "StackWalk64" does not set "GetLastError"...
+-      this->OnDbgHelpErr("StackWalk64", 0, s.AddrPC.Offset);
++      this->OnDbgHelpErr(_T("StackWalk64"), 0, s.AddrPC.Offset);
+       break;
+     }
+ 
+@@ -1167,7 +1071,7 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+     {
+       if ((this->m_MaxRecursionCount > 0) && (curRecursionCount > m_MaxRecursionCount))
+       {
+-        this->OnDbgHelpErr("StackWalk64-Endless-Callstack!", 0, s.AddrPC.Offset);
++        this->OnDbgHelpErr(_T("StackWalk64-Endless-Callstack!"), 0, s.AddrPC.Offset);
+         break;
+       }
+       curRecursionCount++;
+@@ -1178,23 +1082,23 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+     {
+       // we seem to have a valid PC
+       // show procedure info (SymGetSymFromAddr64())
+-      if (this->m_sw->pSGSFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol),
++      if (this->m_sw->symFromAddr(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromSmybol),
+                              pSym) != FALSE)
+       {
+         MyStrCpy(csEntry.name, STACKWALK_MAX_NAMELEN, pSym->Name);
+         // UnDecorateSymbolName()
+-        this->m_sw->pUDSN(pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY);
+-        this->m_sw->pUDSN(pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE);
++        DWORD res = this->m_sw->unDecorateSymbolName(pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY);
++        res = this->m_sw->unDecorateSymbolName(pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE);
+       }
+       else
+       {
+-        this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), s.AddrPC.Offset);
++        this->OnDbgHelpErr(_T("SymGetSymFromAddr64"), GetLastError(), s.AddrPC.Offset);
+       }
+ 
+       // show line number info, NT5.0-method (SymGetLineFromAddr64())
+-      if (this->m_sw->pSGLFA != NULL)
++      if (this->m_sw->symGetLineFromAddr64 != NULL)
+       { // yes, we have SymGetLineFromAddr64()
+-        if (this->m_sw->pSGLFA(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine),
++        if (this->m_sw->symGetLineFromAddr64(this->m_hProcess, s.AddrPC.Offset, &(csEntry.offsetFromLine),
+                                &Line) != FALSE)
+         {
+           csEntry.lineNumber = Line.LineNumber;
+@@ -1202,7 +1106,7 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+         }
+         else
+         {
+-          this->OnDbgHelpErr("SymGetLineFromAddr64", GetLastError(), s.AddrPC.Offset);
++          this->OnDbgHelpErr(_T("SymGetLineFromAddr64"), GetLastError(), s.AddrPC.Offset);
+         }
+       } // yes, we have SymGetLineFromAddr64()
+ 
+@@ -1252,7 +1156,7 @@ BOOL StackWalker::ShowCallstack(HANDLE                    hThread,
+       } // got module info OK
+       else
+       {
+-        this->OnDbgHelpErr("SymGetModuleInfo64", GetLastError(), s.AddrPC.Offset);
++        this->OnDbgHelpErr(_T("SymGetModuleInfo64"), GetLastError(), s.AddrPC.Offset);
+       }
+     } // we seem to have a valid PC
+ 
+@@ -1298,20 +1202,20 @@ BOOL StackWalker::ShowObject(LPVOID pObject)
+   }
+ 
+   // SymGetSymFromAddr64() is required
+-  if (this->m_sw->pSGSFA == NULL)
++  if (this->m_sw->symFromAddr == NULL)
+     return FALSE;
+ 
+   // Show object info (SymGetSymFromAddr64())
+   DWORD64            dwAddress = DWORD64(pObject);
+   DWORD64            dwDisplacement = 0;
+-  IMAGEHLP_SYMBOL64* pSym =
+-      (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
+-  memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN);
+-  pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+-  pSym->MaxNameLength = STACKWALK_MAX_NAMELEN;
+-  if (this->m_sw->pSGSFA(this->m_hProcess, dwAddress, &dwDisplacement, pSym) == FALSE)
++  tSymbolInfo* pSym =
++      (tSymbolInfo*)malloc(sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
++  memset(pSym, 0, sizeof(tSymbolInfo) + STACKWALK_MAX_NAMELEN*sizeof(TCHAR));
++  pSym->SizeOfStruct = sizeof(tSymbolInfo);
++  pSym->MaxNameLen = STACKWALK_MAX_NAMELEN;
++  if (this->m_sw->symFromAddr(this->m_hProcess, dwAddress, &dwDisplacement, pSym) == FALSE)
+   {
+-    this->OnDbgHelpErr("SymGetSymFromAddr64", GetLastError(), dwAddress);
++    this->OnDbgHelpErr(_T("SymGetSymFromAddr64"), GetLastError(), dwAddress);
+     return FALSE;
+   }
+   // Object name output
+@@ -1342,22 +1246,22 @@ BOOL __stdcall StackWalker::myReadProcMem(HANDLE  hProcess,
+   }
+ }
+ 
+-void StackWalker::OnLoadModule(LPCSTR    img,
+-                               LPCSTR    mod,
++void StackWalker::OnLoadModule(LPCTSTR    img,
++                               LPCTSTR    mod,
+                                DWORD64   baseAddr,
+                                DWORD     size,
+                                DWORD     result,
+-                               LPCSTR    symType,
+-                               LPCSTR    pdbName,
++                               LPCTSTR    symType,
++                               LPCTSTR    pdbName,
+                                ULONGLONG fileVersion)
+ {
+-  CHAR   buffer[STACKWALK_MAX_NAMELEN];
++  TCHAR   buffer[STACKWALK_MAX_NAMELEN];
+   size_t maxLen = STACKWALK_MAX_NAMELEN;
+ #if _MSC_VER >= 1400
+   maxLen = _TRUNCATE;
+ #endif
+   if (fileVersion == 0)
+-    _snprintf_s(buffer, maxLen, "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n",
++    _sntprintf_s(buffer, maxLen, _T("%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s'\n"),
+                 img, mod, (LPVOID)baseAddr, size, result, symType, pdbName);
+   else
+   {
+@@ -1365,9 +1269,9 @@ void StackWalker::OnLoadModule(LPCSTR    img,
+     DWORD v3 = (DWORD)((fileVersion >> 16) & 0xFFFF);
+     DWORD v2 = (DWORD)((fileVersion >> 32) & 0xFFFF);
+     DWORD v1 = (DWORD)((fileVersion >> 48) & 0xFFFF);
+-    _snprintf_s(
++    _sntprintf_s(
+         buffer, maxLen,
+-        "%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n",
++        _T("%s:%s (%p), size: %d (result: %d), SymType: '%s', PDB: '%s', fileVersion: %d.%d.%d.%d\n"),
+         img, mod, (LPVOID)baseAddr, size, result, symType, pdbName, v1, v2, v3, v4);
+   }
+   buffer[STACKWALK_MAX_NAMELEN - 1] = 0; // be sure it is NULL terminated
+@@ -1376,7 +1280,7 @@ void StackWalker::OnLoadModule(LPCSTR    img,
+ 
+ void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry)
+ {
+-  CHAR   buffer[STACKWALK_MAX_NAMELEN];
++  TCHAR   buffer[STACKWALK_MAX_NAMELEN];
+   size_t maxLen = STACKWALK_MAX_NAMELEN;
+ #if _MSC_VER >= 1400
+   maxLen = _TRUNCATE;
+@@ -1384,48 +1288,48 @@ void StackWalker::OnCallstackEntry(CallstackEntryType eType, CallstackEntry& ent
+   if ((eType != lastEntry) && (entry.offset != 0))
+   {
+     if (entry.name[0] == 0)
+-      MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, "(function-name not available)");
++      MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, _T("(function-name not available)"));
+     if (entry.undName[0] != 0)
+       MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undName);
+     if (entry.undFullName[0] != 0)
+       MyStrCpy(entry.name, STACKWALK_MAX_NAMELEN, entry.undFullName);
+     if (entry.lineFileName[0] == 0)
+     {
+-      MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, "(filename not available)");
++      MyStrCpy(entry.lineFileName, STACKWALK_MAX_NAMELEN, _T("(filename not available)"));
+       if (entry.moduleName[0] == 0)
+-        MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, "(module-name not available)");
+-      _snprintf_s(buffer, maxLen, "%p (%s): %s: %s\n", (LPVOID)entry.offset, entry.moduleName,
++        MyStrCpy(entry.moduleName, STACKWALK_MAX_NAMELEN, _T("(module-name not available)"));
++      _sntprintf_s(buffer, maxLen, _T("%p (%s): %s: %s\n"), (LPVOID)entry.offset, entry.moduleName,
+                   entry.lineFileName, entry.name);
+     }
+     else
+-      _snprintf_s(buffer, maxLen, "%s (%d): %s\n", entry.lineFileName, entry.lineNumber,
++      _sntprintf_s(buffer, maxLen, _T("%s (%d): %s\n"), entry.lineFileName, entry.lineNumber,
+                   entry.name);
+     buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
+     OnOutput(buffer);
+   }
+ }
+ 
+-void StackWalker::OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr)
++void StackWalker::OnDbgHelpErr(LPCTSTR szFuncName, DWORD gle, DWORD64 addr)
+ {
+-  CHAR   buffer[STACKWALK_MAX_NAMELEN];
++  TCHAR   buffer[STACKWALK_MAX_NAMELEN];
+   size_t maxLen = STACKWALK_MAX_NAMELEN;
+ #if _MSC_VER >= 1400
+   maxLen = _TRUNCATE;
+ #endif
+-  _snprintf_s(buffer, maxLen, "ERROR: %s, GetLastError: %d (Address: %p)\n", szFuncName, gle,
++  _sntprintf_s(buffer, maxLen, _T("ERROR: %s, GetLastError: %d (Address: %p)\n"), szFuncName, gle,
+               (LPVOID)addr);
+   buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
+   OnOutput(buffer);
+ }
+ 
+-void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName)
++void StackWalker::OnSymInit(LPCTSTR szSearchPath, DWORD symOptions, LPCTSTR szUserName)
+ {
+-  CHAR   buffer[STACKWALK_MAX_NAMELEN];
++  TCHAR   buffer[STACKWALK_MAX_NAMELEN];
+   size_t maxLen = STACKWALK_MAX_NAMELEN;
+ #if _MSC_VER >= 1400
+   maxLen = _TRUNCATE;
+ #endif
+-  _snprintf_s(buffer, maxLen, "SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n",
++  _sntprintf_s(buffer, maxLen, _T("SymInit: Symbol-SearchPath: '%s', symOptions: %d, UserName: '%s'\n"),
+               szSearchPath, symOptions, szUserName);
+   buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
+   OnOutput(buffer);
+@@ -1442,16 +1346,16 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser
+     OnOutput(buffer);
+   }
+ #else
+-  OSVERSIONINFOEXA ver;
+-  ZeroMemory(&ver, sizeof(OSVERSIONINFOEXA));
++  OSVERSIONINFOEX ver;
++  ZeroMemory(&ver, sizeof(OSVERSIONINFOEX));
+   ver.dwOSVersionInfoSize = sizeof(ver);
+ #if _MSC_VER >= 1900
+ #pragma warning(push)
+ #pragma warning(disable : 4996)
+ #endif
+-  if (GetVersionExA((OSVERSIONINFOA*)&ver) != FALSE)
++  if (GetVersionEx((OSVERSIONINFO*)&ver) != FALSE)
+   {
+-    _snprintf_s(buffer, maxLen, "OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n", ver.dwMajorVersion,
++    _sntprintf_s(buffer, maxLen, _T("OS-Version: %d.%d.%d (%s) 0x%x-0x%x\n"), ver.dwMajorVersion,
+                 ver.dwMinorVersion, ver.dwBuildNumber, ver.szCSDVersion, ver.wSuiteMask,
+                 ver.wProductType);
+     buffer[STACKWALK_MAX_NAMELEN - 1] = 0;
+@@ -1463,7 +1367,7 @@ void StackWalker::OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUser
+ #endif
+ }
+ 
+-void StackWalker::OnOutput(LPCSTR buffer)
++void StackWalker::OnOutput(LPCTSTR buffer)
+ {
+-  OutputDebugStringA(buffer);
++  OutputDebugString(buffer);
+ }
+diff --git a/Main/StackWalker/StackWalker.h b/Main/StackWalker/StackWalker.h
+index 0a004d9..03efcec 100644
+--- a/Main/StackWalker/StackWalker.h
++++ b/Main/StackWalker/StackWalker.h
+@@ -47,16 +47,6 @@
+ #pragma warning(disable : 4091)
+ #endif
+ 
+-// special defines for VC5/6 (if no actual PSDK is installed):
+-#if _MSC_VER < 1300
+-typedef unsigned __int64 DWORD64, *PDWORD64;
+-#if defined(_WIN64)
+-typedef unsigned __int64 SIZE_T, *PSIZE_T;
+-#else
+-typedef unsigned long SIZE_T, *PSIZE_T;
+-#endif
+-#endif // _MSC_VER < 1300
+-
+ class StackWalkerInternal; // forward
+ class StackWalker
+ {
+@@ -96,7 +86,7 @@ public:
+   } StackWalkOptions;
+ 
+   StackWalker(int    options = OptionsAll, // 'int' is by design, to combine the enum-flags
+-              LPCSTR szSymPath = NULL,
++              LPCTSTR szSymPath = NULL,
+               DWORD  dwProcessId = GetCurrentProcessId(),
+               HANDLE hProcess = GetCurrentProcess());
+   StackWalker(DWORD dwProcessId, HANDLE hProcess);
+@@ -137,18 +127,18 @@ protected:
+   typedef struct CallstackEntry
+   {
+     DWORD64 offset; // if 0, we have no valid entry
+-    CHAR    name[STACKWALK_MAX_NAMELEN];
+-    CHAR    undName[STACKWALK_MAX_NAMELEN];
+-    CHAR    undFullName[STACKWALK_MAX_NAMELEN];
++    TCHAR    name[STACKWALK_MAX_NAMELEN];
++    TCHAR    undName[STACKWALK_MAX_NAMELEN];
++    TCHAR    undFullName[STACKWALK_MAX_NAMELEN];
+     DWORD64 offsetFromSmybol;
+     DWORD   offsetFromLine;
+     DWORD   lineNumber;
+-    CHAR    lineFileName[STACKWALK_MAX_NAMELEN];
++    TCHAR    lineFileName[STACKWALK_MAX_NAMELEN];
+     DWORD   symType;
+     LPCSTR  symTypeString;
+-    CHAR    moduleName[STACKWALK_MAX_NAMELEN];
++    TCHAR    moduleName[STACKWALK_MAX_NAMELEN];
+     DWORD64 baseOfImage;
+-    CHAR    loadedImageName[STACKWALK_MAX_NAMELEN];
++    TCHAR    loadedImageName[STACKWALK_MAX_NAMELEN];
+   } CallstackEntry;
+ 
+   typedef enum CallstackEntryType
+@@ -158,24 +148,24 @@ protected:
+     lastEntry
+   } CallstackEntryType;
+ 
+-  virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
+-  virtual void OnLoadModule(LPCSTR    img,
+-                            LPCSTR    mod,
++  virtual void OnSymInit(LPCTSTR szSearchPath, DWORD symOptions, LPCTSTR szUserName);
++  virtual void OnLoadModule(LPCTSTR    img,
++                            LPCTSTR    mod,
+                             DWORD64   baseAddr,
+                             DWORD     size,
+                             DWORD     result,
+-                            LPCSTR    symType,
+-                            LPCSTR    pdbName,
++                            LPCTSTR    symType,
++                            LPCTSTR    pdbName,
+                             ULONGLONG fileVersion);
+   virtual void OnCallstackEntry(CallstackEntryType eType, CallstackEntry& entry);
+-  virtual void OnDbgHelpErr(LPCSTR szFuncName, DWORD gle, DWORD64 addr);
+-  virtual void OnOutput(LPCSTR szText);
++  virtual void OnDbgHelpErr(LPCTSTR szFuncName, DWORD gle, DWORD64 addr);
++  virtual void OnOutput(LPCTSTR szText);
+ 
+   StackWalkerInternal* m_sw;
+   HANDLE               m_hProcess;
+   DWORD                m_dwProcessId;
+   BOOL                 m_modulesLoaded;
+-  LPSTR                m_szSymPath;
++  LPTSTR               m_szSymPath;
+ 
+   int m_options;
+   int m_MaxRecursionCount;
+diff --git a/Main/StackWalker/StackWalker_VC2017.sln b/Main/StackWalker/StackWalker_VC2017.sln
+index 790d550..2209e23 100644
+--- a/Main/StackWalker/StackWalker_VC2017.sln
++++ b/Main/StackWalker/StackWalker_VC2017.sln
+@@ -16,18 +16,18 @@ Global
+ 		Release_VC2017-UNICODE|x64 = Release_VC2017-UNICODE|x64
+ 	EndGlobalSection
+ 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.ActiveCfg = Debug_VC2017-UNICODE|Win32
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.Build.0 = Debug_VC2017-UNICODE|Win32
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.ActiveCfg = Debug_VC2017-UNICODE|x64
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.Build.0 = Debug_VC2017-UNICODE|x64
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.ActiveCfg = Debug_VC2017|Win32
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|Win32.Build.0 = Debug_VC2017|Win32
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.ActiveCfg = Debug_VC2017|x64
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017|x64.Build.0 = Debug_VC2017|x64
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|Win32.ActiveCfg = Debug_VC2017-UNICODE|Win32
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|Win32.Build.0 = Debug_VC2017-UNICODE|Win32
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|x64.ActiveCfg = Debug_VC2017-UNICODE|x64
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Debug_VC2017-UNICODE|x64.Build.0 = Debug_VC2017-UNICODE|x64
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.ActiveCfg = Release_VC2017-UNICODE|Win32
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.Build.0 = Release_VC2017-UNICODE|Win32
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.ActiveCfg = Release_VC2017-UNICODE|x64
+-		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.Build.0 = Release_VC2017-UNICODE|x64
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.ActiveCfg = Release_VC2017|Win32
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|Win32.Build.0 = Release_VC2017|Win32
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.ActiveCfg = Release_VC2017|x64
++		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017|x64.Build.0 = Release_VC2017|x64
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017-UNICODE|Win32.ActiveCfg = Release_VC2017-UNICODE|Win32
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017-UNICODE|Win32.Build.0 = Release_VC2017-UNICODE|Win32
+ 		{89B2BD42-B130-4811-9043-71A8EBC40DE5}.Release_VC2017-UNICODE|x64.ActiveCfg = Release_VC2017-UNICODE|x64
+diff --git a/Main/StackWalker/main.cpp b/Main/StackWalker/main.cpp
+index 220c97b..496021e 100644
+--- a/Main/StackWalker/main.cpp
++++ b/Main/StackWalker/main.cpp
+@@ -33,7 +33,7 @@ void (*pGlobalFuncPtr)() = 0;
+ class StackWalkerToConsole : public StackWalker
+ {
+ protected:
+-  virtual void OnOutput(LPCSTR szText) { printf("%s", szText); }
++  virtual void OnOutput(LPCTSTR szText) { _tprintf(_T("%s"), szText); }
+ };
+ 
+ void Func5()
diff --git a/upstream_utils/stack_walker_patches/0002-Remove-_M_IX86-checks.patch b/upstream_utils/stack_walker_patches/0002-Remove-_M_IX86-checks.patch
new file mode 100644
index 0000000..14d7bae
--- /dev/null
+++ b/upstream_utils/stack_walker_patches/0002-Remove-_M_IX86-checks.patch
@@ -0,0 +1,79 @@
+From 238eda525de70b57bade634447c967f4f92bc96d Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Mon, 23 May 2022 00:06:45 -0400
+Subject: [PATCH 2/3] Remove _M_IX86 checks
+
+---
+ Main/StackWalker/StackWalker.h | 52 ----------------------------------
+ 1 file changed, 52 deletions(-)
+
+diff --git a/Main/StackWalker/StackWalker.h b/Main/StackWalker/StackWalker.h
+index 03efcec..89be951 100644
+--- a/Main/StackWalker/StackWalker.h
++++ b/Main/StackWalker/StackWalker.h
+@@ -179,57 +179,6 @@ protected:
+   friend StackWalkerInternal;
+ }; // class StackWalker
+ 
+-// The "ugly" assembler-implementation is needed for systems before XP
+-// If you have a new PSDK and you only compile for XP and later, then you can use
+-// the "RtlCaptureContext"
+-// Currently there is no define which determines the PSDK-Version...
+-// So we just use the compiler-version (and assumes that the PSDK is
+-// the one which was installed by the VS-IDE)
+-
+-// INFO: If you want, you can use the RtlCaptureContext if you only target XP and later...
+-//       But I currently use it in x64/IA64 environments...
+-//#if defined(_M_IX86) && (_WIN32_WINNT <= 0x0500) && (_MSC_VER < 1400)
+-
+-#if defined(_M_IX86)
+-#ifdef CURRENT_THREAD_VIA_EXCEPTION
+-// TODO: The following is not a "good" implementation,
+-// because the callstack is only valid in the "__except" block...
+-#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags)               \
+-  do                                                                            \
+-  {                                                                             \
+-    memset(&c, 0, sizeof(CONTEXT));                                             \
+-    EXCEPTION_POINTERS* pExp = NULL;                                            \
+-    __try                                                                       \
+-    {                                                                           \
+-      throw 0;                                                                  \
+-    }                                                                           \
+-    __except (((pExp = GetExceptionInformation()) ? EXCEPTION_EXECUTE_HANDLER   \
+-                                                  : EXCEPTION_EXECUTE_HANDLER)) \
+-    {                                                                           \
+-    }                                                                           \
+-    if (pExp != NULL)                                                           \
+-      memcpy(&c, pExp->ContextRecord, sizeof(CONTEXT));                         \
+-    c.ContextFlags = contextFlags;                                              \
+-  } while (0);
+-#else
+-// clang-format off
+-// The following should be enough for walking the callstack...
+-#define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
+-  do                                                              \
+-  {                                                               \
+-    memset(&c, 0, sizeof(CONTEXT));                               \
+-    c.ContextFlags = contextFlags;                                \
+-    __asm    call x                                               \
+-    __asm x: pop eax                                              \
+-    __asm    mov c.Eip, eax                                       \
+-    __asm    mov c.Ebp, ebp                                       \
+-    __asm    mov c.Esp, esp                                       \
+-  } while (0)
+-// clang-format on
+-#endif
+-
+-#else
+-
+ // The following is defined for x86 (XP and higher), x64 and IA64:
+ #define GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, contextFlags) \
+   do                                                              \
+@@ -238,7 +187,6 @@ protected:
+     c.ContextFlags = contextFlags;                                \
+     RtlCaptureContext(&c);                                        \
+   } while (0);
+-#endif
+ 
+ #endif //defined(_MSC_VER)
+ 
diff --git a/upstream_utils/stack_walker_patches/0003-Add-advapi-pragma.patch b/upstream_utils/stack_walker_patches/0003-Add-advapi-pragma.patch
new file mode 100644
index 0000000..f48ee4e
--- /dev/null
+++ b/upstream_utils/stack_walker_patches/0003-Add-advapi-pragma.patch
@@ -0,0 +1,21 @@
+From 61646f76602a77059c18298caa575b95b702c94c Mon Sep 17 00:00:00 2001
+From: PJ Reiniger <pj.reiniger@gmail.com>
+Date: Tue, 24 May 2022 01:24:31 -0400
+Subject: [PATCH 3/3] Add advapi pragma
+
+---
+ Main/StackWalker/StackWalker.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Main/StackWalker/StackWalker.cpp b/Main/StackWalker/StackWalker.cpp
+index 48c7c57..6f0fbf2 100644
+--- a/Main/StackWalker/StackWalker.cpp
++++ b/Main/StackWalker/StackWalker.cpp
+@@ -88,6 +88,7 @@
+ #include <stdlib.h>
+ #include <tchar.h>
+ #pragma comment(lib, "version.lib") // for "VerQueryValue"
++#pragma comment(lib, "Advapi32.lib") // for "GetUserName"
+ #pragma warning(disable : 4826)
+ 
+ #ifdef UNICODE
diff --git a/upstream_utils/update_drake.py b/upstream_utils/update_drake.py
index 069d3a8..1849494 100755
--- a/upstream_utils/update_drake.py
+++ b/upstream_utils/update_drake.py
@@ -3,68 +3,97 @@
 import os
 import shutil
 
-from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if, apply_patches
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
 
 
 def main():
-    root, repo = setup_upstream_repo("https://github.com/RobotLocomotion/drake",
-                                     "v0.37.0")
-    wpimath = os.path.join(root, "wpimath")
+    upstream_root = clone_repo("https://github.com/RobotLocomotion/drake", "v1.6.0")
+    wpilib_root = get_repo_root()
+    wpimath = os.path.join(wpilib_root, "wpimath")
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in [
+        "0001-Replace-Eigen-Dense-with-Eigen-Core.patch",
+        "0002-Add-WPILIB_DLLEXPORT-to-DARE-function-declarations.patch",
+    ]:
+        git_am(os.path.join(wpilib_root, "upstream_utils/drake_patches", f))
 
     # Delete old install
     for d in [
-            "src/main/native/cpp/drake", "src/main/native/include/drake",
-            "src/test/native/cpp/drake", "src/test/native/include/drake"
+        "src/main/native/thirdparty/drake/src",
+        "src/main/native/thirdparty/drake/include",
+        "src/test/native/cpp/drake",
+        "src/test/native/include/drake",
     ]:
         shutil.rmtree(os.path.join(wpimath, d), ignore_errors=True)
 
     # Copy drake source files into allwpilib
     src_files = walk_cwd_and_copy_if(
-        lambda dp, f: f in
-        ["drake_assert_and_throw.cc", "discrete_algebraic_riccati_equation.cc"],
-        os.path.join(wpimath, "src/main/native/cpp/drake"))
+        lambda dp, f: f
+        in ["drake_assert_and_throw.cc", "discrete_algebraic_riccati_equation.cc"],
+        os.path.join(wpimath, "src/main/native/thirdparty/drake/src"),
+    )
 
     # Copy drake header files into allwpilib
     include_files = walk_cwd_and_copy_if(
-        lambda dp, f: f in [
-            "drake_assert.h", "drake_assertion_error.h",
-            "is_approx_equal_abstol.h", "never_destroyed.h", "drake_copyable.h",
-            "drake_throw.h", "discrete_algebraic_riccati_equation.h"
-        ], os.path.join(wpimath, "src/main/native/include/drake"))
+        lambda dp, f: f
+        in [
+            "drake_assert.h",
+            "drake_assertion_error.h",
+            "is_approx_equal_abstol.h",
+            "never_destroyed.h",
+            "drake_copyable.h",
+            "drake_throw.h",
+            "discrete_algebraic_riccati_equation.h",
+        ],
+        os.path.join(wpimath, "src/main/native/thirdparty/drake/include/drake"),
+    )
 
     # Copy drake test source files into allwpilib
-    os.chdir(os.path.join(repo, "math/test"))
+    os.chdir(os.path.join(upstream_root, "math/test"))
     test_src_files = walk_cwd_and_copy_if(
         lambda dp, f: f == "discrete_algebraic_riccati_equation_test.cc",
-        os.path.join(wpimath, "src/test/native/cpp/drake"))
-    os.chdir(repo)
+        os.path.join(wpimath, "src/test/native/cpp/drake"),
+    )
+    os.chdir(upstream_root)
 
     # Copy drake test header files into allwpilib
     test_include_files = walk_cwd_and_copy_if(
         lambda dp, f: f == "eigen_matrix_compare.h",
-        os.path.join(wpimath, "src/test/native/include/drake"))
+        os.path.join(wpimath, "src/test/native/include/drake"),
+    )
 
     for f in src_files:
         comment_out_invalid_includes(
-            f, [os.path.join(wpimath, "src/main/native/include")])
+            f, [os.path.join(wpimath, "src/main/native/thirdparty/drake/include")]
+        )
     for f in include_files:
         comment_out_invalid_includes(
-            f, [os.path.join(wpimath, "src/main/native/include")])
+            f, [os.path.join(wpimath, "src/main/native/thirdparty/drake/include")]
+        )
     for f in test_src_files:
-        comment_out_invalid_includes(f, [
-            os.path.join(wpimath, "src/main/native/include"),
-            os.path.join(wpimath, "src/test/native/include")
-        ])
+        comment_out_invalid_includes(
+            f,
+            [
+                os.path.join(wpimath, "src/main/native/thirdparty/drake/include"),
+                os.path.join(wpimath, "src/test/native/include"),
+            ],
+        )
     for f in test_include_files:
-        comment_out_invalid_includes(f, [
-            os.path.join(wpimath, "src/main/native/include"),
-            os.path.join(wpimath, "src/test/native/include")
-        ])
-
-    apply_patches(root, [
-        "upstream_utils/drake-replace-dense-with-core.patch",
-        "upstream_utils/drake-dllexport-dare.patch"
-    ])
+        comment_out_invalid_includes(
+            f,
+            [
+                os.path.join(wpimath, "src/main/native/thirdparty/drake/include"),
+                os.path.join(wpimath, "src/test/native/include"),
+            ],
+        )
 
 
 if __name__ == "__main__":
diff --git a/upstream_utils/update_eigen.py b/upstream_utils/update_eigen.py
index 0df72a8..e04689a 100755
--- a/upstream_utils/update_eigen.py
+++ b/upstream_utils/update_eigen.py
@@ -4,7 +4,13 @@
 import re
 import shutil
 
-from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if, apply_patches
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
 
 
 def eigen_inclusions(dp, f):
@@ -38,8 +44,12 @@
 
     # Include architectures we care about
     if "Core/arch/" in abspath:
-        return ("arch/AVX/" in abspath or "arch/Default" in abspath or
-                "arch/NEON" in abspath or "arch/SSE" in abspath)
+        return (
+            "arch/AVX/" in abspath
+            or "arch/Default" in abspath
+            or "arch/NEON" in abspath
+            or "arch/SSE" in abspath
+        )
 
     # Include the following modules
     modules = [
@@ -47,22 +57,24 @@
         "Core",
         "Eigenvalues",
         "Householder",
+        "IterativeLinearSolvers",
         "Jacobi",
         "LU",
+        "OrderingMethods",
         "QR",
         "SVD",
+        "SparseCholesky",
+        "SparseCore",
+        "SparseLU",
+        "SparseQR",
         "StlSupport",
         "misc",
         "plugins",
     ]
     modules_rgx = r"|".join("/" + m for m in modules)
 
-    # "Std" matches StdDeque, StdList, and StdVector headers
-    if re.search(modules_rgx, abspath) or "Std" in f:
-        return True
-    else:
-        # Exclude all other modules
-        return False
+    # "Std" matches StdDeque, StdList, and StdVector headers. Other modules are excluded.
+    return bool(re.search(modules_rgx, abspath) or "Std" in f)
 
 
 def unsupported_inclusions(dp, f):
@@ -82,39 +94,47 @@
     if f == "CMakeLists.txt" or "README" in f:
         return False
 
-    # Include the AutoDiff and MatrixFunctions modules
-    return "AutoDiff" in abspath or "MatrixFunctions" in abspath
+    # Include the MatrixFunctions module
+    return "MatrixFunctions" in abspath
 
 
 def main():
-    root, repo = setup_upstream_repo("https://gitlab.com/libeigen/eigen.git",
-                                     "3.4.0")
-    wpimath = os.path.join(root, "wpimath")
+    upstream_root = clone_repo("https://gitlab.com/libeigen/eigen.git", "3.4.0")
+    wpilib_root = get_repo_root()
+    wpimath = os.path.join(wpilib_root, "wpimath")
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in ["0001-Disable-warnings.patch"]:
+        git_am(os.path.join(wpilib_root, "upstream_utils/eigen_patches", f))
 
     # Delete old install
     for d in [
-            "src/main/native/eigeninclude/Eigen",
-            "src/main/native/eigeninclude/unsupported"
+        "src/main/native/thirdparty/eigen/include/Eigen",
+        "src/main/native/thirdparty/eigen/include/unsupported",
     ]:
         shutil.rmtree(os.path.join(wpimath, d), ignore_errors=True)
 
     # Copy Eigen headers into allwpilib
     eigen_files = walk_cwd_and_copy_if(
-        eigen_inclusions, os.path.join(wpimath, "src/main/native/eigeninclude"))
+        eigen_inclusions,
+        os.path.join(wpimath, "src/main/native/thirdparty/eigen/include"),
+    )
 
     # Copy unsupported headers into allwpilib
     unsupported_files = walk_cwd_and_copy_if(
         unsupported_inclusions,
-        os.path.join(wpimath, "src/main/native/eigeninclude"))
+        os.path.join(wpimath, "src/main/native/thirdparty/eigen/include"),
+    )
 
     for f in eigen_files:
         comment_out_invalid_includes(
-            f, [os.path.join(wpimath, "src/main/native/eigeninclude")])
+            f, [os.path.join(wpimath, "src/main/native/thirdparty/eigen/include")]
+        )
     for f in unsupported_files:
         comment_out_invalid_includes(
-            f, [os.path.join(wpimath, "src/main/native/eigeninclude")])
-
-    apply_patches(root, ["upstream_utils/eigen-maybe-uninitialized.patch"])
+            f, [os.path.join(wpimath, "src/main/native/thirdparty/eigen/include")]
+        )
 
 
 if __name__ == "__main__":
diff --git a/upstream_utils/update_fmt.py b/upstream_utils/update_fmt.py
index f752b3d..1088c39 100755
--- a/upstream_utils/update_fmt.py
+++ b/upstream_utils/update_fmt.py
@@ -3,36 +3,55 @@
 import os
 import shutil
 
-from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if, apply_patches
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
 
 
 def main():
-    root, repo = setup_upstream_repo("https://github.com/fmtlib/fmt", "8.1.1")
-    wpiutil = os.path.join(root, "wpiutil")
+    upstream_root = clone_repo("https://github.com/fmtlib/fmt", "9.1.0")
+    wpilib_root = get_repo_root()
+    wpiutil = os.path.join(wpilib_root, "wpiutil")
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in [
+        "0001-Don-t-throw-on-write-failure.patch",
+        "0002-Suppress-C-20-clang-tidy-warning-false-positive.patch",
+    ]:
+        git_am(os.path.join(wpilib_root, "upstream_utils/fmt_patches", f))
 
     # Delete old install
-    for d in ["src/main/native/fmtlib/src", "src/main/native/fmtlib/include"]:
+    for d in [
+        "src/main/native/thirdparty/fmtlib/src",
+        "src/main/native/thirdparty/fmtlib/include",
+    ]:
         shutil.rmtree(os.path.join(wpiutil, d), ignore_errors=True)
 
     # Copy fmt source files into allwpilib
     src_files = walk_cwd_and_copy_if(
-        lambda dp, f: dp.endswith("src") and f.endswith(".cc") and f !=
-        "fmt.cc", os.path.join(wpiutil, "src/main/native/fmtlib"))
+        lambda dp, f: dp.endswith("src") and f.endswith(".cc") and f != "fmt.cc",
+        os.path.join(wpiutil, "src/main/native/thirdparty/fmtlib"),
+    )
 
     # Copy fmt header files into allwpilib
     include_files = walk_cwd_and_copy_if(
         lambda dp, f: dp.endswith("include/fmt"),
-        os.path.join(wpiutil, "src/main/native/fmtlib"))
+        os.path.join(wpiutil, "src/main/native/thirdparty/fmtlib"),
+    )
 
     for f in src_files:
         comment_out_invalid_includes(
-            f, [os.path.join(wpiutil, "src/main/native/fmtlib/include")])
+            f, [os.path.join(wpiutil, "src/main/native/thirdparty/fmtlib/include")]
+        )
     for f in include_files:
         comment_out_invalid_includes(
-            f, [os.path.join(wpiutil, "src/main/native/fmtlib/include")])
-
-    apply_patches(root,
-                  ["upstream_utils/fmt-dont-throw-on-write-failure.patch"])
+            f, [os.path.join(wpiutil, "src/main/native/thirdparty/fmtlib/include")]
+        )
 
 
 if __name__ == "__main__":
diff --git a/upstream_utils/update_gcem.py b/upstream_utils/update_gcem.py
new file mode 100644
index 0000000..ad1cb5a
--- /dev/null
+++ b/upstream_utils/update_gcem.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
+
+
+def main():
+    upstream_root = clone_repo("https://github.com/kthohr/gcem.git", "v1.16.0")
+    wpilib_root = get_repo_root()
+    wpimath = os.path.join(wpilib_root, "wpimath")
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in []:
+        git_am(os.path.join(wpilib_root, "upstream_utils/gcem_patches", f))
+
+    # Delete old install
+    for d in [
+        "src/main/native/thirdparty/gcem/include",
+    ]:
+        shutil.rmtree(os.path.join(wpimath, d), ignore_errors=True)
+
+    # Copy gcem include files into allwpilib
+    include_files = walk_cwd_and_copy_if(
+        lambda dp, f: dp.endswith("include")
+        or dp.endswith("gcem_incl")
+        or dp.endswith("quadrature"),
+        os.path.join(wpimath, "src/main/native/thirdparty/gcem"),
+    )
+
+    for f in include_files:
+        comment_out_invalid_includes(
+            f, [os.path.join(wpimath, "src/main/native/thirdparty/gcem/include")]
+        )
+
+
+if __name__ == "__main__":
+    main()
diff --git a/upstream_utils/update_libuv.py b/upstream_utils/update_libuv.py
new file mode 100755
index 0000000..a90a6d7
--- /dev/null
+++ b/upstream_utils/update_libuv.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
+
+
+def main():
+    upstream_root = clone_repo("https://github.com/libuv/libuv", "v1.44.2")
+    wpilib_root = get_repo_root()
+    wpinet = os.path.join(wpilib_root, "wpinet")
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in [
+        "0001-Fix-missing-casts.patch",
+        "0002-Fix-warnings.patch",
+        "0003-Preprocessor-cleanup.patch",
+        "0004-Cleanup-problematic-language.patch",
+        "0005-Use-roborio-time.patch",
+        "0006-Style-comments-cleanup.patch",
+        "0007-Squelch-GCC-12.1-warnings.patch",
+        "0008-Fix-Win32-warning-suppression-pragma.patch",
+        "0009-Avoid-unused-variable-warning-on-Mac.patch",
+    ]:
+        git_am(os.path.join(wpilib_root, "upstream_utils/libuv_patches", f))
+
+    # Delete old install
+    for d in ["src/main/native/thirdparty/libuv"]:
+        shutil.rmtree(os.path.join(wpinet, d), ignore_errors=True)
+
+    include_ignorelist = [
+        "aix.h",
+        "os390.h",
+        "stdint-msvc2008.h",
+        "sunos.h",
+    ]
+
+    include_files = walk_cwd_and_copy_if(
+        lambda dp, f: "include" in dp and f not in include_ignorelist,
+        os.path.join(wpinet, "src/main/native/thirdparty/libuv"),
+    )
+
+    src_ignorelist = [
+        "aix-common.c",
+        "aix.c",
+        "bsd-proctitle.c",
+        "darwin-stub.c",
+        "haiku.c",
+        "hurd.c",
+        "os390-proctitle.c",
+        "os390-syscalls.c",
+        "os390-syscalls.h",
+        "os390.c",
+        "qnx.c",
+        "sunos.c",
+        "sysinfo-loadavg.c",
+        "sysinfo-memory.c",
+    ]
+    src_files = walk_cwd_and_copy_if(
+        lambda dp, f: "src" in dp and "docs" not in dp and f not in src_ignorelist,
+        os.path.join(wpinet, "src/main/native/thirdparty/libuv"),
+    )
+
+
+if __name__ == "__main__":
+    main()
diff --git a/upstream_utils/update_llvm.py b/upstream_utils/update_llvm.py
new file mode 100755
index 0000000..c2ebd12
--- /dev/null
+++ b/upstream_utils/update_llvm.py
@@ -0,0 +1,214 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
+
+
+def run_global_replacements(wpiutil_llvm_files):
+
+    for wpi_file in wpiutil_llvm_files:
+        with open(wpi_file) as f:
+            content = f.read()
+
+        # Rename namespace from llvm to wpi
+        content = content.replace("namespace llvm", "namespace wpi")
+        content = content.replace("llvm::", "wpi::")
+
+        # Fix #includes
+        content = content.replace('include "llvm/ADT', 'include "wpi')
+        content = content.replace('include "llvm/Config', 'include "wpi')
+        content = content.replace('include "llvm/Support', 'include "wpi')
+
+        # Fix uses of span
+        content = content.replace("span", "std::span")
+        content = content.replace('include "wpi/std::span.h"', "include <span>")
+        if wpi_file.endswith("ConvertUTFWrapper.cpp"):
+            content = content.replace(
+                "const UTF16 *Src = reinterpret_cast<const UTF16 *>(SrcBytes.begin());",
+                "const UTF16 *Src = reinterpret_cast<const UTF16 *>(&*SrcBytes.begin());",
+            )
+            content = content.replace(
+                "const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(SrcBytes.end());",
+                "const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(&*SrcBytes.begin() + SrcBytes.size());",
+            )
+
+        # Remove unused headers
+        content = content.replace('#include "llvm-c/ErrorHandling.h"\n', "")
+        content = content.replace('#include "wpi/Debug.h"\n', "")
+        content = content.replace('#include "wpi/Error.h"\n', "")
+        content = content.replace('#include "wpi/Format.h"\n', "")
+        content = content.replace('#include "wpi/FormatVariadic.h"\n', "")
+        content = content.replace('#include "wpi/NativeFormatting.h"\n', "")
+        content = content.replace('#include "wpi/Threading.h"\n', "")
+        content = content.replace('#include "wpi/DataTypes.h"\n', "")
+        content = content.replace('#include "wpi/llvm-config.h"\n', "")
+        content = content.replace('#include "wpi/abi-breaking.h"\n', "")
+        content = content.replace('#include "wpi/config.h"\n', "")
+        content = content.replace('#include "wpi/Signals.h"\n', "")
+        content = content.replace('#include "wpi/Process.h"\n', "")
+        content = content.replace('#include "wpi/Path.h"\n', "")
+        content = content.replace('#include "wpi/Program.h"\n', "")
+
+        # Fix include guards
+        content = content.replace("LLVM_ADT_", "WPIUTIL_WPI_")
+        content = content.replace("LLVM_SUPPORT_", "WPIUTIL_WPI_")
+        content = content.replace("LLVM_DEFINED_HAS_FEATURE", "WPI_DEFINED_HAS_FEATURE")
+
+        content = content.replace("const std::string_view &", "std::string_view ")
+        content = content.replace("sys::fs::openFileForRead", "fs::OpenFileForRead")
+        content = content.replace("sys::fs::closeFile", "fs::CloseFile")
+        content = content.replace("sys::fs::", "fs::")
+
+        # Replace wpi/FileSystem.h with wpi/fs.h
+        content = content.replace('include "wpi/FileSystem.h"', 'include "wpi/fs.h"')
+
+        # Replace llvm_unreachable() with wpi_unreachable()
+        content = content.replace("llvm_unreachable", "wpi_unreachable")
+
+        content = content.replace("llvm_is_multithreaded()", "1")
+
+        # Revert message in copyright header
+        content = content.replace("/// Defines the wpi::", "/// Defines the llvm::")
+        content = content.replace("// end llvm namespace", "// end wpi namespace")
+        content = content.replace("// end namespace llvm", "// end namespace wpi")
+        content = content.replace("// End llvm namespace", "// End wpi namespace")
+
+        content = content.replace("fs::openFileForRead", "fs::OpenFileForRead")
+
+        with open(wpi_file, "w") as f:
+            f.write(content)
+
+
+def flattened_llvm_files(llvm, dirs_to_keep):
+    file_lookup = {}
+
+    for dir_to_keep in dirs_to_keep:
+        dir_to_crawl = os.path.join(llvm, dir_to_keep)
+        for root, _, files in os.walk(dir_to_crawl):
+            for f in files:
+                file_lookup[f] = os.path.join(root, f)
+
+    return file_lookup
+
+
+def find_wpiutil_llvm_files(wpiutil_root, subfolder):
+
+    # These files have substantial changes, not worth managing with the patching process
+    ignore_list = [
+        "StringExtras.h",
+        "StringExtras.cpp",
+        "MemoryBuffer.cpp",
+        "MemoryBuffer.h",
+        "SmallVectorMemoryBuffer.h",
+    ]
+
+    wpiutil_files = []
+    for root, _, files in os.walk(os.path.join(wpiutil_root, subfolder)):
+        for f in files:
+            if f not in ignore_list:
+                full_file = os.path.join(root, f)
+                wpiutil_files.append(full_file)
+
+    return wpiutil_files
+
+
+def overwrite_files(wpiutil_files, llvm_files):
+    # Very sparse rips from LLVM sources. Not worth tyring to make match upstream
+    unmatched_files_whitelist = ["fs.h", "fs.cpp", "function_ref.h"]
+
+    for wpi_file in wpiutil_files:
+        wpi_base_name = os.path.basename(wpi_file)
+        if wpi_base_name in llvm_files:
+            shutil.copyfile(llvm_files[wpi_base_name], wpi_file)
+
+        elif wpi_base_name not in unmatched_files_whitelist:
+            print(f"No file match for {wpi_file}, check if LLVM deleted it")
+
+
+def overwrite_source(wpiutil_root, llvm_root):
+    llvm_files = flattened_llvm_files(
+        llvm_root,
+        [
+            "llvm/include/llvm/ADT/",
+            "llvm/include/llvm/Config",
+            "llvm/include/llvm/Support/",
+            "llvm/lib/Support/",
+        ],
+    )
+    wpi_files = find_wpiutil_llvm_files(
+        wpiutil_root, "src/main/native/thirdparty/llvm/include/wpi"
+    ) + find_wpiutil_llvm_files(
+        wpiutil_root, "src/main/native/thirdparty/llvm/cpp/llvm"
+    )
+
+    overwrite_files(wpi_files, llvm_files)
+    run_global_replacements(wpi_files)
+
+
+def overwrite_tests(wpiutil_root, llvm_root):
+    llvm_files = flattened_llvm_files(
+        llvm_root,
+        ["llvm/unittests/ADT/", "llvm/unittests/Config", "llvm/unittests/Support/"],
+    )
+    wpi_files = find_wpiutil_llvm_files(wpiutil_root, "src/test/native/cpp/llvm")
+
+    overwrite_files(wpi_files, llvm_files)
+    run_global_replacements(wpi_files)
+
+
+def main():
+    upstream_root = clone_repo("https://github.com/llvm/llvm-project", "llvmorg-14.0.6")
+    wpilib_root = get_repo_root()
+    wpiutil = os.path.join(wpilib_root, "wpiutil")
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in [
+        "0001-Fix-spelling-language-errors.patch",
+        "0002-Remove-StringRef-ArrayRef-and-Optional.patch",
+        "0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch",
+        "0004-Change-unique_function-storage-size.patch",
+        "0005-Threading-updates.patch",
+        "0006-ifdef-guard-safety.patch",
+        "0007-Explicitly-use-std.patch",
+        "0008-Remove-format_provider.patch",
+        "0009-Add-compiler-warning-pragmas.patch",
+        "0010-Remove-unused-functions.patch",
+        "0011-Detemplatize-SmallVectorBase.patch",
+        "0012-Add-vectors-to-raw_ostream.patch",
+        "0013-Extra-collections-features.patch",
+        "0014-EpochTracker-ABI-macro.patch",
+        "0015-Delete-numbers-from-MathExtras.patch",
+        "0016-Add-lerp-and-sgn.patch",
+        "0017-Fixup-includes.patch",
+        "0018-Use-std-is_trivially_copy_constructible.patch",
+        "0019-Windows-support.patch",
+        "0020-Prefer-fmtlib.patch",
+        "0021-Prefer-wpi-s-fs.h.patch",
+        "0022-Remove-unused-functions.patch",
+        "0023-OS-specific-changes.patch",
+        "0024-Use-SmallVector-for-UTF-conversion.patch",
+        "0025-Prefer-to-use-static-pointers-in-raw_ostream.patch",
+        "0026-constexpr-endian-byte-swap.patch",
+        "0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch",
+        "0028-Remove-StringMap-test-for-llvm-sort.patch",
+    ]:
+        git_am(
+            os.path.join(wpilib_root, "upstream_utils/llvm_patches", f),
+            use_threeway=True,
+        )
+
+    overwrite_source(wpiutil, upstream_root)
+    overwrite_tests(wpiutil, upstream_root)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/upstream_utils/update_memory.py b/upstream_utils/update_memory.py
new file mode 100755
index 0000000..e72717a
--- /dev/null
+++ b/upstream_utils/update_memory.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_if,
+    copy_to,
+)
+
+
+def run_source_replacements(memory_files):
+    for wpi_file in memory_files:
+        with open(wpi_file) as f:
+            content = f.read()
+
+        # Fix #includes
+        content = content.replace('include "', 'include "wpi/memory/')
+        content = content.replace(
+            "wpi/memory/free_list_utils.hpp", "free_list_utils.hpp"
+        )
+
+        with open(wpi_file, "w") as f:
+            f.write(content)
+
+
+def run_header_replacements(memory_files):
+    for wpi_file in memory_files:
+        if "detail" not in wpi_file:
+            continue
+        with open(wpi_file) as f:
+            content = f.read()
+
+        # Fix #includes
+        content = content.replace('include "config.hpp', 'include "../config.hpp')
+
+        with open(wpi_file, "w") as f:
+            f.write(content)
+
+
+def run_global_replacements(memory_files):
+    for wpi_file in memory_files:
+        with open(wpi_file) as f:
+            content = f.read()
+
+        # Rename namespace from foonathan to wpi
+        content = content.replace("namespace foonathan", "namespace wpi")
+        content = content.replace("foonathan::", "wpi::")
+        content = content.replace("FOONATHAN_", "WPI_")
+
+        # Fix #includes
+        content = content.replace('include "foonathan', 'include "wpi')
+
+        with open(wpi_file, "w") as f:
+            f.write(content)
+
+
+def main():
+    upstream_root = clone_repo("https://github.com/foonathan/memory", "v0.7-2")
+    wpilib_root = get_repo_root()
+    wpiutil = os.path.join(wpilib_root, "wpiutil")
+
+    # Delete old install
+    for d in [
+        "src/main/native/thirdparty/memory/src",
+        "src/main/native/thirdparty/memory/include",
+    ]:
+        shutil.rmtree(os.path.join(wpiutil, d), ignore_errors=True)
+
+    # Copy sources
+    os.chdir(upstream_root)
+    src_files = walk_if("src", lambda dp, f: f.endswith(".cpp") or f.endswith(".hpp"))
+    src_files = copy_to(
+        src_files, os.path.join(wpiutil, "src/main/native/thirdparty/memory")
+    )
+    run_global_replacements(src_files)
+    run_source_replacements(src_files)
+
+    # Copy headers
+    os.chdir(os.path.join(upstream_root, "include", "foonathan"))
+    include_files = walk_if(".", lambda dp, f: f.endswith(".hpp"))
+    include_files = copy_to(
+        include_files,
+        os.path.join(wpiutil, "src/main/native/thirdparty/memory/include/wpi"),
+    )
+    os.chdir(os.path.join("..", ".."))
+    run_global_replacements(include_files)
+    run_header_replacements(include_files)
+
+    # Copy config_impl.hpp
+    shutil.copyfile(
+        os.path.join(wpilib_root, "upstream_utils/memory_files/config_impl.hpp"),
+        os.path.join(
+            wpiutil,
+            "src/main/native/thirdparty/memory/include/wpi/memory/config_impl.hpp",
+        ),
+    )
+
+
+if __name__ == "__main__":
+    main()
diff --git a/upstream_utils/update_mpack.py b/upstream_utils/update_mpack.py
new file mode 100755
index 0000000..25eabfc
--- /dev/null
+++ b/upstream_utils/update_mpack.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+import subprocess
+
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    walk_cwd_and_copy_if,
+    git_am,
+)
+
+
+def main():
+    upstream_root = clone_repo("https://github.com/ludocode/mpack", "v1.1")
+    wpilib_root = get_repo_root()
+    wpiutil = os.path.join(wpilib_root, "wpiutil")
+
+    # Delete old install
+    for d in [
+        "src/main/native/thirdparty/mpack/src",
+        "src/main/native/thirdparty/mpack/include",
+    ]:
+        shutil.rmtree(os.path.join(wpiutil, d), ignore_errors=True)
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+
+    for f in [
+        "0001-Don-t-emit-inline-defs.patch",
+        "0002-Update-amalgamation-script.patch",
+        "0003-Use-namespace-for-C.patch",
+    ]:
+        git_am(
+            os.path.join(wpilib_root, "upstream_utils/mpack_patches", f),
+        )
+
+    # Run the amalgmation script
+    subprocess.check_call(["bash", "tools/amalgamate.sh"])
+
+    # Copy the files
+    amalgamation_source_dir = os.path.join(
+        ".", ".build", "amalgamation", "src", "mpack"
+    )
+    os.chdir(amalgamation_source_dir)
+
+    walk_cwd_and_copy_if(
+        lambda dp, f: f.endswith(".h"),
+        os.path.join(wpiutil, "src/main/native/thirdparty/mpack/include/wpi"),
+    )
+    walk_cwd_and_copy_if(
+        lambda dp, f: f.endswith(".c"),
+        os.path.join(wpiutil, "src/main/native/thirdparty/mpack/src"),
+    )
+
+
+if __name__ == "__main__":
+    main()
diff --git a/upstream_utils/update_stack_walker.py b/upstream_utils/update_stack_walker.py
new file mode 100755
index 0000000..95173d2
--- /dev/null
+++ b/upstream_utils/update_stack_walker.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+
+import os
+import shutil
+import subprocess
+
+from upstream_utils import (
+    get_repo_root,
+    clone_repo,
+    comment_out_invalid_includes,
+    walk_cwd_and_copy_if,
+    git_am,
+)
+
+
+def crlf_to_lf(stackwalker_dir):
+    for root, _, files in os.walk(stackwalker_dir):
+        if ".git" in root:
+            continue
+
+        for fname in files:
+            filename = os.path.join(root, fname)
+            print(f"Converting CRLF -> LF for {filename}")
+            with open(filename, "rb") as f:
+                content = f.read()
+                content = content.replace(b"\r\n", b"\n")
+
+                with open(filename, "wb") as f:
+                    f.write(content)
+
+    cwd = os.getcwd()
+    os.chdir(stackwalker_dir)
+    subprocess.check_call(["git", "add", "-A"])
+    subprocess.check_call(["git", "commit", "-m", "Fix line endings"])
+    os.chdir(cwd)
+
+
+def main():
+    upstream_root = clone_repo(
+        "https://github.com/JochenKalmbach/StackWalker",
+        "42e7a6e056a9e7aca911a7e9e54e2e4f90bc2652",
+        shallow=False,
+    )
+    wpilib_root = get_repo_root()
+    wpiutil = os.path.join(wpilib_root, "wpiutil")
+
+    # Run CRLF -> LF before trying any patches
+    crlf_to_lf(upstream_root)
+
+    # Apply patches to upstream Git repo
+    os.chdir(upstream_root)
+    for f in [
+        "0001-Apply-PR-35.patch",
+        "0002-Remove-_M_IX86-checks.patch",
+        "0003-Add-advapi-pragma.patch",
+    ]:
+        git_am(
+            os.path.join(wpilib_root, "upstream_utils/stack_walker_patches", f),
+            ignore_whitespace=True,
+        )
+
+    shutil.copy(
+        os.path.join("Main", "StackWalker", "StackWalker.h"),
+        os.path.join(wpiutil, "src/main/native/windows/StackWalker.h"),
+    )
+
+    shutil.copy(
+        os.path.join("Main", "StackWalker", "StackWalker.cpp"),
+        os.path.join(wpiutil, "src/main/native/windows/StackWalker.cpp"),
+    )
+
+
+if __name__ == "__main__":
+    main()
diff --git a/upstream_utils/upstream_utils.py b/upstream_utils/upstream_utils.py
index c4ee1ae..6454d54 100644
--- a/upstream_utils/upstream_utils.py
+++ b/upstream_utils/upstream_utils.py
@@ -5,24 +5,32 @@
 import tempfile
 
 
-def clone_repo(url, treeish):
-    """Clones a git repo at the given URL into a temp folder and checks out the
-    given tree-ish (either branch or tag).
-
-    The current working directory will be set to the repository folder.
+def clone_repo(url, treeish, shallow=True):
+    """Clones a Git repo at the given URL into a temp folder, checks out the
+    given tree-ish (either branch or tag), then returns the repo root.
 
     Keyword argument:
-    url -- The URL of the git repo
+    url -- The URL of the Git repo
     treeish -- The tree-ish to check out (branch or tag)
+    shallow -- Whether to do a shallow clone
+
+    Returns:
+    root -- root directory of the cloned Git repository
     """
+    cwd = os.getcwd()
     os.chdir(tempfile.gettempdir())
 
     repo = os.path.basename(url)
-    dest = os.path.join(os.getcwd(), repo).removesuffix(".git")
+    dest = os.path.join(os.getcwd(), repo)
+    if dest.endswith(".git"):
+        dest = dest[:-4]
 
     # Clone Git repository into current directory or update it
     if not os.path.exists(dest):
-        subprocess.run(["git", "clone", url, dest])
+        cmd = ["git", "clone"]
+        if shallow:
+            cmd += ["--branch", treeish, "--depth", "1"]
+        subprocess.run(cmd + [url, dest])
         os.chdir(dest)
     else:
         os.chdir(dest)
@@ -33,8 +41,7 @@
     #   From https://gitlab.com/libeigen/eigen.git
     #   77c66e368c7e355f8be299659f57b0ffcaedb505  refs/heads/3.4
     #   3e006bfd31e4389e8c5718c30409cddb65a73b04  refs/heads/master
-    ls_out = subprocess.check_output(["git", "ls-remote",
-                                      "--heads"]).decode().rstrip()
+    ls_out = subprocess.check_output(["git", "ls-remote", "--heads"]).decode().rstrip()
     heads = [x.split()[1] for x in ls_out.split("\n")[1:]]
 
     if f"refs/heads/{treeish}" in heads:
@@ -44,6 +51,9 @@
     else:
         subprocess.run(["git", "checkout", treeish])
 
+    os.chdir(cwd)
+    return dest
+
 
 def get_repo_root():
     """Returns the Git repository root as an absolute path.
@@ -58,26 +68,6 @@
     return ""
 
 
-def setup_upstream_repo(url, treeish):
-    """Clones the given upstream repository, then returns the root of the
-    destination Git repository as well as the cloned upstream Git repository.
-
-    The current working directory will be set to the cloned upstream repository
-    folder.
-
-    Keyword arguments:
-    url -- The URL of the git repo
-    treeish -- The tree-ish to check out (branch or tag)
-
-    Returns:
-    root -- root directory of destination Git repository
-    repo -- root directory of cloned upstream Git repository
-    """
-    root = get_repo_root()
-    clone_repo(url, treeish)
-    return root, os.getcwd()
-
-
 def walk_if(top, pred):
     """Walks the current directory, then returns a list of files for which the
     given predicate is true.
@@ -88,10 +78,7 @@
             True if the file should be included in the output list
     """
     return [
-        os.path.join(dp, f)
-        for dp, dn, fn in os.walk(top)
-        for f in fn
-        if pred(dp, f)
+        os.path.join(dp, f) for dp, dn, fn in os.walk(top) for f in fn if pred(dp, f)
     ]
 
 
@@ -118,6 +105,8 @@
         # Rename .cc file to .cpp
         if dest_file.endswith(".cc"):
             dest_file = os.path.splitext(dest_file)[0] + ".cpp"
+        if dest_file.endswith(".c"):
+            dest_file = os.path.splitext(dest_file)[0] + ".cpp"
 
         # Make leading directory
         dest_dir = os.path.dirname(dest_file)
@@ -166,14 +155,16 @@
         include = match.group(1)
 
         # Write contents from before this match
-        new_contents += old_contents[pos:match.span()[0]]
+        new_contents += old_contents[pos : match.span()[0]]
 
         # Comment out #include if the file doesn't exist in current directory or
         # include root
-        if not os.path.exists(os.path.join(
-                os.path.dirname(filename), include)) and not any(
-                    os.path.exists(os.path.join(include_root, include))
-                    for include_root in include_roots):
+        if not os.path.exists(
+            os.path.join(os.path.dirname(filename), include)
+        ) and not any(
+            os.path.exists(os.path.join(include_root, include))
+            for include_root in include_roots
+        ):
             new_contents += "// "
 
         new_contents += match.group()
@@ -189,13 +180,18 @@
             f.write(new_contents)
 
 
-def apply_patches(root, patches):
-    """Apply list of patches to the destination Git repository.
+def git_am(patch, use_threeway=False, ignore_whitespace=False):
+    """Apply patch to a Git repository in the current directory using "git am".
 
     Keyword arguments:
-    root -- the root directory of the destination Git repository
-    patches -- list of patch files relative to the root
+    patch -- patch file relative to the root
+    use_threeway -- use a three-way merge when applying the patch
+    ignore_whitespace -- ignore whitespace in the patch file
     """
-    os.chdir(root)
-    for patch in patches:
-        subprocess.check_output(["git", "apply", patch])
+    args = ["git", "am"]
+    if use_threeway:
+        args.append("-3")
+    if ignore_whitespace:
+        args.append("--ignore-whitespace")
+
+    subprocess.check_output(args + [patch])