aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-tidy/performance
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy/performance')
-rw-r--r--clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp8
-rw-r--r--clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp55
-rw-r--r--clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp25
3 files changed, 45 insertions, 43 deletions
diff --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
index 7022e9d..1c01899 100644
--- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
@@ -42,11 +42,11 @@ void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) {
// A matcher for a `DstT::DstT(const Src&)` where DstT also has a
// `DstT::DstT(Src&&)`.
const auto LValueRefCtor = cxxConstructorDecl(
- hasParameter(0,
- hasType(lValueReferenceType(pointee(type().bind("SrcT"))))),
+ hasParameter(0, hasType(hasCanonicalType(
+ lValueReferenceType(pointee(type().bind("SrcT")))))),
ofClass(cxxRecordDecl(hasMethod(cxxConstructorDecl(
- hasParameter(0, hasType(rValueReferenceType(
- pointee(type(equalsBoundNode("SrcT")))))))))));
+ hasParameter(0, hasType(hasCanonicalType(rValueReferenceType(
+ pointee(type(equalsBoundNode("SrcT"))))))))))));
// A matcher for `DstT::DstT(const Src&&)`, which typically comes from an
// instantiation of `template <typename U> DstT::DstT(U&&)`.
diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index b6f1981..c413090 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -17,7 +17,6 @@
#include <optional>
namespace clang::tidy::performance {
-namespace {
using namespace ::clang::ast_matchers;
using llvm::StringRef;
@@ -30,8 +29,8 @@ static constexpr StringRef MethodDeclId = "methodDecl";
static constexpr StringRef FunctionDeclId = "functionDecl";
static constexpr StringRef OldVarDeclId = "oldVarDecl";
-void recordFixes(const VarDecl &Var, ASTContext &Context,
- DiagnosticBuilder &Diagnostic) {
+static void recordFixes(const VarDecl &Var, ASTContext &Context,
+ DiagnosticBuilder &Diagnostic) {
Diagnostic << utils::fixit::changeVarDeclToReference(Var, Context);
if (!Var.getType().isLocalConstQualified()) {
if (std::optional<FixItHint> Fix = utils::fixit::addQualifierToVarDecl(
@@ -40,8 +39,8 @@ void recordFixes(const VarDecl &Var, ASTContext &Context,
}
}
-std::optional<SourceLocation> firstLocAfterNewLine(SourceLocation Loc,
- SourceManager &SM) {
+static std::optional<SourceLocation> firstLocAfterNewLine(SourceLocation Loc,
+ SourceManager &SM) {
bool Invalid = false;
const char *TextAfter = SM.getCharacterData(Loc, &Invalid);
if (Invalid) {
@@ -51,8 +50,8 @@ std::optional<SourceLocation> firstLocAfterNewLine(SourceLocation Loc,
return Loc.getLocWithOffset(TextAfter[Offset] == '\0' ? Offset : Offset + 1);
}
-void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
- DiagnosticBuilder &Diagnostic) {
+static void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
+ DiagnosticBuilder &Diagnostic) {
auto &SM = Context.getSourceManager();
// Attempt to remove trailing comments as well.
auto Tok = utils::lexer::findNextTokenSkippingComments(Stmt.getEndLoc(), SM,
@@ -74,6 +73,8 @@ void recordRemoval(const DeclStmt &Stmt, ASTContext &Context,
}
}
+namespace {
+
AST_MATCHER_FUNCTION_P(StatementMatcher,
isRefReturningMethodCallWithConstOverloads,
std::vector<StringRef>, ExcludedContainerTypes) {
@@ -130,6 +131,8 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, initializerReturnsReferenceToConst,
hasUnaryOperand(OldVarDeclRef)))));
}
+} // namespace
+
// This checks that the variable itself is only used as const, and also makes
// sure that it does not reference another variable that could be modified in
// the BlockStmt. It does this by checking the following:
@@ -180,13 +183,13 @@ static bool isInitializingVariableImmutable(
return false;
}
-bool isVariableUnused(const VarDecl &Var, const Stmt &BlockStmt,
- ASTContext &Context) {
+static bool isVariableUnused(const VarDecl &Var, const Stmt &BlockStmt,
+ ASTContext &Context) {
return allDeclRefExprs(Var, BlockStmt, Context).empty();
}
-const SubstTemplateTypeParmType *getSubstitutedType(const QualType &Type,
- ASTContext &Context) {
+static const SubstTemplateTypeParmType *
+getSubstitutedType(const QualType &Type, ASTContext &Context) {
auto Matches = match(
qualType(anyOf(substTemplateTypeParmType().bind("subst"),
hasDescendant(substTemplateTypeParmType().bind("subst")))),
@@ -194,9 +197,9 @@ const SubstTemplateTypeParmType *getSubstitutedType(const QualType &Type,
return selectFirst<SubstTemplateTypeParmType>("subst", Matches);
}
-bool differentReplacedTemplateParams(const QualType &VarType,
- const QualType &InitializerType,
- ASTContext &Context) {
+static bool differentReplacedTemplateParams(const QualType &VarType,
+ const QualType &InitializerType,
+ ASTContext &Context) {
if (const SubstTemplateTypeParmType *VarTmplType =
getSubstitutedType(VarType, Context)) {
if (const SubstTemplateTypeParmType *InitializerTmplType =
@@ -212,8 +215,8 @@ bool differentReplacedTemplateParams(const QualType &VarType,
return false;
}
-QualType constructorArgumentType(const VarDecl *OldVar,
- const BoundNodes &Nodes) {
+static QualType constructorArgumentType(const VarDecl *OldVar,
+ const BoundNodes &Nodes) {
if (OldVar) {
return OldVar->getType();
}
@@ -224,8 +227,6 @@ QualType constructorArgumentType(const VarDecl *OldVar,
return MethodDecl->getReturnType();
}
-} // namespace
-
UnnecessaryCopyInitialization::UnnecessaryCopyInitialization(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@@ -349,12 +350,13 @@ void UnnecessaryCopyInitialization::diagnoseCopyFromMethodReturn(
const CheckContext &Ctx) {
auto Diagnostic =
diag(Ctx.Var.getLocation(),
- "the %select{|const qualified }0variable %1 is "
+ "the %select{|const qualified }0variable %1 of type %2 is "
"copy-constructed "
"from a const reference%select{%select{ but is only used as const "
- "reference|}0| but is never used}2; consider "
- "%select{making it a const reference|removing the statement}2")
- << Ctx.Var.getType().isConstQualified() << &Ctx.Var << Ctx.IsVarUnused;
+ "reference|}0| but is never used}3; consider "
+ "%select{making it a const reference|removing the statement}3")
+ << Ctx.Var.getType().isConstQualified() << &Ctx.Var << Ctx.Var.getType()
+ << Ctx.IsVarUnused;
maybeIssueFixes(Ctx, Diagnostic);
}
@@ -362,10 +364,11 @@ void UnnecessaryCopyInitialization::diagnoseCopyFromLocalVar(
const CheckContext &Ctx, const VarDecl &OldVar) {
auto Diagnostic =
diag(Ctx.Var.getLocation(),
- "local copy %1 of the variable %0 is never modified%select{"
- "| and never used}2; consider %select{avoiding the copy|removing "
- "the statement}2")
- << &OldVar << &Ctx.Var << Ctx.IsVarUnused;
+ "local copy %0 of the variable %1 of type %2 is never "
+ "modified%select{"
+ "| and never used}3; consider %select{avoiding the copy|removing "
+ "the statement}3")
+ << &Ctx.Var << &OldVar << Ctx.Var.getType() << Ctx.IsVarUnused;
maybeIssueFixes(Ctx, Diagnostic);
}
diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
index d89c3a6..c1aa52b 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
@@ -21,16 +21,14 @@ using namespace clang::ast_matchers;
namespace clang::tidy::performance {
-namespace {
-
-std::string paramNameOrIndex(StringRef Name, size_t Index) {
+static std::string paramNameOrIndex(StringRef Name, size_t Index) {
return (Name.empty() ? llvm::Twine('#') + llvm::Twine(Index + 1)
: llvm::Twine('\'') + Name + llvm::Twine('\''))
.str();
}
-bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
- ASTContext &Context) {
+static bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
+ ASTContext &Context) {
auto Matches = match(
traverse(TK_AsIs,
decl(forEachDescendant(declRefExpr(
@@ -41,8 +39,6 @@ bool hasLoopStmtAncestor(const DeclRefExpr &DeclRef, const Decl &Decl,
return Matches.empty();
}
-} // namespace
-
UnnecessaryValueParamCheck::UnnecessaryValueParamCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
@@ -143,10 +139,12 @@ void UnnecessaryValueParamCheck::handleConstRefFix(const FunctionDecl &Function,
auto Diag =
diag(Param.getLocation(),
- "the %select{|const qualified }0parameter %1 is copied for each "
+ "the %select{|const qualified }0parameter %1 of type %2 is copied "
+ "for each "
"invocation%select{ but only used as a const reference|}0; consider "
"making it a %select{const |}0reference")
- << IsConstQualified << paramNameOrIndex(Param.getName(), Index);
+ << IsConstQualified << paramNameOrIndex(Param.getName(), Index)
+ << Param.getType();
// Do not propose fixes when:
// 1. the ParmVarDecl is in a macro, since we cannot place them correctly
// 2. the function is virtual as it might break overrides
@@ -173,10 +171,11 @@ void UnnecessaryValueParamCheck::handleConstRefFix(const FunctionDecl &Function,
void UnnecessaryValueParamCheck::handleMoveFix(const ParmVarDecl &Param,
const DeclRefExpr &CopyArgument,
ASTContext &Context) {
- auto Diag = diag(CopyArgument.getBeginLoc(),
- "parameter %0 is passed by value and only copied once; "
- "consider moving it to avoid unnecessary copies")
- << &Param;
+ auto Diag =
+ diag(CopyArgument.getBeginLoc(),
+ "parameter %0 of type %1 is passed by value and only copied once; "
+ "consider moving it to avoid unnecessary copies")
+ << &Param << Param.getType();
// Do not propose fixes in macros since we cannot place them correctly.
if (CopyArgument.getBeginLoc().isMacroID())
return;