This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

stupid question time (dwarf2 and C++ virtual bases)


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.  */
--------------

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]