clang-tools  3.8.0
MoveConstantArgumentCheck.cpp
Go to the documentation of this file.
1 //===--- MoveConstandArgumentCheck.cpp - clang-tidy -----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 
12 #include <clang/Lex/Lexer.h>
13 
14 namespace clang {
15 namespace tidy {
16 namespace misc {
17 
18 using namespace ast_matchers;
19 
21  if (!getLangOpts().CPlusPlus)
22  return;
23  Finder->addMatcher(callExpr(unless(isInTemplateInstantiation()),
24  callee(functionDecl(hasName("::std::move"))))
25  .bind("call-move"),
26  this);
27 }
28 
29 void MoveConstantArgumentCheck::check(const MatchFinder::MatchResult &Result) {
30  const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move");
31  if (CallMove->getNumArgs() != 1)
32  return;
33  const Expr *Arg = CallMove->getArg(0);
34  SourceManager &SM = Result.Context->getSourceManager();
35 
36  bool IsConstArg = Arg->getType().isConstQualified();
37  bool IsTriviallyCopyable =
38  Arg->getType().isTriviallyCopyableType(*Result.Context);
39 
40  if (IsConstArg || IsTriviallyCopyable) {
41  auto MoveRange = CharSourceRange::getCharRange(CallMove->getSourceRange());
42  auto FileMoveRange = Lexer::makeFileCharRange(MoveRange, SM, getLangOpts());
43  if (!FileMoveRange.isValid())
44  return;
45  bool IsVariable = isa<DeclRefExpr>(Arg);
46  auto Diag =
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;
52 
53  auto BeforeArgumentsRange = Lexer::makeFileCharRange(
54  CharSourceRange::getCharRange(CallMove->getLocStart(),
55  Arg->getLocStart()),
56  SM, getLangOpts());
57  auto AfterArgumentsRange = Lexer::makeFileCharRange(
58  CharSourceRange::getCharRange(
59  CallMove->getLocEnd(), CallMove->getLocEnd().getLocWithOffset(1)),
60  SM, getLangOpts());
61 
62  if (BeforeArgumentsRange.isValid() && AfterArgumentsRange.isValid()) {
63  Diag << FixItHint::CreateRemoval(BeforeArgumentsRange)
64  << FixItHint::CreateRemoval(AfterArgumentsRange);
65  }
66  }
67 }
68 
69 } // namespace misc
70 } // namespace tidy
71 } // namespace clang
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register ASTMatchers with Finder.
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
SourceManager & SM
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
const NamedDecl * Result
Definition: USRFinder.cpp:121