brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 529b5a4 Raw
205 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "UseRangesCheck.h"10#include "clang/AST/Decl.h"11#include "llvm/ADT/ArrayRef.h"12#include "llvm/ADT/IntrusiveRefCntPtr.h"13#include "llvm/ADT/SmallVector.h"14#include "llvm/ADT/StringRef.h"15#include <initializer_list>16 17// FixItHint - Let the docs script know that this class does provide fixits18 19namespace clang::tidy::modernize {20 21static constexpr const char *SingleRangeNames[] = {22    "all_of",23    "any_of",24    "none_of",25    "for_each",26    "find",27    "find_if",28    "find_if_not",29    "adjacent_find",30    "copy",31    "copy_if",32    "copy_backward",33    "move",34    "move_backward",35    "fill",36    "transform",37    "replace",38    "replace_if",39    "generate",40    "remove",41    "remove_if",42    "remove_copy",43    "remove_copy_if",44    "unique",45    "unique_copy",46    "sample",47    "partition_point",48    "lower_bound",49    "upper_bound",50    "equal_range",51    "binary_search",52    "push_heap",53    "pop_heap",54    "make_heap",55    "sort_heap",56    "next_permutation",57    "prev_permutation",58    "reverse",59    "reverse_copy",60    "shift_left",61    "shift_right",62    "is_partitioned",63    "partition",64    "partition_copy",65    "stable_partition",66    "sort",67    "stable_sort",68    "is_sorted",69    "is_sorted_until",70    "is_heap",71    "is_heap_until",72    "max_element",73    "min_element",74    "minmax_element",75    "uninitialized_copy",76    "uninitialized_fill",77    "uninitialized_move",78    "uninitialized_default_construct",79    "uninitialized_value_construct",80    "destroy",81};82 83static constexpr const char *TwoRangeNames[] = {84    "equal",85    "mismatch",86    "partial_sort_copy",87    "includes",88    "set_union",89    "set_intersection",90    "set_difference",91    "set_symmetric_difference",92    "merge",93    "lexicographical_compare",94    "find_end",95    "search",96    "is_permutation",97};98 99static constexpr const char *SinglePivotRangeNames[] = {"rotate", "rotate_copy",100                                                        "inplace_merge"};101 102namespace {103class StdReplacer : public utils::UseRangesCheck::Replacer {104public:105  explicit StdReplacer(SmallVector<UseRangesCheck::Signature> Signatures)106      : Signatures(std::move(Signatures)) {}107  std::optional<std::string>108  getReplaceName(const NamedDecl &OriginalName) const override {109    return ("std::ranges::" + OriginalName.getName()).str();110  }111  ArrayRef<UseRangesCheck::Signature>112  getReplacementSignatures() const override {113    return Signatures;114  }115 116private:117  SmallVector<UseRangesCheck::Signature> Signatures;118};119 120class StdAlgorithmReplacer : public StdReplacer {121  using StdReplacer::StdReplacer;122  std::optional<std::string>123  getHeaderInclusion(const NamedDecl & /*OriginalName*/) const override {124    return "<algorithm>";125  }126};127 128class StdNumericReplacer : public StdReplacer {129  using StdReplacer::StdReplacer;130  std::optional<std::string>131  getHeaderInclusion(const NamedDecl & /*OriginalName*/) const override {132    return "<numeric>";133  }134};135} // namespace136 137utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const {138  utils::UseRangesCheck::ReplacerMap Result;139 140  // template<typename Iter> Func(Iter first, Iter last,...).141  static const Signature SingleRangeArgs = {{0}};142  // template<typename Iter1, typename Iter2>143  // Func(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2,...).144  static const Signature TwoRangeArgs = {{0}, {2}};145 146  // template<typename Iter> Func(Iter first, Iter pivot, Iter last,...).147  static const Signature SinglePivotRange = {{0, 2}};148 149  static const Signature SingleRangeFunc[] = {SingleRangeArgs};150 151  static const Signature TwoRangeFunc[] = {TwoRangeArgs};152 153  static const Signature SinglePivotFunc[] = {SinglePivotRange};154 155  static const std::pair<ArrayRef<Signature>, ArrayRef<const char *>>156      AlgorithmNames[] = {{SingleRangeFunc, SingleRangeNames},157                          {TwoRangeFunc, TwoRangeNames},158                          {SinglePivotFunc, SinglePivotRangeNames}};159  SmallString<64> Buff;160  for (const auto &[Signatures, Values] : AlgorithmNames) {161    auto Replacer = llvm::makeIntrusiveRefCnt<StdAlgorithmReplacer>(162        SmallVector<UseRangesCheck::Signature>{Signatures});163    for (const auto &Name : Values) {164      Buff.assign({"::std::", Name});165      Result.try_emplace(Buff, Replacer);166    }167  }168  if (getLangOpts().CPlusPlus23)169    Result.try_emplace(170        "::std::iota",171        llvm::makeIntrusiveRefCnt<StdNumericReplacer>(172            SmallVector<UseRangesCheck::Signature>{std::begin(SingleRangeFunc),173                                                   std::end(SingleRangeFunc)}));174  return Result;175}176 177UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context)178    : utils::UseRangesCheck(Name, Context),179      UseReversePipe(Options.get("UseReversePipe", false)) {}180 181void UseRangesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {182  utils::UseRangesCheck::storeOptions(Opts);183  Options.store(Opts, "UseReversePipe", UseReversePipe);184}185 186bool UseRangesCheck::isLanguageVersionSupported(187    const LangOptions &LangOpts) const {188  return LangOpts.CPlusPlus20;189}190ArrayRef<std::pair<StringRef, StringRef>>191UseRangesCheck::getFreeBeginEndMethods() const {192  static const std::pair<StringRef, StringRef> Refs[] = {193      {"::std::begin", "::std::end"}, {"::std::cbegin", "::std::cend"}};194  return Refs;195}196std::optional<UseRangesCheck::ReverseIteratorDescriptor>197UseRangesCheck::getReverseDescriptor() const {198  static const std::pair<StringRef, StringRef> Refs[] = {199      {"::std::rbegin", "::std::rend"}, {"::std::crbegin", "::std::crend"}};200  return ReverseIteratorDescriptor{UseReversePipe ? "std::views::reverse"201                                                  : "std::ranges::reverse_view",202                                   "<ranges>", Refs, UseReversePipe};203}204} // namespace clang::tidy::modernize205