[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