[clang-tools-extra] Add checks to convert std library iterator algorithms into c++20 or boost ranges (PR #97764)
Julian Schmidt via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 5 14:11:11 PDT 2024
================
@@ -0,0 +1,181 @@
+//===--- UseRangesCheck.cpp - clang-tidy ----------------------------------===//
+//
+// 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 "UseRangesCheck.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <initializer_list>
+
+// FixItHint - Let the docs script know that this class does provide fixits
+
+namespace clang::tidy::modernize {
+
+static constexpr const char *SingleRangeNames[] = {
+ "all_of",
+ "any_of",
+ "none_of",
+ "for_each",
+ "find",
+ "find_if",
+ "find_if_not",
+ "adjacent_find",
+ "copy",
+ "copy_if",
+ "copy_backward",
+ "move",
+ "move_backward",
+ "fill",
+ "transform",
+ "replace",
+ "replace_if",
+ "generate",
+ "remove",
+ "remove_if",
+ "remove_copy",
+ "remove_copy_if",
+ "unique",
+ "unique_copy",
+ "sample",
+ "partition_point",
+ "lower_bound",
+ "upper_bound",
+ "equal_range",
+ "binary_search",
+ "push_heap",
+ "pop_heap",
+ "make_heap",
+ "sort_heap",
+ "next_permutation",
+ "prev_permutation",
+ "iota",
+};
+
+static constexpr const char *SingleRangeWithExecNames[] = {
+ "reverse",
+ "reverse_copy",
+ "shift_left",
+ "shift_right",
+ "is_partitioned",
+ "partition",
+ "partition_copy",
+ "stable_partition",
+ "sort",
+ "stable_sort",
+ "is_sorted",
+ "is_sorted_until",
+ "is_heap",
+ "is_heap_until",
+ "max_element",
+ "min_element",
+ "minmax_element",
+ "uninitialized_copy",
+ "uninitialized_fill",
+ "uninitialized_move",
+ "uninitialized_default_construct",
+ "uninitialized_value_construct",
+ "destroy",
+};
+
+static constexpr const char *TwoRangeWithExecNames[] = {
+ "partial_sort_copy",
+ "includes",
+ "set_union",
+ "set_intersection",
+ "set_difference",
+ "set_symmetric_difference",
+ "merge",
+ "lexicographical_compare",
+ "find_end",
+ "search",
+};
+
+static constexpr const char *OneOrTwoRangeNames[] = {
+ "is_permutation",
+};
+
+static constexpr const char *OneOrTwoRangeWithExecNames[] = {
+ "equal",
+ "mismatch",
+};
+
+namespace {
+class StdReplacer : public utils::UseRangesCheck::Replacer {
+public:
+ explicit StdReplacer(SmallVector<UseRangesCheck::Signature> Indexes)
+ : Indexes(std::move(Indexes)) {}
+ std::string getReplaceName(const NamedDecl &OriginalName) const override {
+ return ("std::ranges::" + OriginalName.getName()).str();
+ }
+ ArrayRef<UseRangesCheck::Signature>
+ getReplacementSignatures() const override {
+ return Indexes;
+ }
+ std::optional<std::string>
+ getHeaderInclusion(const NamedDecl & /*OriginalName*/) const override {
+ return "<algorithm>";
+ }
+
+private:
+ SmallVector<UseRangesCheck::Signature> Indexes;
+};
+} // namespace
+
+utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const {
+
+ utils::UseRangesCheck::ReplacerMap Result;
+
+ // template<typename Iter> Func(Iter first, Iter last,...).
+ static const Signature SingleRangeArgs = {{0}};
+ // template<typename Policy, typename Iter>
+ // Func(Policy policy, Iter first, // Iter last,...).
+ static const Signature SingleRangeExecPolicy = {{1}};
+ // template<typename Iter1, typename Iter2>
+ // Func(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2,...).
+ static const Signature TwoRangeArgs = {{0}, {2}};
+ // template<typename Policy, typename Iter1, typename Iter2>
+ // Func(Policy policy, Iter1 first1, Iter1 last1, Iter2 first2, Iter2
+ // last2,...).
+ static const Signature TwoRangeExecPolicy = {{1}, {3}};
+
+ static const Signature SingleRangeFunc[] = {SingleRangeArgs};
+
+ static const Signature SingleRangeExecFunc[] = {SingleRangeArgs,
+ SingleRangeExecPolicy};
+ static const Signature TwoRangeExecFunc[] = {TwoRangeArgs,
+ TwoRangeExecPolicy};
+ static const Signature OneOrTwoFunc[] = {SingleRangeArgs, TwoRangeArgs};
+ static const Signature OneOrTwoExecFunc[] = {
+ SingleRangeArgs, SingleRangeExecPolicy, TwoRangeArgs, TwoRangeExecPolicy};
+
+ static const std::pair<ArrayRef<Signature>, ArrayRef<const char *>> Names[] =
+ {{SingleRangeFunc, SingleRangeNames},
+ {SingleRangeExecFunc, SingleRangeWithExecNames},
+ {TwoRangeExecFunc, TwoRangeWithExecNames},
+ {OneOrTwoFunc, OneOrTwoRangeNames},
+ {OneOrTwoExecFunc, OneOrTwoRangeWithExecNames}};
+ SmallString<64> Buff;
+ for (const auto &[Signature, Values] : Names) {
+ auto Replacer = llvm::makeIntrusiveRefCnt<StdReplacer>(
+ SmallVector<UseRangesCheck::Signature>{Signature.begin(),
+ Signature.end()});
----------------
5chmidti wrote:
`SmallVector` supports construction from an `ArrayRef`: https://github.com/llvm/llvm-project/blob/683c8e9913cd87e0b2a8e083298cd3ebc67923fe/llvm/include/llvm/ADT/SmallVector.h#L1243-L1247
https://github.com/llvm/llvm-project/pull/97764
More information about the cfe-commits
mailing list