12 #include "../utils/DeclRefExprUtils.h" 13 #include "../utils/FixItHintUtils.h" 14 #include "../utils/Matchers.h" 15 #include "../utils/OptionsUtils.h" 19 namespace performance {
22 void recordFixes(
const VarDecl &Var, ASTContext &Context,
23 DiagnosticBuilder &Diagnostic) {
25 if (!Var.getType().isLocalConstQualified())
41 auto ConstReference = referenceType(pointee(qualType(isConstQualified())));
49 auto ConstRefReturningMethodCall =
50 cxxMemberCallExpr(callee(cxxMethodDecl(returns(ConstReference))),
51 on(declRefExpr(to(varDecl().bind(
"objectArg")))));
52 auto ConstRefReturningFunctionCall =
53 callExpr(callee(functionDecl(returns(ConstReference))),
54 unless(callee(cxxMethodDecl())));
56 auto localVarCopiedFrom = [
this](
const internal::Matcher<Expr> &CopyCtorArg) {
60 has(varDecl(hasLocalStorage(),
64 unless(hasDeclaration(namedDecl(
65 matchers::matchesAnyListedName(
70 hasDeclaration(cxxConstructorDecl(
71 isCopyConstructor())),
72 hasArgument(0, CopyCtorArg))
79 Finder->addMatcher(localVarCopiedFrom(anyOf(ConstRefReturningFunctionCall,
80 ConstRefReturningMethodCall)),
83 Finder->addMatcher(localVarCopiedFrom(declRefExpr(
84 to(varDecl(hasLocalStorage()).bind(
"oldVarDecl")))),
89 const MatchFinder::MatchResult &
Result) {
90 const auto *NewVar = Result.Nodes.getNodeAs<VarDecl>(
"newVarDecl");
91 const auto *OldVar = Result.Nodes.getNodeAs<VarDecl>(
"oldVarDecl");
92 const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(
"objectArg");
93 const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>(
"blockStmt");
94 const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>(
"ctorCall");
99 Result.Nodes.getNodeAs<DeclStmt>(
"declStmt")->isSingleDecl() &&
100 !NewVar->getLocation().isMacroID();
105 for (
unsigned int i = 1; i < CtorCall->getNumArgs(); ++i)
106 if (!CtorCall->getArg(i)->isDefaultArgument())
109 if (OldVar ==
nullptr) {
110 handleCopyFromMethodReturn(*NewVar, *BlockStmt, IssueFix, ObjectArg,
113 handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, IssueFix,
118 void UnnecessaryCopyInitialization::handleCopyFromMethodReturn(
119 const VarDecl &Var,
const Stmt &BlockStmt,
bool IssueFix,
120 const VarDecl *ObjectArg, ASTContext &Context) {
121 bool IsConstQualified = Var.getType().isConstQualified();
124 if (ObjectArg !=
nullptr &&
129 diag(Var.getLocation(),
130 IsConstQualified ?
"the const qualified variable %0 is " 131 "copy-constructed from a const reference; " 132 "consider making it a const reference" 133 :
"the variable %0 is copy-constructed from a " 134 "const reference but is only used as const " 135 "reference; consider making it a const reference")
138 recordFixes(Var, Context, Diagnostic);
141 void UnnecessaryCopyInitialization::handleCopyFromLocalVar(
142 const VarDecl &NewVar,
const VarDecl &OldVar,
const Stmt &BlockStmt,
143 bool IssueFix, ASTContext &Context) {
148 auto Diagnostic =
diag(NewVar.getLocation(),
149 "local copy %0 of the variable %1 is never modified; " 150 "consider avoiding the copy")
151 << &NewVar << &OldVar;
153 recordFixes(NewVar, Context, Diagnostic);
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
std::string serializeStringList(ArrayRef< std::string > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt, ASTContext &Context)
Returns true if all DeclRefExpr to the variable within Stmt do not modify it.
Base class for all clang-tidy checks.
std::vector< std::string > parseStringList(StringRef Option)
Parse a semicolon separated list of strings.
llvm::Optional< bool > isExpensiveToCopy(QualType Type, const ASTContext &Context)
Returns true if Type is expensive to copy.
static constexpr llvm::StringLiteral Name
std::map< std::string, std::string > OptionMap
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
FixItHint changeVarDeclToConst(const VarDecl &Var)
Creates fix to make VarDecl const qualified.
FixItHint changeVarDeclToReference(const VarDecl &Var, ASTContext &Context)
Creates fix to make VarDecl a reference by adding &.