Mangling ambiguity

Alain Miniussi alainm at cup.hp.com
Fri Apr 28 22:24:39 UTC 2000


Jim Dehnert wrote:
> 
> > Date: Fri, 28 Apr 2000 12:06:47 -0700
> > From: Daveed Vandevoorde <daveed at edg.com>
> >
> > Matt Austern wrote:
> > [...]
> > >        template <class T> struct A { };
> > >        template <class T> struct B { };
> > >
> > >        template <class T> struct X        { void f(T); };
> > >        template <class T> struct X<A<T> > { void f(T); };
> > >
> > > Now consider how to mangle these instantiations:
> > >     void X<A<int> >::f(int);
> > >     void X<B<int> >::f(B<int> >);
> > >
> > > Under our current rules, I claim that the latter is clearly
> > >     _Z N 1X I1BIiEE 1f E vT1_
> > >
> > > How about the former?  It depends on how "multiple levels of template"
> > > is to be interpreted, and we could reasonably interpret it as saying
> > > either that the mangling should be
> > >     _Z N 1X I1AIiEE 1f E vT1_
> > > or that it should be
> > >     _Z N 1X I1AIiEE 1f E vT2_
> > >
> > > We should clarify the rules to make sure we say that it's "T2_"
> > > instead of "T1_", because otherwise we'll have an ambiguity that can
> > > be resolved only by the demangler knowing whether or not it's dealing
> > > with a partial specialization.
> >
> > I must be going blank, but where is the ambiguity with the first
> > mangling?  In the latter case, what does "T2_" refer to given that
> > there is only one template parameter?
> 
> No, there are two.  There's the "int" given by I1E, and the A<int>
> given by I1AIiEE.  The key here is that Matt's second example,
>         void X<B<int> >::f(B<int> >);
> does not match the specialization, so B<int> is "the" template
> parameter, substituted for T in the definition:
>         template <class T> struct X        { void f(T); };
> But in the specialization,
>         template <class T> struct X<A<T> > { void f(T); };
> the mangling prefix is identical, i.e.
>         _Z N 1X I1AIiEE 1f E v...
> vs.
>         _Z N 1X I1BIiEE 1f E v...
> and if we specify the use of T1_ for both, the demangler will get one
> of them wrong (it can't see the template definitions, after all).
> 
> The key to understanding the problem, I think, is that although there
> is no ambiguity to the mangler, the demangler doesn't see the "template
> <class T>" prefix and can't tell whether A<T> is the parameter or T is.
> There are two potential solutions.  I've added one to the writeup as a
> proposal, which is simply to number all of the elements of I..E
> template parameter lists, outer level and inner levels, without regard
> to which are the "real" parameters.

In a situation where we have a specialization, we can have multiple
occurences of the same type (template<class T> X<T,T> {...};) maybe
we should make sure that we agree on the one to choose. Since we
already have substitution at work here, maybe it's enough to say
that substituation components are not numbered ?

Also, it seems that the problem is not limited to template terms but
to compound types in general:

template <class T> struct X        { void f(T); };
template <class T> struct X<T* >   { void f(T); };

void X<int*>::f(int*)

T1_ = int*
T2_ = int

If I don't miss anything (if yes, don't read the following) it seems to
imply 
the use of the same (or reverse ?) numbering as the one used in the
context 
of substitution, for each top level template parameter. This, in turn, 
means
that the numbers used can become relatively big, and that it could be
worth 
adopting the same 36 based encoding as the one used for substututions.
 
Alain


>  An alternative would be to put a
> flag in the mangling to identify the "real" parameters.  I don't have a
> strong bias.  I'll put the new document out shortly so you can see it.
> 
> Jim
> 
> -           Jim Dehnert         dehnert at sgi.com
>                                 (650)933-4272




More information about the cxx-abi-dev mailing list