nridge created this revision. nridge added reviewers: hokein, sammccall. Herald added subscribers: kadircet, arphaman. Herald added a project: All. nridge requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang-tools-extra.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D152645 Files: clang-tools-extra/clangd/HeuristicResolver.cpp clang-tools-extra/clangd/HeuristicResolver.h 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 @@ -877,6 +877,22 @@ } )cpp"; EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()"); + + Code = R"cpp( + template <typename T> + struct Waldo { + void find(); + }; + template <typename T> + struct MetaWaldo { + using Type = Waldo<T>; + }; + template <typename T> + void foo(typename MetaWaldo<T>::Type w) { + w.[[find]](); + } + )cpp"; + EXPECT_DECLS("CXXDependentScopeMemberExpr", "void find()"); } TEST_F(TargetDeclTest, DependentTypes) { Index: clang-tools-extra/clangd/HeuristicResolver.h =================================================================== --- clang-tools-extra/clangd/HeuristicResolver.h +++ clang-tools-extra/clangd/HeuristicResolver.h @@ -94,6 +94,14 @@ // `E`. const Type *resolveExprToType(const Expr *E) const; std::vector<const NamedDecl *> resolveExprToDecls(const Expr *E) const; + + // Helper function for HeuristicResolver::resolveDependentMember() + // which takes a possibly-dependent type `T` and heuristically + // resolves it to a CXXRecordDecl in which we can try name lookup. + CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) const; + + const Type * + resolveDeclsToType(const std::vector<const NamedDecl *> &Decls) const; }; } // namespace clangd Index: clang-tools-extra/clangd/HeuristicResolver.cpp =================================================================== --- clang-tools-extra/clangd/HeuristicResolver.cpp +++ clang-tools-extra/clangd/HeuristicResolver.cpp @@ -10,6 +10,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/Type.h" namespace clang { namespace clangd { @@ -29,15 +30,35 @@ return isa<TemplateDecl>(D); }; +const Type *HeuristicResolver::resolveDeclsToType( + const std::vector<const NamedDecl *> &Decls) const { + if (Decls.size() != 1) // Names an overload set -- just bail. + return nullptr; + if (const auto *TD = dyn_cast<TypeDecl>(Decls[0])) { + return Ctx.getTypeDeclType(TD).getTypePtr(); + } + if (const auto *VD = dyn_cast<ValueDecl>(Decls[0])) { + return VD->getType().getTypePtrOrNull(); + } + return nullptr; +} + // Helper function for HeuristicResolver::resolveDependentMember() // which takes a possibly-dependent type `T` and heuristically // resolves it to a CXXRecordDecl in which we can try name lookup. -CXXRecordDecl *resolveTypeToRecordDecl(const Type *T) { +CXXRecordDecl *HeuristicResolver::resolveTypeToRecordDecl(const Type *T) const { assert(T); // Unwrap type sugar such as type aliases. T = T->getCanonicalTypeInternal().getTypePtr(); + if (const auto *DNT = T->getAs<DependentNameType>()) { + T = resolveDeclsToType(resolveDependentNameType(DNT)); + if (!T) + return nullptr; + T = T->getCanonicalTypeInternal().getTypePtr(); + } + if (const auto *RT = T->getAs<RecordType>()) return dyn_cast<CXXRecordDecl>(RT->getDecl()); @@ -185,18 +206,6 @@ DTST->getIdentifier(), TemplateFilter); } -const Type *resolveDeclsToType(const std::vector<const NamedDecl *> &Decls) { - if (Decls.size() != 1) // Names an overload set -- just bail. - return nullptr; - if (const auto *TD = dyn_cast<TypeDecl>(Decls[0])) { - return TD->getTypeForDecl(); - } - if (const auto *VD = dyn_cast<ValueDecl>(Decls[0])) { - return VD->getType().getTypePtrOrNull(); - } - return nullptr; -} - std::vector<const NamedDecl *> HeuristicResolver::resolveExprToDecls(const Expr *E) const { if (const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(E)) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits