forked from OSchip/llvm-project
Add AST matcher support for FunctionDecls with the hasBody matcher.
Patch by Aleksei Sidorin. llvm-svn: 258322
This commit is contained in:
parent
e8295d7980
commit
2b6963fce9
|
@ -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(ignoringImpCasts(declRefExpr(to(
|
|||
|
||||
|
||||
<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 (;;) {}
|
||||
|
|
|
@ -3189,8 +3189,8 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
|
|||
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, hasBase,
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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())"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue