https://github.com/HighCommander4 created https://github.com/llvm/llvm-project/pull/156404
Fixes https://github.com/clangd/clangd/issues/2478 >From 7c8f310155914c17e8e3c6d485acb4464800ddd1 Mon Sep 17 00:00:00 2001 From: Nathan Ridge <zeratul...@hotmail.com> Date: Tue, 2 Sep 2025 01:06:07 -0400 Subject: [PATCH] [clang][HeuristicResolver] Default argument heuristic for template template parameters Fixes https://github.com/clangd/clangd/issues/2478 --- clang/lib/Sema/HeuristicResolver.cpp | 19 +++++++++++++++++++ .../unittests/Sema/HeuristicResolverTest.cpp | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) 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 { _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits