Copyright updates for 2007.
[deliverable/binutils-gdb.git] / gdb / c-valprint.c
index 07289de0a9c108348f5a3a2c1e82147c02bacc72..efd531e08884f8d913fcec4700464fb4cb56838a 100644 (file)
@@ -1,5 +1,7 @@
 /* Support for printing C values for GDB, the GNU debugger.
-   Copyright 1986, 1988, 1989, 1991-1997, 2000
+
+   Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2003, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
+#include "gdb_string.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "expression.h"
 #include "value.h"
-#include "demangle.h"
 #include "valprint.h"
 #include "language.h"
 #include "c-lang.h"
+#include "cp-abi.h"
+#include "target.h"
 \f
 
+/* Print function pointer with inferior address ADDRESS onto stdio
+   stream STREAM.  */
+
+static void
+print_function_pointer_address (CORE_ADDR address, struct ui_file *stream)
+{
+  CORE_ADDR func_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+                                                           address,
+                                                           &current_target);
+
+  /* If the function pointer is represented by a description, print the
+     address of the description.  */
+  if (addressprint && func_addr != address)
+    {
+      fputs_filtered ("@", stream);
+      deprecated_print_address_numeric (address, 1, stream);
+      fputs_filtered (": ", stream);
+    }
+  print_address_demangle (func_addr, stream, demangle);
+}
+
+
 /* Print data of type TYPE located at VALADDR (within GDB), which came from
    the inferior at address ADDRESS, onto stdio stream STREAM according to
    FORMAT (a letter or 0 for natural format).  The data at VALADDR is in
    The PRETTY parameter controls prettyprinting.  */
 
 int
