Skip to content
This repository was archived by the owner on Feb 26, 2019. It is now read-only.

Commit 2ffe81c

Browse files
author
George Karpenkov
committed
[ASTMatchers] A matcher for Objective-C @autoreleasepool
Differential Revision: https://reviews.llvm.org/D48910 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@336468 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 5137aa7 commit 2ffe81c

File tree

5 files changed

+94
-8
lines changed

5 files changed

+94
-8
lines changed

docs/LibASTMatchersReference.html

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,18 @@ <h2 id="decl-matchers">Node Matchers</h2>
662662
</pre></td></tr>
663663

664664

665+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('autoreleasePoolStmt0')"><a name="autoreleasePoolStmt0Anchor">autoreleasePoolStmt</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCAutoreleasePoolStmt.html">ObjCAutoreleasePoolStmt</a>&gt;...</td></tr>
666+
<tr><td colspan="4" class="doc" id="autoreleasePoolStmt0"><pre>Matches an Objective-C autorelease pool statement.
667+
668+
Given
669+
@autoreleasepool {
670+
int x = 0;
671+
}
672+
autoreleasePoolStmt(stmt()) matches the declaration of "x"
673+
inside the autorelease pool.
674+
</pre></td></tr>
675+
676+
665677
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('binaryConditionalOperator0')"><a name="binaryConditionalOperator0Anchor">binaryConditionalOperator</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryConditionalOperator.html">BinaryConditionalOperator</a>&gt;...</td></tr>
666678
<tr><td colspan="4" class="doc" id="binaryConditionalOperator0"><pre>Matches binary conditional operator expressions (GNU extension).
667679

@@ -5222,8 +5234,8 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
52225234
</pre></td></tr>
52235235

52245236

5225-
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
5226-
<tr><td colspan="4" class="doc" id="hasType3"><pre>Overloaded to match the declaration of the expression's or value
5237+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('hasType4')"><a name="hasType4Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
5238+
<tr><td colspan="4" class="doc" id="hasType4"><pre>Overloaded to match the declaration of the expression's or value
52275239
declaration's type.
52285240

52295241
In case of a value declaration (for example a variable declaration),
@@ -5234,8 +5246,10 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
52345246

52355247
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
52365248
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
5249+
and friend class X (matcher = friendDecl(hasType("X"))
52375250
class X {};
52385251
void y(X &amp;x) { x; X z; }
5252+
class Y { friend class X; };
52395253

52405254
Usable as: Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;, Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;
52415255
</pre></td></tr>
@@ -5248,9 +5262,11 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
52485262
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
52495263
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
52505264
and U (matcher = typedefDecl(hasType(asString("int")))
5265+
and friend class X (matcher = friendDecl(hasType("X"))
52515266
class X {};
52525267
void y(X &amp;x) { x; X z; }
52535268
typedef int U;
5269+
class Y { friend class X; };
52545270
</pre></td></tr>
52555271

52565272

@@ -5396,6 +5412,42 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
53965412
</pre></td></tr>
53975413

53985414

5415+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FriendDecl.html">FriendDecl</a>&gt;</td><td class="name" onclick="toggle('hasType5')"><a name="hasType5Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
5416+
<tr><td colspan="4" class="doc" id="hasType5"><pre>Overloaded to match the declaration of the expression's or value
5417+
declaration's type.
5418+
5419+
In case of a value declaration (for example a variable declaration),
5420+
this resolves one layer of indirection. For example, in the value
5421+
declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
5422+
X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
5423+
declaration of x.
5424+
5425+
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
5426+
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
5427+
and friend class X (matcher = friendDecl(hasType("X"))
5428+
class X {};
5429+
void y(X &amp;x) { x; X z; }
5430+
class Y { friend class X; };
5431+
5432+
Usable as: Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;, Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;
5433+
</pre></td></tr>
5434+
5435+
5436+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FriendDecl.html">FriendDecl</a>&gt;</td><td class="name" onclick="toggle('hasType1')"><a name="hasType1Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
5437+
<tr><td colspan="4" class="doc" id="hasType1"><pre>Matches if the expression's or declaration's type matches a type
5438+
matcher.
5439+
5440+
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
5441+
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
5442+
and U (matcher = typedefDecl(hasType(asString("int")))
5443+
and friend class X (matcher = friendDecl(hasType("X"))
5444+
class X {};
5445+
void y(X &amp;x) { x; X z; }
5446+
typedef int U;
5447+
class Y { friend class X; };
5448+
</pre></td></tr>
5449+
5450+
53995451
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyParameter0')"><a name="hasAnyParameter0Anchor">hasAnyParameter</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>&gt; InnerMatcher</td></tr>
54005452
<tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function or an ObjC method declaration or a
54015453
block.
@@ -6432,16 +6484,18 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
64326484
</pre></td></tr>
64336485

64346486

6435-
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>&gt;</td><td class="name" onclick="toggle('hasType1')"><a name="hasType1Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
6436-
<tr><td colspan="4" class="doc" id="hasType1"><pre>Matches if the expression's or declaration's type matches a type
6487+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>&gt;</td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
6488+
<tr><td colspan="4" class="doc" id="hasType2"><pre>Matches if the expression's or declaration's type matches a type
64376489
matcher.
64386490

64396491
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
64406492
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
64416493
and U (matcher = typedefDecl(hasType(asString("int")))
6494+
and friend class X (matcher = friendDecl(hasType("X"))
64426495
class X {};
64436496
void y(X &amp;x) { x; X z; }
64446497
typedef int U;
6498+
class Y { friend class X; };
64456499
</pre></td></tr>
64466500

64476501

@@ -6564,8 +6618,8 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
65646618
matches using X::b but not using X::a </pre></td></tr>
65656619

65666620

6567-
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;</td><td class="name" onclick="toggle('hasType4')"><a name="hasType4Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
6568-
<tr><td colspan="4" class="doc" id="hasType4"><pre>Overloaded to match the declaration of the expression's or value
6621+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;</td><td class="name" onclick="toggle('hasType6')"><a name="hasType6Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
6622+
<tr><td colspan="4" class="doc" id="hasType6"><pre>Overloaded to match the declaration of the expression's or value
65696623
declaration's type.
65706624

65716625
In case of a value declaration (for example a variable declaration),
@@ -6576,23 +6630,27 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
65766630

65776631
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
65786632
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
6633+
and friend class X (matcher = friendDecl(hasType("X"))
65796634
class X {};
65806635
void y(X &amp;x) { x; X z; }
6636+
class Y { friend class X; };
65816637

65826638
Usable as: Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;, Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;
65836639
</pre></td></tr>
65846640

65856641

6586-
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;</td><td class="name" onclick="toggle('hasType2')"><a name="hasType2Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
6587-
<tr><td colspan="4" class="doc" id="hasType2"><pre>Matches if the expression's or declaration's type matches a type
6642+
<tr><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;</td><td class="name" onclick="toggle('hasType3')"><a name="hasType3Anchor">hasType</a></td><td>Matcher&lt;<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
6643+
<tr><td colspan="4" class="doc" id="hasType3"><pre>Matches if the expression's or declaration's type matches a type
65886644
matcher.
65896645

65906646
Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
65916647
and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
65926648
and U (matcher = typedefDecl(hasType(asString("int")))
6649+
and friend class X (matcher = friendDecl(hasType("X"))
65936650
class X {};
65946651
void y(X &amp;x) { x; X z; }
65956652
typedef int U;
6653+
class Y { friend class X; };
65966654
</pre></td></tr>
65976655

65986656

include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,19 @@ AST_MATCHER_P(TemplateArgument, equalsIntegralValue,
966966
return Node.getAsIntegral().toString(10) == Value;
967967
}
968968

969+
/// Matches an Objective-C autorelease pool statement.
970+
///
971+
/// Given
972+
/// \code
973+
/// @autoreleasepool {
974+
/// int x = 0;
975+
/// }
976+
/// \endcode
977+
/// autoreleasePoolStmt(stmt()) matches the declaration of "x"
978+
/// inside the autorelease pool.
979+
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
980+
ObjCAutoreleasePoolStmt> autoreleasePoolStmt;
981+
969982
/// Matches any value declaration.
970983
///
971984
/// Example matches A, B, C and F

lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@ bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
548548

549549
} // end namespace internal
550550

551+
const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAutoreleasePoolStmt>
552+
autoreleasePoolStmt;
551553
const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
552554
translationUnitDecl;
553555
const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;

lib/ASTMatchers/Dynamic/Registry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ RegistryMaps::RegistryMaps() {
134134
REGISTER_MATCHER(atomicExpr);
135135
REGISTER_MATCHER(atomicType);
136136
REGISTER_MATCHER(autoType);
137+
REGISTER_MATCHER(autoreleasePoolStmt)
137138
REGISTER_MATCHER(binaryOperator);
138139
REGISTER_MATCHER(binaryConditionalOperator);
139140
REGISTER_MATCHER(blockDecl);

unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,5 +1687,17 @@ TEST(ObjCStmtMatcher, ExceptionStmts) {
16871687
objcFinallyStmt()));
16881688
}
16891689

1690+
TEST(ObjCAutoreleaseMatcher, AutoreleasePool) {
1691+
std::string ObjCString =
1692+
"void f() {"
1693+
"@autoreleasepool {"
1694+
" int x = 1;"
1695+
"}"
1696+
"}";
1697+
EXPECT_TRUE(matchesObjC(ObjCString, autoreleasePoolStmt()));
1698+
std::string ObjCStringNoPool = "void f() { int x = 1; }";
1699+
EXPECT_FALSE(matchesObjC(ObjCStringNoPool, autoreleasePoolStmt()));
1700+
}
1701+
16901702
} // namespace ast_matchers
16911703
} // namespace clang

0 commit comments

Comments
 (0)