/* Abstraction of GNU v3 abi.
Contributed by Jim Blandy <jimb@redhat.com>
- Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GDB.
#include "demangle.h"
#include "objfiles.h"
#include "valprint.h"
+#include "c-lang.h"
#include "gdb_assert.h"
#include "gdb_string.h"
/* Correct it to point at the start of the virtual table, rather
than the address point. */
return value_at_lazy (vtable_type,
- vtable_address - vtable_address_point_offset (gdbarch));
+ vtable_address
+ - vtable_address_point_offset (gdbarch));
}
class_name = vtable_symbol_name + 11;
/* Try to look up the class name as a type name. */
- /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */
+ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */
run_time_type = cp_lookup_rtti_type (class_name, NULL);
if (run_time_type == NULL)
return NULL;
The result is the offset of the baseclass value relative
to (the address of)(ARG) + OFFSET.
- -1 is returned on error. */
+ -1 is returned on error. */
+
static int
-gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
- CORE_ADDR address)
+gnuv3_baseclass_offset (struct type *type, int index,
+ const bfd_byte *valaddr, int embedded_offset,
+ CORE_ADDR address, const struct value *val)
{
struct gdbarch *gdbarch;
struct type *ptr_type;
error (_("Misaligned vbase offset."));
cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type));
- vtable = gnuv3_get_vtable (gdbarch, type, address);
+ vtable = gnuv3_get_vtable (gdbarch, type, address + embedded_offset);
gdb_assert (vtable != NULL);
vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
base_offset = value_as_long (value_subscript (vbase_array, cur_base_offset));
LONGEST adjustment)
{
int i;
- const char *physname;
/* Search this class first. */
- physname = NULL;
if (adjustment == 0)
{
int len;
{
char *demangled_name = cplus_demangle (physname,
DMGL_ANSI | DMGL_PARAMS);
- if (demangled_name != NULL)
+
+ fprintf_filtered (stream, "&virtual ");
+ if (demangled_name == NULL)
+ fputs_filtered (physname, stream);
+ else
{
- fprintf_filtered (stream, "&virtual ");
fputs_filtered (demangled_name, stream);
xfree (demangled_name);
- return;
}
+ return;
}
}
+ else if (ptr_value != 0)
+ {
+ /* Found a non-virtual function: print out the type. */
+ fputs_filtered ("(", stream);
+ c_print_type (type, "", stream, -1, 0);
+ fputs_filtered (") ", stream);
+ }
/* We didn't find it; print the raw data. */
if (vbit)
static int
gnuv3_method_ptr_size (struct type *type)
{
- struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
- struct gdbarch *gdbarch = get_type_arch (domain_type);
+ struct gdbarch *gdbarch = get_type_arch (type);
+
return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
}
gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
CORE_ADDR value, int is_virtual)
{
- struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
- struct gdbarch *gdbarch = get_type_arch (domain_type);
+ struct gdbarch *gdbarch = get_type_arch (type);
int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
if (vbit)
{
LONGEST voffset;
+
voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
method_type, voffset);
a reference to this class, then it is a copy constructor. */
if (TYPE_NFIELDS (fieldtype) == 2
&& TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF
- && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype, 1))) == type)
+ && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype,
+ 1))) == type)
return 1;
}
by reference, so does this class. Similarly for members, which
are constructed whenever this class is. We do not need to worry
about recursive loops here, since we are only looking at members
- of complete class type. */
+ of complete class type. Also ignore any static members. */
for (fieldnum = 0; fieldnum < TYPE_NFIELDS (type); fieldnum++)
- if (gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum)))
+ if (! field_is_static (&TYPE_FIELD (type, fieldnum))
+ && gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum)))
return 1;
return 0;
static void
init_gnuv3_ops (void)
{
- vtable_type_gdbarch_data = gdbarch_data_register_post_init (build_gdb_vtable_type);
+ vtable_type_gdbarch_data
+ = gdbarch_data_register_post_init (build_gdb_vtable_type);
gnu_v3_abi_ops.shortname = "gnu-v3";
gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";