12 #include <clang/Lex/Lexer.h>
18 using namespace ast_matchers;
21 if (!getLangOpts().CPlusPlus)
23 Finder->addMatcher(callExpr(unless(isInTemplateInstantiation()),
24 callee(functionDecl(hasName(
"::std::move"))))
30 const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>(
"call-move");
31 if (CallMove->getNumArgs() != 1)
33 const Expr *Arg = CallMove->getArg(0);
34 SourceManager &
SM = Result.Context->getSourceManager();
36 bool IsConstArg = Arg->getType().isConstQualified();
37 bool IsTriviallyCopyable =
38 Arg->getType().isTriviallyCopyableType(*Result.Context);
40 if (IsConstArg || IsTriviallyCopyable) {
41 auto MoveRange = CharSourceRange::getCharRange(CallMove->getSourceRange());
42 auto FileMoveRange = Lexer::makeFileCharRange(MoveRange, SM, getLangOpts());
43 if (!FileMoveRange.isValid())
45 bool IsVariable = isa<DeclRefExpr>(Arg);
47 diag(FileMoveRange.getBegin(),
"std::move of the %select{|const }0"
48 "%select{expression|variable}1 "
49 "%select{|of trivially-copyable type }2"
50 "has no effect; remove std::move()")
51 << IsConstArg << IsVariable << IsTriviallyCopyable;
53 auto BeforeArgumentsRange = Lexer::makeFileCharRange(
54 CharSourceRange::getCharRange(CallMove->getLocStart(),
57 auto AfterArgumentsRange = Lexer::makeFileCharRange(
58 CharSourceRange::getCharRange(
59 CallMove->getLocEnd(), CallMove->getLocEnd().getLocWithOffset(1)),
62 if (BeforeArgumentsRange.isValid() && AfterArgumentsRange.isValid()) {
63 Diag << FixItHint::CreateRemoval(BeforeArgumentsRange)
64 << FixItHint::CreateRemoval(AfterArgumentsRange);
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register ASTMatchers with Finder.
std::unique_ptr< ast_matchers::MatchFinder > Finder
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.