-c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, recurse,
-            pretty)
-     struct type *type;
-     char *valaddr;
-     int embedded_offset;
-     CORE_ADDR address;
-     struct ui_file *stream;
-     int format;
-     int deref_ref;
-     int recurse;
-     enum val_prettyprint pretty;
+c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
+            CORE_ADDR address, struct ui_file *stream, int format,
+            int deref_ref, int recurse, enum val_prettyprint pretty)
 {
-  register unsigned int i = 0; /* Number of characters printed */
+  unsigned int i = 0;  /* Number of characters printed */
   unsigned len;
   struct type *elttype;
   unsigned eltlen;
@@ -108,7 +126,7 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
              if (cp_is_vtbl_ptr_type (elttype))
                {
                  i = 1;
-                 fprintf_filtered (stream, "%d vtable entries", len - 1);
+                 fprintf_filtered (stream, _("%d vtable entries"), len - 1);
                }
              else
                {
@@ -124,6 +142,21 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
       addr = address;
       goto print_unpacked_pointer;
 
+    case TYPE_CODE_MEMBERPTR:
+      if (format)
+       {
+         print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+         break;
+       }
+      cp_print_class_member (valaddr + embedded_offset,
+                            TYPE_DOMAIN_TYPE (type),
+                            stream, "&");
+      break;
+
+    case TYPE_CODE_METHODPTR:
+      cplus_print_method_ptr (valaddr + embedded_offset, type, stream);
+      break;
+
     case TYPE_CODE_PTR:
       if (format && format != 's')
        {
@@ -135,38 +168,27 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
          /* Print the unmangled name if desired.  */
          /* Print vtable entry - we only get here if we ARE using
             -fvtable_thunks.  (Otherwise, look under TYPE_CODE_STRUCT.) */
-         print_address_demangle (extract_address (valaddr + embedded_offset, TYPE_LENGTH (type)),
-                                 stream, demangle);
+         CORE_ADDR addr
+           = extract_typed_address (valaddr + embedded_offset, type);
+         print_function_pointer_address (addr, stream);
          break;
        }
       elttype = check_typedef (TYPE_TARGET_TYPE (type));
-      if (TYPE_CODE (elttype) == TYPE_CODE_METHOD)
-       {
-         cp_print_class_method (valaddr + embedded_offset, type, stream);
-       }
-      else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
-       {
-         cp_print_class_member (valaddr + embedded_offset,
-                                TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
-                                stream, "&");
-       }
-      else
        {
          addr = unpack_pointer (type, valaddr + embedded_offset);
        print_unpacked_pointer:
-         elttype = check_typedef (TYPE_TARGET_TYPE (type));
 
          if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
            {
              /* Try to print what function it points to.  */
-             print_address_demangle (addr, stream, demangle);
+             print_function_pointer_address (addr, stream);
              /* Return value is irrelevant except for string pointers.  */
              return (0);
            }
 
          if (addressprint && format != 's')
            {
-             print_address_numeric (addr, 1, stream);
+             deprecated_print_address_numeric (addr, 1, stream);
            }
 
          /* For a pointer to char or unsigned char, also print the string
@@ -191,21 +213,20 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
                  (vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
                {
                  fputs_filtered (" <", stream);
-                 fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream);
+                 fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream);
                  fputs_filtered (">", stream);
                }
              if (vt_address && vtblprint)
                {
-                 value_ptr vt_val;
+                 struct value *vt_val;
                  struct symbol *wsym = (struct symbol *) NULL;
                  struct type *wtype;
-                 struct symtab *s;
                  struct block *block = (struct block *) NULL;
                  int is_this_fld;
 
                  if (msymbol != NULL)
-                   wsym = lookup_symbol (SYMBOL_NAME (msymbol), block,
-                                         VAR_NAMESPACE, &is_this_fld, &s);
+                   wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block,
+                                         VAR_DOMAIN, &is_this_fld, NULL);
 
                  if (wsym)
                    {
@@ -215,10 +236,9 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
                    {
                      wtype = TYPE_TARGET_TYPE (type);
                    }
-                 vt_val = value_at (wtype, vt_address, NULL);
-                 val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
-                            VALUE_ADDRESS (vt_val), stream, format,
-                            deref_ref, recurse + 1, pretty);
+                 vt_val = value_at (wtype, vt_address);
+                 common_val_print (vt_val, stream, format,
+                                   deref_ref, recurse + 1, pretty);
                  if (pretty)
                    {
                      fprintf_filtered (stream, "\n");
@@ -234,25 +254,14 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
        }
       break;
 
-    case TYPE_CODE_MEMBER:
-      error ("not implemented: member type in c_val_print");
-      break;
-
     case TYPE_CODE_REF:
       elttype = check_typedef (TYPE_TARGET_TYPE (type));
-      if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER)
-       {
-         cp_print_class_member (valaddr + embedded_offset,
-                                TYPE_DOMAIN_TYPE (elttype),
-                                stream, "");
-         break;
-       }
       if (addressprint)
        {
+         CORE_ADDR addr
+           = extract_typed_address (valaddr + embedded_offset, type);
          fprintf_filtered (stream, "@");
-         print_address_numeric
-           (extract_address (valaddr + embedded_offset,
-                             TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream);
+         deprecated_print_address_numeric (addr, 1, stream);
          if (deref_ref)
            fputs_filtered (": ", stream);
        }
@@ -261,21 +270,13 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
        {
          if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
            {
-             value_ptr deref_val =
+             struct value *deref_val =
              value_at
              (TYPE_TARGET_TYPE (type),
               unpack_pointer (lookup_pointer_type (builtin_type_void),
-                              valaddr + embedded_offset),
-              NULL);
-             val_print (VALUE_TYPE (deref_val),
-                        VALUE_CONTENTS (deref_val),
-                        0,
-                        VALUE_ADDRESS (deref_val),
-                        stream,
-                        format,
-                        deref_ref,
-                        recurse,
-                        pretty);
+                              valaddr + embedded_offset));
+             common_val_print (deref_val, stream, format, deref_ref,
+                               recurse, pretty);
            }
          else
            fputs_filtered ("???", stream);
@@ -290,16 +291,19 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
        }
       /* Fall through.  */
     case TYPE_CODE_STRUCT:
+      /*FIXME: Abstract this away */
       if (vtblprint && cp_is_vtbl_ptr_type (type))
        {
          /* Print the unmangled name if desired.  */
          /* Print vtable entry - we only get here if NOT using
             -fvtable_thunks.  (Otherwise, look under TYPE_CODE_PTR.) */
-         print_address_demangle (extract_address (
-                                                valaddr + embedded_offset +
-                          TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8,
-                 TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))),
-                                 stream, demangle);
+         int offset = (embedded_offset +
+                       TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8);
+         struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET);
+         CORE_ADDR addr
+           = extract_typed_address (valaddr + offset, field_type);
+
+         print_function_pointer_address (addr, stream);
        }
       else
        cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format,
@@ -332,7 +336,15 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
        }
       break;
 
+    case TYPE_CODE_FLAGS:
+      if (format)
+         print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
+      else
+       val_print_type_code_flags (type, valaddr + embedded_offset, stream);
+      break;
+
     case TYPE_CODE_FUNC:
+    case TYPE_CODE_METHOD:
       if (format)
        {
          print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream);
@@ -424,41 +436,55 @@ c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
        }
       break;
 
-    case TYPE_CODE_METHOD:
-      cp_print_class_method (valaddr + embedded_offset, lookup_pointer_type (type), stream);
-      break;
-
     case TYPE_CODE_VOID:
       fprintf_filtered (stream, "void");
       break;
 
     case TYPE_CODE_ERROR:
