llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Nathan Ridge (HighCommander4) <details> <summary>Changes</summary> Fixes https://github.com/clangd/clangd/issues/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 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 { `````````` </details> https://github.com/llvm/llvm-project/pull/156404 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits