Gabriel Dos Reis wrote: > At the C++ language level, there are concerns of how to specify the > interaction. All I claimed was that the observable semantics > does not need further specification to make the examples work. > > At the compiler internals level, how overloads are handled has a much > wider variety of practice and I do not think we should have a standard > that says exactly how that should be implemented, as opposed to what the > end behaviour should be.
Agreed. > At the moment, GCC/g++ would ICE claiming that it does not know how > mangle a call expression (and a few othr nodes). My claim is that if > that problem is solved (by whatever means), the overload and template > machinery does not need further modification to handle all the examples > officially presented so far. That sounds a reasonable claim. > | The general philosophy in the current ABI would seem to be > | that the expression is encoded in terms of its template > | parameters, and not with the evaluated expression with the > | subsituted argument. > > That is correct. For a compiler, such as GCC, that uses parse trees > to represent a template declaration there is no additional > difficultly in mangling the expression, compared to the 'ordinary' case. My concern is how, practically, to mangle a call to an overloaded function, as, if the philosophy of encoding the expression in terms of template parameters is continued, you have to introduce ways of mangling the linked list of FUNCTION_DECLs in an OVERLOAD node. This is certainly not impossible, but likely to be long-winded. And the possibility of ADL means that the overload set won't be the same for each instantiation of the template E.g. in int foo(int); long foo(long); template <int> A {}; template <class T, T V> void bar( A<sizeof(foo(V))> ); we could introduce O <overloads expression-list> E to represent a overload set and represent the sizeof expression as szcl2OL_Z3fooiEL_Z3foolEET0_ (where I've adopted your mangling of call expression rather than the one I suggested). A better approach might be to fall back to the token stream and mangle the token stream representing the function being called. E.g. in the same way that sr <type> <unqualified-name> gives you a way of mangling sizeof( T::foo() ), a variant could be introduced for unqualified names, e.g. su <unqualified-name> which would allow the original sizeof(foo(V)) to be mangled as szcl2su3fooT0_ which is much more concise than mangling the overload set, and more accurately reflects the 'same token stream' requirement of the standard. (Though, 14.6.4.1/7 already makes the program ill-formed, no diagnostic required, if a specialisation has different meanings at different points of instantiation, so the difference can only affect ill-formed programs, I think.) > | to mangle a function call, and you could mangle the > | call to the non-overloaded function, foo: > | > | template <class T> int foo(T); > | template <int> A {}; > | template <class T, T V> void bar( A<sizeof(foo(V))> ); > | > | The obvious strategy is to encode bar<int, 42> as (I think) > | > | _Z3barIiLi42EEv1AIXszclL_Z3fooIiEiT_ET0__EE > | > | where _Z3fooIiEiT_ is the result of subsituting T=int into > | the definition of foo. But this means that the template > | parameters of bar are repeated and all the specialisations > | of bar no longer have the form > | > | _Z3barI{parameters}Ev1AIXszclL_Z3fooIiEiT_ET0__EE > | > | ... because the 'i' from T=int is repeated. (Again, this is > | only a problem if one wants to mangle two 'functionally > | equivalent' overloads.) > > The killing point for GCC/g++ is to mangle the original template > declaration -- not just the result of instantiation -- that is close > to the 'same token stream' requirement of the C++ definition. But does this have to be a killing point for GCC? Although it seems preferable to stick as close to the original template declaration as possible, and the note in 14.5.5.8 suggests that as a QoI issue, a compiler should aim to treat functionally equivalent declarations that are not equivalent as distinct, the 'functionally equivalent not not equivalent' [14.5.5.1/7] rule grants compilers licence to ignore any particularly tricky cases. That said, I think my suggestion, above, of mangling the unmangled, unqualified name gets around this. Richard Smith