diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 1a179e63f902f..402203f89e23a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -745,6 +745,8 @@ AST Matchers - Fixed a crash when traverse lambda expr with invalid captures. (#GH106444) +- Fixed ``isInstantiated`` and ``isInTemplateInstantiation`` to also match for variable templates. (#GH110666) + - Ensure ``hasName`` matches template specializations across inline namespaces, making `matchesNodeFullSlow` and `matchesNodeFullFast` consistent. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 54e484d41fb1c..c77140842d7a6 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6750,7 +6750,8 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation, /// matches 'A(int) {...};' and 'A(unsigned) {...}'. AST_MATCHER_FUNCTION(internal::Matcher, isInstantiated) { auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()), - functionDecl(isTemplateInstantiation()))); + functionDecl(isTemplateInstantiation()), + varDecl(isTemplateInstantiation()))); return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation))); } @@ -6769,9 +6770,9 @@ AST_MATCHER_FUNCTION(internal::Matcher, isInstantiated) { /// will NOT match j += 42; as it's shared between the template definition and /// instantiation. AST_MATCHER_FUNCTION(internal::Matcher, isInTemplateInstantiation) { - return stmt( - hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()), - functionDecl(isTemplateInstantiation()))))); + return stmt(hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()), + functionDecl(isTemplateInstantiation()), + varDecl(isTemplateInstantiation()))))); } /// Matches explicit template specializations of function, class, or diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index d696375547acc..056b7c7b571ef 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -3342,6 +3342,45 @@ TEST_P(ASTMatchersTest, declStmt(isInTemplateInstantiation()))); } +TEST_P(ASTMatchersTest, IsInstantiated_MatchesVariableInstantiation) { + if (!GetParam().isCXX14OrLater()) { + return; + } + + EXPECT_TRUE(matches("template int V = 10; void x() { V; }", + varDecl(isInstantiated()))); +} + +TEST_P(ASTMatchersTest, IsInstantiated_NotMatchesVariableDefinition) { + if (!GetParam().isCXX14OrLater()) { + return; + } + + EXPECT_TRUE(notMatches("template int V = 10;", + varDecl(isInstantiated()))); +} + +TEST_P(ASTMatchersTest, + IsInTemplateInstantiation_MatchesVariableInstantiationStmt) { + if (!GetParam().isCXX14OrLater()) { + return; + } + + EXPECT_TRUE(matches( + "template auto V = []() { T i; }; void x() { V(); }", + declStmt(isInTemplateInstantiation()))); +} + +TEST_P(ASTMatchersTest, + IsInTemplateInstantiation_NotMatchesVariableDefinitionStmt) { + if (!GetParam().isCXX14OrLater()) { + return; + } + + EXPECT_TRUE(notMatches("template auto V = []() { T i; };", + declStmt(isInTemplateInstantiation()))); +} + TEST_P(ASTMatchersTest, IsInTemplateInstantiation_Sharing) { if (!GetParam().isCXX()) { return;