[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:08 PDT 2024


================
@@ -0,0 +1,248 @@
+//===--- 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 "Matchers.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <limits>
+#include <optional>
+#include <string>
+
+using namespace clang::ast_matchers;
+
+static constexpr const char BoundCall[] = "CallExpr";
+static constexpr const char FuncDecl[] = "FuncDecl";
+static constexpr const char ArgName[] = "ArgName";
+
+namespace clang::tidy::utils {
+
+static bool operator==(const UseRangesCheck::Indexes &L,
+                       const UseRangesCheck::Indexes &R) {
+  return std::tie(L.BeginArg, L.EndArg, L.ReplaceArg) ==
+         std::tie(R.BeginArg, R.EndArg, R.ReplaceArg);
+}
+
+static std::string getFullPrefix(ArrayRef<UseRangesCheck::Indexes> Signature) {
+  std::string Output;
+  llvm::raw_string_ostream OS(Output);
+  for (const UseRangesCheck::Indexes &Item : Signature) {
+    OS << Item.BeginArg << ":" << Item.EndArg << ":"
+       << (Item.ReplaceArg == Item.First ? '0' : '1');
+  }
+  return Output;
+}
+
+static llvm::hash_code hash_value(const UseRangesCheck::Indexes &Indexes) {
+  return llvm::hash_combine(Indexes.BeginArg, Indexes.EndArg,
+                            Indexes.ReplaceArg);
+}
+
+static llvm::hash_code hash_value(const UseRangesCheck::Signature &Sig) {
+  return llvm::hash_combine_range(Sig.begin(), Sig.end());
+}
+
+namespace {
+
+AST_MATCHER(Expr, hasSideEffects) {
+  return Node.HasSideEffects(Finder->getASTContext());
+}
+} // namespace
+
+static auto makeMatcher(bool IsBegin, StringRef Prefix) {
+  auto Member =
+      IsBegin ? expr(unless(hasSideEffects())).bind((ArgName + Prefix).str())
+              : expr(matchers::isStatementIdenticalToBoundNode(
+                    (ArgName + Prefix).str()));
----------------
5chmidti wrote:

Please add a comment explaining that the `makeMatcherPair` will ensure that this function is called first with `IsBegin` as `true`, then as `false`. Therefore, the begin `Member` will bind `ArgName + Prefix` before the end `Member` compares it.

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


More information about the cfe-commits mailing list