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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits