From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Jacobowitz To: gdb-patches@sources.redhat.com Subject: Re: [RFA/c++] Fix printing classes with virtual base classes Date: Mon, 26 Nov 2001 18:02:00 -0000 Message-ID: <20011126210231.A32203@nevyn.them.org> References: <20011126201945.A27754@nevyn.them.org> X-SW-Source: 2001-11/msg00467.html Message-ID: <20011126180200.mcfeE8BjODpHjUxgT5GKMGN4J9oQbGwblWWC9fdHOs0@z> On Mon, Nov 26, 2001 at 08:19:45PM -0500, Daniel Jacobowitz wrote: > Whew. Finally tracked this down. [snip correct explanation] [snip incorrect patch] I find the use of VALUE_OFFSET and VALUE_EMBEDDED_OFFSET exceedingly unintuitive. Go figure. This one works a little bit better yet. -- Daniel Jacobowitz Carnegie Mellon University MontaVista Software Debian GNU/Linux Developer 2001-11-26 Daniel Jacobowitz * gnu-v3-abi.c (gnuv3_rtti_type): Explicitly cast the vtable pointer to a pointer before loading it. (gnuv3_virtual_fn_field): Likewise. Index: gnu-v3-abi.c =================================================================== RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v retrieving revision 1.4 diff -u -p -r1.4 gnu-v3-abi.c --- gnu-v3-abi.c 2001/10/16 01:58:07 1.4 +++ gnu-v3-abi.c 2001/11/27 02:00:22 @@ -188,7 +188,7 @@ gnuv3_rtti_type (struct value *value, struct type *vtable_type = gdbarch_data (vtable_type_gdbarch_data); struct type *value_type = check_typedef (VALUE_TYPE (value)); CORE_ADDR vtable_address; - struct value *vtable; + struct value *vtable, *vtable_addr_value, *vtable_field; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; @@ -207,9 +207,20 @@ gnuv3_rtti_type (struct value *value, return NULL; /* Fetch VALUE's virtual table pointer, and tweak it to point at - an instance of our imaginary gdb_gnu_v3_abi_vtable structure. */ + an instance of our imaginary gdb_gnu_v3_abi_vtable structure. + The type of the field may not be a pointer type. In a derived + class with a virtual base class, it will be the type of the base + class. Thus we need to cast. */ + vtable_field = value_field (value, + TYPE_VPTR_FIELDNO (value_type)); + vtable_addr_value = + value_at (builtin_type_void_data_ptr, + VALUE_ADDRESS (vtable_field) + + VALUE_OFFSET (vtable_field) + + VALUE_EMBEDDED_OFFSET (vtable_field), + VALUE_BFD_SECTION (value)); vtable_address - = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (value_type))); + = value_as_address (vtable_addr_value); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (), VALUE_BFD_SECTION (value)); @@ -277,7 +288,7 @@ gnuv3_virtual_fn_field (struct value **v struct type *value_type = check_typedef (VALUE_TYPE (value)); struct type *vfn_base; CORE_ADDR vtable_address; - struct value *vtable; + struct value *vtable, *vtable_addr_value, *vtable_field; struct value *vfn; /* Some simple sanity checks. */ @@ -309,9 +320,19 @@ gnuv3_virtual_fn_field (struct value **v value = value_ind (value_cast (vfn_base, value_addr (value))); /* Now value is an object of the appropriate base type. Fetch its - virtual table. */ + virtual table. As in gnuv3_rtti_type, the type of the field may + not be a pointer type. In a derived class with a virtual base class, + it will be the type of the base class. Thus we need to cast. */ + vtable_field = value_field (value, + TYPE_VPTR_FIELDNO (vfn_base)); + vtable_addr_value = + value_at (builtin_type_void_data_ptr, + VALUE_ADDRESS (vtable_field) + + VALUE_OFFSET (vtable_field) + + VALUE_EMBEDDED_OFFSET (vtable_field), + VALUE_BFD_SECTION (value)); vtable_address - = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (vfn_base))); + = value_as_address (vtable_addr_value); vtable = value_at_lazy (vtable_type, vtable_address - vtable_address_point_offset (), VALUE_BFD_SECTION (value));