From: Alexander Kornienko Date: Wed, 5 Feb 2014 16:35:08 +0000 (+0000) Subject: Added the hasLoopVariable sub-matcher for forRangeStmt. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=34d8851c4b5c9313e5e93be550a0763687bad854;p=clang Added the hasLoopVariable sub-matcher for forRangeStmt. Summary: This sub-matcher makes it possible to access directly the range-based for loop variable: forRangeStmt(hasLoopVariable(anything()).bind(...)). I've tried to re-generate the docs, but the diffs seem to include much more than this change could cause, so I'd better leave docs update to someone who knows the intended changes in the contents better. Reviewers: klimek Reviewed By: klimek CC: cfe-commits, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D2702 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200850 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index c2f4928e8f..4be693f292 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -842,15 +842,6 @@ const internal::VariadicDynCastAllOfMatcher ifStmt; /// \endcode const internal::VariadicDynCastAllOfMatcher 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 forRangeStmt; - /// \brief Matches the increment statement of a for loop. /// /// Example: @@ -880,6 +871,29 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher, 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 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, + InnerMatcher) { + const VarDecl *const Var = Node.getLoopVariable(); + return (Var != NULL && InnerMatcher.matches(*Var, Finder, Builder)); +} + /// \brief Matches while statements. /// /// Given diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 771cf673ab..a76903fc4a 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/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()))));