clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

UnnecessaryCopyInitialization.cpp
Go to the documentation of this file.
1 //===--- UnnecessaryCopyInitialization.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 "UnnecessaryCopyInitialization.h"
11
12 #include "../utils/LexerUtils.h"
13 #include "../utils/Matchers.h"
14
15 namespace clang {
16 namespace tidy {
17 namespace performance {
18
19 using namespace ::clang::ast_matchers;
20
21 namespace {
22 AST_MATCHER(QualType, isPointerType) { return Node->isPointerType(); }
23 } // namespace
24
25 void UnnecessaryCopyInitialization::registerMatchers(
26 ast_matchers::MatchFinder *Finder) {
27 auto ConstReference = referenceType(pointee(qualType(isConstQualified())));
28 auto ConstOrConstReference =
29 allOf(anyOf(ConstReference, isConstQualified()),
30 unless(allOf(isPointerType(), unless(pointerType(pointee(qualType(
31 isConstQualified())))))));
32 // Match method call expressions where the this argument is a const
33 // type or const reference. This returned const reference is highly likely to
34 // outlive the local const reference of the variable being declared.
35 // The assumption is that the const reference being returned either points
36 // to a global static variable or to a member of the called object.
37 auto ConstRefReturningMethodCallOfConstParam = cxxMemberCallExpr(
38 callee(cxxMethodDecl(returns(ConstReference))),
39 on(declRefExpr(to(varDecl(hasType(qualType(ConstOrConstReference)))))));
40 auto ConstRefReturningFunctionCall =
41 callExpr(callee(functionDecl(returns(ConstReference))),
42 unless(callee(cxxMethodDecl())));
43 Finder->addMatcher(
44 varDecl(
45 hasLocalStorage(), hasType(isConstQualified()),
46 hasType(matchers::isExpensiveToCopy()),
47 hasInitializer(cxxConstructExpr(
48 hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
49 hasArgument(0, anyOf(ConstRefReturningFunctionCall,
50 ConstRefReturningMethodCallOfConstParam)))))
51 .bind("varDecl"),
52 this);
53 }
54
55 void UnnecessaryCopyInitialization::check(
56 const ast_matchers::MatchFinder::MatchResult &Result) {
57 const auto *Var = Result.Nodes.getNodeAs<VarDecl>("varDecl");
58 SourceLocation AmpLocation = Var->getLocation();
59 auto Token = lexer_utils::getPreviousNonCommentToken(*Result.Context,
60 Var->getLocation());
61 if (!Token.is(tok::unknown)) {
62 AmpLocation = Token.getLocation().getLocWithOffset(Token.getLength());
63 }
64 diag(Var->getLocation(),
65 "the const qualified variable '%0' is copy-constructed from a "
66 "const reference; consider making it a const reference")
67 << Var->getName() << FixItHint::CreateInsertion(AmpLocation, "&");
68 }
69
70 } // namespace performance
71 } // namespace tidy
72 } // namespace clang
clang::tidy::performance::UnnecessaryCopyInitialization::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register ASTMatchers with Finder.
Definition: UnnecessaryCopyInitialization.cpp:25
Finder
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
clang::tidy::lexer_utils::getPreviousNonCommentToken
Token getPreviousNonCommentToken(const ASTContext &Context, SourceLocation Location)
Definition: LexerUtils.cpp:16
clang::tidy::AST_MATCHER
AST_MATCHER(Stmt, isInsideOfRangeBeginEndStmt)
Definition: ProBoundsArrayToPointerDecayCheck.cpp:25
clang::tidy::type_traits::isExpensiveToCopy
llvm::Optional< bool > isExpensiveToCopy(QualType Type, ASTContext &Context)
Definition: TypeTraits.cpp:27
clang::tidy::performance::UnnecessaryCopyInitialization::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: UnnecessaryCopyInitialization.cpp:55
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidy.cpp:323
Result
const NamedDecl * Result
Definition: USRFinder.cpp:121
UnnecessaryCopyInitialization.h