* target.h: Add enum target_waitkind, enum target_signal, and
[deliverable/binutils-gdb.git] / gdb / cp-valprint.c
index 5222f7b9475ea04d4f284f87c43921bbf9135746..2ff2a8c8a9d15dda948db7047effd3e1c44e61e6 100644 (file)
@@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "value.h"
 #include "command.h"
 #include "gdbcmd.h"
+#include "demangle.h"
 
 int vtblprint;                 /* Controls printing of vtbl's */
 int objectprint;               /* Controls looking up an object's derived type
@@ -32,33 +33,122 @@ int objectprint;           /* Controls looking up an object's derived type
 struct obstack dont_print_obstack;
 
 static void
-cplus_print_value PARAMS ((struct type *, char *, FILE *, int, int,
+cplus_print_value PARAMS ((struct type *, char *, GDB_FILE *, int, int,
                           enum val_prettyprint, struct type **));
 
 /* BEGIN-FIXME:  Hooks into typeprint.c, find a better home for prototypes. */
 
 extern void
-c_type_print_base PARAMS ((struct type *, FILE *, int, int));
+c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
 
 extern void
-c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
+c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
 
 extern void
 cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
-                                  FILE *));
+                                  GDB_FILE *));
 
 extern struct obstack dont_print_obstack;
 
 /* END-FIXME */
 
-
-/* BEGIN-FIXME:  Hooks into c-valprint.c */
-
-extern int
-c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int, int,
-                    enum val_prettyprint));
-/* END-FIXME */
-
+void
+cp_print_class_method (valaddr, type, stream)
+     char *valaddr;
+     struct type *type;
+     GDB_FILE *stream;
+{
+  struct type *domain;
+  struct fn_field *f = NULL;
+  int j = 0;
+  int len2;
+  int offset;
+  char *kind = "";
+  CORE_ADDR addr;
+  struct symbol *sym;
+  unsigned len;
+  unsigned int i;
+
+  check_stub_type (TYPE_TARGET_TYPE (type));
+  domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
+  if (domain == (struct type *)NULL)
+    {
+      fprintf_filtered (stream, "<unknown>");
+      return;
+    }
+  addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
+  if (METHOD_PTR_IS_VIRTUAL (addr))
+    {
+      offset = METHOD_PTR_TO_VOFFSET (addr);
+      len = TYPE_NFN_FIELDS (domain);
+      for (i = 0; i < len; i++)
+       {
+         f = TYPE_FN_FIELDLIST1 (domain, i);
+         len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+         
+         for (j = 0; j < len2; j++)
+           {
+             QUIT;
+             if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
+               {
+                 kind = "virtual ";
+                 goto common;
+               }
+           }
+       }
+    }
+  else
+    {
+      sym = find_pc_function (addr);
+      if (sym == 0)
+       {
+         error ("invalid pointer to member function");
+       }
+      len = TYPE_NFN_FIELDS (domain);
+      for (i = 0; i < len; i++)
+       {
+         f = TYPE_FN_FIELDLIST1 (domain, i);
+         len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+         
+         for (j = 0; j < len2; j++)
+           {
+             QUIT;
+             if (TYPE_FN_FIELD_STUB (f, j))
+               check_stub_method (domain, i, j);
+             if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
+               {
+                 goto common;
+               }
+           }
+       }
+    }
+  common:
+  if (i < len)
+    {
+      fprintf_filtered (stream, "&");
+      c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
+      fprintf_unfiltered (stream, kind);
+      if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
+         && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
+       {
+         cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
+                                    TYPE_FN_FIELDLIST_NAME (domain, i),
+                                    0, stream);
+       }
+      else
+       {
+         cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
+                                    TYPE_FN_FIELDLIST_NAME (domain, i),
+                                    0, stream);
+       }
+    }
+  else
+    {
+      fprintf_filtered (stream, "(");
+      type_print (type, "", stream, -1);
+      fprintf_filtered (stream, ") %d", (int) addr >> 3);
+    }
+}
 
 /* Return truth value for assertion that TYPE is of the type
    "pointer to virtual function".  */
@@ -68,10 +158,16 @@ cp_is_vtbl_ptr_type(type)
      struct type *type;
 {
   char *typename = type_name_no_tag (type);
-  static const char vtbl_ptr_name[] =
+  /* This was what it was for gcc 2.4.5 and earlier.  */
+  static const char vtbl_ptr_name_old[] =
     { CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
+  /* It was changed to this after 2.4.5.  */
+  static const char vtbl_ptr_name[] =
+    { '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
 
-  return (typename != NULL && !strcmp(typename, vtbl_ptr_name));
+  return (typename != NULL
+         && (STREQ (typename, vtbl_ptr_name)
+             || STREQ (typename, vtbl_ptr_name_old)));
 }
 
 /* Return truth value for the assertion that TYPE is of the type
@@ -107,7 +203,7 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
                       dont_print)
      struct type *type;
      char *valaddr;
-     FILE *stream;
+     GDB_FILE *stream;
      int format;
      int recurse;
      enum val_prettyprint pretty;
@@ -169,14 +265,20 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
                fputs_filtered ("\"( ptr \"", stream);
              else
                fputs_filtered ("\"( nodef \"", stream);
-             fprint_symbol (stream, TYPE_FIELD_NAME (type, i));
+             fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+                                      language_cplus,
+                                      DMGL_PARAMS | DMGL_ANSI);
              fputs_filtered ("\" \"", stream);
-             fprint_symbol (stream, TYPE_FIELD_NAME (type, i));
+             fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+                                      language_cplus,
+                                      DMGL_PARAMS | DMGL_ANSI);
              fputs_filtered ("\") \"", stream);
            }
          else
            {
-             fprint_symbol (stream, TYPE_FIELD_NAME (type, i));
+             fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+                                      language_cplus,
+                                      DMGL_PARAMS | DMGL_ANSI);
              fputs_filtered (" = ", stream);
            }
          if (TYPE_FIELD_PACKED (type, i))
@@ -185,17 +287,31 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
 
              /* Bitfields require special handling, especially due to byte
                 order problems.  */
-             v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+             if (TYPE_FIELD_IGNORE (type, i))
+               {
+                  fputs_filtered ("<optimized out or zero length>", stream);
+               }
+             else
+               {
+                  v = value_from_longest (TYPE_FIELD_TYPE (type, i),
                                   unpack_field_as_long (type, valaddr, i));
 
-             c_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
-                          stream, format, 0, recurse + 1, pretty);
+                   val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
+                             stream, format, 0, recurse + 1, pretty);
+               }
            }
          else
            {
-             c_val_print (TYPE_FIELD_TYPE (type, i), 
-                          valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
-                          0, stream, format, 0, recurse + 1, pretty);
+             if (TYPE_FIELD_IGNORE (type, i))
+               {
+                  fputs_filtered ("<optimized out or zero length>", stream);
+               }
+             else
+               {
+                  val_print (TYPE_FIELD_TYPE (type, i), 
+                             valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
+                             0, stream, format, 0, recurse + 1, pretty);
+               }
            }
        }
       if (pretty)
@@ -214,7 +330,7 @@ static void
 cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
      struct type *type;
      char *valaddr;
-     FILE *stream;
+     GDB_FILE *stream;
      int format;
      int recurse;
      enum val_prettyprint pretty;
@@ -239,6 +355,10 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
     {
       char *baddr;
       int err;
+      char *basename;
+
+      check_stub_type (TYPE_BASECLASS (type, i));
+      basename = TYPE_NAME (TYPE_BASECLASS (type, i));
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
        {
@@ -258,8 +378,8 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
       /* Fix to use baseclass_offset instead. FIXME */
       baddr = baseclass_addr (type, i, valaddr, 0, &err);
       if (err == 0 && baddr == 0)
-       error ("could not find virtual baseclass `%s'\n",
-              type_name_no_tag (TYPE_BASECLASS (type, i)));
+       error ("could not find virtual baseclass %s\n",
+              basename ? basename : "");
 
       if (pretty)
        {
@@ -267,10 +387,13 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
          print_spaces_filtered (2 * recurse, stream);
        }
       fputs_filtered ("<", stream);
-      fputs_filtered (type_name_no_tag (TYPE_BASECLASS (type, i)), stream);
+      /* Not sure what the best notation is in the case where there is no
+        baseclass name.  */
+      fputs_filtered (basename ? basename : "", stream);
       fputs_filtered ("> = ", stream);
       if (err != 0)
-       fprintf_filtered (stream, "<invalid address 0x%x>", baddr);
+       fprintf_filtered (stream,
+                         "<invalid address 0x%lx>", (unsigned long) baddr);
       else
        cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format,
                               recurse, pretty,
@@ -296,7 +419,7 @@ void
 cp_print_class_member (valaddr, domain, stream, prefix)
      char *valaddr;
      struct type *domain;
-     FILE *stream;
+     GDB_FILE *stream;
      char *prefix;
 {
   
This page took 0.026979 seconds and 4 git commands to generate.