* gdb.dwarf2/dup-psym.exp: Use prepare_for_testing_full.
[deliverable/binutils-gdb.git] / gdb / valprint.c
index b4ac4ec466d78f11514498baaf2ed3c29538b35e..fc5942da77887069a9a1e19192245711df5c8755 100644 (file)
@@ -1,8 +1,6 @@
 /* Print values for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -87,7 +85,8 @@ struct value_print_options user_print_options =
   1,                           /* static_field_print */
   1,                           /* pascal_static_field_print */
   0,                           /* raw */
-  0                            /* summary */
+  0,                           /* summary */
+  1                            /* symbol_print */
 };
 
 /* Initialize *OPTS to be a copy of the user print options.  */
@@ -221,6 +220,16 @@ show_addressprint (struct ui_file *file, int from_tty,
 {
   fprintf_filtered (file, _("Printing of addresses is %s.\n"), value);
 }
+
+static void
+show_symbol_print (struct ui_file *file, int from_tty,
+                  struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file,
+                   _("Printing of symbols when printing pointers is %s.\n"),
+                   value);
+}
+
 \f
 
 /* A helper function for val_print.  When printing in "summary" mode,
@@ -250,17 +259,9 @@ scalar_type_p (struct type *type)
     }
 }
 
-/* Helper function to check the validity of some bits of a value.
-
-   If TYPE represents some aggregate type (e.g., a structure), return 1.
-   
-   Otherwise, any of the bytes starting at OFFSET and extending for
-   TYPE_LENGTH(TYPE) bytes are invalid, print a message to STREAM and
-   return 0.  The checking is done using FUNCS.
-   
-   Otherwise, return 1.  */
+/* See its definition in value.h.  */
 
-static int
+int
 valprint_check_validity (struct ui_file *stream,
                         struct type *type,
                         int embedded_offset,
@@ -314,6 +315,361 @@ val_print_invalid_address (struct ui_file *stream)
   fprintf_filtered (stream, _("<invalid address>"));
 }
 
+/* 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.  */
+
+void
+generic_val_print (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,
+                  const struct generic_val_print_decorations *decorations)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  unsigned int i = 0;  /* Number of characters printed.  */
+  unsigned len;
+  struct type *elttype, *unresolved_elttype;
+  struct type *unresolved_type = type;
+  LONGEST val;
+  CORE_ADDR addr;
+
+  CHECK_TYPEDEF (type);
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      unresolved_elttype = TYPE_TARGET_TYPE (type);
+      elttype = check_typedef (unresolved_elttype);
+      if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0)
+       {
+          LONGEST low_bound, high_bound;
+
+          if (!get_array_bounds (type, &low_bound, &high_bound))
+            error (_("Could not determine the array high bound"));
+
+         if (options->prettyprint_arrays)
+           {
+             print_spaces_filtered (2 + 2 * recurse, stream);
+           }
+
+         fprintf_filtered (stream, "{");
+         val_print_array_elements (type, valaddr, embedded_offset,
+                                   address, stream,
+                                   recurse, original_value, options, 0);
+         fprintf_filtered (stream, "}");
+         break;
+       }
+      /* Array of unspecified length: treat like pointer to first
+        elt.  */
+      addr = address + embedded_offset;
+      goto print_unpacked_pointer;
+
+    case TYPE_CODE_MEMBERPTR:
+      val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                 original_value, options, 0, stream);
+      break;
+
+    case TYPE_CODE_PTR:
+      if (options->format && options->format != 's')
+       {
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
+         break;
+       }
+      unresolved_elttype = TYPE_TARGET_TYPE (type);
+      elttype = check_typedef (unresolved_elttype);
+       {
+         addr = unpack_pointer (type, valaddr + embedded_offset);
+       print_unpacked_pointer:
+
+         if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
+           {
+             /* Try to print what function it points to.  */
+             print_function_pointer_address (options, gdbarch, addr, stream);
+             return;
+           }
+
+         if (options->symbol_print)
+           print_address_demangle (options, gdbarch, addr, stream, demangle);
+         else if (options->addressprint)
+           fputs_filtered (paddress (gdbarch, addr), stream);
+       }
+      break;
+
+    case TYPE_CODE_REF:
+      elttype = check_typedef (TYPE_TARGET_TYPE (type));
+      if (options->addressprint)
+       {
+         CORE_ADDR addr
+           = extract_typed_address (valaddr + embedded_offset, type);
+
+         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);
+           }
+         else
+           fputs_filtered ("???", stream);
+       }
+      break;
+
+    case TYPE_CODE_ENUM:
+      if (options->format)
+       {
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
+         break;
+       }
+      len = TYPE_NFIELDS (type);
+      val = unpack_long (type, valaddr + embedded_offset);
+      for (i = 0; i < len; i++)
+       {
+         QUIT;
+         if (val == TYPE_FIELD_ENUMVAL (type, i))
+           {
+             break;
+           }
+       }
+      if (i < len)
+       {
+         fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+       }
+      else if (TYPE_FLAG_ENUM (type))
+       {
+         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);
+         for (i = 0; i < len; ++i)
+           {
+             QUIT;
+
+             if ((val & TYPE_FIELD_ENUMVAL (type, i)) != 0)
+               {
+                 if (!first)
+                   fputs_filtered (" | ", stream);
+                 first = 0;
+
+                 val &= ~TYPE_FIELD_ENUMVAL (type, i);
+                 fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+               }
+           }
+
+         if (first || val != 0)
+           {
+             if (!first)
+               fputs_filtered (" | ", stream);
+             fputs_filtered ("unknown: ", stream);
+             print_longest (stream, 'd', 0, val);
+           }
+
+         fputs_filtered (")", stream);
+       }
+      else
+       print_longest (stream, 'd', 0, val);
+      break;
+
+    case TYPE_CODE_FLAGS:
+      if (options->format)
+       val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                   original_value, options, 0, stream);
+      else
+       val_print_type_code_flags (type, valaddr + embedded_offset,
+                                  stream);
+      break;
+
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_METHOD:
+      if (options->format)
+       {
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
+         break;
+       }
+      /* 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);
+      break;
+
+    case TYPE_CODE_BOOL:
+      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, valaddr, embedded_offset,
+                                     original_value, &opts, 0, stream);
+       }
+      else
+       {
+         val = unpack_long (type, valaddr + embedded_offset);
+         if (val == 0)
+           fputs_filtered (decorations->false_name, stream);
+         else if (val == 1)
+           fputs_filtered (decorations->true_name, stream);
+         else
+           print_longest (stream, 'd', 0, val);
+       }
+      break;
+
+    case TYPE_CODE_RANGE:
+      /* FIXME: create_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:
+      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, valaddr, embedded_offset,
+                                     original_value, &opts, 0, stream);
+       }
+      else
+       val_print_type_code_int (type, valaddr + embedded_offset, stream);
+      break;
+
+    case TYPE_CODE_CHAR:
+      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, valaddr, embedded_offset,
+                                     original_value, &opts, 0, stream);
+       }
+      else
+       {
+         val = unpack_long (type, valaddr + embedded_offset);
+         if (TYPE_UNSIGNED (type))
+           fprintf_filtered (stream, "%u", (unsigned int) val);
+         else
+           fprintf_filtered (stream, "%d", (int) val);
+         fputs_filtered (" ", stream);
+         LA_PRINT_CHAR (val, unresolved_type, stream);
+       }
+      break;
+
+    case TYPE_CODE_FLT:
+      if (options->format)
+       {
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
+       }
+      else
+       {
+         print_floating (valaddr + embedded_offset, type, stream);
+       }
+      break;
+
+    case TYPE_CODE_DECFLOAT:
+      if (options->format)
+       val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                   original_value, options, 0, stream);
+      else
+       print_decimal_floating (valaddr + embedded_offset,
+                               type, stream);
+      break;
+
+    case TYPE_CODE_VOID:
+      fputs_filtered (decorations->void_name, stream);
+      break;
+
+    case TYPE_CODE_ERROR:
+      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
+      break;
+
+    case TYPE_CODE_UNDEF:
+      /* This happens (without TYPE_FLAG_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.  */
+      fprintf_filtered (stream, _("<incomplete type>"));
+      break;
+
+    case TYPE_CODE_COMPLEX:
+      fprintf_filtered (stream, "%s", decorations->complex_prefix);
+      if (options->format)
+       val_print_scalar_formatted (TYPE_TARGET_TYPE (type),
+                                   valaddr, embedded_offset,
+                                   original_value, options, 0, stream);
+      else
+       print_floating (valaddr + embedded_offset,
+                       TYPE_TARGET_TYPE (type),
+                       stream);
+      fprintf_filtered (stream, "%s", decorations->complex_infix);
+      if (options->format)
+       val_print_scalar_formatted (TYPE_TARGET_TYPE (type),
+                                   valaddr,
+                                   embedded_offset
+                                   + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+                                   original_value,
+                                   options, 0, stream);
+      else
+       print_floating (valaddr + embedded_offset
+                       + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+                       TYPE_TARGET_TYPE (type),
+                       stream);
+      fprintf_filtered (stream, "%s", decorations->complex_suffix);
+      break;
+
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_METHODPTR:
+    default:
+      error (_("Unhandled type code %d in symbol table."),
+            TYPE_CODE (type));
+    }
+  gdb_flush (stream);
+}
+
 /* Print using the given LANGUAGE the data of type TYPE located at
    VALADDR + EMBEDDED_OFFSET (within GDB), which came from the
    inferior at address ADDRESS + EMBEDDED_OFFSET, onto stdio stream
@@ -332,12 +688,9 @@ val_print_invalid_address (struct ui_file *stream)
 
    RECURSE indicates the amount of indentation to supply before
    continuation lines; this amount is roughly twice the value of
-   RECURSE.
-
-   If the data is printed as a string, returns the number of string
-   characters printed.  */
+   RECURSE.  */
 
