[upstream_utils] Upgrade to LLVM 22.1.6 (#8919)

This commit is contained in:
Tyler Veness
2026-05-26 16:25:29 -07:00
committed by GitHub
parent 1392db4529
commit 254ca64106
86 changed files with 3236 additions and 2328 deletions

View File

@@ -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,

View File

@@ -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,
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,12 +445,12 @@ 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,
-LLVM_ABI bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
+LLVM_ABI bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source,
char *&ResultPtr, const UTF8 *&ErrorPtr);
/**
@@ -442,76 +458,79 @@ index c892bb3c03cb569994429649bdbb96e4118dcef1..5c0e3009c25446a34882fb98329b1d95
+* 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,
-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,
-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);
/// Convert from UTF16 to the current code page used in the system
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 @@
@@ -526,27 +545,46 @@ index 9c8e3448f3a03e3540adb8b9dd730c77dd9b20ba..68c27a8c67c4f378b92cfa726659ef78
-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,
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]] void report_fatal_error(StringRef reason,
+[[noreturn]] void report_fatal_error(const std::string &reason,
-[[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]] void report_fatal_error(const Twine &reason,
+[[noreturn]] void report_fatal_error(std::string_view reason,
-[[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,
-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;
};

View File

@@ -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)

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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,
- 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 {

View File

@@ -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.

View File

@@ -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,
-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() {}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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,
-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,
-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)) {

View File

@@ -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>

View File

@@ -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)

View File

@@ -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>

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 @@

View File

@@ -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)) {

View File

@@ -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,64 +125,50 @@ 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.
-///
-/// 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.
@@ -156,62 +179,30 @@ 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);
-}
-
-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);
- // 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;
- _BitScanReverse(&Index, Val);
- return Index ^ 31;
- _BitScanForward(&Index, Val);
- return Index;
-#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)
- } 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;
- _BitScanReverse64(&Index, Val);
- return Index ^ 63;
- _BitScanForward64(&Index, Val);
- return Index;
-#endif
- }
-};
-#endif
-#endif
-} // namespace detail
-
- return countr_zero_constexpr(Val);
-}
-
-/// 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
-/// 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);
-}
-};
-
-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);
-}
-
-// 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) {

View File

@@ -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>);

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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;

View File

@@ -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(

View File

@@ -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");

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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\"")

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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);
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 + MinNonEmpty, RHS.CurArray + RHS.NumNonEmpty,
this->CurArray + MinNonEmpty);
std::copy(RHS.CurArray + MinEntries, RHS.CurArray + RHS.NumEntries,
this->CurArray + MinEntries);
}
assert(this->CurArraySize == RHS.CurArraySize);
std::swap(this->NumNonEmpty, RHS.NumNonEmpty);
std::swap(this->NumEntries, RHS.NumEntries);
std::swap(this->NumTombstones, RHS.NumTombstones);
return;
}
// 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;
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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

View File

@@ -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; }
};

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {
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 */
} ConversionResult;
};
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,
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,26 +331,32 @@ 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,
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,
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,
LLVM_ABI std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
SmallVectorImpl<char> &utf8);
} // namespace windows
} // namespace sys

File diff suppressed because it is too large Load Diff

View File

@@ -17,6 +17,8 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <optional>
#include <tuple>
#include <type_traits>
#include <utility>
@@ -50,8 +52,8 @@ 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 constexpr T getEmptyKey();
// static constexpr T getTombstoneKey();
// static unsigned getHashValue(const T &Val);
// static bool isEqual(const T &LHS, const T &RHS);
};
@@ -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) {
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>;
std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
return detail::combineHashValue(
DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
getHashValueImpl<I + 1>(values, atEnd));
getHashValueImpl<I + 1>(values));
}
template <unsigned I>
static unsigned getHashValueImpl(const Tuple &, std::true_type) {
return 0;
}
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

View File

@@ -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>;

View File

@@ -13,6 +13,7 @@
#ifndef WPIUTIL_WPI_ERRNO_H
#define WPIUTIL_WPI_ERRNO_H
#include "wpi/util/Compiler.hpp"
#include <cerrno>
#include <string>

View File

