11 #include "../utils/DeclRefExprUtils.h" 12 #include "../utils/FixItHintUtils.h" 13 #include "../utils/Matchers.h" 14 #include "../utils/OptionsUtils.h" 18 namespace performance {
21 void recordFixes(
const VarDecl &Var, ASTContext &Context,
22 DiagnosticBuilder &Diagnostic) {
24 if (!Var.getType().isLocalConstQualified())
40 auto ConstReference = referenceType(pointee(qualType(isConstQualified())));
48 auto ConstRefReturningMethodCall =
49 cxxMemberCallExpr(callee(cxxMethodDecl(returns(ConstReference))),
50 on(declRefExpr(to(varDecl().bind(
"objectArg")))));
51 auto ConstRefReturningFunctionCall =
52 callExpr(callee(functionDecl(returns(ConstReference))),
53 unless(callee(cxxMethodDecl())));
55 auto localVarCopiedFrom = [
this](
const internal::Matcher<Expr> &CopyCtorArg) {
59 has(varDecl(hasLocalStorage(),
63 unless(hasDeclaration(namedDecl(
64 matchers::matchesAnyListedName(
69 hasDeclaration(cxxConstructorDecl(
70 isCopyConstructor())),
71 hasArgument(0, CopyCtorArg))
78 Finder->addMatcher(localVarCopiedFrom(anyOf(ConstRefReturningFunctionCall,
79 ConstRefReturningMethodCall)),
82 Finder->addMatcher(localVarCopiedFrom(declRefExpr(
83 to(varDecl(hasLocalStorage()).bind(
"oldVarDecl")))),
88 const MatchFinder::MatchResult &
Result) {
89 const auto *NewVar = Result.Nodes.getNodeAs<VarDecl>(
"newVarDecl");
90 const auto *OldVar = Result.Nodes.getNodeAs<VarDecl>(
"oldVarDecl");
91 const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(
"objectArg");
92 const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>(
"blockStmt");
93 const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>(
"ctorCall");
98 Result.Nodes.getNodeAs<DeclStmt>(
"declStmt")->isSingleDecl() &&
99 !NewVar->getLocation().isMacroID();
104 for (
unsigned int i = 1; i < CtorCall->getNumArgs(); ++i)
105 if (!CtorCall->getArg(i)->isDefaultArgument())
108 if (OldVar ==
nullptr) {
109 handleCopyFromMethodReturn(*NewVar, *BlockStmt, IssueFix, ObjectArg,
112 handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, IssueFix,
117 void UnnecessaryCopyInitialization::handleCopyFromMethodReturn(
118 const VarDecl &Var,
const Stmt &BlockStmt,
bool IssueFix,
119 const VarDecl *ObjectArg, ASTContext &Context) {
120 bool IsConstQualified = Var.getType().isConstQualified();
123 if (ObjectArg !=
nullptr &&
128 diag(Var.getLocation(),
129 IsConstQualified ?
"the const qualified variable %0 is " 130 "copy-constructed from a const reference; " 131 "consider making it a const reference" 132 :
"the variable %0 is copy-constructed from a " 133 "const reference but is only used as const " 134 "reference; consider making it a const reference")
137 recordFixes(Var, Context, Diagnostic);
140 void UnnecessaryCopyInitialization::handleCopyFromLocalVar(
141 const VarDecl &NewVar,
const VarDecl &OldVar,
const Stmt &BlockStmt,
142 bool IssueFix, ASTContext &Context) {
147 auto Diagnostic =
diag(NewVar.getLocation(),
148 "local copy %0 of the variable %1 is never modified; " 149 "consider avoiding the copy")
150 << &NewVar << &OldVar;
152 recordFixes(NewVar, Context, Diagnostic);
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.
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.
static constexpr llvm::StringLiteral Name
std::map< std::string, std::string > OptionMap
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
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 &.