Skip to content

Commit 4d6ca11

Browse files
authored
[AstMatcher]templateArgumentCountIs support FunctionDecl (#130416)
`hasTemplateArgument` and `templateArgumentCountIs` are always used together. It is more convenient to make then support `FunctionDecl`.
1 parent 009dfb4 commit 4d6ca11

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

clang/docs/LibASTMatchersReference.html

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4108,8 +4108,14 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
41084108
Given
41094109
template&lt;typename T&gt; struct C {};
41104110
C&lt;int&gt; c;
4111+
template&lt;typename T&gt; void f() {}
4112+
void func() { f&lt;int&gt;(); };
4113+
41114114
classTemplateSpecializationDecl(templateArgumentCountIs(1))
41124115
matches C&lt;int&gt;.
4116+
4117+
functionDecl(templateArgumentCountIs(1))
4118+
matches f&lt;int&gt;();
41134119
</pre></td></tr>
41144120

41154121

@@ -4833,6 +4839,23 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
48334839
</pre></td></tr>
48344840

48354841

4842+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('templateArgumentCountIs2')"><a name="templateArgumentCountIs2Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr>
4843+
<tr><td colspan="4" class="doc" id="templateArgumentCountIs2"><pre>Matches if the number of template arguments equals N.
4844+
4845+
Given
4846+
template&lt;typename T&gt; struct C {};
4847+
C&lt;int&gt; c;
4848+
template&lt;typename T&gt; void f() {}
4849+
void func() { f&lt;int&gt;(); };
4850+
4851+
classTemplateSpecializationDecl(templateArgumentCountIs(1))
4852+
matches C&lt;int&gt;.
4853+
4854+
functionDecl(templateArgumentCountIs(1))
4855+
matches f&lt;int&gt;();
4856+
</pre></td></tr>
4857+
4858+
48364859
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionProtoType.html">FunctionProtoType</a>&gt;</td><td class="name" onclick="toggle('hasDynamicExceptionSpec1')"><a name="hasDynamicExceptionSpec1Anchor">hasDynamicExceptionSpec</a></td><td></td></tr>
48374860
<tr><td colspan="4" class="doc" id="hasDynamicExceptionSpec1"><pre>Matches functions that have a dynamic exception specification.
48384861

@@ -5783,14 +5806,20 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
57835806
</pre></td></tr>
57845807

57855808

5786-
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('templateArgumentCountIs1')"><a name="templateArgumentCountIs1Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr>
5787-
<tr><td colspan="4" class="doc" id="templateArgumentCountIs1"><pre>Matches if the number of template arguments equals N.
5809+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('templateArgumentCountIs3')"><a name="templateArgumentCountIs3Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr>
5810+
<tr><td colspan="4" class="doc" id="templateArgumentCountIs3"><pre>Matches if the number of template arguments equals N.
57885811

57895812
Given
57905813
template&lt;typename T&gt; struct C {};
57915814
C&lt;int&gt; c;
5815+
template&lt;typename T&gt; void f() {}
5816+
void func() { f&lt;int&gt;(); };
5817+
57925818
classTemplateSpecializationDecl(templateArgumentCountIs(1))
57935819
matches C&lt;int&gt;.
5820+
5821+
functionDecl(templateArgumentCountIs(1))
5822+
matches f&lt;int&gt;();
57945823
</pre></td></tr>
57955824

57965825

@@ -6219,6 +6248,23 @@ <h2 id="narrowing-matchers">Narrowing Matchers</h2>
62196248
Usable as: Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
62206249
</pre></td></tr>
62216250

6251+
6252+
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1VarTemplateSpecializationDecl.html">VarTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('templateArgumentCountIs1')"><a name="templateArgumentCountIs1Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr>
6253+
<tr><td colspan="4" class="doc" id="templateArgumentCountIs1"><pre>Matches if the number of template arguments equals N.
6254+
6255+
Given
6256+
template&lt;typename T&gt; struct C {};
6257+
C&lt;int&gt; c;
6258+
template&lt;typename T&gt; void f() {}
6259+
void func() { f&lt;int&gt;(); };
6260+
6261+
classTemplateSpecializationDecl(templateArgumentCountIs(1))
6262+
matches C&lt;int&gt;.
6263+
6264+
functionDecl(templateArgumentCountIs(1))
6265+
matches f&lt;int&gt;();
6266+
</pre></td></tr>
6267+
62226268
<!--END_NARROWING_MATCHERS -->
62236269
</table>
62246270

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ AST Matchers
397397
------------
398398

399399
- Ensure ``isDerivedFrom`` matches the correct base in case more than one alias exists.
400+
- Extend ``templateArgumentCountIs`` to support function and variable template
401+
specialization.
400402

401403
clang-format
402404
------------

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,12 +1084,19 @@ AST_POLYMORPHIC_MATCHER_P2(
10841084
/// \code
10851085
/// template<typename T> struct C {};
10861086
/// C<int> c;
1087+
/// template<typename T> void f() {}
1088+
/// void func() { f<int>(); };
10871089
/// \endcode
1090+
///
10881091
/// classTemplateSpecializationDecl(templateArgumentCountIs(1))
10891092
/// matches C<int>.
1093+
///
1094+
/// functionDecl(templateArgumentCountIs(1))
1095+
/// matches f<int>();
10901096
AST_POLYMORPHIC_MATCHER_P(
10911097
templateArgumentCountIs,
10921098
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
1099+
VarTemplateSpecializationDecl, FunctionDecl,
10931100
TemplateSpecializationType),
10941101
unsigned, N) {
10951102
return internal::getTemplateSpecializationArgs(Node).size() == N;

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,13 @@ TEST_P(ASTMatchersTest, TemplateArgumentCountIs) {
20282028
EXPECT_TRUE(
20292029
notMatches("template<typename T> struct C {}; C<int> c;",
20302030
templateSpecializationType(templateArgumentCountIs(2))));
2031+
2032+
const char *FuncTemplateCode =
2033+
"template<typename T> T f(); auto v = f<int>();";
2034+
EXPECT_TRUE(
2035+
matches(FuncTemplateCode, functionDecl(templateArgumentCountIs(1))));
2036+
EXPECT_TRUE(
2037+
notMatches(FuncTemplateCode, functionDecl(templateArgumentCountIs(2))));
20312038
}
20322039

20332040
TEST_P(ASTMatchersTest, IsIntegral) {

0 commit comments

Comments
 (0)