LegalizeAdulthood created this revision. LegalizeAdulthood added a reviewer: klimek. LegalizeAdulthood requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Previously if you wanted to match the statement associated with a case or default block, you had to use hasDescendant. Review comments stated that hasDescendant is heavy-handed and that a more specific narrowing matcher was preferred. This is that narrowing matcher. - Separate matcher definitions with a blank line. - Add corresponding unit tests for new narrowing matcher. - Add the new matcher to the Registry - Add documentation in the AST matchers reference HTML page. - Remove trailing semi-colon from REGISTER_MATCHER macro to be consistent with the other macro declarations and fix a missing semi-colon in the invocation of the macro. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D116328 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -311,6 +311,18 @@ EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord)); } +TEST_P(ASTMatchersTest, HasCaseSubstmt) { + EXPECT_TRUE(matches( + "void f() { switch (1) { case 1: return; break; default: break; } }", + traverse(TK_AsIs, caseStmt(hasSubstmt(returnStmt()))))); +} + +TEST_P(ASTMatchersTest, HasDefaultSubstmt) { + EXPECT_TRUE(matches( + "void f() { switch (1) { case 1: return; break; default: break; } }", + traverse(TK_AsIs, defaultStmt(hasSubstmt(breakStmt()))))); +} + TEST_P(ASTMatchersTest, HasCastKind) { EXPECT_TRUE( matches("char *p = 0;", Index: clang/lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -66,7 +66,7 @@ #define REGISTER_MATCHER(name) \ registerMatcher(#name, internal::makeMatcherAutoMarshall( \ - ::clang::ast_matchers::name, #name)); + ::clang::ast_matchers::name, #name)) #define REGISTER_MATCHER_OVERLOAD(name) \ registerMatcher(#name, \ @@ -143,7 +143,7 @@ REGISTER_MATCHER(atomicType); REGISTER_MATCHER(attr); REGISTER_MATCHER(autoType); - REGISTER_MATCHER(autoreleasePoolStmt) + REGISTER_MATCHER(autoreleasePoolStmt); REGISTER_MATCHER(binaryConditionalOperator); REGISTER_MATCHER(binaryOperator); REGISTER_MATCHER(binaryOperation); @@ -355,6 +355,7 @@ REGISTER_MATCHER(hasSpecializedTemplate); REGISTER_MATCHER(hasStaticStorageDuration); REGISTER_MATCHER(hasStructuredBlock); + REGISTER_MATCHER(hasSubstmt); REGISTER_MATCHER(hasSyntacticForm); REGISTER_MATCHER(hasTargetDecl); REGISTER_MATCHER(hasTemplateArgument); Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2429,6 +2429,7 @@ /// Matches co_await expressions where the type of the promise is dependent extern const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr> dependentCoawaitExpr; + /// Matches co_yield expressions. /// /// Given @@ -7716,6 +7717,24 @@ return InnerMatcher.matches(*Node.getLHS(), Finder, Builder); } +/// Matches the substatement associated with a case or default statement. +/// +/// Given +/// \code +/// switch (1) { case 1: break; case 2: return; break; default: return; break; } +/// \endcode +/// +/// caseStmt(hasSubstmt(returnStmt())) +/// matches "case 2: return;" +/// defaultStmt(hasSubstmt(returnStmt())) +/// matches "default: return;" +AST_POLYMORPHIC_MATCHER_P(hasSubstmt, + AST_POLYMORPHIC_SUPPORTED_TYPES(CaseStmt, + DefaultStmt), + internal::Matcher<Stmt>, InnerMatcher) { + return InnerMatcher.matches(*Node.getSubStmt(), Finder, Builder); +} + /// Matches declaration that has a given attribute. /// /// Given Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -7298,6 +7298,16 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CaseStmt.html">CaseStmt</a>></td><td class="name" onclick="toggle('hasSubstmt0')"><a name="hasSubstmt0Anchor">hasSubstmt</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasSubstmt0"><pre>Matches the substatement associated with a case statement. + +Given + switch (1) { case 1: break; case 2: return; break; default: return; break; } +caseStmt(hasSubstmt(returnStmt())) + matches "case 2: return;" +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>></td><td class="name" onclick="toggle('hasSourceExpression0')"><a name="hasSourceExpression0Anchor">hasSourceExpression</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasSourceExpression0"><pre>Matches if the cast's source expression or opaque value's source expression matches the given matcher. @@ -7653,6 +7663,16 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DefaultStmt.html">DefaultStmt</a>></td><td class="name" onclick="toggle('hasSubstmt1')"><a name="hasSubstmt1Anchor">hasSubstmt</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasSubstmt1"><pre>Matches the substatement associated with a default statement. + +Given + switch (1) { case 1: break; case 2: return; break; default: return; break; } +defaultStmt(hasSubstmt(returnStmt())) + matches "default: return;" +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>></td><td class="name" onclick="toggle('hasBody0')"><a name="hasBody0Anchor">hasBody</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasBody0"><pre></pre></td></tr>
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits