[clang-tools-extra] 1a91b82 - [clang-tidy][NFC] Use equalsBoundNode matchers to simplify LoopConvertCheck
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 2 18:51:49 PST 2021
Author: Nathan James
Date: 2021-03-03T02:51:34Z
New Revision: 1a91b8232a5d31ef3a4f8eb52f5a7aaf79525b9b
URL: https://github.com/llvm/llvm-project/commit/1a91b8232a5d31ef3a4f8eb52f5a7aaf79525b9b
DIFF: https://github.com/llvm/llvm-project/commit/1a91b8232a5d31ef3a4f8eb52f5a7aaf79525b9b.diff
LOG: [clang-tidy][NFC] Use equalsBoundNode matchers to simplify LoopConvertCheck
Make use of the `equalsBoundNode` matcher to ensure Init, Conditon and Increment variables all refer to the same variable during matching.
Reviewed By: steveire
Differential Revision: https://reviews.llvm.org/D97639
Added:
Modified:
clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
index ec75be9c5f53..9df343f81d1c 100644
--- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -61,21 +61,16 @@ static const char LoopNameIterator[] = "forLoopIterator";
static const char LoopNameReverseIterator[] = "forLoopReverseIterator";
static const char LoopNamePseudoArray[] = "forLoopPseudoArray";
static const char ConditionBoundName[] = "conditionBound";
-static const char ConditionVarName[] = "conditionVar";
-static const char IncrementVarName[] = "incrementVar";
static const char InitVarName[] = "initVar";
static const char BeginCallName[] = "beginCall";
static const char EndCallName[] = "endCall";
-static const char ConditionEndVarName[] = "conditionEndVar";
static const char EndVarName[] = "endVar";
static const char DerefByValueResultName[] = "derefByValueResult";
static const char DerefByRefResultName[] = "derefByRefResult";
-// shared matchers
-static const TypeMatcher anyType() { return anything(); }
static const StatementMatcher integerComparisonMatcher() {
return expr(ignoringParenImpCasts(
- declRefExpr(to(varDecl(hasType(isInteger())).bind(ConditionVarName)))));
+ declRefExpr(to(varDecl(equalsBoundNode(InitVarName))))));
}
static const DeclarationMatcher initToZeroMatcher() {
@@ -85,25 +80,19 @@ static const DeclarationMatcher initToZeroMatcher() {
}
static const StatementMatcher incrementVarMatcher() {
- return declRefExpr(to(varDecl(hasType(isInteger())).bind(IncrementVarName)));
+ return declRefExpr(to(varDecl(equalsBoundNode(InitVarName))));
}
/// The matcher for loops over arrays.
-///
-/// In this general example, assuming 'j' and 'k' are of integral type:
/// \code
-/// for (int i = 0; j < 3 + 2; ++k) { ... }
+/// for (int i = 0; i < 3 + 2; ++i) { ... }
/// \endcode
/// The following string identifiers are bound to these parts of the AST:
-/// ConditionVarName: 'j' (as a VarDecl)
/// ConditionBoundName: '3 + 2' (as an Expr)
/// InitVarName: 'i' (as a VarDecl)
-/// IncrementVarName: 'k' (as a VarDecl)
/// LoopName: The entire for loop (as a ForStmt)
///
/// Client code will need to make sure that:
-/// - The three index variables identified by the matcher are the same
-/// VarDecl.
/// - The index variable is only used as an array index.
/// - All arrays indexed by the loop are the same.
StatementMatcher makeArrayLoopMatcher() {
@@ -131,27 +120,22 @@ StatementMatcher makeArrayLoopMatcher() {
/// catch loops of the following textual forms (regardless of whether the
/// iterator type is actually a pointer type or a class type):
///
-/// Assuming f, g, and h are of type containerType::iterator,
/// \code
/// for (containerType::iterator it = container.begin(),
-/// e = createIterator(); f != g; ++h) { ... }
+/// e = createIterator(); it != e; ++it) { ... }
/// for (containerType::iterator it = container.begin();
-/// f != anotherContainer.end(); ++h) { ... }
+/// it != anotherContainer.end(); ++it) { ... }
/// \endcode
/// The following string identifiers are bound to the parts of the AST:
/// InitVarName: 'it' (as a VarDecl)
-/// ConditionVarName: 'f' (as a VarDecl)
/// LoopName: The entire for loop (as a ForStmt)
/// In the first example only:
/// EndVarName: 'e' (as a VarDecl)
-/// ConditionEndVarName: 'g' (as a VarDecl)
/// In the second example only:
/// EndCallName: 'container.end()' (as a CXXMemberCallExpr)
///
/// Client code will need to make sure that:
-/// - The iterator variables 'it', 'f', and 'h' are the same.
/// - The two containers on which 'begin' and 'end' are called are the same.
-/// - If the end iterator variable 'g' is defined, it is the same as 'f'.
StatementMatcher makeIteratorLoopMatcher(bool IsReverse) {
auto BeginNameMatcher = IsReverse ? hasAnyName("rbegin", "crbegin")
@@ -180,13 +164,13 @@ StatementMatcher makeIteratorLoopMatcher(bool IsReverse) {
StatementMatcher IteratorBoundMatcher =
expr(anyOf(ignoringParenImpCasts(
- declRefExpr(to(varDecl().bind(ConditionEndVarName)))),
+ declRefExpr(to(varDecl(equalsBoundNode(EndVarName))))),
ignoringParenImpCasts(expr(EndCallMatcher).bind(EndCallName)),
materializeTemporaryExpr(ignoringParenImpCasts(
expr(EndCallMatcher).bind(EndCallName)))));
- StatementMatcher IteratorComparisonMatcher = expr(
- ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ConditionVarName)))));
+ StatementMatcher IteratorComparisonMatcher = expr(ignoringParenImpCasts(
+ declRefExpr(to(varDecl(equalsBoundNode(InitVarName))))));
// This matcher tests that a declaration is a CXXRecordDecl that has an
// overloaded operator*(). If the operator*() returns by value instead of by
@@ -217,13 +201,12 @@ StatementMatcher makeIteratorLoopMatcher(bool IsReverse) {
hasIncrement(anyOf(
unaryOperator(hasOperatorName("++"),
hasUnaryOperand(declRefExpr(
- to(varDecl(hasType(pointsTo(anyType())))
- .bind(IncrementVarName))))),
+ to(varDecl(equalsBoundNode(InitVarName)))))),
cxxOperatorCallExpr(
hasOverloadedOperatorName("++"),
- hasArgument(
- 0, declRefExpr(to(varDecl(TestDerefReturnsByValue)
- .bind(IncrementVarName))))))))
+ hasArgument(0, declRefExpr(to(
+ varDecl(equalsBoundNode(InitVarName),
+ TestDerefReturnsByValue))))))))
.bind(IsReverse ? LoopNameReverseIterator : LoopNameIterator);
}
@@ -233,27 +216,22 @@ StatementMatcher makeIteratorLoopMatcher(bool IsReverse) {
/// loops of the following textual forms (regardless of whether the
/// iterator type is actually a pointer type or a class type):
///
-/// Assuming f, g, and h are of type containerType::iterator,
/// \code
-/// for (int i = 0, j = container.size(); f < g; ++h) { ... }
-/// for (int i = 0; f < container.size(); ++h) { ... }
+/// for (int i = 0, j = container.size(); i < j; ++i) { ... }
+/// for (int i = 0; i < container.size(); ++i) { ... }
/// \endcode
/// The following string identifiers are bound to the parts of the AST:
/// InitVarName: 'i' (as a VarDecl)
-/// ConditionVarName: 'f' (as a VarDecl)
/// LoopName: The entire for loop (as a ForStmt)
/// In the first example only:
/// EndVarName: 'j' (as a VarDecl)
-/// ConditionEndVarName: 'g' (as a VarDecl)
/// In the second example only:
/// EndCallName: 'container.size()' (as a CXXMemberCallExpr)
///
/// Client code will need to make sure that:
-/// - The index variables 'i', 'f', and 'h' are the same.
/// - The containers on which 'size()' is called is the container indexed.
/// - The index variable is only used in overloaded operator[] or
/// container.at().
-/// - If the end iterator variable 'g' is defined, it is the same as 'j'.
/// - The container's iterators would not be invalidated during the loop.
StatementMatcher makePseudoArrayLoopMatcher() {
// Test that the incoming type has a record declaration that has methods
@@ -296,8 +274,8 @@ StatementMatcher makePseudoArrayLoopMatcher() {
varDecl(hasInitializer(EndInitMatcher)).bind(EndVarName);
StatementMatcher IndexBoundMatcher =
- expr(anyOf(ignoringParenImpCasts(declRefExpr(to(
- varDecl(hasType(isInteger())).bind(ConditionEndVarName)))),
+ expr(anyOf(ignoringParenImpCasts(
+ declRefExpr(to(varDecl(equalsBoundNode(EndVarName))))),
EndInitMatcher));
return forStmt(
@@ -829,15 +807,7 @@ bool LoopConvertCheck::isConvertible(ASTContext *Context,
return false;
// Check that we have exactly one index variable and at most one end variable.
- const auto *LoopVar = Nodes.getNodeAs<VarDecl>(IncrementVarName);
- const auto *CondVar = Nodes.getNodeAs<VarDecl>(ConditionVarName);
const auto *InitVar = Nodes.getNodeAs<VarDecl>(InitVarName);
- if (!areSameVariable(LoopVar, CondVar) || !areSameVariable(LoopVar, InitVar))
- return false;
- const auto *EndVar = Nodes.getNodeAs<VarDecl>(EndVarName);
- const auto *ConditionEndVar = Nodes.getNodeAs<VarDecl>(ConditionEndVarName);
- if (EndVar && !areSameVariable(EndVar, ConditionEndVar))
- return false;
// FIXME: Try to put most of this logic inside a matcher.
if (FixerKind == LFK_Iterator || FixerKind == LFK_ReverseIterator) {
@@ -890,7 +860,7 @@ void LoopConvertCheck::check(const MatchFinder::MatchResult &Result) {
if (!isConvertible(Context, Nodes, Loop, FixerKind))
return;
- const auto *LoopVar = Nodes.getNodeAs<VarDecl>(IncrementVarName);
+ const auto *LoopVar = Nodes.getNodeAs<VarDecl>(InitVarName);
const auto *EndVar = Nodes.getNodeAs<VarDecl>(EndVarName);
// If the loop calls end()/size() after each iteration, lower our confidence
More information about the cfe-commits
mailing list