@@ -16,16 +16,31 @@ namespace clang::tidy::performance {
16
16
17
17
using utils::decl_ref_expr::allDeclRefExprs;
18
18
19
+ static const Expr* getLastVarUsage (const VarDecl& Var, const Decl& Func,
20
+ ASTContext& Context) {
21
+ auto Exprs = allDeclRefExprs (Var, Func, Context);
22
+
23
+ const Expr* LastExpr = nullptr ;
24
+ for (const clang::DeclRefExpr* Expr : Exprs) {
25
+ if (!LastExpr) LastExpr = Expr;
26
+
27
+ if (LastExpr->getBeginLoc () < Expr->getBeginLoc ()) LastExpr = Expr;
28
+ }
29
+
30
+ return LastExpr;
31
+ }
32
+
19
33
AST_MATCHER (CXXRecordDecl, hasTrivialMoveConstructor) {
20
34
return Node.hasDefinition () && Node.hasTrivialMoveConstructor ();
21
35
}
22
36
23
- void LostStdMoveCheck::registerMatchers (MatchFinder * Finder) {
37
+ void LostStdMoveCheck::registerMatchers (MatchFinder* Finder) {
24
38
auto returnParent =
25
39
hasParent (expr (hasParent (cxxConstructExpr (hasParent (returnStmt ())))));
26
40
27
41
auto outermostExpr = expr (unless (hasParent (expr ())));
28
- auto leafStatement = stmt (outermostExpr, unless (hasDescendant (outermostExpr)));
42
+ auto leafStatement =
43
+ stmt (outermostExpr, unless (hasDescendant (outermostExpr)));
29
44
30
45
Finder->addMatcher (
31
46
declRefExpr (
@@ -49,7 +64,7 @@ void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
49
64
unless (hasDeclaration (
50
65
varDecl (hasType (qualType (lValueReferenceType ()))))),
51
66
52
- hasAncestor (leafStatement.bind (" leaf_statement" )),
67
+ hasAncestor (leafStatement.bind (" leaf_statement" )),
53
68
54
69
hasDeclaration (
55
70
varDecl (hasAncestor (functionDecl ().bind (" func" ))).bind (" decl" )),
@@ -59,60 +74,44 @@ void LostStdMoveCheck::registerMatchers(MatchFinder *Finder) {
59
74
this );
60
75
}
61
76
62
- const Expr *LostStdMoveCheck::getLastVarUsage (const VarDecl &Var,
63
- const Decl &Func,
64
- ASTContext &Context) {
65
- auto Exprs = allDeclRefExprs (Var, Func, Context);
66
-
67
- const Expr *LastExpr = nullptr ;
68
- for (const auto &Expr : Exprs) {
69
- if (!LastExpr)
70
- LastExpr = Expr;
71
-
72
- if (LastExpr->getBeginLoc () < Expr->getBeginLoc ())
73
- LastExpr = Expr;
74
- }
75
-
76
- return LastExpr;
77
- }
78
-
79
77
template <typename Node>
80
78
void extractNodesByIdTo (ArrayRef<BoundNodes> Matches, StringRef ID,
81
- llvm::SmallPtrSet<const Node *, 16 > & Nodes) {
82
- for (const auto & Match : Matches)
79
+ llvm::SmallPtrSet<const Node*, 16 >& Nodes) {
80
+ for (const BoundNodes& Match : Matches)
83
81
Nodes.insert (Match.getNodeAs <Node>(ID));
84
82
}
85
83
86
- void LostStdMoveCheck::check (const MatchFinder::MatchResult &Result) {
87
- const auto *MatchedDecl = Result.Nodes .getNodeAs <VarDecl>(" decl" );
88
- const auto *MatchedFunc = Result.Nodes .getNodeAs <FunctionDecl>(" func" );
89
- const auto *MatchedUse = Result.Nodes .getNodeAs <Expr>(" use" );
90
- const auto *MatchedUseCall = Result.Nodes .getNodeAs <CallExpr>(" use_parent" );
91
- const auto *MatchedLeafStatement = Result.Nodes .getNodeAs <Stmt>(" leaf_statement" );
84
+ void LostStdMoveCheck::check (const MatchFinder::MatchResult& Result) {
85
+ const auto * MatchedDecl = Result.Nodes .getNodeAs <VarDecl>(" decl" );
86
+ const auto * MatchedFunc = Result.Nodes .getNodeAs <FunctionDecl>(" func" );
87
+ const auto * MatchedUse = Result.Nodes .getNodeAs <Expr>(" use" );
88
+ const auto * MatchedUseCall = Result.Nodes .getNodeAs <CallExpr>(" use_parent" );
89
+ const auto * MatchedLeafStatement =
90
+ Result.Nodes .getNodeAs <Stmt>(" leaf_statement" );
92
91
93
- if (MatchedUseCall)
94
- return ;
92
+ if (MatchedUseCall) return ;
95
93
96
- const auto * LastUsage =
94
+ const auto * LastUsage =
97
95
getLastVarUsage (*MatchedDecl, *MatchedFunc, *Result.Context );
98
- if (LastUsage == nullptr )
99
- return ;
96
+ if (LastUsage == nullptr ) return ;
100
97
101
98
if (LastUsage->getBeginLoc () > MatchedUse->getBeginLoc ()) {
102
99
// "use" is not the last reference to x
103
100
return ;
104
101
}
105
102
106
103
// Calculate X usage count in the statement
107
- llvm::SmallPtrSet<const DeclRefExpr *, 16 > DeclRefs;
108
- auto Matches = match (findAll (declRefExpr (to (varDecl (equalsNode (MatchedDecl)))).bind (" ref" )), *MatchedLeafStatement, *Result.Context );
104
+ llvm::SmallPtrSet<const DeclRefExpr*, 16 > DeclRefs;
105
+ ArrayRef<BoundNodes> Matches = match (
106
+ findAll (declRefExpr (to (varDecl (equalsNode (MatchedDecl)))).bind (" ref" )),
107
+ *MatchedLeafStatement, *Result.Context );
109
108
extractNodesByIdTo (Matches, " ref" , DeclRefs);
110
109
if (DeclRefs.size () > 1 ) {
111
110
// Unspecified order of evaluation, e.g. f(x, x)
112
111
return ;
113
112
}
114
113
115
- diag (LastUsage->getBeginLoc (), " Could be std::move()" );
114
+ diag (LastUsage->getBeginLoc (), " could be std::move()" );
116
115
}
117
116
118
- } // namespace clang::tidy::performance
117
+ } // namespace clang::tidy::performance
0 commit comments