[PATCH] D127351: clang: fix early substitution of alias templates

Matheus Izvekov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 10 18:58:32 PDT 2022


mizvekov added inline comments.


================
Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:1872
   QualType Result = getSema().Context.getTemplateTypeParmType(
-      T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
-      T->isParameterPack(), NewTTPDecl);
+      getNewDepth(T->getDepth()), T->getIndex(), T->isParameterPack(),
+      NewTTPDecl);
----------------
rsmith wrote:
> mizvekov wrote:
> > mark
> Instead of adding the new `EarlySubstitution` flag and wiring it through everywhere, can you use the existing `MultiLevelTemplateArgumentList::getNewDepth` function? That already handles the case of a depth that's within the number of retained outer levels. We might need to set the number of retained outer levels properly when doing alias template substitution; I'm not sure if we do so currently and I suspect we don't.
I think we do set the number of outer levels correctly when substituting within the type of alias templates, circa SemaTemplate.cpp:3718:
```
    // Only substitute for the innermost template argument list.
    MultiLevelTemplateArgumentList TemplateArgLists;
    TemplateArgLists.addOuterTemplateArguments(&StackTemplateArgs);
    TemplateArgLists.addOuterRetainedLevels(
        AliasTemplate->getTemplateParameters()->getDepth());
```

What the flag was done to deal with is what happens in `TemplateDeclInstantiator::VisitTypeAliasTemplateDecl`, when replacing just the inner level. We need to substitute there without changing any depths, including the template parameters of the alias itself, and I could not find a way to do that without extending it with the new flag.

Anyway, I will think about this again.
I ended up finding another test case which this patch only partially helps, so I have been back investigating this problem again: https://godbolt.org/z/9fGb1KKvq
```
template <typename... As> struct Y;
template <typename ...Bs> using Z = Y<Bs...>;
template <typename ...Cs> struct foo {
  template <typename ...Ds> using bind = Z<Ds..., Cs...>;
};
using U = foo<int>::bind<char>;
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127351/new/

https://reviews.llvm.org/D127351



More information about the cfe-commits mailing list