CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
225 lines
6.9 KiB
C++
225 lines
6.9 KiB
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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#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_copy",
|
|
"remove_copy_if",
|
|
"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",
|
|
"reverse",
|
|
"reverse_copy",
|
|
"shift_left",
|
|
"shift_right",
|
|
"is_partitioned",
|
|
"partition_copy",
|
|
"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 *SingleRangeBeginResultNames[] = {
|
|
"remove", "remove_if", "stable_partition", "partition", "unique"};
|
|
|
|
static constexpr const char *TwoRangeNames[] = {
|
|
"equal",
|
|
"mismatch",
|
|
"partial_sort_copy",
|
|
"includes",
|
|
"set_union",
|
|
"set_intersection",
|
|
"set_difference",
|
|
"set_symmetric_difference",
|
|
"merge",
|
|
"lexicographical_compare",
|
|
"find_end",
|
|
"search",
|
|
"is_permutation",
|
|
};
|
|
|
|
static constexpr const char *SinglePivotRangeNames[] = {"rotate_copy",
|
|
"inplace_merge"};
|
|
|
|
static constexpr const char *SinglePivotRangeBeginResultNames[] = {"rotate"};
|
|
|
|
namespace {
|
|
class StdReplacer : public utils::UseRangesCheck::Replacer {
|
|
public:
|
|
using ResultUsePolicy = utils::UseRangesCheck::Replacer::ResultUsePolicy;
|
|
|
|
explicit StdReplacer(SmallVector<UseRangesCheck::Signature> Signatures,
|
|
ResultUsePolicy ResultPolicy = {})
|
|
: Signatures(std::move(Signatures)), ResultPolicy(ResultPolicy) {}
|
|
std::optional<std::string>
|
|
getReplaceName(const NamedDecl &OriginalName) const override {
|
|
return ("std::ranges::" + OriginalName.getName()).str();
|
|
}
|
|
ArrayRef<UseRangesCheck::Signature>
|
|
getReplacementSignatures() const override {
|
|
return Signatures;
|
|
}
|
|
ResultUsePolicy getResultUsePolicy(const NamedDecl &, bool) const override {
|
|
return ResultPolicy;
|
|
}
|
|
|
|
private:
|
|
SmallVector<UseRangesCheck::Signature> Signatures;
|
|
ResultUsePolicy ResultPolicy;
|
|
};
|
|
|
|
class StdAlgorithmReplacer : public StdReplacer {
|
|
using StdReplacer::StdReplacer;
|
|
std::optional<std::string>
|
|
getHeaderInclusion(const NamedDecl & /*OriginalName*/) const override {
|
|
return "<algorithm>";
|
|
}
|
|
};
|
|
|
|
class StdNumericReplacer : public StdReplacer {
|
|
using StdReplacer::StdReplacer;
|
|
std::optional<std::string>
|
|
getHeaderInclusion(const NamedDecl & /*OriginalName*/) const override {
|
|
return "<numeric>";
|
|
}
|
|
};
|
|
} // 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 Iter1, typename Iter2>
|
|
// Func(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2,...).
|
|
static const Signature TwoRangeArgs = {{0}, {2}};
|
|
|
|
// template<typename Iter> Func(Iter first, Iter pivot, Iter last,...).
|
|
static const Signature SinglePivotRange = {{0, 2}};
|
|
|
|
static const Signature SingleRangeFunc[] = {SingleRangeArgs};
|
|
|
|
static const Signature TwoRangeFunc[] = {TwoRangeArgs};
|
|
|
|
static const Signature SinglePivotFunc[] = {SinglePivotRange};
|
|
|
|
using ResultPolicy = StdReplacer::ResultUsePolicy;
|
|
using PolicyKind = ResultPolicy::Kind;
|
|
const ResultPolicy DefaultPolicy;
|
|
const ResultPolicy BeginResultPolicy = {
|
|
PolicyKind::AppendAccessorForUsedResult, ".begin()"};
|
|
|
|
struct AlgorithmGroup {
|
|
ArrayRef<Signature> Signatures;
|
|
ArrayRef<const char *> Names;
|
|
ResultPolicy Policy;
|
|
};
|
|
const AlgorithmGroup AlgorithmNames[] = {
|
|
{SingleRangeFunc, SingleRangeNames, DefaultPolicy},
|
|
{SingleRangeFunc, SingleRangeBeginResultNames, BeginResultPolicy},
|
|
{TwoRangeFunc, TwoRangeNames, DefaultPolicy},
|
|
{SinglePivotFunc, SinglePivotRangeNames, DefaultPolicy},
|
|
{SinglePivotFunc, SinglePivotRangeBeginResultNames, BeginResultPolicy},
|
|
};
|
|
SmallString<64> Buff;
|
|
for (const auto &[Signatures, Values, Policy] : AlgorithmNames) {
|
|
auto Replacer = llvm::makeIntrusiveRefCnt<StdAlgorithmReplacer>(
|
|
SmallVector<UseRangesCheck::Signature>{Signatures}, Policy);
|
|
for (const auto &Name : Values) {
|
|
Buff.assign({"::std::", Name});
|
|
Result.try_emplace(Buff, Replacer);
|
|
}
|
|
}
|
|
if (getLangOpts().CPlusPlus23)
|
|
Result.try_emplace(
|
|
"::std::iota",
|
|
llvm::makeIntrusiveRefCnt<StdNumericReplacer>(
|
|
SmallVector<UseRangesCheck::Signature>{std::begin(SingleRangeFunc),
|
|
std::end(SingleRangeFunc)}));
|
|
return Result;
|
|
}
|
|
|
|
UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context)
|
|
: utils::UseRangesCheck(Name, Context),
|
|
UseReversePipe(Options.get("UseReversePipe", false)) {}
|
|
|
|
void UseRangesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
|
utils::UseRangesCheck::storeOptions(Opts);
|
|
Options.store(Opts, "UseReversePipe", UseReversePipe);
|
|
}
|
|
|
|
bool UseRangesCheck::isLanguageVersionSupported(
|
|
const LangOptions &LangOpts) const {
|
|
return LangOpts.CPlusPlus20;
|
|
}
|
|
ArrayRef<std::pair<StringRef, StringRef>>
|
|
UseRangesCheck::getFreeBeginEndMethods() const {
|
|
static constexpr std::pair<StringRef, StringRef> Refs[] = {
|
|
{"::std::begin", "::std::end"}, {"::std::cbegin", "::std::cend"}};
|
|
return Refs;
|
|
}
|
|
std::optional<UseRangesCheck::ReverseIteratorDescriptor>
|
|
UseRangesCheck::getReverseDescriptor() const {
|
|
static constexpr std::pair<StringRef, StringRef> Refs[] = {
|
|
{"::std::rbegin", "::std::rend"}, {"::std::crbegin", "::std::crend"}};
|
|
return ReverseIteratorDescriptor{"std::views::reverse", "<ranges>", Refs,
|
|
UseReversePipe};
|
|
}
|
|
} // namespace clang::tidy::modernize
|