gdb/MAINTAINERS: add Luis Machado as global maintainer
[binutils-gdb.git] / gdb / gnu-v3-abi.c
index 255cfd14ea728e411cd333bda33d886f65be76cc..73b69da21e5bae094407eca38cda369eb0e01836 100644 (file)
@@ -1,7 +1,7 @@
 /* Abstraction of GNU v3 abi.
    Contributed by Jim Blandy <jimb@redhat.com>
 
-   Copyright (C) 2001-2020 Free Software Foundation, Inc.
+   Copyright (C) 2001-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -19,6 +19,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "language.h"
 #include "value.h"
 #include "cp-abi.h"
 #include "cp-support.h"
 #include <algorithm>
 #include "cli/cli-style.h"
 #include "dwarf2/loc.h"
+#include "inferior.h"
 
 static struct cp_abi_ops gnu_v3_abi_ops;
 
 /* A gdbarch key for std::type_info, in the event that it can't be
    found in the debug info.  */
 
-static struct gdbarch_data *std_type_info_gdbarch_data;
+static const registry<gdbarch>::key<struct type> std_type_info_gdbarch_data;
 
 
 static int
@@ -60,25 +62,25 @@ gnuv3_is_operator_name (const char *name)
    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]) ();
 
    };
@@ -90,7 +92,7 @@ gnuv3_is_operator_name (const char *name)
    vtable_type_gdbarch_data is a gdbarch per-architecture data pointer
    which refers to the struct type * for this structure, laid out
    appropriately for the architecture.  */
-static struct gdbarch_data *vtable_type_gdbarch_data;
+static const registry<gdbarch>::key<struct type> vtable_type_gdbarch_data;
 
 
 /* Human-readable names for the numbers of the fields above.  */
@@ -107,21 +109,28 @@ enum {
 
    We use this function as the gdbarch per-architecture data
    initialization function.  */
-static void *
-build_gdb_vtable_type (struct gdbarch *arch)
+static struct type *
+get_gdb_vtable_type (struct gdbarch *arch)
 {
   struct type *t;
-  struct field *field_list, *field;
   int offset;
 
+  struct type *result = vtable_type_gdbarch_data.get (arch);
+  if (result != nullptr)
+    return result;
+
   struct type *void_ptr_type
     = builtin_type (arch)->builtin_data_ptr;
   struct type *ptr_to_void_fn_type
     = builtin_type (arch)->builtin_func_ptr;
 
+  type_allocator alloc (arch);
+
   /* ARCH can't give us the true ptrdiff_t type, so we guess.  */
   struct type *ptrdiff_type
-    = arch_integer_type (arch, gdbarch_ptr_bit (arch), 0, "ptrdiff_t");
+    = init_integer_type (alloc, gdbarch_ptr_bit (arch), 0, "ptrdiff_t");
+
+  t = alloc.new_type (TYPE_CODE_STRUCT, 0, nullptr);
 
   /* We assume no padding is necessary, since GDB doesn't know
      anything about alignment at the moment.  If this assumption bites
@@ -129,48 +138,54 @@ build_gdb_vtable_type (struct gdbarch *arch)
      the alignment that type requires, and then use that here.  */
 
   /* Build the field list.  */
-  field_list = XCNEWVEC (struct field, 4);
-  field = &field_list[0];
+  t->alloc_fields (4);
+
   offset = 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);
-  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
-  offset += TYPE_LENGTH (FIELD_TYPE (*field));
-  field++;
+  {
+    struct field &field0 = t->field (0);
+    field0.set_name ("vcall_and_vbase_offsets");
+    field0.set_type (lookup_array_range_type (ptrdiff_type, 0, -1));
+    field0.set_loc_bitpos (offset * TARGET_CHAR_BIT);
+    offset += field0.type ()->length ();
+  }
 
   /* ptrdiff_t offset_to_top; */
-  FIELD_NAME (*field) = "offset_to_top";
-  FIELD_TYPE (*field) = ptrdiff_type;
-  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
-  offset += TYPE_LENGTH (FIELD_TYPE (*field));
-  field++;
+  {
+    struct field &field1 = t->field (1);
+    field1.set_name ("offset_to_top");
+    field1.set_type (ptrdiff_type);
+    field1.set_loc_bitpos (offset * TARGET_CHAR_BIT);
+    offset += field1.type ()->length ();
+  }
 
   /* void *type_info; */
-  FIELD_NAME (*field) = "type_info";
-  FIELD_TYPE (*field) = void_ptr_type;
-  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
-  offset += TYPE_LENGTH (FIELD_TYPE (*field));
-  field++;
+  {
+    struct field &field2 = t->field (2);
+    field2.set_name ("type_info");
+    field2.set_type (void_ptr_type);
+    field2.set_loc_bitpos (offset * TARGET_CHAR_BIT);
+    offset += field2.type ()->length ();
+  }
 
   /* void (*virtual_functions[0]) (); */
-  FIELD_NAME (*field) = "virtual_functions";
-  FIELD_TYPE (*field) = 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));
-  field++;
-
-  /* We assumed in the allocation above that there were four fields.  */
-  gdb_assert (field == (field_list + 4));
-
-  t = arch_type (arch, TYPE_CODE_STRUCT, offset * TARGET_CHAR_BIT, NULL);
-  t->set_num_fields (field - field_list);
-  t->set_fields (field_list);
+  {
+    struct field &field3 = t->field (3);
+    field3.set_name ("virtual_functions");
+    field3.set_type (lookup_array_range_type (ptr_to_void_fn_type, 0, -1));
+    field3.set_loc_bitpos (offset * TARGET_CHAR_BIT);
+    offset += field3.type ()->length ();
+  }
+
+  t->set_length (offset);
+
   t->set_name ("gdb_gnu_v3_abi_vtable");
   INIT_CPLUS_SPECIFIC (t);
 
-  return make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
+  result = make_type_with_address_space (t, TYPE_INSTANCE_FLAG_CODE_SPACE);
+  vtable_type_gdbarch_data.set (arch, result);
+  return result;
 }
 
 
@@ -178,11 +193,10 @@ build_gdb_vtable_type (struct gdbarch *arch)
 static struct type *
 vtable_ptrdiff_type (struct gdbarch *gdbarch)
 {
-  struct type *vtable_type
-    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+  struct type *vtable_type = get_gdb_vtable_type (gdbarch);
 
   /* 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
@@ -191,11 +205,10 @@ vtable_ptrdiff_type (struct gdbarch *gdbarch)
 static int
 vtable_address_point_offset (struct gdbarch *gdbarch)
 {
-  struct type *vtable_type
-    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+  struct type *vtable_type = get_gdb_vtable_type (gdbarch);
 
-  return (TYPE_FIELD_BITPOS (vtable_type, vtable_field_virtual_functions)
-          / TARGET_CHAR_BIT);
+  return (vtable_type->field (vtable_field_virtual_functions).loc_bitpos ()
+         / TARGET_CHAR_BIT);
 }
 
 
@@ -221,7 +234,7 @@ gnuv3_dynamic_class (struct type *type)
 
   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;
@@ -252,8 +265,7 @@ static struct value *
 gnuv3_get_vtable (struct gdbarch *gdbarch,
                  struct type *container_type, CORE_ADDR container_addr)
 {
-  struct type *vtable_type
-    = (struct type *) gdbarch_data (gdbarch, vtable_type_gdbarch_data);
+  struct type *vtable_type = get_gdb_vtable_type (gdbarch);
   struct type *vtable_pointer_type;
   struct value *vtable_pointer;
   CORE_ADDR vtable_address;
@@ -290,10 +302,10 @@ gnuv3_get_vtable (struct gdbarch *gdbarch,
 
 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));
+  struct type *values_type = check_typedef (value->type ());
   struct value *vtable;
   struct minimal_symbol *vtable_symbol;
   const char *vtable_symbol_name;
@@ -308,7 +320,7 @@ gnuv3_rtti_type (struct value *value,
     return NULL;
 
   /* Determine architecture.  */
-  gdbarch = get_type_arch (values_type);
+  gdbarch = values_type->arch ();
 
   if (using_enc_p)
     *using_enc_p = 0;
@@ -320,8 +332,8 @@ gnuv3_rtti_type (struct value *value,
 
   /* Find the linker symbol for this vtable.  */
   vtable_symbol
-    = lookup_minimal_symbol_by_pc (value_address (vtable)
-                                   + value_embedded_offset (vtable)).minsym;
+    = lookup_minimal_symbol_by_pc (vtable->address ()
+                                  + vtable->embedded_offset ()).minsym;
   if (! vtable_symbol)
     return NULL;
   
@@ -366,9 +378,9 @@ gnuv3_rtti_type (struct value *value,
     = value_as_long (value_field (vtable, vtable_field_offset_to_top));
 
   if (full_p)
-    *full_p = (- offset_to_top == value_embedded_offset (value)
-               && (TYPE_LENGTH (value_enclosing_type (value))
-                   >= TYPE_LENGTH (run_time_type)));
+    *full_p = (- offset_to_top == value->embedded_offset ()
+              && (value->enclosing_type ()->length ()
+                  >= run_time_type->length ()));
   if (top_p)
     *top_p = - offset_to_top;
   return run_time_type;
@@ -384,13 +396,13 @@ gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
   struct value *vtable, *vfn;
 
   /* Every class with virtual functions must have a vtable.  */
-  vtable = gnuv3_get_vtable (gdbarch, value_type (container),
+  vtable = gnuv3_get_vtable (gdbarch, container->type (),
                             value_as_address (value_addr (container)));
   gdb_assert (vtable != NULL);
 
   /* 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"
@@ -411,10 +423,10 @@ gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
 
 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));
+  struct type *values_type = check_typedef ((*value_p)->type ());
   struct gdbarch *gdbarch;
 
   /* Some simple sanity checks.  */
@@ -422,7 +434,7 @@ gnuv3_virtual_fn_field (struct value **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'
@@ -454,7 +466,7 @@ gnuv3_baseclass_offset (struct type *type, int index,
   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
@@ -463,16 +475,15 @@ gnuv3_baseclass_offset (struct type *type, int index,
     return TYPE_BASECLASS_BITPOS (type, index) / 8;
 
   /* If we have a DWARF expression for the offset, evaluate it.  */
-  if (TYPE_FIELD_LOC_KIND (type, index) == FIELD_LOC_KIND_DWARF_BLOCK)
+  if (type->field (index).loc_kind () == FIELD_LOC_KIND_DWARF_BLOCK)
     {
       struct dwarf2_property_baton baton;
       baton.property_type
-       = lookup_pointer_type (TYPE_FIELD_TYPE (type, index));
-      baton.locexpr = *TYPE_FIELD_DWARF_BLOCK (type, index);
+       = lookup_pointer_type (type->field (index).type ());
+      baton.locexpr = *type->field (index).loc_dwarf_block ();
 
       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;
@@ -483,7 +494,7 @@ gnuv3_baseclass_offset (struct type *type, int index,
 
       CORE_ADDR result;
       if (dwarf2_evaluate_property (&prop, nullptr, &addr_stack, &result,
-                                   true))
+                                   {addr_stack.addr}))
        return (int) (result - addr_stack.addr);
     }
 
@@ -497,9 +508,9 @@ gnuv3_baseclass_offset (struct type *type, int index,
     error (_("Expected a negative vbase offset (old compiler?)"));
 
   cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch);
-  if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0)
+  if ((- cur_base_offset) % ptr_type->length () != 0)
     error (_("Misaligned vbase offset."));
-  cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type));
+  cur_base_offset = cur_base_offset / ((int) ptr_type->length ());
 
   vtable = gnuv3_get_vtable (gdbarch, type, address + embedded_offset);
   gdb_assert (vtable != NULL);
@@ -550,10 +561,10 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset,
        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))
+      if (adjustment >= pos && adjustment < pos + basetype->length ())
        return gnuv3_find_method_in (basetype, voffset, adjustment - pos);
     }
 
