Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -124,6 +124,18 @@ +Matcher<Decl>blockDeclMatcher<BlockDecl>... +
Matches Objective-C block declarations.
+
+Example matches the declaration of the nameless block printing an input
+integer.
+
+  myFunc(^(int p) {
+    printf("%d", p);
+  })
+
+ + Matcher<Decl>classTemplateDeclMatcher<ClassTemplateDecl>...
Matches C++ class template declarations.
 
@@ -4352,6 +4364,54 @@
 
+Matcher<BlockDecl>hasAnyParameterMatcher<ParmVarDecl> InnerMatcher +
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.
+
+For blocks, given
+  b = ^(int y) { printf("%d", y) };
+
+the matcher blockDecl(hasAnyParameter(hasName("y")))
+matches the declaration of the block b with hasParameter
+matching y.
+
+ + +Matcher<BlockDecl>hasParameterunsigned N, Matcher<ParmVarDecl> InnerMatcher +
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.
+
+ + Matcher<BlockPointerTypeLoc>pointeeLocMatcher<TypeLoc>
Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
@@ -5353,6 +5413,13 @@
 the matcher objcMethodDecl(hasAnyParameter(hasName("y")))
 matches the declaration of method f with hasParameter
 matching y.
+
+For blocks, given
+  b = ^(int y) { printf("%d", y) };
+
+the matcher blockDecl(hasAnyParameter(hasName("y")))
+matches the declaration of the block b with hasParameter
+matching y.
 
@@ -5784,6 +5851,13 @@ the matcher objcMethodDecl(hasAnyParameter(hasName("y"))) matches the declaration of method f with hasParameter matching y. + +For blocks, given + b = ^(int y) { printf("%d", y) }; + +the matcher blockDecl(hasAnyParameter(hasName("y"))) +matches the declaration of the block b with hasParameter +matching y. Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -1227,6 +1227,19 @@ extern const internal::VariadicDynCastAllOfMatcher objcMethodDecl; +/// Matches Objective-C block declarations. +/// +/// Example matches the declaration of the nameless block printing an input +/// integer. +/// +/// \code +/// myFunc(^(int p) { +/// printf("%d", p); +/// }) +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher + blockDecl; + /// Matches Objective-C instance variable declarations. /// /// Example matches _enabled @@ -3500,7 +3513,8 @@ /// matching y. AST_POLYMORPHIC_MATCHER_P2(hasParameter, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, - ObjCMethodDecl), + ObjCMethodDecl, + BlockDecl), unsigned, N, internal::Matcher, InnerMatcher) { return (N < Node.parameters().size() @@ -3582,9 +3596,19 @@ /// the matcher objcMethodDecl(hasAnyParameter(hasName("y"))) /// matches the declaration of method f with hasParameter /// matching y. +/// +/// For blocks, given +/// \code +/// b = ^(int y) { printf("%d", y) }; +/// \endcode +/// +/// the matcher blockDecl(hasAnyParameter(hasName("y"))) +/// matches the declaration of the block b with hasParameter +/// matching y. AST_POLYMORPHIC_MATCHER_P(hasAnyParameter, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, - ObjCMethodDecl), + ObjCMethodDecl, + BlockDecl), internal::Matcher, InnerMatcher) { return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(), Index: lib/ASTMatchers/ASTMatchersInternal.cpp =================================================================== --- lib/ASTMatchers/ASTMatchersInternal.cpp +++ lib/ASTMatchers/ASTMatchersInternal.cpp @@ -626,6 +626,8 @@ objcCategoryImplDecl; const internal::VariadicDynCastAllOfMatcher objcMethodDecl; +const internal::VariadicDynCastAllOfMatcher + blockDecl; const internal::VariadicDynCastAllOfMatcher objcIvarDecl; const internal::VariadicDynCastAllOfMatcher objcPropertyDecl; Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -406,6 +406,7 @@ REGISTER_MATCHER(objcIvarDecl); REGISTER_MATCHER(objcMessageExpr); REGISTER_MATCHER(objcMethodDecl); + REGISTER_MATCHER(blockDecl); REGISTER_MATCHER(objcObjectPointerType); REGISTER_MATCHER(objcPropertyDecl); REGISTER_MATCHER(objcProtocolDecl); Index: unittests/ASTMatchers/ASTMatchersTest.h =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.h +++ unittests/ASTMatchers/ASTMatchersTest.h @@ -132,7 +132,7 @@ bool ExpectMatch = true) { return matchesConditionally(Code, AMatcher, ExpectMatch, {"-fobjc-nonfragile-abi", "-Wno-objc-root-class", - "-Wno-incomplete-implementation"}, + "-fblocks", "-Wno-incomplete-implementation"}, FileContentMappings(), "input.m"); } Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -541,6 +541,8 @@ cxxMethodDecl(hasParameter(0, hasName("x"))))); EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end", objcMethodDecl(hasParameter(0, hasName("x"))))); + EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }", + blockDecl(hasParameter(0, hasName("p"))))); } TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) { @@ -572,6 +574,8 @@ cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X"))))))); EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) x; @end", objcMethodDecl(hasAnyParameter(hasName("x"))))); + EXPECT_TRUE(matchesObjC("int main() { void (^b)(int) = ^(int p) {}; }", + blockDecl(hasAnyParameter(hasName("p"))))); } TEST(Returns, MatchesReturnTypes) {