Skip to content

Commit eb1d908

Browse files
committed
Adds AST matcher for ObjCStringLiteral
Differential Revision: https://reviews.llvm.org/D128103
1 parent 5ca39a5 commit eb1d908

File tree

6 files changed

+86
-47
lines changed

6 files changed

+86
-47
lines changed

clang/docs/LibASTMatchersReference.html

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ <h2 id="decl-matchers">Node Matchers</h2>
12361236
#pragma omp parallel
12371237

12381238
``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``,
1239-
``default(private)`` and ``default(firstprivate)``
1239+
`` default(private)`` and ``default(firstprivate)``
12401240
</pre></td></tr>
12411241

12421242

@@ -2036,6 +2036,14 @@ <h2 id="decl-matchers">Node Matchers</h2>
20362036
</pre></td></tr>
20372037

20382038

2039+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('objcStringLiteral0')"><a name="objcStringLiteral0Anchor">objcStringLiteral</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCStringLiteral.html">ObjCStringLiteral</a>&gt;...</td></tr>
2040+
<tr><td colspan="4" class="doc" id="objcStringLiteral0"><pre>Matches ObjectiveC String literal expressions.
2041+
2042+
Example matches @"abcd"
2043+
NSString *s = @"abcd";
2044+
</pre></td></tr>
2045+
2046+
20392047
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('objcThrowStmt0')"><a name="objcThrowStmt0Anchor">objcThrowStmt</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCAtThrowStmt.html">ObjCAtThrowStmt</a>&gt;...</td></tr>
20402048
<tr><td colspan="4" class="doc" id="objcThrowStmt0"><pre>Matches Objective-C statements.
20412049

@@ -4716,8 +4724,8 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47164724
</pre></td></tr>
47174725

47184726

4719-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isPrivateKind0')"><a name="isPrivateKind0Anchor">isFirstPrivateKind</a></td><td></td></tr>
4720-
<tr><td colspan="4" class="doc" id="isPrivateKind0"><pre>Matches if the OpenMP ``default`` clause has ``private`` kind
4727+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isFirstPrivateKind0')"><a name="isFirstPrivateKind0Anchor">isFirstPrivateKind</a></td><td></td></tr>
4728+
<tr><td colspan="4" class="doc" id="isFirstPrivateKind0"><pre>Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
47214729
specified.
47224730

47234731
Given
@@ -4729,12 +4737,12 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47294737
#pragma omp parallel default(firstprivate)
47304738

47314739
``ompDefaultClause(isFirstPrivateKind())`` matches only
4732-
``default(private)``.
4740+
``default(firstprivate)``.
47334741
</pre></td></tr>
47344742

4735-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isFirstPrivateKind0')"><a name="isFirstPrivateKind0Anchor">isFirstPrivateKind</a></td><td></td></tr>
4736-
<tr><td colspan="4" class="doc" id="isFirstPrivateKind0"><pre>Matches if the OpenMP ``default`` clause has ``firstprivate`` kind
4737-
specified.
4743+
4744+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isNoneKind0')"><a name="isNoneKind0Anchor">isNoneKind</a></td><td></td></tr>
4745+
<tr><td colspan="4" class="doc" id="isNoneKind0"><pre>Matches if the OpenMP ``default`` clause has ``none`` kind specified.
47384746

47394747
Given
47404748

@@ -4744,13 +4752,13 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47444752
#pragma omp parallel default(private)
47454753
#pragma omp parallel default(firstprivate)
47464754

4747-
``ompDefaultClause(isFirstPrivateKind())`` matches only
4748-
``default(firstprivate)``.
4755+
``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
47494756
</pre></td></tr>
47504757

47514758

4752-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isNoneKind0')"><a name="isNoneKind0Anchor">isNoneKind</a></td><td></td></tr>
4753-
<tr><td colspan="4" class="doc" id="isNoneKind0"><pre>Matches if the OpenMP ``default`` clause has ``none`` kind specified.
4759+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPDefaultClause.html">OMPDefaultClause</a>&gt;</td><td class="name" onclick="toggle('isPrivateKind0')"><a name="isPrivateKind0Anchor">isPrivateKind</a></td><td></td></tr>
4760+
<tr><td colspan="4" class="doc" id="isPrivateKind0"><pre>Matches if the OpenMP ``default`` clause has ``private`` kind
4761+
specified.
47544762

47554763
Given
47564764

@@ -4760,7 +4768,8 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
47604768
#pragma omp parallel default(private)
47614769
#pragma omp parallel default(firstprivate)
47624770

