mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
* gdbtypes.h (struct cplus_struct_type): Remove runtime_ptr member.
(TYPE_RUNTIME_PTR, TYPE_VTABLE, TYPE_HAS_VTABLE, TYPE_PRIMARY_BASE, TYPE_VIRTUAL_BASE_LIST): Remove macros. (HP_ACC_VFUNC_START, HP_ACC_VBASE_START, HP_ACC_TYPEINFO_OFFSET, HP_ACC_TOP_OFFSET_OFFSET): Likewise. (has_vtable, primary_base_class, virtual_base_list_length, virtual_base_list_length_skip_primaries, virtual_base_index, virtual_base_index_skip_primaries, class_index_in_primary_list, count_virtual_fns): Remove prototypes. * gdbtypes.c (has_vtable, primary_base_class, current_vbase_list, virtual_base_list_aux, virtual_base_list, virtual_base_list_length, virtual_base_list_length_skip_primaries, virtual_base_index, virtual_base_index_skip_primaries, class_index_in_primary_list, count_virtual_fns): Remove. * cp-valprint.c (cp_print_hpacc_virtual_table_entries): Remove. (hpacc_vtbl_ptr_name, hpacc_vtbl_ptr_type_name): Remove. (cp_print_value_fields): Remove support for HP aCC vtables. (cp_print_value): Likewise. * c-typeprint.c (c_type_print_base): Likewise. * value.h (find_rt_vbase_offset): Remove prototype. * valops.c (find_rt_vbase_offset): Remove. (search_struct_method): Remove support for HP aCC vtables. (find_method_list): Likewise.
This commit is contained in:
@ -1,3 +1,31 @@
|
|||||||
|
2007-11-02 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* gdbtypes.h (struct cplus_struct_type): Remove runtime_ptr member.
|
||||||
|
(TYPE_RUNTIME_PTR, TYPE_VTABLE, TYPE_HAS_VTABLE,
|
||||||
|
TYPE_PRIMARY_BASE, TYPE_VIRTUAL_BASE_LIST): Remove macros.
|
||||||
|
(HP_ACC_VFUNC_START, HP_ACC_VBASE_START, HP_ACC_TYPEINFO_OFFSET,
|
||||||
|
HP_ACC_TOP_OFFSET_OFFSET): Likewise.
|
||||||
|
(has_vtable, primary_base_class, virtual_base_list_length,
|
||||||
|
virtual_base_list_length_skip_primaries, virtual_base_index,
|
||||||
|
virtual_base_index_skip_primaries, class_index_in_primary_list,
|
||||||
|
count_virtual_fns): Remove prototypes.
|
||||||
|
* gdbtypes.c (has_vtable, primary_base_class, current_vbase_list,
|
||||||
|
virtual_base_list_aux, virtual_base_list, virtual_base_list_length,
|
||||||
|
virtual_base_list_length_skip_primaries, virtual_base_index,
|
||||||
|
virtual_base_index_skip_primaries, class_index_in_primary_list,
|
||||||
|
count_virtual_fns): Remove.
|
||||||
|
|
||||||
|
* cp-valprint.c (cp_print_hpacc_virtual_table_entries): Remove.
|
||||||
|
(hpacc_vtbl_ptr_name, hpacc_vtbl_ptr_type_name): Remove.
|
||||||
|
(cp_print_value_fields): Remove support for HP aCC vtables.
|
||||||
|
(cp_print_value): Likewise.
|
||||||
|
* c-typeprint.c (c_type_print_base): Likewise.
|
||||||
|
|
||||||
|
* value.h (find_rt_vbase_offset): Remove prototype.
|
||||||
|
* valops.c (find_rt_vbase_offset): Remove.
|
||||||
|
(search_struct_method): Remove support for HP aCC vtables.
|
||||||
|
(find_method_list): Likewise.
|
||||||
|
|
||||||
2007-11-02 Ulrich Weigand <uweigand@de.ibm.com>
|
2007-11-02 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
* language.h (struct language_defn): Remove la_builtin_type_vector
|
* language.h (struct language_defn): Remove la_builtin_type_vector
|
||||||
|
@ -834,11 +834,6 @@ c_type_print_base (struct type *type, struct ui_file *stream, int show,
|
|||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
/* Don't print out virtual function table. */
|
/* Don't print out virtual function table. */
|
||||||
/* HP ANSI C++ case */
|
|
||||||
if (TYPE_HAS_VTABLE (type)
|
|
||||||
&& (strncmp (TYPE_FIELD_NAME (type, i), "__vfp", 5) == 0))
|
|
||||||
continue;
|
|
||||||
/* Other compilers */
|
|
||||||
if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
|
if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
|
||||||
&& is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
|
&& is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
|
||||||
continue;
|
continue;
|
||||||
|
@ -83,20 +83,10 @@ static void cp_print_value (struct type *, struct type *, const gdb_byte *,
|
|||||||
int, CORE_ADDR, struct ui_file *, int, int,
|
int, CORE_ADDR, struct ui_file *, int, int,
|
||||||
enum val_prettyprint, struct type **);
|
enum val_prettyprint, struct type **);
|
||||||
|
|
||||||
static void cp_print_hpacc_virtual_table_entries (struct type *, int *,
|
|
||||||
struct value *,
|
|
||||||
struct ui_file *, int,
|
|
||||||
int,
|
|
||||||
enum val_prettyprint);
|
|
||||||
|
|
||||||
|
|
||||||
/* GCC versions after 2.4.5 use this. */
|
/* GCC versions after 2.4.5 use this. */
|
||||||
const char vtbl_ptr_name[] = "__vtbl_ptr_type";
|
const char vtbl_ptr_name[] = "__vtbl_ptr_type";
|
||||||
|
|
||||||
/* HP aCC uses different names. */
|
|
||||||
const char hpacc_vtbl_ptr_name[] = "__vfp";
|
|
||||||
const char hpacc_vtbl_ptr_type_name[] = "__vftyp";
|
|
||||||
|
|
||||||
/* Return truth value for assertion that TYPE is of the type
|
/* Return truth value for assertion that TYPE is of the type
|
||||||
"pointer to virtual function". */
|
"pointer to virtual function". */
|
||||||
|
|
||||||
@ -183,14 +173,8 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
|||||||
|
|
||||||
/* Second, print out data fields */
|
/* Second, print out data fields */
|
||||||
|
|
||||||
/* If there are no data fields, or if the only field is the
|
/* If there are no data fields, skip this part */
|
||||||
* vtbl pointer, skip this part */
|
if (len == n_baseclasses || !len)
|
||||||
if ((len == n_baseclasses)
|
|
||||||
|| ((len - n_baseclasses == 1)
|
|
||||||
&& TYPE_HAS_VTABLE (type)
|
|
||||||
&& strncmp (TYPE_FIELD_NAME (type, n_baseclasses),
|
|
||||||
hpacc_vtbl_ptr_name, 5) == 0)
|
|
||||||
|| !len)
|
|
||||||
fprintf_filtered (stream, "<No data fields>");
|
fprintf_filtered (stream, "<No data fields>");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -210,12 +194,6 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
|||||||
if (!static_field_print && TYPE_FIELD_STATIC (type, i))
|
if (!static_field_print && TYPE_FIELD_STATIC (type, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If a vtable pointer appears, we'll print it out later */
|
|
||||||
if (TYPE_HAS_VTABLE (type)
|
|
||||||
&& strncmp (TYPE_FIELD_NAME (type, i), hpacc_vtbl_ptr_name,
|
|
||||||
5) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (fields_seen)
|
if (fields_seen)
|
||||||
fprintf_filtered (stream, ", ");
|
fprintf_filtered (stream, ", ");
|
||||||
else if (n_baseclasses > 0)
|
else if (n_baseclasses > 0)
|
||||||
@ -333,84 +311,6 @@ cp_print_value_fields (struct type *type, struct type *real_type,
|
|||||||
print_spaces_filtered (2 * recurse, stream);
|
print_spaces_filtered (2 * recurse, stream);
|
||||||
}
|
}
|
||||||
} /* if there are data fields */
|
} /* if there are data fields */
|
||||||
/* Now print out the virtual table pointer if there is one */
|
|
||||||
if (TYPE_HAS_VTABLE (type)
|
|
||||||
&& strncmp (TYPE_FIELD_NAME (type, n_baseclasses),
|
|
||||||
hpacc_vtbl_ptr_name, 5) == 0)
|
|
||||||
{
|
|
||||||
struct value *v;
|
|
||||||
/* First get the virtual table pointer and print it out */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
fputs_filtered ("__vfp = ", stream);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fputs_filtered (", Virtual table at ", stream);
|
|
||||||
|
|
||||||
/* pai: FIXME 32x64 problem? */
|
|
||||||
/* Not sure what the best notation is in the case where there is no
|
|
||||||
baseclass name. */
|
|
||||||
v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
|
|
||||||
*(unsigned long *) (valaddr + offset));
|
|
||||||
|
|
||||||
common_val_print (v, stream, format, 0, recurse + 1, pretty);
|
|
||||||
fields_seen = 1;
|
|
||||||
|
|
||||||
if (vtblprint)
|
|
||||||
{
|
|
||||||
/* Print out function pointers in vtable. */
|
|
||||||
|
|
||||||
/* FIXME: then-clause is for non-RRBC layout of virtual
|
|
||||||
* table. The RRBC case in the else-clause is yet to be
|
|
||||||
* implemented. The if (1) below should be changed to a
|
|
||||||
* test for whether the executable we have was compiled
|
|
||||||
* with a version of HP aCC that doesn't have RRBC
|
|
||||||
* support. */
|
|
||||||
|
|
||||||
if (1)
|
|
||||||
{
|
|
||||||
/* no RRBC support; function pointers embedded directly
|
|
||||||
in vtable */
|
|
||||||
|
|
||||||
int vfuncs = count_virtual_fns (real_type);
|
|
||||||
|
|
||||||
fputs_filtered (" {", stream);
|
|
||||||
|
|
||||||
/* FIXME : doesn't work at present */
|
|
||||||
#if 0
|
|
||||||
fprintf_filtered (stream, "%d entr%s: ", vfuncs,
|
|
||||||
vfuncs == 1 ? "y" : "ies");
|
|
||||||
#else
|
|
||||||
fputs_filtered ("not implemented", stream);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* recursive function that prints all virtual function entries */
|
|
||||||
#if 0
|
|
||||||
cp_print_hpacc_virtual_table_entries (real_type, &vfuncs, v,
|
|
||||||
stream, format, recurse,
|
|
||||||
pretty);
|
|
||||||
#endif
|
|
||||||
fputs_filtered ("}", stream);
|
|
||||||
} /* non-RRBC case */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* FIXME -- see comments above */
|
|
||||||
/* RRBC support present; function pointers are found
|
|
||||||
* by indirection through the class segment entries. */
|
|
||||||
|
|
||||||
|
|
||||||
} /* RRBC case */
|
|
||||||
} /* if vtblprint */
|
|
||||||
|
|
||||||
if (pretty)
|
|
||||||
{
|
|
||||||
fprintf_filtered (stream, "\n");
|
|
||||||
print_spaces_filtered (2 * recurse, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* if vtable exists */
|
|
||||||
|
|
||||||
fprintf_filtered (stream, "}");
|
fprintf_filtered (stream, "}");
|
||||||
}
|
}
|
||||||
@ -465,50 +365,36 @@ cp_print_value (struct type *type, struct type *real_type,
|
|||||||
|
|
||||||
thisoffset = offset;
|
thisoffset = offset;
|
||||||
thistype = real_type;
|
thistype = real_type;
|
||||||
if (TYPE_HAS_VTABLE (type) && BASETYPE_VIA_VIRTUAL (type, i))
|
|
||||||
{
|
|
||||||
/* Assume HP/Taligent runtime convention */
|
|
||||||
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
|
|
||||||
valaddr, offset, &boffset, &skip);
|
|
||||||
if (skip >= 0)
|
|
||||||
error (_("Virtual base class offset not found from vtable while"
|
|
||||||
" printing"));
|
|
||||||
base_valaddr = valaddr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boffset = baseclass_offset (type, i,
|
|
||||||
valaddr + offset,
|
|
||||||
address);
|
|
||||||
skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
|
|
||||||
|
|
||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
boffset = baseclass_offset (type, i, valaddr + offset, address);
|
||||||
|
skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
|
||||||
|
|
||||||
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
|
{
|
||||||
|
/* The virtual base class pointer might have been
|
||||||
|
clobbered by the user program. Make sure that it
|
||||||
|
still points to a valid memory location. */
|
||||||
|
|
||||||
|
if (boffset != -1
|
||||||
|
&& ((boffset + offset) < 0
|
||||||
|
|| (boffset + offset) >= TYPE_LENGTH (type)))
|
||||||
{
|
{
|
||||||
/* The virtual base class pointer might have been
|
/* FIXME (alloca): unsafe if baseclass is really really large. */
|
||||||
clobbered by the user program. Make sure that it
|
gdb_byte *buf = alloca (TYPE_LENGTH (baseclass));
|
||||||
still points to a valid memory location. */
|
base_valaddr = buf;
|
||||||
|
if (target_read_memory (address + boffset, buf,
|
||||||
if (boffset != -1
|
TYPE_LENGTH (baseclass)) != 0)
|
||||||
&& ((boffset + offset) < 0
|
skip = 1;
|
||||||
|| (boffset + offset) >= TYPE_LENGTH (type)))
|
address = address + boffset;
|
||||||
{
|
thisoffset = 0;
|
||||||
/* FIXME (alloca): unsafe if baseclass is really really large. */
|
boffset = 0;
|
||||||
gdb_byte *buf = alloca (TYPE_LENGTH (baseclass));
|
thistype = baseclass;
|
||||||
base_valaddr = buf;
|
|
||||||
if (target_read_memory (address + boffset, buf,
|
|
||||||
TYPE_LENGTH (baseclass)) != 0)
|
|
||||||
skip = 1;
|
|
||||||
address = address + boffset;
|
|
||||||
thisoffset = 0;
|
|
||||||
boffset = 0;
|
|
||||||
thistype = baseclass;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
base_valaddr = valaddr;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
base_valaddr = valaddr;
|
base_valaddr = valaddr;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
base_valaddr = valaddr;
|
||||||
|
|
||||||
/* now do the printing */
|
/* now do the printing */
|
||||||
if (pretty)
|
if (pretty)
|
||||||
@ -694,75 +580,6 @@ cp_print_class_member (const gdb_byte *valaddr, struct type *domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function prints out virtual table entries for a class; it
|
|
||||||
* recurses on the base classes to find all virtual functions
|
|
||||||
* available in a class.
|
|
||||||
*
|
|
||||||
* pai/1997-05-21 Note: As the name suggests, it's currently
|
|
||||||
* implemented for HP aCC runtime only. g++ objects are handled
|
|
||||||
* differently and I have made no attempt to fold that logic in
|
|
||||||
* here. The runtime layout is different for the two cases. Also,
|
|
||||||
* this currently has only the code for non-RRBC layouts generated by
|
|
||||||
* the HP aCC compiler; RRBC code is stubbed out and will have to be
|
|
||||||
* added later. */
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
cp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs,
|
|
||||||
struct value *v, struct ui_file *stream,
|
|
||||||
int format, int recurse,
|
|
||||||
enum val_prettyprint pretty)
|
|
||||||
{
|
|
||||||
int fn, oi;
|
|
||||||
|
|
||||||
/* pai: FIXME this function doesn't work. It should handle a given
|
|
||||||
* virtual function only once (latest redefinition in class hierarchy)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Recursion on other classes that can share the same vtable */
|
|
||||||
struct type *pbc = primary_base_class (type);
|
|
||||||
if (pbc)
|
|
||||||
cp_print_hpacc_virtual_table_entries (pbc, vfuncs, v, stream, format,
|
|
||||||
recurse, pretty);
|
|
||||||
|
|
||||||
/* Now deal with vfuncs declared in this class */
|
|
||||||
for (fn = 0; fn < TYPE_NFN_FIELDS (type); fn++)
|
|
||||||
for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (type, fn); oi++)
|
|
||||||
if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (type, fn), oi))
|
|
||||||
{
|
|
||||||
char *vf_name;
|
|
||||||
const char *field_physname;
|
|
||||||
|
|
||||||
/* virtual function offset */
|
|
||||||
int vx = (TYPE_FN_FIELD_VOFFSET (TYPE_FN_FIELDLIST1 (type, fn), oi)
|
|
||||||
- 1);
|
|
||||||
|
|
||||||
/* Get the address of the vfunction entry */
|
|
||||||
struct value *vf = value_copy (v);
|
|
||||||
if (value_lazy (vf))
|
|
||||||
(void) value_fetch_lazy (vf);
|
|
||||||
/* adjust by offset */
|
|
||||||
/* NOTE: cagney/2005-01-02: THIS IS BOGUS. */
|
|
||||||
value_contents_writeable (vf)[0] += 4 * (HP_ACC_VFUNC_START + vx);
|
|
||||||
vf = value_ind (vf); /* get the entry */
|
|
||||||
/* make it a pointer */
|
|
||||||
deprecated_set_value_type (vf, value_type (v));
|
|
||||||
|
|
||||||
/* print out the entry */
|
|
||||||
common_val_print (vf, stream, format, 0, recurse + 1, pretty);
|
|
||||||
field_physname
|
|
||||||
= TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi);
|
|
||||||
/* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
|
|
||||||
vf_name = cplus_demangle (field_physname, DMGL_ARM);
|
|
||||||
fprintf_filtered (stream, " %s", vf_name);
|
|
||||||
xfree (vf_name);
|
|
||||||
if (--(*vfuncs) > 0)
|
|
||||||
fputs_filtered (", ", stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_initialize_cp_valprint (void)
|
_initialize_cp_valprint (void)
|
||||||
{
|
{
|
||||||
|
333
gdb/gdbtypes.c
333
gdb/gdbtypes.c
@ -135,7 +135,6 @@ static void print_bit_vector (B_TYPE *, int);
|
|||||||
static void print_arg_types (struct field *, int, int);
|
static void print_arg_types (struct field *, int, int);
|
||||||
static void dump_fn_fieldlists (struct type *, int);
|
static void dump_fn_fieldlists (struct type *, int);
|
||||||
static void print_cplus_stuff (struct type *, int);
|
static void print_cplus_stuff (struct type *, int);
|
||||||
static void virtual_base_list_aux (struct type *dclass);
|
|
||||||
|
|
||||||
|
|
||||||
/* Alloc a new type structure and fill it with some defaults. If
|
/* Alloc a new type structure and fill it with some defaults. If
|
||||||
@ -1906,338 +1905,6 @@ is_ancestor (struct type *base, struct type *dclass)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* See whether DCLASS has a virtual table. This routine is aimed at
|
|
||||||
the HP/Taligent ANSI C++ runtime model, and may not work with other
|
|
||||||
runtime models. Return 1 => Yes, 0 => No. */
|
|
||||||
|
|
||||||
int
|
|
||||||
has_vtable (struct type *dclass)
|
|
||||||
{
|
|
||||||
/* In the HP ANSI C++ runtime model, a class has a vtable only if it
|
|
||||||
has virtual functions or virtual bases. */
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* First check for the presence of virtual bases. */
|
|
||||||
if (TYPE_FIELD_VIRTUAL_BITS (dclass))
|
|
||||||
for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
|
|
||||||
if (B_TST (TYPE_FIELD_VIRTUAL_BITS (dclass), i))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Next check for virtual functions. */
|
|
||||||
if (TYPE_FN_FIELDLISTS (dclass))
|
|
||||||
for (i = 0; i < TYPE_NFN_FIELDS (dclass); i++)
|
|
||||||
if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, i), 0))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Recurse on non-virtual bases to see if any of them needs a
|
|
||||||
vtable. */
|
|
||||||
if (TYPE_FIELD_VIRTUAL_BITS (dclass))
|
|
||||||
for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
|
|
||||||
if ((!B_TST (TYPE_FIELD_VIRTUAL_BITS (dclass), i))
|
|
||||||
&& (has_vtable (TYPE_FIELD_TYPE (dclass, i))))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Well, maybe we don't need a virtual table. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a pointer to the "primary base class" of DCLASS.
|
|
||||||
|
|
||||||
A NULL return indicates that DCLASS has no primary base, or that it
|
|
||||||
couldn't be found (insufficient information).
|
|
||||||
|
|
||||||
This routine is aimed at the HP/Taligent ANSI C++ runtime model,
|
|
||||||
and may not work with other runtime models. */
|
|
||||||
|
|
||||||
struct type *
|
|
||||||
primary_base_class (struct type *dclass)
|
|
||||||
{
|
|
||||||
/* In HP ANSI C++'s runtime model, a "primary base class" of a class
|
|
||||||
is the first directly inherited, non-virtual base class that
|
|
||||||
requires a virtual table. */
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
|
|
||||||
if (!TYPE_FIELD_VIRTUAL (dclass, i)
|
|
||||||
&& has_vtable (TYPE_FIELD_TYPE (dclass, i)))
|
|
||||||
return TYPE_FIELD_TYPE (dclass, i);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global manipulated by virtual_base_list[_aux](). */
|
|
||||||
|
|
||||||
static struct vbase *current_vbase_list = NULL;
|
|
||||||
|
|
||||||
/* Return a pointer to a null-terminated list of struct vbase items.
|
|
||||||
The vbasetype pointer of each item in the list points to the type
|
|
||||||
information for a virtual base of the argument DCLASS.
|
|
||||||
|
|
||||||
Helper function for virtual_base_list().
|
|
||||||
Note: the list goes backward, right-to-left.
|
|
||||||
virtual_base_list() copies the items out in reverse order. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
virtual_base_list_aux (struct type *dclass)
|
|
||||||
{
|
|
||||||
struct vbase *tmp_vbase;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (TYPE_CODE (dclass) != TYPE_CODE_CLASS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (i = 0; i < TYPE_N_BASECLASSES (dclass); i++)
|
|
||||||
{
|
|
||||||
/* Recurse on this ancestor, first */
|
|
||||||
virtual_base_list_aux (TYPE_FIELD_TYPE (dclass, i));
|
|
||||||
|
|
||||||
/* If this current base is itself virtual, add it to the list */
|
|
||||||
if (BASETYPE_VIA_VIRTUAL (dclass, i))
|
|
||||||
{
|
|
||||||
struct type *basetype = TYPE_FIELD_TYPE (dclass, i);
|
|
||||||
|
|
||||||
/* Check if base already recorded */
|
|
||||||
tmp_vbase = current_vbase_list;
|
|
||||||
while (tmp_vbase)
|
|
||||||
{
|
|
||||||
if (tmp_vbase->vbasetype == basetype)
|
|
||||||
break; /* found it */
|
|
||||||
tmp_vbase = tmp_vbase->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tmp_vbase) /* normal exit from loop */
|
|
||||||
{
|
|
||||||
/* Allocate new item for this virtual base */
|
|
||||||
tmp_vbase = (struct vbase *) xmalloc (sizeof (struct vbase));
|
|
||||||
|
|
||||||
/* Stick it on at the end of the list */
|
|
||||||
tmp_vbase->vbasetype = basetype;
|
|
||||||
tmp_vbase->next = current_vbase_list;
|
|
||||||
current_vbase_list = tmp_vbase;
|
|
||||||
}
|
|
||||||
} /* if virtual */
|
|
||||||
} /* for loop over bases */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute the list of virtual bases in the right order. Virtual
|
|
||||||
bases are laid out in the object's memory area in order of their
|
|
||||||
occurrence in a depth-first, left-to-right search through the
|
|
||||||
ancestors.
|
|
||||||
|
|
||||||
Argument DCLASS is the type whose virtual bases are required.
|
|
||||||
Return value is the address of a null-terminated array of pointers
|
|
||||||
to struct type items.
|
|
||||||
|
|
||||||
This routine is aimed at the HP/Taligent ANSI C++ runtime model,
|
|
||||||
and may not work with other runtime models.
|
|
||||||
|
|
||||||
This routine merely hands off the argument to virtual_base_list_aux()
|
|
||||||
and then copies the result into an array to save space. */
|
|
||||||
|
|
||||||
static struct type **
|
|
||||||
virtual_base_list (struct type *dclass)
|
|
||||||
{
|
|
||||||
struct vbase *tmp_vbase;
|
|
||||||
struct vbase *tmp_vbase_2;
|
|
||||||
int i;
|
|
||||||
int count;
|
|
||||||
struct type **vbase_array;
|
|
||||||
|
|
||||||
current_vbase_list = NULL;
|
|
||||||
virtual_base_list_aux (dclass);
|
|
||||||
|
|
||||||
for (i = 0, tmp_vbase = current_vbase_list;
|
|
||||||
tmp_vbase != NULL;
|
|
||||||
i++, tmp_vbase = tmp_vbase->next)
|
|
||||||
/* no body */ ;
|
|
||||||
|
|
||||||
count = i;
|
|
||||||
|
|
||||||
vbase_array = (struct type **)
|
|
||||||
xmalloc ((count + 1) * sizeof (struct type *));
|
|
||||||
|
|
||||||
for (i = count - 1, tmp_vbase = current_vbase_list;
|
|
||||||
i >= 0; i--,
|
|
||||||
tmp_vbase = tmp_vbase->next)
|
|
||||||
vbase_array[i] = tmp_vbase->vbasetype;
|
|
||||||
|
|
||||||
/* Get rid of constructed chain. */
|
|
||||||
tmp_vbase_2 = tmp_vbase = current_vbase_list;
|
|
||||||
while (tmp_vbase)
|
|
||||||
{
|
|
||||||
tmp_vbase = tmp_vbase->next;
|
|
||||||
xfree (tmp_vbase_2);
|
|
||||||
tmp_vbase_2 = tmp_vbase;
|
|
||||||
}
|
|
||||||
|
|
||||||
vbase_array[count] = NULL;
|
|
||||||
return vbase_array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the length of the virtual base list of the type DCLASS. */
|
|
||||||
|
|
||||||
int
|
|
||||||
virtual_base_list_length (struct type *dclass)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct vbase *tmp_vbase;
|
|
||||||
|
|
||||||
current_vbase_list = NULL;
|
|
||||||
virtual_base_list_aux (dclass);
|
|
||||||
|
|
||||||
for (i = 0, tmp_vbase = current_vbase_list;
|
|
||||||
tmp_vbase != NULL;
|
|
||||||
i++, tmp_vbase = tmp_vbase->next)
|
|
||||||
/* no body */ ;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the number of elements of the virtual base list of the type
|
|
||||||
DCLASS, ignoring those appearing in the primary base (and its
|
|
||||||
primary base, recursively). */
|
|
||||||
|
|
||||||
int
|
|
||||||
virtual_base_list_length_skip_primaries (struct type *dclass)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
struct vbase *tmp_vbase;
|
|
||||||
struct type *primary;
|
|
||||||
|
|
||||||
primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
|
|
||||||
|
|
||||||
if (!primary)
|
|
||||||
return virtual_base_list_length (dclass);
|
|
||||||
|
|
||||||
current_vbase_list = NULL;
|
|
||||||
virtual_base_list_aux (dclass);
|
|
||||||
|
|
||||||
for (i = 0, tmp_vbase = current_vbase_list;
|
|
||||||
tmp_vbase != NULL;
|
|
||||||
tmp_vbase = tmp_vbase->next)
|
|
||||||
{
|
|
||||||
if (virtual_base_index (tmp_vbase->vbasetype, primary) >= 0)
|
|
||||||
continue;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the index (position) of type BASE, which is a virtual base
|
|
||||||
class of DCLASS, in the latter's virtual base list. A return of -1
|
|
||||||
indicates "not found" or a problem. */
|
|
||||||
|
|
||||||
int
|
|
||||||
virtual_base_index (struct type *base, struct type *dclass)
|
|
||||||
{
|
|
||||||
struct type *vbase, **vbase_list;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS)
|
|
||||||
|| (TYPE_CODE (base) != TYPE_CODE_CLASS))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
vbase_list = virtual_base_list (dclass);
|
|
||||||
for (i = 0, vbase = vbase_list[0];
|
|
||||||
vbase != NULL;
|
|
||||||
vbase = vbase_list[++i])
|
|
||||||
if (vbase == base)
|
|
||||||
break;
|
|
||||||
|
|
||||||
xfree (vbase_list);
|
|
||||||
return vbase ? i : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the index (position) of type BASE, which is a virtual base
|
|
||||||
class of DCLASS, in the latter's virtual base list. Skip over all
|
|
||||||
bases that may appear in the virtual base list of the primary base
|
|
||||||
class of DCLASS (recursively). A return of -1 indicates "not
|
|
||||||
found" or a problem. */
|
|
||||||
|
|
||||||
int
|
|
||||||
virtual_base_index_skip_primaries (struct type *base,
|
|
||||||
struct type *dclass)
|
|
||||||
{
|
|
||||||
struct type *vbase, **vbase_list;
|
|
||||||
int i, j;
|
|
||||||
struct type *primary;
|
|
||||||
|
|
||||||
if ((TYPE_CODE (dclass) != TYPE_CODE_CLASS)
|
|
||||||
|| (TYPE_CODE (base) != TYPE_CODE_CLASS))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
primary = TYPE_RUNTIME_PTR (dclass) ? TYPE_PRIMARY_BASE (dclass) : NULL;
|
|
||||||
|
|
||||||
vbase_list = virtual_base_list (dclass);
|
|
||||||
for (i = 0, j = -1, vbase = vbase_list[0];
|
|
||||||
vbase != NULL;
|
|
||||||
vbase = vbase_list[++i])
|
|
||||||
{
|
|
||||||
if (!primary
|
|
||||||
|| (virtual_base_index_skip_primaries (vbase, primary) < 0))
|
|
||||||
j++;
|
|
||||||
if (vbase == base)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
xfree (vbase_list);
|
|
||||||
return vbase ? j : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return position of a derived class DCLASS in the list of primary
|
|
||||||
bases starting with the remotest ancestor. Position returned is
|
|
||||||
0-based. */
|
|
||||||
|
|
||||||
int
|
|
||||||
class_index_in_primary_list (struct type *dclass)
|
|
||||||
{
|
|
||||||
struct type *pbc; /* primary base class */
|
|
||||||
|
|
||||||
/* Simply recurse on primary base */
|
|
||||||
pbc = TYPE_PRIMARY_BASE (dclass);
|
|
||||||
if (pbc)
|
|
||||||
return 1 + class_index_in_primary_list (pbc);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a count of the number of virtual functions a type has. This
|
|
||||||
includes all the virtual functions it inherits from its base
|
|
||||||
classes too. */
|
|
||||||
|
|
||||||
/* pai: FIXME This doesn't do the right thing: count redefined virtual
|
|
||||||
functions only once (latest redefinition). */
|
|
||||||
|
|
||||||
int
|
|
||||||
count_virtual_fns (struct type *dclass)
|
|
||||||
{
|
|
||||||
int fn, oi; /* function and overloaded instance indices */
|
|
||||||
int vfuncs; /* count to return */
|
|
||||||
|
|
||||||
/* recurse on bases that can share virtual table */
|
|
||||||
struct type *pbc = primary_base_class (dclass);
|
|
||||||
if (pbc)
|
|
||||||
vfuncs = count_virtual_fns (pbc);
|
|
||||||
else
|
|
||||||
vfuncs = 0;
|
|
||||||
|
|
||||||
for (fn = 0; fn < TYPE_NFN_FIELDS (dclass); fn++)
|
|
||||||
for (oi = 0; oi < TYPE_FN_FIELDLIST_LENGTH (dclass, fn); oi++)
|
|
||||||
if (TYPE_FN_FIELD_VIRTUAL_P (TYPE_FN_FIELDLIST1 (dclass, fn), oi))
|
|
||||||
vfuncs++;
|
|
||||||
|
|
||||||
return vfuncs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -761,32 +761,6 @@ struct cplus_struct_type
|
|||||||
short ninstantiations;
|
short ninstantiations;
|
||||||
struct type **instantiations;
|
struct type **instantiations;
|
||||||
|
|
||||||
/* The following points to information relevant to the runtime model
|
|
||||||
* of the compiler.
|
|
||||||
* Currently being used only for HP's ANSI C++ compiler.
|
|
||||||
* (This type may have to be changed/enhanced for other compilers.)
|
|
||||||
*
|
|
||||||
* RUNTIME_PTR is NULL if there is no runtime information (currently
|
|
||||||
* this means the type was not compiled by HP aCC).
|
|
||||||
*
|
|
||||||
* Fields in structure pointed to:
|
|
||||||
* ->HAS_VTABLE : 0 => no virtual table, 1 => vtable present
|
|
||||||
*
|
|
||||||
* ->PRIMARY_BASE points to the first non-virtual base class that has
|
|
||||||
* a virtual table.
|
|
||||||
*
|
|
||||||
* ->VIRTUAL_BASE_LIST points to a list of struct type * pointers that
|
|
||||||
* point to the type information for all virtual bases among this type's
|
|
||||||
* ancestors.
|
|
||||||
*/
|
|
||||||
struct runtime_info
|
|
||||||
{
|
|
||||||
short has_vtable;
|
|
||||||
struct type *primary_base;
|
|
||||||
struct type **virtual_base_list;
|
|
||||||
}
|
|
||||||
*runtime_ptr;
|
|
||||||
|
|
||||||
/* Pointer to information about enclosing scope, if this is a
|
/* Pointer to information about enclosing scope, if this is a
|
||||||
* local type. If it is not a local type, this is NULL
|
* local type. If it is not a local type, this is NULL
|
||||||
*/
|
*/
|
||||||
@ -975,12 +949,6 @@ extern void allocate_cplus_struct_type (struct type *);
|
|||||||
#define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
|
#define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
|
||||||
#define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
|
#define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
|
||||||
|
|
||||||
#define TYPE_RUNTIME_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->runtime_ptr)
|
|
||||||
#define TYPE_VTABLE(thistype) (TYPE_RUNTIME_PTR(thistype)->has_vtable)
|
|
||||||
#define TYPE_HAS_VTABLE(thistype) (TYPE_RUNTIME_PTR(thistype) && TYPE_VTABLE(thistype))
|
|
||||||
#define TYPE_PRIMARY_BASE(thistype) (TYPE_RUNTIME_PTR(thistype)->primary_base)
|
|
||||||
#define TYPE_VIRTUAL_BASE_LIST(thistype) (TYPE_RUNTIME_PTR(thistype)->virtual_base_list)
|
|
||||||
|
|
||||||
#define TYPE_LOCALTYPE_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr)
|
#define TYPE_LOCALTYPE_PTR(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr)
|
||||||
#define TYPE_LOCALTYPE_FILE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->file)
|
#define TYPE_LOCALTYPE_FILE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->file)
|
||||||
#define TYPE_LOCALTYPE_LINE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->line)
|
#define TYPE_LOCALTYPE_LINE(thistype) (TYPE_CPLUS_SPECIFIC(thistype)->localtype_ptr->line)
|
||||||
@ -1358,46 +1326,6 @@ extern int get_discrete_bounds (struct type *, LONGEST *, LONGEST *);
|
|||||||
|
|
||||||
extern int is_ancestor (struct type *, struct type *);
|
extern int is_ancestor (struct type *, struct type *);
|
||||||
|
|
||||||
extern int has_vtable (struct type *);
|
|
||||||
|
|
||||||
extern struct type *primary_base_class (struct type *);
|
|
||||||
|
|
||||||
extern int virtual_base_list_length (struct type *);
|
|
||||||
extern int virtual_base_list_length_skip_primaries (struct type *);
|
|
||||||
|
|
||||||
extern int virtual_base_index (struct type *, struct type *);
|
|
||||||
extern int virtual_base_index_skip_primaries (struct type *, struct type *);
|
|
||||||
|
|
||||||
|
|
||||||
extern int class_index_in_primary_list (struct type *);
|
|
||||||
|
|
||||||
extern int count_virtual_fns (struct type *);
|
|
||||||
|
|
||||||
/* Constants for HP/Taligent ANSI C++ runtime model */
|
|
||||||
|
|
||||||
/* Where virtual function entries begin in the
|
|
||||||
* virtual table, in the non-RRBC vtable format.
|
|
||||||
* First 4 are the metavtable pointer, top offset,
|
|
||||||
* typeinfo pointer, and dup base info pointer */
|
|
||||||
#define HP_ACC_VFUNC_START 4
|
|
||||||
|
|
||||||
/* (Negative) Offset where virtual base offset entries begin
|
|
||||||
* in the virtual table. Skips over metavtable pointer and
|
|
||||||
* the self-offset entry.
|
|
||||||
* NOTE: NEGATE THIS BEFORE USING! The virtual base offsets
|
|
||||||
* appear before the address point of the vtable (the slot
|
|
||||||
* pointed to by the object's vtable pointer), i.e. at lower
|
|
||||||
* addresses than the vtable pointer. */
|
|
||||||
#define HP_ACC_VBASE_START 2
|
|
||||||
|
|
||||||
/* (Positive) Offset where the pointer to the typeinfo
|
|
||||||
* object is present in the virtual table */
|
|
||||||
#define HP_ACC_TYPEINFO_OFFSET 2
|
|
||||||
|
|
||||||
/* (Positive) Offset where the ``top offset'' entry of
|
|
||||||
* the virtual table is */
|
|
||||||
#define HP_ACC_TOP_OFFSET_OFFSET 1
|
|
||||||
|
|
||||||
/* Overload resolution */
|
/* Overload resolution */
|
||||||
|
|
||||||
#define LENGTH_MATCH(bv) ((bv)->rank[0])
|
#define LENGTH_MATCH(bv) ((bv)->rank[0])
|
||||||
|
180
gdb/valops.c
180
gdb/valops.c
@ -1346,100 +1346,6 @@ search_struct_field (char *name, struct value *arg1, int offset,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return the offset (in bytes) of the virtual base of type BASETYPE
|
|
||||||
* in an object pointed to by VALADDR (on the host), assumed to be of
|
|
||||||
* type TYPE. OFFSET is number of bytes beyond start of ARG to start
|
|
||||||
* looking (in case VALADDR is the contents of an enclosing object).
|
|
||||||
*
|
|
||||||
* This routine recurses on the primary base of the derived class
|
|
||||||
* because the virtual base entries of the primary base appear before
|
|
||||||
* the other virtual base entries.
|
|
||||||
*
|
|
||||||
* If the virtual base is not found, a negative integer is returned.
|
|
||||||
* The magnitude of the negative integer is the number of entries in
|
|
||||||
* the virtual table to skip over (entries corresponding to various
|
|
||||||
* ancestral classes in the chain of primary bases).
|
|
||||||
*
|
|
||||||
* Important: This assumes the HP / Taligent C++ runtime conventions.
|
|
||||||
* Use baseclass_offset() instead to deal with g++ conventions. */
|
|
||||||
|
|
||||||
void
|
|
||||||
find_rt_vbase_offset (struct type *type, struct type *basetype,
|
|
||||||
const gdb_byte *valaddr, int offset,
|
|
||||||
int *boffset_p, int *skip_p)
|
|
||||||
{
|
|
||||||
int boffset; /* Offset of virtual base. */
|
|
||||||
int index; /* Displacement to use in virtual
|
|
||||||
table. */
|
|
||||||
int skip;
|
|
||||||
|
|
||||||
struct value *vp;
|
|
||||||
CORE_ADDR vtbl; /* The virtual table pointer. */
|
|
||||||
struct type *pbc; /* The primary base class. */
|
|
||||||
|
|
||||||
/* Look for the virtual base recursively in the primary base, first.
|
|
||||||
* This is because the derived class object and its primary base
|
|
||||||
* subobject share the primary virtual table. */
|
|
||||||
|
|
||||||
boffset = 0;
|
|
||||||
pbc = TYPE_PRIMARY_BASE (type);
|
|
||||||
if (pbc)
|
|
||||||
{
|
|
||||||
find_rt_vbase_offset (pbc, basetype, valaddr,
|
|
||||||
offset, &boffset, &skip);
|
|
||||||
if (skip < 0)
|
|
||||||
{
|
|
||||||
*boffset_p = boffset;
|
|
||||||
*skip_p = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
skip = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Find the index of the virtual base according to HP/Taligent
|
|
||||||
runtime spec. (Depth-first, left-to-right.) */
|
|
||||||
index = virtual_base_index_skip_primaries (basetype, type);
|
|
||||||
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
*skip_p = skip + virtual_base_list_length_skip_primaries (type);
|
|
||||||
*boffset_p = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pai: FIXME -- 32x64 possible problem. */
|
|
||||||
/* First word (4 bytes) in object layout is the vtable pointer. */
|
|
||||||
vtbl = *(CORE_ADDR *) (valaddr + offset);
|
|
||||||
|
|
||||||
/* Before the constructor is invoked, things are usually zero'd
|
|
||||||
out. */
|
|
||||||
if (vtbl == 0)
|
|
||||||
error (_("Couldn't find virtual table -- object may not be constructed yet."));
|
|
||||||
|
|
||||||
|
|
||||||
/* Find virtual base's offset -- jump over entries for primary base
|
|
||||||
* ancestors, then use the index computed above. But also adjust by
|
|
||||||
* HP_ACC_VBASE_START for the vtable slots before the start of the
|
|
||||||
* virtual base entries. Offset is negative -- virtual base entries
|
|
||||||
* appear _before_ the address point of the virtual table. */
|
|
||||||
|
|
||||||
/* pai: FIXME -- 32x64 problem, if word = 8 bytes, change multiplier
|
|
||||||
& use long type */
|
|
||||||
|
|
||||||
/* epstein : FIXME -- added param for overlay section. May not be
|
|
||||||
correct. */
|
|
||||||
vp = value_at (builtin_type_int,
|
|
||||||
vtbl + 4 * (-skip - index - HP_ACC_VBASE_START));
|
|
||||||
boffset = value_as_long (vp);
|
|
||||||
*skip_p = -1;
|
|
||||||
*boffset_p = boffset;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper function used by value_struct_elt to recurse through
|
/* Helper function used by value_struct_elt to recurse through
|
||||||
baseclasses. Look for a field NAME in ARG1. Adjust the address of
|
baseclasses. Look for a field NAME in ARG1. Adjust the address of
|
||||||
ARG1 by OFFSET bytes, and search in it assuming it has (class) type
|
ARG1 by OFFSET bytes, and search in it assuming it has (class) type
|
||||||
@ -1516,47 +1422,30 @@ search_struct_method (char *name, struct value **arg1p,
|
|||||||
|
|
||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
{
|
{
|
||||||
if (TYPE_HAS_VTABLE (type))
|
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
|
||||||
|
const gdb_byte *base_valaddr;
|
||||||
|
|
||||||
|
/* The virtual base class pointer might have been
|
||||||
|
clobbered by the user program. Make sure that it
|
||||||
|
still points to a valid memory location. */
|
||||||
|
|
||||||
|
if (offset < 0 || offset >= TYPE_LENGTH (type))
|
||||||
{
|
{
|
||||||
/* HP aCC compiled type, search for virtual base offset
|
gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass));
|
||||||
according to HP/Taligent runtime spec. */
|
if (target_read_memory (VALUE_ADDRESS (*arg1p)
|
||||||
int skip;
|
+ value_offset (*arg1p) + offset,
|
||||||
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
|
tmp, TYPE_LENGTH (baseclass)) != 0)
|
||||||
value_contents_all (*arg1p),
|
error (_("virtual baseclass botch"));
|
||||||
offset + value_embedded_offset (*arg1p),
|
base_valaddr = tmp;
|
||||||
&base_offset, &skip);
|
|
||||||
if (skip >= 0)
|
|
||||||
error (_("Virtual base class offset not found in vtable"));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
base_valaddr = value_contents (*arg1p) + offset;
|
||||||
struct type *baseclass =
|
|
||||||
check_typedef (TYPE_BASECLASS (type, i));
|
|
||||||
const gdb_byte *base_valaddr;
|
|
||||||
|
|
||||||
/* The virtual base class pointer might have been
|
base_offset = baseclass_offset (type, i, base_valaddr,
|
||||||
clobbered by the user program. Make sure that it
|
VALUE_ADDRESS (*arg1p)
|
||||||
still points to a valid memory location. */
|
+ value_offset (*arg1p) + offset);
|
||||||
|
if (base_offset == -1)
|
||||||
if (offset < 0 || offset >= TYPE_LENGTH (type))
|
error (_("virtual baseclass botch"));
|
||||||
{
|
|
||||||
gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass));
|
|
||||||
if (target_read_memory (VALUE_ADDRESS (*arg1p)
|
|
||||||
+ value_offset (*arg1p) + offset,
|
|
||||||
tmp, TYPE_LENGTH (baseclass)) != 0)
|
|
||||||
error (_("virtual baseclass botch"));
|
|
||||||
base_valaddr = tmp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
base_valaddr = value_contents (*arg1p) + offset;
|
|
||||||
|
|
||||||
base_offset =
|
|
||||||
baseclass_offset (type, i, base_valaddr,
|
|
||||||
VALUE_ADDRESS (*arg1p)
|
|
||||||
+ value_offset (*arg1p) + offset);
|
|
||||||
if (base_offset == -1)
|
|
||||||
error (_("virtual baseclass botch"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1756,29 +1645,12 @@ find_method_list (struct value **argp, char *method,
|
|||||||
int base_offset;
|
int base_offset;
|
||||||
if (BASETYPE_VIA_VIRTUAL (type, i))
|
if (BASETYPE_VIA_VIRTUAL (type, i))
|
||||||
{
|
{
|
||||||
if (TYPE_HAS_VTABLE (type))
|
base_offset = value_offset (*argp) + offset;
|
||||||
{
|
base_offset = baseclass_offset (type, i,
|
||||||
/* HP aCC compiled type, search for virtual base offset
|
value_contents (*argp) + base_offset,
|
||||||
* according to HP/Taligent runtime spec. */
|
VALUE_ADDRESS (*argp) + base_offset);
|
||||||
int skip;
|
if (base_offset == -1)
|
||||||
find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
|
error (_("virtual baseclass botch"));
|
||||||
value_contents_all (*argp),
|
|
||||||
offset + value_embedded_offset (*argp),
|
|
||||||
&base_offset, &skip);
|
|
||||||
if (skip >= 0)
|
|
||||||
error (_("Virtual base class offset not found in vtable"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* probably g++ runtime model */
|
|
||||||
base_offset = value_offset (*argp) + offset;
|
|
||||||
base_offset =
|
|
||||||
baseclass_offset (type, i,
|
|
||||||
value_contents (*argp) + base_offset,
|
|
||||||
VALUE_ADDRESS (*argp) + base_offset);
|
|
||||||
if (base_offset == -1)
|
|
||||||
error (_("virtual baseclass botch"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else /* Non-virtual base, simply use bit position from debug
|
else /* Non-virtual base, simply use bit position from debug
|
||||||
info. */
|
info. */
|
||||||
|
@ -547,9 +547,6 @@ extern struct value *value_slice (struct value *, int, int);
|
|||||||
extern struct value *value_literal_complex (struct value *, struct value *,
|
extern struct value *value_literal_complex (struct value *, struct value *,
|
||||||
struct type *);
|
struct type *);
|
||||||
|
|
||||||
extern void find_rt_vbase_offset (struct type *, struct type *,
|
|
||||||
const gdb_byte *, int, int *, int *);
|
|
||||||
|
|
||||||
extern struct value *find_function_in_inferior (const char *);
|
extern struct value *find_function_in_inferior (const char *);
|
||||||
|
|
||||||
extern struct value *value_allocate_space_in_inferior (int);
|
extern struct value *value_allocate_space_in_inferior (int);
|
||||||
|
Reference in New Issue
Block a user