> On Feb 18, 2015, at 3:54 PM, Richard Smith <[email protected]> wrote:
> On 18 February 2015 at 15:35, John McCall <[email protected]
> <mailto:[email protected]>> wrote:
>> On Feb 18, 2015, at 1:45 PM, Richard Smith <[email protected]
>> <mailto:[email protected]>> wrote:
>> On 18 February 2015 at 13:04, John McCall <[email protected]
>> <mailto:[email protected]>> wrote:
>> > On Feb 18, 2015, at 11:46 AM, Richard Smith <[email protected]
>> > <mailto:[email protected]>> wrote:
>> > Consider these two cases:
>> >
>> > template<typename T> struct X { struct Y {}; };
>> >
>> > template<template<typename> class U> decltype(X<int>().~U<int>()) f();
>> > template<template<typename> class U> decltype(X<int>::Y().U<int>::Y::~Y())
>> > g();
>> >
>> > Neither of these function templates has a mangling. We get to
>> > <unresolved-name> for the destructor name, and find a template template
>> > parameter with template args, which we cannot mangle as an
>> > <unresolved-type>, and must not mangle as a <simple-id> (because the name
>> > of the template template parameter can change between redeclarations).
>> >
>> > Suggested fix: U<int> should be an <unresolved-type>. Replace
>> >
>> > <unresolved-type> ::= <template-param>
>> >
>> > with
>> >
>> > <unresolved-type> ::= <template-param> [ <template-args> ]
>> >
>> > ... which results, I think, in these manglings for f<X> and g<X>:
>> >
>> > _Z1fI1XEDTcldtcvS0_IiE_EdnT_IiEEEv
>> > _Z1gI1XEDTcldtcvNS0_IiE1YE_EsrNT_IiE1YEdn1YEEv
>> >
>> > (Clang trunk implements this, but gets the g<X> mangling wrong for other
>> > reasons.)
>> >
>> > OK?
>>
>> I had to go and convince myself that an optional dangling production is fine
>> here, but it does look like it can unambiguously and unheroically demangled.
>> There are several other major productions that use an optional dangling
>> <template-args> like this, most notably <simple-id>; so while this is not my
>> favorite way of designing a mangling, it’s widely precedented in the grammar
>> with this exact production, so the rest of the grammar has been designed to
>> not collide with it. I did go ahead and verify that it’s unambiguous
>> anyway. So this looks good to me.
>>
>> Is ~T::T() legal with a template parameter, or does that actually look up
>> “T" in the template argument?
>>
>> It depends on whether the base object has a dependent type. If x's type is
>> not dependent, then x.T::~T() looks up the first T within the type and names
>> the template parameter if T is not found within the type. If x's type is
>> dependent, (the standard is not clear but) lookup within the class is deemed
>> to fail and the first T always names the template parameter. In all cases,
>> the second T is looked up in the same scope(s) as the first.
>
> Okay, thanks. Do you agree that that’s not something that needs to be
> preserved in the mangling? It seems like that rule allows us to uniformly
> decide on srT_dnT_ or sd1Tdn1T at parse time in the non-dependent case, and
> whether we’re in the dependent or non-dependent case should always be
> reflected by the mangling of the base expression.
>
> Yes, I agree.
>
> If the language required us to do the member-type lookup in the dependent
> case, we’d need a special kind of <unresolved-type> (and even crazier logic
> in function template redeclaration matching, because you wouldn’t be able to
> match templates using different template parameter names when this happened…).
>
> If the language required that, I'd call it a defect in the specification.
Agreed on that, too.
Okay, I’ll commit this in a week or so if nobody objects.
John.
_______________________________________________
cxx-abi-dev mailing list
[email protected]
http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev