11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
15 using namespace clang::ast_matchers;
22 AST_MATCHER(Decl, isInStdNamespace) {
return Node.isInStdNamespace(); }
25 void InaccurateEraseCheck::registerMatchers(MatchFinder *
Finder) {
28 if (!getLangOpts().CPlusPlus)
33 callee(functionDecl(hasAnyName(
"remove",
"remove_if",
"unique"))),
36 anyOf(cxxConstructExpr(has(ignoringImplicit(
37 cxxMemberCallExpr(callee(cxxMethodDecl(hasName(
"end"))))
42 const auto DeclInStd = decl(isInStdNamespace());
45 on(anyOf(hasType(DeclInStd), hasType(pointsTo(DeclInStd)))),
46 callee(cxxMethodDecl(hasName(
"erase"))), argumentCountIs(1),
47 hasArgument(0, has(ignoringImplicit(
48 anyOf(EndCall, has(ignoringImplicit(EndCall)))))),
49 unless(isInTemplateInstantiation()))
54 void InaccurateEraseCheck::check(
const MatchFinder::MatchResult &Result) {
55 const auto *MemberCall =
56 Result.Nodes.getNodeAs<CXXMemberCallExpr>(
"erase");
58 Result.Nodes.getNodeAs<CXXMemberCallExpr>(
"end");
59 const SourceLocation
Loc = MemberCall->getLocStart();
63 if (!Loc.isMacroID() && EndExpr) {
64 const auto *AlgCall = Result.Nodes.getNodeAs<CallExpr>(
"alg");
65 std::string ReplacementText = Lexer::getSourceText(
66 CharSourceRange::getTokenRange(EndExpr->getSourceRange()),
67 *Result.SourceManager, getLangOpts());
68 const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
69 AlgCall->getLocEnd(), 0, *Result.SourceManager, getLangOpts());
70 Hint = FixItHint::CreateInsertion(EndLoc,
", " + ReplacementText);
73 diag(Loc,
"this call will remove at most one item even when multiple items "
SourceLocation Loc
'#' location in the include directive
std::unique_ptr< ast_matchers::MatchFinder > Finder
AST_MATCHER(VarDecl, isAsm)