Introduce ada_value_print_num
[deliverable/binutils-gdb.git] / gdb / ada-valprint.c
index 714b6259ec0e6edd8b98b072aab26798aac387dd..4b89473fef39cbb6407ad837e8afcc299da13d71 100644 (file)
@@ -1,6 +1,6 @@
 /* Support for printing Ada values for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include <ctype.h>
-#include "symtab.h"
 #include "gdbtypes.h"
 #include "expression.h"
 #include "value.h"
-#include "demangle.h"
 #include "valprint.h"
 #include "language.h"
 #include "annotate.h"
 #include "ada-lang.h"
-#include "c-lang.h"
-#include "infcall.h"
-#include "objfiles.h"
 #include "target-float.h"
 #include "cli/cli-style.h"
+#include "gdbarch.h"
 
 static int print_field_values (struct type *, const gdb_byte *,
                               int,
@@ -422,7 +418,8 @@ ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream)
        }
       if (i < len)
        {
-         fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
+         fputs_styled (ada_enum_name (TYPE_FIELD_NAME (type, i)),
+                       variable_name_style.style (), stream);
        }
       else
        {
@@ -480,7 +477,7 @@ printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
          unsigned int length, int force_ellipses, int type_len,
          const struct value_print_options *options)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype));
+  enum bfd_endian byte_order = type_byte_order (elttype);
   unsigned int i;
   unsigned int things_printed = 0;
   int in_quotes = 0;
@@ -723,7 +720,7 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr,
                      struct value *original_value,
                      const struct value_print_options *options)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+  enum bfd_endian byte_order = type_byte_order (type);
   struct type *elttype = TYPE_TARGET_TYPE (type);
   unsigned int eltlen;
   unsigned int len;
@@ -765,16 +762,14 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr,
    thin pointers, etc).  */
 
 static void
-ada_val_print_gnat_array (struct type *type, const gdb_byte *valaddr,
-                         int offset, CORE_ADDR address,
+ada_val_print_gnat_array (struct value *val,
                          struct ui_file *stream, int recurse,
-                         struct value *original_value,
                          const struct value_print_options *options)
 {
-  struct value *mark = value_mark ();
-  struct value *val;
+  scoped_value_mark free_values;
+
+  struct type *type = ada_check_typedef (value_type (val));
 
-  val = value_from_contents_and_address (type, valaddr + offset, address);
   /* If this is a reference, coerce it now.  This helps taking care
      of the case where ADDRESS is meaningless because original_value
      was not an lval.  */
@@ -789,11 +784,8 @@ ada_val_print_gnat_array (struct type *type, const gdb_byte *valaddr,
       fprintf_filtered (stream, "0x0");
     }
   else
-    val_print (value_type (val),
-              value_embedded_offset (val), value_address (val),
-              stream, recurse, val, options,
-              language_def (language_ada));
-  value_free_to_mark (mark);
+    common_val_print (val, stream, recurse, options,
+                     language_def (language_ada));
 }
 
 /* Implement Ada val_print'ing for the case where TYPE is
@@ -822,6 +814,26 @@ ada_val_print_ptr (struct type *type, const gdb_byte *valaddr,
     }
 }
 
+/* Implement Ada value_print'ing for the case where TYPE is a
+   TYPE_CODE_PTR.  */
+
+static void
+ada_value_print_ptr (struct value *val,
+                    struct ui_file *stream, int recurse,
+                    const struct value_print_options *options)
+{
+  common_val_print (val, stream, recurse, options, language_def (language_c));
+
+  struct type *type = ada_check_typedef (value_type (val));
+  if (ada_is_tag_type (type))
+    {
+      const char *name = ada_tag_name (val);
+
+      if (name != NULL)
+       fprintf_filtered (stream, " (%s)", name);
+    }
+}
+
 /* Implement Ada val_print'ing for the case where TYPE is
    a TYPE_CODE_INT or TYPE_CODE_RANGE.  */
 
@@ -925,6 +937,88 @@ ada_val_print_num (struct type *type, const gdb_byte *valaddr,
     }
 }
 
+/* Implement Ada val_print'ing for the case where TYPE is
+   a TYPE_CODE_INT or TYPE_CODE_RANGE.  */
+
+static void
+ada_value_print_num (struct value *val, struct ui_file *stream, int recurse,
+                    const struct value_print_options *options)
+{
+  struct type *type = ada_check_typedef (value_type (val));
+  const gdb_byte *valaddr = value_contents_for_printing (val);
+
+  if (ada_is_fixed_point_type (type))
+    {
+      struct value *scale = ada_scaling_factor (type);
+      val = value_cast (value_type (scale), val);
+      val = value_binop (val, scale, BINOP_MUL);
+
+      const char *fmt = TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g";
+      std::string str
+       = target_float_to_string (value_contents (val), value_type (val), fmt);
+      fputs_filtered (str.c_str (), stream);
+      return;
+    }
+  else if (TYPE_CODE (type) == TYPE_CODE_RANGE
+          && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ENUM
+              || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_BOOL
+              || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CHAR))
+    {
+      /* For enum-valued ranges, we want to recurse, because we'll end
+        up printing the constant's name rather than its numeric
+        value.  Character and fixed-point types are also printed
+        differently, so recuse for those as well.  */
+      struct type *target_type = TYPE_TARGET_TYPE (type);
+      val = value_cast (target_type, val);
+      common_val_print (val, stream, recurse + 1, options,
+                       language_def (language_ada));
+      return;
+    }
+  else
+    {
+      int format = (options->format ? options->format
+                   : options->output_format);
+
+      if (format)
+       {
+         struct value_print_options opts = *options;
+
+         opts.format = format;
+         value_print_scalar_formatted (val, &opts, 0, stream);
+       }
+      else if (ada_is_system_address_type (type))
+       {
+         /* FIXME: We want to print System.Address variables using
+            the same format as for any access type.  But for some
+            reason GNAT encodes the System.Address type as an int,
+            so we have to work-around this deficiency by handling
+            System.Address values as a special case.  */
+
+         struct gdbarch *gdbarch = get_type_arch (type);
+         struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+         CORE_ADDR addr = extract_typed_address (valaddr, ptr_type);
+
+         fprintf_filtered (stream, "(");
+         type_print (type, "", stream, -1);
+         fprintf_filtered (stream, ") ");
+         fputs_filtered (paddress (gdbarch, addr), stream);
+       }
+      else
+       {
+         value_print_scalar_formatted (val, options, 0, stream);
+         if (ada_is_character_type (type))
+           {
+             LONGEST c;
+
+             fputs_filtered (" ", stream);
+             c = unpack_long (type, valaddr);
+             ada_printchar (c, type, stream);
+           }
+       }
+      return;
+    }
+}
+
 /* Implement Ada val_print'ing for the case where TYPE is
    a TYPE_CODE_ENUM.  */
 
@@ -960,9 +1054,11 @@ ada_val_print_enum (struct type *type, const gdb_byte *valaddr,
       const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i));
 
       if (name[0] == '\'')
-       fprintf_filtered (stream, "%ld %s", (long) val, name);
+       fprintf_filtered (stream, "%ld %ps", (long) val,
+                         styled_string (variable_name_style.style (),
+                                        name));
       else
-       fputs_filtered (name, stream);
+       fputs_styled (name, variable_name_style.style (), stream);
     }
   else
     print_longest (stream, 'd', 0, val);
@@ -1136,9 +1232,10 @@ ada_val_print_1 (struct type *type,
       || (ada_is_constrained_packed_array_type (type)
          && TYPE_CODE (type) != TYPE_CODE_PTR))
     {
-      ada_val_print_gnat_array (type, valaddr, offset, address,
-                               stream, recurse, original_value,
-                               options);
+      struct value *val = value_from_contents_and_address (type,
+                                                          valaddr + offset,
+                                                          address);
+      ada_val_print_gnat_array (val, stream, recurse, options);
       return;
     }
 
@@ -1223,6 +1320,110 @@ ada_val_print (struct type *type,
     }
 }
 
+/* See the comment on ada_value_print.  This function differs in that
+   it does not catch evaluation errors (leaving that to
+   ada_value_print).  */
+
+static void
+ada_value_print_1 (struct value *val, struct ui_file *stream, int recurse,
+                  const struct value_print_options *options)
+{
+  struct type *type = ada_check_typedef (value_type (val));
+
+  if (ada_is_array_descriptor_type (type)
+      || (ada_is_constrained_packed_array_type (type)
+         && TYPE_CODE (type) != TYPE_CODE_PTR))
+    {
+      ada_val_print_gnat_array (val, stream, recurse, options);
+      return;
+    }
+
+  val = ada_to_fixed_value (val);
+  type = value_type (val);
+  struct type *saved_type = type;
+
+  const gdb_byte *valaddr = value_contents_for_printing (val);
+  CORE_ADDR address = value_address (val);
+  type = ada_check_typedef (resolve_dynamic_type (type, valaddr, address));
+  if (type != saved_type)
+    {
+      val = value_copy (val);
+      deprecated_set_value_type (val, type);
+    }
+
+  switch (TYPE_CODE (type))
+    {
+    default:
+      common_val_print (val, stream, recurse, options,
+                       language_def (language_c));
+      break;
+
+    case TYPE_CODE_PTR:
+      ada_value_print_ptr (val, stream, recurse, options);
+      break;
+
+    case TYPE_CODE_INT:
+    case TYPE_CODE_RANGE:
+      ada_value_print_num (val, stream, recurse, options);
+      break;
+
+    case TYPE_CODE_ENUM:
+      ada_val_print_enum (type, valaddr, 0, 0,
+                         address, stream, recurse, val,
+                         options);
+      break;
+
+    case TYPE_CODE_FLT:
+      if (options->format)
+       {
+         common_val_print (val, stream, recurse, options,
+                           language_def (language_c));
+         break;
+       }
+
+      ada_print_floating (valaddr, type, stream);
+      break;
+
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_STRUCT:
+      ada_val_print_struct_union (type, valaddr, 0, 0,
+                                 address, stream, recurse,
+                                 val, options);
+      break;
+
+    case TYPE_CODE_ARRAY:
+      ada_val_print_array (type, valaddr, 0, 0,
+                          address, stream, recurse, val,
+                          options);
+      return;
+
+    case TYPE_CODE_REF:
+      ada_val_print_ref (type, valaddr, 0, 0,
+                        address, stream, recurse, val,
+                        options);
+      break;
+    }
+}
+
+/* See ada-lang.h.  */
+
+void
+ada_value_print_inner (struct value *val, struct ui_file *stream,
+                      int recurse,
+                      const struct value_print_options *options)
+{
+  try
+    {
+      ada_value_print_1 (val, stream, recurse, options);
+    }
+  catch (const gdb_exception_error &except)
+    {
+      fprintf_styled (stream, metadata_style.style (),
+                     _("<error reading variable: %s>"),
+                     except.what ());
+    }
+}
+
 void
 ada_value_print (struct value *val0, struct ui_file *stream,
                 const struct value_print_options *options)
This page took 0.027287 seconds and 4 git commands to generate.