Skip to content

Commit bc79ec0

Browse files
authoredOct 30, 2024··
[clang][ASTMatcher] Handle variable templates in isInstantiated and isInTemplateInstantiation matchers (#110666)
Fix `isInstantiated` and `isInTemplateInstantiation` matchers, so they return true for instantiations of variable templates, and any declaration in statements contained in such instantiations.
1 parent dc1ff88 commit bc79ec0

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed
 

‎clang/docs/ReleaseNotes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,8 @@ AST Matchers
745745

746746
- Fixed a crash when traverse lambda expr with invalid captures. (#GH106444)
747747

748+
- Fixed ``isInstantiated`` and ``isInTemplateInstantiation`` to also match for variable templates. (#GH110666)
749+
748750
- Ensure ``hasName`` matches template specializations across inline namespaces,
749751
making `matchesNodeFullSlow` and `matchesNodeFullFast` consistent.
750752

‎clang/include/clang/ASTMatchers/ASTMatchers.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -6750,7 +6750,8 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
67506750
/// matches 'A(int) {...};' and 'A(unsigned) {...}'.
67516751
AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
67526752
auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
6753-
functionDecl(isTemplateInstantiation())));
6753+
functionDecl(isTemplateInstantiation()),
6754+
varDecl(isTemplateInstantiation())));
67546755
return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation)));
67556756
}
67566757

@@ -6769,9 +6770,9 @@ AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) {
67696770
/// will NOT match j += 42; as it's shared between the template definition and
67706771
/// instantiation.
67716772
AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) {
6772-
return stmt(
6773-
hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
6774-
functionDecl(isTemplateInstantiation())))));
6773+
return stmt(hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()),
6774+
functionDecl(isTemplateInstantiation()),
6775+
varDecl(isTemplateInstantiation())))));
67756776
}
67766777

67776778
/// Matches explicit template specializations of function, class, or

‎clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -3342,6 +3342,45 @@ TEST_P(ASTMatchersTest,
33423342
declStmt(isInTemplateInstantiation())));
33433343
}
33443344

3345+
TEST_P(ASTMatchersTest, IsInstantiated_MatchesVariableInstantiation) {
3346+
if (!GetParam().isCXX14OrLater()) {
3347+
return;
3348+
}
3349+
3350+
EXPECT_TRUE(matches("template<typename T> int V = 10; void x() { V<int>; }",
3351+
varDecl(isInstantiated())));
3352+
}
3353+
3354+
TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesVariableDefinition) {
3355+
if (!GetParam().isCXX14OrLater()) {
3356+
return;
3357+
}
3358+
3359+
EXPECT_TRUE(notMatches("template<typename T> int V = 10;",
3360+
varDecl(isInstantiated())));
3361+
}
3362+
3363+
TEST_P(ASTMatchersTest,
3364+
IsInTemplateInstantiation_MatchesVariableInstantiationStmt) {
3365+
if (!GetParam().isCXX14OrLater()) {
3366+
return;
3367+
}
3368+
3369+
EXPECT_TRUE(matches(
3370+
"template<typename T> auto V = []() { T i; }; void x() { V<int>(); }",
3371+
declStmt(isInTemplateInstantiation())));
3372+
}
3373+
3374+
TEST_P(ASTMatchersTest,
3375+
IsInTemplateInstantiation_NotMatchesVariableDefinitionStmt) {
3376+
if (!GetParam().isCXX14OrLater()) {
3377+
return;
3378+
}
3379+
3380+
EXPECT_TRUE(notMatches("template<typename T> auto V = []() { T i; };",
3381+
declStmt(isInTemplateInstantiation())));
3382+
}
3383+
33453384
TEST_P(ASTMatchersTest, IsInTemplateInstantiation_Sharing) {
33463385
if (!GetParam().isCXX()) {
33473386
return;

0 commit comments

Comments
 (0)
Please sign in to comment.