Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp =================================================================== --- clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -918,7 +918,7 @@ if (ClassDecl == Declaration) { // This can happen for recursive template definitions; if the // current declaration did not match, we can safely return false. - return false; + continue; } BoundNodesTreeBuilder Result(*Builder); if (Base.matches(*ClassDecl, this, &Result)) { Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -453,6 +453,8 @@ EXPECT_TRUE(notMatches("class X;", IsDerivedFromX)); EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX)); EXPECT_TRUE(notMatches("", IsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; template class Y : Y, X {};", IsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; template class Y : X, Y {};", IsDerivedFromX)); DeclarationMatcher IsDirectlyDerivedFromX = cxxRecordDecl(isDirectlyDerivedFrom("X"));