This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
stupid question time (dwarf2 and C++ virtual bases)
- To: gcc at gcc dot gnu dot org
- Subject: stupid question time (dwarf2 and C++ virtual bases)
- From: Mike Stump <mrs at windriver dot com>
- Date: Mon, 9 Oct 2000 19:56:13 -0700 (PDT)
Ok, so I have a stupid question. Does dwarf2 debugging of virtual
bases for C++ work? I don't mean with special hacks to debuggers that
understand _vb$..., but rather by using the defined in the standard
dwarf2 spec. I seem to possibly need something like the below
(unclean) to get it to do something more reasonably.
Could someone that actually knows dwarf2 try it out and comment on it.
Am I going in the right direction? Is the below complete?
The idea is instead of using a:
DW_OP_plus_uconst <zero>
which I think wanted to be:
DW_OP_plus_uconst <offset to virtual base>
but wasn't, I generate:
DW_OP_plus_uconst <offset to vbase pointer>, DW_OP_deref
instead.
Help! And much thanks.
The testcase looks something lile:
extern "C" int printf(const char *...);
class A
{
public:
int a;
};
class B
{
public:
int b;
};
class C
{
public:
int c;
};
class D: public virtual A, public virtual B, virtual public C
{
int d;
public:
D();
};
D::D()
{
printf("\n\nClass locations for D (virtual bases.)\n");
printf("D::D this %p\n",this);
printf("D::A %p D::B %p D::C %p \n",(A *)this,(B *)this,(C *)this);
}
class E: public A, public B, public C
{
int e;
public:
E();
};
E::E()
{
printf("Class locations for E (ordinary bases).\n");
printf("E::E this %p\n",this);
printf("E::A %p E::B %p E::C %p \n",(A *)this,(B *)this,(C *)this);
}
int main()
{
D *d1heap = new D;
E *e1heap = new E;
printf("Classes: %x %x\n", d1heap, e1heap);
}
Doing diffs in dwarf2out.c.~1~:
*** dwarf2out.c.~1~ Mon Oct 9 17:22:40 2000
--- dwarf2out.c Mon Oct 9 19:09:22 2000
*************** static unsigned simple_type_size_in_bits
*** 2580,2586 ****
static unsigned field_byte_offset PROTO((tree));
static void add_AT_location_description PROTO((dw_die_ref,
enum dwarf_attribute, rtx));
! static void add_data_member_location_attribute PROTO((dw_die_ref, tree));
static void add_const_value_attribute PROTO((dw_die_ref, rtx));
static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree));
static void add_name_attribute PROTO((dw_die_ref, char *));
--- 2580,2586 ----
static unsigned field_byte_offset PROTO((tree));
static void add_AT_location_description PROTO((dw_die_ref,
enum dwarf_attribute, rtx));
! static void add_data_member_location_attribute PROTO((dw_die_ref, tree, tree));
static void add_const_value_attribute PROTO((dw_die_ref, rtx));
static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree));
static void add_name_attribute PROTO((dw_die_ref, char *));
*************** static void gen_field_die PROTO((tree,
*** 2628,2634 ****
static void gen_ptr_to_mbr_type_die PROTO((tree, dw_die_ref));
static void gen_compile_unit_die PROTO((char *));
static void gen_string_type_die PROTO((tree, dw_die_ref));
! static void gen_inheritance_die PROTO((tree, dw_die_ref));
static void gen_member_die PROTO((tree, dw_die_ref));
static void gen_struct_or_union_type_die PROTO((tree, dw_die_ref));
static void gen_subroutine_type_die PROTO((tree, dw_die_ref));
--- 2628,2634 ----
static void gen_ptr_to_mbr_type_die PROTO((tree, dw_die_ref));
static void gen_compile_unit_die PROTO((char *));
static void gen_string_type_die PROTO((tree, dw_die_ref));
! static void gen_inheritance_die PROTO((tree, dw_die_ref, tree));
static void gen_member_die PROTO((tree, dw_die_ref));
static void gen_struct_or_union_type_die PROTO((tree, dw_die_ref));
static void gen_subroutine_type_die PROTO((tree, dw_die_ref));
*************** add_AT_location_description (die, attr_k
*** 6945,6960 ****
(See the `bit_offset_attribute' function below). */
static void
! add_data_member_location_attribute (die, decl)
register dw_die_ref die;
! register tree decl;
{
register unsigned long offset;
register dw_loc_descr_ref loc_descr;
register enum dwarf_location_atom op;
if (TREE_CODE (decl) == TREE_VEC)
! offset = TREE_INT_CST_LOW (BINFO_OFFSET (decl));
else
offset = field_byte_offset (decl);
--- 6945,6965 ----
(See the `bit_offset_attribute' function below). */
static void
! add_data_member_location_attribute (die, decl, for_type)
register dw_die_ref die;
! register tree decl, for_type;
{
register unsigned long offset;
register dw_loc_descr_ref loc_descr;
register enum dwarf_location_atom op;
if (TREE_CODE (decl) == TREE_VEC)
! {
! if (TREE_VIA_VIRTUAL (decl))
! offset = find_vbase_pointer (decl, for_type);
! else
! offset = TREE_INT_CST_LOW (BINFO_OFFSET (decl));
! }
else
offset = field_byte_offset (decl);
*************** add_data_member_location_attribute (die,
*** 6971,6976 ****
--- 6976,6985 ----
#endif
loc_descr = new_loc_descr (op, offset, 0);
+ if (TREE_VIA_VIRTUAL (decl))
+ {
+ add_loc_descr (&loc_descr, new_loc_descr (DW_OP_deref, 0, 0));
+ }
add_AT_loc (die, DW_AT_data_member_location, loc_descr);
}
*************** gen_field_die (decl, context_die)
*** 8810,8816 ****
}
if (TREE_CODE (DECL_FIELD_CONTEXT (decl)) != UNION_TYPE)
! add_data_member_location_attribute (decl_die, decl);
if (DECL_ARTIFICIAL (decl))
add_AT_flag (decl_die, DW_AT_artificial, 1);
--- 8819,8825 ----
}
if (TREE_CODE (DECL_FIELD_CONTEXT (decl)) != UNION_TYPE)
! add_data_member_location_attribute (decl_die, decl, 0);
if (DECL_ARTIFICIAL (decl))
add_AT_flag (decl_die, DW_AT_artificial, 1);
*************** gen_string_type_die (type, context_die)
*** 8949,8962 ****
/* Generate the DIE for a base class. */
static void
! gen_inheritance_die (binfo, context_die)
! register tree binfo;
register dw_die_ref context_die;
{
dw_die_ref die = new_die (DW_TAG_inheritance, context_die);
add_type_attribute (die, BINFO_TYPE (binfo), 0, 0, context_die);
! add_data_member_location_attribute (die, binfo);
if (TREE_VIA_VIRTUAL (binfo))
add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);
--- 8958,8971 ----
/* Generate the DIE for a base class. */
static void
! gen_inheritance_die (binfo, context_die, for_type)
! register tree binfo, for_type;
register dw_die_ref context_die;
{
dw_die_ref die = new_die (DW_TAG_inheritance, context_die);
add_type_attribute (die, BINFO_TYPE (binfo), 0, 0, context_die);
! add_data_member_location_attribute (die, binfo, for_type);
if (TREE_VIA_VIRTUAL (binfo))
add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);
*************** gen_member_die (type, context_die)
*** 8996,9002 ****
register int i;
for (i = 0; i < n_bases; i++)
! gen_inheritance_die (TREE_VEC_ELT (bases, i), context_die);
}
/* Now output info about the data members and type members. */
--- 9005,9011 ----
register int i;
for (i = 0; i < n_bases; i++)
! gen_inheritance_die (TREE_VEC_ELT (bases, i), context_die, type);
}
/* Now output info about the data members and type members. */
--------------
Doing diffs in class.c.~1~:
*** class.c.~1~ Mon Oct 9 19:08:46 2000
--- class.c Mon Oct 9 19:24:15 2000
*************** build_vbase_pointer (exp, type)
*** 186,191 ****
--- 186,207 ----
return build_component_ref (exp, get_identifier (name), NULL_TREE, 0);
}
+ int
+ find_vbase_pointer (base, for_type)
+ tree base, for_type;
+ {
+ tree decl;
+ char *name;
+ FORMAT_VBASE_NAME (name, BINFO_TYPE (base));
+
+ decl = lookup_field (for_type, get_identifier (name), 0, 0);
+ my_friendly_assert (decl != 0, 999);
+
+ decl = size_binop (FLOOR_DIV_EXPR, DECL_FIELD_BITPOS (decl), size_int (BITS_PER_UNIT));
+ my_friendly_assert (TREE_CODE (decl) == INTEGER_CST, 999);
+ return TREE_INT_CST_LOW (decl);
+ }
+
#if 0
/* Is the type of the EXPR, the complete type of the object?
If we are going to be wrong, we must be conservative, and return 0. */
--------------