r332545 - [ASTMatchers] Introduce a blockDecl matcher for matching block declarations

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Wed May 16 15:47:03 PDT 2018


Author: george.karpenkov
Date: Wed May 16 15:47:03 2018
New Revision: 332545

URL: http://llvm.org/viewvc/llvm-project?rev=332545&view=rev
Log:
[ASTMatchers] Introduce a blockDecl matcher for matching block declarations

Blocks can be matched just as well as functions or Objective-C methods.

Differential Revision: https://reviews.llvm.org/D46980

Modified:
    cfe/trunk/docs/LibASTMatchersReference.html
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
    cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=332545&r1=332544&r2=332545&view=diff
==============================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Wed May 16 15:47:03 2018
@@ -124,6 +124,18 @@ accessSpecDecl()
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('blockDecl0')"><a name="blockDecl0Anchor">blockDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockDecl.html">BlockDecl</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="blockDecl0"><pre>Matches block declarations.
+
+Example matches the declaration of the nameless block printing an input
+integer.
+
+  myFunc(^(int p) {
+    printf("%d", p);
+  })
+</pre></td></tr>
+
+
 <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('classTemplateDecl0')"><a name="classTemplateDecl0Anchor">classTemplateDecl</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateDecl.html">ClassTemplateDecl</a>>...</td></tr>
 <tr><td colspan="4" class="doc" id="classTemplateDecl0"><pre>Matches C++ class template declarations.
 
@@ -4352,6 +4364,55 @@ Example matches b (matcher = binaryOpera
 </pre></td></tr>
 
 
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockDecl.html">BlockDecl</a>></td><td class="name" onclick="toggle('hasAnyParameter2')"><a name="hasAnyParameter2Anchor">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="hasAnyParameter2"><pre>Matches any parameter of a function or an ObjC method declaration or a
+block.
+
+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.
+</pre></td></tr>
+
+
+<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1BlockDecl.html">BlockDecl</a>></td><td class="name" onclick="toggle('hasParameter2')"><a name="hasParameter2Anchor">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="hasParameter2"><pre>Matches the n'th parameter of a function or an ObjC method
+declaration or a block.
+
+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_1BlockPointerTypeLoc.html">BlockPointerTypeLoc</a>></td><td class="name" onclick="toggle('pointeeLoc0')"><a name="pointeeLoc0Anchor">pointeeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td></tr>
 <tr><td colspan="4" class="doc" id="pointeeLoc0"><pre>Narrows PointerType (and similar) matchers to those where the
 pointee matches a given matcher.
@@ -5336,7 +5397,8 @@ matches 'int x = 0' in
 
 
 <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 or ObjC method declaration.
+<tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function or an ObjC method declaration or a
+block.
 
 Does not match the 'this' parameter of a method.
 
@@ -5353,6 +5415,13 @@ For ObjectiveC, given
 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.
 </pre></td></tr>
 
 
@@ -5393,7 +5462,7 @@ with compoundStmt()
 
 <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 or an ObjC method
-declaration.
+declaration or a block.
 
 Given
   class X { void f(int x) {} };
@@ -5767,7 +5836,8 @@ matches the [webView ...] message invoca
 
 
 <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.
+<tr><td colspan="4" class="doc" id="hasAnyParameter1"><pre>Matches any parameter of a function or an ObjC method declaration or a
+block.
 
 Does not match the 'this' parameter of a method.
 
@@ -5784,12 +5854,19 @@ For ObjectiveC, given
 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.
 </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.
+declaration or a block.
 
 Given
   class X { void f(int x) {} };

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=332545&r1=332544&r2=332545&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed May 16 15:47:03 2018
@@ -1227,6 +1227,19 @@ extern const internal::VariadicDynCastAl
 extern const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
     objcMethodDecl;
 
+/// Matches 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<Decl, BlockDecl>
+    blockDecl;
+
 /// Matches Objective-C instance variable declarations.
 ///
 /// Example matches _enabled
@@ -3479,7 +3492,7 @@ AST_MATCHER(CXXConstructExpr, requiresZe
 }
 
 /// Matches the n'th parameter of a function or an ObjC method
-/// declaration.
+/// declaration or a block.
 ///
 /// Given
 /// \code
@@ -3500,7 +3513,8 @@ AST_MATCHER(CXXConstructExpr, requiresZe
 /// matching y.
 AST_POLYMORPHIC_MATCHER_P2(hasParameter,
                            AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
-                                                           ObjCMethodDecl),
+                                                           ObjCMethodDecl,
+                                                           BlockDecl),
                            unsigned, N, internal::Matcher<ParmVarDecl>,
                            InnerMatcher) {
   return (N < Node.parameters().size()
@@ -3561,7 +3575,8 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgume
   return Matched;
 }
 
-/// Matches any parameter of a function or ObjC method declaration.
+/// Matches any parameter of a function or an ObjC method declaration or a
+/// block.
 ///
 /// Does not match the 'this' parameter of a method.
 ///
@@ -3582,9 +3597,19 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgume
 /// 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<ParmVarDecl>,
                           InnerMatcher) {
   return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),

Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=332545&r1=332544&r2=332545&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Wed May 16 15:47:03 2018
@@ -626,6 +626,8 @@ const internal::VariadicDynCastAllOfMatc
     objcCategoryImplDecl;
 const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
     objcMethodDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, BlockDecl>
+    blockDecl;
 const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
 const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
     objcPropertyDecl;

Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=332545&r1=332544&r2=332545&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Wed May 16 15:47:03 2018
@@ -136,6 +136,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(autoType);
   REGISTER_MATCHER(binaryOperator);
   REGISTER_MATCHER(binaryConditionalOperator);
+  REGISTER_MATCHER(blockDecl);
   REGISTER_MATCHER(blockPointerType);
   REGISTER_MATCHER(booleanType);
   REGISTER_MATCHER(breakStmt);

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h?rev=332545&r1=332544&r2=332545&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h Wed May 16 15:47:03 2018
@@ -132,7 +132,7 @@ testing::AssertionResult matchesObjC(con
                                      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");
 }
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=332545&r1=332544&r2=332545&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Wed May 16 15:47:03 2018
@@ -541,6 +541,8 @@ TEST(HasParameter, CallsInnerMatcher) {
                          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 @@ TEST(HasAnyParameter, MatchesIndependent
     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) {




More information about the cfe-commits mailing list