https://github.com/HighCommander4 updated https://github.com/llvm/llvm-project/pull/131074
>From aeeb8f20927850b11c66110021fe404576ff084f Mon Sep 17 00:00:00 2001 From: Nathan Ridge <zeratul...@hotmail.com> Date: Thu, 13 Mar 2025 01:23:03 -0400 Subject: [PATCH] [clang][HeuristicResolver] Default argument heuristic for template parameters --- .../clangd/unittests/XRefsTests.cpp | 2 +- clang/lib/Sema/HeuristicResolver.cpp | 15 +++++++++++++++ clang/unittests/Sema/HeuristicResolverTest.cpp | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index e12d7691c58fb..693e965e78a96 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1091,7 +1091,7 @@ TEST(LocateSymbol, All) { )objc", R"cpp( struct PointerIntPairInfo { - static void *getPointer(void *Value); + static void *$decl[[getPointer]](void *Value); }; template <typename Info = PointerIntPairInfo> struct PointerIntPair { diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp index d377379c627db..feda9696b8e05 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 { @@ -125,6 +126,20 @@ TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) { if (!T) return nullptr; + // If T is the type of a template parameter, we can't get a useful TagDecl + // out of 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 *TTPT = dyn_cast<TemplateTypeParmType>(T)) { + if (const auto *TTPD = TTPT->getDecl()) { + if (TTPD->hasDefaultArgument()) { + const auto &DefaultArg = TTPD->getDefaultArgument().getArgument(); + if (DefaultArg.getKind() == TemplateArgument::Type) { + T = DefaultArg.getAsType().getTypePtrOrNull(); + } + } + } + } + // Unwrap type sugar such as type aliases. T = T->getCanonicalTypeInternal().getTypePtr(); diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp index c7cfe7917c532..5e36108172702 100644 --- a/clang/unittests/Sema/HeuristicResolverTest.cpp +++ b/clang/unittests/Sema/HeuristicResolverTest.cpp @@ -410,6 +410,23 @@ 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, DeclRefExpr_StaticMethod) { std::string Code = R"cpp( template <typename T> _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits