mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[upstream_utils] Upgrade to LLVM 22.1.6 (#8919)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:09:18 -0400
|
||||
Subject: [PATCH 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 <limits>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
@@ -324,7 +325,7 @@ index bd3e887e36bce4129d95099e84e833adc6a82cee..be06bb817e24e723265f9a8038d94123
|
||||
template <typename IteratorT> class iterator_range;
|
||||
|
||||
template <class Iterator>
|
||||
@@ -114,7 +113,7 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
|
||||
@@ -116,7 +115,7 @@ template <class T, typename = void> 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 <typename T, typename = void>
|
||||
class SmallVectorTemplateCommon
|
||||
@@ -1229,7 +1228,7 @@ public:
|
||||
@@ -739,7 +738,7 @@ public:
|
||||
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
- void assign(ArrayRef<U> AR) {
|
||||
+ void assign(span<const U> AR) {
|
||||
assign(AR.begin(), AR.end());
|
||||
}
|
||||
|
||||
@@ -1238,7 +1237,7 @@ public:
|
||||
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
- explicit SmallVector(ArrayRef<U> A) : SmallVectorImpl<T>(N) {
|
||||
+ explicit SmallVector(span<const U> A) : SmallVectorImpl<T>(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<sys::TimePoint<>> {
|
||||
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<sys::UtcTime<std::chrono::seconds>> {
|
||||
@@ -148,7 +148,7 @@ private:
|
||||
LLVM_ABI static void format(const sys::UtcTime<std::chrono::seconds> &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<duration<InternalRep, AsPeriod>>(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<Period>::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 <cstddef>
|
||||
#include <string>
|
||||
-
|
||||
@@ -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<char> SrcBytes);
|
||||
+bool hasUTF16ByteOrderMark(span<const char> SrcBytes);
|
||||
-LLVM_ABI bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
|
||||
+LLVM_ABI bool hasUTF16ByteOrderMark(span<const char> SrcBytes);
|
||||
|
||||
/**
|
||||
* Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
|
||||
@@ -291,7 +288,7 @@ bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
|
||||
@@ -304,7 +301,7 @@ LLVM_ABI bool hasUTF16ByteOrderMark(ArrayRef<char> SrcBytes);
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
|
||||
+bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out);
|
||||
-LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes,
|
||||
+LLVM_ABI bool convertUTF16ToUTF8String(span<const char> SrcBytes,
|
||||
std::string &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF16 string into a UTF8 std::string.
|
||||
@@ -300,7 +297,7 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
|
||||
@@ -314,7 +311,7 @@ LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes,
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out);
|
||||
+bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out);
|
||||
-LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out);
|
||||
+LLVM_ABI bool convertUTF16ToUTF8String(span<const UTF16> 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<UTF16> Src, std::string &Out);
|
||||
@@ -323,7 +320,7 @@ LLVM_ABI bool convertUTF16ToUTF8String(ArrayRef<UTF16> Src, std::string &Out);
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
|
||||
+bool convertUTF32ToUTF8String(span<const char> SrcBytes, std::string &Out);
|
||||
-LLVM_ABI bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes,
|
||||
+LLVM_ABI bool convertUTF32ToUTF8String(span<const char> SrcBytes,
|
||||
std::string &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF32 string into a UTF8 std::string.
|
||||
@@ -318,22 +315,22 @@ bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out);
|
||||
@@ -333,14 +330,14 @@ LLVM_ABI bool convertUTF32ToUTF8String(ArrayRef<char> SrcBytes,
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF32ToUTF8String(ArrayRef<UTF32> Src, std::string &Out);
|
||||
+bool convertUTF32ToUTF8String(span<const UTF32> Src, std::string &Out);
|
||||
-LLVM_ABI bool convertUTF32ToUTF8String(ArrayRef<UTF32> Src, std::string &Out);
|
||||
+LLVM_ABI bool convertUTF32ToUTF8String(span<const UTF32> Src, std::string &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF-8 string into a UTF-16 string with native endianness.
|
||||
*
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF8ToUTF16String(StringRef SrcUTF8,
|
||||
+bool convertUTF8ToUTF16String(std::string_view SrcUTF8,
|
||||
SmallVectorImpl<UTF16> &DstUTF16);
|
||||
-LLVM_ABI bool convertUTF8ToUTF16String(StringRef SrcUTF8,
|
||||
+LLVM_ABI bool convertUTF8ToUTF16String(std::string_view SrcUTF8,
|
||||
SmallVectorImpl<UTF16> &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<wchar_t> &utf16);
|
||||
+std::error_code UTF8ToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||
-LLVM_ABI std::error_code UTF8ToUTF16(StringRef utf8,
|
||||
+LLVM_ABI std::error_code UTF8ToUTF16(std::string_view utf8,
|
||||
SmallVectorImpl<wchar_t> &utf16);
|
||||
/// Convert to UTF16 from the current code page used in the system
|
||||
-std::error_code CurCPToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||
+std::error_code CurCPToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
/// Convert from UTF16 to the current code page used in the system
|
||||
-LLVM_ABI std::error_code CurCPToUTF16(StringRef utf8,
|
||||
+LLVM_ABI std::error_code CurCPToUTF16(std::string_view utf8,
|
||||
SmallVectorImpl<wchar_t> &utf16);
|
||||
LLVM_ABI std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &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 <string_view>
|
||||
|
||||
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 <string> dependency.
|
||||
[[noreturn]] void report_fatal_error(const char *reason,
|
||||
bool gen_crash_diag = true);
|
||||
-[[noreturn]] void report_fatal_error(StringRef reason,
|
||||
+[[noreturn]] void report_fatal_error(const std::string &reason,
|
||||
bool gen_crash_diag = true);
|
||||
-[[noreturn]] void report_fatal_error(const Twine &reason,
|
||||
+[[noreturn]] void report_fatal_error(std::string_view reason,
|
||||
bool gen_crash_diag = true);
|
||||
/// 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 <typename HasherT, llvm::endianness Endianness> 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 <typename HandleTraits>
|
||||
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 <cassert>
|
||||
#include <cstddef>
|
||||
@@ -607,7 +646,7 @@ index d3b411590e7fd796913aca8517020d02aa2559cc..c43c68c9114d8cd564484b190456b006
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
@@ -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<char> &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<char> &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<Error(raw_ostream &)> Write);
|
||||
-LLVM_ABI Error writeToOutput(StringRef OutputFileName,
|
||||
+LLVM_ABI Error writeToOutput(std::string_view OutputFileName,
|
||||
std::function<Error(raw_ostream &)> 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<char, 64> Buffer;
|
||||
raw_svector_ostream OS(Buffer);
|
||||
OS << "LLVM ERROR: " << Reason << "\n";
|
||||
- StringRef MessageStr = OS.str();
|
||||
+ std::string_view MessageStr = OS.str();
|
||||
ssize_t written = ::write(2, MessageStr.data(), MessageStr.size());
|
||||
(void)written; // If something went wrong, we deliberately just give up.
|
||||
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<wchar_t, 256> 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 <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
+#include <string_view>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
@@ -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<int, StringRef> PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}};
|
||||
- SmallDenseMap<int, StringRef> M(llvm::from_range, PlainArray);
|
||||
+ std::pair<int, std::string_view> PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}};
|
||||
+ SmallDenseMap<int, std::string_view> 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 <list>
|
||||
+#include <span>
|
||||
#include <stdarg.h>
|
||||
|
||||
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<Constructable, 4>(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<const Constructable>(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<char> v = {'a', 'b', 'c'};
|
||||
@@ -1183,10 +1165,10 @@ private:
|
||||
namespace namespace_with_adl {
|
||||
struct MyVector {
|
||||
std::vector<int> data;
|
||||
@@ -1209,10 +1191,10 @@ private:
|
||||
To T;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,45 +1,99 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:12:41 -0400
|
||||
Subject: [PATCH 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<unsigned>(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<unsigned>(NextPowerOf2(MinNumBuckets - 1)));
|
||||
+ return (std::max)(64u,
|
||||
+ static_cast<unsigned>(NextPowerOf2(MinNumBuckets - 1)));
|
||||
}
|
||||
|
||||
bool maybeMoveFast(DenseMap &&Other) {
|
||||
@@ -861,7 +861,7 @@ private:
|
||||
std::pair<bool, unsigned> 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<unsigned>(NextPowerOf2(MinNumBuckets - 1)));
|
||||
+ return (std::max)(64u,
|
||||
+ static_cast<unsigned>(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<char> {
|
||||
template <typename T>
|
||||
struct DenseMapInfo<
|
||||
T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, char>>> {
|
||||
- static constexpr T getEmptyKey() { return std::numeric_limits<T>::max(); }
|
||||
+ static constexpr T getEmptyKey() { return (std::numeric_limits<T>::max)(); }
|
||||
|
||||
static constexpr T getTombstoneKey() {
|
||||
if constexpr (std::is_unsigned_v<T> || std::is_same_v<T, long>)
|
||||
- return std::numeric_limits<T>::max() - 1;
|
||||
+ return (std::numeric_limits<T>::max)() - 1;
|
||||
else
|
||||
- return std::numeric_limits<T>::min();
|
||||
+ return (std::numeric_limits<T>::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 <typename T, typename... Ts> 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 <typename U, typename V>
|
||||
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<std::is_unsigned_v<T>, T> SaturatingAdd(T X, T Y, T Z,
|
||||
@@ -626,7 +626,7 @@ std::enable_if_t<std::is_unsigned_v<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<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
|
||||
@@ -772,9 +772,9 @@ std::enable_if_t<std::is_signed_v<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)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:13:55 -0400
|
||||
Subject: [PATCH 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<std::disjunction<
|
||||
@@ -74,7 +74,7 @@ using EnableIfCallable = std::enable_if_t<std::disjunction<
|
||||
|
||||
template <typename ReturnT, typename... ParamTs> 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 <typename T, class = void>
|
||||
@@ -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
|
||||
@@ -1,10 +1,10 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:17:19 -0400
|
||||
Subject: [PATCH 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");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:28:13 -0400
|
||||
Subject: [PATCH 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
|
||||
|
||||
@@ -1,20 +1,69 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:37:34 -0400
|
||||
Subject: [PATCH 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 <initializer_list>
|
||||
#include <iterator>
|
||||
#include <new>
|
||||
+#include <ranges>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
@@ -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<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
|
||||
@@ -287,7 +287,7 @@ template <typename T, unsigned LN, unsigned RN, typename C>
|
||||
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 <algorithm>
|
||||
@@ -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 <string>
|
||||
|
||||
using namespace llvm;
|
||||
@@ -180,7 +180,7 @@ TEST(SmallSetTest, IteratorInt) {
|
||||
@@ -186,7 +186,7 @@ TEST(SmallSetTest, IteratorInt) {
|
||||
|
||||
std::vector<int> 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<std::string> 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.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sat, 7 May 2022 22:53:50 -0400
|
||||
Subject: [PATCH 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 <chrono>
|
||||
#include <ctime>
|
||||
@@ -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<sys::TimePoint<>> {
|
||||
- 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<sys::UtcTime<std::chrono::seconds>> {
|
||||
- static void format(const sys::UtcTime<std::chrono::seconds> &TP,
|
||||
- llvm::raw_ostream &OS, StringRef Style);
|
||||
- LLVM_ABI static void format(const sys::UtcTime<std::chrono::seconds> &TP,
|
||||
- llvm::raw_ostream &OS, std::string_view Style);
|
||||
-};
|
||||
-
|
||||
-namespace detail {
|
||||
-template <typename Period> struct unit { static const char value[]; };
|
||||
-template <typename Period> const char unit<Period>::value[] = "";
|
||||
-
|
||||
-template <> struct unit<std::ratio<3600>> { static const char value[]; };
|
||||
-template <> struct unit<std::ratio<60>> { static const char value[]; };
|
||||
-template <> struct unit<std::ratio<1>> { static const char value[]; };
|
||||
-template <> struct unit<std::milli> { static const char value[]; };
|
||||
-template <> struct unit<std::micro> { static const char value[]; };
|
||||
-template <> struct unit<std::nano> { static const char value[]; };
|
||||
-template <> struct unit<std::ratio<3600>> {
|
||||
- LLVM_ABI static const char value[];
|
||||
-};
|
||||
-template <> struct unit<std::ratio<60>> {
|
||||
- LLVM_ABI static const char value[];
|
||||
-};
|
||||
-template <> struct unit<std::ratio<1>> {
|
||||
- LLVM_ABI static const char value[];
|
||||
-};
|
||||
-template <> struct unit<std::milli> {
|
||||
- LLVM_ABI static const char value[];
|
||||
-};
|
||||
-template <> struct unit<std::micro> {
|
||||
- LLVM_ABI static const char value[];
|
||||
-};
|
||||
-template <> struct unit<std::nano> {
|
||||
- LLVM_ABI static const char value[];
|
||||
-};
|
||||
-} // namespace detail
|
||||
-
|
||||
-/// Implementation of format_provider<T> for duration types.
|
||||
@@ -83,10 +95,10 @@ index 9c9ba7002310eba5113c14957f769702c61f4326..b269ff8bb5db7bb3c62c3a87daf255b1
|
||||
-template <typename Rep, typename Period>
|
||||
-struct format_provider<std::chrono::duration<Rep, Period>> {
|
||||
-private:
|
||||
- typedef std::chrono::duration<Rep, Period> Dur;
|
||||
- typedef std::conditional_t<std::chrono::treat_as_floating_point<Rep>::value,
|
||||
- double, intmax_t>
|
||||
- InternalRep;
|
||||
- using Dur = std::chrono::duration<Rep, Period>;
|
||||
- using InternalRep =
|
||||
- std::conditional_t<std::chrono::treat_as_floating_point<Rep>::value,
|
||||
- double, intmax_t>;
|
||||
-
|
||||
- template <typename AsPeriod> 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 {
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 13:34:07 -0400
|
||||
Subject: [PATCH 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 <typename FunctionT> class unique_function;
|
||||
|
||||
@@ -32,8 +32,8 @@ index df7fe3e19462ebecd30f7a9d006027c75751de5b..28a9ba756a4075987fbee28c6ed6387e
|
||||
+
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
@@ -414,6 +421,10 @@ public:
|
||||
template <typename CallableT, typename ThisT>
|
||||
@@ -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<unsigned int, unsigned int>.
|
||||
+// That type is POD, but the standard doesn't guarantee that. GCC doesn't treat
|
||||
+// the type as POD so it throws a warning. We want to consider this a warning
|
||||
@@ -64,10 +65,10 @@ index 2232b741d5359a129adb0e5b3f0f70110c38e90d..3cab284f5b6105956d6fff49a27d3748
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
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 <span>
|
||||
#include <stdarg.h>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 13:43:50 -0400
|
||||
Subject: [PATCH 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 <typename FailT, typename Fun, typename... Args>
|
||||
inline decltype(auto) RetryAfterSignal(const FailT &Fail, const Fun &F,
|
||||
const Args &... As) {
|
||||
diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h
|
||||
index 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<VersionTuple> {
|
||||
@@ -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<Error(raw_ostream &)> Write);
|
||||
-LLVM_ABI Error writeToOutput(std::string_view OutputFileName,
|
||||
- std::function<Error(raw_ostream &)> Write);
|
||||
-
|
||||
-raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);
|
||||
-LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t);
|
||||
-
|
||||
-template <typename T, typename = decltype(std::declval<raw_ostream &>()
|
||||
- << std::declval<const T &>())>
|
||||
@@ -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 <char C>
|
||||
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() {}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Thu, 5 May 2022 23:18:34 -0400
|
||||
Subject: [PATCH 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<std::is_convertible<
|
||||
@@ -59,19 +59,19 @@ using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible<
|
||||
/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
|
||||
/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
|
||||
/// buffering bitcode output - which can exceed 4GB.
|
||||
@@ -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 <class T, typename = void> struct SmallVectorAlignmentAndSize {
|
||||
@@ -128,8 +123,8 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
|
||||
/// to avoid unnecessarily requiring T to be complete.
|
||||
template <typename T, typename = void>
|
||||
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 <typename T, bool TriviallyCopyable>
|
||||
@@ -455,7 +450,7 @@ template <typename T, bool TriviallyCopyable>
|
||||
T *SmallVectorTemplateBase<T, TriviallyCopyable>::mallocForGrow(
|
||||
size_t MinSize, size_t &NewCapacity) {
|
||||
return static_cast<T *>(
|
||||
@@ -89,8 +89,8 @@ index 3cab284f5b6105956d6fff49a27d37482a3c321d..b8981ab67322f7888ad63d953ba72dbf
|
||||
this->getFirstEl(), MinSize, sizeof(T), NewCapacity));
|
||||
}
|
||||
|
||||
@@ -1320,12 +1315,6 @@ template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
|
||||
return {std::begin(Range), std::end(Range)};
|
||||
@@ -1329,12 +1324,6 @@ template <typename Out, typename R> SmallVector<Out> 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<uint64_t>;
|
||||
-#endif
|
||||
-
|
||||
} // end namespace llvm
|
||||
|
||||
namespace std {
|
||||
// Provide DenseMapInfo for SmallVector of a type which has info.
|
||||
template <typename T, unsigned N> struct DenseMapInfo<llvm::SmallVector<T, N>> {
|
||||
static SmallVector<T, N> 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
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 13:48:59 -0400
|
||||
Subject: [PATCH 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 <string_view>
|
||||
#include <system_error>
|
||||
#include <type_traits>
|
||||
@@ -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<char> &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<uint8_t> &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<uint8_t> &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;
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Thu, 5 May 2022 18:09:45 -0400
|
||||
Subject: [PATCH 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 <typename T, typename U, typename = enableif_int<T, U>>
|
||||
using common_sint =
|
||||
std::common_type_t<std::make_signed_t<T>, std::make_signed_t<U>>;
|
||||
|
||||
-/// 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 <typename T> T maskTrailingOnes(unsigned N) {
|
||||
@@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Thu, 5 May 2022 18:09:45 -0400
|
||||
Subject: [PATCH 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 <typename T, typename U, typename = enableif_int<T, U>>
|
||||
using common_sint =
|
||||
std::common_type_t<std::make_signed_t<T>, std::make_signed_t<U>>;
|
||||
|
||||
-/// Mathematical constants.
|
||||
-namespace numbers {
|
||||
-// clang-format off
|
||||
-inline constexpr float ef = e_v<float>;
|
||||
-inline constexpr float egammaf = egamma_v<float>;
|
||||
-inline constexpr float ln2f = ln2_v<float>;
|
||||
-inline constexpr float ln10f = ln10_v<float>;
|
||||
-inline constexpr float log2ef = log2e_v<float>;
|
||||
-inline constexpr float log10ef = log10e_v<float>;
|
||||
-inline constexpr float pif = pi_v<float>;
|
||||
-inline constexpr float inv_pif = inv_pi_v<float>;
|
||||
-inline constexpr float inv_sqrtpif = inv_sqrtpi_v<float>;
|
||||
-inline constexpr float sqrt2f = sqrt2_v<float>;
|
||||
-inline constexpr float inv_sqrt2f = inv_sqrt2_v<float>;
|
||||
-inline constexpr float sqrt3f = sqrt3_v<float>;
|
||||
-inline constexpr float inv_sqrt3f = inv_sqrt3_v<float>;
|
||||
-inline constexpr float phif = phi_v<float>;
|
||||
-
|
||||
-// sqrtpi is not in C++20 std::numbers.
|
||||
-template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
-inline constexpr T sqrtpi_v = T(0x1.c5bf891b4ef6bP+0); // (1.7724538509055160273) https://oeis.org/A002161
|
||||
-inline constexpr double sqrtpi = sqrtpi_v<double>;
|
||||
-inline constexpr float sqrtpif = sqrtpi_v<float>;
|
||||
-
|
||||
-// 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 <typename T> constexpr T maskTrailingOnes(unsigned N) {
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Tue, 3 May 2022 22:50:24 -0400
|
||||
Subject: [PATCH 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 16:38:11 -0400
|
||||
Subject: [PATCH 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 <cassert>
|
||||
+#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
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 <span>
|
||||
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 <mutex>
|
||||
#include <new>
|
||||
|
||||
@@ -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 <ntstatus.h>
|
||||
#include <winerror.h>
|
||||
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 @@
|
||||
// <fcntl.h> may provide O_BINARY.
|
||||
# include <fcntl.h>
|
||||
|
||||
@@ -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 <array>
|
||||
#include <list>
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 16:42:09 -0400
|
||||
Subject: [PATCH 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 <typename T>
|
||||
-struct is_copy_assignable {
|
||||
- template<class F>
|
||||
- static auto get(F*) -> decltype(std::declval<F &>() = std::declval<const F &>(), std::true_type{});
|
||||
- static std::false_type get(...);
|
||||
- static constexpr bool value = decltype(get((T*)nullptr))::value;
|
||||
-};
|
||||
-
|
||||
-template <typename T>
|
||||
-struct is_move_assignable {
|
||||
- template<class F>
|
||||
- static auto get(F*) -> decltype(std::declval<F &>() = std::declval<F &&>(), std::true_type{});
|
||||
- static std::false_type get(...);
|
||||
- static constexpr bool value = decltype(get((T*)nullptr))::value;
|
||||
-};
|
||||
-
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_SUPPORT_TYPE_TRAITS_H
|
||||
@@ -1,16 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Tue, 3 May 2022 20:22:38 -0400
|
||||
Subject: [PATCH 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<const char *> &Args,
|
||||
- BumpPtrAllocator &Alloc);
|
||||
-LLVM_ABI std::error_code
|
||||
-GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
|
||||
- BumpPtrAllocator &Alloc);
|
||||
-
|
||||
-/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
|
||||
-/// File API.
|
||||
-std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
|
||||
- size_t MaxPathLen = MAX_PATH);
|
||||
-LLVM_ABI std::error_code widenPath(const Twine &Path8,
|
||||
- SmallVectorImpl<wchar_t> &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<char> &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)) {
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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 <ntstatus.h>
|
||||
#include <winerror.h>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 16:46:20 -0400
|
||||
Subject: [PATCH 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 <cassert>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
@@ -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)
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 16:49:36 -0400
|
||||
Subject: [PATCH 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 <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 19:16:51 -0400
|
||||
Subject: [PATCH 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 <tuple>
|
||||
|
||||
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) {
|
||||
@@ -1,47 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Mon, 9 May 2022 00:04:30 -0400
|
||||
Subject: [PATCH 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<char> &Result);
|
||||
|
||||
LLVM_ABI bool convertWideToUTF8(const std::wstring &Source,
|
||||
- std::string &Result);
|
||||
+ SmallVectorImpl<char> &Result);
|
||||
|
||||
/**
|
||||
@@ -288,7 +288,7 @@ bool hasUTF16ByteOrderMark(span<const char> 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<const char> SrcBytes);
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out);
|
||||
+bool convertUTF16ToUTF8String(span<const char> SrcBytes, SmallVectorImpl<char> &Out);
|
||||
LLVM_ABI bool convertUTF16ToUTF8String(span<const char> SrcBytes,
|
||||
- std::string &Out);
|
||||
+ SmallVectorImpl<char> &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF16 string into a UTF8 std::string.
|
||||
@@ -297,7 +297,7 @@ bool convertUTF16ToUTF8String(span<const char> SrcBytes, std::string &Out);
|
||||
@@ -311,7 +311,8 @@ LLVM_ABI bool convertUTF16ToUTF8String(span<const char> SrcBytes,
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
-bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out);
|
||||
+bool convertUTF16ToUTF8String(span<const UTF16> Src, SmallVectorImpl<char> &Out);
|
||||
-LLVM_ABI bool convertUTF16ToUTF8String(span<const UTF16> Src, std::string &Out);
|
||||
+LLVM_ABI bool convertUTF16ToUTF8String(span<const UTF16> Src,
|
||||
+ SmallVectorImpl<char> &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<const char> S) {
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Sun, 8 May 2022 19:30:43 -0400
|
||||
Subject: [PATCH 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();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
Date: Thu, 19 May 2022 00:58:36 -0400
|
||||
Subject: [PATCH 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);
|
||||
@@ -1,20 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: PJ Reiniger <pj.reiniger@gmail.com>
|
||||
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 <typename value_type>
|
||||
/// Swap the bytes of value to match the given endianness.
|
||||
template <typename value_type, endianness endian>
|
||||
[[nodiscard]] inline value_type byte_swap(value_type value) {
|
||||
@@ -52,7 +52,9 @@ template <typename value_type, endianness endian>
|
||||
[[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);
|
||||
@@ -1,14 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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 @@
|
||||
@@ -1,22 +1,22 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Leander Schulten <Leander.Schulten@rwth-aachen.de>
|
||||
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)) {
|
||||
@@ -1,19 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
Date: Tue, 11 Jul 2023 22:56:09 -0700
|
||||
Subject: [PATCH 27/36] Use C++20 <bit> header
|
||||
Subject: [PATCH 25/33] Use C++20 <bit> 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 <algorithm>
|
||||
@@ -21,26 +23,61 @@ index 69ce7982d732887642c7f46163b753ee17be9b30..927a9c72ec939d268ae7463f7113f051
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
@@ -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 <typename... Ts> 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<PtrType> {
|
||||
using BaseT = SmallPtrSetImpl<PtrType>;
|
||||
|
||||
// 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 <cstdlib> // 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 <endian.h>
|
||||
-#elif defined(_AIX)
|
||||
-#include <sys/machine.h>
|
||||
@@ -79,7 +116,7 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59
|
||||
namespace llvm {
|
||||
|
||||
enum class endianness {
|
||||
@@ -142,281 +104,6 @@ template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
@@ -143,254 +105,6 @@ template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,67 +125,53 @@ index c42b5e686bdc9cf3da71d8edaddc08216fe5fb2a..a19b6a9b80da2965f1308d3e7b0ade59
|
||||
- return (Value != 0) && ((Value & (Value - 1)) == 0);
|
||||
-}
|
||||
-
|
||||
-namespace detail {
|
||||
-template <typename T, std::size_t SizeOfT> struct TrailingZerosCounter {
|
||||
- static unsigned count(T Val) {
|
||||
- if (!Val)
|
||||
- return std::numeric_limits<T>::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 <typename T> [[nodiscard]] constexpr int popcount(T Value) noexcept {
|
||||
- static_assert(std::is_unsigned_v<T>, "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<T>::digits >> 1;
|
||||
- T Mask = std::numeric_limits<T>::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 <typename T> struct TrailingZerosCounter<T, 4> {
|
||||
- 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 <typename T> struct TrailingZerosCounter<T, 8> {
|
||||
- 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<T>::digits on an input of 0.
|
||||
-template <typename T> [[nodiscard]] constexpr int countr_zero_constexpr(T Val) {
|
||||
- static_assert(std::is_unsigned_v<T>,
|
||||
- "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<std::make_unsigned_t<T>>((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 <typename T> [[nodiscard]] int countr_zero(T Val) {
|
||||
- static_assert(std::is_unsigned_v<T>,
|
||||
- "Only unsigned integral types are allowed.");
|
||||
- return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val);
|
||||
- if (!Val)
|
||||
- return std::numeric_limits<T>::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 <typename T, std::size_t SizeOfT> struct LeadingZerosCounter {
|
||||
- static unsigned count(T Val) {
|
||||
- if (!Val)
|
||||
- return std::numeric_limits<T>::digits;
|
||||
-
|
||||
- // Bisection method.
|
||||
- unsigned ZeroBits = 0;
|
||||
- for (T Shift = std::numeric_limits<T>::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 <typename T> struct LeadingZerosCounter<T, 4> {
|
||||
- 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 <typename T> struct LeadingZerosCounter<T, 8> {
|
||||
- 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 <typename T> [[nodiscard]] int countl_zero(T Val) {
|
||||
- static_assert(std::is_unsigned_v<T>,
|
||||
- "Only unsigned integral types are allowed.");
|
||||
- return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val);
|
||||
- if (!Val)
|
||||
- return std::numeric_limits<T>::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<T>::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<T>::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 <typename T> [[nodiscard]] constexpr int bit_width_constexpr(T Value) {
|
||||
- static_assert(std::is_unsigned_v<T>,
|
||||
- "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<T>(Value - 1u);
|
||||
-}
|
||||
-
|
||||
-namespace detail {
|
||||
-template <typename T, std::size_t SizeOfT> 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 <typename T> struct PopulationCounter<T, 8> {
|
||||
- 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 <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
-[[nodiscard]] inline int popcount(T Value) noexcept {
|
||||
- return detail::PopulationCounter<T, sizeof(T)>::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 <typename T> [[nodiscard]] constexpr T bit_ceil_constexpr(T Value) {
|
||||
- static_assert(std::is_unsigned_v<T>,
|
||||
- "Only unsigned integral types are allowed.");
|
||||
- if (Value < 2)
|
||||
- return 1;
|
||||
- return T(1) << llvm::bit_width_constexpr<T>(Value - 1u);
|
||||
-}
|
||||
-
|
||||
-// Forward-declare rotr so that rotl can use it.
|
||||
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
-[[nodiscard]] constexpr T rotr(T V, int R);
|
||||
-
|
||||
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
-[[nodiscard]] constexpr T rotl(T V, int R) {
|
||||
- unsigned N = std::numeric_limits<T>::digits;
|
||||
- constexpr unsigned N = std::numeric_limits<T>::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 <typename T, typename> [[nodiscard]] constexpr T rotr(T V, int R) {
|
||||
- unsigned N = std::numeric_limits<T>::digits;
|
||||
-template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
|
||||
-[[nodiscard]] constexpr T rotr(T V, int R) {
|
||||
- constexpr unsigned N = std::numeric_limits<T>::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 <bit>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
@@ -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 <size_t kValue> 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 <size_t kValue>
|
||||
@@ -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) {
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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<variant>::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<int *, int>);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Johnson <johnson.peter@gmail.com>
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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)
|
||||
@@ -1,25 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Johnson <johnson.peter@gmail.com>
|
||||
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 <typename T> struct const_pointer_or_const_ref {
|
||||
typename add_const_past_pointer<T>::type, const T &>;
|
||||
};
|
||||
|
||||
+// https://stackoverflow.com/questions/55288555/c-check-if-statement-can-be-evaluated-constexpr
|
||||
+template<class Lambda, int=(Lambda{}(), 0)>
|
||||
+constexpr bool is_constexpr(Lambda) { return true; }
|
||||
+constexpr bool is_constexpr(...) { return false; }
|
||||
+
|
||||
} // end namespace llvm
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_SUPPORT_TYPE_TRAITS_H
|
||||
@@ -1,14 +1,14 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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;
|
||||
@@ -1,19 +1,19 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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 <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
|
||||
return {std::begin(Range), std::end(Range)};
|
||||
}
|
||||
@@ -1344,6 +1344,14 @@ template <typename T, unsigned N> struct DenseMapInfo<llvm::SmallVector<T, N>> {
|
||||
}
|
||||
};
|
||||
|
||||
+template <typename T, typename Pred>
|
||||
+typename SmallVectorImpl<T>::size_type erase_if(
|
||||
@@ -1,29 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: crueter <crueter@eden-emu.dev>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Veness <calcmogul@gmail.com>
|
||||
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 <type_traits>
|
||||
+#include <algorithm>
|
||||
+#include <cstddef>
|
||||
|
||||
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 <typename T, typename... Ts> struct AlignedCharArrayUnion {
|
||||
- using AlignedUnion = std::aligned_union_t<1, T, Ts...>;
|
||||
- alignas(alignof(AlignedUnion)) char buffer[sizeof(AlignedUnion)];
|
||||
+template <typename... Ts> struct AlignedCharArrayUnion {
|
||||
+ alignas((std::max)({alignof(Ts)...}))
|
||||
+ std::byte buffer[(std::max)({static_cast<size_t>(1), sizeof(Ts)...})];
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
@@ -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\"")
|
||||
|
||||
@@ -305,5 +305,15 @@ bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl<char> &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
|
||||
|
||||
|
||||
@@ -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 <cassert>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<const void**>(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<void**>(FindBucketFor(Elt)) = const_cast<void*>(Elt);
|
||||
if (Bucket != getTombstoneMarker() && Bucket != getEmptyMarker())
|
||||
*const_cast<void **>(FindBucketFor(Bucket)) = const_cast<void *>(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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 <algorithm>
|
||||
#include <cerrno>
|
||||
@@ -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;
|
||||
|
||||
@@ -14,15 +14,16 @@
|
||||
#define WPIUTIL_WPI_ALIGNOF_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
/// A suitably aligned and sized character array member which can hold elements
|
||||
/// of any type.
|
||||
template <typename... Ts> struct AlignedCharArrayUnion {
|
||||
alignas((std::max)({alignof(Ts)...}))
|
||||
std::byte buffer[(std::max)({static_cast<size_t>(1), sizeof(Ts)...})];
|
||||
template <typename T, typename... Ts> 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
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include "wpi/util/MemAlloc.hpp"
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
@@ -111,7 +112,7 @@ template <typename Alloc> class AllocatorHolder : Alloc {
|
||||
public:
|
||||
AllocatorHolder() = default;
|
||||
AllocatorHolder(const Alloc &A) : Alloc(A) {}
|
||||
AllocatorHolder(Alloc &&A) : Alloc(static_cast<Alloc &&>(A)) {}
|
||||
AllocatorHolder(Alloc &&A) : Alloc(std::move(A)) {}
|
||||
Alloc &getAllocator() { return *this; }
|
||||
const Alloc &getAllocator() const { return *this; }
|
||||
};
|
||||
|
||||
@@ -340,7 +340,7 @@ struct ValueFromPointerCast
|
||||
/// during the cast. It's also a good example of how to implement a move-only
|
||||
/// cast.
|
||||
template <typename To, typename From, typename Derived = void>
|
||||
struct UniquePtrCast : public CastIsPossible<To, From *> {
|
||||
struct UniquePtrCast : CastIsPossible<To, From *> {
|
||||
using Self = detail::SelfType<Derived, UniquePtrCast<To, From>>;
|
||||
using CastResultType = std::unique_ptr<
|
||||
std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
|
||||
@@ -473,7 +473,7 @@ struct ForwardToPointerCast {
|
||||
// take advantage of the cast traits whenever possible!
|
||||
|
||||
template <typename To, typename From, typename Enable = void>
|
||||
struct CastInfo : public CastIsPossible<To, From> {
|
||||
struct CastInfo : CastIsPossible<To, From> {
|
||||
using Self = CastInfo<To, From, Enable>;
|
||||
|
||||
using CastReturnType = typename cast_retty<To, From>::ret_type;
|
||||
@@ -536,22 +536,16 @@ struct CastInfo<To, std::unique_ptr<From>> : public UniquePtrCast<To, From> {};
|
||||
/// the input is std::optional<From> that the output can be std::optional<To>.
|
||||
/// If that's not the case, specialize CastInfo for your use case.
|
||||
template <typename To, typename From>
|
||||
struct CastInfo<To, std::optional<From>> : public OptionalValueCast<To, From> {
|
||||
};
|
||||
struct CastInfo<To, std::optional<From>> : OptionalValueCast<To, From> {};
|
||||
|
||||
/// isa<X> - Return true if the parameter to the template is an instance of one
|
||||
/// of the template type arguments. Used like this:
|
||||
///
|
||||
/// if (isa<Type>(myVal)) { ... }
|
||||
/// if (isa<Type0, Type1, Type2>(myVal)) { ... }
|
||||
template <typename To, typename From>
|
||||
template <typename... To, typename From>
|
||||
[[nodiscard]] inline bool isa(const From &Val) {
|
||||
return CastInfo<To, const From>::isPossible(Val);
|
||||
}
|
||||
|
||||
template <typename First, typename Second, typename... Rest, typename From>
|
||||
[[nodiscard]] inline bool isa(const From &Val) {
|
||||
return isa<First>(Val) || isa<Second, Rest...>(Val);
|
||||
return (CastInfo<To, const From>::isPossible(Val) || ...);
|
||||
}
|
||||
|
||||
/// cast<X> - Return the argument parameter cast to the specified type. This
|
||||
@@ -822,6 +816,42 @@ template <typename... Types> struct IsaAndPresentCheckPredicate {
|
||||
return isa_and_present<Types...>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Casting Function Objects
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Usable in generic algorithms like map_range
|
||||
template <typename U> struct StaticCastFunc {
|
||||
template <typename T> decltype(auto) operator()(T &&Val) const {
|
||||
return static_cast<U>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U> struct DynCastFunc {
|
||||
template <typename T> decltype(auto) operator()(T &&Val) const {
|
||||
return dyn_cast<U>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U> struct CastFunc {
|
||||
template <typename T> decltype(auto) operator()(T &&Val) const {
|
||||
return cast<U>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U> struct CastIfPresentFunc {
|
||||
template <typename T> decltype(auto) operator()(T &&Val) const {
|
||||
return cast_if_present<U>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename U> struct DynCastIfPresentFunc {
|
||||
template <typename T> decltype(auto) operator()(T &&Val) const {
|
||||
return dyn_cast_if_present<U>(Val);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Function object wrapper for the `wpi::util::isa` type check. The function call
|
||||
@@ -847,6 +877,20 @@ template <typename... Types>
|
||||
inline constexpr detail::IsaAndPresentCheckPredicate<Types...>
|
||||
IsaAndPresentPred{};
|
||||
|
||||
/// Function objects corresponding to the Cast types defined above.
|
||||
template <typename To>
|
||||
inline constexpr detail::StaticCastFunc<To> StaticCastTo{};
|
||||
|
||||
template <typename To> inline constexpr detail::CastFunc<To> CastTo{};
|
||||
|
||||
template <typename To>
|
||||
inline constexpr detail::CastIfPresentFunc<To> CastIfPresentTo{};
|
||||
|
||||
template <typename To>
|
||||
inline constexpr detail::DynCastIfPresentFunc<To> DynCastIfPresentTo{};
|
||||
|
||||
template <typename To> inline constexpr detail::DynCastFunc<To> DynCastTo{};
|
||||
|
||||
} // end namespace wpi::util
|
||||
|
||||
#endif // WPIUTIL_WPI_CASTING_H
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <cstddef>
|
||||
#include <string>
|
||||
#include <span>
|
||||
@@ -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 <typename T> 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<char> &Result);
|
||||
|
||||
LLVM_ABI bool convertWideToUTF8(const std::wstring &Source,
|
||||
SmallVectorImpl<char> &Result);
|
||||
|
||||
/**
|
||||
* Convert an Unicode code point to UTF8 sequence.
|
||||
@@ -246,7 +259,7 @@ bool convertWideToUTF8(const std::wstring &Source, SmallVectorImpl<char> &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<const char> SrcBytes);
|
||||
LLVM_ABI bool hasUTF16ByteOrderMark(std::span<const char> SrcBytes);
|
||||
|
||||
/**
|
||||
* Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string.
|
||||
@@ -288,7 +301,8 @@ bool hasUTF16ByteOrderMark(std::span<const char> SrcBytes);
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
bool convertUTF16ToUTF8String(std::span<const char> SrcBytes, SmallVectorImpl<char> &Out);
|
||||
LLVM_ABI bool convertUTF16ToUTF8String(std::span<const char> SrcBytes,
|
||||
SmallVectorImpl<char> &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF16 string into a UTF8 std::string.
|
||||
@@ -297,7 +311,8 @@ bool convertUTF16ToUTF8String(std::span<const char> SrcBytes, SmallVectorImpl<ch
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
bool convertUTF16ToUTF8String(std::span<const UTF16> Src, SmallVectorImpl<char> &Out);
|
||||
LLVM_ABI bool convertUTF16ToUTF8String(std::span<const UTF16> Src,
|
||||
SmallVectorImpl<char> &Out);
|
||||
|
||||
/**
|
||||
* Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string.
|
||||
@@ -306,7 +321,8 @@ bool convertUTF16ToUTF8String(std::span<const UTF16> Src, SmallVectorImpl<char>
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
bool convertUTF32ToUTF8String(std::span<const char> SrcBytes, std::string &Out);
|
||||
LLVM_ABI bool convertUTF32ToUTF8String(std::span<const char> SrcBytes,
|
||||
std::string &Out);
|
||||
|
||||
/**
|
||||
* Converts a UTF32 string into a UTF8 std::string.
|
||||
@@ -315,27 +331,33 @@ bool convertUTF32ToUTF8String(std::span<const char> SrcBytes, std::string &Out);
|
||||
* \param [out] Out Converted UTF-8 is stored here on success.
|
||||
* \returns true on success
|
||||
*/
|
||||
bool convertUTF32ToUTF8String(std::span<const UTF32> Src, std::string &Out);
|
||||
LLVM_ABI bool convertUTF32ToUTF8String(std::span<const UTF32> 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<UTF16> &DstUTF16);
|
||||
LLVM_ABI bool convertUTF8ToUTF16String(std::string_view SrcUTF8,
|
||||
SmallVectorImpl<UTF16> &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<wchar_t> &utf16);
|
||||
LLVM_ABI std::error_code UTF8ToUTF16(std::string_view utf8,
|
||||
SmallVectorImpl<wchar_t> &utf16);
|
||||
/// Convert to UTF16 from the current code page used in the system
|
||||
std::error_code CurCPToUTF16(std::string_view utf8, SmallVectorImpl<wchar_t> &utf16);
|
||||
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
LLVM_ABI std::error_code CurCPToUTF16(std::string_view utf8,
|
||||
SmallVectorImpl<wchar_t> &utf16);
|
||||
LLVM_ABI std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
/// Convert from UTF16 to the current code page used in the system
|
||||
std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
LLVM_ABI std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
|
||||
SmallVectorImpl<char> &utf8);
|
||||
} // namespace windows
|
||||
} // namespace sys
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,8 @@
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -50,10 +52,10 @@ inline unsigned combineHashValue(unsigned a, unsigned b) {
|
||||
/// just be `void`.
|
||||
template<typename T, typename Enable = void>
|
||||
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<T*> {
|
||||
// "Log2MaxAlign bits of alignment");
|
||||
static constexpr uintptr_t Log2MaxAlign = 12;
|
||||
|
||||
static inline T* getEmptyKey() {
|
||||
static constexpr T *getEmptyKey() {
|
||||
uintptr_t Val = static_cast<uintptr_t>(-1);
|
||||
Val <<= Log2MaxAlign;
|
||||
return reinterpret_cast<T*>(Val);
|
||||
}
|
||||
|
||||
static inline T* getTombstoneKey() {
|
||||
static constexpr T *getTombstoneKey() {
|
||||
uintptr_t Val = static_cast<uintptr_t>(-2);
|
||||
Val <<= Log2MaxAlign;
|
||||
return reinterpret_cast<T*>(Val);
|
||||
@@ -91,8 +93,8 @@ struct DenseMapInfo<T*> {
|
||||
|
||||
// Provide DenseMapInfo for chars.
|
||||
template<> struct DenseMapInfo<char> {
|
||||
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<char> {
|
||||
}
|
||||
};
|
||||
|
||||
// Provide DenseMapInfo for unsigned chars.
|
||||
template <> struct DenseMapInfo<unsigned char> {
|
||||
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<T, char>" is included below
|
||||
// for clarity; technically, we do not need it because the explicit
|
||||
// specialization above "wins",
|
||||
template <typename T>
|
||||
struct DenseMapInfo<
|
||||
T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<T, char>>> {
|
||||
static constexpr T getEmptyKey() { return (std::numeric_limits<T>::max)(); }
|
||||
|
||||
static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
// Provide DenseMapInfo for unsigned shorts.
|
||||
template <> struct DenseMapInfo<unsigned short> {
|
||||
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<unsigned> {
|
||||
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<unsigned long> {
|
||||
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<unsigned>::getHashValue(Val);
|
||||
static constexpr T getTombstoneKey() {
|
||||
if constexpr (std::is_unsigned_v<T> || std::is_same_v<T, long>)
|
||||
return (std::numeric_limits<T>::max)() - 1;
|
||||
else
|
||||
return (std::numeric_limits<T>::min)();
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const T &Val) {
|
||||
if constexpr (std::is_unsigned_v<T> && sizeof(T) > sizeof(unsigned))
|
||||
return densemap::detail::mix(Val);
|
||||
else
|
||||
return static_cast<unsigned>(Val *
|
||||
static_cast<std::make_unsigned_t<T>>(37U));
|
||||
}
|
||||
|
||||
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
// Provide DenseMapInfo for unsigned long longs.
|
||||
template<> struct DenseMapInfo<unsigned long long> {
|
||||
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<short> {
|
||||
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<int> {
|
||||
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<long> {
|
||||
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<long long> {
|
||||
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<std::pair<T, U>> {
|
||||
using FirstInfo = DenseMapInfo<T>;
|
||||
using SecondInfo = DenseMapInfo<U>;
|
||||
|
||||
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<std::pair<T, U>> {
|
||||
template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
|
||||
using Tuple = std::tuple<Ts...>;
|
||||
|
||||
static inline Tuple getEmptyKey() {
|
||||
static constexpr Tuple getEmptyKey() {
|
||||
return Tuple(DenseMapInfo<Ts>::getEmptyKey()...);
|
||||
}
|
||||
|
||||
static inline Tuple getTombstoneKey() {
|
||||
static constexpr Tuple getTombstoneKey() {
|
||||
return Tuple(DenseMapInfo<Ts>::getTombstoneKey()...);
|
||||
}
|
||||
|
||||
template <unsigned I>
|
||||
static unsigned getHashValueImpl(const Tuple &values, std::false_type) {
|
||||
using EltType = std::tuple_element_t<I, Tuple>;
|
||||
std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
|
||||
return detail::combineHashValue(
|
||||
DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
|
||||
getHashValueImpl<I + 1>(values, atEnd));
|
||||
}
|
||||
|
||||
template <unsigned I>
|
||||
static unsigned getHashValueImpl(const Tuple &, std::true_type) {
|
||||
return 0;
|
||||
template <unsigned I> static unsigned getHashValueImpl(const Tuple &values) {
|
||||
if constexpr (I == sizeof...(Ts)) {
|
||||
return 0;
|
||||
} else {
|
||||
using EltType = std::tuple_element_t<I, Tuple>;
|
||||
return detail::combineHashValue(
|
||||
DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
|
||||
getHashValueImpl<I + 1>(values));
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const std::tuple<Ts...> &values) {
|
||||
std::integral_constant<bool, 0 == sizeof...(Ts)> atEnd;
|
||||
return getHashValueImpl<0>(values, atEnd);
|
||||
return getHashValueImpl<0>(values);
|
||||
}
|
||||
|
||||
template <unsigned I>
|
||||
static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) {
|
||||
using EltType = std::tuple_element_t<I, Tuple>;
|
||||
std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
|
||||
return DenseMapInfo<EltType>::isEqual(std::get<I>(lhs), std::get<I>(rhs)) &&
|
||||
isEqualImpl<I + 1>(lhs, rhs, atEnd);
|
||||
}
|
||||
|
||||
template <unsigned I>
|
||||
static bool isEqualImpl(const Tuple &, const Tuple &, std::true_type) {
|
||||
return true;
|
||||
template <std::size_t... Is>
|
||||
static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs,
|
||||
std::index_sequence<Is...>) {
|
||||
return (DenseMapInfo<std::tuple_element_t<Is, Tuple>>::isEqual(
|
||||
std::get<Is>(lhs), std::get<Is>(rhs)) &&
|
||||
...);
|
||||
}
|
||||
|
||||
static bool isEqual(const Tuple &lhs, const Tuple &rhs) {
|
||||
std::integral_constant<bool, 0 == sizeof...(Ts)> atEnd;
|
||||
return isEqualImpl<0>(lhs, rhs, atEnd);
|
||||
return isEqualImpl(lhs, rhs, std::index_sequence_for<Ts...>{});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -308,10 +211,22 @@ struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
|
||||
using UnderlyingType = std::underlying_type_t<Enum>;
|
||||
using Info = DenseMapInfo<UnderlyingType>;
|
||||
|
||||
static Enum getEmptyKey() { return static_cast<Enum>(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<Enum>(Info::getTombstoneKey());
|
||||
static constexpr Enum getEmptyKey() {
|
||||
constexpr Enum V = static_cast<Enum>(Info::getEmptyKey());
|
||||
return V;
|
||||
}
|
||||
|
||||
static constexpr Enum getTombstoneKey() {
|
||||
constexpr Enum V = static_cast<Enum>(Info::getTombstoneKey());
|
||||
return V;
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const Enum &Val) {
|
||||
@@ -320,6 +235,30 @@ struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
|
||||
|
||||
static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; }
|
||||
};
|
||||
|
||||
template <typename T> struct DenseMapInfo<std::optional<T>> {
|
||||
using Optional = std::optional<T>;
|
||||
using Info = DenseMapInfo<T>;
|
||||
|
||||
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
|
||||
|
||||
@@ -49,7 +49,9 @@ template <typename value_type>
|
||||
|
||||
/// Swap the bytes of value to match the given endianness.
|
||||
template <typename value_type, endianness endian>
|
||||
[[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 <typename value_type, std::size_t alignment = unaligned>
|
||||
}
|
||||
|
||||
template <typename value_type, endianness endian, std::size_t alignment>
|
||||
[[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<value_type, alignment>(memory, endian);
|
||||
}
|
||||
|
||||
@@ -98,9 +102,8 @@ inline void write(void *memory, value_type value, endianness endian) {
|
||||
&value, sizeof(value_type));
|
||||
}
|
||||
|
||||
template<typename value_type,
|
||||
endianness endian,
|
||||
std::size_t alignment>
|
||||
template <typename value_type, endianness endian, std::size_t alignment>
|
||||
LLVM_DEPRECATED("Pass endian as a function argument instead", "write")
|
||||
inline void write(void *memory, value_type value) {
|
||||
write<value_type, alignment>(memory, value, endian);
|
||||
}
|
||||
@@ -130,7 +133,7 @@ template <typename value_type, endianness endian, std::size_t alignment>
|
||||
uint64_t startBit) {
|
||||
assert(startBit < 8);
|
||||
if (startBit == 0)
|
||||
return read<value_type, endian, alignment>(memory);
|
||||
return read<value_type, alignment>(memory, endian);
|
||||
else {
|
||||
// Read two values and compose the result from them.
|
||||
value_type val[2];
|
||||
@@ -138,8 +141,8 @@ template <typename value_type, endianness endian, std::size_t alignment>
|
||||
LLVM_ASSUME_ALIGNED(
|
||||
memory, (detail::PickAlignment<value_type, alignment>::value)),
|
||||
sizeof(value_type) * 2);
|
||||
val[0] = byte_swap<value_type, endian>(val[0]);
|
||||
val[1] = byte_swap<value_type, endian>(val[1]);
|
||||
val[0] = byte_swap<value_type>(val[0], endian);
|
||||
val[1] = byte_swap<value_type>(val[1], endian);
|
||||
|
||||
// Shift bits from the lower value into place.
|
||||
make_unsigned_t<value_type> 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<value_type, endian, alignment>(memory, value);
|
||||
write<value_type, alignment>(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_type, alignment>::value)),
|
||||
sizeof(value_type) * 2);
|
||||
val[0] = byte_swap<value_type, endian>(val[0]);
|
||||
val[1] = byte_swap<value_type, endian>(val[1]);
|
||||
val[0] = byte_swap<value_type>(val[0], endian);
|
||||
val[1] = byte_swap<value_type>(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<value_type, endian>(val[0]);
|
||||
val[1] = byte_swap<value_type, endian>(val[1]);
|
||||
val[0] = byte_swap<value_type>(val[0], endian);
|
||||
val[1] = byte_swap<value_type>(val[1], endian);
|
||||
memcpy(LLVM_ASSUME_ALIGNED(
|
||||
memory, (detail::PickAlignment<value_type, alignment>::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<value_type, endian, alignment>(
|
||||
(const void*)Value.buffer);
|
||||
value_type value() const {
|
||||
return endian::read<value_type, alignment>((const void *)Value.buffer,
|
||||
endian);
|
||||
}
|
||||
operator value_type() const { return value(); }
|
||||
|
||||
void operator=(value_type newValue) {
|
||||
endian::write<value_type, endian, alignment>(
|
||||
(void*)Value.buffer, newValue);
|
||||
endian::write<value_type, alignment>((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<value_type, endian, alignment>(Ptr);
|
||||
return endian::read<value_type, alignment>(Ptr, endian);
|
||||
}
|
||||
|
||||
void operator=(value_type NewValue) {
|
||||
endian::write<value_type, endian, alignment>(Ptr, NewValue);
|
||||
endian::write<value_type, alignment>(Ptr, NewValue, endian);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -279,6 +283,9 @@ public:
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
using ulittle8_t =
|
||||
detail::packed_endian_specific_integral<uint8_t, wpi::util::endianness::little,
|
||||
unaligned>;
|
||||
using ulittle16_t =
|
||||
detail::packed_endian_specific_integral<uint16_t, wpi::util::endianness::little,
|
||||
unaligned>;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef WPIUTIL_WPI_ERRNO_H
|
||||
#define WPIUTIL_WPI_ERRNO_H
|
||||
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <cerrno>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "wpi/util/MemAlloc.hpp"
|
||||
#include "wpi/util/type_traits.hpp"
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace wpi::util {
|
||||
@@ -65,10 +64,6 @@ template <typename FunctionT> class unique_function;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
using EnableIfTrivial =
|
||||
std::enable_if_t<std::is_trivially_move_constructible<T>::value &&
|
||||
std::is_trivially_destructible<T>::value>;
|
||||
template <typename CallableT, typename ThisT>
|
||||
using EnableUnlessSameType =
|
||||
std::enable_if_t<!std::is_same<remove_cvref_t<CallableT>, ThisT>::value>;
|
||||
@@ -89,13 +84,6 @@ protected:
|
||||
static constexpr size_t InlineStorageSize = sizeof(void *) * 4;
|
||||
static constexpr size_t InlineStorageAlign = alignof(void *);
|
||||
|
||||
template <typename T, class = void>
|
||||
struct IsSizeLessThanThresholdT : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct IsSizeLessThanThresholdT<
|
||||
T, std::enable_if_t<sizeof(T) <= 2 * sizeof(void *)>> : 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 <typename T> struct AdjustedParamTBase {
|
||||
static_assert(!std::is_reference<T>::value,
|
||||
"references should be handled by template specialization");
|
||||
static constexpr bool IsSizeLessThanThreshold =
|
||||
sizeof(T) <= 2 * sizeof(void *);
|
||||
using type =
|
||||
std::conditional_t<std::is_trivially_copy_constructible<T>::value &&
|
||||
std::is_trivially_move_constructible<T>::value &&
|
||||
IsSizeLessThanThresholdT<T>::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 <typename CallableT, typename CalledAs, typename Enable = void>
|
||||
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 <typename CallableT, typename CalledAs>
|
||||
struct CallbacksHolder<CallableT, CalledAs, EnableIfTrivial<CallableT>> {
|
||||
static TrivialCallback Callbacks;
|
||||
template <typename CallableT, typename CalledAs> 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<CallableT> &&
|
||||
std::is_trivially_destructible_v<CallableT>)
|
||||
return TrivialCallback{&CallImpl<CalledAs>};
|
||||
else
|
||||
return NonTrivialCallbacks{&CallImpl<CalledAs>, &MoveImpl<CallableT>,
|
||||
&DestroyImpl<CallableT>};
|
||||
}();
|
||||
};
|
||||
|
||||
// A simple tag type so the call-as type to be passed to the constructor.
|
||||
@@ -355,19 +345,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename R, typename... P>
|
||||
template <typename CallableT, typename CalledAsT, typename Enable>
|
||||
typename UniqueFunctionBase<R, P...>::NonTrivialCallbacks UniqueFunctionBase<
|
||||
R, P...>::CallbacksHolder<CallableT, CalledAsT, Enable>::Callbacks = {
|
||||
&CallImpl<CalledAsT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
|
||||
|
||||
template <typename R, typename... P>
|
||||
template <typename CallableT, typename CalledAsT>
|
||||
typename UniqueFunctionBase<R, P...>::TrivialCallback
|
||||
UniqueFunctionBase<R, P...>::CallbacksHolder<
|
||||
CallableT, CalledAsT, EnableIfTrivial<CallableT>>::Callbacks{
|
||||
&CallImpl<CalledAsT>};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename R, typename... P>
|
||||
|
||||
42
wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/IOSandbox.hpp
vendored
Normal file
42
wpiutil/src/main/native/thirdparty/llvm/include/wpi/util/IOSandbox.hpp
vendored
Normal file
@@ -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<bool> 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
|
||||
@@ -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 <bit>
|
||||
@@ -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 <typename T> T maskTrailingOnes(unsigned N) {
|
||||
template <typename T> constexpr T maskTrailingOnes(unsigned N) {
|
||||
static_assert(std::is_unsigned_v<T>, "Invalid type!");
|
||||
const unsigned Bits = CHAR_BIT * sizeof(T);
|
||||
assert(N <= Bits && "Invalid bit index");
|
||||
@@ -54,19 +55,19 @@ template <typename T> 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 <typename T> T maskLeadingOnes(unsigned N) {
|
||||
template <typename T> constexpr T maskLeadingOnes(unsigned N) {
|
||||
return ~maskTrailingOnes<T>(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 <typename T> T maskTrailingZeros(unsigned N) {
|
||||
template <typename T> constexpr T maskTrailingZeros(unsigned N) {
|
||||
return maskLeadingOnes<T>(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 <typename T> T maskLeadingZeros(unsigned N) {
|
||||
template <typename T> constexpr T maskLeadingZeros(unsigned N) {
|
||||
return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
|
||||
}
|
||||
|
||||
@@ -84,7 +85,7 @@ static const unsigned char BitReverseTable256[256] = {
|
||||
};
|
||||
|
||||
/// Reverse the bits in \p Val.
|
||||
template <typename T> T reverseBits(T Val) {
|
||||
template <typename T> constexpr T reverseBits(T Val) {
|
||||
#if __has_builtin(__builtin_bitreverse8)
|
||||
if constexpr (std::is_same_v<T, uint8_t>)
|
||||
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 <unsigned N> constexpr bool isUInt(uint64_t x) {
|
||||
if constexpr (N == 0)
|
||||
return 0 == x;
|
||||
if constexpr (N == 8)
|
||||
return static_cast<uint8_t>(x) == x;
|
||||
if constexpr (N == 16)
|
||||
return static_cast<uint16_t>(x) == x;
|
||||
if constexpr (N == 32)
|
||||
return static_cast<uint32_t>(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 <size_t kValue> constexpr size_t CTLog2() {
|
||||
static_assert(kValue > 0 && wpi::util::isPowerOf2_64(kValue),
|
||||
"Value is not a valid power of 2");
|
||||
return 1 + CTLog2<kValue / 2>();
|
||||
template <size_t kValue> 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 <size_t kValue>
|
||||
LLVM_DEPRECATED("Use ConstantLog2 instead", "ConstantLog2")
|
||||
constexpr size_t CTLog2() {
|
||||
return ConstantLog2<kValue>();
|
||||
}
|
||||
|
||||
/// 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 <typename T, typename U = std::make_unsigned_t<T>>
|
||||
constexpr U AbsoluteValue(T X) {
|
||||
// If X is negative, cast it to the unsigned type _before_ negating it.
|
||||
return X < 0 ? -static_cast<U>(X) : X;
|
||||
}
|
||||
|
||||
/// Subtract two unsigned integers, X and Y, of type T and return the absolute
|
||||
/// value of the result.
|
||||
template <typename U, typename V, typename T = common_uint<U, V>>
|
||||
@@ -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<std::is_signed_v<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 <typename T>
|
||||
std::enable_if_t<std::is_signed_v<T>, T> SubOverflow(T X, T Y, T &Result) {
|
||||
#if __has_builtin(__builtin_sub_overflow)
|
||||
@@ -722,7 +727,7 @@ std::enable_if_t<std::is_signed_v<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 <typename T>
|
||||
std::enable_if_t<std::is_signed_v<T>, T> MulOverflow(T X, T Y, T &Result) {
|
||||
#if __has_builtin(__builtin_mul_overflow)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<intptr_t>(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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#ifndef WPIUTIL_WPI_POINTERLIKETYPETRAITS_H
|
||||
#define WPIUTIL_WPI_POINTERLIKETYPETRAITS_H
|
||||
|
||||
#include "wpi/util/MathExtras.hpp"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
@@ -25,12 +25,6 @@ namespace wpi::util {
|
||||
template <typename T> struct PointerLikeTypeTraits;
|
||||
|
||||
namespace detail {
|
||||
/// A tiny meta function to compute the log2 of a compile time constant.
|
||||
template <size_t N>
|
||||
struct ConstantLog2
|
||||
: std::integral_constant<size_t, ConstantLog2<N / 2>::value + 1> {};
|
||||
template <> struct ConstantLog2<1> : std::integral_constant<size_t, 0> {};
|
||||
|
||||
// Provide a trait to check if T is pointer-like.
|
||||
template <typename T, typename U = void> struct HasPointerLikeTypeTraits {
|
||||
static const bool value = false;
|
||||
@@ -57,8 +51,7 @@ template <typename T> struct PointerLikeTypeTraits<T *> {
|
||||
static inline void *getAsVoidPointer(T *P) { return P; }
|
||||
static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); }
|
||||
|
||||
static constexpr int NumLowBitsAvailable =
|
||||
detail::ConstantLog2<alignof(T)>::value;
|
||||
static constexpr int NumLowBitsAvailable = ConstantLog2<alignof(T)>();
|
||||
};
|
||||
|
||||
template <> struct PointerLikeTypeTraits<void *> {
|
||||
@@ -77,7 +70,7 @@ template <> struct PointerLikeTypeTraits<void *> {
|
||||
|
||||
// Provide PointerLikeTypeTraits for const things.
|
||||
template <typename T> struct PointerLikeTypeTraits<const T> {
|
||||
typedef PointerLikeTypeTraits<T> NonConst;
|
||||
using NonConst = PointerLikeTypeTraits<T>;
|
||||
|
||||
static inline const void *getAsVoidPointer(const T P) {
|
||||
return NonConst::getAsVoidPointer(P);
|
||||
@@ -90,7 +83,7 @@ template <typename T> struct PointerLikeTypeTraits<const T> {
|
||||
|
||||
// Provide PointerLikeTypeTraits for const pointers.
|
||||
template <typename T> struct PointerLikeTypeTraits<const T *> {
|
||||
typedef PointerLikeTypeTraits<T *> NonConst;
|
||||
using NonConst = PointerLikeTypeTraits<T *>;
|
||||
|
||||
static inline const void *getAsVoidPointer(const T *P) {
|
||||
return NonConst::getAsVoidPointer(const_cast<T *>(P));
|
||||
@@ -123,8 +116,7 @@ template <> struct PointerLikeTypeTraits<uintptr_t> {
|
||||
/// potentially use alignment attributes on functions to satisfy that.
|
||||
template <int Alignment, typename FunctionPointerT>
|
||||
struct FunctionPointerLikeTypeTraits {
|
||||
static constexpr int NumLowBitsAvailable =
|
||||
detail::ConstantLog2<Alignment>::value;
|
||||
static constexpr int NumLowBitsAvailable = ConstantLog2<Alignment>();
|
||||
static inline void *getAsVoidPointer(FunctionPointerT P) {
|
||||
assert((reinterpret_cast<uintptr_t>(P) &
|
||||
~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 &&
|
||||
|
||||
@@ -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 <typename... Ts> constexpr int lowBitsAvailable() {
|
||||
return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...});
|
||||
}
|
||||
|
||||
/// Find the first type in a list of types.
|
||||
template <typename T, typename...> struct GetFirstType {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
/// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
|
||||
/// for the template arguments.
|
||||
template <typename ...PTs> 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 <typename... PTs> 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<PTs...>;
|
||||
// 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 <typename To, typename From, typename Enable> friend struct CastInfo;
|
||||
|
||||
public:
|
||||
PointerUnion() = default;
|
||||
@@ -264,42 +258,21 @@ bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> 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<typename To>
|
||||
/// friend struct CastInfo<To, PointerUnion<PTs...>>;
|
||||
/// ```
|
||||
/// 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 <typename... PTs> struct CastInfoPointerUnionImpl {
|
||||
using From = PointerUnion<PTs...>;
|
||||
|
||||
template <typename To> static inline bool isPossible(From &F) {
|
||||
return F.Val.getInt() == FirstIndexOfType<To, PTs...>::value;
|
||||
}
|
||||
|
||||
template <typename To> static To doCast(From &F) {
|
||||
assert(isPossible<To>(F) && "cast to an incompatible type!");
|
||||
return PointerLikeTypeTraits<To>::getFromVoidPointer(F.Val.getPointer());
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization of CastInfo for PointerUnion
|
||||
template <typename To, typename... PTs>
|
||||
struct CastInfo<To, PointerUnion<PTs...>>
|
||||
: public DefaultDoCastIfPossible<To, PointerUnion<PTs...>,
|
||||
CastInfo<To, PointerUnion<PTs...>>> {
|
||||
using From = PointerUnion<PTs...>;
|
||||
using Impl = CastInfoPointerUnionImpl<PTs...>;
|
||||
|
||||
static inline bool isPossible(From &f) {
|
||||
return Impl::template isPossible<To>(f);
|
||||
return f.Val.getInt() == FirstIndexOfType<To, PTs...>::value;
|
||||
}
|
||||
|
||||
static To doCast(From &f) { return Impl::template doCast<To>(f); }
|
||||
static To doCast(From &f) {
|
||||
assert(isPossible(f) && "cast to an incompatible type!");
|
||||
return PointerLikeTypeTraits<To>::getFromVoidPointer(f.Val.getPointer());
|
||||
}
|
||||
|
||||
static inline To castFailed() { return To(); }
|
||||
};
|
||||
@@ -331,8 +304,7 @@ struct PointerLikeTypeTraits<PointerUnion<PTs...>> {
|
||||
// Teach DenseMap how to use PointerUnions as keys.
|
||||
template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> {
|
||||
using Union = PointerUnion<PTs...>;
|
||||
using FirstInfo =
|
||||
DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>;
|
||||
using FirstInfo = DenseMapInfo<TypeAtIndex<0, PTs...>>;
|
||||
|
||||
static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); }
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
template<class T = void *>
|
||||
bool shouldReverseIterate() {
|
||||
template <class T = void *> constexpr bool shouldReverseIterate() {
|
||||
#if LLVM_ENABLE_REVERSE_ITERATION
|
||||
return detail::IsPointerLike<T>::value;
|
||||
#else
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
@@ -26,6 +27,54 @@ namespace wpi::util {
|
||||
// Features from C++20
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace numbers {
|
||||
// clang-format off
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T e_v = T(0x1.5bf0a8b145769P+1); // (2.7182818284590452354) https://oeis.org/A001113
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T egamma_v = T(0x1.2788cfc6fb619P-1); // (.57721566490153286061) https://oeis.org/A001620
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T ln2_v = T(0x1.62e42fefa39efP-1); // (.69314718055994530942) https://oeis.org/A002162
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T ln10_v = T(0x1.26bb1bbb55516P+1); // (2.3025850929940456840) https://oeis.org/A002392
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T log2e_v = T(0x1.71547652b82feP+0); // (1.4426950408889634074)
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T log10e_v = T(0x1.bcb7b1526e50eP-2); // (.43429448190325182765)
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T pi_v = T(0x1.921fb54442d18P+1); // (3.1415926535897932385) https://oeis.org/A000796
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T inv_pi_v = T(0x1.45f306dc9c883P-2); // (.31830988618379067154) https://oeis.org/A049541
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T inv_sqrtpi_v = T(0x1.20dd750429b6dP-1); // (.56418958354775628695) https://oeis.org/A087197
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T sqrt2_v = T(0x1.6a09e667f3bcdP+0); // (1.4142135623730950488) https://oeis.org/A00219
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T inv_sqrt2_v = T(0x1.6a09e667f3bcdP-1); // (.70710678118654752440)
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T sqrt3_v = T(0x1.bb67ae8584caaP+0); // (1.7320508075688772935) https://oeis.org/A002194
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T inv_sqrt3_v = T(0x1.279a74590331cP-1); // (.57735026918962576451)
|
||||
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
|
||||
inline constexpr T phi_v = T(0x1.9e3779b97f4a8P+0); // (1.6180339887498948482) https://oeis.org/A001622
|
||||
|
||||
inline constexpr double e = e_v<double>;
|
||||
inline constexpr double egamma = egamma_v<double>;
|
||||
inline constexpr double ln2 = ln2_v<double>;
|
||||
inline constexpr double ln10 = ln10_v<double>;
|
||||
inline constexpr double log2e = log2e_v<double>;
|
||||
inline constexpr double log10e = log10e_v<double>;
|
||||
inline constexpr double pi = pi_v<double>;
|
||||
inline constexpr double inv_pi = inv_pi_v<double>;
|
||||
inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
|
||||
inline constexpr double sqrt2 = sqrt2_v<double>;
|
||||
inline constexpr double inv_sqrt2 = inv_sqrt2_v<double>;
|
||||
inline constexpr double sqrt3 = sqrt3_v<double>;
|
||||
inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
|
||||
inline constexpr double phi = phi_v<double>;
|
||||
// clang-format on
|
||||
} // namespace numbers
|
||||
|
||||
template <typename T>
|
||||
struct remove_cvref // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
@@ -36,27 +85,81 @@ template <typename T>
|
||||
using remove_cvref_t // NOLINT(readability-identifier-naming)
|
||||
= typename wpi::util::remove_cvref<T>::type;
|
||||
|
||||
// TODO: Remove this in favor of std::type_identity<T> once we switch to C++20.
|
||||
template <typename T>
|
||||
struct type_identity // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
// TODO: Remove this in favor of std::type_identity_t<T> once we switch to
|
||||
// C++20.
|
||||
template <typename T>
|
||||
using type_identity_t // NOLINT(readability-identifier-naming)
|
||||
= typename wpi::util::type_identity<T>::type;
|
||||
|
||||
namespace detail {
|
||||
template <class, template <class...> class Op, class... Args> struct detector {
|
||||
using value_t = std::false_type;
|
||||
};
|
||||
template <template <class...> class Op, class... Args>
|
||||
struct detector<std::void_t<Op<Args...>>, Op, Args...> {
|
||||
using value_t = std::true_type;
|
||||
};
|
||||
} // end namespace detail
|
||||
|
||||
/// Detects if a given trait holds for some set of arguments 'Args'.
|
||||
/// For example, the given trait could be used to detect if a given type
|
||||
/// has a copy assignment operator:
|
||||
/// template<class T>
|
||||
/// using has_copy_assign_t = decltype(std::declval<T&>()
|
||||
/// = std::declval<const T&>());
|
||||
/// bool fooHasCopyAssign = is_detected<has_copy_assign_t, FooClass>::value;
|
||||
///
|
||||
/// NOTE: The C++20 standard has adopted concepts and requires clauses as a
|
||||
/// superior alternative to std::is_detected.
|
||||
///
|
||||
/// This utility is placed in STLForwardCompat.h as a reminder
|
||||
/// to migrate usages of wpi::util::is_detected to concepts and 'requires'
|
||||
/// clauses when the codebase adopts C++20.
|
||||
template <template <class...> class Op, class... Args>
|
||||
using is_detected = typename detail::detector<void, Op, Args...>::value_t;
|
||||
|
||||
struct identity // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
using is_transparent = void;
|
||||
|
||||
template <typename T> constexpr T &&operator()(T &&self) const noexcept {
|
||||
return std::forward<T>(self);
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns a raw pointer that represents the same address as the argument.
|
||||
///
|
||||
/// This implementation can be removed once we move to C++20 where it's defined
|
||||
/// as std::to_address().
|
||||
///
|
||||
/// The std::pointer_traits<>::to_address(p) variations of these overloads has
|
||||
/// not been implemented.
|
||||
template <class Ptr> auto to_address(const Ptr &P) { return P.operator->(); }
|
||||
template <class T> constexpr T *to_address(T *P) {
|
||||
static_assert(!std::is_function_v<T>);
|
||||
return P;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Features from C++23
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// TODO: Remove this in favor of std::optional<T>::transform once we switch to
|
||||
// C++23.
|
||||
template <typename T, typename Function>
|
||||
auto transformOptional(const std::optional<T> &O, const Function &F)
|
||||
-> std::optional<decltype(F(*O))> {
|
||||
if (O)
|
||||
return F(*O);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// TODO: Remove this in favor of std::optional<T>::transform once we switch to
|
||||
// C++23.
|
||||
template <typename T, typename Function>
|
||||
auto transformOptional(std::optional<T> &&O, const Function &F)
|
||||
-> std::optional<decltype(F(*std::move(O)))> {
|
||||
if (O)
|
||||
return F(*std::move(O));
|
||||
template <typename Optional, typename Function,
|
||||
typename Value = typename wpi::util::remove_cvref_t<Optional>::value_type>
|
||||
std::optional<std::invoke_result_t<Function, Value>>
|
||||
transformOptional(Optional &&O, Function &&F) {
|
||||
if (O) {
|
||||
return F(*std::forward<Optional>(O));
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -67,6 +170,11 @@ template <typename Enum>
|
||||
return static_cast<std::underlying_type_t<Enum>>(E);
|
||||
}
|
||||
|
||||
// A tag for constructors accepting ranges.
|
||||
struct from_range_t {
|
||||
explicit from_range_t() = default;
|
||||
};
|
||||
inline constexpr from_range_t from_range{};
|
||||
} // namespace wpi::util
|
||||
|
||||
#endif // WPIUTIL_WPI_STLFORWARDCOMPAT_H
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
#ifndef WPIUTIL_WPI_SMALLPTRSET_H
|
||||
#define WPIUTIL_WPI_SMALLPTRSET_H
|
||||
|
||||
#include "wpi/util/ADL.hpp"
|
||||
#include "wpi/util/EpochTracker.hpp"
|
||||
#include "wpi/util/STLForwardCompat.hpp"
|
||||
#include "wpi/util/iterator_range.hpp"
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include "wpi/util/MathExtras.hpp"
|
||||
#include "wpi/util/ReverseIteration.hpp"
|
||||
#include "wpi/util/type_traits.hpp"
|
||||
@@ -43,7 +47,7 @@ namespace wpi::util {
|
||||
/// sets are often small. In this case, no memory allocation is used, and only
|
||||
/// light-weight and cache-efficient scanning is used.
|
||||
///
|
||||
/// Large sets use a classic exponentially-probed hash table. Empty buckets are
|
||||
/// Large sets use a classic quadratically-probed hash table. Empty buckets are
|
||||
/// represented with an illegal pointer value (-1) to allow null pointers to be
|
||||
/// inserted. Tombstones are represented with another illegal pointer value
|
||||
/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
|
||||
@@ -58,25 +62,26 @@ protected:
|
||||
/// CurArraySize - The allocated size of CurArray, always a power of two.
|
||||
unsigned CurArraySize;
|
||||
|
||||
/// Number of elements in CurArray that contain a value or are a tombstone.
|
||||
/// Number of elements in CurArray that contain a value.
|
||||
/// If small, all these elements are at the beginning of CurArray and the rest
|
||||
/// is uninitialized.
|
||||
unsigned NumNonEmpty;
|
||||
unsigned NumEntries;
|
||||
/// Number of tombstones in CurArray.
|
||||
unsigned NumTombstones;
|
||||
/// Whether the set is in small representation.
|
||||
bool IsSmall;
|
||||
|
||||
// Helpers to copy and move construct a SmallPtrSet.
|
||||
SmallPtrSetImplBase(const void **SmallStorage,
|
||||
const SmallPtrSetImplBase &that);
|
||||
SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
|
||||
const void **RHSSmallStorage, SmallPtrSetImplBase &&that);
|
||||
LLVM_ABI SmallPtrSetImplBase(const void **SmallStorage,
|
||||
const SmallPtrSetImplBase &that);
|
||||
LLVM_ABI SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
|
||||
const void **RHSSmallStorage,
|
||||
SmallPtrSetImplBase &&that);
|
||||
|
||||
explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize)
|
||||
: CurArray(SmallStorage), CurArraySize(SmallSize), NumNonEmpty(0),
|
||||
: CurArray(SmallStorage), CurArraySize(SmallSize), NumEntries(0),
|
||||
NumTombstones(0), IsSmall(true) {
|
||||
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
|
||||
assert(std::has_single_bit(SmallSize) &&
|
||||
"Initial size must be a power of two!");
|
||||
}
|
||||
|
||||
@@ -91,8 +96,8 @@ public:
|
||||
SmallPtrSetImplBase &operator=(const SmallPtrSetImplBase &) = delete;
|
||||
|
||||
[[nodiscard]] bool empty() const { return size() == 0; }
|
||||
size_type size() const { return NumNonEmpty - NumTombstones; }
|
||||
size_type capacity() const { return CurArraySize; }
|
||||
[[nodiscard]] size_type size() const { return NumEntries; }
|
||||
[[nodiscard]] size_type capacity() const { return CurArraySize; }
|
||||
|
||||
void clear() {
|
||||
incrementEpoch();
|
||||
@@ -105,42 +110,58 @@ public:
|
||||
memset(CurArray, -1, CurArraySize * sizeof(void *));
|
||||
}
|
||||
|
||||
NumNonEmpty = 0;
|
||||
NumEntries = 0;
|
||||
NumTombstones = 0;
|
||||
}
|
||||
|
||||
void reserve(size_type NumEntries) {
|
||||
void reserve(size_type NewNumEntries) {
|
||||
incrementEpoch();
|
||||
// Do nothing if we're given zero as a reservation size.
|
||||
if (NumEntries == 0)
|
||||
if (NewNumEntries == 0)
|
||||
return;
|
||||
// No need to expand if we're small and NumEntries will fit in the space.
|
||||
if (isSmall() && NumEntries <= CurArraySize)
|
||||
// No need to expand if we're small and NewNumEntries will fit in the space.
|
||||
if (isSmall() && NewNumEntries <= CurArraySize)
|
||||
return;
|
||||
// insert_imp_big will reallocate if stores is more than 75% full, on the
|
||||
// /final/ insertion.
|
||||
if (!isSmall() && ((NumEntries - 1) * 4) < (CurArraySize * 3))
|
||||
if (!isSmall() && ((NewNumEntries - 1) * 4) < (CurArraySize * 3))
|
||||
return;
|
||||
// We must Grow -- find the size where we'd be 75% full, then round up to
|
||||
// the next power of two.
|
||||
size_type NewSize = NumEntries + (NumEntries / 3);
|
||||
NewSize = 1 << (Log2_32_Ceil(NewSize) + 1);
|
||||
size_type NewSize = NewNumEntries + (NewNumEntries / 3);
|
||||
NewSize = std::bit_ceil(NewSize);
|
||||
// Like insert_imp_big, always allocate at least 128 elements.
|
||||
NewSize = (std::max)(128u, NewSize);
|
||||
Grow(NewSize);
|
||||
}
|
||||
|
||||
protected:
|
||||
static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
|
||||
static void *getTombstoneMarker() { return reinterpret_cast<void *>(-2); }
|
||||
|
||||
static void *getEmptyMarker() {
|
||||
// Note that -1 is chosen to make clear() efficiently implementable with
|
||||
// memset and because it's not a valid pointer value.
|
||||
return reinterpret_cast<void*>(-1);
|
||||
return reinterpret_cast<void *>(-1);
|
||||
}
|
||||
|
||||
const void **EndPointer() const {
|
||||
return isSmall() ? CurArray + NumNonEmpty : CurArray + CurArraySize;
|
||||
return isSmall() ? CurArray + NumEntries : CurArray + CurArraySize;
|
||||
}
|
||||
|
||||
iterator_range<const void **> small_buckets() {
|
||||
return make_range(CurArray, CurArray + NumEntries);
|
||||
}
|
||||
|
||||
iterator_range<const void *const *> small_buckets() const {
|
||||
return {CurArray, CurArray + NumEntries};
|
||||
}
|
||||
|
||||
iterator_range<const void **> buckets() {
|
||||
return make_range(CurArray, EndPointer());
|
||||
}
|
||||
|
||||
iterator_range<const void *const *> buckets() const {
|
||||
return make_range(CurArray, EndPointer());
|
||||
}
|
||||
|
||||
/// insert_imp - This returns true if the pointer was new to the set, false if
|
||||
@@ -149,18 +170,16 @@ protected:
|
||||
std::pair<const void *const *, bool> insert_imp(const void *Ptr) {
|
||||
if (isSmall()) {
|
||||
// Check to see if it is already in the set.
|
||||
for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty;
|
||||
APtr != E; ++APtr) {
|
||||
const void *Value = *APtr;
|
||||
if (Value == Ptr)
|
||||
return std::make_pair(APtr, false);
|
||||
for (const void *&Bucket : small_buckets()) {
|
||||
if (Bucket == Ptr)
|
||||
return {&Bucket, false};
|
||||
}
|
||||
|
||||
// Nope, there isn't. If we stay small, just 'pushback' now.
|
||||
if (NumNonEmpty < CurArraySize) {
|
||||
CurArray[NumNonEmpty++] = Ptr;
|
||||
if (NumEntries < CurArraySize) {
|
||||
CurArray[NumEntries++] = Ptr;
|
||||
incrementEpoch();
|
||||
return std::make_pair(CurArray + (NumNonEmpty - 1), true);
|
||||
return {CurArray + (NumEntries - 1), true};
|
||||
}
|
||||
// Otherwise, hit the big set case, which will call grow.
|
||||
}
|
||||
@@ -171,12 +190,11 @@ protected:
|
||||
/// return true, otherwise return false. This is hidden from the client so
|
||||
/// that the derived class can check that the right type of pointer is passed
|
||||
/// in.
|
||||
bool erase_imp(const void * Ptr) {
|
||||
bool erase_imp(const void *Ptr) {
|
||||
if (isSmall()) {
|
||||
for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty;
|
||||
APtr != E; ++APtr) {
|
||||
if (*APtr == Ptr) {
|
||||
*APtr = CurArray[--NumNonEmpty];
|
||||
for (const void *&Bucket : small_buckets()) {
|
||||
if (Bucket == Ptr) {
|
||||
Bucket = CurArray[--NumEntries];
|
||||
incrementEpoch();
|
||||
return true;
|
||||
}
|
||||
@@ -190,6 +208,7 @@ protected:
|
||||
|
||||
*const_cast<const void **>(Bucket) = getTombstoneMarker();
|
||||
NumTombstones++;
|
||||
--NumEntries;
|
||||
// Treat this consistently from an API perspective, even if we don't
|
||||
// actually invalidate iterators here.
|
||||
incrementEpoch();
|
||||
@@ -199,14 +218,12 @@ protected:
|
||||
/// Returns the raw pointer needed to construct an iterator. If element not
|
||||
/// found, this will be EndPointer. Otherwise, it will be a pointer to the
|
||||
/// slot which stores Ptr;
|
||||
const void *const * find_imp(const void * Ptr) const {
|
||||
const void *const *find_imp(const void *Ptr) const {
|
||||
if (isSmall()) {
|
||||
// Linear search for the item.
|
||||
for (const void *const *APtr = CurArray, *const *E =
|
||||
CurArray + NumNonEmpty;
|
||||
APtr != E; ++APtr)
|
||||
if (*APtr == Ptr)
|
||||
return APtr;
|
||||
for (const void *const &Bucket : small_buckets())
|
||||
if (Bucket == Ptr)
|
||||
return &Bucket;
|
||||
return EndPointer();
|
||||
}
|
||||
|
||||
@@ -219,10 +236,8 @@ protected:
|
||||
bool contains_imp(const void *Ptr) const {
|
||||
if (isSmall()) {
|
||||
// Linear search for the item.
|
||||
const void *const *APtr = CurArray;
|
||||
const void *const *E = CurArray + NumNonEmpty;
|
||||
for (; APtr != E; ++APtr)
|
||||
if (*APtr == Ptr)
|
||||
for (const void *const &Bucket : small_buckets())
|
||||
if (Bucket == Ptr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -233,24 +248,26 @@ protected:
|
||||
bool isSmall() const { return IsSmall; }
|
||||
|
||||
private:
|
||||
std::pair<const void *const *, bool> insert_imp_big(const void *Ptr);
|
||||
LLVM_ABI std::pair<const void *const *, bool> insert_imp_big(const void *Ptr);
|
||||
|
||||
const void *const *doFind(const void *Ptr) const;
|
||||
const void * const *FindBucketFor(const void *Ptr) const;
|
||||
void shrink_and_clear();
|
||||
LLVM_ABI const void *const *doFind(const void *Ptr) const;
|
||||
const void *const *FindBucketFor(const void *Ptr) const;
|
||||
LLVM_ABI void shrink_and_clear();
|
||||
|
||||
/// Grow - Allocate a larger backing store for the buckets and move it over.
|
||||
void Grow(unsigned NewSize);
|
||||
LLVM_ABI void Grow(unsigned NewSize);
|
||||
|
||||
protected:
|
||||
/// swap - Swaps the elements of two sets.
|
||||
/// Note: This method assumes that both sets have the same small size.
|
||||
void swap(const void **SmallStorage, const void **RHSSmallStorage,
|
||||
SmallPtrSetImplBase &RHS);
|
||||
LLVM_ABI void swap(const void **SmallStorage, const void **RHSSmallStorage,
|
||||
SmallPtrSetImplBase &RHS);
|
||||
|
||||
void copyFrom(const void **SmallStorage, const SmallPtrSetImplBase &RHS);
|
||||
void moveFrom(const void **SmallStorage, unsigned SmallSize,
|
||||
const void **RHSSmallStorage, SmallPtrSetImplBase &&RHS);
|
||||
LLVM_ABI void copyFrom(const void **SmallStorage,
|
||||
const SmallPtrSetImplBase &RHS);
|
||||
LLVM_ABI void moveFrom(const void **SmallStorage, unsigned SmallSize,
|
||||
const void **RHSSmallStorage,
|
||||
SmallPtrSetImplBase &&RHS);
|
||||
|
||||
private:
|
||||
/// Code shared by moveFrom() and move constructor.
|
||||
@@ -262,18 +279,12 @@ private:
|
||||
|
||||
/// SmallPtrSetIteratorImpl - This is the common base class shared between all
|
||||
/// instances of SmallPtrSetIterator.
|
||||
class SmallPtrSetIteratorImpl {
|
||||
protected:
|
||||
const void *const *Bucket;
|
||||
const void *const *End;
|
||||
|
||||
class LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE SmallPtrSetIteratorImpl
|
||||
: public DebugEpochBase::HandleBase {
|
||||
public:
|
||||
explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
|
||||
: Bucket(BP), End(E) {
|
||||
if (shouldReverseIterate()) {
|
||||
RetreatIfNotValid();
|
||||
return;
|
||||
}
|
||||
explicit SmallPtrSetIteratorImpl(const void *const *BP, const void *const *E,
|
||||
const DebugEpochBase &Epoch)
|
||||
: DebugEpochBase::HandleBase(&Epoch), Bucket(BP), End(E) {
|
||||
AdvanceIfNotValid();
|
||||
}
|
||||
|
||||
@@ -285,6 +296,18 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void *dereference() const {
|
||||
assert(isHandleInSync() && "invalid iterator access!");
|
||||
assert(Bucket < End);
|
||||
return const_cast<void *>(*Bucket);
|
||||
}
|
||||
void increment() {
|
||||
assert(isHandleInSync() && "invalid iterator access!");
|
||||
++Bucket;
|
||||
AdvanceIfNotValid();
|
||||
}
|
||||
|
||||
private:
|
||||
/// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket
|
||||
/// that is. This is guaranteed to stop because the end() bucket is marked
|
||||
/// valid.
|
||||
@@ -295,21 +318,19 @@ protected:
|
||||
*Bucket == SmallPtrSetImplBase::getTombstoneMarker()))
|
||||
++Bucket;
|
||||
}
|
||||
void RetreatIfNotValid() {
|
||||
assert(Bucket >= End);
|
||||
while (Bucket != End &&
|
||||
(Bucket[-1] == SmallPtrSetImplBase::getEmptyMarker() ||
|
||||
Bucket[-1] == SmallPtrSetImplBase::getTombstoneMarker())) {
|
||||
--Bucket;
|
||||
}
|
||||
}
|
||||
|
||||
using BucketItTy =
|
||||
std::conditional_t<shouldReverseIterate(),
|
||||
std::reverse_iterator<const void *const *>,
|
||||
const void *const *>;
|
||||
|
||||
BucketItTy Bucket;
|
||||
BucketItTy End;
|
||||
};
|
||||
|
||||
/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
|
||||
template <typename PtrTy>
|
||||
class LLVM_DEBUGEPOCHBASE_HANDLEBASE_EMPTYBASE SmallPtrSetIterator
|
||||
: public SmallPtrSetIteratorImpl,
|
||||
DebugEpochBase::HandleBase {
|
||||
class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
|
||||
using PtrTraits = PointerLikeTypeTraits<PtrTy>;
|
||||
|
||||
public:
|
||||
@@ -319,37 +340,22 @@ public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E,
|
||||
const DebugEpochBase &Epoch)
|
||||
: SmallPtrSetIteratorImpl(BP, E), DebugEpochBase::HandleBase(&Epoch) {}
|
||||
using SmallPtrSetIteratorImpl::SmallPtrSetIteratorImpl;
|
||||
|
||||
// Most methods are provided by the base class.
|
||||
|
||||
const PtrTy operator*() const {
|
||||
assert(isHandleInSync() && "invalid iterator access!");
|
||||
if (shouldReverseIterate()) {
|
||||
assert(Bucket > End);
|
||||
return PtrTraits::getFromVoidPointer(const_cast<void *>(Bucket[-1]));
|
||||
}
|
||||
assert(Bucket < End);
|
||||
return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket));
|
||||
[[nodiscard]] const PtrTy operator*() const {
|
||||
return PtrTraits::getFromVoidPointer(dereference());
|
||||
}
|
||||
|
||||
inline SmallPtrSetIterator& operator++() { // Preincrement
|
||||
assert(isHandleInSync() && "invalid iterator access!");
|
||||
if (shouldReverseIterate()) {
|
||||
--Bucket;
|
||||
RetreatIfNotValid();
|
||||
return *this;
|
||||
}
|
||||
++Bucket;
|
||||
AdvanceIfNotValid();
|
||||
inline SmallPtrSetIterator &operator++() { // Preincrement
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallPtrSetIterator operator++(int) { // Postincrement
|
||||
SmallPtrSetIterator operator++(int) { // Postincrement
|
||||
SmallPtrSetIterator tmp = *this;
|
||||
++*this;
|
||||
increment();
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
@@ -359,8 +365,7 @@ public:
|
||||
///
|
||||
/// This is particularly useful for passing around between interface boundaries
|
||||
/// to avoid encoding a particular small size in the interface boundary.
|
||||
template <typename PtrType>
|
||||
class SmallPtrSetImpl : public SmallPtrSetImplBase {
|
||||
template <typename PtrType> class SmallPtrSetImpl : public SmallPtrSetImplBase {
|
||||
using ConstPtrType = typename add_const_past_pointer<PtrType>::type;
|
||||
using PtrTraits = PointerLikeTypeTraits<PtrType>;
|
||||
using ConstPtrTraits = PointerLikeTypeTraits<ConstPtrType>;
|
||||
@@ -383,15 +388,13 @@ public:
|
||||
/// the element equal to Ptr.
|
||||
std::pair<iterator, bool> insert(PtrType Ptr) {
|
||||
auto p = insert_imp(PtrTraits::getAsVoidPointer(Ptr));
|
||||
return std::make_pair(makeIterator(p.first), p.second);
|
||||
return {makeIterator(p.first), p.second};
|
||||
}
|
||||
|
||||
/// Insert the given pointer with an iterator hint that is ignored. This is
|
||||
/// identical to calling insert(Ptr), but allows SmallPtrSet to be used by
|
||||
/// std::insert_iterator and std::inserter().
|
||||
iterator insert(iterator, PtrType Ptr) {
|
||||
return insert(Ptr).first;
|
||||
}
|
||||
iterator insert(iterator, PtrType Ptr) { return insert(Ptr).first; }
|
||||
|
||||
/// Remove pointer from the set.
|
||||
///
|
||||
@@ -414,16 +417,16 @@ public:
|
||||
/// Returns whether anything was removed. It is safe to read the set inside
|
||||
/// the predicate function. However, the predicate must not modify the set
|
||||
/// itself, only indicate a removal by returning true.
|
||||
template <typename UnaryPredicate>
|
||||
bool remove_if(UnaryPredicate P) {
|
||||
template <typename UnaryPredicate> bool remove_if(UnaryPredicate P) {
|
||||
bool Removed = false;
|
||||
if (isSmall()) {
|
||||
const void **APtr = CurArray, **E = CurArray + NumNonEmpty;
|
||||
auto Buckets = small_buckets();
|
||||
const void **APtr = Buckets.begin(), **E = Buckets.end();
|
||||
while (APtr != E) {
|
||||
PtrType Ptr = PtrTraits::getFromVoidPointer(const_cast<void *>(*APtr));
|
||||
if (P(Ptr)) {
|
||||
*APtr = *--E;
|
||||
--NumNonEmpty;
|
||||
--NumEntries;
|
||||
incrementEpoch();
|
||||
Removed = true;
|
||||
} else {
|
||||
@@ -433,14 +436,14 @@ public:
|
||||
return Removed;
|
||||
}
|
||||
|
||||
for (const void **APtr = CurArray, **E = EndPointer(); APtr != E; ++APtr) {
|
||||
const void *Value = *APtr;
|
||||
if (Value == getTombstoneMarker() || Value == getEmptyMarker())
|
||||
for (const void *&Bucket : buckets()) {
|
||||
if (Bucket == getTombstoneMarker() || Bucket == getEmptyMarker())
|
||||
continue;
|
||||
PtrType Ptr = PtrTraits::getFromVoidPointer(const_cast<void *>(Value));
|
||||
PtrType Ptr = PtrTraits::getFromVoidPointer(const_cast<void *>(Bucket));
|
||||
if (P(Ptr)) {
|
||||
*APtr = getTombstoneMarker();
|
||||
Bucket = getTombstoneMarker();
|
||||
++NumTombstones;
|
||||
--NumEntries;
|
||||
incrementEpoch();
|
||||
Removed = true;
|
||||
}
|
||||
@@ -449,18 +452,17 @@ public:
|
||||
}
|
||||
|
||||
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
|
||||
size_type count(ConstPtrType Ptr) const {
|
||||
[[nodiscard]] size_type count(ConstPtrType Ptr) const {
|
||||
return contains_imp(ConstPtrTraits::getAsVoidPointer(Ptr));
|
||||
}
|
||||
iterator find(ConstPtrType Ptr) const {
|
||||
[[nodiscard]] iterator find(ConstPtrType Ptr) const {
|
||||
return makeIterator(find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)));
|
||||
}
|
||||
bool contains(ConstPtrType Ptr) const {
|
||||
[[nodiscard]] bool contains(ConstPtrType Ptr) const {
|
||||
return contains_imp(ConstPtrTraits::getAsVoidPointer(Ptr));
|
||||
}
|
||||
|
||||
template <typename IterT>
|
||||
void insert(IterT I, IterT E) {
|
||||
template <typename IterT> void insert(IterT I, IterT E) {
|
||||
for (; I != E; ++I)
|
||||
insert(*I);
|
||||
}
|
||||
@@ -469,19 +471,25 @@ public:
|
||||
insert(IL.begin(), IL.end());
|
||||
}
|
||||
|
||||
iterator begin() const {
|
||||
if (shouldReverseIterate())
|
||||
return makeIterator(EndPointer() - 1);
|
||||
return makeIterator(CurArray);
|
||||
template <typename Range> void insert_range(Range &&R) {
|
||||
insert(adl_begin(R), adl_end(R));
|
||||
}
|
||||
iterator end() const { return makeIterator(EndPointer()); }
|
||||
|
||||
[[nodiscard]] iterator begin() const {
|
||||
if constexpr (shouldReverseIterate())
|
||||
return makeIterator(EndPointer() - 1);
|
||||
else
|
||||
return makeIterator(CurArray);
|
||||
}
|
||||
[[nodiscard]] iterator end() const { return makeIterator(EndPointer()); }
|
||||
|
||||
private:
|
||||
/// Create an iterator that dereferences to same place as the given pointer.
|
||||
iterator makeIterator(const void *const *P) const {
|
||||
if (shouldReverseIterate())
|
||||
if constexpr (shouldReverseIterate())
|
||||
return iterator(P == EndPointer() ? CurArray : P + 1, CurArray, *this);
|
||||
return iterator(P, EndPointer(), *this);
|
||||
else
|
||||
return iterator(P, EndPointer(), *this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -490,8 +498,8 @@ private:
|
||||
/// Iterates over elements of LHS confirming that each value from LHS is also in
|
||||
/// RHS, and that no additional values are in RHS.
|
||||
template <typename PtrType>
|
||||
bool operator==(const SmallPtrSetImpl<PtrType> &LHS,
|
||||
const SmallPtrSetImpl<PtrType> &RHS) {
|
||||
[[nodiscard]] bool operator==(const SmallPtrSetImpl<PtrType> &LHS,
|
||||
const SmallPtrSetImpl<PtrType> &RHS) {
|
||||
if (LHS.size() != RHS.size())
|
||||
return false;
|
||||
|
||||
@@ -506,8 +514,8 @@ bool operator==(const SmallPtrSetImpl<PtrType> &LHS,
|
||||
///
|
||||
/// Equivalent to !(LHS == RHS).
|
||||
template <typename PtrType>
|
||||
bool operator!=(const SmallPtrSetImpl<PtrType> &LHS,
|
||||
const SmallPtrSetImpl<PtrType> &RHS) {
|
||||
[[nodiscard]] bool operator!=(const SmallPtrSetImpl<PtrType> &LHS,
|
||||
const SmallPtrSetImpl<PtrType> &RHS) {
|
||||
return !(LHS == RHS);
|
||||
}
|
||||
|
||||
@@ -515,7 +523,7 @@ bool operator!=(const SmallPtrSetImpl<PtrType> &LHS,
|
||||
/// SmallSize or less elements. This internally rounds up SmallSize to the next
|
||||
/// power of two if it is not already a power of two. See the comments above
|
||||
/// SmallPtrSetImplBase for details of the algorithm.
|
||||
template<class PtrType, unsigned SmallSize>
|
||||
template <class PtrType, unsigned SmallSize>
|
||||
class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
|
||||
// In small mode SmallPtrSet uses linear search for the elements, so it is
|
||||
// not a good idea to choose this value too high. You may consider using a
|
||||
@@ -524,18 +532,8 @@ class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
|
||||
|
||||
using BaseT = SmallPtrSetImpl<PtrType>;
|
||||
|
||||
// A constexpr version of wpi::util::bit_ceil.
|
||||
// TODO: Replace this with std::bit_ceil once C++20 is available.
|
||||
static constexpr size_t RoundUpToPowerOfTwo(size_t X) {
|
||||
size_t C = 1;
|
||||
size_t CMax = C << (std::numeric_limits<size_t>::digits - 1);
|
||||
while (C < X && C < CMax)
|
||||
C <<= 1;
|
||||
return C;
|
||||
}
|
||||
|
||||
// Make sure that SmallSize is a power of two, round up if not.
|
||||
static constexpr size_t SmallSizePowTwo = RoundUpToPowerOfTwo(SmallSize);
|
||||
static constexpr size_t SmallSizePowTwo = std::bit_ceil(SmallSize);
|
||||
/// SmallStorage - Fixed size storage used in 'small mode'.
|
||||
const void *SmallStorage[SmallSizePowTwo];
|
||||
|
||||
@@ -546,11 +544,15 @@ public:
|
||||
: BaseT(SmallStorage, SmallSizePowTwo, that.SmallStorage,
|
||||
std::move(that)) {}
|
||||
|
||||
template<typename It>
|
||||
template <typename It>
|
||||
SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) {
|
||||
this->insert(I, E);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
SmallPtrSet(wpi::util::from_range_t, Range &&R)
|
||||
: SmallPtrSet(adl_begin(R), adl_end(R)) {}
|
||||
|
||||
SmallPtrSet(std::initializer_list<PtrType> IL)
|
||||
: BaseT(SmallStorage, SmallSizePowTwo) {
|
||||
this->insert(IL.begin(), IL.end());
|
||||
@@ -584,16 +586,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace wpi::util
|
||||
} // namespace wpi::util
|
||||
|
||||
namespace std {
|
||||
|
||||
/// Implement std::swap in terms of SmallPtrSet swap.
|
||||
template<class T, unsigned N>
|
||||
inline void swap(wpi::util::SmallPtrSet<T, N> &LHS, wpi::util::SmallPtrSet<T, N> &RHS) {
|
||||
LHS.swap(RHS);
|
||||
}
|
||||
/// Implement std::swap in terms of SmallPtrSet swap.
|
||||
template <class T, unsigned N>
|
||||
inline void swap(wpi::util::SmallPtrSet<T, N> &LHS, wpi::util::SmallPtrSet<T, N> &RHS) {
|
||||
LHS.swap(RHS);
|
||||
}
|
||||
|
||||
} // end namespace std
|
||||
} // namespace std
|
||||
|
||||
#endif // WPIUTIL_WPI_SMALLPTRSET_H
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#ifndef WPIUTIL_WPI_SMALLSET_H
|
||||
#define WPIUTIL_WPI_SMALLSET_H
|
||||
|
||||
#include "wpi/util/ADL.hpp"
|
||||
#include "wpi/util/STLForwardCompat.hpp"
|
||||
#include "wpi/util/SmallPtrSet.hpp"
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/iterator.hpp"
|
||||
@@ -34,7 +36,6 @@ class SmallSetIterator
|
||||
private:
|
||||
using SetIterTy = typename std::set<T, C>::const_iterator;
|
||||
using VecIterTy = typename SmallVector<T, N>::const_iterator;
|
||||
using SelfTy = SmallSetIterator<T, N, C>;
|
||||
|
||||
/// Iterators to the parts of the SmallSet containing the data. They are set
|
||||
/// depending on isSmall.
|
||||
@@ -161,10 +162,9 @@ public:
|
||||
insert(Begin, End);
|
||||
}
|
||||
|
||||
template <typename RangeT>
|
||||
explicit SmallSet(const iterator_range<RangeT> &R) {
|
||||
insert(R.begin(), R.end());
|
||||
}
|
||||
template <typename Range>
|
||||
SmallSet(wpi::util::from_range_t, Range &&R)
|
||||
: SmallSet(adl_begin(R), adl_end(R)) {}
|
||||
|
||||
SmallSet(std::initializer_list<T> L) { insert(L.begin(), L.end()); }
|
||||
|
||||
@@ -173,12 +173,14 @@ public:
|
||||
|
||||
[[nodiscard]] bool empty() const { return Vector.empty() && Set.empty(); }
|
||||
|
||||
size_type size() const {
|
||||
[[nodiscard]] size_type size() const {
|
||||
return isSmall() ? Vector.size() : Set.size();
|
||||
}
|
||||
|
||||
/// count - Return 1 if the element is in the set, 0 otherwise.
|
||||
size_type count(const T &V) const { return contains(V) ? 1 : 0; }
|
||||
[[nodiscard]] size_type count(const T &V) const {
|
||||
return contains(V) ? 1 : 0;
|
||||
}
|
||||
|
||||
/// insert - Insert an element into the set if it isn't already there.
|
||||
/// Returns a pair. The first value of it is an iterator to the inserted
|
||||
@@ -196,6 +198,10 @@ public:
|
||||
insert(*I);
|
||||
}
|
||||
|
||||
template <typename Range> void insert_range(Range &&R) {
|
||||
insert(adl_begin(R), adl_end(R));
|
||||
}
|
||||
|
||||
bool erase(const T &V) {
|
||||
if (!isSmall())
|
||||
return Set.erase(V);
|
||||
@@ -212,20 +218,20 @@ public:
|
||||
Set.clear();
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
[[nodiscard]] const_iterator begin() const {
|
||||
if (isSmall())
|
||||
return {Vector.begin()};
|
||||
return {Set.begin()};
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
[[nodiscard]] const_iterator end() const {
|
||||
if (isSmall())
|
||||
return {Vector.end()};
|
||||
return {Set.end()};
|
||||
}
|
||||
|
||||
/// Check if the SmallSet contains the given element.
|
||||
bool contains(const T &V) const {
|
||||
[[nodiscard]] bool contains(const T &V) const {
|
||||
if (isSmall())
|
||||
return vfind(V) != Vector.end();
|
||||
return Set.find(V) != Set.end();
|
||||
@@ -270,7 +276,7 @@ private:
|
||||
/// If this set is of pointer values, transparently switch over to using
|
||||
/// SmallPtrSet for performance.
|
||||
template <typename PointeeType, unsigned N>
|
||||
class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
|
||||
class SmallSet<PointeeType *, N> : public SmallPtrSet<PointeeType *, N> {};
|
||||
|
||||
/// Equality comparison for SmallSet.
|
||||
///
|
||||
@@ -281,7 +287,8 @@ class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
|
||||
/// For large-set mode amortized complexity is linear, worst case is O(N^2) (if
|
||||
/// every hash collides).
|
||||
template <typename T, unsigned LN, unsigned RN, typename C>
|
||||
bool operator==(const SmallSet<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
|
||||
[[nodiscard]] bool operator==(const SmallSet<T, LN, C> &LHS,
|
||||
const SmallSet<T, RN, C> &RHS) {
|
||||
if (LHS.size() != RHS.size())
|
||||
return false;
|
||||
|
||||
@@ -293,7 +300,8 @@ bool operator==(const SmallSet<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
|
||||
///
|
||||
/// Equivalent to !(LHS == RHS). See operator== for performance notes.
|
||||
template <typename T, unsigned LN, unsigned RN, typename C>
|
||||
bool operator!=(const SmallSet<T, LN, C> &LHS, const SmallSet<T, RN, C> &RHS) {
|
||||
[[nodiscard]] bool operator!=(const SmallSet<T, LN, C> &LHS,
|
||||
const SmallSet<T, RN, C> &RHS) {
|
||||
return !(LHS == RHS);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#ifndef WPIUTIL_WPI_SMALLVECTOR_H
|
||||
#define WPIUTIL_WPI_SMALLVECTOR_H
|
||||
|
||||
#include "wpi/util/ADL.hpp"
|
||||
#include "wpi/util/DenseMapInfo.hpp"
|
||||
|
||||
// This file uses std::memcpy() to copy std::pair<unsigned int, unsigned int>.
|
||||
// That type is POD, but the standard doesn't guarantee that. GCC doesn't treat
|
||||
// the type as POD so it throws a warning. We want to consider this a warning
|
||||
@@ -73,13 +76,13 @@ protected:
|
||||
/// 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
|
||||
/// least to \p MinSize.
|
||||
void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
|
||||
size_t &NewCapacity);
|
||||
LLVM_ABI void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
|
||||
size_t &NewCapacity);
|
||||
|
||||
/// This is an implementation of the grow() method which only works
|
||||
/// on POD-like data types and is out of line to reduce code duplication.
|
||||
/// This function will report a fatal error if it cannot increase capacity.
|
||||
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
|
||||
LLVM_ABI void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
|
||||
|
||||
public:
|
||||
size_t size() const { return Size; }
|
||||
@@ -200,30 +203,34 @@ protected:
|
||||
}
|
||||
|
||||
/// Check whether any part of the range will be invalidated by clearing.
|
||||
void assertSafeToReferenceAfterClear(const T *From, const T *To) {
|
||||
if (From == To)
|
||||
return;
|
||||
this->assertSafeToReferenceAfterResize(From, 0);
|
||||
this->assertSafeToReferenceAfterResize(To - 1, 0);
|
||||
template <class ItTy>
|
||||
void assertSafeToReferenceAfterClear(ItTy From, ItTy To) {
|
||||
if constexpr (std::is_pointer_v<ItTy> &&
|
||||
std::is_same_v<
|
||||
std::remove_const_t<std::remove_pointer_t<ItTy>>,
|
||||
std::remove_const_t<T>>) {
|
||||
if (From == To)
|
||||
return;
|
||||
this->assertSafeToReferenceAfterResize(From, 0);
|
||||
this->assertSafeToReferenceAfterResize(To - 1, 0);
|
||||
}
|
||||
(void)From;
|
||||
(void)To;
|
||||
}
|
||||
template <
|
||||
class ItTy,
|
||||
std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
|
||||
bool> = false>
|
||||
void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
|
||||
|
||||
/// Check whether any part of the range will be invalidated by growing.
|
||||
void assertSafeToAddRange(const T *From, const T *To) {
|
||||
if (From == To)
|
||||
return;
|
||||
this->assertSafeToAdd(From, To - From);
|
||||
this->assertSafeToAdd(To - 1, To - From);
|
||||
template <class ItTy> void assertSafeToAddRange(ItTy From, ItTy To) {
|
||||
if constexpr (std::is_pointer_v<ItTy> &&
|
||||
std::is_same_v<std::remove_cv_t<std::remove_pointer_t<ItTy>>,
|
||||
T>) {
|
||||
if (From == To)
|
||||
return;
|
||||
this->assertSafeToAdd(From, To - From);
|
||||
this->assertSafeToAdd(To - 1, To - From);
|
||||
}
|
||||
(void)From;
|
||||
(void)To;
|
||||
}
|
||||
template <
|
||||
class ItTy,
|
||||
std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
|
||||
bool> = false>
|
||||
void assertSafeToAddRange(ItTy, ItTy) {}
|
||||
|
||||
/// Reserve enough space to add one element, and return the updated element
|
||||
/// pointer in case it was a reference to the storage.
|
||||
@@ -501,25 +508,22 @@ protected:
|
||||
|
||||
/// Copy the range [I, E) onto the uninitialized memory
|
||||
/// starting with "Dest", constructing elements into it as needed.
|
||||
template<typename It1, typename It2>
|
||||
template <typename It1, typename It2>
|
||||
static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
|
||||
// Arbitrary iterator types; just use the basic implementation.
|
||||
std::uninitialized_copy(I, E, Dest);
|
||||
}
|
||||
|
||||
/// Copy the range [I, E) onto the uninitialized memory
|
||||
/// starting with "Dest", constructing elements into it as needed.
|
||||
template <typename T1, typename T2>
|
||||
static void uninitialized_copy(
|
||||
T1 *I, T1 *E, T2 *Dest,
|
||||
std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>::value> * =
|
||||
nullptr) {
|
||||
// Use memcpy for PODs iterated by pointers (which includes SmallVector
|
||||
// iterators): std::uninitialized_copy optimizes to memmove, but we can
|
||||
// use memcpy here. Note that I and E are iterators and thus might be
|
||||
// invalid for memcpy if they are equal.
|
||||
if (I != E)
|
||||
memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
|
||||
if constexpr (std::is_pointer_v<It1> && std::is_pointer_v<It2> &&
|
||||
std::is_same_v<
|
||||
std::remove_const_t<std::remove_pointer_t<It1>>,
|
||||
std::remove_pointer_t<It2>>) {
|
||||
// Use memcpy for PODs iterated by pointers (which includes SmallVector
|
||||
// iterators): std::uninitialized_copy optimizes to memmove, but we can
|
||||
// use memcpy here. Note that I and E are iterators and thus might be
|
||||
// invalid for memcpy if they are equal.
|
||||
if (I != E)
|
||||
std::memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
|
||||
} else {
|
||||
// Arbitrary iterator types; just use the basic implementation.
|
||||
std::uninitialized_copy(I, E, Dest);
|
||||
}
|
||||
}
|
||||
|
||||
/// Double the size of the allocated memory, guaranteeing space for at
|
||||
@@ -562,7 +566,7 @@ protected:
|
||||
public:
|
||||
void push_back(ValueParamT Elt) {
|
||||
const T *EltPtr = reserveForParamAndGetAddress(Elt);
|
||||
memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
|
||||
std::memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
|
||||
this->set_size(this->size() + 1);
|
||||
}
|
||||
|
||||
@@ -736,6 +740,12 @@ public:
|
||||
|
||||
void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
|
||||
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
void assign(std::span<const U> AR) {
|
||||
assign(AR.begin(), AR.end());
|
||||
}
|
||||
|
||||
iterator erase(const_iterator CI) {
|
||||
// Just cast away constness because this is a non-const member function.
|
||||
iterator I = const_cast<iterator>(CI);
|
||||
@@ -1230,7 +1240,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename U,
|
||||
typename = std::enable_if_t<std::is_convertible<U, T>::value>>
|
||||
typename = std::enable_if_t<std::is_convertible_v<U, T>>>
|
||||
explicit SmallVector(std::span<const U> A) : SmallVectorImpl<T>(N) {
|
||||
this->append(A.begin(), A.end());
|
||||
}
|
||||
@@ -1291,30 +1301,49 @@ inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
|
||||
|
||||
template <typename RangeType>
|
||||
using ValueTypeFromRangeType =
|
||||
std::remove_const_t<std::remove_reference_t<decltype(*std::begin(
|
||||
std::declval<RangeType &>()))>>;
|
||||
std::remove_const_t<detail::ValueOfRange<RangeType>>;
|
||||
|
||||
/// Given a range of type R, iterate the entire range and return a
|
||||
/// SmallVector with elements of the vector. This is useful, for example,
|
||||
/// when you want to iterate a range and then sort the results.
|
||||
template <unsigned Size, typename R>
|
||||
SmallVector<ValueTypeFromRangeType<R>, Size> to_vector(R &&Range) {
|
||||
return {std::begin(Range), std::end(Range)};
|
||||
return {adl_begin(Range), adl_end(Range)};
|
||||
}
|
||||
template <typename R>
|
||||
SmallVector<ValueTypeFromRangeType<R>> to_vector(R &&Range) {
|
||||
return {std::begin(Range), std::end(Range)};
|
||||
return {adl_begin(Range), adl_end(Range)};
|
||||
}
|
||||
|
||||
template <typename Out, unsigned Size, typename R>
|
||||
SmallVector<Out, Size> to_vector_of(R &&Range) {
|
||||
return {std::begin(Range), std::end(Range)};
|
||||
return {adl_begin(Range), adl_end(Range)};
|
||||
}
|
||||
|
||||
template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) {
|
||||
return {std::begin(Range), std::end(Range)};
|
||||
return {adl_begin(Range), adl_end(Range)};
|
||||
}
|
||||
|
||||
// Provide DenseMapInfo for SmallVector of a type which has info.
|
||||
template <typename T, unsigned N> struct DenseMapInfo<wpi::util::SmallVector<T, N>> {
|
||||
static SmallVector<T, N> getEmptyKey() {
|
||||
return {DenseMapInfo<T>::getEmptyKey()};
|
||||
}
|
||||
|
||||
static SmallVector<T, N> getTombstoneKey() {
|
||||
return {DenseMapInfo<T>::getTombstoneKey()};
|
||||
}
|
||||
|
||||
static unsigned getHashValue(const SmallVector<T, N> &V) {
|
||||
return static_cast<unsigned>(hash_combine_range(V));
|
||||
}
|
||||
|
||||
static bool isEqual(const SmallVector<T, N> &LHS,
|
||||
const SmallVector<T, N> &RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Pred>
|
||||
typename SmallVectorImpl<T>::size_type erase_if(
|
||||
SmallVectorImpl<T>& c, Pred pred) {
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace sys {
|
||||
constexpr bool IsBigEndianHost =
|
||||
wpi::util::endianness::native == wpi::util::endianness::big;
|
||||
|
||||
static const bool IsLittleEndianHost = !IsBigEndianHost;
|
||||
constexpr bool IsLittleEndianHost = !IsBigEndianHost;
|
||||
|
||||
inline unsigned char getSwappedBytes(unsigned char C) { return wpi::util::byteswap(C); }
|
||||
inline signed char getSwappedBytes( signed char C) { return wpi::util::byteswap(C); }
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define WPIUTIL_WPI_VERSIONTUPLE_H
|
||||
|
||||
#include "wpi/util/DenseMapInfo.hpp"
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
@@ -97,9 +98,7 @@ public:
|
||||
|
||||
/// Return a version tuple that contains a different major version but
|
||||
/// everything else is the same.
|
||||
VersionTuple withMajorReplaced(unsigned NewMajor) const {
|
||||
return VersionTuple(NewMajor, Minor, Subminor, Build);
|
||||
}
|
||||
LLVM_ABI VersionTuple withMajorReplaced(unsigned NewMajor) const;
|
||||
|
||||
/// Return a version tuple that contains only components that are non-zero.
|
||||
VersionTuple normalize() const {
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
#ifndef WPIUTIL_WPI_WINDOWSERROR_H
|
||||
#define WPIUTIL_WPI_WINDOWSERROR_H
|
||||
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <system_error>
|
||||
|
||||
namespace wpi::util {
|
||||
std::error_code mapLastWindowsError();
|
||||
std::error_code mapWindowsError(unsigned EV);
|
||||
LLVM_ABI std::error_code mapLastWindowsError();
|
||||
LLVM_ABI std::error_code mapWindowsError(unsigned EV);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define WPIUTIL_WPI_BIT_H
|
||||
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -85,7 +85,9 @@ public:
|
||||
using pointer = PointerT;
|
||||
using reference = ReferenceT;
|
||||
|
||||
protected:
|
||||
// Note: These were previously protected, but MSVC has trouble with SFINAE
|
||||
// accessing protected members in derived class templates (specifically in
|
||||
// iterator_adaptor_base::operator-). Making them public fixes the build.
|
||||
enum {
|
||||
IsRandomAccess = std::is_base_of<std::random_access_iterator_tag,
|
||||
IteratorCategoryT>::value,
|
||||
@@ -93,6 +95,7 @@ protected:
|
||||
IteratorCategoryT>::value,
|
||||
};
|
||||
|
||||
protected:
|
||||
/// A proxy object for computing a reference via indirecting a copy of an
|
||||
/// iterator. This is used in APIs which need to produce a reference via
|
||||
/// indirection but for which the iterator object might be a temporary. The
|
||||
@@ -267,6 +270,8 @@ public:
|
||||
return *static_cast<DerivedT *>(this);
|
||||
}
|
||||
using BaseT::operator-;
|
||||
template <bool Enabled = BaseT::IsRandomAccess,
|
||||
typename = std::enable_if_t<Enabled>>
|
||||
difference_type operator-(const DerivedT &RHS) const {
|
||||
static_assert(
|
||||
BaseT::IsRandomAccess,
|
||||
|
||||
@@ -24,16 +24,6 @@
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
template <typename From, typename To, typename = void>
|
||||
struct explicitly_convertible : std::false_type {};
|
||||
|
||||
template <typename From, typename To>
|
||||
struct explicitly_convertible<
|
||||
From, To,
|
||||
std::void_t<decltype(static_cast<To>(
|
||||
std::declval<std::add_rvalue_reference_t<From>>()))>> : std::true_type {
|
||||
};
|
||||
|
||||
/// A range adaptor for a pair of iterators.
|
||||
///
|
||||
/// This just wraps two iterators into a range-compatible interface. Nothing
|
||||
@@ -42,6 +32,10 @@ template <typename IteratorT>
|
||||
class iterator_range {
|
||||
IteratorT begin_iterator, end_iterator;
|
||||
|
||||
template <typename From, typename To>
|
||||
using explicitly_converted_t = decltype(static_cast<To>(
|
||||
std::declval<std::add_rvalue_reference_t<From>>()));
|
||||
|
||||
public:
|
||||
#if defined(__GNUC__) && \
|
||||
(__GNUC__ == 7 || (__GNUC__ == 8 && __GNUC_MINOR__ < 4))
|
||||
@@ -49,10 +43,9 @@ public:
|
||||
// See https://github.com/llvm/llvm-project/issues/63843
|
||||
template <typename Container>
|
||||
#else
|
||||
template <
|
||||
typename Container,
|
||||
std::enable_if_t<explicitly_convertible<
|
||||
wpi::util::detail::IterOfRange<Container>, IteratorT>::value> * = nullptr>
|
||||
template <typename Container,
|
||||
std::void_t<explicitly_converted_t<
|
||||
wpi::util::detail::IterOfRange<Container>, IteratorT>> * = nullptr>
|
||||
#endif
|
||||
iterator_range(Container &&c)
|
||||
: begin_iterator(adl_begin(c)), end_iterator(adl_end(c)) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef WPIUTIL_WPI_RAW_OS_OSTREAM_H
|
||||
#define WPIUTIL_WPI_RAW_OS_OSTREAM_H
|
||||
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include "wpi/util/raw_ostream.hpp"
|
||||
#include <iosfwd>
|
||||
|
||||
@@ -21,7 +22,7 @@ namespace wpi::util {
|
||||
/// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
|
||||
/// simple adaptor class. It does not check for output errors; clients should
|
||||
/// use the underlying stream to detect errors.
|
||||
class raw_os_ostream : public raw_ostream {
|
||||
class LLVM_ABI raw_os_ostream : public raw_ostream {
|
||||
std::ostream &OS;
|
||||
|
||||
/// write_impl - See raw_ostream::write_impl.
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define WPIUTIL_WPI_RAW_OSTREAM_H
|
||||
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -40,7 +41,7 @@ namespace wpi::util {
|
||||
/// output to a stream. It does not support seeking, reopening, rewinding, line
|
||||
/// buffered disciplines etc. It is a simple buffer that outputs
|
||||
/// a chunk at a time.
|
||||
class raw_ostream {
|
||||
class LLVM_ABI raw_ostream {
|
||||
public:
|
||||
// Class kinds to support LLVM-style RTTI.
|
||||
enum class OStreamKind {
|
||||
@@ -409,7 +410,7 @@ operator<<(OStream &&OS, const T &Value) {
|
||||
/// An abstract base class for streams implementations that also support a
|
||||
/// pwrite operation. This is useful for code that can mostly stream out data,
|
||||
/// but needs to patch in a header that needs to know the output size.
|
||||
class raw_pwrite_stream : public raw_ostream {
|
||||
class LLVM_ABI raw_pwrite_stream : public raw_ostream {
|
||||
virtual void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) = 0;
|
||||
void anchor() override;
|
||||
|
||||
@@ -435,7 +436,7 @@ public:
|
||||
|
||||
/// A raw_ostream that writes to a file descriptor.
|
||||
///
|
||||
class raw_fd_ostream : public raw_pwrite_stream {
|
||||
class LLVM_ABI raw_fd_ostream : public raw_pwrite_stream {
|
||||
int FD;
|
||||
bool ShouldClose;
|
||||
bool SupportsSeeking = false;
|
||||
@@ -548,17 +549,17 @@ public:
|
||||
|
||||
/// This returns a reference to a raw_fd_ostream for standard output. Use it
|
||||
/// like: outs() << "foo" << "bar";
|
||||
raw_fd_ostream &outs();
|
||||
LLVM_ABI raw_fd_ostream &outs();
|
||||
|
||||
/// This returns a reference to a raw_ostream for standard error.
|
||||
/// Use it like: errs() << "foo" << "bar";
|
||||
/// By default, the stream is tied to stdout to ensure stdout is flushed before
|
||||
/// stderr is written, to ensure the error messages are written in their
|
||||
/// expected place.
|
||||
raw_fd_ostream &errs();
|
||||
LLVM_ABI raw_fd_ostream &errs();
|
||||
|
||||
/// This returns a reference to a raw_ostream which simply discards output.
|
||||
raw_ostream &nulls();
|
||||
LLVM_ABI raw_ostream &nulls();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// File Streams
|
||||
@@ -571,10 +572,10 @@ 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(std::string_view Filename, std::error_code &EC);
|
||||
LLVM_ABI raw_fd_stream(std::string_view Filename, std::error_code &EC);
|
||||
|
||||
/// 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);
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -586,7 +587,7 @@ public:
|
||||
/// raw_string_ostream operates without a buffer, delegating all memory
|
||||
/// management to the std::string. Thus the std::string is always up-to-date,
|
||||
/// may be used directly and there is no need to call flush().
|
||||
class raw_string_ostream : public raw_ostream {
|
||||
class LLVM_ABI raw_string_ostream : public raw_ostream {
|
||||
std::string &OS;
|
||||
|
||||
/// See raw_ostream::write_impl.
|
||||
@@ -616,7 +617,7 @@ public:
|
||||
/// 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_svector_ostream : public raw_pwrite_stream {
|
||||
class LLVM_ABI raw_svector_ostream : public raw_pwrite_stream {
|
||||
SmallVectorImpl<char> &OS;
|
||||
|
||||
/// See raw_ostream::write_impl.
|
||||
@@ -660,7 +661,7 @@ public:
|
||||
/// 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<char> &OS;
|
||||
|
||||
/// See raw_ostream::write_impl.
|
||||
@@ -693,7 +694,7 @@ public:
|
||||
/// 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<uint8_t> &OS;
|
||||
|
||||
/// See raw_ostream::write_impl.
|
||||
@@ -727,7 +728,7 @@ public:
|
||||
/// 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<uint8_t> &OS;
|
||||
|
||||
/// See raw_ostream::write_impl.
|
||||
@@ -758,7 +759,7 @@ public:
|
||||
|
||||
|
||||
/// 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.
|
||||
void write_impl(const char *Ptr, size_t size) override;
|
||||
void pwrite_impl(const char *Ptr, size_t Size, uint64_t Offset) override;
|
||||
@@ -768,11 +769,11 @@ class raw_null_ostream : public raw_pwrite_stream {
|
||||
uint64_t current_pos() const override;
|
||||
|
||||
public:
|
||||
explicit raw_null_ostream() = default;
|
||||
explicit raw_null_ostream() : raw_pwrite_stream(/*Unbuffered=*/true) {}
|
||||
~raw_null_ostream() override;
|
||||
};
|
||||
|
||||
class buffer_ostream : public raw_svector_ostream {
|
||||
class LLVM_ABI buffer_ostream : public raw_svector_ostream {
|
||||
raw_ostream &OS;
|
||||
SmallVector<char, 0> Buffer;
|
||||
|
||||
@@ -783,7 +784,7 @@ public:
|
||||
~buffer_ostream() override { OS << str(); }
|
||||
};
|
||||
|
||||
class buffer_unique_ostream : public raw_svector_ostream {
|
||||
class LLVM_ABI buffer_unique_ostream : public raw_svector_ostream {
|
||||
std::unique_ptr<raw_ostream> OS;
|
||||
SmallVector<char, 0> Buffer;
|
||||
|
||||
|
||||
@@ -15,11 +15,9 @@
|
||||
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
|
||||
/// Metafunction that determines whether the given type is either an
|
||||
/// integral type or an enumeration type, including enum classes.
|
||||
///
|
||||
@@ -40,47 +38,28 @@ public:
|
||||
};
|
||||
|
||||
/// If T is a pointer, just return it. If it is not, return T&.
|
||||
template<typename T, typename Enable = void>
|
||||
struct add_lvalue_reference_if_not_pointer { using type = T &; };
|
||||
|
||||
template <typename T>
|
||||
struct add_lvalue_reference_if_not_pointer<
|
||||
T, std::enable_if_t<std::is_pointer_v<T>>> {
|
||||
using type = T;
|
||||
template <typename T> struct add_lvalue_reference_if_not_pointer {
|
||||
using type = std::conditional_t<std::is_pointer_v<T>, T, T &>;
|
||||
};
|
||||
|
||||
/// If T is a pointer to X, return a pointer to const X. If it is not,
|
||||
/// return const T.
|
||||
template<typename T, typename Enable = void>
|
||||
struct add_const_past_pointer { using type = const T; };
|
||||
|
||||
template <typename T>
|
||||
struct add_const_past_pointer<T, std::enable_if_t<std::is_pointer_v<T>>> {
|
||||
using type = const std::remove_pointer_t<T> *;
|
||||
template <typename T> struct add_const_past_pointer {
|
||||
using type = std::conditional_t<std::is_pointer_v<T>,
|
||||
const std::remove_pointer_t<T> *, const T>;
|
||||
};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct const_pointer_or_const_ref {
|
||||
using type = const T &;
|
||||
template <typename T> struct const_pointer_or_const_ref {
|
||||
using type =
|
||||
std::conditional_t<std::is_pointer_v<T>,
|
||||
typename add_const_past_pointer<T>::type, const T &>;
|
||||
};
|
||||
template <typename T>
|
||||
struct const_pointer_or_const_ref<T, std::enable_if_t<std::is_pointer_v<T>>> {
|
||||
using type = typename add_const_past_pointer<T>::type;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<class T>
|
||||
union trivial_helper {
|
||||
T t;
|
||||
};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
// https://stackoverflow.com/questions/55288555/c-check-if-statement-can-be-evaluated-constexpr
|
||||
template<class Lambda, int=(Lambda{}(), 0)>
|
||||
constexpr bool is_constexpr(Lambda) { return true; }
|
||||
constexpr bool is_constexpr(...) { return false; }
|
||||
|
||||
} // end namespace wpi::util
|
||||
} // namespace wpi::util
|
||||
|
||||
#endif // WPIUTIL_WPI_TYPE_TRAITS_H
|
||||
|
||||
@@ -14,9 +14,12 @@
|
||||
#include "CountCopyAndMove.hpp"
|
||||
#include "wpi/util/DenseMapInfo.hpp"
|
||||
#include "wpi/util/DenseMapInfoVariant.hpp"
|
||||
#include "wpi/util/STLForwardCompat.hpp"
|
||||
#include "wpi/util/SmallSet.hpp"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
@@ -71,6 +74,16 @@ public:
|
||||
|
||||
int getValue() const { return Value; }
|
||||
bool operator==(const CtorTester &RHS) const { return Value == RHS.Value; }
|
||||
|
||||
// Return the number of live CtorTester objects, excluding the empty and
|
||||
// tombstone keys.
|
||||
static size_t getNumConstructed() {
|
||||
return std::count_if(Constructed.begin(), Constructed.end(),
|
||||
[](const CtorTester *Obj) {
|
||||
int V = Obj->getValue();
|
||||
return V != -1 && V != -2;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
std::set<CtorTester *> CtorTester::Constructed;
|
||||
@@ -89,6 +102,10 @@ struct CtorTesterMapInfo {
|
||||
CtorTester getTestKey(int i, CtorTester *) { return CtorTester(i); }
|
||||
CtorTester getTestValue(int i, CtorTester *) { return CtorTester(42 + i); }
|
||||
|
||||
std::optional<uint32_t> getTestKey(int i, std::optional<uint32_t> *) {
|
||||
return i;
|
||||
}
|
||||
|
||||
// Test fixture, with helper functions implemented by forwarding to global
|
||||
// function overloads selected by component types of the type parameter. This
|
||||
// allows all of the map implementations to be tested with shared
|
||||
@@ -116,16 +133,17 @@ typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
|
||||
|
||||
// Register these types for testing.
|
||||
// clang-format off
|
||||
typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
|
||||
DenseMap<uint32_t *, uint32_t *>,
|
||||
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
|
||||
DenseMap<EnumClass, uint32_t>,
|
||||
SmallDenseMap<uint32_t, uint32_t>,
|
||||
SmallDenseMap<uint32_t *, uint32_t *>,
|
||||
SmallDenseMap<CtorTester, CtorTester, 4,
|
||||
CtorTesterMapInfo>,
|
||||
SmallDenseMap<EnumClass, uint32_t>
|
||||
> DenseMapTestTypes;
|
||||
using DenseMapTestTypes = ::testing::Types<
|
||||
DenseMap<uint32_t, uint32_t>,
|
||||
DenseMap<uint32_t *, uint32_t *>,
|
||||
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
|
||||
DenseMap<EnumClass, uint32_t>,
|
||||
DenseMap<std::optional<uint32_t>, uint32_t>,
|
||||
SmallDenseMap<uint32_t, uint32_t>,
|
||||
SmallDenseMap<uint32_t *, uint32_t *>,
|
||||
SmallDenseMap<CtorTester, CtorTester, 4, CtorTesterMapInfo>,
|
||||
SmallDenseMap<EnumClass, uint32_t>,
|
||||
SmallDenseMap<std::optional<uint32_t>, uint32_t>>;
|
||||
// clang-format on
|
||||
|
||||
TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, );
|
||||
@@ -186,6 +204,14 @@ TYPED_TEST(DenseMapTest, AtTest) {
|
||||
EXPECT_EQ(this->getValue(0), this->Map.at(this->getKey(0)));
|
||||
EXPECT_EQ(this->getValue(1), this->Map.at(this->getKey(1)));
|
||||
EXPECT_EQ(this->getValue(2), this->Map.at(this->getKey(2)));
|
||||
|
||||
this->Map.at(this->getKey(0)) = this->getValue(1);
|
||||
EXPECT_EQ(this->getValue(1), this->Map.at(this->getKey(0)));
|
||||
|
||||
const auto &ConstMap = this->Map;
|
||||
EXPECT_EQ(this->getValue(1), ConstMap.at(this->getKey(0)));
|
||||
EXPECT_EQ(this->getValue(1), ConstMap.at(this->getKey(1)));
|
||||
EXPECT_EQ(this->getValue(2), ConstMap.at(this->getKey(2)));
|
||||
}
|
||||
|
||||
// Test clear() method
|
||||
@@ -245,6 +271,25 @@ TYPED_TEST(DenseMapTest, CopyConstructorNotSmallTest) {
|
||||
EXPECT_EQ(this->getValue(Key), copyMap[this->getKey(Key)]);
|
||||
}
|
||||
|
||||
// Test range constructors.
|
||||
TYPED_TEST(DenseMapTest, RangeConstructorTest) {
|
||||
using KeyAndValue =
|
||||
std::pair<typename TypeParam::key_type, typename TypeParam::mapped_type>;
|
||||
KeyAndValue PlainArray[] = {{this->getKey(0), this->getValue(0)},
|
||||
{this->getKey(1), this->getValue(1)}};
|
||||
|
||||
TypeParam MapFromRange(wpi::util::from_range, PlainArray);
|
||||
EXPECT_EQ(2u, MapFromRange.size());
|
||||
EXPECT_EQ(this->getValue(0), MapFromRange[this->getKey(0)]);
|
||||
EXPECT_EQ(this->getValue(1), MapFromRange[this->getKey(1)]);
|
||||
|
||||
TypeParam MapFromInitList({{this->getKey(0), this->getValue(1)},
|
||||
{this->getKey(1), this->getValue(2)}});
|
||||
EXPECT_EQ(2u, MapFromInitList.size());
|
||||
EXPECT_EQ(this->getValue(1), MapFromInitList[this->getKey(0)]);
|
||||
EXPECT_EQ(this->getValue(2), MapFromInitList[this->getKey(1)]);
|
||||
}
|
||||
|
||||
// Test copying from a default-constructed map.
|
||||
TYPED_TEST(DenseMapTest, CopyConstructorFromDefaultTest) {
|
||||
TypeParam copyMap(this->Map);
|
||||
@@ -363,6 +408,58 @@ TYPED_TEST(DenseMapTest, ConstIteratorTest) {
|
||||
EXPECT_TRUE(cit == cit2);
|
||||
}
|
||||
|
||||
// TYPED_TEST below cycles through different types. We define UniversalSmallSet
|
||||
// here so that we'll use SmallSet or SmallPtrSet depending on whether the
|
||||
// element type is a pointer.
|
||||
template <typename T, unsigned N>
|
||||
using UniversalSmallSet =
|
||||
std::conditional_t<std::is_pointer_v<T>, SmallPtrSet<T, N>, SmallSet<T, N>>;
|
||||
|
||||
TYPED_TEST(DenseMapTest, KeysValuesIterator) {
|
||||
UniversalSmallSet<typename TypeParam::key_type, 10> Keys;
|
||||
UniversalSmallSet<typename TypeParam::mapped_type, 10> Values;
|
||||
for (int I = 0; I < 10; ++I) {
|
||||
auto K = this->getKey(I);
|
||||
auto V = this->getValue(I);
|
||||
Keys.insert(K);
|
||||
Values.insert(V);
|
||||
this->Map[K] = V;
|
||||
}
|
||||
|
||||
UniversalSmallSet<typename TypeParam::key_type, 10> ActualKeys;
|
||||
UniversalSmallSet<typename TypeParam::mapped_type, 10> ActualValues;
|
||||
for (auto K : this->Map.keys())
|
||||
ActualKeys.insert(K);
|
||||
for (auto V : this->Map.values())
|
||||
ActualValues.insert(V);
|
||||
|
||||
EXPECT_EQ(Keys, ActualKeys);
|
||||
EXPECT_EQ(Values, ActualValues);
|
||||
}
|
||||
|
||||
TYPED_TEST(DenseMapTest, ConstKeysValuesIterator) {
|
||||
UniversalSmallSet<typename TypeParam::key_type, 10> Keys;
|
||||
UniversalSmallSet<typename TypeParam::mapped_type, 10> Values;
|
||||
for (int I = 0; I < 10; ++I) {
|
||||
auto K = this->getKey(I);
|
||||
auto V = this->getValue(I);
|
||||
Keys.insert(K);
|
||||
Values.insert(V);
|
||||
this->Map[K] = V;
|
||||
}
|
||||
|
||||
const TypeParam &ConstMap = this->Map;
|
||||
UniversalSmallSet<typename TypeParam::key_type, 10> ActualKeys;
|
||||
UniversalSmallSet<typename TypeParam::mapped_type, 10> ActualValues;
|
||||
for (auto K : ConstMap.keys())
|
||||
ActualKeys.insert(K);
|
||||
for (auto V : ConstMap.values())
|
||||
ActualValues.insert(V);
|
||||
|
||||
EXPECT_EQ(Keys, ActualKeys);
|
||||
EXPECT_EQ(Values, ActualValues);
|
||||
}
|
||||
|
||||
// Test initializer list construction.
|
||||
TEST(DenseMapCustomTest, InitializerList) {
|
||||
DenseMap<int, int> M({{0, 0}, {0, 1}, {1, 2}});
|
||||
@@ -383,6 +480,28 @@ TEST(DenseMapCustomTest, EqualityComparison) {
|
||||
EXPECT_NE(M1, M3);
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, InsertRange) {
|
||||
DenseMap<int, int> M;
|
||||
|
||||
std::pair<int, int> InputVals[3] = {{0, 0}, {0, 1}, {1, 2}};
|
||||
M.insert_range(InputVals);
|
||||
|
||||
EXPECT_EQ(M.size(), 2u);
|
||||
EXPECT_THAT(M, testing::UnorderedElementsAre(testing::Pair(0, 0),
|
||||
testing::Pair(1, 2)));
|
||||
}
|
||||
|
||||
TEST(SmallDenseMapCustomTest, InsertRange) {
|
||||
SmallDenseMap<int, int> M;
|
||||
|
||||
std::pair<int, int> InputVals[3] = {{0, 0}, {0, 1}, {1, 2}};
|
||||
M.insert_range(InputVals);
|
||||
|
||||
EXPECT_EQ(M.size(), 2u);
|
||||
EXPECT_THAT(M, testing::UnorderedElementsAre(testing::Pair(0, 0),
|
||||
testing::Pair(1, 2)));
|
||||
}
|
||||
|
||||
// Test for the default minimum size of a DenseMap
|
||||
TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
|
||||
// IF THIS VALUE CHANGE, please update InitialSizeTest, InitFromIterator, and
|
||||
@@ -527,6 +646,68 @@ TEST(DenseMapCustomTest, InsertOrAssignTest) {
|
||||
EXPECT_EQ(1, CountCopyAndMove::MoveAssignments);
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, EmplaceOrAssign) {
|
||||
DenseMap<int, CountCopyAndMove> Map;
|
||||
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto Try0 = Map.emplace_or_assign(3, 3);
|
||||
EXPECT_TRUE(Try0.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
|
||||
EXPECT_EQ(1, CountCopyAndMove::ValueConstructions);
|
||||
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto Try1 = Map.emplace_or_assign(3, 4);
|
||||
EXPECT_FALSE(Try1.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(1, CountCopyAndMove::ValueConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(1, CountCopyAndMove::MoveAssignments);
|
||||
|
||||
int Key = 5;
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto Try2 = Map.emplace_or_assign(Key, 3);
|
||||
EXPECT_TRUE(Try2.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
|
||||
EXPECT_EQ(1, CountCopyAndMove::ValueConstructions);
|
||||
|
||||
CountCopyAndMove::ResetCounts();
|
||||
auto Try3 = Map.emplace_or_assign(Key, 4);
|
||||
EXPECT_FALSE(Try3.second);
|
||||
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
|
||||
EXPECT_EQ(1, CountCopyAndMove::ValueConstructions);
|
||||
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
|
||||
EXPECT_EQ(1, CountCopyAndMove::MoveAssignments);
|
||||
}
|
||||
|
||||
struct NonDefaultConstructible {
|
||||
unsigned V;
|
||||
NonDefaultConstructible(unsigned V) : V(V) {};
|
||||
bool operator==(const NonDefaultConstructible &Other) const {
|
||||
return V == Other.V;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(DenseMapCustomTest, LookupOr) {
|
||||
DenseMap<int, NonDefaultConstructible> M;
|
||||
|
||||
M.insert_or_assign(0, 3u);
|
||||
M.insert_or_assign(1, 2u);
|
||||
M.insert_or_assign(1, 0u);
|
||||
|
||||
EXPECT_EQ(M.lookup_or(0, 4u), 3u);
|
||||
EXPECT_EQ(M.lookup_or(1, 4u), 0u);
|
||||
EXPECT_EQ(M.lookup_or(2, 4u), 4u);
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, LookupOrConstness) {
|
||||
DenseMap<int, unsigned *> M;
|
||||
unsigned Default = 3u;
|
||||
unsigned *Ret = M.lookup_or(0, &Default);
|
||||
EXPECT_EQ(Ret, &Default);
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@@ -568,6 +749,15 @@ TEST(DenseMapCustomTest, FindAsTest) {
|
||||
EXPECT_TRUE(map.find_as("d") == map.end());
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, SmallDenseMapFromRange) {
|
||||
std::pair<int, std::string_view> PlainArray[] = {{0, "0"}, {1, "1"}, {2, "2"}};
|
||||
SmallDenseMap<int, std::string_view> M(wpi::util::from_range, PlainArray);
|
||||
EXPECT_EQ(3u, M.size());
|
||||
using testing::Pair;
|
||||
EXPECT_THAT(M, testing::UnorderedElementsAre(Pair(0, "0"), Pair(1, "1"),
|
||||
Pair(2, "2")));
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, SmallDenseMapInitializerList) {
|
||||
SmallDenseMap<int, int> M = {{0, 0}, {0, 1}, {1, 2}};
|
||||
EXPECT_EQ(2u, M.size());
|
||||
@@ -761,4 +951,133 @@ TEST(DenseMapCustomTest, VariantSupport) {
|
||||
EXPECT_FALSE(DenseMapInfo<variant>::isEqual(Keys[2], Keys[2]));
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, InitSize) {
|
||||
constexpr unsigned ElemSize = sizeof(std::pair<int *, int>);
|
||||
|
||||
{
|
||||
DenseMap<int *, int> Map;
|
||||
EXPECT_EQ(ElemSize * 0U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
DenseMap<int *, int> Map(0);
|
||||
EXPECT_EQ(ElemSize * 0U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
DenseMap<int *, int> Map(1);
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
DenseMap<int *, int> Map(2);
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
DenseMap<int *, int> Map(3);
|
||||
EXPECT_EQ(ElemSize * 8U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
int A, B;
|
||||
DenseMap<int *, int> Map = {{&A, 1}, {&B, 2}};
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
int A, B, C;
|
||||
DenseMap<int *, int> Map = {{&A, 1}, {&B, 2}, {&C, 3}};
|
||||
EXPECT_EQ(ElemSize * 8U, Map.getMemorySize());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SmallDenseMapCustomTest, InitSize) {
|
||||
constexpr unsigned ElemSize = sizeof(std::pair<int *, int>);
|
||||
{
|
||||
SmallDenseMap<int *, int> Map;
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
SmallDenseMap<int *, int> Map(0);
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
SmallDenseMap<int *, int> Map(1);
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
SmallDenseMap<int *, int> Map(2);
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
SmallDenseMap<int *, int> Map(3);
|
||||
EXPECT_EQ(ElemSize * 8U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
int A, B;
|
||||
SmallDenseMap<int *, int> Map = {{&A, 1}, {&B, 2}};
|
||||
EXPECT_EQ(ElemSize * 4U, Map.getMemorySize());
|
||||
}
|
||||
{
|
||||
int A, B, C;
|
||||
SmallDenseMap<int *, int> Map = {{&A, 1}, {&B, 2}, {&C, 3}};
|
||||
EXPECT_EQ(ElemSize * 8U, Map.getMemorySize());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, KeyDtor) {
|
||||
// This test relies on CtorTester being non-trivially destructible.
|
||||
static_assert(!std::is_trivially_destructible_v<CtorTester>,
|
||||
"CtorTester must not be trivially destructible");
|
||||
|
||||
// Test that keys are destructed on scope exit.
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
{
|
||||
DenseMap<CtorTester, int, CtorTesterMapInfo> Map;
|
||||
Map.try_emplace(CtorTester(0), 1);
|
||||
Map.try_emplace(CtorTester(1), 2);
|
||||
EXPECT_EQ(2u, CtorTester::getNumConstructed());
|
||||
}
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
|
||||
// Test that keys are destructed on erase and shrink_and_clear.
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
{
|
||||
DenseMap<CtorTester, int, CtorTesterMapInfo> Map;
|
||||
Map.try_emplace(CtorTester(0), 1);
|
||||
Map.try_emplace(CtorTester(1), 2);
|
||||
EXPECT_EQ(2u, CtorTester::getNumConstructed());
|
||||
Map.erase(CtorTester(1));
|
||||
EXPECT_EQ(1u, CtorTester::getNumConstructed());
|
||||
Map.shrink_and_clear();
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
}
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
}
|
||||
|
||||
TEST(DenseMapCustomTest, ValueDtor) {
|
||||
// This test relies on CtorTester being non-trivially destructible.
|
||||
static_assert(!std::is_trivially_destructible_v<CtorTester>,
|
||||
"CtorTester must not be trivially destructible");
|
||||
|
||||
// Test that values are destructed on scope exit.
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
{
|
||||
DenseMap<int, CtorTester> Map;
|
||||
Map.try_emplace(0, CtorTester(1));
|
||||
Map.try_emplace(1, CtorTester(2));
|
||||
EXPECT_EQ(2u, CtorTester::getNumConstructed());
|
||||
}
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
|
||||
// Test that values are destructed on erase and shrink_and_clear.
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
{
|
||||
DenseMap<int, CtorTester> Map;
|
||||
Map.try_emplace(0, CtorTester(1));
|
||||
Map.try_emplace(1, CtorTester(2));
|
||||
EXPECT_EQ(2u, CtorTester::getNumConstructed());
|
||||
Map.erase(1);
|
||||
EXPECT_EQ(1u, CtorTester::getNumConstructed());
|
||||
Map.shrink_and_clear();
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
}
|
||||
EXPECT_EQ(0u, CtorTester::getNumConstructed());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -23,16 +23,15 @@ TEST(Endian, Read) {
|
||||
unsigned char littleval[] = {0x00, 0x04, 0x03, 0x02, 0x01};
|
||||
int32_t BigAsHost = 0x00010203;
|
||||
EXPECT_EQ(BigAsHost,
|
||||
(endian::read<int32_t, wpi::util::endianness::big, unaligned>(bigval)));
|
||||
(endian::read<int32_t, unaligned>(bigval, wpi::util::endianness::big)));
|
||||
int32_t LittleAsHost = 0x02030400;
|
||||
EXPECT_EQ(
|
||||
LittleAsHost,
|
||||
(endian::read<int32_t, wpi::util::endianness::little, unaligned>(littleval)));
|
||||
EXPECT_EQ(LittleAsHost, (endian::read<int32_t, unaligned>(
|
||||
littleval, wpi::util::endianness::little)));
|
||||
|
||||
EXPECT_EQ(
|
||||
(endian::read<int32_t, wpi::util::endianness::big, unaligned>(bigval + 1)),
|
||||
(endian::read<int32_t, wpi::util::endianness::little, unaligned>(littleval +
|
||||
1)));
|
||||
(endian::read<int32_t, unaligned>(bigval + 1, wpi::util::endianness::big)),
|
||||
(endian::read<int32_t, unaligned>(littleval + 1,
|
||||
wpi::util::endianness::little)));
|
||||
}
|
||||
|
||||
TEST(Endian, WriteNext) {
|
||||
@@ -200,26 +199,26 @@ TEST(Endian, WriteBitAligned) {
|
||||
|
||||
TEST(Endian, Write) {
|
||||
unsigned char data[5];
|
||||
endian::write<int32_t, wpi::util::endianness::big, unaligned>(data, -1362446643);
|
||||
endian::write<int32_t, unaligned>(data, -1362446643, wpi::util::endianness::big);
|
||||
EXPECT_EQ(data[0], 0xAE);
|
||||
EXPECT_EQ(data[1], 0xCA);
|
||||
EXPECT_EQ(data[2], 0xB6);
|
||||
EXPECT_EQ(data[3], 0xCD);
|
||||
endian::write<int32_t, wpi::util::endianness::big, unaligned>(data + 1,
|
||||
-1362446643);
|
||||
endian::write<int32_t, unaligned>(data + 1, -1362446643,
|
||||
wpi::util::endianness::big);
|
||||
EXPECT_EQ(data[1], 0xAE);
|
||||
EXPECT_EQ(data[2], 0xCA);
|
||||
EXPECT_EQ(data[3], 0xB6);
|
||||
EXPECT_EQ(data[4], 0xCD);
|
||||
|
||||
endian::write<int32_t, wpi::util::endianness::little, unaligned>(data,
|
||||
-1362446643);
|
||||
endian::write<int32_t, unaligned>(data, -1362446643,
|
||||
wpi::util::endianness::little);
|
||||
EXPECT_EQ(data[0], 0xCD);
|
||||
EXPECT_EQ(data[1], 0xB6);
|
||||
EXPECT_EQ(data[2], 0xCA);
|
||||
EXPECT_EQ(data[3], 0xAE);
|
||||
endian::write<int32_t, wpi::util::endianness::little, unaligned>(data + 1,
|
||||
-1362446643);
|
||||
endian::write<int32_t, unaligned>(data + 1, -1362446643,
|
||||
wpi::util::endianness::little);
|
||||
EXPECT_EQ(data[1], 0xCD);
|
||||
EXPECT_EQ(data[2], 0xB6);
|
||||
EXPECT_EQ(data[3], 0xCA);
|
||||
@@ -236,6 +235,7 @@ TEST(Endian, PackedEndianSpecificIntegral) {
|
||||
reinterpret_cast<little32_t *>(little + 1);
|
||||
|
||||
EXPECT_EQ(*big_val, *little_val);
|
||||
EXPECT_EQ(big_val->value(), little_val->value());
|
||||
}
|
||||
|
||||
TEST(Endian, PacketEndianSpecificIntegralAsEnum) {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
using namespace wpi::util;
|
||||
|
||||
|
||||
@@ -152,23 +152,23 @@ TEST(MathExtras, PowerOf2Ceil) {
|
||||
EXPECT_EQ(8U, PowerOf2Ceil(7U));
|
||||
}
|
||||
|
||||
TEST(MathExtras, CTLog2) {
|
||||
EXPECT_EQ(CTLog2<1ULL << 0>(), 0U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 1>(), 1U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 2>(), 2U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 3>(), 3U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 4>(), 4U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 5>(), 5U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 6>(), 6U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 7>(), 7U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 8>(), 8U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 9>(), 9U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 10>(), 10U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 11>(), 11U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 12>(), 12U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 13>(), 13U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 14>(), 14U);
|
||||
EXPECT_EQ(CTLog2<1ULL << 15>(), 15U);
|
||||
TEST(MathExtras, ConstantLog2) {
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 0>(), 0U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 1>(), 1U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 2>(), 2U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 3>(), 3U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 4>(), 4U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 5>(), 5U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 6>(), 6U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 7>(), 7U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 8>(), 8U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 9>(), 9U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 10>(), 10U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 11>(), 11U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 12>(), 12U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 13>(), 13U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 14>(), 14U);
|
||||
EXPECT_EQ(ConstantLog2<1ULL << 15>(), 15U);
|
||||
}
|
||||
|
||||
TEST(MathExtras, MinAlign) {
|
||||
|
||||
@@ -12,9 +12,9 @@ using namespace wpi::util;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef PointerUnion<int *, float *> PU;
|
||||
typedef PointerUnion<int *, float *, long long *> PU3;
|
||||
typedef PointerUnion<int *, float *, long long *, double *> PU4;
|
||||
using PU = PointerUnion<int *, float *>;
|
||||
using PU3 = PointerUnion<int *, float *, long long *>;
|
||||
using PU4 = PointerUnion<int *, float *, long long *, double *>;
|
||||
|
||||
struct PointerUnionTest : public testing::Test {
|
||||
float f;
|
||||
@@ -116,9 +116,9 @@ TEST_F(PointerUnionTest, Get) {
|
||||
|
||||
template<int I> struct alignas(8) Aligned {};
|
||||
|
||||
typedef PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *,
|
||||
Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *>
|
||||
PU8;
|
||||
using PU8 =
|
||||
PointerUnion<Aligned<0> *, Aligned<1> *, Aligned<2> *, Aligned<3> *,
|
||||
Aligned<4> *, Aligned<5> *, Aligned<6> *, Aligned<7> *>;
|
||||
|
||||
TEST_F(PointerUnionTest, ManyElements) {
|
||||
Aligned<0> a0;
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include "CountCopyAndMove.hpp"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
@@ -45,6 +49,25 @@ TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRefT) {
|
||||
wpi::util::remove_cvref_t<From>>::value));
|
||||
}
|
||||
|
||||
template <typename T> class TypeIdentityTest : public ::testing::Test {
|
||||
public:
|
||||
using TypeIdentity = wpi::util::type_identity<T>;
|
||||
};
|
||||
|
||||
struct A {
|
||||
struct B {};
|
||||
};
|
||||
using TypeIdentityTestTypes =
|
||||
::testing::Types<int, volatile int, A, const A::B>;
|
||||
|
||||
TYPED_TEST_SUITE(TypeIdentityTest, TypeIdentityTestTypes, /*NameGenerator*/);
|
||||
|
||||
TYPED_TEST(TypeIdentityTest, Identity) {
|
||||
// TestFixture is the instantiated TypeIdentityTest.
|
||||
EXPECT_TRUE(
|
||||
(std::is_same_v<TypeParam, typename TestFixture::TypeIdentity::type>));
|
||||
}
|
||||
|
||||
TEST(TransformTest, TransformStd) {
|
||||
std::optional<int> A;
|
||||
|
||||
@@ -123,6 +146,26 @@ TEST(TransformTest, MoveTransformLlvm) {
|
||||
EXPECT_EQ(0, CountCopyAndMove::Destructions);
|
||||
}
|
||||
|
||||
TEST(TransformTest, TransformCategory) {
|
||||
struct StructA {
|
||||
int x;
|
||||
};
|
||||
struct StructB : StructA {
|
||||
StructB(StructA &&A) : StructA(std::move(A)) {}
|
||||
};
|
||||
|
||||
std::optional<StructA> A{StructA{}};
|
||||
wpi::util::transformOptional(A, [](auto &&s) {
|
||||
EXPECT_FALSE(std::is_rvalue_reference_v<decltype(s)>);
|
||||
return StructB{std::move(s)};
|
||||
});
|
||||
|
||||
wpi::util::transformOptional(std::move(A), [](auto &&s) {
|
||||
EXPECT_TRUE(std::is_rvalue_reference_v<decltype(s)>);
|
||||
return StructB{std::move(s)};
|
||||
});
|
||||
}
|
||||
|
||||
TEST(TransformTest, ToUnderlying) {
|
||||
enum E { A1 = 0, B1 = -1 };
|
||||
static_assert(wpi::util::to_underlying(A1) == 0);
|
||||
@@ -140,4 +183,26 @@ TEST(TransformTest, ToUnderlying) {
|
||||
static_assert(wpi::util::to_underlying(E3::B3) == 0);
|
||||
}
|
||||
|
||||
TEST(STLForwardCompatTest, IdentityCxx20) {
|
||||
wpi::util::identity identity;
|
||||
|
||||
// Test with an lvalue.
|
||||
int X = 42;
|
||||
int &Y = identity(X);
|
||||
EXPECT_EQ(&X, &Y);
|
||||
|
||||
// Test with a const lvalue.
|
||||
const int CX = 10;
|
||||
const int &CY = identity(CX);
|
||||
EXPECT_EQ(&CX, &CY);
|
||||
|
||||
// Test with an rvalue.
|
||||
EXPECT_EQ(identity(123), 123);
|
||||
|
||||
// Test perfect forwarding.
|
||||
static_assert(std::is_same_v<int &, decltype(identity(X))>);
|
||||
static_assert(std::is_same_v<const int &, decltype(identity(CX))>);
|
||||
static_assert(std::is_same_v<int &&, decltype(identity(int(5)))>);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -58,7 +58,7 @@ TEST(SmallPtrSetTest, GrowthTest) {
|
||||
|
||||
|
||||
SmallPtrSet<int *, 4> s;
|
||||
typedef SmallPtrSet<int *, 4>::iterator iter;
|
||||
using iter = SmallPtrSet<int *, 4>::iterator;
|
||||
|
||||
s.insert(&buf[0]);
|
||||
s.insert(&buf[1]);
|
||||
@@ -412,6 +412,25 @@ TEST(SmallPtrSetTest, RemoveIf) {
|
||||
EXPECT_FALSE(Removed);
|
||||
}
|
||||
|
||||
TEST(SmallPtrSetTest, CtorRange) {
|
||||
int V0 = 0;
|
||||
int V1 = 1;
|
||||
int V2 = 2;
|
||||
int *Args[] = {&V2, &V0, &V1};
|
||||
SmallPtrSet<int *, 4> Set(wpi::util::from_range, Args);
|
||||
EXPECT_THAT(Set, UnorderedElementsAre(&V0, &V1, &V2));
|
||||
}
|
||||
|
||||
TEST(SmallPtrSetTest, InsertRange) {
|
||||
int V0 = 0;
|
||||
int V1 = 1;
|
||||
int V2 = 2;
|
||||
SmallPtrSet<int *, 4> Set;
|
||||
int *Args[] = {&V2, &V0, &V1};
|
||||
Set.insert_range(Args);
|
||||
EXPECT_THAT(Set, UnorderedElementsAre(&V0, &V1, &V2));
|
||||
}
|
||||
|
||||
TEST(SmallPtrSetTest, Reserve) {
|
||||
// Check that we don't do anything silly when using reserve().
|
||||
SmallPtrSet<int *, 4> Set;
|
||||
@@ -457,4 +476,8 @@ TEST(SmallPtrSetTest, Reserve) {
|
||||
EXPECT_EQ(Set.capacity(), 128u);
|
||||
EXPECT_EQ(Set.size(), 6u);
|
||||
EXPECT_THAT(Set, UnorderedElementsAre(&Vals[0], &Vals[1], &Vals[2], &Vals[3], &Vals[4], &Vals[5]));
|
||||
|
||||
// Reserving 192 should result in 256 buckets.
|
||||
Set.reserve(192);
|
||||
EXPECT_EQ(Set.capacity(), 256u);
|
||||
}
|
||||
|
||||
@@ -24,13 +24,6 @@ TEST(SmallSetTest, ConstructorIteratorPair) {
|
||||
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
|
||||
}
|
||||
|
||||
TEST(SmallSet, ConstructorRange) {
|
||||
std::initializer_list<int> L = {1, 2, 3, 4, 5};
|
||||
|
||||
SmallSet<int, 4> S(wpi::util::make_range(std::begin(L), std::end(L)));
|
||||
EXPECT_THAT(S, testing::UnorderedElementsAreArray(L));
|
||||
}
|
||||
|
||||
TEST(SmallSet, ConstructorInitializerList) {
|
||||
std::initializer_list<int> L = {1, 2, 3, 4, 5};
|
||||
SmallSet<int, 4> S = {1, 2, 3, 4, 5};
|
||||
@@ -127,6 +120,19 @@ TEST(SmallSetTest, InsertPerfectFwd) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(SmallSetTest, CtorRange) {
|
||||
constexpr unsigned Args[] = {3, 1, 2};
|
||||
SmallSet<int, 4> s1(wpi::util::from_range, Args);
|
||||
EXPECT_THAT(s1, ::testing::UnorderedElementsAre(1, 2, 3));
|
||||
}
|
||||
|
||||
TEST(SmallSetTest, InsertRange) {
|
||||
SmallSet<int, 4> s1;
|
||||
constexpr unsigned Args[] = {3, 1, 2};
|
||||
s1.insert_range(Args);
|
||||
EXPECT_THAT(s1, ::testing::UnorderedElementsAre(1, 2, 3));
|
||||
}
|
||||
|
||||
TEST(SmallSetTest, Grow) {
|
||||
SmallSet<int, 4> s1;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
// Test fixture class
|
||||
class SmallStringTest : public testing::Test {
|
||||
protected:
|
||||
typedef SmallString<40> StringType;
|
||||
using StringType = SmallString<40>;
|
||||
|
||||
StringType theString;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/Compiler.hpp"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <array>
|
||||
#include <list>
|
||||
@@ -132,24 +133,24 @@ public:
|
||||
return c0.getValue() == c1.getValue();
|
||||
}
|
||||
|
||||
friend bool LLVM_ATTRIBUTE_UNUSED operator!=(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
[[maybe_unused]] friend bool operator!=(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
return c0.getValue() != c1.getValue();
|
||||
}
|
||||
|
||||
friend bool operator<(const Constructable &c0, const Constructable &c1) {
|
||||
return c0.getValue() < c1.getValue();
|
||||
}
|
||||
friend bool LLVM_ATTRIBUTE_UNUSED operator<=(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
[[maybe_unused]] friend bool operator<=(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
return c0.getValue() <= c1.getValue();
|
||||
}
|
||||
friend bool LLVM_ATTRIBUTE_UNUSED operator>(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
[[maybe_unused]] friend bool operator>(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
return c0.getValue() > c1.getValue();
|
||||
}
|
||||
friend bool LLVM_ATTRIBUTE_UNUSED operator>=(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
[[maybe_unused]] friend bool operator>=(const Constructable &c0,
|
||||
const Constructable &c1) {
|
||||
return c0.getValue() >= c1.getValue();
|
||||
}
|
||||
};
|
||||
@@ -163,7 +164,7 @@ int Constructable::numCopyAssignmentCalls;
|
||||
int Constructable::numMoveAssignmentCalls;
|
||||
|
||||
struct NonCopyable {
|
||||
NonCopyable() {}
|
||||
NonCopyable() = default;
|
||||
NonCopyable(NonCopyable &&) {}
|
||||
NonCopyable &operator=(NonCopyable &&) { return *this; }
|
||||
private:
|
||||
@@ -230,13 +231,10 @@ protected:
|
||||
VectorT otherVector;
|
||||
};
|
||||
|
||||
|
||||
typedef ::testing::Types<SmallVector<Constructable, 0>,
|
||||
SmallVector<Constructable, 1>,
|
||||
SmallVector<Constructable, 2>,
|
||||
SmallVector<Constructable, 4>,
|
||||
SmallVector<Constructable, 5>
|
||||
> SmallVectorTestTypes;
|
||||
using SmallVectorTestTypes = ::testing::Types<
|
||||
SmallVector<Constructable, 0>, SmallVector<Constructable, 1>,
|
||||
SmallVector<Constructable, 2>, SmallVector<Constructable, 4>,
|
||||
SmallVector<Constructable, 5>>;
|
||||
TYPED_TEST_SUITE(SmallVectorTest, SmallVectorTestTypes, );
|
||||
|
||||
// Constructor test.
|
||||
@@ -541,11 +539,11 @@ TYPED_TEST(SmallVectorTest, AppendNonIterTest) {
|
||||
}
|
||||
|
||||
struct output_iterator {
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef int value_type;
|
||||
typedef int difference_type;
|
||||
typedef value_type *pointer;
|
||||
typedef value_type &reference;
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using value_type = int;
|
||||
using difference_type = int;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
operator int() { return 2; }
|
||||
operator Constructable() { return 7; }
|
||||
};
|
||||
@@ -604,6 +602,15 @@ TYPED_TEST(SmallVectorTest, AssignSmallVector) {
|
||||
assertValuesInOrder(V, 2u, 7, 7);
|
||||
}
|
||||
|
||||
TYPED_TEST(SmallVectorTest, AssignSpan) {
|
||||
SCOPED_TRACE("AssignSpan");
|
||||
auto &V = this->theVector;
|
||||
Constructable Other[] = {7, 8, 9};
|
||||
V.push_back(Constructable(1));
|
||||
V.assign(std::span<const Constructable>(Other));
|
||||
assertValuesInOrder(V, 3u, 7, 8, 9);
|
||||
}
|
||||
|
||||
// Move-assign test
|
||||
TYPED_TEST(SmallVectorTest, MoveAssignTest) {
|
||||
SCOPED_TRACE("MoveAssignTest");
|
||||
@@ -891,7 +898,7 @@ protected:
|
||||
VectorT2 otherVector;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<
|
||||
using DualSmallVectorTestTypes = ::testing::Types<
|
||||
// Small mode -> Small mode.
|
||||
std::pair<SmallVector<Constructable, 4>, SmallVector<Constructable, 4>>,
|
||||
// Small mode -> Big mode.
|
||||
@@ -899,8 +906,7 @@ typedef ::testing::Types<
|
||||
// Big mode -> Small mode.
|
||||
std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 4>>,
|
||||
// Big mode -> Big mode.
|
||||
std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>>
|
||||
> DualSmallVectorTestTypes;
|
||||
std::pair<SmallVector<Constructable, 2>, SmallVector<Constructable, 2>>>;
|
||||
|
||||
TYPED_TEST_SUITE(DualSmallVectorsTest, DualSmallVectorTestTypes, );
|
||||
|
||||
@@ -1134,6 +1140,17 @@ TEST(SmallVectorTest, DefaultInlinedElements) {
|
||||
EXPECT_EQ(NestedV[0][0][0], 42);
|
||||
}
|
||||
|
||||
namespace namespace_with_adl {
|
||||
struct MyVector {
|
||||
std::vector<int> data;
|
||||
};
|
||||
|
||||
std::vector<int>::const_iterator begin(const MyVector &V) {
|
||||
return V.data.begin();
|
||||
}
|
||||
std::vector<int>::const_iterator end(const MyVector &V) { return V.data.end(); }
|
||||
} // namespace namespace_with_adl
|
||||
|
||||
TEST(SmallVectorTest, ToVector) {
|
||||
{
|
||||
std::vector<char> v = {'a', 'b', 'c'};
|
||||
@@ -1151,6 +1168,15 @@ TEST(SmallVectorTest, ToVector) {
|
||||
for (size_t I = 0; I < v.size(); ++I)
|
||||
EXPECT_EQ(v[I], Vector[I]);
|
||||
}
|
||||
{
|
||||
// Check that to_vector and to_vector_of work with types that require ADL
|
||||
// for being/end iterators.
|
||||
namespace_with_adl::MyVector V = {{1, 2, 3}};
|
||||
auto IntVector = to_vector(V);
|
||||
EXPECT_THAT(IntVector, testing::ElementsAre(1, 2, 3));
|
||||
IntVector = to_vector<3>(V);
|
||||
EXPECT_THAT(IntVector, testing::ElementsAre(1, 2, 3));
|
||||
}
|
||||
}
|
||||
|
||||
struct To {
|
||||
@@ -1209,6 +1235,15 @@ TEST(SmallVectorTest, ToVectorOf) {
|
||||
for (size_t I = 0; I < StdVector.size(); ++I)
|
||||
EXPECT_EQ(StdVector[I], Vector[I]);
|
||||
}
|
||||
{
|
||||
// Check that to_vector works with types that require ADL for being/end
|
||||
// iterators.
|
||||
namespace_with_adl::MyVector V = {{1, 2, 3}};
|
||||
auto UnsignedVector = to_vector_of<unsigned>(V);
|
||||
EXPECT_THAT(UnsignedVector, testing::ElementsAre(1u, 2u, 3u));
|
||||
UnsignedVector = to_vector_of<unsigned, 3>(V);
|
||||
EXPECT_THAT(UnsignedVector, testing::ElementsAre(1u, 2u, 3u));
|
||||
}
|
||||
}
|
||||
|
||||
template <class VectorT>
|
||||
|
||||
Reference in New Issue
Block a user