@@ -583,10 +594,10 @@ gnuv3_decode_method_ptr (struct gdbarch *gdbarch,
      interpretations and choose the right one later on.  */
   ptr_value = extract_typed_address (contents, funcptr_type);
   voffset = extract_signed_integer (contents,
-                                   TYPE_LENGTH (funcptr_type), byte_order);
-  contents += TYPE_LENGTH (funcptr_type);
+                                   funcptr_type->length (), byte_order);
+  contents += funcptr_type->length ();
   adjustment = extract_signed_integer (contents,
-                                      TYPE_LENGTH (offset_type), byte_order);
+                                      offset_type->length (), byte_order);
 
   if (!gdbarch_vbit_in_delta (gdbarch))
     {
@@ -612,7 +623,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
                        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;
@@ -623,7 +634,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
   /* Check for NULL.  */
   if (ptr_value == 0 && vbit == 0)
     {
-      fprintf_filtered (stream, "NULL");
+      gdb_printf (stream, "NULL");
       return;
     }
 
@@ -636,7 +647,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
       /* It's a virtual table offset, maybe in this class.  Search
         for a field with the correct vtable offset.  First convert it
         to an index, as used in TYPE_FN_FIELD_VOFFSET.  */
-      voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
+      voffset = ptr_value / vtable_ptrdiff_type (gdbarch)->length ();
 
       physname = gnuv3_find_method_in (self_type, voffset, adjustment);
 
@@ -644,32 +655,30 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
         possible paths to the method based on the adjustment.  */
       if (physname)
        {
-         char *demangled_name = gdb_demangle (physname,
-                                              DMGL_ANSI | DMGL_PARAMS);
+         gdb::unique_xmalloc_ptr<char> demangled_name
+           = gdb_demangle (physname, DMGL_ANSI | DMGL_PARAMS);
 
-         fprintf_filtered (stream, "&virtual ");
+         gdb_printf (stream, "&virtual ");
          if (demangled_name == NULL)
-           fputs_filtered (physname, stream);
+           gdb_puts (physname, stream);
          else
-           {
-             fputs_filtered (demangled_name, stream);
-             xfree (demangled_name);
-           }
+           gdb_puts (demangled_name.get (), stream);
          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, &type_print_raw_options);
-      fputs_filtered (") ", stream);
+      gdb_puts ("(", stream);
+      c_print_type (type, "", stream, -1, 0, current_language->la_language,
+                   &type_print_raw_options);
+      gdb_puts (") ", stream);
     }
 
   /* We didn't find it; print the raw data.  */
   if (vbit)
     {
-      fprintf_filtered (stream, "&virtual table offset ");
+      gdb_printf (stream, "&virtual table offset ");
       print_longest (stream, 'd', 1, ptr_value);
     }
   else
@@ -682,7 +691,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
 
   if (adjustment)
     {
-      fprintf_filtered (stream, ", this adjustment ");
+      gdb_printf (stream, ", this adjustment ");
       print_longest (stream, 'd', 1, adjustment);
     }
 }
@@ -692,9 +701,7 @@ gnuv3_print_method_ptr (const gdb_byte *contents,
 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 * builtin_type (type->arch ())->builtin_data_ptr->length ();
 }
 
 /* GNU v3 implementation of cplus_make_method_ptr.  */
@@ -703,8 +710,8 @@ static void
 gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
                       CORE_ADDR value, int is_virtual)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
+  struct gdbarch *gdbarch = type->arch ();
+  int size = builtin_type (gdbarch)->builtin_data_ptr->length ();
   enum bfd_endian byte_order = type_byte_order (type);
 
   /* FIXME drow/2006-12-24: The adjustment of "this" is currently
@@ -734,19 +741,19 @@ static struct value *
 gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
 {
   struct gdbarch *gdbarch;
-  const gdb_byte *contents = value_contents (method_ptr);
+  const gdb_byte *contents = method_ptr->contents ().data ();
   CORE_ADDR ptr_value;
   struct type *self_type, *final_type, *method_type;
   LONGEST adjustment;
   int vbit;
 
-  self_type = TYPE_SELF_TYPE (check_typedef (value_type (method_ptr)));
+  self_type = TYPE_SELF_TYPE (check_typedef (method_ptr->type ()));
   final_type = lookup_pointer_type (self_type);
 
-  method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
+  method_type = check_typedef (method_ptr->type ())->target_type ();
 
   /* 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
@@ -776,7 +783,7 @@ gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
     {
       LONGEST voffset;
 
-      voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
+      voffset = ptr_value / vtable_ptrdiff_type (gdbarch)->length ();
       return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
                                   method_type, voffset);
     }
@@ -804,7 +811,7 @@ hash_value_and_voffset (const void *p)
 {
   const struct value_and_voffset *o = (const struct value_and_voffset *) p;
 
-  return value_address (o->value) + value_embedded_offset (o->value);
+  return o->value->address () + o->value->embedded_offset ();
 }
 
 /* Equality function for value_and_voffset.  */
@@ -815,8 +822,8 @@ eq_value_and_voffset (const void *a, const void *b)
   const struct value_and_voffset *ova = (const struct value_and_voffset *) a;
   const struct value_and_voffset *ovb = (const struct value_and_voffset *) b;
 
-  return (value_address (ova->value) + value_embedded_offset (ova->value)
-         == value_address (ovb->value) + value_embedded_offset (ovb->value));
+  return (ova->value->address () + ova->value->embedded_offset ()
+         == ovb->value->address () + ovb->value->embedded_offset ());
 }
 
 /* Comparison function for value_and_voffset.  */
@@ -825,10 +832,10 @@ static bool
 compare_value_and_voffset (const struct value_and_voffset *va,
                           const struct value_and_voffset *vb)
 {
-  CORE_ADDR addra = (value_address (va->value)
-                    + value_embedded_offset (va->value));
-  CORE_ADDR addrb = (value_address (vb->value)
-                    + value_embedded_offset (vb->value));
+  CORE_ADDR addra = (va->value->address ()
+                    + va->value->embedded_offset ());
+  CORE_ADDR addrb = (vb->value->address ()
+                    + vb->value->embedded_offset ());
 
   return addra < addrb;
 }
@@ -845,7 +852,7 @@ compute_vtable_size (htab_t offset_hash,
                     struct value *value)
 {
   int i;
-  struct type *type = check_typedef (value_type (value));
+  struct type *type = check_typedef (value->type ());
   void **slot;
   struct value_and_voffset search_vo, *current_vo;
 
@@ -902,21 +909,21 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
                  struct value_print_options *opts)
 {
   int i;
-  struct type *type = check_typedef (value_type (value));
+  struct type *type = check_typedef (value->type ());
   struct value *vtable;
   CORE_ADDR vt_addr;
 
   vtable = gnuv3_get_vtable (gdbarch, type,
-                            value_address (value)
-                            + value_embedded_offset (value));
-  vt_addr = value_address (value_field (vtable,
-                                       vtable_field_virtual_functions));
+                            value->address ()
+                            + value->embedded_offset ());
+  vt_addr = value_field (vtable,
+                        vtable_field_virtual_functions)->address ();
 
-  printf_filtered (_("vtable for '%s' @ %s (subobject @ %s):\n"),
-                  TYPE_SAFE_NAME (type),
-                  paddress (gdbarch, vt_addr),
-                  paddress (gdbarch, (value_address (value)
-                                      + value_embedded_offset (value))));
+  gdb_printf (_("vtable for '%s' @ %s (subobject @ %s):\n"),
+             TYPE_SAFE_NAME (type),
+             paddress (gdbarch, vt_addr),
+             paddress (gdbarch, (value->address ()
+                                 + value->embedded_offset ())));
 
   for (i = 0; i <= max_voffset; ++i)
     {
@@ -925,7 +932,7 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
       int got_error = 0;
       struct value *vfn;
 
-      printf_filtered ("[%d]: ", i);
+      gdb_printf ("[%d]: ", i);
 
       vfn = value_subscript (value_field (vtable,
                                          vtable_field_virtual_functions),
@@ -947,7 +954,7 @@ print_one_vtable (struct gdbarch *gdbarch, struct value *value,
 
       if (!got_error)
        print_function_pointer_address (opts, gdbarch, addr, gdb_stdout);
-      printf_filtered ("\n");
+      gdb_printf ("\n");
     }
 }
 
@@ -963,11 +970,11 @@ gnuv3_print_vtable (struct value *value)
   int count;
 
   value = coerce_ref (value);
-  type = check_typedef (value_type (value));
+  type = check_typedef (value->type ());
   if (type->code () == TYPE_CODE_PTR)
     {
       value = value_ind (value);
-      type = check_typedef (value_type (value));
+      type = check_typedef (value->type ());
     }
 
   get_user_print_options (&opts);
@@ -976,10 +983,10 @@ gnuv3_print_vtable (struct value *value)
   if (opts.objectprint)
     {
       value = value_full_object (value, NULL, 0, 0, 0);
-      type = check_typedef (value_type (value));
+      type = check_typedef (value->type ());
     }
 
-  gdbarch = get_type_arch (type);
+  gdbarch = type->arch ();
 
   vtable = NULL;
   if (type->code () == TYPE_CODE_STRUCT)
@@ -988,7 +995,7 @@ gnuv3_print_vtable (struct value *value)
 
   if (!vtable)
     {
-      printf_filtered (_("This object does not have a virtual function table\n"));
+      gdb_printf (_("This object does not have a virtual function table\n"));
       return;
     }
 
@@ -1007,7 +1014,7 @@ gnuv3_print_vtable (struct value *value)
       if (iter->max_voffset >= 0)
        {
          if (count > 0)
-           printf_filtered ("\n");
+           gdb_printf ("\n");
          print_one_vtable (gdbarch, iter->value, iter->max_voffset, &opts);
          ++count;
        }
@@ -1020,11 +1027,10 @@ gnuv3_print_vtable (struct value *value)
    We use this function as the gdbarch per-architecture data
    initialization function.  */
 
-static void *
+static struct type *
 build_std_type_info_type (struct gdbarch *arch)
 {
   struct type *t;
-  struct field *field_list, *field;
   int offset;
   struct type *void_ptr_type
     = builtin_type (arch)->builtin_data_ptr;
@@ -1033,29 +1039,32 @@ build_std_type_info_type (struct gdbarch *arch)
   struct type *char_ptr_type
     = make_pointer_type (make_cv_type (1, 0, char_type, NULL), NULL);
 
-  field_list = XCNEWVEC (struct field, 2);
-  field = &field_list[0];
+  t = type_allocator (arch).new_type (TYPE_CODE_STRUCT, 0, nullptr);
+
+  t->alloc_fields (2);
+
   offset = 0;
 
   /* The vtable.  */
-  FIELD_NAME (*field) = "_vptr.type_info";
-  FIELD_TYPE (*field) = void_ptr_type;
-  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
-  offset += TYPE_LENGTH (FIELD_TYPE (*field));
-  field++;
+  {
+    struct field &field0 = t->field (0);
+    field0.set_name ("_vptr.type_info");
+    field0.set_type (void_ptr_type);
+    field0.set_loc_bitpos (offset * TARGET_CHAR_BIT);
+    offset += field0.type ()->length ();
+  }
 
   /* The name.  */
-  FIELD_NAME (*field) = "__name";
-  FIELD_TYPE (*field) = char_ptr_type;
-  SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT);
-  offset += TYPE_LENGTH (FIELD_TYPE (*field));
-  field++;
+  {
+    struct field &field1 = t->field (1);
+    field1.set_name ("__name");
+    field1.set_type (char_ptr_type);
+    field1.set_loc_bitpos (offset * TARGET_CHAR_BIT);
+    offset += field1.type ()->length ();
+  }
 
-  gdb_assert (field == (field_list + 2));
+  t->set_length (offset);
 
-  t = arch_type (arch, TYPE_CODE_STRUCT, offset * TARGET_CHAR_BIT, NULL);
-  t->set_num_fields (field - field_list);
-  t->set_fields (field_list);
   t->set_name ("gdb_gnu_v3_type_info");
   INIT_CPLUS_SPECIFIC (t);
 
@@ -1073,10 +1082,16 @@ gnuv3_get_typeid_type (struct gdbarch *gdbarch)
   typeinfo = lookup_symbol ("std::type_info", NULL, STRUCT_DOMAIN,
                            NULL).symbol;
   if (typeinfo == NULL)
-    typeinfo_type
-      = (struct type *) gdbarch_data (gdbarch, std_type_info_gdbarch_data);
+    {
+      typeinfo_type = std_type_info_gdbarch_data.get (gdbarch);
+      if (typeinfo_type == nullptr)
+       {
+         typeinfo_type = build_std_type_info_type (gdbarch);
+         std_type_info_gdbarch_data.set (gdbarch, typeinfo_type);
+       }
+    }
   else
-    typeinfo_type = SYMBOL_TYPE (typeinfo);
+    typeinfo_type = typeinfo->type ();
 
   return typeinfo_type;
 }
@@ -1096,19 +1111,19 @@ gnuv3_get_typeid (struct value *value)
   /* We have to handle values a bit trickily here, to allow this code
      to work properly with non_lvalue values that are really just
      disguised types.  */
-  if (value_lval_const (value) == lval_memory)
+  if (value->lval () == lval_memory)
     value = coerce_ref (value);
 
-  type = check_typedef (value_type (value));
+  type = check_typedef (value->type ());
 
   /* In the non_lvalue case, a reference might have slipped through
      here.  */
   if (type->code () == TYPE_CODE_REF)
-    type = check_typedef (TYPE_TARGET_TYPE (type));
+    type = check_typedef (type->target_type ());
 
   /* 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 ())
@@ -1128,11 +1143,11 @@ gnuv3_get_typeid (struct value *value)
   /* We check for lval_memory because in the "typeid (type-id)" case,
      the type is passed via a not_lval value object.  */
   if (type->code () == TYPE_CODE_STRUCT
-      && value_lval_const (value) == lval_memory
+      && value->lval () == lval_memory
       && gnuv3_dynamic_class (type))
     {
       struct value *vtable, *typeinfo_value;
-      CORE_ADDR address = value_address (value) + value_embedded_offset (value);
+      CORE_ADDR address = value->address () + value->embedded_offset ();
 
       vtable = gnuv3_get_vtable (gdbarch, type, address);
       if (vtable == NULL)
@@ -1151,7 +1166,7 @@ gnuv3_get_typeid (struct value *value)
       if (minsym.minsym == NULL)
        error (_("could not find typeinfo symbol for '%s'"), name);
 
-      result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym));
+      result = value_at_lazy (typeinfo_type, minsym.value_address ());
     }
 
   return result;
@@ -1162,7 +1177,7 @@ gnuv3_get_typeid (struct value *value)
 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 = type_info_ptr->type ()->arch ();
   struct bound_minimal_symbol typeinfo_sym;
   CORE_ADDR addr;
   const char *symname;
@@ -1202,15 +1217,15 @@ gnuv3_get_type_from_type_info (struct value *type_info_ptr)
      internal form to reconstruct the type somehow.  */
   std::string type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
   expression_up expr (parse_expression (type_name.c_str ()));
-  struct value *type_val = evaluate_type (expr.get ());
-  return value_type (type_val);
+  struct value *type_val = expr->evaluate_type ();
+  return type_val->type ();
 }
 
 /* Determine if we are currently in a C++ thunk.  If so, get the address
    of the routine we are thunking to and continue to there instead.  */
 
 static CORE_ADDR 
-gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
+gnuv3_skip_trampoline (frame_info_ptr frame, CORE_ADDR stop_pc)
 {
   CORE_ADDR real_stop_pc, method_stop_pc, func_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1240,14 +1255,14 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
   if (fn_sym.minsym == NULL)
     return 0;
 
-  method_stop_pc = BMSYMBOL_VALUE_ADDRESS (fn_sym);
+  method_stop_pc = fn_sym.value_address ();
 
   /* Some targets have minimal symbols pointing to function descriptors
      (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;
 
@@ -1331,12 +1346,12 @@ is_copy_or_move_constructor_type (struct type *class_type,
 
   /* ...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;
 
-  struct type *target = check_typedef (TYPE_TARGET_TYPE (arg_type));
+  struct type *target = check_typedef (arg_type->target_type ());
   if (!(class_types_same_p (target, class_type)))
     return false;
 
@@ -1345,7 +1360,7 @@ is_copy_or_move_constructor_type (struct type *class_type,
      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.
@@ -1527,13 +1542,13 @@ gnuv3_pass_by_reference (struct type *type)
      about recursive loops here, since we are only looking at members
      of complete class type.  Also ignore any static members.  */
   for (fieldnum = 0; fieldnum < type->num_fields (); fieldnum++)
-    if (!field_is_static (&type->field (fieldnum)))
+    if (!type->field (fieldnum).is_static ())
       {
-       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)
-         field_type = check_typedef (TYPE_TARGET_TYPE (field_type));
+         field_type = check_typedef (field_type->target_type ());
 
        struct language_pass_by_ref_info field_info
          = gnuv3_pass_by_reference (field_type);
@@ -1564,11 +1579,6 @@ gnuv3_pass_by_reference (struct type *type)
 static void
 init_gnuv3_ops (void)
 {
-  vtable_type_gdbarch_data
-    = gdbarch_data_register_post_init (build_gdb_vtable_type);
-  std_type_info_gdbarch_data
-    = gdbarch_data_register_post_init (build_std_type_info_type);
-
   gnu_v3_abi_ops.shortname = "gnu-v3";
   gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";
   gnu_v3_abi_ops.doc = "G++ Version 3 ABI";