Skip to content

Conversation

HighCommander4
Copy link
Collaborator

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Sep 2, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 2, 2025

@llvm/pr-subscribers-clang

Author: Nathan Ridge (HighCommander4)

Changes

Fixes clangd/clangd#2478


Full diff: https://github.com/llvm/llvm-project/pull/156404.diff

2 Files Affected:

  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+19)
  • (modified) clang/unittests/Sema/HeuristicResolverTest.cpp (+18)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp
index 8b424610feeda..6bfd1db602d4e 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -260,6 +260,25 @@ QualType HeuristicResolverImpl::simplifyType(QualType Type, const Expr *E,
         }
       }
     }
+
+    // Similarly, heuristically replace a template template parameter with its
+    // default argument if it has one.
+    if (const auto *TST =
+            dyn_cast_if_present<TemplateSpecializationType>(T.Type)) {
+      if (const auto *TTPD = dyn_cast_if_present<TemplateTemplateParmDecl>(
+              TST->getTemplateName().getAsTemplateDecl())) {
+        if (TTPD->hasDefaultArgument()) {
+          const auto &DefaultArg = TTPD->getDefaultArgument().getArgument();
+          if (DefaultArg.getKind() == TemplateArgument::Template) {
+            if (const auto *CTD = dyn_cast_if_present<ClassTemplateDecl>(
+                    DefaultArg.getAsTemplate().getAsTemplateDecl())) {
+              return {Ctx.getCanonicalTagType(CTD->getTemplatedDecl())};
+            }
+          }
+        }
+      }
+    }
+
     // Check if the expression refers to an explicit object parameter of
     // templated type. If so, heuristically treat it as having the type of the
     // enclosing class.
diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp
index cdbb4fe7c7eda..a69605e9f7466 100644
--- a/clang/unittests/Sema/HeuristicResolverTest.cpp
+++ b/clang/unittests/Sema/HeuristicResolverTest.cpp
@@ -545,6 +545,24 @@ TEST(HeuristicResolver, MemberExpr_DefaultTemplateArgument_Recursive) {
       cxxMethodDecl(hasName("foo")).bind("output"));
 }
 
+TEST(HeuristicResolver, MemberExpr_DefaultTemplateTemplateArgument) {
+  std::string Code = R"cpp(
+    template <typename T>
+    struct vector {
+      void push_back(T);
+    };
+    template <typename Element, template <typename> class Container = vector>
+    void foo(Container<Element> c, Element e) {
+      c.push_back(e);
+    }
+  )cpp";
+  // Test resolution of "push_back" in "c.push_back(e)".
+  expectResolution(
+      Code, &HeuristicResolver::resolveMemberExpr,
+      cxxDependentScopeMemberExpr(hasMemberName("push_back")).bind("input"),
+      cxxMethodDecl(hasName("push_back")).bind("output"));
+}
+
 TEST(HeuristicResolver, MemberExpr_ExplicitObjectParameter) {
   std::string Code = R"cpp(
     struct Foo {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants