clang-tools  14.0.0git
InaccurateEraseCheck.cpp
Go to the documentation of this file.
1 //===--- InaccurateEraseCheck.cpp - clang-tidy-----------------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "InaccurateEraseCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Lex/Lexer.h"
13 
14 using namespace clang::ast_matchers;
15 
16 namespace clang {
17 namespace tidy {
18 namespace bugprone {
19 
20 void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
21  const auto EndCall =
22  callExpr(
23  callee(functionDecl(hasAnyName("remove", "remove_if", "unique"))),
24  hasArgument(
25  1, optionally(cxxMemberCallExpr(callee(cxxMethodDecl(hasName("end"))))
26  .bind("end"))))
27  .bind("alg");
28 
29  const auto DeclInStd = type(hasUnqualifiedDesugaredType(
30  tagType(hasDeclaration(decl(isInStdNamespace())))));
31  Finder->addMatcher(
32  cxxMemberCallExpr(
33  on(anyOf(hasType(DeclInStd), hasType(pointsTo(DeclInStd)))),
34  callee(cxxMethodDecl(hasName("erase"))), argumentCountIs(1),
35  hasArgument(0, EndCall))
36  .bind("erase"),
37  this);
38 }
39 
40 void InaccurateEraseCheck::check(const MatchFinder::MatchResult &Result) {
41  const auto *MemberCall =
42  Result.Nodes.getNodeAs<CXXMemberCallExpr>("erase");
43  const auto *EndExpr =
44  Result.Nodes.getNodeAs<CXXMemberCallExpr>("end");
45  const SourceLocation Loc = MemberCall->getBeginLoc();
46 
47  FixItHint Hint;
48 
49  if (!Loc.isMacroID() && EndExpr) {
50  const auto *AlgCall = Result.Nodes.getNodeAs<CallExpr>("alg");
51  std::string ReplacementText = std::string(Lexer::getSourceText(
52  CharSourceRange::getTokenRange(EndExpr->getSourceRange()),
53  *Result.SourceManager, getLangOpts()));
54  const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
55  AlgCall->getEndLoc(), 0, *Result.SourceManager, getLangOpts());
56  Hint = FixItHint::CreateInsertion(EndLoc, ", " + ReplacementText);
57  }
58 
59  diag(Loc, "this call will remove at most one item even when multiple items "
60  "should be removed")
61  << Hint;
62 }
63 
64 } // namespace bugprone
65 } // namespace tidy
66 } // namespace clang
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
clang::tidy::cppcoreguidelines::getSourceText
static std::string getSourceText(const CXXDestructorDecl &Destructor)
Definition: VirtualClassDestructorCheck.cpp:112
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang::clangd::check
bool check(llvm::StringRef File, llvm::function_ref< bool(const Position &)> ShouldCheckLine, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, bool EnableCodeCompletion)
Definition: Check.cpp:259
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
InaccurateEraseCheck.h