[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