[llvm-branch-commits] [clang] [clang-tools-extra] [clang][HeuristicResolver] Default argument heuristic for template parameters (PR #131074)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Mar 14 09:13:55 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Nathan Ridge (HighCommander4)
<details>
<summary>Changes</summary>
Fixes https://github.com/clangd/clangd/discussions/1056
---
Full diff: https://github.com/llvm/llvm-project/pull/131074.diff
3 Files Affected:
- (modified) clang-tools-extra/clangd/unittests/XRefsTests.cpp (+1-1)
- (modified) clang/lib/Sema/HeuristicResolver.cpp (+15)
- (modified) clang/unittests/Sema/HeuristicResolverTest.cpp (+17)
``````````diff
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>
``````````
</details>
https://github.com/llvm/llvm-project/pull/131074
More information about the llvm-branch-commits
mailing list