* gdbarch.sh (make_corefile_notes): New architecture callback.
[deliverable/binutils-gdb.git] / gdb / c-valprint.c
index 7213cf3a7745f8181e0fed457a7733a5fade8d8f..82551e9dc93173bf20da0ea4091b31b664fe8b61 100644 (file)
@@ -1,8 +1,7 @@
 /* Support for printing C values for GDB, the GNU debugger.
 
-   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1986, 1988-1989, 1991-2001, 2003, 2005-2012 Free
+   Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -142,13 +141,9 @@ c_textual_element_type (struct type *type, char format)
   return 0;
 }
 
-
-/* Print data of type TYPE located at VALADDR (within GDB), which came
-   from the inferior at address ADDRESS, onto stdio stream STREAM
-   according to OPTIONS.  The data at VALADDR is in target byte order.
-
-   If the data are a string pointer, returns the number of string
-   characters printed.  */
+/* See val_print for a description of the various parameters of this
+   function; they are identical.  The semantics of the return value is
+   also identical to val_print.  */
 
 int
 c_val_print (struct type *type, const gdb_byte *valaddr,
@@ -191,6 +186,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
             long as the entire array is valid.  */
           if (c_textual_element_type (unresolved_elttype,
                                      options->format)
+             && value_bytes_available (original_value, embedded_offset,
+                                       TYPE_LENGTH (type))
              && value_bits_valid (original_value,
                                   TARGET_CHAR_BIT * embedded_offset,
                                   TARGET_CHAR_BIT * TYPE_LENGTH (type)))
@@ -233,24 +230,23 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
                {
                  i = 0;
                }
-             val_print_array_elements (type, valaddr + embedded_offset,
-                                       address + embedded_offset,
-                                       stream, recurse,
-                                       original_value, options, i);
+             val_print_array_elements (type, valaddr, embedded_offset,
+                                       address, stream,
+                                       recurse, original_value, options, i);
              fprintf_filtered (stream, "}");
            }
          break;
        }
       /* Array of unspecified length: treat like pointer to first
         elt.  */
-      addr = address;
+      addr = address + embedded_offset;
       goto print_unpacked_pointer;
 
     case TYPE_CODE_MEMBERPTR:
       if (options->format)
        {
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 options, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
          break;
        }
       cp_print_class_member (valaddr + embedded_offset, type, stream, "&");
@@ -263,8 +259,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
     case TYPE_CODE_PTR:
       if (options->format && options->format != 's')
        {
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 options, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
          break;
        }
       if (options->vtblprint && cp_is_vtbl_ptr_type (type))
@@ -383,10 +379,19 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
        {
          if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
            {
-             struct value *deref_val =
-               value_at
-               (TYPE_TARGET_TYPE (type),
-                unpack_pointer (type, valaddr + embedded_offset));
+             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);
@@ -404,7 +409,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
        }
       /* Fall through.  */
     case TYPE_CODE_STRUCT:
-      /*FIXME: Abstract this away */
+      /*FIXME: Abstract this away */
       if (options->vtblprint && cp_is_vtbl_ptr_type (type))
        {
          /* Print the unmangled name if desired.  */
@@ -433,8 +438,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
     case TYPE_CODE_ENUM:
       if (options->format)
        {
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 options, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
          break;
        }
       len = TYPE_NFIELDS (type);
@@ -451,16 +456,47 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
        {
          fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
        }
-      else
+      else if (TYPE_FLAG_ENUM (type))
        {
-         print_longest (stream, 'd', 0, val);
+         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_BITPOS (type, i)) != 0)
+               {
+                 if (!first)
+                   fputs_filtered (" | ", stream);
+                 first = 0;
+
+                 val &= ~TYPE_FIELD_BITPOS (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)
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 options, 0, stream);
+       val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                   original_value, options, 0, stream);
       else
        val_print_type_code_flags (type, valaddr + embedded_offset,
                                   stream);
@@ -470,8 +506,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
     case TYPE_CODE_METHOD:
       if (options->format)
        {
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 options, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
          break;
        }
       /* FIXME, we should consider, at least for ANSI C language,
@@ -490,8 +526,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
          struct value_print_options opts = *options;
          opts.format = (options->format ? options->format
                         : options->output_format);
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 &opts, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, &opts, 0, stream);
        }
       else
        {
@@ -522,8 +558,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
 
          opts.format = (options->format ? options->format
                         : options->output_format);
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 &opts, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, &opts, 0, stream);
        }
       else
        {
@@ -536,9 +572,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
          if (c_textual_element_type (unresolved_type, options->format))
            {
              fputs_filtered (" ", stream);
-             LA_PRINT_CHAR ((unsigned char) unpack_long (type,
-                                                         valaddr
-                                                         + embedded_offset),
+             LA_PRINT_CHAR (unpack_long (type, valaddr + embedded_offset),
                             unresolved_type, stream);
            }
        }
@@ -550,8 +584,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
          struct value_print_options opts = *options;
          opts.format = (options->format ? options->format
                         : options->output_format);
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 &opts, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, &opts, 0, stream);
        }
       else
        {
@@ -561,15 +595,15 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
          else
            fprintf_filtered (stream, "%d", (int) val);
          fputs_filtered (" ", stream);
-         LA_PRINT_CHAR ((unsigned char) val, unresolved_type, stream);
+         LA_PRINT_CHAR (val, unresolved_type, stream);
        }
       break;
 
     case TYPE_CODE_FLT:
       if (options->format)
        {
-         print_scalar_formatted (valaddr + embedded_offset, type,
-                                 options, 0, stream);
+         val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                     original_value, options, 0, stream);
        }
       else
        {
@@ -579,8 +613,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
 
     case TYPE_CODE_DECFLOAT:
       if (options->format)
-       print_scalar_formatted (valaddr + embedded_offset, type,
-                               options, 0, stream);
+       val_print_scalar_formatted (type, valaddr, embedded_offset,
+                                   original_value, options, 0, stream);
       else
        print_decimal_floating (valaddr + embedded_offset,
                                type, stream);
@@ -604,19 +638,21 @@ c_val_print (struct type *type, const gdb_byte *valaddr,
 
     case TYPE_CODE_COMPLEX:
       if (options->format)
-       print_scalar_formatted (valaddr + embedded_offset,
-                               TYPE_TARGET_TYPE (type),
-                               options, 0, stream);
+       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, " + ");
       if (options->format)
-       print_scalar_formatted (valaddr + embedded_offset
-                               + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
-                               TYPE_TARGET_TYPE (type),
-                               options, 0, stream);
+       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)),
@@ -689,30 +725,33 @@ c_value_print (struct value *val, struct ui_file *stream,
            }
          /* Pointer to class, check real type of object.  */
          fprintf_filtered (stream, "(");
-          real_type = value_rtti_target_type (val, &full,
-                                             &top, &using_enc);
-          if (real_type)
-           {
-             /* RTTI entry found.  */
-              if (TYPE_CODE (type) == TYPE_CODE_PTR)
-                {
-                  /* Create a pointer type pointing to the real
-                    type.  */
-                  type = lookup_pointer_type (real_type);
-                }
-              else
-                {
-                  /* Create a reference type referencing the real
-                    type.  */
-                  type = lookup_reference_type (real_type);
-                }
-             /* JYG: Need to adjust pointer value.  */
-             /* NOTE: cagney/2005-01-02: THIS IS BOGUS.  */
-              value_contents_writeable (val)[0] -= top;
-
-              /* Note: When we look up RTTI entries, we don't get any 
-                 information on const or volatile attributes.  */
-            }
+
+         if (value_entirely_available (val))
+           {
+             real_type = value_rtti_target_type (val, &full, &top, &using_enc);
+             if (real_type)
+               {
+                 /* RTTI entry found.  */
+                 if (TYPE_CODE (type) == TYPE_CODE_PTR)
+                   {
+                     /* Create a pointer type pointing to the real
+                        type.  */
+                     type = lookup_pointer_type (real_type);
+                   }
+                 else
+                   {
+                     /* Create a reference type referencing the real
+                        type.  */
+                     type = lookup_reference_type (real_type);
+                   }
+                 /* Need to adjust pointer value.  */
+                 val = value_from_pointer (type, value_as_address (val) - top);
+
+                 /* Note: When we look up RTTI entries, we don't get
+                    any information on const or volatile
+                    attributes.  */
+               }
+           }
           type_print (type, "", stream, -1);
          fprintf_filtered (stream, ") ");
          val_type = type;
This page took 0.036385 seconds and 4 git commands to generate.