Allow resetting an empty inferior-tty
[deliverable/binutils-gdb.git] / gdb / valprint.c
index 753c2a148ee2d1ebb4073e9498911b454b68d75f..6896da2b624d17f679ef89f2a7de6a2a21659089 100644 (file)
@@ -1,6 +1,6 @@
 /* Print values for GDB, the GNU debugger.
 
-   Copyright (C) 1986-2015 Free Software Foundation, Inc.
+   Copyright (C) 1986-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -98,6 +98,10 @@ static void set_output_radix (char *, int, struct cmd_list_element *);
 
 static void set_output_radix_1 (int, unsigned);
 
+static void val_print_type_code_flags (struct type *type,
+                                      const gdb_byte *valaddr,
+                                      struct ui_file *stream);
+
 void _initialize_valprint (void);
 
 #define PRINT_MAX_DEFAULT 200  /* Start print_max off at this value.  */
@@ -299,7 +303,7 @@ val_print_scalar_type_p (struct type *type)
 int
 valprint_check_validity (struct ui_file *stream,
                         struct type *type,
-                        int embedded_offset,
+                        LONGEST embedded_offset,
                         const struct value *val)
 {
   type = check_typedef (type);
@@ -331,8 +335,22 @@ valprint_check_validity (struct ui_file *stream,
       if (value_bits_synthetic_pointer (val, TARGET_CHAR_BIT * embedded_offset,
                                        TARGET_CHAR_BIT * TYPE_LENGTH (type)))
        {
-         fputs_filtered (_("<synthetic pointer>"), stream);
-         return 0;
+         const int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;
+         int ref_is_addressable = 0;
+
+         if (is_ref)
+           {
+             const struct value *deref_val = coerce_ref_if_computed (val);
+
+             if (deref_val != NULL)
+               ref_is_addressable = value_lval_const (deref_val) == lval_memory;
+           }
+
+         if (!is_ref || !ref_is_addressable)
+           fputs_filtered (_("<synthetic pointer>"), stream);
+
+         /* C++ references should be valid even if they're synthetic.  */
+         return is_ref;
        }
 
       if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
@@ -403,10 +421,12 @@ print_unpacked_pointer (struct type *type, struct type *elttype,
 
 static void
 generic_val_print_array (struct type *type, const gdb_byte *valaddr,
-                  int embedded_offset, CORE_ADDR address,
-                  struct ui_file *stream, int recurse,
-                  const struct value *original_value,
-                  const struct value_print_options *options)
+                        int embedded_offset, CORE_ADDR address,
+                        struct ui_file *stream, int recurse,
+                        const struct value *original_value,
+                        const struct value_print_options *options,
+                        const struct
+                            generic_val_print_decorations *decorations)
 {
   struct type *unresolved_elttype = TYPE_TARGET_TYPE (type);
   struct type *elttype = check_typedef (unresolved_elttype);
@@ -423,11 +443,11 @@ generic_val_print_array (struct type *type, const gdb_byte *valaddr,
          print_spaces_filtered (2 + 2 * recurse, stream);
        }
 
-      fprintf_filtered (stream, "{");
+      fputs_filtered (decorations->array_start, stream);
       val_print_array_elements (type, valaddr, embedded_offset,
                                address, stream,
                                recurse, original_value, options, 0);
-      fprintf_filtered (stream, "}");
+      fputs_filtered (decorations->array_end, stream);
     }
   else
     {
@@ -478,6 +498,42 @@ generic_val_print_memberptr (struct type *type, const gdb_byte *valaddr,
                              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)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+
+  if (address_buffer != NULL)
+    {
+      CORE_ADDR address
+       = extract_typed_address (address_buffer + embedded_offset, type);
+
+      fprintf_filtered (stream, "@");
+      fputs_filtered (paddress (gdbarch, address), stream);
+    }
+  /* Else: we have a non-addressable value, such as a DW_AT_const_value.  */
+}
+
+/* If VAL is addressable, return the value contents buffer of a value that
+   represents a pointer to VAL.  Otherwise return NULL.  */
+
+static const gdb_byte *
+get_value_addr_contents (struct value *deref_val)
+{
+  gdb_assert (deref_val != NULL);
+
+  if (value_lval_const (deref_val) == lval_memory)
+    return value_contents_for_printing_const (value_addr (deref_val));
+  else
+    {
+      /* We have a non-addressable value, such as a DW_AT_const_value.  */
+      return NULL;
+    }
+}
+
 /* generic_val_print helper for TYPE_CODE_REF.  */
 
 static void
@@ -486,68 +542,74 @@ generic_val_print_ref (struct type *type, const gdb_byte *valaddr,
                       const struct value *original_value,
                       const struct value_print_options *options)
 {
-  struct gdbarch *gdbarch = get_type_arch (type);
   struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type));
+  struct value *deref_val = NULL;
+  const int value_is_synthetic
+    = value_bits_synthetic_pointer (original_value,
+                                   TARGET_CHAR_BIT * embedded_offset,
+                                   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;
+
+  if (must_coerce_ref && type_is_defined)
+    {
+      deref_val = coerce_ref_if_computed (original_value);
+
+      if (deref_val != NULL)
+       {
+         /* More complicated computed references are not supported.  */
+         gdb_assert (embedded_offset == 0);
+       }
+      else
+       deref_val = value_at (TYPE_TARGET_TYPE (type),
+                             unpack_pointer (type, valaddr + embedded_offset));
+    }
+  /* Else, original_value isn't a synthetic reference or we don't have to print
+     the reference's contents.
+
+     Notice that for references to TYPE_CODE_STRUCT, 'set print object on' will
+     cause original_value to be a not_lval instead of an lval_computed,
+     which will make value_bits_synthetic_pointer return false.
+     This happens because if options->objectprint is true, c_value_print will
+     overwrite original_value's contents with the result of coercing
+     the reference through value_addr, and then set its type back to
+     TYPE_CODE_REF.  In that case we don't have to coerce the reference again;
+     we can simply treat it as non-synthetic and move on.  */
 
   if (options->addressprint)
     {
-      CORE_ADDR addr
-       = extract_typed_address (valaddr + embedded_offset, type);
+      const gdb_byte *address = (value_is_synthetic && type_is_defined
+                                ? get_value_addr_contents (deref_val)
+                                : valaddr);
+
+      print_ref_address (type, address, embedded_offset, stream);
 
-      fprintf_filtered (stream, "@");
-      fputs_filtered (paddress (gdbarch, addr), stream);
       if (options->deref_ref)
        fputs_filtered (": ", stream);
     }
-  /* De-reference the reference.  */
+
   if (options->deref_ref)
     {
-      if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
-       {
-         struct value *deref_val;
-
-         deref_val = coerce_ref_if_computed (original_value);
-         if (deref_val != NULL)
-           {
-             /* More complicated computed references are not supported.  */
-             gdb_assert (embedded_offset == 0);
-           }
-         else
-           deref_val = value_at (TYPE_TARGET_TYPE (type),
-                                 unpack_pointer (type,
-                                                 (valaddr
-                                                  + embedded_offset)));
-
-         common_val_print (deref_val, stream, recurse, options,
-                           current_language);
-       }
+      if (type_is_defined)
+       common_val_print (deref_val, stream, recurse, options,
+                         current_language);
       else
        fputs_filtered ("???", stream);
     }
 }
 
-/* generic_val_print helper for TYPE_CODE_ENUM.  */
+/* Helper function for generic_val_print_enum.
+   This is also used to print enums in TYPE_CODE_FLAGS values.  */
 
 static void
-generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
-                       int embedded_offset, struct ui_file *stream,
-                       const struct value *original_value,
-                       const struct value_print_options *options)
+generic_val_print_enum_1 (struct type *type, LONGEST val,
+                         struct ui_file *stream)
 {
   unsigned int i;
   unsigned int len;
-  LONGEST val;
-  struct gdbarch *gdbarch = get_type_arch (type);
-  int unit_size = gdbarch_addressable_memory_unit_size (gdbarch);
 
-  if (options->format)
-    {
-      val_print_scalar_formatted (type, valaddr, embedded_offset,
-                                 original_value, options, 0, stream);
-      return;
-    }
   len = TYPE_NFIELDS (type);
-  val = unpack_long (type, valaddr + embedded_offset * unit_size);
   for (i = 0; i < len; i++)
     {
       QUIT;
@@ -597,6 +659,29 @@ generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
     print_longest (stream, 'd', 0, val);
 }
 
+/* generic_val_print helper for TYPE_CODE_ENUM.  */
+
+static void
+generic_val_print_enum (struct type *type, const gdb_byte *valaddr,
+                       int embedded_offset, struct ui_file *stream,
+                       const struct value *original_value,
+                       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)
+    {
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, options, 0, stream);
+      return;
+    }
+  val = unpack_long (type, valaddr + embedded_offset * unit_size);
+
+  generic_val_print_enum_1 (type, val, stream);
+}
+
 /* generic_val_print helper for TYPE_CODE_FLAGS.  */
 
 static void
@@ -835,7 +920,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
     {
     case TYPE_CODE_ARRAY:
       generic_val_print_array (type, valaddr, embedded_offset, address, stream,
-                              recurse, original_value, options);
+                              recurse, original_value, options, decorations);
       break;
 
     case TYPE_CODE_MEMBERPTR:
@@ -957,7 +1042,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
    RECURSE.  */
 
 void
-val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
+val_print (struct type *type, const gdb_byte *valaddr, LONGEST embedded_offset,
           CORE_ADDR address, struct ui_file *stream, int recurse,
           const struct value *val,
           const struct value_print_options *options,
@@ -1162,26 +1247,51 @@ val_print_type_code_int (struct type *type, const gdb_byte *valaddr,
     }
 }
 
-void
+static void
 val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
                           struct ui_file *stream)
 {
   ULONGEST val = unpack_long (type, valaddr);
-  int bitpos, nfields = TYPE_NFIELDS (type);
+  int field, nfields = TYPE_NFIELDS (type);
+  struct gdbarch *gdbarch = get_type_arch (type);
+  struct type *bool_type = builtin_type (gdbarch)->builtin_bool;
 
-  fputs_filtered ("[ ", stream);
-  for (bitpos = 0; bitpos < nfields; bitpos++)
+  fputs_filtered ("[", stream);
+  for (field = 0; field < nfields; field++)
     {
-      if (TYPE_FIELD_BITPOS (type, bitpos) != -1
-         && (val & ((ULONGEST)1 << bitpos)))
+      if (TYPE_FIELD_NAME (type, field)[0] != '\0')
        {
-         if (TYPE_FIELD_NAME (type, bitpos))
-           fprintf_filtered (stream, "%s ", TYPE_FIELD_NAME (type, bitpos));
+         struct type *field_type = TYPE_FIELD_TYPE (type, field);
+
+         if (field_type == bool_type
+             /* We require boolean types here to be one bit wide.  This is a
+                problematic place to notify the user of an internal error
+                though.  Instead just fall through and print the field as an
+                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));
+           }
          else
-           fprintf_filtered (stream, "#%d ", bitpos);
+           {
+             unsigned field_len = TYPE_FIELD_BITSIZE (type, field);
+             ULONGEST field_val
+               = val >> (TYPE_FIELD_BITPOS (type, field) - 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)
+               generic_val_print_enum_1 (field_type, field_val, stream);
+             else
+               print_longest (stream, 'd', 0, field_val);
+           }
        }
     }
-  fputs_filtered ("]", stream);
+  fputs_filtered (" ]", stream);
 }
 
 /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
@@ -1193,7 +1303,7 @@ val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
 
 void
 val_print_scalar_formatted (struct type *type,
-                           const gdb_byte *valaddr, int embedded_offset,
+                           const gdb_byte *valaddr, LONGEST embedded_offset,
                            const struct value *val,
                            const struct value_print_options *options,
                            int size,
@@ -1855,7 +1965,7 @@ maybe_print_array_index (struct type *index_type, LONGEST index,
 
 void
 val_print_array_elements (struct type *type,
-                         const gdb_byte *valaddr, int embedded_offset,
+                         const gdb_byte *valaddr, LONGEST embedded_offset,
                          CORE_ADDR address, struct ui_file *stream,
                          int recurse,
                          const struct value *val,
This page took 0.030522 seconds and 4 git commands to generate.