[llvm-branch-commits] [clang] [clang-tools-extra] [clang][HeuristicResolver] Default argument heuristic for template parameters (PR #131074)

Younan Zhang via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Mar 19 18:50:34 PDT 2025


================
@@ -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();
----------------
zyn0217 wrote:

Do we traverse the default arguments recursively? I'm thinking a case like
```cpp
template <typename W = Waldo, typename T = W>
void bar(T t) {
  t.foo(); // Can we resolve it to Waldo::foo()?
}
```

Also there are some usages for template template parameters, e.g.
```cpp
template <class E, class A, template <class, class> class V = std::vector>
void foo(V<E, A>) {
  V.push_back(42); // Would be great to resolve it to std::vector<>::push_back()
}
```

However it depends on the implementation complexity - there's no necessity to handle these in this patch

https://github.com/llvm/llvm-project/pull/131074


More information about the llvm-branch-commits mailing list