[clang-tools-extra] 73adf26 - [clangd] Handle DeducedTemplateSpecializationType in HeuristicResolver (#119107)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 9 09:59:05 PST 2024
Author: Nathan Ridge
Date: 2024-12-09T12:59:01-05:00
New Revision: 73adf26d504ba945251b87d78267e2bbfd34928f
URL: https://github.com/llvm/llvm-project/commit/73adf26d504ba945251b87d78267e2bbfd34928f
DIFF: https://github.com/llvm/llvm-project/commit/73adf26d504ba945251b87d78267e2bbfd34928f.diff
LOG: [clangd] Handle DeducedTemplateSpecializationType in HeuristicResolver (#119107)
Fixes https://github.com/clangd/clangd/issues/2227
Added:
Modified:
clang-tools-extra/clangd/HeuristicResolver.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/HeuristicResolver.cpp b/clang-tools-extra/clangd/HeuristicResolver.cpp
index 26d54200eeffd2..9eb892e8e4a8ea 100644
--- a/clang-tools-extra/clangd/HeuristicResolver.cpp
+++ b/clang-tools-extra/clangd/HeuristicResolver.cpp
@@ -118,6 +118,16 @@ const Type *resolveDeclsToType(const std::vector<const NamedDecl *> &Decls,
return nullptr;
}
+TemplateName getReferencedTemplateName(const Type *T) {
+ if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
+ return TST->getTemplateName();
+ }
+ if (const auto *DTST = T->getAs<DeducedTemplateSpecializationType>()) {
+ return DTST->getTemplateName();
+ }
+ return TemplateName();
+}
+
// 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.
@@ -142,12 +152,12 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) {
if (!T)
return nullptr;
- const auto *TST = T->getAs<TemplateSpecializationType>();
- if (!TST)
+ TemplateName TN = getReferencedTemplateName(T);
+ if (TN.isNull())
return nullptr;
- const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
- TST->getTemplateName().getAsTemplateDecl());
+ const ClassTemplateDecl *TD =
+ dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
if (!TD)
return nullptr;
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 3220a5a6a98250..fc54f89f4941e1 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -842,6 +842,8 @@ TEST_F(TargetDeclTest, OverloadExpr) {
}
TEST_F(TargetDeclTest, DependentExprs) {
+ Flags.push_back("--std=c++20");
+
// Heuristic resolution of method of dependent field
Code = R"cpp(
struct A { void foo() {} };
@@ -962,6 +964,21 @@ TEST_F(TargetDeclTest, DependentExprs) {
};
)cpp";
EXPECT_DECLS("MemberExpr", "void find()");
+
+ // Base expression is the type of a non-type template parameter
+ // which is deduced using CTAD.
+ Code = R"cpp(
+ template <int N>
+ struct Waldo {
+ const int found = N;
+ };
+
+ template <Waldo W>
+ int test() {
+ return W.[[found]];
+ }
+ )cpp";
+ EXPECT_DECLS("CXXDependentScopeMemberExpr", "const int found = N");
}
TEST_F(TargetDeclTest, DependentTypes) {
More information about the cfe-commits
mailing list