4763-
``ompDefaultClause(isNoneKind())`` matches only ``default(none)``.
4771+
``ompDefaultClause(isPrivateKind())`` matches only
4772+
``default(private)``.
47644773
</pre></td></tr>
47654774

47664775

@@ -7411,8 +7420,9 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
74117420
</pre></td></tr>
74127421

74137422

7414-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('forEachTemplateArgument0')"><a name="forEachTemplateArgument0Anchor">forEachTemplateArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
7415-
<tr><td colspan="4" class="doc" id="forEachTemplateArgument0"><pre>Matches classTemplateSpecialization, templateSpecializationType and functionDecl nodes where the template argument matches the inner matcher.
7423+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('forEachTemplateArgument0')"><a name="forEachTemplateArgument0Anchor">forEachTemplateArgument</a></td><td>clang::ast_matchers::Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
7424+
<tr><td colspan="4" class="doc" id="forEachTemplateArgument0"><pre>Matches classTemplateSpecialization, templateSpecializationType and
7425+
functionDecl nodes where the template argument matches the inner matcher.
74167426
This matcher may produce multiple matches.
74177427

74187428
Given
@@ -7427,10 +7437,8 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
74277437

74287438
bool B = false;
74297439
f(R, B);
7430-
74317440
templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
74327441
matches twice, with expr() matching 'R * 2' and 'R * 4'
7433-
74347442
functionDecl(forEachTemplateArgument(refersToType(builtinType())))
74357443
matches the specialization f&lt;unsigned, bool&gt; twice, for 'unsigned'
74367444
and 'bool'
@@ -8180,6 +8188,31 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
81808188
</pre></td></tr>
81818189

81828190

8191+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('forEachTemplateArgument2')"><a name="forEachTemplateArgument2Anchor">forEachTemplateArgument</a></td><td>clang::ast_matchers::Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
8192+
<tr><td colspan="4" class="doc" id="forEachTemplateArgument2"><pre>Matches classTemplateSpecialization, templateSpecializationType and
8193+
functionDecl nodes where the template argument matches the inner matcher.
8194+
This matcher may produce multiple matches.
8195+
8196+
Given
8197+
template &lt;typename T, unsigned N, unsigned M&gt;
8198+
struct Matrix {};
8199+
8200+
constexpr unsigned R = 2;
8201+
Matrix&lt;int, R * 2, R * 4&gt; M;
8202+
8203+
template &lt;typename T, typename U&gt;
8204+
void f(T&amp;&amp; t, U&amp;&amp; u) {}
8205+
8206+
bool B = false;
8207+
f(R, B);
8208+
templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
8209+
matches twice, with expr() matching 'R * 2' and 'R * 4'
8210+
functionDecl(forEachTemplateArgument(refersToType(builtinType())))
8211+
matches the specialization f&lt;unsigned, bool&gt; twice, for 'unsigned'
8212+
and 'bool'
8213+
</pre></td></tr>
8214+
8215+
81838216
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyBody0')"><a name="hasAnyBody0Anchor">hasAnyBody</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
81848217
<tr><td colspan="4" class="doc" id="hasAnyBody0"><pre>Matches a function declaration that has a given body present in the AST.
81858218
Note that this matcher matches all the declarations of a function whose
@@ -8227,32 +8260,6 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
82278260
</pre></td></tr>
82288261

82298262

8230-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('forEachTemplateArgument1')"><a name="forEachTemplateArgument1Anchor">forEachTemplateArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
8231-
<tr><td colspan="4" class="doc" id="forEachTemplateArgument1"><pre>Matches classTemplateSpecialization, templateSpecializationType and functionDecl nodes where the template argument matches the inner matcher.
8232-
This matcher may produce multiple matches.
8233-
8234-
Given
8235-
template &lt;typename T, unsigned N, unsigned M&gt;
8236-
struct Matrix {};
8237-
8238-
constexpr unsigned R = 2;
8239-
Matrix&lt;int, R * 2, R * 4&gt; M;
8240-
8241-
template &lt;typename T, typename U&gt;
8242-
void f(T&amp;&amp; t, U&amp;&amp; u) {}
8243-
8244-
bool B = false;
8245-
f(R, B);
8246-
8247-
templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
8248-
matches twice, with expr() matching 'R * 2' and 'R * 4'
8249-
8250-
functionDecl(forEachTemplateArgument(refersToType(builtinType())))
8251-
matches the specialization f&lt;unsigned, bool&gt; twice, for 'unsigned'
8252-
and 'bool'
8253-
</pre></td></tr>
8254-
8255-
82568263
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyTemplateArgument2')"><a name="hasAnyTemplateArgument2Anchor">hasAnyTemplateArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
82578264
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument2"><pre>Matches classTemplateSpecializations, templateSpecializationType and
82588265
functionDecl that have at least one TemplateArgument matching the given
@@ -9477,11 +9484,11 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
94779484
</pre></td></tr>
94789485

94799486

9480-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('forEachTemplateArgument2')"><a name="forEachTemplateArgument2Anchor">forEachTemplateArgument</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
9481-
<tr><td colspan="4" class="doc" id="forEachTemplateArgument2"><pre>Matches classTemplateSpecialization, templateSpecializationType and functionDecl nodes where the template argument matches the inner matcher.
9487+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('forEachTemplateArgument1')"><a name="forEachTemplateArgument1Anchor">forEachTemplateArgument</a></td><td>clang::ast_matchers::Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
9488+
<tr><td colspan="4" class="doc" id="forEachTemplateArgument1"><pre>Matches classTemplateSpecialization, templateSpecializationType and
9489+
functionDecl nodes where the template argument matches the inner matcher.
94829490
This matcher may produce multiple matches.
94839491

9484-
94859492
Given
94869493
template &lt;typename T, unsigned N, unsigned M&gt;
94879494
struct Matrix {};
@@ -9494,10 +9501,8 @@ <h2 id="traversal-matchers">AST Traversal Matchers</h2>
94949501

94959502
bool B = false;
94969503
f(R, B);
9497-
94989504
templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
94999505
matches twice, with expr() matching 'R * 2' and 'R * 4'
9500-
95019506
functionDecl(forEachTemplateArgument(refersToType(builtinType())))
95029507
matches the specialization f&lt;unsigned, bool&gt; twice, for 'unsigned'
95039508
and 'bool'

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,9 @@ AST Matchers
565565

566566
- Added ``forEachTemplateArgument`` matcher which creates a match every
567567
time a ``templateArgument`` matches the matcher supplied to it.
568+
569+
- Added ``objcStringLiteral`` matcher which matches ObjectiveC String
570+
literal expressions.
568571

569572
clang-format
570573
------------

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,6 +1515,15 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
15151515
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
15161516
objcMessageExpr;
15171517

1518+
/// Matches ObjectiveC String literal expressions.
1519+
///
1520+
/// Example matches @"abcd"
1521+
/// \code
1522+
/// NSString *s = @"abcd";
1523+
/// \endcode
1524+
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral>
1525+
objcStringLiteral;
1526+
15181527
/// Matches Objective-C interface declarations.
15191528
///
15201529
/// Example matches Foo

clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
917917
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
918918
cxxBoolLiteral;
919919
const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
920+
const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCStringLiteral> objcStringLiteral;
920921
const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
921922
characterLiteral;
922923
const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>

clang/lib/ASTMatchers/Dynamic/Registry.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ RegistryMaps::RegistryMaps() {
505505
REGISTER_MATCHER(objcObjectPointerType);
506506
REGISTER_MATCHER(objcPropertyDecl);
507507
REGISTER_MATCHER(objcProtocolDecl);
508+
REGISTER_MATCHER(objcStringLiteral);
508509
REGISTER_MATCHER(objcThrowStmt);
509510
REGISTER_MATCHER(objcTryStmt);
510511
REGISTER_MATCHER(ofClass);

clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,6 +2352,26 @@ TEST(ASTMatchersTestObjC, ObjCMessageExpr) {
23522352
argumentCountIs(0))));
23532353
}
23542354

2355+
TEST(ASTMatchersTestObjC, ObjCStringLiteral) {
2356+
2357+
StringRef Objc1String = "@interface NSObject "
2358+
"@end "
2359+
"@interface NSString "
2360+
"@end "
2361+
"@interface Test : NSObject "
2362+
"+ (void)someFunction:(NSString *)Desc; "
2363+
"@end "
2364+
"@implementation Test "
2365+
"+ (void)someFunction:(NSString *)Desc { "
2366+
" return; "
2367+
"} "
2368+
"- (void) foo { "
2369+
" [Test someFunction:@\"Ola!\"]; "
2370+
"}\n"
2371+
"@end ";
2372+
EXPECT_TRUE(matchesObjC(Objc1String, objcStringLiteral()));
2373+
}
2374+
23552375
TEST(ASTMatchersTestObjC, ObjCDecls) {
23562376
StringRef ObjCString = "@protocol Proto "
23572377
"- (void)protoDidThing; "

0 commit comments

Comments
 (0)