This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG7a709689bc17: [clangd] Handle DependentNameType in HeuristicResolver::resolveTypeToRecordDecl… (authored by nridge).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D152645/new/ 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,11 @@ // `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; }; } // 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,39 @@ return isa<TemplateDecl>(D); }; +namespace { + +const Type *resolveDeclsToType(const std::vector<const NamedDecl *> &Decls, + ASTContext &Ctx) { + 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; +} + +} // namespace + // 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), Ctx); + if (!T) + return nullptr; + T = T->getCanonicalTypeInternal().getTypePtr(); + } + if (const auto *RT = T->getAs<RecordType>()) return dyn_cast<CXXRecordDecl>(RT->getDecl()); @@ -185,18 +210,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)) { @@ -220,7 +233,7 @@ const Type *HeuristicResolver::resolveExprToType(const Expr *E) const { std::vector<const NamedDecl *> Decls = resolveExprToDecls(E); if (!Decls.empty()) - return resolveDeclsToType(Decls); + return resolveDeclsToType(Decls, Ctx); return E->getType().getTypePtr(); } @@ -239,9 +252,11 @@ case NestedNameSpecifier::TypeSpecWithTemplate: return NNS->getAsType(); case NestedNameSpecifier::Identifier: { - return resolveDeclsToType(resolveDependentMember( - resolveNestedNameSpecifierToType(NNS->getPrefix()), - NNS->getAsIdentifier(), TypeFilter)); + return resolveDeclsToType( + resolveDependentMember( + resolveNestedNameSpecifierToType(NNS->getPrefix()), + NNS->getAsIdentifier(), TypeFilter), + Ctx); } default: break;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits