From 254ca6410610dc4636a58d542630f9a9922ee025 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 26 May 2026 16:25:29 -0700 Subject: [PATCH] [upstream_utils] Upgrade to LLVM 22.1.6 (#8919) --- upstream_utils/llvm.py | 2 +- ...move-StringRef-ArrayRef-and-Optional.patch | 442 +++++--- ...-calls-in-parens-for-Windows-warning.patch | 145 ++- ...change-unique_function-storage-size.patch} | 10 +- .../llvm_patches/0004-Threading-updates.patch | 40 +- .../0005-ifdef-guard-safety.patch | 69 +- .../0006-Explicitly-use-std.patch | 112 +- .../0007-Remove-format_provider.patch | 60 +- .../0008-Add-compiler-warning-pragmas.patch | 55 +- .../0009-Remove-unused-functions.patch | 66 +- ...Vector-detemplatize-SmallVectorBase.patch} | 24 +- ...0011-raw_ostream-add-vector-support.patch} | 22 +- .../0012-Delete-numbers-from-MathExtras.patch | 57 - .../0012-MathExtras-delete-numbers.patch | 51 + ...=> 0013-MathExtras-add-Lerp-and-sgn.patch} | 6 +- .../llvm_patches/0014-Fixup-includes.patch | 32 +- ...-std-is_trivially_copy_constructible.patch | 36 - ...pport.patch => 0015-Windows-support.patch} | 73 +- ...g-remove-call-to-RtlGetLastNtStatus.patch} | 6 +- ...=> 0017-ErrorHandling-prefer-fmtlib.patch} | 19 +- ... 0018-raw_ostream-prefer-wpi-s-fs.h.patch} | 6 +- ...tch => 0019-Remove-unused-functions.patch} | 32 +- ...-use-SmallVector-for-UTF-conversion.patch} | 35 +- .../0021-OS-specific-changes.patch | 46 - ...-use-static-pointers-in-raw_ostream.patch} | 20 +- ...2-Endian-constexpr-endian-byte-swap.patch} | 12 +- ...ion-copy-type-traits-from-STLExtras.patch} | 4 +- ...Map-unused-variable-in-release-mode.patch} | 16 +- ...r.patch => 0025-Use-C-20-bit-header.patch} | 401 +++---- ...> 0026-DenseMap-remove-printer-test.patch} | 10 +- ...raw_ostream-Add-SetNumBytesInBuffer.patch} | 6 +- ...aw_ostream-Replace-errnoAsErrorCode.patch} | 8 +- ...0029-type_traits.h-Add-is_constexpr.patch} | 12 +- ...-raw_ostream-remove-auto-conversion.patch} | 30 +- ...ch => 0031-SmallVector-add-erase_if.patch} | 10 +- ...-fix-minIntN-and-maxIntN-assertions.patch} | 12 +- ...lSetIterator-postincrement-operator.patch} | 6 +- ...4-Fix-AlignedCharArrayUnion-for-C-23.patch | 39 - .../thirdparty/llvm/cpp/llvm/ConvertUTF.cpp | 2 +- .../llvm/cpp/llvm/ConvertUTFWrapper.cpp | 10 + .../llvm/cpp/llvm/ErrorHandling.cpp | 47 +- .../thirdparty/llvm/cpp/llvm/SmallPtrSet.cpp | 107 +- .../llvm/cpp/llvm/Windows/WindowsSupport.hpp | 6 +- .../thirdparty/llvm/cpp/llvm/raw_ostream.cpp | 22 +- .../llvm/include/wpi/util/AlignOf.hpp | 9 +- .../llvm/include/wpi/util/AllocatorBase.hpp | 3 +- .../llvm/include/wpi/util/Casting.hpp | 66 +- .../llvm/include/wpi/util/Chrono.hpp | 4 +- .../llvm/include/wpi/util/Compiler.hpp | 104 +- .../llvm/include/wpi/util/ConvertUTF.hpp | 142 +-- .../llvm/include/wpi/util/DenseMap.hpp | 992 +++++++++--------- .../llvm/include/wpi/util/DenseMapInfo.hpp | 249 ++--- .../llvm/include/wpi/util/Endian.hpp | 47 +- .../llvm/include/wpi/util/Errno.hpp | 1 + .../llvm/include/wpi/util/ErrorHandling.hpp | 146 +-- .../llvm/include/wpi/util/FunctionExtras.hpp | 51 +- .../llvm/include/wpi/util/IOSandbox.hpp | 42 + .../llvm/include/wpi/util/MathExtras.hpp | 63 +- .../llvm/include/wpi/util/MemAlloc.hpp | 4 +- .../llvm/include/wpi/util/PointerIntPair.hpp | 10 +- .../wpi/util/PointerLikeTypeTraits.hpp | 18 +- .../llvm/include/wpi/util/PointerUnion.hpp | 54 +- .../include/wpi/util/ReverseIteration.hpp | 3 +- .../include/wpi/util/STLForwardCompat.hpp | 138 ++- .../llvm/include/wpi/util/SmallPtrSet.hpp | 302 +++--- .../llvm/include/wpi/util/SmallSet.hpp | 34 +- .../llvm/include/wpi/util/SmallVector.hpp | 127 ++- .../llvm/include/wpi/util/SwapByteOrder.hpp | 2 +- .../llvm/include/wpi/util/VersionTuple.hpp | 5 +- .../llvm/include/wpi/util/WindowsError.hpp | 5 +- .../thirdparty/llvm/include/wpi/util/bit.hpp | 1 + .../llvm/include/wpi/util/iterator.hpp | 7 +- .../llvm/include/wpi/util/iterator_range.hpp | 21 +- .../llvm/include/wpi/util/raw_os_ostream.hpp | 3 +- .../llvm/include/wpi/util/raw_ostream.hpp | 35 +- .../llvm/include/wpi/util/type_traits.hpp | 41 +- .../src/test/native/cpp/llvm/DenseMapTest.cpp | 339 +++++- .../src/test/native/cpp/llvm/EndianTest.cpp | 28 +- .../native/cpp/llvm/FunctionExtrasTest.cpp | 1 - .../test/native/cpp/llvm/MathExtrasTest.cpp | 34 +- .../test/native/cpp/llvm/PointerUnionTest.cpp | 12 +- .../native/cpp/llvm/STLForwardCompatTest.cpp | 65 ++ .../test/native/cpp/llvm/SmallPtrSetTest.cpp | 25 +- .../src/test/native/cpp/llvm/SmallSetTest.cpp | 20 +- .../test/native/cpp/llvm/SmallStringTest.cpp | 2 +- .../test/native/cpp/llvm/SmallVectorTest.cpp | 83 +- 86 files changed, 3236 insertions(+), 2328 deletions(-) rename upstream_utils/llvm_patches/{0003-Change-unique_function-storage-size.patch => 0003-FunctionExtras-change-unique_function-storage-size.patch} (77%) rename upstream_utils/llvm_patches/{0010-Detemplatize-SmallVectorBase.patch => 0010-SmallVector-detemplatize-SmallVectorBase.patch} (91%) rename upstream_utils/llvm_patches/{0011-Add-vectors-to-raw_ostream.patch => 0011-raw_ostream-add-vector-support.patch} (92%) delete mode 100644 upstream_utils/llvm_patches/0012-Delete-numbers-from-MathExtras.patch create mode 100644 upstream_utils/llvm_patches/0012-MathExtras-delete-numbers.patch rename upstream_utils/llvm_patches/{0013-Add-lerp-and-sgn.patch => 0013-MathExtras-add-Lerp-and-sgn.patch} (83%) delete mode 100644 upstream_utils/llvm_patches/0015-Use-std-is_trivially_copy_constructible.patch rename upstream_utils/llvm_patches/{0016-Windows-support.patch => 0015-Windows-support.patch} (71%) rename upstream_utils/llvm_patches/{0017-Remove-call-to-RtlGetLastNtStatus.patch => 0016-ErrorHandling-remove-call-to-RtlGetLastNtStatus.patch} (89%) rename upstream_utils/llvm_patches/{0018-Prefer-fmtlib.patch => 0017-ErrorHandling-prefer-fmtlib.patch} (72%) rename upstream_utils/llvm_patches/{0019-Prefer-wpi-s-fs.h.patch => 0018-raw_ostream-prefer-wpi-s-fs.h.patch} (84%) rename upstream_utils/llvm_patches/{0020-Remove-unused-functions.patch => 0019-Remove-unused-functions.patch} (90%) rename upstream_utils/llvm_patches/{0022-Use-SmallVector-for-UTF-conversion.patch => 0020-ConvertUTF-use-SmallVector-for-UTF-conversion.patch} (80%) delete mode 100644 upstream_utils/llvm_patches/0021-OS-specific-changes.patch rename upstream_utils/llvm_patches/{0023-Prefer-to-use-static-pointers-in-raw_ostream.patch => 0021-raw_ostream-use-static-pointers-in-raw_ostream.patch} (67%) rename upstream_utils/llvm_patches/{0024-constexpr-endian-byte-swap.patch => 0022-Endian-constexpr-endian-byte-swap.patch} (62%) rename upstream_utils/llvm_patches/{0025-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch => 0023-PointerUnion-copy-type-traits-from-STLExtras.patch} (94%) rename upstream_utils/llvm_patches/{0026-Unused-variable-in-release-mode.patch => 0024-DenseMap-unused-variable-in-release-mode.patch} (53%) rename upstream_utils/llvm_patches/{0027-Use-C-20-bit-header.patch => 0025-Use-C-20-bit-header.patch} (56%) rename upstream_utils/llvm_patches/{0028-Remove-DenseMap-GTest-printer-test.patch => 0026-DenseMap-remove-printer-test.patch} (73%) rename upstream_utils/llvm_patches/{0029-raw_ostream-Add-SetNumBytesInBuffer.patch => 0027-raw_ostream-Add-SetNumBytesInBuffer.patch} (80%) rename upstream_utils/llvm_patches/{0030-raw_ostream-Replace-errnoAsErrorCode.patch => 0028-raw_ostream-Replace-errnoAsErrorCode.patch} (74%) rename upstream_utils/llvm_patches/{0031-type_traits.h-Add-is_constexpr.patch => 0029-type_traits.h-Add-is_constexpr.patch} (68%) rename upstream_utils/llvm_patches/{0032-Remove-auto-conversion-from-raw_ostream.patch => 0030-raw_ostream-remove-auto-conversion.patch} (63%) rename upstream_utils/llvm_patches/{0033-Add-SmallVector-erase_if.patch => 0031-SmallVector-add-erase_if.patch} (70%) rename upstream_utils/llvm_patches/{0035-Fix-minIntN-and-maxIntN-assertions.patch => 0032-MathExtras-fix-minIntN-and-maxIntN-assertions.patch} (70%) rename upstream_utils/llvm_patches/{0036-Add-postincrement-operator-to-SmallSetIterator.patch => 0033-SmallSet-add-SmallSetIterator-postincrement-operator.patch} (76%) delete mode 100644 upstream_utils/llvm_patches/0034-Fix-AlignedCharArrayUnion-for-C-23.patch create mode 100644 wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/IOSandbox.hpp diff --git a/upstream_utils/llvm.py b/upstream_utils/llvm.py index 50787e2257..e1abf59d25 100755 --- a/upstream_utils/llvm.py +++ b/upstream_utils/llvm.py @@ -202,7 +202,7 @@ def copy_upstream_src(wpilib_root: Path): def main(): name = "llvm" url = "https://github.com/llvm/llvm-project" - tag = "llvmorg-20.1.7" + tag = "llvmorg-22.1.6" patch_options = { "use_threeway": True, diff --git a/upstream_utils/llvm_patches/0001-Remove-StringRef-ArrayRef-and-Optional.patch b/upstream_utils/llvm_patches/0001-Remove-StringRef-ArrayRef-and-Optional.patch index 15328b3885..ba8700fa37 100644 --- a/upstream_utils/llvm_patches/0001-Remove-StringRef-ArrayRef-and-Optional.patch +++ b/upstream_utils/llvm_patches/0001-Remove-StringRef-ArrayRef-and-Optional.patch @@ -1,33 +1,34 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:09:18 -0400 -Subject: [PATCH 01/36] Remove StringRef, ArrayRef, and Optional +Subject: [PATCH 01/33] Remove StringRef, ArrayRef, and Optional --- llvm/include/llvm/ADT/PointerUnion.h | 1 - llvm/include/llvm/ADT/SmallString.h | 101 ++++++++++-------- - llvm/include/llvm/ADT/SmallVector.h | 7 +- - llvm/include/llvm/Support/Chrono.h | 10 +- + llvm/include/llvm/ADT/SmallVector.h | 9 +- + llvm/include/llvm/Support/Chrono.h | 12 +-- llvm/include/llvm/Support/Compiler.h | 2 +- llvm/include/llvm/Support/ConvertUTF.h | 31 +++--- - llvm/include/llvm/Support/ErrorHandling.h | 9 +- + llvm/include/llvm/Support/ErrorHandling.h | 16 +-- llvm/include/llvm/Support/VersionTuple.h | 6 -- .../llvm/Support/Windows/WindowsSupport.h | 4 +- llvm/include/llvm/Support/raw_ostream.h | 46 ++++---- llvm/lib/Support/ConvertUTFWrapper.cpp | 39 +++---- - llvm/lib/Support/ErrorHandling.cpp | 13 ++- + llvm/lib/Support/ErrorHandling.cpp | 21 ++-- llvm/lib/Support/SmallVector.cpp | 5 +- + llvm/lib/Support/VersionTuple.cpp | 49 --------- llvm/lib/Support/raw_ostream.cpp | 25 +++-- - llvm/unittests/ADT/DenseMapTest.cpp | 29 +---- + llvm/unittests/ADT/DenseMapTest.cpp | 33 +----- llvm/unittests/ADT/FunctionExtrasTest.cpp | 12 +-- llvm/unittests/ADT/SmallPtrSetTest.cpp | 1 - llvm/unittests/ADT/SmallStringTest.cpp | 50 ++++----- - llvm/unittests/ADT/SmallVectorTest.cpp | 30 ++---- + llvm/unittests/ADT/SmallVectorTest.cpp | 36 ++----- llvm/unittests/Support/ConvertUTFTest.cpp | 42 ++++---- - 20 files changed, 211 insertions(+), 252 deletions(-) + 21 files changed, 226 insertions(+), 315 deletions(-) diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h -index cdbd76d7f505be277c3886cc821fb60336cbec59..23394db93cfed492bb1747eb9c8c55ed9230120d 100644 +index d9087dd1c516ee265aa00851ca98b1df09936f3e..c3d6458777d186a700c359089c4afcac8db0185a 100644 --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h @@ -17,7 +17,6 @@ @@ -306,10 +307,10 @@ index be3193c6ef9beba622f39e3e76cd0f0c6dd422b0..9fab1a7726bc6745296f5ebb24aee405 return *this; } diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index bd3e887e36bce4129d95099e84e833adc6a82cee..be06bb817e24e723265f9a8038d94123de1fc53c 100644 +index 23d40c3e07675d5c5cb8aa0089920ebd47cd1ccd..4499a51d40da615a3074ece034f7c30a3ddd709e 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -27,13 +27,12 @@ +@@ -29,13 +29,12 @@ #include #include #include @@ -324,7 +325,7 @@ index bd3e887e36bce4129d95099e84e833adc6a82cee..be06bb817e24e723265f9a8038d94123 template class iterator_range; template -@@ -114,7 +113,7 @@ template struct SmallVectorAlignmentAndSize { +@@ -116,7 +115,7 @@ template struct SmallVectorAlignmentAndSize { }; /// This is the part of SmallVectorTemplateBase which does not depend on whether @@ -333,29 +334,44 @@ index bd3e887e36bce4129d95099e84e833adc6a82cee..be06bb817e24e723265f9a8038d94123 /// to avoid unnecessarily requiring T to be complete. template class SmallVectorTemplateCommon -@@ -1229,7 +1228,7 @@ public: +@@ -739,7 +738,7 @@ public: template ::value>> + typename = std::enable_if_t>> +- void assign(ArrayRef AR) { ++ void assign(span AR) { + assign(AR.begin(), AR.end()); + } + +@@ -1238,7 +1237,7 @@ public: + + template >> - explicit SmallVector(ArrayRef A) : SmallVectorImpl(N) { + explicit SmallVector(span A) : SmallVectorImpl(N) { this->append(A.begin(), A.end()); } diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h -index 71859af7c7e4a595140475daf356744f52d14d24..9c9ba7002310eba5113c14957f769702c61f4326 100644 +index e5f98249cc07464c4961ce4f86f973556e2d4dfb..dae64305f2b41766bb7bf9cf49b5d672b91f9493 100644 --- a/llvm/include/llvm/Support/Chrono.h +++ b/llvm/include/llvm/Support/Chrono.h -@@ -91,7 +91,7 @@ raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP); +@@ -91,12 +91,12 @@ LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP); template <> struct format_provider> { - static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS, -- StringRef Style); -+ std::string_view Style); + LLVM_ABI static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS, +- StringRef Style); ++ std::string_view Style); }; template <> struct format_provider> { -@@ -148,7 +148,7 @@ private: + LLVM_ABI static void format(const sys::UtcTime &TP, +- llvm::raw_ostream &OS, StringRef Style); ++ llvm::raw_ostream &OS, std::string_view Style); + }; + + namespace detail { +@@ -160,7 +160,7 @@ private: return duration_cast>(D).count(); } @@ -364,7 +380,7 @@ index 71859af7c7e4a595140475daf356744f52d14d24..9c9ba7002310eba5113c14957f769702 const Dur &D) { using namespace std::chrono; if (Style.consume_front("ns")) -@@ -166,7 +166,7 @@ private: +@@ -178,7 +178,7 @@ private: return {D.count(), detail::unit::value}; } @@ -373,7 +389,7 @@ index 71859af7c7e4a595140475daf356744f52d14d24..9c9ba7002310eba5113c14957f769702 if (Style.empty()) return true; if (Style.consume_front("-")) -@@ -178,9 +178,9 @@ private: +@@ -190,9 +190,9 @@ private: } public: @@ -386,10 +402,10 @@ index 71859af7c7e4a595140475daf356744f52d14d24..9c9ba7002310eba5113c14957f769702 bool show_unit = consumeShowUnit(Style); diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index dc8b5389069ebfe217d323fb9c75d6e0fe7d5b8e..021d1d29368deb330418ff4e08fbf3931e4b7453 100644 +index 56f498a36ae52455a336c0f77a56fd16d199706b..a160164a33903408d60d6e8a57462a3b8c8623e2 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h -@@ -406,7 +406,7 @@ +@@ -422,7 +422,7 @@ #endif /// LLVM_GSL_POINTER - Apply this to non-owning classes like @@ -399,11 +415,11 @@ index dc8b5389069ebfe217d323fb9c75d6e0fe7d5b8e..021d1d29368deb330418ff4e08fbf393 #define LLVM_GSL_POINTER [[gsl::Pointer]] #else diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h -index c892bb3c03cb569994429649bdbb96e4118dcef1..5c0e3009c25446a34882fb98329b1d955231bb39 100644 +index ddf7057bff59d1302ad26dd6da6c11937dd003e5..4049b742683ce5c61202e61c856f33074d2fc586 100644 --- a/llvm/include/llvm/Support/ConvertUTF.h +++ b/llvm/include/llvm/Support/ConvertUTF.h -@@ -107,10 +107,9 @@ - +@@ -108,10 +108,9 @@ + #include "llvm/Support/Compiler.h" #include #include - @@ -415,7 +431,7 @@ index c892bb3c03cb569994429649bdbb96e4118dcef1..5c0e3009c25446a34882fb98329b1d95 // Wrap everything in namespace llvm so that programs can link with llvm and // their own version of the unicode libraries. -@@ -204,12 +203,10 @@ unsigned getNumBytesForUTF8(UTF8 firstByte); +@@ -217,12 +216,10 @@ LLVM_ABI unsigned getNumBytesForUTF8(UTF8 firstByte); /*************************************************************************/ /* Below are LLVM-specific wrappers of the functions above. */ @@ -429,89 +445,92 @@ index c892bb3c03cb569994429649bdbb96e4118dcef1..5c0e3009c25446a34882fb98329b1d95 * 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, -@@ -217,14 +214,14 @@ class StringRef; +@@ -230,14 +227,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); +-LLVM_ABI bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, ++LLVM_ABI 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); +-LLVM_ABI bool ConvertUTF8toWide(llvm::StringRef Source, std::wstring &Result); ++LLVM_ABI bool ConvertUTF8toWide(std::string_view Source, std::wstring &Result); /** * Converts a UTF-8 C-string to a std::wstring. -@@ -282,7 +279,7 @@ inline ConversionResult convertUTF8Sequence(const UTF8 **source, +@@ -295,7 +292,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 SrcBytes); -+bool hasUTF16ByteOrderMark(span SrcBytes); +-LLVM_ABI bool hasUTF16ByteOrderMark(ArrayRef SrcBytes); ++LLVM_ABI bool hasUTF16ByteOrderMark(span SrcBytes); /** * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string. -@@ -291,7 +288,7 @@ bool hasUTF16ByteOrderMark(ArrayRef SrcBytes); +@@ -304,7 +301,7 @@ LLVM_ABI bool hasUTF16ByteOrderMark(ArrayRef SrcBytes); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ --bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out); -+bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out); +-LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef SrcBytes, ++LLVM_ABI bool convertUTF16ToUTF8String(span SrcBytes, + std::string &Out); /** - * Converts a UTF16 string into a UTF8 std::string. -@@ -300,7 +297,7 @@ bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out); +@@ -314,7 +311,7 @@ LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef SrcBytes, * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ --bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out); -+bool convertUTF16ToUTF8String(span Src, std::string &Out); +-LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out); ++LLVM_ABI bool convertUTF16ToUTF8String(span Src, std::string &Out); /** * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string. -@@ -309,7 +306,7 @@ bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out); +@@ -323,7 +320,7 @@ LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ --bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out); -+bool convertUTF32ToUTF8String(span SrcBytes, std::string &Out); +-LLVM_ABI bool convertUTF32ToUTF8String(ArrayRef SrcBytes, ++LLVM_ABI bool convertUTF32ToUTF8String(span SrcBytes, + std::string &Out); /** - * Converts a UTF32 string into a UTF8 std::string. -@@ -318,22 +315,22 @@ bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out); +@@ -333,14 +330,14 @@ LLVM_ABI bool convertUTF32ToUTF8String(ArrayRef SrcBytes, * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ --bool convertUTF32ToUTF8String(ArrayRef Src, std::string &Out); -+bool convertUTF32ToUTF8String(span Src, std::string &Out); +-LLVM_ABI bool convertUTF32ToUTF8String(ArrayRef Src, std::string &Out); ++LLVM_ABI bool convertUTF32ToUTF8String(span 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 &DstUTF16); +-LLVM_ABI bool convertUTF8ToUTF16String(StringRef SrcUTF8, ++LLVM_ABI bool convertUTF8ToUTF16String(std::string_view SrcUTF8, + SmallVectorImpl &DstUTF16); + LLVM_ABI bool IsSingleCodeUnitUTF8Codepoint(unsigned); +@@ -350,10 +347,10 @@ LLVM_ABI bool IsSingleCodeUnitUTF32Codepoint(unsigned); #if defined(_WIN32) namespace sys { namespace windows { --std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl &utf16); -+std::error_code UTF8ToUTF16(std::string_view utf8, SmallVectorImpl &utf16); +-LLVM_ABI std::error_code UTF8ToUTF16(StringRef utf8, ++LLVM_ABI std::error_code UTF8ToUTF16(std::string_view utf8, + SmallVectorImpl &utf16); /// Convert to UTF16 from the current code page used in the system --std::error_code CurCPToUTF16(StringRef utf8, SmallVectorImpl &utf16); -+std::error_code CurCPToUTF16(std::string_view utf8, SmallVectorImpl &utf16); - std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, - SmallVectorImpl &utf8); - /// Convert from UTF16 to the current code page used in the system +-LLVM_ABI std::error_code CurCPToUTF16(StringRef utf8, ++LLVM_ABI std::error_code CurCPToUTF16(std::string_view utf8, + SmallVectorImpl &utf16); + LLVM_ABI std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, + SmallVectorImpl &utf8); diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h -index 9c8e3448f3a03e3540adb8b9dd730c77dd9b20ba..68c27a8c67c4f378b92cfa726659ef7824b56dea 100644 +index a4fd008a9ff3fc50cbb81e4b8a90ef2284ec6474..aabdfa0ad5e0caf15a72eb95ec9f888fbe608099 100644 --- a/llvm/include/llvm/Support/ErrorHandling.h +++ b/llvm/include/llvm/Support/ErrorHandling.h @@ -15,10 +15,10 @@ @@ -522,31 +541,50 @@ index 9c8e3448f3a03e3540adb8b9dd730c77dd9b20ba..68c27a8c67c4f378b92cfa726659ef78 +#include namespace llvm { -- class StringRef; -- class Twine; +-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 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); + /// An error handler callback. + using fatal_error_handler_t = void (*)(void *user_data, const char *reason, +@@ -62,9 +62,9 @@ struct ScopedFatalErrorHandler { + /// instead. + [[noreturn]] LLVM_ABI void report_fatal_error(const char *reason, + bool gen_crash_diag = true); +-[[noreturn]] LLVM_ABI void report_fatal_error(StringRef reason, ++[[noreturn]] LLVM_ABI void report_fatal_error(const std::string& reason, + bool gen_crash_diag = true); +-[[noreturn]] LLVM_ABI void report_fatal_error(const Twine &reason, ++[[noreturn]] LLVM_ABI void report_fatal_error(std::string_view reason, + bool gen_crash_diag = true); + + /// Report a fatal error that likely indicates a bug in LLVM. It serves a +@@ -75,8 +75,8 @@ struct ScopedFatalErrorHandler { + /// and then abort. This will produce a crash trace and *will* ask users to + /// report an LLVM bug. + [[noreturn]] LLVM_ABI void reportFatalInternalError(const char *reason); +-[[noreturn]] LLVM_ABI void reportFatalInternalError(StringRef reason); +-[[noreturn]] LLVM_ABI void reportFatalInternalError(const Twine &reason); ++[[noreturn]] LLVM_ABI void reportFatalInternalError(const std::string& reason); ++[[noreturn]] LLVM_ABI void reportFatalInternalError(std::string_view reason); + + /// Report a fatal error that does not indicate a bug in LLVM. + /// +@@ -93,8 +93,8 @@ struct ScopedFatalErrorHandler { + /// and then exit with code 1. It will not produce a crash trace and will + /// *not* ask users to report an LLVM bug. + [[noreturn]] LLVM_ABI void reportFatalUsageError(const char *reason); +-[[noreturn]] LLVM_ABI void reportFatalUsageError(StringRef reason); +-[[noreturn]] LLVM_ABI void reportFatalUsageError(const Twine &reason); ++[[noreturn]] LLVM_ABI void reportFatalUsageError(const std::string& reason); ++[[noreturn]] LLVM_ABI void reportFatalUsageError(std::string_view reason); /// Installs a new bad alloc error handler that should be used whenever a + /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM. diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h -index 0a4623f049d28825530bf50c8acfe85deaed96ba..e1cdce77ce8659305c99a21e01f9b3cc3481a5fd 100644 +index 867f81d74fb4d72a63a8e52ca6599cf4f463ec56..32c3ad9a9fc2c9827dc4afd81c6f9d03ec1b25c2 100644 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h -@@ -23,7 +23,6 @@ +@@ -24,7 +24,6 @@ namespace llvm { template class HashBuilder; class raw_ostream; @@ -554,20 +592,20 @@ index 0a4623f049d28825530bf50c8acfe85deaed96ba..e1cdce77ce8659305c99a21e01f9b3cc /// Represents a version number in the form major[.minor[.subminor[.build]]]. class VersionTuple { -@@ -180,11 +179,6 @@ public: +@@ -179,11 +178,6 @@ public: /// Retrieve a string representation of the version number. - std::string getAsString() const; + LLVM_ABI 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); +- LLVM_ABI 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 6f5aae2485c525f100eace5316b3e53e7b4fa544..83d5586ae8a77ec585e7e59df3075ca59cfb9d0c 100644 +index 50a2540dba68795237fa922c2afc972f90873b5c..30644ef7f62cb81a33f2b62068f77f4e7f3f5019 100644 --- a/llvm/include/llvm/Support/Windows/WindowsSupport.h +++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h @@ -33,8 +33,6 @@ @@ -579,7 +617,7 @@ index 6f5aae2485c525f100eace5316b3e53e7b4fa544..83d5586ae8a77ec585e7e59df3075ca5 #include "llvm/Config/llvm-config.h" // Get build system configuration settings #include "llvm/Support/Allocator.h" #include "llvm/Support/Chrono.h" -@@ -72,7 +70,7 @@ bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); +@@ -72,7 +70,7 @@ LLVM_ABI bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) { std::string ErrMsg; MakeErrMsg(&ErrMsg, Msg); @@ -589,14 +627,15 @@ index 6f5aae2485c525f100eace5316b3e53e7b4fa544..83d5586ae8a77ec585e7e59df3075ca5 template diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b0069818dc87 100644 +index 70916d8e4adb0f98984ff335187a083a3091bc58..19df8739b6013c1b1a1527f5880a040d3cfb478f 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -14,13 +14,12 @@ +@@ -14,14 +14,13 @@ #define LLVM_SUPPORT_RAW_OSTREAM_H #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" + #include "llvm/Support/Compiler.h" -#include "llvm/Support/DataTypes.h" #include #include @@ -607,7 +646,7 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 #include #include #include -@@ -221,7 +220,22 @@ public: +@@ -222,7 +221,22 @@ public: return *this; } @@ -631,7 +670,7 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 // Inline fast path, particularly for strings with a known length. size_t Size = Str.size(); -@@ -254,7 +268,7 @@ public: +@@ -255,7 +269,7 @@ public: // Inline fast path, particularly for constant strings where a sufficiently // smart compiler will simplify strlen. @@ -640,7 +679,7 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 } raw_ostream &operator<<(const std::string &Str) { -@@ -262,10 +276,6 @@ public: +@@ -263,10 +277,6 @@ public: return write(Str.data(), Str.length()); } @@ -651,7 +690,7 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 raw_ostream &operator<<(const SmallVectorImpl &Str) { return write(Str.data(), Str.size()); } -@@ -298,7 +308,7 @@ public: +@@ -299,7 +309,7 @@ public: /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't /// satisfy llvm::isPrint into an escape sequence. @@ -660,7 +699,7 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 raw_ostream &write(unsigned char C); raw_ostream &write(const char *Ptr, size_t Size); -@@ -511,14 +521,14 @@ public: +@@ -512,14 +522,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. @@ -680,16 +719,16 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access, sys::fs::OpenFlags Flags); -@@ -630,7 +640,7 @@ public: +@@ -631,7 +641,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); +- LLVM_ABI raw_fd_stream(StringRef Filename, std::error_code &EC); ++ LLVM_ABI raw_fd_stream(std::string_view Filename, std::error_code &EC); - raw_fd_stream(int fd, bool shouldClose); + LLVM_ABI raw_fd_stream(int fd, bool shouldClose); -@@ -716,8 +726,8 @@ public: +@@ -717,8 +727,8 @@ public: void flush() = delete; @@ -700,17 +739,17 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006 SmallVectorImpl &buffer() { return OS; } void reserveExtraSpace(uint64_t ExtraSize) override { -@@ -835,7 +845,7 @@ class Error; +@@ -836,7 +846,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 Write); +-LLVM_ABI Error writeToOutput(StringRef OutputFileName, ++LLVM_ABI Error writeToOutput(std::string_view OutputFileName, + std::function Write); - raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); + LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp -index 4952fe65d77675aeae8f4f5fdad7b47863e36ca5..d53462e742e61d3476915d5b2c5aa63772e78a8a 100644 +index 76ead00c977bd37147048d321b425a9a9e76497a..39f151c716dacfef07038551add0f84a09b0cb62 100644 --- a/llvm/lib/Support/ConvertUTFWrapper.cpp +++ b/llvm/lib/Support/ConvertUTFWrapper.cpp @@ -6,23 +6,24 @@ @@ -842,7 +881,7 @@ index 4952fe65d77675aeae8f4f5fdad7b47863e36ca5..d53462e742e61d3476915d5b2c5aa637 Result); } else if (sizeof(wchar_t) == 4) { diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index afe3b37cc343195e9ea12a68077d6b9d7506d5bb..d4ca266f3c1f98337499fba4fd0675e49a7dcf18 100644 +index 097041f1ae282a0387da8f839e5e37fe350d5d51..fc9d118e85508cdf86553bb63cce4a1c567045b7 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -14,7 +14,6 @@ @@ -853,7 +892,7 @@ index afe3b37cc343195e9ea12a68077d6b9d7506d5bb..d4ca266f3c1f98337499fba4fd0675e4 #include "llvm/Config/config.h" #include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS #include "llvm/Support/Debug.h" -@@ -81,14 +80,14 @@ void llvm::remove_fatal_error_handler() { +@@ -93,14 +92,14 @@ void llvm::remove_fatal_error_handler() { } void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) { @@ -872,7 +911,7 @@ index afe3b37cc343195e9ea12a68077d6b9d7506d5bb..d4ca266f3c1f98337499fba4fd0675e4 llvm::fatal_error_handler_t handler = nullptr; void* handlerData = nullptr; { -@@ -102,7 +101,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { +@@ -114,7 +113,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { } if (handler) { @@ -881,15 +920,39 @@ index afe3b37cc343195e9ea12a68077d6b9d7506d5bb..d4ca266f3c1f98337499fba4fd0675e4 } 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 -@@ -110,7 +109,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { +@@ -122,7 +121,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { SmallVector 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. + write_retry(2, MessageStr.data(), MessageStr.size()); } + +@@ -140,19 +139,19 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { + void llvm::reportFatalInternalError(const char *reason) { + report_fatal_error(reason, /*GenCrashDiag=*/true); + } +-void llvm::reportFatalInternalError(StringRef reason) { ++void llvm::reportFatalInternalError(const std::string& reason) { + report_fatal_error(reason, /*GenCrashDiag=*/true); + } +-void llvm::reportFatalInternalError(const Twine &reason) { ++void llvm::reportFatalInternalError(std::string_view reason) { + report_fatal_error(reason, /*GenCrashDiag=*/true); + } + void llvm::reportFatalUsageError(const char *reason) { + report_fatal_error(reason, /*GenCrashDiag=*/false); + } +-void llvm::reportFatalUsageError(StringRef reason) { ++void llvm::reportFatalUsageError(const std::string& reason) { + report_fatal_error(reason, /*GenCrashDiag=*/false); + } +-void llvm::reportFatalUsageError(const Twine &reason) { ++void llvm::reportFatalUsageError(std::string_view reason) { + report_fatal_error(reason, /*GenCrashDiag=*/false); + } + diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp index dceea4fbc630e85a869458af8b35ee1066c5866d..fba8fcb7cf56f4914e6ab6ede78eb8d8c8bf3424 100644 --- a/llvm/lib/Support/SmallVector.cpp @@ -920,11 +983,71 @@ index dceea4fbc630e85a869458af8b35ee1066c5866d..fba8fcb7cf56f4914e6ab6ede78eb8d8 #endif } +diff --git a/llvm/lib/Support/VersionTuple.cpp b/llvm/lib/Support/VersionTuple.cpp +index c6e20f1bd3ef4df881e9f7b02c04af88c8342d66..9526f17bba696cc4ad00d04f7cd0a3b1d7b56981 100644 +--- a/llvm/lib/Support/VersionTuple.cpp ++++ b/llvm/lib/Support/VersionTuple.cpp +@@ -60,55 +60,6 @@ static bool parseInt(StringRef &input, unsigned &value) { + return false; + } + +-bool VersionTuple::tryParse(StringRef input) { +- unsigned major = 0, minor = 0, micro = 0, build = 0; +- +- // Parse the major version, [0-9]+ +- if (parseInt(input, major)) +- return true; +- +- if (input.empty()) { +- *this = VersionTuple(major); +- return false; +- } +- +- // If we're not done, parse the minor version, \.[0-9]+ +- if (input[0] != '.') +- return true; +- input = input.substr(1); +- if (parseInt(input, minor)) +- return true; +- +- if (input.empty()) { +- *this = VersionTuple(major, minor); +- return false; +- } +- +- // If we're not done, parse the micro version, \.[0-9]+ +- if (!input.consume_front(".")) +- return true; +- if (parseInt(input, micro)) +- return true; +- +- if (input.empty()) { +- *this = VersionTuple(major, minor, micro); +- return false; +- } +- +- // If we're not done, parse the micro version, \.[0-9]+ +- if (!input.consume_front(".")) +- return true; +- if (parseInt(input, build)) +- return true; +- +- // If we have characters left over, it's an error. +- if (!input.empty()) +- return true; +- +- *this = VersionTuple(major, minor, micro, build); +- return false; +-} +- + VersionTuple VersionTuple::withMajorReplaced(unsigned NewMajor) const { + if (HasBuild) + return VersionTuple(NewMajor, Minor, Subminor, Build); diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417d82b3b78 100644 +index fe07aed335f7e49fd59488cdd4876e23e5b898b8..bf5d06018979474cf6166fed61be93eede0dece1 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -165,7 +165,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) { +@@ -155,7 +155,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) { } @@ -933,7 +1056,7 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 bool UseHexEscapes) { for (unsigned char c : Str) { switch (c) { -@@ -562,7 +562,7 @@ void format_object_base::home() { +@@ -552,7 +552,7 @@ void format_object_base::home() { // raw_fd_ostream //===----------------------------------------------------------------------===// @@ -941,8 +1064,8 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 +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) && -@@ -588,25 +588,25 @@ static int getFD(StringRef Filename, std::error_code &EC, + // FIXME(sandboxing): Remove this by adopting `llvm::vfs::OutputBackend`. +@@ -581,25 +581,25 @@ static int getFD(StringRef Filename, std::error_code &EC, return FD; } @@ -973,17 +1096,17 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access, sys::fs::OpenFlags Flags) -@@ -678,8 +678,7 @@ raw_fd_ostream::~raw_fd_ostream() { +@@ -674,8 +674,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); +- reportFatalUsageError(Twine("IO failure on output stream: ") + +- error().message()); ++ reportFatalUsageError("IO failure on output stream: " + error().message()); } -@@ -698,7 +697,7 @@ raw_fd_ostream::~raw_fd_ostream() { + #if defined(_WIN32) +@@ -693,7 +692,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. @@ -992,7 +1115,7 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 SmallVector WideText; // Fall back to ::write if it wasn't valid UTF-8. -@@ -744,7 +743,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { +@@ -739,7 +738,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) @@ -1001,7 +1124,7 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 return; #endif -@@ -924,7 +923,7 @@ raw_ostream &llvm::nulls() { +@@ -922,7 +921,7 @@ raw_ostream &llvm::nulls() { // File Streams //===----------------------------------------------------------------------===// @@ -1010,7 +1133,7 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write | sys::fs::FA_Read, sys::fs::OF_None), -@@ -1009,7 +1008,7 @@ void buffer_ostream::anchor() {} +@@ -1007,7 +1006,7 @@ void buffer_ostream::anchor() {} void buffer_unique_ostream::anchor() {} @@ -1020,23 +1143,24 @@ index e75ddc66b7d1629a4e71c53d891ae0d3edf90813..681b6fdc95eb4fda4f23d0b381b83417 if (OutputFileName == "-") return Write(outs()); diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp -index d1bbdde8dfc267770b9d98808de54381571f2785..e93e18423507655ce8275a0718d8e5d01915985f 100644 +index 553d159d33b1a55178a5e67e3669db48474cc40d..fffa07e1978bb3b8c2013073bdd58556d145ff23 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp -@@ -10,11 +10,11 @@ - #include "CountCopyAndMove.h" - #include "llvm/ADT/DenseMapInfo.h" +@@ -12,12 +12,12 @@ #include "llvm/ADT/DenseMapInfoVariant.h" + #include "llvm/ADT/STLForwardCompat.h" + #include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/StringRef.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include + #include #include +#include #include #include -@@ -523,31 +523,6 @@ TEST(DenseMapCustomTest, InsertOrAssignTest) { +@@ -677,31 +677,6 @@ TEST(DenseMapCustomTest, EmplaceOrAssign) { EXPECT_EQ(1, CountCopyAndMove::MoveAssignments); } @@ -1065,10 +1189,21 @@ index d1bbdde8dfc267770b9d98808de54381571f2785..e93e18423507655ce8275a0718d8e5d0 - 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 { -@@ -785,7 +760,7 @@ TEST(DenseMapCustomTest, VariantSupport) { + struct NonDefaultConstructible { + unsigned V; + NonDefaultConstructible(unsigned V) : V(V) {}; +@@ -771,8 +746,8 @@ TEST(DenseMapCustomTest, FindAsTest) { + } + + TEST(DenseMapCustomTest, SmallDenseMapFromRange) { +- std::pair PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}}; +- SmallDenseMap M(llvm::from_range, PlainArray); ++ std::pair PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}}; ++ SmallDenseMap M(llvm::from_range, PlainArray); + EXPECT_EQ(3u, M.size()); + using testing::Pair; + EXPECT_THAT(M, testing::UnorderedElementsAre(Pair(0, "0"), Pair(1, "1"), +@@ -975,7 +950,7 @@ TEST(DenseMapCustomTest, VariantSupport) { // Test that gTest prints map entries as pairs instead of opaque objects. // See third-party/unittest/googletest/internal/custom/gtest-printers.h TEST(DenseMapCustomTest, PairPrinting) { @@ -1078,10 +1213,10 @@ index d1bbdde8dfc267770b9d98808de54381571f2785..e93e18423507655ce8275a0718d8e5d0 } diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp -index 9809a92daac72468ed5bbd1762798523c2c3d628..777c5784949fd3c07bbbcef8dc3fc8e5764896a9 100644 +index fdabdca269da2e2be6a7a0e11b0f7f82afca0b5a..e92f5fcdfce0175eea843e81ef89604e0c2297f6 100644 --- a/llvm/unittests/ADT/FunctionExtrasTest.cpp +++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp -@@ -250,23 +250,23 @@ TEST(UniqueFunctionTest, Const) { +@@ -249,23 +249,23 @@ TEST(UniqueFunctionTest, Const) { // Overloaded call operator correctly resolved. struct ChooseCorrectOverload { @@ -1112,7 +1247,7 @@ index 9809a92daac72468ed5bbd1762798523c2c3d628..777c5784949fd3c07bbbcef8dc3fc8e5 TEST(UniqueFunctionTest, SFINAE) { EXPECT_EQ("not a function", returns("boo!")); diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp -index 1d9a0d1725a92ffd1bddcddf0a9ede28a1a74969..88be2b68915573a3b3a343ff53a84d86604d7bfd 100644 +index fe7a8279d06b10ccc5a2028ddf9e1708eb76dd9b..a25c07c08bbbba7b9edaa36adc5f9eaec14ea98d 100644 --- a/llvm/unittests/ADT/SmallPtrSetTest.cpp +++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp @@ -12,7 +12,6 @@ @@ -1124,7 +1259,7 @@ index 1d9a0d1725a92ffd1bddcddf0a9ede28a1a74969..88be2b68915573a3b3a343ff53a84d86 #include "gmock/gmock.h" #include "gtest/gtest.h" diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp -index 2f4df8afeafa592cb9616bb78feb4964187786f2..6cf14700b34739420cd3dc4ff8a4c16ce162f715 100644 +index db858246c9bbf7d298dff21d73c0dbd96e9b5f7e..20b0585e00e87b91c1486f045646a872cc99d208 100644 --- a/llvm/unittests/ADT/SmallStringTest.cpp +++ b/llvm/unittests/ADT/SmallStringTest.cpp @@ -50,43 +50,43 @@ TEST_F(SmallStringTest, AssignRepeated) { @@ -1263,22 +1398,23 @@ index 2f4df8afeafa592cb9616bb78feb4964187786f2..6cf14700b34739420cd3dc4ff8a4c16c 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 137dd43b473068eae34b39edc4b9b8b9633bab95..7029038d18d433cef987bedbfa4fda269b24fb8f 100644 +index dbc626db54482634415599b00697283f293bfdc7..f83bc116e4851f39fd6e496ee25ae1fb9acd96ca 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp -@@ -11,10 +11,10 @@ +@@ -11,11 +11,11 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Compiler.h" + #include "gmock/gmock.h" #include "gtest/gtest.h" #include +#include #include using namespace llvm; -@@ -252,11 +252,11 @@ TYPED_TEST(SmallVectorTest, ConstructorIterTest) { +@@ -250,11 +250,11 @@ TYPED_TEST(SmallVectorTest, ConstructorIterTest) { } // Constructor test. @@ -1293,7 +1429,23 @@ index 137dd43b473068eae34b39edc4b9b8b9633bab95..7029038d18d433cef987bedbfa4fda26 auto &V = this->theVector; V = SmallVector(Array); assertValuesInOrder(V, 3u, 1, 2, 3); -@@ -1129,24 +1129,6 @@ TEST(SmallVectorTest, DefaultInlinedElements) { +@@ -597,12 +597,12 @@ TYPED_TEST(SmallVectorTest, AssignSmallVector) { + assertValuesInOrder(V, 2u, 7, 7); + } + +-TYPED_TEST(SmallVectorTest, AssignArrayRef) { +- SCOPED_TRACE("AssignArrayRef"); ++TYPED_TEST(SmallVectorTest, AssignSpan) { ++ SCOPED_TRACE("AssignSpan"); + auto &V = this->theVector; + Constructable Other[] = {7, 8, 9}; + V.push_back(Constructable(1)); +- V.assign(ArrayRef(Other)); ++ V.assign(span(Other)); + assertValuesInOrder(V, 3u, 7, 8, 9); + } + +@@ -1135,24 +1135,6 @@ TEST(SmallVectorTest, DefaultInlinedElements) { EXPECT_EQ(NestedV[0][0][0], 42); } @@ -1315,10 +1467,10 @@ index 137dd43b473068eae34b39edc4b9b8b9633bab95..7029038d18d433cef987bedbfa4fda26 - EXPECT_TRUE(ArrayRef(V2).equals({4, 5, 3, 2})); -} - - TEST(SmallVectorTest, ToVector) { - { - std::vector v = {'a', 'b', 'c'}; -@@ -1183,10 +1165,10 @@ private: + namespace namespace_with_adl { + struct MyVector { + std::vector data; +@@ -1209,10 +1191,10 @@ private: To T; }; diff --git a/upstream_utils/llvm_patches/0002-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch b/upstream_utils/llvm_patches/0002-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch index 02d082e28a..19dad03dec 100644 --- a/upstream_utils/llvm_patches/0002-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch +++ b/upstream_utils/llvm_patches/0002-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch @@ -1,45 +1,99 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:12:41 -0400 -Subject: [PATCH 02/36] Wrap std::min/max calls in parens, for Windows warnings +Subject: [PATCH 02/33] Wrap std::min/max calls in parens, for Windows warnings --- - llvm/include/llvm/ADT/DenseMap.h | 4 ++-- + llvm/include/llvm/ADT/DenseMap.h | 14 +++++++------- + llvm/include/llvm/ADT/DenseMapInfo.h | 6 +++--- llvm/include/llvm/ADT/SmallPtrSet.h | 2 +- llvm/include/llvm/ADT/SmallVector.h | 6 +++--- + llvm/include/llvm/Support/AlignOf.h | 4 ++-- llvm/include/llvm/Support/ConvertUTF.h | 2 +- llvm/include/llvm/Support/MathExtras.h | 20 ++++++++++---------- - 5 files changed, 17 insertions(+), 17 deletions(-) + 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h -index f0f992f8eac389e36156e369ea24e0387bdf0057..4c852d2b142b4a3de76a1ce4049822cc449287f7 100644 +index fe8868619730e4c7054974905cc959cd99c7ef12..d207a515ef05425f924920a8d06d7c65d33e0909 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h -@@ -400,7 +400,7 @@ protected: +@@ -429,7 +429,7 @@ protected: return 0; - // +1 is required because of the strict equality. - // For example if NumEntries is 48, we need to return 401. + // +1 is required because of the strict inequality. + // For example, if NumEntries is 48, we need to return 128. - return NextPowerOf2(NumEntries * 4 / 3 + 1); + return static_cast(NextPowerOf2(NumEntries * 4 / 3 + 1)); } - void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) { -@@ -837,7 +837,7 @@ public: - // Reduce the number of buckets. + // Move key/value from Other to *this. +@@ -846,8 +846,8 @@ private: + } + + static unsigned roundUpNumBuckets(unsigned MinNumBuckets) { +- return std::max(64u, +- static_cast(NextPowerOf2(MinNumBuckets - 1))); ++ return (std::max)(64u, ++ static_cast(NextPowerOf2(MinNumBuckets - 1))); + } + + bool maybeMoveFast(DenseMap &&Other) { +@@ -861,7 +861,7 @@ private: + std::pair planShrinkAndClear() const { 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; + if (NumEntries) +- NewNumBuckets = std::max(64u, 1u << (Log2_32_Ceil(NumEntries) + 1)); ++ NewNumBuckets = (std::max)(64u, 1u << (Log2_32_Ceil(NumEntries) + 1)); + if (NewNumBuckets == NumBuckets) + return {false, 0}; // Reuse. + return {true, NewNumBuckets}; // Reallocate. +@@ -1109,8 +1109,8 @@ private: + static unsigned roundUpNumBuckets(unsigned MinNumBuckets) { + if (MinNumBuckets <= InlineBuckets) + return MinNumBuckets; +- return std::max(64u, +- static_cast(NextPowerOf2(MinNumBuckets - 1))); ++ return (std::max)(64u, ++ static_cast(NextPowerOf2(MinNumBuckets - 1))); + } + + bool maybeMoveFast(SmallDenseMap &&Other) { +@@ -1133,7 +1133,7 @@ private: + if (!this->empty()) { + NewNumBuckets = 1u << (Log2_32_Ceil(this->size()) + 1); + if (NewNumBuckets > InlineBuckets) +- NewNumBuckets = std::max(64u, NewNumBuckets); ++ NewNumBuckets = (std::max)(64u, NewNumBuckets); + } + bool Reuse = Small ? NewNumBuckets <= InlineBuckets + : NewNumBuckets == getLargeRep()->NumBuckets; +diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h +index f24aeb4371e7f4844d93dfda6f52b44216f01c6d..9e8378b5b119dcd2c14b0b281a4d24bae94d4a36 100644 +--- a/llvm/include/llvm/ADT/DenseMapInfo.h ++++ b/llvm/include/llvm/ADT/DenseMapInfo.h +@@ -111,13 +111,13 @@ template<> struct DenseMapInfo { + template + struct DenseMapInfo< + T, std::enable_if_t && !std::is_same_v>> { +- static constexpr T getEmptyKey() { return std::numeric_limits::max(); } ++ static constexpr T getEmptyKey() { return (std::numeric_limits::max)(); } + + static constexpr T getTombstoneKey() { + if constexpr (std::is_unsigned_v || std::is_same_v) +- return std::numeric_limits::max() - 1; ++ return (std::numeric_limits::max)() - 1; + else +- return std::numeric_limits::min(); ++ return (std::numeric_limits::min)(); + } + + static unsigned getHashValue(const T &Val) { diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h -index cf6abc9129b40eed6749213eb23439ec91621005..9115fc74363a9cccd0579427d88fa9edf5baae1b 100644 +index 8e7c8b30293b203d70d1b0d07d1d6866edc89934..c07de1a110479ed625b112cc5b30d0bd5d56430f 100644 --- a/llvm/include/llvm/ADT/SmallPtrSet.h +++ b/llvm/include/llvm/ADT/SmallPtrSet.h -@@ -126,7 +126,7 @@ public: - size_type NewSize = NumEntries + (NumEntries / 3); - NewSize = 1 << (Log2_32_Ceil(NewSize) + 1); +@@ -131,7 +131,7 @@ public: + size_type NewSize = NewNumEntries + (NewNumEntries / 3); + NewSize = llvm::bit_ceil(NewSize); // Like insert_imp_big, always allocate at least 128 elements. - NewSize = std::max(128u, NewSize); + NewSize = (std::max)(128u, NewSize); @@ -47,10 +101,10 @@ index cf6abc9129b40eed6749213eb23439ec91621005..9115fc74363a9cccd0579427d88fa9ed } diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index be06bb817e24e723265f9a8038d94123de1fc53c..2232b741d5359a129adb0e5b3f0f70110c38e90d 100644 +index 4499a51d40da615a3074ece034f7c30a3ddd709e..e27d0d71ec6176ee8081660f9ed6ba6672d7828d 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -55,7 +55,7 @@ protected: +@@ -57,7 +57,7 @@ protected: /// The maximum value of the Size_T used. static constexpr size_t SizeTypeMax() { @@ -59,7 +113,7 @@ index be06bb817e24e723265f9a8038d94123de1fc53c..2232b741d5359a129adb0e5b3f0f7011 } SmallVectorBase() = delete; -@@ -276,7 +276,7 @@ public: +@@ -282,7 +282,7 @@ public: size_type size_in_bytes() const { return size() * sizeof(T); } size_type max_size() const { @@ -68,7 +122,7 @@ index be06bb817e24e723265f9a8038d94123de1fc53c..2232b741d5359a129adb0e5b3f0f7011 } size_t capacity_in_bytes() const { return capacity() * sizeof(T); } -@@ -708,7 +708,7 @@ public: +@@ -711,7 +711,7 @@ public: } // Assign over existing elements. @@ -77,24 +131,39 @@ index be06bb817e24e723265f9a8038d94123de1fc53c..2232b741d5359a129adb0e5b3f0f7011 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/AlignOf.h b/llvm/include/llvm/Support/AlignOf.h +index 4f02e81dba151e01f48f3f7eacfa264f7143d6b7..6e843a345116700b921be8d1129d31ac779e9309 100644 +--- a/llvm/include/llvm/Support/AlignOf.h ++++ b/llvm/include/llvm/Support/AlignOf.h +@@ -22,8 +22,8 @@ namespace llvm { + template struct AlignedCharArrayUnion { + // Work around "internal compiler error: Segmentation fault" with GCC 7.5, + // apparently caused by alignas(Ts...). +- static constexpr std::size_t Align = std::max({alignof(T), alignof(Ts)...}); +- alignas(Align) char buffer[std::max({sizeof(T), sizeof(Ts)...})]; ++ static constexpr std::size_t Align = (std::max)({alignof(T), alignof(Ts)...}); ++ alignas(Align) char buffer[(std::max)({sizeof(T), sizeof(Ts)...})]; + }; + + } // end namespace llvm diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h -index 5c0e3009c25446a34882fb98329b1d955231bb39..72321022beb373945f7935ed72944fd68eb7d02f 100644 +index 4049b742683ce5c61202e61c856f33074d2fc586..d5f66c4525dd5b2e2cdb4ab5e4d523c19e36b25f 100644 --- a/llvm/include/llvm/Support/ConvertUTF.h +++ b/llvm/include/llvm/Support/ConvertUTF.h -@@ -127,7 +127,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 */ +@@ -128,7 +128,7 @@ namespace llvm { + using UTF32 = unsigned int; /* at least 32 bits */ + using UTF16 = unsigned short; /* at least 16 bits */ + using UTF8 = unsigned char; /* typically 8 bits */ +-using Boolean = unsigned char; /* 0 or 1 */ ++using Boolean = bool; /* 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 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d185a93f1e 100644 +index 0a253efc2abcb54f4f7146460c8cac1d61c01029..120a1641110aca97acf2ab9cd3806d94accbb8aa 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -339,26 +339,26 @@ template <> constexpr size_t CTLog2<1>() { return 0; } +@@ -329,26 +329,26 @@ constexpr size_t CTLog2() { /// (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) { @@ -125,7 +194,7 @@ index 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d1 } /// A and B are either alignments or offsets. Return the minimum alignment that -@@ -418,7 +418,7 @@ constexpr uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { +@@ -408,7 +408,7 @@ constexpr uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { // happens only when Numerator = INT_MIN and Denominator = -1. template constexpr bool divideSignedWouldOverflow(U Numerator, V Denominator) { @@ -134,7 +203,7 @@ index 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d1 } /// Returns the integer ceil(Numerator / Denominator). Signed version. -@@ -614,7 +614,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { +@@ -613,7 +613,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { T Z = X + Y; Overflowed = (Z < X || Z < Y); if (Overflowed) @@ -143,7 +212,7 @@ index 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d1 else return Z; } -@@ -627,7 +627,7 @@ std::enable_if_t, T> SaturatingAdd(T X, T Y, T Z, +@@ -626,7 +626,7 @@ std::enable_if_t, T> SaturatingAdd(T X, T Y, T Z, bool Overflowed = false; T XY = SaturatingAdd(X, Y, &Overflowed); if (Overflowed) @@ -152,7 +221,7 @@ index 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d1 return SaturatingAdd(XY, Z, Args...); } -@@ -651,7 +651,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) { +@@ -650,7 +650,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); @@ -161,7 +230,7 @@ index 5a6f51adc07f3976bdf8f3412bdb119b220a0e9b..5db59bb848024fca622b2919efd773d1 int Log2Max = Log2_64(Max); if (Log2Z < Log2Max) { return X * Y; -@@ -773,9 +773,9 @@ std::enable_if_t, T> MulOverflow(T X, T Y, T &Result) { +@@ -772,9 +772,9 @@ std::enable_if_t, 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) diff --git a/upstream_utils/llvm_patches/0003-Change-unique_function-storage-size.patch b/upstream_utils/llvm_patches/0003-FunctionExtras-change-unique_function-storage-size.patch similarity index 77% rename from upstream_utils/llvm_patches/0003-Change-unique_function-storage-size.patch rename to upstream_utils/llvm_patches/0003-FunctionExtras-change-unique_function-storage-size.patch index 985b49e352..663082b7e3 100644 --- a/upstream_utils/llvm_patches/0003-Change-unique_function-storage-size.patch +++ b/upstream_utils/llvm_patches/0003-FunctionExtras-change-unique_function-storage-size.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:13:55 -0400 -Subject: [PATCH 03/36] Change unique_function storage size +Subject: [PATCH 03/33] FunctionExtras: 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 d92868e3715f40e1c2c305a784afc55726e3a812..df7fe3e19462ebecd30f7a9d006027c75751de5b 100644 +index 807a2e769999c8caca5cb9edc97c8ddccf88b694..c4d0821076d63842927d2abeef4a5189cdf325e7 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h -@@ -79,7 +79,7 @@ using EnableIfCallable = std::enable_if_t class UniqueFunctionBase { protected: @@ -19,8 +19,8 @@ index d92868e3715f40e1c2c305a784afc55726e3a812..df7fe3e19462ebecd30f7a9d006027c7 + static constexpr size_t InlineStorageSize = sizeof(void *) * 4; static constexpr size_t InlineStorageAlign = alignof(void *); - template -@@ -159,7 +159,7 @@ protected: + // Provide a type function to map parameters that won't observe extra copies +@@ -149,7 +149,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 diff --git a/upstream_utils/llvm_patches/0004-Threading-updates.patch b/upstream_utils/llvm_patches/0004-Threading-updates.patch index cd00f749f5..9539e8528b 100644 --- a/upstream_utils/llvm_patches/0004-Threading-updates.patch +++ b/upstream_utils/llvm_patches/0004-Threading-updates.patch @@ -1,10 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:17:19 -0400 -Subject: [PATCH 04/36] Threading updates +Subject: [PATCH 04/33] Threading updates - Remove guards for threads and exception -- Prefer scope gaurd over lock gaurd +- Replace std::lock_guard with std::scoped_lock --- llvm/include/llvm/Support/Compiler.h | 6 ----- llvm/lib/Support/ErrorHandling.cpp | 39 +++++----------------------- @@ -12,10 +12,10 @@ Subject: [PATCH 04/36] Threading updates 3 files changed, 11 insertions(+), 44 deletions(-) diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index 021d1d29368deb330418ff4e08fbf3931e4b7453..586242b53bbf4ceb9bad5c9c8b495f83cb088cda 100644 +index a160164a33903408d60d6e8a57462a3b8c8623e2..f2b356ef04be557795afe9c356acc4af53fcdf52 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h -@@ -648,7 +648,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -665,7 +665,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. @@ -23,7 +23,7 @@ index 021d1d29368deb330418ff4e08fbf3931e4b7453..586242b53bbf4ceb9bad5c9c8b495f83 #if __has_feature(cxx_thread_local) || defined(_MSC_VER) #define LLVM_THREAD_LOCAL thread_local #else -@@ -656,11 +655,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -673,11 +672,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); // we only need the restricted functionality that provides. #define LLVM_THREAD_LOCAL __thread #endif @@ -36,7 +36,7 @@ index 021d1d29368deb330418ff4e08fbf3931e4b7453..586242b53bbf4ceb9bad5c9c8b495f83 /// \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 d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780ca021bf2 100644 +index fc9d118e85508cdf86553bb63cce4a1c567045b7..7ab8a97bb85929615fc751a1eda1fee62004a26f 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -15,7 +15,6 @@ @@ -46,8 +46,8 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 -#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" - #include "llvm/Support/Error.h" -@@ -45,7 +44,6 @@ static void *ErrorHandlerUserData = nullptr; + #include "llvm/Support/Errno.h" +@@ -46,7 +45,6 @@ static void *ErrorHandlerUserData = nullptr; static fatal_error_handler_t BadAllocErrorHandler = nullptr; static void *BadAllocErrorHandlerUserData = nullptr; @@ -55,12 +55,16 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 // 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. -@@ -59,22 +57,17 @@ static void *BadAllocErrorHandlerUserData = nullptr; +@@ -60,7 +58,6 @@ static void *BadAllocErrorHandlerUserData = nullptr; // builds. We can remove these ifdefs if that script goes away. static std::mutex ErrorHandlerMutex; static std::mutex BadAllocErrorHandlerMutex; -#endif + static bool write_retry(int fd, const char *buf, size_t count) { + while (count > 0) { +@@ -75,18 +72,14 @@ static bool write_retry(int fd, const char *buf, size_t count) { + void llvm::install_fatal_error_handler(fatal_error_handler_t handler, void *user_data) { -#if LLVM_ENABLE_THREADS == 1 @@ -80,7 +84,7 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 ErrorHandler = nullptr; ErrorHandlerUserData = nullptr; } -@@ -93,9 +86,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { +@@ -105,9 +98,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. @@ -91,7 +95,7 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 handler = ErrorHandler; handlerData = ErrorHandlerUserData; } -@@ -127,9 +118,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { +@@ -157,9 +148,7 @@ void llvm::reportFatalUsageError(std::string_view reason) { void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, void *user_data) { @@ -102,7 +106,7 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 assert(!BadAllocErrorHandler && "Bad alloc error handler already registered!\n"); BadAllocErrorHandler = handler; -@@ -137,9 +126,7 @@ void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, +@@ -167,9 +156,7 @@ void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, } void llvm::remove_bad_alloc_error_handler() { @@ -113,7 +117,7 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 BadAllocErrorHandler = nullptr; BadAllocErrorHandlerUserData = nullptr; } -@@ -150,9 +137,7 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { +@@ -180,9 +167,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. @@ -124,7 +128,7 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 Handler = BadAllocErrorHandler; HandlerData = BadAllocErrorHandlerUserData; } -@@ -162,10 +147,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { +@@ -192,10 +177,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { llvm_unreachable("bad alloc handler should not return"); } @@ -135,9 +139,9 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 // 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"; -@@ -174,15 +155,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { - (void)!::write(2, Reason, strlen(Reason)); - (void)!::write(2, Newline, strlen(Newline)); +@@ -204,15 +185,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { + write_retry(2, Reason, strlen(Reason)); + write_retry(2, Newline, strlen(Newline)); abort(); -#endif } @@ -151,7 +155,7 @@ index d4ca266f3c1f98337499fba4fd0675e49a7dcf18..4e1dca80a21881bfb8fa886a5921c780 // 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() { -@@ -197,7 +171,6 @@ void llvm::install_out_of_memory_new_handler() { +@@ -227,7 +201,6 @@ void llvm::install_out_of_memory_new_handler() { assert((old == nullptr || old == out_of_memory_new_handler) && "new-handler already installed"); } diff --git a/upstream_utils/llvm_patches/0005-ifdef-guard-safety.patch b/upstream_utils/llvm_patches/0005-ifdef-guard-safety.patch index 3ef68089e0..b5ce14251f 100644 --- a/upstream_utils/llvm_patches/0005-ifdef-guard-safety.patch +++ b/upstream_utils/llvm_patches/0005-ifdef-guard-safety.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:28:13 -0400 -Subject: [PATCH 05/36] \#ifdef guard safety +Subject: [PATCH 05/33] \#ifdef guard safety Prevents redefinition if someone is pulling in real LLVM, since the macros are in global namespace --- @@ -9,10 +9,10 @@ Prevents redefinition if someone is pulling in real LLVM, since the macros are i 1 file changed, 42 insertions(+) diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48c55b18eb 100644 +index f2b356ef04be557795afe9c356acc4af53fcdf52..e6cd94157803dea836c13195a4d5f795b5d1c8a6 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h -@@ -86,6 +86,7 @@ +@@ -90,6 +90,7 @@ /// * 1928: VS2019, version 16.8 + 16.9 /// * 1929: VS2019, version 16.10 + 16.11 /// * 1930: VS2022, version 17.0 @@ -20,7 +20,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #ifdef _MSC_VER #define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version)) -@@ -99,6 +100,7 @@ +@@ -103,6 +104,7 @@ #else #define LLVM_MSC_PREREQ(version) 0 #endif @@ -28,8 +28,8 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// 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 -@@ -218,17 +220,21 @@ - #define LLVM_C_ABI LLVM_ABI +@@ -218,11 +220,13 @@ + #define LLVM_ABI_FOR_TEST LLVM_ABI #endif +#ifndef LLVM_PREFETCH @@ -40,6 +40,12 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #endif +#endif + #if __has_attribute(uninitialized) + #define LLVM_ATTRIBUTE_UNINITIALIZED __attribute__((uninitialized)) +@@ -230,11 +234,13 @@ + #define LLVM_ATTRIBUTE_UNINITIALIZED + #endif + +#ifndef LLVM_ATTRIBUTE_USED #if __has_attribute(used) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) @@ -48,9 +54,9 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #endif +#endif - #if defined(__clang__) - #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX))) -@@ -276,11 +282,13 @@ + // Only enabled for clang: + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99587 +@@ -292,11 +298,13 @@ // more portable solution: // (void)unused_var_name; // Prefer cast-to-void wherever it is sufficient. @@ -64,7 +70,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 // FIXME: Provide this for PE/COFF targets. #if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) && \ -@@ -290,6 +298,7 @@ +@@ -306,6 +314,7 @@ #define LLVM_ATTRIBUTE_WEAK #endif @@ -72,7 +78,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 // 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__) -@@ -298,13 +307,16 @@ +@@ -314,13 +323,16 @@ #else #define LLVM_READNONE #endif @@ -89,7 +95,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_attribute(minsize) #define LLVM_ATTRIBUTE_MINSIZE __attribute__((minsize)) -@@ -312,6 +324,7 @@ +@@ -328,6 +340,7 @@ #define LLVM_ATTRIBUTE_MINSIZE #endif @@ -97,7 +103,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #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) -@@ -319,9 +332,11 @@ +@@ -335,9 +348,11 @@ #define LLVM_LIKELY(EXPR) (EXPR) #define LLVM_UNLIKELY(EXPR) (EXPR) #endif @@ -109,7 +115,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_attribute(noinline) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) -@@ -329,9 +344,11 @@ +@@ -345,9 +360,11 @@ #else #define LLVM_ATTRIBUTE_NOINLINE #endif @@ -121,7 +127,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_attribute(always_inline) #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) -@@ -339,6 +356,7 @@ +@@ -355,6 +372,7 @@ #else #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline #endif @@ -129,7 +135,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// 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 -@@ -349,6 +367,7 @@ +@@ -365,6 +383,7 @@ #define LLVM_ATTRIBUTE_NODEBUG #endif @@ -137,7 +143,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_attribute(returns_nonnull) #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #elif defined(_MSC_VER) -@@ -356,6 +375,7 @@ +@@ -372,6 +391,7 @@ #else #define LLVM_ATTRIBUTE_RETURNS_NONNULL #endif @@ -145,7 +151,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// LLVM_ATTRIBUTE_RESTRICT - Annotates a pointer to tell the compiler that /// it is not aliased in the current scope. -@@ -367,6 +387,7 @@ +@@ -383,6 +403,7 @@ /// \macro LLVM_ATTRIBUTE_RETURNS_NOALIAS Used to mark a function as returning a /// pointer that does not alias any other valid pointer. @@ -153,7 +159,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #ifdef __GNUC__ #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) #elif defined(_MSC_VER) -@@ -374,8 +395,10 @@ +@@ -390,8 +411,10 @@ #else #define LLVM_ATTRIBUTE_RETURNS_NOALIAS #endif @@ -164,7 +170,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough) #define LLVM_FALLTHROUGH [[fallthrough]] #elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough) -@@ -387,6 +410,7 @@ +@@ -403,6 +426,7 @@ #else #define LLVM_FALLTHROUGH #endif @@ -172,7 +178,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that /// they are constant initialized. -@@ -427,11 +451,13 @@ +@@ -443,11 +467,13 @@ /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress /// pedantic diagnostics. @@ -186,7 +192,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands /// to an expression which states that it is undefined behavior for the -@@ -440,14 +466,17 @@ +@@ -456,14 +482,17 @@ /// '#else' is intentionally left out so that other macro logic (e.g., /// LLVM_ASSUME_ALIGNED and llvm_unreachable()) can detect whether /// LLVM_BUILTIN_UNREACHABLE has a definition. @@ -204,7 +210,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_builtin(__builtin_trap) || defined(__GNUC__) # define LLVM_BUILTIN_TRAP __builtin_trap() #elif defined(_MSC_VER) -@@ -459,10 +488,12 @@ +@@ -475,10 +504,12 @@ #else # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 #endif @@ -217,7 +223,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_builtin(__builtin_debugtrap) # define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap() #elif defined(_MSC_VER) -@@ -476,9 +507,11 @@ +@@ -492,9 +523,11 @@ // program to abort if encountered. # define LLVM_BUILTIN_DEBUGTRAP #endif @@ -229,7 +235,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) #elif defined(LLVM_BUILTIN_UNREACHABLE) -@@ -487,6 +520,7 @@ +@@ -503,6 +536,7 @@ #else # define LLVM_ASSUME_ALIGNED(p, a) (p) #endif @@ -237,7 +243,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// \macro LLVM_PACKED /// Used to specify a packed structure. -@@ -506,6 +540,7 @@ +@@ -522,6 +556,7 @@ /// long long l; /// }; /// LLVM_PACKED_END @@ -245,7 +251,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #ifdef _MSC_VER # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop)) # define LLVM_PACKED_START __pragma(pack(push, 1)) -@@ -515,6 +550,7 @@ +@@ -531,6 +566,7 @@ # define LLVM_PACKED_START _Pragma("pack(push, 1)") # define LLVM_PACKED_END _Pragma("pack(pop)") #endif @@ -253,7 +259,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// \macro LLVM_MEMORY_SANITIZER_BUILD /// Whether LLVM itself is built with MemorySanitizer instrumentation. -@@ -606,11 +642,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -622,11 +658,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); /// \macro LLVM_NO_SANITIZE /// Disable a particular sanitizer for a function. @@ -267,13 +273,14 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 /// Mark debug helper function definitions like dump() that should not be /// stripped from debug builds. -@@ -618,17 +656,20 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -634,18 +672,21 @@ 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 + #define LLVM_DUMP_METHOD \ + LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED LLVM_ATTRIBUTE_RETAIN #else #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE #endif @@ -288,7 +295,7 @@ index 586242b53bbf4ceb9bad5c9c8b495f83cb088cda..1d601fbc5d8d80d88e2da98a1874fb48 #if defined(_MSC_VER) #define LLVM_PRETTY_FUNCTION __FUNCSIG__ #elif defined(__GNUC__) || defined(__clang__) -@@ -636,6 +677,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -653,6 +694,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #else #define LLVM_PRETTY_FUNCTION __func__ #endif diff --git a/upstream_utils/llvm_patches/0006-Explicitly-use-std.patch b/upstream_utils/llvm_patches/0006-Explicitly-use-std.patch index 7cdf6d48d8..adf7562b44 100644 --- a/upstream_utils/llvm_patches/0006-Explicitly-use-std.patch +++ b/upstream_utils/llvm_patches/0006-Explicitly-use-std.patch @@ -1,20 +1,69 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:37:34 -0400 -Subject: [PATCH 06/36] Explicitly use std:: +Subject: [PATCH 06/33] Explicitly use std:: --- + llvm/include/llvm/ADT/DenseMap.h | 11 ++++++----- llvm/include/llvm/ADT/SmallSet.h | 2 +- llvm/lib/Support/ErrorHandling.cpp | 2 +- + llvm/lib/Support/SmallPtrSet.cpp | 7 +++---- llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 +- llvm/unittests/ADT/SmallSetTest.cpp | 10 +++++----- - 4 files changed, 8 insertions(+), 8 deletions(-) + 6 files changed, 17 insertions(+), 17 deletions(-) +diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h +index d207a515ef05425f924920a8d06d7c65d33e0909..37d8970209dcedf8840324a376ab27b3ba3bdf6a 100644 +--- a/llvm/include/llvm/ADT/DenseMap.h ++++ b/llvm/include/llvm/ADT/DenseMap.h +@@ -17,8 +17,8 @@ + #include "llvm/ADT/ADL.h" + #include "llvm/ADT/DenseMapInfo.h" + #include "llvm/ADT/EpochTracker.h" +-#include "llvm/ADT/STLExtras.h" + #include "llvm/ADT/STLForwardCompat.h" ++#include "llvm/ADT/iterator_range.h" + #include "llvm/Support/AlignOf.h" + #include "llvm/Support/Compiler.h" + #include "llvm/Support/MathExtras.h" +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -90,20 +91,20 @@ public: + + // Return an iterator to iterate over keys in the map. + [[nodiscard]] inline auto keys() { +- return map_range(*this, [](const BucketT &P) { return P.getFirst(); }); ++ return std::views::transform(*this, [](const BucketT &P) { return P.getFirst(); }); + } + + // Return an iterator to iterate over values in the map. + [[nodiscard]] inline auto values() { +- return map_range(*this, [](const BucketT &P) { return P.getSecond(); }); ++ return std::views::transform(*this, [](const BucketT &P) { return P.getSecond(); }); + } + + [[nodiscard]] inline auto keys() const { +- return map_range(*this, [](const BucketT &P) { return P.getFirst(); }); ++ return std::views::transform(*this, [](const BucketT &P) { return P.getFirst(); }); + } + + [[nodiscard]] inline auto values() const { +- return map_range(*this, [](const BucketT &P) { return P.getSecond(); }); ++ return std::views::transform(*this, [](const BucketT &P) { return P.getSecond(); }); + } + + [[nodiscard]] bool empty() const { return getNumEntries() == 0; } diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h -index ed3c6bfd3418d70a92eb602d0eb3e5d88da2a095..c62a3a55d9bda188670e7d6042867943dcd44c68 100644 +index 3ca833f15eed37a4df2f8de37bcc4582d30581c4..2bc8ed01ff84671b5246a0dee42a76f086bb4687 100644 --- a/llvm/include/llvm/ADT/SmallSet.h +++ b/llvm/include/llvm/ADT/SmallSet.h -@@ -280,7 +280,7 @@ bool operator==(const SmallSet &LHS, const SmallSet &RHS) { +@@ -287,7 +287,7 @@ template return false; // All elements in LHS must also be in RHS @@ -24,10 +73,10 @@ index ed3c6bfd3418d70a92eb602d0eb3e5d88da2a095..c62a3a55d9bda188670e7d6042867943 /// Inequality comparison for SmallSet. diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index 4e1dca80a21881bfb8fa886a5921c780ca021bf2..4de36d969b3776b72ff85888355b64f7f3262ccc 100644 +index 7ab8a97bb85929615fc751a1eda1fee62004a26f..fcbc70535bf9869f72d001ec214d7046e975961a 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -249,7 +249,7 @@ std::error_code llvm::mapLastWindowsError() { +@@ -279,7 +279,7 @@ std::error_code llvm::mapLastWindowsError() { // I'd rather not double the line count of the following. #define MAP_ERR_TO_COND(x, y) \ case x: \ @@ -36,8 +85,47 @@ index 4e1dca80a21881bfb8fa886a5921c780ca021bf2..4de36d969b3776b72ff85888355b64f7 std::error_code llvm::mapWindowsError(unsigned EV) { switch (EV) { +diff --git a/llvm/lib/Support/SmallPtrSet.cpp b/llvm/lib/Support/SmallPtrSet.cpp +index e377dbf4a6999173ee0d04644ec5ee07e204d14d..9a8f99e4df164920d646909e614734894010047b 100644 +--- a/llvm/lib/Support/SmallPtrSet.cpp ++++ b/llvm/lib/Support/SmallPtrSet.cpp +@@ -13,7 +13,6 @@ + + #include "llvm/ADT/SmallPtrSet.h" + #include "llvm/ADT/DenseMapInfo.h" +-#include "llvm/ADT/STLExtras.h" + #include "llvm/Support/MathExtras.h" + #include "llvm/Support/MemAlloc.h" + #include +@@ -191,7 +190,7 @@ void SmallPtrSetImplBase::copyHelper(const SmallPtrSetImplBase &RHS) { + CurArraySize = RHS.CurArraySize; + + // Copy over the contents from the other set +- llvm::copy(RHS.buckets(), CurArray); ++ std::ranges::copy(RHS.buckets(), CurArray); + + NumEntries = RHS.NumEntries; + NumTombstones = RHS.NumTombstones; +@@ -215,7 +214,7 @@ void SmallPtrSetImplBase::moveHelper(const void **SmallStorage, + if (RHS.isSmall()) { + // Copy a small RHS rather than moving. + CurArray = SmallStorage; +- llvm::copy(RHS.small_buckets(), CurArray); ++ std::ranges::copy(RHS.small_buckets(), CurArray); + } else { + CurArray = RHS.CurArray; + RHS.CurArray = RHSSmallStorage; +@@ -273,7 +272,7 @@ void SmallPtrSetImplBase::swap(const void **SmallStorage, + SmallPtrSetImplBase &LargeSide = this->isSmall() ? RHS : *this; + const void **LargeSideInlineStorage = + this->isSmall() ? RHSSmallStorage : SmallStorage; +- llvm::copy(SmallSide.small_buckets(), LargeSideInlineStorage); ++ std::ranges::copy(SmallSide.small_buckets(), LargeSideInlineStorage); + std::swap(LargeSide.CurArraySize, SmallSide.CurArraySize); + std::swap(LargeSide.NumEntries, SmallSide.NumEntries); + std::swap(LargeSide.NumTombstones, SmallSide.NumTombstones); diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp -index 88be2b68915573a3b3a343ff53a84d86604d7bfd..65c0c564e91a40a98432d985c6949d3d4aa0717d 100644 +index a25c07c08bbbba7b9edaa36adc5f9eaec14ea98d..bbe18dffdcf32d1bd71e756bccca74f1fcee5d0c 100644 --- a/llvm/unittests/ADT/SmallPtrSetTest.cpp +++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp @@ -261,7 +261,7 @@ TEST(SmallPtrSetTest, dereferenceAndIterate) { @@ -50,7 +138,7 @@ index 88be2b68915573a3b3a343ff53a84d86604d7bfd..65c0c564e91a40a98432d985c6949d3d EXPECT_EQ(F - Found + 1, *F); } diff --git a/llvm/unittests/ADT/SmallSetTest.cpp b/llvm/unittests/ADT/SmallSetTest.cpp -index 2feb0b1feb421bf734e6433ccce3d94dd2b0aeca..65d5998c63d9d7dd69c5a7054bcd82c4ce5d725f 100644 +index 1d1e84ba7fcfd7aa528239a809fce5ede78618c1..7cb7e6c9d8482ed185845c6b09e4b91355d9b413 100644 --- a/llvm/unittests/ADT/SmallSetTest.cpp +++ b/llvm/unittests/ADT/SmallSetTest.cpp @@ -11,9 +11,9 @@ @@ -64,7 +152,7 @@ index 2feb0b1feb421bf734e6433ccce3d94dd2b0aeca..65d5998c63d9d7dd69c5a7054bcd82c4 #include using namespace llvm; -@@ -180,7 +180,7 @@ TEST(SmallSetTest, IteratorInt) { +@@ -186,7 +186,7 @@ TEST(SmallSetTest, IteratorInt) { std::vector V(s1.begin(), s1.end()); // Make sure the elements are in the expected order. @@ -73,7 +161,7 @@ index 2feb0b1feb421bf734e6433ccce3d94dd2b0aeca..65d5998c63d9d7dd69c5a7054bcd82c4 for (int i = 0; i < 3; i++) EXPECT_EQ(i, V[i]); -@@ -191,7 +191,7 @@ TEST(SmallSetTest, IteratorInt) { +@@ -197,7 +197,7 @@ TEST(SmallSetTest, IteratorInt) { V.assign(s1.begin(), s1.end()); // Make sure the elements are in the expected order. @@ -82,7 +170,7 @@ index 2feb0b1feb421bf734e6433ccce3d94dd2b0aeca..65d5998c63d9d7dd69c5a7054bcd82c4 for (int i = 0; i < 6; i++) EXPECT_EQ(i, V[i]); } -@@ -206,7 +206,7 @@ TEST(SmallSetTest, IteratorString) { +@@ -212,7 +212,7 @@ TEST(SmallSetTest, IteratorString) { s1.insert("str 1"); std::vector V(s1.begin(), s1.end()); @@ -91,7 +179,7 @@ index 2feb0b1feb421bf734e6433ccce3d94dd2b0aeca..65d5998c63d9d7dd69c5a7054bcd82c4 EXPECT_EQ(2u, s1.size()); EXPECT_EQ("str 1", V[0]); EXPECT_EQ("str 2", V[1]); -@@ -217,7 +217,7 @@ TEST(SmallSetTest, IteratorString) { +@@ -223,7 +223,7 @@ TEST(SmallSetTest, IteratorString) { V.assign(s1.begin(), s1.end()); // Make sure the elements are in the expected order. diff --git a/upstream_utils/llvm_patches/0007-Remove-format_provider.patch b/upstream_utils/llvm_patches/0007-Remove-format_provider.patch index 6283d65222..d56171c2b1 100644 --- a/upstream_utils/llvm_patches/0007-Remove-format_provider.patch +++ b/upstream_utils/llvm_patches/0007-Remove-format_provider.patch @@ -1,16 +1,16 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sat, 7 May 2022 22:53:50 -0400 -Subject: [PATCH 07/36] Remove format_provider +Subject: [PATCH 07/33] Remove format_provider --- - llvm/include/llvm/Support/Chrono.h | 114 ------------------------ + llvm/include/llvm/Support/Chrono.h | 126 ------------------------ llvm/include/llvm/Support/raw_ostream.h | 6 -- - llvm/unittests/Support/Chrono.cpp | 67 -------------- - 3 files changed, 187 deletions(-) + llvm/unittests/Support/Chrono.cpp | 67 ------------- + 3 files changed, 199 deletions(-) diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h -index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b18ece4cd7 100644 +index dae64305f2b41766bb7bf9cf49b5d672b91f9493..0e1b490a908de2daf3d7a5c8bbcd1e6beff1a536 100644 --- a/llvm/include/llvm/Support/Chrono.h +++ b/llvm/include/llvm/Support/Chrono.h @@ -10,7 +10,6 @@ @@ -21,9 +21,9 @@ index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b1 #include #include -@@ -80,119 +79,6 @@ toTimePoint(std::time_t T, uint32_t nsec) { - raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP); - raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP); +@@ -80,131 +79,6 @@ toTimePoint(std::time_t T, uint32_t nsec) { + LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP); + LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP); -/// Format provider for TimePoint<> -/// @@ -35,25 +35,37 @@ index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b1 -/// If no options are given, the default format is "%Y-%m-%d %H:%M:%S.%N". -template <> -struct format_provider> { -- static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS, -- std::string_view Style); +- LLVM_ABI static void format(const sys::TimePoint<> &TP, llvm::raw_ostream &OS, +- std::string_view Style); -}; - -template <> struct format_provider> { -- static void format(const sys::UtcTime &TP, -- llvm::raw_ostream &OS, StringRef Style); +- LLVM_ABI static void format(const sys::UtcTime &TP, +- llvm::raw_ostream &OS, std::string_view Style); -}; - -namespace detail { -template struct unit { static const char value[]; }; -template const char unit::value[] = ""; - --template <> struct unit> { static const char value[]; }; --template <> struct unit> { static const char value[]; }; --template <> struct unit> { static const char value[]; }; --template <> struct unit { static const char value[]; }; --template <> struct unit { static const char value[]; }; --template <> struct unit { static const char value[]; }; +-template <> struct unit> { +- LLVM_ABI static const char value[]; +-}; +-template <> struct unit> { +- LLVM_ABI static const char value[]; +-}; +-template <> struct unit> { +- LLVM_ABI static const char value[]; +-}; +-template <> struct unit { +- LLVM_ABI static const char value[]; +-}; +-template <> struct unit { +- LLVM_ABI static const char value[]; +-}; +-template <> struct unit { +- LLVM_ABI static const char value[]; +-}; -} // namespace detail - -/// Implementation of format_provider for duration types. @@ -83,10 +95,10 @@ index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b1 -template -struct format_provider> { -private: -- typedef std::chrono::duration Dur; -- typedef std::conditional_t::value, -- double, intmax_t> -- InternalRep; +- using Dur = std::chrono::duration; +- using InternalRep = +- std::conditional_t::value, +- double, intmax_t>; - - template static InternalRep getAs(const Dur &D) { - using namespace std::chrono; @@ -142,10 +154,10 @@ index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b1 #endif // LLVM_SUPPORT_CHRONO_H diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index c43c68c9114d8cd564484b190456b0069818dc87..96b7a2463e2336a0f61a03ce11cf643bc253f422 100644 +index 19df8739b6013c1b1a1527f5880a040d3cfb478f..856b9f9342f1ca9ee358af2bf4998f506a9d539a 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -27,12 +27,6 @@ +@@ -28,12 +28,6 @@ namespace llvm { diff --git a/upstream_utils/llvm_patches/0008-Add-compiler-warning-pragmas.patch b/upstream_utils/llvm_patches/0008-Add-compiler-warning-pragmas.patch index 374c92a4f0..1aa55d3548 100644 --- a/upstream_utils/llvm_patches/0008-Add-compiler-warning-pragmas.patch +++ b/upstream_utils/llvm_patches/0008-Add-compiler-warning-pragmas.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 13:34:07 -0400 -Subject: [PATCH 08/36] Add compiler warning pragmas +Subject: [PATCH 08/33] Add compiler warning pragmas --- llvm/include/llvm/ADT/FunctionExtras.h | 11 +++++++++++ - llvm/include/llvm/ADT/SmallVector.h | 8 ++++++++ + llvm/include/llvm/ADT/SmallVector.h | 9 +++++++++ llvm/include/llvm/Support/MathExtras.h | 9 +++++++++ llvm/include/llvm/Support/MemAlloc.h | 13 +++++++++++++ llvm/lib/Support/raw_ostream.cpp | 4 ++++ @@ -13,13 +13,13 @@ Subject: [PATCH 08/36] Add compiler warning pragmas llvm/unittests/ADT/FunctionExtrasTest.cpp | 6 ++++++ llvm/unittests/ADT/SmallVectorTest.cpp | 4 ++++ llvm/unittests/Support/AlignOfTest.cpp | 7 +++---- - 9 files changed, 62 insertions(+), 4 deletions(-) + 9 files changed, 63 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h -index df7fe3e19462ebecd30f7a9d006027c75751de5b..28a9ba756a4075987fbee28c6ed6387e99dfd14b 100644 +index c4d0821076d63842927d2abeef4a5189cdf325e7..730822d37c62b992316c850021dc5edb8ff13c36 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h -@@ -56,6 +56,13 @@ namespace llvm { +@@ -55,6 +55,13 @@ namespace llvm { /// It can hold functions with a non-const operator(), like mutable lambdas. template class unique_function; @@ -32,8 +32,8 @@ index df7fe3e19462ebecd30f7a9d006027c75751de5b..28a9ba756a4075987fbee28c6ed6387e + namespace detail { - template -@@ -414,6 +421,10 @@ public: + template +@@ -391,6 +398,10 @@ public: } }; @@ -45,13 +45,14 @@ index df7fe3e19462ebecd30f7a9d006027c75751de5b..28a9ba756a4075987fbee28c6ed6387e #endif // LLVM_ADT_FUNCTIONEXTRAS_H diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index 2232b741d5359a129adb0e5b3f0f70110c38e90d..3cab284f5b6105956d6fff49a27d37482a3c321d 100644 +index e27d0d71ec6176ee8081660f9ed6ba6672d7828d..913be7105222efb45015485fc04c0ab984dbe638 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 +@@ -16,6 +16,15 @@ + #include "llvm/ADT/ADL.h" + #include "llvm/ADT/DenseMapInfo.h" ++ +// This file uses std::memcpy() to copy std::pair. +// 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 @@ -64,10 +65,10 @@ index 2232b741d5359a129adb0e5b3f0f70110c38e90d..3cab284f5b6105956d6fff49a27d3748 #include #include diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index 5db59bb848024fca622b2919efd773d185a93f1e..b2c62d833038f92d2621ca2e6838d0d6b3b48760 100644 +index 120a1641110aca97acf2ab9cd3806d94accbb8aa..78c500e18c7639afc02b595b788333b6b9a4e69b 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -232,6 +232,11 @@ inline uint64_t maxUIntN(uint64_t N) { +@@ -219,6 +219,11 @@ inline constexpr uint64_t maxUIntN(uint64_t N) { return UINT64_MAX >> (64 - N); } @@ -77,10 +78,10 @@ index 5db59bb848024fca622b2919efd773d185a93f1e..b2c62d833038f92d2621ca2e6838d0d6 +#endif + /// Gets the minimum value for a N-bit signed integer. - inline int64_t minIntN(int64_t N) { + inline constexpr int64_t minIntN(int64_t N) { assert(N <= 64 && "integer width out of range"); -@@ -241,6 +246,10 @@ inline int64_t minIntN(int64_t N) { - return UINT64_C(1) + ~(UINT64_C(1) << (N - 1)); +@@ -228,6 +233,10 @@ inline constexpr int64_t minIntN(int64_t N) { + return UINT64_MAX << (N - 1); } +#ifdef _WIN32 @@ -88,10 +89,10 @@ index 5db59bb848024fca622b2919efd773d185a93f1e..b2c62d833038f92d2621ca2e6838d0d6 +#endif + /// Gets the maximum value for a N-bit signed integer. - inline int64_t maxIntN(int64_t N) { + inline constexpr int64_t maxIntN(int64_t N) { assert(N <= 64 && "integer width out of range"); diff --git a/llvm/include/llvm/Support/MemAlloc.h b/llvm/include/llvm/Support/MemAlloc.h -index f3f378b7697a18f57b189c5322b080fe23d45bec..0028e871f6a05baf6172c60c602b8b26e5f116c6 100644 +index 3b086cb171806f3f216a9bac7de46a29da3c5481..9205299d1cc7ddc93d2d5781e744305679ff39c8 100644 --- a/llvm/include/llvm/Support/MemAlloc.h +++ b/llvm/include/llvm/Support/MemAlloc.h @@ -22,6 +22,14 @@ @@ -110,7 +111,7 @@ index f3f378b7697a18f57b189c5322b080fe23d45bec..0028e871f6a05baf6172c60c602b8b26 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); + LLVM_ABI void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment); } // namespace llvm + @@ -120,7 +121,7 @@ index f3f378b7697a18f57b189c5322b080fe23d45bec..0028e871f6a05baf6172c60c602b8b26 + #endif diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 681b6fdc95eb4fda4f23d0b381b83417d82b3b78..a75abb7a4abf71e214ea6342352cfbaa5ce3ea27 100644 +index bf5d06018979474cf6166fed61be93eede0dece1..5496df7f6f83debb8b13bb9b828cdbddab91b07b 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -10,6 +10,10 @@ @@ -135,7 +136,7 @@ index 681b6fdc95eb4fda4f23d0b381b83417d82b3b78..a75abb7a4abf71e214ea6342352cfbaa #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp -index e93e18423507655ce8275a0718d8e5d01915985f..b930a21f8b43b64835436fcd27f4802a7987827f 100644 +index fffa07e1978bb3b8c2013073bdd58556d145ff23..1a81ecdd758ce285533fcb0565713f30a6cef33e 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp @@ -6,6 +6,10 @@ @@ -150,10 +151,10 @@ index e93e18423507655ce8275a0718d8e5d01915985f..b930a21f8b43b64835436fcd27f4802a #include "CountCopyAndMove.h" #include "llvm/ADT/DenseMapInfo.h" diff --git a/llvm/unittests/ADT/FunctionExtrasTest.cpp b/llvm/unittests/ADT/FunctionExtrasTest.cpp -index 777c5784949fd3c07bbbcef8dc3fc8e5764896a9..3777eedff54639f0380218eaad767f27f1958a67 100644 +index e92f5fcdfce0175eea843e81ef89604e0c2297f6..3a2008adb0697757c68af8ad462b9af716c456a6 100644 --- a/llvm/unittests/ADT/FunctionExtrasTest.cpp +++ b/llvm/unittests/ADT/FunctionExtrasTest.cpp -@@ -330,6 +330,12 @@ TEST(UniqueFunctionTest, InlineStorageWorks) { +@@ -329,6 +329,12 @@ TEST(UniqueFunctionTest, InlineStorageWorks) { UniqueFunctionWithInlineStorage(&UniqueFunctionWithInlineStorage); } @@ -167,10 +168,10 @@ index 777c5784949fd3c07bbbcef8dc3fc8e5764896a9..3777eedff54639f0380218eaad767f27 // move construction/assignment. TEST(UniqueFunctionTest, MovedFromStateIsDestroyedCorrectly) { diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp -index 7029038d18d433cef987bedbfa4fda269b24fb8f..f8c37820ef9fdfe0af067f5aa8d2297ed15e73bc 100644 +index f83bc116e4851f39fd6e496ee25ae1fb9acd96ca..5589671f7909d1994626c3f0ad043e64ef9768ab 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp -@@ -17,6 +17,10 @@ +@@ -18,6 +18,10 @@ #include #include @@ -182,13 +183,13 @@ index 7029038d18d433cef987bedbfa4fda269b24fb8f..f8c37820ef9fdfe0af067f5aa8d2297e namespace { diff --git a/llvm/unittests/Support/AlignOfTest.cpp b/llvm/unittests/Support/AlignOfTest.cpp -index f84895c18602d3936d623ed79c5d9689cd57cc91..6a50205b143b7ff553066f048a45bf4e1ecc475b 100644 +index 53358a2815daa4d6d55e01b4d286b962d3d947e5..d297da14525295fb5b6d60d2017de177cc48bcf7 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 + #elif defined(__GNUC__) -// 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. diff --git a/upstream_utils/llvm_patches/0009-Remove-unused-functions.patch b/upstream_utils/llvm_patches/0009-Remove-unused-functions.patch index 6908a9164d..44a6306121 100644 --- a/upstream_utils/llvm_patches/0009-Remove-unused-functions.patch +++ b/upstream_utils/llvm_patches/0009-Remove-unused-functions.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 13:43:50 -0400 -Subject: [PATCH 09/36] Remove unused functions +Subject: [PATCH 09/33] Remove unused functions --- llvm/include/llvm/ADT/SmallString.h | 77 ------ @@ -114,10 +114,10 @@ index 9fab1a7726bc6745296f5ebb24aee4055408e5f5..cb6136d8fd1886e8dc444cb807b33a5f // Extra methods. diff --git a/llvm/include/llvm/Support/Errno.h b/llvm/include/llvm/Support/Errno.h -index e095c66b90860001d90b5c2eb74f6032de6de454..787805dac6c5e3c8cb85dabeb80254443d60806c 100644 +index 64817257141bbc03098624437731d31ce66f7ce8..409f39a0b2d658bd6cefc75c68cec3ccceda98c9 100644 --- a/llvm/include/llvm/Support/Errno.h +++ b/llvm/include/llvm/Support/Errno.h -@@ -19,15 +19,6 @@ +@@ -20,15 +20,6 @@ namespace llvm { namespace sys { @@ -125,19 +125,19 @@ index e095c66b90860001d90b5c2eb74f6032de6de454..787805dac6c5e3c8cb85dabeb8025444 -/// 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(); +-LLVM_ABI std::string StrError(); - -/// Like the no-argument version above, but uses \p errnum instead of errno. --std::string StrError(int errnum); +-LLVM_ABI std::string StrError(int errnum); - template 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 e1cdce77ce8659305c99a21e01f9b3cc3481a5fd..9102ff063afedc03bd524b2805cba98ea5afeba8 100644 +index 32c3ad9a9fc2c9827dc4afd81c6f9d03ec1b25c2..735f73d0447fb35fc64a0f449b45bab19947bf58 100644 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h -@@ -166,45 +166,6 @@ public: +@@ -165,45 +165,6 @@ public: friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) { return !(X < Y); } @@ -153,11 +153,11 @@ index e1cdce77ce8659305c99a21e01f9b3cc3481a5fd..9102ff063afedc03bd524b2805cba98e - } - - /// Retrieve a string representation of the version number. -- std::string getAsString() const; +- LLVM_ABI std::string getAsString() const; -}; - -/// Print a version number. --raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V); +-LLVM_ABI raw_ostream &operator<<(raw_ostream &Out, const VersionTuple &V); - -// Provide DenseMapInfo for version tuples. -template <> struct DenseMapInfo { @@ -184,10 +184,10 @@ index e1cdce77ce8659305c99a21e01f9b3cc3481a5fd..9102ff063afedc03bd524b2805cba98e } // end namespace llvm diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d74819e794a3c 100644 +index 856b9f9342f1ca9ee358af2bf4998f506a9d539a..f346d36ca7a36ab2d9bcddc205db0abf50c2a136 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -274,32 +274,6 @@ public: +@@ -275,32 +275,6 @@ public: return write(Str.data(), Str.size()); } @@ -220,7 +220,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 /// 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); -@@ -307,21 +281,6 @@ public: +@@ -308,21 +282,6 @@ public: raw_ostream &write(unsigned char C); raw_ostream &write(const char *Ptr, size_t Size); @@ -242,7 +242,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 /// indent - Insert 'NumSpaces' spaces. raw_ostream &indent(unsigned NumSpaces); -@@ -336,14 +295,19 @@ public: +@@ -337,14 +296,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, @@ -265,7 +265,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 /// This function determines if this stream is connected to a "tty" or /// "console" window. That is, the output would be displayed to the user -@@ -414,10 +378,6 @@ private: +@@ -415,10 +379,6 @@ private: /// unused bytes in the buffer. void copy_to_buffer(const char *Ptr, size_t Size); @@ -276,7 +276,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 virtual void anchor(); }; -@@ -466,7 +426,6 @@ class raw_fd_ostream : public raw_pwrite_stream { +@@ -467,7 +427,6 @@ class LLVM_ABI raw_fd_ostream : public raw_pwrite_stream { bool ShouldClose; bool SupportsSeeking = false; bool IsRegularFile = false; @@ -284,7 +284,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 /// Optional stream this stream is tied to. If this stream is written to, the /// tied-to stream will be flushed first. -@@ -546,10 +505,6 @@ public: +@@ -547,10 +506,6 @@ public: /// to the offset specified from the beginning of the file. uint64_t seek(uint64_t off); @@ -295,7 +295,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 /// Tie this stream to the specified stream. Replaces any existing tied-to /// stream. Specifying a nullptr unties the stream. This is intended for to /// tie errs() to outs(), so that outs() is flushed whenever something is -@@ -575,38 +530,6 @@ public: +@@ -576,38 +531,6 @@ public: /// - from The Zen of Python, by Tim Peters /// void clear_error() { EC = std::error_code(); } @@ -334,11 +334,11 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 }; /// This returns a reference to a raw_fd_ostream for standard output. Use it -@@ -636,19 +559,6 @@ public: +@@ -637,19 +560,6 @@ public: /// immediately destroyed. - raw_fd_stream(std::string_view Filename, std::error_code &EC); + LLVM_ABI raw_fd_stream(std::string_view Filename, std::error_code &EC); -- raw_fd_stream(int fd, bool shouldClose); +- LLVM_ABI raw_fd_stream(int fd, bool shouldClose); - - /// This reads the \p Size bytes into a buffer pointed by \p Ptr. - /// @@ -349,12 +349,12 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 - /// 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); +- LLVM_ABI 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); + LLVM_ABI static bool classof(const raw_ostream *OS); }; -@@ -773,87 +683,6 @@ public: +@@ -774,87 +684,6 @@ public: ~buffer_unique_ostream() override { *OS << str(); } }; @@ -424,10 +424,10 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 -/// 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 Write); +-LLVM_ABI Error writeToOutput(std::string_view OutputFileName, +- std::function Write); - --raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); +-LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); - -template () - << std::declval())> @@ -443,7 +443,7 @@ index 96b7a2463e2336a0f61a03ce11cf643bc253f422..fed78518c3b6c44b366d04f45a1d7481 #endif // LLVM_SUPPORT_RAW_OSTREAM_H diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0e3fcf848 100644 +index 5496df7f6f83debb8b13bb9b828cdbddab91b07b..32f5d5fb78b1a9e4288b875c64ded0040d6fdce6 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -19,7 +19,6 @@ @@ -454,7 +454,7 @@ index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0 #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" -@@ -126,49 +125,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, +@@ -116,49 +115,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, assert(OutBufStart <= OutBufEnd && "Invalid size!"); } @@ -504,7 +504,7 @@ index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0 raw_ostream &raw_ostream::write_escaped(std::string_view Str, bool UseHexEscapes) { for (unsigned char c : Str) { -@@ -308,173 +264,6 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) { +@@ -298,173 +254,6 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) { OutBufCur += Size; } @@ -678,7 +678,7 @@ index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0 template static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) { static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, -@@ -505,63 +294,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) { +@@ -495,63 +284,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) { return write_padding<'\0'>(*this, NumZeros); } @@ -742,7 +742,7 @@ index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0 //===----------------------------------------------------------------------===// // raw_fd_ostream //===----------------------------------------------------------------------===// -@@ -864,31 +598,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const { +@@ -859,31 +593,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const { #endif } @@ -774,7 +774,7 @@ index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0 void raw_fd_ostream::anchor() {} //===----------------------------------------------------------------------===// -@@ -939,19 +648,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC) +@@ -937,19 +646,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC) EC = std::make_error_code(std::errc::invalid_argument); } @@ -794,7 +794,7 @@ index a75abb7a4abf71e214ea6342352cfbaa5ce3ea27..e06253e8f3a16dc09573cdec74cf54e0 bool raw_fd_stream::classof(const raw_ostream *OS) { return OS->get_kind() == OStreamKind::OK_FDStream; } -@@ -1011,31 +707,3 @@ void raw_pwrite_stream::anchor() {} +@@ -1009,31 +705,3 @@ void raw_pwrite_stream::anchor() {} void buffer_ostream::anchor() {} void buffer_unique_ostream::anchor() {} diff --git a/upstream_utils/llvm_patches/0010-Detemplatize-SmallVectorBase.patch b/upstream_utils/llvm_patches/0010-SmallVector-detemplatize-SmallVectorBase.patch similarity index 91% rename from upstream_utils/llvm_patches/0010-Detemplatize-SmallVectorBase.patch rename to upstream_utils/llvm_patches/0010-SmallVector-detemplatize-SmallVectorBase.patch index e6828a33ae..f23af5bf03 100644 --- a/upstream_utils/llvm_patches/0010-Detemplatize-SmallVectorBase.patch +++ b/upstream_utils/llvm_patches/0010-SmallVector-detemplatize-SmallVectorBase.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Thu, 5 May 2022 23:18:34 -0400 -Subject: [PATCH 10/36] Detemplatize SmallVectorBase +Subject: [PATCH 10/33] SmallVector: detemplatize SmallVectorBase --- llvm/include/llvm/ADT/SmallVector.h | 35 ++++++++++------------------- @@ -9,10 +9,10 @@ Subject: [PATCH 10/36] Detemplatize SmallVectorBase 2 files changed, 17 insertions(+), 52 deletions(-) diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbfa53b2939 100644 +index 913be7105222efb45015485fc04c0ab984dbe638..7f759efc1588bfb6eaef65b822bbdbf4f201ef8b 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -56,19 +56,19 @@ using EnableIfConvertibleToInputIterator = std::enable_if_t, where a /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for /// buffering bitcode output - which can exceed 4GB. @@ -37,7 +37,7 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf /// 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 -@@ -94,7 +94,7 @@ protected: +@@ -97,7 +97,7 @@ protected: /// This does not construct or destroy any elements in the vector. void set_size(size_t N) { assert(N <= capacity()); // implies no overflow in assignment @@ -46,7 +46,7 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf } /// Set the array data pointer to \p Begin and capacity to \p N. -@@ -104,19 +104,14 @@ protected: +@@ -107,19 +107,14 @@ protected: void set_allocation_range(void *Begin, size_t N) { assert(N <= SizeTypeMax()); BeginX = Begin; @@ -69,7 +69,7 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf alignas(T) char FirstEl[sizeof(T)]; }; -@@ -125,8 +120,8 @@ template struct SmallVectorAlignmentAndSize { +@@ -128,8 +123,8 @@ template struct SmallVectorAlignmentAndSize { /// to avoid unnecessarily requiring T to be complete. template class SmallVectorTemplateCommon @@ -80,7 +80,7 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf protected: /// Find the address of the first element. For this pointer math to be valid -@@ -448,7 +443,7 @@ template +@@ -455,7 +450,7 @@ template T *SmallVectorTemplateBase::mallocForGrow( size_t MinSize, size_t &NewCapacity) { return static_cast( @@ -89,8 +89,8 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf this->getFirstEl(), MinSize, sizeof(T), NewCapacity)); } -@@ -1320,12 +1315,6 @@ template SmallVector to_vector_of(R &&Range) { - return {std::begin(Range), std::end(Range)}; +@@ -1329,12 +1324,6 @@ template SmallVector to_vector_of(R &&Range) { + return {adl_begin(Range), adl_end(Range)}; } -// Explicit instantiations @@ -99,9 +99,9 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf -extern template class llvm::SmallVectorBase; -#endif - - } // end namespace llvm - - namespace std { + // Provide DenseMapInfo for SmallVector of a type which has info. + template struct DenseMapInfo> { + static SmallVector getEmptyKey() { diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp index fba8fcb7cf56f4914e6ab6ede78eb8d8c8bf3424..5fe82c223193e7353d0576b84897422bed26186b 100644 --- a/llvm/lib/Support/SmallVector.cpp diff --git a/upstream_utils/llvm_patches/0011-Add-vectors-to-raw_ostream.patch b/upstream_utils/llvm_patches/0011-raw_ostream-add-vector-support.patch similarity index 92% rename from upstream_utils/llvm_patches/0011-Add-vectors-to-raw_ostream.patch rename to upstream_utils/llvm_patches/0011-raw_ostream-add-vector-support.patch index 0d91c3692e..834400f0ba 100644 --- a/upstream_utils/llvm_patches/0011-Add-vectors-to-raw_ostream.patch +++ b/upstream_utils/llvm_patches/0011-raw_ostream-add-vector-support.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 13:48:59 -0400 -Subject: [PATCH 11/36] Add vectors to raw_ostream +Subject: [PATCH 11/33] raw_ostream: add vector support --- llvm/include/llvm/Support/raw_ostream.h | 115 ++++++++++++++++++++++++ @@ -9,10 +9,10 @@ Subject: [PATCH 11/36] Add vectors to raw_ostream 2 files changed, 162 insertions(+) diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82335b9913 100644 +index f346d36ca7a36ab2d9bcddc205db0abf50c2a136..991ede221d8c265a384ede4d4b037dbbb61d6afd 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -24,6 +24,7 @@ +@@ -25,6 +25,7 @@ #include #include #include @@ -20,7 +20,7 @@ index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82 namespace llvm { -@@ -274,12 +275,24 @@ public: +@@ -275,12 +276,24 @@ public: return write(Str.data(), Str.size()); } @@ -45,7 +45,7 @@ index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82 /// indent - Insert 'NumSpaces' spaces. raw_ostream &indent(unsigned NumSpaces); -@@ -641,6 +654,108 @@ public: +@@ -642,6 +655,108 @@ public: static bool classof(const raw_ostream *OS); }; @@ -54,7 +54,7 @@ index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82 +/// 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 { ++class LLVM_ABI raw_vector_ostream : public raw_pwrite_stream { + std::vector &OS; + + /// See raw_ostream::write_impl. @@ -87,7 +87,7 @@ index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82 +/// 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 { ++class LLVM_ABI raw_usvector_ostream : public raw_pwrite_stream { + SmallVectorImpl &OS; + + /// See raw_ostream::write_impl. @@ -121,7 +121,7 @@ index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82 +/// 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 { ++class LLVM_ABI raw_uvector_ostream : public raw_pwrite_stream { + std::vector &OS; + + /// See raw_ostream::write_impl. @@ -152,13 +152,13 @@ index fed78518c3b6c44b366d04f45a1d74819e794a3c..2c37ff9c0966506c53d15d7cb84abc82 + + /// A raw_ostream that discards all output. - class raw_null_ostream : public raw_pwrite_stream { + class LLVM_ABI 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 e06253e8f3a16dc09573cdec74cf54e0e3fcf848..a74b6b00d616828a8e5ab25c1fd15f2528b4d76d 100644 +index 32f5d5fb78b1a9e4288b875c64ded0040d6fdce6..dd1ce4a784d096949681e297103c50aa002d636d 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -679,6 +679,53 @@ bool raw_svector_ostream::classof(const raw_ostream *OS) { +@@ -677,6 +677,53 @@ bool raw_svector_ostream::classof(const raw_ostream *OS) { return OS->get_kind() == OStreamKind::OK_SVecStream; } diff --git a/upstream_utils/llvm_patches/0012-Delete-numbers-from-MathExtras.patch b/upstream_utils/llvm_patches/0012-Delete-numbers-from-MathExtras.patch deleted file mode 100644 index 11c6f92250..0000000000 --- a/upstream_utils/llvm_patches/0012-Delete-numbers-from-MathExtras.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: PJ Reiniger -Date: Thu, 5 May 2022 18:09:45 -0400 -Subject: [PATCH 12/36] Delete numbers from MathExtras - ---- - llvm/include/llvm/Support/MathExtras.h | 37 -------------------------- - 1 file changed, 37 deletions(-) - -diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index b2c62d833038f92d2621ca2e6838d0d6b3b48760..60f8c48031b1809e9de66220103b3a504f32c225 100644 ---- a/llvm/include/llvm/Support/MathExtras.h -+++ b/llvm/include/llvm/Support/MathExtras.h -@@ -40,43 +40,6 @@ template > - using common_sint = - std::common_type_t, std::make_signed_t>; - --/// Mathematical constants. --namespace numbers { --// TODO: Track C++20 std::numbers. --// clang-format off --constexpr double e = 0x1.5bf0a8b145769P+1, // (2.7182818284590452354) https://oeis.org/A001113 -- egamma = 0x1.2788cfc6fb619P-1, // (.57721566490153286061) https://oeis.org/A001620 -- ln2 = 0x1.62e42fefa39efP-1, // (.69314718055994530942) https://oeis.org/A002162 -- ln10 = 0x1.26bb1bbb55516P+1, // (2.3025850929940456840) https://oeis.org/A002392 -- log2e = 0x1.71547652b82feP+0, // (1.4426950408889634074) -- log10e = 0x1.bcb7b1526e50eP-2, // (.43429448190325182765) -- pi = 0x1.921fb54442d18P+1, // (3.1415926535897932385) https://oeis.org/A000796 -- inv_pi = 0x1.45f306dc9c883P-2, // (.31830988618379067154) https://oeis.org/A049541 -- sqrtpi = 0x1.c5bf891b4ef6bP+0, // (1.7724538509055160273) https://oeis.org/A002161 -- inv_sqrtpi = 0x1.20dd750429b6dP-1, // (.56418958354775628695) https://oeis.org/A087197 -- sqrt2 = 0x1.6a09e667f3bcdP+0, // (1.4142135623730950488) https://oeis.org/A00219 -- inv_sqrt2 = 0x1.6a09e667f3bcdP-1, // (.70710678118654752440) -- sqrt3 = 0x1.bb67ae8584caaP+0, // (1.7320508075688772935) https://oeis.org/A002194 -- inv_sqrt3 = 0x1.279a74590331cP-1, // (.57735026918962576451) -- phi = 0x1.9e3779b97f4a8P+0; // (1.6180339887498948482) https://oeis.org/A001622 --constexpr float ef = 0x1.5bf0a8P+1F, // (2.71828183) https://oeis.org/A001113 -- egammaf = 0x1.2788d0P-1F, // (.577215665) https://oeis.org/A001620 -- ln2f = 0x1.62e430P-1F, // (.693147181) https://oeis.org/A002162 -- ln10f = 0x1.26bb1cP+1F, // (2.30258509) https://oeis.org/A002392 -- log2ef = 0x1.715476P+0F, // (1.44269504) -- log10ef = 0x1.bcb7b2P-2F, // (.434294482) -- pif = 0x1.921fb6P+1F, // (3.14159265) https://oeis.org/A000796 -- inv_pif = 0x1.45f306P-2F, // (.318309886) https://oeis.org/A049541 -- sqrtpif = 0x1.c5bf8aP+0F, // (1.77245385) https://oeis.org/A002161 -- inv_sqrtpif = 0x1.20dd76P-1F, // (.564189584) https://oeis.org/A087197 -- sqrt2f = 0x1.6a09e6P+0F, // (1.41421356) https://oeis.org/A002193 -- inv_sqrt2f = 0x1.6a09e6P-1F, // (.707106781) -- sqrt3f = 0x1.bb67aeP+0F, // (1.73205081) https://oeis.org/A002194 -- inv_sqrt3f = 0x1.279a74P-1F, // (.577350269) -- phif = 0x1.9e377aP+0F; // (1.61803399) https://oeis.org/A001622 --// clang-format on --} // namespace numbers -- - /// Create a bitmask with the N right-most bits set to 1, and all other - /// bits set to 0. Only unsigned types are allowed. - template T maskTrailingOnes(unsigned N) { diff --git a/upstream_utils/llvm_patches/0012-MathExtras-delete-numbers.patch b/upstream_utils/llvm_patches/0012-MathExtras-delete-numbers.patch new file mode 100644 index 0000000000..2ec2a17ece --- /dev/null +++ b/upstream_utils/llvm_patches/0012-MathExtras-delete-numbers.patch @@ -0,0 +1,51 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: PJ Reiniger +Date: Thu, 5 May 2022 18:09:45 -0400 +Subject: [PATCH 12/33] MathExtras: delete numbers + +--- + llvm/include/llvm/Support/MathExtras.h | 31 -------------------------- + 1 file changed, 31 deletions(-) + +diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h +index 78c500e18c7639afc02b595b788333b6b9a4e69b..b8e858f9c530e31430f824cc2d93ff1cc78a92f7 100644 +--- a/llvm/include/llvm/Support/MathExtras.h ++++ b/llvm/include/llvm/Support/MathExtras.h +@@ -41,37 +41,6 @@ template > + using common_sint = + std::common_type_t, std::make_signed_t>; + +-/// Mathematical constants. +-namespace numbers { +-// clang-format off +-inline constexpr float ef = e_v; +-inline constexpr float egammaf = egamma_v; +-inline constexpr float ln2f = ln2_v; +-inline constexpr float ln10f = ln10_v; +-inline constexpr float log2ef = log2e_v; +-inline constexpr float log10ef = log10e_v; +-inline constexpr float pif = pi_v; +-inline constexpr float inv_pif = inv_pi_v; +-inline constexpr float inv_sqrtpif = inv_sqrtpi_v; +-inline constexpr float sqrt2f = sqrt2_v; +-inline constexpr float inv_sqrt2f = inv_sqrt2_v; +-inline constexpr float sqrt3f = sqrt3_v; +-inline constexpr float inv_sqrt3f = inv_sqrt3_v; +-inline constexpr float phif = phi_v; +- +-// sqrtpi is not in C++20 std::numbers. +-template >> +-inline constexpr T sqrtpi_v = T(0x1.c5bf891b4ef6bP+0); // (1.7724538509055160273) https://oeis.org/A002161 +-inline constexpr double sqrtpi = sqrtpi_v; +-inline constexpr float sqrtpif = sqrtpi_v; +- +-// These string literals are taken from below: +-// https://github.com/bminor/glibc/blob/8543577b04ded6d979ffcc5a818930e4d74d0645/math/math.h#L1215-L1229 +-constexpr const char *pis = "3.141592653589793238462643383279502884", +- *inv_pis = "0.318309886183790671537767526745028724"; +-// clang-format on +-} // namespace numbers +- + /// Create a bitmask with the N right-most bits set to 1, and all other + /// bits set to 0. Only unsigned types are allowed. + template constexpr T maskTrailingOnes(unsigned N) { diff --git a/upstream_utils/llvm_patches/0013-Add-lerp-and-sgn.patch b/upstream_utils/llvm_patches/0013-MathExtras-add-Lerp-and-sgn.patch similarity index 83% rename from upstream_utils/llvm_patches/0013-Add-lerp-and-sgn.patch rename to upstream_utils/llvm_patches/0013-MathExtras-add-Lerp-and-sgn.patch index f12db73d89..d3482731dc 100644 --- a/upstream_utils/llvm_patches/0013-Add-lerp-and-sgn.patch +++ b/upstream_utils/llvm_patches/0013-MathExtras-add-Lerp-and-sgn.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Tue, 3 May 2022 22:50:24 -0400 -Subject: [PATCH 13/36] Add lerp and sgn +Subject: [PATCH 13/33] MathExtras: add Lerp() and sgn() --- llvm/include/llvm/Support/MathExtras.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index 60f8c48031b1809e9de66220103b3a504f32c225..acd16bb0e6cf73f565d44d654c34057d9b97dd95 100644 +index b8e858f9c530e31430f824cc2d93ff1cc78a92f7..0735d9c9f756349a19c5aa2ec34ceca5d8274f16 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -759,6 +759,27 @@ using stack_float_t = volatile float; +@@ -764,6 +764,27 @@ using stack_float_t = volatile float; using stack_float_t = float; #endif diff --git a/upstream_utils/llvm_patches/0014-Fixup-includes.patch b/upstream_utils/llvm_patches/0014-Fixup-includes.patch index 782c99f9f6..78175d6a2f 100644 --- a/upstream_utils/llvm_patches/0014-Fixup-includes.patch +++ b/upstream_utils/llvm_patches/0014-Fixup-includes.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 16:38:11 -0400 -Subject: [PATCH 14/36] Fixup includes +Subject: [PATCH 14/33] Fixup includes --- llvm/include/llvm/Support/PointerLikeTypeTraits.h | 1 + @@ -14,19 +14,19 @@ Subject: [PATCH 14/36] Fixup includes 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/llvm/include/llvm/Support/PointerLikeTypeTraits.h -index 1b15f930bd87d97d51824af5e62ea5f222a6b4c9..acadd5e89a1651cfbad67a5b1b0933d1f288d094 100644 +index a47d68406acf38350a67ce846af4f0c1a5818db1..85152589f7e0f3d31163c5aab109cedf55131681 100644 --- a/llvm/include/llvm/Support/PointerLikeTypeTraits.h +++ b/llvm/include/llvm/Support/PointerLikeTypeTraits.h -@@ -16,6 +16,7 @@ - +@@ -17,6 +17,7 @@ #include "llvm/Support/DataTypes.h" + #include "llvm/Support/MathExtras.h" #include +#include - #include namespace llvm { + diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp -index d53462e742e61d3476915d5b2c5aa63772e78a8a..34054140489e4d536ace4650207c783d669d850e 100644 +index 39f151c716dacfef07038551add0f84a09b0cb62..d15c9652b0b79e5ce7a708d30844d0ece3944d2c 100644 --- a/llvm/lib/Support/ConvertUTFWrapper.cpp +++ b/llvm/lib/Support/ConvertUTFWrapper.cpp @@ -7,6 +7,7 @@ @@ -38,10 +38,10 @@ index d53462e742e61d3476915d5b2c5aa63772e78a8a..34054140489e4d536ace4650207c783d #include "llvm/Support/SwapByteOrder.h" #include diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index 4de36d969b3776b72ff85888355b64f7f3262ccc..e813fd3faa9f76148f9802c4b7308e517df32269 100644 +index fcbc70535bf9869f72d001ec214d7046e975961a..c4366de2aec2f1730954aecfc627dd0e164481ab 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -28,12 +28,11 @@ +@@ -29,12 +29,11 @@ #include #include @@ -57,7 +57,7 @@ index 4de36d969b3776b72ff85888355b64f7f3262ccc..e813fd3faa9f76148f9802c4b7308e51 #endif using namespace llvm; -@@ -210,7 +209,7 @@ void LLVMResetFatalErrorHandler() { +@@ -240,7 +239,7 @@ void LLVMResetFatalErrorHandler() { #ifdef _WIN32 #define WIN32_NO_STATUS @@ -67,7 +67,7 @@ index 4de36d969b3776b72ff85888355b64f7f3262ccc..e813fd3faa9f76148f9802c4b7308e51 #include #include diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index a74b6b00d616828a8e5ab25c1fd15f2528b4d76d..d8f0c5c7f0f4d5e468b30d53dc6eb8d777a0da9f 100644 +index dd1ce4a784d096949681e297103c50aa002d636d..459189b0f0a006d465a857f26a78968c4f234a8d 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -15,6 +15,8 @@ @@ -79,7 +79,7 @@ index a74b6b00d616828a8e5ab25c1fd15f2528b4d76d..d8f0c5c7f0f4d5e468b30d53dc6eb8d7 #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/AutoConvert.h" -@@ -35,8 +37,9 @@ +@@ -36,8 +38,9 @@ // may provide O_BINARY. # include @@ -91,7 +91,7 @@ index a74b6b00d616828a8e5ab25c1fd15f2528b4d76d..d8f0c5c7f0f4d5e468b30d53dc6eb8d7 #endif #if defined(__CYGWIN__) -@@ -59,7 +62,7 @@ +@@ -60,7 +63,7 @@ #ifdef _WIN32 #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Signals.h" @@ -101,7 +101,7 @@ index a74b6b00d616828a8e5ab25c1fd15f2528b4d76d..d8f0c5c7f0f4d5e468b30d53dc6eb8d7 using namespace llvm; diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp -index 65c0c564e91a40a98432d985c6949d3d4aa0717d..98045c6349237c620ae7d4d1792bf93c9317e145 100644 +index bbe18dffdcf32d1bd71e756bccca74f1fcee5d0c..33d167cf87e588d46682916888eaf81713854046 100644 --- a/llvm/unittests/ADT/SmallPtrSetTest.cpp +++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp @@ -16,6 +16,8 @@ @@ -114,12 +114,12 @@ index 65c0c564e91a40a98432d985c6949d3d4aa0717d..98045c6349237c620ae7d4d1792bf93c using testing::UnorderedElementsAre; diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp -index f8c37820ef9fdfe0af067f5aa8d2297ed15e73bc..5e91f71bc9ac0e499a64dd1591e581d0707417f6 100644 +index 5589671f7909d1994626c3f0ad043e64ef9768ab..f7a3110f183820212179644fd31009685e172943 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp -@@ -13,6 +13,7 @@ - #include "llvm/ADT/SmallVector.h" +@@ -14,6 +14,7 @@ #include "llvm/Support/Compiler.h" + #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include diff --git a/upstream_utils/llvm_patches/0015-Use-std-is_trivially_copy_constructible.patch b/upstream_utils/llvm_patches/0015-Use-std-is_trivially_copy_constructible.patch deleted file mode 100644 index a6d3b6b564..0000000000 --- a/upstream_utils/llvm_patches/0015-Use-std-is_trivially_copy_constructible.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: PJ Reiniger -Date: Sun, 8 May 2022 16:42:09 -0400 -Subject: [PATCH 15/36] Use std::is_trivially_copy_constructible - ---- - llvm/include/llvm/Support/type_traits.h | 16 ---------------- - 1 file changed, 16 deletions(-) - -diff --git a/llvm/include/llvm/Support/type_traits.h b/llvm/include/llvm/Support/type_traits.h -index 3fd158def34d7256a736f8fb0b30dadea2177864..3171af93fa7ffe4707c03289270cf5951e3db7c5 100644 ---- a/llvm/include/llvm/Support/type_traits.h -+++ b/llvm/include/llvm/Support/type_traits.h -@@ -76,22 +76,6 @@ union trivial_helper { - - } // end namespace detail - --template --struct is_copy_assignable { -- template -- static auto get(F*) -> decltype(std::declval() = std::declval(), std::true_type{}); -- static std::false_type get(...); -- static constexpr bool value = decltype(get((T*)nullptr))::value; --}; -- --template --struct is_move_assignable { -- template -- static auto get(F*) -> decltype(std::declval() = std::declval(), std::true_type{}); -- static std::false_type get(...); -- static constexpr bool value = decltype(get((T*)nullptr))::value; --}; -- - } // end namespace llvm - - #endif // LLVM_SUPPORT_TYPE_TRAITS_H diff --git a/upstream_utils/llvm_patches/0016-Windows-support.patch b/upstream_utils/llvm_patches/0015-Windows-support.patch similarity index 71% rename from upstream_utils/llvm_patches/0016-Windows-support.patch rename to upstream_utils/llvm_patches/0015-Windows-support.patch index 37fbb9fe78..d9cb1f0742 100644 --- a/upstream_utils/llvm_patches/0016-Windows-support.patch +++ b/upstream_utils/llvm_patches/0015-Windows-support.patch @@ -1,16 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Tue, 3 May 2022 20:22:38 -0400 -Subject: [PATCH 16/36] Windows support +Subject: [PATCH 15/33] Windows support --- - .../llvm/Support/Windows/WindowsSupport.h | 45 +++++---- + .../llvm/Support/Windows/WindowsSupport.h | 56 +++++------ llvm/lib/Support/ConvertUTF.cpp | 95 +++++++++++++++++++ + llvm/lib/Support/ErrorHandling.cpp | 14 +-- llvm/lib/Support/raw_ostream.cpp | 1 - - 3 files changed, 124 insertions(+), 17 deletions(-) + 4 files changed, 129 insertions(+), 37 deletions(-) diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h -index 83d5586ae8a77ec585e7e59df3075ca59cfb9d0c..395965bc6fc969ed9a2d92743a0010ddf3923394 100644 +index 30644ef7f62cb81a33f2b62068f77f4e7f3f5019..994a145668d8f7b6c4569099fdb3b1c9096a6b30 100644 --- a/llvm/include/llvm/Support/Windows/WindowsSupport.h +++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h @@ -33,8 +33,6 @@ @@ -62,15 +63,15 @@ index 83d5586ae8a77ec585e7e59df3075ca59cfb9d0c..395965bc6fc969ed9a2d92743a0010dd /// 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(); +-LLVM_ABI bool RunningWindows8OrGreater(); +inline bool RunningWindows8OrGreater() { + // Windows 8 is version 6.2, service pack 0. + return GetWindowsOSVersion() >= llvm::VersionTuple(6, 2, 0, 0); +} /// Determines if the program is running on Windows 11 or Windows Server 2022. - bool RunningWindows11OrGreater(); -@@ -229,19 +255,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) { + LLVM_ABI bool RunningWindows11OrGreater(); +@@ -229,30 +255,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) { return Time; } @@ -78,20 +79,31 @@ index 83d5586ae8a77ec585e7e59df3075ca59cfb9d0c..395965bc6fc969ed9a2d92743a0010dd -// 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 &Args, -- BumpPtrAllocator &Alloc); +-LLVM_ABI std::error_code +-GetCommandLineArguments(SmallVectorImpl &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 &Path16, -- size_t MaxPathLen = MAX_PATH); +-LLVM_ABI std::error_code widenPath(const Twine &Path8, +- SmallVectorImpl &Path16, +- size_t MaxPathLen = MAX_PATH); - +-/// Retrieves the handle to a in-memory system module such as ntdll.dll, while +-/// ensuring we're not retrieving a malicious injected module but a module +-/// loaded from the system path. +-LLVM_ABI HMODULE loadSystemModuleSecure(LPCWSTR lpModuleName); +- +-/// Convert a UTF-8 path to a long form UTF-8 path expanding any short 8.3 form +-/// components. +-LLVM_ABI std::error_code makeLongFormPath(const Twine &Path8, +- llvm::SmallVectorImpl &Result8); -} // end namespace windows } // end namespace sys } // end namespace llvm. diff --git a/llvm/lib/Support/ConvertUTF.cpp b/llvm/lib/Support/ConvertUTF.cpp -index bc04c5ab5113563fb82d7b3b168985369b611f4b..b865b5589df961813007e57a910dbc14f875426b 100644 +index 63f92631d5b473cf9a69a06eddf4271304e8c730..f8551c7136ed44b8ed8c2f0bc4498145af504dd0 100644 --- a/llvm/lib/Support/ConvertUTF.cpp +++ b/llvm/lib/Support/ConvertUTF.cpp @@ -67,6 +67,11 @@ @@ -203,11 +215,44 @@ index bc04c5ab5113563fb82d7b3b168985369b611f4b..b865b5589df961813007e57a910dbc14 } // namespace llvm ConvertUTF_RESTORE_WARNINGS +diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp +index c4366de2aec2f1730954aecfc627dd0e164481ab..cc0e4665da20b619f0cf52a25b0c71bdf78e62f6 100644 +--- a/llvm/lib/Support/ErrorHandling.cpp ++++ b/llvm/lib/Support/ErrorHandling.cpp +@@ -60,7 +60,11 @@ static std::mutex BadAllocErrorHandlerMutex; + + static bool write_retry(int fd, const char *buf, size_t count) { + while (count > 0) { ++#ifdef _WIN32 ++ int written = sys::RetryAfterSignal(-1, ::_write, fd, buf, count); ++#else + ssize_t written = sys::RetryAfterSignal(-1, ::write, fd, buf, count); ++#endif + if (written <= 0) + return false; + buf += written; +@@ -115,15 +119,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { + write_retry(2, MessageStr.data(), MessageStr.size()); + } + +- // 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(); +- +- if (GenCrashDiag) +- abort(); +- else +- exit(1); ++ exit(1); + } + + void llvm::reportFatalInternalError(const char *reason) { diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index d8f0c5c7f0f4d5e468b30d53dc6eb8d777a0da9f..a1b40ae78da9fed4bb9d489f298c7adc9cf437b9 100644 +index 459189b0f0a006d465a857f26a78968c4f234a8d..7a834a0562af1f7da4315e735fe444278a9eef0e 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -524,7 +524,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { +@@ -519,7 +519,6 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { DWORD WinLastError = GetLastError(); if (WinLastError == ERROR_BROKEN_PIPE || (WinLastError == ERROR_NO_DATA && errno == EINVAL)) { diff --git a/upstream_utils/llvm_patches/0017-Remove-call-to-RtlGetLastNtStatus.patch b/upstream_utils/llvm_patches/0016-ErrorHandling-remove-call-to-RtlGetLastNtStatus.patch similarity index 89% rename from upstream_utils/llvm_patches/0017-Remove-call-to-RtlGetLastNtStatus.patch rename to upstream_utils/llvm_patches/0016-ErrorHandling-remove-call-to-RtlGetLastNtStatus.patch index 464aa619be..8be880a72b 100644 --- a/upstream_utils/llvm_patches/0017-Remove-call-to-RtlGetLastNtStatus.patch +++ b/upstream_utils/llvm_patches/0016-ErrorHandling-remove-call-to-RtlGetLastNtStatus.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 17 Sep 2024 21:19:52 -0700 -Subject: [PATCH 17/36] Remove call to RtlGetLastNtStatus() +Subject: [PATCH 16/33] ErrorHandling: remove call to RtlGetLastNtStatus() --- llvm/lib/Support/ErrorHandling.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index e813fd3faa9f76148f9802c4b7308e517df32269..d0fd67bd3c0d4cf33922cdda042531424d277951 100644 +index cc0e4665da20b619f0cf52a25b0c71bdf78e62f6..69328303a1cc0cc6e210de5adbb4fdafafbe978f 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -214,34 +214,11 @@ void LLVMResetFatalErrorHandler() { +@@ -240,34 +240,11 @@ void LLVMResetFatalErrorHandler() { #include #include diff --git a/upstream_utils/llvm_patches/0018-Prefer-fmtlib.patch b/upstream_utils/llvm_patches/0017-ErrorHandling-prefer-fmtlib.patch similarity index 72% rename from upstream_utils/llvm_patches/0018-Prefer-fmtlib.patch rename to upstream_utils/llvm_patches/0017-ErrorHandling-prefer-fmtlib.patch index e53716bbbe..c20ee4108e 100644 --- a/upstream_utils/llvm_patches/0018-Prefer-fmtlib.patch +++ b/upstream_utils/llvm_patches/0017-ErrorHandling-prefer-fmtlib.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 16:46:20 -0400 -Subject: [PATCH 18/36] Prefer fmtlib +Subject: [PATCH 17/33] ErrorHandling: prefer fmtlib --- - llvm/lib/Support/ErrorHandling.cpp | 20 ++++++-------------- - 1 file changed, 6 insertions(+), 14 deletions(-) + llvm/lib/Support/ErrorHandling.cpp | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index d0fd67bd3c0d4cf33922cdda042531424d277951..c153b91391fe63e819e4907ac98d2ee26228107a 100644 +index 69328303a1cc0cc6e210de5adbb4fdafafbe978f..cb455ed43ffba58443fd71dcdb2e60cc7fc812a6 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -22,7 +22,7 @@ +@@ -23,7 +23,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/Threading.h" #include "llvm/Support/WindowsError.h" @@ -20,7 +20,7 @@ index d0fd67bd3c0d4cf33922cdda042531424d277951..c153b91391fe63e819e4907ac98d2ee2 #include #include #include -@@ -93,15 +93,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { +@@ -109,14 +109,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { if (handler) { handler(handlerData, std::string{Reason}.c_str(), GenCrashDiag); } else { @@ -31,13 +31,12 @@ index d0fd67bd3c0d4cf33922cdda042531424d277951..c153b91391fe63e819e4907ac98d2ee2 - 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. +- write_retry(2, MessageStr.data(), MessageStr.size()); + wpi::util::print(stderr, "LLVM ERROR: {}\n", Reason); } - // If we reached here, we are failing ungracefully. Run the interrupt handlers -@@ -177,11 +169,11 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, + exit(1); +@@ -203,11 +196,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) diff --git a/upstream_utils/llvm_patches/0019-Prefer-wpi-s-fs.h.patch b/upstream_utils/llvm_patches/0018-raw_ostream-prefer-wpi-s-fs.h.patch similarity index 84% rename from upstream_utils/llvm_patches/0019-Prefer-wpi-s-fs.h.patch rename to upstream_utils/llvm_patches/0018-raw_ostream-prefer-wpi-s-fs.h.patch index 525783096b..db88f889c3 100644 --- a/upstream_utils/llvm_patches/0019-Prefer-wpi-s-fs.h.patch +++ b/upstream_utils/llvm_patches/0018-raw_ostream-prefer-wpi-s-fs.h.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 16:49:36 -0400 -Subject: [PATCH 19/36] Prefer wpi's fs.h +Subject: [PATCH 18/33] raw_ostream: 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 2c37ff9c0966506c53d15d7cb84abc82335b9913..990d3e4cfe53e025df6ce797f46f9de5af8ca6dc 100644 +index 991ede221d8c265a384ede4d4b037dbbb61d6afd..bd1a260835b874bfbe4177cf92094d3507157c82 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -26,18 +26,15 @@ +@@ -27,18 +27,15 @@ #include #include diff --git a/upstream_utils/llvm_patches/0020-Remove-unused-functions.patch b/upstream_utils/llvm_patches/0019-Remove-unused-functions.patch similarity index 90% rename from upstream_utils/llvm_patches/0020-Remove-unused-functions.patch rename to upstream_utils/llvm_patches/0019-Remove-unused-functions.patch index 71ba8b94af..748f8270dc 100644 --- a/upstream_utils/llvm_patches/0020-Remove-unused-functions.patch +++ b/upstream_utils/llvm_patches/0019-Remove-unused-functions.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Sun, 8 May 2022 19:16:51 -0400 -Subject: [PATCH 20/36] Remove unused functions +Subject: [PATCH 19/33] Remove unused functions --- llvm/include/llvm/Support/VersionTuple.h | 1 - @@ -12,10 +12,10 @@ Subject: [PATCH 20/36] Remove unused functions 5 files changed, 23 insertions(+), 127 deletions(-) diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h -index 9102ff063afedc03bd524b2805cba98ea5afeba8..7638d1ab0d12e22608d4c3e3a14ec8e0ce15d2d5 100644 +index 735f73d0447fb35fc64a0f449b45bab19947bf58..c361921d80b9250bc7678e09c4e56854928b65d7 100644 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h -@@ -21,7 +21,6 @@ +@@ -22,7 +22,6 @@ #include namespace llvm { @@ -24,10 +24,10 @@ index 9102ff063afedc03bd524b2805cba98ea5afeba8..7638d1ab0d12e22608d4c3e3a14ec8e0 /// Represents a version number in the form major[.minor[.subminor[.build]]]. diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index 990d3e4cfe53e025df6ce797f46f9de5af8ca6dc..264b8192a0473b94363765995517851cbf30d045 100644 +index bd1a260835b874bfbe4177cf92094d3507157c82..f2df534b6bd7a37840fc0c3dba0f657b8b90812e 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -71,7 +71,6 @@ private: +@@ -72,7 +72,6 @@ private: /// for a \see write_impl() call to handle the data which has been put into /// this buffer. char *OutBufStart, *OutBufEnd, *OutBufCur; @@ -35,7 +35,7 @@ index 990d3e4cfe53e025df6ce797f46f9de5af8ca6dc..264b8192a0473b94363765995517851c enum class BufferKind { Unbuffered = 0, -@@ -330,9 +329,9 @@ public: +@@ -331,9 +330,9 @@ public: // Enable or disable colors. Once enable_colors(false) is called, // changeColor() has no effect until enable_colors(true) is called. @@ -48,10 +48,10 @@ index 990d3e4cfe53e025df6ce797f46f9de5af8ca6dc..264b8192a0473b94363765995517851c //===--------------------------------------------------------------------===// // Subclass Interface diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index c153b91391fe63e819e4907ac98d2ee26228107a..c9bb71be96f0ea3ad26c61cfa8ab35dfa6f60d02 100644 +index cb455ed43ffba58443fd71dcdb2e60cc7fc812a6..a78e667876e4daaa629e6c18bb6c835285483a64 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -182,22 +182,6 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, +@@ -209,22 +209,6 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, #endif } @@ -75,10 +75,10 @@ index c153b91391fe63e819e4907ac98d2ee26228107a..c9bb71be96f0ea3ad26c61cfa8ab35df #define WIN32_NO_STATUS diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d191a47f89 100644 +index 7a834a0562af1f7da4315e735fe444278a9eef0e..ca4492ad814505349f3e5ddfe67a165d78e35a6e 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -168,16 +168,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str, +@@ -158,16 +158,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str, return *this; } @@ -95,7 +95,7 @@ index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d1 void raw_ostream::flush_nonempty() { assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty."); size_t Length = OutBufCur - OutBufStart; -@@ -314,15 +304,22 @@ static int getFD(std::string_view Filename, std::error_code &EC, +@@ -307,15 +297,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. @@ -123,7 +123,7 @@ index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d1 if (EC) return -1; -@@ -382,12 +379,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, +@@ -378,12 +375,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); @@ -137,7 +137,7 @@ index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d1 #else SupportsSeeking = !EC && loc != (off_t)-1; #endif -@@ -400,10 +393,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, +@@ -396,10 +389,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, raw_fd_ostream::~raw_fd_ostream() { if (FD >= 0) { flush(); @@ -150,7 +150,7 @@ index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d1 } #ifdef __MINGW32__ -@@ -501,7 +492,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { +@@ -496,7 +487,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { do { size_t ChunkSize = std::min(Size, MaxWriteSize); @@ -162,7 +162,7 @@ index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d1 if (ret < 0) { // If it's a recoverable error, swallow it and retry the write. -@@ -544,8 +539,8 @@ void raw_fd_ostream::close() { +@@ -539,8 +534,8 @@ void raw_fd_ostream::close() { assert(ShouldClose); ShouldClose = false; flush(); @@ -174,7 +174,7 @@ index a1b40ae78da9fed4bb9d489f298c7adc9cf437b9..3333890ed1b086c94cdfce8bc9efb3d1 } diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp -index 6cf14700b34739420cd3dc4ff8a4c16ce162f715..87600ea4704bc98acab9085d16cfafd3d586714e 100644 +index 20b0585e00e87b91c1486f045646a872cc99d208..e8c8085f4620628764d866c5fd042777de92d820 100644 --- a/llvm/unittests/ADT/SmallStringTest.cpp +++ b/llvm/unittests/ADT/SmallStringTest.cpp @@ -129,23 +129,6 @@ TEST_F(SmallStringTest, StdStringConversion) { diff --git a/upstream_utils/llvm_patches/0022-Use-SmallVector-for-UTF-conversion.patch b/upstream_utils/llvm_patches/0020-ConvertUTF-use-SmallVector-for-UTF-conversion.patch similarity index 80% rename from upstream_utils/llvm_patches/0022-Use-SmallVector-for-UTF-conversion.patch rename to upstream_utils/llvm_patches/0020-ConvertUTF-use-SmallVector-for-UTF-conversion.patch index 10001b4969..59333077ab 100644 --- a/upstream_utils/llvm_patches/0022-Use-SmallVector-for-UTF-conversion.patch +++ b/upstream_utils/llvm_patches/0020-ConvertUTF-use-SmallVector-for-UTF-conversion.patch @@ -1,47 +1,48 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Mon, 9 May 2022 00:04:30 -0400 -Subject: [PATCH 22/36] Use SmallVector for UTF conversion +Subject: [PATCH 20/33] ConvertUTF: use SmallVector for UTF conversion --- - llvm/include/llvm/Support/ConvertUTF.h | 6 +++--- + llvm/include/llvm/Support/ConvertUTF.h | 7 ++++--- llvm/lib/Support/ConvertUTFWrapper.cpp | 6 +++--- llvm/unittests/Support/ConvertUTFTest.cpp | 22 +++++++++++----------- - 3 files changed, 17 insertions(+), 17 deletions(-) + 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h -index 72321022beb373945f7935ed72944fd68eb7d02f..5c8b966ce296699a0315d72cdfdcdb5af3d1d0b0 100644 +index d5f66c4525dd5b2e2cdb4ab5e4d523c19e36b25f..6d746c88be56f42a1056a26d44b4ab0ac2bd6ef8 100644 --- a/llvm/include/llvm/Support/ConvertUTF.h +++ b/llvm/include/llvm/Support/ConvertUTF.h -@@ -233,7 +233,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result); - * Converts a std::wstring to a UTF-8 encoded std::string. +@@ -247,7 +247,7 @@ LLVM_ABI bool ConvertUTF8toWide(const char *Source, std::wstring &Result); * \return true on success. */ --bool convertWideToUTF8(const std::wstring &Source, std::string &Result); -+bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl &Result); - + LLVM_ABI bool convertWideToUTF8(const std::wstring &Source, +- std::string &Result); ++ SmallVectorImpl &Result); /** -@@ -288,7 +288,7 @@ bool hasUTF16ByteOrderMark(span SrcBytes); - * \param [out] Out Converted UTF-8 is stored here on success. + * Convert an Unicode code point to UTF8 sequence. +@@ -302,7 +302,7 @@ LLVM_ABI bool hasUTF16ByteOrderMark(span SrcBytes); * \returns true on success */ --bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out); -+bool convertUTF16ToUTF8String(span SrcBytes, SmallVectorImpl &Out); + LLVM_ABI bool convertUTF16ToUTF8String(span SrcBytes, +- std::string &Out); ++ SmallVectorImpl &Out); /** * Converts a UTF16 string into a UTF8 std::string. -@@ -297,7 +297,7 @@ bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out); +@@ -311,7 +311,8 @@ LLVM_ABI bool convertUTF16ToUTF8String(span SrcBytes, * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ --bool convertUTF16ToUTF8String(span Src, std::string &Out); -+bool convertUTF16ToUTF8String(span Src, SmallVectorImpl &Out); +-LLVM_ABI bool convertUTF16ToUTF8String(span Src, std::string &Out); ++LLVM_ABI bool convertUTF16ToUTF8String(span Src, ++ SmallVectorImpl &Out); /** * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string. diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp -index 34054140489e4d536ace4650207c783d669d850e..0b62315e3461ff60a8313e73b4142b1f83e36ca7 100644 +index d15c9652b0b79e5ce7a708d30844d0ece3944d2c..a14e5a6fb155c31a5f4db6b7b39a429186825651 100644 --- a/llvm/lib/Support/ConvertUTFWrapper.cpp +++ b/llvm/lib/Support/ConvertUTFWrapper.cpp @@ -82,7 +82,7 @@ bool hasUTF16ByteOrderMark(span S) { diff --git a/upstream_utils/llvm_patches/0021-OS-specific-changes.patch b/upstream_utils/llvm_patches/0021-OS-specific-changes.patch deleted file mode 100644 index 190274bbd0..0000000000 --- a/upstream_utils/llvm_patches/0021-OS-specific-changes.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: PJ Reiniger -Date: Sun, 8 May 2022 19:30:43 -0400 -Subject: [PATCH 21/36] OS-specific changes - ---- - llvm/lib/Support/ErrorHandling.cpp | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index c9bb71be96f0ea3ad26c61cfa8ab35dfa6f60d02..01d46c847d274628fc2a8a39c44f0588b8c1bb06 100644 ---- a/llvm/lib/Support/ErrorHandling.cpp -+++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -96,15 +96,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { - wpi::util::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(); -- -- if (GenCrashDiag) -- abort(); -- else -- exit(1); -+ exit(1); - } - - void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, -@@ -142,9 +134,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/0023-Prefer-to-use-static-pointers-in-raw_ostream.patch b/upstream_utils/llvm_patches/0021-raw_ostream-use-static-pointers-in-raw_ostream.patch similarity index 67% rename from upstream_utils/llvm_patches/0023-Prefer-to-use-static-pointers-in-raw_ostream.patch rename to upstream_utils/llvm_patches/0021-raw_ostream-use-static-pointers-in-raw_ostream.patch index ca57e81831..71b7472f02 100644 --- a/upstream_utils/llvm_patches/0023-Prefer-to-use-static-pointers-in-raw_ostream.patch +++ b/upstream_utils/llvm_patches/0021-raw_ostream-use-static-pointers-in-raw_ostream.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Thu, 19 May 2022 00:58:36 -0400 -Subject: [PATCH 23/36] Prefer to use static pointers in raw_ostream +Subject: [PATCH 21/33] raw_ostream: use static pointers in raw_ostream See #1401 --- @@ -9,13 +9,13 @@ See #1401 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 3333890ed1b086c94cdfce8bc9efb3d191a47f89..7561f818287d208c628a126c3f8a6f7d531df236 100644 +index ca4492ad814505349f3e5ddfe67a165d78e35a6e..09f7ede10e4c3decb2c6d70a3e8ce7660f542519 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -608,9 +608,9 @@ raw_fd_ostream &llvm::outs() { - EC = enablezOSAutoConversion(STDOUT_FILENO); - assert(!EC); - #endif +@@ -605,9 +605,9 @@ raw_fd_ostream &llvm::outs() { + assert(!EC1); + (void)EC1; + - 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); @@ -24,10 +24,10 @@ index 3333890ed1b086c94cdfce8bc9efb3d191a47f89..7561f818287d208c628a126c3f8a6f7d } raw_fd_ostream &llvm::errs() { -@@ -619,8 +619,8 @@ raw_fd_ostream &llvm::errs() { - std::error_code EC = enablezOSAutoConversion(STDERR_FILENO); - assert(!EC); - #endif +@@ -617,8 +617,8 @@ raw_fd_ostream &llvm::errs() { + (void)EC; + + // Set standard error to be unbuffered. - static raw_fd_ostream S(STDERR_FILENO, false, true); - return S; + static raw_fd_ostream* S = new raw_fd_ostream(STDERR_FILENO, false, true); diff --git a/upstream_utils/llvm_patches/0024-constexpr-endian-byte-swap.patch b/upstream_utils/llvm_patches/0022-Endian-constexpr-endian-byte-swap.patch similarity index 62% rename from upstream_utils/llvm_patches/0024-constexpr-endian-byte-swap.patch rename to upstream_utils/llvm_patches/0022-Endian-constexpr-endian-byte-swap.patch index 24ce725744..9b1bb78c18 100644 --- a/upstream_utils/llvm_patches/0024-constexpr-endian-byte-swap.patch +++ b/upstream_utils/llvm_patches/0022-Endian-constexpr-endian-byte-swap.patch @@ -1,20 +1,20 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Fri, 1 Mar 2024 11:56:17 -0800 -Subject: [PATCH 24/36] constexpr endian byte swap +Subject: [PATCH 22/33] Endian: 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 f86ea8901ae46b8b724b76ac44e0b54b84b9eda8..ca4252fc064d3349d10b7e540aadb885ae96a3b5 100644 +index 51db225841dbe01c2d21480b7359d51326d46b48..f5f4381c1003572024223da4825363d93a60aad9 100644 --- a/llvm/include/llvm/Support/Endian.h +++ b/llvm/include/llvm/Support/Endian.h -@@ -50,7 +50,9 @@ template - /// Swap the bytes of value to match the given endianness. - template - [[nodiscard]] inline value_type byte_swap(value_type value) { +@@ -52,7 +52,9 @@ template + [[nodiscard]] + LLVM_DEPRECATED("Pass endian as a function argument instead", + "byte_swap") inline value_type byte_swap(value_type value) { - return byte_swap(value, endian); + if constexpr (endian != llvm::endianness::native) + sys::swapByteOrder(value); diff --git a/upstream_utils/llvm_patches/0025-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch b/upstream_utils/llvm_patches/0023-PointerUnion-copy-type-traits-from-STLExtras.patch similarity index 94% rename from upstream_utils/llvm_patches/0025-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch rename to upstream_utils/llvm_patches/0023-PointerUnion-copy-type-traits-from-STLExtras.patch index 4f7e9215c6..6102fff311 100644 --- a/upstream_utils/llvm_patches/0025-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch +++ b/upstream_utils/llvm_patches/0023-PointerUnion-copy-type-traits-from-STLExtras.patch @@ -1,14 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Wed, 10 Aug 2022 17:07:52 -0700 -Subject: [PATCH 25/36] Copy type traits from STLExtras.h into PointerUnion.h +Subject: [PATCH 23/33] PointerUnion: copy type traits from STLExtras --- 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 23394db93cfed492bb1747eb9c8c55ed9230120d..124b869c6974ac78d908b3c55d89455a471b5185 100644 +index c3d6458777d186a700c359089c4afcac8db0185a..02d11537e3823a43301295e4645d84357df63703 100644 --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h @@ -23,9 +23,55 @@ diff --git a/upstream_utils/llvm_patches/0026-Unused-variable-in-release-mode.patch b/upstream_utils/llvm_patches/0024-DenseMap-unused-variable-in-release-mode.patch similarity index 53% rename from upstream_utils/llvm_patches/0026-Unused-variable-in-release-mode.patch rename to upstream_utils/llvm_patches/0024-DenseMap-unused-variable-in-release-mode.patch index 5020a7410d..d58c43e2cc 100644 --- a/upstream_utils/llvm_patches/0026-Unused-variable-in-release-mode.patch +++ b/upstream_utils/llvm_patches/0024-DenseMap-unused-variable-in-release-mode.patch @@ -1,22 +1,22 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Mon, 10 Jul 2023 00:53:43 +0200 -Subject: [PATCH 26/36] Unused variable in release mode +Subject: [PATCH 24/33] DenseMap: unused variable in release mode --- llvm/include/llvm/ADT/DenseMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h -index 4c852d2b142b4a3de76a1ce4049822cc449287f7..69ce7982d732887642c7f46163b753ee17be9b30 100644 +index 37d8970209dcedf8840324a376ab27b3ba3bdf6a..41199ac39da56994d9086600e6dfc1dad2c93ce0 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h -@@ -126,7 +126,7 @@ public: - P->getFirst() = EmptyKey; +@@ -138,7 +138,7 @@ public: + B.getFirst() = EmptyKey; } else { - const KeyT TombstoneKey = getTombstoneKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); - unsigned NumEntries = getNumEntries(); + [[maybe_unused]] unsigned NumEntries = getNumEntries(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { - if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { + for (BucketT &B : buckets()) { + if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey)) { + if (!KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) { diff --git a/upstream_utils/llvm_patches/0027-Use-C-20-bit-header.patch b/upstream_utils/llvm_patches/0025-Use-C-20-bit-header.patch similarity index 56% rename from upstream_utils/llvm_patches/0027-Use-C-20-bit-header.patch rename to upstream_utils/llvm_patches/0025-Use-C-20-bit-header.patch index fa8867f425..4c165ca012 100644 --- a/upstream_utils/llvm_patches/0027-Use-C-20-bit-header.patch +++ b/upstream_utils/llvm_patches/0025-Use-C-20-bit-header.patch @@ -1,19 +1,21 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 11 Jul 2023 22:56:09 -0700 -Subject: [PATCH 27/36] Use C++20 header +Subject: [PATCH 25/33] Use C++20 header --- - llvm/include/llvm/ADT/DenseMap.h | 3 +- - llvm/include/llvm/ADT/bit.h | 313 ------------------------- - llvm/include/llvm/Support/MathExtras.h | 21 +- - 3 files changed, 13 insertions(+), 324 deletions(-) + llvm/include/llvm/ADT/DenseMap.h | 1 + + llvm/include/llvm/ADT/PointerUnion.h | 2 +- + llvm/include/llvm/ADT/SmallPtrSet.h | 6 +- + llvm/include/llvm/ADT/bit.h | 286 ------------------------- + llvm/include/llvm/Support/MathExtras.h | 23 +- + 5 files changed, 17 insertions(+), 301 deletions(-) diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h -index 69ce7982d732887642c7f46163b753ee17be9b30..927a9c72ec939d268ae7463f7113f051cc92cf3f 100644 +index 41199ac39da56994d9086600e6dfc1dad2c93ce0..2c23fa2d268d34429faa0ed7b1d889c2c5ea4f9c 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h -@@ -23,6 +23,7 @@ +@@ -26,6 +26,7 @@ #include "llvm/Support/ReverseIteration.h" #include "llvm/Support/type_traits.h" #include @@ -21,26 +23,61 @@ index 69ce7982d732887642c7f46163b753ee17be9b30..927a9c72ec939d268ae7463f7113f051 #include #include #include -@@ -906,7 +907,7 @@ class SmallDenseMap - public: - explicit SmallDenseMap(unsigned NumInitBuckets = 0) { - if (NumInitBuckets > InlineBuckets) -- NumInitBuckets = llvm::bit_ceil(NumInitBuckets); -+ NumInitBuckets = std::bit_ceil(NumInitBuckets); - init(NumInitBuckets); +diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h +index 02d11537e3823a43301295e4645d84357df63703..be3bbb6ac65588626b746ce83aa3ed65ac9dc856 100644 +--- a/llvm/include/llvm/ADT/PointerUnion.h ++++ b/llvm/include/llvm/ADT/PointerUnion.h +@@ -76,7 +76,7 @@ namespace pointer_union_detail { + /// Determine the number of bits required to store integers with values < n. + /// This is ceil(log2(n)). + constexpr int bitsRequired(unsigned n) { +- return n == 0 ? 0 : llvm::bit_width_constexpr(n - 1); ++ return n == 0 ? 0 : std::bit_width(n - 1); } + template constexpr int lowBitsAvailable() { +diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h +index c07de1a110479ed625b112cc5b30d0bd5d56430f..474aa405d789e8c291d3bfc16a653ad043365883 100644 +--- a/llvm/include/llvm/ADT/SmallPtrSet.h ++++ b/llvm/include/llvm/ADT/SmallPtrSet.h +@@ -81,7 +81,7 @@ protected: + explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize) + : CurArray(SmallStorage), CurArraySize(SmallSize), NumEntries(0), + NumTombstones(0), IsSmall(true) { +- assert(llvm::has_single_bit(SmallSize) && ++ assert(std::has_single_bit(SmallSize) && + "Initial size must be a power of two!"); + } + +@@ -129,7 +129,7 @@ public: + // We must Grow -- find the size where we'd be 75% full, then round up to + // the next power of two. + size_type NewSize = NewNumEntries + (NewNumEntries / 3); +- NewSize = llvm::bit_ceil(NewSize); ++ NewSize = std::bit_ceil(NewSize); + // Like insert_imp_big, always allocate at least 128 elements. + NewSize = (std::max)(128u, NewSize); + Grow(NewSize); +@@ -533,7 +533,7 @@ class SmallPtrSet : public SmallPtrSetImpl { + using BaseT = SmallPtrSetImpl; + + // Make sure that SmallSize is a power of two, round up if not. +- static constexpr size_t SmallSizePowTwo = llvm::bit_ceil_constexpr(SmallSize); ++ static constexpr size_t SmallSizePowTwo = std::bit_ceil(SmallSize); + /// SmallStorage - Fixed size storage used in 'small mode'. + const void *SmallStorage[SmallSizePowTwo]; + diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h -index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade593b522a08 100644 +index 5971b75045b6b5f40b46900b685faf2e475c5a7f..3426ea7602a95f7292ec262ed246527c840dc176 100644 --- a/llvm/include/llvm/ADT/bit.h +++ b/llvm/include/llvm/ADT/bit.h -@@ -27,44 +27,6 @@ +@@ -28,44 +28,6 @@ #include // for _byteswap_{ushort,ulong,uint64} #endif -#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ - defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \ -- defined(__OpenBSD__) || defined(__DragonFly__) +- defined(__OpenBSD__) || defined(__DragonFly__) || defined(__managarm__) -#include -#elif defined(_AIX) -#include @@ -79,7 +116,7 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 namespace llvm { enum class endianness { -@@ -142,281 +104,6 @@ template >> +@@ -143,254 +105,6 @@ template >> } } @@ -88,67 +125,53 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 - return (Value != 0) && ((Value & (Value - 1)) == 0); -} - --namespace detail { --template struct TrailingZerosCounter { -- static unsigned count(T Val) { -- if (!Val) -- return std::numeric_limits::digits; -- if (Val & 0x1) -- return 0; +-/// Count the number of set bits in a value. +-/// Ex. popcount(0xF000F000) = 8 +-/// Returns 0 if Value is zero. +-template [[nodiscard]] constexpr int popcount(T Value) noexcept { +- static_assert(std::is_unsigned_v, "T must be an unsigned integer type"); +- static_assert(sizeof(T) <= 8, "T must be 8 bytes or less"); - -- // Bisection method. -- unsigned ZeroBits = 0; -- T Shift = std::numeric_limits::digits >> 1; -- T Mask = std::numeric_limits::max() >> Shift; -- while (Shift) { -- if ((Val & Mask) == 0) { -- Val >>= Shift; -- ZeroBits |= Shift; -- } -- Shift >>= 1; -- Mask >>= Shift; -- } -- return ZeroBits; -- } --}; -- --#if defined(__GNUC__) || defined(_MSC_VER) --template struct TrailingZerosCounter { -- static unsigned count(T Val) { -- if (Val == 0) -- return 32; -- --#if __has_builtin(__builtin_ctz) || defined(__GNUC__) -- return __builtin_ctz(Val); --#elif defined(_MSC_VER) -- unsigned long Index; -- _BitScanForward(&Index, Val); -- return Index; +- if constexpr (sizeof(T) <= 4) { +-#if defined(__GNUC__) +- return (int)__builtin_popcount(Value); +-#else +- uint32_t V = Value; +- V = V - ((V >> 1) & 0x55555555); +- V = (V & 0x33333333) + ((V >> 2) & 0x33333333); +- return int(((V + (V >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); +-#endif +- } else { +-#if defined(__GNUC__) +- return (int)__builtin_popcountll(Value); +-#else +- uint64_t V = Value; +- V = V - ((V >> 1) & 0x5555555555555555ULL); +- V = (V & 0x3333333333333333ULL) + ((V >> 2) & 0x3333333333333333ULL); +- V = (V + (V >> 4)) & 0x0F0F0F0F0F0F0F0FULL; +- return int((uint64_t)(V * 0x0101010101010101ULL) >> 56); -#endif - } --}; -- --#if !defined(_MSC_VER) || defined(_M_X64) --template struct TrailingZerosCounter { -- static unsigned count(T Val) { -- if (Val == 0) -- return 64; -- --#if __has_builtin(__builtin_ctzll) || defined(__GNUC__) -- return __builtin_ctzll(Val); --#elif defined(_MSC_VER) -- unsigned long Index; -- _BitScanForward64(&Index, Val); -- return Index; --#endif -- } --}; --#endif --#endif --} // namespace detail +-} - -/// Count number of 0's from the least significant bit to the most --/// stopping at the first 1. +-/// stopping at the first 1. +-/// +-/// A constexpr version of countr_zero. +-/// +-/// Only unsigned integral types are allowed. +-/// +-/// Returns std::numeric_limits::digits on an input of 0. +-template [[nodiscard]] constexpr int countr_zero_constexpr(T Val) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- // "(Val & -Val) - 1" generates a mask with all bits set up to (but not +- // including) the least significant set bit of Val. +- return llvm::popcount(static_cast>((Val & -Val) - 1)); +-} +- +-/// Count number of 0's from the least significant bit to the most +-/// stopping at the first 1. -/// -/// Only unsigned integral types are allowed. -/// @@ -156,63 +179,31 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 -template [[nodiscard]] int countr_zero(T Val) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); -- return llvm::detail::TrailingZerosCounter::count(Val); +- if (!Val) +- return std::numeric_limits::digits; +- +- // Use the intrinsic if available. +- if constexpr (sizeof(T) <= 4) { +-#if __has_builtin(__builtin_ctz) || defined(__GNUC__) +- return __builtin_ctz(Val); +-#elif defined(_MSC_VER) +- unsigned long Index; +- _BitScanForward(&Index, Val); +- return Index; +-#endif +- } else if constexpr (sizeof(T) == 8) { +-#if __has_builtin(__builtin_ctzll) || defined(__GNUC__) +- return __builtin_ctzll(Val); +-#elif defined(_MSC_VER) && defined(_M_X64) +- unsigned long Index; +- _BitScanForward64(&Index, Val); +- return Index; +-#endif +- } +- +- return countr_zero_constexpr(Val); -} - --namespace detail { --template struct LeadingZerosCounter { -- static unsigned count(T Val) { -- if (!Val) -- return std::numeric_limits::digits; -- -- // Bisection method. -- unsigned ZeroBits = 0; -- for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { -- T Tmp = Val >> Shift; -- if (Tmp) -- Val = Tmp; -- else -- ZeroBits |= Shift; -- } -- return ZeroBits; -- } --}; -- --#if defined(__GNUC__) || defined(_MSC_VER) --template struct LeadingZerosCounter { -- static unsigned count(T Val) { -- if (Val == 0) -- return 32; -- --#if __has_builtin(__builtin_clz) || defined(__GNUC__) -- return __builtin_clz(Val); --#elif defined(_MSC_VER) -- unsigned long Index; -- _BitScanReverse(&Index, Val); -- return Index ^ 31; --#endif -- } --}; -- --#if !defined(_MSC_VER) || defined(_M_X64) --template struct LeadingZerosCounter { -- static unsigned count(T Val) { -- if (Val == 0) -- return 64; -- --#if __has_builtin(__builtin_clzll) || defined(__GNUC__) -- return __builtin_clzll(Val); --#elif defined(_MSC_VER) -- unsigned long Index; -- _BitScanReverse64(&Index, Val); -- return Index ^ 63; --#endif -- } --}; --#endif --#endif --} // namespace detail -- -/// Count number of 0's from the most significant bit to the least -/// stopping at the first 1. -/// @@ -222,7 +213,38 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 -template [[nodiscard]] int countl_zero(T Val) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); -- return llvm::detail::LeadingZerosCounter::count(Val); +- if (!Val) +- return std::numeric_limits::digits; +- +- // Use the intrinsic if available. +- if constexpr (sizeof(T) == 4) { +-#if __has_builtin(__builtin_clz) || defined(__GNUC__) +- return __builtin_clz(Val); +-#elif defined(_MSC_VER) +- unsigned long Index; +- _BitScanReverse(&Index, Val); +- return Index ^ 31; +-#endif +- } else if constexpr (sizeof(T) == 8) { +-#if __has_builtin(__builtin_clzll) || defined(__GNUC__) +- return __builtin_clzll(Val); +-#elif defined(_MSC_VER) && defined(_M_X64) +- unsigned long Index; +- _BitScanReverse64(&Index, Val); +- return Index ^ 63; +-#endif +- } +- +- // Fall back to the bisection method. +- unsigned ZeroBits = 0; +- for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { +- T Tmp = Val >> Shift; +- if (Tmp) +- Val = Tmp; +- else +- ZeroBits |= Shift; +- } +- return ZeroBits; -} - -/// Count the number of ones from the most significant bit to the first @@ -261,6 +283,23 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 - return std::numeric_limits::digits - llvm::countl_zero(Value); -} - +-/// Returns the number of bits needed to represent Value if Value is nonzero. +-/// Returns 0 otherwise. +-/// +-/// A constexpr version of bit_width. +-/// +-/// Ex. bit_width_constexpr(5) == 3. +-template [[nodiscard]] constexpr int bit_width_constexpr(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- int Width = 0; +- while (Value > 0) { +- Value >>= 1; +- ++Width; +- } +- return Width; +-} +- -/// Returns the largest integral power of two no greater than Value if Value is -/// nonzero. Returns 0 otherwise. -/// @@ -288,73 +327,44 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 - return T(1) << llvm::bit_width(Value - 1u); -} - --namespace detail { --template struct PopulationCounter { -- static int count(T Value) { -- // Generic version, forward to 32 bits. -- static_assert(SizeOfT <= 4, "Not implemented!"); --#if defined(__GNUC__) -- return (int)__builtin_popcount(Value); --#else -- uint32_t v = Value; -- v = v - ((v >> 1) & 0x55555555); -- v = (v & 0x33333333) + ((v >> 2) & 0x33333333); -- return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); --#endif -- } --}; -- --template struct PopulationCounter { -- static int count(T Value) { --#if defined(__GNUC__) -- return (int)__builtin_popcountll(Value); --#else -- uint64_t v = Value; -- v = v - ((v >> 1) & 0x5555555555555555ULL); -- v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); -- v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; -- return int((uint64_t)(v * 0x0101010101010101ULL) >> 56); --#endif -- } --}; --} // namespace detail -- --/// Count the number of set bits in a value. --/// Ex. popcount(0xF000F000) = 8 --/// Returns 0 if the word is zero. --template >> --[[nodiscard]] inline int popcount(T Value) noexcept { -- return detail::PopulationCounter::count(Value); +-/// Returns the smallest integral power of two no smaller than Value if Value is +-/// nonzero. Returns 1 otherwise. +-/// +-/// Ex. bit_ceil(5) == 8. +-/// +-/// The return value is undefined if the input is larger than the largest power +-/// of two representable in T. +-template [[nodiscard]] constexpr T bit_ceil_constexpr(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- if (Value < 2) +- return 1; +- return T(1) << llvm::bit_width_constexpr(Value - 1u); -} - --// Forward-declare rotr so that rotl can use it. --template >> --[[nodiscard]] constexpr T rotr(T V, int R); -- -template >> -[[nodiscard]] constexpr T rotl(T V, int R) { -- unsigned N = std::numeric_limits::digits; +- constexpr unsigned N = std::numeric_limits::digits; - -- R = R % N; -- if (!R) +- static_assert(has_single_bit(N), "& (N - 1) is only valid for powers of two"); +- R = R & (N - 1); +- +- if (R == 0) - return V; - -- if (R < 0) -- return llvm::rotr(V, -R); -- - return (V << R) | (V >> (N - R)); -} - --template [[nodiscard]] constexpr T rotr(T V, int R) { -- unsigned N = std::numeric_limits::digits; +-template >> +-[[nodiscard]] constexpr T rotr(T V, int R) { +- constexpr unsigned N = std::numeric_limits::digits; - -- R = R % N; -- if (!R) +- static_assert(has_single_bit(N), "& (N - 1) is only valid for powers of two"); +- R = R & (N - 1); +- +- if (R == 0) - return V; - -- if (R < 0) -- return llvm::rotl(V, -R); -- - return (V >> R) | (V << (N - R)); -} - @@ -362,18 +372,18 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59 #endif diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index acd16bb0e6cf73f565d44d654c34057d9b97dd95..5191831247ff668f22b6015d5b135fd9701afdd2 100644 +index 0735d9c9f756349a19c5aa2ec34ceca5d8274f16..38b1486c54be5102025192b3b90e86e54ab347c0 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -15,6 +15,7 @@ - +@@ -16,6 +16,7 @@ + #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/bit.h" #include "llvm/Support/Compiler.h" +#include #include #include #include -@@ -262,12 +263,12 @@ constexpr bool isShiftedMask_64(uint64_t Value) { +@@ -255,12 +256,12 @@ constexpr bool isShiftedMask_64(uint64_t Value) { /// Return true if the argument is a power of two > 0. /// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.) constexpr bool isPowerOf2_32(uint32_t Value) { @@ -388,7 +398,7 @@ index acd16bb0e6cf73f565d44d654c34057d9b97dd95..5191831247ff668f22b6015d5b135fd9 } /// Return true if the argument contains a non-empty sequence of ones with the -@@ -279,8 +280,8 @@ inline bool isShiftedMask_32(uint32_t Value, unsigned &MaskIdx, +@@ -272,8 +273,8 @@ inline bool isShiftedMask_32(uint32_t Value, unsigned &MaskIdx, unsigned &MaskLen) { if (!isShiftedMask_32(Value)) return false; @@ -399,7 +409,7 @@ index acd16bb0e6cf73f565d44d654c34057d9b97dd95..5191831247ff668f22b6015d5b135fd9 return true; } -@@ -292,8 +293,8 @@ inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, +@@ -285,8 +286,8 @@ inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, unsigned &MaskLen) { if (!isShiftedMask_64(Value)) return false; @@ -410,7 +420,16 @@ index acd16bb0e6cf73f565d44d654c34057d9b97dd95..5191831247ff668f22b6015d5b135fd9 return true; } -@@ -311,26 +312,26 @@ template <> constexpr size_t CTLog2<1>() { return 0; } +@@ -294,7 +295,7 @@ inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, + /// Valid only for positive powers of two. + template constexpr size_t ConstantLog2() { + static_assert(llvm::isPowerOf2_64(kValue), "Value is not a valid power of 2"); +- return llvm::countr_zero_constexpr(kValue); ++ return std::countr_zero(kValue); + } + + template +@@ -307,26 +308,26 @@ constexpr size_t CTLog2() { /// (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) { diff --git a/upstream_utils/llvm_patches/0028-Remove-DenseMap-GTest-printer-test.patch b/upstream_utils/llvm_patches/0026-DenseMap-remove-printer-test.patch similarity index 73% rename from upstream_utils/llvm_patches/0028-Remove-DenseMap-GTest-printer-test.patch rename to upstream_utils/llvm_patches/0026-DenseMap-remove-printer-test.patch index efc1e111c5..69144dc41a 100644 --- a/upstream_utils/llvm_patches/0028-Remove-DenseMap-GTest-printer-test.patch +++ b/upstream_utils/llvm_patches/0026-DenseMap-remove-printer-test.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Sun, 30 Jul 2023 14:17:37 -0700 -Subject: [PATCH 28/36] Remove DenseMap GTest printer test +Subject: [PATCH 26/33] DenseMap: remove printer test LLVM modifies internal GTest headers to support it, which we can't do. --- @@ -9,10 +9,10 @@ LLVM modifies internal GTest headers to support it, which we can't do. 1 file changed, 7 deletions(-) diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp -index b930a21f8b43b64835436fcd27f4802a7987827f..b49100899c658fa952d37e526880913d57d07c5c 100644 +index 1a81ecdd758ce285533fcb0565713f30a6cef33e..0b20004ebb91f519158d244d48aa71f2a23a0dca 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp -@@ -761,11 +761,4 @@ TEST(DenseMapCustomTest, VariantSupport) { +@@ -951,13 +951,6 @@ TEST(DenseMapCustomTest, VariantSupport) { EXPECT_FALSE(DenseMapInfo::isEqual(Keys[2], Keys[2])); } @@ -23,4 +23,6 @@ index b930a21f8b43b64835436fcd27f4802a7987827f..b49100899c658fa952d37e526880913d - EXPECT_EQ(R"({ (1, "one"), (2, "two") })", ::testing::PrintToString(Map)); -} - - } // namespace + TEST(DenseMapCustomTest, InitSize) { + constexpr unsigned ElemSize = sizeof(std::pair); + diff --git a/upstream_utils/llvm_patches/0029-raw_ostream-Add-SetNumBytesInBuffer.patch b/upstream_utils/llvm_patches/0027-raw_ostream-Add-SetNumBytesInBuffer.patch similarity index 80% rename from upstream_utils/llvm_patches/0029-raw_ostream-Add-SetNumBytesInBuffer.patch rename to upstream_utils/llvm_patches/0027-raw_ostream-Add-SetNumBytesInBuffer.patch index e7e921e355..48807c01d7 100644 --- a/upstream_utils/llvm_patches/0029-raw_ostream-Add-SetNumBytesInBuffer.patch +++ b/upstream_utils/llvm_patches/0027-raw_ostream-Add-SetNumBytesInBuffer.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sun, 29 Oct 2023 23:00:08 -0700 -Subject: [PATCH 29/36] raw_ostream: Add SetNumBytesInBuffer +Subject: [PATCH 27/33] raw_ostream: Add SetNumBytesInBuffer --- llvm/include/llvm/Support/raw_ostream.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index 264b8192a0473b94363765995517851cbf30d045..d0e5ba46a9e748037c2ad444207fc8fc236ec5d5 100644 +index f2df534b6bd7a37840fc0c3dba0f657b8b90812e..5289d11d630cc57deebff6647c684fa26a70a16a 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -365,6 +365,11 @@ protected: +@@ -366,6 +366,11 @@ protected: SetBufferAndMode(BufferStart, Size, BufferKind::ExternalBuffer); } diff --git a/upstream_utils/llvm_patches/0030-raw_ostream-Replace-errnoAsErrorCode.patch b/upstream_utils/llvm_patches/0028-raw_ostream-Replace-errnoAsErrorCode.patch similarity index 74% rename from upstream_utils/llvm_patches/0030-raw_ostream-Replace-errnoAsErrorCode.patch rename to upstream_utils/llvm_patches/0028-raw_ostream-Replace-errnoAsErrorCode.patch index 1564203d47..f76ae0ff4d 100644 --- a/upstream_utils/llvm_patches/0030-raw_ostream-Replace-errnoAsErrorCode.patch +++ b/upstream_utils/llvm_patches/0028-raw_ostream-Replace-errnoAsErrorCode.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 17 Sep 2024 15:30:31 -0700 -Subject: [PATCH 30/36] raw_ostream: Replace errnoAsErrorCode() +Subject: [PATCH 28/33] raw_ostream: Replace errnoAsErrorCode() --- llvm/lib/Support/raw_ostream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 7561f818287d208c628a126c3f8a6f7d531df236..816242fa1139d66467435a4b1acbfa93f799c00f 100644 +index 09f7ede10e4c3decb2c6d70a3e8ce7660f542519..a9cea8ac7fa2a7edbfeb76dbed6a92e189edbbd9 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -523,7 +523,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { +@@ -518,7 +518,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { } #endif // Otherwise it's a non-recoverable error. Note it and quit. @@ -20,7 +20,7 @@ index 7561f818287d208c628a126c3f8a6f7d531df236..816242fa1139d66467435a4b1acbfa93 break; } -@@ -553,7 +553,7 @@ uint64_t raw_fd_ostream::seek(uint64_t off) { +@@ -548,7 +548,7 @@ uint64_t raw_fd_ostream::seek(uint64_t off) { pos = ::lseek(FD, off, SEEK_SET); #endif if (pos == (uint64_t)-1) diff --git a/upstream_utils/llvm_patches/0031-type_traits.h-Add-is_constexpr.patch b/upstream_utils/llvm_patches/0029-type_traits.h-Add-is_constexpr.patch similarity index 68% rename from upstream_utils/llvm_patches/0031-type_traits.h-Add-is_constexpr.patch rename to upstream_utils/llvm_patches/0029-type_traits.h-Add-is_constexpr.patch index 0a1e762c85..b7d7fb236e 100644 --- a/upstream_utils/llvm_patches/0031-type_traits.h-Add-is_constexpr.patch +++ b/upstream_utils/llvm_patches/0029-type_traits.h-Add-is_constexpr.patch @@ -1,25 +1,25 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 2 Dec 2023 15:21:32 -0800 -Subject: [PATCH 31/36] type_traits.h: Add is_constexpr() +Subject: [PATCH 29/33] type_traits.h: Add is_constexpr() --- llvm/include/llvm/Support/type_traits.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/llvm/include/llvm/Support/type_traits.h b/llvm/include/llvm/Support/type_traits.h -index 3171af93fa7ffe4707c03289270cf5951e3db7c5..e1b094640876649709abc199f83942dbfef09771 100644 +index d037132fa5bada96b09f17a586fc292cbfb05e83..f77c097331693538b36f8131bdf3a27547fb6b41 100644 --- a/llvm/include/llvm/Support/type_traits.h +++ b/llvm/include/llvm/Support/type_traits.h -@@ -76,6 +76,11 @@ union trivial_helper { - - } // end namespace detail +@@ -55,6 +55,11 @@ template struct const_pointer_or_const_ref { + typename add_const_past_pointer::type, const T &>; + }; +// https://stackoverflow.com/questions/55288555/c-check-if-statement-can-be-evaluated-constexpr +template +constexpr bool is_constexpr(Lambda) { return true; } +constexpr bool is_constexpr(...) { return false; } + - } // end namespace llvm + } // namespace llvm #endif // LLVM_SUPPORT_TYPE_TRAITS_H diff --git a/upstream_utils/llvm_patches/0032-Remove-auto-conversion-from-raw_ostream.patch b/upstream_utils/llvm_patches/0030-raw_ostream-remove-auto-conversion.patch similarity index 63% rename from upstream_utils/llvm_patches/0032-Remove-auto-conversion-from-raw_ostream.patch rename to upstream_utils/llvm_patches/0030-raw_ostream-remove-auto-conversion.patch index e8e2e28d2d..aec8b8c304 100644 --- a/upstream_utils/llvm_patches/0032-Remove-auto-conversion-from-raw_ostream.patch +++ b/upstream_utils/llvm_patches/0030-raw_ostream-remove-auto-conversion.patch @@ -1,14 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Sun, 17 Mar 2024 14:51:11 -0700 -Subject: [PATCH 32/36] Remove auto-conversion from raw_ostream +Subject: [PATCH 30/33] raw_ostream: remove auto-conversion --- - llvm/lib/Support/raw_ostream.cpp | 11 +---------- - 1 file changed, 1 insertion(+), 10 deletions(-) + llvm/lib/Support/raw_ostream.cpp | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 816242fa1139d66467435a4b1acbfa93f799c00f..40da41028c75f4906b76e85b36ca546494d5bd12 100644 +index a9cea8ac7fa2a7edbfeb76dbed6a92e189edbbd9..21a00f58e3ed3a033a75fd5ca64d94486f9a8d42 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -19,7 +19,6 @@ @@ -19,25 +19,27 @@ index 816242fa1139d66467435a4b1acbfa93f799c00f..40da41028c75f4906b76e85b36ca5464 #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" -@@ -604,21 +603,13 @@ void raw_fd_ostream::anchor() {} - raw_fd_ostream &llvm::outs() { +@@ -600,23 +599,13 @@ raw_fd_ostream &llvm::outs() { // Set buffer settings to model stdout behavior. std::error_code EC; --#ifdef __MVS__ -- EC = enablezOSAutoConversion(STDOUT_FILENO); -- assert(!EC); --#endif + +- // On z/OS we need to enable auto conversion +- static std::error_code EC1 = enableAutoConversion(STDOUT_FILENO); +- assert(!EC1); +- (void)EC1; +- static raw_fd_ostream* S = new raw_fd_ostream("-", EC, sys::fs::OF_None); assert(!EC); return *S; } raw_fd_ostream &llvm::errs() { -- // Set standard error to be unbuffered. --#ifdef __MVS__ -- std::error_code EC = enablezOSAutoConversion(STDERR_FILENO); +- // On z/OS we need to enable auto conversion +- static std::error_code EC = enableAutoConversion(STDERR_FILENO); - assert(!EC); --#endif +- (void)EC; +- +- // Set standard error to be unbuffered. + // Set standard error to be unbuffered and tied to outs() by default. static raw_fd_ostream* S = new raw_fd_ostream(STDERR_FILENO, false, true); return *S; diff --git a/upstream_utils/llvm_patches/0033-Add-SmallVector-erase_if.patch b/upstream_utils/llvm_patches/0031-SmallVector-add-erase_if.patch similarity index 70% rename from upstream_utils/llvm_patches/0033-Add-SmallVector-erase_if.patch rename to upstream_utils/llvm_patches/0031-SmallVector-add-erase_if.patch index 3f104a9168..98f00dac9a 100644 --- a/upstream_utils/llvm_patches/0033-Add-SmallVector-erase_if.patch +++ b/upstream_utils/llvm_patches/0031-SmallVector-add-erase_if.patch @@ -1,19 +1,19 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Tue, 18 Jun 2024 09:07:33 -0700 -Subject: [PATCH 33/36] Add SmallVector erase_if() +Subject: [PATCH 31/33] SmallVector: add erase_if() --- llvm/include/llvm/ADT/SmallVector.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index b8981ab67322f7888ad63d953ba72dbfa53b2939..9a22c95aaf84d276b1c097c0997de3e6b04ea05e 100644 +index 7f759efc1588bfb6eaef65b822bbdbf4f201ef8b..e51771928717625a218981ccd5b9068b63329b02 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -1315,6 +1315,14 @@ template SmallVector to_vector_of(R &&Range) { - return {std::begin(Range), std::end(Range)}; - } +@@ -1344,6 +1344,14 @@ template struct DenseMapInfo> { + } + }; +template +typename SmallVectorImpl::size_type erase_if( diff --git a/upstream_utils/llvm_patches/0035-Fix-minIntN-and-maxIntN-assertions.patch b/upstream_utils/llvm_patches/0032-MathExtras-fix-minIntN-and-maxIntN-assertions.patch similarity index 70% rename from upstream_utils/llvm_patches/0035-Fix-minIntN-and-maxIntN-assertions.patch rename to upstream_utils/llvm_patches/0032-MathExtras-fix-minIntN-and-maxIntN-assertions.patch index d2b46e650e..425c6e3c89 100644 --- a/upstream_utils/llvm_patches/0035-Fix-minIntN-and-maxIntN-assertions.patch +++ b/upstream_utils/llvm_patches/0032-MathExtras-fix-minIntN-and-maxIntN-assertions.patch @@ -1,29 +1,29 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Mon, 23 Dec 2024 22:56:29 -0800 -Subject: [PATCH 35/36] Fix minIntN() and maxIntN() assertions +Subject: [PATCH 32/33] MathExtras: fix minIntN() and maxIntN() assertions --- llvm/include/llvm/Support/MathExtras.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index 5191831247ff668f22b6015d5b135fd9701afdd2..5b2dccf8959856f2c6dbf3cc4d5260d1ad541459 100644 +index 38b1486c54be5102025192b3b90e86e54ab347c0..3141d443674735f334c5da934f891c113c31d582 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -203,7 +203,7 @@ inline uint64_t maxUIntN(uint64_t N) { +@@ -196,7 +196,7 @@ inline constexpr uint64_t maxUIntN(uint64_t N) { /// Gets the minimum value for a N-bit signed integer. - inline int64_t minIntN(int64_t N) { + inline constexpr int64_t minIntN(int64_t N) { - assert(N <= 64 && "integer width out of range"); + assert(N >= 0 && N <= 64 && "integer width out of range"); if (N == 0) return 0; -@@ -216,7 +216,7 @@ inline int64_t minIntN(int64_t N) { +@@ -209,7 +209,7 @@ inline constexpr int64_t minIntN(int64_t N) { /// Gets the maximum value for a N-bit signed integer. - inline int64_t maxIntN(int64_t N) { + inline constexpr int64_t maxIntN(int64_t N) { - assert(N <= 64 && "integer width out of range"); + assert(N >= 0 && N <= 64 && "integer width out of range"); diff --git a/upstream_utils/llvm_patches/0036-Add-postincrement-operator-to-SmallSetIterator.patch b/upstream_utils/llvm_patches/0033-SmallSet-add-SmallSetIterator-postincrement-operator.patch similarity index 76% rename from upstream_utils/llvm_patches/0036-Add-postincrement-operator-to-SmallSetIterator.patch rename to upstream_utils/llvm_patches/0033-SmallSet-add-SmallSetIterator-postincrement-operator.patch index 562a56e108..1beb57a91b 100644 --- a/upstream_utils/llvm_patches/0036-Add-postincrement-operator-to-SmallSetIterator.patch +++ b/upstream_utils/llvm_patches/0033-SmallSet-add-SmallSetIterator-postincrement-operator.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: crueter Date: Wed, 6 May 2026 12:42:53 -0400 -Subject: [PATCH 36/36] Add postincrement operator to SmallSetIterator +Subject: [PATCH 33/33] SmallSet: add SmallSetIterator postincrement operator Required for Xcode 26.4 --- @@ -9,10 +9,10 @@ Required for Xcode 26.4 1 file changed, 6 insertions(+) diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h -index c62a3a55d9bda188670e7d6042867943dcd44c68..ffe5ae6e227368dc5582258b402c6521d68bc724 100644 +index 2bc8ed01ff84671b5246a0dee42a76f086bb4687..1221621b7d1123831710ce74e5de4d0ab5f30422 100644 --- a/llvm/include/llvm/ADT/SmallSet.h +++ b/llvm/include/llvm/ADT/SmallSet.h -@@ -121,6 +121,12 @@ public: +@@ -122,6 +122,12 @@ public: return *this; } diff --git a/upstream_utils/llvm_patches/0034-Fix-AlignedCharArrayUnion-for-C-23.patch b/upstream_utils/llvm_patches/0034-Fix-AlignedCharArrayUnion-for-C-23.patch deleted file mode 100644 index 6390f93d12..0000000000 --- a/upstream_utils/llvm_patches/0034-Fix-AlignedCharArrayUnion-for-C-23.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tyler Veness -Date: Sat, 13 Jul 2024 15:24:30 -0700 -Subject: [PATCH 34/36] Fix AlignedCharArrayUnion for C++23 - ---- - llvm/include/llvm/Support/AlignOf.h | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/llvm/include/llvm/Support/AlignOf.h b/llvm/include/llvm/Support/AlignOf.h -index f586d7f182aab6e56b7fae6ae98a7cd89e63976c..ca98a564733a07a5e16122d31805e970bf76b673 100644 ---- a/llvm/include/llvm/Support/AlignOf.h -+++ b/llvm/include/llvm/Support/AlignOf.h -@@ -13,20 +13,16 @@ - #ifndef LLVM_SUPPORT_ALIGNOF_H - #define LLVM_SUPPORT_ALIGNOF_H - --#include -+#include -+#include - - namespace llvm { - - /// A suitably aligned and sized character array member which can hold elements - /// of any type. --/// --/// This template is equivalent to std::aligned_union_t<1, ...>, but we cannot --/// use it due to a bug in the MSVC x86 compiler: --/// https://github.com/microsoft/STL/issues/1533 --/// Using `alignas` here works around the bug. --template struct AlignedCharArrayUnion { -- using AlignedUnion = std::aligned_union_t<1, T, Ts...>; -- alignas(alignof(AlignedUnion)) char buffer[sizeof(AlignedUnion)]; -+template struct AlignedCharArrayUnion { -+ alignas((std::max)({alignof(Ts)...})) -+ std::byte buffer[(std::max)({static_cast(1), sizeof(Ts)...})]; - }; - - } // end namespace llvm diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp index d7bf17a081..110fbe062e 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp @@ -84,7 +84,7 @@ # define ConvertUTF_RESTORE_WARNINGS \ _Pragma("clang diagnostic pop") # endif -#elif defined(__GNUC__) && __GNUC__ > 6 +#elif defined(__GNUC__) # define ConvertUTF_DISABLE_WARNINGS \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp index cabc377fb2..5eaa2fbb81 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp @@ -305,5 +305,15 @@ bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl &Result } } +bool IsSingleCodeUnitUTF8Codepoint(unsigned V) { return V <= 0x7F; } + +bool IsSingleCodeUnitUTF16Codepoint(unsigned V) { + return V <= 0xD7FF || (V >= 0xE000 && V <= 0xFFFF); +} + +bool IsSingleCodeUnitUTF32Codepoint(unsigned V) { + return V <= 0xD7FF || (V >= 0xE000 && V <= 0x10FFFF); +} + } // end namespace wpi::util diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ErrorHandling.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ErrorHandling.cpp index 8d8c68de97..99ec397dac 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ErrorHandling.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ErrorHandling.cpp @@ -14,6 +14,7 @@ #include "wpi/util/ErrorHandling.hpp" #include "wpi/util/SmallVector.hpp" #include "wpi/util/Errc.hpp" +#include "wpi/util/Errno.hpp" #include "wpi/util/WindowsError.hpp" #include "wpi/util/print.hpp" #include @@ -50,6 +51,21 @@ static void *BadAllocErrorHandlerUserData = nullptr; static std::mutex ErrorHandlerMutex; static std::mutex BadAllocErrorHandlerMutex; +static bool write_retry(int fd, const char *buf, size_t count) { + while (count > 0) { +#ifdef _WIN32 + int written = sys::RetryAfterSignal(-1, ::_write, fd, buf, count); +#else + ssize_t written = sys::RetryAfterSignal(-1, ::write, fd, buf, count); +#endif + if (written <= 0) + return false; + buf += written; + count -= written; + } + return true; +} + void wpi::util::install_fatal_error_handler(fatal_error_handler_t handler, void *user_data) { std::scoped_lock Lock(ErrorHandlerMutex); @@ -92,6 +108,25 @@ void wpi::util::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { exit(1); } +void wpi::util::reportFatalInternalError(const char *reason) { + report_fatal_error(reason, /*GenCrashDiag=*/true); +} +void wpi::util::reportFatalInternalError(const std::string& reason) { + report_fatal_error(reason, /*GenCrashDiag=*/true); +} +void wpi::util::reportFatalInternalError(std::string_view reason) { + report_fatal_error(reason, /*GenCrashDiag=*/true); +} +void wpi::util::reportFatalUsageError(const char *reason) { + report_fatal_error(reason, /*GenCrashDiag=*/false); +} +void wpi::util::reportFatalUsageError(const std::string& reason) { + report_fatal_error(reason, /*GenCrashDiag=*/false); +} +void wpi::util::reportFatalUsageError(std::string_view reason) { + report_fatal_error(reason, /*GenCrashDiag=*/false); +} + void wpi::util::install_bad_alloc_error_handler(fatal_error_handler_t handler, void *user_data) { std::scoped_lock Lock(BadAllocErrorHandlerMutex); @@ -127,15 +162,9 @@ void wpi::util::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 + write_retry(2, OOMMessage, strlen(OOMMessage)); + write_retry(2, Reason, strlen(Reason)); + write_retry(2, Newline, strlen(Newline)); abort(); } diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallPtrSet.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallPtrSet.cpp index a30825eaf5..3ef292eba1 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallPtrSet.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallPtrSet.cpp @@ -28,7 +28,7 @@ void SmallPtrSetImplBase::shrink_and_clear() { // Reduce the number of buckets. unsigned Size = size(); CurArraySize = Size > 16 ? 1 << (Log2_32_Ceil(Size) + 1) : 32; - NumNonEmpty = NumTombstones = 0; + NumEntries = NumTombstones = 0; // Install the new array. Clear all the buckets to empty. CurArray = (const void**)safe_malloc(sizeof(void*) * CurArraySize); @@ -41,7 +41,8 @@ SmallPtrSetImplBase::insert_imp_big(const void *Ptr) { if (LLVM_UNLIKELY(size() * 4 >= CurArraySize * 3)) { // If more than 3/4 of the array is full, grow. Grow(CurArraySize < 64 ? 128 : CurArraySize * 2); - } else if (LLVM_UNLIKELY(CurArraySize - NumNonEmpty < CurArraySize / 8)) { + } else if (LLVM_UNLIKELY(CurArraySize - NumEntries - NumTombstones < + CurArraySize / 8)) { // If fewer of 1/8 of the array is empty (meaning that many are filled with // tombstones), rehash. Grow(CurArraySize); @@ -50,16 +51,15 @@ SmallPtrSetImplBase::insert_imp_big(const void *Ptr) { // Okay, we know we have space. Find a hash bucket. const void **Bucket = const_cast(FindBucketFor(Ptr)); if (*Bucket == Ptr) - return std::make_pair(Bucket, false); // Already inserted, good. + return {Bucket, false}; // Already inserted, good. // Otherwise, insert it! if (*Bucket == getTombstoneMarker()) --NumTombstones; - else - ++NumNonEmpty; // Track density. + ++NumEntries; *Bucket = Ptr; incrementEpoch(); - return std::make_pair(Bucket, true); + return {Bucket, true}; } const void *const *SmallPtrSetImplBase::doFind(const void *Ptr) const { @@ -110,8 +110,7 @@ const void *const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const { /// Grow - Allocate a larger backing store for the buckets and move it over. /// void SmallPtrSetImplBase::Grow(unsigned NewSize) { - const void **OldBuckets = CurArray; - const void **OldEnd = EndPointer(); + auto OldBuckets = buckets(); bool WasSmall = isSmall(); // Install the new array. Clear all the buckets to empty. @@ -123,16 +122,14 @@ void SmallPtrSetImplBase::Grow(unsigned NewSize) { memset(CurArray, -1, NewSize*sizeof(void*)); // Copy over all valid entries. - for (const void **BucketPtr = OldBuckets; BucketPtr != OldEnd; ++BucketPtr) { + for (const void *&Bucket : OldBuckets) { // Copy over the element if it is valid. - const void *Elt = *BucketPtr; - if (Elt != getTombstoneMarker() && Elt != getEmptyMarker()) - *const_cast(FindBucketFor(Elt)) = const_cast(Elt); + if (Bucket != getTombstoneMarker() && Bucket != getEmptyMarker()) + *const_cast(FindBucketFor(Bucket)) = const_cast(Bucket); } if (!WasSmall) - free(OldBuckets); - NumNonEmpty -= NumTombstones; + free(OldBuckets.begin()); NumTombstones = 0; IsSmall = false; } @@ -193,9 +190,9 @@ void SmallPtrSetImplBase::copyHelper(const SmallPtrSetImplBase &RHS) { CurArraySize = RHS.CurArraySize; // Copy over the contents from the other set - std::copy(RHS.CurArray, RHS.EndPointer(), CurArray); + std::ranges::copy(RHS.buckets(), CurArray); - NumNonEmpty = RHS.NumNonEmpty; + NumEntries = RHS.NumEntries; NumTombstones = RHS.NumTombstones; } @@ -217,7 +214,7 @@ void SmallPtrSetImplBase::moveHelper(const void **SmallStorage, if (RHS.isSmall()) { // Copy a small RHS rather than moving. CurArray = SmallStorage; - std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, CurArray); + std::ranges::copy(RHS.small_buckets(), CurArray); } else { CurArray = RHS.CurArray; RHS.CurArray = RHSSmallStorage; @@ -225,13 +222,13 @@ void SmallPtrSetImplBase::moveHelper(const void **SmallStorage, // Copy the rest of the trivial members. CurArraySize = RHS.CurArraySize; - NumNonEmpty = RHS.NumNonEmpty; + NumEntries = RHS.NumEntries; NumTombstones = RHS.NumTombstones; IsSmall = RHS.IsSmall; // Make the RHS small and empty. RHS.CurArraySize = SmallSize; - RHS.NumNonEmpty = 0; + RHS.NumEntries = 0; RHS.NumTombstones = 0; RHS.IsSmall = true; } @@ -245,54 +242,42 @@ void SmallPtrSetImplBase::swap(const void **SmallStorage, if (!this->isSmall() && !RHS.isSmall()) { std::swap(this->CurArray, RHS.CurArray); std::swap(this->CurArraySize, RHS.CurArraySize); - std::swap(this->NumNonEmpty, RHS.NumNonEmpty); + std::swap(this->NumEntries, RHS.NumEntries); std::swap(this->NumTombstones, RHS.NumTombstones); return; } // FIXME: From here on we assume that both sets have the same small size. - // If only RHS is small, copy the small elements into LHS and move the pointer - // from LHS to RHS. - if (!this->isSmall() && RHS.isSmall()) { - std::copy(RHS.CurArray, RHS.CurArray + RHS.NumNonEmpty, SmallStorage); - std::swap(RHS.CurArraySize, this->CurArraySize); - std::swap(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap(this->NumTombstones, RHS.NumTombstones); - RHS.CurArray = this->CurArray; - RHS.IsSmall = false; - this->CurArray = SmallStorage; - this->IsSmall = true; - return; - } - - // If only LHS is small, copy the small elements into RHS and move the pointer - // from RHS to LHS. - if (this->isSmall() && !RHS.isSmall()) { - std::copy(this->CurArray, this->CurArray + this->NumNonEmpty, - RHSSmallStorage); - std::swap(RHS.CurArraySize, this->CurArraySize); - std::swap(RHS.NumNonEmpty, this->NumNonEmpty); - std::swap(RHS.NumTombstones, this->NumTombstones); - this->CurArray = RHS.CurArray; - this->IsSmall = false; - RHS.CurArray = RHSSmallStorage; - RHS.IsSmall = true; - return; - } - // Both a small, just swap the small elements. - assert(this->isSmall() && RHS.isSmall()); - unsigned MinNonEmpty = std::min(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap_ranges(this->CurArray, this->CurArray + MinNonEmpty, RHS.CurArray); - if (this->NumNonEmpty > MinNonEmpty) { - std::copy(this->CurArray + MinNonEmpty, this->CurArray + this->NumNonEmpty, - RHS.CurArray + MinNonEmpty); - } else { - std::copy(RHS.CurArray + MinNonEmpty, RHS.CurArray + RHS.NumNonEmpty, - this->CurArray + MinNonEmpty); + if (this->isSmall() && RHS.isSmall()) { + unsigned MinEntries = std::min(this->NumEntries, RHS.NumEntries); + std::swap_ranges(this->CurArray, this->CurArray + MinEntries, RHS.CurArray); + if (this->NumEntries > MinEntries) { + std::copy(this->CurArray + MinEntries, this->CurArray + this->NumEntries, + RHS.CurArray + MinEntries); + } else { + std::copy(RHS.CurArray + MinEntries, RHS.CurArray + RHS.NumEntries, + this->CurArray + MinEntries); + } + assert(this->CurArraySize == RHS.CurArraySize); + std::swap(this->NumEntries, RHS.NumEntries); + std::swap(this->NumTombstones, RHS.NumTombstones); + return; } - assert(this->CurArraySize == RHS.CurArraySize); - std::swap(this->NumNonEmpty, RHS.NumNonEmpty); - std::swap(this->NumTombstones, RHS.NumTombstones); + + // If only one side is small, copy the small elements into the large side and + // move the pointer from the large side to the small side. + SmallPtrSetImplBase &SmallSide = this->isSmall() ? *this : RHS; + SmallPtrSetImplBase &LargeSide = this->isSmall() ? RHS : *this; + const void **LargeSideInlineStorage = + this->isSmall() ? RHSSmallStorage : SmallStorage; + std::ranges::copy(SmallSide.small_buckets(), LargeSideInlineStorage); + std::swap(LargeSide.CurArraySize, SmallSide.CurArraySize); + std::swap(LargeSide.NumEntries, SmallSide.NumEntries); + std::swap(LargeSide.NumTombstones, SmallSide.NumTombstones); + SmallSide.CurArray = LargeSide.CurArray; + SmallSide.IsSmall = false; + LargeSide.CurArray = LargeSideInlineStorage; + LargeSide.IsSmall = true; } diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.hpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.hpp index e7f28f870e..f03295004a 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.hpp @@ -82,15 +82,15 @@ inline bool RunningWindows8OrGreater() { } /// Determines if the program is running on Windows 11 or Windows Server 2022. -bool RunningWindows11OrGreater(); +LLVM_ABI bool RunningWindows11OrGreater(); /// 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. -wpi::util::VersionTuple GetWindowsOSVersion(); +LLVM_ABI wpi::util::VersionTuple GetWindowsOSVersion(); -bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); +LLVM_ABI bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); // Include GetLastError() in a fatal error message. [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) { diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp index 0258a9bced..1e8f66b33b 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp @@ -21,6 +21,7 @@ #include "wpi/util/Compiler.hpp" #include "wpi/util/ErrorHandling.hpp" #include "wpi/util/fs.hpp" +#include "wpi/util/IOSandbox.hpp" #include "wpi/util/MathExtras.hpp" #include #include @@ -59,17 +60,6 @@ using namespace wpi::util; -constexpr raw_ostream::Colors raw_ostream::BLACK; -constexpr raw_ostream::Colors raw_ostream::RED; -constexpr raw_ostream::Colors raw_ostream::GREEN; -constexpr raw_ostream::Colors raw_ostream::YELLOW; -constexpr raw_ostream::Colors raw_ostream::BLUE; -constexpr raw_ostream::Colors raw_ostream::MAGENTA; -constexpr raw_ostream::Colors raw_ostream::CYAN; -constexpr raw_ostream::Colors raw_ostream::WHITE; -constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR; -constexpr raw_ostream::Colors raw_ostream::RESET; - raw_ostream::~raw_ostream() { // raw_ostream's subclasses should take care to flush the buffer // in their destructors. @@ -288,6 +278,9 @@ void raw_ostream::anchor() {} static int getFD(std::string_view Filename, std::error_code &EC, fs::CreationDisposition Disp, fs::FileAccess Access, fs::OpenFlags Flags) { + // FIXME(sandboxing): Remove this by adopting `wpi::util::vfs::OutputBackend`. + auto BypassSandbox = sys::sandbox::scopedDisable(); + assert((Access & fs::FA_Write) && "Cannot make a raw_ostream from a read-only descriptor!"); @@ -347,6 +340,9 @@ raw_fd_ostream::raw_fd_ostream(std::string_view Filename, std::error_code &EC, raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, OStreamKind K) : raw_pwrite_stream(unbuffered, K), FD(fd), ShouldClose(shouldClose) { + // FIXME(sandboxing): Remove this by adopting `wpi::util::vfs::OutputBackend`. + auto BypassSandbox = sys::sandbox::scopedDisable(); + if (FD < 0 ) { ShouldClose = false; return; @@ -402,8 +398,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("IO failure on output stream: " + error().message(), - /*gen_crash_diag=*/false); + reportFatalUsageError("IO failure on output stream: " + error().message()); } #if defined(_WIN32) @@ -596,6 +591,7 @@ void raw_fd_ostream::anchor() {} raw_fd_ostream &wpi::util::outs() { // Set buffer settings to model stdout behavior. std::error_code EC; + static raw_fd_ostream* S = new raw_fd_ostream("-", EC, fs::OF_None); assert(!EC); return *S; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AlignOf.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AlignOf.hpp index 484c2df504..26868347ea 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AlignOf.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AlignOf.hpp @@ -14,15 +14,16 @@ #define WPIUTIL_WPI_ALIGNOF_H #include -#include namespace wpi::util { /// A suitably aligned and sized character array member which can hold elements /// of any type. -template struct AlignedCharArrayUnion { - alignas((std::max)({alignof(Ts)...})) - std::byte buffer[(std::max)({static_cast(1), sizeof(Ts)...})]; +template struct AlignedCharArrayUnion { + // Work around "internal compiler error: Segmentation fault" with GCC 7.5, + // apparently caused by alignas(Ts...). + static constexpr std::size_t Align = (std::max)({alignof(T), alignof(Ts)...}); + alignas(Align) char buffer[(std::max)({sizeof(T), sizeof(Ts)...})]; }; } // end namespace wpi::util diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AllocatorBase.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AllocatorBase.hpp index c1ae124352..5c7491b099 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AllocatorBase.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/AllocatorBase.hpp @@ -28,6 +28,7 @@ #include "wpi/util/Compiler.hpp" #include "wpi/util/MemAlloc.hpp" #include +#include namespace wpi::util { @@ -111,7 +112,7 @@ template class AllocatorHolder : Alloc { public: AllocatorHolder() = default; AllocatorHolder(const Alloc &A) : Alloc(A) {} - AllocatorHolder(Alloc &&A) : Alloc(static_cast(A)) {} + AllocatorHolder(Alloc &&A) : Alloc(std::move(A)) {} Alloc &getAllocator() { return *this; } const Alloc &getAllocator() const { return *this; } }; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Casting.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Casting.hpp index 12136e3a1b..f3e617a711 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Casting.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Casting.hpp @@ -340,7 +340,7 @@ struct ValueFromPointerCast /// during the cast. It's also a good example of how to implement a move-only /// cast. template -struct UniquePtrCast : public CastIsPossible { +struct UniquePtrCast : CastIsPossible { using Self = detail::SelfType>; using CastResultType = std::unique_ptr< std::remove_reference_t::ret_type>>; @@ -473,7 +473,7 @@ struct ForwardToPointerCast { // take advantage of the cast traits whenever possible! template -struct CastInfo : public CastIsPossible { +struct CastInfo : CastIsPossible { using Self = CastInfo; using CastReturnType = typename cast_retty::ret_type; @@ -536,22 +536,16 @@ struct CastInfo> : public UniquePtrCast {}; /// the input is std::optional that the output can be std::optional. /// If that's not the case, specialize CastInfo for your use case. template -struct CastInfo> : public OptionalValueCast { -}; +struct CastInfo> : OptionalValueCast {}; /// isa - Return true if the parameter to the template is an instance of one /// of the template type arguments. Used like this: /// /// if (isa(myVal)) { ... } /// if (isa(myVal)) { ... } -template +template [[nodiscard]] inline bool isa(const From &Val) { - return CastInfo::isPossible(Val); -} - -template -[[nodiscard]] inline bool isa(const From &Val) { - return isa(Val) || isa(Val); + return (CastInfo::isPossible(Val) || ...); } /// cast - Return the argument parameter cast to the specified type. This @@ -822,6 +816,42 @@ template struct IsaAndPresentCheckPredicate { return isa_and_present(Val); } }; + +//===----------------------------------------------------------------------===// +// Casting Function Objects +//===----------------------------------------------------------------------===// + +/// Usable in generic algorithms like map_range +template struct StaticCastFunc { + template decltype(auto) operator()(T &&Val) const { + return static_cast(Val); + } +}; + +template struct DynCastFunc { + template decltype(auto) operator()(T &&Val) const { + return dyn_cast(Val); + } +}; + +template struct CastFunc { + template decltype(auto) operator()(T &&Val) const { + return cast(Val); + } +}; + +template struct CastIfPresentFunc { + template decltype(auto) operator()(T &&Val) const { + return cast_if_present(Val); + } +}; + +template struct DynCastIfPresentFunc { + template decltype(auto) operator()(T &&Val) const { + return dyn_cast_if_present(Val); + } +}; + } // namespace detail /// Function object wrapper for the `wpi::util::isa` type check. The function call @@ -847,6 +877,20 @@ template inline constexpr detail::IsaAndPresentCheckPredicate IsaAndPresentPred{}; +/// Function objects corresponding to the Cast types defined above. +template +inline constexpr detail::StaticCastFunc StaticCastTo{}; + +template inline constexpr detail::CastFunc CastTo{}; + +template +inline constexpr detail::CastIfPresentFunc CastIfPresentTo{}; + +template +inline constexpr detail::DynCastIfPresentFunc DynCastIfPresentTo{}; + +template inline constexpr detail::DynCastFunc DynCastTo{}; + } // end namespace wpi::util #endif // WPIUTIL_WPI_CASTING_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Chrono.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Chrono.hpp index cd40cab6ac..bf8149ec1f 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Chrono.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Chrono.hpp @@ -76,8 +76,8 @@ toTimePoint(std::time_t T, uint32_t nsec) { } // namespace sys -raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP); -raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP); +LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, sys::TimePoint<> TP); +LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, sys::UtcTime<> TP); } // namespace wpi::util diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Compiler.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Compiler.hpp index ef642c4751..6a4b65fe01 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Compiler.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Compiler.hpp @@ -38,6 +38,10 @@ # define __has_builtin(x) 0 #endif +#ifndef __has_warning +# define __has_warning(x) 0 +#endif + // Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in // C mode, but the :: in __has_cpp_attribute(scoped::attribute) is invalid. #ifndef LLVM_HAS_CPP_ATTRIBUTE @@ -130,7 +134,7 @@ #endif #if (!(defined(_WIN32) || defined(__CYGWIN__)) || \ - (defined(__MINGW32__) && defined(__clang__))) + ((defined(__MINGW32__) || defined(__CYGWIN__)) && defined(__clang__))) #define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN // Clang compilers older then 15 do not support gnu style attributes on // namespaces. @@ -168,26 +172,19 @@ /// for both functions and classes. On windows its turned in to dllimport for /// library consumers, for other platforms its a default visibility attribute. /// -/// LLVM_C_ABI is used to annotated functions and data that need to be exported -/// for the libllvm-c API. This used both for the llvm-c headers and for the -/// functions declared in the different Target's c++ source files that don't -/// include the header forward declaring them. +/// LLVM_ABI_FOR_TEST is for annotating symbols that are only exported because +/// they are imported from a test. These symbols are not technically part of the +/// LLVM public interface and could be conditionally excluded when not building +/// tests in the future. +/// #ifndef LLVM_ABI_GENERATING_ANNOTATIONS // Marker to add to classes or functions in public headers that should not have // export macros added to them by the clang tool #define LLVM_ABI_NOT_EXPORTED -#if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS) || \ - defined(LLVM_ENABLE_PLUGINS) -// Some libraries like those for tablegen are linked in to tools that used -// in the build so can't depend on the llvm shared library. If export macros -// were left enabled when building these we would get duplicate or -// missing symbol linker errors on windows. -#if defined(LLVM_BUILD_STATIC) -#define LLVM_ABI -#define LLVM_TEMPLATE_ABI -#define LLVM_EXPORT_TEMPLATE -#define LLVM_ABI_EXPORT -#elif defined(_WIN32) && !defined(__MINGW32__) +// TODO(https://github.com/llvm/llvm-project/issues/145406): eliminate need for +// two preprocessor definitions to gate LLVM_ABI macro definitions. +#if defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && !defined(LLVM_BUILD_STATIC) +#if defined(_WIN32) && !defined(__MINGW32__) #if defined(LLVM_EXPORTS) #define LLVM_ABI __declspec(dllexport) #define LLVM_TEMPLATE_ABI @@ -198,25 +195,28 @@ #define LLVM_EXPORT_TEMPLATE #endif #define LLVM_ABI_EXPORT __declspec(dllexport) -#elif defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) || \ - defined(__MVS__) -#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT -#define LLVM_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#elif __has_attribute(visibility) +#if defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) || \ + defined(__MVS__) || defined(__CYGWIN__) +#define LLVM_ABI __attribute__((visibility("default"))) +#define LLVM_TEMPLATE_ABI LLVM_ABI #define LLVM_EXPORT_TEMPLATE -#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define LLVM_ABI_EXPORT LLVM_ABI #elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__) -#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define LLVM_ABI __attribute__((visibility("default"))) #define LLVM_TEMPLATE_ABI #define LLVM_EXPORT_TEMPLATE -#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#define LLVM_ABI_EXPORT LLVM_ABI #endif -#else +#endif +#endif +#if !defined(LLVM_ABI) #define LLVM_ABI #define LLVM_TEMPLATE_ABI #define LLVM_EXPORT_TEMPLATE #define LLVM_ABI_EXPORT #endif -#define LLVM_C_ABI LLVM_ABI +#define LLVM_ABI_FOR_TEST LLVM_ABI #endif #ifndef LLVM_PREFETCH @@ -227,6 +227,12 @@ #endif #endif +#if __has_attribute(uninitialized) +#define LLVM_ATTRIBUTE_UNINITIALIZED __attribute__((uninitialized)) +#else +#define LLVM_ATTRIBUTE_UNINITIALIZED +#endif + #ifndef LLVM_ATTRIBUTE_USED #if __has_attribute(used) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) @@ -235,6 +241,16 @@ #endif #endif +// Only enabled for clang: +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99587 +// GCC may produce "warning: 'retain' attribute ignored" (despite +// __has_attribute(retain) being 1). +#if defined(__clang__) && __has_attribute(retain) +#define LLVM_ATTRIBUTE_RETAIN __attribute__((__retain__)) +#else +#define LLVM_ATTRIBUTE_RETAIN +#endif + #if defined(__clang__) #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX))) #else @@ -657,7 +673,8 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); // 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 +#define LLVM_DUMP_METHOD \ + LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED LLVM_ATTRIBUTE_RETAIN #else #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE #endif @@ -724,4 +741,37 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #define LLVM_PREFERRED_TYPE(T) #endif +#if LLVM_HAS_CPP_ATTRIBUTE(clang::ptrauth_vtable_pointer) && \ + (defined(__PTRAUTH__) || __has_feature(ptrauth_calls)) +#define LLVM_MOVABLE_POLYMORPHIC_TYPE \ + [[clang::ptrauth_vtable_pointer(default_key, no_address_discrimination, \ + default_extra_discrimination)]] +#else +#define LLVM_MOVABLE_POLYMORPHIC_TYPE +#endif + +/// \macro LLVM_VIRTUAL_ANCHOR_FUNCTION +/// This macro is used to adhere to LLVM's policy that each class with a vtable +/// must have at least one out-of-line virtual function. This macro allows us +/// to declare such a function in `final` classes without triggering a warning. +// clang-format off +// Autoformatting makes this look awful. +#if defined(__clang__) + // Make sure this is only parsed if __clang__ is defined + #if __has_warning("-Wunnecessary-virtual-specifier") + #define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wunnecessary-virtual-specifier\"") \ + virtual void anchor() \ + _Pragma("clang diagnostic pop") + #else // __has_warning + #define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \ + virtual void anchor() + #endif +#else // defined(__clang__) + #define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \ + virtual void anchor() +#endif +// clang-format on + #endif diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ConvertUTF.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ConvertUTF.hpp index c8a07714b9..7e3fcc1db5 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ConvertUTF.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ConvertUTF.hpp @@ -47,7 +47,7 @@ Conversions between UTF32, UTF-16, and UTF-8. Header file. - Several funtions are included here, forming a complete set of + Several functions are included here, forming a complete set of conversions between the three formats. UTF-7 is not included here, but is handled in a separate source file. @@ -105,6 +105,7 @@ #ifndef WPIUTIL_WPI_CONVERTUTF_H #define WPIUTIL_WPI_CONVERTUTF_H +#include "wpi/util/Compiler.hpp" #include #include #include @@ -124,10 +125,10 @@ namespace wpi::util { bit mask & shift operations. ------------------------------------------------------------------------ */ -typedef unsigned int UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef bool Boolean; /* 0 or 1 */ +using UTF32 = unsigned int; /* at least 32 bits */ +using UTF16 = unsigned short; /* at least 16 bits */ +using UTF8 = unsigned char; /* typically 8 bits */ +using Boolean = bool; /* 0 or 1 */ /* Some fundamental constants */ #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD @@ -144,61 +145,73 @@ typedef bool Boolean; /* 0 or 1 */ #define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0x0000FEFF #define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE0000 -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; +enum ConversionResult { + conversionOK, /* conversion successful */ + sourceExhausted, /* partial character in source, but hit end */ + targetExhausted, /* insuff. room in target for conversion */ + sourceIllegal /* source sequence is illegal/malformed */ +}; -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; +enum ConversionFlags { strictConversion = 0, lenientConversion }; -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF8toUTF16(const UTF8 **sourceStart, + const UTF8 *sourceEnd, + UTF16 **targetStart, + UTF16 *targetEnd, + ConversionFlags flags); /** * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an * incomplete code unit sequence, returns \c sourceExhausted. */ -ConversionResult ConvertUTF8toUTF32Partial( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF8toUTF32Partial(const UTF8 **sourceStart, + const UTF8 *sourceEnd, + UTF32 **targetStart, + UTF32 *targetEnd, + ConversionFlags flags); /** * Convert a partial UTF8 sequence to UTF32. If the sequence ends in an * incomplete code unit sequence, returns \c sourceIllegal. */ -ConversionResult ConvertUTF8toUTF32( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, + const UTF8 *sourceEnd, + UTF32 **targetStart, + UTF32 *targetEnd, + ConversionFlags flags); -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF16toUTF8(const UTF16 **sourceStart, + const UTF16 *sourceEnd, + UTF8 **targetStart, + UTF8 *targetEnd, + ConversionFlags flags); -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, + const UTF32 *sourceEnd, + UTF8 **targetStart, + UTF8 *targetEnd, + ConversionFlags flags); -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF16toUTF32(const UTF16 **sourceStart, + const UTF16 *sourceEnd, + UTF32 **targetStart, + UTF32 *targetEnd, + ConversionFlags flags); -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); +LLVM_ABI ConversionResult ConvertUTF32toUTF16(const UTF32 **sourceStart, + const UTF32 *sourceEnd, + UTF16 **targetStart, + UTF16 *targetEnd, + ConversionFlags flags); -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); +LLVM_ABI Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); -Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); +LLVM_ABI Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); -unsigned getUTF8SequenceSize(const UTF8 *source, const UTF8 *sourceEnd); +LLVM_ABI unsigned getUTF8SequenceSize(const UTF8 *source, + const UTF8 *sourceEnd); -unsigned getNumBytesForUTF8(UTF8 firstByte); +LLVM_ABI unsigned getNumBytesForUTF8(UTF8 firstByte); /*************************************************************************/ /* Below are LLVM-specific wrappers of the functions above. */ @@ -214,27 +227,27 @@ template class SmallVectorImpl; * the first character which could not be converted. * \return true on success. */ -bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source, - char *&ResultPtr, const UTF8 *&ErrorPtr); +LLVM_ABI bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source, + char *&ResultPtr, const UTF8 *&ErrorPtr); /** * Converts a UTF-8 string_view to a std::wstring. * \return true on success. */ -bool ConvertUTF8toWide(std::string_view Source, std::wstring &Result); +LLVM_ABI bool ConvertUTF8toWide(std::string_view Source, std::wstring &Result); /** * Converts a UTF-8 C-string to a std::wstring. * \return true on success. */ -bool ConvertUTF8toWide(const char *Source, std::wstring &Result); +LLVM_ABI 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, SmallVectorImpl &Result); - +LLVM_ABI bool convertWideToUTF8(const std::wstring &Source, + SmallVectorImpl &Result); /** * Convert an Unicode code point to UTF8 sequence. @@ -246,7 +259,7 @@ bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl &Result * * \returns true on success. */ -bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr); +LLVM_ABI bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr); /** * Convert the first UTF8 sequence in the given source buffer to a UTF32 @@ -279,7 +292,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(std::span SrcBytes); +LLVM_ABI bool hasUTF16ByteOrderMark(std::span SrcBytes); /** * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string. @@ -288,7 +301,8 @@ bool hasUTF16ByteOrderMark(std::span SrcBytes); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ -bool convertUTF16ToUTF8String(std::span SrcBytes, SmallVectorImpl &Out); +LLVM_ABI bool convertUTF16ToUTF8String(std::span SrcBytes, + SmallVectorImpl &Out); /** * Converts a UTF16 string into a UTF8 std::string. @@ -297,7 +311,8 @@ bool convertUTF16ToUTF8String(std::span SrcBytes, SmallVectorImpl Src, SmallVectorImpl &Out); +LLVM_ABI bool convertUTF16ToUTF8String(std::span Src, + SmallVectorImpl &Out); /** * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string. @@ -306,7 +321,8 @@ bool convertUTF16ToUTF8String(std::span Src, SmallVectorImpl * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ -bool convertUTF32ToUTF8String(std::span SrcBytes, std::string &Out); +LLVM_ABI bool convertUTF32ToUTF8String(std::span SrcBytes, + std::string &Out); /** * Converts a UTF32 string into a UTF8 std::string. @@ -315,27 +331,33 @@ bool convertUTF32ToUTF8String(std::span SrcBytes, std::string &Out); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ -bool convertUTF32ToUTF8String(std::span Src, std::string &Out); +LLVM_ABI bool convertUTF32ToUTF8String(std::span Src, std::string &Out); /** * Converts a UTF-8 string into a UTF-16 string with native endianness. * * \returns true on success */ -bool convertUTF8ToUTF16String(std::string_view SrcUTF8, - SmallVectorImpl &DstUTF16); +LLVM_ABI bool convertUTF8ToUTF16String(std::string_view SrcUTF8, + SmallVectorImpl &DstUTF16); + +LLVM_ABI bool IsSingleCodeUnitUTF8Codepoint(unsigned); +LLVM_ABI bool IsSingleCodeUnitUTF16Codepoint(unsigned); +LLVM_ABI bool IsSingleCodeUnitUTF32Codepoint(unsigned); #if defined(_WIN32) namespace sys { namespace windows { -std::error_code UTF8ToUTF16(std::string_view utf8, SmallVectorImpl &utf16); +LLVM_ABI std::error_code UTF8ToUTF16(std::string_view utf8, + SmallVectorImpl &utf16); /// Convert to UTF16 from the current code page used in the system -std::error_code CurCPToUTF16(std::string_view utf8, SmallVectorImpl &utf16); -std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, - SmallVectorImpl &utf8); +LLVM_ABI std::error_code CurCPToUTF16(std::string_view utf8, + SmallVectorImpl &utf16); +LLVM_ABI std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, + SmallVectorImpl &utf8); /// Convert from UTF16 to the current code page used in the system -std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len, - SmallVectorImpl &utf8); +LLVM_ABI std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len, + SmallVectorImpl &utf8); } // namespace windows } // namespace sys #endif diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMap.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMap.hpp index feeff2934a..30a611c847 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMap.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMap.hpp @@ -14,8 +14,11 @@ #ifndef WPIUTIL_WPI_DENSEMAP_H #define WPIUTIL_WPI_DENSEMAP_H +#include "wpi/util/ADL.hpp" #include "wpi/util/DenseMapInfo.hpp" #include "wpi/util/EpochTracker.hpp" +#include "wpi/util/STLForwardCompat.hpp" +#include "wpi/util/iterator_range.hpp" #include "wpi/util/AlignOf.hpp" #include "wpi/util/Compiler.hpp" #include "wpi/util/MathExtras.hpp" @@ -30,6 +33,7 @@ #include #include #include +#include #include #include @@ -40,7 +44,7 @@ namespace detail { // We extend a pair to allow users to override the bucket type with their own // implementation without requiring two members. template -struct DenseMapPair : public std::pair { +struct DenseMapPair : std::pair { using std::pair::pair; KeyT &getFirst() { return std::pair::first; } @@ -73,31 +77,39 @@ public: using const_iterator = DenseMapIterator; - inline iterator begin() { - // When the map is empty, avoid the overhead of advancing/retreating past - // empty buckets. - if (empty()) - return end(); - if (shouldReverseIterate()) - return makeIterator(getBucketsEnd() - 1, getBuckets(), *this); - return makeIterator(getBuckets(), getBucketsEnd(), *this); + [[nodiscard]] inline iterator begin() { + return iterator::makeBegin(buckets(), empty(), *this); } - inline iterator end() { - return makeIterator(getBucketsEnd(), getBucketsEnd(), *this, true); + [[nodiscard]] inline iterator end() { + return iterator::makeEnd(buckets(), *this); } - inline const_iterator begin() const { - if (empty()) - return end(); - if (shouldReverseIterate()) - return makeConstIterator(getBucketsEnd() - 1, getBuckets(), *this); - return makeConstIterator(getBuckets(), getBucketsEnd(), *this); + [[nodiscard]] inline const_iterator begin() const { + return const_iterator::makeBegin(buckets(), empty(), *this); } - inline const_iterator end() const { - return makeConstIterator(getBucketsEnd(), getBucketsEnd(), *this, true); + [[nodiscard]] inline const_iterator end() const { + return const_iterator::makeEnd(buckets(), *this); + } + + // Return an iterator to iterate over keys in the map. + [[nodiscard]] inline auto keys() { + return std::views::transform(*this, [](const BucketT &P) { return P.getFirst(); }); + } + + // Return an iterator to iterate over values in the map. + [[nodiscard]] inline auto values() { + return std::views::transform(*this, [](const BucketT &P) { return P.getSecond(); }); + } + + [[nodiscard]] inline auto keys() const { + return std::views::transform(*this, [](const BucketT &P) { return P.getFirst(); }); + } + + [[nodiscard]] inline auto values() const { + return std::views::transform(*this, [](const BucketT &P) { return P.getSecond(); }); } [[nodiscard]] bool empty() const { return getNumEntries() == 0; } - unsigned size() const { return getNumEntries(); } + [[nodiscard]] unsigned size() const { return getNumEntries(); } /// Grow the densemap so that it can contain at least \p NumEntries items /// before resizing again. @@ -120,21 +132,21 @@ public: return; } - const KeyT EmptyKey = getEmptyKey(); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); if constexpr (std::is_trivially_destructible_v) { // Use a simpler loop when values don't need destruction. - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) - P->getFirst() = EmptyKey; + for (BucketT &B : buckets()) + B.getFirst() = EmptyKey; } else { - const KeyT TombstoneKey = getTombstoneKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); [[maybe_unused]] unsigned NumEntries = getNumEntries(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { - if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { - P->getSecond().~ValueT(); + for (BucketT &B : buckets()) { + if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey)) { + if (!KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) { + B.getSecond().~ValueT(); --NumEntries; } - P->getFirst() = EmptyKey; + B.getFirst() = EmptyKey; } } assert(NumEntries == 0 && "Node count imbalance!"); @@ -144,29 +156,32 @@ public: setNumTombstones(0); } + void shrink_and_clear() { + auto [Reallocate, NewNumBuckets] = derived().planShrinkAndClear(); + destroyAll(); + if (!Reallocate) { + initEmpty(); + return; + } + derived().deallocateBuckets(); + initWithExactBucketCount(NewNumBuckets); + } + /// Return true if the specified key is in the map, false otherwise. - bool contains(const_arg_type_t Val) const { + [[nodiscard]] bool contains(const_arg_type_t Val) const { return doFind(Val) != nullptr; } /// Return 1 if the specified key is in the map, 0 otherwise. - size_type count(const_arg_type_t Val) const { + [[nodiscard]] size_type count(const_arg_type_t Val) const { return contains(Val) ? 1 : 0; } - iterator find(const_arg_type_t Val) { - if (BucketT *Bucket = doFind(Val)) - return makeIterator( - Bucket, shouldReverseIterate() ? getBuckets() : getBucketsEnd(), - *this, true); - return end(); + [[nodiscard]] iterator find(const_arg_type_t Val) { + return find_as(Val); } - const_iterator find(const_arg_type_t Val) const { - if (const BucketT *Bucket = doFind(Val)) - return makeConstIterator( - Bucket, shouldReverseIterate() ? getBuckets() : getBucketsEnd(), - *this, true); - return end(); + [[nodiscard]] const_iterator find(const_arg_type_t Val) const { + return find_as(Val); } /// Alternate version of find() which allows a different, and possibly @@ -174,33 +189,49 @@ public: /// The DenseMapInfo is responsible for supplying methods /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key /// type used. - template iterator find_as(const LookupKeyT &Val) { + template + [[nodiscard]] iterator find_as(const LookupKeyT &Val) { if (BucketT *Bucket = doFind(Val)) - return makeIterator( - Bucket, shouldReverseIterate() ? getBuckets() : getBucketsEnd(), - *this, true); + return makeIterator(Bucket); return end(); } template - const_iterator find_as(const LookupKeyT &Val) const { + [[nodiscard]] const_iterator find_as(const LookupKeyT &Val) const { if (const BucketT *Bucket = doFind(Val)) - return makeConstIterator( - Bucket, shouldReverseIterate() ? getBuckets() : getBucketsEnd(), - *this, true); + return makeConstIterator(Bucket); return end(); } /// lookup - Return the entry for the specified key, or a default /// constructed value if no such entry exists. - ValueT lookup(const_arg_type_t Val) const { + [[nodiscard]] ValueT lookup(const_arg_type_t Val) const { if (const BucketT *Bucket = doFind(Val)) return Bucket->getSecond(); return ValueT(); } + // Return the entry with the specified key, or \p Default. This variant is + // useful, because `lookup` cannot be used with non-default-constructible + // values. + template > + [[nodiscard]] ValueT lookup_or(const_arg_type_t Val, + U &&Default) const { + if (const BucketT *Bucket = doFind(Val)) + return Bucket->getSecond(); + return Default; + } + /// at - Return the entry for the specified key, or abort if no such /// entry exists. - const ValueT &at(const_arg_type_t Val) const { + [[nodiscard]] ValueT &at(const_arg_type_t Val) { + auto Iter = this->find(std::move(Val)); + assert(Iter != this->end() && "DenseMap::at failed due to a missing key"); + return Iter->second; + } + + /// at - Return the entry for the specified key, or abort if no such + /// entry exists. + [[nodiscard]] const ValueT &at(const_arg_type_t Val) const { auto Iter = this->find(std::move(Val)); assert(Iter != this->end() && "DenseMap::at failed due to a missing key"); return Iter->second; @@ -210,14 +241,14 @@ public: // If the key is already in the map, it returns false and doesn't update the // value. std::pair insert(const std::pair &KV) { - return try_emplace(KV.first, KV.second); + return try_emplace_impl(KV.first, KV.second); } // Inserts key,value pair into the map if the key isn't already in the map. // If the key is already in the map, it returns false and doesn't update the // value. std::pair insert(std::pair &&KV) { - return try_emplace(std::move(KV.first), std::move(KV.second)); + return try_emplace_impl(std::move(KV.first), std::move(KV.second)); } // Inserts key,value pair into the map if the key isn't already in the map. @@ -225,24 +256,7 @@ public: // it is not moved. template std::pair try_emplace(KeyT &&Key, Ts &&...Args) { - BucketT *TheBucket; - if (LookupBucketFor(Key, TheBucket)) - return std::make_pair(makeIterator(TheBucket, - shouldReverseIterate() - ? getBuckets() - : getBucketsEnd(), - *this, true), - false); // Already in map. - - // Otherwise, insert the new element. - TheBucket = - InsertIntoBucket(TheBucket, std::move(Key), std::forward(Args)...); - return std::make_pair(makeIterator(TheBucket, - shouldReverseIterate() - ? getBuckets() - : getBucketsEnd(), - *this, true), - true); + return try_emplace_impl(std::move(Key), std::forward(Args)...); } // Inserts key,value pair into the map if the key isn't already in the map. @@ -250,23 +264,7 @@ public: // it is not moved. template std::pair try_emplace(const KeyT &Key, Ts &&...Args) { - BucketT *TheBucket; - if (LookupBucketFor(Key, TheBucket)) - return std::make_pair(makeIterator(TheBucket, - shouldReverseIterate() - ? getBuckets() - : getBucketsEnd(), - *this, true), - false); // Already in map. - - // Otherwise, insert the new element. - TheBucket = InsertIntoBucket(TheBucket, Key, std::forward(Args)...); - return std::make_pair(makeIterator(TheBucket, - shouldReverseIterate() - ? getBuckets() - : getBucketsEnd(), - *this, true), - true); + return try_emplace_impl(Key, std::forward(Args)...); } /// Alternate version of insert() which allows a different, and possibly @@ -279,22 +277,13 @@ public: const LookupKeyT &Val) { BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return std::make_pair(makeIterator(TheBucket, - shouldReverseIterate() - ? getBuckets() - : getBucketsEnd(), - *this, true), - false); // Already in map. + return {makeIterator(TheBucket), false}; // Already in map. // Otherwise, insert the new element. - TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first), - std::move(KV.second), Val); - return std::make_pair(makeIterator(TheBucket, - shouldReverseIterate() - ? getBuckets() - : getBucketsEnd(), - *this, true), - true); + TheBucket = findBucketForInsertion(Val, TheBucket); + TheBucket->getFirst() = std::move(KV.first); + ::new (&TheBucket->getSecond()) ValueT(std::move(KV.second)); + return {makeIterator(TheBucket), true}; } /// insert - Range insertion of pairs. @@ -303,6 +292,11 @@ public: insert(*I); } + /// Inserts range of 'std::pair' values into the map. + template void insert_range(Range &&R) { + insert(adl_begin(R), adl_end(R)); + } + template std::pair insert_or_assign(const KeyT &Key, V &&Val) { auto Ret = try_emplace(Key, std::forward(Val)); @@ -319,13 +313,29 @@ public: return Ret; } + template + std::pair emplace_or_assign(const KeyT &Key, Ts &&...Args) { + auto Ret = try_emplace(Key, std::forward(Args)...); + if (!Ret.second) + Ret.first->second = ValueT(std::forward(Args)...); + return Ret; + } + + template + std::pair emplace_or_assign(KeyT &&Key, Ts &&...Args) { + auto Ret = try_emplace(std::move(Key), std::forward(Args)...); + if (!Ret.second) + Ret.first->second = ValueT(std::forward(Args)...); + return Ret; + } + bool erase(const KeyT &Val) { BucketT *TheBucket = doFind(Val); if (!TheBucket) return false; // not in map. TheBucket->getSecond().~ValueT(); - TheBucket->getFirst() = getTombstoneKey(); + TheBucket->getFirst() = KeyInfoT::getTombstoneKey(); decrementNumEntries(); incrementNumTombstones(); return true; @@ -333,64 +343,84 @@ public: void erase(iterator I) { BucketT *TheBucket = &*I; TheBucket->getSecond().~ValueT(); - TheBucket->getFirst() = getTombstoneKey(); + TheBucket->getFirst() = KeyInfoT::getTombstoneKey(); decrementNumEntries(); incrementNumTombstones(); } ValueT &operator[](const KeyT &Key) { - BucketT *TheBucket; - if (LookupBucketFor(Key, TheBucket)) - return TheBucket->second; - - return InsertIntoBucket(TheBucket, Key)->second; + return lookupOrInsertIntoBucket(Key).first->second; } ValueT &operator[](KeyT &&Key) { - BucketT *TheBucket; - if (LookupBucketFor(Key, TheBucket)) - return TheBucket->second; - - return InsertIntoBucket(TheBucket, std::move(Key))->second; + return lookupOrInsertIntoBucket(std::move(Key)).first->second; } /// isPointerIntoBucketsArray - Return true if the specified pointer points /// somewhere into the DenseMap's array of buckets (i.e. either to a key or /// value in the DenseMap). - bool isPointerIntoBucketsArray(const void *Ptr) const { + [[nodiscard]] bool isPointerIntoBucketsArray(const void *Ptr) const { return Ptr >= getBuckets() && Ptr < getBucketsEnd(); } /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets /// array. In conjunction with the previous method, this can be used to /// determine whether an insertion caused the DenseMap to reallocate. - const void *getPointerIntoBucketsArray() const { return getBuckets(); } + [[nodiscard]] const void *getPointerIntoBucketsArray() const { + return getBuckets(); + } + + void swap(DerivedT &RHS) { + this->incrementEpoch(); + RHS.incrementEpoch(); + derived().swapImpl(RHS); + } protected: DenseMapBase() = default; + struct ExactBucketCount {}; + + void initWithExactBucketCount(unsigned NewNumBuckets) { + if (derived().allocateBuckets(NewNumBuckets)) { + initEmpty(); + } else { + setNumEntries(0); + setNumTombstones(0); + } + } + void destroyAll() { + // No need to iterate through the buckets if both KeyT and ValueT are + // trivially destructible. + if constexpr (std::is_trivially_destructible_v && + std::is_trivially_destructible_v) + return; + if (getNumBuckets() == 0) // Nothing to do. return; - const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) - P->getSecond().~ValueT(); - P->getFirst().~KeyT(); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); + for (BucketT &B : buckets()) { + if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) && + !KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) + B.getSecond().~ValueT(); + B.getFirst().~KeyT(); } } void initEmpty() { + static_assert(std::is_base_of_v, + "Must pass the derived type to this template!"); setNumEntries(0); setNumTombstones(0); assert((getNumBuckets() & (getNumBuckets() - 1)) == 0 && "# initial buckets must be a power of two!"); - const KeyT EmptyKey = getEmptyKey(); - for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B) - ::new (&B->getFirst()) KeyT(EmptyKey); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + for (BucketT &B : buckets()) + ::new (&B.getFirst()) KeyT(EmptyKey); } /// Returns the number of buckets to allocate to ensure that the DenseMap can @@ -399,39 +429,47 @@ protected: // Ensure that "NumEntries * 4 < NumBuckets * 3" if (NumEntries == 0) return 0; - // +1 is required because of the strict equality. - // For example if NumEntries is 48, we need to return 401. + // +1 is required because of the strict inequality. + // For example, if NumEntries is 48, we need to return 128. return static_cast(NextPowerOf2(NumEntries * 4 / 3 + 1)); } - void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) { - initEmpty(); - + // Move key/value from Other to *this. + // Other is left in a valid but empty state. + void moveFrom(DerivedT &Other) { // Insert all the old elements. - const KeyT EmptyKey = getEmptyKey(); - const KeyT TombstoneKey = getTombstoneKey(); - for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) { - if (!KeyInfoT::isEqual(B->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(B->getFirst(), TombstoneKey)) { + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); + for (BucketT &B : Other.buckets()) { + if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) && + !KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) { // Insert the key/value into the new table. BucketT *DestBucket; - bool FoundVal = LookupBucketFor(B->getFirst(), DestBucket); + bool FoundVal = LookupBucketFor(B.getFirst(), DestBucket); (void)FoundVal; // silence warning. assert(!FoundVal && "Key already in new map?"); - DestBucket->getFirst() = std::move(B->getFirst()); - ::new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond())); + DestBucket->getFirst() = std::move(B.getFirst()); + ::new (&DestBucket->getSecond()) ValueT(std::move(B.getSecond())); incrementNumEntries(); // Free the value. - B->getSecond().~ValueT(); + B.getSecond().~ValueT(); } - B->getFirst().~KeyT(); + B.getFirst().~KeyT(); } + Other.derived().kill(); } - template - void copyFrom( - const DenseMapBase &other) { + void copyFrom(const DerivedT &other) { + this->destroyAll(); + derived().deallocateBuckets(); + setNumEntries(0); + setNumTombstones(0); + if (!derived().allocateBuckets(other.getNumBuckets())) { + // The bucket list is empty. No work to do. + return; + } + assert(&other != this); assert(getNumBuckets() == other.getNumBuckets()); @@ -446,8 +484,8 @@ protected: memcpy(reinterpret_cast(Buckets), OtherBuckets, NumBuckets * sizeof(BucketT)); } else { - const KeyT EmptyKey = getEmptyKey(); - const KeyT TombstoneKey = getTombstoneKey(); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); for (size_t I = 0; I < NumBuckets; ++I) { ::new (&Buckets[I].getFirst()) KeyT(OtherBuckets[I].getFirst()); if (!KeyInfoT::isEqual(Buckets[I].getFirst(), EmptyKey) && @@ -457,76 +495,62 @@ protected: } } - static unsigned getHashValue(const KeyT &Val) { - return KeyInfoT::getHashValue(Val); - } - - template - static unsigned getHashValue(const LookupKeyT &Val) { - return KeyInfoT::getHashValue(Val); - } - - static const KeyT getEmptyKey() { - static_assert(std::is_base_of_v, - "Must pass the derived type to this template!"); - return KeyInfoT::getEmptyKey(); - } - - static const KeyT getTombstoneKey() { return KeyInfoT::getTombstoneKey(); } - private: - iterator makeIterator(BucketT *P, BucketT *E, DebugEpochBase &Epoch, - bool NoAdvance = false) { - if (shouldReverseIterate()) { - BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1; - return iterator(B, E, Epoch, NoAdvance); - } - return iterator(P, E, Epoch, NoAdvance); + DerivedT &derived() { return *static_cast(this); } + const DerivedT &derived() const { + return *static_cast(this); } - const_iterator makeConstIterator(const BucketT *P, const BucketT *E, - const DebugEpochBase &Epoch, - const bool NoAdvance = false) const { - if (shouldReverseIterate()) { - const BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1; - return const_iterator(B, E, Epoch, NoAdvance); - } - return const_iterator(P, E, Epoch, NoAdvance); + template + std::pair lookupOrInsertIntoBucket(KeyArgT &&Key, + Ts &&...Args) { + BucketT *TheBucket = nullptr; + if (LookupBucketFor(Key, TheBucket)) + return {TheBucket, false}; // Already in the map. + + // Otherwise, insert the new element. + TheBucket = findBucketForInsertion(Key, TheBucket); + TheBucket->getFirst() = std::forward(Key); + ::new (&TheBucket->getSecond()) ValueT(std::forward(Args)...); + return {TheBucket, true}; } - unsigned getNumEntries() const { - return static_cast(this)->getNumEntries(); + template + std::pair try_emplace_impl(KeyArgT &&Key, Ts &&...Args) { + auto [Bucket, Inserted] = lookupOrInsertIntoBucket( + std::forward(Key), std::forward(Args)...); + return {makeIterator(Bucket), Inserted}; } - void setNumEntries(unsigned Num) { - static_cast(this)->setNumEntries(Num); + iterator makeIterator(BucketT *TheBucket) { + return iterator::makeIterator(TheBucket, buckets(), *this); } + const_iterator makeConstIterator(const BucketT *TheBucket) const { + return const_iterator::makeIterator(TheBucket, buckets(), *this); + } + + unsigned getNumEntries() const { return derived().getNumEntries(); } + + void setNumEntries(unsigned Num) { derived().setNumEntries(Num); } + void incrementNumEntries() { setNumEntries(getNumEntries() + 1); } void decrementNumEntries() { setNumEntries(getNumEntries() - 1); } - unsigned getNumTombstones() const { - return static_cast(this)->getNumTombstones(); - } + unsigned getNumTombstones() const { return derived().getNumTombstones(); } - void setNumTombstones(unsigned Num) { - static_cast(this)->setNumTombstones(Num); - } + void setNumTombstones(unsigned Num) { derived().setNumTombstones(Num); } void incrementNumTombstones() { setNumTombstones(getNumTombstones() + 1); } void decrementNumTombstones() { setNumTombstones(getNumTombstones() - 1); } - const BucketT *getBuckets() const { - return static_cast(this)->getBuckets(); - } + const BucketT *getBuckets() const { return derived().getBuckets(); } - BucketT *getBuckets() { return static_cast(this)->getBuckets(); } + BucketT *getBuckets() { return derived().getBuckets(); } - unsigned getNumBuckets() const { - return static_cast(this)->getNumBuckets(); - } + unsigned getNumBuckets() const { return derived().getNumBuckets(); } BucketT *getBucketsEnd() { return getBuckets() + getNumBuckets(); } @@ -534,32 +558,27 @@ private: return getBuckets() + getNumBuckets(); } - void grow(unsigned AtLeast) { static_cast(this)->grow(AtLeast); } + iterator_range buckets() { + return wpi::util::make_range(getBuckets(), getBucketsEnd()); + } - void shrink_and_clear() { static_cast(this)->shrink_and_clear(); } + iterator_range buckets() const { + return wpi::util::make_range(getBuckets(), getBucketsEnd()); + } - template - BucketT *InsertIntoBucket(BucketT *TheBucket, KeyArg &&Key, - ValueArgs &&...Values) { - TheBucket = InsertIntoBucketImpl(Key, TheBucket); - - TheBucket->getFirst() = std::forward(Key); - ::new (&TheBucket->getSecond()) ValueT(std::forward(Values)...); - return TheBucket; + void grow(unsigned MinNumBuckets) { + unsigned NumBuckets = DerivedT::roundUpNumBuckets(MinNumBuckets); + DerivedT Tmp(NumBuckets, ExactBucketCount{}); + Tmp.moveFrom(derived()); + if (derived().maybeMoveFast(std::move(Tmp))) + return; + initWithExactBucketCount(NumBuckets); + moveFrom(Tmp); } template - BucketT *InsertIntoBucketWithLookup(BucketT *TheBucket, KeyT &&Key, - ValueT &&Value, LookupKeyT &Lookup) { - TheBucket = InsertIntoBucketImpl(Lookup, TheBucket); - - TheBucket->getFirst() = std::move(Key); - ::new (&TheBucket->getSecond()) ValueT(std::move(Value)); - return TheBucket; - } - - template - BucketT *InsertIntoBucketImpl(const LookupKeyT &Lookup, BucketT *TheBucket) { + BucketT *findBucketForInsertion(const LookupKeyT &Lookup, + BucketT *TheBucket) { incrementEpoch(); // If the load of the hash table is more than 3/4, or if fewer than 1/8 of @@ -576,7 +595,6 @@ private: if (LLVM_UNLIKELY(NewNumEntries * 4 >= NumBuckets * 3)) { this->grow(NumBuckets * 2); LookupBucketFor(Lookup, TheBucket); - NumBuckets = getNumBuckets(); } else if (LLVM_UNLIKELY(NumBuckets - (NewNumEntries + getNumTombstones()) <= NumBuckets / 8)) { @@ -590,24 +608,25 @@ private: incrementNumEntries(); // If we are writing over a tombstone, remember this. - const KeyT EmptyKey = getEmptyKey(); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey)) decrementNumTombstones(); return TheBucket; } - template BucketT *doFind(const LookupKeyT &Val) { - BucketT *BucketsPtr = getBuckets(); + template + const BucketT *doFind(const LookupKeyT &Val) const { + const BucketT *BucketsPtr = getBuckets(); const unsigned NumBuckets = getNumBuckets(); if (NumBuckets == 0) return nullptr; - const KeyT EmptyKey = getEmptyKey(); - unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + unsigned BucketNo = KeyInfoT::getHashValue(Val) & (NumBuckets - 1); unsigned ProbeAmt = 1; while (true) { - BucketT *Bucket = BucketsPtr + BucketNo; + const BucketT *Bucket = BucketsPtr + BucketNo; if (LLVM_LIKELY(KeyInfoT::isEqual(Val, Bucket->getFirst()))) return Bucket; if (LLVM_LIKELY(KeyInfoT::isEqual(Bucket->getFirst(), EmptyKey))) @@ -620,9 +639,9 @@ private: } } - template - const BucketT *doFind(const LookupKeyT &Val) const { - return const_cast(this)->doFind(Val); // NOLINT + template BucketT *doFind(const LookupKeyT &Val) { + return const_cast( + static_cast(this)->doFind(Val)); } /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in @@ -641,13 +660,13 @@ private: // FoundTombstone - Keep track of whether we find a tombstone while probing. BucketT *FoundTombstone = nullptr; - const KeyT EmptyKey = getEmptyKey(); - const KeyT TombstoneKey = getTombstoneKey(); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); assert(!KeyInfoT::isEqual(Val, EmptyKey) && !KeyInfoT::isEqual(Val, TombstoneKey) && "Empty/Tombstone value shouldn't be inserted into map!"); - unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1); + unsigned BucketNo = KeyInfoT::getHashValue(Val) & (NumBuckets - 1); unsigned ProbeAmt = 1; while (true) { BucketT *ThisBucket = BucketsPtr + BucketNo; @@ -684,7 +703,9 @@ public: /// This is just the raw memory used by DenseMap. /// If entries are pointers to objects, the size of the referenced objects /// are not included. - size_t getMemorySize() const { return getNumBuckets() * sizeof(BucketT); } + [[nodiscard]] size_t getMemorySize() const { + return getNumBuckets() * sizeof(BucketT); + } }; /// Equality comparison for DenseMap. @@ -695,9 +716,9 @@ public: /// complexity is linear, worst case is O(N^2) (if every hash collides). template -bool operator==( - const DenseMapBase &LHS, - const DenseMapBase &RHS) { +[[nodiscard]] bool +operator==(const DenseMapBase &LHS, + const DenseMapBase &RHS) { if (LHS.size() != RHS.size()) return false; @@ -715,9 +736,9 @@ bool operator==( /// Equivalent to !(LHS == RHS). See operator== for performance notes. template -bool operator!=( - const DenseMapBase &LHS, - const DenseMapBase &RHS) { +[[nodiscard]] bool +operator!=(const DenseMapBase &LHS, + const DenseMapBase &RHS) { return !(LHS == RHS); } @@ -737,119 +758,60 @@ class DenseMap : public DenseMapBase, unsigned NumTombstones; unsigned NumBuckets; + explicit DenseMap(unsigned NumBuckets, typename BaseT::ExactBucketCount) { + this->initWithExactBucketCount(NumBuckets); + } + public: - /// Create a DenseMap with an optional \p InitialReserve that guarantee that - /// this number of elements can be inserted in the map without grow() - explicit DenseMap(unsigned InitialReserve = 0) { init(InitialReserve); } + /// Create a DenseMap with an optional \p NumElementsToReserve to guarantee + /// that this number of elements can be inserted in the map without grow(). + explicit DenseMap(unsigned NumElementsToReserve = 0) + : DenseMap(BaseT::getMinBucketToReserveForEntries(NumElementsToReserve), + typename BaseT::ExactBucketCount{}) {} - DenseMap(const DenseMap &other) : BaseT() { - init(0); - copyFrom(other); - } + DenseMap(const DenseMap &other) : DenseMap() { this->copyFrom(other); } - DenseMap(DenseMap &&other) : BaseT() { - init(0); - swap(other); - } + DenseMap(DenseMap &&other) : DenseMap() { this->swap(other); } - template DenseMap(const InputIt &I, const InputIt &E) { - init(std::distance(I, E)); + template + DenseMap(const InputIt &I, const InputIt &E) : DenseMap(std::distance(I, E)) { this->insert(I, E); } - DenseMap(std::initializer_list Vals) { - init(Vals.size()); - this->insert(Vals.begin(), Vals.end()); - } + template + DenseMap(wpi::util::from_range_t, const RangeT &Range) + : DenseMap(adl_begin(Range), adl_end(Range)) {} + + DenseMap(std::initializer_list Vals) + : DenseMap(Vals.begin(), Vals.end()) {} ~DenseMap() { this->destroyAll(); - deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); + deallocateBuckets(); } - void swap(DenseMap &RHS) { - this->incrementEpoch(); - RHS.incrementEpoch(); + DenseMap &operator=(const DenseMap &other) { + if (&other != this) + this->copyFrom(other); + return *this; + } + + DenseMap &operator=(DenseMap &&other) { + this->destroyAll(); + deallocateBuckets(); + this->initWithExactBucketCount(0); + this->swap(other); + return *this; + } + +private: + void swapImpl(DenseMap &RHS) { std::swap(Buckets, RHS.Buckets); std::swap(NumEntries, RHS.NumEntries); std::swap(NumTombstones, RHS.NumTombstones); std::swap(NumBuckets, RHS.NumBuckets); } - DenseMap &operator=(const DenseMap &other) { - if (&other != this) - copyFrom(other); - return *this; - } - - DenseMap &operator=(DenseMap &&other) { - this->destroyAll(); - deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); - init(0); - swap(other); - return *this; - } - - void copyFrom(const DenseMap &other) { - this->destroyAll(); - deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); - if (allocateBuckets(other.NumBuckets)) { - this->BaseT::copyFrom(other); - } else { - NumEntries = 0; - NumTombstones = 0; - } - } - - void init(unsigned InitNumEntries) { - auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries); - if (allocateBuckets(InitBuckets)) { - this->BaseT::initEmpty(); - } else { - NumEntries = 0; - NumTombstones = 0; - } - } - - void grow(unsigned AtLeast) { - unsigned OldNumBuckets = NumBuckets; - BucketT *OldBuckets = Buckets; - - allocateBuckets(std::max( - 64, static_cast(NextPowerOf2(AtLeast - 1)))); - assert(Buckets); - if (!OldBuckets) { - this->BaseT::initEmpty(); - return; - } - - this->moveFromOldBuckets(OldBuckets, OldBuckets + OldNumBuckets); - - // Free the old table. - deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets, - alignof(BucketT)); - } - - void shrink_and_clear() { - unsigned OldNumBuckets = NumBuckets; - unsigned OldNumEntries = NumEntries; - this->destroyAll(); - - // Reduce the number of buckets. - unsigned NewNumBuckets = 0; - if (OldNumEntries) - NewNumBuckets = (std::max)(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1)); - if (NewNumBuckets == NumBuckets) { - this->BaseT::initEmpty(); - return; - } - - deallocate_buffer(Buckets, sizeof(BucketT) * OldNumBuckets, - alignof(BucketT)); - init(NewNumBuckets); - } - -private: unsigned getNumEntries() const { return NumEntries; } void setNumEntries(unsigned Num) { NumEntries = Num; } @@ -862,6 +824,10 @@ private: unsigned getNumBuckets() const { return NumBuckets; } + void deallocateBuckets() { + deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); + } + bool allocateBuckets(unsigned Num) { NumBuckets = Num; if (NumBuckets == 0) { @@ -873,6 +839,35 @@ private: allocate_buffer(sizeof(BucketT) * NumBuckets, alignof(BucketT))); return true; } + + // Put the zombie instance in a known good state after a move. + void kill() { + deallocateBuckets(); + Buckets = nullptr; + NumBuckets = 0; + } + + static unsigned roundUpNumBuckets(unsigned MinNumBuckets) { + return (std::max)(64u, + static_cast(NextPowerOf2(MinNumBuckets - 1))); + } + + bool maybeMoveFast(DenseMap &&Other) { + swapImpl(Other); + return true; + } + + // Plan how to shrink the bucket table. Return: + // - {false, 0} to reuse the existing bucket table + // - {true, N} to reallocate a bucket table with N entries + std::pair planShrinkAndClear() const { + unsigned NewNumBuckets = 0; + if (NumEntries) + NewNumBuckets = (std::max)(64u, 1u << (Log2_32_Ceil(NumEntries) + 1)); + if (NewNumBuckets == NumBuckets) + return {false, 0}; // Reuse. + return {true, NewNumBuckets}; // Reallocate. + } }; template buckets() { + return wpi::util::make_range(Buckets, Buckets + NumBuckets); + } }; /// A "union" of an inline bucket array and the struct representing /// a large bucket. This union will be discriminated by the 'Small' bit. AlignedCharArrayUnion storage; + SmallDenseMap(unsigned NumBuckets, typename BaseT::ExactBucketCount) { + this->initWithExactBucketCount(NumBuckets); + } + public: - explicit SmallDenseMap(unsigned NumInitBuckets = 0) { - if (NumInitBuckets > InlineBuckets) - NumInitBuckets = std::bit_ceil(NumInitBuckets); - init(NumInitBuckets); + explicit SmallDenseMap(unsigned NumElementsToReserve = 0) + : SmallDenseMap( + BaseT::getMinBucketToReserveForEntries(NumElementsToReserve), + typename BaseT::ExactBucketCount{}) {} + + SmallDenseMap(const SmallDenseMap &other) : SmallDenseMap() { + this->copyFrom(other); } - SmallDenseMap(const SmallDenseMap &other) : BaseT() { - init(0); - copyFrom(other); - } - - SmallDenseMap(SmallDenseMap &&other) : BaseT() { - init(0); - swap(other); - } + SmallDenseMap(SmallDenseMap &&other) : SmallDenseMap() { this->swap(other); } template - SmallDenseMap(const InputIt &I, const InputIt &E) { - init(NextPowerOf2(std::distance(I, E))); + SmallDenseMap(const InputIt &I, const InputIt &E) + : SmallDenseMap(std::distance(I, E)) { this->insert(I, E); } + template + SmallDenseMap(wpi::util::from_range_t, const RangeT &Range) + : SmallDenseMap(adl_begin(Range), adl_end(Range)) {} + SmallDenseMap(std::initializer_list Vals) : SmallDenseMap(Vals.begin(), Vals.end()) {} @@ -935,14 +936,29 @@ public: deallocateBuckets(); } - void swap(SmallDenseMap &RHS) { + SmallDenseMap &operator=(const SmallDenseMap &other) { + if (&other != this) + this->copyFrom(other); + return *this; + } + + SmallDenseMap &operator=(SmallDenseMap &&other) { + this->destroyAll(); + deallocateBuckets(); + this->initWithExactBucketCount(0); + this->swap(other); + return *this; + } + +private: + void swapImpl(SmallDenseMap &RHS) { unsigned TmpNumEntries = RHS.NumEntries; RHS.NumEntries = NumEntries; NumEntries = TmpNumEntries; std::swap(NumTombstones, RHS.NumTombstones); - const KeyT EmptyKey = this->getEmptyKey(); - const KeyT TombstoneKey = this->getTombstoneKey(); + const KeyT EmptyKey = KeyInfoT::getEmptyKey(); + const KeyT TombstoneKey = KeyInfoT::getTombstoneKey(); if (Small && RHS.Small) { // If we're swapping inline bucket arrays, we have to cope with some of // the tricky bits of DenseMap's storage system: the buckets are not @@ -973,8 +989,7 @@ public: return; } if (!Small && !RHS.Small) { - std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets); - std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets); + std::swap(*getLargeRep(), *RHS.getLargeRep()); return; } @@ -1007,116 +1022,6 @@ public: new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep)); } - SmallDenseMap &operator=(const SmallDenseMap &other) { - if (&other != this) - copyFrom(other); - return *this; - } - - SmallDenseMap &operator=(SmallDenseMap &&other) { - this->destroyAll(); - deallocateBuckets(); - init(0); - swap(other); - return *this; - } - - void copyFrom(const SmallDenseMap &other) { - this->destroyAll(); - deallocateBuckets(); - Small = true; - if (other.getNumBuckets() > InlineBuckets) { - Small = false; - new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets())); - } - this->BaseT::copyFrom(other); - } - - void init(unsigned InitBuckets) { - Small = true; - if (InitBuckets > InlineBuckets) { - Small = false; - new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets)); - } - this->BaseT::initEmpty(); - } - - void grow(unsigned AtLeast) { - if (AtLeast > InlineBuckets) - AtLeast = std::max(64, NextPowerOf2(AtLeast - 1)); - - if (Small) { - // First move the inline buckets into a temporary storage. - AlignedCharArrayUnion TmpStorage; - BucketT *TmpBegin = reinterpret_cast(&TmpStorage); - BucketT *TmpEnd = TmpBegin; - - // Loop over the buckets, moving non-empty, non-tombstones into the - // temporary storage. Have the loop move the TmpEnd forward as it goes. - const KeyT EmptyKey = this->getEmptyKey(); - const KeyT TombstoneKey = this->getTombstoneKey(); - for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) && - !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { - assert(size_t(TmpEnd - TmpBegin) < InlineBuckets && - "Too many inline buckets!"); - ::new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst())); - ::new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond())); - ++TmpEnd; - P->getSecond().~ValueT(); - } - P->getFirst().~KeyT(); - } - - // AtLeast == InlineBuckets can happen if there are many tombstones, - // and grow() is used to remove them. Usually we always switch to the - // large rep here. - if (AtLeast > InlineBuckets) { - Small = false; - new (getLargeRep()) LargeRep(allocateBuckets(AtLeast)); - } - this->moveFromOldBuckets(TmpBegin, TmpEnd); - return; - } - - LargeRep OldRep = std::move(*getLargeRep()); - getLargeRep()->~LargeRep(); - if (AtLeast <= InlineBuckets) { - Small = true; - } else { - new (getLargeRep()) LargeRep(allocateBuckets(AtLeast)); - } - - this->moveFromOldBuckets(OldRep.Buckets, - OldRep.Buckets + OldRep.NumBuckets); - - // Free the old table. - deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets, - alignof(BucketT)); - } - - void shrink_and_clear() { - unsigned OldSize = this->size(); - this->destroyAll(); - - // Reduce the number of buckets. - unsigned NewNumBuckets = 0; - if (OldSize) { - NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1); - if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u) - NewNumBuckets = 64; - } - if ((Small && NewNumBuckets <= InlineBuckets) || - (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) { - this->BaseT::initEmpty(); - return; - } - - deallocateBuckets(); - init(NewNumBuckets); - } - -private: unsigned getNumEntries() const { return NumEntries; } void setNumEntries(unsigned Num) { @@ -1166,8 +1071,16 @@ private: return Small ? InlineBuckets : getLargeRep()->NumBuckets; } + iterator_range inlineBuckets() { + BucketT *Begin = getInlineBuckets(); + return wpi::util::make_range(Begin, Begin + InlineBuckets); + } + void deallocateBuckets() { - if (Small) + // Fast path to deallocateBuckets in case getLargeRep()->NumBuckets == 0, + // just like destroyAll. This path is used to destruct zombie instances + // after moves. + if (Small || getLargeRep()->NumBuckets == 0) return; deallocate_buffer(getLargeRep()->Buckets, @@ -1176,12 +1089,59 @@ private: getLargeRep()->~LargeRep(); } - LargeRep allocateBuckets(unsigned Num) { - assert(Num > InlineBuckets && "Must allocate more buckets than are inline"); - LargeRep Rep = {static_cast(allocate_buffer( - sizeof(BucketT) * Num, alignof(BucketT))), - Num}; - return Rep; + bool allocateBuckets(unsigned Num) { + if (Num <= InlineBuckets) { + Small = true; + } else { + Small = false; + BucketT *NewBuckets = static_cast( + allocate_buffer(sizeof(BucketT) * Num, alignof(BucketT))); + new (getLargeRep()) LargeRep{NewBuckets, Num}; + } + return true; + } + + // Put the zombie instance in a known good state after a move. + void kill() { + deallocateBuckets(); + Small = false; + new (getLargeRep()) LargeRep{nullptr, 0}; + } + + static unsigned roundUpNumBuckets(unsigned MinNumBuckets) { + if (MinNumBuckets <= InlineBuckets) + return MinNumBuckets; + return (std::max)(64u, + static_cast(NextPowerOf2(MinNumBuckets - 1))); + } + + bool maybeMoveFast(SmallDenseMap &&Other) { + if (Other.Small) + return false; + + Small = false; + NumEntries = Other.NumEntries; + NumTombstones = Other.NumTombstones; + *getLargeRep() = std::move(*Other.getLargeRep()); + Other.getLargeRep()->NumBuckets = 0; + return true; + } + + // Plan how to shrink the bucket table. Return: + // - {false, 0} to reuse the existing bucket table + // - {true, N} to reallocate a bucket table with N entries + std::pair planShrinkAndClear() const { + unsigned NewNumBuckets = 0; + if (!this->empty()) { + NewNumBuckets = 1u << (Log2_32_Ceil(this->size()) + 1); + if (NewNumBuckets > InlineBuckets) + NewNumBuckets = (std::max)(64u, NewNumBuckets); + } + bool Reuse = Small ? NewNumBuckets <= InlineBuckets + : NewNumBuckets == getLargeRep()->NumBuckets; + if (Reuse) + return {false, 0}; // Reuse. + return {true, NewNumBuckets}; // Reallocate. } }; @@ -1199,24 +1159,45 @@ public: using iterator_category = std::forward_iterator_tag; private: - pointer Ptr = nullptr; - pointer End = nullptr; + using BucketItTy = + std::conditional_t(), + std::reverse_iterator, pointer>; + + BucketItTy Ptr = {}; + BucketItTy End = {}; + + DenseMapIterator(BucketItTy Pos, BucketItTy E, const DebugEpochBase &Epoch) + : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) { + assert(isHandleInSync() && "invalid construction!"); + } public: DenseMapIterator() = default; - DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch, - bool NoAdvance = false) - : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) { - assert(isHandleInSync() && "invalid construction!"); + static DenseMapIterator makeBegin(iterator_range Buckets, + bool IsEmpty, const DebugEpochBase &Epoch) { + // When the map is empty, avoid the overhead of advancing/retreating past + // empty buckets. + if (IsEmpty) + return makeEnd(Buckets, Epoch); + auto R = maybeReverse(Buckets); + DenseMapIterator Iter(R.begin(), R.end(), Epoch); + Iter.AdvancePastEmptyBuckets(); + return Iter; + } - if (NoAdvance) - return; - if (shouldReverseIterate()) { - RetreatPastEmptyBuckets(); - return; - } - AdvancePastEmptyBuckets(); + static DenseMapIterator makeEnd(iterator_range Buckets, + const DebugEpochBase &Epoch) { + auto R = maybeReverse(Buckets); + return DenseMapIterator(R.end(), R.end(), Epoch); + } + + static DenseMapIterator makeIterator(pointer P, + iterator_range Buckets, + const DebugEpochBase &Epoch) { + auto R = maybeReverse(Buckets); + constexpr int Offset = shouldReverseIterate() ? 1 : 0; + return DenseMapIterator(BucketItTy(P + Offset), R.end(), Epoch); } // Converting ctor from non-const iterators to const iterators. SFINAE'd out @@ -1228,43 +1209,32 @@ public: const DenseMapIterator &I) : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {} - reference operator*() const { + [[nodiscard]] reference operator*() const { assert(isHandleInSync() && "invalid iterator access!"); assert(Ptr != End && "dereferencing end() iterator"); - if (shouldReverseIterate()) - return Ptr[-1]; return *Ptr; } - pointer operator->() const { - assert(isHandleInSync() && "invalid iterator access!"); - assert(Ptr != End && "dereferencing end() iterator"); - if (shouldReverseIterate()) - return &(Ptr[-1]); - return Ptr; - } + [[nodiscard]] pointer operator->() const { return &operator*(); } - friend bool operator==(const DenseMapIterator &LHS, - const DenseMapIterator &RHS) { - assert((!LHS.Ptr || LHS.isHandleInSync()) && "handle not in sync!"); - assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!"); + [[nodiscard]] friend bool operator==(const DenseMapIterator &LHS, + const DenseMapIterator &RHS) { + assert((!LHS.getEpochAddress() || LHS.isHandleInSync()) && + "handle not in sync!"); + assert((!RHS.getEpochAddress() || RHS.isHandleInSync()) && + "handle not in sync!"); assert(LHS.getEpochAddress() == RHS.getEpochAddress() && "comparing incomparable iterators!"); return LHS.Ptr == RHS.Ptr; } - friend bool operator!=(const DenseMapIterator &LHS, - const DenseMapIterator &RHS) { + [[nodiscard]] friend bool operator!=(const DenseMapIterator &LHS, + const DenseMapIterator &RHS) { return !(LHS == RHS); } inline DenseMapIterator &operator++() { // Preincrement assert(isHandleInSync() && "invalid iterator access!"); assert(Ptr != End && "incrementing end() iterator"); - if (shouldReverseIterate()) { - --Ptr; - RetreatPastEmptyBuckets(); - return *this; - } ++Ptr; AdvancePastEmptyBuckets(); return *this; @@ -1287,19 +1257,17 @@ private: ++Ptr; } - void RetreatPastEmptyBuckets() { - assert(Ptr >= End); - const KeyT Empty = KeyInfoT::getEmptyKey(); - const KeyT Tombstone = KeyInfoT::getTombstoneKey(); - - while (Ptr != End && (KeyInfoT::isEqual(Ptr[-1].getFirst(), Empty) || - KeyInfoT::isEqual(Ptr[-1].getFirst(), Tombstone))) - --Ptr; + static auto maybeReverse(iterator_range Range) { + if constexpr (shouldReverseIterate()) + return reverse(Range); + else + return Range; } }; template -inline size_t capacity_in_bytes(const DenseMap &X) { +[[nodiscard]] inline size_t +capacity_in_bytes(const DenseMap &X) { return X.getMemorySize(); } diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMapInfo.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMapInfo.hpp index 8e5f085f7b..c2e17938a8 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMapInfo.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/DenseMapInfo.hpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -50,10 +52,10 @@ inline unsigned combineHashValue(unsigned a, unsigned b) { /// just be `void`. template struct DenseMapInfo { - //static inline T getEmptyKey(); - //static inline T getTombstoneKey(); - //static unsigned getHashValue(const T &Val); - //static bool isEqual(const T &LHS, const T &RHS); + // static constexpr T getEmptyKey(); + // static constexpr T getTombstoneKey(); + // static unsigned getHashValue(const T &Val); + // static bool isEqual(const T &LHS, const T &RHS); }; // Provide DenseMapInfo for all pointers. Come up with sentinel pointer values @@ -69,13 +71,13 @@ struct DenseMapInfo { // "Log2MaxAlign bits of alignment"); static constexpr uintptr_t Log2MaxAlign = 12; - static inline T* getEmptyKey() { + static constexpr T *getEmptyKey() { uintptr_t Val = static_cast(-1); Val <<= Log2MaxAlign; return reinterpret_cast(Val); } - static inline T* getTombstoneKey() { + static constexpr T *getTombstoneKey() { uintptr_t Val = static_cast(-2); Val <<= Log2MaxAlign; return reinterpret_cast(Val); @@ -91,8 +93,8 @@ struct DenseMapInfo { // Provide DenseMapInfo for chars. template<> struct DenseMapInfo { - static inline char getEmptyKey() { return ~0; } - static inline char getTombstoneKey() { return ~0 - 1; } + static constexpr char getEmptyKey() { return ~0; } + static constexpr char getTombstoneKey() { return ~0 - 1; } static unsigned getHashValue(const char& Val) { return Val * 37U; } static bool isEqual(const char &LHS, const char &RHS) { @@ -100,120 +102,33 @@ template<> struct DenseMapInfo { } }; -// Provide DenseMapInfo for unsigned chars. -template <> struct DenseMapInfo { - static inline unsigned char getEmptyKey() { return ~0; } - static inline unsigned char getTombstoneKey() { return ~0 - 1; } - static unsigned getHashValue(const unsigned char &Val) { return Val * 37U; } +// Provide DenseMapInfo for all integral types except char. +// +// The "char" case is excluded because it uses ~0 as the empty key despite +// "char" being a signed type. "std::is_same_v" is included below +// for clarity; technically, we do not need it because the explicit +// specialization above "wins", +template +struct DenseMapInfo< + T, std::enable_if_t && !std::is_same_v>> { + static constexpr T getEmptyKey() { return (std::numeric_limits::max)(); } - static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned shorts. -template <> struct DenseMapInfo { - static inline unsigned short getEmptyKey() { return 0xFFFF; } - static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; } - static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; } - - static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned ints. -template<> struct DenseMapInfo { - static inline unsigned getEmptyKey() { return ~0U; } - static inline unsigned getTombstoneKey() { return ~0U - 1; } - static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } - - static bool isEqual(const unsigned& LHS, const unsigned& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned longs. -template<> struct DenseMapInfo { - static inline unsigned long getEmptyKey() { return ~0UL; } - static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } - - static unsigned getHashValue(const unsigned long& Val) { - if constexpr (sizeof(Val) == 4) - return DenseMapInfo::getHashValue(Val); + static constexpr T getTombstoneKey() { + if constexpr (std::is_unsigned_v || std::is_same_v) + return (std::numeric_limits::max)() - 1; else + return (std::numeric_limits::min)(); + } + + static unsigned getHashValue(const T &Val) { + if constexpr (std::is_unsigned_v && sizeof(T) > sizeof(unsigned)) return densemap::detail::mix(Val); + else + return static_cast(Val * + static_cast>(37U)); } - static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for unsigned long longs. -template<> struct DenseMapInfo { - static inline unsigned long long getEmptyKey() { return ~0ULL; } - static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } - - static unsigned getHashValue(const unsigned long long& Val) { - return densemap::detail::mix(Val); - } - - static bool isEqual(const unsigned long long& LHS, - const unsigned long long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for shorts. -template <> struct DenseMapInfo { - static inline short getEmptyKey() { return 0x7FFF; } - static inline short getTombstoneKey() { return -0x7FFF - 1; } - static unsigned getHashValue(const short &Val) { return Val * 37U; } - static bool isEqual(const short &LHS, const short &RHS) { return LHS == RHS; } -}; - -// Provide DenseMapInfo for ints. -template<> struct DenseMapInfo { - static inline int getEmptyKey() { return 0x7fffffff; } - static inline int getTombstoneKey() { return -0x7fffffff - 1; } - static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } - - static bool isEqual(const int& LHS, const int& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for longs. -template<> struct DenseMapInfo { - static inline long getEmptyKey() { - return (1UL << (sizeof(long) * 8 - 1)) - 1UL; - } - - static inline long getTombstoneKey() { return getEmptyKey() - 1L; } - - static unsigned getHashValue(const long& Val) { - return (unsigned)(Val * 37UL); - } - - static bool isEqual(const long& LHS, const long& RHS) { - return LHS == RHS; - } -}; - -// Provide DenseMapInfo for long longs. -template<> struct DenseMapInfo { - static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } - static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } - - static unsigned getHashValue(const long long& Val) { - return (unsigned)(Val * 37ULL); - } - - static bool isEqual(const long long& LHS, - const long long& RHS) { - return LHS == RHS; - } + static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; } }; // Provide DenseMapInfo for all pairs whose members have info. @@ -223,14 +138,12 @@ struct DenseMapInfo> { using FirstInfo = DenseMapInfo; using SecondInfo = DenseMapInfo; - static inline Pair getEmptyKey() { - return std::make_pair(FirstInfo::getEmptyKey(), - SecondInfo::getEmptyKey()); + static constexpr Pair getEmptyKey() { + return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; } - static inline Pair getTombstoneKey() { - return std::make_pair(FirstInfo::getTombstoneKey(), - SecondInfo::getTombstoneKey()); + static constexpr Pair getTombstoneKey() { + return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; } static unsigned getHashValue(const Pair& PairVal) { @@ -256,49 +169,39 @@ struct DenseMapInfo> { template struct DenseMapInfo> { using Tuple = std::tuple; - static inline Tuple getEmptyKey() { + static constexpr Tuple getEmptyKey() { return Tuple(DenseMapInfo::getEmptyKey()...); } - static inline Tuple getTombstoneKey() { + static constexpr Tuple getTombstoneKey() { return Tuple(DenseMapInfo::getTombstoneKey()...); } - template - static unsigned getHashValueImpl(const Tuple &values, std::false_type) { - using EltType = std::tuple_element_t; - std::integral_constant atEnd; - return detail::combineHashValue( - DenseMapInfo::getHashValue(std::get(values)), - getHashValueImpl(values, atEnd)); - } - - template - static unsigned getHashValueImpl(const Tuple &, std::true_type) { - return 0; + template static unsigned getHashValueImpl(const Tuple &values) { + if constexpr (I == sizeof...(Ts)) { + return 0; + } else { + using EltType = std::tuple_element_t; + return detail::combineHashValue( + DenseMapInfo::getHashValue(std::get(values)), + getHashValueImpl(values)); + } } static unsigned getHashValue(const std::tuple &values) { - std::integral_constant atEnd; - return getHashValueImpl<0>(values, atEnd); + return getHashValueImpl<0>(values); } - template - static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) { - using EltType = std::tuple_element_t; - std::integral_constant atEnd; - return DenseMapInfo::isEqual(std::get(lhs), std::get(rhs)) && - isEqualImpl(lhs, rhs, atEnd); - } - - template - static bool isEqualImpl(const Tuple &, const Tuple &, std::true_type) { - return true; + template + static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, + std::index_sequence) { + return (DenseMapInfo>::isEqual( + std::get(lhs), std::get(rhs)) && + ...); } static bool isEqual(const Tuple &lhs, const Tuple &rhs) { - std::integral_constant atEnd; - return isEqualImpl<0>(lhs, rhs, atEnd); + return isEqualImpl(lhs, rhs, std::index_sequence_for{}); } }; @@ -308,10 +211,22 @@ struct DenseMapInfo>> { using UnderlyingType = std::underlying_type_t; using Info = DenseMapInfo; - static Enum getEmptyKey() { return static_cast(Info::getEmptyKey()); } + // If an enum does not have a "fixed" underlying type, it may be UB to cast + // some values of the underlying type to the enum. We use an "extra" constexpr + // local to ensure that such UB would trigger "static assertion expression is + // not an integral constant expression", rather than runtime UB. + // + // If you hit this error, you can fix by switching to `enum class`, or adding + // an explicit underlying type (e.g. `enum X : int`) to the enum's definition. - static Enum getTombstoneKey() { - return static_cast(Info::getTombstoneKey()); + static constexpr Enum getEmptyKey() { + constexpr Enum V = static_cast(Info::getEmptyKey()); + return V; + } + + static constexpr Enum getTombstoneKey() { + constexpr Enum V = static_cast(Info::getTombstoneKey()); + return V; } static unsigned getHashValue(const Enum &Val) { @@ -320,6 +235,30 @@ struct DenseMapInfo>> { static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; } }; + +template struct DenseMapInfo> { + using Optional = std::optional; + using Info = DenseMapInfo; + + static constexpr Optional getEmptyKey() { return {Info::getEmptyKey()}; } + + static constexpr Optional getTombstoneKey() { + return {Info::getTombstoneKey()}; + } + + static unsigned getHashValue(const Optional &OptionalVal) { + return detail::combineHashValue( + OptionalVal.has_value(), + Info::getHashValue(OptionalVal.value_or(Info::getEmptyKey()))); + } + + static bool isEqual(const Optional &LHS, const Optional &RHS) { + if (LHS && RHS) { + return Info::isEqual(LHS.value(), RHS.value()); + } + return !LHS && !RHS; + } +}; } // end namespace wpi::util #endif // WPIUTIL_WPI_DENSEMAPINFO_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Endian.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Endian.hpp index ad9126a57f..3cd70f2dd4 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Endian.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Endian.hpp @@ -49,7 +49,9 @@ template /// Swap the bytes of value to match the given endianness. template -[[nodiscard]] inline value_type byte_swap(value_type value) { +[[nodiscard]] +LLVM_DEPRECATED("Pass endian as a function argument instead", + "byte_swap") inline value_type byte_swap(value_type value) { if constexpr (endian != wpi::util::endianness::native) sys::swapByteOrder(value); return value; @@ -68,7 +70,9 @@ template } template -[[nodiscard]] inline value_type read(const void *memory) { +[[nodiscard]] LLVM_DEPRECATED("Pass endian as a function argument instead", + "read") inline value_type + read(const void *memory) { return read(memory, endian); } @@ -98,9 +102,8 @@ inline void write(void *memory, value_type value, endianness endian) { &value, sizeof(value_type)); } -template +template +LLVM_DEPRECATED("Pass endian as a function argument instead", "write") inline void write(void *memory, value_type value) { write(memory, value, endian); } @@ -130,7 +133,7 @@ template uint64_t startBit) { assert(startBit < 8); if (startBit == 0) - return read(memory); + return read(memory, endian); else { // Read two values and compose the result from them. value_type val[2]; @@ -138,8 +141,8 @@ template LLVM_ASSUME_ALIGNED( memory, (detail::PickAlignment::value)), sizeof(value_type) * 2); - val[0] = byte_swap(val[0]); - val[1] = byte_swap(val[1]); + val[0] = byte_swap(val[0], endian); + val[1] = byte_swap(val[1], endian); // Shift bits from the lower value into place. make_unsigned_t lowerVal = val[0] >> startBit; @@ -165,7 +168,7 @@ inline void writeAtBitAlignment(void *memory, value_type value, uint64_t startBit) { assert(startBit < 8); if (startBit == 0) - write(memory, value); + write(memory, value, endian); else { // Read two values and shift the result into them. value_type val[2]; @@ -173,8 +176,8 @@ inline void writeAtBitAlignment(void *memory, value_type value, LLVM_ASSUME_ALIGNED( memory, (detail::PickAlignment::value)), sizeof(value_type) * 2); - val[0] = byte_swap(val[0]); - val[1] = byte_swap(val[1]); + val[0] = byte_swap(val[0], endian); + val[1] = byte_swap(val[1], endian); // Mask off any existing bits in the upper part of the lower value that // we want to replace. @@ -202,8 +205,8 @@ inline void writeAtBitAlignment(void *memory, value_type value, val[1] |= upperVal; // Finally, rewrite values. - val[0] = byte_swap(val[0]); - val[1] = byte_swap(val[1]); + val[0] = byte_swap(val[0], endian); + val[1] = byte_swap(val[1], endian); memcpy(LLVM_ASSUME_ALIGNED( memory, (detail::PickAlignment::value)), &val[0], sizeof(value_type) * 2); @@ -225,14 +228,15 @@ struct packed_endian_specific_integral { explicit packed_endian_specific_integral(value_type val) { *this = val; } - operator value_type() const { - return endian::read( - (const void*)Value.buffer); + value_type value() const { + return endian::read((const void *)Value.buffer, + endian); } + operator value_type() const { return value(); } void operator=(value_type newValue) { - endian::write( - (void*)Value.buffer, newValue); + endian::write((void *)Value.buffer, newValue, + endian); } packed_endian_specific_integral &operator+=(value_type newValue) { @@ -265,11 +269,11 @@ public: explicit ref(void *Ptr) : Ptr(Ptr) {} operator value_type() const { - return endian::read(Ptr); + return endian::read(Ptr, endian); } void operator=(value_type NewValue) { - endian::write(Ptr, NewValue); + endian::write(Ptr, NewValue, endian); } private: @@ -279,6 +283,9 @@ public: } // end namespace detail +using ulittle8_t = + detail::packed_endian_specific_integral; using ulittle16_t = detail::packed_endian_specific_integral; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Errno.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Errno.hpp index e844eb961a..dfa13199e5 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Errno.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/Errno.hpp @@ -13,6 +13,7 @@ #ifndef WPIUTIL_WPI_ERRNO_H #define WPIUTIL_WPI_ERRNO_H +#include "wpi/util/Compiler.hpp" #include #include diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ErrorHandling.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ErrorHandling.hpp index 6f277fbf59..f2e2561807 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ErrorHandling.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ErrorHandling.hpp @@ -20,59 +20,81 @@ namespace wpi::util { - /// An error handler callback. - typedef void (*fatal_error_handler_t)(void *user_data, - const char *reason, - bool gen_crash_diag); +/// An error handler callback. +using fatal_error_handler_t = void (*)(void *user_data, const char *reason, + bool gen_crash_diag); - /// install_fatal_error_handler - Installs a new error handler to be used - /// whenever a serious (non-recoverable) error is encountered by LLVM. - /// - /// If no error handler is installed the default is to print the error message - /// to stderr, and call exit(1). If an error handler is installed then it is - /// the handler's responsibility to log the message, it will no longer be - /// printed to stderr. If the error handler returns, then exit(1) will be - /// called. - /// - /// It is dangerous to naively use an error handler which throws an exception. - /// Even though some applications desire to gracefully recover from arbitrary - /// faults, blindly throwing exceptions through unfamiliar code isn't a way to - /// achieve this. - /// - /// \param user_data - An argument which will be passed to the install error - /// handler. - void install_fatal_error_handler(fatal_error_handler_t handler, - void *user_data = nullptr); - - /// Restores default error handling behaviour. - void remove_fatal_error_handler(); - - /// ScopedFatalErrorHandler - This is a simple helper class which just - /// calls install_fatal_error_handler in its constructor and - /// remove_fatal_error_handler in its destructor. - struct ScopedFatalErrorHandler { - explicit ScopedFatalErrorHandler(fatal_error_handler_t handler, - void *user_data = nullptr) { - install_fatal_error_handler(handler, user_data); - } - - ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } - }; - -/// Reports a serious error, calling any installed error handler. These -/// functions are intended to be used for error conditions which are outside -/// the control of the compiler (I/O errors, invalid user input, etc.) +/// install_fatal_error_handler - Installs a new error handler to be used +/// whenever a serious (non-recoverable) error is encountered by LLVM. /// -/// If no error handler is installed the default is to print the message to -/// standard error, followed by a newline. -/// After the error handler is called this function will call abort(), it -/// does not return. -[[noreturn]] void report_fatal_error(const char *reason, - bool gen_crash_diag = true); -[[noreturn]] void report_fatal_error(const std::string &reason, - bool gen_crash_diag = true); -[[noreturn]] void report_fatal_error(std::string_view reason, - bool gen_crash_diag = true); +/// If no error handler is installed the default is to print the error message +/// to stderr, and call exit(1). If an error handler is installed then it is +/// the handler's responsibility to log the message, it will no longer be +/// printed to stderr. If the error handler returns, then exit(1) will be +/// called. +/// +/// It is dangerous to naively use an error handler which throws an exception. +/// Even though some applications desire to gracefully recover from arbitrary +/// faults, blindly throwing exceptions through unfamiliar code isn't a way to +/// achieve this. +/// +/// \param user_data - An argument which will be passed to the install error +/// handler. +LLVM_ABI void install_fatal_error_handler(fatal_error_handler_t handler, + void *user_data = nullptr); + +/// Restores default error handling behaviour. +LLVM_ABI void remove_fatal_error_handler(); + +/// ScopedFatalErrorHandler - This is a simple helper class which just +/// calls install_fatal_error_handler in its constructor and +/// remove_fatal_error_handler in its destructor. +struct ScopedFatalErrorHandler { + explicit ScopedFatalErrorHandler(fatal_error_handler_t handler, + void *user_data = nullptr) { + install_fatal_error_handler(handler, user_data); + } + + ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } +}; + +/// @deprecated Use reportFatalInternalError() or reportFatalUsageError() +/// instead. +[[noreturn]] LLVM_ABI void report_fatal_error(const char *reason, + bool gen_crash_diag = true); +[[noreturn]] LLVM_ABI void report_fatal_error(const std::string& reason, + bool gen_crash_diag = true); +[[noreturn]] LLVM_ABI void report_fatal_error(std::string_view reason, + bool gen_crash_diag = true); + +/// Report a fatal error that likely indicates a bug in LLVM. It serves a +/// similar purpose as an assertion, but is always enabled, regardless of the +/// value of NDEBUG. +/// +/// This will call installed error handlers (or print the message by default) +/// and then abort. This will produce a crash trace and *will* ask users to +/// report an LLVM bug. +[[noreturn]] LLVM_ABI void reportFatalInternalError(const char *reason); +[[noreturn]] LLVM_ABI void reportFatalInternalError(const std::string& reason); +[[noreturn]] LLVM_ABI void reportFatalInternalError(std::string_view reason); + +/// Report a fatal error that does not indicate a bug in LLVM. +/// +/// This can be used in contexts where a proper error reporting mechanism +/// (such as Error/Expected or DiagnosticInfo) is currently not supported, and +/// would be too involved to introduce at the moment. +/// +/// Examples where this function should be used instead of +/// reportFatalInternalError() include invalid inputs or options, but also +/// environment error conditions outside LLVM's control. It should also be used +/// for known unsupported/unimplemented functionality. +/// +/// This will call installed error handlers (or print the message by default) +/// and then exit with code 1. It will not produce a crash trace and will +/// *not* ask users to report an LLVM bug. +[[noreturn]] LLVM_ABI void reportFatalUsageError(const char *reason); +[[noreturn]] LLVM_ABI void reportFatalUsageError(const std::string& reason); +[[noreturn]] LLVM_ABI void reportFatalUsageError(std::string_view reason); /// Installs a new bad alloc error handler that should be used whenever a /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM. @@ -90,13 +112,13 @@ namespace wpi::util { /// /// \param user_data - An argument which will be passed to the installed error /// handler. -void install_bad_alloc_error_handler(fatal_error_handler_t handler, - void *user_data = nullptr); +LLVM_ABI void install_bad_alloc_error_handler(fatal_error_handler_t handler, + void *user_data = nullptr); /// Restores default bad alloc error handling behavior. -void remove_bad_alloc_error_handler(); +LLVM_ABI void remove_bad_alloc_error_handler(); -void install_out_of_memory_new_handler(); +LLVM_ABI void install_out_of_memory_new_handler(); /// Reports a bad alloc error, calling any user defined bad alloc /// error handler. In contrast to the generic 'report_fatal_error' @@ -110,16 +132,16 @@ void install_out_of_memory_new_handler(); /// If no error handler is installed (default), throws a bad_alloc exception /// if LLVM is compiled with exception support. Otherwise prints the error /// to standard error and calls abort(). -[[noreturn]] void report_bad_alloc_error(const char *Reason, - bool GenCrashDiag = true); +[[noreturn]] LLVM_ABI void report_bad_alloc_error(const char *Reason, + bool GenCrashDiag = true); /// This function calls abort(), and prints the optional message to stderr. /// Use the wpi_unreachable macro (that adds location info), instead of /// calling this function directly. -[[noreturn]] void -wpi_unreachable_internal(const char *msg = nullptr, const char *file = nullptr, - unsigned line = 0); -} +[[noreturn]] LLVM_ABI void wpi_unreachable_internal(const char *msg = nullptr, + const char *file = nullptr, + unsigned line = 0); +} // namespace wpi::util /// Marks that the current location is not supposed to be reachable. /// In !NDEBUG builds, prints the message and location info to stderr. @@ -139,7 +161,7 @@ wpi_unreachable_internal(const char *msg = nullptr, const char *file = nullptr, /// diagnostics for unreachable code paths, and allows compilers to omit /// unnecessary code. #ifndef NDEBUG -#define wpi_unreachable(msg) \ +#define wpi_unreachable(msg) \ ::wpi::util::wpi_unreachable_internal(msg, __FILE__, __LINE__) #elif !defined(LLVM_BUILTIN_UNREACHABLE) #define wpi_unreachable(msg) ::wpi::util::wpi_unreachable_internal() diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/FunctionExtras.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/FunctionExtras.hpp index 59e222c803..eaf8601047 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/FunctionExtras.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/FunctionExtras.hpp @@ -39,7 +39,6 @@ #include "wpi/util/MemAlloc.hpp" #include "wpi/util/type_traits.hpp" #include -#include #include namespace wpi::util { @@ -65,10 +64,6 @@ template class unique_function; namespace detail { -template -using EnableIfTrivial = - std::enable_if_t::value && - std::is_trivially_destructible::value>; template using EnableUnlessSameType = std::enable_if_t, ThisT>::value>; @@ -89,13 +84,6 @@ protected: static constexpr size_t InlineStorageSize = sizeof(void *) * 4; static constexpr size_t InlineStorageAlign = alignof(void *); - template - struct IsSizeLessThanThresholdT : std::false_type {}; - - template - struct IsSizeLessThanThresholdT< - T, std::enable_if_t> : std::true_type {}; - // Provide a type function to map parameters that won't observe extra copies // or moves and which are small enough to likely pass in register to values // and all other types to l-value reference types. We use this to compute the @@ -108,10 +96,12 @@ protected: template struct AdjustedParamTBase { static_assert(!std::is_reference::value, "references should be handled by template specialization"); + static constexpr bool IsSizeLessThanThreshold = + sizeof(T) <= 2 * sizeof(void *); using type = std::conditional_t::value && std::is_trivially_move_constructible::value && - IsSizeLessThanThresholdT::value, + IsSizeLessThanThreshold, T, T &>; }; @@ -242,22 +232,22 @@ protected: // The pointers to call/move/destroy functions are determined for each // callable type (and called-as type, which determines the overload chosen). - // (definitions are out-of-line). // By default, we need an object that contains all the different // type erased behaviors needed. Create a static instance of the struct type // here and each instance will contain a pointer to it. // Wrap in a struct to avoid https://gcc.gnu.org/PR71954 - template - struct CallbacksHolder { - static NonTrivialCallbacks Callbacks; - }; - // See if we can create a trivial callback. We need the callable to be - // trivially moved and trivially destroyed so that we don't have to store - // type erased callbacks for those operations. - template - struct CallbacksHolder> { - static TrivialCallback Callbacks; + template struct CallbacksHolder { + inline static auto Callbacks = []() constexpr { + // For trivial callables, we don't need to store move and destroy + // callbacks. + if constexpr (std::is_trivially_move_constructible_v && + std::is_trivially_destructible_v) + return TrivialCallback{&CallImpl}; + else + return NonTrivialCallbacks{&CallImpl, &MoveImpl, + &DestroyImpl}; + }(); }; // A simple tag type so the call-as type to be passed to the constructor. @@ -355,19 +345,6 @@ public: } }; -template -template -typename UniqueFunctionBase::NonTrivialCallbacks UniqueFunctionBase< - R, P...>::CallbacksHolder::Callbacks = { - &CallImpl, &MoveImpl, &DestroyImpl}; - -template -template -typename UniqueFunctionBase::TrivialCallback - UniqueFunctionBase::CallbacksHolder< - CallableT, CalledAsT, EnableIfTrivial>::Callbacks{ - &CallImpl}; - } // namespace detail template diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/IOSandbox.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/IOSandbox.hpp new file mode 100644 index 0000000000..a11737ab1a --- /dev/null +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/IOSandbox.hpp @@ -0,0 +1,42 @@ +//===- IOSandbox.h ----------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef WPIUTIL_WPI_IOSANDBOX_H +#define WPIUTIL_WPI_IOSANDBOX_H + +#if defined(LLVM_ENABLE_IO_SANDBOX) && LLVM_ENABLE_IO_SANDBOX + +#include "wpi/util/Compiler.hpp" +#include "wpi/util/ErrorHandling.hpp" +#include "wpi/util/SaveAndRestore.hpp" + +namespace wpi::util::sys::sandbox { +inline LLVM_THREAD_LOCAL bool Enabled = false; +struct ScopedSetting { + SaveAndRestore Impl; +}; +inline ScopedSetting scopedEnable() { return {{Enabled, true}}; } +inline ScopedSetting scopedDisable() { return {{Enabled, false}}; } +inline void violationIfEnabled() { + if (Enabled) + reportFatalInternalError("IO sandbox violation"); +} +} // namespace wpi::util::sys::sandbox + +#else + +namespace wpi::util::sys::sandbox { +struct [[maybe_unused]] ScopedSetting {}; +inline ScopedSetting scopedEnable() { return {}; } +inline ScopedSetting scopedDisable() { return {}; } +inline void violationIfEnabled() {} +} // namespace wpi::util::sys::sandbox + +#endif + +#endif diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MathExtras.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MathExtras.hpp index 1649198942..8fa4d64570 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MathExtras.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MathExtras.hpp @@ -13,6 +13,7 @@ #ifndef WPIUTIL_WPI_MATHEXTRAS_H #define WPIUTIL_WPI_MATHEXTRAS_H +#include "wpi/util/STLForwardCompat.hpp" #include "wpi/util/bit.hpp" #include "wpi/util/Compiler.hpp" #include @@ -43,7 +44,7 @@ using common_sint = /// Create a bitmask with the N right-most bits set to 1, and all other /// bits set to 0. Only unsigned types are allowed. -template T maskTrailingOnes(unsigned N) { +template constexpr T maskTrailingOnes(unsigned N) { static_assert(std::is_unsigned_v, "Invalid type!"); const unsigned Bits = CHAR_BIT * sizeof(T); assert(N <= Bits && "Invalid bit index"); @@ -54,19 +55,19 @@ template T maskTrailingOnes(unsigned N) { /// Create a bitmask with the N left-most bits set to 1, and all other /// bits set to 0. Only unsigned types are allowed. -template T maskLeadingOnes(unsigned N) { +template constexpr T maskLeadingOnes(unsigned N) { return ~maskTrailingOnes(CHAR_BIT * sizeof(T) - N); } /// Create a bitmask with the N right-most bits set to 0, and all other /// bits set to 1. Only unsigned types are allowed. -template T maskTrailingZeros(unsigned N) { +template constexpr T maskTrailingZeros(unsigned N) { return maskLeadingOnes(CHAR_BIT * sizeof(T) - N); } /// Create a bitmask with the N left-most bits set to 0, and all other /// bits set to 1. Only unsigned types are allowed. -template T maskLeadingZeros(unsigned N) { +template constexpr T maskLeadingZeros(unsigned N) { return maskTrailingOnes(CHAR_BIT * sizeof(T) - N); } @@ -84,7 +85,7 @@ static const unsigned char BitReverseTable256[256] = { }; /// Reverse the bits in \p Val. -template T reverseBits(T Val) { +template constexpr T reverseBits(T Val) { #if __has_builtin(__builtin_bitreverse8) if constexpr (std::is_same_v) return __builtin_bitreverse8(Val); @@ -156,16 +157,8 @@ constexpr bool isShiftedInt(int64_t x) { /// Checks if an unsigned integer fits into the given bit width. template constexpr bool isUInt(uint64_t x) { - if constexpr (N == 0) - return 0 == x; - if constexpr (N == 8) - return static_cast(x) == x; - if constexpr (N == 16) - return static_cast(x) == x; - if constexpr (N == 32) - return static_cast(x) == x; if constexpr (N < 64) - return x < (UINT64_C(1) << (N)); + return (x >> N) == 0; (void)x; // MSVC v19.25 warns that x is unused. return true; } @@ -181,7 +174,7 @@ constexpr bool isShiftedUInt(uint64_t x) { } /// Gets the maximum value for a N-bit unsigned integer. -inline uint64_t maxUIntN(uint64_t N) { +inline constexpr uint64_t maxUIntN(uint64_t N) { assert(N <= 64 && "integer width out of range"); // uint64_t(1) << 64 is undefined behavior, so we can't do @@ -202,12 +195,12 @@ inline uint64_t maxUIntN(uint64_t N) { #endif /// Gets the minimum value for a N-bit signed integer. -inline int64_t minIntN(int64_t N) { +inline constexpr int64_t minIntN(int64_t N) { assert(N >= 0 && N <= 64 && "integer width out of range"); if (N == 0) return 0; - return UINT64_C(1) + ~(UINT64_C(1) << (N - 1)); + return UINT64_MAX << (N - 1); } #ifdef _WIN32 @@ -215,7 +208,7 @@ inline int64_t minIntN(int64_t N) { #endif /// Gets the maximum value for a N-bit signed integer. -inline int64_t maxIntN(int64_t N) { +inline constexpr int64_t maxIntN(int64_t N) { assert(N >= 0 && N <= 64 && "integer width out of range"); // This relies on two's complement wraparound when N == 64, so we convert to @@ -226,12 +219,12 @@ inline int64_t maxIntN(int64_t N) { } /// Checks if an unsigned integer fits into the given (dynamic) bit width. -inline bool isUIntN(unsigned N, uint64_t x) { - return N >= 64 || x <= maxUIntN(N); +inline constexpr bool isUIntN(unsigned N, uint64_t x) { + return N >= 64 || (x >> N) == 0; } /// Checks if an signed integer fits into the given (dynamic) bit width. -inline bool isIntN(unsigned N, int64_t x) { +inline constexpr bool isIntN(unsigned N, int64_t x) { return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N)); } @@ -300,13 +293,16 @@ inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, /// Compile time Log2. /// Valid only for positive powers of two. -template constexpr size_t CTLog2() { - static_assert(kValue > 0 && wpi::util::isPowerOf2_64(kValue), - "Value is not a valid power of 2"); - return 1 + CTLog2(); +template constexpr size_t ConstantLog2() { + static_assert(wpi::util::isPowerOf2_64(kValue), "Value is not a valid power of 2"); + return std::countr_zero(kValue); } -template <> constexpr size_t CTLog2<1>() { return 0; } +template +LLVM_DEPRECATED("Use ConstantLog2 instead", "ConstantLog2") +constexpr size_t CTLog2() { + return ConstantLog2(); +} /// Return the floor log base 2 of the specified value, -1 if the value is zero. /// (32 bit edition.) @@ -568,6 +564,15 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) { return int64_t(X << (64 - B)) >> (64 - B); } +/// Return the absolute value of a signed integer, converted to the +/// corresponding unsigned integer type. Avoids undefined behavior in std::abs +/// when you pass it INT_MIN or similar. +template > +constexpr U AbsoluteValue(T X) { + // If X is negative, cast it to the unsigned type _before_ negating it. + return X < 0 ? -static_cast(X) : X; +} + /// Subtract two unsigned integers, X and Y, of type T and return the absolute /// value of the result. template > @@ -667,7 +672,7 @@ SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) { } /// Use this rather than HUGE_VALF; the latter causes warnings on MSVC. -extern const float huge_valf; +LLVM_ABI extern const float huge_valf; /// Add two signed integers, computing the two's complement truncated result, /// returning true if overflow occurred. @@ -696,7 +701,7 @@ std::enable_if_t, T> AddOverflow(T X, T Y, T &Result) { } /// Subtract two signed integers, computing the two's complement truncated -/// result, returning true if an overflow ocurred. +/// result, returning true if an overflow occurred. template std::enable_if_t, T> SubOverflow(T X, T Y, T &Result) { #if __has_builtin(__builtin_sub_overflow) @@ -722,7 +727,7 @@ std::enable_if_t, T> SubOverflow(T X, T Y, T &Result) { } /// Multiply two signed integers, computing the two's complement truncated -/// result, returning true if an overflow ocurred. +/// result, returning true if an overflow occurred. template std::enable_if_t, T> MulOverflow(T X, T Y, T &Result) { #if __has_builtin(__builtin_mul_overflow) diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemAlloc.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemAlloc.hpp index c25acc100e..a0164409a7 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemAlloc.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/MemAlloc.hpp @@ -79,7 +79,7 @@ LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) { /// like posix_memalign due to portability. It is mostly intended to allow /// compatibility with platforms that, after aligned allocation was added, use /// reduced default alignment. -LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * +LLVM_ABI LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * allocate_buffer(size_t Size, size_t Alignment); /// Deallocate a buffer of memory with the given size and alignment. @@ -89,7 +89,7 @@ allocate_buffer(size_t Size, size_t Alignment); /// /// The pointer must have been allocated with the corresponding new operator, /// most likely using the above helper. -void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment); +LLVM_ABI void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment); } // namespace wpi::util diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerIntPair.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerIntPair.hpp index ed8c7f8c86..87e9dbf88e 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerIntPair.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerIntPair.hpp @@ -173,15 +173,14 @@ struct PointerIntPairInfo { "PointerIntPair with integer size too large for pointer"); enum MaskAndShiftConstants : uintptr_t { /// PointerBitMask - The bits that come from the pointer. - PointerBitMask = - ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1), + PointerBitMask = (~(uintptr_t)0) << PtrTraits::NumLowBitsAvailable, /// IntShift - The number of low bits that we reserve for other uses, and /// keep zero. IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits, /// IntMask - This is the unshifted mask for valid bits of the int type. - IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1), + IntMask = ((uintptr_t)1 << IntBits) - 1, // ShiftedIntMask - This is the bits for the integer shifted in place. ShiftedIntMask = (uintptr_t)(IntMask << IntShift) @@ -206,11 +205,10 @@ struct PointerIntPairInfo { } static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) { - intptr_t IntWord = static_cast(Int); - assert((IntWord & ~IntMask) == 0 && "Integer too large for field"); + assert((Int & ~IntMask) == 0 && "Integer too large for field"); // Preserve all bits other than the ones we are updating. - return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift; + return (OrigValue & ~ShiftedIntMask) | Int << IntShift; } }; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerLikeTypeTraits.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerLikeTypeTraits.hpp index 6fdff82c86..d42b835a92 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerLikeTypeTraits.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerLikeTypeTraits.hpp @@ -14,9 +14,9 @@ #ifndef WPIUTIL_WPI_POINTERLIKETYPETRAITS_H #define WPIUTIL_WPI_POINTERLIKETYPETRAITS_H +#include "wpi/util/MathExtras.hpp" #include #include -#include namespace wpi::util { @@ -25,12 +25,6 @@ namespace wpi::util { template struct PointerLikeTypeTraits; namespace detail { -/// A tiny meta function to compute the log2 of a compile time constant. -template -struct ConstantLog2 - : std::integral_constant::value + 1> {}; -template <> struct ConstantLog2<1> : std::integral_constant {}; - // Provide a trait to check if T is pointer-like. template struct HasPointerLikeTypeTraits { static const bool value = false; @@ -57,8 +51,7 @@ template struct PointerLikeTypeTraits { static inline void *getAsVoidPointer(T *P) { return P; } static inline T *getFromVoidPointer(void *P) { return static_cast(P); } - static constexpr int NumLowBitsAvailable = - detail::ConstantLog2::value; + static constexpr int NumLowBitsAvailable = ConstantLog2(); }; template <> struct PointerLikeTypeTraits { @@ -77,7 +70,7 @@ template <> struct PointerLikeTypeTraits { // Provide PointerLikeTypeTraits for const things. template struct PointerLikeTypeTraits { - typedef PointerLikeTypeTraits NonConst; + using NonConst = PointerLikeTypeTraits; static inline const void *getAsVoidPointer(const T P) { return NonConst::getAsVoidPointer(P); @@ -90,7 +83,7 @@ template struct PointerLikeTypeTraits { // Provide PointerLikeTypeTraits for const pointers. template struct PointerLikeTypeTraits { - typedef PointerLikeTypeTraits NonConst; + using NonConst = PointerLikeTypeTraits; static inline const void *getAsVoidPointer(const T *P) { return NonConst::getAsVoidPointer(const_cast(P)); @@ -123,8 +116,7 @@ template <> struct PointerLikeTypeTraits { /// potentially use alignment attributes on functions to satisfy that. template struct FunctionPointerLikeTypeTraits { - static constexpr int NumLowBitsAvailable = - detail::ConstantLog2::value; + static constexpr int NumLowBitsAvailable = ConstantLog2(); static inline void *getAsVoidPointer(FunctionPointerT P) { assert((reinterpret_cast(P) & ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 && diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerUnion.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerUnion.hpp index 440e12d8b9..53a5b38d8b 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerUnion.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/PointerUnion.hpp @@ -76,18 +76,13 @@ namespace pointer_union_detail { /// Determine the number of bits required to store integers with values < n. /// This is ceil(log2(n)). constexpr int bitsRequired(unsigned n) { - return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0; + return n == 0 ? 0 : std::bit_width(n - 1); } template constexpr int lowBitsAvailable() { return std::min({PointerLikeTypeTraits::NumLowBitsAvailable...}); } - /// Find the first type in a list of types. - template struct GetFirstType { - using type = T; - }; - /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion /// for the template arguments. template class PointerUnionUIntTraits { @@ -133,9 +128,6 @@ namespace pointer_union_detail { }; } -// This is a forward declaration of CastInfoPointerUnionImpl -// Refer to its definition below for further details -template struct CastInfoPointerUnionImpl; /// A discriminated union of two or more pointer types, with the discriminator /// in the low bit of the pointer. /// @@ -171,10 +163,12 @@ class PointerUnion using First = TypeAtIndex<0, PTs...>; using Base = typename PointerUnion::PointerUnionMembers; - /// This is needed to give the CastInfo implementation below access - /// to protected members. - /// Refer to its definition for further details. - friend struct CastInfoPointerUnionImpl; + // Give the CastInfo specialization below access to protected members. + // + // This makes all of CastInfo a friend, which is more than strictly + // necessary. It's a workaround for C++'s inability to friend a + // partial template specialization. + template friend struct CastInfo; public: PointerUnion() = default; @@ -264,42 +258,21 @@ bool operator<(PointerUnion lhs, PointerUnion rhs) { return lhs.getOpaqueValue() < rhs.getOpaqueValue(); } -/// We can't (at least, at this moment with C++14) declare CastInfo -/// as a friend of PointerUnion like this: -/// ``` -/// template -/// friend struct CastInfo>; -/// ``` -/// The compiler complains 'Partial specialization cannot be declared as a -/// friend'. -/// So we define this struct to be a bridge between CastInfo and -/// PointerUnion. -template struct CastInfoPointerUnionImpl { - using From = PointerUnion; - - template static inline bool isPossible(From &F) { - return F.Val.getInt() == FirstIndexOfType::value; - } - - template static To doCast(From &F) { - assert(isPossible(F) && "cast to an incompatible type!"); - return PointerLikeTypeTraits::getFromVoidPointer(F.Val.getPointer()); - } -}; - // Specialization of CastInfo for PointerUnion template struct CastInfo> : public DefaultDoCastIfPossible, CastInfo>> { using From = PointerUnion; - using Impl = CastInfoPointerUnionImpl; static inline bool isPossible(From &f) { - return Impl::template isPossible(f); + return f.Val.getInt() == FirstIndexOfType::value; } - static To doCast(From &f) { return Impl::template doCast(f); } + static To doCast(From &f) { + assert(isPossible(f) && "cast to an incompatible type!"); + return PointerLikeTypeTraits::getFromVoidPointer(f.Val.getPointer()); + } static inline To castFailed() { return To(); } }; @@ -331,8 +304,7 @@ struct PointerLikeTypeTraits> { // Teach DenseMap how to use PointerUnions as keys. template struct DenseMapInfo> { using Union = PointerUnion; - using FirstInfo = - DenseMapInfo::type>; + using FirstInfo = DenseMapInfo>; static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ReverseIteration.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ReverseIteration.hpp index 16eec5a61d..f231ed4ade 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ReverseIteration.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/ReverseIteration.hpp @@ -5,8 +5,7 @@ namespace wpi::util { -template -bool shouldReverseIterate() { +template constexpr bool shouldReverseIterate() { #if LLVM_ENABLE_REVERSE_ITERATION return detail::IsPointerLike::value; #else diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/STLForwardCompat.hpp b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/STLForwardCompat.hpp index 0f979add02..c7ed9966a4 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/STLForwardCompat.hpp +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/STLForwardCompat.hpp @@ -19,6 +19,7 @@ #include #include +#include namespace wpi::util { @@ -26,6 +27,54 @@ namespace wpi::util { // Features from C++20 //===----------------------------------------------------------------------===// +namespace numbers { +// clang-format off +template >> +inline constexpr T e_v = T(0x1.5bf0a8b145769P+1); // (2.7182818284590452354) https://oeis.org/A001113 +template >> +inline constexpr T egamma_v = T(0x1.2788cfc6fb619P-1); // (.57721566490153286061) https://oeis.org/A001620 +template >> +inline constexpr T ln2_v = T(0x1.62e42fefa39efP-1); // (.69314718055994530942) https://oeis.org/A002162 +template >> +inline constexpr T ln10_v = T(0x1.26bb1bbb55516P+1); // (2.3025850929940456840) https://oeis.org/A002392 +template >> +inline constexpr T log2e_v = T(0x1.71547652b82feP+0); // (1.4426950408889634074) +template >> +inline constexpr T log10e_v = T(0x1.bcb7b1526e50eP-2); // (.43429448190325182765) +template >> +inline constexpr T pi_v = T(0x1.921fb54442d18P+1); // (3.1415926535897932385) https://oeis.org/A000796 +template >> +inline constexpr T inv_pi_v = T(0x1.45f306dc9c883P-2); // (.31830988618379067154) https://oeis.org/A049541 +template >> +inline constexpr T inv_sqrtpi_v = T(0x1.20dd750429b6dP-1); // (.56418958354775628695) https://oeis.org/A087197 +template >> +inline constexpr T sqrt2_v = T(0x1.6a09e667f3bcdP+0); // (1.4142135623730950488) https://oeis.org/A00219 +template >> +inline constexpr T inv_sqrt2_v = T(0x1.6a09e667f3bcdP-1); // (.70710678118654752440) +template >> +inline constexpr T sqrt3_v = T(0x1.bb67ae8584caaP+0); // (1.7320508075688772935) https://oeis.org/A002194 +template >> +inline constexpr T inv_sqrt3_v = T(0x1.279a74590331cP-1); // (.57735026918962576451) +template >> +inline constexpr T phi_v = T(0x1.9e3779b97f4a8P+0); // (1.6180339887498948482) https://oeis.org/A001622 + +inline constexpr double e = e_v; +inline constexpr double egamma = egamma_v; +inline constexpr double ln2 = ln2_v; +inline constexpr double ln10 = ln10_v; +inline constexpr double log2e = log2e_v; +inline constexpr double log10e = log10e_v; +inline constexpr double pi = pi_v; +inline constexpr double inv_pi = inv_pi_v; +inline constexpr double inv_sqrtpi = inv_sqrtpi_v; +inline constexpr double sqrt2 = sqrt2_v; +inline constexpr double inv_sqrt2 = inv_sqrt2_v; +inline constexpr double sqrt3 = sqrt3_v; +inline constexpr double inv_sqrt3 = inv_sqrt3_v; +inline constexpr double phi = phi_v; +// clang-format on +} // namespace numbers + template struct remove_cvref // NOLINT(readability-identifier-naming) { @@ -36,27 +85,81 @@ template using remove_cvref_t // NOLINT(readability-identifier-naming) = typename wpi::util::remove_cvref::type; +// TODO: Remove this in favor of std::type_identity once we switch to C++20. +template +struct type_identity // NOLINT(readability-identifier-naming) +{ + using type = T; +}; + +// TODO: Remove this in favor of std::type_identity_t once we switch to +// C++20. +template +using type_identity_t // NOLINT(readability-identifier-naming) + = typename wpi::util::type_identity::type; + +namespace detail { +template class Op, class... Args> struct detector { + using value_t = std::false_type; +}; +template