diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index c2f4928e8f51..4be693f29292 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -842,15 +842,6 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt; /// \endcode const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt; -/// \brief Matches range-based for statements. -/// -/// forRangeStmt() matches 'for (auto a : i)' -/// \code -/// int i[] = {1, 2, 3}; for (auto a : i); -/// for(int j = 0; j < 5; ++j); -/// \endcode -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt; - /// \brief Matches the increment statement of a for loop. /// /// Example: @@ -880,6 +871,29 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>, return (Init != NULL && InnerMatcher.matches(*Init, Finder, Builder)); } +/// \brief Matches range-based for statements. +/// +/// forRangeStmt() matches 'for (auto a : i)' +/// \code +/// int i[] = {1, 2, 3}; for (auto a : i); +/// for(int j = 0; j < 5; ++j); +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt; + +/// \brief Matches the initialization statement of a for loop. +/// +/// Example: +/// forStmt(hasLoopVariable(anything())) +/// matches 'int x' in +/// \code +/// for (int x : a) { } +/// \endcode +AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>, + InnerMatcher) { + const VarDecl *const Var = Node.getLoopVariable(); + return (Var != NULL && InnerMatcher.matches(*Var, Finder, Builder)); +} + /// \brief Matches while statements. /// /// Given diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 771cf673ab2c..a76903fc4af6 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -2339,6 +2339,11 @@ TEST(For, ForLoopInternals) { forStmt(hasLoopInit(anything())))); } +TEST(For, ForRangeLoopInternals) { + EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }", + forRangeStmt(hasLoopVariable(anything())))); +} + TEST(For, NegativeForLoopInternals) { EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }", forStmt(hasCondition(expr()))));