gdb/linux-tdep.c: Add Perms to the 'info proc mappings' output
[binutils-gdb.git] / gdb / valprint.c
index 4f80ee0dfe3b0e7fbb9ae0042c8bf5b25f3bd5f4..d6ec64845f4be9bd3eb10664ac86cb623d5b3b42 100644 (file)
@@ -1,6 +1,6 @@
 /* Print values for GDB, the GNU debugger.
 
 /* Print values for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -30,7 +30,7 @@
 #include "target-float.h"
 #include "extension.h"
 #include "ada-lang.h"
 #include "target-float.h"
 #include "extension.h"
 #include "ada-lang.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
 #include "charset.h"
 #include "typeprint.h"
 #include <ctype.h>
 #include "charset.h"
 #include "typeprint.h"
 #include <ctype.h>
 #include "cli/cli-option.h"
 #include "gdbarch.h"
 #include "cli/cli-style.h"
 #include "cli/cli-option.h"
 #include "gdbarch.h"
 #include "cli/cli-style.h"
+#include "count-one-bits.h"
+#include "c-lang.h"
+#include "cp-abi.h"
+#include "inferior.h"
+#include "gdbsupport/selftest.h"
+#include "selftest-arch.h"
 
 /* Maximum number of wchars returned from wchar_iterate.  */
 #define MAX_WCHARS 4
 
 /* Maximum number of wchars returned from wchar_iterate.  */
 #define MAX_WCHARS 4
@@ -87,7 +93,8 @@ static void set_input_radix_1 (int, unsigned);
 static void set_output_radix_1 (int, unsigned);
 
 static void val_print_type_code_flags (struct type *type,
 static void set_output_radix_1 (int, unsigned);
 
 static void val_print_type_code_flags (struct type *type,
-                                      const gdb_byte *valaddr,
+                                      struct value *original_value,
+                                      int embedded_offset,
                                       struct ui_file *stream);
 
 #define PRINT_MAX_DEFAULT 200  /* Start print_max off at this value.  */
                                       struct ui_file *stream);
 
 #define PRINT_MAX_DEFAULT 200  /* Start print_max off at this value.  */
@@ -106,6 +113,7 @@ struct value_print_options user_print_options =
   10,                          /* repeat_count_threshold */
   0,                           /* output_format */
   0,                           /* format */
   10,                          /* repeat_count_threshold */
   0,                           /* output_format */
   0,                           /* format */
+  1,                           /* memory_tag_violations */
   0,                           /* stop_print_at_null */
   0,                           /* print_array_indexes */
   0,                           /* deref_ref */
   0,                           /* stop_print_at_null */
   0,                           /* print_array_indexes */
   0,                           /* deref_ref */
@@ -182,7 +190,7 @@ show_output_radix (struct ui_file *file, int from_tty,
 
 static void
 show_print_array_indexes (struct ui_file *file, int from_tty,
 
 static void
 show_print_array_indexes (struct ui_file *file, int from_tty,
-                         struct cmd_list_element *c, const char *value)
+                         struct cmd_list_element *c, const char *value)
 {
   fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
 }
 {
   fprintf_filtered (file, _("Printing of array indexes is %s.\n"), value);
 }
@@ -199,6 +207,17 @@ show_repeat_count_threshold (struct ui_file *file, int from_tty,
                    value);
 }
 
                    value);
 }
 
+/* If nonzero, prints memory tag violations for pointers.  */
+
+static void
+show_memory_tag_violations (struct ui_file *file, int from_tty,
+                           struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file,
+                   _("Printing of memory tag violations is %s.\n"),
+                   value);
+}
+
 /* If nonzero, stops printing of char arrays at first null.  */
 
 static void
 /* If nonzero, stops printing of char arrays at first null.  */
 
 static void
@@ -274,7 +293,7 @@ val_print_scalar_type_p (struct type *type)
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
     }
       type = TYPE_TARGET_TYPE (type);
       type = check_typedef (type);
     }
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_STRUCT:
     {
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_STRUCT:
@@ -296,10 +315,10 @@ val_print_scalar_or_string_type_p (struct type *type,
                                   const struct language_defn *language)
 {
   return (val_print_scalar_type_p (type)
                                   const struct language_defn *language)
 {
   return (val_print_scalar_type_p (type)
-         || language->la_is_string_type_p (type));
+         || language->is_string_type_p (type));
 }
 
 }
 
-/* See its definition in value.h.  */
+/* See valprint.h.  */
 
 int
 valprint_check_validity (struct ui_file *stream,
 
 int
 valprint_check_validity (struct ui_file *stream,
@@ -321,9 +340,9 @@ valprint_check_validity (struct ui_file *stream,
       return 0;
     }
 
       return 0;
     }
 
-  if (TYPE_CODE (type) != TYPE_CODE_UNION
-      && TYPE_CODE (type) != TYPE_CODE_STRUCT
-      && TYPE_CODE (type) != TYPE_CODE_ARRAY)
+  if (type->code () != TYPE_CODE_UNION
+      && type->code () != TYPE_CODE_STRUCT
+      && type->code () != TYPE_CODE_ARRAY)
     {
       if (value_bits_any_optimized_out (val,
                                        TARGET_CHAR_BIT * embedded_offset,
     {
       if (value_bits_any_optimized_out (val,
                                        TARGET_CHAR_BIT * embedded_offset,
@@ -336,7 +355,7 @@ valprint_check_validity (struct ui_file *stream,
       if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset,
                                        TARGET_CHAR_BIT * TYPE_LENGTH (type)))
        {
       if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset,
                                        TARGET_CHAR_BIT * TYPE_LENGTH (type)))
        {
-         const int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+         const int is_ref = type->code () == TYPE_CODE_REF;
          int ref_is_addressable = 0;
 
          if (is_ref)
          int ref_is_addressable = 0;
 
          if (is_ref)
@@ -404,9 +423,9 @@ print_unpacked_pointer (struct type *type, struct type *elttype,
                        CORE_ADDR address, struct ui_file *stream,
                        const struct value_print_options *options)
 {
                        CORE_ADDR address, struct ui_file *stream,
                        const struct value_print_options *options)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
+  struct gdbarch *gdbarch = type->arch ();
 
 
-  if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+  if (elttype->code () == TYPE_CODE_FUNC)
     {
       /* Try to print what function it points to.  */
       print_function_pointer_address (options, gdbarch, address, stream);
     {
       /* Try to print what function it points to.  */
       print_function_pointer_address (options, gdbarch, address, stream);
@@ -422,14 +441,13 @@ print_unpacked_pointer (struct type *type, struct type *elttype,
 /* generic_val_print helper for TYPE_CODE_ARRAY.  */
 
 static void
 /* generic_val_print helper for TYPE_CODE_ARRAY.  */
 
 static void
-generic_val_print_array (struct type *type,
-                        int embedded_offset, CORE_ADDR address,
+generic_val_print_array (struct value *val,
                         struct ui_file *stream, int recurse,
                         struct ui_file *stream, int recurse,
-                        struct value *original_value,
                         const struct value_print_options *options,
                         const struct
                             generic_val_print_decorations *decorations)
 {
                         const struct value_print_options *options,
                         const struct
                             generic_val_print_decorations *decorations)
 {
+  struct type *type = check_typedef (value_type (val));
   struct type *unresolved_elttype = TYPE_TARGET_TYPE (type);
   struct type *elttype = check_typedef (unresolved_elttype);
 
   struct type *unresolved_elttype = TYPE_TARGET_TYPE (type);
   struct type *elttype = check_typedef (unresolved_elttype);
 
@@ -440,74 +458,47 @@ generic_val_print_array (struct type *type,
       if (!get_array_bounds (type, &low_bound, &high_bound))
        error (_("Could not determine the array high bound"));
 
       if (!get_array_bounds (type, &low_bound, &high_bound))
        error (_("Could not determine the array high bound"));
 
-      if (options->prettyformat_arrays)
-       {
-         print_spaces_filtered (2 + 2 * recurse, stream);
-       }
-
       fputs_filtered (decorations->array_start, stream);
       fputs_filtered (decorations->array_start, stream);
-      val_print_array_elements (type, embedded_offset,
-                               address, stream,
-                               recurse, original_value, options, 0);
+      value_print_array_elements (val, stream, recurse, options, 0);
       fputs_filtered (decorations->array_end, stream);
     }
   else
     {
       /* Array of unspecified length: treat like pointer to first elt.  */
       fputs_filtered (decorations->array_end, stream);
     }
   else
     {
       /* Array of unspecified length: treat like pointer to first elt.  */
-      print_unpacked_pointer (type, elttype, address + embedded_offset, stream,
-                             options);
+      print_unpacked_pointer (type, elttype, value_address (val),
+                             stream, options);
     }
 
 }
 
     }
 
 }
 
-/* generic_val_print helper for TYPE_CODE_PTR.  */
+/* generic_value_print helper for TYPE_CODE_PTR.  */
 
 static void
 
 static void
-generic_val_print_ptr (struct type *type,
-                      int embedded_offset, struct ui_file *stream,
-                      struct value *original_value,
-                      const struct value_print_options *options)
+generic_value_print_ptr (struct value *val, struct ui_file *stream,
+                        const struct value_print_options *options)
 {
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
 
   if (options->format && options->format != 's')
 
   if (options->format && options->format != 's')
-    {
-      val_print_scalar_formatted (type, embedded_offset,
-                                 original_value, options, 0, stream);
-    }
+    value_print_scalar_formatted (val, options, 0, stream);
   else
     {
   else
     {
-      struct type *unresolved_elttype = TYPE_TARGET_TYPE(type);
-      struct type *elttype = check_typedef (unresolved_elttype);
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
-      CORE_ADDR addr = unpack_pointer (type,
-                                      valaddr + embedded_offset * unit_size);
+      struct type *type = check_typedef (value_type (val));
+      struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
+      CORE_ADDR addr = unpack_pointer (type, valaddr);
 
       print_unpacked_pointer (type, elttype, addr, stream, options);
     }
 }
 
 
 
       print_unpacked_pointer (type, elttype, addr, stream, options);
     }
 }
 
 
-/* generic_val_print helper for TYPE_CODE_MEMBERPTR.  */
-
-static void
-generic_val_print_memberptr (struct type *type,
-                            int embedded_offset, struct ui_file *stream,
-                            struct value *original_value,
-                            const struct value_print_options *options)
-{
-  val_print_scalar_formatted (type, embedded_offset,
-                             original_value, options, 0, stream);
-}
-
 /* Print '@' followed by the address contained in ADDRESS_BUFFER.  */
 
 static void
 print_ref_address (struct type *type, const gdb_byte *address_buffer,
                  int embedded_offset, struct ui_file *stream)
 {
 /* Print '@' followed by the address contained in ADDRESS_BUFFER.  */
 
 static void
 print_ref_address (struct type *type, const gdb_byte *address_buffer,
                  int embedded_offset, struct ui_file *stream)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
+  struct gdbarch *gdbarch = type->arch ();
 
   if (address_buffer != NULL)
     {
 
   if (address_buffer != NULL)
     {
@@ -529,7 +520,7 @@ get_value_addr_contents (struct value *deref_val)
   gdb_assert (deref_val != NULL);
 
   if (value_lval_const (deref_val) == lval_memory)
   gdb_assert (deref_val != NULL);
 
   if (value_lval_const (deref_val) == lval_memory)
-    return value_contents_for_printing_const (value_addr (deref_val));
+    return value_contents_for_printing_const (value_addr (deref_val)).data ();
   else
     {
       /* We have a non-addressable value, such as a DW_AT_const_value.  */
   else
     {
       /* We have a non-addressable value, such as a DW_AT_const_value.  */
@@ -553,8 +544,8 @@ generic_val_print_ref (struct type *type,
                                    TARGET_CHAR_BIT * TYPE_LENGTH (type));
   const int must_coerce_ref = ((options->addressprint && value_is_synthetic)
                               || options->deref_ref);
                                    TARGET_CHAR_BIT * TYPE_LENGTH (type));
   const int must_coerce_ref = ((options->addressprint && value_is_synthetic)
                               || options->deref_ref);
-  const int type_is_defined = TYPE_CODE (elttype) != TYPE_CODE_UNDEF;
-  const gdb_byte *valaddr = value_contents_for_printing (original_value);
+  const int type_is_defined = elttype->code () != TYPE_CODE_UNDEF;
+  const gdb_byte *valaddr = value_contents_for_printing (original_value).data ();
 
   if (must_coerce_ref && type_is_defined)
     {
 
   if (must_coerce_ref && type_is_defined)
     {
@@ -613,51 +604,76 @@ generic_val_print_enum_1 (struct type *type, LONGEST val,
   unsigned int i;
   unsigned int len;
 
   unsigned int i;
   unsigned int len;
 
-  len = TYPE_NFIELDS (type);
+  len = type->num_fields ();
   for (i = 0; i < len; i++)
     {
       QUIT;
   for (i = 0; i < len; i++)
     {
       QUIT;
-      if (val == TYPE_FIELD_ENUMVAL (type, i))
+      if (val == type->field (i).loc_enumval ())
        {
          break;
        }
     }
   if (i < len)
     {
        {
          break;
        }
     }
   if (i < len)
     {
-      fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+      fputs_styled (type->field (i).name (), variable_name_style.style (),
+                   stream);
     }
     }
-  else if (TYPE_FLAG_ENUM (type))
+  else if (type->is_flag_enum ())
     {
       int first = 1;
 
     {
       int first = 1;
 
-      /* We have a "flag" enum, so we try to decompose it into
-        pieces as appropriate.  A flag enum has disjoint
-        constants by definition.  */
-      fputs_filtered ("(", stream);
+      /* We have a "flag" enum, so we try to decompose it into pieces as
+        appropriate.  The enum may have multiple enumerators representing
+        the same bit, in which case we choose to only print the first one
+        we find.  */
       for (i = 0; i < len; ++i)
        {
          QUIT;
 
       for (i = 0; i < len; ++i)
        {
          QUIT;
 
-         if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0)
+         ULONGEST enumval = type->field (i).loc_enumval ();
+         int nbits = count_one_bits_ll (enumval);
+
+         gdb_assert (nbits == 0 || nbits == 1);
+
+         if ((val & enumval) != 0)
            {
            {
-             if (!first)
+             if (first)
+               {
+                 fputs_filtered ("(", stream);
+                 first = 0;
+               }
+             else
                fputs_filtered (" | ", stream);
                fputs_filtered (" | ", stream);
-             first = 0;
 
 
-             val &= ~TYPE_FIELD_ENUMVAL (type, i);
-             fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+             val &= ~type->field (i).loc_enumval ();
+             fputs_styled (type->field (i).name (),
+                           variable_name_style.style (), stream);
            }
        }
 
            }
        }
 
-      if (first || val != 0)
+      if (val != 0)
        {
        {
-         if (!first)
+         /* There are leftover bits, print them.  */
+         if (first)
+           fputs_filtered ("(", stream);
+         else
            fputs_filtered (" | ", stream);
            fputs_filtered (" | ", stream);
-         fputs_filtered ("unknown: ", stream);
-         print_longest (stream, 'd', 0, val);
-       }
 
 
-      fputs_filtered (")", stream);
+         fputs_filtered ("unknown: 0x", stream);
+         print_longest (stream, 'x', 0, val);
+         fputs_filtered (")", stream);
+       }
+      else if (first)
+       {
+         /* Nothing has been printed and the value is 0, the enum value must
+            have been 0.  */
+         fputs_filtered ("0", stream);
+       }
+      else
+       {
+         /* Something has been printed, close the parenthesis.  */
+         fputs_filtered (")", stream);
+       }
     }
   else
     print_longest (stream, 'd', 0, val);
     }
   else
     print_longest (stream, 'd', 0, val);
@@ -672,42 +688,16 @@ generic_val_print_enum (struct type *type,
                        const struct value_print_options *options)
 {
   LONGEST val;
                        const struct value_print_options *options)
 {
   LONGEST val;
-  struct gdbarch *gdbarch = get_type_arch (type);
+  struct gdbarch *gdbarch = type->arch ();
   int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
 
   int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
 
-  if (options->format)
-    {
-      val_print_scalar_formatted (type, embedded_offset,
-                                 original_value, options, 0, stream);
-    }
-  else
-    {
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
+  gdb_assert (!options->format);
 
 
-      val = unpack_long (type, valaddr + embedded_offset * unit_size);
+  const gdb_byte *valaddr = value_contents_for_printing (original_value).data ();
 
 
-      generic_val_print_enum_1 (type, val, stream);
-    }
-}
+  val = unpack_long (type, valaddr + embedded_offset * unit_size);
 
 
-/* generic_val_print helper for TYPE_CODE_FLAGS.  */
-
-static void
-generic_val_print_flags (struct type *type,
-                        int embedded_offset, struct ui_file *stream,
-                        struct value *original_value,
-                        const struct value_print_options *options)
-
-{
-  if (options->format)
-    val_print_scalar_formatted (type, embedded_offset, original_value,
-                               options, 0, stream);
-  else
-    {
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
-
-      val_print_type_code_flags (type, valaddr + embedded_offset, stream);
-    }
+  generic_val_print_enum_1 (type, val, stream);
 }
 
 /* generic_val_print helper for TYPE_CODE_FUNC and TYPE_CODE_METHOD.  */
 }
 
 /* generic_val_print helper for TYPE_CODE_FUNC and TYPE_CODE_METHOD.  */
@@ -719,52 +709,40 @@ generic_val_print_func (struct type *type,
                        struct value *original_value,
                        const struct value_print_options *options)
 {
                        struct value *original_value,
                        const struct value_print_options *options)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
+  struct gdbarch *gdbarch = type->arch ();
 
 
-  if (options->format)
-    {
-      val_print_scalar_formatted (type, embedded_offset,
-                                 original_value, options, 0, stream);
-    }
-  else
-    {
-      /* FIXME, we should consider, at least for ANSI C language,
-         eliminating the distinction made between FUNCs and POINTERs
-         to FUNCs.  */
-      fprintf_filtered (stream, "{");
-      type_print (type, "", stream, -1);
-      fprintf_filtered (stream, "} ");
-      /* Try to print what function it points to, and its address.  */
-      print_address_demangle (options, gdbarch, address, stream, demangle);
-    }
+  gdb_assert (!options->format);
+
+  /* FIXME, we should consider, at least for ANSI C language,
+     eliminating the distinction made between FUNCs and POINTERs to
+     FUNCs.  */
+  fprintf_filtered (stream, "{");
+  type_print (type, "", stream, -1);
+  fprintf_filtered (stream, "} ");
+  /* Try to print what function it points to, and its address.  */
+  print_address_demangle (options, gdbarch, address, stream, demangle);
 }
 
 }
 
-/* generic_val_print helper for TYPE_CODE_BOOL.  */
+/* generic_value_print helper for TYPE_CODE_BOOL.  */
 
 static void
 
 static void
-generic_val_print_bool (struct type *type,
-                       int embedded_offset, struct ui_file *stream,
-                       struct value *original_value,
-                       const struct value_print_options *options,
-                       const struct generic_val_print_decorations *decorations)
+generic_value_print_bool
+  (struct value *value, struct ui_file *stream,
+   const struct value_print_options *options,
+   const struct generic_val_print_decorations *decorations)
 {
 {
-  LONGEST val;
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
-
   if (options->format || options->output_format)
     {
       struct value_print_options opts = *options;
       opts.format = (options->format ? options->format
                     : options->output_format);
   if (options->format || options->output_format)
     {
       struct value_print_options opts = *options;
       opts.format = (options->format ? options->format
                     : options->output_format);
-      val_print_scalar_formatted (type, embedded_offset,
-                                 original_value, &opts, 0, stream);
+      value_print_scalar_formatted (value, &opts, 0, stream);
     }
   else
     {
     }
   else
     {
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
-
-      val = unpack_long (type, valaddr + embedded_offset * unit_size);
+      const gdb_byte *valaddr = value_contents_for_printing (value).data ();
+      struct type *type = check_typedef (value_type (value));
+      LONGEST val = unpack_long (type, valaddr);
       if (val == 0)
        fputs_filtered (decorations->false_name, stream);
       else if (val == 1)
       if (val == 0)
        fputs_filtered (decorations->false_name, stream);
       else if (val == 1)
@@ -774,208 +752,209 @@ generic_val_print_bool (struct type *type,
     }
 }
 
     }
 }
 
-/* generic_val_print helper for TYPE_CODE_INT.  */
+/* generic_value_print helper for TYPE_CODE_INT.  */
 
 static void
 
 static void
-generic_val_print_int (struct type *type,
-                      int embedded_offset, struct ui_file *stream,
-                      struct value *original_value,
-                      const struct value_print_options *options)
+generic_value_print_int (struct value *val, struct ui_file *stream,
+                        const struct value_print_options *options)
 {
   struct value_print_options opts = *options;
 
   opts.format = (options->format ? options->format
                 : options->output_format);
 {
   struct value_print_options opts = *options;
 
   opts.format = (options->format ? options->format
                 : options->output_format);
-  val_print_scalar_formatted (type, embedded_offset,
-                             original_value, &opts, 0, stream);
+  value_print_scalar_formatted (val, &opts, 0, stream);
 }
 
 }
 
-/* generic_val_print helper for TYPE_CODE_CHAR.  */
+/* generic_value_print helper for TYPE_CODE_CHAR.  */
 
 static void
 
 static void
-generic_val_print_char (struct type *type, struct type *unresolved_type,
-                       int embedded_offset,
-                       struct ui_file *stream,
-                       struct value *original_value,
-                       const struct value_print_options *options)
+generic_value_print_char (struct value *value, struct ui_file *stream,
+                         const struct value_print_options *options)
 {
 {
-  LONGEST val;
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
-
   if (options->format || options->output_format)
     {
       struct value_print_options opts = *options;
 
       opts.format = (options->format ? options->format
                     : options->output_format);
   if (options->format || options->output_format)
     {
       struct value_print_options opts = *options;
 
       opts.format = (options->format ? options->format
                     : options->output_format);
-      val_print_scalar_formatted (type, embedded_offset,
-                                 original_value, &opts, 0, stream);
+      value_print_scalar_formatted (value, &opts, 0, stream);
     }
   else
     {
     }
   else
     {
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
+      struct type *unresolved_type = value_type (value);
+      struct type *type = check_typedef (unresolved_type);
+      const gdb_byte *valaddr = value_contents_for_printing (value).data ();
 
 
-      val = unpack_long (type, valaddr + embedded_offset * unit_size);
-      if (TYPE_UNSIGNED (type))
+      LONGEST val = unpack_long (type, valaddr);
+      if (type->is_unsigned ())
        fprintf_filtered (stream, "%u", (unsigned int) val);
       else
        fprintf_filtered (stream, "%d", (int) val);
       fputs_filtered (" ", stream);
        fprintf_filtered (stream, "%u", (unsigned int) val);
       else
        fprintf_filtered (stream, "%d", (int) val);
       fputs_filtered (" ", stream);
-      LA_PRINT_CHAR (val, unresolved_type, stream);
+      current_language->printchar (val, unresolved_type, stream);
     }
 }
 
 /* generic_val_print helper for TYPE_CODE_FLT and TYPE_CODE_DECFLOAT.  */
 
 static void
     }
 }
 
 /* generic_val_print helper for TYPE_CODE_FLT and TYPE_CODE_DECFLOAT.  */
 
 static void
-generic_val_print_float (struct type *type,
-                        int embedded_offset, struct ui_file *stream,
+generic_val_print_float (struct type *type, struct ui_file *stream,
                         struct value *original_value,
                         const struct value_print_options *options)
 {
                         struct value *original_value,
                         const struct value_print_options *options)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
+  gdb_assert (!options->format);
+
+  const gdb_byte *valaddr = value_contents_for_printing (original_value).data ();
+
+  print_floating (valaddr, type, stream);
+}
+
+/* generic_val_print helper for TYPE_CODE_FIXED_POINT.  */
 
 
+static void
+generic_val_print_fixed_point (struct value *val, struct ui_file *stream,
+                              const struct value_print_options *options)
+{
   if (options->format)
   if (options->format)
-    {
-      val_print_scalar_formatted (type, embedded_offset,
-                                 original_value, options, 0, stream);
-    }
+    value_print_scalar_formatted (val, options, 0, stream);
   else
     {
   else
     {
-      const gdb_byte *valaddr = value_contents_for_printing (original_value);
+      struct type *type = value_type (val);
+
+      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
+      gdb_mpf f;
 
 
-      print_floating (valaddr + embedded_offset * unit_size, type, stream);
+      f.read_fixed_point (gdb::make_array_view (valaddr, TYPE_LENGTH (type)),
+                         type_byte_order (type), type->is_unsigned (),
+                         type->fixed_point_scaling_factor ());
+
+      const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11Fg" : "%.17Fg";
+      std::string str = gmp_string_printf (fmt, f.val);
+      fprintf_filtered (stream, "%s", str.c_str ());
     }
 }
 
     }
 }
 
-/* generic_val_print helper for TYPE_CODE_COMPLEX.  */
+/* generic_value_print helper for TYPE_CODE_COMPLEX.  */
 
 static void
 
 static void
-generic_val_print_complex (struct type *type,
-                          int embedded_offset, struct ui_file *stream,
-                          struct value *original_value,
-                          const struct value_print_options *options,
-                          const struct generic_val_print_decorations
-                            *decorations)
+generic_value_print_complex (struct value *val, struct ui_file *stream,
+                            const struct value_print_options *options,
+                            const struct generic_val_print_decorations
+                              *decorations)
 {
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
-  const gdb_byte *valaddr = value_contents_for_printing (original_value);
-
   fprintf_filtered (stream, "%s", decorations->complex_prefix);
   fprintf_filtered (stream, "%s", decorations->complex_prefix);
-  if (options->format)
-    val_print_scalar_formatted (TYPE_TARGET_TYPE (type),
-                               embedded_offset, original_value, options, 0,
-                               stream);
-  else
-    print_floating (valaddr + embedded_offset * unit_size,
-                   TYPE_TARGET_TYPE (type), stream);
+
+  struct value *real_part = value_real_part (val);
+  value_print_scalar_formatted (real_part, options, 0, stream);
   fprintf_filtered (stream, "%s", decorations->complex_infix);
   fprintf_filtered (stream, "%s", decorations->complex_infix);
-  if (options->format)
-    val_print_scalar_formatted (TYPE_TARGET_TYPE (type),
-                               embedded_offset
-                               + type_length_units (TYPE_TARGET_TYPE (type)),
-                               original_value, options, 0, stream);
-  else
-    print_floating (valaddr + embedded_offset * unit_size
-                   + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
-                   TYPE_TARGET_TYPE (type), stream);
+
+  struct value *imag_part = value_imaginary_part (val);
+  value_print_scalar_formatted (imag_part, options, 0, stream);
   fprintf_filtered (stream, "%s", decorations->complex_suffix);
 }
 
   fprintf_filtered (stream, "%s", decorations->complex_suffix);
 }
 
-/* A generic val_print that is suitable for use by language
-   implementations of the la_val_print method.  This function can
-   handle most type codes, though not all, notably exception
-   TYPE_CODE_UNION and TYPE_CODE_STRUCT, which must be implemented by
-   the caller.
-   
-   Most arguments are as to val_print.
-   
-   The additional DECORATIONS argument can be used to customize the
-   output in some small, language-specific ways.  */
+/* generic_value_print helper for TYPE_CODE_MEMBERPTR.  */
+
+static void
+generic_value_print_memberptr
+  (struct value *val, struct ui_file *stream,
+   int recurse,
+   const struct value_print_options *options,
+   const struct generic_val_print_decorations *decorations)
+{
+  if (!options->format)
+    {
+      /* Member pointers are essentially specific to C++, and so if we
+        encounter one, we should print it according to C++ rules.  */
+      struct type *type = check_typedef (value_type (val));
+      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
+      cp_print_class_member (valaddr, type, stream, "&");
+    }
+  else
+    generic_value_print (val, stream, recurse, options, decorations);
+}
+
+/* See valprint.h.  */
 
 void
 
 void
-generic_val_print (struct type *type,
-                  int embedded_offset, CORE_ADDR address,
-                  struct ui_file *stream, int recurse,
-                  struct value *original_value,
-                  const struct value_print_options *options,
-                  const struct generic_val_print_decorations *decorations)
+generic_value_print (struct value *val, struct ui_file *stream, int recurse,
+                    const struct value_print_options *options,
+                    const struct generic_val_print_decorations *decorations)
 {
 {
-  struct type *unresolved_type = type;
+  struct type *type = value_type (val);
 
   type = check_typedef (type);
 
   type = check_typedef (type);
-  switch (TYPE_CODE (type))
+
+  if (is_fixed_point_type (type))
+    type = type->fixed_point_type_base_type ();
+
+  switch (type->code ())
     {
     case TYPE_CODE_ARRAY:
     {
     case TYPE_CODE_ARRAY:
-      generic_val_print_array (type, embedded_offset, address, stream,
-                              recurse, original_value, options, decorations);
+      generic_val_print_array (val, stream, recurse, options, decorations);
       break;
 
     case TYPE_CODE_MEMBERPTR:
       break;
 
     case TYPE_CODE_MEMBERPTR:
-      generic_val_print_memberptr (type, embedded_offset, stream,
-                                  original_value, options);
+      generic_value_print_memberptr (val, stream, recurse, options,
+                                    decorations);
       break;
 
     case TYPE_CODE_PTR:
       break;
 
     case TYPE_CODE_PTR:
-      generic_val_print_ptr (type, embedded_offset, stream,
-                            original_value, options);
+      generic_value_print_ptr (val, stream, options);
       break;
 
     case TYPE_CODE_REF:
     case TYPE_CODE_RVALUE_REF:
       break;
 
     case TYPE_CODE_REF:
     case TYPE_CODE_RVALUE_REF:
-      generic_val_print_ref (type, embedded_offset, stream, recurse,
-                            original_value, options);
+      generic_val_print_ref (type, 0, stream, recurse,
+                            val, options);
       break;
 
     case TYPE_CODE_ENUM:
       break;
 
     case TYPE_CODE_ENUM:
-      generic_val_print_enum (type, embedded_offset, stream,
-                             original_value, options);
+      if (options->format)
+       value_print_scalar_formatted (val, options, 0, stream);
+      else
+       generic_val_print_enum (type, 0, stream, val, options);
       break;
 
     case TYPE_CODE_FLAGS:
       break;
 
     case TYPE_CODE_FLAGS:
-      generic_val_print_flags (type, embedded_offset, stream,
-                              original_value, options);
+      if (options->format)
+       value_print_scalar_formatted (val, options, 0, stream);
+      else
+       val_print_type_code_flags (type, val, 0, stream);
       break;
 
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
       break;
 
     case TYPE_CODE_FUNC:
     case TYPE_CODE_METHOD:
-      generic_val_print_func (type, embedded_offset, address, stream,
-                             original_value, options);
+      if (options->format)
+       value_print_scalar_formatted (val, options, 0, stream);
+      else
+       generic_val_print_func (type, 0, value_address (val), stream,
+                               val, options);
       break;
 
     case TYPE_CODE_BOOL:
       break;
 
     case TYPE_CODE_BOOL:
-      generic_val_print_bool (type, embedded_offset, stream,
-                             original_value, options, decorations);
+      generic_value_print_bool (val, stream, options, decorations);
       break;
 
     case TYPE_CODE_RANGE:
       break;
 
     case TYPE_CODE_RANGE:
-      /* FIXME: create_static_range_type does not set the unsigned bit in a
-         range type (I think it probably should copy it from the
-         target type), so we won't print values which are too large to
-         fit in a signed integer correctly.  */
-      /* FIXME: Doesn't handle ranges of enums correctly.  (Can't just
-         print with the target type, though, because the size of our
-         type and the target type might differ).  */
-
-      /* FALLTHROUGH */
-
     case TYPE_CODE_INT:
     case TYPE_CODE_INT:
-      generic_val_print_int (type, embedded_offset, stream,
-                            original_value, options);
+      generic_value_print_int (val, stream, options);
       break;
 
     case TYPE_CODE_CHAR:
       break;
 
     case TYPE_CODE_CHAR:
-      generic_val_print_char (type, unresolved_type, embedded_offset,
-                             stream, original_value, options);
+      generic_value_print_char (val, stream, options);
       break;
 
     case TYPE_CODE_FLT:
     case TYPE_CODE_DECFLOAT:
       break;
 
     case TYPE_CODE_FLT:
     case TYPE_CODE_DECFLOAT:
-      generic_val_print_float (type, embedded_offset, stream,
-                              original_value, options);
+      if (options->format)
+       value_print_scalar_formatted (val, options, 0, stream);
+      else
+       generic_val_print_float (type, stream, val, options);
+      break;
+
+    case TYPE_CODE_FIXED_POINT:
+      generic_val_print_fixed_point (val, stream, options);
       break;
 
     case TYPE_CODE_VOID:
       break;
 
     case TYPE_CODE_VOID:
@@ -988,53 +967,51 @@ generic_val_print (struct type *type,
 
     case TYPE_CODE_UNDEF:
       /* This happens (without TYPE_STUB set) on systems which don't use
 
     case TYPE_CODE_UNDEF:
       /* This happens (without TYPE_STUB set) on systems which don't use
-         dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
-         and no complete type for struct foo in that file.  */
+        dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
+        and no complete type for struct foo in that file.  */
       fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
       break;
 
     case TYPE_CODE_COMPLEX:
       fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
       break;
 
     case TYPE_CODE_COMPLEX:
-      generic_val_print_complex (type, embedded_offset, stream,
-                                original_value, options, decorations);
+      generic_value_print_complex (val, stream, options, decorations);
+      break;
+
+    case TYPE_CODE_METHODPTR:
+      cplus_print_method_ptr (value_contents_for_printing (val).data (), type,
+                             stream);
       break;
 
     case TYPE_CODE_UNION:
     case TYPE_CODE_STRUCT:
       break;
 
     case TYPE_CODE_UNION:
     case TYPE_CODE_STRUCT:
-    case TYPE_CODE_METHODPTR:
     default:
       error (_("Unhandled type code %d in symbol table."),
     default:
       error (_("Unhandled type code %d in symbol table."),
-            TYPE_CODE (type));
+            type->code ());
     }
 }
 
     }
 }
 
-/* Print using the given LANGUAGE the data of type TYPE located at
-   VAL's contents buffer + EMBEDDED_OFFSET (within GDB), which came
-   from the inferior at address ADDRESS + EMBEDDED_OFFSET, onto
-   stdio stream STREAM according to OPTIONS.  VAL is the whole object
-   that came from ADDRESS.
-
-   The language printers will pass down an adjusted EMBEDDED_OFFSET to
-   further helper subroutines as subfields of TYPE are printed.  In
-   such cases, VAL is passed down unadjusted, so
-   that VAL can be queried for metadata about the contents data being
-   printed, using EMBEDDED_OFFSET as an offset into VAL's contents
-   buffer.  For example: "has this field been optimized out", or "I'm
-   printing an object while inspecting a traceframe; has this
-   particular piece of data been collected?".
+/* Print using the given LANGUAGE the value VAL onto stream STREAM according
+   to OPTIONS.
 
 
-   RECURSE indicates the amount of indentation to supply before
-   continuation lines; this amount is roughly twice the value of
-   RECURSE.  */
+   This is a preferable interface to val_print, above, because it uses
+   GDB's value mechanism.  */
 
 void
 
 void
-val_print (struct type *type, LONGEST embedded_offset,
-          CORE_ADDR address, struct ui_file *stream, int recurse,
-          struct value *val,
-          const struct value_print_options *options,
-          const struct language_defn *language)
+common_val_print (struct value *value, struct ui_file *stream, int recurse,
+                 const struct value_print_options *options,
+                 const struct language_defn *language)
 {
 {
-  int ret = 0;
+  if (language->la_language == language_ada)
+    /* The value might have a dynamic type, which would cause trouble
+       below when trying to extract the value contents (since the value
+       size is determined from the type size which is unknown).  So
+       get a fixed representation of our value.  */
+    value = ada_to_fixed_value (value);
+
+  if (value_lazy (value))
+    value_fetch_lazy (value);
+
   struct value_print_options local_opts = *options;
   struct value_print_options local_opts = *options;
+  struct type *type = value_type (value);
   struct type *real_type = check_typedef (type);
 
   if (local_opts.prettyformat == Val_prettyformat_default)
   struct type *real_type = check_typedef (type);
 
   if (local_opts.prettyformat == Val_prettyformat_default)
@@ -1047,21 +1024,19 @@ val_print (struct type *type, LONGEST embedded_offset,
      only a stub and we can't find and substitute its complete type, then
      print appropriate string and return.  */
 
      only a stub and we can't find and substitute its complete type, then
      print appropriate string and return.  */
 
-  if (TYPE_STUB (real_type))
+  if (real_type->is_stub ())
     {
       fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
       return;
     }
 
     {
       fprintf_styled (stream, metadata_style.style (), _("<incomplete type>"));
       return;
     }
 
-  if (!valprint_check_validity (stream, real_type, embedded_offset, val))
+  if (!valprint_check_validity (stream, real_type, 0, value))
     return;
 
   if (!options->raw)
     {
     return;
 
   if (!options->raw)
     {
-      ret = apply_ext_lang_val_pretty_printer (type, embedded_offset,
-                                              address, stream, recurse,
-                                              val, options, language);
-      if (ret)
+      if (apply_ext_lang_val_pretty_printer (value, stream, recurse, options,
+                                            language))
        return;
     }
 
        return;
     }
 
@@ -1080,14 +1055,12 @@ val_print (struct type *type, LONGEST embedded_offset,
 
   try
     {
 
   try
     {
-      language->la_val_print (type, embedded_offset, address,
-                             stream, recurse, val,
-                             &local_opts);
+      language->value_print_inner (value, stream, recurse, &local_opts);
     }
   catch (const gdb_exception_error &except)
     {
       fprintf_styled (stream, metadata_style.style (),
     }
   catch (const gdb_exception_error &except)
     {
       fprintf_styled (stream, metadata_style.style (),
-                     _("<error reading variable>"));
+                     _("<error reading variable: %s>"), except.what ());
     }
 }
 
     }
 }
 
@@ -1100,8 +1073,8 @@ val_print_check_max_depth (struct ui_file *stream, int recurse,
 {
   if (options->max_depth > -1 && recurse >= options->max_depth)
     {
 {
   if (options->max_depth > -1 && recurse >= options->max_depth)
     {
-      gdb_assert (language->la_struct_too_deep_ellipsis != NULL);
-      fputs_filtered (language->la_struct_too_deep_ellipsis, stream);
+      gdb_assert (language->struct_too_deep_ellipsis () != NULL);
+      fputs_filtered (language->struct_too_deep_ellipsis (), stream);
       return true;
     }
 
       return true;
     }
 
@@ -1141,7 +1114,7 @@ value_check_printable (struct value *val, struct ui_file *stream,
       return 0;
     }
 
       return 0;
     }
 
-  if (TYPE_CODE (value_type (val)) == TYPE_CODE_INTERNAL_FUNCTION)
+  if (value_type (val)->code () == TYPE_CODE_INTERNAL_FUNCTION)
     {
       fprintf_styled (stream, metadata_style.style (),
                      _("<internal function %s>"),
     {
       fprintf_styled (stream, metadata_style.style (),
                      _("<internal function %s>"),
@@ -1164,34 +1137,17 @@ value_check_printable (struct value *val, struct ui_file *stream,
   return 1;
 }
 
   return 1;
 }
 
-/* Print using the given LANGUAGE the value VAL onto stream STREAM according
-   to OPTIONS.
-
-   This is a preferable interface to val_print, above, because it uses
-   GDB's value mechanism.  */
+/* See valprint.h.  */
 
 void
 
 void
-common_val_print (struct value *val, struct ui_file *stream, int recurse,
-                 const struct value_print_options *options,
-                 const struct language_defn *language)
+common_val_print_checked (struct value *val, struct ui_file *stream,
+                         int recurse,
+                         const struct value_print_options *options,
+                         const struct language_defn *language)
 {
   if (!value_check_printable (val, stream, options))
     return;
 {
   if (!value_check_printable (val, stream, options))
     return;
-
-  if (language->la_language == language_ada)
-    /* The value might have a dynamic type, which would cause trouble
-       below when trying to extract the value contents (since the value
-       size is determined from the type size which is unknown).  So
-       get a fixed representation of our value.  */
-    val = ada_to_fixed_value (val);
-
-  if (value_lazy (val))
-    value_fetch_lazy (val);
-
-  val_print (value_type (val),
-            value_embedded_offset (val), value_address (val),
-            stream, recurse,
-            val, options, language);
+  common_val_print (val, stream, recurse, options, language);
 }
 
 /* Print on stream STREAM the value VAL according to OPTIONS.  The value
 }
 
 /* Print on stream STREAM the value VAL according to OPTIONS.  The value
@@ -1201,40 +1157,41 @@ void
 value_print (struct value *val, struct ui_file *stream,
             const struct value_print_options *options)
 {
 value_print (struct value *val, struct ui_file *stream,
             const struct value_print_options *options)
 {
+  scoped_value_mark free_values;
+
   if (!value_check_printable (val, stream, options))
     return;
 
   if (!options->raw)
     {
       int r
   if (!value_check_printable (val, stream, options))
     return;
 
   if (!options->raw)
     {
       int r
-       = apply_ext_lang_val_pretty_printer (value_type (val),
-                                            value_embedded_offset (val),
-                                            value_address (val),
-                                            stream, 0,
-                                            val, options, current_language);
+       = apply_ext_lang_val_pretty_printer (val, stream, 0, options,
+                                            current_language);
 
       if (r)
        return;
     }
 
 
       if (r)
        return;
     }
 
-  LA_VALUE_PRINT (val, stream, options);
+  current_language->value_print (val, stream, options);
 }
 
 static void
 }
 
 static void
-val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
-                          struct ui_file *stream)
+val_print_type_code_flags (struct type *type, struct value *original_value,
+                          int embedded_offset, struct ui_file *stream)
 {
 {
+  const gdb_byte *valaddr = (value_contents_for_printing (original_value).data ()
+                            + embedded_offset);
   ULONGEST val = unpack_long (type, valaddr);
   ULONGEST val = unpack_long (type, valaddr);
-  int field, nfields = TYPE_NFIELDS (type);
-  struct gdbarch *gdbarch = get_type_arch (type);
+  int field, nfields = type->num_fields ();
+  struct gdbarch *gdbarch = type->arch ();
   struct type *bool_type = builtin_type (gdbarch)->builtin_bool;
 
   fputs_filtered ("[", stream);
   for (field = 0; field < nfields; field++)
     {
   struct type *bool_type = builtin_type (gdbarch)->builtin_bool;
 
   fputs_filtered ("[", stream);
   for (field = 0; field < nfields; field++)
     {
-      if (TYPE_FIELD_NAME (type, field)[0] != '\0')
+      if (type->field (field).name ()[0] != '\0')
        {
        {
-         struct type *field_type = TYPE_FIELD_TYPE (type, field);
+         struct type *field_type = type->field (field).type ();
 
          if (field_type == bool_type
              /* We require boolean types here to be one bit wide.  This is a
 
          if (field_type == bool_type
              /* We require boolean types here to be one bit wide.  This is a
@@ -1243,21 +1200,23 @@ val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
                 int.  */
              && TYPE_FIELD_BITSIZE (type, field) == 1)
            {
                 int.  */
              && TYPE_FIELD_BITSIZE (type, field) == 1)
            {
-             if (val & ((ULONGEST)1 << TYPE_FIELD_BITPOS (type, field)))
-               fprintf_filtered (stream, " %s",
-                                 TYPE_FIELD_NAME (type, field));
+             if (val & ((ULONGEST)1 << type->field (field).loc_bitpos ()))
+               fprintf_filtered
+                 (stream, " %ps",
+                  styled_string (variable_name_style.style (),
+                                 type->field (field).name ()));
            }
          else
            {
              unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
            }
          else
            {
              unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
-             ULONGEST field_val
-               = val >> (TYPE_FIELD_BITPOS (type, field) - field_len + 1);
+             ULONGEST field_val = val >> type->field (field).loc_bitpos ();
 
              if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT)
                field_val &= ((ULONGEST) 1 << field_len) - 1;
 
              if (field_len < sizeof (ULONGEST) * TARGET_CHAR_BIT)
                field_val &= ((ULONGEST) 1 << field_len) - 1;
-             fprintf_filtered (stream, " %s=",
-                               TYPE_FIELD_NAME (type, field));
-             if (TYPE_CODE (field_type) == TYPE_CODE_ENUM)
+             fprintf_filtered (stream, " %ps=",
+                               styled_string (variable_name_style.style (),
+                                              type->field (field).name ()));
+             if (field_type->code () == TYPE_CODE_ENUM)
                generic_val_print_enum_1 (field_type, field_val, stream);
              else
                print_longest (stream, 'd', 0, field_val);
                generic_val_print_enum_1 (field_type, field_val, stream);
              else
                print_longest (stream, 'd', 0, field_val);
@@ -1267,23 +1226,15 @@ val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
   fputs_filtered (" ]", stream);
 }
 
   fputs_filtered (" ]", stream);
 }
 
-/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
-   according to OPTIONS and SIZE on STREAM.  Format i is not supported
-   at this level.
-
-   This is how the elements of an array or structure are printed
-   with a format.  */
+/* See valprint.h.  */
 
 void
 
 void
-val_print_scalar_formatted (struct type *type,
-                           LONGEST embedded_offset,
-                           struct value *val,
-                           const struct value_print_options *options,
-                           int size,
-                           struct ui_file *stream)
+value_print_scalar_formatted (struct value *val,
+                             const struct value_print_options *options,
+                             int size,
+                             struct ui_file *stream)
 {
 {
-  struct gdbarch *arch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (arch);
+  struct type *type = check_typedef (value_type (val));
 
   gdb_assert (val != NULL);
 
 
   gdb_assert (val != NULL);
 
@@ -1295,27 +1246,24 @@ val_print_scalar_formatted (struct type *type,
       struct value_print_options opts = *options;
       opts.format = 0;
       opts.deref_ref = 0;
       struct value_print_options opts = *options;
       opts.format = 0;
       opts.deref_ref = 0;
-      val_print (type, embedded_offset, 0, stream, 0, val, &opts,
-                current_language);
+      common_val_print (val, stream, 0, &opts, current_language);
       return;
     }
 
   /* value_contents_for_printing fetches all VAL's contents.  They are
      needed to check whether VAL is optimized-out or unavailable
      below.  */
       return;
     }
 
   /* value_contents_for_printing fetches all VAL's contents.  They are
      needed to check whether VAL is optimized-out or unavailable
      below.  */
-  const gdb_byte *valaddr = value_contents_for_printing (val);
+  const gdb_byte *valaddr = value_contents_for_printing (val).data ();
 
   /* A scalar object that does not have all bits available can't be
      printed, because all bits contribute to its representation.  */
 
   /* A scalar object that does not have all bits available can't be
      printed, because all bits contribute to its representation.  */
-  if (value_bits_any_optimized_out (val,
-                                   TARGET_CHAR_BIT * embedded_offset,
+  if (value_bits_any_optimized_out (val, 0,
                                    TARGET_CHAR_BIT * TYPE_LENGTH (type)))
     val_print_optimized_out (val, stream);
                                    TARGET_CHAR_BIT * TYPE_LENGTH (type)))
     val_print_optimized_out (val, stream);
-  else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
+  else if (!value_bytes_available (val, 0, TYPE_LENGTH (type)))
     val_print_unavailable (stream);
   else
     val_print_unavailable (stream);
   else
-    print_scalar_formatted (valaddr + embedded_offset * unit_size, type,
-                           options, size, stream);
+    print_scalar_formatted (valaddr, type, options, size, stream);
 }
 
 /* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
 }
 
 /* Print a number according to FORMAT which is one of d,u,x,o,b,h,w,g.
@@ -1762,7 +1710,7 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr,
          /* Take low nibble and bump our pointer "p".  */
 
          digits[0] += LOW_NIBBLE (*p);
          /* Take low nibble and bump our pointer "p".  */
 
          digits[0] += LOW_NIBBLE (*p);
-          if (byte_order == BFD_ENDIAN_BIG)
+         if (byte_order == BFD_ENDIAN_BIG)
            p++;
          else
            p--;
            p++;
          else
            p--;
@@ -1879,43 +1827,6 @@ print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr,
     }
 }
 
     }
 }
 
-/* VALADDR points to a char integer of LEN bytes.
-   Print it out in appropriate language form on stream.
-   Omit any leading zero chars.  */
-
-void
-print_char_chars (struct ui_file *stream, struct type *type,
-                 const gdb_byte *valaddr,
-                 unsigned len, enum bfd_endian byte_order)
-{
-  const gdb_byte *p;
-
-  if (byte_order == BFD_ENDIAN_BIG)
-    {
-      p = valaddr;
-      while (p < valaddr + len - 1 && *p == 0)
-       ++p;
-
-      while (p < valaddr + len)
-       {
-         LA_EMIT_CHAR (*p, type, stream, '\'');
-         ++p;
-       }
-    }
-  else
-    {
-      p = valaddr + len - 1;
-      while (p > valaddr && *p == 0)
-       --p;
-
-      while (p >= valaddr)
-       {
-         LA_EMIT_CHAR (*p, type, stream, '\'');
-         --p;
-       }
-    }
-}
-
 /* Print function pointer with inferior address ADDRESS onto stdio
    stream STREAM.  */
 
 /* Print function pointer with inferior address ADDRESS onto stdio
    stream STREAM.  */
 
@@ -1925,9 +1836,8 @@ print_function_pointer_address (const struct value_print_options *options,
                                CORE_ADDR address,
                                struct ui_file *stream)
 {
                                CORE_ADDR address,
                                struct ui_file *stream)
 {
-  CORE_ADDR func_addr
-    = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
-                                         current_top_target ());
+  CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr
+    (gdbarch, address, current_inferior ()->top_target ());
 
   /* If the function pointer is represented by a description, print
      the address of the description.  */
 
   /* If the function pointer is represented by a description, print
      the address of the description.  */
@@ -1946,39 +1856,26 @@ print_function_pointer_address (const struct value_print_options *options,
     
 void  
 maybe_print_array_index (struct type *index_type, LONGEST index,
     
 void  
 maybe_print_array_index (struct type *index_type, LONGEST index,
-                         struct ui_file *stream,
+                        struct ui_file *stream,
                         const struct value_print_options *options)
 {
                         const struct value_print_options *options)
 {
-  struct value *index_value;
-
   if (!options->print_array_indexes)
     return; 
   if (!options->print_array_indexes)
     return; 
-    
-  index_value = value_from_longest (index_type, index);
 
 
-  LA_PRINT_ARRAY_INDEX (index_value, stream, options);
+  current_language->print_array_index (index_type, index, stream, options);
 }
 
 }
 
-/*  Called by various <lang>_val_print routines to print elements of an
-   array in the form "<elem1>, <elem2>, <elem3>, ...".
-
-   (FIXME?)  Assumes array element separator is a comma, which is correct
-   for all languages currently handled.
-   (FIXME?)  Some languages have a notation for repeated array elements,
-   perhaps we should try to use that notation when appropriate.  */
+/* See valprint.h.  */
 
 void
 
 void
-val_print_array_elements (struct type *type,
-                         LONGEST embedded_offset,
-                         CORE_ADDR address, struct ui_file *stream,
-                         int recurse,
-                         struct value *val,
-                         const struct value_print_options *options,
-                         unsigned int i)
+value_print_array_elements (struct value *val, struct ui_file *stream,
+                           int recurse,
+                           const struct value_print_options *options,
+                           unsigned int i)
 {
   unsigned int things_printed = 0;
   unsigned len;
 {
   unsigned int things_printed = 0;
   unsigned len;
-  struct type *elttype, *index_type, *base_index_type;
+  struct type *elttype, *index_type;
   unsigned eltlen;
   /* Position of the array element we are examining to see
      whether it is repeated.  */
   unsigned eltlen;
   /* Position of the array element we are examining to see
      whether it is repeated.  */
@@ -1986,41 +1883,26 @@ val_print_array_elements (struct type *type,
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
   LONGEST low_bound, high_bound;
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
   LONGEST low_bound, high_bound;
-  LONGEST low_pos, high_pos;
+
+  struct type *type = check_typedef (value_type (val));
 
   elttype = TYPE_TARGET_TYPE (type);
   eltlen = type_length_units (check_typedef (elttype));
 
   elttype = TYPE_TARGET_TYPE (type);
   eltlen = type_length_units (check_typedef (elttype));
-  index_type = TYPE_INDEX_TYPE (type);
+  index_type = type->index_type ();
+  if (index_type->code () == TYPE_CODE_RANGE)
+    index_type = TYPE_TARGET_TYPE (index_type);
 
   if (get_array_bounds (type, &low_bound, &high_bound))
     {
 
   if (get_array_bounds (type, &low_bound, &high_bound))
     {
-      if (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
-       base_index_type = TYPE_TARGET_TYPE (index_type);
-      else
-       base_index_type = index_type;
-
-      /* Non-contiguous enumerations types can by used as index types
-        in some languages (e.g. Ada).  In this case, the array length
-        shall be computed from the positions of the first and last
-        literal in the enumeration type, and not from the values
-        of these literals.  */
-      if (!discrete_position (base_index_type, low_bound, &low_pos)
-         || !discrete_position (base_index_type, high_bound, &high_pos))
-       {
-         warning (_("unable to get positions in array, use bounds instead"));
-         low_pos = low_bound;
-         high_pos = high_bound;
-       }
-
-      /* The array length should normally be HIGH_POS - LOW_POS + 1.
-         But we have to be a little extra careful, because some languages
-        such as Ada allow LOW_POS to be greater than HIGH_POS for
-        empty arrays.  In that situation, the array length is just zero,
-        not negative!  */
-      if (low_pos > high_pos)
+      /* The array length should normally be HIGH_BOUND - LOW_BOUND +
+        1.  But we have to be a little extra careful, because some
+        languages such as Ada allow LOW_BOUND to be greater than
+        HIGH_BOUND for empty arrays.  In that situation, the array
+        length is just zero, not negative!  */
+      if (low_bound > high_bound)
        len = 0;
       else
        len = 0;
       else
-       len = high_pos - low_pos + 1;
+       len = high_bound - low_bound + 1;
     }
   else
     {
     }
   else
     {
@@ -2033,6 +1915,8 @@ val_print_array_elements (struct type *type,
 
   for (; i < len && things_printed < options->print_max; i++)
     {
 
   for (; i < len && things_printed < options->print_max; i++)
     {
+      scoped_value_mark free_values;
+
       if (i != 0)
        {
          if (options->prettyformat_arrays)
       if (i != 0)
        {
          if (options->prettyformat_arrays)
@@ -2041,13 +1925,16 @@ val_print_array_elements (struct type *type,
              print_spaces_filtered (2 + 2 * recurse, stream);
            }
          else
              print_spaces_filtered (2 + 2 * recurse, stream);
            }
          else
-           {
-             fprintf_filtered (stream, ", ");
-           }
+           fprintf_filtered (stream, ", ");
+       }
+      else if (options->prettyformat_arrays)
+       {
+         fprintf_filtered (stream, "\n");
+         print_spaces_filtered (2 + 2 * recurse, stream);
        }
        }
-      wrap_here (n_spaces (2 + 2 * recurse));
+      stream->wrap_here (2 + 2 * recurse);
       maybe_print_array_index (index_type, i + low_bound,
       maybe_print_array_index (index_type, i + low_bound,
-                               stream, options);
+                              stream, options);
 
       rep1 = i + 1;
       reps = 1;
 
       rep1 = i + 1;
       reps = 1;
@@ -2056,11 +1943,8 @@ val_print_array_elements (struct type *type,
       if (options->repeat_count_threshold < UINT_MAX)
        {
          while (rep1 < len
       if (options->repeat_count_threshold < UINT_MAX)
        {
          while (rep1 < len
-                && value_contents_eq (val,
-                                      embedded_offset + i * eltlen,
-                                      val,
-                                      (embedded_offset
-                                       + rep1 * eltlen),
+                && value_contents_eq (val, i * eltlen,
+                                      val, rep1 * eltlen,
                                       eltlen))
            {
              ++reps;
                                       eltlen))
            {
              ++reps;
@@ -2068,11 +1952,12 @@ val_print_array_elements (struct type *type,
            }
        }
 
            }
        }
 
+      struct value *element = value_from_component (val, elttype, eltlen * i);
+      common_val_print (element, stream, recurse + 1, options,
+                       current_language);
+
       if (reps > options->repeat_count_threshold)
        {
       if (reps > options->repeat_count_threshold)
        {
-         val_print (elttype, embedded_offset + i * eltlen,
-                    address, stream, recurse + 1, val, options,
-                    current_language);
          annotate_elt_rep (reps);
          fprintf_filtered (stream, " %p[<repeats %u times>%p]",
                            metadata_style.style ().ptr (), reps, nullptr);
          annotate_elt_rep (reps);
          fprintf_filtered (stream, " %p[<repeats %u times>%p]",
                            metadata_style.style ().ptr (), reps, nullptr);
@@ -2083,17 +1968,17 @@ val_print_array_elements (struct type *type,
        }
       else
        {
        }
       else
        {
-         val_print (elttype, embedded_offset + i * eltlen,
-                    address,
-                    stream, recurse + 1, val, options, current_language);
          annotate_elt ();
          things_printed++;
        }
     }
   annotate_array_section_end ();
   if (i < len)
          annotate_elt ();
          things_printed++;
        }
     }
   annotate_array_section_end ();
   if (i < len)
+    fprintf_filtered (stream, "...");
+  if (options->prettyformat_arrays)
     {
     {
-      fprintf_filtered (stream, "...");
+      fprintf_filtered (stream, "\n");
+      print_spaces_filtered (2 * recurse, stream);
     }
 }
 
     }
 }
 
@@ -2155,13 +2040,7 @@ partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr,
 
    Unless an exception is thrown, BUFFER will always be allocated, even on
    failure.  In this case, some characters might have been read before the
 
    Unless an exception is thrown, BUFFER will always be allocated, even on
    failure.  In this case, some characters might have been read before the
-   failure happened.  Check BYTES_READ to recognize this situation.
-
-   Note: There was a FIXME asking to make this code use target_read_string,
-   but this function is more general (can read past null characters, up to
-   given LEN).  Besides, it is used much more often than target_read_string
-   so it is more tested.  Perhaps callers of target_read_string should use
-   this function instead?  */
+   failure happened.  Check BYTES_READ to recognize this situation.  */
 
 int
 read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
 
 int
 read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
@@ -2833,7 +2712,7 @@ val_print_string (struct type *elttype, const char *encoding,
   unsigned int fetchlimit;     /* Maximum number of chars to print.  */
   int bytes_read;
   gdb::unique_xmalloc_ptr<gdb_byte> buffer;    /* Dynamically growable fetch buffer.  */
   unsigned int fetchlimit;     /* Maximum number of chars to print.  */
   int bytes_read;
   gdb::unique_xmalloc_ptr<gdb_byte> buffer;    /* Dynamically growable fetch buffer.  */
-  struct gdbarch *gdbarch = get_type_arch (elttype);
+  struct gdbarch *gdbarch = elttype->arch ();
   enum bfd_endian byte_order = type_byte_order (elttype);
   int width = TYPE_LENGTH (elttype);
 
   enum bfd_endian byte_order = type_byte_order (elttype);
   int width = TYPE_LENGTH (elttype);
 
@@ -2867,8 +2746,8 @@ val_print_string (struct type *elttype, const char *encoding,
       gdb_byte *peekbuf;
 
       /* We didn't find a NUL terminator we were looking for.  Attempt
       gdb_byte *peekbuf;
 
       /* We didn't find a NUL terminator we were looking for.  Attempt
-         to peek at the next character.  If not successful, or it is not
-         a null byte, then force ellipsis to be printed.  */
+        to peek at the next character.  If not successful, or it is not
+        a null byte, then force ellipsis to be printed.  */
 
       peekbuf = (gdb_byte *) alloca (width);
 
 
       peekbuf = (gdb_byte *) alloca (width);
 
@@ -2879,8 +2758,8 @@ val_print_string (struct type *elttype, const char *encoding,
   else if ((len >= 0 && err != 0) || (len > bytes_read / width))
     {
       /* Getting an error when we have a requested length, or fetching less
   else if ((len >= 0 && err != 0) || (len > bytes_read / width))
     {
       /* Getting an error when we have a requested length, or fetching less
-         than the number of characters actually requested, always make us
-         print ellipsis.  */
+        than the number of characters actually requested, always make us
+        print ellipsis.  */
       force_ellipsis = 1;
     }
 
       force_ellipsis = 1;
     }
 
@@ -2888,10 +2767,9 @@ val_print_string (struct type *elttype, const char *encoding,
      But if we fetch something and then get an error, print the string
      and then the error message.  */
   if (err == 0 || bytes_read > 0)
      But if we fetch something and then get an error, print the string
      and then the error message.  */
   if (err == 0 || bytes_read > 0)
-    {
-      LA_PRINT_STRING (stream, elttype, buffer.get (), bytes_read / width,
-                      encoding, force_ellipsis, options);
-    }
+    current_language->printstr (stream, elttype, buffer.get (),
+                               bytes_read / width,
+                               encoding, force_ellipsis, options);
 
   if (err != 0)
     {
 
   if (err != 0)
     {
@@ -3049,34 +2927,6 @@ show_radix (const char *arg, int from_tty)
 }
 \f
 
 }
 \f
 
-static void
-set_print (const char *arg, int from_tty)
-{
-  printf_unfiltered (
-     "\"set print\" must be followed by the name of a print subcommand.\n");
-  help_list (setprintlist, "set print ", all_commands, gdb_stdout);
-}
-
-static void
-show_print (const char *args, int from_tty)
-{
-  cmd_show_list (showprintlist, from_tty, "");
-}
-
-static void
-set_print_raw (const char *arg, int from_tty)
-{
-  printf_unfiltered (
-     "\"set print raw\" must be followed by the name of a \"print raw\" subcommand.\n");
-  help_list (setprintrawlist, "set print raw ", all_commands, gdb_stdout);
-}
-
-static void
-show_print_raw (const char *args, int from_tty)
-{
-  cmd_show_list (showprintrawlist, from_tty, "");
-}
-
 /* Controls printing of vtbl's.  */
 static void
 show_vtblprint (struct ui_file *file, int from_tty,
 /* Controls printing of vtbl's.  */
 static void
 show_vtblprint (struct ui_file *file, int from_tty,
@@ -3171,6 +3021,17 @@ will be replaced with either '{...}' or '(...)' depending on the language.\n\
 Use \"unlimited\" to print the complete structure.")
   },
 
 Use \"unlimited\" to print the complete structure.")
   },
 
+  boolean_option_def {
+    "memory-tag-violations",
+    [] (value_print_options *opt) { return &opt->memory_tag_violations; },
+    show_memory_tag_violations, /* show_cmd_cb */
+    N_("Set printing of memory tag violations for pointers."),
+    N_("Show printing of memory tag violations for pointers."),
+    N_("Issue a warning when the printed value is a pointer\n\
+whose logical tag doesn't match the allocation tag of the memory\n\
+location it points to."),
+  },
+
   boolean_option_def {
     "null-stop",
     [] (value_print_options *opt) { return &opt->stop_print_at_null; },
   boolean_option_def {
     "null-stop",
     [] (value_print_options *opt) { return &opt->stop_print_at_null; },
@@ -3262,36 +3123,61 @@ make_value_print_options_def_group (value_print_options *opts)
   return {{value_print_option_defs}, opts};
 }
 
   return {{value_print_option_defs}, opts};
 }
 
-void
-_initialize_valprint (void)
+#if GDB_SELF_TEST
+
+/* Test printing of TYPE_CODE_FLAGS values.  */
+
+static void
+test_print_flags (gdbarch *arch)
 {
 {
-  cmd_list_element *cmd;
+  type *flags_type = arch_flags_type (arch, "test_type", 32);
+  type *field_type = builtin_type (arch)->builtin_uint32;
+
+  /* Value:  1010 1010
+     Fields: CCCB BAAA */
+  append_flags_type_field (flags_type, 0, 3, field_type, "A");
+  append_flags_type_field (flags_type, 3, 2, field_type, "B");
+  append_flags_type_field (flags_type, 5, 3, field_type, "C");
 
 
-  add_prefix_cmd ("print", no_class, set_print,
-                 _("Generic command for setting how things print."),
-                 &setprintlist, "set print ", 0, &setlist);
-  add_alias_cmd ("p", "print", no_class, 1, &setlist);
+  value *val = allocate_value (flags_type);
+  gdb_byte *contents = value_contents_writeable (val).data ();
+  store_unsigned_integer (contents, 4, gdbarch_byte_order (arch), 0xaa);
+
+  string_file out;
+  val_print_type_code_flags (flags_type, val, 0, &out);
+  SELF_CHECK (out.string () == "[ A=2 B=1 C=5 ]");
+}
+
+#endif
+
+void _initialize_valprint ();
+void
+_initialize_valprint ()
+{
+#if GDB_SELF_TEST
+  selftests::register_test_foreach_arch ("print-flags", test_print_flags);
+#endif
+
+  set_show_commands setshow_print_cmds
+    = add_setshow_prefix_cmd ("print", no_class,
+                             _("Generic command for setting how things print."),
+                             _("Generic command for showing print settings."),
+                             &setprintlist, &showprintlist,
+                             &setlist, &showlist);
+  add_alias_cmd ("p", setshow_print_cmds.set, no_class, 1, &setlist);
   /* Prefer set print to set prompt.  */
   /* Prefer set print to set prompt.  */
-  add_alias_cmd ("pr", "print", no_class, 1, &setlist);
-
-  add_prefix_cmd ("print", no_class, show_print,
-                 _("Generic command for showing print settings."),
-                 &showprintlist, "show print ", 0, &showlist);
-  add_alias_cmd ("p", "print", no_class, 1, &showlist);
-  add_alias_cmd ("pr", "print", no_class, 1, &showlist);
-
-  cmd = add_prefix_cmd ("raw", no_class, set_print_raw,
-                       _("\
-Generic command for setting what things to print in \"raw\" mode."),
-                       &setprintrawlist, "set print raw ", 0,
-                       &setprintlist);
-  deprecate_cmd (cmd, nullptr);
-
-  cmd = add_prefix_cmd ("raw", no_class, show_print_raw,
-                       _("Generic command for showing \"print raw\" settings."),
-                       &showprintrawlist, "show print raw ", 0,
-                       &showprintlist);
-  deprecate_cmd (cmd, nullptr);
+  add_alias_cmd ("pr", setshow_print_cmds.set, no_class, 1, &setlist);
+  add_alias_cmd ("p", setshow_print_cmds.show, no_class, 1, &showlist);
+  add_alias_cmd ("pr", setshow_print_cmds.show, no_class, 1, &showlist);
+
+  set_show_commands setshow_print_raw_cmds
+    = add_setshow_prefix_cmd
+       ("raw", no_class,
+        _("Generic command for setting what things to print in \"raw\" mode."),
+        _("Generic command for showing \"print raw\" settings."),
+        &setprintrawlist, &showprintrawlist, &setprintlist, &showprintlist);
+  deprecate_cmd (setshow_print_raw_cmds.set, nullptr);
+  deprecate_cmd (setshow_print_raw_cmds.show, nullptr);
 
   gdb::option::add_setshow_cmds_for_options
     (class_support, &user_print_options, value_print_option_defs,
 
   gdb::option::add_setshow_cmds_for_options
     (class_support, &user_print_options, value_print_option_defs,