diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/performance')
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; |