<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasAnyArgument1')"><a name="hasAnyArgument1Anchor">hasAnyArgument</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="hasAnyArgument1"><pre>Matches any argument of a call expression or a constructor call
-expression.
+expression, or an ObjC-message-send expression.
Given
void x(int, int, int) { int y; x(1, y, 42); }
matches x(1, y, 42)
with hasAnyArgument(...)
matching y
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+ void foo(I *i) { [i f:12] }
+objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
+ matches [i f:12]
</pre></td></tr>
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasAnyArgument0')"><a name="hasAnyArgument0Anchor">hasAnyArgument</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="hasAnyArgument0"><pre>Matches any argument of a call expression or a constructor call
-expression.
+expression, or an ObjC-message-send expression.
Given
void x(int, int, int) { int y; x(1, y, 42); }
matches x(1, y, 42)
with hasAnyArgument(...)
matching y
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+ void foo(I *i) { [i f:12] }
+objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
+ matches [i f:12]
</pre></td></tr>
</pre></td></tr>
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasAnyArgument2')"><a name="hasAnyArgument2Anchor">hasAnyArgument</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="hasAnyArgument2"><pre>Matches any argument of a call expression or a constructor call
+expression, or an ObjC-message-send expression.
+
+Given
+ void x(int, int, int) { int y; x(1, y, 42); }
+callExpr(hasAnyArgument(declRefExpr()))
+ matches x(1, y, 42)
+with hasAnyArgument(...)
+ matching y
+
+For ObjectiveC, given
+ @interface I - (void) f:(int) y; @end
+ void foo(I *i) { [i f:12] }
+objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
+ matches [i f:12]
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasArgument2')"><a name="hasArgument2Anchor">hasArgument</a></td><td>unsigned N, Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="hasArgument2"><pre>Matches the n'th argument of a call expression or a constructor
call expression.
}
/// \brief Matches any argument of a call expression or a constructor call
-/// expression.
+/// expression, or an ObjC-message-send expression.
///
/// Given
/// \code
/// matches x(1, y, 42)
/// with hasAnyArgument(...)
/// matching y
+///
+/// For ObjectiveC, given
+/// \code
+/// @interface I - (void) f:(int) y; @end
+/// void foo(I *i) { [i f:12]; }
+/// \endcode
+/// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12))))
+/// matches [i f:12]
AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
- CXXConstructExpr),
+ CXXConstructExpr,
+ ObjCMessageExpr),
internal::Matcher<Expr>, InnerMatcher) {
for (const Expr *Arg : Node.arguments()) {
BoundNodesTreeBuilder Result(*Builder);
}
TEST(Matcher, AnyArgument) {
- StatementMatcher CallArgumentY = callExpr(
- hasAnyArgument(
- ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))));
+ auto HasArgumentY = hasAnyArgument(
+ ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"))))));
+ StatementMatcher CallArgumentY = callExpr(HasArgumentY);
+ StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
+ EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
+ "void x(I* i) { int y; [i f:y]; }",
+ ObjCCallArgumentY));
+ EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
+ "void x(I* i) { int z; [i f:z]; }",
+ ObjCCallArgumentY));
EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
StatementMatcher ImplicitCastedArgument = callExpr(