-int
+void
 val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
           CORE_ADDR address, struct ui_file *stream, int recurse,
           const struct value *val,
@@ -363,11 +716,11 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
     {
       fprintf_filtered (stream, _("<incomplete type>"));
       gdb_flush (stream);
-      return (0);
+      return;
     }
 
   if (!valprint_check_validity (stream, real_type, embedded_offset, val))
-    return 0;
+    return;
 
   if (!options->raw)
     {
@@ -375,7 +728,7 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
                                      address, stream, recurse,
                                      val, options, language);
       if (ret)
-       return ret;
+       return;
     }
 
   /* Handle summary mode.  If the value is a scalar, print it;
@@ -383,19 +736,17 @@ val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
   if (options->summary && !scalar_type_p (type))
     {
       fprintf_filtered (stream, "...");
-      return 0;
+      return;
     }
 
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
-      ret = language->la_val_print (type, valaddr, embedded_offset, address,
-                                   stream, recurse, val,
-                                   &local_opts);
+      language->la_val_print (type, valaddr, embedded_offset, address,
+                             stream, recurse, val,
+                             &local_opts);
     }
   if (except.reason < 0)
     fprintf_filtered (stream, _("<error reading variable>"));
-
-  return ret;
 }
 
 /* Check whether the value VAL is printable.  Return 1 if it is;
@@ -434,19 +785,16 @@ value_check_printable (struct value *val, struct ui_file *stream,
 /* Print using the given LANGUAGE the value VAL onto stream STREAM according
    to OPTIONS.
 
-   If the data are a string pointer, returns the number of string characters
-   printed.
-
    This is a preferable interface to val_print, above, because it uses
    GDB's value mechanism.  */
 
-int
+void
 common_val_print (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 0;
+    return;
 
   if (language->la_language == language_ada)
     /* The value might have a dynamic type, which would cause trouble
@@ -455,24 +803,21 @@ common_val_print (struct value *val, struct ui_file *stream, int recurse,
        get a fixed representation of our value.  */
     val = ada_to_fixed_value (val);
 
-  return val_print (value_type (val), value_contents_for_printing (val),
-                   value_embedded_offset (val), value_address (val),
-                   stream, recurse,
-                   val, options, language);
+  val_print (value_type (val), value_contents_for_printing (val),
+            value_embedded_offset (val), value_address (val),
+            stream, recurse,
+            val, options, language);
 }
 
 /* Print on stream STREAM the value VAL according to OPTIONS.  The value
-   is printed using the current_language syntax.
+   is printed using the current_language syntax.  */
 
