diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -302,6 +302,8 @@ // Record the underlying decl instead, if allowed. D = USD->getTargetDecl(); Flags |= Rel::Underlying; // continue with the underlying decl. + } else if (const auto *DG = dyn_cast(D)) { + D = DG->getDeducedTemplate(); } if (const Decl *Pat = getTemplatePattern(D)) { @@ -659,6 +661,15 @@ /*IsDecl=*/true, {ND}}); } + + void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *DG) { + // The class template name in a deduction guide targets the class + // template. + Refs.push_back(ReferenceLoc{DG->getQualifierLoc(), + DG->getNameInfo().getLoc(), + /*IsDecl=*/false, + {DG->getDeducedTemplate()}}); + } }; Visitor V; diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -376,6 +376,8 @@ {"template<> class Foo", Rel::TemplateInstantiation}, {"template class Foo", Rel::TemplatePattern}); + Flags.push_back("-std=c++17"); // for CTAD tests + Code = R"cpp( // Class template argument deduction template @@ -386,9 +388,20 @@ [[Test]] a(5); } )cpp"; - Flags.push_back("-std=c++17"); EXPECT_DECLS("DeducedTemplateSpecializationTypeLoc", {"struct Test", Rel::TemplatePattern}); + + Code = R"cpp( + // Deduction guide + template + struct Test { + template + Test(I, I); + }; + template + [[Test]](I, I) -> Test; + )cpp"; + EXPECT_DECLS("CXXDeductionGuideDecl", {"template struct Test"}); } TEST_F(TargetDeclTest, Concept) { @@ -792,8 +805,8 @@ goto $1^ten; } )cpp", - "0: targets = {ten}, decl\n" - "1: targets = {ten}\n"}, + "0: targets = {ten}, decl\n" + "1: targets = {ten}\n"}, // Simple templates. {R"cpp( template struct vector { using value_type = T; }; @@ -1295,7 +1308,7 @@ "6: targets = {bar}, decl\n" "7: targets = {foo()::Bar::Foo}\n" "8: targets = {foo()::Baz::Field}\n"}, - {R"cpp( + {R"cpp( template void crash(T); template @@ -1305,10 +1318,9 @@ )cpp", "0: targets = {crash}\n" "1: targets = {}\n" - "2: targets = {T}\n" - }, - // unknown template name should not crash. - {R"cpp( + "2: targets = {T}\n"}, + // unknown template name should not crash. + {R"cpp( template