nridge created this revision. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman. Herald added a project: clang. nridge requested review of this revision. Herald added subscribers: MaskRay, ilya-biryukov.
Fixes https://github.com/clangd/clangd/issues/543 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D88469 Files: clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -731,6 +731,33 @@ "template <typename T> T convert() const"); } +TEST_F(TargetDeclTest, DependentTypes) { + Flags = {"-fno-delayed-template-parsing"}; + + // Heuristic resolution of dependent type name + Code = R"cpp( + template <typename> + struct A { struct B {}; }; + + template <typename T> + void foo(typename A<T>::[[B]]); + )cpp"; + EXPECT_DECLS("DependentNameTypeLoc", "struct B"); + + // Heuristic resolution of dependent template name + Code = R"cpp( + template <typename> + struct A { + template <typename> struct B {}; + }; + + template <typename T> + void foo(typename A<T>::template [[B]]<int>); + )cpp"; + EXPECT_DECLS("DependentTemplateSpecializationTypeLoc", + "template <typename> struct B"); +} + TEST_F(TargetDeclTest, ObjC) { Flags = {"-xobjective-c"}; Code = R"cpp( Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -125,6 +125,7 @@ return !D->isCXXInstanceMember(); }; const auto ValueFilter = [](const NamedDecl *D) { return isa<ValueDecl>(D); }; +const auto TypeFilter = [](const NamedDecl *D) { return !isa<ValueDecl>(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); }
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -731,6 +731,33 @@ "template <typename T> T convert() const"); } +TEST_F(TargetDeclTest, DependentTypes) { + Flags = {"-fno-delayed-template-parsing"}; + + // Heuristic resolution of dependent type name + Code = R"cpp( + template <typename> + struct A { struct B {}; }; + + template <typename T> + void foo(typename A<T>::[[B]]); + )cpp"; + EXPECT_DECLS("DependentNameTypeLoc", "struct B"); + + // Heuristic resolution of dependent template name + Code = R"cpp( + template <typename> + struct A { + template <typename> struct B {}; + }; + + template <typename T> + void foo(typename A<T>::template [[B]]<int>); + )cpp"; + EXPECT_DECLS("DependentTemplateSpecializationTypeLoc", + "template <typename> struct B"); +} + TEST_F(TargetDeclTest, ObjC) { Flags = {"-xobjective-c"}; Code = R"cpp( Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -125,6 +125,7 @@ return !D->isCXXInstanceMember(); }; const auto ValueFilter = [](const NamedDecl *D) { return isa<ValueDecl>(D); }; +const auto TypeFilter = [](const NamedDecl *D) { return !isa<ValueDecl>(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); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits