erichkeane marked an inline comment as done.
erichkeane added a comment.

In D80743#2074537 <https://reviews.llvm.org/D80743#2074537>, @rsmith wrote:

> In D80743#2074121 <https://reviews.llvm.org/D80743#2074121>, @erichkeane 
> wrote:
>
> > @rsmith I think this implements what you've suggested?
>
>
> Yes, thanks.
>
> > This seems to 'work' for a small subset of works, but it doesn't properly 
> > register the typedef to the LocalInstantiationScope, so the normal template 
> > instantiation (like here 
> > https://github.com/llvm/llvm-project/blob/master/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp#L156)
> >  ends up hitting the 'findInstantiationOf' assert here: 
> > https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplateInstantiate.cpp#L3564
>
> Hm. Yes, that'd be a problem. To fix that, we'll need to transform the 
> typedef declarations as part of transforming the deduction guide. 
> Roughly-speaking, we've transformed
>
>   template<typename T> struct A {
>     using U = X1<T>;
>     A(X2<U>);
>   };
>
>
> into something like
>
>   template<typename T> A(X2<U>) -> A<T> {
>     using U = X1<T>;
>   };
>
>
> ... and the problem is that we need to substitute into the new `using U =` 
> typedef before we form a use of `U` when producing the substituted type of 
> the alias declaration.
>
> There are a couple of ways we could approach this:
>
> 1. when we start transforming a deduction guide, we can walk its 
> `TypedefDecl` children, and instantiate those into new typedef declarations 
> immediately, so that later references to them work
> 2. when we reach the reference to the typedef declaration (in 
> `FindInstantiatedDecl`, when we see a declaration whose decl context is a 
> deduction guide), instantiate the declaration then
>
>   These are distinguishable by an example such as:
>
>   ``` template<typename T> struct Type { using type = typename T::type; }; 
> struct B { using type = int; }; template<typename T = B> struct A { using 
> type = Type<T>::type; A(T, typename T::type, type); // #1 A(...); // #2 }; A 
> a(1, 2, 3); ```
>
>   For which option 1 would result in a hard error when substituting T=int 
> into the injected typedef for #1, but option 2 would accept, because 
> substitution stops at the 'typename T::type' without ever reaching the 
> typedef.
>
>   For that reason I think option 2 is the way to go. We already have some 
> logic for this in `FindInstantiatedDecl`; search there for `NeedInstantiate` 
> and try extending it from local classes and enums to also cover typedefs 
> whose decl context is a deduction guide. (You'll need a matching change in 
> `findInstantiationOf` to return `nullptr` in that case. This code doesn't 
> seem very well factored...)


Patch incoming!  option 2 ended up being pretty easy to implement (perhaps 
embarassingly so on my part after your explaination, I can't help but think I 
should have put that together), and it results in it passing all the tests.  
Thanks so much for your patience.



================
Comment at: clang/lib/Sema/SemaTemplate.cpp:1969-1970
+        SemaRef.getASTContext(),
+        SemaRef.getASTContext().getTranslationUnitDecl(), SourceLocation(),
+        SourceLocation(), TL.getTypedefNameDecl()->getIdentifier(), TSI);
+    MaterializedTypedefs.push_back(Decl);
----------------
rsmith wrote:
> I think it would be a good idea to retain the source location from the 
> original typedef (and to produce a `TypeAliasDecl` if that's what we started 
> with); if any diagnostics end up referring to this typedef, we will want them 
> to point to the one in the class template (and describe it as a "typedef 
> declaration" or "alias declaration" as appropriate).
Ah, right!  I had a TODO in my notebook for the source locations, but didn't 
think about TypeAliasDecl, though I should have.

Looks like it shouldbe easy enough, thanks!


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

https://reviews.llvm.org/D80743



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to