@@ -21,8 +21,7 @@
namespace wpi::util {
/// An error handler callback.
typedef void (*fatal_error_handler_t)(void *user_data,
const char *reason,
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
@@ -41,11 +40,11 @@ namespace wpi::util {
///
/// \param user_data - An argument which will be passed to the install error
/// handler.
void install_fatal_error_handler(fatal_error_handler_t handler,
LLVM_ABI void install_fatal_error_handler(fatal_error_handler_t handler,
void *user_data = nullptr);
/// Restores default error handling behaviour.
void remove_fatal_error_handler();
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
@@ -59,20 +58,43 @@ namespace wpi::util {
~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.)
/// @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.
///
/// 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);
/// 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,
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,
[[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,
[[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.

View File

@@ -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>

View 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

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}
};

View File

@@ -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 &&

View File

@@ -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()); }

View File

@@ -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

View File

@@ -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;
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));
}
// 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));
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

View File

@@ -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,
LLVM_ABI SmallPtrSetImplBase(const void **SmallStorage,
const SmallPtrSetImplBase &that);
SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
const void **RHSSmallStorage, 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,26 +110,26 @@ 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);
@@ -140,7 +145,23 @@ protected:
}
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.
}
@@ -173,10 +192,9 @@ protected:
/// in.
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();
@@ -202,11 +221,9 @@ protected:
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;
LLVM_ABI const void *const *doFind(const void *Ptr) const;
const void *const *FindBucketFor(const void *Ptr) const;
void shrink_and_clear();
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,
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();
increment();
return *this;
}
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,18 +471,24 @@ public:
insert(IL.begin(), IL.end());
}
iterator begin() const {
if (shouldReverseIterate())
template <typename Range> void insert_range(Range &&R) {
insert(adl_begin(R), adl_end(R));
}
[[nodiscard]] iterator begin() const {
if constexpr (shouldReverseIterate())
return makeIterator(EndPointer() - 1);
else
return makeIterator(CurArray);
}
iterator end() const { return makeIterator(EndPointer()); }
[[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);
else
return iterator(P, EndPointer(), *this);
}
};
@@ -490,7 +498,7 @@ 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,
[[nodiscard]] bool operator==(const SmallPtrSetImpl<PtrType> &LHS,
const SmallPtrSetImpl<PtrType> &RHS) {
if (LHS.size() != RHS.size())
return false;
@@ -506,7 +514,7 @@ bool operator==(const SmallPtrSetImpl<PtrType> &LHS,
///
/// Equivalent to !(LHS == RHS).
template <typename PtrType>
bool operator!=(const SmallPtrSetImpl<PtrType> &LHS,
[[nodiscard]] bool operator!=(const SmallPtrSetImpl<PtrType> &LHS,
const SmallPtrSetImpl<PtrType> &RHS) {
return !(LHS == RHS);
}
@@ -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];
@@ -551,6 +549,10 @@ public:
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,7 +586,7 @@ public:
}
};
} // end namespace wpi::util
} // namespace wpi::util
namespace std {
@@ -594,6 +596,6 @@ namespace std {
LHS.swap(RHS);
}
} // end namespace std
} // namespace std
#endif // WPIUTIL_WPI_SMALLPTRSET_H

View File

@@ -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();
@@ -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);
}

View File

@@ -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,
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) {
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);
}
template <
class ItTy,
std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
bool> = false>
void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
(void)From;
(void)To;
}
/// Check whether any part of the range will be invalidated by growing.
void assertSafeToAddRange(const T *From, const T *To) {
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);
}
template <
class ItTy,
std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
bool> = false>
void assertSafeToAddRange(ItTy, ItTy) {}
(void)From;
(void)To;
}
/// Reserve enough space to add one element, and return the updated element
/// pointer in case it was a reference to the storage.
@@ -503,23 +510,20 @@ protected:
/// starting with "Dest", constructing elements into it as needed.
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) {
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)
memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
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) {

View File

@@ -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); }

View File

@@ -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 {

View File

@@ -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

View File

@@ -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>

View File

@@ -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,

View File

@@ -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)) {

View File

@@ -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.

View File

@@ -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;

View File

@@ -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

View File

@@ -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>,
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>
> DenseMapTestTypes;
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

View File

@@ -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) {

View File

@@ -11,7 +11,6 @@
#include "gtest/gtest.h"
#include <memory>
#include <type_traits>
using namespace wpi::util;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -23,7 +23,7 @@ namespace {
// Test fixture class
class SmallStringTest : public testing::Test {
protected:
typedef SmallString<40> StringType;
using StringType = SmallString<40>;
StringType theString;

View File

@@ -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,7 +133,7 @@ public:
return c0.getValue() == c1.getValue();
}
friend bool LLVM_ATTRIBUTE_UNUSED operator!=(const Constructable &c0,
[[maybe_unused]] friend bool operator!=(const Constructable &c0,
const Constructable &c1) {
return c0.getValue() != c1.getValue();
}
@@ -140,15 +141,15 @@ public:
friend bool operator<(const Constructable &c0, const Constructable &c1) {
return c0.getValue() < c1.getValue();
}
friend bool LLVM_ATTRIBUTE_UNUSED operator<=(const Constructable &c0,
[[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,
[[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,
[[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>