diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index f701f11d1518bd3f770ad84ca662efcc1bde8344..3b862cd861146fe03377b7b27e578e4ab8fe4327 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -631,6 +631,15 @@ Example matches x() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('exprWithCleanups0')"><a name="exprWithCleanups0Anchor">exprWithCleanups</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ExprWithCleanups.html">ExprWithCleanups</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="exprWithCleanups0"><pre>Matches expressions that introduce cleanups to be run at the end +of the sub-expression's evaluation. + +Example matches std::string() + const std::string str = std::string(); +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('floatLiteral0')"><a name="floatLiteral0Anchor">floatLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>>...</td></tr> <tr><td colspan="4" class="doc" id="floatLiteral0"><pre>Matches float literals of all sizes encodings, e.g. 1.0, 1.0f, 1.0L and 1e10. @@ -1357,12 +1366,6 @@ Example matches f(0, 0) (matcher = callExpr(argumentCountIs(2))) </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a constructor declaration that has been implicitly added -by the compiler (eg. implicit defaultcopy constructors). -</pre></td></tr> - - <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></td><td class="name" onclick="toggle('isWritten0')"><a name="isWritten0Anchor">isWritten</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isWritten0"><pre>Matches a constructor initializer if it is explicitly written in code (as opposed to implicitly added by the compiler). @@ -1605,6 +1608,12 @@ Decl has pointer identity in the AST. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a declaration that has been implicitly added +by the compiler (eg. implicit defaultcopy constructors). +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isPrivate0')"><a name="isPrivate0Anchor">isPrivate</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations. @@ -2393,6 +2402,19 @@ with withInitializer matching (1) </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>></td><td class="name" onclick="toggle('hasBody3')"><a name="hasBody3Anchor">hasBody</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasBody3"><pre>Matches a 'for', 'while', or 'do while' statement that has +a given body. + +Given + for (;;) {} +hasBody(compoundStmt()) + matches 'for (;;) {}' +with compoundStmt() + matching '{}' +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>></td><td class="name" onclick="toggle('hasLoopVariable0')"><a name="hasLoopVariable0Anchor">hasLoopVariable</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasLoopVariable0"><pre>Matches the initialization statement of a for loop. @@ -2403,6 +2425,16 @@ matches 'int x' in </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>></td><td class="name" onclick="toggle('hasRangeInit0')"><a name="hasRangeInit0Anchor">hasRangeInit</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasRangeInit0"><pre>Matches the range initialization statement of a for loop. + +Example: + forStmt(hasRangeInit(anything())) +matches 'a' in + for (int x : a) { } +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>></td><td class="name" onclick="toggle('onImplicitObjectArgument0')"><a name="onImplicitObjectArgument0Anchor">onImplicitObjectArgument</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre></pre></td></tr> diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 2bee8e61b857246502fcd8bfbff5461b9ec098b7..30f0264aaf5adc17f18e3ab0320997f32edd72b2 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -2430,9 +2430,11 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// matches 'for (;;) {}' /// with compoundStmt() /// matching '{}' -AST_POLYMORPHIC_MATCHER_P( - hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES_3(DoStmt, ForStmt, WhileStmt), - internal::Matcher<Stmt>, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P(hasBody, + AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt, + WhileStmt, + CXXForRangeStmt), + internal::Matcher<Stmt>, InnerMatcher) { const Stmt *const Statement = Node.getBody(); return (Statement != nullptr && InnerMatcher.matches(*Statement, Finder, Builder)); diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 4b364679152340af6e27e2f2c343498bb3730a35..4ce56fd0238d2d5b39c86e60e28b3e1db8cb9881 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -2432,6 +2432,8 @@ TEST(HasBody, FindsBodyOfForWhileDoLoops) { whileStmt(hasBody(compoundStmt())))); EXPECT_TRUE(matches("void f() { do {} while(true); }", doStmt(hasBody(compoundStmt())))); + EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }", + forRangeStmt(hasBody(compoundStmt())))); } TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) { diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp index a4b493295ee46bf86f9ad5fc30a693059ad2eeda..4e3239ff5a5054ea6a313d2c5160863dd02565da 100644 --- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -257,7 +257,7 @@ TEST(ParserTest, Errors) { "1:1: Matcher does not support binding.", ParseWithError("isArrow().bind(\"foo\")")); EXPECT_EQ("Input value has unresolved overloaded type: " - "Matcher<DoStmt|ForStmt|WhileStmt>", + "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt>", ParseMatcherWithError("hasBody(stmt())")); }