Notes from the meeting

Jim Dehnert dehnert at baalbek.engr.sgi.com
Thu Jul 6 23:55:17 UTC 2000


> From loewis at informatik.hu-berlin.de Thu Jul  6 15:37:50 2000
> 
> >      Upon further thought, though, I don't think this is needed.  The
> >      two functions have different definitions, with different
> >      hierarchical names.  The result adjustment is determined by which
> >      function is called and where it is called from, and there
> >      shouldn't be an opportunity to confuse them.
> > 
> >      Am I missing something?
> 
> I think so, yes. What do you mean by "hierarchical names"? Consider
> 
> struct A{};struct B:primary,A{};
> 
> struct Base{
>   virtual A* func(int);  // _ZN4Base4funcEi
> };
> 
> struct Derived:Base{
>   B* func(int);
> };
> 
> Now, _ZN7Derived4funcEi refers to - what? In the vtable of Derived,
> you have two slots - what symbols do you put in there?

Well, you're right that I was a bit confused.
Let me try to work through it.

The two slots in the Derived vtable are the shared slot with the Base
vtable, and the unshared one at the end.  In the unshared one goes the
unadorned Derived::func pointer:

	_ZN7Derived4funcEP7Derivedi

(except that the second 7Derived gets substituted).

In the shared slot goes what a Base caller expects to see, which is a
thunk that converts 'this' to Derived, calls Derived::func, and
converts the result back to an A*.  It would be named, by our current
convention:

	_ZTh0_N7Derived4funcEP7Derivedi

This encodes the 'this' adjustment (0) and the target function name.
It works (is distinguishable), but only because the thunk prefix is
there.  So if we add another level of derivation, again as a primary
base, we have a problem.  So I was wrong... (but you knew that
already).

> The obvious solution would be to have
> 
>   _ZN7Derived4funcEP1Ai  // A* Derived::func(int)
>   _ZN7Derived4funcEP1Bi  // B* Derived::func(int)
> 
> However, that won't work, because e.g. the first one is confused with
> 
>   Ret? Derived::func(A*, int)
> 
> and the same confusion arises for the second one.

It isn't really a problem, because you only need to do it for the thunk
names, and we could add the rule that covariant return thunk names,
identified by a different special prefix, encode the result type.

> Was there any
> concrete proposal in the meeting?

Yes.  Observing that the offset encoding is likely shorter than the
return type name, we would encode covariant return thunk names with
the return type adjustment information.  We had agreed to new prefixes
Tc and Td, analogous to Th and Tv, but it occurs to me that the return
type adjustment is independent of the call adjustment, so I suggest the
following:

  Tch <static this adjust>_ <static result adjust>_ <base function>
  Tcv <static this adjust>_ <vcall offset for this adjust>_ \
	<static result adjust>_ <base function>
  Tdh <static this adjust>_ <static result adjust>_ \
	<vbase offset for result adjust>_ <base function>
  Tdv <static this adjust>_ <vcall offset for this adjust>_ \
	<static result adjust>_ <vbase offset for result adjust>_ \
	<base function>

For Tch/Tdh, the static result adjust (a number) is added to the
result pointer in the thunk (to convert B* to A* in our example),
when A is a non-virtual base of B.

For Tcv/Tdv, the vbase pointer at offset given, in B, is added to
the result pointer B* to get the virtual base of B containing A, and
then the static result adjust is added to that to get A*.

Does this match what people thought at the meeting?  Does it sound OK,
Martin?

Regards,
Jim

-	    Jim Dehnert		dehnert at sgi.com
				(650)933-4272




More information about the cxx-abi-dev mailing list