<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasAnyParameter0')"><a name="hasAnyParameter0Anchor">hasAnyParameter</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function declaration.
+<tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function or ObjC method declaration.
Does not match the 'this' parameter of a method.
matches f(int x, int y, int z) {}
with hasAnyParameter(...)
matching int y
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+
+the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
+matches the declaration of method f with hasParameter
+matching y.
</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.
+<tr><td colspan="4" class="doc" id="hasParameter0"><pre>Matches the n'th parameter of a function or an ObjC method
+declaration.
Given
class X { void f(int x) {} };
matches f(int x) {}
with hasParameter(...)
matching int x
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+
+the matcher objcMethodDecl(hasParameter(0, hasName("y")))
+matches the declaration of method f with hasParameter
+matching y.
</pre></td></tr>
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>></td><td class="name" onclick="toggle('hasAnyParameter1')"><a name="hasAnyParameter1Anchor">hasAnyParameter</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyParameter1"><pre>Matches any parameter of a function or ObjC method declaration.
+
+Does not match the 'this' parameter of a method.
+
+Given
+ class X { void f(int x, int y, int z) {} };
+cxxMethodDecl(hasAnyParameter(hasName("y")))
+ matches f(int x, int y, int z) {}
+with hasAnyParameter(...)
+ matching int y
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+
+the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
+matches the declaration of method f with hasParameter
+matching y.
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMethodDecl.html">ObjCMethodDecl</a>></td><td class="name" onclick="toggle('hasParameter1')"><a name="hasParameter1Anchor">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="hasParameter1"><pre>Matches the n'th parameter of a function or an ObjC method
+declaration.
+
+Given
+ class X { void f(int x) {} };
+cxxMethodDecl(hasParameter(0, hasType(varDecl())))
+ matches f(int x) {}
+with hasParameter(...)
+ matching int x
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+
+the matcher objcMethodDecl(hasParameter(0, hasName("y")))
+matches the declaration of method f with hasParameter
+matching y.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1OpaqueValueExpr.html">OpaqueValueExpr</a>></td><td class="name" onclick="toggle('hasSourceExpression1')"><a name="hasSourceExpression1Anchor">hasSourceExpression</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="hasSourceExpression1"><pre>Matches if the cast's source expression
or opaque value's source expression matches the given matcher.
return Node.requiresZeroInitialization();
}
-/// \brief Matches the n'th parameter of a function declaration.
+/// \brief Matches the n'th parameter of a function or an ObjC method
+/// declaration.
///
/// Given
/// \code
/// matches f(int x) {}
/// with hasParameter(...)
/// matching int x
-AST_MATCHER_P2(FunctionDecl, hasParameter,
- unsigned, N, internal::Matcher<ParmVarDecl>,
- InnerMatcher) {
- return (N < Node.getNumParams() &&
- InnerMatcher.matches(
- *Node.getParamDecl(N), Finder, Builder));
+///
+/// For ObjectiveC, given
+/// \code
+/// @interface I - (void) f:(int) y; @end
+/// \endcode
+//
+/// the matcher objcMethodDecl(hasParameter(0, hasName("y")))
+/// matches the declaration of method f with hasParameter
+/// matching y.
+AST_POLYMORPHIC_MATCHER_P2(hasParameter,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ ObjCMethodDecl),
+ unsigned, N, internal::Matcher<ParmVarDecl>,
+ InnerMatcher) {
+ return (N < Node.parameters().size()
+ && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
}
/// \brief Matches all arguments and their respective ParmVarDecl.
return Matched;
}
-/// \brief Matches any parameter of a function declaration.
+/// \brief Matches any parameter of a function or ObjC method declaration.
///
/// Does not match the 'this' parameter of a method.
///
/// matches f(int x, int y, int z) {}
/// with hasAnyParameter(...)
/// matching int y
-AST_MATCHER_P(FunctionDecl, hasAnyParameter,
- internal::Matcher<ParmVarDecl>, InnerMatcher) {
+///
+/// For ObjectiveC, given
+/// \code
+/// @interface I - (void) f:(int) y; @end
+/// \endcode
+//
+/// the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
+/// matches the declaration of method f with hasParameter
+/// matching y.
+AST_POLYMORPHIC_MATCHER_P(hasAnyParameter,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
+ ObjCMethodDecl),
+ internal::Matcher<ParmVarDecl>,
+ InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
Node.param_end(), Finder, Builder);
}
static std::unique_ptr<WorkList> makeUnexploredFirstPriorityQueue();
};
-} // end GR namespace
+} // end ento namespace
} // end clang namespace
cxxMethodDecl(hasParameter(0, varDecl()))));
EXPECT_TRUE(notMatches("class X { void x(int) {} };",
cxxMethodDecl(hasParameter(0, hasName("x")))));
+ EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
+ objcMethodDecl(hasParameter(0, hasName("x")))));
}
TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
EXPECT_TRUE(matches(
"class Y {}; class X { void x(Y y, X x) {} };",
cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
+ EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end",
+ objcMethodDecl(hasAnyParameter(hasName("x")))));
}
TEST(Returns, MatchesReturnTypes) {
Parser::NamedValueMap getTestNamedValues() {
Parser::NamedValueMap Values;
Values["nameX"] = llvm::StringRef("x");
- Values["hasParamA"] =
- VariantMatcher::SingleMatcher(hasParameter(0, hasName("a")));
+ Values["hasParamA"] = VariantMatcher::SingleMatcher(
+ functionDecl(hasParameter(0, hasName("a"))));
return Values;
}
EXPECT_LT(0u, Comps.size());
// Can complete names and registry together.
- Code = "cxxMethodDecl(hasP";
+ Code = "functionDecl(hasP";
Comps = Parser::completeExpression(Code, Code.size(), nullptr, &NamedValues);
ASSERT_EQ(3u, Comps.size());
- EXPECT_EQ("aramA", Comps[0].TypedText);
- EXPECT_EQ("Matcher<FunctionDecl> hasParamA", Comps[0].MatcherDecl);
- EXPECT_EQ("arameter(", Comps[1].TypedText);
+ EXPECT_EQ("arameter(", Comps[0].TypedText);
EXPECT_EQ(
"Matcher<FunctionDecl> hasParameter(unsigned, Matcher<ParmVarDecl>)",
- Comps[1].MatcherDecl);
+ Comps[0].MatcherDecl);
+
+ EXPECT_EQ("aramA", Comps[1].TypedText);
+ EXPECT_EQ("Matcher<Decl> hasParamA", Comps[1].MatcherDecl);
EXPECT_EQ("arent(", Comps[2].TypedText);
EXPECT_EQ(