diff options
author | Malcolm Parsons <malcolm.parsons@gmail.com> | 2017-01-03 12:10:44 +0000 |
---|---|---|
committer | Malcolm Parsons <malcolm.parsons@gmail.com> | 2017-01-03 12:10:44 +0000 |
commit | f74e4f516710dec29059d3aef36e7dd3645937f1 (patch) | |
tree | 18c2cf8f6a23156525487030add506b506414b6a /clang-tidy/utils | |
parent | 3424f854215556c26553748aafc4abdc34ad30bb (diff) |
[clang-tidy] Handle constructors in performance-unnecessary-value-param
Summary:
modernize-pass-by-value doesn't warn about value parameters that
cannot be moved, so performance-unnecessary-value-param should.
Reviewers: aaron.ballman, flx, alexfh
Subscribers: JDevlieghere, cfe-commits
Differential Revision: https://reviews.llvm.org/D28022
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@290883 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy/utils')
-rw-r--r-- | clang-tidy/utils/DeclRefExprUtils.cpp | 57 | ||||
-rw-r--r-- | clang-tidy/utils/DeclRefExprUtils.h | 27 |
2 files changed, 70 insertions, 14 deletions
diff --git a/clang-tidy/utils/DeclRefExprUtils.cpp b/clang-tidy/utils/DeclRefExprUtils.cpp index 11d0c311..a28b1d25 100644 --- a/clang-tidy/utils/DeclRefExprUtils.cpp +++ b/clang-tidy/utils/DeclRefExprUtils.cpp @@ -71,6 +71,40 @@ constReferenceDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, return DeclRefs; } +// Finds all DeclRefExprs where a const method is called on VarDecl or VarDecl +// is the a const reference or value argument to a CallExpr or CXXConstructExpr. +SmallPtrSet<const DeclRefExpr *, 16> +constReferenceDeclRefExprs(const VarDecl &VarDecl, const Decl &Decl, + ASTContext &Context) { + auto DeclRefToVar = + declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind("declRef"); + auto ConstMethodCallee = callee(cxxMethodDecl(isConst())); + // Match method call expressions where the variable is referenced as the this + // implicit object argument and opertor call expression for member operators + // where the variable is the 0-th argument. + auto Matches = + match(decl(forEachDescendant(expr( + anyOf(cxxMemberCallExpr(ConstMethodCallee, on(DeclRefToVar)), + cxxOperatorCallExpr(ConstMethodCallee, + hasArgument(0, DeclRefToVar)))))), + Decl, Context); + SmallPtrSet<const DeclRefExpr *, 16> DeclRefs; + extractNodesByIdTo(Matches, "declRef", DeclRefs); + auto ConstReferenceOrValue = + qualType(anyOf(referenceType(pointee(qualType(isConstQualified()))), + unless(anyOf(referenceType(), pointerType())))); + auto UsedAsConstRefOrValueArg = forEachArgumentWithParam( + DeclRefToVar, parmVarDecl(hasType(ConstReferenceOrValue))); + Matches = match(decl(forEachDescendant(callExpr(UsedAsConstRefOrValueArg))), + Decl, Context); + extractNodesByIdTo(Matches, "declRef", DeclRefs); + Matches = + match(decl(forEachDescendant(cxxConstructExpr(UsedAsConstRefOrValueArg))), + Decl, Context); + extractNodesByIdTo(Matches, "declRef", DeclRefs); + return DeclRefs; +} + bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt, ASTContext &Context) { // Collect all DeclRefExprs to the loop variable and all CallExprs and @@ -93,30 +127,41 @@ allDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context) { return DeclRefs; } -bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Stmt &Stmt, +SmallPtrSet<const DeclRefExpr *, 16> +allDeclRefExprs(const VarDecl &VarDecl, const Decl &Decl, ASTContext &Context) { + auto Matches = match( + decl(forEachDescendant( + declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind("declRef"))), + Decl, Context); + SmallPtrSet<const DeclRefExpr *, 16> DeclRefs; + extractNodesByIdTo(Matches, "declRef", DeclRefs); + return DeclRefs; +} + +bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context) { auto UsedAsConstRefArg = forEachArgumentWithParam( declRefExpr(equalsNode(&DeclRef)), parmVarDecl(hasType(matchers::isReferenceToConst()))); auto Matches = match( - stmt(hasDescendant( + decl(hasDescendant( cxxConstructExpr(UsedAsConstRefArg, hasDeclaration(cxxConstructorDecl( isCopyConstructor()))) .bind("constructExpr"))), - Stmt, Context); + Decl, Context); return !Matches.empty(); } -bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Stmt &Stmt, +bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context) { auto UsedAsConstRefArg = forEachArgumentWithParam( declRefExpr(equalsNode(&DeclRef)), parmVarDecl(hasType(matchers::isReferenceToConst()))); auto Matches = match( - stmt(hasDescendant( + decl(hasDescendant( cxxOperatorCallExpr(UsedAsConstRefArg, hasOverloadedOperatorName("=")) .bind("operatorCallExpr"))), - Stmt, Context); + Decl, Context); return !Matches.empty(); } diff --git a/clang-tidy/utils/DeclRefExprUtils.h b/clang-tidy/utils/DeclRefExprUtils.h index 5d56f7f0..c25102f8 100644 --- a/clang-tidy/utils/DeclRefExprUtils.h +++ b/clang-tidy/utils/DeclRefExprUtils.h @@ -28,23 +28,34 @@ namespace decl_ref_expr { bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt, ASTContext &Context); -// Returns set of all DeclRefExprs to VarDecl in Stmt. +/// Returns set of all ``DeclRefExprs`` to ``VarDecl`` within ``Stmt``. llvm::SmallPtrSet<const DeclRefExpr *, 16> allDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context); -// Returns set of all DeclRefExprs where VarDecl is guaranteed to be accessed in -// a const fashion. +/// Returns set of all ``DeclRefExprs`` to ``VarDecl`` within ``Decl``. +llvm::SmallPtrSet<const DeclRefExpr *, 16> +allDeclRefExprs(const VarDecl &VarDecl, const Decl &Decl, ASTContext &Context); + +/// Returns set of all ``DeclRefExprs`` to ``VarDecl`` within ``Stmt`` where +/// ``VarDecl`` is guaranteed to be accessed in a const fashion. llvm::SmallPtrSet<const DeclRefExpr *, 16> constReferenceDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context); -// Returns true if DeclRefExpr is the argument of a copy-constructor call expr. -bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Stmt &Stmt, +/// Returns set of all ``DeclRefExprs`` to ``VarDecl`` within ``Decl`` where +/// ``VarDecl`` is guaranteed to be accessed in a const fashion. +llvm::SmallPtrSet<const DeclRefExpr *, 16> +constReferenceDeclRefExprs(const VarDecl &VarDecl, const Decl &Decl, + ASTContext &Context); + +/// Returns ``true`` if ``DeclRefExpr`` is the argument of a copy-constructor +/// call expression within ``Decl``. +bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context); -// Returns true if DeclRefExpr is the argument of a copy-assignment operator -// call expr. -bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Stmt &Stmt, +/// Returns ``true`` if ``DeclRefExpr`` is the argument of a copy-assignment +/// operator CallExpr within ``Decl``. +bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Decl &Decl, ASTContext &Context); } // namespace decl_ref_expr |