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 @@ -125,6 +125,7 @@ return !D->isCXXInstanceMember(); }; const auto ValueFilter = [](const NamedDecl *D) { return isa(D); }; +const auto TypeFilter = [](const NamedDecl *D) { return !isa(D); }; // Given the type T of a dependent expression that appears of the LHS of a // "->", heuristically find a corresponding pointee type in whose scope we @@ -291,10 +292,8 @@ // and both are lossy. We must know upfront what the caller ultimately wants. // // FIXME: improve common dependent scope using name lookup in primary templates. -// We currently handle DependentScopeDeclRefExpr and -// CXXDependentScopeMemberExpr, but some other constructs remain to be handled: -// - DependentTemplateSpecializationType, -// - DependentNameType +// We currently handle several dependent constructs, but some others remain to +// be handled: // - UnresolvedUsingTypenameDecl struct TargetFinder { using RelSet = DeclRelationSet; @@ -536,6 +535,23 @@ if (auto *TD = DTST->getTemplateName().getAsTemplateDecl()) Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern); } + void VisitDependentNameType(const DependentNameType *DNT) { + for (const NamedDecl *ND : getMembersReferencedViaDependentName( + DNT->getQualifier()->getAsType(), + [DNT](ASTContext &) { return DNT->getIdentifier(); }, + TypeFilter)) { + Outer.add(ND, Flags); + } + } + void VisitDependentTemplateSpecializationType( + const DependentTemplateSpecializationType *DTST) { + for (const NamedDecl *ND : getMembersReferencedViaDependentName( + DTST->getQualifier()->getAsType(), + [DTST](ASTContext &) { return DTST->getIdentifier(); }, + TypeFilter)) { + Outer.add(ND, Flags); + } + } void VisitTypedefType(const TypedefType *TT) { Outer.add(TT->getDecl(), Flags); } 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 @@ -731,6 +731,33 @@ "template T convert() const"); } +TEST_F(TargetDeclTest, DependentTypes) { + Flags = {"-fno-delayed-template-parsing"}; + + // Heuristic resolution of dependent type name + Code = R"cpp( + template + struct A { struct B {}; }; + + template + void foo(typename A::[[B]]); + )cpp"; + EXPECT_DECLS("DependentNameTypeLoc", "struct B"); + + // Heuristic resolution of dependent template name + Code = R"cpp( + template + struct A { + template struct B {}; + }; + + template + void foo(typename A::template [[B]]); + )cpp"; + EXPECT_DECLS("DependentTemplateSpecializationTypeLoc", + "template struct B"); +} + TEST_F(TargetDeclTest, ObjC) { Flags = {"-xobjective-c"}; Code = R"cpp(