diff --git a/docs/build.gradle b/docs/build.gradle index 5ac88ac9bc..6ef7c6da96 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -73,6 +73,7 @@ doxygen { // LLVM exclude 'wpi/AlignOf.h' + exclude 'wpi/Casting.h' exclude 'wpi/Chrono.h' exclude 'wpi/Compiler.h' exclude 'wpi/ConvertUTF.h' @@ -83,6 +84,7 @@ doxygen { exclude 'wpi/Errc.h' exclude 'wpi/Errno.h' exclude 'wpi/ErrorHandling.h' + exclude 'wpi/bit.h' exclude 'wpi/fs.h' exclude 'wpi/FunctionExtras.h' exclude 'wpi/function_ref.h' diff --git a/upstream_utils/README.md b/upstream_utils/README.md index 2ce0f6f24d..f4ce090ce9 100644 --- a/upstream_utils/README.md +++ b/upstream_utils/README.md @@ -39,11 +39,20 @@ git fetch origin 2.0 git fetch --depth 1 origin tag 2.0 ``` -Rebase any patches onto the new version. +Rebase any patches onto the new version. If the old version and new version are +on the same branch, run the following. ```bash git rebase 2.0 ``` +If the old version and new version are on different branches (e.g., +llvm-project), use interactive rebase instead and remove commits that are common +between the two branches from the list of commits to rebase. In other words, +only commits representing downstream patches should be listed. +```bash +git rebase -i 2.0 +``` + Generate patch files for the new version. ```bash git format-patch 2.0..HEAD --zero-commit --abbrev=40 --no-signature diff --git a/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch b/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch index ce08d7e384..2f9b1df6be 100644 --- a/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch +++ b/upstream_utils/llvm_patches/0001-Fix-spelling-language-errors.patch @@ -8,7 +8,7 @@ Subject: [PATCH 01/30] Fix spelling/language errors 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h -index f980510d37f0644bceea5b54e1469625b8115c97..6791df6be3362fa199556ecb2131f971cfef5210 100644 +index 9c8e3448f3a03e3540adb8b9dd730c77dd9b20ba..dd1384a63af71b50ba1ccbb5933a1e472f50a39b 100644 --- a/llvm/include/llvm/Support/ErrorHandling.h +++ b/llvm/include/llvm/Support/ErrorHandling.h @@ -44,7 +44,7 @@ namespace llvm { diff --git a/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch b/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch index 4eea7fa92f..21aaede35f 100644 --- a/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch +++ b/upstream_utils/llvm_patches/0002-Remove-StringRef-ArrayRef-and-Optional.patch @@ -5,20 +5,21 @@ Subject: [PATCH 02/30] Remove StringRef, ArrayRef, and Optional --- llvm/include/llvm/ADT/PointerUnion.h | 1 - - llvm/include/llvm/ADT/SmallSet.h | 13 ++-- + llvm/include/llvm/ADT/SmallSet.h | 2 +- llvm/include/llvm/ADT/SmallString.h | 77 ++++++++++--------- + llvm/include/llvm/ADT/SmallVector.h | 7 +- llvm/include/llvm/ADT/StringMap.h | 34 ++++---- - llvm/include/llvm/ADT/StringMapEntry.h | 25 +++--- + llvm/include/llvm/ADT/StringMapEntry.h | 20 ++--- llvm/include/llvm/Support/Chrono.h | 10 +-- llvm/include/llvm/Support/Compiler.h | 2 +- - llvm/include/llvm/Support/ConvertUTF.h | 28 ++++--- + llvm/include/llvm/Support/ConvertUTF.h | 31 ++++---- llvm/include/llvm/Support/DJB.h | 6 +- llvm/include/llvm/Support/ErrorHandling.h | 9 +-- .../llvm/Support/SmallVectorMemoryBuffer.h | 6 +- - llvm/include/llvm/Support/VersionTuple.h | 20 ++--- + llvm/include/llvm/Support/VersionTuple.h | 6 -- .../llvm/Support/Windows/WindowsSupport.h | 4 +- - llvm/include/llvm/Support/raw_ostream.h | 51 ++++++------ - llvm/lib/Support/ConvertUTFWrapper.cpp | 32 ++++---- + llvm/include/llvm/Support/raw_ostream.h | 46 ++++++----- + llvm/lib/Support/ConvertUTFWrapper.cpp | 38 ++++----- llvm/lib/Support/ErrorHandling.cpp | 13 ++-- llvm/lib/Support/SmallVector.cpp | 5 +- llvm/lib/Support/StringMap.cpp | 12 +-- @@ -28,13 +29,13 @@ Subject: [PATCH 02/30] Remove StringRef, ArrayRef, and Optional llvm/unittests/ADT/HashingTest.cpp | 2 +- llvm/unittests/ADT/SmallPtrSetTest.cpp | 1 - llvm/unittests/ADT/SmallStringTest.cpp | 50 ++++++------ - llvm/unittests/ADT/SmallVectorTest.cpp | 20 +---- + llvm/unittests/ADT/SmallVectorTest.cpp | 30 ++------ llvm/unittests/ADT/StringMapTest.cpp | 32 ++++---- - llvm/unittests/Support/ConvertUTFTest.cpp | 37 +++++---- - 27 files changed, 248 insertions(+), 304 deletions(-) + llvm/unittests/Support/ConvertUTFTest.cpp | 41 +++++----- + 28 files changed, 247 insertions(+), 300 deletions(-) diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h -index 04d566bbc75e01d4bd648273e1a299de9e1d97b6..1d4cc747ce320e27004170fb0aa76323d2ac22b1 100644 +index 061c4000fcb3532f8d24bf015dffd0e1f58120d2..6abec033a4008057f30d445d47ab22ebbb046a2f 100644 --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h @@ -17,7 +17,6 @@ @@ -42,18 +43,15 @@ index 04d566bbc75e01d4bd648273e1a299de9e1d97b6..1d4cc747ce320e27004170fb0aa76323 #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/STLExtras.h" + #include "llvm/Support/Casting.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include - #include diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h -index 0eed85449c9d6bf88068c8b5c0f5f10ed9b9ff7b..bfe93e997fc896e82a9b96219967f754df82bcfb 100644 +index 5ac868d58314ce42476bee5aa08dee5c7a9d1c17..06bc9b5556dd76432552ee79aa916b850f829f4d 100644 --- a/llvm/include/llvm/ADT/SmallSet.h +++ b/llvm/include/llvm/ADT/SmallSet.h -@@ -14,15 +14,14 @@ - #ifndef LLVM_ADT_SMALLSET_H - #define LLVM_ADT_SMALLSET_H +@@ -16,12 +16,12 @@ --#include "llvm/ADT/None.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" @@ -66,38 +64,8 @@ index 0eed85449c9d6bf88068c8b5c0f5f10ed9b9ff7b..bfe93e997fc896e82a9b96219967f754 #include #include #include -@@ -179,16 +178,16 @@ public: - /// concept. - // FIXME: Add iterators that abstract over the small and large form, and then - // return those here. -- std::pair insert(const T &V) { -+ std::pair insert(const T &V) { - if (!isSmall()) -- return std::make_pair(None, Set.insert(V).second); -+ return std::make_pair(std::nullopt, Set.insert(V).second); - - VIterator I = vfind(V); - if (I != Vector.end()) // Don't reinsert if it already exists. -- return std::make_pair(None, false); -+ return std::make_pair(std::nullopt, false); - if (Vector.size() < N) { - Vector.push_back(V); -- return std::make_pair(None, true); -+ return std::make_pair(std::nullopt, true); - } - - // Otherwise, grow from vector to set. -@@ -197,7 +196,7 @@ public: - Vector.pop_back(); - } - Set.insert(V); -- return std::make_pair(None, true); -+ return std::make_pair(std::nullopt, true); - } - - template diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h -index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28e4177d11 100644 +index 0052c86fb37b82dcdf577a7acf06e3a47f54da61..4d673cc8b1c49cf8a3f19653de53881cd12662ee 100644 --- a/llvm/include/llvm/ADT/SmallString.h +++ b/llvm/include/llvm/ADT/SmallString.h @@ -15,8 +15,9 @@ @@ -171,7 +139,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 std::copy(Ref.begin(), Ref.end(), this->begin() + CurrentSize); CurrentSize += Ref.size(); } -@@ -89,29 +90,29 @@ public: +@@ -89,30 +90,30 @@ public: /// Check for string equality. This is more efficient than compare() when /// the relative ordering of inequal strings isn't needed. @@ -186,8 +154,9 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().equals_insensitive(RHS); } - /// Compare two strings; the result is -1, 0, or 1 if this string is - /// lexicographically less than, equal to, or greater than the \p RHS. + /// compare - Compare two strings; the result is negative, zero, or positive + /// if this string is lexicographically less than, equal to, or greater than + /// the \p RHS. - int compare(StringRef RHS) const { + int compare(std::string_view RHS) const { return str().compare(RHS); @@ -206,7 +175,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().compare_numeric(RHS); } -@@ -120,12 +121,12 @@ public: +@@ -121,12 +122,12 @@ public: /// @{ /// startswith - Check if this string starts with the given \p Prefix. @@ -221,7 +190,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().endswith(Suffix); } -@@ -145,7 +146,7 @@ public: +@@ -146,7 +147,7 @@ public: /// /// \returns The index of the first occurrence of \p Str, or npos if not /// found. @@ -230,7 +199,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().find(Str, From); } -@@ -153,7 +154,7 @@ public: +@@ -154,7 +155,7 @@ public: /// /// \returns The index of the last occurrence of \p C, or npos if not /// found. @@ -239,7 +208,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().rfind(C, From); } -@@ -161,7 +162,7 @@ public: +@@ -162,7 +163,7 @@ public: /// /// \returns The index of the last occurrence of \p Str, or npos if not /// found. @@ -248,7 +217,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().rfind(Str); } -@@ -175,7 +176,7 @@ public: +@@ -176,7 +177,7 @@ public: /// not found. /// /// Complexity: O(size() + Chars.size()) @@ -257,7 +226,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().find_first_of(Chars, From); } -@@ -189,13 +190,13 @@ public: +@@ -190,13 +191,13 @@ public: /// \p Chars, or npos if not found. /// /// Complexity: O(size() + Chars.size()) @@ -273,7 +242,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().find_last_of(C, From); } -@@ -204,7 +205,7 @@ public: +@@ -205,7 +206,7 @@ public: /// /// Complexity: O(size() + Chars.size()) size_t find_last_of( @@ -282,7 +251,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().find_last_of(Chars, From); } -@@ -219,7 +220,7 @@ public: +@@ -220,7 +221,7 @@ public: /// Return the number of non-overlapped occurrences of \p Str in the /// string. @@ -291,7 +260,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().count(Str); } -@@ -236,7 +237,7 @@ public: +@@ -237,7 +238,7 @@ public: /// \param N The number of characters to included in the substring. If \p N /// exceeds the number of characters remaining in the string, the string /// suffix (starting with \p Start) will be returned. @@ -300,7 +269,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 return str().substr(Start, N); } -@@ -250,14 +251,14 @@ public: +@@ -251,14 +252,14 @@ public: /// substring. If this is npos, or less than \p Start, or exceeds the /// number of characters remaining in the string, the string suffix /// (starting with \p Start) will be returned. @@ -318,7 +287,7 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 // TODO: Make this const, if it's safe... const char* c_str() { -@@ -266,20 +267,20 @@ public: +@@ -267,20 +268,20 @@ public: return this->data(); } @@ -343,8 +312,45 @@ index 874968f0a13f3e7de07caf1c42794b36e7a5c237..50cbdade405770e80a6a45521a446a28 this->append(RHS.begin(), RHS.end()); return *this; } +diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h +index 98dce891688dac9530c968e99440e239148faece..92cccb130466a47127fbf8092286f9c5052dd26c 100644 +--- a/llvm/include/llvm/ADT/SmallVector.h ++++ b/llvm/include/llvm/ADT/SmallVector.h +@@ -27,13 +27,12 @@ + #include + #include + #include ++#include + #include + #include + + namespace llvm { + +-template class ArrayRef; +- + template class iterator_range; + + template +@@ -117,7 +116,7 @@ template struct SmallVectorAlignmentAndSize { + }; + + /// This is the part of SmallVectorTemplateBase which does not depend on whether +-/// the type T is a POD. The extra dummy template argument is used by ArrayRef ++/// the type T is a POD. The extra dummy template argument is used by span + /// to avoid unnecessarily requiring T to be complete. + template + class SmallVectorTemplateCommon +@@ -1228,7 +1227,7 @@ public: + + template ::value>> +- explicit SmallVector(ArrayRef A) : SmallVectorImpl(N) { ++ explicit SmallVector(span A) : SmallVectorImpl(N) { + this->append(A.begin(), A.end()); + } + diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h -index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e68571d456 100644 +index 0849bef53ba164dbe524972f6ca5a761c7c10603..1c8cda7ef0f8e2984f2d7960260f2a109a2986f7 100644 --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -60,12 +60,12 @@ protected: @@ -373,14 +379,14 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 /// setup the map as empty. @@ -126,7 +126,7 @@ public: : StringMapImpl(InitialSize, static_cast(sizeof(MapEntryTy))), - Allocator(A) {} + AllocTy(A) {} - StringMap(std::initializer_list> List) + StringMap(std::initializer_list> List) : StringMapImpl(List.size(), static_cast(sizeof(MapEntryTy))) { insert(List); } -@@ -215,14 +215,14 @@ public: +@@ -214,14 +214,14 @@ public: StringMapKeyIterator(end())); } @@ -397,7 +403,7 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 int Bucket = FindKey(Key); if (Bucket == -1) return end(); -@@ -231,7 +231,7 @@ public: +@@ -230,7 +230,7 @@ public: /// lookup - Return the entry for the specified key, or a default /// constructed value if no such entry exists. @@ -406,7 +412,7 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 const_iterator it = find(Key); if (it != end()) return it->second; -@@ -240,10 +240,10 @@ public: +@@ -239,10 +239,10 @@ public: /// Lookup the ValueTy for the \p Key, or create a default constructed value /// if the key is not in the map. @@ -419,7 +425,7 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 template size_type count(const StringMapEntry &MapEntry) const { -@@ -293,7 +293,7 @@ public: +@@ -292,7 +292,7 @@ public: /// isn't already in the map. The bool component of the returned pair is true /// if and only if the insertion takes place, and the iterator component of /// the pair points to the element with key equivalent to the key of the pair. @@ -428,7 +434,7 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 return try_emplace(KV.first, std::move(KV.second)); } -@@ -308,14 +308,14 @@ public: +@@ -307,14 +307,14 @@ public: /// Inserts elements from initializer list ilist. If multiple elements in /// the range have keys that compare equivalent, it is unspecified which /// element is inserted @@ -445,17 +451,17 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 auto Ret = try_emplace(Key, std::forward(Val)); if (!Ret.second) Ret.first->second = std::forward(Val); -@@ -327,7 +327,7 @@ public: +@@ -326,7 +326,7 @@ public: /// if and only if the insertion takes place, and the iterator component of /// the pair points to the element with key equivalent to the key of the pair. template -- std::pair try_emplace(StringRef Key, ArgsTy &&... Args) { -+ std::pair try_emplace(std::string_view Key, ArgsTy &&... Args) { +- std::pair try_emplace(StringRef Key, ArgsTy &&...Args) { ++ std::pair try_emplace(std::string_view Key, ArgsTy &&...Args) { unsigned BucketNo = LookupBucketFor(Key); StringMapEntryBase *&Bucket = TheTable[BucketNo]; if (Bucket && Bucket != getTombstoneVal()) @@ -373,7 +373,7 @@ public: - V.Destroy(Allocator); + V.Destroy(getAllocator()); } - bool erase(StringRef Key) { @@ -485,22 +491,20 @@ index 23248093c67e25505e980bc99c067f8e4aff6fd4..8747cdb353a89952e242ccfa5ea8a3e6 } // end namespace llvm diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h -index 6e13c8618c851d32466f4b44908ffc9d044140f8..39976a02b5ecbbf5d08a6073708cac0a5aef447d 100644 +index 98b51cc1aebd59eba20076e6d8a4eebc0eebb982..388e81c361642113937f7d5680de73a50635b07d 100644 --- a/llvm/include/llvm/ADT/StringMapEntry.h +++ b/llvm/include/llvm/ADT/StringMapEntry.h -@@ -16,9 +16,8 @@ +@@ -16,8 +16,8 @@ #ifndef LLVM_ADT_STRINGMAPENTRY_H #define LLVM_ADT_STRINGMAPENTRY_H --#include "llvm/ADT/None.h" -#include "llvm/ADT/StringRef.h" --#include "llvm/ADT/STLFunctionalExtras.h" -+#include + #include +#include namespace llvm { -@@ -37,13 +36,13 @@ protected: +@@ -36,13 +36,13 @@ protected: /// type-erase the allocator and put it in a source file. template static void *allocateWithKey(size_t EntrySize, size_t EntryAlign, @@ -516,26 +520,9 @@ index 6e13c8618c851d32466f4b44908ffc9d044140f8..39976a02b5ecbbf5d08a6073708cac0a AllocatorTy &Allocator) { size_t KeyLength = Key.size(); -@@ -85,13 +84,13 @@ public: - void setValue(const ValueTy &V) { second = V; } - }; +@@ -105,8 +105,8 @@ public: --template <> class StringMapEntryStorage : public StringMapEntryBase { -+template <> class StringMapEntryStorage : public StringMapEntryBase { - public: -- explicit StringMapEntryStorage(size_t keyLength, NoneType = None) -+ explicit StringMapEntryStorage(size_t keyLength, std::nullopt_t = std::nullopt) - : StringMapEntryBase(keyLength) {} - StringMapEntryStorage(StringMapEntryStorage &entry) = delete; - -- NoneType getValue() const { return None; } -+ std::nullopt_t getValue() const { return std::nullopt; } - }; - - /// StringMapEntry - This is used to represent one value that is inserted into -@@ -102,8 +101,8 @@ class StringMapEntry final : public StringMapEntryStorage { - public: - using StringMapEntryStorage::StringMapEntryStorage; + using ValueType = ValueTy; - StringRef getKey() const { - return StringRef(getKeyData(), this->getKeyLength()); @@ -544,7 +531,7 @@ index 6e13c8618c851d32466f4b44908ffc9d044140f8..39976a02b5ecbbf5d08a6073708cac0a } /// getKeyData - Return the start of the string data that is the key for this -@@ -113,14 +112,14 @@ public: +@@ -116,15 +116,15 @@ public: return reinterpret_cast(this + 1); } @@ -557,11 +544,22 @@ index 6e13c8618c851d32466f4b44908ffc9d044140f8..39976a02b5ecbbf5d08a6073708cac0a /// Create a StringMapEntry for the specified key construct the value using /// \p InitiVals. template -- static StringMapEntry *Create(StringRef key, AllocatorTy &allocator, -+ static StringMapEntry *Create(std::string_view key, AllocatorTy &allocator, - InitTy &&... initVals) { +- static StringMapEntry *create(StringRef key, AllocatorTy &allocator, +- InitTy &&...initVals) { ++ static StringMapEntry *create(std::string_view key, AllocatorTy &allocator, ++ InitTy &&... initVals) { return new (StringMapEntryBase::allocateWithKey( sizeof(StringMapEntry), alignof(StringMapEntry), key, allocator)) + StringMapEntry(key.size(), std::forward(initVals)...); +@@ -167,7 +167,7 @@ struct tuple_size> + + template + struct tuple_element> +- : std::conditional {}; ++ : std::conditional {}; + } // namespace std + + #endif // LLVM_ADT_STRINGMAPENTRY_H diff --git a/llvm/include/llvm/Support/Chrono.h b/llvm/include/llvm/Support/Chrono.h index 9c2bd45d2803e56ed316d8552d899d87f2fbbb07..a7dea19d9193bcff4bc6b553b80a10b2bc7b64af 100644 --- a/llvm/include/llvm/Support/Chrono.h @@ -606,10 +604,10 @@ index 9c2bd45d2803e56ed316d8552d899d87f2fbbb07..a7dea19d9193bcff4bc6b553b80a10b2 bool show_unit = consumeShowUnit(Style); diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index 80b2dfaec4273a9831adc92ffa1a2b2059d9659f..f5d726ec8a2c4c39a31a6a557591a99a64caea3a 100644 +index cf330662cf4b4d2ec759f1d8d253e20210602a95..4a54933031baa90c6f21138fb1f04c5da89878a4 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h -@@ -312,7 +312,7 @@ +@@ -288,7 +288,7 @@ #endif /// LLVM_GSL_POINTER - Apply this to non-owning classes like @@ -619,26 +617,23 @@ index 80b2dfaec4273a9831adc92ffa1a2b2059d9659f..f5d726ec8a2c4c39a31a6a557591a99a #define LLVM_GSL_POINTER [[gsl::Pointer]] #else diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h -index 374cdb907fdc2c41912c2fa606b36e108259fa31..7f1527f51cdf59238607becfb2fdaf4afc91d4b6 100644 +index c892bb3c03cb569994429649bdbb96e4118dcef1..5c0e3009c25446a34882fb98329b1d955231bb39 100644 --- a/llvm/include/llvm/Support/ConvertUTF.h +++ b/llvm/include/llvm/Support/ConvertUTF.h -@@ -89,12 +89,12 @@ - #ifndef LLVM_SUPPORT_CONVERTUTF_H - #define LLVM_SUPPORT_CONVERTUTF_H +@@ -107,10 +107,9 @@ -+#include "wpi/span.h" -+ #include #include - -#if defined(_WIN32) ++#include +#include #include -#endif // Wrap everything in namespace llvm so that programs can link with llvm and // their own version of the unicode libraries. -@@ -183,12 +183,10 @@ unsigned getNumBytesForUTF8(UTF8 firstByte); +@@ -204,12 +203,10 @@ unsigned getNumBytesForUTF8(UTF8 firstByte); /*************************************************************************/ /* Below are LLVM-specific wrappers of the functions above. */ @@ -652,7 +647,7 @@ index 374cdb907fdc2c41912c2fa606b36e108259fa31..7f1527f51cdf59238607becfb2fdaf4a * WideCharWidth. The converted data is written to ResultPtr, which needs to * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success, * ResultPtr will point one after the end of the copied string. On failure, -@@ -196,14 +194,14 @@ class StringRef; +@@ -217,14 +214,14 @@ class StringRef; * the first character which could not be converted. * \return true on success. */ @@ -670,7 +665,7 @@ index 374cdb907fdc2c41912c2fa606b36e108259fa31..7f1527f51cdf59238607becfb2fdaf4a /** * Converts a UTF-8 C-string to a std::wstring. -@@ -261,7 +259,7 @@ inline ConversionResult convertUTF8Sequence(const UTF8 **source, +@@ -282,7 +279,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. */ @@ -679,7 +674,7 @@ index 374cdb907fdc2c41912c2fa606b36e108259fa31..7f1527f51cdf59238607becfb2fdaf4a /** * Converts a stream of raw bytes assumed to be UTF16 into a UTF8 std::string. -@@ -270,7 +268,7 @@ bool hasUTF16ByteOrderMark(ArrayRef SrcBytes); +@@ -291,7 +288,7 @@ bool hasUTF16ByteOrderMark(ArrayRef SrcBytes); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ @@ -688,13 +683,31 @@ index 374cdb907fdc2c41912c2fa606b36e108259fa31..7f1527f51cdf59238607becfb2fdaf4a /** * Converts a UTF16 string into a UTF8 std::string. -@@ -279,22 +277,22 @@ bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out); +@@ -300,7 +297,7 @@ bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ -bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out); +bool convertUTF16ToUTF8String(span Src, std::string &Out); + /** + * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string. +@@ -309,7 +306,7 @@ bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out); + * \param [out] Out Converted UTF-8 is stored here on success. + * \returns true on success + */ +-bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out); ++bool convertUTF32ToUTF8String(span SrcBytes, std::string &Out); + + /** + * Converts a UTF32 string into a UTF8 std::string. +@@ -318,22 +315,22 @@ bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out); + * \param [out] Out Converted UTF-8 is stored here on success. + * \returns true on success + */ +-bool convertUTF32ToUTF8String(ArrayRef Src, std::string &Out); ++bool convertUTF32ToUTF8String(span Src, std::string &Out); + /** * Converts a UTF-8 string into a UTF-16 string with native endianness. * @@ -737,7 +750,7 @@ index 8a04a324a5dc6cccaaa6af7b0e9b340f0755587e..8737cd144c37f9041a781a74e9f2b433 return H; } diff --git a/llvm/include/llvm/Support/ErrorHandling.h b/llvm/include/llvm/Support/ErrorHandling.h -index 6791df6be3362fa199556ecb2131f971cfef5210..3f726d40ba7b8987c504cc3d933b137cfbc895d3 100644 +index dd1384a63af71b50ba1ccbb5933a1e472f50a39b..67e889fe26ac5ba1f4f81dc407210b76d507a517 100644 --- a/llvm/include/llvm/Support/ErrorHandling.h +++ b/llvm/include/llvm/Support/ErrorHandling.h @@ -15,10 +15,10 @@ @@ -793,56 +806,18 @@ index f7f2d4e54e705d6f29812dc93d1fb0a3ca2dee12..b5e321b5f74ce35940649b9d1342b3cd BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; } diff --git a/llvm/include/llvm/Support/VersionTuple.h b/llvm/include/llvm/Support/VersionTuple.h -index 1a1072d228f1164b22fa66ce9d020e9c6a5b1935..3d6573bf5a96e115ef264c7885b91aa3b32ac91e 100644 +index 828a6db54708dfa9a1a4b4456a92945a92ad80cb..953b40701dc934c1a356b5413c9c6c692d5f5679 100644 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h -@@ -16,14 +16,13 @@ - - #include "llvm/ADT/DenseMapInfo.h" - #include "llvm/ADT/Hashing.h" --#include "llvm/ADT/Optional.h" - #include "llvm/Support/HashBuilder.h" -+#include - #include - #include - - namespace llvm { +@@ -25,7 +25,6 @@ namespace llvm { + template + class HashBuilderImpl; class raw_ostream; -class StringRef; /// Represents a version number in the form major[.minor[.subminor[.build]]]. class VersionTuple { -@@ -70,23 +69,23 @@ public: - unsigned getMajor() const { return Major; } - - /// Retrieve the minor version number, if provided. -- Optional getMinor() const { -+ std::optional getMinor() const { - if (!HasMinor) -- return None; -+ return std::nullopt; - return Minor; - } - - /// Retrieve the subminor version number, if provided. -- Optional getSubminor() const { -+ std::optional getSubminor() const { - if (!HasSubminor) -- return None; -+ return std::nullopt; - return Subminor; - } - - /// Retrieve the build version number, if provided. -- Optional getBuild() const { -+ std::optional getBuild() const { - if (!HasBuild) -- return None; -+ return std::nullopt; - return Build; - } - -@@ -173,11 +172,6 @@ public: +@@ -182,11 +181,6 @@ public: /// Retrieve a string representation of the version number. std::string getAsString() const; @@ -855,7 +830,7 @@ index 1a1072d228f1164b22fa66ce9d020e9c6a5b1935..3d6573bf5a96e115ef264c7885b91aa3 /// Print a version number. diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h -index 917822678e979690dc09173510f8c62569e467f1..180803fbd3104ddf32c183684f226954c4fb8b0e 100644 +index d3aacd14b2097b1e7e13c1003987c1fd52e0cf76..aabdb2f14668a990329b57f5454a0d7db73e12ce 100644 --- a/llvm/include/llvm/Support/Windows/WindowsSupport.h +++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h @@ -35,8 +35,6 @@ @@ -867,7 +842,7 @@ index 917822678e979690dc09173510f8c62569e467f1..180803fbd3104ddf32c183684f226954 #include "llvm/Config/llvm-config.h" // Get build system configuration settings #include "llvm/Support/Allocator.h" #include "llvm/Support/Chrono.h" -@@ -71,7 +69,7 @@ bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); +@@ -74,7 +72,7 @@ bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) { std::string ErrMsg; MakeErrMsg(&ErrMsg, Msg); @@ -877,21 +852,25 @@ index 917822678e979690dc09173510f8c62569e467f1..180803fbd3104ddf32c183684f226954 template diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a509e54fe2f 100644 +index 7c42f355fd431791116226f6c6934213a130141c..c8a94f46fab18dabc123fd709974138c8b0b0beb 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -14,9 +14,7 @@ +@@ -14,13 +14,12 @@ #define LLVM_SUPPORT_RAW_OSTREAM_H #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" --#include "llvm/ADT/Optional.h" -#include "llvm/Support/DataTypes.h" -+#include "llvm/ADT/span.h" #include #include #include -@@ -210,7 +208,22 @@ public: + #include + #include ++#include + #include + #include + #include +@@ -208,7 +207,22 @@ public: return *this; } @@ -915,7 +894,7 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 // Inline fast path, particularly for strings with a known length. size_t Size = Str.size(); -@@ -229,7 +242,7 @@ public: +@@ -241,7 +255,7 @@ public: // Inline fast path, particularly for constant strings where a sufficiently // smart compiler will simplify strlen. @@ -924,20 +903,18 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 } raw_ostream &operator<<(const std::string &Str) { -@@ -237,12 +250,6 @@ public: +@@ -249,10 +263,6 @@ public: return write(Str.data(), Str.length()); } --#if __cplusplus > 201402L - raw_ostream &operator<<(const std::string_view &Str) { - return write(Str.data(), Str.length()); - } --#endif - raw_ostream &operator<<(const SmallVectorImpl &Str) { return write(Str.data(), Str.size()); } -@@ -275,7 +282,7 @@ public: +@@ -285,7 +295,7 @@ public: /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't /// satisfy llvm::isPrint into an escape sequence. @@ -946,16 +923,7 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 raw_ostream &write(unsigned char C); raw_ostream &write(const char *Ptr, size_t Size); -@@ -446,7 +453,7 @@ class raw_fd_ostream : public raw_pwrite_stream { - bool ShouldClose; - bool SupportsSeeking = false; - bool IsRegularFile = false; -- mutable Optional HasColors; -+ mutable std::optional HasColors; - - #ifdef _WIN32 - /// True if this fd refers to a Windows console device. Mintty and other -@@ -491,14 +498,14 @@ public: +@@ -501,14 +511,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. @@ -975,7 +943,7 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access, sys::fs::OpenFlags Flags); -@@ -603,7 +610,7 @@ public: +@@ -613,7 +623,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. @@ -984,7 +952,7 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 /// This reads the \p Size bytes into a buffer pointed by \p Ptr. /// -@@ -683,8 +690,8 @@ public: +@@ -693,8 +703,8 @@ public: void flush() = delete; @@ -995,7 +963,7 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 void reserveExtraSpace(uint64_t ExtraSize) override { OS.reserve(tell() + ExtraSize); -@@ -741,7 +748,7 @@ class Error; +@@ -751,7 +761,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. @@ -1003,9 +971,9 @@ index 58adb41cb0ef6e57011694bc678c9ae13b416904..9a1dd7a6070c20609660bfc63db10a50 +Error writeToOutput(std::string_view OutputFileName, std::function Write); - } // end namespace llvm + raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp -index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8be5e0e030 100644 +index 9bf3f8f8b897c4f2c49fa65d8036412675526369..bb5164ff9dce0271cafc5889a049b5d343530f8d 100644 --- a/llvm/lib/Support/ConvertUTFWrapper.cpp +++ b/llvm/lib/Support/ConvertUTFWrapper.cpp @@ -6,24 +6,24 @@ @@ -1014,10 +982,10 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -+#include "llvm/ADT/span.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SwapByteOrder.h" ++#include #include +#include #include @@ -1038,15 +1006,14 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b result = sourceIllegal; ErrorPtr = Pos; } else { -@@ -77,13 +77,13 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) { +@@ -76,12 +76,12 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) { return true; } -bool hasUTF16ByteOrderMark(ArrayRef S) { +bool hasUTF16ByteOrderMark(span S) { - return (S.size() >= 2 && - ((S[0] == '\xff' && S[1] == '\xfe') || - (S[0] == '\xfe' && S[1] == '\xff'))); + return (S.size() >= 2 && ((S[0] == '\xff' && S[1] == '\xfe') || + (S[0] == '\xfe' && S[1] == '\xff'))); } -bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out) { @@ -1054,17 +1021,35 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b assert(Out.empty()); // Error out on an uneven byte count. -@@ -134,14 +134,14 @@ bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out) { +@@ -132,14 +132,14 @@ bool convertUTF16ToUTF8String(ArrayRef SrcBytes, std::string &Out) { return true; } --bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out) -+bool convertUTF16ToUTF8String(span Src, std::string &Out) - { +-bool convertUTF16ToUTF8String(ArrayRef Src, std::string &Out) { ++bool convertUTF16ToUTF8String(span Src, std::string &Out) { return convertUTF16ToUTF8String( - llvm::ArrayRef(reinterpret_cast(Src.data()), + span(reinterpret_cast(Src.data()), - Src.size() * sizeof(UTF16)), Out); + Src.size() * sizeof(UTF16)), + Out); + } + +-bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out) { ++bool convertUTF32ToUTF8String(span SrcBytes, std::string &Out) { + assert(Out.empty()); + + // Error out on an uneven byte count. +@@ -190,14 +190,14 @@ bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out) { + return true; + } + +-bool convertUTF32ToUTF8String(ArrayRef Src, std::string &Out) { ++bool convertUTF32ToUTF8String(span Src, std::string &Out) { + return convertUTF32ToUTF8String( +- llvm::ArrayRef(reinterpret_cast(Src.data()), ++ span(reinterpret_cast(Src.data()), + Src.size() * sizeof(UTF32)), + Out); } -bool convertUTF8ToUTF16String(StringRef SrcUTF8, @@ -1072,7 +1057,7 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b SmallVectorImpl &DstUTF16) { assert(DstUTF16.empty()); -@@ -152,8 +152,8 @@ bool convertUTF8ToUTF16String(StringRef SrcUTF8, +@@ -208,8 +208,8 @@ bool convertUTF8ToUTF16String(StringRef SrcUTF8, return true; } @@ -1083,7 +1068,7 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b // Allocate the same number of UTF-16 code units as UTF-8 code units. Encoding // as UTF-16 should always require the same amount or less code units than the -@@ -184,7 +184,7 @@ static_assert(sizeof(wchar_t) == 1 || sizeof(wchar_t) == 2 || +@@ -240,7 +240,7 @@ static_assert(sizeof(wchar_t) == 1 || sizeof(wchar_t) == 2 || "Expected wchar_t to be 1, 2, or 4 bytes"); template @@ -1092,7 +1077,7 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b TResult &Result) { // Even in the case of UTF-16, the number of bytes in a UTF-8 string is // at least as large as the number of elements in the resulting wide -@@ -200,7 +200,7 @@ static inline bool ConvertUTF8toWideInternal(llvm::StringRef Source, +@@ -256,7 +256,7 @@ static inline bool ConvertUTF8toWideInternal(llvm::StringRef Source, return true; } @@ -1101,7 +1086,7 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b return ConvertUTF8toWideInternal(Source, Result); } -@@ -209,7 +209,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) { +@@ -265,7 +265,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) { Result.clear(); return true; } @@ -1110,7 +1095,7 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b } bool convertWideToUTF8(const std::wstring &Source, std::string &Result) { -@@ -224,7 +224,7 @@ bool convertWideToUTF8(const std::wstring &Source, std::string &Result) { +@@ -280,7 +280,7 @@ bool convertWideToUTF8(const std::wstring &Source, std::string &Result) { return true; } else if (sizeof(wchar_t) == 2) { return convertUTF16ToUTF8String( @@ -1120,7 +1105,7 @@ index 392c4c4890e1666714acaa3630276515e4dec176..396ab0c655ed50707c8725ebd22b1f8b Result); } else if (sizeof(wchar_t) == 4) { diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index 80c0e00439a58078742fe75569a980ea3dd9bdf1..8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a 100644 +index b8b3b7424ac6b1de782e739782f9671194ce77a1..0aa13a0f78eb370b2a673ca4a773f26820575052 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -14,7 +14,6 @@ @@ -1169,7 +1154,7 @@ index 80c0e00439a58078742fe75569a980ea3dd9bdf1..8ae8fb8b40079a5da59f4008b9dc8de2 (void)written; // If something went wrong, we deliberately just give up. } diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp -index 8cafbc7fad0de3fa672f747feffbf933e88d53ca..8bad715e45cdf894e811020f3c146fc234e8e9f0 100644 +index f7e7e80332cc337f6dfa388d1e218e6f3ec95cf2..6cefdff7c28060ca18b522acf5279af3a206e23a 100644 --- a/llvm/lib/Support/SmallVector.cpp +++ b/llvm/lib/Support/SmallVector.cpp @@ -11,7 +11,6 @@ @@ -1199,19 +1184,19 @@ index 8cafbc7fad0de3fa672f747feffbf933e88d53ca..8bad715e45cdf894e811020f3c146fc2 } diff --git a/llvm/lib/Support/StringMap.cpp b/llvm/lib/Support/StringMap.cpp -index 012c785b4351d13183205099acb214df382510e3..317f4ee43bced6d76031babfae043befc42608b4 100644 +index 9b2f96fca2cd035963f88dc462c5d723b7adf164..3c790039bffbc11b2db28cbf13c248fdccec4383 100644 --- a/llvm/lib/Support/StringMap.cpp +++ b/llvm/lib/Support/StringMap.cpp -@@ -70,7 +70,7 @@ void StringMapImpl::init(unsigned InitSize) { +@@ -80,7 +80,7 @@ void StringMapImpl::init(unsigned InitSize) { /// specified bucket will be non-null. Otherwise, it will be null. In either /// case, the FullHashValue field of the bucket will be set to the hash value /// of the string. -unsigned StringMapImpl::LookupBucketFor(StringRef Name) { +unsigned StringMapImpl::LookupBucketFor(std::string_view Name) { - unsigned HTSize = NumBuckets; - if (HTSize == 0) { // Hash table unallocated so far? + // Hash table unallocated so far? + if (NumBuckets == 0) init(16); -@@ -110,7 +110,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) { +@@ -118,7 +118,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) { // Do the comparison like this because Name isn't necessarily // null-terminated! char *ItemStr = (char *)BucketItem + ItemSize; @@ -1220,16 +1205,16 @@ index 012c785b4351d13183205099acb214df382510e3..317f4ee43bced6d76031babfae043bef // We found a match! return BucketNo; } -@@ -128,7 +128,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) { +@@ -136,7 +136,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) { /// FindKey - Look up the bucket that contains the specified key. If it exists /// in the map, return the bucket number of the key. Otherwise return -1. /// This does not modify the map. -int StringMapImpl::FindKey(StringRef Key) const { +int StringMapImpl::FindKey(std::string_view Key) const { - unsigned HTSize = NumBuckets; - if (HTSize == 0) + if (NumBuckets == 0) return -1; // Really empty table? -@@ -154,7 +154,7 @@ int StringMapImpl::FindKey(StringRef Key) const { + unsigned FullHashValue = djbHash(Key, 0); +@@ -161,7 +161,7 @@ int StringMapImpl::FindKey(StringRef Key) const { // Do the comparison like this because NameStart isn't necessarily // null-terminated! char *ItemStr = (char *)BucketItem + ItemSize; @@ -1238,7 +1223,7 @@ index 012c785b4351d13183205099acb214df382510e3..317f4ee43bced6d76031babfae043bef // We found a match! return BucketNo; } -@@ -173,14 +173,14 @@ int StringMapImpl::FindKey(StringRef Key) const { +@@ -180,14 +180,14 @@ int StringMapImpl::FindKey(StringRef Key) const { /// delete it. This aborts if the value isn't in the table. void StringMapImpl::RemoveKey(StringMapEntryBase *V) { const char *VStr = (char *)V + ItemSize; @@ -1256,10 +1241,10 @@ index 012c785b4351d13183205099acb214df382510e3..317f4ee43bced6d76031babfae043bef if (Bucket == -1) return nullptr; diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7fd0d055de 100644 +index fae4a4308fd7fdc2126932a097d8c9a366d0840b..ce3ffa575995b9f00f8d569176c7aeae7892d30d 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -159,7 +159,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) { +@@ -166,7 +166,7 @@ raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) { } @@ -1268,7 +1253,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f bool UseHexEscapes) { for (unsigned char c : Str) { switch (c) { -@@ -563,7 +563,7 @@ void format_object_base::home() { +@@ -569,7 +569,7 @@ void format_object_base::home() { // raw_fd_ostream //===----------------------------------------------------------------------===// @@ -1277,7 +1262,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access, sys::fs::OpenFlags Flags) { assert((Access & sys::fs::FA_Write) && -@@ -589,25 +589,25 @@ static int getFD(StringRef Filename, std::error_code &EC, +@@ -595,25 +595,25 @@ static int getFD(StringRef Filename, std::error_code &EC, return FD; } @@ -1308,7 +1293,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access, sys::fs::OpenFlags Flags) -@@ -679,8 +679,7 @@ raw_fd_ostream::~raw_fd_ostream() { +@@ -685,8 +685,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()) @@ -1318,7 +1303,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f /*gen_crash_diag=*/false); } -@@ -699,7 +698,7 @@ raw_fd_ostream::~raw_fd_ostream() { +@@ -705,7 +704,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. @@ -1327,7 +1312,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f SmallVector WideText; // Fall back to ::write if it wasn't valid UTF-8. -@@ -742,7 +741,7 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { +@@ -748,7 +747,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) @@ -1336,7 +1321,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f return; #endif -@@ -906,7 +905,7 @@ raw_ostream &llvm::nulls() { +@@ -919,7 +918,7 @@ raw_ostream &llvm::nulls() { // File Streams //===----------------------------------------------------------------------===// @@ -1345,7 +1330,7 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f : raw_fd_ostream(getFD(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write | sys::fs::FA_Read, sys::fs::OF_None), -@@ -984,7 +983,7 @@ void buffer_ostream::anchor() {} +@@ -997,7 +996,7 @@ void buffer_ostream::anchor() {} void buffer_unique_ostream::anchor() {} @@ -1355,10 +1340,10 @@ index 69d4fe96bee898967e1637d495283bc0281ec255..e4c318eb8265c588f1d84dd1abeafc7f if (OutputFileName == "-") return Write(outs()); diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp -index 4dd314c5c90191f733676f037fb476e96f284380..e505b19070bfdc9af45e0c2ae017e6ea50d81c98 100644 +index 2d01316e658b8dbb6b77b8158da11701fedb9e94..ab575dfe920e314489025bb68e6113f6227fe41f 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp -@@ -481,31 +481,6 @@ TEST(DenseMapCustomTest, ReserveTest) { +@@ -486,31 +486,6 @@ TEST(DenseMapCustomTest, ReserveTest) { } } @@ -1425,10 +1410,10 @@ index fc856a976946bf6decda9b6724cac66afc7bdcd6..aff9d61c7f0d48834123b04b74a2e4f7 TEST(UniqueFunctionTest, SFINAE) { EXPECT_EQ("not a function", returns("boo!")); diff --git a/llvm/unittests/ADT/HashingTest.cpp b/llvm/unittests/ADT/HashingTest.cpp -index bb19a569999f2dc3cae4eaff07d4da73c13ff6fd..0634767a456345a980fa43b67aa1937be1fcb8ae 100644 +index 01a8a962b8e2e33ca8f189c049e9548ced42ec3a..62aff9c3b21eea785ca71c6e290c9c4f3a20ae00 100644 --- a/llvm/unittests/ADT/HashingTest.cpp +++ b/llvm/unittests/ADT/HashingTest.cpp -@@ -277,7 +277,7 @@ TEST(HashingTest, HashCombineRangeGoldenTest) { +@@ -295,7 +295,7 @@ TEST(HashingTest, HashCombineRangeGoldenTest) { #endif }; for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) { @@ -1438,7 +1423,7 @@ index bb19a569999f2dc3cae4eaff07d4da73c13ff6fd..0634767a456345a980fa43b67aa1937b #if 0 // Enable this to generate paste-able text for the above structure. std::string member_str = "\"" + str.str() + "\","; diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp -index 414298c4e67df194dd69bbb674908b920fdfd828..6f3c94eed2737d4e35995454ec7d007cedb1235a 100644 +index a97f2617cbf70783f3569709f7ee1bff03baebd2..7ed8670fd31ea2a14e6ba7f59a8ac8e35046890c 100644 --- a/llvm/unittests/ADT/SmallPtrSetTest.cpp +++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp @@ -12,7 +12,6 @@ @@ -1450,7 +1435,7 @@ index 414298c4e67df194dd69bbb674908b920fdfd828..6f3c94eed2737d4e35995454ec7d007c #include "gtest/gtest.h" diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp -index b207f582e9197fa9ee0f1676b2d3f1f62333b144..bee3875d11c9b793d79ac442312559b11dba9f5f 100644 +index 2f4df8afeafa592cb9616bb78feb4964187786f2..6cf14700b34739420cd3dc4ff8a4c16ce162f715 100644 --- a/llvm/unittests/ADT/SmallStringTest.cpp +++ b/llvm/unittests/ADT/SmallStringTest.cpp @@ -50,43 +50,43 @@ TEST_F(SmallStringTest, AssignRepeated) { @@ -1589,19 +1574,37 @@ index b207f582e9197fa9ee0f1676b2d3f1f62333b144..bee3875d11c9b793d79ac442312559b1 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 3fbea5299501bdb2c36ceb2caf8f2cbda40efdde..fe827546aef2c26b8c5372b2643e84d60683a19a 100644 +index fd3780a42ce50404216f248bedf79002e69d4070..e1090e6f605696f60a82d1708605ddd45f4e15f8 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp -@@ -11,7 +11,7 @@ +@@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/ArrayRef.h" -+#include "llvm/ADT/span.h" #include "llvm/Support/Compiler.h" #include "gtest/gtest.h" #include -@@ -1070,24 +1070,6 @@ TEST(SmallVectorTest, DefaultInlinedElements) { ++#include + #include + + using namespace llvm; +@@ -247,11 +247,11 @@ TYPED_TEST(SmallVectorTest, ConstructorIterTest) { + } + + // Constructor test. +-TYPED_TEST(SmallVectorTest, ConstructorFromArrayRefSimpleTest) { +- SCOPED_TRACE("ConstructorFromArrayRefSimpleTest"); ++TYPED_TEST(SmallVectorTest, ConstructorFromSpanSimpleTest) { ++ SCOPED_TRACE("ConstructorFromSpanSimpleTest"); + std::array StdArray = {Constructable(1), Constructable(2), + Constructable(3)}; +- ArrayRef Array = StdArray; ++ span Array = StdArray; + auto &V = this->theVector; + V = SmallVector(Array); + assertValuesInOrder(V, 3u, 1, 2, 3); +@@ -1124,24 +1124,6 @@ TEST(SmallVectorTest, DefaultInlinedElements) { EXPECT_EQ(NestedV[0][0][0], 42); } @@ -1609,25 +1612,38 @@ index 3fbea5299501bdb2c36ceb2caf8f2cbda40efdde..fe827546aef2c26b8c5372b2643e84d6 - SmallVector V1 = {}; - EXPECT_TRUE(V1.empty()); - V1 = {0, 0}; -- EXPECT_TRUE(makeArrayRef(V1).equals({0, 0})); +- EXPECT_TRUE(ArrayRef(V1).equals({0, 0})); - V1 = {-1, -1}; -- EXPECT_TRUE(makeArrayRef(V1).equals({-1, -1})); +- EXPECT_TRUE(ArrayRef(V1).equals({-1, -1})); - - SmallVector V2 = {1, 2, 3, 4}; -- EXPECT_TRUE(makeArrayRef(V2).equals({1, 2, 3, 4})); +- EXPECT_TRUE(ArrayRef(V2).equals({1, 2, 3, 4})); - V2.assign({4}); -- EXPECT_TRUE(makeArrayRef(V2).equals({4})); +- EXPECT_TRUE(ArrayRef(V2).equals({4})); - V2.append({3, 2}); -- EXPECT_TRUE(makeArrayRef(V2).equals({4, 3, 2})); +- EXPECT_TRUE(ArrayRef(V2).equals({4, 3, 2})); - V2.insert(V2.begin() + 1, 5); -- EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2})); +- EXPECT_TRUE(ArrayRef(V2).equals({4, 5, 3, 2})); -} - - template - class SmallVectorReferenceInvalidationTest : public SmallVectorTestBase { - protected: + TEST(SmallVectorTest, ToVector) { + { + std::vector v = {'a', 'b', 'c'}; +@@ -1178,10 +1160,10 @@ private: + To T; + }; + +-TEST(SmallVectorTest, ConstructFromArrayRefOfConvertibleType) { ++TEST(SmallVectorTest, ConstructFromSpanOfConvertibleType) { + To to1{1}, to2{2}, to3{3}; + std::vector StdVector = {From(to1), From(to2), From(to3)}; +- ArrayRef Array = StdVector; ++ span Array = StdVector; + { + llvm::SmallVector Vector(Array); + diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp -index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482eadd314d 100644 +index f40f22ad140cbe7c2d2dd1ea6697cc2570ed51c3..ff68c66bd1eda0aa4fb78702875ff734557eb07d 100644 --- a/llvm/unittests/ADT/StringMapTest.cpp +++ b/llvm/unittests/ADT/StringMapTest.cpp @@ -7,8 +7,6 @@ @@ -1639,7 +1655,7 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 #include "llvm/Support/DataTypes.h" #include "gtest/gtest.h" #include -@@ -38,10 +36,10 @@ protected: +@@ -42,10 +40,10 @@ protected: // Lookup tests EXPECT_EQ(0u, testMap.count(testKey)); @@ -1647,12 +1663,12 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 + EXPECT_EQ(0u, testMap.count(std::string_view(testKeyFirst, testKeyLength))); EXPECT_EQ(0u, testMap.count(testKeyStr)); EXPECT_TRUE(testMap.find(testKey) == testMap.end()); -- EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) == -+ EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == +- EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) == ++ EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == testMap.end()); EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end()); } -@@ -61,10 +59,10 @@ protected: +@@ -65,10 +63,10 @@ protected: // Lookup tests EXPECT_EQ(1u, testMap.count(testKey)); @@ -1660,12 +1676,12 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 + EXPECT_EQ(1u, testMap.count(std::string_view(testKeyFirst, testKeyLength))); EXPECT_EQ(1u, testMap.count(testKeyStr)); EXPECT_TRUE(testMap.find(testKey) == testMap.begin()); -- EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) == -+ EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == +- EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) == ++ EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == testMap.begin()); EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin()); } -@@ -104,10 +102,10 @@ TEST_F(StringMapTest, ConstEmptyMapTest) { +@@ -106,10 +104,10 @@ TEST_F(StringMapTest, ConstEmptyMapTest) { // Lookup tests EXPECT_EQ(0u, constTestMap.count(testKey)); @@ -1678,24 +1694,24 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 constTestMap.end()); EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end()); } -@@ -235,7 +233,7 @@ TEST_F(StringMapTest, StringMapEntryTest) { +@@ -237,7 +235,7 @@ TEST_F(StringMapTest, StringMapEntryTest) { MallocAllocator Allocator; StringMap::value_type *entry = - StringMap::value_type::Create( + StringMap::value_type::create( - StringRef(testKeyFirst, testKeyLength), Allocator, 1u); + std::string_view(testKeyFirst, testKeyLength), Allocator, 1u); EXPECT_STREQ(testKey, entry->first().data()); EXPECT_EQ(1u, entry->second); entry->Destroy(Allocator); -@@ -246,7 +244,7 @@ TEST_F(StringMapTest, InsertTest) { +@@ -247,7 +245,7 @@ TEST_F(StringMapTest, StringMapEntryTest) { + TEST_F(StringMapTest, InsertTest) { SCOPED_TRACE("InsertTest"); - testMap.insert( - StringMap::value_type::Create( -- StringRef(testKeyFirst, testKeyLength), -+ std::string_view(testKeyFirst, testKeyLength), - testMap.getAllocator(), 1u)); + testMap.insert(StringMap::value_type::create( +- StringRef(testKeyFirst, testKeyLength), testMap.getAllocator(), 1u)); ++ std::string_view(testKeyFirst, testKeyLength), testMap.getAllocator(), 1u)); assertSingleItemMap(); } + @@ -316,10 +314,10 @@ TEST_F(StringMapTest, IterMapKeysVector) { Map["C"] = 3; Map["D"] = 3; @@ -1724,7 +1740,7 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 t.insert(std::make_pair("Test", MoveOnly(42))); - StringRef Key = "Test"; + std::string_view Key = "Test"; - StringMapEntry::Create(Key, t.getAllocator(), MoveOnly(42)) + StringMapEntry::create(Key, t.getAllocator(), MoveOnly(42)) ->Destroy(t.getAllocator()); } @@ -1732,9 +1748,9 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 - StringRef Key = "Test"; + std::string_view Key = "Test"; MallocAllocator Allocator; - StringMapEntry::Create(Key, Allocator, Immovable()) + StringMapEntry::create(Key, Allocator, Immovable()) ->Destroy(Allocator); -@@ -556,7 +554,7 @@ TEST(StringMapCustomTest, InitialSizeTest) { +@@ -566,7 +564,7 @@ TEST(StringMapCustomTest, InitialSizeTest) { CountCtorCopyAndMove::Copy = 0; for (int i = 0; i < Size; ++i) Map.insert(std::pair( @@ -1743,7 +1759,7 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 std::forward_as_tuple(i))); // After the initial move, the map will move the Elts in the Entry. EXPECT_EQ((unsigned)Size * 2, CountCtorCopyAndMove::Move); -@@ -625,7 +623,7 @@ TEST(StringMapCustomTest, StringMapEntrySize) { +@@ -635,7 +633,7 @@ TEST(StringMapCustomTest, StringMapEntrySize) { else LargeValue = std::numeric_limits::max() + 1ULL; StringMapEntry LargeEntry(LargeValue); @@ -1753,7 +1769,7 @@ index 817fec6c37a2a6a443e9cee9a4322b15c10da2b7..86907ab61a2c24effcef3b88c7849482 // Test that the entry can hold at least max size_t. diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp -index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc46c70f0d8 100644 +index 6e75fbae0969ba1bf0a76c4d79a123e405a8dae7..3b07d344f15a555f11ad5f8177a0a65b8a4fa472 100644 --- a/llvm/unittests/Support/ConvertUTFTest.cpp +++ b/llvm/unittests/Support/ConvertUTFTest.cpp @@ -7,7 +7,6 @@ @@ -1773,7 +1789,16 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 std::string Result; bool Success = convertUTF16ToUTF8String(Ref, Result); EXPECT_TRUE(Success); -@@ -28,7 +27,7 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) { +@@ -29,7 +28,7 @@ TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) { + // Src is the look of disapproval. + alignas(UTF32) static const char Src[] = + "\xFF\xFE\x00\x00\xA0\x0C\x00\x00\x5F\x00\x00\x00\xA0\x0C\x00\x00"; +- ArrayRef Ref(Src, sizeof(Src) - 1); ++ span Ref(Src, sizeof(Src) - 1); + std::string Result; + bool Success = convertUTF32ToUTF8String(Ref, Result); + EXPECT_TRUE(Success); +@@ -40,7 +39,7 @@ TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) { TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) { // Src is the look of disapproval. alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0"; @@ -1782,7 +1807,16 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 std::string Result; bool Success = convertUTF16ToUTF8String(Ref, Result); EXPECT_TRUE(Success); -@@ -39,7 +38,7 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) { +@@ -52,7 +51,7 @@ TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) { + // Src is the look of disapproval. + alignas(UTF32) static const char Src[] = + "\x00\x00\xFE\xFF\x00\x00\x0C\xA0\x00\x00\x00\x5F\x00\x00\x0C\xA0"; +- ArrayRef Ref(Src, sizeof(Src) - 1); ++ span Ref(Src, sizeof(Src) - 1); + std::string Result; + bool Success = convertUTF32ToUTF8String(Ref, Result); + EXPECT_TRUE(Success); +@@ -63,7 +62,7 @@ TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) { TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { // Src is the look of disapproval. static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0"; @@ -1791,41 +1825,42 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 SmallVector Result; bool Success = convertUTF8ToUTF16String(Ref, Result); EXPECT_TRUE(Success); -@@ -51,37 +50,37 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { +@@ -75,38 +74,38 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { TEST(ConvertUTFTest, OddLengthInput) { std::string Result; -- bool Success = convertUTF16ToUTF8String(makeArrayRef("xxxxx", 5), Result); +- bool Success = convertUTF16ToUTF8String(ArrayRef("xxxxx", 5), Result); + bool Success = convertUTF16ToUTF8String(span("xxxxx", 5), Result); EXPECT_FALSE(Success); } TEST(ConvertUTFTest, Empty) { std::string Result; -- bool Success = convertUTF16ToUTF8String(llvm::ArrayRef(None), Result); -+ bool Success = convertUTF16ToUTF8String(span(), Result); + bool Success = +- convertUTF16ToUTF8String(llvm::ArrayRef(std::nullopt), Result); ++ convertUTF16ToUTF8String(span(), Result); EXPECT_TRUE(Success); EXPECT_TRUE(Result.empty()); } TEST(ConvertUTFTest, HasUTF16BOM) { -- bool HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xff\xfe", 2)); +- bool HasBOM = hasUTF16ByteOrderMark(ArrayRef("\xff\xfe", 2)); + bool HasBOM = hasUTF16ByteOrderMark("\xff\xfe"); EXPECT_TRUE(HasBOM); -- HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff", 2)); +- HasBOM = hasUTF16ByteOrderMark(ArrayRef("\xfe\xff", 2)); + HasBOM = hasUTF16ByteOrderMark("\xfe\xff"); EXPECT_TRUE(HasBOM); -- HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff ", 3)); +- HasBOM = hasUTF16ByteOrderMark(ArrayRef("\xfe\xff ", 3)); + HasBOM = hasUTF16ByteOrderMark("\xfe\xff "); EXPECT_TRUE(HasBOM); // Don't care about odd lengths. -- HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe\xff\x00asdf", 6)); +- HasBOM = hasUTF16ByteOrderMark(ArrayRef("\xfe\xff\x00asdf", 6)); + HasBOM = hasUTF16ByteOrderMark("\xfe\xff\x00asdf"); EXPECT_TRUE(HasBOM); -- HasBOM = hasUTF16ByteOrderMark(None); +- HasBOM = hasUTF16ByteOrderMark(std::nullopt); + HasBOM = hasUTF16ByteOrderMark(""); EXPECT_FALSE(HasBOM); -- HasBOM = hasUTF16ByteOrderMark(makeArrayRef("\xfe", 1)); +- HasBOM = hasUTF16ByteOrderMark(ArrayRef("\xfe", 1)); + HasBOM = hasUTF16ByteOrderMark("\xfe"); EXPECT_FALSE(HasBOM); } @@ -1833,12 +1868,12 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) { // Src is the look of disapproval. alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c"; -- ArrayRef SrcRef = makeArrayRef((const UTF16 *)Src, 4); +- ArrayRef SrcRef = ArrayRef((const UTF16 *)Src, 4); + span SrcRef((const UTF16 *)Src, 4); std::string Result; bool Success = convertUTF16ToUTF8String(SrcRef, Result); EXPECT_TRUE(Success); -@@ -98,7 +97,7 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) { +@@ -123,7 +122,7 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) { std::wstring Expected(L"\x0ca0_\x0ca0"); EXPECT_EQ(Expected, Result); Result.clear(); @@ -1847,7 +1882,7 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 EXPECT_TRUE(Success); EXPECT_EQ(Expected, Result); } -@@ -147,7 +146,7 @@ struct ConvertUTFResultContainer { +@@ -172,7 +171,7 @@ struct ConvertUTFResultContainer { }; std::pair> @@ -1856,7 +1891,7 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 const UTF8 *SourceStart = reinterpret_cast(S.data()); const UTF8 *SourceNext = SourceStart; -@@ -164,7 +163,7 @@ ConvertUTF8ToUnicodeScalarsLenient(StringRef S) { +@@ -189,7 +188,7 @@ ConvertUTF8ToUnicodeScalarsLenient(StringRef S) { } std::pair> @@ -1865,7 +1900,7 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 const UTF8 *SourceStart = reinterpret_cast(S.data()); const UTF8 *SourceNext = SourceStart; -@@ -182,7 +181,7 @@ ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) { +@@ -207,7 +206,7 @@ ConvertUTF8ToUnicodeScalarsPartialLenient(StringRef S) { ::testing::AssertionResult CheckConvertUTF8ToUnicodeScalars(ConvertUTFResultContainer Expected, @@ -1874,7 +1909,7 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 ConversionResult ErrorCode; std::vector Decoded; if (!Partial) -@@ -277,7 +276,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) { +@@ -302,7 +301,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) { // U+0000 NULL EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars( ConvertUTFResultContainer(conversionOK).withScalars(0x0000), @@ -1883,7 +1918,7 @@ index 7bda6ea28ad69c579b29bb656bf019d3b5a4b358..9c798437a12d971a9206cbaff546ebc4 // U+0080 PADDING CHARACTER EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars( -@@ -1051,7 +1050,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) { +@@ -1076,7 +1075,7 @@ TEST(ConvertUTFTest, UTF8ToUTF32Lenient) { // U+0000 NULL EXPECT_TRUE(CheckConvertUTF8ToUnicodeScalars( ConvertUTFResultContainer(conversionOK).withScalars(0x0000), diff --git a/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch b/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch index 14492dd1e0..0953f51b27 100644 --- a/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch +++ b/upstream_utils/llvm_patches/0003-Wrap-std-min-max-calls-in-parens-for-Windows-warning.patch @@ -8,14 +8,13 @@ Subject: [PATCH 03/30] Wrap std::min/max calls in parens, for Windows warnings llvm/include/llvm/ADT/SmallVector.h | 12 ++++++------ llvm/include/llvm/Support/ConvertUTF.h | 2 +- llvm/include/llvm/Support/MathExtras.h | 22 +++++++++++----------- - llvm/lib/Support/SmallVector.cpp | 2 +- - 5 files changed, 21 insertions(+), 21 deletions(-) + 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h -index 7673b66ca42a0c9c16b7cadd6cc21c14a4d21d43..975c3b97e2cbf09225299c421406ad2bbe4ef125 100644 +index 7adc6710cfa86db119446580246fc94a16dd9b3c..7f4ddc256a207289980b60385f02da69f7119578 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h -@@ -390,7 +390,7 @@ protected: +@@ -389,7 +389,7 @@ protected: return 0; // +1 is required because of the strict equality. // For example if NumEntries is 48, we need to return 401. @@ -24,7 +23,7 @@ index 7673b66ca42a0c9c16b7cadd6cc21c14a4d21d43..975c3b97e2cbf09225299c421406ad2b } void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) { -@@ -826,7 +826,7 @@ public: +@@ -825,7 +825,7 @@ public: // Reduce the number of buckets. unsigned NewNumBuckets = 0; if (OldNumEntries) @@ -34,10 +33,10 @@ index 7673b66ca42a0c9c16b7cadd6cc21c14a4d21d43..975c3b97e2cbf09225299c421406ad2b this->BaseT::initEmpty(); return; diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index a4a790323a6b80950de087f623668ab6ad3d935c..8686f7bb5407611979e8cecfe9da292d3a4b4160 100644 +index 92cccb130466a47127fbf8092286f9c5052dd26c..4a93f4c1d8102fc322ebde9c3c697877a1b9048a 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -49,12 +49,12 @@ protected: +@@ -55,12 +55,12 @@ protected: /// The maximum value of the Size_T used. static constexpr size_t SizeTypeMax() { @@ -52,7 +51,7 @@ index a4a790323a6b80950de087f623668ab6ad3d935c..8686f7bb5407611979e8cecfe9da292d /// This is a helper for \a grow() that's out of line to reduce code /// duplication. This function will report a fatal error if it can't grow at -@@ -79,7 +79,7 @@ protected: +@@ -99,7 +99,7 @@ protected: /// This does not construct or destroy any elements in the vector. void set_size(size_t N) { assert(N <= capacity()); @@ -61,7 +60,7 @@ index a4a790323a6b80950de087f623668ab6ad3d935c..8686f7bb5407611979e8cecfe9da292d } }; -@@ -259,7 +259,7 @@ public: +@@ -279,7 +279,7 @@ public: size_type size_in_bytes() const { return size() * sizeof(T); } size_type max_size() const { @@ -70,7 +69,7 @@ index a4a790323a6b80950de087f623668ab6ad3d935c..8686f7bb5407611979e8cecfe9da292d } size_t capacity_in_bytes() const { return capacity() * sizeof(T); } -@@ -444,7 +444,7 @@ void SmallVectorTemplateBase::takeAllocationForGrow( +@@ -467,7 +467,7 @@ void SmallVectorTemplateBase::takeAllocationForGrow( free(this->begin()); this->BeginX = NewElts; @@ -79,7 +78,7 @@ index a4a790323a6b80950de087f623668ab6ad3d935c..8686f7bb5407611979e8cecfe9da292d } /// SmallVectorTemplateBase - This is where we put -@@ -693,7 +693,7 @@ public: +@@ -712,7 +712,7 @@ public: } // Assign over existing elements. @@ -89,10 +88,10 @@ index a4a790323a6b80950de087f623668ab6ad3d935c..8686f7bb5407611979e8cecfe9da292d std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt); else if (NumElts < this->size()) diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h -index 7f1527f51cdf59238607becfb2fdaf4afc91d4b6..b085c8a179e8767a258f9feafc8d1111828f10b1 100644 +index 5c0e3009c25446a34882fb98329b1d955231bb39..72321022beb373945f7935ed72944fd68eb7d02f 100644 --- a/llvm/include/llvm/Support/ConvertUTF.h +++ b/llvm/include/llvm/Support/ConvertUTF.h -@@ -112,7 +112,7 @@ namespace llvm { +@@ -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 */ @@ -102,29 +101,20 @@ index 7f1527f51cdf59238607becfb2fdaf4afc91d4b6..b085c8a179e8767a258f9feafc8d1111 /* 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 753b1998c40c0f9d2a178b5e748d620ffd23ac7e..db9fbc148ae3064faa94a23713d1def3b466e899 100644 +index ff136ba2a8848e61fc85923e031fb3d60904a33d..45840976a09a733b69dee4070f2f9f8339455da2 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -97,7 +97,7 @@ template struct TrailingZerosCounter { - // Bisection method. - unsigned ZeroBits = 0; - T Shift = std::numeric_limits::digits >> 1; -- T Mask = std::numeric_limits::max() >> Shift; -+ T Mask = (std::numeric_limits::max)() >> Shift; - while (Shift) { - if ((Val & Mask) == 0) { - Val >>= Shift; -@@ -238,7 +238,7 @@ unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { - /// valid arguments. +@@ -100,7 +100,7 @@ template unsigned countLeadingZeros(T Val) { + /// \param ZB the behavior on an input of 0. template T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) - return std::numeric_limits::max(); + return (std::numeric_limits::max)(); - return countTrailingZeros(Val, ZB_Undefined); + return llvm::countr_zero(Val); } -@@ -279,7 +279,7 @@ template T maskLeadingZeros(unsigned N) { - /// valid arguments. +@@ -140,7 +140,7 @@ template T maskLeadingZeros(unsigned N) { + /// \param ZB the behavior on an input of 0. template T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) - return std::numeric_limits::max(); @@ -132,38 +122,38 @@ index 753b1998c40c0f9d2a178b5e748d620ffd23ac7e..db9fbc148ae3064faa94a23713d1def3 // Use ^ instead of - because both gcc and llvm can remove the associated ^ // in the __builtin_clz intrinsic on x86. -@@ -594,26 +594,26 @@ inline double Log2(double Value) { +@@ -407,26 +407,26 @@ template <> constexpr inline size_t CTLog2<1>() { return 0; } /// (32 bit edition.) /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 inline unsigned Log2_32(uint32_t Value) { -- return 31 - countLeadingZeros(Value); -+ return static_cast(31 - countLeadingZeros(Value)); +- return 31 - llvm::countl_zero(Value); ++ return static_cast(31 - llvm::countl_zero(Value)); } /// Return the floor log base 2 of the specified value, -1 if the value is zero. /// (64 bit edition.) inline unsigned Log2_64(uint64_t Value) { -- return 63 - countLeadingZeros(Value); -+ return static_cast(63 - countLeadingZeros(Value)); +- return 63 - llvm::countl_zero(Value); ++ return static_cast(63 - llvm::countl_zero(Value)); } /// Return the ceil log base 2 of the specified value, 32 if the value is zero. /// (32 bit edition). /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 inline unsigned Log2_32_Ceil(uint32_t Value) { -- return 32 - countLeadingZeros(Value - 1); -+ return static_cast(32 - countLeadingZeros(Value - 1)); +- return 32 - llvm::countl_zero(Value - 1); ++ return static_cast(32 - llvm::countl_zero(Value - 1)); } /// Return the ceil log base 2 of the specified value, 64 if the value is zero. /// (64 bit edition.) inline unsigned Log2_64_Ceil(uint64_t Value) { -- return 64 - countLeadingZeros(Value - 1); -+ return static_cast(64 - countLeadingZeros(Value - 1)); +- return 64 - llvm::countl_zero(Value - 1); ++ return static_cast(64 - llvm::countl_zero(Value - 1)); } - /// Return the greatest common divisor of the values using Euclid's algorithm. -@@ -807,7 +807,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { + /// This function takes a 64-bit integer and returns the bit equivalent double. +@@ -609,7 +609,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { T Z = X + Y; Overflowed = (Z < X || Z < Y); if (Overflowed) @@ -172,7 +162,16 @@ index 753b1998c40c0f9d2a178b5e748d620ffd23ac7e..db9fbc148ae3064faa94a23713d1def3 else return Z; } -@@ -832,7 +832,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) { +@@ -622,7 +622,7 @@ std::enable_if_t, T> SaturatingAdd(T X, T Y, T Z, + bool Overflowed = false; + T XY = SaturatingAdd(X, Y, &Overflowed); + if (Overflowed) +- return SaturatingAdd(std::numeric_limits::max(), T(1), Args...); ++ return SaturatingAdd((std::numeric_limits::max)(), T(1), Args...); + return SaturatingAdd(XY, Z, Args...); + } + +@@ -646,7 +646,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); @@ -181,7 +180,7 @@ index 753b1998c40c0f9d2a178b5e748d620ffd23ac7e..db9fbc148ae3064faa94a23713d1def3 int Log2Max = Log2_64(Max); if (Log2Z < Log2Max) { return X * Y; -@@ -952,9 +952,9 @@ std::enable_if_t::value, T> MulOverflow(T X, T Y, T &Result) { +@@ -766,9 +766,9 @@ std::enable_if_t::value, T> MulOverflow(T X, T Y, T &Result) { // Check how the max allowed absolute value (2^n for negative, 2^(n-1) for // positive) divided by an argument compares to the other. if (IsNegative) @@ -193,16 +192,3 @@ index 753b1998c40c0f9d2a178b5e748d620ffd23ac7e..db9fbc148ae3064faa94a23713d1def3 } } // End llvm namespace -diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp -index 8bad715e45cdf894e811020f3c146fc234e8e9f0..a2b4899e1ffe0ae19d236f43e2e2e2fe1db14110 100644 ---- a/llvm/lib/Support/SmallVector.cpp -+++ b/llvm/lib/Support/SmallVector.cpp -@@ -104,7 +104,7 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) { - // In theory 2*capacity can overflow if the capacity is 64 bit, but the - // original capacity would never be large enough for this to be a problem. - size_t NewCapacity = 2 * OldCapacity + 1; // Always grow. -- return std::min(std::max(NewCapacity, MinSize), MaxSize); -+ return (std::min)((std::max)(NewCapacity, MinSize), MaxSize); - } - - // Note: Moving this function into the header may cause performance regression. diff --git a/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch b/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch index 28f8f35a49..74f777b760 100644 --- a/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch +++ b/upstream_utils/llvm_patches/0004-Change-unique_function-storage-size.patch @@ -8,10 +8,10 @@ Subject: [PATCH 04/30] Change unique_function storage size 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h -index 5a37417ddde5ddf116dd63939c41064330d539d2..8a9d78f41f540f51559c11c1f9f40645165796e5 100644 +index 8f04277cdf0e5b3d3b0be4a307cf0e4fada810fd..ba145bf783775042ff4a2d4be4bb048f16db669d 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h -@@ -78,7 +78,7 @@ using EnableIfCallable = std::enable_if_t class UniqueFunctionBase { protected: @@ -28,4 +28,4 @@ index 5a37417ddde5ddf116dd63939c41064330d539d2..8a9d78f41f540f51559c11c1f9f40645 + // provide four pointers worth of storage here. // This is mutable as an inlined `const unique_function` may // still modify its own mutable members. - mutable + mutable std::aligned_storage_t diff --git a/upstream_utils/llvm_patches/0005-Threading-updates.patch b/upstream_utils/llvm_patches/0005-Threading-updates.patch index 70897fdcf0..83e37482db 100644 --- a/upstream_utils/llvm_patches/0005-Threading-updates.patch +++ b/upstream_utils/llvm_patches/0005-Threading-updates.patch @@ -12,10 +12,10 @@ Subject: [PATCH 05/30] Threading updates 3 files changed, 11 insertions(+), 43 deletions(-) diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index f5d726ec8a2c4c39a31a6a557591a99a64caea3a..ede1cb1726f2d2dd89e588489e062368763a4b68 100644 +index 4a54933031baa90c6f21138fb1f04c5da89878a4..ef9c0d1a73aec870b924faace3b4a32b187e197f 100644 --- a/llvm/include/llvm/Support/Compiler.h +++ b/llvm/include/llvm/Support/Compiler.h -@@ -540,7 +540,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -518,7 +518,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 f5d726ec8a2c4c39a31a6a557591a99a64caea3a..ede1cb1726f2d2dd89e588489e062368 #if __has_feature(cxx_thread_local) || defined(_MSC_VER) #define LLVM_THREAD_LOCAL thread_local #else -@@ -548,11 +547,6 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -526,11 +525,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 f5d726ec8a2c4c39a31a6a557591a99a64caea3a..ede1cb1726f2d2dd89e588489e062368 /// \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 8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a..89440b5ab872cbeb5e3fbebfa4550e67aea1486b 100644 +index 0aa13a0f78eb370b2a673ca4a773f26820575052..637b669a7d0dae69ef4b34955f21a9fb8ba1276e 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -44,7 +44,6 @@ static void *ErrorHandlerUserData = nullptr; @@ -83,7 +83,7 @@ index 8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a..89440b5ab872cbeb5e3fbebfa4550e67 handler = ErrorHandler; handlerData = ErrorHandlerUserData; } -@@ -123,18 +115,14 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { +@@ -126,18 +118,14 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, void *user_data) { @@ -104,7 +104,7 @@ index 8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a..89440b5ab872cbeb5e3fbebfa4550e67 BadAllocErrorHandler = nullptr; BadAllocErrorHandlerUserData = nullptr; } -@@ -145,9 +133,7 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { +@@ -148,9 +136,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. @@ -115,7 +115,7 @@ index 8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a..89440b5ab872cbeb5e3fbebfa4550e67 Handler = BadAllocErrorHandler; HandlerData = BadAllocErrorHandlerUserData; } -@@ -157,10 +143,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { +@@ -160,10 +146,6 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { llvm_unreachable("bad alloc handler should not return"); } @@ -126,7 +126,7 @@ index 8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a..89440b5ab872cbeb5e3fbebfa4550e67 // Don't call the normal error handler. It may allocate memory. Directly write // an OOM to stderr and abort. const char *OOMMessage = "LLVM ERROR: out of memory\n"; -@@ -169,15 +151,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { +@@ -172,15 +154,8 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { (void)!::write(2, Reason, strlen(Reason)); (void)!::write(2, Newline, strlen(Newline)); abort(); @@ -142,7 +142,7 @@ index 8ae8fb8b40079a5da59f4008b9dc8de258d8cb5a..89440b5ab872cbeb5e3fbebfa4550e67 // Causes crash on allocation failure. It is called prior to the handler set by // 'install_bad_alloc_error_handler'. static void out_of_memory_new_handler() { -@@ -192,7 +167,6 @@ void llvm::install_out_of_memory_new_handler() { +@@ -195,7 +170,6 @@ void llvm::install_out_of_memory_new_handler() { assert((old == nullptr || old == out_of_memory_new_handler) && "new-handler already installed"); } diff --git a/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch b/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch index 659b48653b..dbafc025ae 100644 --- a/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch +++ b/upstream_utils/llvm_patches/0006-ifdef-guard-safety.patch @@ -5,14 +5,14 @@ Subject: [PATCH 06/30] \#ifdef guard safety Prevents redefinition if someone is pulling in real LLVM, since the macros are in global namespace --- - llvm/include/llvm/Support/Compiler.h | 50 ++++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) + llvm/include/llvm/Support/Compiler.h | 42 ++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h -index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b82763088bb74a8 100644 +index ef9c0d1a73aec870b924faace3b4a32b187e197f..53c272034ae8f735d02556ced5bae93a1c8644c4 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,29 +20,15 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #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 +#endif - /// Does the compiler support ref-qualifiers for *this? - /// -@@ -112,11 +114,13 @@ - /// - /// This can be used to provide lvalue/rvalue overrides of member functions. - /// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS -+#ifndef LLVM_LVALUE_FUNCTION - #if LLVM_HAS_RVALUE_REFERENCE_THIS - #define LLVM_LVALUE_FUNCTION & - #else - #define LLVM_LVALUE_FUNCTION - #endif -+#endif - /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked /// into a shared library, then the class should be private to the library and -@@ -140,21 +144,26 @@ +@@ -127,17 +129,21 @@ #define LLVM_EXTERNAL_VISIBILITY #endif @@ -62,22 +48,9 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #endif +#endif - /// LLVM_NODISCARD - Warn if a type or return value is discarded. - - // Use the 'nodiscard' attribute in C++17 or newer mode. -+#ifndef LLVM_NODISCARD - #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) - #define LLVM_NODISCARD [[nodiscard]] - #elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result) -@@ -168,6 +177,7 @@ - #else - #define LLVM_NODISCARD - #endif -+#endif - - // Indicate that a non-static, non-const C++ member function reinitializes - // the entire object to a known state, independent of the previous state of -@@ -190,11 +200,13 @@ + #if defined(__clang__) + #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX))) +@@ -166,11 +172,13 @@ // more portable solution: // (void)unused_var_name; // Prefer cast-to-void wherever it is sufficient. @@ -91,7 +64,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 // FIXME: Provide this for PE/COFF targets. #if __has_attribute(weak) && !defined(__MINGW32__) && !defined(__CYGWIN__) && \ -@@ -204,6 +216,7 @@ +@@ -180,6 +188,7 @@ #define LLVM_ATTRIBUTE_WEAK #endif @@ -99,7 +72,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 // Prior to clang 3.2, clang did not accept any spelling of // __has_attribute(const), so assume it is supported. #if defined(__clang__) || defined(__GNUC__) -@@ -212,13 +225,16 @@ +@@ -188,13 +197,16 @@ #else #define LLVM_READNONE #endif @@ -116,7 +89,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_attribute(minsize) #define LLVM_ATTRIBUTE_MINSIZE __attribute__((minsize)) -@@ -226,6 +242,7 @@ +@@ -202,6 +214,7 @@ #define LLVM_ATTRIBUTE_MINSIZE #endif @@ -124,7 +97,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_builtin(__builtin_expect) || defined(__GNUC__) #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) -@@ -233,9 +250,11 @@ +@@ -209,9 +222,11 @@ #define LLVM_LIKELY(EXPR) (EXPR) #define LLVM_UNLIKELY(EXPR) (EXPR) #endif @@ -136,7 +109,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_attribute(noinline) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) -@@ -243,9 +262,11 @@ +@@ -219,9 +234,11 @@ #else #define LLVM_ATTRIBUTE_NOINLINE #endif @@ -148,7 +121,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_attribute(always_inline) #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) -@@ -253,6 +274,7 @@ +@@ -229,6 +246,7 @@ #else #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline #endif @@ -156,7 +129,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 /// LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do /// so, mark a method "no debug" because debug info makes the debugger -@@ -263,6 +285,7 @@ +@@ -239,6 +257,7 @@ #define LLVM_ATTRIBUTE_NODEBUG #endif @@ -164,7 +137,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_attribute(returns_nonnull) #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #elif defined(_MSC_VER) -@@ -270,9 +293,11 @@ +@@ -246,9 +265,11 @@ #else #define LLVM_ATTRIBUTE_RETURNS_NONNULL #endif @@ -176,7 +149,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #ifdef __GNUC__ #define LLVM_ATTRIBUTE_RETURNS_NOALIAS __attribute__((__malloc__)) #elif defined(_MSC_VER) -@@ -280,8 +305,10 @@ +@@ -256,8 +277,10 @@ #else #define LLVM_ATTRIBUTE_RETURNS_NOALIAS #endif @@ -187,7 +160,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(fallthrough) #define LLVM_FALLTHROUGH [[fallthrough]] #elif LLVM_HAS_CPP_ATTRIBUTE(gnu::fallthrough) -@@ -293,6 +320,7 @@ +@@ -269,6 +292,7 @@ #else #define LLVM_FALLTHROUGH #endif @@ -195,7 +168,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 /// LLVM_REQUIRE_CONSTANT_INITIALIZATION - Apply this to globals to ensure that /// they are constant initialized. -@@ -321,20 +349,25 @@ +@@ -297,11 +321,13 @@ /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress /// pedantic diagnostics. @@ -207,23 +180,17 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #endif +#endif - // LLVM_ATTRIBUTE_DEPRECATED(decl, "message") - // This macro will be removed. - // Use C++14's attribute instead: [[deprecated("message")]] -+#ifndef LLVM_ATTRIBUTE_DEPRECATED - #define LLVM_ATTRIBUTE_DEPRECATED(decl, message) [[deprecated(message)]] decl -+#endif - /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands /// to an expression which states that it is undefined behavior for the - /// compiler to reach this point. Otherwise is not defined. +@@ -310,14 +336,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. +#ifndef LLVM_BUILTIN_UNREACHABLE #if __has_builtin(__builtin_unreachable) || defined(__GNUC__) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #elif defined(_MSC_VER) -@@ -342,9 +375,11 @@ - #else - # define LLVM_BUILTIN_UNREACHABLE + # define LLVM_BUILTIN_UNREACHABLE __assume(false) #endif +#endif @@ -233,7 +200,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_builtin(__builtin_trap) || defined(__GNUC__) # define LLVM_BUILTIN_TRAP __builtin_trap() #elif defined(_MSC_VER) -@@ -356,10 +391,12 @@ +@@ -329,10 +358,12 @@ #else # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 #endif @@ -246,7 +213,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_builtin(__builtin_debugtrap) # define LLVM_BUILTIN_DEBUGTRAP __builtin_debugtrap() #elif defined(_MSC_VER) -@@ -373,9 +410,11 @@ +@@ -346,9 +377,11 @@ // program to abort if encountered. # define LLVM_BUILTIN_DEBUGTRAP #endif @@ -258,7 +225,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if __has_builtin(__builtin_assume_aligned) || defined(__GNUC__) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) #elif defined(LLVM_BUILTIN_UNREACHABLE) -@@ -384,6 +423,7 @@ +@@ -357,6 +390,7 @@ #else # define LLVM_ASSUME_ALIGNED(p, a) (p) #endif @@ -266,7 +233,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 /// \macro LLVM_PACKED /// Used to specify a packed structure. -@@ -403,6 +443,7 @@ +@@ -376,6 +410,7 @@ /// long long l; /// }; /// LLVM_PACKED_END @@ -274,29 +241,15 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #ifdef _MSC_VER # define LLVM_PACKED(d) __pragma(pack(push, 1)) d __pragma(pack(pop)) # define LLVM_PACKED_START __pragma(pack(push, 1)) -@@ -412,11 +453,13 @@ +@@ -385,6 +420,7 @@ # define LLVM_PACKED_START _Pragma("pack(push, 1)") # define LLVM_PACKED_END _Pragma("pack(pop)") #endif +#endif - /// \macro LLVM_PTR_SIZE - /// A constant integer equivalent to the value of sizeof(void*). - /// Generally used in combination with alignas or when doing computation in the - /// preprocessor. -+#ifndef LLVM_PTR_SIZE - #ifdef __SIZEOF_POINTER__ - # define LLVM_PTR_SIZE __SIZEOF_POINTER__ - #elif defined(_WIN64) -@@ -428,6 +471,7 @@ - #else - # define LLVM_PTR_SIZE sizeof(void *) - #endif -+#endif - /// \macro LLVM_MEMORY_SANITIZER_BUILD /// Whether LLVM itself is built with MemorySanitizer instrumentation. -@@ -498,11 +542,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -476,11 +512,13 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); /// \macro LLVM_NO_SANITIZE /// Disable a particular sanitizer for a function. @@ -310,7 +263,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 /// Mark debug helper function definitions like dump() that should not be /// stripped from debug builds. -@@ -510,17 +556,20 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -488,17 +526,20 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); /// `#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)` so they do always /// get stripped in release builds. // FIXME: Move this to a private config.h as it's not usable in public headers. @@ -331,7 +284,7 @@ index ede1cb1726f2d2dd89e588489e062368763a4b68..8b8260b50504876d79bd94ae5b827630 #if defined(_MSC_VER) #define LLVM_PRETTY_FUNCTION __FUNCSIG__ #elif defined(__GNUC__) || defined(__clang__) -@@ -528,6 +577,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); +@@ -506,6 +547,7 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #else #define LLVM_PRETTY_FUNCTION __func__ #endif diff --git a/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch b/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch index afb49ad5fd..6ba921a822 100644 --- a/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch +++ b/upstream_utils/llvm_patches/0007-Explicitly-use-std.patch @@ -4,18 +4,18 @@ Date: Sat, 7 May 2022 22:37:34 -0400 Subject: [PATCH 07/30] Explicitly use std:: --- - llvm/include/llvm/ADT/SmallSet.h | 2 +- - llvm/include/llvm/Support/MathExtras.h | 2 +- - llvm/lib/Support/ErrorHandling.cpp | 2 +- - llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 +- - llvm/unittests/ADT/StringMapTest.cpp | 2 +- - 5 files changed, 5 insertions(+), 5 deletions(-) + llvm/include/llvm/ADT/SmallSet.h | 2 +- + llvm/lib/Support/ErrorHandling.cpp | 2 +- + llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 +- + llvm/unittests/ADT/SmallSetTest.cpp | 10 +++++----- + llvm/unittests/ADT/StringMapTest.cpp | 2 +- + 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/ADT/SmallSet.h b/llvm/include/llvm/ADT/SmallSet.h -index bfe93e997fc896e82a9b96219967f754df82bcfb..403e108fd361d314762acc317ba6dce7226bb6e5 100644 +index 06bc9b5556dd76432552ee79aa916b850f829f4d..630a79c21efeaed6822e7bcad85db0b0d5e42526 100644 --- a/llvm/include/llvm/ADT/SmallSet.h +++ b/llvm/include/llvm/ADT/SmallSet.h -@@ -270,7 +270,7 @@ bool operator==(const SmallSet &LHS, const SmallSet &RHS) { +@@ -267,7 +267,7 @@ bool operator==(const SmallSet &LHS, const SmallSet &RHS) { return false; // All elements in LHS must also be in RHS @@ -24,24 +24,11 @@ index bfe93e997fc896e82a9b96219967f754df82bcfb..403e108fd361d314762acc317ba6dce7 } /// Inequality comparison for SmallSet. -diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index db9fbc148ae3064faa94a23713d1def3b466e899..da843ef79ff9fd1e2b702763fcdc6f33771bef94 100644 ---- a/llvm/include/llvm/Support/MathExtras.h -+++ b/llvm/include/llvm/Support/MathExtras.h -@@ -586,7 +586,7 @@ inline double Log2(double Value) { - #if defined(__ANDROID_API__) && __ANDROID_API__ < 18 - return __builtin_log(Value) / __builtin_log(2.0); - #else -- return log2(Value); -+ return std::log2(Value); - #endif - } - diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index 89440b5ab872cbeb5e3fbebfa4550e67aea1486b..f80e28e8710817aa19ca7c012a0a4eaecc801c83 100644 +index 637b669a7d0dae69ef4b34955f21a9fb8ba1276e..0b87b375de67dc18647e3ebe646bf323dd05e8c5 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -210,7 +210,7 @@ void LLVMResetFatalErrorHandler() { +@@ -213,7 +213,7 @@ void LLVMResetFatalErrorHandler() { // I'd rather not double the line count of the following. #define MAP_ERR_TO_COND(x, y) \ case x: \ @@ -51,20 +38,70 @@ index 89440b5ab872cbeb5e3fbebfa4550e67aea1486b..f80e28e8710817aa19ca7c012a0a4eae std::error_code llvm::mapWindowsError(unsigned EV) { switch (EV) { diff --git a/llvm/unittests/ADT/SmallPtrSetTest.cpp b/llvm/unittests/ADT/SmallPtrSetTest.cpp -index 6f3c94eed2737d4e35995454ec7d007cedb1235a..531f81ab5b3fc1dcff731230f3cb7649cb90aedf 100644 +index 7ed8670fd31ea2a14e6ba7f59a8ac8e35046890c..531f81ab5b3fc1dcff731230f3cb7649cb90aedf 100644 --- a/llvm/unittests/ADT/SmallPtrSetTest.cpp +++ b/llvm/unittests/ADT/SmallPtrSetTest.cpp @@ -298,7 +298,7 @@ TEST(SmallPtrSetTest, dereferenceAndIterate) { // Sort. We should hit the first element just once and the final element N // times. -- llvm::sort(std::begin(Found), std::end(Found)); +- llvm::sort(Found); + std::sort(std::begin(Found), std::end(Found)); for (auto F = std::begin(Found), E = std::end(Found); F != E; ++F) EXPECT_EQ(F - Found + 1, *F); } +diff --git a/llvm/unittests/ADT/SmallSetTest.cpp b/llvm/unittests/ADT/SmallSetTest.cpp +index b50b368ae663614f050c220432c05b32c201db00..f9d84fa8a42a7feaaffa3aa080e84574dc3671b3 100644 +--- a/llvm/unittests/ADT/SmallSetTest.cpp ++++ b/llvm/unittests/ADT/SmallSetTest.cpp +@@ -11,8 +11,8 @@ + //===----------------------------------------------------------------------===// + + #include "llvm/ADT/SmallSet.h" +-#include "llvm/ADT/STLExtras.h" + #include "gtest/gtest.h" ++#include + #include + + using namespace llvm; +@@ -94,7 +94,7 @@ TEST(SmallSetTest, IteratorInt) { + + std::vector V(s1.begin(), s1.end()); + // Make sure the elements are in the expected order. +- llvm::sort(V); ++ std::sort(V.begin(), V.end()); + for (int i = 0; i < 3; i++) + EXPECT_EQ(i, V[i]); + +@@ -105,7 +105,7 @@ TEST(SmallSetTest, IteratorInt) { + + V.assign(s1.begin(), s1.end()); + // Make sure the elements are in the expected order. +- llvm::sort(V); ++ std::sort(V.begin(), V.end()); + for (int i = 0; i < 6; i++) + EXPECT_EQ(i, V[i]); + } +@@ -120,7 +120,7 @@ TEST(SmallSetTest, IteratorString) { + s1.insert("str 1"); + + std::vector V(s1.begin(), s1.end()); +- llvm::sort(V); ++ std::sort(V.begin(), V.end()); + EXPECT_EQ(2u, s1.size()); + EXPECT_EQ("str 1", V[0]); + EXPECT_EQ("str 2", V[1]); +@@ -131,7 +131,7 @@ TEST(SmallSetTest, IteratorString) { + + V.assign(s1.begin(), s1.end()); + // Make sure the elements are in the expected order. +- llvm::sort(V); ++ std::sort(V.begin(), V.end()); + EXPECT_EQ(4u, s1.size()); + EXPECT_EQ("str 0", V[0]); + EXPECT_EQ("str 1", V[1]); diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp -index 86907ab61a2c24effcef3b88c7849482eadd314d..6d0c0942cdc256a01afbeb1902f53bc9c53198d9 100644 +index ff68c66bd1eda0aa4fb78702875ff734557eb07d..d12c585660ba8d00556c37bd1e5e41fbc953acc1 100644 --- a/llvm/unittests/ADT/StringMapTest.cpp +++ b/llvm/unittests/ADT/StringMapTest.cpp @@ -329,7 +329,7 @@ TEST_F(StringMapTest, IterMapKeysSmallVector) { diff --git a/upstream_utils/llvm_patches/0008-Remove-format_provider.patch b/upstream_utils/llvm_patches/0008-Remove-format_provider.patch index 6a77d840f5..df13e7de52 100644 --- a/upstream_utils/llvm_patches/0008-Remove-format_provider.patch +++ b/upstream_utils/llvm_patches/0008-Remove-format_provider.patch @@ -137,10 +137,10 @@ index a7dea19d9193bcff4bc6b553b80a10b2bc7b64af..9f9a2b5cab270327898cee3f97d9ae7c #endif // LLVM_SUPPORT_CHRONO_H diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index 9a1dd7a6070c20609660bfc63db10a509e54fe2f..a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e 100644 +index c8a94f46fab18dabc123fd709974138c8b0b0beb..0bf165c55921d7e09208a8fa8df7f9f5ad68d1e2 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -28,12 +28,6 @@ +@@ -27,12 +27,6 @@ namespace llvm { @@ -150,7 +150,7 @@ index 9a1dd7a6070c20609660bfc63db10a509e54fe2f..a25ca5b7b556fd9ccd08ad13a6ceae6b -class FormattedString; -class FormattedNumber; -class FormattedBytes; - template class LLVM_NODISCARD Expected; + template class [[nodiscard]] Expected; namespace sys { diff --git a/llvm/unittests/Support/Chrono.cpp b/llvm/unittests/Support/Chrono.cpp diff --git a/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch b/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch index 1c6fec2e0c..02c80c4e3e 100644 --- a/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch +++ b/upstream_utils/llvm_patches/0009-Add-compiler-warning-pragmas.patch @@ -17,7 +17,7 @@ Subject: [PATCH 09/30] Add compiler warning pragmas 10 files changed, 72 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/ADT/FunctionExtras.h b/llvm/include/llvm/ADT/FunctionExtras.h -index 8a9d78f41f540f51559c11c1f9f40645165796e5..3efa73587071b12af07398a4879e7b38c114867f 100644 +index ba145bf783775042ff4a2d4be4bb048f16db669d..07f9632bb871b1915b3016348d58938e738b3331 100644 --- a/llvm/include/llvm/ADT/FunctionExtras.h +++ b/llvm/include/llvm/ADT/FunctionExtras.h @@ -55,6 +55,13 @@ namespace llvm { @@ -34,7 +34,7 @@ index 8a9d78f41f540f51559c11c1f9f40645165796e5..3efa73587071b12af07398a4879e7b38 namespace detail { template -@@ -411,6 +418,10 @@ public: +@@ -410,6 +417,10 @@ public: } }; @@ -46,10 +46,10 @@ index 8a9d78f41f540f51559c11c1f9f40645165796e5..3efa73587071b12af07398a4879e7b38 #endif // LLVM_ADT_FUNCTIONEXTRAS_H diff --git a/llvm/include/llvm/ADT/Hashing.h b/llvm/include/llvm/ADT/Hashing.h -index 74a87a3d8dbbd1b13604fac694ad0294c53ee11c..47ff1b2bcbc14bf522abb66a1728123581c148d8 100644 +index 463a8d572aa17c415b0ca160b7580862aa9ae197..13e79a12a4f8449c764c9fcf85194bcc2b52b74a 100644 --- a/llvm/include/llvm/ADT/Hashing.h +++ b/llvm/include/llvm/ADT/Hashing.h -@@ -55,6 +55,11 @@ +@@ -56,6 +56,11 @@ #include #include @@ -61,7 +61,7 @@ index 74a87a3d8dbbd1b13604fac694ad0294c53ee11c..47ff1b2bcbc14bf522abb66a17281235 namespace llvm { template struct DenseMapInfo; -@@ -687,4 +692,8 @@ template <> struct DenseMapInfo { +@@ -678,4 +683,8 @@ template <> struct DenseMapInfo { } // namespace llvm @@ -71,7 +71,7 @@ index 74a87a3d8dbbd1b13604fac694ad0294c53ee11c..47ff1b2bcbc14bf522abb66a17281235 + #endif diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index 8686f7bb5407611979e8cecfe9da292d3a4b4160..1e311ea56fd1d35505ca6740922c713d97636f09 100644 +index 4a93f4c1d8102fc322ebde9c3c697877a1b9048a..70c77618b307acfee816006d54eeddc422ab619b 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -14,6 +14,14 @@ @@ -90,10 +90,10 @@ index 8686f7bb5407611979e8cecfe9da292d3a4b4160..1e311ea56fd1d35505ca6740922c713d #include "llvm/Support/type_traits.h" #include diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index da843ef79ff9fd1e2b702763fcdc6f33771bef94..fac12dd0e4c6316ff4887542dd59adc954f099e4 100644 +index 45840976a09a733b69dee4070f2f9f8339455da2..062ed2f4057820547cc6bfc4c91e7a13ceaa2f8a 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -435,6 +435,11 @@ inline uint64_t maxUIntN(uint64_t N) { +@@ -268,6 +268,11 @@ inline uint64_t maxUIntN(uint64_t N) { return UINT64_MAX >> (64 - N); } @@ -105,7 +105,7 @@ index da843ef79ff9fd1e2b702763fcdc6f33771bef94..fac12dd0e4c6316ff4887542dd59adc9 /// Gets the minimum value for a N-bit signed integer. inline int64_t minIntN(int64_t N) { assert(N > 0 && N <= 64 && "integer width out of range"); -@@ -442,6 +447,10 @@ inline int64_t minIntN(int64_t N) { +@@ -275,6 +280,10 @@ inline int64_t minIntN(int64_t N) { return UINT64_C(1) + ~(UINT64_C(1) << (N - 1)); } @@ -146,7 +146,7 @@ index d6012bd5a6985d8405136039aa85931605cd8a40..01007deb89bba625b1b3ad3e703d0c16 + #endif diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index e4c318eb8265c588f1d84dd1abeafc7fd0d055de..ee01a95220806c500d2c0149e9f1e667ea8bf28b 100644 +index ce3ffa575995b9f00f8d569176c7aeae7892d30d..a2778407119ccd73031b22a5a091e21923905aa9 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -10,6 +10,10 @@ @@ -158,10 +158,10 @@ index e4c318eb8265c588f1d84dd1abeafc7fd0d055de..ee01a95220806c500d2c0149e9f1e667 +#endif + #include "llvm/Support/raw_ostream.h" - #include "llvm/ADT/STLArrayExtras.h" #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 e505b19070bfdc9af45e0c2ae017e6ea50d81c98..9fe83a45d751719b9f99d57f8f5e983824d108f0 100644 +index ab575dfe920e314489025bb68e6113f6227fe41f..d83ba0009c8a70e64a4e3a43a7f3b58663711b87 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp @@ -6,6 +6,10 @@ @@ -173,8 +173,8 @@ index e505b19070bfdc9af45e0c2ae017e6ea50d81c98..9fe83a45d751719b9f99d57f8f5e9838 +#endif + #include "llvm/ADT/DenseMap.h" - #include "gtest/gtest.h" - #include + #include "llvm/ADT/DenseMapInfo.h" + #include "gmock/gmock.h" diff --git a/llvm/unittests/ADT/MapVectorTest.cpp b/llvm/unittests/ADT/MapVectorTest.cpp index 552f9956bdc2c6148f2e338b02074b7c479994a9..20ebcd753bcce0112f6a2d96ea23ccb6662996bb 100644 --- a/llvm/unittests/ADT/MapVectorTest.cpp @@ -194,11 +194,11 @@ index 552f9956bdc2c6148f2e338b02074b7c479994a9..20ebcd753bcce0112f6a2d96ea23ccb6 #include "llvm/ADT/iterator_range.h" #include "gtest/gtest.h" diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp -index fe827546aef2c26b8c5372b2643e84d60683a19a..0e68bad6c4d70737d42fdf385512d117ca7aac4c 100644 +index e1090e6f605696f60a82d1708605ddd45f4e15f8..26ef3aee0bebf351c148a3ce9eaada24d365f603 100644 --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp @@ -17,6 +17,10 @@ - #include + #include #include +#if defined(__GNUC__) diff --git a/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch b/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch index a6b0f68e94..8c32855848 100644 --- a/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch +++ b/upstream_utils/llvm_patches/0010-Remove-unused-functions.patch @@ -4,18 +4,18 @@ Date: Sun, 8 May 2022 13:43:50 -0400 Subject: [PATCH 10/30] Remove unused functions --- - llvm/include/llvm/ADT/SmallString.h | 80 ------ + llvm/include/llvm/ADT/SmallString.h | 85 +----- llvm/include/llvm/Support/Errno.h | 9 - - llvm/include/llvm/Support/VersionTuple.h | 40 --- - llvm/include/llvm/Support/raw_ostream.h | 115 +------- - llvm/lib/Support/raw_ostream.cpp | 328 ----------------------- - 5 files changed, 8 insertions(+), 564 deletions(-) + llvm/include/llvm/Support/VersionTuple.h | 39 --- + llvm/include/llvm/Support/raw_ostream.h | 127 +-------- + llvm/lib/Support/raw_ostream.cpp | 329 ----------------------- + 5 files changed, 10 insertions(+), 579 deletions(-) diff --git a/llvm/include/llvm/ADT/SmallString.h b/llvm/include/llvm/ADT/SmallString.h -index 50cbdade405770e80a6a45521a446a28e4177d11..bfa965fd68a09d7ca3b332e38585ae37a5982ed0 100644 +index 4d673cc8b1c49cf8a3f19653de53881cd12662ee..bfa965fd68a09d7ca3b332e38585ae37a5982ed0 100644 --- a/llvm/include/llvm/ADT/SmallString.h +++ b/llvm/include/llvm/ADT/SmallString.h -@@ -88,48 +88,12 @@ public: +@@ -88,49 +88,12 @@ public: /// @name String Comparison /// @{ @@ -30,8 +30,11 @@ index 50cbdade405770e80a6a45521a446a28e4177d11..bfa965fd68a09d7ca3b332e38585ae37 - return str().equals_insensitive(RHS); - } - - /// Compare two strings; the result is -1, 0, or 1 if this string is - /// lexicographically less than, equal to, or greater than the \p RHS. +- /// compare - Compare two strings; the result is negative, zero, or positive +- /// if this string is lexicographically less than, equal to, or greater than +- /// the \p RHS. ++ /// Compare two strings; the result is -1, 0, or 1 if this string is ++ /// lexicographically less than, equal to, or greater than the \p RHS. int compare(std::string_view RHS) const { return str().compare(RHS); } @@ -64,7 +67,7 @@ index 50cbdade405770e80a6a45521a446a28e4177d11..bfa965fd68a09d7ca3b332e38585ae37 /// @} /// @name String Searching /// @{ -@@ -210,50 +174,6 @@ public: +@@ -211,50 +174,6 @@ public: } /// @} @@ -116,10 +119,10 @@ index 50cbdade405770e80a6a45521a446a28e4177d11..bfa965fd68a09d7ca3b332e38585ae37 // Extra methods. diff --git a/llvm/include/llvm/Support/Errno.h b/llvm/include/llvm/Support/Errno.h -index 07df6765d9dbf5d6b88092737e081b441b1ccdc4..d9bf68bb369e524be5453c738ab9faa42f4b8cb8 100644 +index e095c66b90860001d90b5c2eb74f6032de6de454..787805dac6c5e3c8cb85dabeb80254443d60806c 100644 --- a/llvm/include/llvm/Support/Errno.h +++ b/llvm/include/llvm/Support/Errno.h -@@ -20,15 +20,6 @@ +@@ -19,15 +19,6 @@ namespace llvm { namespace sys { @@ -136,24 +139,16 @@ index 07df6765d9dbf5d6b88092737e081b441b1ccdc4..d9bf68bb369e524be5453c738ab9faa4 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 3d6573bf5a96e115ef264c7885b91aa3b32ac91e..a28e12adcc251bc3673f6a7c07d96d447aa0da98 100644 +index 953b40701dc934c1a356b5413c9c6c692d5f5679..30cf717973fb15ff65a47a2d80795c351b0d2768 100644 --- a/llvm/include/llvm/Support/VersionTuple.h +++ b/llvm/include/llvm/Support/VersionTuple.h -@@ -16,7 +16,6 @@ - - #include "llvm/ADT/DenseMapInfo.h" - #include "llvm/ADT/Hashing.h" --#include "llvm/Support/HashBuilder.h" - #include - #include - #include -@@ -159,45 +158,6 @@ public: +@@ -168,45 +168,6 @@ public: friend bool operator>=(const VersionTuple &X, const VersionTuple &Y) { return !(X < Y); } - -- friend llvm::hash_code hash_value(const VersionTuple &VT) { -- return llvm::hash_combine(VT.Major, VT.Minor, VT.Subminor, VT.Build); +- friend hash_code hash_value(const VersionTuple &VT) { +- return hash_combine(VT.Major, VT.Minor, VT.Subminor, VT.Build); - } - - template @@ -194,10 +189,10 @@ index 3d6573bf5a96e115ef264c7885b91aa3b32ac91e..a28e12adcc251bc3673f6a7c07d96d44 } // end namespace llvm diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c410121c71f83 100644 +index 0bf165c55921d7e09208a8fa8df7f9f5ad68d1e2..429d1dca24942d16e5c3a551035c0d459e7c5c00 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -248,32 +248,6 @@ public: +@@ -261,32 +261,6 @@ public: return write(Str.data(), Str.size()); } @@ -230,7 +225,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't /// satisfy llvm::isPrint into an escape sequence. raw_ostream &write_escaped(std::string_view Str, bool UseHexEscapes = false); -@@ -281,21 +255,6 @@ public: +@@ -294,21 +268,6 @@ public: raw_ostream &write(unsigned char C); raw_ostream &write(const char *Ptr, size_t Size); @@ -252,7 +247,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 /// indent - Insert 'NumSpaces' spaces. raw_ostream &indent(unsigned NumSpaces); -@@ -310,14 +269,19 @@ public: +@@ -323,14 +282,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, @@ -275,7 +270,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 /// This function determines if this stream is connected to a "tty" or /// "console" window. That is, the output would be displayed to the user -@@ -392,10 +356,6 @@ private: +@@ -405,10 +369,6 @@ private: /// unused bytes in the buffer. void copy_to_buffer(const char *Ptr, size_t Size); @@ -286,7 +281,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 /// Flush the tied-to stream (if present) and then write the required data. void flush_tied_then_write(const char *Ptr, size_t Size); -@@ -447,7 +407,6 @@ class raw_fd_ostream : public raw_pwrite_stream { +@@ -460,7 +420,6 @@ class raw_fd_ostream : public raw_pwrite_stream { bool ShouldClose; bool SupportsSeeking = false; bool IsRegularFile = false; @@ -294,7 +289,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 #ifdef _WIN32 /// True if this fd refers to a Windows console device. Mintty and other -@@ -523,10 +482,6 @@ public: +@@ -536,10 +495,6 @@ public: /// to the offset specified from the beginning of the file. uint64_t seek(uint64_t off); @@ -305,7 +300,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 std::error_code error() const { return EC; } /// Return the value of the flag in this raw_fd_ostream indicating whether an -@@ -545,38 +500,6 @@ public: +@@ -558,38 +513,6 @@ public: /// - from The Zen of Python, by Tim Peters /// void clear_error() { EC = std::error_code(); } @@ -330,7 +325,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 - /// }); - /// } - /// @endcode -- LLVM_NODISCARD Expected lock(); +- [[nodiscard]] Expected lock(); - - /// Tries to lock the underlying file within the specified period. - /// @@ -339,12 +334,12 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 - /// error code. - /// - /// It is used as @ref lock. -- LLVM_NODISCARD -- Expected tryLockFor(Duration const& Timeout); +- [[nodiscard]] Expected +- tryLockFor(Duration const &Timeout); }; /// This returns a reference to a raw_fd_ostream for standard output. Use it -@@ -606,17 +529,6 @@ public: +@@ -619,17 +542,6 @@ public: /// immediately destroyed. raw_fd_stream(std::string_view Filename, std::error_code &EC); @@ -362,7 +357,7 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 /// Check if \p OS is a pointer of type raw_fd_stream*. static bool classof(const raw_ostream *OS); }; -@@ -734,17 +646,6 @@ public: +@@ -747,29 +659,6 @@ public: ~buffer_unique_ostream() override { *OS << str(); } }; @@ -376,15 +371,27 @@ index a25ca5b7b556fd9ccd08ad13a6ceae6bedbcb09e..d4521c8e285f3fc404d27a6c528c4101 -/// temporary file after the \p Write function is finished. -Error writeToOutput(std::string_view OutputFileName, - std::function Write); +- +-raw_ostream &operator<<(raw_ostream &OS, std::nullopt_t); +- +-template () +- << std::declval())> +-raw_ostream &operator<<(raw_ostream &OS, const std::optional &O) { +- if (O) +- OS << *O; +- else +- OS << std::nullopt; +- return OS; +-} - } // end namespace llvm #endif // LLVM_SUPPORT_RAW_OSTREAM_H diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3ad8d2c74 100644 +index a2778407119ccd73031b22a5a091e21923905aa9..76c32155b4296fbbf3f4b164cd58d63f472ccd5e 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -19,7 +19,6 @@ +@@ -18,7 +18,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/Compiler.h" @@ -392,7 +399,7 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" -@@ -120,49 +119,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, +@@ -127,49 +126,6 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, assert(OutBufStart <= OutBufEnd && "Invalid size!"); } @@ -442,7 +449,7 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 raw_ostream &raw_ostream::write_escaped(std::string_view Str, bool UseHexEscapes) { for (unsigned char c : Str) { -@@ -308,172 +264,6 @@ void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) { +@@ -315,173 +271,6 @@ void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) { write_impl(Ptr, Size); } @@ -550,7 +557,7 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 - const size_t Size = Bytes.size(); - HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower; - uint64_t OffsetWidth = 0; -- if (FB.FirstByteOffset.hasValue()) { +- if (FB.FirstByteOffset) { - // Figure out how many nibbles are needed to print the largest offset - // represented by this data set, so that we can align the offset field - // to the right width. @@ -570,8 +577,8 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 - while (!Bytes.empty()) { - indent(FB.IndentLevel); - -- if (FB.FirstByteOffset.hasValue()) { -- uint64_t Offset = FB.FirstByteOffset.getValue(); +- if (FB.FirstByteOffset) { +- uint64_t Offset = *FB.FirstByteOffset; - llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth); - *this << ": "; - } @@ -612,10 +619,11 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 - } - return *this; -} - +- template static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) { -@@ -506,63 +296,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) { + static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, +@@ -512,63 +301,8 @@ raw_ostream &raw_ostream::write_zeros(unsigned NumZeros) { return write_padding<'\0'>(*this, NumZeros); } @@ -679,7 +687,7 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 //===----------------------------------------------------------------------===// // raw_fd_ostream //===----------------------------------------------------------------------===// -@@ -854,31 +589,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const { +@@ -867,31 +601,6 @@ size_t raw_fd_ostream::preferred_buffer_size() const { #endif } @@ -711,7 +719,7 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 void raw_fd_ostream::anchor() {} //===----------------------------------------------------------------------===// -@@ -921,16 +631,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC) +@@ -934,16 +643,6 @@ raw_fd_stream::raw_fd_stream(std::string_view Filename, std::error_code &EC) EC = std::make_error_code(std::errc::invalid_argument); } @@ -728,7 +736,7 @@ index ee01a95220806c500d2c0149e9f1e667ea8bf28b..875eda7ba440f2ae64dc32ebb0502ad3 bool raw_fd_stream::classof(const raw_ostream *OS) { return OS->get_kind() == OStreamKind::OK_FDStream; } -@@ -986,31 +686,3 @@ void raw_pwrite_stream::anchor() {} +@@ -999,31 +698,3 @@ void raw_pwrite_stream::anchor() {} void buffer_ostream::anchor() {} void buffer_unique_ostream::anchor() {} diff --git a/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch b/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch index fd60e00ca1..ee8a6fed31 100644 --- a/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch +++ b/upstream_utils/llvm_patches/0011-Detemplatize-SmallVectorBase.patch @@ -4,15 +4,15 @@ Date: Thu, 5 May 2022 23:18:34 -0400 Subject: [PATCH 11/30] Detemplatize SmallVectorBase --- - llvm/include/llvm/ADT/SmallVector.h | 21 +++++++----------- - llvm/lib/Support/SmallVector.cpp | 34 +++++------------------------ - 2 files changed, 13 insertions(+), 42 deletions(-) + llvm/include/llvm/ADT/SmallVector.h | 27 +++++++-------------- + llvm/lib/Support/SmallVector.cpp | 37 +++++------------------------ + 2 files changed, 14 insertions(+), 50 deletions(-) diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index 1e311ea56fd1d35505ca6740922c713d97636f09..4b6bbdeb2ea3e602978733351e352968ccdca36d 100644 +index 70c77618b307acfee816006d54eeddc422ab619b..3c523c969bd6ee0cc2f19c923231e55787879df9 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -50,14 +50,14 @@ template class iterator_range; +@@ -56,14 +56,14 @@ using EnableIfConvertibleToInputIterator = std::enable_if_t, where a /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for /// buffering bitcode output - which can exceed 4GB. @@ -30,14 +30,14 @@ index 1e311ea56fd1d35505ca6740922c713d97636f09..4b6bbdeb2ea3e602978733351e352968 } SmallVectorBase() = delete; -@@ -91,15 +91,10 @@ protected: +@@ -111,15 +111,10 @@ protected: } }; -template -using SmallVectorSizeType = -- typename std::conditional= 8, uint64_t, -- uint32_t>::type; +- std::conditional_t= 8, uint64_t, +- uint32_t>; - /// Figure out the offset of the first element. template struct SmallVectorAlignmentAndSize { @@ -48,7 +48,7 @@ index 1e311ea56fd1d35505ca6740922c713d97636f09..4b6bbdeb2ea3e602978733351e352968 alignas(T) char FirstEl[sizeof(T)]; }; -@@ -108,8 +103,8 @@ template struct SmallVectorAlignmentAndSize { +@@ -128,8 +123,8 @@ template struct SmallVectorAlignmentAndSize { /// to avoid unnecessarily requiring T to be complete. template class SmallVectorTemplateCommon @@ -57,19 +57,32 @@ index 1e311ea56fd1d35505ca6740922c713d97636f09..4b6bbdeb2ea3e602978733351e352968 + : public SmallVectorBase { + using Base = SmallVectorBase; + protected: /// Find the address of the first element. For this pointer math to be valid - /// with small-size of 0 for T with lots of alignment, it's important that -@@ -356,7 +351,7 @@ protected: - /// in \p NewCapacity. This is the first section of \a grow(). - T *mallocForGrow(size_t MinSize, size_t &NewCapacity) { - return static_cast( -- SmallVectorBase>::mallocForGrow( -+ SmallVectorBase::mallocForGrow( - MinSize, sizeof(T), NewCapacity)); - } +@@ -451,7 +446,7 @@ template + T *SmallVectorTemplateBase::mallocForGrow( + size_t MinSize, size_t &NewCapacity) { + return static_cast( +- SmallVectorBase>::mallocForGrow( ++ SmallVectorBase::mallocForGrow( + this->getFirstEl(), MinSize, sizeof(T), NewCapacity)); + } +@@ -1319,12 +1314,6 @@ template SmallVector to_vector_of(R &&Range) { + return {std::begin(Range), std::end(Range)}; + } + +-// Explicit instantiations +-extern template class llvm::SmallVectorBase; +-#if SIZE_MAX > UINT32_MAX +-extern template class llvm::SmallVectorBase; +-#endif +- + } // end namespace llvm + + namespace std { diff --git a/llvm/lib/Support/SmallVector.cpp b/llvm/lib/Support/SmallVector.cpp -index a2b4899e1ffe0ae19d236f43e2e2e2fe1db14110..bdfc963d7ff8ca684e37d08410b92a84d5d27730 100644 +index 6cefdff7c28060ca18b522acf5279af3a206e23a..ae64a36dcf4b9ceaf8767adbf8100f164f3738ac 100644 --- a/llvm/lib/Support/SmallVector.cpp +++ b/llvm/lib/Support/SmallVector.cpp @@ -51,10 +51,6 @@ static_assert(sizeof(SmallVector) == @@ -94,17 +107,31 @@ index a2b4899e1ffe0ae19d236f43e2e2e2fe1db14110..bdfc963d7ff8ca684e37d08410b92a84 // Ensure we can fit the new capacity. // This is only going to be applicable when the capacity is 32 bit. -@@ -108,18 +103,16 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) { +@@ -107,8 +102,7 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) { + return std::clamp(NewCapacity, MinSize, MaxSize); + } + +-template +-void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize, ++void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize, + size_t NewCapacity, + size_t VSize) { + void *NewEltsReplace = llvm::safe_malloc(NewCapacity * TSize); +@@ -119,11 +113,10 @@ void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize, } // Note: Moving this function into the header may cause performance regression. -template --void *SmallVectorBase::mallocForGrow(size_t MinSize, size_t TSize, -+void *SmallVectorBase::mallocForGrow(size_t MinSize, size_t TSize, +-void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, ++void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, + size_t TSize, size_t &NewCapacity) { - NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); + NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); - return llvm::safe_malloc(NewCapacity * TSize); + // Even if capacity is not 0 now, if the vector was originally created with + // capacity 0, it's possible for the malloc to return FirstEl. + void *NewElts = llvm::safe_malloc(NewCapacity * TSize); +@@ -133,10 +126,9 @@ void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, } // Note: Moving this function into the header may cause performance regression. @@ -116,8 +143,8 @@ index a2b4899e1ffe0ae19d236f43e2e2e2fe1db14110..bdfc963d7ff8ca684e37d08410b92a84 + size_t NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); void *NewElts; if (BeginX == FirstEl) { - NewElts = safe_malloc(NewCapacity * TSize); -@@ -134,20 +127,3 @@ void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize, + NewElts = llvm::safe_malloc(NewCapacity * TSize); +@@ -155,20 +147,3 @@ void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize, this->BeginX = NewElts; this->Capacity = NewCapacity; } diff --git a/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch b/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch index 52f261ce7a..4149596173 100644 --- a/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch +++ b/upstream_utils/llvm_patches/0012-Add-vectors-to-raw_ostream.patch @@ -9,18 +9,18 @@ Subject: [PATCH 12/30] 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 d4521c8e285f3fc404d27a6c528c410121c71f83..bf5630ab549d39cedcdaac80672c5122883e125b 100644 +index 429d1dca24942d16e5c3a551035c0d459e7c5c00..d656123867f331b32463f2da9e637892e0e39930 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -25,6 +25,7 @@ - #endif +@@ -24,6 +24,7 @@ + #include #include #include +#include namespace llvm { -@@ -248,12 +249,24 @@ public: +@@ -261,12 +262,24 @@ public: return write(Str.data(), Str.size()); } @@ -45,7 +45,7 @@ index d4521c8e285f3fc404d27a6c528c410121c71f83..bf5630ab549d39cedcdaac80672c5122 /// indent - Insert 'NumSpaces' spaces. raw_ostream &indent(unsigned NumSpaces); -@@ -604,6 +617,108 @@ public: +@@ -617,6 +630,108 @@ public: } }; @@ -155,10 +155,10 @@ index d4521c8e285f3fc404d27a6c528c410121c71f83..bf5630ab549d39cedcdaac80672c5122 class raw_null_ostream : public raw_pwrite_stream { /// See raw_ostream::write_impl. diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 875eda7ba440f2ae64dc32ebb0502ad3ad8d2c74..36faf744cf6c429917a793a363a7d3f22a6d7e67 100644 +index 76c32155b4296fbbf3f4b164cd58d63f472ccd5e..dcdfdfd7a8e3fcc4019538a4fc9e158aeda0a8b8 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -658,6 +658,53 @@ void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size, +@@ -670,6 +670,53 @@ void raw_svector_ostream::pwrite_impl(const char *Ptr, size_t Size, memcpy(OS.data() + Offset, Ptr, Size); } diff --git a/upstream_utils/llvm_patches/0013-Extra-collections-features.patch b/upstream_utils/llvm_patches/0013-Extra-collections-features.patch index 98e7f066bc..1a1b075dad 100644 --- a/upstream_utils/llvm_patches/0013-Extra-collections-features.patch +++ b/upstream_utils/llvm_patches/0013-Extra-collections-features.patch @@ -9,7 +9,7 @@ Subject: [PATCH 13/30] Extra collections features 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h -index 8747cdb353a89952e242ccfa5ea8a3e68571d456..16f13f048415182e061de6ba439eb23ddddb3bdc 100644 +index 1c8cda7ef0f8e2984f2d7960260f2a109a2986f7..99a183772f909ed9eab8c8e0c0fc87f183d2c98d 100644 --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -42,7 +42,7 @@ protected: @@ -142,7 +142,7 @@ index 8747cdb353a89952e242ccfa5ea8a3e68571d456..16f13f048415182e061de6ba439eb23d #endif // LLVM_ADT_STRINGMAP_H diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 36faf744cf6c429917a793a363a7d3f22a6d7e67..95152849cb920a61b4906f886f78d76e3fa2b22c 100644 +index dcdfdfd7a8e3fcc4019538a4fc9e158aeda0a8b8..b2a726633b48b179abfd24a5de110a2301e0f877 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -76,6 +76,14 @@ constexpr raw_ostream::Colors raw_ostream::WHITE; diff --git a/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch b/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch index 83bdd934de..1d3b5f5230 100644 --- a/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch +++ b/upstream_utils/llvm_patches/0014-EpochTracker-ABI-macro.patch @@ -8,7 +8,7 @@ Subject: [PATCH 14/30] EpochTracker ABI macro 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/ADT/EpochTracker.h b/llvm/include/llvm/ADT/EpochTracker.h -index b06888494466496b0c768e824ee25e2154d20f15..f35461d1c6e424cea6f072d749a6324699f8edd4 100644 +index a639d1b5b3ec4a18d3666ee62d83a9a382075d93..6fb2199ca3b9d7bb636a3e46e18b71f15bfa0494 100644 --- a/llvm/include/llvm/ADT/EpochTracker.h +++ b/llvm/include/llvm/ADT/EpochTracker.h @@ -22,7 +22,7 @@ diff --git a/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch b/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch index e3d0377546..6123e68331 100644 --- a/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch +++ b/upstream_utils/llvm_patches/0015-Delete-numbers-from-MathExtras.patch @@ -8,11 +8,11 @@ Subject: [PATCH 15/30] Delete numbers from MathExtras 1 file changed, 36 deletions(-) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index fac12dd0e4c6316ff4887542dd59adc954f099e4..e8f1f2aca6106af3885468f686331d8b083630d7 100644 +index 062ed2f4057820547cc6bfc4c91e7a13ceaa2f8a..cc0c1cbd1c8bb523bce720b9783afad7f602c88c 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -50,42 +50,6 @@ enum ZeroBehavior { - ZB_Width +@@ -32,42 +32,6 @@ enum ZeroBehavior { + ZB_Max }; -/// Mathematical constants. @@ -51,6 +51,6 @@ index fac12dd0e4c6316ff4887542dd59adc954f099e4..e8f1f2aca6106af3885468f686331d8b - phif = 1.61803399F; // (0x1.9e377aP+0) https://oeis.org/A001622 -} // namespace numbers - - namespace detail { - template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior) { + /// Count number of 0's from the least significant bit to the most + /// stopping at the first 1. + /// diff --git a/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch b/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch index 08ebb1d503..76283502df 100644 --- a/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch +++ b/upstream_utils/llvm_patches/0016-Add-lerp-and-sgn.patch @@ -8,10 +8,10 @@ Subject: [PATCH 16/30] Add lerp and sgn 1 file changed, 20 insertions(+) diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h -index e8f1f2aca6106af3885468f686331d8b083630d7..8116c58bd0d6d2b880a5a7c8c5f9ca07217987de 100644 +index cc0c1cbd1c8bb523bce720b9783afad7f602c88c..fe9c5136f9f2f687577a0b1ecce69262568a9c3c 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/include/llvm/Support/MathExtras.h -@@ -930,6 +930,26 @@ std::enable_if_t::value, T> MulOverflow(T X, T Y, T &Result) { +@@ -744,6 +744,26 @@ std::enable_if_t::value, T> MulOverflow(T X, T Y, T &Result) { return UX > (static_cast((std::numeric_limits::max)())) / UY; } diff --git a/upstream_utils/llvm_patches/0017-Fixup-includes.patch b/upstream_utils/llvm_patches/0017-Fixup-includes.patch index cf293c139d..ff06867326 100644 --- a/upstream_utils/llvm_patches/0017-Fixup-includes.patch +++ b/upstream_utils/llvm_patches/0017-Fixup-includes.patch @@ -9,14 +9,15 @@ Subject: [PATCH 17/30] Fixup includes llvm/include/llvm/Support/PointerLikeTypeTraits.h | 1 + llvm/lib/Support/ConvertUTFWrapper.cpp | 1 + llvm/lib/Support/ErrorHandling.cpp | 7 +++---- - llvm/lib/Support/raw_ostream.cpp | 12 ++++++------ + llvm/lib/Support/raw_ostream.cpp | 11 ++++++----- llvm/unittests/ADT/SmallPtrSetTest.cpp | 2 ++ + llvm/unittests/ADT/SmallVectorTest.cpp | 1 + llvm/unittests/ADT/StringMapTest.cpp | 1 + llvm/unittests/Support/ConvertUTFTest.cpp | 2 ++ - 9 files changed, 24 insertions(+), 10 deletions(-) + 10 files changed, 25 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h -index 16f13f048415182e061de6ba439eb23ddddb3bdc..6ae0e39a125ef145ca0887763e55c8150a902047 100644 +index 99a183772f909ed9eab8c8e0c0fc87f183d2c98d..2605dcd3dfd60a93d714caf8bc8058e3c983dbde 100644 --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -17,6 +17,10 @@ @@ -31,7 +32,7 @@ index 16f13f048415182e061de6ba439eb23ddddb3bdc..6ae0e39a125ef145ca0887763e55c815 #include #include diff --git a/llvm/include/llvm/ADT/StringMapEntry.h b/llvm/include/llvm/ADT/StringMapEntry.h -index 39976a02b5ecbbf5d08a6073708cac0a5aef447d..cdefc5449236a34683e64c1f4eebceae28954017 100644 +index 388e81c361642113937f7d5680de73a50635b07d..011806f5fd89ff738ed805a82b3ddbc6fc9b08ce 100644 --- a/llvm/include/llvm/ADT/StringMapEntry.h +++ b/llvm/include/llvm/ADT/StringMapEntry.h @@ -16,6 +16,10 @@ @@ -58,19 +59,19 @@ index 1b15f930bd87d97d51824af5e62ea5f222a6b4c9..acadd5e89a1651cfbad67a5b1b0933d1 namespace llvm { diff --git a/llvm/lib/Support/ConvertUTFWrapper.cpp b/llvm/lib/Support/ConvertUTFWrapper.cpp -index 396ab0c655ed50707c8725ebd22b1f8be5e0e030..cff30f16ca907959843dd58ff30f58ead333f17f 100644 +index bb5164ff9dce0271cafc5889a049b5d343530f8d..195071cc697070af2a75207fced50d49bae46c23 100644 --- a/llvm/lib/Support/ConvertUTFWrapper.cpp +++ b/llvm/lib/Support/ConvertUTFWrapper.cpp -@@ -8,6 +8,7 @@ +@@ -7,6 +7,7 @@ + //===----------------------------------------------------------------------===// - #include "llvm/ADT/span.h" #include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/SmallVector.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SwapByteOrder.h" - #include + #include diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index f80e28e8710817aa19ca7c012a0a4eaecc801c83..ec1a1633ae2952857619ba5e55dee3be7bc6aed5 100644 +index 0b87b375de67dc18647e3ebe646bf323dd05e8c5..3a88178cfbbcf7062a958c7de820247bc913ab33 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -28,12 +28,11 @@ @@ -90,20 +91,19 @@ index f80e28e8710817aa19ca7c012a0a4eaecc801c83..ec1a1633ae2952857619ba5e55dee3be using namespace llvm; diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 95152849cb920a61b4906f886f78d76e3fa2b22c..878a3a5e99949da360a93dc51298460cc61d4f3f 100644 +index b2a726633b48b179abfd24a5de110a2301e0f877..3b7d8d6db5f0df31e18b91be716a4fd21e7e3549 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -15,7 +15,8 @@ +@@ -15,6 +15,8 @@ #endif #include "llvm/Support/raw_ostream.h" --#include "llvm/ADT/STLArrayExtras.h" +#include "wpi/SmallString.h" +#include "wpi/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/Compiler.h" -@@ -33,12 +34,11 @@ +@@ -32,12 +34,11 @@ #include // may provide O_BINARY. @@ -119,10 +119,10 @@ index 95152849cb920a61b4906f886f78d76e3fa2b22c..878a3a5e99949da360a93dc51298460c #endif #if defined(__CYGWIN__) -@@ -60,7 +60,7 @@ - +@@ -60,7 +61,7 @@ #ifdef _WIN32 #include "llvm/Support/ConvertUTF.h" + #include "llvm/Support/Signals.h" -#include "llvm/Support/Windows/WindowsSupport.h" +#include "Windows/WindowsSupport.h" #endif @@ -141,8 +141,20 @@ index 531f81ab5b3fc1dcff731230f3cb7649cb90aedf..3db8b6e37d31a0a3cc304da8fc4cbbe1 using namespace llvm; TEST(SmallPtrSetTest, Assignment) { +diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp +index 26ef3aee0bebf351c148a3ce9eaada24d365f603..adb0755988c67ecd126931425296d32d833da561 100644 +--- a/llvm/unittests/ADT/SmallVectorTest.cpp ++++ b/llvm/unittests/ADT/SmallVectorTest.cpp +@@ -13,6 +13,7 @@ + #include "llvm/ADT/SmallVector.h" + #include "llvm/Support/Compiler.h" + #include "gtest/gtest.h" ++#include + #include + #include + #include diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp -index 6d0c0942cdc256a01afbeb1902f53bc9c53198d9..de6daf3daf4e59b57fa43df2526c62e854fa65ee 100644 +index d12c585660ba8d00556c37bd1e5e41fbc953acc1..a45dde69f833900fa1d7c5a1984edee3d501111d 100644 --- a/llvm/unittests/ADT/StringMapTest.cpp +++ b/llvm/unittests/ADT/StringMapTest.cpp @@ -9,6 +9,7 @@ @@ -154,7 +166,7 @@ index 6d0c0942cdc256a01afbeb1902f53bc9c53198d9..de6daf3daf4e59b57fa43df2526c62e8 #include using namespace llvm; diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp -index 9c798437a12d971a9206cbaff546ebc46c70f0d8..2fee8ad5c01294988457002517dcb8d983cac23d 100644 +index 3b07d344f15a555f11ad5f8177a0a65b8a4fa472..77e70a46d3621ecfaed923d87256184addfda721 100644 --- a/llvm/unittests/Support/ConvertUTFTest.cpp +++ b/llvm/unittests/Support/ConvertUTFTest.cpp @@ -7,6 +7,8 @@ diff --git a/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch b/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch index b67c4f3d1e..e0c72595ec 100644 --- a/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch +++ b/upstream_utils/llvm_patches/0018-Use-std-is_trivially_copy_constructible.patch @@ -4,38 +4,14 @@ Date: Sun, 8 May 2022 16:42:09 -0400 Subject: [PATCH 18/30] Use std::is_trivially_copy_constructible --- - llvm/include/llvm/ADT/PointerIntPair.h | 12 ---- - llvm/include/llvm/Support/type_traits.h | 91 +------------------------ - 2 files changed, 2 insertions(+), 101 deletions(-) + llvm/include/llvm/Support/type_traits.h | 37 ++----------------------- + 1 file changed, 2 insertions(+), 35 deletions(-) -diff --git a/llvm/include/llvm/ADT/PointerIntPair.h b/llvm/include/llvm/ADT/PointerIntPair.h -index b7ddf8855605d23ebe3d7587e4ccc694a72045ac..a48fb904bbf6fa70d8d81bffc34202978eccb71a 100644 ---- a/llvm/include/llvm/ADT/PointerIntPair.h -+++ b/llvm/include/llvm/ADT/PointerIntPair.h -@@ -128,18 +128,6 @@ public: - } - }; - --// Specialize is_trivially_copyable to avoid limitation of llvm::is_trivially_copyable --// when compiled with gcc 4.9. --template --struct is_trivially_copyable> : std::true_type { --#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE -- static_assert(std::is_trivially_copyable>::value, -- "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); --#endif --}; -- - - template - struct PointerIntPairInfo { diff --git a/llvm/include/llvm/Support/type_traits.h b/llvm/include/llvm/Support/type_traits.h -index 7b7d5d991f3f51862fad3267798737bc6ef8c845..72a2e84ad452a609d42ce7a43a3d26d118a08043 100644 +index a6046de87d1e3e1264a0040826ea347b870a8f9e..292a2cb78b93717647cf88d00f88c2eec14f52f6 100644 --- a/llvm/include/llvm/Support/type_traits.h +++ b/llvm/include/llvm/Support/type_traits.h -@@ -92,98 +92,11 @@ union trivial_helper { +@@ -92,44 +92,11 @@ union trivial_helper { } // end namespace detail @@ -78,61 +54,7 @@ index 7b7d5d991f3f51862fad3267798737bc6ef8c845..72a2e84ad452a609d42ce7a43a3d26d1 - static std::false_type get(...); - static constexpr bool value = decltype(get((T*)nullptr))::value; -}; -- -- --// An implementation of `std::is_trivially_copyable` since STL version --// is not equally supported by all compilers, especially GCC 4.9. --// Uniform implementation of this trait is important for ABI compatibility --// as it has an impact on SmallVector's ABI (among others). --template --class is_trivially_copyable { -- -- // copy constructors -- static constexpr bool has_trivial_copy_constructor = -- std::is_copy_constructible>::value; -- static constexpr bool has_deleted_copy_constructor = -- !std::is_copy_constructible::value; -- -- // move constructors -- static constexpr bool has_trivial_move_constructor = -- std::is_move_constructible>::value; -- static constexpr bool has_deleted_move_constructor = -- !std::is_move_constructible::value; -- -- // copy assign -- static constexpr bool has_trivial_copy_assign = -- is_copy_assignable>::value; -- static constexpr bool has_deleted_copy_assign = -- !is_copy_assignable::value; -- -- // move assign -- static constexpr bool has_trivial_move_assign = -- is_move_assignable>::value; -- static constexpr bool has_deleted_move_assign = -- !is_move_assignable::value; -- -- // destructor -- static constexpr bool has_trivial_destructor = -- std::is_destructible>::value; -- -- public: -- -- static constexpr bool value = -- has_trivial_destructor && -- (has_deleted_move_assign || has_trivial_move_assign) && -- (has_deleted_move_constructor || has_trivial_move_constructor) && -- (has_deleted_copy_assign || has_trivial_copy_assign) && -- (has_deleted_copy_constructor || has_trivial_copy_constructor); -- --#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE -- static_assert(value == std::is_trivially_copyable::value, -- "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); --#endif --}; --template --class is_trivially_copyable : public std::true_type { --}; +using is_trivially_copy_constructible = std::is_trivially_copy_constructible; - } // end namespace llvm + diff --git a/upstream_utils/llvm_patches/0019-Windows-support.patch b/upstream_utils/llvm_patches/0019-Windows-support.patch index 14d9fc4da4..524587acb0 100644 --- a/upstream_utils/llvm_patches/0019-Windows-support.patch +++ b/upstream_utils/llvm_patches/0019-Windows-support.patch @@ -6,10 +6,11 @@ Subject: [PATCH 19/30] Windows support --- .../llvm/Support/Windows/WindowsSupport.h | 45 +++++---- llvm/lib/Support/ConvertUTF.cpp | 95 +++++++++++++++++++ - 2 files changed, 124 insertions(+), 16 deletions(-) + llvm/lib/Support/raw_ostream.cpp | 1 - + 3 files changed, 124 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/Support/Windows/WindowsSupport.h b/llvm/include/llvm/Support/Windows/WindowsSupport.h -index 180803fbd3104ddf32c183684f226954c4fb8b0e..31120cfa0e8cafa8d4f332bf2374a88a3418f748 100644 +index aabdb2f14668a990329b57f5454a0d7db73e12ce..2ac474092a62d488da1ec7f07a1cd10b0781d938 100644 --- a/llvm/include/llvm/Support/Windows/WindowsSupport.h +++ b/llvm/include/llvm/Support/Windows/WindowsSupport.h @@ -35,8 +35,6 @@ @@ -67,9 +68,9 @@ index 180803fbd3104ddf32c183684f226954c4fb8b0e..31120cfa0e8cafa8d4f332bf2374a88a + return GetWindowsOSVersion() >= llvm::VersionTuple(6, 2, 0, 0); +} - /// Returns the Windows version as Major.Minor.0.BuildNumber. Uses - /// RtlGetVersion or GetVersionEx under the hood depending on what is available. -@@ -228,19 +254,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) { + /// Determines if the program is running on Windows 11 or Windows Server 2022. + bool RunningWindows11OrGreater(); +@@ -231,19 +257,6 @@ inline FILETIME toFILETIME(TimePoint<> TP) { return Time; } @@ -90,10 +91,10 @@ index 180803fbd3104ddf32c183684f226954c4fb8b0e..31120cfa0e8cafa8d4f332bf2374a88a } // end namespace llvm. diff --git a/llvm/lib/Support/ConvertUTF.cpp b/llvm/lib/Support/ConvertUTF.cpp -index e24a918c5c898206dc8b401c6214e4e9c652e9a9..c906ded91dfeaa07b782e1eccc28643d5497cb94 100644 +index bc04c5ab5113563fb82d7b3b168985369b611f4b..57eb64a6017a6964ab14b40b8c6b3563cd41ffac 100644 --- a/llvm/lib/Support/ConvertUTF.cpp +++ b/llvm/lib/Support/ConvertUTF.cpp -@@ -51,6 +51,11 @@ +@@ -67,6 +67,11 @@ #endif #include @@ -105,7 +106,7 @@ index e24a918c5c898206dc8b401c6214e4e9c652e9a9..c906ded91dfeaa07b782e1eccc28643d /* * This code extensively uses fall-through switches. * Keep the compiler from warning about that. -@@ -733,6 +738,96 @@ ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, +@@ -759,6 +764,96 @@ ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, --------------------------------------------------------------------- */ @@ -202,3 +203,15 @@ index e24a918c5c898206dc8b401c6214e4e9c652e9a9..c906ded91dfeaa07b782e1eccc28643d } // namespace llvm ConvertUTF_RESTORE_WARNINGS +diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp +index 3b7d8d6db5f0df31e18b91be716a4fd21e7e3549..4769d34a14f3f2cbaaa4df50ea7111fe9fa2792f 100644 +--- a/llvm/lib/Support/raw_ostream.cpp ++++ b/llvm/lib/Support/raw_ostream.cpp +@@ -534,7 +534,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)) { +- llvm::sys::CallOneShotPipeSignalHandler(); + errno = EPIPE; + } + #endif diff --git a/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch b/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch index ea7575c8e5..494e5d4483 100644 --- a/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch +++ b/upstream_utils/llvm_patches/0020-Prefer-fmtlib.patch @@ -8,7 +8,7 @@ Subject: [PATCH 20/30] Prefer fmtlib 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index ec1a1633ae2952857619ba5e55dee3be7bc6aed5..27ca15f7d239a8e5050cadd159dad96de150e444 100644 +index 3a88178cfbbcf7062a958c7de820247bc913ab33..54137a331ca9e752b02c0f16ae996094a6f2fafa 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp @@ -22,7 +22,7 @@ @@ -37,7 +37,7 @@ index ec1a1633ae2952857619ba5e55dee3be7bc6aed5..27ca15f7d239a8e5050cadd159dad96d } // If we reached here, we are failing ungracefully. Run the interrupt handlers -@@ -173,11 +165,11 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, +@@ -176,11 +168,11 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, // llvm_unreachable is intended to be used to indicate "impossible" // situations, and not legitimate runtime errors. if (msg) diff --git a/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch b/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch index 14093446d3..210914c895 100644 --- a/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch +++ b/upstream_utils/llvm_patches/0021-Prefer-wpi-s-fs.h.patch @@ -8,16 +8,16 @@ Subject: [PATCH 21/30] Prefer wpi's fs.h 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 bf5630ab549d39cedcdaac80672c5122883e125b..256bcec259a8026473a5f3926bd79b215bd5b888 100644 +index d656123867f331b32463f2da9e637892e0e39930..582b731b0495ad2a38911ef1f9fe6d2aec58aea1 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -27,18 +27,15 @@ +@@ -26,18 +26,15 @@ #include #include -namespace llvm { - --template class LLVM_NODISCARD Expected; +-template class [[nodiscard]] Expected; -namespace sys { namespace fs { diff --git a/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch b/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch index 5a42498772..3ee83aaf5b 100644 --- a/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch +++ b/upstream_utils/llvm_patches/0022-Remove-unused-functions.patch @@ -7,9 +7,9 @@ Subject: [PATCH 22/30] Remove unused functions llvm/include/llvm/Support/DJB.h | 3 - llvm/include/llvm/Support/raw_ostream.h | 5 +- llvm/lib/Support/ErrorHandling.cpp | 16 ----- - llvm/lib/Support/raw_ostream.cpp | 49 +++++++-------- + llvm/lib/Support/raw_ostream.cpp | 47 +++++++------- llvm/unittests/ADT/SmallStringTest.cpp | 81 ------------------------- - 5 files changed, 23 insertions(+), 131 deletions(-) + 5 files changed, 23 insertions(+), 129 deletions(-) diff --git a/llvm/include/llvm/Support/DJB.h b/llvm/include/llvm/Support/DJB.h index 8737cd144c37f9041a781a74e9f2b43384e85761..67b0ae91b4b1401374d7d39d859daaf30da17ee2 100644 @@ -26,10 +26,10 @@ index 8737cd144c37f9041a781a74e9f2b43384e85761..67b0ae91b4b1401374d7d39d859daaf3 #endif // LLVM_SUPPORT_DJB_H diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h -index 256bcec259a8026473a5f3926bd79b215bd5b888..9b3a87e1bbc0abe83b204bd8f889ffe3a3cafffa 100644 +index 582b731b0495ad2a38911ef1f9fe6d2aec58aea1..3edc33b9dcc94a2ef68d52bc0af178121447acaa 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h -@@ -71,7 +71,6 @@ private: +@@ -70,7 +70,6 @@ private: /// for a \see write_impl() call to handle the data which has been put into /// this buffer. char *OutBufStart, *OutBufEnd, *OutBufCur; @@ -37,7 +37,7 @@ index 256bcec259a8026473a5f3926bd79b215bd5b888..9b3a87e1bbc0abe83b204bd8f889ffe3 /// Optional stream this stream is tied to. If this stream is written to, the /// tied-to stream will be flushed first. -@@ -304,9 +303,9 @@ public: +@@ -317,9 +316,9 @@ public: // Enable or disable colors. Once enable_colors(false) is called, // changeColor() has no effect until enable_colors(true) is called. @@ -50,10 +50,10 @@ index 256bcec259a8026473a5f3926bd79b215bd5b888..9b3a87e1bbc0abe83b204bd8f889ffe3 /// Tie this stream to the specified stream. Replaces any existing tied-to /// stream. Specifying a nullptr unties the stream. diff --git a/llvm/lib/Support/ErrorHandling.cpp b/llvm/lib/Support/ErrorHandling.cpp -index 27ca15f7d239a8e5050cadd159dad96de150e444..53fe22b5eb8dad289cced414ed6f544fd0249504 100644 +index 54137a331ca9e752b02c0f16ae996094a6f2fafa..e253d6f7a5ca3aee75823efdb9717dcd93fff5dc 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -178,22 +178,6 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, +@@ -181,22 +181,6 @@ void llvm::llvm_unreachable_internal(const char *msg, const char *file, #endif } @@ -77,10 +77,10 @@ index 27ca15f7d239a8e5050cadd159dad96de150e444..53fe22b5eb8dad289cced414ed6f544f #include diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp -index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf14093bc3 100644 +index 4769d34a14f3f2cbaaa4df50ea7111fe9fa2792f..f9928ac969932b6baea60a80750477d78b6a5b02 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -167,16 +167,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str, +@@ -175,16 +175,6 @@ raw_ostream &raw_ostream::write_escaped(std::string_view Str, return *this; } @@ -97,7 +97,7 @@ index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf void raw_ostream::flush_nonempty() { assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty."); size_t Length = OutBufCur - OutBufStart; -@@ -321,15 +311,22 @@ static int getFD(std::string_view Filename, std::error_code &EC, +@@ -327,15 +317,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. @@ -125,7 +125,7 @@ index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf if (EC) return -1; -@@ -389,12 +386,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, +@@ -395,12 +392,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); @@ -139,7 +139,7 @@ index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf #else SupportsSeeking = !EC && loc != (off_t)-1; #endif -@@ -407,10 +400,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, +@@ -413,10 +406,8 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered, raw_fd_ostream::~raw_fd_ostream() { if (FD >= 0) { flush(); @@ -152,7 +152,7 @@ index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf } #ifdef __MINGW32__ -@@ -505,7 +496,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { +@@ -511,7 +502,11 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { do { size_t ChunkSize = std::min(Size, MaxWriteSize); @@ -164,7 +164,7 @@ index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf if (ret < 0) { // If it's a recoverable error, swallow it and retry the write. -@@ -540,8 +535,8 @@ void raw_fd_ostream::close() { +@@ -554,8 +549,8 @@ void raw_fd_ostream::close() { assert(ShouldClose); ShouldClose = false; flush(); @@ -175,17 +175,8 @@ index 878a3a5e99949da360a93dc51298460cc61d4f3f..632b522358c969682f01dbbb9a6f86cf FD = -1; } -@@ -550,8 +545,6 @@ uint64_t raw_fd_ostream::seek(uint64_t off) { - flush(); - #ifdef _WIN32 - pos = ::_lseeki64(FD, off, SEEK_SET); --#elif defined(HAVE_LSEEK64) -- pos = ::lseek64(FD, off, SEEK_SET); - #else - pos = ::lseek(FD, off, SEEK_SET); - #endif diff --git a/llvm/unittests/ADT/SmallStringTest.cpp b/llvm/unittests/ADT/SmallStringTest.cpp -index bee3875d11c9b793d79ac442312559b11dba9f5f..87600ea4704bc98acab9085d16cfafd3d586714e 100644 +index 6cf14700b34739420cd3dc4ff8a4c16ce162f715..87600ea4704bc98acab9085d16cfafd3d586714e 100644 --- a/llvm/unittests/ADT/SmallStringTest.cpp +++ b/llvm/unittests/ADT/SmallStringTest.cpp @@ -129,23 +129,6 @@ TEST_F(SmallStringTest, StdStringConversion) { @@ -239,12 +230,12 @@ index bee3875d11c9b793d79ac442312559b11dba9f5f..87600ea4704bc98acab9085d16cfafd3 -} - -TEST_F(SmallStringTest, Comparisons) { -- EXPECT_EQ(-1, SmallString<10>("aab").compare("aad")); +- EXPECT_GT( 0, SmallString<10>("aab").compare("aad")); - EXPECT_EQ( 0, SmallString<10>("aab").compare("aab")); -- EXPECT_EQ( 1, SmallString<10>("aab").compare("aaa")); -- EXPECT_EQ(-1, SmallString<10>("aab").compare("aabb")); -- EXPECT_EQ( 1, SmallString<10>("aab").compare("aa")); -- EXPECT_EQ( 1, SmallString<10>("\xFF").compare("\1")); +- EXPECT_LT( 0, SmallString<10>("aab").compare("aaa")); +- EXPECT_GT( 0, SmallString<10>("aab").compare("aabb")); +- EXPECT_LT( 0, SmallString<10>("aab").compare("aa")); +- EXPECT_LT( 0, SmallString<10>("\xFF").compare("\1")); - - EXPECT_EQ(-1, SmallString<10>("AaB").compare_insensitive("aAd")); - EXPECT_EQ( 0, SmallString<10>("AaB").compare_insensitive("aab")); diff --git a/upstream_utils/llvm_patches/0023-OS-specific-changes.patch b/upstream_utils/llvm_patches/0023-OS-specific-changes.patch index 4ef327dccb..1fa478753c 100644 --- a/upstream_utils/llvm_patches/0023-OS-specific-changes.patch +++ b/upstream_utils/llvm_patches/0023-OS-specific-changes.patch @@ -4,14 +4,14 @@ Date: Sun, 8 May 2022 19:30:43 -0400 Subject: [PATCH 23/30] OS-specific changes --- - llvm/lib/Support/ErrorHandling.cpp | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) + 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 53fe22b5eb8dad289cced414ed6f544fd0249504..5c08e469e2e44b27e69f4aa974bc59deb8217c9b 100644 +index e253d6f7a5ca3aee75823efdb9717dcd93fff5dc..5c08e469e2e44b27e69f4aa974bc59deb8217c9b 100644 --- a/llvm/lib/Support/ErrorHandling.cpp +++ b/llvm/lib/Support/ErrorHandling.cpp -@@ -96,12 +96,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { +@@ -96,15 +96,7 @@ void llvm::report_fatal_error(std::string_view Reason, bool GenCrashDiag) { fmt::print(stderr, "LLVM ERROR: {}\n", Reason); } @@ -20,12 +20,15 @@ index 53fe22b5eb8dad289cced414ed6f544fd0249504..5c08e469e2e44b27e69f4aa974bc59de - // files registered with RemoveFileOnSignal. - sys::RunInterruptHandlers(); - -- abort(); +- if (GenCrashDiag) +- abort(); +- else +- exit(1); + exit(1); } void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, -@@ -138,9 +133,15 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { +@@ -141,9 +133,15 @@ void llvm::report_bad_alloc_error(const char *Reason, bool GenCrashDiag) { // an OOM to stderr and abort. const char *OOMMessage = "LLVM ERROR: out of memory\n"; const char *Newline = "\n"; diff --git a/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch b/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch index 2da05d94ff..38a87c197a 100644 --- a/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch +++ b/upstream_utils/llvm_patches/0024-Use-SmallVector-for-UTF-conversion.patch @@ -10,10 +10,10 @@ Subject: [PATCH 24/30] Use SmallVector for UTF conversion 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/Support/ConvertUTF.h b/llvm/include/llvm/Support/ConvertUTF.h -index b085c8a179e8767a258f9feafc8d1111828f10b1..c82947006afb3f8b41c0369352de63fd62be574b 100644 +index 72321022beb373945f7935ed72944fd68eb7d02f..5c8b966ce296699a0315d72cdfdcdb5af3d1d0b0 100644 --- a/llvm/include/llvm/Support/ConvertUTF.h +++ b/llvm/include/llvm/Support/ConvertUTF.h -@@ -213,7 +213,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result); +@@ -233,7 +233,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result); * Converts a std::wstring to a UTF-8 encoded std::string. * \return true on success. */ @@ -22,7 +22,7 @@ index b085c8a179e8767a258f9feafc8d1111828f10b1..c82947006afb3f8b41c0369352de63fd /** -@@ -268,7 +268,7 @@ bool hasUTF16ByteOrderMark(span SrcBytes); +@@ -288,7 +288,7 @@ bool hasUTF16ByteOrderMark(span SrcBytes); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ @@ -31,7 +31,7 @@ index b085c8a179e8767a258f9feafc8d1111828f10b1..c82947006afb3f8b41c0369352de63fd /** * Converts a UTF16 string into a UTF8 std::string. -@@ -277,7 +277,7 @@ bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out); +@@ -297,7 +297,7 @@ bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out); * \param [out] Out Converted UTF-8 is stored here on success. * \returns true on success */ @@ -39,13 +39,13 @@ index b085c8a179e8767a258f9feafc8d1111828f10b1..c82947006afb3f8b41c0369352de63fd +bool convertUTF16ToUTF8String(span Src, SmallVectorImpl &Out); /** - * Converts a UTF-8 string into a UTF-16 string with native endianness. + * 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 cff30f16ca907959843dd58ff30f58ead333f17f..d3689d92a45a289aaca30c47790a5e46c484344c 100644 +index 195071cc697070af2a75207fced50d49bae46c23..d13d876d6c5c830bede6ed90ff2cfa6236a79504 100644 --- a/llvm/lib/Support/ConvertUTFWrapper.cpp +++ b/llvm/lib/Support/ConvertUTFWrapper.cpp -@@ -84,7 +84,7 @@ bool hasUTF16ByteOrderMark(span S) { - (S[0] == '\xfe' && S[1] == '\xff'))); +@@ -82,7 +82,7 @@ bool hasUTF16ByteOrderMark(span S) { + (S[0] == '\xfe' && S[1] == '\xff'))); } -bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out) { @@ -53,16 +53,16 @@ index cff30f16ca907959843dd58ff30f58ead333f17f..d3689d92a45a289aaca30c47790a5e46 assert(Out.empty()); // Error out on an uneven byte count. -@@ -135,7 +135,7 @@ bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out) { +@@ -133,7 +133,7 @@ bool convertUTF16ToUTF8String(span SrcBytes, std::string &Out) { return true; } --bool convertUTF16ToUTF8String(span Src, std::string &Out) -+bool convertUTF16ToUTF8String(span Src, SmallVectorImpl &Out) - { +-bool convertUTF16ToUTF8String(span Src, std::string &Out) { ++bool convertUTF16ToUTF8String(span Src, SmallVectorImpl &Out) { return convertUTF16ToUTF8String( span(reinterpret_cast(Src.data()), -@@ -213,7 +213,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) { + Src.size() * sizeof(UTF16)), +@@ -269,7 +269,7 @@ bool ConvertUTF8toWide(const char *Source, std::wstring &Result) { return ConvertUTF8toWide(std::string_view(Source), Result); } @@ -72,10 +72,10 @@ index cff30f16ca907959843dd58ff30f58ead333f17f..d3689d92a45a289aaca30c47790a5e46 const UTF8 *Start = reinterpret_cast(Source.data()); const UTF8 *End = diff --git a/llvm/unittests/Support/ConvertUTFTest.cpp b/llvm/unittests/Support/ConvertUTFTest.cpp -index 2fee8ad5c01294988457002517dcb8d983cac23d..7d7650b1c077af7baed2b408584e857602bc329a 100644 +index 77e70a46d3621ecfaed923d87256184addfda721..eb17a06c4369c9486c57b61f519a7429d9ef3d80 100644 --- a/llvm/unittests/Support/ConvertUTFTest.cpp +++ b/llvm/unittests/Support/ConvertUTFTest.cpp -@@ -19,22 +19,22 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) { +@@ -19,11 +19,11 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) { // Src is the look of disapproval. alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c"; span Ref(Src, sizeof(Src) - 1); @@ -88,7 +88,8 @@ index 2fee8ad5c01294988457002517dcb8d983cac23d..7d7650b1c077af7baed2b408584e8576 + EXPECT_EQ(Expected, std::string{Result}); } - TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) { + TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) { +@@ -42,11 +42,11 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) { // Src is the look of disapproval. alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0"; span Ref(Src, sizeof(Src) - 1); @@ -101,8 +102,8 @@ index 2fee8ad5c01294988457002517dcb8d983cac23d..7d7650b1c077af7baed2b408584e8576 + EXPECT_EQ(Expected, std::string{Result}); } - TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { -@@ -51,16 +51,16 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { + TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) { +@@ -75,17 +75,17 @@ TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { } TEST(ConvertUTFTest, OddLengthInput) { @@ -115,14 +116,15 @@ index 2fee8ad5c01294988457002517dcb8d983cac23d..7d7650b1c077af7baed2b408584e8576 TEST(ConvertUTFTest, Empty) { - std::string Result; + SmallString<20> Result; - bool Success = convertUTF16ToUTF8String(span(), Result); + bool Success = + convertUTF16ToUTF8String(span(), Result); EXPECT_TRUE(Success); - EXPECT_TRUE(Result.empty()); + EXPECT_TRUE(std::string{Result}.empty()); } TEST(ConvertUTFTest, HasUTF16BOM) { -@@ -83,11 +83,11 @@ TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) { +@@ -108,11 +108,11 @@ TEST(ConvertUTFTest, UTF16WrappersForConvertUTF16ToUTF8String) { // Src is the look of disapproval. alignas(UTF16) static const char Src[] = "\xff\xfe\xa0\x0c_\x00\xa0\x0c"; span SrcRef((const UTF16 *)Src, 4); @@ -136,7 +138,7 @@ index 2fee8ad5c01294988457002517dcb8d983cac23d..7d7650b1c077af7baed2b408584e8576 } TEST(ConvertUTFTest, ConvertUTF8toWide) { -@@ -107,11 +107,11 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) { +@@ -132,11 +132,11 @@ TEST(ConvertUTFTest, ConvertUTF8toWide) { TEST(ConvertUTFTest, convertWideToUTF8) { // Src is the look of disapproval. static const wchar_t Src[] = L"\x0ca0_\x0ca0"; diff --git a/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch b/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch index bfbe6b3bc8..5d23715883 100644 --- a/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch +++ b/upstream_utils/llvm_patches/0025-Prefer-to-use-static-pointers-in-raw_ostream.patch @@ -9,10 +9,10 @@ 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 632b522358c969682f01dbbb9a6f86cf14093bc3..a703a75edb480b6499ea5ef5945237719b3c565a 100644 +index f9928ac969932b6baea60a80750477d78b6a5b02..1de34976844d500970b833fca35324e2948733b7 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp -@@ -599,15 +599,15 @@ void raw_fd_ostream::anchor() {} +@@ -613,15 +613,15 @@ void raw_fd_ostream::anchor() {} raw_fd_ostream &llvm::outs() { // Set buffer settings to model stdout behavior. std::error_code EC; diff --git a/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch b/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch index 555fbd3ab7..d075e7c867 100644 --- a/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch +++ b/upstream_utils/llvm_patches/0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch @@ -8,10 +8,10 @@ Subject: [PATCH 27/30] Copy type traits from STLExtras.h into PointerUnion.h 1 file changed, 46 insertions(+) diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h -index 1d4cc747ce320e27004170fb0aa76323d2ac22b1..7d090da591ad722a9cde7915bea48eec0ef1a408 100644 +index 6abec033a4008057f30d445d47ab22ebbb046a2f..7303694ef3d0cb833db3cb9f86bd155ab6136511 100644 --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h -@@ -22,9 +22,55 @@ +@@ -23,9 +23,55 @@ #include #include #include diff --git a/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch b/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch index 1cb9dc54b0..feb662e8ce 100644 --- a/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch +++ b/upstream_utils/llvm_patches/0028-Remove-StringMap-test-for-llvm-sort.patch @@ -8,7 +8,7 @@ Subject: [PATCH 28/30] Remove StringMap test for llvm::sort() 1 file changed, 14 deletions(-) diff --git a/llvm/unittests/ADT/StringMapTest.cpp b/llvm/unittests/ADT/StringMapTest.cpp -index de6daf3daf4e59b57fa43df2526c62e854fa65ee..ca41631ccf9519740e9f5f303dfbfe31762e3ab8 100644 +index a45dde69f833900fa1d7c5a1984edee3d501111d..d232c61e84a93fdc4d4c3a77b1f6124269d1fc05 100644 --- a/llvm/unittests/ADT/StringMapTest.cpp +++ b/llvm/unittests/ADT/StringMapTest.cpp @@ -308,20 +308,6 @@ TEST_F(StringMapTest, InsertOrAssignTest) { diff --git a/upstream_utils/llvm_patches/0029-Fix-docs-typo-in-SmallVector.patch b/upstream_utils/llvm_patches/0029-Fix-docs-typo-in-SmallVector.patch deleted file mode 100644 index 90e9bdebfb..0000000000 --- a/upstream_utils/llvm_patches/0029-Fix-docs-typo-in-SmallVector.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ryan Blue -Date: Thu, 8 Jun 2023 18:49:52 -0400 -Subject: [PATCH 29/30] Fix docs typo in SmallVector - ---- - llvm/include/llvm/ADT/SmallVector.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h -index 4b6bbdeb2ea3e602978733351e352968ccdca36d..84713da54c49125697635381002d81df954915d9 100644 ---- a/llvm/include/llvm/ADT/SmallVector.h -+++ b/llvm/include/llvm/ADT/SmallVector.h -@@ -6,7 +6,7 @@ - // - //===----------------------------------------------------------------------===// - /// --/// /file -+/// \file - /// This file defines the SmallVector class. - /// - //===----------------------------------------------------------------------===// diff --git a/upstream_utils/llvm_patches/0030-Unused-variable-in-release-mode.patch b/upstream_utils/llvm_patches/0029-Unused-variable-in-release-mode.patch similarity index 82% rename from upstream_utils/llvm_patches/0030-Unused-variable-in-release-mode.patch rename to upstream_utils/llvm_patches/0029-Unused-variable-in-release-mode.patch index a22b54d33a..497387d2bc 100644 --- a/upstream_utils/llvm_patches/0030-Unused-variable-in-release-mode.patch +++ b/upstream_utils/llvm_patches/0029-Unused-variable-in-release-mode.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Mon, 10 Jul 2023 00:53:43 +0200 -Subject: [PATCH 30/30] Unused variable in release mode +Subject: [PATCH 29/30] 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 975c3b97e2cbf09225299c421406ad2bbe4ef125..ada70d6c826d8f5bb65e502be15317692febb55c 100644 +index 7f4ddc256a207289980b60385f02da69f7119578..838a9b88648c7ce57b9ef4894573ddc25c74340a 100644 --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h -@@ -126,7 +126,7 @@ public: +@@ -124,7 +124,7 @@ public: for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) P->getFirst() = EmptyKey; } else { diff --git a/upstream_utils/llvm_patches/0030-Use-C-20-bit-header.patch b/upstream_utils/llvm_patches/0030-Use-C-20-bit-header.patch new file mode 100644 index 0000000000..f1ce2c5d6d --- /dev/null +++ b/upstream_utils/llvm_patches/0030-Use-C-20-bit-header.patch @@ -0,0 +1,436 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tyler Veness +Date: Tue, 11 Jul 2023 22:56:09 -0700 +Subject: [PATCH 30/30] Use C++20 header + +--- + llvm/include/llvm/ADT/bit.h | 256 ------------------------- + llvm/include/llvm/Support/MathExtras.h | 37 ++-- + 2 files changed, 19 insertions(+), 274 deletions(-) + +diff --git a/llvm/include/llvm/ADT/bit.h b/llvm/include/llvm/ADT/bit.h +index d93023d88b4efe962f425d0b8fe98fc25394f1fe..0a4a3634820efbc0a8ca675e3ad7c98469260d0b 100644 +--- a/llvm/include/llvm/ADT/bit.h ++++ b/llvm/include/llvm/ADT/bit.h +@@ -27,18 +27,6 @@ + #include // for _byteswap_{ushort,ulong,uint64} + #endif + +-#ifdef _MSC_VER +-// Declare these intrinsics manually rather including intrin.h. It's very +-// expensive, and bit.h is popular via MathExtras.h. +-// #include +-extern "C" { +-unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); +-unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); +-unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); +-unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); +-} +-#endif +- + namespace llvm { + + // This implementation of bit_cast is different from the C++20 one in two ways: +@@ -106,250 +94,6 @@ template >> + } + } + +-template >> +-[[nodiscard]] constexpr inline bool has_single_bit(T Value) noexcept { +- return (Value != 0) && ((Value & (Value - 1)) == 0); +-} +- +-namespace detail { +-template struct TrailingZerosCounter { +- static unsigned count(T Val) { +- if (!Val) +- return std::numeric_limits::digits; +- if (Val & 0x1) +- return 0; +- +- // Bisection method. +- unsigned ZeroBits = 0; +- T Shift = std::numeric_limits::digits >> 1; +- T Mask = std::numeric_limits::max() >> Shift; +- while (Shift) { +- if ((Val & Mask) == 0) { +- Val >>= Shift; +- ZeroBits |= Shift; +- } +- Shift >>= 1; +- Mask >>= Shift; +- } +- return ZeroBits; +- } +-}; +- +-#if defined(__GNUC__) || defined(_MSC_VER) +-template struct TrailingZerosCounter { +- static unsigned count(T Val) { +- if (Val == 0) +- return 32; +- +-#if __has_builtin(__builtin_ctz) || defined(__GNUC__) +- return __builtin_ctz(Val); +-#elif defined(_MSC_VER) +- unsigned long Index; +- _BitScanForward(&Index, Val); +- return Index; +-#endif +- } +-}; +- +-#if !defined(_MSC_VER) || defined(_M_X64) +-template struct TrailingZerosCounter { +- static unsigned count(T Val) { +- if (Val == 0) +- return 64; +- +-#if __has_builtin(__builtin_ctzll) || defined(__GNUC__) +- return __builtin_ctzll(Val); +-#elif defined(_MSC_VER) +- unsigned long Index; +- _BitScanForward64(&Index, Val); +- return Index; +-#endif +- } +-}; +-#endif +-#endif +-} // namespace detail +- +-/// Count number of 0's from the least significant bit to the most +-/// stopping at the first 1. +-/// +-/// Only unsigned integral types are allowed. +-/// +-/// Returns std::numeric_limits::digits on an input of 0. +-template [[nodiscard]] int countr_zero(T Val) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- return llvm::detail::TrailingZerosCounter::count(Val); +-} +- +-namespace detail { +-template struct LeadingZerosCounter { +- static unsigned count(T Val) { +- if (!Val) +- return std::numeric_limits::digits; +- +- // Bisection method. +- unsigned ZeroBits = 0; +- for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { +- T Tmp = Val >> Shift; +- if (Tmp) +- Val = Tmp; +- else +- ZeroBits |= Shift; +- } +- return ZeroBits; +- } +-}; +- +-#if defined(__GNUC__) || defined(_MSC_VER) +-template struct LeadingZerosCounter { +- static unsigned count(T Val) { +- if (Val == 0) +- return 32; +- +-#if __has_builtin(__builtin_clz) || defined(__GNUC__) +- return __builtin_clz(Val); +-#elif defined(_MSC_VER) +- unsigned long Index; +- _BitScanReverse(&Index, Val); +- return Index ^ 31; +-#endif +- } +-}; +- +-#if !defined(_MSC_VER) || defined(_M_X64) +-template struct LeadingZerosCounter { +- static unsigned count(T Val) { +- if (Val == 0) +- return 64; +- +-#if __has_builtin(__builtin_clzll) || defined(__GNUC__) +- return __builtin_clzll(Val); +-#elif defined(_MSC_VER) +- unsigned long Index; +- _BitScanReverse64(&Index, Val); +- return Index ^ 63; +-#endif +- } +-}; +-#endif +-#endif +-} // namespace detail +- +-/// Count number of 0's from the most significant bit to the least +-/// stopping at the first 1. +-/// +-/// Only unsigned integral types are allowed. +-/// +-/// Returns std::numeric_limits::digits on an input of 0. +-template [[nodiscard]] int countl_zero(T Val) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- return llvm::detail::LeadingZerosCounter::count(Val); +-} +- +-/// Count the number of ones from the most significant bit to the first +-/// zero bit. +-/// +-/// Ex. countl_one(0xFF0FFF00) == 8. +-/// Only unsigned integral types are allowed. +-/// +-/// Returns std::numeric_limits::digits on an input of all ones. +-template [[nodiscard]] int countl_one(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- return llvm::countl_zero(~Value); +-} +- +-/// Count the number of ones from the least significant bit to the first +-/// zero bit. +-/// +-/// Ex. countr_one(0x00FF00FF) == 8. +-/// Only unsigned integral types are allowed. +-/// +-/// Returns std::numeric_limits::digits on an input of all ones. +-template [[nodiscard]] int countr_one(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- return llvm::countr_zero(~Value); +-} +- +-/// Returns the number of bits needed to represent Value if Value is nonzero. +-/// Returns 0 otherwise. +-/// +-/// Ex. bit_width(5) == 3. +-template [[nodiscard]] int bit_width(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- return std::numeric_limits::digits - llvm::countl_zero(Value); +-} +- +-/// Returns the largest integral power of two no greater than Value if Value is +-/// nonzero. Returns 0 otherwise. +-/// +-/// Ex. bit_floor(5) == 4. +-template [[nodiscard]] T bit_floor(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- if (!Value) +- return 0; +- return T(1) << (llvm::bit_width(Value) - 1); +-} +- +-/// Returns the smallest integral power of two no smaller than Value if Value is +-/// nonzero. Returns 0 otherwise. +-/// +-/// Ex. bit_ceil(5) == 8. +-/// +-/// The return value is undefined if the input is larger than the largest power +-/// of two representable in T. +-template [[nodiscard]] T bit_ceil(T Value) { +- static_assert(std::is_unsigned_v, +- "Only unsigned integral types are allowed."); +- if (Value < 2) +- return 1; +- return T(1) << llvm::bit_width(Value - 1u); +-} +- +-namespace detail { +-template struct PopulationCounter { +- static int count(T Value) { +- // Generic version, forward to 32 bits. +- static_assert(SizeOfT <= 4, "Not implemented!"); +-#if defined(__GNUC__) +- return (int)__builtin_popcount(Value); +-#else +- uint32_t v = Value; +- v = v - ((v >> 1) & 0x55555555); +- v = (v & 0x33333333) + ((v >> 2) & 0x33333333); +- return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); +-#endif +- } +-}; +- +-template struct PopulationCounter { +- static int count(T Value) { +-#if defined(__GNUC__) +- return (int)__builtin_popcountll(Value); +-#else +- uint64_t v = Value; +- v = v - ((v >> 1) & 0x5555555555555555ULL); +- v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); +- v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; +- return int((uint64_t)(v * 0x0101010101010101ULL) >> 56); +-#endif +- } +-}; +-} // namespace detail +- +-/// Count the number of set bits in a value. +-/// Ex. popcount(0xF000F000) = 8 +-/// Returns 0 if the word is zero. +-template >> +-[[nodiscard]] inline int popcount(T Value) noexcept { +- return detail::PopulationCounter::count(Value); +-} +- + } // namespace llvm + + #endif +diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h +index fe9c5136f9f2f687577a0b1ecce69262568a9c3c..c269839c309e92d92ff8835127dcd2dfc0dd2c23 100644 +--- a/llvm/include/llvm/Support/MathExtras.h ++++ b/llvm/include/llvm/Support/MathExtras.h +@@ -15,6 +15,7 @@ + + #include "llvm/ADT/bit.h" + #include "llvm/Support/Compiler.h" ++#include + #include + #include + #include +@@ -41,7 +42,7 @@ enum ZeroBehavior { + template unsigned countTrailingZeros(T Val) { + static_assert(std::is_unsigned_v, + "Only unsigned integral types are allowed."); +- return llvm::countr_zero(Val); ++ return std::countr_zero(Val); + } + + /// Count number of 0's from the most significant bit to the least +@@ -53,7 +54,7 @@ template unsigned countTrailingZeros(T Val) { + template unsigned countLeadingZeros(T Val) { + static_assert(std::is_unsigned_v, + "Only unsigned integral types are allowed."); +- return llvm::countl_zero(Val); ++ return std::countl_zero(Val); + } + + /// Get the index of the first set bit starting from the least +@@ -66,7 +67,7 @@ template T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { + if (ZB == ZB_Max && Val == 0) + return (std::numeric_limits::max)(); + +- return llvm::countr_zero(Val); ++ return std::countr_zero(Val); + } + + /// Create a bitmask with the N right-most bits set to 1, and all other +@@ -108,7 +109,7 @@ template T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { + + // Use ^ instead of - because both gcc and llvm can remove the associated ^ + // in the __builtin_clz intrinsic on x86. +- return llvm::countl_zero(Val) ^ (std::numeric_limits::digits - 1); ++ return std::countl_zero(Val) ^ (std::numeric_limits::digits - 1); + } + + /// Macro compressed bit reversal table for 256 bits. +@@ -295,12 +296,12 @@ constexpr inline 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 inline bool isPowerOf2_32(uint32_t Value) { +- return llvm::has_single_bit(Value); ++ return std::has_single_bit(Value); + } + + /// Return true if the argument is a power of two > 0 (64 bit edition.) + constexpr inline bool isPowerOf2_64(uint64_t Value) { +- return llvm::has_single_bit(Value); ++ return std::has_single_bit(Value); + } + + /// Count the number of ones from the most significant bit to the first +@@ -313,7 +314,7 @@ constexpr inline bool isPowerOf2_64(uint64_t Value) { + template unsigned countLeadingOnes(T Value) { + static_assert(std::is_unsigned_v, + "Only unsigned integral types are allowed."); +- return llvm::countl_one(Value); ++ return std::countl_one(Value); + } + + /// Count the number of ones from the least significant bit to the first +@@ -326,7 +327,7 @@ template unsigned countLeadingOnes(T Value) { + template unsigned countTrailingOnes(T Value) { + static_assert(std::is_unsigned_v, + "Only unsigned integral types are allowed."); +- return llvm::countr_one(Value); ++ return std::countr_one(Value); + } + + /// Count the number of set bits in a value. +@@ -336,7 +337,7 @@ template + inline unsigned countPopulation(T Value) { + static_assert(std::is_unsigned_v, + "Only unsigned integral types are allowed."); +- return (unsigned)llvm::popcount(Value); ++ return (unsigned)std::popcount(Value); + } + + /// Return true if the argument contains a non-empty sequence of ones with the +@@ -348,8 +349,8 @@ inline bool isShiftedMask_32(uint32_t Value, unsigned &MaskIdx, + unsigned &MaskLen) { + if (!isShiftedMask_32(Value)) + return false; +- MaskIdx = llvm::countr_zero(Value); +- MaskLen = llvm::popcount(Value); ++ MaskIdx = std::countr_zero(Value); ++ MaskLen = std::popcount(Value); + return true; + } + +@@ -361,8 +362,8 @@ inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, + unsigned &MaskLen) { + if (!isShiftedMask_64(Value)) + return false; +- MaskIdx = llvm::countr_zero(Value); +- MaskLen = llvm::popcount(Value); ++ MaskIdx = std::countr_zero(Value); ++ MaskLen = std::popcount(Value); + return true; + } + +@@ -380,26 +381,26 @@ template <> constexpr inline size_t CTLog2<1>() { return 0; } + /// (32 bit edition.) + /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 + inline unsigned Log2_32(uint32_t Value) { +- return static_cast(31 - llvm::countl_zero(Value)); ++ return static_cast(31 - std::countl_zero(Value)); + } + + /// Return the floor log base 2 of the specified value, -1 if the value is zero. + /// (64 bit edition.) + inline unsigned Log2_64(uint64_t Value) { +- return static_cast(63 - llvm::countl_zero(Value)); ++ return static_cast(63 - std::countl_zero(Value)); + } + + /// Return the ceil log base 2 of the specified value, 32 if the value is zero. + /// (32 bit edition). + /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 + inline unsigned Log2_32_Ceil(uint32_t Value) { +- return static_cast(32 - llvm::countl_zero(Value - 1)); ++ return static_cast(32 - std::countl_zero(Value - 1)); + } + + /// Return the ceil log base 2 of the specified value, 64 if the value is zero. + /// (64 bit edition.) + inline unsigned Log2_64_Ceil(uint64_t Value) { +- return static_cast(64 - llvm::countl_zero(Value - 1)); ++ return static_cast(64 - std::countl_zero(Value - 1)); + } + + /// This function takes a 64-bit integer and returns the bit equivalent double. +@@ -456,7 +457,7 @@ constexpr inline uint64_t NextPowerOf2(uint64_t A) { + /// Returns the power of two which is less than or equal to the given value. + /// Essentially, it is a floor operation across the domain of powers of two. + inline uint64_t PowerOf2Floor(uint64_t A) { +- return llvm::bit_floor(A); ++ return std::bit_floor(A); + } + + /// Returns the power of two which is greater than or equal to the given value. diff --git a/upstream_utils/update_llvm.py b/upstream_utils/update_llvm.py index 31a345befb..4bdfdfbbca 100755 --- a/upstream_utils/update_llvm.py +++ b/upstream_utils/update_llvm.py @@ -28,7 +28,7 @@ def run_global_replacements(wpiutil_llvm_files): # Fix uses of span content = content.replace("span", "std::span") - content = content.replace('include "wpi/std::span.h"', "include ") + content = content.replace("include ", "include ") if wpi_file.endswith("ConvertUTFWrapper.cpp"): content = content.replace( "const UTF16 *Src = reinterpret_cast(SrcBytes.begin());", @@ -38,6 +38,14 @@ def run_global_replacements(wpiutil_llvm_files): "const UTF16 *SrcEnd = reinterpret_cast(SrcBytes.end());", "const UTF16 *SrcEnd = reinterpret_cast(&*SrcBytes.begin() + SrcBytes.size());", ) + content = content.replace( + "const UTF32 *Src = reinterpret_cast(SrcBytes.begin());", + "const UTF32 *Src = reinterpret_cast(&*SrcBytes.begin());", + ) + content = content.replace( + "const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());", + "const UTF32 *SrcEnd = reinterpret_cast(&*SrcBytes.begin() + SrcBytes.size());", + ) # Remove unused headers content = content.replace('#include "llvm-c/ErrorHandling.h"\n', "") @@ -163,7 +171,7 @@ def overwrite_tests(wpiutil_root, llvm_root): def main(): - upstream_root = clone_repo("https://github.com/llvm/llvm-project", "llvmorg-14.0.6") + upstream_root = clone_repo("https://github.com/llvm/llvm-project", "llvmorg-16.0.6") wpilib_root = get_repo_root() wpiutil = os.path.join(wpilib_root, "wpiutil") @@ -198,8 +206,8 @@ def main(): "0026-constexpr-endian-byte-swap.patch", "0027-Copy-type-traits-from-STLExtras.h-into-PointerUnion..patch", "0028-Remove-StringMap-test-for-llvm-sort.patch", - "0029-Fix-docs-typo-in-SmallVector.patch", - "0030-Unused-variable-in-release-mode.patch", + "0029-Unused-variable-in-release-mode.patch", + "0030-Use-C-20-bit-header.patch", ]: git_am( os.path.join(wpilib_root, "upstream_utils/llvm_patches", f), diff --git a/upstream_utils/upstream_utils.py b/upstream_utils/upstream_utils.py index 6454d54bea..ccf668b738 100644 --- a/upstream_utils/upstream_utils.py +++ b/upstream_utils/upstream_utils.py @@ -18,7 +18,10 @@ def clone_repo(url, treeish, shallow=True): root -- root directory of the cloned Git repository """ cwd = os.getcwd() - os.chdir(tempfile.gettempdir()) + if url.startswith("file://"): + os.chdir(os.path.dirname(url[7:])) + else: + os.chdir(tempfile.gettempdir()) repo = os.path.basename(url) dest = os.path.join(os.getcwd(), repo) diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp index dbf41ab206..d9aed15c7b 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTF.cpp @@ -6,25 +6,41 @@ * *===------------------------------------------------------------------------=*/ /* - * Copyright 2001-2004 Unicode, Inc. + * Copyright © 1991-2015 Unicode, Inc. All rights reserved. + * Distributed under the Terms of Use in + * http://www.unicode.org/copyright.html. * - * Disclaimer + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of the Unicode data files and any associated documentation + * (the "Data Files") or Unicode software and any associated documentation + * (the "Software") to deal in the Data Files or Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, and/or sell copies of + * the Data Files or Software, and to permit persons to whom the Data Files + * or Software are furnished to do so, provided that + * (a) this copyright and permission notice appear with all copies + * of the Data Files or Software, + * (b) this copyright and permission notice appear in associated + * documentation, and + * (c) there is clear notice in each modified Data File or in the Software + * as well as in the documentation associated with the Data File(s) or + * Software that the data or software has been modified. * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. + * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + * DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in these Data Files or Software without prior + * written authorization of the copyright holder. */ /* --------------------------------------------------------------------- @@ -422,6 +438,16 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { return isLegalUTF8(source, length); } +/* + * Exported function to return the size of the first utf-8 code unit sequence, + * Or 0 if the sequence is not valid; + */ +unsigned getUTF8SequenceSize(const UTF8 *source, const UTF8 *sourceEnd) { + int length = trailingBytesForUTF8[*source] + 1; + return (length <= sourceEnd - source && isLegalUTF8(source, length)) ? length + : 0; +} + /* --------------------------------------------------------------------- */ static unsigned diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp index e95c04fba9..1ab937da40 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/ConvertUTFWrapper.cpp @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// -#include #include "wpi/ConvertUTF.h" #include "wpi/SmallVector.h" #include "wpi/ErrorHandling.h" #include "wpi/SwapByteOrder.h" +#include #include #include #include @@ -35,31 +35,31 @@ bool ConvertUTF8toWide(unsigned WideCharWidth, std::string_view Source, const UTF8 *sourceStart = (const UTF8*)Source.data(); // FIXME: Make the type of the result buffer correct instead of // using reinterpret_cast. - UTF16 *targetStart = reinterpret_cast(ResultPtr); + UTF16 *targetStart = reinterpret_cast(ResultPtr); ConversionFlags flags = strictConversion; - result = ConvertUTF8toUTF16( - &sourceStart, sourceStart + Source.size(), - &targetStart, targetStart + Source.size(), flags); + result = + ConvertUTF8toUTF16(&sourceStart, sourceStart + Source.size(), + &targetStart, targetStart + Source.size(), flags); if (result == conversionOK) - ResultPtr = reinterpret_cast(targetStart); + ResultPtr = reinterpret_cast(targetStart); else ErrorPtr = sourceStart; } else if (WideCharWidth == 4) { - const UTF8 *sourceStart = (const UTF8*)Source.data(); + const UTF8 *sourceStart = (const UTF8 *)Source.data(); // FIXME: Make the type of the result buffer correct instead of // using reinterpret_cast. - UTF32 *targetStart = reinterpret_cast(ResultPtr); + UTF32 *targetStart = reinterpret_cast(ResultPtr); ConversionFlags flags = strictConversion; - result = ConvertUTF8toUTF32( - &sourceStart, sourceStart + Source.size(), - &targetStart, targetStart + Source.size(), flags); + result = + ConvertUTF8toUTF32(&sourceStart, sourceStart + Source.size(), + &targetStart, targetStart + Source.size(), flags); if (result == conversionOK) - ResultPtr = reinterpret_cast(targetStart); + ResultPtr = reinterpret_cast(targetStart); else ErrorPtr = sourceStart; } - assert((result != targetExhausted) - && "ConvertUTF8toUTFXX exhausted target buffer"); + assert((result != targetExhausted) && + "ConvertUTF8toUTFXX exhausted target buffer"); return result == conversionOK; } @@ -68,20 +68,18 @@ bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) { const UTF32 *SourceEnd = SourceStart + 1; UTF8 *TargetStart = reinterpret_cast(ResultPtr); UTF8 *TargetEnd = TargetStart + 4; - ConversionResult CR = ConvertUTF32toUTF8(&SourceStart, SourceEnd, - &TargetStart, TargetEnd, - strictConversion); + ConversionResult CR = ConvertUTF32toUTF8( + &SourceStart, SourceEnd, &TargetStart, TargetEnd, strictConversion); if (CR != conversionOK) return false; - ResultPtr = reinterpret_cast(TargetStart); + ResultPtr = reinterpret_cast(TargetStart); return true; } bool hasUTF16ByteOrderMark(std::span S) { - return (S.size() >= 2 && - ((S[0] == '\xff' && S[1] == '\xfe') || - (S[0] == '\xfe' && S[1] == '\xff'))); + return (S.size() >= 2 && ((S[0] == '\xff' && S[1] == '\xfe') || + (S[0] == '\xfe' && S[1] == '\xff'))); } bool convertUTF16ToUTF8String(std::span SrcBytes, SmallVectorImpl &Out) { @@ -135,11 +133,69 @@ bool convertUTF16ToUTF8String(std::span SrcBytes, SmallVectorImpl Src, SmallVectorImpl &Out) -{ +bool convertUTF16ToUTF8String(std::span Src, SmallVectorImpl &Out) { return convertUTF16ToUTF8String( std::span(reinterpret_cast(Src.data()), - Src.size() * sizeof(UTF16)), Out); + Src.size() * sizeof(UTF16)), + Out); +} + +bool convertUTF32ToUTF8String(std::span SrcBytes, std::string &Out) { + assert(Out.empty()); + + // Error out on an uneven byte count. + if (SrcBytes.size() % 4) + return false; + + // Avoid OOB by returning early on empty input. + if (SrcBytes.empty()) + return true; + + const UTF32 *Src = reinterpret_cast(&*SrcBytes.begin()); + const UTF32 *SrcEnd = reinterpret_cast(&*SrcBytes.begin() + SrcBytes.size()); + + assert((uintptr_t)Src % sizeof(UTF32) == 0); + + // Byteswap if necessary. + std::vector ByteSwapped; + if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_SWAPPED) { + ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd); + for (UTF32 &I : ByteSwapped) + I = wpi::ByteSwap_32(I); + Src = &ByteSwapped[0]; + SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1; + } + + // Skip the BOM for conversion. + if (Src[0] == UNI_UTF32_BYTE_ORDER_MARK_NATIVE) + Src++; + + // Just allocate enough space up front. We'll shrink it later. Allocate + // enough that we can fit a null terminator without reallocating. + Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1); + UTF8 *Dst = reinterpret_cast(&Out[0]); + UTF8 *DstEnd = Dst + Out.size(); + + ConversionResult CR = + ConvertUTF32toUTF8(&Src, SrcEnd, &Dst, DstEnd, strictConversion); + assert(CR != targetExhausted); + + if (CR != conversionOK) { + Out.clear(); + return false; + } + + Out.resize(reinterpret_cast(Dst) - &Out[0]); + Out.push_back(0); + Out.pop_back(); + return true; +} + +bool convertUTF32ToUTF8String(std::span Src, std::string &Out) { + return convertUTF32ToUTF8String( + std::span(reinterpret_cast(Src.data()), + Src.size() * sizeof(UTF32)), + Out); } bool convertUTF8ToUTF16String(std::string_view SrcUTF8, diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallVector.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallVector.cpp index 04f4e06b28..803523af25 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallVector.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/SmallVector.cpp @@ -99,14 +99,30 @@ static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) { // In theory 2*capacity can overflow if the capacity is 64 bit, but the // original capacity would never be large enough for this to be a problem. size_t NewCapacity = 2 * OldCapacity + 1; // Always grow. - return (std::min)((std::max)(NewCapacity, MinSize), MaxSize); + return std::clamp(NewCapacity, MinSize, MaxSize); +} + +void *SmallVectorBase::replaceAllocation(void *NewElts, size_t TSize, + size_t NewCapacity, + size_t VSize) { + void *NewEltsReplace = wpi::safe_malloc(NewCapacity * TSize); + if (VSize) + memcpy(NewEltsReplace, NewElts, VSize * TSize); + free(NewElts); + return NewEltsReplace; } // Note: Moving this function into the header may cause performance regression. -void *SmallVectorBase::mallocForGrow(size_t MinSize, size_t TSize, +void *SmallVectorBase::mallocForGrow(void *FirstEl, size_t MinSize, + size_t TSize, size_t &NewCapacity) { NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); - return wpi::safe_malloc(NewCapacity * TSize); + // Even if capacity is not 0 now, if the vector was originally created with + // capacity 0, it's possible for the malloc to return FirstEl. + void *NewElts = wpi::safe_malloc(NewCapacity * TSize); + if (NewElts == FirstEl) + NewElts = replaceAllocation(NewElts, TSize, NewCapacity); + return NewElts; } // Note: Moving this function into the header may cause performance regression. @@ -115,13 +131,17 @@ void SmallVectorBase::grow_pod(void *FirstEl, size_t MinSize, size_t NewCapacity = getNewCapacity(MinSize, TSize, this->capacity()); void *NewElts; if (BeginX == FirstEl) { - NewElts = safe_malloc(NewCapacity * TSize); + NewElts = wpi::safe_malloc(NewCapacity * TSize); + if (NewElts == FirstEl) + NewElts = replaceAllocation(NewElts, TSize, NewCapacity); // Copy the elements over. No need to run dtors on PODs. memcpy(NewElts, this->BeginX, size() * TSize); } else { // If this wasn't grown from the inline copy, grow the allocated space. - NewElts = safe_realloc(this->BeginX, NewCapacity * TSize); + NewElts = wpi::safe_realloc(this->BeginX, NewCapacity * TSize); + if (NewElts == FirstEl) + NewElts = replaceAllocation(NewElts, TSize, NewCapacity, size()); } this->BeginX = NewElts; diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/StringMap.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/StringMap.cpp index 2405f2f9ef..101bf32397 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/StringMap.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/StringMap.cpp @@ -18,7 +18,7 @@ using namespace wpi; /// Returns the number of buckets to allocate to ensure that the DenseMap can /// accommodate \p NumEntries without need to grow(). -static unsigned getMinBucketToReserveForEntries(unsigned NumEntries) { +static inline unsigned getMinBucketToReserveForEntries(unsigned NumEntries) { // Ensure that "NumEntries * 4 < NumBuckets * 3" if (NumEntries == 0) return 0; @@ -27,6 +27,21 @@ static unsigned getMinBucketToReserveForEntries(unsigned NumEntries) { return NextPowerOf2(NumEntries * 4 / 3 + 1); } +static inline StringMapEntryBase **createTable(unsigned NewNumBuckets) { + auto **Table = static_cast(safe_calloc( + NewNumBuckets + 1, sizeof(StringMapEntryBase **) + sizeof(unsigned))); + + // Allocate one extra bucket, set it to look filled so the iterators stop at + // end. + Table[NewNumBuckets] = (StringMapEntryBase *)2; + return Table; +} + +static inline unsigned *getHashTable(StringMapEntryBase **TheTable, + unsigned NumBuckets) { + return reinterpret_cast(TheTable + NumBuckets + 1); +} + StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) { ItemSize = itemSize; @@ -54,15 +69,10 @@ void StringMapImpl::init(unsigned InitSize) { NumItems = 0; NumTombstones = 0; - TheTable = static_cast(safe_calloc( - NewNumBuckets + 1, sizeof(StringMapEntryBase **) + sizeof(unsigned))); + TheTable = createTable(NewNumBuckets); // Set the member only if TheTable was successfully allocated NumBuckets = NewNumBuckets; - - // Allocate one extra bucket, set it to look filled so the iterators stop at - // end. - TheTable[NumBuckets] = (StringMapEntryBase *)2; } /// LookupBucketFor - Look up the bucket that the specified string should end @@ -71,14 +81,12 @@ void StringMapImpl::init(unsigned InitSize) { /// case, the FullHashValue field of the bucket will be set to the hash value /// of the string. unsigned StringMapImpl::LookupBucketFor(std::string_view Name) { - unsigned HTSize = NumBuckets; - if (HTSize == 0) { // Hash table unallocated so far? + // Hash table unallocated so far? + if (NumBuckets == 0) init(16); - HTSize = NumBuckets; - } unsigned FullHashValue = djbHash(Name, 0); - unsigned BucketNo = FullHashValue & (HTSize - 1); - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); + unsigned BucketNo = FullHashValue & (NumBuckets - 1); + unsigned *HashTable = getHashTable(TheTable, NumBuckets); unsigned ProbeAmt = 1; int FirstTombstone = -1; @@ -117,7 +125,7 @@ unsigned StringMapImpl::LookupBucketFor(std::string_view Name) { } // Okay, we didn't find the item. Probe to the next bucket. - BucketNo = (BucketNo + ProbeAmt) & (HTSize - 1); + BucketNo = (BucketNo + ProbeAmt) & (NumBuckets - 1); // Use quadratic probing, it has fewer clumping artifacts than linear // probing and has good cache behavior in the common case. @@ -129,12 +137,11 @@ unsigned StringMapImpl::LookupBucketFor(std::string_view Name) { /// in the map, return the bucket number of the key. Otherwise return -1. /// This does not modify the map. int StringMapImpl::FindKey(std::string_view Key) const { - unsigned HTSize = NumBuckets; - if (HTSize == 0) + if (NumBuckets == 0) return -1; // Really empty table? unsigned FullHashValue = djbHash(Key, 0); - unsigned BucketNo = FullHashValue & (HTSize - 1); - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); + unsigned BucketNo = FullHashValue & (NumBuckets - 1); + unsigned *HashTable = getHashTable(TheTable, NumBuckets); unsigned ProbeAmt = 1; while (true) { @@ -161,7 +168,7 @@ int StringMapImpl::FindKey(std::string_view Key) const { } // Okay, we didn't find the item. Probe to the next bucket. - BucketNo = (BucketNo + ProbeAmt) & (HTSize - 1); + BucketNo = (BucketNo + ProbeAmt) & (NumBuckets - 1); // Use quadratic probing, it has fewer clumping artifacts than linear // probing and has good cache behavior in the common case. @@ -198,8 +205,6 @@ StringMapEntryBase *StringMapImpl::RemoveKey(std::string_view Key) { /// the appropriate mod-of-hashtable-size. unsigned StringMapImpl::RehashTable(unsigned BucketNo) { unsigned NewSize; - unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); - // If the hash table is now more than 3/4 full, or if fewer than 1/8 of // the buckets are empty (meaning that many are filled with tombstones), // grow/rehash the table. @@ -213,36 +218,25 @@ unsigned StringMapImpl::RehashTable(unsigned BucketNo) { } unsigned NewBucketNo = BucketNo; - // Allocate one extra bucket which will always be non-empty. This allows the - // iterators to stop at end. - auto NewTableArray = static_cast(safe_calloc( - NewSize + 1, sizeof(StringMapEntryBase *) + sizeof(unsigned))); - - unsigned *NewHashArray = (unsigned *)(NewTableArray + NewSize + 1); - NewTableArray[NewSize] = (StringMapEntryBase *)2; + auto **NewTableArray = createTable(NewSize); + unsigned *NewHashArray = getHashTable(NewTableArray, NewSize); + unsigned *HashTable = getHashTable(TheTable, NumBuckets); // Rehash all the items into their new buckets. Luckily :) we already have // the hash values available, so we don't have to rehash any strings. for (unsigned I = 0, E = NumBuckets; I != E; ++I) { StringMapEntryBase *Bucket = TheTable[I]; if (Bucket && Bucket != getTombstoneVal()) { - // Fast case, bucket available. + // If the bucket is not available, probe for a spot. unsigned FullHash = HashTable[I]; unsigned NewBucket = FullHash & (NewSize - 1); - if (!NewTableArray[NewBucket]) { - NewTableArray[FullHash & (NewSize - 1)] = Bucket; - NewHashArray[FullHash & (NewSize - 1)] = FullHash; - if (I == BucketNo) - NewBucketNo = NewBucket; - continue; + if (NewTableArray[NewBucket]) { + unsigned ProbeSize = 1; + do { + NewBucket = (NewBucket + ProbeSize++) & (NewSize - 1); + } while (NewTableArray[NewBucket]); } - // Otherwise probe for a spot. - unsigned ProbeSize = 1; - do { - NewBucket = (NewBucket + ProbeSize++) & (NewSize - 1); - } while (NewTableArray[NewBucket]); - // Finally found a slot. Fill it in. NewTableArray[NewBucket] = Bucket; NewHashArray[NewBucket] = FullHash; diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.h b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.h index 01200e22a0..735ce48e70 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.h +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/Windows/WindowsSupport.h @@ -83,6 +83,9 @@ inline bool RunningWindows8OrGreater() { return GetWindowsOSVersion() >= wpi::VersionTuple(6, 2, 0, 0); } +/// Determines if the program is running on Windows 11 or Windows Server 2022. +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 diff --git a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp index a2d586bad6..05036a84a3 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp +++ b/wpiutil/src/main/native/thirdparty/llvm/cpp/llvm/raw_ostream.cpp @@ -89,8 +89,15 @@ raw_ostream::~raw_ostream() { } size_t raw_ostream::preferred_buffer_size() const { +#ifdef _WIN32 + // On Windows BUFSIZ is only 512 which results in more calls to write. This + // overhead can cause significant performance degradation. Therefore use a + // better default. + return (16 * 1024); +#else // BUFSIZ is intended to be a reasonable default. return BUFSIZ; +#endif } void raw_ostream::SetBuffered() { @@ -237,10 +244,10 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) { // Handle short strings specially, memcpy isn't very good at very short // strings. switch (Size) { - case 4: OutBufCur[3] = Ptr[3]; LLVM_FALLTHROUGH; - case 3: OutBufCur[2] = Ptr[2]; LLVM_FALLTHROUGH; - case 2: OutBufCur[1] = Ptr[1]; LLVM_FALLTHROUGH; - case 1: OutBufCur[0] = Ptr[0]; LLVM_FALLTHROUGH; + case 4: OutBufCur[3] = Ptr[3]; [[fallthrough]]; + case 3: OutBufCur[2] = Ptr[2]; [[fallthrough]]; + case 2: OutBufCur[1] = Ptr[1]; [[fallthrough]]; + case 1: OutBufCur[0] = Ptr[0]; [[fallthrough]]; case 0: break; default: memcpy(OutBufCur, Ptr, Size); @@ -256,7 +263,6 @@ void raw_ostream::flush_tied_then_write(const char *Ptr, size_t Size) { write_impl(Ptr, Size); } - template static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) { static const char Chars[] = {C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, @@ -266,12 +272,11 @@ static raw_ostream &write_padding(raw_ostream &OS, unsigned NumChars) { C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C}; // Usually the indentation is small, handle it with a fastpath. - if (NumChars < array_lengthof(Chars)) + if (NumChars < std::size(Chars)) return OS.write(Chars, NumChars); while (NumChars) { - unsigned NumToWrite = std::min(NumChars, - (unsigned)array_lengthof(Chars)-1); + unsigned NumToWrite = std::min(NumChars, (unsigned)std::size(Chars) - 1); OS.write(Chars, NumToWrite); NumChars -= NumToWrite; } @@ -512,6 +517,14 @@ void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { ) continue; +#ifdef _WIN32 + // Windows equivalents of SIGPIPE/EPIPE. + DWORD WinLastError = GetLastError(); + if (WinLastError == ERROR_BROKEN_PIPE || + (WinLastError == ERROR_NO_DATA && errno == EINVAL)) { + errno = EPIPE; + } +#endif // Otherwise it's a non-recoverable error. Note it and quit. error_detected(std::error_code(errno, std::generic_category())); break; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/AllocatorBase.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/AllocatorBase.h index 29ba16f167..dc1d004584 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/AllocatorBase.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/AllocatorBase.h @@ -99,6 +99,28 @@ public: void PrintStats() const {} }; +namespace detail { + +template class AllocatorHolder : Alloc { +public: + AllocatorHolder() = default; + AllocatorHolder(const Alloc &A) : Alloc(A) {} + AllocatorHolder(Alloc &&A) : Alloc(static_cast(A)) {} + Alloc &getAllocator() { return *this; } + const Alloc &getAllocator() const { return *this; } +}; + +template class AllocatorHolder { + Alloc &A; + +public: + AllocatorHolder(Alloc &A) : A(A) {} + Alloc &getAllocator() { return A; } + const Alloc &getAllocator() const { return A; } +}; + +} // namespace detail + } // namespace wpi #endif // WPIUTIL_WPI_ALLOCATORBASE_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Casting.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Casting.h new file mode 100644 index 0000000000..b85cd8566b --- /dev/null +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Casting.h @@ -0,0 +1,808 @@ +//===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the isa(), cast(), dyn_cast(), +// cast_if_present(), and dyn_cast_if_present() templates. +// +//===----------------------------------------------------------------------===// + +#ifndef WPIUTIL_WPI_CASTING_H +#define WPIUTIL_WPI_CASTING_H + +#include "wpi/Compiler.h" +#include "wpi/type_traits.h" +#include +#include +#include +#include + +namespace wpi { + +//===----------------------------------------------------------------------===// +// simplify_type +//===----------------------------------------------------------------------===// + +/// Define a template that can be specialized by smart pointers to reflect the +/// fact that they are automatically dereferenced, and are not involved with the +/// template selection process... the default implementation is a noop. +// TODO: rename this and/or replace it with other cast traits. +template struct simplify_type { + using SimpleType = From; // The real type this represents... + + // An accessor to get the real value... + static SimpleType &getSimplifiedValue(From &Val) { return Val; } +}; + +template struct simplify_type { + using NonConstSimpleType = typename simplify_type::SimpleType; + using SimpleType = typename add_const_past_pointer::type; + using RetType = + typename add_lvalue_reference_if_not_pointer::type; + + static RetType getSimplifiedValue(const From &Val) { + return simplify_type::getSimplifiedValue(const_cast(Val)); + } +}; + +// TODO: add this namespace once everyone is switched to using the new +// interface. +// namespace detail { + +//===----------------------------------------------------------------------===// +// isa_impl +//===----------------------------------------------------------------------===// + +// The core of the implementation of isa is here; To and From should be +// the names of classes. This template can be specialized to customize the +// implementation of isa<> without rewriting it from scratch. +template struct isa_impl { + static inline bool doit(const From &Val) { return To::classof(&Val); } +}; + +// Always allow upcasts, and perform no dynamic check for them. +template +struct isa_impl::value>> { + static inline bool doit(const From &) { return true; } +}; + +template struct isa_impl_cl { + static inline bool doit(const From &Val) { + return isa_impl::doit(Val); + } +}; + +template struct isa_impl_cl { + static inline bool doit(const From &Val) { + return isa_impl::doit(Val); + } +}; + +template +struct isa_impl_cl> { + static inline bool doit(const std::unique_ptr &Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl_cl::doit(*Val); + } +}; + +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); + } +}; + +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); + } +}; + +template struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); + } +}; + +template +struct isa_impl_cl { + static inline bool doit(const From *Val) { + assert(Val && "isa<> used on a null pointer"); + return isa_impl::doit(*Val); + } +}; + +template +struct isa_impl_wrap { + // When From != SimplifiedType, we can simplify the type some more by using + // the simplify_type template. + static bool doit(const From &Val) { + return isa_impl_wrap::SimpleType>:: + doit(simplify_type::getSimplifiedValue(Val)); + } +}; + +template +struct isa_impl_wrap { + // When From == SimpleType, we are as simple as we are going to get. + static bool doit(const FromTy &Val) { + return isa_impl_cl::doit(Val); + } +}; + +//===----------------------------------------------------------------------===// +// cast_retty + cast_retty_impl +//===----------------------------------------------------------------------===// + +template struct cast_retty; + +// Calculate what type the 'cast' function should return, based on a requested +// type of To and a source type of From. +template struct cast_retty_impl { + using ret_type = To &; // Normal case, return Ty& +}; +template struct cast_retty_impl { + using ret_type = const To &; // Normal case, return Ty& +}; + +template struct cast_retty_impl { + using ret_type = To *; // Pointer arg case, return Ty* +}; + +template struct cast_retty_impl { + using ret_type = const To *; // Constant pointer arg case, return const Ty* +}; + +template struct cast_retty_impl { + using ret_type = const To *; // Constant pointer arg case, return const Ty* +}; + +template +struct cast_retty_impl> { +private: + using PointerType = typename cast_retty_impl::ret_type; + using ResultType = std::remove_pointer_t; + +public: + using ret_type = std::unique_ptr; +}; + +template struct cast_retty_wrap { + // When the simplified type and the from type are not the same, use the type + // simplifier to reduce the type, then reuse cast_retty_impl to get the + // resultant type. + using ret_type = typename cast_retty::ret_type; +}; + +template struct cast_retty_wrap { + // When the simplified type is equal to the from type, use it directly. + using ret_type = typename cast_retty_impl::ret_type; +}; + +template struct cast_retty { + using ret_type = typename cast_retty_wrap< + To, From, typename simplify_type::SimpleType>::ret_type; +}; + +//===----------------------------------------------------------------------===// +// cast_convert_val +//===----------------------------------------------------------------------===// + +// Ensure the non-simple values are converted using the simplify_type template +// that may be specialized by smart pointers... +// +template struct cast_convert_val { + // This is not a simple type, use the template to simplify it... + static typename cast_retty::ret_type doit(const From &Val) { + return cast_convert_val::SimpleType>:: + doit(simplify_type::getSimplifiedValue(const_cast(Val))); + } +}; + +template struct cast_convert_val { + // If it's a reference, switch to a pointer to do the cast and then deref it. + static typename cast_retty::ret_type doit(const FromTy &Val) { + return *(std::remove_reference_t::ret_type> + *)&const_cast(Val); + } +}; + +template +struct cast_convert_val { + // If it's a pointer, we can use c-style casting directly. + static typename cast_retty::ret_type doit(const FromTy *Val) { + return (typename cast_retty::ret_type) const_cast( + Val); + } +}; + +//===----------------------------------------------------------------------===// +// is_simple_type +//===----------------------------------------------------------------------===// + +template struct is_simple_type { + static const bool value = + std::is_same::SimpleType>::value; +}; + +// } // namespace detail + +//===----------------------------------------------------------------------===// +// CastIsPossible +//===----------------------------------------------------------------------===// + +/// This struct provides a way to check if a given cast is possible. It provides +/// a static function called isPossible that is used to check if a cast can be +/// performed. It should be overridden like this: +/// +/// template<> struct CastIsPossible { +/// static inline bool isPossible(const bar &b) { +/// return bar.isFoo(); +/// } +/// }; +template +struct CastIsPossible { + static inline bool isPossible(const From &f) { + return isa_impl_wrap< + To, const From, + typename simplify_type::SimpleType>::doit(f); + } +}; + +// Needed for optional unwrapping. This could be implemented with isa_impl, but +// we want to implement things in the new method and move old implementations +// over. In fact, some of the isa_impl templates should be moved over to +// CastIsPossible. +template +struct CastIsPossible> { + static inline bool isPossible(const std::optional &f) { + assert(f && "CastIsPossible::isPossible called on a nullopt!"); + return isa_impl_wrap< + To, const From, + typename simplify_type::SimpleType>::doit(*f); + } +}; + +/// Upcasting (from derived to base) and casting from a type to itself should +/// always be possible. +template +struct CastIsPossible::value>> { + static inline bool isPossible(const From &f) { return true; } +}; + +//===----------------------------------------------------------------------===// +// Cast traits +//===----------------------------------------------------------------------===// + +/// All of these cast traits are meant to be implementations for useful casts +/// that users may want to use that are outside the standard behavior. An +/// example of how to use a special cast called `CastTrait` is: +/// +/// template<> struct CastInfo : public CastTrait {}; +/// +/// Essentially, if your use case falls directly into one of the use cases +/// supported by a given cast trait, simply inherit your special CastInfo +/// directly from one of these to avoid having to reimplement the boilerplate +/// `isPossible/castFailed/doCast/doCastIfPossible`. A cast trait can also +/// provide a subset of those functions. + +/// This cast trait just provides castFailed for the specified `To` type to make +/// CastInfo specializations more declarative. In order to use this, the target +/// result type must be `To` and `To` must be constructible from `nullptr`. +template struct NullableValueCastFailed { + static To castFailed() { return To(nullptr); } +}; + +/// This cast trait just provides the default implementation of doCastIfPossible +/// to make CastInfo specializations more declarative. The `Derived` template +/// parameter *must* be provided for forwarding castFailed and doCast. +template +struct DefaultDoCastIfPossible { + static To doCastIfPossible(From f) { + if (!Derived::isPossible(f)) + return Derived::castFailed(); + return Derived::doCast(f); + } +}; + +namespace detail { +/// A helper to derive the type to use with `Self` for cast traits, when the +/// provided CRTP derived type is allowed to be void. +template +using SelfType = std::conditional_t::value, + Default, OptionalDerived>; +} // namespace detail + +/// This cast trait provides casting for the specific case of casting to a +/// value-typed object from a pointer-typed object. Note that `To` must be +/// nullable/constructible from a pointer to `From` to use this cast. +template +struct ValueFromPointerCast + : public CastIsPossible, + public NullableValueCastFailed, + public DefaultDoCastIfPossible< + To, From *, + detail::SelfType>> { + static inline To doCast(From *f) { return To(f); } +}; + +/// This cast trait provides std::unique_ptr casting. It has the semantics of +/// moving the contents of the input unique_ptr into the output unique_ptr +/// during the cast. It's also a good example of how to implement a move-only +/// cast. +template +struct UniquePtrCast : public CastIsPossible { + using Self = detail::SelfType>; + using CastResultType = std::unique_ptr< + std::remove_reference_t::ret_type>>; + + static inline CastResultType doCast(std::unique_ptr &&f) { + return CastResultType((typename CastResultType::element_type *)f.release()); + } + + static inline CastResultType castFailed() { return CastResultType(nullptr); } + + static inline CastResultType doCastIfPossible(std::unique_ptr &&f) { + if (!Self::isPossible(f)) + return castFailed(); + return doCast(f); + } +}; + +/// This cast trait provides std::optional casting. This means that if you +/// have a value type, you can cast it to another value type and have dyn_cast +/// return an std::optional. +template +struct OptionalValueCast + : public CastIsPossible, + public DefaultDoCastIfPossible< + std::optional, From, + detail::SelfType>> { + static inline std::optional castFailed() { return std::optional{}; } + + static inline std::optional doCast(const From &f) { return To(f); } +}; + +/// Provides a cast trait that strips `const` from types to make it easier to +/// implement a const-version of a non-const cast. It just removes boilerplate +/// and reduces the amount of code you as the user need to implement. You can +/// use it like this: +/// +/// template<> struct CastInfo { +/// ...verbose implementation... +/// }; +/// +/// template<> struct CastInfo : public +/// ConstStrippingForwardingCast> {}; +/// +template +struct ConstStrippingForwardingCast { + // Remove the pointer if it exists, then we can get rid of consts/volatiles. + using DecayedFrom = std::remove_cv_t>; + // Now if it's a pointer, add it back. Otherwise, we want a ref. + using NonConstFrom = std::conditional_t::value, + DecayedFrom *, DecayedFrom &>; + + static inline bool isPossible(const From &f) { + return ForwardTo::isPossible(const_cast(f)); + } + + static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); } + + static inline decltype(auto) doCast(const From &f) { + return ForwardTo::doCast(const_cast(f)); + } + + static inline decltype(auto) doCastIfPossible(const From &f) { + return ForwardTo::doCastIfPossible(const_cast(f)); + } +}; + +/// Provides a cast trait that uses a defined pointer to pointer cast as a base +/// for reference-to-reference casts. Note that it does not provide castFailed +/// and doCastIfPossible because a pointer-to-pointer cast would likely just +/// return `nullptr` which could cause nullptr dereference. You can use it like +/// this: +/// +/// template <> struct CastInfo { ... verbose implementation... }; +/// +/// template <> +/// struct CastInfo +/// : public ForwardToPointerCast> {}; +/// +template +struct ForwardToPointerCast { + static inline bool isPossible(const From &f) { + return ForwardTo::isPossible(&f); + } + + static inline decltype(auto) doCast(const From &f) { + return *ForwardTo::doCast(&f); + } +}; + +//===----------------------------------------------------------------------===// +// CastInfo +//===----------------------------------------------------------------------===// + +/// This struct provides a method for customizing the way a cast is performed. +/// It inherits from CastIsPossible, to support the case of declaring many +/// CastIsPossible specializations without having to specialize the full +/// CastInfo. +/// +/// In order to specialize different behaviors, specify different functions in +/// your CastInfo specialization. +/// For isa<> customization, provide: +/// +/// `static bool isPossible(const From &f)` +/// +/// For cast<> customization, provide: +/// +/// `static To doCast(const From &f)` +/// +/// For dyn_cast<> and the *_if_present<> variants' customization, provide: +/// +/// `static To castFailed()` and `static To doCastIfPossible(const From &f)` +/// +/// Your specialization might look something like this: +/// +/// template<> struct CastInfo : public CastIsPossible { +/// static inline foo doCast(const bar &b) { +/// return foo(const_cast(b)); +/// } +/// static inline foo castFailed() { return foo(); } +/// static inline foo doCastIfPossible(const bar &b) { +/// if (!CastInfo::isPossible(b)) +/// return castFailed(); +/// return doCast(b); +/// } +/// }; + +// The default implementations of CastInfo don't use cast traits for now because +// we need to specify types all over the place due to the current expected +// casting behavior and the way cast_retty works. New use cases can and should +// take advantage of the cast traits whenever possible! + +template +struct CastInfo : public CastIsPossible { + using Self = CastInfo; + + using CastReturnType = typename cast_retty::ret_type; + + static inline CastReturnType doCast(const From &f) { + return cast_convert_val< + To, From, + typename simplify_type::SimpleType>::doit(const_cast(f)); + } + + // This assumes that you can construct the cast return type from `nullptr`. + // This is largely to support legacy use cases - if you don't want this + // behavior you should specialize CastInfo for your use case. + static inline CastReturnType castFailed() { return CastReturnType(nullptr); } + + static inline CastReturnType doCastIfPossible(const From &f) { + if (!Self::isPossible(f)) + return castFailed(); + return doCast(f); + } +}; + +/// This struct provides an overload for CastInfo where From has simplify_type +/// defined. This simply forwards to the appropriate CastInfo with the +/// simplified type/value, so you don't have to implement both. +template +struct CastInfo::value>> { + using Self = CastInfo; + using SimpleFrom = typename simplify_type::SimpleType; + using SimplifiedSelf = CastInfo; + + static inline bool isPossible(From &f) { + return SimplifiedSelf::isPossible( + simplify_type::getSimplifiedValue(f)); + } + + static inline decltype(auto) doCast(From &f) { + return SimplifiedSelf::doCast(simplify_type::getSimplifiedValue(f)); + } + + static inline decltype(auto) castFailed() { + return SimplifiedSelf::castFailed(); + } + + static inline decltype(auto) doCastIfPossible(From &f) { + return SimplifiedSelf::doCastIfPossible( + simplify_type::getSimplifiedValue(f)); + } +}; + +//===----------------------------------------------------------------------===// +// Pre-specialized CastInfo +//===----------------------------------------------------------------------===// + +/// Provide a CastInfo specialized for std::unique_ptr. +template +struct CastInfo> : public UniquePtrCast {}; + +/// Provide a CastInfo specialized for std::optional. It's assumed that if +/// the input is std::optional that the output can be std::optional. +/// If that's not the case, specialize CastInfo for your use case. +template +struct CastInfo> : public OptionalValueCast { +}; + +/// isa - Return true if the parameter to the template is an instance of one +/// of the template type arguments. Used like this: +/// +/// if (isa(myVal)) { ... } +/// if (isa(myVal)) { ... } +template +[[nodiscard]] inline bool isa(const From &Val) { + return CastInfo::isPossible(Val); +} + +template +[[nodiscard]] inline bool isa(const From &Val) { + return isa(Val) || isa(Val); +} + +/// cast - Return the argument parameter cast to the specified type. This +/// casting operator asserts that the type is correct, so it does not return +/// null on failure. It does not allow a null argument (use cast_if_present for +/// that). It is typically used like this: +/// +/// cast(myVal)->getParent() + +template +[[nodiscard]] inline decltype(auto) cast(const From &Val) { + assert(isa(Val) && "cast() argument of incompatible type!"); + return CastInfo::doCast(Val); +} + +template +[[nodiscard]] inline decltype(auto) cast(From &Val) { + assert(isa(Val) && "cast() argument of incompatible type!"); + return CastInfo::doCast(Val); +} + +template +[[nodiscard]] inline decltype(auto) cast(From *Val) { + assert(isa(Val) && "cast() argument of incompatible type!"); + return CastInfo::doCast(Val); +} + +template +[[nodiscard]] inline decltype(auto) cast(std::unique_ptr &&Val) { + assert(isa(Val) && "cast() argument of incompatible type!"); + return CastInfo>::doCast(std::move(Val)); +} + +//===----------------------------------------------------------------------===// +// ValueIsPresent +//===----------------------------------------------------------------------===// + +template +constexpr bool IsNullable = + std::is_pointer_v || std::is_constructible_v; + +/// ValueIsPresent provides a way to check if a value is, well, present. For +/// pointers, this is the equivalent of checking against nullptr, for Optionals +/// this is the equivalent of checking hasValue(). It also provides a method for +/// unwrapping a value (think calling .value() on an optional). + +// Generic values can't *not* be present. +template struct ValueIsPresent { + using UnwrappedType = T; + static inline bool isPresent(const T &t) { return true; } + static inline decltype(auto) unwrapValue(T &t) { return t; } +}; + +// Optional provides its own way to check if something is present. +template struct ValueIsPresent> { + using UnwrappedType = T; + static inline bool isPresent(const std::optional &t) { + return t.has_value(); + } + static inline decltype(auto) unwrapValue(std::optional &t) { return *t; } +}; + +// If something is "nullable" then we just compare it to nullptr to see if it +// exists. +template +struct ValueIsPresent>> { + using UnwrappedType = T; + static inline bool isPresent(const T &t) { return t != T(nullptr); } + static inline decltype(auto) unwrapValue(T &t) { return t; } +}; + +namespace detail { +// Convenience function we can use to check if a value is present. Because of +// simplify_type, we have to call it on the simplified type for now. +template inline bool isPresent(const T &t) { + return ValueIsPresent::SimpleType>::isPresent( + simplify_type::getSimplifiedValue(const_cast(t))); +} + +// Convenience function we can use to unwrap a value. +template inline decltype(auto) unwrapValue(T &t) { + return ValueIsPresent::unwrapValue(t); +} +} // namespace detail + +/// dyn_cast - Return the argument parameter cast to the specified type. This +/// casting operator returns null if the argument is of the wrong type, so it +/// can be used to test for a type as well as cast if successful. The value +/// passed in must be present, if not, use dyn_cast_if_present. This should be +/// used in the context of an if statement like this: +/// +/// if (const Instruction *I = dyn_cast(myVal)) { ... } + +template +[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo::doCastIfPossible(Val); +} + +template +[[nodiscard]] inline decltype(auto) dyn_cast(From &Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo::doCastIfPossible(Val); +} + +template +[[nodiscard]] inline decltype(auto) dyn_cast(From *Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo::doCastIfPossible(Val); +} + +template +[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr &&Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo>::doCastIfPossible( + std::forward &&>(Val)); +} + +/// isa_and_present - Functionally identical to isa, except that a null value +/// is accepted. +template +[[nodiscard]] inline bool isa_and_present(const Y &Val) { + if (!detail::isPresent(Val)) + return false; + return isa(Val); +} + +template +[[nodiscard]] inline bool isa_and_nonnull(const Y &Val) { + return isa_and_present(Val); +} + +/// cast_if_present - Functionally identical to cast, except that a null +/// value is accepted. +template +[[nodiscard]] inline auto cast_if_present(const Y &Val) { + if (!detail::isPresent(Val)) + return CastInfo::castFailed(); + assert(isa(Val) && "cast_if_present() argument of incompatible type!"); + return cast(detail::unwrapValue(Val)); +} + +template [[nodiscard]] inline auto cast_if_present(Y &Val) { + if (!detail::isPresent(Val)) + return CastInfo::castFailed(); + assert(isa(Val) && "cast_if_present() argument of incompatible type!"); + return cast(detail::unwrapValue(Val)); +} + +template [[nodiscard]] inline auto cast_if_present(Y *Val) { + if (!detail::isPresent(Val)) + return CastInfo::castFailed(); + assert(isa(Val) && "cast_if_present() argument of incompatible type!"); + return cast(detail::unwrapValue(Val)); +} + +template +[[nodiscard]] inline auto cast_if_present(std::unique_ptr &&Val) { + if (!detail::isPresent(Val)) + return UniquePtrCast::castFailed(); + return UniquePtrCast::doCast(std::move(Val)); +} + +// Provide a forwarding from cast_or_null to cast_if_present for current +// users. This is deprecated and will be removed in a future patch, use +// cast_if_present instead. +template auto cast_or_null(const Y &Val) { + return cast_if_present(Val); +} + +template auto cast_or_null(Y &Val) { + return cast_if_present(Val); +} + +template auto cast_or_null(Y *Val) { + return cast_if_present(Val); +} + +template auto cast_or_null(std::unique_ptr &&Val) { + return cast_if_present(std::move(Val)); +} + +/// dyn_cast_if_present - Functionally identical to dyn_cast, except that a +/// null (or none in the case of optionals) value is accepted. +template auto dyn_cast_if_present(const Y &Val) { + if (!detail::isPresent(Val)) + return CastInfo::castFailed(); + return CastInfo::doCastIfPossible(detail::unwrapValue(Val)); +} + +template auto dyn_cast_if_present(Y &Val) { + if (!detail::isPresent(Val)) + return CastInfo::castFailed(); + return CastInfo::doCastIfPossible(detail::unwrapValue(Val)); +} + +template auto dyn_cast_if_present(Y *Val) { + if (!detail::isPresent(Val)) + return CastInfo::castFailed(); + return CastInfo::doCastIfPossible(detail::unwrapValue(Val)); +} + +// Forwards to dyn_cast_if_present to avoid breaking current users. This is +// deprecated and will be removed in a future patch, use +// cast_if_present instead. +template auto dyn_cast_or_null(const Y &Val) { + return dyn_cast_if_present(Val); +} + +template auto dyn_cast_or_null(Y &Val) { + return dyn_cast_if_present(Val); +} + +template auto dyn_cast_or_null(Y *Val) { + return dyn_cast_if_present(Val); +} + +/// unique_dyn_cast - Given a unique_ptr, try to return a unique_ptr, +/// taking ownership of the input pointer iff isa(Val) is true. If the +/// cast is successful, From refers to nullptr on exit and the casted value +/// is returned. If the cast is unsuccessful, the function returns nullptr +/// and From is unchanged. +template +[[nodiscard]] inline typename CastInfo>::CastResultType +unique_dyn_cast(std::unique_ptr &Val) { + if (!isa(Val)) + return nullptr; + return cast(std::move(Val)); +} + +template +[[nodiscard]] inline auto unique_dyn_cast(std::unique_ptr &&Val) { + return unique_dyn_cast(Val); +} + +// unique_dyn_cast_or_null - Functionally identical to unique_dyn_cast, +// except that a null value is accepted. +template +[[nodiscard]] inline typename CastInfo>::CastResultType +unique_dyn_cast_or_null(std::unique_ptr &Val) { + if (!Val) + return nullptr; + return unique_dyn_cast(Val); +} + +template +[[nodiscard]] inline auto unique_dyn_cast_or_null(std::unique_ptr &&Val) { + return unique_dyn_cast_or_null(Val); +} + +} // end namespace wpi + +#endif // WPIUTIL_WPI_CASTING_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Compiler.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Compiler.h index c98386e0f1..87a1f203a2 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Compiler.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Compiler.h @@ -38,6 +38,10 @@ # define __has_builtin(x) 0 #endif +#ifndef __has_include +# define __has_include(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 @@ -101,26 +105,6 @@ #endif #endif -/// Does the compiler support ref-qualifiers for *this? -/// -/// Sadly, this is separate from just rvalue reference support because GCC -/// and MSVC implemented this later than everything else. This appears to be -/// corrected in MSVC 2019 but not MSVC 2017. -/// FIXME: Remove LLVM_HAS_RVALUE_REFERENCE_THIS macro -#define LLVM_HAS_RVALUE_REFERENCE_THIS 1 - -/// Expands to '&' if ref-qualifiers for *this are supported. -/// -/// This can be used to provide lvalue/rvalue overrides of member functions. -/// The rvalue override should be guarded by LLVM_HAS_RVALUE_REFERENCE_THIS -#ifndef LLVM_LVALUE_FUNCTION -#if LLVM_HAS_RVALUE_REFERENCE_THIS -#define LLVM_LVALUE_FUNCTION & -#else -#define LLVM_LVALUE_FUNCTION -#endif -#endif - /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked /// into a shared library, then the class should be private to the library and /// not accessible from outside it. Can also be used to mark variables and @@ -130,8 +114,9 @@ /// LLVM_EXTERNAL_VISIBILITY - classes, functions, and variables marked with /// this attribute will be made public and visible outside of any shared library /// they are linked in to. -#if __has_attribute(visibility) && !defined(__MINGW32__) && \ - !defined(__CYGWIN__) && !defined(_WIN32) +#if __has_attribute(visibility) && \ + (!(defined(_WIN32) || defined(__CYGWIN__)) || \ + (defined(__MINGW32__) && defined(__clang__))) #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS) #define LLVM_EXTERNAL_VISIBILITY __attribute__((visibility("default"))) @@ -159,23 +144,10 @@ #endif #endif -/// LLVM_NODISCARD - Warn if a type or return value is discarded. - -// Use the 'nodiscard' attribute in C++17 or newer mode. -#ifndef LLVM_NODISCARD -#if defined(__cplusplus) && __cplusplus > 201402L && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) -#define LLVM_NODISCARD [[nodiscard]] -#elif LLVM_HAS_CPP_ATTRIBUTE(clang::warn_unused_result) -#define LLVM_NODISCARD [[clang::warn_unused_result]] -// Clang in C++14 mode claims that it has the 'nodiscard' attribute, but also -// warns in the pedantic mode that 'nodiscard' is a C++17 extension (PR33518). -// Use the 'nodiscard' attribute in C++14 mode only with GCC. -// TODO: remove this workaround when PR33518 is resolved. -#elif defined(__GNUC__) && LLVM_HAS_CPP_ATTRIBUTE(nodiscard) -#define LLVM_NODISCARD [[nodiscard]] +#if defined(__clang__) +#define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX))) #else -#define LLVM_NODISCARD -#endif +#define LLVM_DEPRECATED(MSG, FIX) [[deprecated(MSG)]] #endif // Indicate that a non-static, non-const C++ member function reinitializes @@ -356,23 +328,18 @@ #endif #endif -// LLVM_ATTRIBUTE_DEPRECATED(decl, "message") -// This macro will be removed. -// Use C++14's attribute instead: [[deprecated("message")]] -#ifndef LLVM_ATTRIBUTE_DEPRECATED -#define LLVM_ATTRIBUTE_DEPRECATED(decl, message) [[deprecated(message)]] decl -#endif - /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands /// to an expression which states that it is undefined behavior for the /// compiler to reach this point. Otherwise is not defined. +/// +/// '#else' is intentionally left out so that other macro logic (e.g., +/// LLVM_ASSUME_ALIGNED and wpi_unreachable()) can detect whether +/// LLVM_BUILTIN_UNREACHABLE has a definition. #ifndef LLVM_BUILTIN_UNREACHABLE #if __has_builtin(__builtin_unreachable) || defined(__GNUC__) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #elif defined(_MSC_VER) # define LLVM_BUILTIN_UNREACHABLE __assume(false) -#else -# define LLVM_BUILTIN_UNREACHABLE #endif #endif @@ -454,24 +421,6 @@ #endif #endif -/// \macro LLVM_PTR_SIZE -/// A constant integer equivalent to the value of sizeof(void*). -/// Generally used in combination with alignas or when doing computation in the -/// preprocessor. -#ifndef LLVM_PTR_SIZE -#ifdef __SIZEOF_POINTER__ -# define LLVM_PTR_SIZE __SIZEOF_POINTER__ -#elif defined(_WIN64) -# define LLVM_PTR_SIZE 8 -#elif defined(_WIN32) -# define LLVM_PTR_SIZE 4 -#elif defined(_MSC_VER) -# error "could not determine LLVM_PTR_SIZE as a constant int for MSVC" -#else -# define LLVM_PTR_SIZE sizeof(void *) -#endif -#endif - /// \macro LLVM_MEMORY_SANITIZER_BUILD /// Whether LLVM itself is built with MemorySanitizer instrumentation. #if __has_feature(memory_sanitizer) @@ -489,13 +438,34 @@ /// Whether LLVM itself is built with AddressSanitizer instrumentation. #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) # define LLVM_ADDRESS_SANITIZER_BUILD 1 +#if __has_include() # include #else +// These declarations exist to support ASan with MSVC. If MSVC eventually ships +// asan_interface.h in their headers, then we can remove this. +#ifdef __cplusplus +extern "C" { +#endif +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#ifdef __cplusplus +} // extern "C" +#endif +#endif +#else # define LLVM_ADDRESS_SANITIZER_BUILD 0 # define __asan_poison_memory_region(p, size) # define __asan_unpoison_memory_region(p, size) #endif +/// \macro LLVM_HWADDRESS_SANITIZER_BUILD +/// Whether LLVM itself is built with HWAddressSanitizer instrumentation. +#if __has_feature(hwaddress_sanitizer) +#define LLVM_HWADDRESS_SANITIZER_BUILD 1 +#else +#define LLVM_HWADDRESS_SANITIZER_BUILD 0 +#endif + /// \macro LLVM_THREAD_SANITIZER_BUILD /// Whether LLVM itself is built with ThreadSanitizer instrumentation. #if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__) diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ConvertUTF.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ConvertUTF.h index 436bc6d58b..6153d818aa 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ConvertUTF.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ConvertUTF.h @@ -6,25 +6,41 @@ * *==------------------------------------------------------------------------==*/ /* - * Copyright 2001-2004 Unicode, Inc. + * Copyright © 1991-2015 Unicode, Inc. All rights reserved. + * Distributed under the Terms of Use in + * http://www.unicode.org/copyright.html. * - * Disclaimer + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of the Unicode data files and any associated documentation + * (the "Data Files") or Unicode software and any associated documentation + * (the "Software") to deal in the Data Files or Software + * without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, and/or sell copies of + * the Data Files or Software, and to permit persons to whom the Data Files + * or Software are furnished to do so, provided that + * (a) this copyright and permission notice appear with all copies + * of the Data Files or Software, + * (b) this copyright and permission notice appear in associated + * documentation, and + * (c) there is clear notice in each modified Data File or in the Software + * as well as in the documentation associated with the Data File(s) or + * Software that the data or software has been modified. * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. + * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + * NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + * DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THE DATA FILES OR SOFTWARE. * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in these Data Files or Software without prior + * written authorization of the copyright holder. */ /* --------------------------------------------------------------------- @@ -89,10 +105,9 @@ #ifndef WPIUTIL_WPI_CONVERTUTF_H #define WPIUTIL_WPI_CONVERTUTF_H -#include - #include #include +#include #include #include @@ -126,6 +141,9 @@ typedef bool Boolean; /* 0 or 1 */ #define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF #define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE +#define UNI_UTF32_BYTE_ORDER_MARK_NATIVE 0x0000FEFF +#define UNI_UTF32_BYTE_ORDER_MARK_SWAPPED 0xFFFE0000 + typedef enum { conversionOK, /* conversion successful */ sourceExhausted, /* partial character in source, but hit end */ @@ -178,6 +196,8 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); +unsigned getUTF8SequenceSize(const UTF8 *source, const UTF8 *sourceEnd); + unsigned getNumBytesForUTF8(UTF8 firstByte); /*************************************************************************/ @@ -279,6 +299,24 @@ bool convertUTF16ToUTF8String(std::span SrcBytes, SmallVectorImpl Src, SmallVectorImpl &Out); +/** + * Converts a stream of raw bytes assumed to be UTF32 into a UTF8 std::string. + * + * \param [in] SrcBytes A buffer of what is assumed to be UTF-32 encoded text. + * \param [out] Out Converted UTF-8 is stored here on success. + * \returns true on success + */ +bool convertUTF32ToUTF8String(std::span SrcBytes, std::string &Out); + +/** + * Converts a UTF32 string into a UTF8 std::string. + * + * \param [in] Src A buffer of UTF-32 encoded text. + * \param [out] Out Converted UTF-8 is stored here on success. + * \returns true on success + */ +bool convertUTF32ToUTF8String(std::span Src, std::string &Out); + /** * Converts a UTF-8 string into a UTF-16 string with native endianness. * diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMap.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMap.h index 4135bc3915..fbd1644cc9 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMap.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMap.h @@ -95,9 +95,7 @@ public: return makeConstIterator(getBucketsEnd(), getBucketsEnd(), *this, true); } - LLVM_NODISCARD bool empty() const { - return getNumEntries() == 0; - } + [[nodiscard]] bool empty() const { return getNumEntries() == 0; } unsigned size() const { return getNumEntries(); } /// Grow the densemap so that it can contain at least \p NumEntries items @@ -137,6 +135,7 @@ public: } } assert(NumEntries == 0 && "Node count imbalance!"); + (void)NumEntries; } setNumEntries(0); setNumTombstones(0); @@ -906,6 +905,8 @@ class SmallDenseMap public: explicit SmallDenseMap(unsigned NumInitBuckets = 0) { + if (NumInitBuckets > InlineBuckets) + NumInitBuckets = NextPowerOf2(NumInitBuckets - 1); init(NumInitBuckets); } @@ -1196,8 +1197,7 @@ class DenseMapIterator : DebugEpochBase::HandleBase { public: using difference_type = ptrdiff_t; - using value_type = - typename std::conditional::type; + using value_type = std::conditional_t; using pointer = value_type *; using reference = value_type &; using iterator_category = std::forward_iterator_tag; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMapInfo.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMapInfo.h index 0ff8fc9e22..f207359f18 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMapInfo.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/DenseMapInfo.h @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include namespace wpi { @@ -252,7 +254,7 @@ template struct DenseMapInfo> { template static unsigned getHashValueImpl(const Tuple &values, std::false_type) { - using EltType = typename std::tuple_element::type; + using EltType = std::tuple_element_t; std::integral_constant atEnd; return detail::combineHashValue( DenseMapInfo::getHashValue(std::get(values)), @@ -271,7 +273,7 @@ template struct DenseMapInfo> { template static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) { - using EltType = typename std::tuple_element::type; + using EltType = std::tuple_element_t; std::integral_constant atEnd; return DenseMapInfo::isEqual(std::get(lhs), std::get(rhs)) && isEqualImpl(lhs, rhs, atEnd); @@ -288,6 +290,37 @@ template struct DenseMapInfo> { } }; +// Provide DenseMapInfo for variants whose all alternatives have DenseMapInfo. +template struct DenseMapInfo> { + using Variant = std::variant; + using FirstT = std::variant_alternative_t<0, Variant>; + + static inline Variant getEmptyKey() { + return Variant(std::in_place_index<0>, DenseMapInfo::getEmptyKey()); + } + + static inline Variant getTombstoneKey() { + return Variant(std::in_place_index<0>, + DenseMapInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const Variant &Val) { + return std::visit( + [&Val](auto &&Alternative) { + using T = std::decay_t; + // Include index in hash to make sure same value as different + // alternatives don't collide. + return detail::combineHashValue( + DenseMapInfo::getHashValue(Val.index()), + DenseMapInfo::getHashValue(Alternative)); + }, + Val); + } + + static bool isEqual(const Variant &LHS, const Variant &RHS) { + return LHS == RHS; + } +}; } // end namespace wpi #endif // WPIUTIL_WPI_DENSEMAPINFO_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/EpochTracker.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/EpochTracker.h index 6417c05d71..14a32f1699 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/EpochTracker.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/EpochTracker.h @@ -33,10 +33,10 @@ namespace wpi { /// is still valid. /// class DebugEpochBase { - uint64_t Epoch; + uint64_t Epoch = 0; public: - DebugEpochBase() : Epoch(0) {} + DebugEpochBase() = default; /// Calling incrementEpoch invalidates all handles pointing into the /// calling instance. @@ -55,11 +55,11 @@ public: /// make an iterator-invalidating modification. /// class HandleBase { - const uint64_t *EpochAddress; - uint64_t EpochAtCreation; + const uint64_t *EpochAddress = nullptr; + uint64_t EpochAtCreation = UINT64_MAX; public: - HandleBase() : EpochAddress(nullptr), EpochAtCreation(UINT64_MAX) {} + HandleBase() = default; explicit HandleBase(const DebugEpochBase *Parent) : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {} diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Errno.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Errno.h index febfc372a9..a01ebdae0c 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Errno.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Errno.h @@ -15,7 +15,6 @@ #include #include -#include namespace wpi { namespace sys { diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ErrorHandling.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ErrorHandling.h index 7b4367103d..f3cf658fe6 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ErrorHandling.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/ErrorHandling.h @@ -123,19 +123,34 @@ wpi_unreachable_internal(const char *msg = nullptr, const char *file = nullptr, /// Marks that the current location is not supposed to be reachable. /// In !NDEBUG builds, prints the message and location info to stderr. -/// In NDEBUG builds, becomes an optimizer hint that the current location -/// is not supposed to be reachable. On compilers that don't support -/// such hints, prints a reduced message instead and aborts the program. +/// In NDEBUG builds, if the platform does not support a builtin unreachable +/// then we call an internal LLVM runtime function. Otherwise the behavior is +/// controlled by the CMake flag +/// -DLLVM_UNREACHABLE_OPTIMIZE +/// * When "ON" (default) wpi_unreachable() becomes an optimizer hint +/// that the current location is not supposed to be reachable: the hint +/// turns such code path into undefined behavior. On compilers that don't +/// support such hints, prints a reduced message instead and aborts the +/// program. +/// * When "OFF", a builtin_trap is emitted instead of an +// optimizer hint or printing a reduced message. /// -/// Use this instead of assert(0). It conveys intent more clearly and -/// allows compilers to omit some unnecessary code. +/// Use this instead of assert(0). It conveys intent more clearly, suppresses +/// diagnostics for unreachable code paths, and allows compilers to omit +/// unnecessary code. #ifndef NDEBUG #define wpi_unreachable(msg) \ ::wpi::wpi_unreachable_internal(msg, __FILE__, __LINE__) -#elif defined(LLVM_BUILTIN_UNREACHABLE) +#elif !defined(LLVM_BUILTIN_UNREACHABLE) +#define wpi_unreachable(msg) ::wpi::wpi_unreachable_internal() +#elif LLVM_UNREACHABLE_OPTIMIZE #define wpi_unreachable(msg) LLVM_BUILTIN_UNREACHABLE #else -#define wpi_unreachable(msg) ::wpi::wpi_unreachable_internal() +#define wpi_unreachable(msg) \ + do { \ + LLVM_BUILTIN_TRAP; \ + LLVM_BUILTIN_UNREACHABLE; \ + } while (false) #endif #endif diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/FunctionExtras.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/FunctionExtras.h index 681b87e888..3bd2b3383d 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/FunctionExtras.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/FunctionExtras.h @@ -72,7 +72,7 @@ template using EnableUnlessSameType = std::enable_if_t, ThisT>::value>; template -using EnableIfCallable = std::enable_if_t, std::is_same()(std::declval()...)), Ret>, @@ -106,11 +106,11 @@ protected: template struct AdjustedParamTBase { static_assert(!std::is_reference::value, "references should be handled by template specialization"); - using type = typename std::conditional< + using type = std::conditional_t< wpi::is_trivially_copy_constructible::value && wpi::is_trivially_move_constructible::value && IsSizeLessThanThresholdT::value, - T, T &>::type; + T, T &>; }; // This specialization ensures that 'AdjustedParam&>' or @@ -167,9 +167,8 @@ protected: // provide four pointers worth of storage here. // This is mutable as an inlined `const unique_function` may // still modify its own mutable members. - mutable - typename std::aligned_storage::type - InlineStorage; + mutable std::aligned_storage_t + InlineStorage; } StorageUnion; // A compressed pointer to either our dispatching callback or our table of diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Hashing.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Hashing.h index 0d4a4c6d93..0f5c224352 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Hashing.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/Hashing.h @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,8 @@ hash_code hash_value(const std::tuple &arg); template hash_code hash_value(const std::basic_string &arg); +/// Compute a hash_code for a standard string. +template hash_code hash_value(const std::optional &arg); /// Override the execution seed with a fixed value. /// @@ -655,24 +658,8 @@ hash_code hash_value(const std::pair &arg) { return hash_combine(arg.first, arg.second); } -// Implementation details for the hash_value overload for std::tuple<...>(...). -namespace hashing { -namespace detail { - -template -hash_code hash_value_tuple_helper(const std::tuple &arg, - std::index_sequence) { - return hash_combine(std::get(arg)...); -} - -} // namespace detail -} // namespace hashing - -template -hash_code hash_value(const std::tuple &arg) { - // TODO: Use std::apply when LLVM starts using C++17. - return ::wpi::hashing::detail::hash_value_tuple_helper( - arg, typename std::index_sequence_for()); +template hash_code hash_value(const std::tuple &arg) { + return std::apply([](const auto &...xs) { return hash_combine(xs...); }, arg); } // Declared and documented above, but defined here so that any of the hashing @@ -682,6 +669,10 @@ hash_code hash_value(const std::basic_string &arg) { return hash_combine_range(arg.begin(), arg.end()); } +template hash_code hash_value(const std::optional &arg) { + return arg ? hash_combine(true, *arg) : hash_value(false); +} + template <> struct DenseMapInfo { static inline hash_code getEmptyKey() { return hash_code(-1); } static inline hash_code getTombstoneKey() { return hash_code(-2); } diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MapVector.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MapVector.h index e4706c7997..26db80038d 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MapVector.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MapVector.h @@ -39,7 +39,7 @@ class MapVector { VectorType Vector; static_assert( - std::is_integral::value, + std::is_integral_v, "The mapped_type of the specified Map must be an integral type"); public: @@ -109,7 +109,7 @@ public: // Returns a copy of the value. Only allowed if ValueT is copyable. ValueT lookup(const KeyT &Key) const { - static_assert(std::is_copy_constructible::value, + static_assert(std::is_copy_constructible_v, "Cannot call lookup() if ValueT is not copyable."); typename MapType::const_iterator Pos = Map.find(Key); return Pos == Map.end()? ValueT() : Vector[Pos->second].second; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MathExtras.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MathExtras.h index ea669ee28b..af3727ba64 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MathExtras.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/MathExtras.h @@ -13,31 +13,16 @@ #ifndef WPIUTIL_WPI_MATHEXTRAS_H #define WPIUTIL_WPI_MATHEXTRAS_H +#include "wpi/bit.h" #include "wpi/Compiler.h" +#include #include #include -#include #include #include #include #include -#ifdef __ANDROID_NDK__ -#include -#endif - -#ifdef _MSC_VER -// Declare these intrinsics manually rather including intrin.h. It's very -// expensive, and MathExtras.h is popular. -// #include -extern "C" { -unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask); -unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask); -unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask); -unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask); -} -#endif - namespace wpi { /// The behavior an operation has on an input of 0. @@ -45,152 +30,31 @@ enum ZeroBehavior { /// The returned value is undefined. ZB_Undefined, /// The returned value is numeric_limits::max() - ZB_Max, - /// The returned value is numeric_limits::digits - ZB_Width + ZB_Max }; -namespace detail { -template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior) { - if (!Val) - return std::numeric_limits::digits; - if (Val & 0x1) - return 0; - - // Bisection method. - unsigned ZeroBits = 0; - T Shift = std::numeric_limits::digits >> 1; - T Mask = (std::numeric_limits::max)() >> Shift; - while (Shift) { - if ((Val & Mask) == 0) { - Val >>= Shift; - ZeroBits |= Shift; - } - Shift >>= 1; - Mask >>= Shift; - } - return ZeroBits; - } -}; - -#if defined(__GNUC__) || defined(_MSC_VER) -template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && 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; -#endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct TrailingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && 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. /// /// Only unsigned integral types are allowed. /// -/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are -/// valid arguments. -template -unsigned countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, +/// Returns std::numeric_limits::digits on an input of 0. +template unsigned countTrailingZeros(T Val) { + static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return wpi::detail::TrailingZerosCounter::count(Val, ZB); + return std::countr_zero(Val); } -namespace detail { -template struct LeadingZerosCounter { - static unsigned count(T Val, ZeroBehavior) { - if (!Val) - return std::numeric_limits::digits; - - // Bisection method. - unsigned ZeroBits = 0; - for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { - T Tmp = Val >> Shift; - if (Tmp) - Val = Tmp; - else - ZeroBits |= Shift; - } - return ZeroBits; - } -}; - -#if defined(__GNUC__) || defined(_MSC_VER) -template struct LeadingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && Val == 0) - return 32; - -#if __has_builtin(__builtin_clz) || defined(__GNUC__) - return __builtin_clz(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanReverse(&Index, Val); - return Index ^ 31; -#endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct LeadingZerosCounter { - static unsigned count(T Val, ZeroBehavior ZB) { - if (ZB != ZB_Undefined && Val == 0) - return 64; - -#if __has_builtin(__builtin_clzll) || defined(__GNUC__) - return __builtin_clzll(Val); -#elif defined(_MSC_VER) - unsigned long Index; - _BitScanReverse64(&Index, Val); - return Index ^ 63; -#endif - } -}; -#endif -#endif -} // namespace detail - /// Count number of 0's from the most significant bit to the least /// stopping at the first 1. /// /// Only unsigned integral types are allowed. /// -/// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are -/// valid arguments. -template -unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, +/// Returns std::numeric_limits::digits on an input of 0. +template unsigned countLeadingZeros(T Val) { + static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return wpi::detail::LeadingZerosCounter::count(Val, ZB); + return std::countl_zero(Val); } /// Get the index of the first set bit starting from the least @@ -198,13 +62,12 @@ unsigned countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { /// /// Only unsigned integral types are allowed. /// -/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are -/// valid arguments. +/// \param ZB the behavior on an input of 0. template T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return (std::numeric_limits::max)(); - return countTrailingZeros(Val, ZB_Undefined); + return std::countr_zero(Val); } /// Create a bitmask with the N right-most bits set to 1, and all other @@ -239,16 +102,14 @@ template T maskLeadingZeros(unsigned N) { /// /// Only unsigned integral types are allowed. /// -/// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are -/// valid arguments. +/// \param ZB the behavior on an input of 0. template T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return (std::numeric_limits::max)(); // Use ^ instead of - because both gcc and llvm can remove the associated ^ // in the __builtin_clz intrinsic on x86. - return countLeadingZeros(Val, ZB_Undefined) ^ - (std::numeric_limits::digits - 1); + return std::countl_zero(Val) ^ (std::numeric_limits::digits - 1); } /// Macro compressed bit reversal table for 256 bits. @@ -265,8 +126,24 @@ static const unsigned char BitReverseTable256[256] = { }; /// Reverse the bits in \p Val. -template -T reverseBits(T Val) { +template T reverseBits(T Val) { +#if __has_builtin(__builtin_bitreverse8) + if constexpr (std::is_same_v) + return __builtin_bitreverse8(Val); +#endif +#if __has_builtin(__builtin_bitreverse16) + if constexpr (std::is_same_v) + return __builtin_bitreverse16(Val); +#endif +#if __has_builtin(__builtin_bitreverse32) + if constexpr (std::is_same_v) + return __builtin_bitreverse32(Val); +#endif +#if __has_builtin(__builtin_bitreverse64) + if constexpr (std::is_same_v) + return __builtin_bitreverse64(Val); +#endif + unsigned char in[sizeof(Val)]; unsigned char out[sizeof(Val)]; std::memcpy(in, &Val, sizeof(Val)); @@ -276,34 +153,6 @@ T reverseBits(T Val) { return Val; } -#if __has_builtin(__builtin_bitreverse8) -template<> -inline uint8_t reverseBits(uint8_t Val) { - return __builtin_bitreverse8(Val); -} -#endif - -#if __has_builtin(__builtin_bitreverse16) -template<> -inline uint16_t reverseBits(uint16_t Val) { - return __builtin_bitreverse16(Val); -} -#endif - -#if __has_builtin(__builtin_bitreverse32) -template<> -inline uint32_t reverseBits(uint32_t Val) { - return __builtin_bitreverse32(Val); -} -#endif - -#if __has_builtin(__builtin_bitreverse64) -template<> -inline uint64_t reverseBits(uint64_t Val) { - return __builtin_bitreverse64(Val); -} -#endif - // NOTE: The following support functions use the _32/_64 extensions instead of // type overloading so that signed and unsigned integers can be used without // ambiguity. @@ -325,17 +174,16 @@ constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) { /// Checks if an integer fits into the given bit width. template constexpr inline bool isInt(int64_t x) { - return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1))); -} -// Template specializations to get better code for common cases. -template <> constexpr inline bool isInt<8>(int64_t x) { - return static_cast(x) == x; -} -template <> constexpr inline bool isInt<16>(int64_t x) { - return static_cast(x) == x; -} -template <> constexpr inline bool isInt<32>(int64_t x) { - return static_cast(x) == x; + if constexpr (N == 8) + return static_cast(x) == x; + if constexpr (N == 16) + return static_cast(x) == x; + if constexpr (N == 32) + return static_cast(x) == x; + if constexpr (N < 64) + return -(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1)); + (void)x; // MSVC v19.25 warns that x is unused. + return true; } /// Checks if a signed integer is an N bit number shifted left by S. @@ -348,34 +196,20 @@ constexpr inline bool isShiftedInt(int64_t x) { } /// Checks if an unsigned integer fits into the given bit width. -/// -/// This is written as two functions rather than as simply -/// -/// return N >= 64 || X < (UINT64_C(1) << N); -/// -/// to keep MSVC from (incorrectly) warning on isUInt<64> that we're shifting -/// left too many places. -template -constexpr inline std::enable_if_t<(N < 64), bool> isUInt(uint64_t X) { +template constexpr inline bool isUInt(uint64_t x) { static_assert(N > 0, "isUInt<0> doesn't make sense"); - return X < (UINT64_C(1) << (N)); -} -template -constexpr inline std::enable_if_t= 64, bool> isUInt(uint64_t) { + if constexpr (N == 8) + return static_cast(x) == x; + if constexpr (N == 16) + return static_cast(x) == x; + if constexpr (N == 32) + return static_cast(x) == x; + if constexpr (N < 64) + return x < (UINT64_C(1) << (N)); + (void)x; // MSVC v19.25 warns that x is unused. return true; } -// Template specializations to get better code for common cases. -template <> constexpr inline bool isUInt<8>(uint64_t x) { - return static_cast(x) == x; -} -template <> constexpr inline bool isUInt<16>(uint64_t x) { - return static_cast(x) == x; -} -template <> constexpr inline bool isUInt<32>(uint64_t x) { - return static_cast(x) == x; -} - /// Checks if a unsigned integer is an N bit number shifted left by S. template constexpr inline bool isShiftedUInt(uint64_t x) { @@ -462,12 +296,12 @@ constexpr inline 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 inline bool isPowerOf2_32(uint32_t Value) { - return Value && !(Value & (Value - 1)); + return std::has_single_bit(Value); } /// Return true if the argument is a power of two > 0 (64 bit edition.) constexpr inline bool isPowerOf2_64(uint64_t Value) { - return Value && !(Value & (Value - 1)); + return std::has_single_bit(Value); } /// Count the number of ones from the most significant bit to the first @@ -476,14 +310,11 @@ constexpr inline bool isPowerOf2_64(uint64_t Value) { /// Ex. countLeadingOnes(0xFF0FFF00) == 8. /// Only unsigned integral types are allowed. /// -/// \param ZB the behavior on an input of all ones. Only ZB_Width and -/// ZB_Undefined are valid arguments. -template -unsigned countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, +/// Returns std::numeric_limits::digits on an input of all ones. +template unsigned countLeadingOnes(T Value) { + static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return countLeadingZeros(~Value, ZB); + return std::countl_one(Value); } /// Count the number of ones from the least significant bit to the first @@ -492,56 +323,48 @@ unsigned countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { /// Ex. countTrailingOnes(0x00FF00FF) == 8. /// Only unsigned integral types are allowed. /// -/// \param ZB the behavior on an input of all ones. Only ZB_Width and -/// ZB_Undefined are valid arguments. -template -unsigned countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, +/// Returns std::numeric_limits::digits on an input of all ones. +template unsigned countTrailingOnes(T Value) { + static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return countTrailingZeros(~Value, ZB); + return std::countr_one(Value); } -namespace detail { -template struct PopulationCounter { - static unsigned count(T Value) { - // Generic version, forward to 32 bits. - static_assert(SizeOfT <= 4, "Not implemented!"); -#if defined(__GNUC__) - return __builtin_popcount(Value); -#else - uint32_t v = Value; - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; -#endif - } -}; - -template struct PopulationCounter { - static unsigned count(T Value) { -#if defined(__GNUC__) - return __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 unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); -#endif - } -}; -} // namespace detail - /// Count the number of set bits in a value. /// Ex. countPopulation(0xF000F000) = 8 /// Returns 0 if the word is zero. template inline unsigned countPopulation(T Value) { - static_assert(std::numeric_limits::is_integer && - !std::numeric_limits::is_signed, + static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return detail::PopulationCounter::count(Value); + return (unsigned)std::popcount(Value); +} + +/// Return true if the argument contains a non-empty sequence of ones with the +/// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true. +/// If true, \p MaskIdx will specify the index of the lowest set bit and \p +/// MaskLen is updated to specify the length of the mask, else neither are +/// updated. +inline bool isShiftedMask_32(uint32_t Value, unsigned &MaskIdx, + unsigned &MaskLen) { + if (!isShiftedMask_32(Value)) + return false; + MaskIdx = std::countr_zero(Value); + MaskLen = std::popcount(Value); + return true; +} + +/// Return true if the argument contains a non-empty sequence of ones with the +/// remainder zero (64 bit version.) If true, \p MaskIdx will specify the index +/// of the lowest set bit and \p MaskLen is updated to specify the length of the +/// mask, else neither are updated. +inline bool isShiftedMask_64(uint64_t Value, unsigned &MaskIdx, + unsigned &MaskLen) { + if (!isShiftedMask_64(Value)) + return false; + MaskIdx = std::countr_zero(Value); + MaskLen = std::popcount(Value); + return true; } /// Compile time Log2. @@ -554,90 +377,58 @@ template constexpr inline size_t CTLog2() { template <> constexpr inline size_t CTLog2<1>() { return 0; } -/// Return the log base 2 of the specified value. -inline double Log2(double Value) { -#if defined(__ANDROID_API__) && __ANDROID_API__ < 18 - return __builtin_log(Value) / __builtin_log(2.0); -#else - return std::log2(Value); -#endif -} - /// Return the floor log base 2 of the specified value, -1 if the value is zero. /// (32 bit edition.) /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 inline unsigned Log2_32(uint32_t Value) { - return static_cast(31 - countLeadingZeros(Value)); + return static_cast(31 - std::countl_zero(Value)); } /// Return the floor log base 2 of the specified value, -1 if the value is zero. /// (64 bit edition.) inline unsigned Log2_64(uint64_t Value) { - return static_cast(63 - countLeadingZeros(Value)); + return static_cast(63 - std::countl_zero(Value)); } /// Return the ceil log base 2 of the specified value, 32 if the value is zero. /// (32 bit edition). /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 inline unsigned Log2_32_Ceil(uint32_t Value) { - return static_cast(32 - countLeadingZeros(Value - 1)); + return static_cast(32 - std::countl_zero(Value - 1)); } /// Return the ceil log base 2 of the specified value, 64 if the value is zero. /// (64 bit edition.) inline unsigned Log2_64_Ceil(uint64_t Value) { - return static_cast(64 - countLeadingZeros(Value - 1)); -} - -/// Return the greatest common divisor of the values using Euclid's algorithm. -template -inline T greatestCommonDivisor(T A, T B) { - while (B) { - T Tmp = B; - B = A % B; - A = Tmp; - } - return A; -} - -inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { - return greatestCommonDivisor(A, B); + return static_cast(64 - std::countl_zero(Value - 1)); } /// This function takes a 64-bit integer and returns the bit equivalent double. inline double BitsToDouble(uint64_t Bits) { - double D; static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); - memcpy(&D, &Bits, sizeof(Bits)); - return D; + return wpi::bit_cast(Bits); } /// This function takes a 32-bit integer and returns the bit equivalent float. inline float BitsToFloat(uint32_t Bits) { - float F; static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); - memcpy(&F, &Bits, sizeof(Bits)); - return F; + return wpi::bit_cast(Bits); } /// This function takes a double and returns the bit equivalent 64-bit integer. /// Note that copying doubles around changes the bits of NaNs on some hosts, /// notably x86, so this routine cannot be used if these bits are needed. inline uint64_t DoubleToBits(double Double) { - uint64_t Bits; static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); - memcpy(&Bits, &Double, sizeof(Double)); - return Bits; + return wpi::bit_cast(Double); } /// This function takes a float and returns the bit equivalent 32-bit integer. /// Note that copying floats around changes the bits of NaNs on some hosts, /// notably x86, so this routine cannot be used if these bits are needed. inline uint32_t FloatToBits(float Float) { - uint32_t Bits; static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); - memcpy(&Bits, &Float, sizeof(Float)); - return Bits; + return wpi::bit_cast(Float); } /// A and B are either alignments or offsets. Return the minimum alignment that @@ -653,7 +444,7 @@ constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) { /// Returns the next power of two (in 64-bits) that is strictly greater than A. /// Returns zero on overflow. -inline uint64_t NextPowerOf2(uint64_t A) { +constexpr inline uint64_t NextPowerOf2(uint64_t A) { A |= (A >> 1); A |= (A >> 2); A |= (A >> 4); @@ -666,8 +457,7 @@ inline uint64_t NextPowerOf2(uint64_t A) { /// Returns the power of two which is less than or equal to the given value. /// Essentially, it is a floor operation across the domain of powers of two. inline uint64_t PowerOf2Floor(uint64_t A) { - if (!A) return 0; - return 1ull << (63 - countLeadingZeros(A, ZB_Undefined)); + return std::bit_floor(A); } /// Returns the power of two which is greater than or equal to the given value. @@ -681,27 +471,40 @@ inline uint64_t PowerOf2Ceil(uint64_t A) { /// Returns the next integer (mod 2**64) that is greater than or equal to /// \p Value and is a multiple of \p Align. \p Align must be non-zero. /// -/// If non-zero \p Skew is specified, the return value will be a minimal -/// integer that is greater than or equal to \p Value and equal to -/// \p Align * N + \p Skew for some integer N. If \p Skew is larger than -/// \p Align, its value is adjusted to '\p Skew mod \p Align'. -/// /// Examples: /// \code /// alignTo(5, 8) = 8 /// alignTo(17, 8) = 24 /// alignTo(~0LL, 8) = 0 /// alignTo(321, 255) = 510 +/// \endcode +inline uint64_t alignTo(uint64_t Value, uint64_t Align) { + assert(Align != 0u && "Align can't be 0."); + return (Value + Align - 1) / Align * Align; +} + +inline uint64_t alignToPowerOf2(uint64_t Value, uint64_t Align) { + assert(Align != 0 && (Align & (Align - 1)) == 0 && + "Align must be a power of 2"); + return (Value + Align - 1) & -Align; +} + +/// If non-zero \p Skew is specified, the return value will be a minimal integer +/// that is greater than or equal to \p Size and equal to \p A * N + \p Skew for +/// some integer N. If \p Skew is larger than \p A, its value is adjusted to '\p +/// Skew mod \p A'. \p Align must be non-zero. /// +/// Examples: +/// \code /// alignTo(5, 8, 7) = 7 /// alignTo(17, 8, 1) = 17 /// alignTo(~0LL, 8, 3) = 3 /// alignTo(321, 255, 42) = 552 /// \endcode -inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { +inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew) { assert(Align != 0u && "Align can't be 0."); Skew %= Align; - return (Value + Align - 1 - Skew) / Align * Align + Skew; + return alignTo(Value - Skew, Align) + Skew; } /// Returns the next integer (mod 2**64) that is greater than or equal to @@ -785,6 +588,18 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { return Z; } +/// Add multiple unsigned integers of type T. Clamp the result to the +/// maximum representable value of T on overflow. +template +std::enable_if_t, T> SaturatingAdd(T X, T Y, T Z, + Ts... Args) { + bool Overflowed = false; + T XY = SaturatingAdd(X, Y, &Overflowed); + if (Overflowed) + return SaturatingAdd((std::numeric_limits::max)(), T(1), Args...); + return SaturatingAdd(XY, Z, Args...); +} + /// Multiply two unsigned integers, X and Y, of type T. Clamp the result to the /// maximum representable value of T on overflow. ResultOverflowed indicates if /// the result is larger than the maximum representable value of type T. @@ -852,7 +667,7 @@ extern const float huge_valf; /// Add two signed integers, computing the two's complement truncated result, -/// returning true if overflow occured. +/// returning true if overflow occurred. template std::enable_if_t::value, T> AddOverflow(T X, T Y, T &Result) { #if __has_builtin(__builtin_add_overflow) diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerIntPair.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerIntPair.h index 34ff4e1387..2344001e9b 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerIntPair.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerIntPair.h @@ -61,19 +61,19 @@ public: IntType getInt() const { return (IntType)Info::getInt(Value); } - void setPointer(PointerTy PtrVal) LLVM_LVALUE_FUNCTION { + void setPointer(PointerTy PtrVal) & { Value = Info::updatePointer(Value, PtrVal); } - void setInt(IntType IntVal) LLVM_LVALUE_FUNCTION { + void setInt(IntType IntVal) & { Value = Info::updateInt(Value, static_cast(IntVal)); } - void initWithPointer(PointerTy PtrVal) LLVM_LVALUE_FUNCTION { + void initWithPointer(PointerTy PtrVal) & { Value = Info::updatePointer(0, PtrVal); } - void setPointerAndInt(PointerTy PtrVal, IntType IntVal) LLVM_LVALUE_FUNCTION { + void setPointerAndInt(PointerTy PtrVal, IntType IntVal) & { Value = Info::updateInt(Info::updatePointer(0, PtrVal), static_cast(IntVal)); } @@ -91,7 +91,7 @@ public: void *getOpaqueValue() const { return reinterpret_cast(Value); } - void setFromOpaqueValue(void *Val) LLVM_LVALUE_FUNCTION { + void setFromOpaqueValue(void *Val) & { Value = reinterpret_cast(Val); } @@ -128,7 +128,6 @@ public: } }; - template struct PointerIntPairInfo { static_assert(PtrTraits::NumLowBitsAvailable < @@ -228,6 +227,32 @@ struct PointerLikeTypeTraits< PtrTraits::NumLowBitsAvailable - IntBits; }; +// Allow structured bindings on PointerIntPair. +template +decltype(auto) +get(const PointerIntPair &Pair) { + static_assert(I < 2); + if constexpr (I == 0) + return Pair.getPointer(); + else + return Pair.getInt(); +} + } // end namespace wpi +namespace std { +template +struct tuple_size< + wpi::PointerIntPair> + : std::integral_constant {}; + +template +struct tuple_element< + I, wpi::PointerIntPair> + : std::conditional {}; +} // namespace std + #endif // WPIUTIL_WPI_POINTERINTPAIR_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerUnion.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerUnion.h index cc12bbc3ac..f0ed39223a 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerUnion.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/PointerUnion.h @@ -17,6 +17,7 @@ #include "wpi/DenseMapInfo.h" #include "wpi/PointerIntPair.h" +#include "wpi/Casting.h" #include "wpi/PointerLikeTypeTraits.h" #include #include @@ -132,6 +133,9 @@ namespace pointer_union_detail { }; } +// This is a forward declaration of CastInfoPointerUnionImpl +// Refer to its definition below for further details +template struct CastInfoPointerUnionImpl; /// A discriminated union of two or more pointer types, with the discriminator /// in the low bit of the pointer. /// @@ -167,6 +171,11 @@ 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; + public: PointerUnion() = default; @@ -179,25 +188,24 @@ public: explicit operator bool() const { return !isNull(); } + // FIXME: Replace the uses of is(), get() and dyn_cast() with + // isa, cast and the wpi::dyn_cast + /// Test if the Union currently holds the type matching T. - template bool is() const { - return this->Val.getInt() == FirstIndexOfType::value; - } + template inline bool is() const { return isa(*this); } /// Returns the value of the specified pointer type. /// /// If the specified pointer type is incorrect, assert. - template T get() const { - assert(is() && "Invalid accessor called"); - return PointerLikeTypeTraits::getFromVoidPointer(this->Val.getPointer()); + template inline T get() const { + assert(isa(*this) && "Invalid accessor called"); + return cast(*this); } /// Returns the current pointer if it is of the specified pointer type, /// otherwise returns null. - template T dyn_cast() const { - if (is()) - return get(); - return T(); + template inline T dyn_cast() const { + return wpi::dyn_cast_if_present(*this); } /// If the union is set to the first pointer type get an address pointing to @@ -250,6 +258,52 @@ bool operator<(PointerUnion lhs, PointerUnion rhs) { return lhs.getOpaqueValue() < rhs.getOpaqueValue(); } +/// We can't (at least, at this moment with C++14) declare CastInfo +/// as a friend of PointerUnion like this: +/// ``` +/// template +/// friend struct CastInfo>; +/// ``` +/// The compiler complains 'Partial specialization cannot be declared as a +/// friend'. +/// So we define this struct to be a bridge between CastInfo and +/// PointerUnion. +template struct CastInfoPointerUnionImpl { + using From = PointerUnion; + + template static inline bool isPossible(From &F) { + return F.Val.getInt() == FirstIndexOfType::value; + } + + template static To doCast(From &F) { + assert(isPossible(F) && "cast to an incompatible type !"); + return PointerLikeTypeTraits::getFromVoidPointer(F.Val.getPointer()); + } +}; + +// Specialization of CastInfo for PointerUnion +template +struct CastInfo> + : public DefaultDoCastIfPossible, + CastInfo>> { + using From = PointerUnion; + using Impl = CastInfoPointerUnionImpl; + + static inline bool isPossible(From &f) { + return Impl::template isPossible(f); + } + + static To doCast(From &f) { return Impl::template doCast(f); } + + static inline To castFailed() { return To(); } +}; + +template +struct CastInfo> + : public ConstStrippingForwardingCast, + CastInfo>> { +}; + // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits)-1. template diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/STLForwardCompat.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/STLForwardCompat.h index 7f8f068f44..02cf826989 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/STLForwardCompat.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/STLForwardCompat.h @@ -17,53 +17,11 @@ #ifndef WPIUTIL_WPI_STLFORWARDCOMPAT_H #define WPIUTIL_WPI_STLFORWARDCOMPAT_H +#include #include namespace wpi { -//===----------------------------------------------------------------------===// -// Features from C++17 -//===----------------------------------------------------------------------===// - -template -struct negation // NOLINT(readability-identifier-naming) - : std::integral_constant {}; - -template -struct conjunction // NOLINT(readability-identifier-naming) - : std::true_type {}; -template struct conjunction : B1 {}; -template -struct conjunction - : std::conditional, B1>::type {}; - -template -struct disjunction // NOLINT(readability-identifier-naming) - : std::false_type {}; -template struct disjunction : B1 {}; -template -struct disjunction - : std::conditional>::type {}; - -struct in_place_t // NOLINT(readability-identifier-naming) -{ - explicit in_place_t() = default; -}; -/// \warning This must not be odr-used, as it cannot be made \c inline in C++14. -constexpr in_place_t in_place; // NOLINT(readability-identifier-naming) - -template -struct in_place_type_t // NOLINT(readability-identifier-naming) -{ - explicit in_place_type_t() = default; -}; - -template -struct in_place_index_t // NOLINT(readability-identifier-naming) -{ - explicit in_place_index_t() = default; -}; - //===----------------------------------------------------------------------===// // Features from C++20 //===----------------------------------------------------------------------===// @@ -78,6 +36,30 @@ template using remove_cvref_t // NOLINT(readability-identifier-naming) = typename wpi::remove_cvref::type; +//===----------------------------------------------------------------------===// +// Features from C++23 +//===----------------------------------------------------------------------===// + +// TODO: Remove this in favor of std::optional::transform once we switch to +// C++23. +template +auto transformOptional(const std::optional &O, const Function &F) + -> std::optional { + if (O) + return F(*O); + return std::nullopt; +} + +// TODO: Remove this in favor of std::optional::transform once we switch to +// C++23. +template +auto transformOptional(std::optional &&O, const Function &F) + -> std::optional { + if (O) + return F(*std::move(O)); + return std::nullopt; +} + } // namespace wpi #endif // WPIUTIL_WPI_STLFORWARDCOMPAT_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallPtrSet.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallPtrSet.h index 1ada1e0f46..824518d61b 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallPtrSet.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallPtrSet.h @@ -89,7 +89,7 @@ public: SmallPtrSetImplBase &operator=(const SmallPtrSetImplBase &) = delete; - LLVM_NODISCARD bool empty() const { return size() == 0; } + [[nodiscard]] bool empty() const { return size() == 0; } size_type size() const { return NumNonEmpty - NumTombstones; } void clear() { diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallSet.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallSet.h index 7b1b283048..2679642965 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallSet.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallSet.h @@ -140,6 +140,7 @@ class SmallSet { std::set Set; using VIterator = typename SmallVector::const_iterator; + using SIterator = typename std::set::const_iterator; using mutable_iterator = typename SmallVector::iterator; // In small mode SmallPtrSet uses linear search for the elements, so it is @@ -153,9 +154,7 @@ public: SmallSet() = default; - LLVM_NODISCARD bool empty() const { - return Vector.empty() && Set.empty(); - } + [[nodiscard]] bool empty() const { return Vector.empty() && Set.empty(); } size_type size() const { return isSmall() ? Vector.size() : Set.size(); @@ -172,22 +171,21 @@ public: } /// insert - Insert an element into the set if it isn't already there. - /// Returns true if the element is inserted (it was not in the set before). - /// The first value of the returned pair is unused and provided for - /// partial compatibility with the standard library self-associative container - /// concept. - // FIXME: Add iterators that abstract over the small and large form, and then - // return those here. - std::pair insert(const T &V) { - if (!isSmall()) - return std::make_pair(std::nullopt, Set.insert(V).second); + /// Returns a pair. The first value of it is an iterator to the inserted + /// element or the existing element in the set. The second value is true + /// if the element is inserted (it was not in the set before). + std::pair insert(const T &V) { + if (!isSmall()) { + auto [I, Inserted] = Set.insert(V); + return std::make_pair(const_iterator(I), Inserted); + } VIterator I = vfind(V); if (I != Vector.end()) // Don't reinsert if it already exists. - return std::make_pair(std::nullopt, false); + return std::make_pair(const_iterator(I), false); if (Vector.size() < N) { Vector.push_back(V); - return std::make_pair(std::nullopt, true); + return std::make_pair(const_iterator(std::prev(Vector.end())), true); } // Otherwise, grow from vector to set. @@ -195,8 +193,7 @@ public: Set.insert(Vector.back()); Vector.pop_back(); } - Set.insert(V); - return std::make_pair(std::nullopt, true); + return std::make_pair(const_iterator(Set.insert(V).first), true); } template diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallVector.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallVector.h index eaeb79dce6..8f7af89b0d 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallVector.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SmallVector.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,11 @@ namespace wpi { template class iterator_range; +template +using EnableIfConvertibleToInputIterator = std::enable_if_t::iterator_category, + std::input_iterator_tag>::value>; + /// This is all the stuff common to all SmallVectors. /// /// The template parameter specifies the type which should be used to hold the @@ -67,18 +73,32 @@ 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(size_t MinSize, size_t TSize, size_t &NewCapacity); + 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); + /// If vector was first created with capacity 0, getFirstEl() points to the + /// memory right after, an area unallocated. If a subsequent allocation, + /// that grows the vector, happens to return the same pointer as getFirstEl(), + /// get a new allocation, otherwise isSmall() will falsely return that no + /// allocation was done (true) and the memory will not be freed in the + /// destructor. If a VSize is given (vector size), also copy that many + /// elements to the new allocation - used if realloca fails to increase + /// space, and happens to allocate precisely at BeginX. + /// This is unlikely to be called often, but resolves a memory leak when the + /// situation does occur. + void *replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity, + size_t VSize = 0); + public: size_t size() const { return Size; } size_t capacity() const { return Capacity; } - LLVM_NODISCARD bool empty() const { return !Size; } + [[nodiscard]] bool empty() const { return !Size; } protected: /// Set the array size to \p N, which the current array must have enough @@ -99,13 +119,14 @@ template struct SmallVectorAlignmentAndSize { }; /// This is the part of SmallVectorTemplateBase which does not depend on whether -/// the type T is a POD. The extra dummy template argument is used by ArrayRef +/// the type T is a POD. The extra dummy template argument is used by std::span /// to avoid unnecessarily requiring T to be complete. template class SmallVectorTemplateCommon : public SmallVectorBase { using Base = SmallVectorBase; +protected: /// Find the address of the first element. For this pointer math to be valid /// with small-size of 0 for T with lots of alignment, it's important that /// SmallVectorStorage is properly-aligned even for small-size of 0. @@ -116,7 +137,6 @@ class SmallVectorTemplateCommon } // Space after 'FirstEl' is clobbered, do not add any instance vars after it. -protected: SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {} void grow_pod(size_t MinSize, size_t TSize) { @@ -331,8 +351,7 @@ protected: /// constructing elements as needed. template static void uninitialized_move(It1 I, It1 E, It2 Dest) { - std::uninitialized_copy(std::make_move_iterator(I), - std::make_move_iterator(E), Dest); + std::uninitialized_move(I, E, Dest); } /// Copy the range [I, E) onto the uninitialized memory starting with "Dest", @@ -349,11 +368,7 @@ protected: /// Create a new allocation big enough for \p MinSize and pass back its size /// in \p NewCapacity. This is the first section of \a grow(). - T *mallocForGrow(size_t MinSize, size_t &NewCapacity) { - return static_cast( - SmallVectorBase::mallocForGrow( - MinSize, sizeof(T), NewCapacity)); - } + T *mallocForGrow(size_t MinSize, size_t &NewCapacity); /// Move existing elements over to the new allocation \p NewElts, the middle /// section of \a grow(). @@ -427,6 +442,14 @@ void SmallVectorTemplateBase::grow(size_t MinSize) { takeAllocationForGrow(NewElts, NewCapacity); } +template +T *SmallVectorTemplateBase::mallocForGrow( + size_t MinSize, size_t &NewCapacity) { + return static_cast( + SmallVectorBase::mallocForGrow( + this->getFirstEl(), MinSize, sizeof(T), NewCapacity)); +} + // Define this out-of-line to dissuade the C++ compiler from inlining it. template void SmallVectorTemplateBase::moveElementsForGrow( @@ -465,8 +488,7 @@ protected: /// Either const T& or T, depending on whether it's cheap enough to take /// parameters by value. - using ValueParamT = - typename std::conditional::type; + using ValueParamT = std::conditional_t; SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} @@ -494,8 +516,8 @@ protected: template static void uninitialized_copy( T1 *I, T1 *E, T2 *Dest, - std::enable_if_t::type, - T2>::value> * = nullptr) { + std::enable_if_t, T2>::value> * = + nullptr) { // Use memcpy for PODs iterated by pointers (which includes SmallVector // iterators): std::uninitialized_copy optimizes to memmove, but we can // use memcpy here. Note that I and E are iterators and thus might be @@ -654,7 +676,7 @@ public: truncate(this->size() - NumItems); } - LLVM_NODISCARD T pop_back_val() { + [[nodiscard]] T pop_back_val() { T Result = ::std::move(this->back()); this->pop_back(); return Result; @@ -663,11 +685,8 @@ public: void swap(SmallVectorImpl &RHS); /// Add the specified range to the end of the SmallVector. - template ::iterator_category, - std::input_iterator_tag>::value>> - void append(in_iter in_start, in_iter in_end) { + template > + void append(ItTy in_start, ItTy in_end) { this->assertSafeToAddRange(in_start, in_end); size_type NumInputs = std::distance(in_start, in_end); this->reserve(this->size() + NumInputs); @@ -707,11 +726,8 @@ public: // FIXME: Consider assigning over existing elements, rather than clearing & // re-initializing them - for all assign(...) variants. - template ::iterator_category, - std::input_iterator_tag>::value>> - void assign(in_iter in_start, in_iter in_end) { + template > + void assign(ItTy in_start, ItTy in_end) { this->assertSafeToReferenceAfterClear(in_start, in_end); clear(); append(in_start, in_end); @@ -861,10 +877,7 @@ public: return I; } - template ::iterator_category, - std::input_iterator_tag>::value>> + template > iterator insert(iterator I, ItTy From, ItTy To) { // Convert iterator to elt# to avoid invalidating iterator when we reserve() size_t InsertElt = I - this->begin(); @@ -952,6 +965,9 @@ public: return std::lexicographical_compare(this->begin(), this->end(), RHS.begin(), RHS.end()); } + bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; } + bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); } + bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); } }; template @@ -1197,10 +1213,7 @@ public: this->assign(Size, Value); } - template ::iterator_category, - std::input_iterator_tag>::value>> + template > SmallVector(ItTy S, ItTy E) : SmallVectorImpl(N) { this->append(S, E); } @@ -1212,7 +1225,13 @@ public: } SmallVector(std::initializer_list IL) : SmallVectorImpl(N) { - this->assign(IL); + this->append(IL); + } + + template ::value>> + explicit SmallVector(std::span A) : SmallVectorImpl(N) { + this->append(A.begin(), A.end()); } SmallVector(const SmallVector &RHS) : SmallVectorImpl(N) { @@ -1271,8 +1290,8 @@ inline size_t capacity_in_bytes(const SmallVector &X) { template using ValueTypeFromRangeType = - typename std::remove_const()))>::type>::type; + std::remove_const_t()))>>; /// Given a range of type R, iterate the entire range and return a /// SmallVector with elements of the vector. This is useful, for example, @@ -1282,10 +1301,16 @@ SmallVector, Size> to_vector(R &&Range) { return {std::begin(Range), std::end(Range)}; } template -SmallVector, - CalculateSmallVectorDefaultInlinedElements< - ValueTypeFromRangeType>::value> -to_vector(R &&Range) { +SmallVector> to_vector(R &&Range) { + return {std::begin(Range), std::end(Range)}; +} + +template +SmallVector to_vector_of(R &&Range) { + return {std::begin(Range), std::end(Range)}; +} + +template SmallVector to_vector_of(R &&Range) { return {std::begin(Range), std::end(Range)}; } diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMap.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMap.h index c7da670993..8b1d66a8dc 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMap.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMap.h @@ -111,8 +111,9 @@ public: /// funky memory allocation and hashing things to make it extremely efficient, /// storing the string data *after* the value in the map. template -class StringMap : public StringMapImpl { - AllocatorTy Allocator; +class StringMap : public StringMapImpl, + private detail::AllocatorHolder { + using AllocTy = detail::AllocatorHolder; public: using MapEntryTy = StringMapEntry; @@ -123,12 +124,11 @@ public: : StringMapImpl(InitialSize, static_cast(sizeof(MapEntryTy))) {} explicit StringMap(AllocatorTy A) - : StringMapImpl(static_cast(sizeof(MapEntryTy))), Allocator(A) { - } + : StringMapImpl(static_cast(sizeof(MapEntryTy))), AllocTy(A) {} StringMap(unsigned InitialSize, AllocatorTy A) : StringMapImpl(InitialSize, static_cast(sizeof(MapEntryTy))), - Allocator(A) {} + AllocTy(A) {} StringMap(std::initializer_list> List) : StringMapImpl(List.size(), static_cast(sizeof(MapEntryTy))) { @@ -136,11 +136,11 @@ public: } StringMap(StringMap &&RHS) - : StringMapImpl(std::move(RHS)), Allocator(std::move(RHS.Allocator)) {} + : StringMapImpl(std::move(RHS)), AllocTy(std::move(RHS.getAllocator())) {} StringMap(const StringMap &RHS) : StringMapImpl(static_cast(sizeof(MapEntryTy))), - Allocator(RHS.Allocator) { + AllocTy(RHS.getAllocator()) { if (RHS.empty()) return; @@ -159,8 +159,8 @@ public: continue; } - TheTable[I] = MapEntryTy::Create( - static_cast(Bucket)->getKey(), Allocator, + TheTable[I] = MapEntryTy::create( + static_cast(Bucket)->getKey(), getAllocator(), static_cast(Bucket)->getValue()); HashTable[I] = RHSHashTable[I]; } @@ -175,7 +175,7 @@ public: StringMap &operator=(StringMap RHS) { StringMapImpl::swap(RHS); - std::swap(Allocator, RHS.Allocator); + std::swap(getAllocator(), RHS.getAllocator()); return *this; } @@ -187,15 +187,14 @@ public: for (unsigned I = 0, E = NumBuckets; I != E; ++I) { StringMapEntryBase *Bucket = TheTable[I]; if (Bucket && Bucket != getTombstoneVal()) { - static_cast(Bucket)->Destroy(Allocator); + static_cast(Bucket)->Destroy(getAllocator()); } } } free(TheTable); } - AllocatorTy &getAllocator() { return Allocator; } - const AllocatorTy &getAllocator() const { return Allocator; } + using AllocTy::getAllocator; using key_type = const char *; using mapped_type = ValueTy; @@ -331,7 +330,7 @@ public: /// if and only if the insertion takes place, and the iterator component of /// the pair points to the element with key equivalent to the key of the pair. template - std::pair try_emplace(std::string_view Key, ArgsTy &&... Args) { + std::pair try_emplace(std::string_view Key, ArgsTy &&...Args) { unsigned BucketNo = LookupBucketFor(Key); StringMapEntryBase *&Bucket = TheTable[BucketNo]; if (Bucket && Bucket != getTombstoneVal()) @@ -340,7 +339,8 @@ public: if (Bucket == getTombstoneVal()) --NumTombstones; - Bucket = MapEntryTy::Create(Key, Allocator, std::forward(Args)...); + Bucket = + MapEntryTy::create(Key, getAllocator(), std::forward(Args)...); ++NumItems; assert(NumItems + NumTombstones <= NumBuckets); @@ -358,7 +358,7 @@ public: for (unsigned I = 0, E = NumBuckets; I != E; ++I) { StringMapEntryBase *&Bucket = TheTable[I]; if (Bucket && Bucket != getTombstoneVal()) { - static_cast(Bucket)->Destroy(Allocator); + static_cast(Bucket)->Destroy(getAllocator()); } Bucket = nullptr; } @@ -374,7 +374,7 @@ public: void erase(iterator I) { MapEntryTy &V = *I; remove(&V); - V.Destroy(Allocator); + V.Destroy(getAllocator()); } bool erase(std::string_view Key) { diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMapEntry.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMapEntry.h index 2b33aa6ad7..88de972219 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMapEntry.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/StringMapEntry.h @@ -77,7 +77,7 @@ public: explicit StringMapEntryStorage(size_t keyLength) : StringMapEntryBase(keyLength), second() {} template - StringMapEntryStorage(size_t keyLength, InitTy &&... initVals) + StringMapEntryStorage(size_t keyLength, InitTy &&...initVals) : StringMapEntryBase(keyLength), second(std::forward(initVals)...) {} StringMapEntryStorage(StringMapEntryStorage &e) = delete; @@ -88,9 +88,11 @@ public: void setValue(const ValueTy &V) { second = V; } }; -template <> class StringMapEntryStorage : public StringMapEntryBase { +template <> +class StringMapEntryStorage : public StringMapEntryBase { public: - explicit StringMapEntryStorage(size_t keyLength, std::nullopt_t = std::nullopt) + explicit StringMapEntryStorage(size_t keyLength, + std::nullopt_t = std::nullopt) : StringMapEntryBase(keyLength) {} StringMapEntryStorage(StringMapEntryStorage &entry) = delete; @@ -105,6 +107,8 @@ class StringMapEntry final : public StringMapEntryStorage { public: using StringMapEntryStorage::StringMapEntryStorage; + using ValueType = ValueTy; + std::string_view getKey() const { return std::string_view(getKeyData(), this->getKeyLength()); } @@ -123,7 +127,7 @@ public: /// Create a StringMapEntry for the specified key construct the value using /// \p InitiVals. template - static StringMapEntry *Create(std::string_view key, AllocatorTy &allocator, + static StringMapEntry *create(std::string_view key, AllocatorTy &allocator, InitTy &&... initVals) { return new (StringMapEntryBase::allocateWithKey( sizeof(StringMapEntry), alignof(StringMapEntry), key, allocator)) @@ -148,6 +152,26 @@ public: } }; +// Allow structured bindings on StringMapEntry. +template +decltype(auto) get(const StringMapEntry &E) { + static_assert(Index < 2); + if constexpr (Index == 0) + return E.first(); + else + return E.second; +} + } // end namespace wpi +namespace std { +template +struct tuple_size> + : std::integral_constant {}; + +template +struct tuple_element> + : std::conditional {}; +} // namespace std + #endif // WPIUTIL_WPI_STRINGMAPENTRY_H diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SwapByteOrder.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SwapByteOrder.h index ab2791a25d..47706cf6ab 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SwapByteOrder.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/SwapByteOrder.h @@ -14,12 +14,10 @@ #ifndef WPIUTIL_WPI_SWAPBYTEORDER_H #define WPIUTIL_WPI_SWAPBYTEORDER_H +#include "wpi/bit.h" #include #include #include -#if defined(_MSC_VER) && !defined(_DEBUG) -#include -#endif #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ defined(__Fuchsia__) || defined(__EMSCRIPTEN__) @@ -50,45 +48,13 @@ namespace wpi { /// ByteSwap_16 - This function returns a byte-swapped representation of /// the 16-bit argument. -inline uint16_t ByteSwap_16(uint16_t value) { -#if defined(_MSC_VER) && !defined(_DEBUG) - // The DLL version of the runtime lacks these functions (bug!?), but in a - // release build they're replaced with BSWAP instructions anyway. - return _byteswap_ushort(value); -#else - uint16_t Hi = value << 8; - uint16_t Lo = value >> 8; - return Hi | Lo; -#endif -} +inline uint16_t ByteSwap_16(uint16_t value) { return wpi::byteswap(value); } /// This function returns a byte-swapped representation of the 32-bit argument. -inline uint32_t ByteSwap_32(uint32_t value) { -#if defined(__llvm__) || (defined(__GNUC__) && !defined(__ICC)) - return __builtin_bswap32(value); -#elif defined(_MSC_VER) && !defined(_DEBUG) - return _byteswap_ulong(value); -#else - uint32_t Byte0 = value & 0x000000FF; - uint32_t Byte1 = value & 0x0000FF00; - uint32_t Byte2 = value & 0x00FF0000; - uint32_t Byte3 = value & 0xFF000000; - return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24); -#endif -} +inline uint32_t ByteSwap_32(uint32_t value) { return wpi::byteswap(value); } /// This function returns a byte-swapped representation of the 64-bit argument. -inline uint64_t ByteSwap_64(uint64_t value) { -#if defined(__llvm__) || (defined(__GNUC__) && !defined(__ICC)) - return __builtin_bswap64(value); -#elif defined(_MSC_VER) && !defined(_DEBUG) - return _byteswap_uint64(value); -#else - uint64_t Hi = ByteSwap_32(uint32_t(value)); - uint32_t Lo = ByteSwap_32(uint32_t(value >> 32)); - return (Hi << 32) | Lo; -#endif -} +inline uint64_t ByteSwap_64(uint64_t value) { return wpi::byteswap(value); } namespace sys { @@ -100,33 +66,21 @@ constexpr bool IsBigEndianHost = false; static const bool IsLittleEndianHost = !IsBigEndianHost; -inline unsigned char getSwappedBytes(unsigned char C) { return C; } -inline signed char getSwappedBytes(signed char C) { return C; } -inline char getSwappedBytes(char C) { return C; } +inline unsigned char getSwappedBytes(unsigned char C) { return wpi::byteswap(C); } +inline signed char getSwappedBytes( signed char C) { return wpi::byteswap(C); } +inline char getSwappedBytes( char C) { return wpi::byteswap(C); } -inline unsigned short getSwappedBytes(unsigned short C) { return ByteSwap_16(C); } -inline signed short getSwappedBytes( signed short C) { return ByteSwap_16(C); } +inline unsigned short getSwappedBytes(unsigned short C) { return wpi::byteswap(C); } +inline signed short getSwappedBytes( signed short C) { return wpi::byteswap(C); } -inline unsigned int getSwappedBytes(unsigned int C) { return ByteSwap_32(C); } -inline signed int getSwappedBytes( signed int C) { return ByteSwap_32(C); } +inline unsigned int getSwappedBytes(unsigned int C) { return wpi::byteswap(C); } +inline signed int getSwappedBytes( signed int C) { return wpi::byteswap(C); } -inline unsigned long getSwappedBytes(unsigned long C) { - // Handle LLP64 and LP64 platforms. - return sizeof(long) == sizeof(int) ? ByteSwap_32((uint32_t)C) - : ByteSwap_64((uint64_t)C); -} -inline signed long getSwappedBytes(signed long C) { - // Handle LLP64 and LP64 platforms. - return sizeof(long) == sizeof(int) ? ByteSwap_32((uint32_t)C) - : ByteSwap_64((uint64_t)C); -} +inline unsigned long getSwappedBytes(unsigned long C) { return wpi::byteswap(C); } +inline signed long getSwappedBytes( signed long C) { return wpi::byteswap(C); } -inline unsigned long long getSwappedBytes(unsigned long long C) { - return ByteSwap_64(C); -} -inline signed long long getSwappedBytes(signed long long C) { - return ByteSwap_64(C); -} +inline unsigned long long getSwappedBytes(unsigned long long C) { return wpi::byteswap(C); } +inline signed long long getSwappedBytes( signed long long C) { return wpi::byteswap(C); } inline float getSwappedBytes(float C) { union { @@ -134,7 +88,7 @@ inline float getSwappedBytes(float C) { float f; } in, out; in.f = C; - out.i = ByteSwap_32(in.i); + out.i = wpi::byteswap(in.i); return out.f; } @@ -144,14 +98,14 @@ inline double getSwappedBytes(double C) { double d; } in, out; in.d = C; - out.i = ByteSwap_64(in.i); + out.i = wpi::byteswap(in.i); return out.d; } template inline std::enable_if_t::value, T> getSwappedBytes(T C) { return static_cast( - getSwappedBytes(static_cast>(C))); + wpi::byteswap(static_cast>(C))); } template diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/VersionTuple.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/VersionTuple.h index c08ff372d0..02f24dd7c4 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/VersionTuple.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/VersionTuple.h @@ -16,11 +16,14 @@ #include "wpi/DenseMapInfo.h" #include "wpi/Hashing.h" +#include "wpi/Endian.h" #include #include #include namespace wpi { +template +class HashBuilderImpl; class raw_ostream; /// Represents a version number in the form major[.minor[.subminor[.build]]]. @@ -37,24 +40,25 @@ class VersionTuple { unsigned HasBuild : 1; public: - VersionTuple() + constexpr VersionTuple() : Major(0), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major) + explicit constexpr VersionTuple(unsigned Major) : Major(Major), Minor(0), HasMinor(false), Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major, unsigned Minor) + explicit constexpr VersionTuple(unsigned Major, unsigned Minor) : Major(Major), Minor(Minor), HasMinor(true), Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor) + explicit constexpr VersionTuple(unsigned Major, unsigned Minor, + unsigned Subminor) : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0), HasBuild(false) {} - explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, - unsigned Build) + explicit constexpr VersionTuple(unsigned Major, unsigned Minor, + unsigned Subminor, unsigned Build) : Major(Major), Minor(Minor), HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build), HasBuild(true) {} @@ -95,6 +99,12 @@ public: return *this; } + /// 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); + } + /// Return a version tuple that contains only components that are non-zero. VersionTuple normalize() const { VersionTuple Result = *this; diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/bit.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/bit.h new file mode 100644 index 0000000000..fce6d85201 --- /dev/null +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/bit.h @@ -0,0 +1,99 @@ +//===-- llvm/ADT/bit.h - C++20 ----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements the C++20 header. +/// +//===----------------------------------------------------------------------===// + +#ifndef WPIUTIL_WPI_BIT_H +#define WPIUTIL_WPI_BIT_H + +#include "wpi/Compiler.h" +#include +#include +#include + +#if !__has_builtin(__builtin_bit_cast) +#include +#endif + +#if defined(_MSC_VER) && !defined(_DEBUG) +#include // for _byteswap_{ushort,ulong,uint64} +#endif + +namespace wpi { + +// This implementation of bit_cast is different from the C++20 one in two ways: +// - It isn't constexpr because that requires compiler support. +// - It requires trivially-constructible To, to avoid UB in the implementation. +template < + typename To, typename From, + typename = std::enable_if_t, + typename = std::enable_if_t::value>, + typename = std::enable_if_t::value>, + typename = std::enable_if_t::value>> +[[nodiscard]] inline To bit_cast(const From &from) noexcept { +#if __has_builtin(__builtin_bit_cast) + return __builtin_bit_cast(To, from); +#else + To to; + std::memcpy(&to, &from, sizeof(To)); + return to; +#endif +} + +/// Reverses the bytes in the given integer value V. +template >> +[[nodiscard]] constexpr T byteswap(T V) noexcept { + if constexpr (sizeof(T) == 1) { + return V; + } else if constexpr (sizeof(T) == 2) { + uint16_t UV = V; +#if defined(_MSC_VER) && !defined(_DEBUG) + // The DLL version of the runtime lacks these functions (bug!?), but in a + // release build they're replaced with BSWAP instructions anyway. + return _byteswap_ushort(UV); +#else + uint16_t Hi = UV << 8; + uint16_t Lo = UV >> 8; + return Hi | Lo; +#endif + } else if constexpr (sizeof(T) == 4) { + uint32_t UV = V; +#if __has_builtin(__builtin_bswap32) + return __builtin_bswap32(UV); +#elif defined(_MSC_VER) && !defined(_DEBUG) + return _byteswap_ulong(UV); +#else + uint32_t Byte0 = UV & 0x000000FF; + uint32_t Byte1 = UV & 0x0000FF00; + uint32_t Byte2 = UV & 0x00FF0000; + uint32_t Byte3 = UV & 0xFF000000; + return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24); +#endif + } else if constexpr (sizeof(T) == 8) { + uint64_t UV = V; +#if __has_builtin(__builtin_bswap64) + return __builtin_bswap64(UV); +#elif defined(_MSC_VER) && !defined(_DEBUG) + return _byteswap_uint64(UV); +#else + uint64_t Hi = wpi::byteswap(UV); + uint32_t Lo = wpi::byteswap(UV >> 32); + return (Hi << 32) | Lo; +#endif + } else { + static_assert(!sizeof(T *), "Don't know how to handle the given type."); + return 0; + } +} + +} // namespace wpi + +#endif diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/raw_ostream.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/raw_ostream.h index 350262bdfc..49fb44d873 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/raw_ostream.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/raw_ostream.h @@ -14,15 +14,14 @@ #define WPIUTIL_WPI_RAW_OSTREAM_H #include "wpi/SmallVector.h" -#include #include #include #include #include +#include +#include #include -#if __cplusplus > 201402L #include -#endif #include #include #include @@ -229,6 +228,20 @@ public: return *this; } +#if defined(__cpp_char8_t) + // When using `char8_t *` integers or pointers are written to the ostream + // instead of UTF-8 code as one might expect. This might lead to unexpected + // behavior, especially as `u8""` literals are of type `char8_t*` instead of + // type `char_t*` from C++20 onwards. Thus we disallow using them with + // raw_ostreams. + // If you have u8"" literals to stream, you can rewrite them as ordinary + // literals with escape sequences + // e.g. replace `u8"\u00a0"` by `"\xc2\xa0"` + // or use `reinterpret_cast`: + // e.g. replace `u8"\u00a0"` by `reinterpret_cast(u8"\u00a0")` + raw_ostream &operator<<(const char8_t *Str) = delete; +#endif + raw_ostream &operator<<(const char *Str) { // Inline fast path, particularly for constant strings where a sufficiently // smart compiler will simplify strlen. @@ -734,7 +747,7 @@ class buffer_ostream : public raw_svector_ostream { raw_ostream &OS; SmallVector Buffer; - virtual void anchor() override; + void anchor() override; public: buffer_ostream(raw_ostream &OS) : raw_svector_ostream(Buffer), OS(OS) {} @@ -745,7 +758,7 @@ class buffer_unique_ostream : public raw_svector_ostream { std::unique_ptr OS; SmallVector Buffer; - virtual void anchor() override; + void anchor() override; public: buffer_unique_ostream(std::unique_ptr OS) diff --git a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/type_traits.h b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/type_traits.h index 53e18d342e..7fe78660b6 100644 --- a/wpiutil/src/main/native/thirdparty/llvm/include/wpi/type_traits.h +++ b/wpiutil/src/main/native/thirdparty/llvm/include/wpi/type_traits.h @@ -98,7 +98,6 @@ using is_trivially_move_constructible = std::is_trivially_move_constructible; template using is_trivially_copy_constructible = std::is_trivially_copy_constructible; - } // end namespace wpi #endif // WPIUTIL_WPI_TYPE_TRAITS_H diff --git a/wpiutil/src/test/native/cpp/llvm/ConvertUTFTest.cpp b/wpiutil/src/test/native/cpp/llvm/ConvertUTFTest.cpp index 762682e4de..3ea7ab0ec9 100644 --- a/wpiutil/src/test/native/cpp/llvm/ConvertUTFTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/ConvertUTFTest.cpp @@ -26,6 +26,18 @@ TEST(ConvertUTFTest, ConvertUTF16LittleEndianToUTF8String) { EXPECT_EQ(Expected, std::string{Result}); } +TEST(ConvertUTFTest, ConvertUTF32LittleEndianToUTF8String) { + // Src is the look of disapproval. + alignas(UTF32) static const char Src[] = + "\xFF\xFE\x00\x00\xA0\x0C\x00\x00\x5F\x00\x00\x00\xA0\x0C\x00\x00"; + std::span Ref(Src, sizeof(Src) - 1); + std::string Result; + bool Success = convertUTF32ToUTF8String(Ref, Result); + EXPECT_TRUE(Success); + std::string Expected("\xE0\xB2\xA0_\xE0\xB2\xA0"); + EXPECT_EQ(Expected, Result); +} + TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) { // Src is the look of disapproval. alignas(UTF16) static const char Src[] = "\xfe\xff\x0c\xa0\x00_\x0c\xa0"; @@ -37,6 +49,18 @@ TEST(ConvertUTFTest, ConvertUTF16BigEndianToUTF8String) { EXPECT_EQ(Expected, std::string{Result}); } +TEST(ConvertUTFTest, ConvertUTF32BigEndianToUTF8String) { + // Src is the look of disapproval. + alignas(UTF32) static const char Src[] = + "\x00\x00\xFE\xFF\x00\x00\x0C\xA0\x00\x00\x00\x5F\x00\x00\x0C\xA0"; + std::span Ref(Src, sizeof(Src) - 1); + std::string Result; + bool Success = convertUTF32ToUTF8String(Ref, Result); + EXPECT_TRUE(Success); + std::string Expected("\xE0\xB2\xA0_\xE0\xB2\xA0"); + EXPECT_EQ(Expected, Result); +} + TEST(ConvertUTFTest, ConvertUTF8ToUTF16String) { // Src is the look of disapproval. static const char Src[] = "\xe0\xb2\xa0_\xe0\xb2\xa0"; @@ -58,7 +82,8 @@ TEST(ConvertUTFTest, OddLengthInput) { TEST(ConvertUTFTest, Empty) { SmallString<20> Result; - bool Success = convertUTF16ToUTF8String(std::span(), Result); + bool Success = + convertUTF16ToUTF8String(std::span(), Result); EXPECT_TRUE(Success); EXPECT_TRUE(std::string{Result}.empty()); } diff --git a/wpiutil/src/test/native/cpp/llvm/DenseMapTest.cpp b/wpiutil/src/test/native/cpp/llvm/DenseMapTest.cpp index 68c37c0f04..fa339d1851 100644 --- a/wpiutil/src/test/native/cpp/llvm/DenseMapTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/DenseMapTest.cpp @@ -11,9 +11,13 @@ #endif #include "wpi/DenseMap.h" +#include "wpi/DenseMapInfo.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include #include +#include +#include using namespace wpi; @@ -446,6 +450,7 @@ TEST(DenseMapCustomTest, InitFromIterator) { std::vector> Values; // The size is a random value greater than 64 (hardcoded DenseMap min init) const int Count = 65; + Values.reserve(Count); for (int i = 0; i < Count; i++) Values.emplace_back(i, CountCopyAndMove()); @@ -586,6 +591,15 @@ TEST(DenseMapCustomTest, LargeSmallDenseMapCompaction) { EXPECT_TRUE(map.find(0) == map.end()); } +TEST(DenseMapCustomTest, SmallDenseMapWithNumBucketsNonPowerOf2) { + // Is not power of 2. + const unsigned NumInitBuckets = 33; + // Power of 2 less then NumInitBuckets. + constexpr unsigned InlineBuckets = 4; + // Constructor should not trigger assert. + SmallDenseMap map(NumInitBuckets); +} + TEST(DenseMapCustomTest, TryEmplaceTest) { DenseMap> Map; std::unique_ptr P(new int(2)); @@ -648,7 +662,7 @@ struct B : public A { namespace wpi { template -struct DenseMapInfo::value>> { +struct DenseMapInfo>> { static inline T getEmptyKey() { return {static_cast(~0)}; } static inline T getTombstoneKey() { return {static_cast(~0U - 1)}; } static unsigned getHashValue(const T &Val) { return Val.value; } @@ -677,4 +691,18 @@ TEST(DenseMapCustomTest, SFINAEMapInfo) { EXPECT_EQ(Map.find(Keys[1]), Map.end()); EXPECT_EQ(Map.find(Keys[2]), Map.end()); } + +TEST(DenseMapCustomTest, VariantSupport) { + using variant = std::variant; + DenseMap Map; + variant Keys[] = { + variant(std::in_place_index<0>, 1), + variant(std::in_place_index<1>, 1), + }; + Map.try_emplace(Keys[0], 0); + Map.try_emplace(Keys[1], 1); + EXPECT_THAT(Map, testing::SizeIs(2)); + EXPECT_NE(DenseMapInfo::getHashValue(Keys[0]), + DenseMapInfo::getHashValue(Keys[1])); +} } // namespace diff --git a/wpiutil/src/test/native/cpp/llvm/MathExtrasTest.cpp b/wpiutil/src/test/native/cpp/llvm/MathExtrasTest.cpp index f392887386..0026711d98 100644 --- a/wpiutil/src/test/native/cpp/llvm/MathExtrasTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/MathExtrasTest.cpp @@ -175,6 +175,44 @@ TEST(MathExtras, reverseBits) { EXPECT_EQ(0x5400000000000000ULL, reverseBits(NZ64)); } +TEST(MathExtras, isShiftedMask_32) { + EXPECT_FALSE(isShiftedMask_32(0x01010101)); + EXPECT_TRUE(isShiftedMask_32(0xf0000000)); + EXPECT_TRUE(isShiftedMask_32(0xffff0000)); + EXPECT_TRUE(isShiftedMask_32(0xff << 1)); + + unsigned MaskIdx, MaskLen; + EXPECT_FALSE(isShiftedMask_32(0x01010101, MaskIdx, MaskLen)); + EXPECT_TRUE(isShiftedMask_32(0xf0000000, MaskIdx, MaskLen)); + EXPECT_EQ(28, (int)MaskIdx); + EXPECT_EQ(4, (int)MaskLen); + EXPECT_TRUE(isShiftedMask_32(0xffff0000, MaskIdx, MaskLen)); + EXPECT_EQ(16, (int)MaskIdx); + EXPECT_EQ(16, (int)MaskLen); + EXPECT_TRUE(isShiftedMask_32(0xff << 1, MaskIdx, MaskLen)); + EXPECT_EQ(1, (int)MaskIdx); + EXPECT_EQ(8, (int)MaskLen); +} + +TEST(MathExtras, isShiftedMask_64) { + EXPECT_FALSE(isShiftedMask_64(0x0101010101010101ull)); + EXPECT_TRUE(isShiftedMask_64(0xf000000000000000ull)); + EXPECT_TRUE(isShiftedMask_64(0xffff000000000000ull)); + EXPECT_TRUE(isShiftedMask_64(0xffull << 55)); + + unsigned MaskIdx, MaskLen; + EXPECT_FALSE(isShiftedMask_64(0x0101010101010101ull, MaskIdx, MaskLen)); + EXPECT_TRUE(isShiftedMask_64(0xf000000000000000ull, MaskIdx, MaskLen)); + EXPECT_EQ(60, (int)MaskIdx); + EXPECT_EQ(4, (int)MaskLen); + EXPECT_TRUE(isShiftedMask_64(0xffff000000000000ull, MaskIdx, MaskLen)); + EXPECT_EQ(48, (int)MaskIdx); + EXPECT_EQ(16, (int)MaskLen); + EXPECT_TRUE(isShiftedMask_64(0xffull << 55, MaskIdx, MaskLen)); + EXPECT_EQ(55, (int)MaskIdx); + EXPECT_EQ(8, (int)MaskLen); +} + TEST(MathExtras, isPowerOf2_32) { EXPECT_FALSE(isPowerOf2_32(0)); EXPECT_TRUE(isPowerOf2_32(1 << 6)); @@ -271,9 +309,7 @@ TEST(MathExtras, alignTo) { EXPECT_EQ(552u, alignTo(321, 255, 42)); } -template -void SaturatingAddTestHelper() -{ +template void SaturatingAddTestHelper() { const T Max = std::numeric_limits::max(); bool ResultOverflowed; @@ -296,6 +332,42 @@ void SaturatingAddTestHelper() EXPECT_EQ(Max, SaturatingAdd(Max, Max)); EXPECT_EQ(Max, SaturatingAdd(Max, Max, &ResultOverflowed)); EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(T(6), SaturatingAdd(T(1), T(2), T(3))); + EXPECT_EQ(T(6), SaturatingAdd(T(1), T(2), T(3), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(T(10), SaturatingAdd(T(1), T(2), T(3), T(4))); + EXPECT_EQ(T(10), SaturatingAdd(T(1), T(2), T(3), T(4), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(0))); + EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(0), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(T(0), T(0), Max)); + EXPECT_EQ(Max, SaturatingAdd(T(0), T(0), Max, &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(1))); + EXPECT_EQ(Max, SaturatingAdd(Max, T(0), T(1), &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(T(0), T(1), Max)); + EXPECT_EQ(Max, SaturatingAdd(T(0), T(1), Max, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 2), T(1))); + EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 2), T(1), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(T(1), T(1), T(Max - 2))); + EXPECT_EQ(Max, SaturatingAdd(T(1), T(1), T(Max - 2), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(Max, Max, Max)); + EXPECT_EQ(Max, SaturatingAdd(Max, Max, Max, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); } TEST(MathExtras, SaturatingAdd) { diff --git a/wpiutil/src/test/native/cpp/llvm/MoveOnly.cpp b/wpiutil/src/test/native/cpp/llvm/MoveOnly.cpp new file mode 100644 index 0000000000..efbf2445f8 --- /dev/null +++ b/wpiutil/src/test/native/cpp/llvm/MoveOnly.cpp @@ -0,0 +1,15 @@ +//===- llvm/unittest/ADT/MoveOnly.cpp - Optional unit tests ---------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "MoveOnly.h" + +using namespace wpi; + +unsigned MoveOnly::MoveConstructions = 0; +unsigned MoveOnly::Destructions = 0; +unsigned MoveOnly::MoveAssignments = 0; diff --git a/wpiutil/src/test/native/cpp/llvm/MoveOnly.h b/wpiutil/src/test/native/cpp/llvm/MoveOnly.h new file mode 100644 index 0000000000..b9923354ec --- /dev/null +++ b/wpiutil/src/test/native/cpp/llvm/MoveOnly.h @@ -0,0 +1,42 @@ +//===- llvm/unittest/ADT/MoveOnly.h - Optional unit tests -----------------===// +// +// 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 LLVM_UNITTESTS_ADT_MOVEONLY_H +#define LLVM_UNITTESTS_ADT_MOVEONLY_H + +namespace wpi { + +struct MoveOnly { + static unsigned MoveConstructions; + static unsigned Destructions; + static unsigned MoveAssignments; + int val; + explicit MoveOnly(int val) : val(val) { + } + MoveOnly(MoveOnly&& other) { + val = other.val; + ++MoveConstructions; + } + MoveOnly &operator=(MoveOnly&& other) { + val = other.val; + ++MoveAssignments; + return *this; + } + ~MoveOnly() { + ++Destructions; + } + static void ResetCounts() { + MoveConstructions = 0; + Destructions = 0; + MoveAssignments = 0; + } +}; + +} // end namespace wpi + +#endif // LLVM_UNITTESTS_ADT_MOVEONLY_H diff --git a/wpiutil/src/test/native/cpp/llvm/PointerIntPairTest.cpp b/wpiutil/src/test/native/cpp/llvm/PointerIntPairTest.cpp index fcca5b6388..a13e7bca22 100644 --- a/wpiutil/src/test/native/cpp/llvm/PointerIntPairTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/PointerIntPairTest.cpp @@ -62,7 +62,11 @@ TEST(PointerIntPairTest, GetSet) { EXPECT_EQ(&s, Pair2.getPointer()); EXPECT_EQ(E::Case3, Pair2.getInt()); - static_assert(std::is_trivially_copyable>::value, + auto [Pointer2, Int2] = Pair2; + EXPECT_EQ(Pair2.getPointer(), Pointer2); + EXPECT_EQ(Pair2.getInt(), Int2); + + static_assert(std::is_trivially_copyable_v>, "trivially copyable"); } @@ -100,10 +104,9 @@ TEST(PointerIntPairTest, ManyUnusedBits) { EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1, (int)PointerLikeTypeTraits::NumLowBitsAvailable); - static_assert( - std::is_trivially_copyable< - PointerIntPair>::value, - "trivially copyable"); + static_assert(std::is_trivially_copyable_v< + PointerIntPair>, + "trivially copyable"); } } // end anonymous namespace diff --git a/wpiutil/src/test/native/cpp/llvm/PointerUnionTest.cpp b/wpiutil/src/test/native/cpp/llvm/PointerUnionTest.cpp index 5a94a45ef9..bf02aef987 100644 --- a/wpiutil/src/test/native/cpp/llvm/PointerUnionTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/PointerUnionTest.cpp @@ -156,4 +156,137 @@ TEST_F(PointerUnionTest, GetAddrOfPtr1) { EXPECT_TRUE((void *)n.getAddrOfPtr1() == (void *)&n); } +TEST_F(PointerUnionTest, NewCastInfra) { + // test isa<> + EXPECT_TRUE(isa(a)); + EXPECT_TRUE(isa(b)); + EXPECT_TRUE(isa(c)); + EXPECT_TRUE(isa(n)); + EXPECT_TRUE(isa(i3)); + EXPECT_TRUE(isa(f3)); + EXPECT_TRUE(isa(l3)); + EXPECT_TRUE(isa(i4)); + EXPECT_TRUE(isa(f4)); + EXPECT_TRUE(isa(l4)); + EXPECT_TRUE(isa(d4)); + EXPECT_TRUE(isa(i4null)); + EXPECT_TRUE(isa(f4null)); + EXPECT_TRUE(isa(l4null)); + EXPECT_TRUE(isa(d4null)); + EXPECT_FALSE(isa(a)); + EXPECT_FALSE(isa(b)); + EXPECT_FALSE(isa(c)); + EXPECT_FALSE(isa(n)); + EXPECT_FALSE(isa(i3)); + EXPECT_FALSE(isa(i3)); + EXPECT_FALSE(isa(f3)); + EXPECT_FALSE(isa(f3)); + EXPECT_FALSE(isa(l3)); + EXPECT_FALSE(isa(l3)); + EXPECT_FALSE(isa(i4)); + EXPECT_FALSE(isa(i4)); + EXPECT_FALSE(isa(i4)); + EXPECT_FALSE(isa(f4)); + EXPECT_FALSE(isa(f4)); + EXPECT_FALSE(isa(f4)); + EXPECT_FALSE(isa(l4)); + EXPECT_FALSE(isa(l4)); + EXPECT_FALSE(isa(l4)); + EXPECT_FALSE(isa(d4)); + EXPECT_FALSE(isa(d4)); + EXPECT_FALSE(isa(d4)); + EXPECT_FALSE(isa(i4null)); + EXPECT_FALSE(isa(i4null)); + EXPECT_FALSE(isa(i4null)); + EXPECT_FALSE(isa(f4null)); + EXPECT_FALSE(isa(f4null)); + EXPECT_FALSE(isa(f4null)); + EXPECT_FALSE(isa(l4null)); + EXPECT_FALSE(isa(l4null)); + EXPECT_FALSE(isa(l4null)); + EXPECT_FALSE(isa(d4null)); + EXPECT_FALSE(isa(d4null)); + EXPECT_FALSE(isa(d4null)); + + // test cast<> + EXPECT_EQ(cast(a), &f); + EXPECT_EQ(cast(b), &i); + EXPECT_EQ(cast(c), &i); + EXPECT_EQ(cast(i3), &i); + EXPECT_EQ(cast(f3), &f); + EXPECT_EQ(cast(l3), &l); + EXPECT_EQ(cast(i4), &i); + EXPECT_EQ(cast(f4), &f); + EXPECT_EQ(cast(l4), &l); + EXPECT_EQ(cast(d4), &d); + + // test dyn_cast + EXPECT_EQ(dyn_cast(a), nullptr); + EXPECT_EQ(dyn_cast(a), &f); + EXPECT_EQ(dyn_cast(b), &i); + EXPECT_EQ(dyn_cast(b), nullptr); + EXPECT_EQ(dyn_cast(c), &i); + EXPECT_EQ(dyn_cast(c), nullptr); + EXPECT_EQ(dyn_cast_if_present(n), nullptr); + EXPECT_EQ(dyn_cast_if_present(n), nullptr); + EXPECT_EQ(dyn_cast(i3), &i); + EXPECT_EQ(dyn_cast(i3), nullptr); + EXPECT_EQ(dyn_cast(i3), nullptr); + EXPECT_EQ(dyn_cast(f3), nullptr); + EXPECT_EQ(dyn_cast(f3), &f); + EXPECT_EQ(dyn_cast(f3), nullptr); + EXPECT_EQ(dyn_cast(l3), nullptr); + EXPECT_EQ(dyn_cast(l3), nullptr); + EXPECT_EQ(dyn_cast(l3), &l); + EXPECT_EQ(dyn_cast(i4), &i); + EXPECT_EQ(dyn_cast(i4), nullptr); + EXPECT_EQ(dyn_cast(i4), nullptr); + EXPECT_EQ(dyn_cast(i4), nullptr); + EXPECT_EQ(dyn_cast(f4), nullptr); + EXPECT_EQ(dyn_cast(f4), &f); + EXPECT_EQ(dyn_cast(f4), nullptr); + EXPECT_EQ(dyn_cast(f4), nullptr); + EXPECT_EQ(dyn_cast(l4), nullptr); + EXPECT_EQ(dyn_cast(l4), nullptr); + EXPECT_EQ(dyn_cast(l4), &l); + EXPECT_EQ(dyn_cast(l4), nullptr); + EXPECT_EQ(dyn_cast(d4), nullptr); + EXPECT_EQ(dyn_cast(d4), nullptr); + EXPECT_EQ(dyn_cast(d4), nullptr); + EXPECT_EQ(dyn_cast(d4), &d); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + + // test for const + const PU4 constd4(&d); + EXPECT_TRUE(isa(constd4)); + EXPECT_FALSE(isa(constd4)); + EXPECT_EQ(cast(constd4), &d); + EXPECT_EQ(dyn_cast(constd4), nullptr); + + auto *result1 = cast(constd4); + static_assert(std::is_same_v, + "type mismatch for cast with PointerUnion"); + + PointerUnion constd2(&d); + auto *result2 = cast(constd2); + EXPECT_EQ(result2, &d); + static_assert(std::is_same_v, + "type mismatch for cast with PointerUnion"); +} + } // end anonymous namespace diff --git a/wpiutil/src/test/native/cpp/llvm/STLForwardCompatTest.cpp b/wpiutil/src/test/native/cpp/llvm/STLForwardCompatTest.cpp index 333359ef31..153305bb21 100644 --- a/wpiutil/src/test/native/cpp/llvm/STLForwardCompatTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/STLForwardCompatTest.cpp @@ -7,41 +7,11 @@ //===----------------------------------------------------------------------===// #include "wpi/STLForwardCompat.h" +#include "MoveOnly.h" #include "gtest/gtest.h" namespace { -TEST(STLForwardCompatTest, NegationTest) { - EXPECT_TRUE((wpi::negation::value)); - EXPECT_FALSE((wpi::negation::value)); -} - -struct incomplete_type; - -TEST(STLForwardCompatTest, ConjunctionTest) { - EXPECT_TRUE((wpi::conjunction<>::value)); - EXPECT_FALSE((wpi::conjunction::value)); - EXPECT_TRUE((wpi::conjunction::value)); - EXPECT_FALSE((wpi::conjunction::value)); - EXPECT_FALSE((wpi::conjunction::value)); - EXPECT_FALSE((wpi::conjunction::value)); - EXPECT_TRUE((wpi::conjunction::value)); - EXPECT_TRUE((wpi::conjunction::value)); -} - -TEST(STLForwardCompatTest, DisjunctionTest) { - EXPECT_FALSE((wpi::disjunction<>::value)); - EXPECT_FALSE((wpi::disjunction::value)); - EXPECT_TRUE((wpi::disjunction::value)); - EXPECT_TRUE((wpi::disjunction::value)); - EXPECT_TRUE((wpi::disjunction::value)); - EXPECT_TRUE((wpi::disjunction::value)); - EXPECT_TRUE((wpi::disjunction::value)); - EXPECT_TRUE((wpi::disjunction::value)); -} - template class STLForwardCompatRemoveCVRefTest : public ::testing::Test {}; @@ -75,4 +45,78 @@ TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRefT) { wpi::remove_cvref_t>::value)); } +TEST(TransformTest, TransformStd) { + std::optional A; + + std::optional B = wpi::transformOptional(A, [&](int N) { return N + 1; }); + EXPECT_FALSE(B.has_value()); + + A = 3; + std::optional C = wpi::transformOptional(A, [&](int N) { return N + 1; }); + EXPECT_TRUE(C.has_value()); + EXPECT_EQ(4, *C); +} + +TEST(TransformTest, MoveTransformStd) { + using wpi::MoveOnly; + + std::optional A; + + MoveOnly::ResetCounts(); + std::optional B = wpi::transformOptional( + std::move(A), [&](const MoveOnly &M) { return M.val + 2; }); + EXPECT_FALSE(B.has_value()); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); + + A = MoveOnly(5); + MoveOnly::ResetCounts(); + std::optional C = wpi::transformOptional( + std::move(A), [&](const MoveOnly &M) { return M.val + 2; }); + EXPECT_TRUE(C.has_value()); + EXPECT_EQ(7, *C); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); +} + +TEST(TransformTest, TransformLlvm) { + std::optional A; + + std::optional B = + wpi::transformOptional(A, [&](int N) { return N + 1; }); + EXPECT_FALSE(B.has_value()); + + A = 3; + std::optional C = + wpi::transformOptional(A, [&](int N) { return N + 1; }); + EXPECT_TRUE(C.has_value()); + EXPECT_EQ(4, *C); +} + +TEST(TransformTest, MoveTransformLlvm) { + using wpi::MoveOnly; + + std::optional A; + + MoveOnly::ResetCounts(); + std::optional B = wpi::transformOptional( + std::move(A), [&](const MoveOnly &M) { return M.val + 2; }); + EXPECT_FALSE(B.has_value()); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); + + A = MoveOnly(5); + MoveOnly::ResetCounts(); + std::optional C = wpi::transformOptional( + std::move(A), [&](const MoveOnly &M) { return M.val + 2; }); + EXPECT_TRUE(C.has_value()); + EXPECT_EQ(7, *C); + EXPECT_EQ(0u, MoveOnly::MoveConstructions); + EXPECT_EQ(0u, MoveOnly::MoveAssignments); + EXPECT_EQ(0u, MoveOnly::Destructions); +} + } // namespace diff --git a/wpiutil/src/test/native/cpp/llvm/SmallSetTest.cpp b/wpiutil/src/test/native/cpp/llvm/SmallSetTest.cpp index e245aa48dc..6f35907da9 100644 --- a/wpiutil/src/test/native/cpp/llvm/SmallSetTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/SmallSetTest.cpp @@ -12,6 +12,7 @@ #include "wpi/SmallSet.h" #include "gtest/gtest.h" +#include #include using namespace wpi; @@ -20,11 +21,17 @@ TEST(SmallSetTest, Insert) { SmallSet s1; - for (int i = 0; i < 4; i++) - s1.insert(i); + for (int i = 0; i < 4; i++) { + auto InsertResult = s1.insert(i); + EXPECT_EQ(*InsertResult.first, i); + EXPECT_EQ(InsertResult.second, true); + } - for (int i = 0; i < 4; i++) - s1.insert(i); + for (int i = 0; i < 4; i++) { + auto InsertResult = s1.insert(i); + EXPECT_EQ(*InsertResult.first, i); + EXPECT_EQ(InsertResult.second, false); + } EXPECT_EQ(4u, s1.size()); @@ -37,8 +44,17 @@ TEST(SmallSetTest, Insert) { TEST(SmallSetTest, Grow) { SmallSet s1; - for (int i = 0; i < 8; i++) - s1.insert(i); + for (int i = 0; i < 8; i++) { + auto InsertResult = s1.insert(i); + EXPECT_EQ(*InsertResult.first, i); + EXPECT_EQ(InsertResult.second, true); + } + + for (int i = 0; i < 8; i++) { + auto InsertResult = s1.insert(i); + EXPECT_EQ(*InsertResult.first, i); + EXPECT_EQ(InsertResult.second, false); + } EXPECT_EQ(8u, s1.size()); diff --git a/wpiutil/src/test/native/cpp/llvm/SmallVectorTest.cpp b/wpiutil/src/test/native/cpp/llvm/SmallVectorTest.cpp index a60e683885..d097c2b6ab 100644 --- a/wpiutil/src/test/native/cpp/llvm/SmallVectorTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/SmallVectorTest.cpp @@ -11,10 +11,11 @@ //===----------------------------------------------------------------------===// #include "wpi/SmallVector.h" -#include #include "wpi/Compiler.h" #include "gtest/gtest.h" +#include #include +#include #include #if defined(__GNUC__) @@ -127,14 +128,30 @@ public: return numCopyAssignmentCalls; } - friend bool operator==(const Constructable & c0, const Constructable & c1) { + friend bool operator==(const Constructable &c0, const Constructable &c1) { return c0.getValue() == c1.getValue(); } - friend bool LLVM_ATTRIBUTE_UNUSED - operator!=(const Constructable & c0, const Constructable & c1) { + friend bool LLVM_ATTRIBUTE_UNUSED operator!=(const Constructable &c0, + const Constructable &c1) { return c0.getValue() != c1.getValue(); } + + friend bool operator<(const Constructable &c0, const Constructable &c1) { + return c0.getValue() < c1.getValue(); + } + friend bool LLVM_ATTRIBUTE_UNUSED operator<=(const Constructable &c0, + const Constructable &c1) { + return c0.getValue() <= c1.getValue(); + } + friend bool LLVM_ATTRIBUTE_UNUSED operator>(const Constructable &c0, + const Constructable &c1) { + return c0.getValue() > c1.getValue(); + } + friend bool LLVM_ATTRIBUTE_UNUSED operator>=(const Constructable &c0, + const Constructable &c1) { + return c0.getValue() >= c1.getValue(); + } }; int Constructable::numConstructorCalls; @@ -159,42 +176,45 @@ LLVM_ATTRIBUTE_USED void CompileTest() { V.resize(42); } +// Assert that v contains the specified values, in order. +template +void assertValuesInOrder(VectorT &v, size_t size, ...) { + EXPECT_EQ(size, v.size()); + + va_list ap; + va_start(ap, size); + for (size_t i = 0; i < size; ++i) { + int value = va_arg(ap, int); + EXPECT_EQ(value, v[i].getValue()); + } + + va_end(ap); +} + +template void assertEmpty(VectorT &v) { + // Size tests + EXPECT_EQ(0u, v.size()); + EXPECT_TRUE(v.empty()); + + // Iterator tests + EXPECT_TRUE(v.begin() == v.end()); +} + +// Generate a sequence of values to initialize the vector. +template void makeSequence(VectorT &v, int start, int end) { + for (int i = start; i <= end; ++i) { + v.push_back(Constructable(i)); + } +} + +template +constexpr static unsigned NumBuiltinElts(const SmallVector &) { + return N; +} + class SmallVectorTestBase : public testing::Test { protected: void SetUp() override { Constructable::reset(); } - - template - void assertEmpty(VectorT & v) { - // Size tests - EXPECT_EQ(0u, v.size()); - EXPECT_TRUE(v.empty()); - - // Iterator tests - EXPECT_TRUE(v.begin() == v.end()); - } - - // Assert that v contains the specified values, in order. - template - void assertValuesInOrder(VectorT & v, size_t size, ...) { - EXPECT_EQ(size, v.size()); - - va_list ap; - va_start(ap, size); - for (size_t i = 0; i < size; ++i) { - int value = va_arg(ap, int); - EXPECT_EQ(value, v[i].getValue()); - } - - va_end(ap); - } - - // Generate a sequence of values to initialize the vector. - template - void makeSequence(VectorT & v, int start, int end) { - for (int i = start; i <= end; ++i) { - v.push_back(Constructable(i)); - } - } }; // Test fixture class @@ -217,24 +237,38 @@ TYPED_TEST_SUITE(SmallVectorTest, SmallVectorTestTypes, ); // Constructor test. TYPED_TEST(SmallVectorTest, ConstructorNonIterTest) { SCOPED_TRACE("ConstructorTest"); - this->theVector = SmallVector(2, 2); - this->assertValuesInOrder(this->theVector, 2u, 2, 2); + auto &V = this->theVector; + V = SmallVector(2, 2); + assertValuesInOrder(V, 2u, 2, 2); } // Constructor test. TYPED_TEST(SmallVectorTest, ConstructorIterTest) { SCOPED_TRACE("ConstructorTest"); int arr[] = {1, 2, 3}; - this->theVector = - SmallVector(std::begin(arr), std::end(arr)); - this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); + auto &V = this->theVector; + V = SmallVector(std::begin(arr), std::end(arr)); + assertValuesInOrder(V, 3u, 1, 2, 3); +} + +// Constructor test. +TYPED_TEST(SmallVectorTest, ConstructorFromSpanSimpleTest) { + SCOPED_TRACE("ConstructorFromSpanSimpleTest"); + std::array StdArray = {Constructable(1), Constructable(2), + Constructable(3)}; + std::span Array = StdArray; + auto &V = this->theVector; + V = SmallVector(Array); + assertValuesInOrder(V, 3u, 1, 2, 3); + ASSERT_EQ(NumBuiltinElts(TypeParam{}), NumBuiltinElts(V)); } // New vector test. TYPED_TEST(SmallVectorTest, EmptyVectorTest) { SCOPED_TRACE("EmptyVectorTest"); - this->assertEmpty(this->theVector); - EXPECT_TRUE(this->theVector.rbegin() == this->theVector.rend()); + auto &V = this->theVector; + assertEmpty(V); + EXPECT_TRUE(V.rbegin() == V.rend()); EXPECT_EQ(0, Constructable::getNumConstructorCalls()); EXPECT_EQ(0, Constructable::getNumDestructorCalls()); } @@ -242,35 +276,35 @@ TYPED_TEST(SmallVectorTest, EmptyVectorTest) { // Simple insertions and deletions. TYPED_TEST(SmallVectorTest, PushPopTest) { SCOPED_TRACE("PushPopTest"); - + auto &V = this->theVector; // Track whether the vector will potentially have to grow. - bool RequiresGrowth = this->theVector.capacity() < 3; + bool RequiresGrowth = V.capacity() < 3; // Push an element - this->theVector.push_back(Constructable(1)); + V.push_back(Constructable(1)); // Size tests - this->assertValuesInOrder(this->theVector, 1u, 1); - EXPECT_FALSE(this->theVector.begin() == this->theVector.end()); - EXPECT_FALSE(this->theVector.empty()); + assertValuesInOrder(V, 1u, 1); + EXPECT_FALSE(V.begin() == V.end()); + EXPECT_FALSE(V.empty()); // Push another element - this->theVector.push_back(Constructable(2)); - this->assertValuesInOrder(this->theVector, 2u, 1, 2); + V.push_back(Constructable(2)); + assertValuesInOrder(V, 2u, 1, 2); // Insert at beginning. Reserve space to avoid reference invalidation from - // this->theVector[1]. - this->theVector.reserve(this->theVector.size() + 1); - this->theVector.insert(this->theVector.begin(), this->theVector[1]); - this->assertValuesInOrder(this->theVector, 3u, 2, 1, 2); + // V[1]. + V.reserve(V.size() + 1); + V.insert(V.begin(), V[1]); + assertValuesInOrder(V, 3u, 2, 1, 2); // Pop one element - this->theVector.pop_back(); - this->assertValuesInOrder(this->theVector, 2u, 2, 1); + V.pop_back(); + assertValuesInOrder(V, 2u, 2, 1); // Pop remaining elements - this->theVector.pop_back_n(2); - this->assertEmpty(this->theVector); + V.pop_back_n(2); + assertEmpty(V); // Check number of constructor calls. Should be 2 for each list element, // one for the argument to push_back, one for the argument to insert, @@ -290,12 +324,12 @@ TYPED_TEST(SmallVectorTest, PushPopTest) { // Clear test. TYPED_TEST(SmallVectorTest, ClearTest) { SCOPED_TRACE("ClearTest"); + auto &V = this->theVector; + V.reserve(2); + makeSequence(V, 1, 2); + V.clear(); - this->theVector.reserve(2); - this->makeSequence(this->theVector, 1, 2); - this->theVector.clear(); - - this->assertEmpty(this->theVector); + assertEmpty(V); EXPECT_EQ(4, Constructable::getNumConstructorCalls()); EXPECT_EQ(4, Constructable::getNumDestructorCalls()); } @@ -303,12 +337,12 @@ TYPED_TEST(SmallVectorTest, ClearTest) { // Resize smaller test. TYPED_TEST(SmallVectorTest, ResizeShrinkTest) { SCOPED_TRACE("ResizeShrinkTest"); + auto &V = this->theVector; + V.reserve(3); + makeSequence(V, 1, 3); + V.resize(1); - this->theVector.reserve(3); - this->makeSequence(this->theVector, 1, 3); - this->theVector.resize(1); - - this->assertValuesInOrder(this->theVector, 1u, 1); + assertValuesInOrder(V, 1u, 1); EXPECT_EQ(6, Constructable::getNumConstructorCalls()); EXPECT_EQ(5, Constructable::getNumDestructorCalls()); } @@ -316,25 +350,25 @@ TYPED_TEST(SmallVectorTest, ResizeShrinkTest) { // Truncate test. TYPED_TEST(SmallVectorTest, TruncateTest) { SCOPED_TRACE("TruncateTest"); + auto &V = this->theVector; + V.reserve(3); + makeSequence(V, 1, 3); + V.truncate(1); - this->theVector.reserve(3); - this->makeSequence(this->theVector, 1, 3); - this->theVector.truncate(1); - - this->assertValuesInOrder(this->theVector, 1u, 1); + assertValuesInOrder(V, 1u, 1); EXPECT_EQ(6, Constructable::getNumConstructorCalls()); EXPECT_EQ(5, Constructable::getNumDestructorCalls()); #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST - EXPECT_DEATH(this->theVector.truncate(2), "Cannot increase size"); + EXPECT_DEATH(V.truncate(2), "Cannot increase size"); #endif - this->theVector.truncate(1); - this->assertValuesInOrder(this->theVector, 1u, 1); + V.truncate(1); + assertValuesInOrder(V, 1u, 1); EXPECT_EQ(6, Constructable::getNumConstructorCalls()); EXPECT_EQ(5, Constructable::getNumDestructorCalls()); - this->theVector.truncate(0); - this->assertEmpty(this->theVector); + V.truncate(0); + assertEmpty(V); EXPECT_EQ(6, Constructable::getNumConstructorCalls()); EXPECT_EQ(6, Constructable::getNumDestructorCalls()); } @@ -342,20 +376,21 @@ TYPED_TEST(SmallVectorTest, TruncateTest) { // Resize bigger test. TYPED_TEST(SmallVectorTest, ResizeGrowTest) { SCOPED_TRACE("ResizeGrowTest"); - - this->theVector.resize(2); + auto &V = this->theVector; + V.resize(2); EXPECT_EQ(2, Constructable::getNumConstructorCalls()); EXPECT_EQ(0, Constructable::getNumDestructorCalls()); - EXPECT_EQ(2u, this->theVector.size()); + EXPECT_EQ(2u, V.size()); } TYPED_TEST(SmallVectorTest, ResizeWithElementsTest) { - this->theVector.resize(2); + auto &V = this->theVector; + V.resize(2); Constructable::reset(); - this->theVector.resize(4); + V.resize(4); size_t Ctors = Constructable::getNumConstructorCalls(); EXPECT_TRUE(Ctors == 2 || Ctors == 4); @@ -368,9 +403,9 @@ TYPED_TEST(SmallVectorTest, ResizeWithElementsTest) { // Resize with fill value. TYPED_TEST(SmallVectorTest, ResizeFillTest) { SCOPED_TRACE("ResizeFillTest"); - - this->theVector.resize(3, Constructable(77)); - this->assertValuesInOrder(this->theVector, 3u, 77, 77, 77); + auto &V = this->theVector; + V.resize(3, Constructable(77)); + assertValuesInOrder(V, 3u, 77, 77, 77); } TEST(SmallVectorTest, ResizeForOverwrite) { @@ -401,100 +436,103 @@ TEST(SmallVectorTest, ResizeForOverwrite) { // Overflow past fixed size. TYPED_TEST(SmallVectorTest, OverflowTest) { SCOPED_TRACE("OverflowTest"); - + auto &V = this->theVector; // Push more elements than the fixed size. - this->makeSequence(this->theVector, 1, 10); + makeSequence(V, 1, 10); // Test size and values. - EXPECT_EQ(10u, this->theVector.size()); + EXPECT_EQ(10u, V.size()); for (int i = 0; i < 10; ++i) { - EXPECT_EQ(i+1, this->theVector[i].getValue()); + EXPECT_EQ(i + 1, V[i].getValue()); } // Now resize back to fixed size. - this->theVector.resize(1); + V.resize(1); - this->assertValuesInOrder(this->theVector, 1u, 1); + assertValuesInOrder(V, 1u, 1); } // Iteration tests. TYPED_TEST(SmallVectorTest, IterationTest) { - this->makeSequence(this->theVector, 1, 2); + auto &V = this->theVector; + makeSequence(V, 1, 2); // Forward Iteration - typename TypeParam::iterator it = this->theVector.begin(); - EXPECT_TRUE(*it == this->theVector.front()); - EXPECT_TRUE(*it == this->theVector[0]); + typename TypeParam::iterator it = V.begin(); + EXPECT_TRUE(*it == V.front()); + EXPECT_TRUE(*it == V[0]); EXPECT_EQ(1, it->getValue()); ++it; - EXPECT_TRUE(*it == this->theVector[1]); - EXPECT_TRUE(*it == this->theVector.back()); + EXPECT_TRUE(*it == V[1]); + EXPECT_TRUE(*it == V.back()); EXPECT_EQ(2, it->getValue()); ++it; - EXPECT_TRUE(it == this->theVector.end()); + EXPECT_TRUE(it == V.end()); --it; - EXPECT_TRUE(*it == this->theVector[1]); + EXPECT_TRUE(*it == V[1]); EXPECT_EQ(2, it->getValue()); --it; - EXPECT_TRUE(*it == this->theVector[0]); + EXPECT_TRUE(*it == V[0]); EXPECT_EQ(1, it->getValue()); // Reverse Iteration - typename TypeParam::reverse_iterator rit = this->theVector.rbegin(); - EXPECT_TRUE(*rit == this->theVector[1]); + typename TypeParam::reverse_iterator rit = V.rbegin(); + EXPECT_TRUE(*rit == V[1]); EXPECT_EQ(2, rit->getValue()); ++rit; - EXPECT_TRUE(*rit == this->theVector[0]); + EXPECT_TRUE(*rit == V[0]); EXPECT_EQ(1, rit->getValue()); ++rit; - EXPECT_TRUE(rit == this->theVector.rend()); + EXPECT_TRUE(rit == V.rend()); --rit; - EXPECT_TRUE(*rit == this->theVector[0]); + EXPECT_TRUE(*rit == V[0]); EXPECT_EQ(1, rit->getValue()); --rit; - EXPECT_TRUE(*rit == this->theVector[1]); + EXPECT_TRUE(*rit == V[1]); EXPECT_EQ(2, rit->getValue()); } // Swap test. TYPED_TEST(SmallVectorTest, SwapTest) { SCOPED_TRACE("SwapTest"); + auto &V = this->theVector; + auto &U = this->otherVector; + makeSequence(V, 1, 2); + std::swap(V, U); - this->makeSequence(this->theVector, 1, 2); - std::swap(this->theVector, this->otherVector); - - this->assertEmpty(this->theVector); - this->assertValuesInOrder(this->otherVector, 2u, 1, 2); + assertEmpty(V); + assertValuesInOrder(U, 2u, 1, 2); } // Append test TYPED_TEST(SmallVectorTest, AppendTest) { SCOPED_TRACE("AppendTest"); + auto &V = this->theVector; + auto &U = this->otherVector; + makeSequence(U, 2, 3); - this->makeSequence(this->otherVector, 2, 3); + V.push_back(Constructable(1)); + V.append(U.begin(), U.end()); - this->theVector.push_back(Constructable(1)); - this->theVector.append(this->otherVector.begin(), this->otherVector.end()); - - this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); + assertValuesInOrder(V, 3u, 1, 2, 3); } // Append repeated test TYPED_TEST(SmallVectorTest, AppendRepeatedTest) { SCOPED_TRACE("AppendRepeatedTest"); - - this->theVector.push_back(Constructable(1)); - this->theVector.append(2, Constructable(77)); - this->assertValuesInOrder(this->theVector, 3u, 1, 77, 77); + auto &V = this->theVector; + V.push_back(Constructable(1)); + V.append(2, Constructable(77)); + assertValuesInOrder(V, 3u, 1, 77, 77); } // Append test TYPED_TEST(SmallVectorTest, AppendNonIterTest) { SCOPED_TRACE("AppendRepeatedTest"); - - this->theVector.push_back(Constructable(1)); - this->theVector.append(2, 7); - this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); + auto &V = this->theVector; + V.push_back(Constructable(1)); + V.append(2, 7); + assertValuesInOrder(V, 3u, 1, 7, 7); } struct output_iterator { @@ -509,84 +547,85 @@ struct output_iterator { TYPED_TEST(SmallVectorTest, AppendRepeatedNonForwardIterator) { SCOPED_TRACE("AppendRepeatedTest"); - - this->theVector.push_back(Constructable(1)); - this->theVector.append(output_iterator(), output_iterator()); - this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); + auto &V = this->theVector; + V.push_back(Constructable(1)); + V.append(output_iterator(), output_iterator()); + assertValuesInOrder(V, 3u, 1, 7, 7); } TYPED_TEST(SmallVectorTest, AppendSmallVector) { SCOPED_TRACE("AppendSmallVector"); - + auto &V = this->theVector; SmallVector otherVector = {7, 7}; - this->theVector.push_back(Constructable(1)); - this->theVector.append(otherVector); - this->assertValuesInOrder(this->theVector, 3u, 1, 7, 7); + V.push_back(Constructable(1)); + V.append(otherVector); + assertValuesInOrder(V, 3u, 1, 7, 7); } // Assign test TYPED_TEST(SmallVectorTest, AssignTest) { SCOPED_TRACE("AssignTest"); - - this->theVector.push_back(Constructable(1)); - this->theVector.assign(2, Constructable(77)); - this->assertValuesInOrder(this->theVector, 2u, 77, 77); + auto &V = this->theVector; + V.push_back(Constructable(1)); + V.assign(2, Constructable(77)); + assertValuesInOrder(V, 2u, 77, 77); } // Assign test TYPED_TEST(SmallVectorTest, AssignRangeTest) { SCOPED_TRACE("AssignTest"); - - this->theVector.push_back(Constructable(1)); + auto &V = this->theVector; + V.push_back(Constructable(1)); int arr[] = {1, 2, 3}; - this->theVector.assign(std::begin(arr), std::end(arr)); - this->assertValuesInOrder(this->theVector, 3u, 1, 2, 3); + V.assign(std::begin(arr), std::end(arr)); + assertValuesInOrder(V, 3u, 1, 2, 3); } // Assign test TYPED_TEST(SmallVectorTest, AssignNonIterTest) { SCOPED_TRACE("AssignTest"); - - this->theVector.push_back(Constructable(1)); - this->theVector.assign(2, 7); - this->assertValuesInOrder(this->theVector, 2u, 7, 7); + auto &V = this->theVector; + V.push_back(Constructable(1)); + V.assign(2, 7); + assertValuesInOrder(V, 2u, 7, 7); } TYPED_TEST(SmallVectorTest, AssignSmallVector) { SCOPED_TRACE("AssignSmallVector"); - + auto &V = this->theVector; SmallVector otherVector = {7, 7}; - this->theVector.push_back(Constructable(1)); - this->theVector.assign(otherVector); - this->assertValuesInOrder(this->theVector, 2u, 7, 7); + V.push_back(Constructable(1)); + V.assign(otherVector); + assertValuesInOrder(V, 2u, 7, 7); } // Move-assign test TYPED_TEST(SmallVectorTest, MoveAssignTest) { SCOPED_TRACE("MoveAssignTest"); - + auto &V = this->theVector; + auto &U = this->otherVector; // Set up our vector with a single element, but enough capacity for 4. - this->theVector.reserve(4); - this->theVector.push_back(Constructable(1)); - + V.reserve(4); + V.push_back(Constructable(1)); + // Set up the other vector with 2 elements. - this->otherVector.push_back(Constructable(2)); - this->otherVector.push_back(Constructable(3)); + U.push_back(Constructable(2)); + U.push_back(Constructable(3)); // Move-assign from the other vector. - this->theVector = std::move(this->otherVector); + V = std::move(U); // Make sure we have the right result. - this->assertValuesInOrder(this->theVector, 2u, 2, 3); + assertValuesInOrder(V, 2u, 2, 3); // Make sure the # of constructor/destructor calls line up. There // are two live objects after clearing the other vector. - this->otherVector.clear(); + U.clear(); EXPECT_EQ(Constructable::getNumConstructorCalls()-2, Constructable::getNumDestructorCalls()); // There shouldn't be any live objects any more. - this->theVector.clear(); + V.clear(); EXPECT_EQ(Constructable::getNumConstructorCalls(), Constructable::getNumDestructorCalls()); } @@ -594,54 +633,51 @@ TYPED_TEST(SmallVectorTest, MoveAssignTest) { // Erase a single element TYPED_TEST(SmallVectorTest, EraseTest) { SCOPED_TRACE("EraseTest"); - - this->makeSequence(this->theVector, 1, 3); - const auto &theConstVector = this->theVector; - this->theVector.erase(theConstVector.begin()); - this->assertValuesInOrder(this->theVector, 2u, 2, 3); + auto &V = this->theVector; + makeSequence(V, 1, 3); + const auto &theConstVector = V; + V.erase(theConstVector.begin()); + assertValuesInOrder(V, 2u, 2, 3); } // Erase a range of elements TYPED_TEST(SmallVectorTest, EraseRangeTest) { SCOPED_TRACE("EraseRangeTest"); - - this->makeSequence(this->theVector, 1, 3); - const auto &theConstVector = this->theVector; - this->theVector.erase(theConstVector.begin(), theConstVector.begin() + 2); - this->assertValuesInOrder(this->theVector, 1u, 3); + auto &V = this->theVector; + makeSequence(V, 1, 3); + const auto &theConstVector = V; + V.erase(theConstVector.begin(), theConstVector.begin() + 2); + assertValuesInOrder(V, 1u, 3); } // Insert a single element. TYPED_TEST(SmallVectorTest, InsertTest) { SCOPED_TRACE("InsertTest"); - - this->makeSequence(this->theVector, 1, 3); - typename TypeParam::iterator I = - this->theVector.insert(this->theVector.begin() + 1, Constructable(77)); - EXPECT_EQ(this->theVector.begin() + 1, I); - this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3); + auto &V = this->theVector; + makeSequence(V, 1, 3); + typename TypeParam::iterator I = V.insert(V.begin() + 1, Constructable(77)); + EXPECT_EQ(V.begin() + 1, I); + assertValuesInOrder(V, 4u, 1, 77, 2, 3); } // Insert a copy of a single element. TYPED_TEST(SmallVectorTest, InsertCopy) { SCOPED_TRACE("InsertTest"); - - this->makeSequence(this->theVector, 1, 3); + auto &V = this->theVector; + makeSequence(V, 1, 3); Constructable C(77); - typename TypeParam::iterator I = - this->theVector.insert(this->theVector.begin() + 1, C); - EXPECT_EQ(this->theVector.begin() + 1, I); - this->assertValuesInOrder(this->theVector, 4u, 1, 77, 2, 3); + typename TypeParam::iterator I = V.insert(V.begin() + 1, C); + EXPECT_EQ(V.begin() + 1, I); + assertValuesInOrder(V, 4u, 1, 77, 2, 3); } // Insert repeated elements. TYPED_TEST(SmallVectorTest, InsertRepeatedTest) { SCOPED_TRACE("InsertRepeatedTest"); - - this->makeSequence(this->theVector, 1, 4); + auto &V = this->theVector; + makeSequence(V, 1, 4); Constructable::reset(); - auto I = - this->theVector.insert(this->theVector.begin() + 1, 2, Constructable(16)); + auto I = V.insert(V.begin() + 1, 2, Constructable(16)); // Move construct the top element into newly allocated space, and optionally // reallocate the whole buffer, move constructing into it. // FIXME: This is inefficient, we shouldn't move things into newly allocated @@ -655,26 +691,26 @@ TYPED_TEST(SmallVectorTest, InsertRepeatedTest) { EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls()); // All without any copy construction. EXPECT_EQ(0, Constructable::getNumCopyConstructorCalls()); - EXPECT_EQ(this->theVector.begin() + 1, I); - this->assertValuesInOrder(this->theVector, 6u, 1, 16, 16, 2, 3, 4); + EXPECT_EQ(V.begin() + 1, I); + assertValuesInOrder(V, 6u, 1, 16, 16, 2, 3, 4); } TYPED_TEST(SmallVectorTest, InsertRepeatedNonIterTest) { SCOPED_TRACE("InsertRepeatedTest"); - - this->makeSequence(this->theVector, 1, 4); + auto &V = this->theVector; + makeSequence(V, 1, 4); Constructable::reset(); - auto I = this->theVector.insert(this->theVector.begin() + 1, 2, 7); - EXPECT_EQ(this->theVector.begin() + 1, I); - this->assertValuesInOrder(this->theVector, 6u, 1, 7, 7, 2, 3, 4); + auto I = V.insert(V.begin() + 1, 2, 7); + EXPECT_EQ(V.begin() + 1, I); + assertValuesInOrder(V, 6u, 1, 7, 7, 2, 3, 4); } TYPED_TEST(SmallVectorTest, InsertRepeatedAtEndTest) { SCOPED_TRACE("InsertRepeatedTest"); - - this->makeSequence(this->theVector, 1, 4); + auto &V = this->theVector; + makeSequence(V, 1, 4); Constructable::reset(); - auto I = this->theVector.insert(this->theVector.end(), 2, Constructable(16)); + auto I = V.insert(V.end(), 2, Constructable(16)); // Just copy construct them into newly allocated space EXPECT_EQ(2, Constructable::getNumCopyConstructorCalls()); // Move everything across if reallocation is needed. @@ -684,34 +720,30 @@ TYPED_TEST(SmallVectorTest, InsertRepeatedAtEndTest) { EXPECT_EQ(0, Constructable::getNumCopyAssignmentCalls()); EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls()); - EXPECT_EQ(this->theVector.begin() + 4, I); - this->assertValuesInOrder(this->theVector, 6u, 1, 2, 3, 4, 16, 16); + EXPECT_EQ(V.begin() + 4, I); + assertValuesInOrder(V, 6u, 1, 2, 3, 4, 16, 16); } TYPED_TEST(SmallVectorTest, InsertRepeatedEmptyTest) { SCOPED_TRACE("InsertRepeatedTest"); - - this->makeSequence(this->theVector, 10, 15); + auto &V = this->theVector; + makeSequence(V, 10, 15); // Empty insert. - EXPECT_EQ(this->theVector.end(), - this->theVector.insert(this->theVector.end(), - 0, Constructable(42))); - EXPECT_EQ(this->theVector.begin() + 1, - this->theVector.insert(this->theVector.begin() + 1, - 0, Constructable(42))); + EXPECT_EQ(V.end(), V.insert(V.end(), 0, Constructable(42))); + EXPECT_EQ(V.begin() + 1, V.insert(V.begin() + 1, 0, Constructable(42))); } // Insert range. TYPED_TEST(SmallVectorTest, InsertRangeTest) { SCOPED_TRACE("InsertRangeTest"); - + auto &V = this->theVector; Constructable Arr[3] = { Constructable(77), Constructable(77), Constructable(77) }; - this->makeSequence(this->theVector, 1, 3); + makeSequence(V, 1, 3); Constructable::reset(); - auto I = this->theVector.insert(this->theVector.begin() + 1, Arr, Arr + 3); + auto I = V.insert(V.begin() + 1, Arr, Arr + 3); // Move construct the top 3 elements into newly allocated space. // Possibly move the whole sequence into new space first. // FIXME: This is inefficient, we shouldn't move things into newly allocated @@ -723,22 +755,22 @@ TYPED_TEST(SmallVectorTest, InsertRangeTest) { EXPECT_EQ(2, Constructable::getNumCopyAssignmentCalls()); // Copy construct the third element into newly allocated space. EXPECT_EQ(1, Constructable::getNumCopyConstructorCalls()); - EXPECT_EQ(this->theVector.begin() + 1, I); - this->assertValuesInOrder(this->theVector, 6u, 1, 77, 77, 77, 2, 3); + EXPECT_EQ(V.begin() + 1, I); + assertValuesInOrder(V, 6u, 1, 77, 77, 77, 2, 3); } TYPED_TEST(SmallVectorTest, InsertRangeAtEndTest) { SCOPED_TRACE("InsertRangeTest"); - + auto &V = this->theVector; Constructable Arr[3] = { Constructable(77), Constructable(77), Constructable(77) }; - this->makeSequence(this->theVector, 1, 3); + makeSequence(V, 1, 3); // Insert at end. Constructable::reset(); - auto I = this->theVector.insert(this->theVector.end(), Arr, Arr+3); + auto I = V.insert(V.end(), Arr, Arr + 3); // Copy construct the 3 elements into new space at the top. EXPECT_EQ(3, Constructable::getNumCopyConstructorCalls()); // Don't copy/move anything else. @@ -748,42 +780,67 @@ TYPED_TEST(SmallVectorTest, InsertRangeAtEndTest) { EXPECT_TRUE(Constructable::getNumMoveConstructorCalls() == 0 || Constructable::getNumMoveConstructorCalls() == 3); EXPECT_EQ(0, Constructable::getNumMoveAssignmentCalls()); - EXPECT_EQ(this->theVector.begin() + 3, I); - this->assertValuesInOrder(this->theVector, 6u, - 1, 2, 3, 77, 77, 77); + EXPECT_EQ(V.begin() + 3, I); + assertValuesInOrder(V, 6u, 1, 2, 3, 77, 77, 77); } TYPED_TEST(SmallVectorTest, InsertEmptyRangeTest) { SCOPED_TRACE("InsertRangeTest"); - - this->makeSequence(this->theVector, 1, 3); + auto &V = this->theVector; + makeSequence(V, 1, 3); // Empty insert. - EXPECT_EQ(this->theVector.end(), - this->theVector.insert(this->theVector.end(), - this->theVector.begin(), - this->theVector.begin())); - EXPECT_EQ(this->theVector.begin() + 1, - this->theVector.insert(this->theVector.begin() + 1, - this->theVector.begin(), - this->theVector.begin())); + EXPECT_EQ(V.end(), V.insert(V.end(), V.begin(), V.begin())); + EXPECT_EQ(V.begin() + 1, V.insert(V.begin() + 1, V.begin(), V.begin())); } // Comparison tests. -TYPED_TEST(SmallVectorTest, ComparisonTest) { - SCOPED_TRACE("ComparisonTest"); +TYPED_TEST(SmallVectorTest, ComparisonEqualityTest) { + SCOPED_TRACE("ComparisonEqualityTest"); + auto &V = this->theVector; + auto &U = this->otherVector; + makeSequence(V, 1, 3); + makeSequence(U, 1, 3); - this->makeSequence(this->theVector, 1, 3); - this->makeSequence(this->otherVector, 1, 3); + EXPECT_TRUE(V == U); + EXPECT_FALSE(V != U); - EXPECT_TRUE(this->theVector == this->otherVector); - EXPECT_FALSE(this->theVector != this->otherVector); + U.clear(); + makeSequence(U, 2, 4); - this->otherVector.clear(); - this->makeSequence(this->otherVector, 2, 4); + EXPECT_FALSE(V == U); + EXPECT_TRUE(V != U); +} - EXPECT_FALSE(this->theVector == this->otherVector); - EXPECT_TRUE(this->theVector != this->otherVector); +// Comparison tests. +TYPED_TEST(SmallVectorTest, ComparisonLessThanTest) { + SCOPED_TRACE("ComparisonLessThanTest"); + auto &V = this->theVector; + auto &U = this->otherVector; + V = {1, 2, 4}; + U = {1, 4}; + + EXPECT_TRUE(V < U); + EXPECT_TRUE(V <= U); + EXPECT_FALSE(V > U); + EXPECT_FALSE(V >= U); + + EXPECT_FALSE(U < V); + EXPECT_FALSE(U <= V); + EXPECT_TRUE(U > V); + EXPECT_TRUE(U >= V); + + U = {1, 2, 4}; + + EXPECT_FALSE(V < U); + EXPECT_TRUE(V <= U); + EXPECT_FALSE(V > U); + EXPECT_TRUE(V >= U); + + EXPECT_FALSE(U < V); + EXPECT_TRUE(U <= V); + EXPECT_FALSE(U > V); + EXPECT_TRUE(U >= V); } // Constant vector tests. @@ -797,25 +854,27 @@ TYPED_TEST(SmallVectorTest, ConstVectorTest) { // Direct array access. TYPED_TEST(SmallVectorTest, DirectVectorTest) { - EXPECT_EQ(0u, this->theVector.size()); - this->theVector.reserve(4); - EXPECT_LE(4u, this->theVector.capacity()); + auto &V = this->theVector; + EXPECT_EQ(0u, V.size()); + V.reserve(4); + EXPECT_LE(4u, V.capacity()); EXPECT_EQ(0, Constructable::getNumConstructorCalls()); - this->theVector.push_back(1); - this->theVector.push_back(2); - this->theVector.push_back(3); - this->theVector.push_back(4); - EXPECT_EQ(4u, this->theVector.size()); + V.push_back(1); + V.push_back(2); + V.push_back(3); + V.push_back(4); + EXPECT_EQ(4u, V.size()); EXPECT_EQ(8, Constructable::getNumConstructorCalls()); - EXPECT_EQ(1, this->theVector[0].getValue()); - EXPECT_EQ(2, this->theVector[1].getValue()); - EXPECT_EQ(3, this->theVector[2].getValue()); - EXPECT_EQ(4, this->theVector[3].getValue()); + EXPECT_EQ(1, V[0].getValue()); + EXPECT_EQ(2, V[1].getValue()); + EXPECT_EQ(3, V[2].getValue()); + EXPECT_EQ(4, V[3].getValue()); } TYPED_TEST(SmallVectorTest, IteratorTest) { + auto &V = this->theVector; std::list L; - this->theVector.insert(this->theVector.end(), L.begin(), L.end()); + V.insert(V.end(), L.begin(), L.end()); } template class DualSmallVectorsTest; @@ -825,9 +884,6 @@ class DualSmallVectorsTest> : public SmallVectorTe protected: VectorT1 theVector; VectorT2 otherVector; - - template - static unsigned NumBuiltinElts(const SmallVector&) { return N; } }; typedef ::testing::Types< @@ -845,33 +901,32 @@ TYPED_TEST_SUITE(DualSmallVectorsTest, DualSmallVectorTestTypes, ); TYPED_TEST(DualSmallVectorsTest, MoveAssignment) { SCOPED_TRACE("MoveAssignTest-DualVectorTypes"); - + auto &V = this->theVector; + auto &U = this->otherVector; // Set up our vector with four elements. for (unsigned I = 0; I < 4; ++I) - this->otherVector.push_back(Constructable(I)); + U.push_back(Constructable(I)); - const Constructable *OrigDataPtr = this->otherVector.data(); + const Constructable *OrigDataPtr = U.data(); // Move-assign from the other vector. - this->theVector = - std::move(static_cast&>(this->otherVector)); + V = std::move(static_cast &>(U)); // Make sure we have the right result. - this->assertValuesInOrder(this->theVector, 4u, 0, 1, 2, 3); + assertValuesInOrder(V, 4u, 0, 1, 2, 3); // Make sure the # of constructor/destructor calls line up. There // are two live objects after clearing the other vector. - this->otherVector.clear(); + U.clear(); EXPECT_EQ(Constructable::getNumConstructorCalls()-4, Constructable::getNumDestructorCalls()); // If the source vector (otherVector) was in small-mode, assert that we just // moved the data pointer over. - EXPECT_TRUE(this->NumBuiltinElts(this->otherVector) == 4 || - this->theVector.data() == OrigDataPtr); + EXPECT_TRUE(NumBuiltinElts(U) == 4 || V.data() == OrigDataPtr); // There shouldn't be any live objects any more. - this->theVector.clear(); + V.clear(); EXPECT_EQ(Constructable::getNumConstructorCalls(), Constructable::getNumDestructorCalls()); @@ -1074,6 +1129,83 @@ TEST(SmallVectorTest, DefaultInlinedElements) { EXPECT_EQ(NestedV[0][0][0], 42); } +TEST(SmallVectorTest, ToVector) { + { + std::vector v = {'a', 'b', 'c'}; + auto Vector = to_vector<4>(v); + static_assert(NumBuiltinElts(Vector) == 4u); + ASSERT_EQ(3u, Vector.size()); + for (size_t I = 0; I < v.size(); ++I) + EXPECT_EQ(v[I], Vector[I]); + } + { + std::vector v = {'a', 'b', 'c'}; + auto Vector = to_vector(v); + static_assert(NumBuiltinElts(Vector) != 4u); + ASSERT_EQ(3u, Vector.size()); + for (size_t I = 0; I < v.size(); ++I) + EXPECT_EQ(v[I], Vector[I]); + } +} + +struct To { + int Content; + friend bool operator==(const To &LHS, const To &RHS) { + return LHS.Content == RHS.Content; + } +}; + +class From { +public: + From() = default; + From(To M) { T = M; } + operator To() const { return T; } + +private: + To T; +}; + +TEST(SmallVectorTest, ConstructFromSpanOfConvertibleType) { + To to1{1}, to2{2}, to3{3}; + std::vector StdVector = {From(to1), From(to2), From(to3)}; + std::span Array = StdVector; + { + wpi::SmallVector Vector(Array); + + ASSERT_EQ(Array.size(), Vector.size()); + for (size_t I = 0; I < Array.size(); ++I) + EXPECT_EQ(Array[I], Vector[I]); + } + { + wpi::SmallVector Vector(Array); + + ASSERT_EQ(Array.size(), Vector.size()); + ASSERT_EQ(4u, NumBuiltinElts(Vector)); + for (size_t I = 0; I < Array.size(); ++I) + EXPECT_EQ(Array[I], Vector[I]); + } +} + +TEST(SmallVectorTest, ToVectorOf) { + To to1{1}, to2{2}, to3{3}; + std::vector StdVector = {From(to1), From(to2), From(to3)}; + { + wpi::SmallVector Vector = wpi::to_vector_of(StdVector); + + ASSERT_EQ(StdVector.size(), Vector.size()); + for (size_t I = 0; I < StdVector.size(); ++I) + EXPECT_EQ(StdVector[I], Vector[I]); + } + { + auto Vector = wpi::to_vector_of(StdVector); + + ASSERT_EQ(StdVector.size(), Vector.size()); + static_assert(NumBuiltinElts(Vector) == 4u); + for (size_t I = 0; I < StdVector.size(); ++I) + EXPECT_EQ(StdVector[I], Vector[I]); + } +} + template class SmallVectorReferenceInvalidationTest : public SmallVectorTestBase { protected: @@ -1083,13 +1215,8 @@ protected: VectorT V; - template - static unsigned NumBuiltinElts(const SmallVector &) { - return N; - } - template static bool isValueType() { - return std::is_same::value; + return std::is_same_v; } void SetUp() override { @@ -1113,7 +1240,7 @@ TYPED_TEST_SUITE(SmallVectorReferenceInvalidationTest, TYPED_TEST(SmallVectorReferenceInvalidationTest, PushBack) { // Note: setup adds [1, 2, ...] to V until it's at capacity in small mode. auto &V = this->V; - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); // Push back a reference to last element when growing from small storage. V.push_back(V.back()); @@ -1135,7 +1262,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, PushBack) { TYPED_TEST(SmallVectorReferenceInvalidationTest, PushBackMoved) { // Note: setup adds [1, 2, ...] to V until it's at capacity in small mode. auto &V = this->V; - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); // Push back a reference to last element when growing from small storage. V.push_back(std::move(V.back())); @@ -1164,7 +1291,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, PushBackMoved) { TYPED_TEST(SmallVectorReferenceInvalidationTest, Resize) { auto &V = this->V; (void)V; - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); V.resize(N + 1, V.back()); EXPECT_EQ(N, V.back()); @@ -1179,7 +1306,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, Append) { auto &V = this->V; (void)V; V.append(1, V.back()); - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); EXPECT_EQ(N, V[N - 1]); // Append enough more elements that V will grow again. This tests growing @@ -1197,7 +1324,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, AppendRange) { #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST EXPECT_DEATH(V.append(V.begin(), V.begin() + 1), this->AssertionMessage); - ASSERT_EQ(3u, this->NumBuiltinElts(V)); + ASSERT_EQ(3u, NumBuiltinElts(V)); ASSERT_EQ(3u, V.size()); V.pop_back(); ASSERT_EQ(2u, V.size()); @@ -1212,7 +1339,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, Assign) { // Note: setup adds [1, 2, ...] to V until it's at capacity in small mode. auto &V = this->V; (void)V; - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); ASSERT_EQ(unsigned(N), V.size()); ASSERT_EQ(unsigned(N), V.capacity()); @@ -1312,7 +1439,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, InsertN) { // Cover NumToInsert <= this->end() - I. V.insert(V.begin() + 1, 1, V.back()); - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); EXPECT_EQ(N, V[1]); // Cover NumToInsert > this->end() - I, inserting enough elements that V will @@ -1332,7 +1459,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, InsertRange) { EXPECT_DEATH(V.insert(V.begin(), V.begin(), V.begin() + 1), this->AssertionMessage); - ASSERT_EQ(3u, this->NumBuiltinElts(V)); + ASSERT_EQ(3u, NumBuiltinElts(V)); ASSERT_EQ(3u, V.size()); V.pop_back(); ASSERT_EQ(2u, V.size()); @@ -1346,7 +1473,7 @@ TYPED_TEST(SmallVectorReferenceInvalidationTest, InsertRange) { TYPED_TEST(SmallVectorReferenceInvalidationTest, EmplaceBack) { // Note: setup adds [1, 2, ...] to V until it's at capacity in small mode. auto &V = this->V; - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); // Push back a reference to last element when growing from small storage. V.emplace_back(V.back()); @@ -1375,11 +1502,6 @@ protected: VectorT V; - template - static unsigned NumBuiltinElts(const SmallVector &) { - return N; - } - void SetUp() override { SmallVectorTestBase::SetUp(); @@ -1400,7 +1522,7 @@ TYPED_TEST_SUITE(SmallVectorInternalReferenceInvalidationTest, TYPED_TEST(SmallVectorInternalReferenceInvalidationTest, EmplaceBack) { // Note: setup adds [1, 2, ...] to V until it's at capacity in small mode. auto &V = this->V; - int N = this->NumBuiltinElts(V); + int N = NumBuiltinElts(V); // Push back a reference to last element when growing from small storage. V.emplace_back(V.back().first, V.back().second); diff --git a/wpiutil/src/test/native/cpp/llvm/StringMapTest.cpp b/wpiutil/src/test/native/cpp/llvm/StringMapTest.cpp index 71baa20105..1fa206b4ed 100644 --- a/wpiutil/src/test/native/cpp/llvm/StringMapTest.cpp +++ b/wpiutil/src/test/native/cpp/llvm/StringMapTest.cpp @@ -15,6 +15,10 @@ using namespace wpi; namespace { +static_assert(sizeof(StringMap) < + sizeof(StringMap), + "Ensure empty base optimization happens with default allocator"); + // Test fixture class StringMapTest : public testing::Test { protected: @@ -22,7 +26,7 @@ protected: static const char testKey[]; static const uint32_t testValue; - static const char* testKeyFirst; + static const char *testKeyFirst; static size_t testKeyLength; static const std::string testKeyStr; @@ -39,7 +43,7 @@ protected: EXPECT_EQ(0u, testMap.count(std::string_view(testKeyFirst, testKeyLength))); EXPECT_EQ(0u, testMap.count(testKeyStr)); EXPECT_TRUE(testMap.find(testKey) == testMap.end()); - EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == + EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == testMap.end()); EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end()); } @@ -62,7 +66,7 @@ protected: EXPECT_EQ(1u, testMap.count(std::string_view(testKeyFirst, testKeyLength))); EXPECT_EQ(1u, testMap.count(testKeyStr)); EXPECT_TRUE(testMap.find(testKey) == testMap.begin()); - EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == + EXPECT_TRUE(testMap.find(std::string_view(testKeyFirst, testKeyLength)) == testMap.begin()); EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin()); } @@ -70,7 +74,7 @@ protected: const char StringMapTest::testKey[] = "key"; const uint32_t StringMapTest::testValue = 1u; -const char* StringMapTest::testKeyFirst = testKey; +const char *StringMapTest::testKeyFirst = testKey; size_t StringMapTest::testKeyLength = sizeof(testKey) - 1; const std::string StringMapTest::testKeyStr(testKey); @@ -85,13 +89,11 @@ struct CountCopyAndMove { }; // Empty map tests. -TEST_F(StringMapTest, EmptyMapTest) { - assertEmptyMap(); -} +TEST_F(StringMapTest, EmptyMapTest) { assertEmptyMap(); } // Constant map tests. TEST_F(StringMapTest, ConstEmptyMapTest) { - const StringMap& constTestMap = testMap; + const StringMap &constTestMap = testMap; // Size tests EXPECT_EQ(0u, constTestMap.size()); @@ -214,8 +216,8 @@ TEST_F(StringMapTest, IterationTest) { } // Iterate over all numbers and mark each one found. - for (StringMap::iterator it = testMap.begin(); - it != testMap.end(); ++it) { + for (StringMap::iterator it = testMap.begin(); it != testMap.end(); + ++it) { std::stringstream ss; ss << "key_" << it->second; ASSERT_STREQ(ss.str().c_str(), it->first().data()); @@ -232,7 +234,7 @@ TEST_F(StringMapTest, IterationTest) { TEST_F(StringMapTest, StringMapEntryTest) { MallocAllocator Allocator; StringMap::value_type *entry = - StringMap::value_type::Create( + StringMap::value_type::create( std::string_view(testKeyFirst, testKeyLength), Allocator, 1u); EXPECT_STREQ(testKey, entry->first().data()); EXPECT_EQ(1u, entry->second); @@ -242,10 +244,8 @@ TEST_F(StringMapTest, StringMapEntryTest) { // Test insert() method. TEST_F(StringMapTest, InsertTest) { SCOPED_TRACE("InsertTest"); - testMap.insert( - StringMap::value_type::Create( - std::string_view(testKeyFirst, testKeyLength), - testMap.getAllocator(), 1u)); + testMap.insert(StringMap::value_type::create( + std::string_view(testKeyFirst, testKeyLength), testMap.getAllocator(), 1u)); assertSingleItemMap(); } @@ -280,7 +280,7 @@ TEST_F(StringMapTest, InsertRehashingPairTest) { EXPECT_EQ(0u, t.getNumBuckets()); StringMap::iterator It = - t.insert(std::make_pair("abcdef", 42)).first; + t.insert(std::make_pair("abcdef", 42)).first; EXPECT_EQ(16u, t.getNumBuckets()); EXPECT_EQ("abcdef", It->first()); EXPECT_EQ(42u, It->second); @@ -338,13 +338,13 @@ TEST_F(StringMapTest, NonDefaultConstructable) { struct Immovable { Immovable() {} - Immovable(Immovable&&) = delete; // will disable the other special members + Immovable(Immovable &&) = delete; // will disable the other special members }; struct MoveOnly { int i; MoveOnly(int i) : i(i) {} - MoveOnly(const Immovable&) : i(0) {} + MoveOnly(const Immovable &) : i(0) {} MoveOnly(MoveOnly &&RHS) : i(RHS.i) {} MoveOnly &operator=(MoveOnly &&RHS) { i = RHS.i; @@ -360,14 +360,14 @@ TEST_F(StringMapTest, MoveOnly) { StringMap t; t.insert(std::make_pair("Test", MoveOnly(42))); std::string_view Key = "Test"; - StringMapEntry::Create(Key, t.getAllocator(), MoveOnly(42)) + StringMapEntry::create(Key, t.getAllocator(), MoveOnly(42)) ->Destroy(t.getAllocator()); } TEST_F(StringMapTest, CtorArg) { std::string_view Key = "Test"; MallocAllocator Allocator; - StringMapEntry::Create(Key, Allocator, Immovable()) + StringMapEntry::create(Key, Allocator, Immovable()) ->Destroy(Allocator); } @@ -501,6 +501,16 @@ TEST_F(StringMapTest, MoveDtor) { ASSERT_TRUE(B.empty()); } +TEST_F(StringMapTest, StructuredBindings) { + StringMap A; + A["a"] = 42; + + for (auto &[Key, Value] : A) { + EXPECT_EQ("a", Key); + EXPECT_EQ(42, Value); + } +} + namespace { // Simple class that counts how many moves and copy happens when growing a map struct CountCtorCopyAndMove { @@ -570,7 +580,7 @@ struct NonMoveableNonCopyableType { NonMoveableNonCopyableType(const NonMoveableNonCopyableType &) = delete; NonMoveableNonCopyableType(NonMoveableNonCopyableType &&) = delete; }; -} +} // namespace // Test that we can "emplace" an element in the map without involving map/move TEST(StringMapCustomTest, EmplaceTest) {