[ASTMatchers] Fix child traversal over range-for loops

Differential Revision: https://reviews.llvm.org/D94031
This commit is contained in:
Stephen Kelly 2020-12-26 21:07:14 +00:00
parent 8cf1cc578d
commit 16c6e9c58e
2 changed files with 59 additions and 4 deletions

View File

@ -236,6 +236,20 @@ public:
ScopedIncrement ScopedDepth(&CurrentDepth);
return traverse(TAL);
}
bool TraverseCXXForRangeStmt(CXXForRangeStmt *Node) {
if (!Finder->isTraversalIgnoringImplicitNodes())
return VisitorBase::TraverseCXXForRangeStmt(Node);
if (!Node)
return true;
ScopedIncrement ScopedDepth(&CurrentDepth);
if (auto *Init = Node->getInit())
if (!match(*Init))
return false;
if (!match(*Node->getLoopVariable()) || !match(*Node->getRangeInit()) ||
!match(*Node->getBody()))
return false;
return VisitorBase::TraverseStmt(Node->getBody());
}
bool TraverseLambdaExpr(LambdaExpr *Node) {
if (!Finder->isTraversalIgnoringImplicitNodes())
return VisitorBase::TraverseLambdaExpr(Node);
@ -575,8 +589,6 @@ public:
if (isTraversalIgnoringImplicitNodes()) {
IgnoreImplicitChildren = true;
if (Node.get<CXXForRangeStmt>())
ScopedTraversal = true;
}
ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal);

View File

@ -2553,7 +2553,9 @@ struct CtorInitsNonTrivial : NonTrivial
int arr[2];
for (auto i : arr)
{
if (true)
{
}
}
}
)cpp";
@ -2596,6 +2598,33 @@ struct CtorInitsNonTrivial : NonTrivial
EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
}
{
auto M = cxxForRangeStmt(hasDescendant(ifStmt()));
EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
}
{
EXPECT_TRUE(matches(
Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(
hasSingleDecl(varDecl(hasName("i")))))))));
EXPECT_TRUE(
matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
cxxForRangeStmt(has(varDecl(hasName("i")))))));
}
{
EXPECT_TRUE(matches(
Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl(
varDecl(hasInitializer(declRefExpr(
to(varDecl(hasName("arr")))))))))))));
EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource,
cxxForRangeStmt(has(declRefExpr(
to(varDecl(hasName("arr")))))))));
}
{
auto M = cxxForRangeStmt(has(compoundStmt()));
EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
}
{
auto M = binaryOperator(hasOperatorName("!="));
EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
@ -2659,7 +2688,8 @@ struct CtorInitsNonTrivial : NonTrivial
true, {"-std=c++20"}));
}
{
auto M = cxxForRangeStmt(has(declStmt()));
auto M =
cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i"))))));
EXPECT_TRUE(
matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
EXPECT_FALSE(
@ -2679,6 +2709,19 @@ struct CtorInitsNonTrivial : NonTrivial
matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
true, {"-std=c++20"}));
}
{
auto M = cxxForRangeStmt(
has(declStmt(hasSingleDecl(varDecl(
hasName("a"),
hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))),
hasLoopVariable(varDecl(hasName("i"))),
hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))));
EXPECT_TRUE(
matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"}));
EXPECT_TRUE(
matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M),
true, {"-std=c++20"}));
}
Code = R"cpp(
void hasDefaultArg(int i, int j = 0)
{