> 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

Reply via email to