/* Abstraction of GNU v3 abi.
Contributed by Jim Blandy <jimb@redhat.com>
- Copyright (C) 2001-2020 Free Software Foundation, Inc.
+ Copyright (C) 2001-2021 Free Software Foundation, Inc.
This file is part of GDB.
#include <algorithm>
#include "cli/cli-style.h"
#include "dwarf2/loc.h"
+#include "inferior.h"
static struct cp_abi_ops gnu_v3_abi_ops;
struct gdb_gnu_v3_abi_vtable {
/ * An array of virtual call and virtual base offsets. The real
- length of this array depends on the class hierarchy; we use
- negative subscripts to access the elements. Yucky, but
- better than the alternatives. * /
+ length of this array depends on the class hierarchy; we use
+ negative subscripts to access the elements. Yucky, but
+ better than the alternatives. * /
ptrdiff_t vcall_and_vbase_offsets[0];
/ * The offset from a virtual pointer referring to this table
- to the top of the complete object. * /
+ to the top of the complete object. * /
ptrdiff_t offset_to_top;
/ * The type_info pointer for this class. This is really a
- std::type_info *, but GDB doesn't really look at the
- type_info object itself, so we don't bother to get the type
- exactly right. * /
+ std::type_info *, but GDB doesn't really look at the
+ type_info object itself, so we don't bother to get the type
+ exactly right. * /
void *type_info;
/ * Virtual table pointers in objects point here. * /
/ * Virtual function pointers. Like the vcall/vbase array, the
- real length of this table depends on the class hierarchy. * /
+ real length of this table depends on the class hierarchy. * /
void (*virtual_functions[0]) ();
};
/* ptrdiff_t vcall_and_vbase_offsets[0]; */
FIELD_NAME (*field) = "vcall_and_vbase_offsets";
- FIELD_TYPE (*field) = lookup_array_range_type (ptrdiff_type, 0, -1);
+ field->set_type (lookup_array_range_type (ptrdiff_type, 0, -1));
SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
- offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ offset += TYPE_LENGTH (field->type ());
field++;
/* ptrdiff_t offset_to_top; */
FIELD_NAME (*field) = "offset_to_top";
- FIELD_TYPE (*field) = ptrdiff_type;
+ field->set_type (ptrdiff_type);
SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
- offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ offset += TYPE_LENGTH (field->type ());
field++;
/* void *type_info; */
FIELD_NAME (*field) = "type_info";
- FIELD_TYPE (*field) = void_ptr_type;
+ field->set_type (void_ptr_type);
SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
- offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ offset += TYPE_LENGTH (field->type ());
field++;
/* void (*virtual_functions[0]) (); */
FIELD_NAME (*field) = "virtual_functions";
- FIELD_TYPE (*field) = lookup_array_range_type (ptr_to_void_fn_type, 0, -1);
+ field->set_type (lookup_array_range_type (ptr_to_void_fn_type, 0, -1));
SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
- offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ offset += TYPE_LENGTH (field->type ());
field++;
/* We assumed in the allocation above that there were four fields. */
= (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
/* The "offset_to_top" field has the appropriate (ptrdiff_t) type. */
- return TYPE_FIELD_TYPE (vtable_type, vtable_field_offset_to_top);
+ return vtable_type->field (vtable_field_offset_to_top).type ();
}
/* Return the offset from the start of the imaginary `struct
= (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
- / TARGET_CHAR_BIT);
+ / TARGET_CHAR_BIT);
}
for (fieldnum = 0; fieldnum < TYPE_N_BASECLASSES (type); fieldnum++)
if (BASETYPE_VIA_VIRTUAL (type, fieldnum)
- || gnuv3_dynamic_class (TYPE_FIELD_TYPE (type, fieldnum)))
+ || gnuv3_dynamic_class (type->field (fieldnum).type ()))
{
TYPE_CPLUS_DYNAMIC (type) = 1;
return 1;
static struct type *
gnuv3_rtti_type (struct value *value,
- int *full_p, LONGEST *top_p, int *using_enc_p)
+ int *full_p, LONGEST *top_p, int *using_enc_p)
{
struct gdbarch *gdbarch;
struct type *values_type = check_typedef (value_type (value));
return NULL;
/* Determine architecture. */
- gdbarch = get_type_arch (values_type);
+ gdbarch = values_type->arch ();
if (using_enc_p)
*using_enc_p = 0;
/* Find the linker symbol for this vtable. */
vtable_symbol
= lookup_minimal_symbol_by_pc (value_address (vtable)
- + value_embedded_offset (vtable)).minsym;
+ + value_embedded_offset (vtable)).minsym;
if (! vtable_symbol)
return NULL;
if (full_p)
*full_p = (- offset_to_top == value_embedded_offset (value)
- && (TYPE_LENGTH (value_enclosing_type (value))
- >= TYPE_LENGTH (run_time_type)));
+ && (TYPE_LENGTH (value_enclosing_type (value))
+ >= TYPE_LENGTH (run_time_type)));
if (top_p)
*top_p = - offset_to_top;
return run_time_type;
/* Fetch the appropriate function pointer from the vtable. */
vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
- vtable_index);
+ vtable_index);
/* If this architecture uses function descriptors directly in the vtable,
then the address of the vtable entry is actually a "function pointer"
static struct value *
gnuv3_virtual_fn_field (struct value **value_p,
- struct fn_field *f, int j,
+ struct fn_field *f, int j,
struct type *vfn_base, int offset)
{
struct type *values_type = check_typedef (value_type (*value_p));
error (_("Only classes can have virtual functions."));
/* Determine architecture. */
- gdbarch = get_type_arch (values_type);
+ gdbarch = values_type->arch ();
/* Cast our value to the base class which defines this virtual
function. This takes care of any necessary `this'
long int cur_base_offset, base_offset;
/* Determine architecture. */
- gdbarch = get_type_arch (type);
+ gdbarch = type->arch ();
ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
/* If it isn't a virtual base, this is easy. The offset is in the
{
struct dwarf2_property_baton baton;
baton.property_type
- = lookup_pointer_type (TYPE_FIELD_TYPE (type, index));
+ = lookup_pointer_type (type->field (index).type ());
baton.locexpr = *TYPE_FIELD_DWARF_BLOCK (type, index);
struct dynamic_prop prop;
- prop.kind = PROP_LOCEXPR;
- prop.data.baton = &baton;
+ prop.set_locexpr (&baton);
struct property_addr_info addr_stack;
addr_stack.type = type;
continue;
pos = TYPE_BASECLASS_BITPOS (domain, i) / 8;
- basetype = TYPE_FIELD_TYPE (domain, i);
+ basetype = domain->field (i).type ();
/* Recurse with a modified adjustment. We don't need to adjust
voffset. */
if (adjustment >= pos && adjustment < pos + TYPE_LENGTH (basetype))
struct ui_file *stream)
{
struct type *self_type = TYPE_SELF_TYPE (type);
- struct gdbarch *gdbarch = get_type_arch (self_type);
+ struct gdbarch *gdbarch = self_type->arch ();
CORE_ADDR ptr_value;
LONGEST adjustment;
int vbit;
static int
gnuv3_method_ptr_size (struct type *type)
{
- struct gdbarch *gdbarch = get_type_arch (type);
-
- return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
+ return 2 * TYPE_LENGTH (builtin_type (type->arch ())->builtin_data_ptr);
}
/* GNU v3 implementation of cplus_make_method_ptr. */
gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
CORE_ADDR value, int is_virtual)
{
- struct gdbarch *gdbarch = get_type_arch (type);
+ struct gdbarch *gdbarch = type->arch ();
int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
enum bfd_endian byte_order = type_byte_order (type);
method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
/* Extract the pointer to member. */
- gdbarch = get_type_arch (self_type);
+ gdbarch = self_type->arch ();
vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);
/* First convert THIS to match the containing type of the pointer to
type = check_typedef (value_type (value));
}
- gdbarch = get_type_arch (type);
+ gdbarch = type->arch ();
vtable = NULL;
if (type->code () == TYPE_CODE_STRUCT)
/* The vtable. */
FIELD_NAME (*field) = "_vptr.type_info";
- FIELD_TYPE (*field) = void_ptr_type;
+ field->set_type (void_ptr_type);
SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
- offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ offset += TYPE_LENGTH (field->type ());
field++;
/* The name. */
FIELD_NAME (*field) = "__name";
- FIELD_TYPE (*field) = char_ptr_type;
+ field->set_type (char_ptr_type);
SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
- offset += TYPE_LENGTH (FIELD_TYPE (*field));
+ offset += TYPE_LENGTH (field->type ());
field++;
gdb_assert (field == (field_list + 2));
/* Ignore top-level cv-qualifiers. */
type = make_cv_type (0, 0, type, NULL);
- gdbarch = get_type_arch (type);
+ gdbarch = type->arch ();
type_name = type_to_string (type);
if (type_name.empty ())
static std::string
gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
{
- struct gdbarch *gdbarch = get_type_arch (value_type (type_info_ptr));
+ struct gdbarch *gdbarch = value_type (type_info_ptr)->arch ();
struct bound_minimal_symbol typeinfo_sym;
CORE_ADDR addr;
const char *symname;
(powerpc 64 for example). Make sure to retrieve the address
of the real function from the function descriptor before passing on
the address to other layers of GDB. */
- func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, method_stop_pc,
- current_top_target ());
+ func_addr = gdbarch_convert_from_func_ptr_addr
+ (gdbarch, method_stop_pc, current_inferior ()->top_target ());
if (func_addr != 0)
method_stop_pc = func_addr;
/* ...and the second argument should be the same as the class
type, with the expected type code... */
- struct type *arg_type = TYPE_FIELD_TYPE (method_type, 1);
+ struct type *arg_type = method_type->field (1).type ();
if (arg_type->code () != expected)
return false;
constructor. */
for (int i = 2; i < method_type->num_fields (); i++)
{
- arg_type = TYPE_FIELD_TYPE (method_type, i);
+ arg_type = method_type->field (i).type ();
/* FIXME aktemur/2019-10-31: As of this date, neither
clang++-7.0.0 nor g++-8.2.0 produce a DW_AT_default_value
attribute. GDB is also not set to read this attribute, yet.
for (fieldnum = 0; fieldnum < type->num_fields (); fieldnum++)
if (!field_is_static (&type->field (fieldnum)))
{
- struct type *field_type = TYPE_FIELD_TYPE (type, fieldnum);
+ struct type *field_type = type->field (fieldnum).type ();
/* For arrays, make the decision based on the element type. */
if (field_type->code () == TYPE_CODE_ARRAY)