https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/191030
>From 554c5b139755b2057b1f276d9d86d1ec29e63fb9 Mon Sep 17 00:00:00 2001 From: Alexis Engelke <[email protected]> Date: Wed, 8 Apr 2026 18:49:57 +0000 Subject: [PATCH 1/4] [spr] initial version Created using spr 1.3.8-wip --- clang/lib/Lex/PPDirectives.cpp | 5 ++-- clang/lib/Sema/SemaCodeComplete.cpp | 2 +- clang/lib/Serialization/ASTWriter.cpp | 3 ++- llvm/include/llvm/ADT/SmallVector.h | 19 +++++++++----- llvm/include/llvm/IR/Metadata.h | 2 +- llvm/include/llvm/SandboxIR/User.h | 2 +- llvm/tools/llvm-cov/CoverageReport.cpp | 5 ++-- llvm/unittests/ADT/IteratorTest.cpp | 10 +++---- .../DWARF/DWARFAcceleratorTableTest.cpp | 26 ++++++++++--------- 9 files changed, 42 insertions(+), 32 deletions(-) diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 172c2fa57db00..153ddc944cad3 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -2652,8 +2652,9 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport( NameWithoriginalSlashes.consume_front("\\\\?\\"); #endif StringRef RealPathName = File->getFileEntry().tryGetRealPathName(); - SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name), - llvm::sys::path::end(Name)); + SmallVector<StringRef, 16> Components; + std::copy(llvm::sys::path::begin(Name), llvm::sys::path::end(Name), + std::back_inserter(Components)); #if defined(_WIN32) // -Wnonportable-include-path is designed to diagnose includes using // case even on systems with a case-insensitive file system. diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 0cd9819dc2964..e9f856b891361 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -10053,7 +10053,7 @@ void SemaCodeCompletion::CodeCompleteObjCMethodDecl( IFace = Category->getClassInterface(); if (IFace) - llvm::append_range(Containers, IFace->visible_categories()); + llvm::copy(IFace->visible_categories(), std::back_inserter(Containers)); if (IsInstanceMethod) { for (unsigned I = 0, N = Containers.size(); I != N; ++I) diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 4b3adce07f10c..8100d6dfd0d3d 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3982,7 +3982,8 @@ class ASTIdentifierTableTrait { // "stat"), but the ASTReader adds declarations to the end of the list // (so we need to see the struct "stat" before the function "stat"). // Only emit declarations that aren't from a chained PCH, though. - SmallVector<NamedDecl *, 16> Decls(IdResolver->decls(II)); + SmallVector<NamedDecl *, 16> Decls; + llvm::copy(IdResolver->decls(II), std::back_inserter(Decls)); for (NamedDecl *D : llvm::reverse(Decls)) LE.write<DeclID>((DeclID)Writer.getDeclID( getDeclForLocalLookup(PP.getLangOpts(), D))); diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h index 23d40c3e07675..c8ea0654f0a04 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -39,9 +39,10 @@ template <typename T> class ArrayRef; template <typename IteratorT> class iterator_range; template <class Iterator> -using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible< - typename std::iterator_traits<Iterator>::iterator_category, - std::input_iterator_tag>::value>; +using EnableIfConvertibleToForwardIterator = + std::enable_if_t<std::is_convertible< + typename std::iterator_traits<Iterator>::iterator_category, + std::forward_iterator_tag>::value>; /// This is all the stuff common to all SmallVectors. /// @@ -682,7 +683,8 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { void swap(SmallVectorImpl &RHS); /// Add the specified range to the end of the SmallVector. - template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> + template <typename ItTy, + typename = EnableIfConvertibleToForwardIterator<ItTy>> void append(ItTy in_start, ItTy in_end) { this->assertSafeToAddRange(in_start, in_end); size_type NumInputs = std::distance(in_start, in_end); @@ -723,7 +725,8 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { // FIXME: Consider assigning over existing elements, rather than clearing & // re-initializing them - for all assign(...) variants. - template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> + template <typename ItTy, + typename = EnableIfConvertibleToForwardIterator<ItTy>> void assign(ItTy in_start, ItTy in_end) { this->assertSafeToReferenceAfterClear(in_start, in_end); clear(); @@ -880,7 +883,8 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { return I; } - template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> + template <typename ItTy, + typename = EnableIfConvertibleToForwardIterator<ItTy>> 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(); @@ -1221,7 +1225,8 @@ class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>, this->assign(Size, Value); } - template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> + template <typename ItTy, + typename = EnableIfConvertibleToForwardIterator<ItTy>> SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) { this->append(S, E); } diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h index f6c393c1d8c67..09bdb79a4dfda 100644 --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -1625,7 +1625,7 @@ template <class T> class TypedMDOperandIterator { MDNode::op_iterator I = nullptr; public: - using iterator_category = std::input_iterator_tag; + using iterator_category = std::forward_iterator_tag; using value_type = T *; using difference_type = std::ptrdiff_t; using pointer = void; diff --git a/llvm/include/llvm/SandboxIR/User.h b/llvm/include/llvm/SandboxIR/User.h index c552e2e3378be..2404ca40a72ae 100644 --- a/llvm/include/llvm/SandboxIR/User.h +++ b/llvm/include/llvm/SandboxIR/User.h @@ -34,7 +34,7 @@ class OperandUseIterator { using value_type = sandboxir::Use; using pointer = value_type *; using reference = value_type &; - using iterator_category = std::input_iterator_tag; + using iterator_category = std::forward_iterator_tag; OperandUseIterator() = default; LLVM_ABI value_type operator*() const; diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp index 9b754d613370c..b243854793579 100644 --- a/llvm/tools/llvm-cov/CoverageReport.cpp +++ b/llvm/tools/llvm-cov/CoverageReport.cpp @@ -139,8 +139,9 @@ raw_ostream::Colors determineCoveragePercentageColor(const T &Info) { unsigned getNumRedundantPathComponents(ArrayRef<std::string> Paths) { // To start, set the number of redundant path components to the maximum // possible value. - SmallVector<StringRef, 8> FirstPathComponents{sys::path::begin(Paths[0]), - sys::path::end(Paths[0])}; + SmallVector<StringRef, 8> FirstPathComponents; + std::copy(sys::path::begin(Paths[0]), sys::path::end(Paths[0]), + std::back_inserter(FirstPathComponents)); unsigned NumRedundant = FirstPathComponents.size(); for (unsigned I = 1, E = Paths.size(); NumRedundant > 0 && I < E; ++I) { diff --git a/llvm/unittests/ADT/IteratorTest.cpp b/llvm/unittests/ADT/IteratorTest.cpp index 9dd8c1a84f44a..6f4bc4ca8bffe 100644 --- a/llvm/unittests/ADT/IteratorTest.cpp +++ b/llvm/unittests/ADT/IteratorTest.cpp @@ -336,16 +336,16 @@ TEST(FilterIteratorTest, Composition) { EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual); } -TEST(FilterIteratorTest, InputIterator) { - struct InputIterator - : iterator_adaptor_base<InputIterator, int *, std::input_iterator_tag> { - InputIterator(int *It) : InputIterator::iterator_adaptor_base(It) {} +TEST(FilterIteratorTest, ForwardIterator) { + struct ForwardIterator : iterator_adaptor_base<ForwardIterator, int *, + std::forward_iterator_tag> { + ForwardIterator(int *It) : ForwardIterator::iterator_adaptor_base(It) {} }; auto IsOdd = [](int N) { return N % 2 == 1; }; int A[] = {0, 1, 2, 3, 4, 5, 6}; auto Range = make_filter_range( - make_range(InputIterator(std::begin(A)), InputIterator(std::end(A))), + make_range(ForwardIterator(std::begin(A)), ForwardIterator(std::end(A))), IsOdd); SmallVector<int, 3> Actual(Range.begin(), Range.end()); EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual); diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp index 82cc02c921d15..76bc93cf970ac 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp @@ -106,16 +106,18 @@ TEST(DWARFDebugNames, BasicTestEntries) { DWARFDebugNames::NameTableEntry SecondEntry = NameIndex.getNameTableEntry(2); ASSERT_EQ(SecondEntry.getString(), StringRef("NameType2")); - SmallVector<DWARFDebugNames::Entry> FirstNameEntries = - to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("NameType1")); + SmallVector<DWARFDebugNames::Entry> FirstNameEntries; + llvm::copy(NameIndex.equal_range("NameType1"), + std::back_inserter(FirstNameEntries)); ASSERT_EQ(FirstNameEntries.size(), 2u); ASSERT_EQ(FirstNameEntries[0].getCUIndex(), 0u); ASSERT_EQ(FirstNameEntries[1].getCUIndex(), 0x2); ASSERT_EQ(FirstNameEntries[0].getDIEUnitOffset(), 0x0); ASSERT_EQ(FirstNameEntries[1].getDIEUnitOffset(), 0x2); - SmallVector<DWARFDebugNames::Entry> SecondNameEntries = - to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("NameType2")); + SmallVector<DWARFDebugNames::Entry> SecondNameEntries; + llvm::copy(NameIndex.equal_range("NameType2"), + std::back_inserter(SecondNameEntries)); ASSERT_EQ(SecondNameEntries.size(), 1u); ASSERT_EQ(SecondNameEntries[0].getCUIndex(), 0x1); ASSERT_EQ(SecondNameEntries[0].getDIEUnitOffset(), 0x1); @@ -181,32 +183,32 @@ TEST(DWARFDebugNames, ParentEntries) { ASSERT_NE(DebugNames.begin(), DebugNames.end()); const DWARFDebugNames::NameIndex &NameIndex = *DebugNames.begin(); - SmallVector<DWARFDebugNames::Entry> Name1Entries = - to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name1")); + SmallVector<DWARFDebugNames::Entry> Name1Entries; + llvm::copy(NameIndex.equal_range("Name1"), std::back_inserter(Name1Entries)); ASSERT_EQ(Name1Entries.size(), 1u); Expected<std::optional<DWARFDebugNames::Entry>> Name1Parent = Name1Entries[0].getParentDIEEntry(); ASSERT_THAT_EXPECTED(Name1Parent, Succeeded()); ASSERT_EQ(*Name1Parent, std::nullopt); // Name1 has no parent - SmallVector<DWARFDebugNames::Entry> Name2Entries = - to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name2")); + SmallVector<DWARFDebugNames::Entry> Name2Entries; + llvm::copy(NameIndex.equal_range("Name2"), std::back_inserter(Name2Entries)); ASSERT_EQ(Name2Entries.size(), 1u); Expected<std::optional<DWARFDebugNames::Entry>> Name2Parent = Name2Entries[0].getParentDIEEntry(); ASSERT_THAT_EXPECTED(Name2Parent, Succeeded()); ASSERT_EQ((**Name2Parent).getDIEUnitOffset(), 0x0); // Name2 parent == Name1 - SmallVector<DWARFDebugNames::Entry> Name3Entries = - to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name3")); + SmallVector<DWARFDebugNames::Entry> Name3Entries; + llvm::copy(NameIndex.equal_range("Name3"), std::back_inserter(Name3Entries)); ASSERT_EQ(Name3Entries.size(), 1u); Expected<std::optional<DWARFDebugNames::Entry>> Name3Parent = Name3Entries[0].getParentDIEEntry(); ASSERT_THAT_EXPECTED(Name3Parent, Succeeded()); ASSERT_EQ((**Name3Parent).getDIEUnitOffset(), 0x1); // Name3 parent == Name2 - SmallVector<DWARFDebugNames::Entry> Name4Entries = - to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name4")); + SmallVector<DWARFDebugNames::Entry> Name4Entries; + llvm::copy(NameIndex.equal_range("Name4"), std::back_inserter(Name4Entries)); ASSERT_EQ(Name4Entries.size(), 1u); ASSERT_FALSE(Name4Entries[0].hasParentInformation()); } >From 9feee2c8345a50041e1ee02c55f2c6bcf4df3208 Mon Sep 17 00:00:00 2001 From: Alexis Engelke <[email protected]> Date: Thu, 9 Apr 2026 14:17:47 +0000 Subject: [PATCH 2/4] implement input iterator append instead Created using spr 1.3.8-wip --- clang/lib/Lex/PPDirectives.cpp | 5 +-- clang/lib/Sema/SemaCodeComplete.cpp | 2 +- clang/lib/Serialization/ASTWriter.cpp | 3 +- llvm/include/llvm/ADT/SmallVector.h | 43 +++++++++++-------- llvm/tools/llvm-cov/CoverageReport.cpp | 5 +-- llvm/unittests/ADT/IteratorTest.cpp | 10 ++--- .../DWARF/DWARFAcceleratorTableTest.cpp | 26 ++++++----- 7 files changed, 49 insertions(+), 45 deletions(-) diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 153ddc944cad3..172c2fa57db00 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -2652,9 +2652,8 @@ Preprocessor::ImportAction Preprocessor::HandleHeaderIncludeOrImport( NameWithoriginalSlashes.consume_front("\\\\?\\"); #endif StringRef RealPathName = File->getFileEntry().tryGetRealPathName(); - SmallVector<StringRef, 16> Components; - std::copy(llvm::sys::path::begin(Name), llvm::sys::path::end(Name), - std::back_inserter(Components)); + SmallVector<StringRef, 16> Components(llvm::sys::path::begin(Name), + llvm::sys::path::end(Name)); #if defined(_WIN32) // -Wnonportable-include-path is designed to diagnose includes using // case even on systems with a case-insensitive file system. diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index e9f856b891361..0cd9819dc2964 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -10053,7 +10053,7 @@ void SemaCodeCompletion::CodeCompleteObjCMethodDecl( IFace = Category->getClassInterface(); if (IFace) - llvm::copy(IFace->visible_categories(), std::back_inserter(Containers)); + llvm::append_range(Containers, IFace->visible_categories()); if (IsInstanceMethod) { for (unsigned I = 0, N = Containers.size(); I != N; ++I) diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 8100d6dfd0d3d..4b3adce07f10c 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3982,8 +3982,7 @@ class ASTIdentifierTableTrait { // "stat"), but the ASTReader adds declarations to the end of the list // (so we need to see the struct "stat" before the function "stat"). // Only emit declarations that aren't from a chained PCH, though. - SmallVector<NamedDecl *, 16> Decls; - llvm::copy(IdResolver->decls(II), std::back_inserter(Decls)); + SmallVector<NamedDecl *, 16> Decls(IdResolver->decls(II)); for (NamedDecl *D : llvm::reverse(Decls)) LE.write<DeclID>((DeclID)Writer.getDeclID( getDeclForLocalLookup(PP.getLangOpts(), D))); diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h index c8ea0654f0a04..fc2599aa1192b 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -38,11 +38,13 @@ template <typename T> class ArrayRef; template <typename IteratorT> class iterator_range; +template <class Iterator, class Tag> +using HasIteratorTag = std::is_convertible< + typename std::iterator_traits<Iterator>::iterator_category, Tag>; + template <class Iterator> -using EnableIfConvertibleToForwardIterator = - std::enable_if_t<std::is_convertible< - typename std::iterator_traits<Iterator>::iterator_category, - std::forward_iterator_tag>::value>; +using EnableIfConvertibleToInputIterator = + std::enable_if_t<HasIteratorTag<Iterator, std::input_iterator_tag>::value>; /// This is all the stuff common to all SmallVectors. /// @@ -683,14 +685,19 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { void swap(SmallVectorImpl &RHS); /// Add the specified range to the end of the SmallVector. - template <typename ItTy, - typename = EnableIfConvertibleToForwardIterator<ItTy>> + template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> 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); - this->uninitialized_copy(in_start, in_end, this->end()); - this->set_size(this->size() + NumInputs); + if constexpr (HasIteratorTag<ItTy, std::forward_iterator_tag>::value) { + this->assertSafeToAddRange(in_start, in_end); + size_type NumInputs = std::distance(in_start, in_end); + this->reserve(this->size() + NumInputs); + this->uninitialized_copy(in_start, in_end, this->end()); + this->set_size(this->size() + NumInputs); + } else { + // Input iterator, we can't know ahead how many elements we'll add. + for (; in_start != in_end; ++in_start) + this->push_back(*in_start); + } } /// Append \p NumInputs copies of \p Elt to the end. @@ -725,8 +732,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { // FIXME: Consider assigning over existing elements, rather than clearing & // re-initializing them - for all assign(...) variants. - template <typename ItTy, - typename = EnableIfConvertibleToForwardIterator<ItTy>> + template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> void assign(ItTy in_start, ItTy in_end) { this->assertSafeToReferenceAfterClear(in_start, in_end); clear(); @@ -883,9 +889,13 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { return I; } - template <typename ItTy, - typename = EnableIfConvertibleToForwardIterator<ItTy>> + template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> iterator insert(iterator I, ItTy From, ItTy To) { + // TODO: support efficient insert with input iterators. This requires + // appending all elements and rotating them later to their correct position. + static_assert(HasIteratorTag<ItTy, std::forward_iterator_tag>::value, + "insert() with input iterator is not implemented"); + // Convert iterator to elt# to avoid invalidating iterator when we reserve() size_t InsertElt = I - this->begin(); @@ -1225,8 +1235,7 @@ class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>, this->assign(Size, Value); } - template <typename ItTy, - typename = EnableIfConvertibleToForwardIterator<ItTy>> + template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) { this->append(S, E); } diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp index b243854793579..9b754d613370c 100644 --- a/llvm/tools/llvm-cov/CoverageReport.cpp +++ b/llvm/tools/llvm-cov/CoverageReport.cpp @@ -139,9 +139,8 @@ raw_ostream::Colors determineCoveragePercentageColor(const T &Info) { unsigned getNumRedundantPathComponents(ArrayRef<std::string> Paths) { // To start, set the number of redundant path components to the maximum // possible value. - SmallVector<StringRef, 8> FirstPathComponents; - std::copy(sys::path::begin(Paths[0]), sys::path::end(Paths[0]), - std::back_inserter(FirstPathComponents)); + SmallVector<StringRef, 8> FirstPathComponents{sys::path::begin(Paths[0]), + sys::path::end(Paths[0])}; unsigned NumRedundant = FirstPathComponents.size(); for (unsigned I = 1, E = Paths.size(); NumRedundant > 0 && I < E; ++I) { diff --git a/llvm/unittests/ADT/IteratorTest.cpp b/llvm/unittests/ADT/IteratorTest.cpp index 6f4bc4ca8bffe..9dd8c1a84f44a 100644 --- a/llvm/unittests/ADT/IteratorTest.cpp +++ b/llvm/unittests/ADT/IteratorTest.cpp @@ -336,16 +336,16 @@ TEST(FilterIteratorTest, Composition) { EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual); } -TEST(FilterIteratorTest, ForwardIterator) { - struct ForwardIterator : iterator_adaptor_base<ForwardIterator, int *, - std::forward_iterator_tag> { - ForwardIterator(int *It) : ForwardIterator::iterator_adaptor_base(It) {} +TEST(FilterIteratorTest, InputIterator) { + struct InputIterator + : iterator_adaptor_base<InputIterator, int *, std::input_iterator_tag> { + InputIterator(int *It) : InputIterator::iterator_adaptor_base(It) {} }; auto IsOdd = [](int N) { return N % 2 == 1; }; int A[] = {0, 1, 2, 3, 4, 5, 6}; auto Range = make_filter_range( - make_range(ForwardIterator(std::begin(A)), ForwardIterator(std::end(A))), + make_range(InputIterator(std::begin(A)), InputIterator(std::end(A))), IsOdd); SmallVector<int, 3> Actual(Range.begin(), Range.end()); EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual); diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp index 76bc93cf970ac..82cc02c921d15 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFAcceleratorTableTest.cpp @@ -106,18 +106,16 @@ TEST(DWARFDebugNames, BasicTestEntries) { DWARFDebugNames::NameTableEntry SecondEntry = NameIndex.getNameTableEntry(2); ASSERT_EQ(SecondEntry.getString(), StringRef("NameType2")); - SmallVector<DWARFDebugNames::Entry> FirstNameEntries; - llvm::copy(NameIndex.equal_range("NameType1"), - std::back_inserter(FirstNameEntries)); + SmallVector<DWARFDebugNames::Entry> FirstNameEntries = + to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("NameType1")); ASSERT_EQ(FirstNameEntries.size(), 2u); ASSERT_EQ(FirstNameEntries[0].getCUIndex(), 0u); ASSERT_EQ(FirstNameEntries[1].getCUIndex(), 0x2); ASSERT_EQ(FirstNameEntries[0].getDIEUnitOffset(), 0x0); ASSERT_EQ(FirstNameEntries[1].getDIEUnitOffset(), 0x2); - SmallVector<DWARFDebugNames::Entry> SecondNameEntries; - llvm::copy(NameIndex.equal_range("NameType2"), - std::back_inserter(SecondNameEntries)); + SmallVector<DWARFDebugNames::Entry> SecondNameEntries = + to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("NameType2")); ASSERT_EQ(SecondNameEntries.size(), 1u); ASSERT_EQ(SecondNameEntries[0].getCUIndex(), 0x1); ASSERT_EQ(SecondNameEntries[0].getDIEUnitOffset(), 0x1); @@ -183,32 +181,32 @@ TEST(DWARFDebugNames, ParentEntries) { ASSERT_NE(DebugNames.begin(), DebugNames.end()); const DWARFDebugNames::NameIndex &NameIndex = *DebugNames.begin(); - SmallVector<DWARFDebugNames::Entry> Name1Entries; - llvm::copy(NameIndex.equal_range("Name1"), std::back_inserter(Name1Entries)); + SmallVector<DWARFDebugNames::Entry> Name1Entries = + to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name1")); ASSERT_EQ(Name1Entries.size(), 1u); Expected<std::optional<DWARFDebugNames::Entry>> Name1Parent = Name1Entries[0].getParentDIEEntry(); ASSERT_THAT_EXPECTED(Name1Parent, Succeeded()); ASSERT_EQ(*Name1Parent, std::nullopt); // Name1 has no parent - SmallVector<DWARFDebugNames::Entry> Name2Entries; - llvm::copy(NameIndex.equal_range("Name2"), std::back_inserter(Name2Entries)); + SmallVector<DWARFDebugNames::Entry> Name2Entries = + to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name2")); ASSERT_EQ(Name2Entries.size(), 1u); Expected<std::optional<DWARFDebugNames::Entry>> Name2Parent = Name2Entries[0].getParentDIEEntry(); ASSERT_THAT_EXPECTED(Name2Parent, Succeeded()); ASSERT_EQ((**Name2Parent).getDIEUnitOffset(), 0x0); // Name2 parent == Name1 - SmallVector<DWARFDebugNames::Entry> Name3Entries; - llvm::copy(NameIndex.equal_range("Name3"), std::back_inserter(Name3Entries)); + SmallVector<DWARFDebugNames::Entry> Name3Entries = + to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name3")); ASSERT_EQ(Name3Entries.size(), 1u); Expected<std::optional<DWARFDebugNames::Entry>> Name3Parent = Name3Entries[0].getParentDIEEntry(); ASSERT_THAT_EXPECTED(Name3Parent, Succeeded()); ASSERT_EQ((**Name3Parent).getDIEUnitOffset(), 0x1); // Name3 parent == Name2 - SmallVector<DWARFDebugNames::Entry> Name4Entries; - llvm::copy(NameIndex.equal_range("Name4"), std::back_inserter(Name4Entries)); + SmallVector<DWARFDebugNames::Entry> Name4Entries = + to_vector_of<DWARFDebugNames::Entry>(NameIndex.equal_range("Name4")); ASSERT_EQ(Name4Entries.size(), 1u); ASSERT_FALSE(Name4Entries[0].hasParentInformation()); } >From c4932140427d88b07a8994b0896232f6a8d61911 Mon Sep 17 00:00:00 2001 From: Alexis Engelke <[email protected]> Date: Thu, 9 Apr 2026 14:24:07 +0000 Subject: [PATCH 3/4] push_back -> emplace_back Created using spr 1.3.8-wip --- 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 fc2599aa1192b..708fbda4c8c39 100644 --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -696,7 +696,7 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { } else { // Input iterator, we can't know ahead how many elements we'll add. for (; in_start != in_end; ++in_start) - this->push_back(*in_start); + this->emplace_back(*in_start); } } >From e78203dab2b3ac68c7f194fbbe01c4d2d2e320ef Mon Sep 17 00:00:00 2001 From: Alexis Engelke <[email protected]> Date: Thu, 9 Apr 2026 14:52:07 +0000 Subject: [PATCH 4/4] Clang fix... Created using spr 1.3.8-wip --- clang/lib/Sema/SemaCodeComplete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 0cd9819dc2964..e9f856b891361 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -10053,7 +10053,7 @@ void SemaCodeCompletion::CodeCompleteObjCMethodDecl( IFace = Category->getClassInterface(); if (IFace) - llvm::append_range(Containers, IFace->visible_categories()); + llvm::copy(IFace->visible_categories(), std::back_inserter(Containers)); if (IsInstanceMethod) { for (unsigned I = 0, N = Containers.size(); I != N; ++I) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
