Author: aaronballman Date: Wed Jan 20 10:26:48 2016 New Revision: 258322 URL: http://llvm.org/viewvc/llvm-project?rev=258322&view=rev Log: Add AST matcher support for FunctionDecls with the hasBody matcher.
Patch by Aleksei Sidorin. Modified: cfe/trunk/docs/LibASTMatchersReference.html cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Modified: cfe/trunk/docs/LibASTMatchersReference.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=258322&r1=258321&r2=258322&view=diff ============================================================================== --- cfe/trunk/docs/LibASTMatchersReference.html (original) +++ cfe/trunk/docs/LibASTMatchersReference.html Wed Jan 20 10:26:48 2016 @@ -3436,8 +3436,8 @@ with withInitializer matching (1) <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. +<tr><td colspan="4" class="doc" id="hasBody3"><pre>Matches a 'for', 'while', 'do while' statement or a function +definition that has a given body. Given for (;;) {} @@ -3878,8 +3878,8 @@ declaration of class D. <tr><td>Matcher<<a href="http://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="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasBody0"><pre>Matches a 'for', 'while', or 'do while' statement that has -a given body. +<tr><td colspan="4" class="doc" id="hasBody0"><pre>Matches a 'for', 'while', 'do while' statement or a function +definition that has a given body. Given for (;;) {} @@ -4059,8 +4059,8 @@ would only match the declaration for a. <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasBody1')"><a name="hasBody1Anchor">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="hasBody1"><pre>Matches a 'for', 'while', or 'do while' statement that has -a given body. +<tr><td colspan="4" class="doc" id="hasBody1"><pre>Matches a 'for', 'while', 'do while' statement or a function +definition that has a given body. Given for (;;) {} @@ -4114,6 +4114,19 @@ with hasAnyParameter(...) </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasBody4')"><a name="hasBody4Anchor">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="hasBody4"><pre>Matches a 'for', 'while', 'do while' statement or a function +definition 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_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasParameter0')"><a name="hasParameter0Anchor">hasParameter</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasParameter0"><pre>Matches the n'th parameter of a function declaration. @@ -4891,8 +4904,8 @@ variableArrayType(hasSizeExpr(ignoringIm <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>></td><td class="name" onclick="toggle('hasBody2')"><a name="hasBody2Anchor">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="hasBody2"><pre>Matches a 'for', 'while', or 'do while' statement that has -a given body. +<tr><td colspan="4" class="doc" id="hasBody2"><pre>Matches a 'for', 'while', 'do while' statement or a function +definition that has a given body. Given for (;;) {} Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=258322&r1=258321&r2=258322&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed Jan 20 10:26:48 2016 @@ -3189,8 +3189,8 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBas return false; } -/// \brief Matches a 'for', 'while', or 'do while' statement that has -/// a given body. +/// \brief Matches a 'for', 'while', 'do while' statement or a function +/// definition that has a given body. /// /// Given /// \code @@ -3203,9 +3203,10 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBas AST_POLYMORPHIC_MATCHER_P(hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, WhileStmt, - CXXForRangeStmt), + CXXForRangeStmt, + FunctionDecl), internal::Matcher<Stmt>, InnerMatcher) { - const Stmt *const Statement = Node.getBody(); + const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node); return (Statement != nullptr && InnerMatcher.matches(*Statement, Finder, Builder)); } Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=258322&r1=258321&r2=258322&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Wed Jan 20 10:26:48 2016 @@ -1584,6 +1584,18 @@ struct NotEqualsBoundNodePredicate { ast_type_traits::DynTypedNode Node; }; +template <typename Ty> +struct GetBodyMatcher { + static const Stmt *get(const Ty &Node) { + return Node.getBody(); + } +}; + +template <> +inline const Stmt *GetBodyMatcher<FunctionDecl>::get(const FunctionDecl &Node) { + return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr; +} + } // end namespace internal } // end namespace ast_matchers } // end namespace clang Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=258322&r1=258321&r2=258322&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Wed Jan 20 10:26:48 2016 @@ -2973,6 +2973,10 @@ TEST(HasBody, FindsBodyOfForWhileDoLoops doStmt(hasBody(compoundStmt())))); EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }", cxxForRangeStmt(hasBody(compoundStmt())))); + EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt())))); + EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt())))); + EXPECT_TRUE(matches("void f(); void f() {}", + functionDecl(hasBody(compoundStmt())))); } TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) { Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=258322&r1=258321&r2=258322&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Wed Jan 20 10:26:48 2016 @@ -263,7 +263,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|CXXForRangeStmt>", + "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt|FunctionDecl>", ParseMatcherWithError("hasBody(stmt())")); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits