[clang-tools-extra] [clangd] Resolve the dependent type from its single instantiation. Take 1 (PR #71279)
Nathan Ridge via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 27 01:03:44 PST 2023
HighCommander4 wrote:
> > I also discovered some complications related to nested templates [...]
>
> Does my previous comment elaborate on the same issue you've encountered?
I believe so, yes.
> Could you kindly share your thoughts more?
Let's consider a nested template like this:
```c++
template <typename T>
struct Outer {
template <typename U>
void inner(U u) {
u.foo();
}
}
```
I believe our heuristic needs to require two things:
1. `Outer` has an "only instantiation", say `Outer<A>`
2. `Outer<A>::inner` also has an "only instantiation", say `Outer<A>::inner<B>`
Now, suppose we have written an algorithm for "given a template `X`, and some AST node `N` inside the body of `X`, find the corresponding AST node inside an instantiation `X<C>`.
Then, I think we can proceed as follows:
1. Start with the expression `u.foo` in the uninstantiated template
2. Get the enclosing template decl, it's `Outer<T>::inner`
3. (As you observed, `Outer<T>::inner` has no "only instantiation", only `Outer<A>::inner` does.)
4. Walk the `DeclContext` chain further to see if there are any further enclosing templates. We find `Outer`
5. Check `Outer` for an "only instantiation". It has one, `Outer<A>`!
6. Run our algorithm with `X = Outer`, `N = Outer<T>::inner`, `C = A`. It finds `Outer<A>::inner`
7. Run our algorithm with `X = Outer<A>::inner`, `N = u.foo`, `C = B`. It finds the concrete `MemberExpr` which `u.foo` instantiated to inside `Outer<A>::inner<B>`.
https://github.com/llvm/llvm-project/pull/71279
More information about the cfe-commits
mailing list