[all-commits] [llvm/llvm-project] 9c0f55: [clang][HeuristicResolver] Resolve more dependent ...
Christian Kandeler via All-commits
all-commits at lists.llvm.org
Thu Sep 24 14:44:33 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 9c0f5509f959b0d44e2f2395bb5ef8e89eacac0b
https://github.com/llvm/llvm-project/commit/9c0f5509f959b0d44e2f2395bb5ef8e89eacac0b
Author: Christian Kandeler <christian.kandeler at qt.io>
Date: 2026-09-24 (Thu, 24 Sep 2026)
Changed paths:
M clang/lib/Sema/HeuristicResolver.cpp
M clang/unittests/Sema/HeuristicResolverTest.cpp
Log Message:
-----------
[clang][HeuristicResolver] Resolve more dependent member accesses (#223667)
`HeuristicResolver` already falls back to a template parameter's default
argument when there is nothing else it can do with the parameter, but it
only did so when it met the parameter directly. Two common ways of
arriving at one were missed, both of which occur in `std::vector`:
- through a dependent name — libstdc++ has `typedef _Alloc
allocator_type;`, so `std::vector<T>::allocator_type` resolves to a bare
template parameter;
- through the sugar of the member typedef itself, e.g. when it is the
declared return type of a member function.
Neither can be done on a canonicalized type: a canonical
`TemplateTypeParmType` does not retain its `TemplateTypeParmDecl` (see
`ASTContext::getTemplateTypeParmType()`), so there is no default
argument left to consult. The typedef's underlying type as written is
consulted instead.
A separate gap shows up on the same example. A member re-exported from a
dependent base class by a using declaration, such as libstdc++'s `using
_Base::get_allocator;`, is found as an `UnresolvedUsingValueDecl`, which
has no function type of its own, so `resolveTypeOfCallExpr()` could not
determine the type of a call to it. Such a declaration is now resolved
to what it names, using the existing `resolveUsingValueDecl()`.
Together these make code completion work for, for example:
```c++
template <class T> void f(std::vector<T> &v) {
typename std::vector<T>::allocator_type al = v.get_allocator();
al. // now offers std::allocator's members
}
```
Tests are also added for cases the heuristic does not get right, so that
they are recorded and will be noticed if that ever changes: a parameter
whose default argument is not the one we end up looking at, because
looking a name up in a base class's primary template discards the
arguments the derived class passes to it; and an explicitly provided
template argument being ignored in favour of the default. Tests
asserting that a name does not resolve now state whether that is the
desired behaviour or a limitation worth lifting.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list