-   If the object printed is a string pointer, return the number of string
-   bytes printed.  */
-
-int
+void
 value_print (struct value *val, struct ui_file *stream,
             const struct value_print_options *options)
 {
   if (!value_check_printable (val, stream, options))
-    return 0;
+    return;
 
   if (!options->raw)
     {
@@ -484,10 +829,10 @@ value_print (struct value *val, struct ui_file *stream,
                                        val, options, current_language);
 
       if (r)
-       return r;
+       return;
     }
 
-  return LA_VALUE_PRINT (val, stream, options);
+  LA_VALUE_PRINT (val, stream, options);
 }
 
 /* Called by various <lang>_val_print routines to print
@@ -547,6 +892,7 @@ val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
        }
     }
   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
@@ -554,7 +900,6 @@ val_print_type_code_flags (struct type *type, const gdb_byte *valaddr,
 
    This is how the elements of an array or structure are printed
    with a format.  */
-}
 
 void
 val_print_scalar_formatted (struct type *type,
@@ -1163,6 +1508,31 @@ print_char_chars (struct ui_file *stream, struct type *type,
     }
 }
 
+/* Print function pointer with inferior address ADDRESS onto stdio
+   stream STREAM.  */
+
+void
+print_function_pointer_address (const struct value_print_options *options,
+                               struct gdbarch *gdbarch,
+                               CORE_ADDR address,
+                               struct ui_file *stream)
+{
+  CORE_ADDR func_addr
+    = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
+                                         &current_target);
+
+  /* If the function pointer is represented by a description, print
+     the address of the description.  */
+  if (options->addressprint && func_addr != address)
+    {
+      fputs_filtered ("@", stream);
+      fputs_filtered (paddress (gdbarch, address), stream);
+      fputs_filtered (": ", stream);
+    }
+  print_address_demangle (options, gdbarch, func_addr, stream, demangle);
+}
+
+
 /* Print on STREAM using the given OPTIONS the index for the element
    at INDEX of an array whose index type is INDEX_TYPE.  */
     
@@ -1993,10 +2363,6 @@ val_print_string (struct type *elttype, const char *encoding,
      and then the error message.  */
   if (errcode == 0 || bytes_read > 0)
     {
-      if (options->addressprint)
-       {
-         fputs_filtered (" ", stream);
-       }
       LA_PRINT_STRING (stream, elttype, buffer, bytes_read / width,
                       encoding, force_ellipsis, options);
     }
@@ -2005,13 +2371,13 @@ val_print_string (struct type *elttype, const char *encoding,
     {
       if (errcode == EIO)
        {
-         fprintf_filtered (stream, " <Address ");
+         fprintf_filtered (stream, "<Address ");
          fputs_filtered (paddress (gdbarch, addr), stream);
          fprintf_filtered (stream, " out of bounds>");
        }
       else
        {
-         fprintf_filtered (stream, " <Error reading address ");
+         fprintf_filtered (stream, "<Error reading address ");
          fputs_filtered (paddress (gdbarch, addr), stream);
          fprintf_filtered (stream, ": %s>", safe_strerror (errcode));
        }
@@ -2246,6 +2612,14 @@ Show printing of addresses."), NULL,
                           show_addressprint,
                           &setprintlist, &showprintlist);
 
+  add_setshow_boolean_cmd ("symbol", class_support,
+                          &user_print_options.symbol_print, _("\
+Set printing of symbol names when printing pointers."), _("\
+Show printing of symbol names when printing pointers."),
+                          NULL, NULL,
+                          show_symbol_print,
+                          &setprintlist, &showprintlist);
+
   add_setshow_zuinteger_cmd ("input-radix", class_support, &input_radix_1,
                             _("\
 Set default input radix for entering numbers."), _("\
This page took 0.030608 seconds and 4 git commands to generate.