Mangling ambiguity

Matt Austern austern at sgi.com
Fri Apr 28 22:12:17 UTC 2000


Daveed Vandevoorde writes:
 > 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?

Well, that's the interesting question.  According to the data layout
document (and I wish we had section numbers so I could give a precise
citation), "Objects appearing within multiple levels of template
number the top-level parameters 1..n, the next level n+1..n_m, etc."

We have I1AIiEE, so we have an I...E nested within an I...E.  Is this
what's meant by "multiple levels of template"?  If so, then the way
to represent that inner parameter (IiE) is by T2_.

And now let's look at it the other way.  Suppose we decide that this
isn't what's meant by "multiple levels of template", and that
void X<A<int> >::f(int) should be mangled as _ZN1XI1AIiEE1fEvT1_.
How do we demangle it?  When we see the T1_, it seems to me that
it would naturally refer to the outer I...E block, i.e. to 
I1AIiEE, and that we would demangle _ZN1XI1AIiEE1fEvT1_ as 
void X<A<int> >::f(A<int>).  Remember, we've already decided that
we should demangle _ZN1XI1BIiEE1fEvT1_ as X<B<int> >::f(B<int>).

                        --Matt




More information about the cxx-abi-dev mailing list