Skip to content

[clang][HeuristicResolver] Default argument heuristic for template parameters #132465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

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 Mar 21, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2025

@llvm/pr-subscribers-clang

Author: Nathan Ridge (HighCommander4)

Changes

Fixes clangd/clangd#1056


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

2 Files Affected:

  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+15)
  • (modified) clang/unittests/Sema/HeuristicResolverTest.cpp (+34)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp
index 7aecd2a73b539..4544d75ea73c4 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -11,6 +11,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/TemplateBase.h"
 #include "clang/AST/Type.h"
 
 namespace clang {
@@ -247,6 +248,20 @@ QualType HeuristicResolverImpl::simplifyType(QualType Type, const Expr *E,
         }
       }
     }
+    if (const auto *TTPT = dyn_cast_if_present<TemplateTypeParmType>(T.Type)) {
+      // We can't do much useful with a template parameter (e.g. we cannot look
+      // up member names inside it). However, if the template parameter has a
+      // default argument, as a heuristic we can replace T with the default
+      // argument type.
+      if (const auto *TTPD = TTPT->getDecl()) {
+        if (TTPD->hasDefaultArgument()) {
+          const auto &DefaultArg = TTPD->getDefaultArgument().getArgument();
+          if (DefaultArg.getKind() == TemplateArgument::Type) {
+            return {DefaultArg.getAsType()};
+          }
+        }
+      }
+    }
     return T;
   };
   // As an additional protection against infinite loops, bound the number of
diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp
index c7cfe7917c532..f7eb4b23c2ab0 100644
--- a/clang/unittests/Sema/HeuristicResolverTest.cpp
+++ b/clang/unittests/Sema/HeuristicResolverTest.cpp
@@ -410,6 +410,40 @@ TEST(HeuristicResolver, MemberExpr_HangIssue126536) {
       cxxDependentScopeMemberExpr(hasMemberName("foo")).bind("input"));
 }
 
+TEST(HeuristicResolver, MemberExpr_DefaultTemplateArgument) {
+  std::string Code = R"cpp(
+    struct Default {
+      void foo();
+    };
+    template <typename T = Default>
+    void bar(T t) {
+      t.foo();
+    }
+  )cpp";
+  // Test resolution of "foo" in "t.foo()".
+  expectResolution(
+      Code, &HeuristicResolver::resolveMemberExpr,
+      cxxDependentScopeMemberExpr(hasMemberName("foo")).bind("input"),
+      cxxMethodDecl(hasName("foo")).bind("output"));
+}
+
+TEST(HeuristicResolver, MemberExpr_DefaultTemplateArgument_Recursive) {
+  std::string Code = R"cpp(
+    struct Default {
+      void foo();
+    };
+    template <typename D = Default, typename T = D>
+    void bar(T t) {
+      t.foo();
+    }
+  )cpp";
+  // Test resolution of "foo" in "t.foo()".
+  expectResolution(
+      Code, &HeuristicResolver::resolveMemberExpr,
+      cxxDependentScopeMemberExpr(hasMemberName("foo")).bind("input"),
+      cxxMethodDecl(hasName("foo")).bind("output"));
+}
+
 TEST(HeuristicResolver, DeclRefExpr_StaticMethod) {
   std::string Code = R"cpp(
     template <typename T>

@HighCommander4
Copy link
Collaborator Author

This was previously submitted and approved at #131074, I just mistakenly merged that into a user branch.

@HighCommander4 HighCommander4 merged commit 44573bc into main Mar 21, 2025
14 checks passed
@HighCommander4 HighCommander4 deleted the users/HighCommander4/clangd-issue-1056-resubmit branch March 21, 2025 23:15
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