* dwarf2read.c (dwarf2_add_member_fn): Handle correct form of
DW_AT_vtable_elem_location even when GCC extension is seen.
This commit is contained in:
parent
7f01b0c676
commit
aec5aa8bde
|
@ -1,3 +1,8 @@
|
||||||
|
2010-06-11 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* dwarf2read.c (dwarf2_add_member_fn): Handle correct form of
|
||||||
|
DW_AT_vtable_elem_location even when GCC extension is seen.
|
||||||
|
|
||||||
2010-06-11 Tom Tromey <tromey@redhat.com>
|
2010-06-11 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
PR gdb/9977, PR exp/11636:
|
PR gdb/9977, PR exp/11636:
|
||||||
|
|
|
@ -4879,19 +4879,46 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
||||||
fnp->is_artificial = 1;
|
fnp->is_artificial = 1;
|
||||||
|
|
||||||
/* Get index in virtual function table if it is a virtual member
|
/* Get index in virtual function table if it is a virtual member
|
||||||
function. For GCC, this is an offset in the appropriate
|
function. For older versions of GCC, this is an offset in the
|
||||||
virtual table, as specified by DW_AT_containing_type. For
|
appropriate virtual table, as specified by DW_AT_containing_type.
|
||||||
everyone else, it is an expression to be evaluated relative
|
For everyone else, it is an expression to be evaluated relative
|
||||||
to the object address. */
|
to the object address. */
|
||||||
|
|
||||||
attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
|
attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
|
||||||
if (attr && fnp->fcontext)
|
if (attr)
|
||||||
{
|
{
|
||||||
/* Support the .debug_loc offsets */
|
if (attr_form_is_block (attr) && DW_BLOCK (attr)->size > 0)
|
||||||
if (attr_form_is_block (attr))
|
|
||||||
{
|
{
|
||||||
fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
|
if (DW_BLOCK (attr)->data[0] == DW_OP_constu)
|
||||||
}
|
{
|
||||||
|
/* Old-style GCC. */
|
||||||
|
fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2;
|
||||||
|
}
|
||||||
|
else if (DW_BLOCK (attr)->data[0] == DW_OP_deref
|
||||||
|
|| (DW_BLOCK (attr)->size > 1
|
||||||
|
&& DW_BLOCK (attr)->data[0] == DW_OP_deref_size
|
||||||
|
&& DW_BLOCK (attr)->data[1] == cu->header.addr_size))
|
||||||
|
{
|
||||||
|
struct dwarf_block blk;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
offset = (DW_BLOCK (attr)->data[0] == DW_OP_deref
|
||||||
|
? 1 : 2);
|
||||||
|
blk.size = DW_BLOCK (attr)->size - offset;
|
||||||
|
blk.data = DW_BLOCK (attr)->data + offset;
|
||||||
|
fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu);
|
||||||
|
if ((fnp->voffset % cu->header.addr_size) != 0)
|
||||||
|
dwarf2_complex_location_expr_complaint ();
|
||||||
|
else
|
||||||
|
fnp->voffset /= cu->header.addr_size;
|
||||||
|
fnp->voffset += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dwarf2_complex_location_expr_complaint ();
|
||||||
|
|
||||||
|
if (!fnp->fcontext)
|
||||||
|
fnp->fcontext = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0));
|
||||||
|
}
|
||||||
else if (attr_form_is_section_offset (attr))
|
else if (attr_form_is_section_offset (attr))
|
||||||
{
|
{
|
||||||
dwarf2_complex_location_expr_complaint ();
|
dwarf2_complex_location_expr_complaint ();
|
||||||
|
@ -4902,28 +4929,6 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
|
||||||
fieldname);
|
fieldname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (attr)
|
|
||||||
{
|
|
||||||
/* We only support trivial expressions here. This hack will work
|
|
||||||
for v3 classes, which always start with the vtable pointer. */
|
|
||||||
if (attr_form_is_block (attr) && DW_BLOCK (attr)->size > 0
|
|
||||||
&& DW_BLOCK (attr)->data[0] == DW_OP_deref)
|
|
||||||
{
|
|
||||||
struct dwarf_block blk;
|
|
||||||
|
|
||||||
blk.size = DW_BLOCK (attr)->size - 1;
|
|
||||||
blk.data = DW_BLOCK (attr)->data + 1;
|
|
||||||
fnp->voffset = decode_locdesc (&blk, cu);
|
|
||||||
if ((fnp->voffset % cu->header.addr_size) != 0)
|
|
||||||
dwarf2_complex_location_expr_complaint ();
|
|
||||||
else
|
|
||||||
fnp->voffset /= cu->header.addr_size;
|
|
||||||
fnp->voffset += 2;
|
|
||||||
fnp->fcontext = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dwarf2_complex_location_expr_complaint ();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
attr = dwarf2_attr (die, DW_AT_virtuality, cu);
|
attr = dwarf2_attr (die, DW_AT_virtuality, cu);
|
||||||
|
|
Loading…
Reference in New Issue