-      fprintf_filtered (stream, "<error type>");
+      fprintf_filtered (stream, _("<error 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>");
+      fprintf_filtered (stream, _("<incomplete type>"));
+      break;
+
+    case TYPE_CODE_COMPLEX:
+      if (format)
+       print_scalar_formatted (valaddr + embedded_offset,
+                               TYPE_TARGET_TYPE (type),
+                               format, 0, stream);
+      else
+       print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type),
+                       stream);
+      fprintf_filtered (stream, " + ");
+      if (format)
+       print_scalar_formatted (valaddr + embedded_offset
+                               + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+                               TYPE_TARGET_TYPE (type),
+                               format, 0, stream);
+      else
+       print_floating (valaddr + embedded_offset
+                       + TYPE_LENGTH (TYPE_TARGET_TYPE (type)),
+                       TYPE_TARGET_TYPE (type),
+                       stream);
+      fprintf_filtered (stream, " * I");
       break;
 
     default:
-      error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type));
+      error (_("Invalid C/C++ type code %d in symbol table."), TYPE_CODE (type));
     }
   gdb_flush (stream);
   return (0);
 }
 \f
 int
-c_value_print (val, stream, format, pretty)
-     value_ptr val;
-     struct ui_file *stream;
-     int format;
-     enum val_prettyprint pretty;
+c_value_print (struct value *val, struct ui_file *stream, int format,
+              enum val_prettyprint pretty)
 {
-  struct type *type = VALUE_TYPE (val);
-  struct type *real_type;
+  struct type *type, *real_type;
   int full, top, using_enc;
 
   /* If it is a pointer, indicate what it points to.
@@ -467,20 +493,34 @@ c_value_print (val, stream, format, pretty)
 
      C++: if it is a member pointer, we will take care
      of that when we print it.  */
-  if (TYPE_CODE (type) == TYPE_CODE_PTR ||
-      TYPE_CODE (type) == TYPE_CODE_REF)
+
+  type = check_typedef (value_type (val));
+
+  if (TYPE_CODE (type) == TYPE_CODE_PTR
+      || TYPE_CODE (type) == TYPE_CODE_REF)
     {
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway. */
-      if (TYPE_CODE (type) == TYPE_CODE_PTR &&
-         TYPE_NAME (type) == NULL &&
-         TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL &&
-         STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char"))
+      if (TYPE_CODE (type) == TYPE_CODE_PTR
+         && TYPE_NAME (type) == NULL
+         && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL
+         && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0)
        {
          /* Print nothing */
        }
       else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
        {
+
+         if (TYPE_CODE(type) == TYPE_CODE_REF)
+           {
+             /* Copy value, change to pointer, so we don't get an
+              * error about a non-pointer type in value_rtti_target_type
+              */
+             struct value *temparg;
+             temparg=value_copy(val);
+             deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type)));
+             val=temparg;
+           }
          /* Pointer to class, check real type of object */
          fprintf_filtered (stream, "(");
           real_type = value_rtti_target_type (val, &full, &top, &using_enc);
@@ -497,6 +537,10 @@ c_value_print (val, stream, format, pretty)
                   /* 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 */
             }
@@ -507,11 +551,12 @@ c_value_print (val, stream, format, pretty)
        {
          /* normal case */
          fprintf_filtered (stream, "(");
-         type_print (type, "", stream, -1);
+         type_print (value_type (val), "", stream, -1);
          fprintf_filtered (stream, ") ");
        }
     }
-  if (objectprint && (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_CLASS))
+
+  if (objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS))
     {
       /* Attempt to determine real type of object */
       real_type = value_rtti_type (val, &full, &top, &using_enc);
@@ -521,25 +566,28 @@ c_value_print (val, stream, format, pretty)
          val = value_full_object (val, real_type, full, top, using_enc);
          fprintf_filtered (stream, "(%s%s) ",
                            TYPE_NAME (real_type),
-                           full ? "" : " [incomplete object]");
+                           full ? "" : _(" [incomplete object]"));
          /* Print out object: enclosing type is same as real_type if full */
-         return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
-                        VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+         return val_print (value_enclosing_type (val),
+                           value_contents_all (val), 0,
+                           VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
           /* Note: When we look up RTTI entries, we don't get any information on
              const or volatile attributes */
        }
-      else if (type != VALUE_ENCLOSING_TYPE (val))
+      else if (type != check_typedef (value_enclosing_type (val)))
        {
          /* No RTTI information, so let's do our best */
          fprintf_filtered (stream, "(%s ?) ",
-                           TYPE_NAME (VALUE_ENCLOSING_TYPE (val)));
-         return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0,
-                        VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
+                           TYPE_NAME (value_enclosing_type (val)));
+         return val_print (value_enclosing_type (val),
+                           value_contents_all (val), 0,
+                           VALUE_ADDRESS (val), stream, format, 1, 0, pretty);
        }
       /* Otherwise, we end up at the return outside this "if" */
     }
 
-  return val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val),
-                   VALUE_ADDRESS (val),
+  return val_print (type, value_contents_all (val),
+                   value_embedded_offset (val),
+                   VALUE_ADDRESS (val) + value_offset (val),
                    stream, format, 1, 0, pretty);
 }
This page took 0.044185 seconds and 4 git commands to generate.