991108.2 | R | I | J. Merrill | C++ | Virtual functions |
The DWARF 2 spec says that
An entry for a virtual function also has a DW_AT_vtable_elem_location
attribute whose value contains a location description yielding the address
of the slot for the function within the virtual function table for the
enclosing class or structure.
The description suggests that the location description should assume that
the address of the vtable is already on the stack, and produce the address
of the slot accordingly. Another interpretation would be to start from a
pointer to an object, and retrieve the vtable pointer first.
The first has the problem that it fails to consider the possibility of a
class having multiple vtables. The second has the problem that the
information will be highly redundant. Furthermore, neither interpretation
says anything about the contents of the slot once it has been found.
The SGI DWARF 2 implementation uses a simple index for this attribute. The
GNU implementation follows this precedent, and adds a DW_AT_containing_type
attribute to virtual functions to indicate what base (and hence what
vtable) they come from. Both of these are highly dependent on the consumer
knowing about the C++ ABI of the producer, particularly how to find a
vtable.
My preference would be to:
1) take the first interpretation I describe above,
2) add DW_AT_containing_type to virtual functions as we have done, perhaps
referring to the DW_TAG_inheritance for the base rather than the type
itself. A missing attribute would be defined to mean "the primary
vtable for this class". And
3) define DW_AT_virtuality on a DW_TAG_member to mean "this is the vtable
pointer for this class".
This still doesn't solve the problem of knowing what to do with the vtable
slot once you've found it. One possibility would be to add attributes like
DW_AT_vptr_this_offset_loc, DW_AT_vptr_vtable_offset_loc and
DW_AT_vptr_function_pointer_loc to the vptr DIE. These would start with
the address of the slot. Defaults would be N/A, N/A, and DW_OP_deref.
This proposal is being revised. A proposal for DW_op_call replaces the first part
of the proposal, and
a new proposal describing DW_AT_vptr_* is being drafted.
This proposal is rejected with the recommendation that it be implemented as a vendor extension.
Discussion of this on February 21, 2000
Subject: 991108.2: vtable element decoding
Date: Mon, 21 Feb 2000 14:22:35 -0800
From: Jason Merrill <jason@cygnus.com>
To: dwarf2@corp.sgi.com
Felix' DW_OP_call proposal covers finding the appropriate vtable slot, but
we still need to know what to do with it once we've found it. In some
implementations, a vtable slot also includes an offset for adjusting the
'this' argument to the member functions. So I propose adding to 2.8:
-----
The vtable entry for a virtual function is found using
DW_AT_vtable_elem_location, as described in 5.5.5. But since the format of
such an entry may vary between producers, the following attributes may also
be present:
DW_AT_vptr_this_offset_location
Expects the address of the vtable slot for the virtual function we want
to be on the stack before being evaluated. Evaluates to the constant
offset by which to adjust the first ('this') argument before calling the
virtual function. Defaults to DW_OP_lit0.
DW_AT_vptr_function_pointer_location
Expects the address of the vtable slot for the virtual function we want
to be on the stack before being evaluated. Evaluates to the address of
the virtual function itself. Defaults to DW_OP_deref.
These attributes can appear in TAG_compile_unit, TAG_module,
TAG_{structure,union,class}_type or TAG_subprogram entries. If they appear
on a non-function entry, they apply to all function entries within that
entry.