[cfe-dev] Template parameters of friend declarations.

Enea Zaffanella zaffanella at cs.unipr.it
Wed Jan 23 04:46:36 PST 2013


On 01/23/2013 12:16 AM, John McCall wrote:
> On Jan 22, 2013, at 3:07 PM, Enea Zaffanella <zaffanella at cs.unipr.it> wrote:
>> On 01/22/2013 08:34 PM, John McCall wrote:
>>> On Jan 21, 2013, at 12:42 AM, Enea Zaffanella <zaffanella at cs.unipr.it> wrote:
>>>> Currently, the FriendDecl node uses a pointer union:
>>>>
>>>>   typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
>>>>
>>>> A possibility would be to add an ExtInfo inner class (similar to what was done for DeclaratorDecl) and then change the union above to become:
>>>>
>>>>   typedef llvm::PointerUnion3<NamedDecl*,TypeSourceInfo*,ExtInfo*> FriendUnion;
>>>>
>>>> This way, we would incur a memory space penalty only when there actually are template parameter lists. Are you willing to accept patches following this approach?
>>>
>>> Are the template parameter lists not attached to the target declaration?
>>>
>>> John.
>>
>> I am actually referring to a friend *type* declaration such as
>>
>> class C {
>>   template<class T> friend struct S<T>::B;
>> };
>>
>> That is, I am interested in the "outer" template parameter lists (such as those of out-of-line definitions of non-template members of class templates). Afaict, this kind of friend declarations is handled in
>>
>>   Sema::ActOnTemplatedFriendTag
>>
>> where I see the comment:
>>
>>   // [...] TODO: for source fidelity, remember the headers.
>
> Ah, yes, I see.  This is actually the "unsupported friend" case, for which
> we do not actually implement correct semantic analysis at all — which
> should be obvious from the fact that we drop the template parameter
> lists, which would otherwise be necessary for correctness.
>
> These outer template parameter lists can be present for both cases of a
> friend declaration:
>    template <class T> class A<T>::B;
>    template <class T> void A<T>::B::foo();
>
> So I don't suggest adding this as ExtInfo in the FriendUnion.  Fortunately,
> FriendDecl has no subclasses, and we know how many outer template
> parameter lists there are when parsing it, so you can actually just store
> the number of parameter lists in the class and tail-allocate the array of
> template parameter lists.
>
> John.

For the second case

   template <class T> friend void A<T>::B::foo();

the outer template parameter list(s) are already stored inside the 
function declaration, namely in the QualifierInfo base class of 
DeclaratorDecl::ExtInfo.

I think that friend *types* are the only cases where these outer 
template parameter lists are missing. Anyway, tail-allocation as 
suggested will be fine.

Enea.



More information about the cfe-dev mailing list