Gabriel Dos Reis wrote: > On Wednesday July 18, 2007 I brought factual evidence to > that claim by showing g++ behaviour on all of the examples > discussed (including those from the "decltype" proposal). > (All I did was to encode call expressions, new expressions > and a few other tree nodes).
I'm curious as to how this works with overloaded functions. 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, for template <int I> void fn( A<-I> ); the specialisation fn<1> would be mangled as _Z2fnILi1EEv1AIXngT_EE void fn<I>( A<-I> ) [with I=1] instead of, say, _Z2fnILi1EEv1AILin1EE void fn<I>( A<-1> ) [with I=1] This has the result that all specialisations of this template have the mangled form _Z2fnI{parameters}Ev1AIXngT_EE (I'm not convinced this is absolutely necessary, even though it seems a good idea. The oft-quoted example is template <int I, int J> A<I+J> fn(A<I>, A<J>); template <int I, int J> A<I-J> fn(A<I>, A<J>); and then setting I=J=0. If you substuted the arguments, you'd get _Z2fnILi0ELi0EE1AILi0EES0_ILi0EES0_ILi0EE for both. However, by my reading of 14.5.5.1, these are functionally equivalent but not equivalent and thus render the program ill-formed; no diagnostic required.) However, the obvious strategy for dealing with overloaded functions is to perform overload resolution and then mangle the selected overload. For example, if we make up the syntax <expression> ::= ... ::= cl <function expression> <args expression-list> _ <expression-list> ::= <expression>+ _ 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.) An alernative is to propagate bar's parameter into foo's argument: _Z3barIiLi42EEv1AIXszclL_Z3fooIT_EiT_ET0__EE But then extending this to an overloaded function call of foo looks very hard, as you no longer know the function is being called when you want to mangle the expression 'foo(V)'. Effectively, you have a choice: mangle the whole of the candidate set (or enough information to regenerate it); or mangle the name after overload resolution and loose the ability to mangle 'functionally equivalent' expressions accurately. The latter sounds far easier, but is contrary to the spirit of the existing ABI. Richard Smith