ldionne added inline comments.

================
Comment at: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:1268
+  // Instantiate the attributes on both the template declaration and the 
associated record declaration.
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, Pattern, Inst, LateAttrs, 
StartingScope);
+  SemaRef.InstantiateAttrsForDecl(TemplateArgs, Pattern, RecordInst, 
LateAttrs, StartingScope);
----------------
rsmith wrote:
> ldionne wrote:
> > erik.pilkington wrote:
> > > Why are you instantiating the attributes onto the ClassTemplateDecl? At 
> > > the very least it seems wrong to instantiate attributes from the pattern 
> > > to the ClassTemplateDecl.
> > My understanding was that
> > - `Inst` represented `B<int>::X<T>` (the template)
> > - `RecordInst` represented `B<int>::X<int>` (the template specialization, 
> > which is a "real struct")
> > - `Pattern`  represented `B<T>::X<T>`
> > 
> > If that is right, then it seemed to make sense that both `B<int>::X<T>` and 
> > `B<int>::X<int>` should have the attribute, since `B<T>::X<T>` has it. I 
> > might be misunderstanding something though.
> That's almost right.
> 
>   * `Inst` represents `B<int>::X` (the template declaration in the 
> instantiation of `B<int>`).
>   * `RecordInst` represents `B<int>::X<U>` (the class declaration within the 
> template declaration in the instantiation of `B<int>`).
>   * `Pattern` represents `B<T>::X<U>` (the class declaration within the 
> template declaration in the definition of `B<int>`).
> 
> And we don't yet have a value for `U`, so there is no `B<int>::X<int>` here.
> 
> That is:
> 
> ```
> template<typename T>
>   struct B {
>     template<typename U> // #1
>       struct X; // Pattern
>   };
> // implicit instantiation of B<int>:
> template<> struct B<int> {
>   template<typename U> // Inst
>     struct X; // RecordInst
> };
> ```
> 
> A template-declaration can never have attributes on it (there is no syntactic 
> location where they can be written), so we should never be instantiating 
> attributes onto it. If it could, we should instantiate those attributes from 
> `#1`, not from `Pattern`.
Thanks a lot for the explanation -- this is really helpful. It's now clear that 
this line should not be there.


================
Comment at: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:2971
   InstD->setExternLoc(D->getExternLoc());
   InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc());
 
----------------
ldionne wrote:
> I tried a couple variations of things like:
> 
> ```
> SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, InstD, LateAttrs, 
> StartingScope);
> ```
> 
> and 
> 
> ```
> SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, 
> ClassTemplate->getTemplatedDecl(), LateAttrs, StartingScope);
> ```
> 
> For some reason, none of them end up instantiating the attribute on the 
> `CXXRecordDecl` that is used to determine the mangling.
> 
So, assuming this:

```
template<class T> struct Foo {
  template<class U> struct X { };
  template<> struct ATTRS X<int> { };
};
```

Based on what @rsmith says about partial specializations, my understanding is 
that:

- `D` is the explicit specialization inside the general class template: 
`Foo<T>::X<int>`
- `InstD` is the explicit specialization inside the specialization of 
`Foo<int>`: `Foo<int>::X<int>`

And hence, what we want to do here is apply the attributes from 
`Foo<T>::X<int>` onto `Foo<int>::X<int>`:

```
SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, InstD, LateAttrs, 
StartingScope);
```

However, like I said previously this is not sufficient and I'll just not 
implement this for specializations for the time being (for the sake of making 
progress on `no_extern_template`).


Repository:
  rC Clang

https://reviews.llvm.org/D51997



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

Reply via email to