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

Reply via email to