Author: Nathan Ridge Date: 2026-10-05T06:02:38Z New Revision: 487ba792d817afc4807c27a446d15c4c0669897f
URL: https://github.com/llvm/llvm-project/commit/487ba792d817afc4807c27a446d15c4c0669897f DIFF: https://github.com/llvm/llvm-project/commit/487ba792d817afc4807c27a446d15c4c0669897f.diff LOG: [clangd] Handle template template parameters in TargetFinder::VisitDeducedTemplateSpecializationType (#228601) Fixes https://github.com/clangd/clangd/issues/1870 Added: Modified: clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index 142776d0dfaa7..a3379d1337d62 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -397,14 +397,20 @@ struct TargetFinder { if (const auto *USD = DTST->getTemplateName().getAsUsingShadowDecl()) Outer.add(USD, Flags); - // FIXME: This is a workaround for https://llvm.org/PR42914, - // which is causing DTST->getDeducedType() to be empty. We - // fall back to the template pattern and miss the instantiation - // even when it's known in principle. Once that bug is fixed, - // the following code can be removed (the existing handling in - // VisitDeducedType() is sufficient). - if (auto *TD = DTST->getTemplateName().getAsTemplateDecl()) + // Template template parameters have no templated decl, so they must + // refer to the parameter itself. + if (const auto *Parm = + DTST->getTemplateName().getAsTemplateTemplateParmDecl()) { + Outer.add(Parm, Flags); + } else if (auto *TD = DTST->getTemplateName().getAsTemplateDecl()) { + // FIXME: This is a workaround for https://llvm.org/PR42914, + // which is causing DTST->getDeducedType() to be empty. We + // fall back to the template pattern and miss the instantiation + // even when it's known in principle. Once that bug is fixed, + // the following code can be removed (the existing handling in + // VisitDeducedType() is sufficient). Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern); + } } void VisitDependentNameType(const DependentNameType *DNT) { if (Outer.Resolver) { diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 0c0ef1262141f..94837803cd64c 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -593,6 +593,16 @@ TEST_F(TargetDeclTest, ClassTemplate) { EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc", {"struct Test", Rel::TemplatePattern}); + Code = R"cpp( + // Deduced specialization of a template template parameter + template <template<typename> class X> + void foo() { + [[X]] a; + } + )cpp"; + EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc", + "template <typename> class X"); + Code = R"cpp( // Deduction guide template <typename T> @@ -604,6 +614,18 @@ TEST_F(TargetDeclTest, ClassTemplate) { [[Test]](I, I) -> Test<typename I::type>; )cpp"; EXPECT_DECLS("CXXDeductionGuideDecl", {"template <typename T> struct Test"}); + + Flags.push_back("-std=c++26"); // for pack indexing + + Code = R"cpp( + // Deduced specialization of an indexed template template parameter pack + template <template <typename> class... X> + void foo() { + [[X]]...[0] a(1); + } + )cpp"; + EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc", + "template <typename> class ...X"); } TEST_F(TargetDeclTest, Concept) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
