[clang-tools-extra] [clang-tidy] Add llvm-use-vector-utils (PR #177722)

via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 24 07:20:33 PST 2026


================
@@ -0,0 +1,107 @@
+// RUN: %check_clang_tidy %s llvm-use-vector-utils %t
+
+// CHECK-FIXES: #include "llvm/ADT/SmallVectorExtras.h"
+
+namespace llvm {
+
+template <typename T> class SmallVector {};
+
+template <typename RangeT>
+SmallVector<int> to_vector(RangeT &&Range);
+
+template <unsigned Size, typename RangeT>
+SmallVector<int> to_vector(RangeT &&Range);
+
+template <typename Out, typename RangeT>
+SmallVector<Out> to_vector_of(RangeT &&Range);
+
+template <typename Out, unsigned Size, typename RangeT>
+SmallVector<Out> to_vector_of(RangeT &&Range);
+
+template <typename ContainerT, typename FuncT>
+struct mapped_range {};
+
+template <typename ContainerT, typename FuncT>
+mapped_range<ContainerT, FuncT> map_range(ContainerT &&C, FuncT &&F);
+
+// Hypothetical 3-arg overload (for future-proofing).
+template <typename ContainerT, typename FuncT, typename ExtraT>
+mapped_range<ContainerT, FuncT> map_range(ContainerT &&C, FuncT &&F, ExtraT &&E);
+
+template <typename ContainerT, typename PredT>
+struct filter_range {};
+
+template <typename ContainerT, typename PredT>
+filter_range<ContainerT, PredT> make_filter_range(ContainerT &&C, PredT &&P);
+
+// Hypothetical 3-arg overload (for future-proofing).
+template <typename ContainerT, typename PredT, typename ExtraT>
+filter_range<ContainerT, PredT> make_filter_range(ContainerT &&C, PredT &&P, ExtraT &&E);
+
+} // namespace llvm
+
+int transform(int x);
+bool is_even(int x);
+
+void test_map_range() {
+  llvm::SmallVector<int> vec;
+
+  auto result = llvm::to_vector(llvm::map_range(vec, transform));
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use 'map_to_vector'
+  // CHECK-FIXES: auto result = llvm::map_to_vector(vec, transform);
+
+  auto result_sized = llvm::to_vector<4>(llvm::map_range(vec, transform));
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use 'map_to_vector'
+  // CHECK-FIXES: auto result_sized = llvm::map_to_vector<4>(vec, transform);
+
+  auto result_global = ::llvm::to_vector(::llvm::map_range(vec, transform));
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use 'map_to_vector'
+  // CHECK-FIXES: auto result_global = ::llvm::map_to_vector(vec, transform);
+}
+
+void test_filter_range() {
+  llvm::SmallVector<int> vec;
+
+  auto result = llvm::to_vector(llvm::make_filter_range(vec, is_even));
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use 'filter_to_vector'
+  // CHECK-FIXES: auto result = llvm::filter_to_vector(vec, is_even);
+
+  auto result_sized = llvm::to_vector<6>(llvm::make_filter_range(vec, is_even));
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use 'filter_to_vector'
+  // CHECK-FIXES: auto result_sized = llvm::filter_to_vector<6>(vec, is_even);
+}
+
+namespace llvm {
+
+void test_inside_llvm_namespace() {
+  SmallVector<int> vec;
+
+  // Unprefixed calls inside the `llvm` namespace should also be detected.
+  auto result = to_vector(map_range(vec, transform));
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use 'map_to_vector'
+  // CHECK-FIXES: auto result = map_to_vector(vec, transform);
+}
+
+} // namespace llvm
+
----------------
zeyi2 wrote:

It might be worth adding a test case to verify that the check preserves comments correctly :)

For example:

```c++
auto r1 = llvm::to_vector( /* please keep me */ llvm::map_range(vec, transform));
auto r2 = llvm::to_vector(llvm::map_range( /* please keep me */ vec, transform));
```

I grepped the codebase and didn't find any current occurrences of this pattern, so this is a minor nit (I'm okay if you don't want to address it in this PR), but it would be good to ensure the Fix-It logic is robust.


https://github.com/llvm/llvm-project/pull/177722


More information about the cfe-commits mailing list