clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
10 #include "MoveConstantArgumentCheck.h"
11
12 #include <clang/Lex/Lexer.h>
13
14 namespace clang {
15 namespace tidy {
16 namespace misc {
17
18 using namespace ast_matchers;
19
20 void MoveConstantArgumentCheck::registerMatchers(MatchFinder *Finder) {
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
clang::tidy::misc::MoveConstantArgumentCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register ASTMatchers with Finder.
Definition: MoveConstantArgumentCheck.cpp:20
Finder
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
SM
SourceManager & SM
Definition: IncludeOrderCheck.cpp:44
clang::tidy::misc::MoveConstantArgumentCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: MoveConstantArgumentCheck.cpp:29
MoveConstantArgumentCheck.h
Result
const NamedDecl * Result
Definition: USRFinder.cpp:121