home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gdb-4.9 / gdb / cp-valprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-12  |  12.4 KB  |  469 lines

  1. /* Support for printing C++ values for GDB, the GNU debugger.
  2.    Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "obstack.h"
  22. #include "symtab.h"
  23. #include "gdbtypes.h"
  24. #include "expression.h"
  25. #include "value.h"
  26. #include "command.h"
  27. #include "gdbcmd.h"
  28. #include "demangle.h"
  29.  
  30. int vtblprint;            /* Controls printing of vtbl's */
  31. int objectprint;        /* Controls looking up an object's derived type
  32.                    using what we find in its vtables.  */
  33. struct obstack dont_print_obstack;
  34.  
  35. static void
  36. cplus_print_value PARAMS ((struct type *, char *, FILE *, int, int,
  37.                enum val_prettyprint, struct type **));
  38.  
  39. /* BEGIN-FIXME:  Hooks into typeprint.c, find a better home for prototypes. */
  40.  
  41. extern void
  42. c_type_print_base PARAMS ((struct type *, FILE *, int, int));
  43.  
  44. extern void
  45. c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
  46.  
  47. extern void
  48. cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
  49.                    FILE *));
  50.  
  51. extern struct obstack dont_print_obstack;
  52.  
  53. /* END-FIXME */
  54.  
  55.  
  56. /* BEGIN-FIXME:  Hooks into c-valprint.c */
  57.  
  58. extern int
  59. c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int, int,
  60.              enum val_prettyprint));
  61. /* END-FIXME */
  62.  
  63.  
  64. void
  65. cp_print_class_method (valaddr, type, stream)
  66.      char *valaddr;
  67.      struct type *type;
  68.      FILE *stream;
  69. {
  70.   struct type *domain;
  71.   struct fn_field *f;
  72.   int j;
  73.   int len2;
  74.   int offset;
  75.   char *kind = "";
  76.   CORE_ADDR addr;
  77.   struct symbol *sym;
  78.   unsigned len;
  79.   unsigned int i;
  80.  
  81.   domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
  82.   addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
  83.   if (METHOD_PTR_IS_VIRTUAL (addr))
  84.     {
  85.       offset = METHOD_PTR_TO_VOFFSET (addr);
  86.       len = TYPE_NFN_FIELDS (domain);
  87.       for (i = 0; i < len; i++)
  88.     {
  89.       f = TYPE_FN_FIELDLIST1 (domain, i);
  90.       len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
  91.       
  92.       for (j = 0; j < len2; j++)
  93.         {
  94.           QUIT;
  95.           if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
  96.         {
  97.           kind = "virtual ";
  98.           goto common;
  99.         }
  100.         }
  101.     }
  102.     }
  103.   else
  104.     {
  105.       sym = find_pc_function (addr);
  106.       if (sym == 0)
  107.     {
  108.       error ("invalid pointer to member function");
  109.     }
  110.       len = TYPE_NFN_FIELDS (domain);
  111.       for (i = 0; i < len; i++)
  112.     {
  113.       f = TYPE_FN_FIELDLIST1 (domain, i);
  114.       len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
  115.       
  116.       for (j = 0; j < len2; j++)
  117.         {
  118.           QUIT;
  119.           if (TYPE_FN_FIELD_STUB (f, j))
  120.         check_stub_method (domain, i, j);
  121.           if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
  122.         {
  123.           goto common;
  124.         }
  125.         }
  126.     }
  127.     }
  128.   common:
  129.   if (i < len)
  130.     {
  131.       fprintf_filtered (stream, "&");
  132.       c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
  133.       fprintf (stream, kind);
  134.       if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
  135.       && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
  136.     {
  137.       cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
  138.                      TYPE_FN_FIELDLIST_NAME (domain, i),
  139.                      0, stream);
  140.     }
  141.       else
  142.     {
  143.       cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
  144.                      TYPE_FN_FIELDLIST_NAME (domain, i),
  145.                      0, stream);
  146.     }
  147.     }
  148.   else
  149.     {
  150.       fprintf_filtered (stream, "(");
  151.       type_print (type, "", stream, -1);
  152.       fprintf_filtered (stream, ") %d", (int) addr >> 3);
  153.     }
  154. }
  155.  
  156. /* Return truth value for assertion that TYPE is of the type
  157.    "pointer to virtual function".  */
  158.  
  159. int
  160. cp_is_vtbl_ptr_type(type)
  161.      struct type *type;
  162. {
  163.   char *typename = type_name_no_tag (type);
  164.   static const char vtbl_ptr_name[] =
  165.     { CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
  166.  
  167.   return (typename != NULL && STREQ(typename, vtbl_ptr_name));
  168. }
  169.  
  170. /* Return truth value for the assertion that TYPE is of the type
  171.    "pointer to virtual function table".  */
  172.  
  173. int
  174. cp_is_vtbl_member(type)
  175.      struct type *type;
  176. {
  177.   if (TYPE_CODE (type) == TYPE_CODE_PTR)
  178.     type = TYPE_TARGET_TYPE (type);
  179.   else
  180.     return 0;
  181.  
  182.   if (TYPE_CODE (type) == TYPE_CODE_ARRAY
  183.       && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)
  184.     /* Virtual functions tables are full of pointers to virtual functions.  */
  185.     return cp_is_vtbl_ptr_type (TYPE_TARGET_TYPE (type));
  186.   return 0;
  187. }
  188.  
  189. /* Mutually recursive subroutines of cplus_print_value and c_val_print to
  190.    print out a structure's fields: cp_print_value_fields and cplus_print_value.
  191.  
  192.    TYPE, VALADDR, STREAM, RECURSE, and PRETTY have the
  193.    same meanings as in cplus_print_value and c_val_print.
  194.  
  195.    DONT_PRINT is an array of baseclass types that we
  196.    should not print, or zero if called from top level.  */
  197.  
  198. void
  199. cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
  200.                dont_print)
  201.      struct type *type;
  202.      char *valaddr;
  203.      FILE *stream;
  204.      int format;
  205.      int recurse;
  206.      enum val_prettyprint pretty;
  207.      struct type **dont_print;
  208. {
  209.   int i, len, n_baseclasses;
  210.  
  211.   check_stub_type (type);
  212.  
  213.   fprintf_filtered (stream, "{");
  214.   len = TYPE_NFIELDS (type);
  215.   n_baseclasses = TYPE_N_BASECLASSES (type);
  216.  
  217.   /* Print out baseclasses such that we don't print
  218.      duplicates of virtual baseclasses.  */
  219.   if (n_baseclasses > 0)
  220.     cplus_print_value (type, valaddr, stream, format, recurse+1, pretty,
  221.                dont_print);
  222.  
  223.   if (!len && n_baseclasses == 1)
  224.     fprintf_filtered (stream, "<No data fields>");
  225.   else
  226.     {
  227.       extern int inspect_it;
  228.       int fields_seen = 0;
  229.  
  230.       for (i = n_baseclasses; i < len; i++)
  231.     {
  232.       /* Check if static field */
  233.       if (TYPE_FIELD_STATIC (type, i))
  234.         continue;
  235.       if (fields_seen)
  236.         fprintf_filtered (stream, ", ");
  237.       else if (n_baseclasses > 0)
  238.         {
  239.           if (pretty)
  240.         {
  241.           fprintf_filtered (stream, "\n");
  242.           print_spaces_filtered (2 + 2 * recurse, stream);
  243.           fputs_filtered ("members of ", stream);
  244.           fputs_filtered (type_name_no_tag (type), stream);
  245.           fputs_filtered (": ", stream);
  246.         }
  247.         }
  248.       fields_seen = 1;
  249.  
  250.       if (pretty)
  251.         {
  252.           fprintf_filtered (stream, "\n");
  253.           print_spaces_filtered (2 + 2 * recurse, stream);
  254.         }
  255.       else 
  256.         {
  257.           wrap_here (n_spaces (2 + 2 * recurse));
  258.         }
  259.       if (inspect_it)
  260.         {
  261.           if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR)
  262.         fputs_filtered ("\"( ptr \"", stream);
  263.           else
  264.         fputs_filtered ("\"( nodef \"", stream);
  265.           fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
  266.                        language_cplus,
  267.                        DMGL_PARAMS | DMGL_ANSI);
  268.           fputs_filtered ("\" \"", stream);
  269.           fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
  270.                        language_cplus,
  271.                        DMGL_PARAMS | DMGL_ANSI);
  272.           fputs_filtered ("\") \"", stream);
  273.         }
  274.       else
  275.         {
  276.           fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
  277.                        language_cplus,
  278.                        DMGL_PARAMS | DMGL_ANSI);
  279.           fputs_filtered (" = ", stream);
  280.         }
  281.       if (TYPE_FIELD_PACKED (type, i))
  282.         {
  283.           value v;
  284.  
  285.           /* Bitfields require special handling, especially due to byte
  286.          order problems.  */
  287.           v = value_from_longest (TYPE_FIELD_TYPE (type, i),
  288.                    unpack_field_as_long (type, valaddr, i));
  289.  
  290.           c_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
  291.                stream, format, 0, recurse + 1, pretty);
  292.         }
  293.       else
  294.         {
  295.           c_val_print (TYPE_FIELD_TYPE (type, i), 
  296.                valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
  297.                0, stream, format, 0, recurse + 1, pretty);
  298.         }
  299.     }
  300.       if (pretty)
  301.     {
  302.       fprintf_filtered (stream, "\n");
  303.       print_spaces_filtered (2 * recurse, stream);
  304.     }
  305.     }
  306.   fprintf_filtered (stream, "}");
  307. }
  308.  
  309. /* Special val_print routine to avoid printing multiple copies of virtual
  310.    baseclasses.  */
  311.  
  312. static void
  313. cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
  314.      struct type *type;
  315.      char *valaddr;
  316.      FILE *stream;
  317.      int format;
  318.      int recurse;
  319.      enum val_prettyprint pretty;
  320.      struct type **dont_print;
  321. {
  322.   struct obstack tmp_obstack;
  323.   struct type **last_dont_print
  324.     = (struct type **)obstack_next_free (&dont_print_obstack);
  325.   int i, n_baseclasses = TYPE_N_BASECLASSES (type);
  326.  
  327.   if (dont_print == 0)
  328.     {
  329.       /* If we're at top level, carve out a completely fresh
  330.      chunk of the obstack and use that until this particular
  331.      invocation returns.  */
  332.       tmp_obstack = dont_print_obstack;
  333.       /* Bump up the high-water mark.  Now alpha is omega.  */
  334.       obstack_finish (&dont_print_obstack);
  335.     }
  336.  
  337.   for (i = 0; i < n_baseclasses; i++)
  338.     {
  339.       char *baddr;
  340.       int err;
  341.  
  342.       if (BASETYPE_VIA_VIRTUAL (type, i))
  343.     {
  344.       struct type **first_dont_print
  345.         = (struct type **)obstack_base (&dont_print_obstack);
  346.  
  347.       int j = (struct type **)obstack_next_free (&dont_print_obstack)
  348.         - first_dont_print;
  349.  
  350.       while (--j >= 0)
  351.         if (TYPE_BASECLASS (type, i) == first_dont_print[j])
  352.           goto flush_it;
  353.  
  354.       obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i));
  355.     }
  356.  
  357.       /* Fix to use baseclass_offset instead. FIXME */
  358.       baddr = baseclass_addr (type, i, valaddr, 0, &err);
  359.       if (err == 0 && baddr == 0)
  360.     error ("could not find virtual baseclass `%s'\n",
  361.            type_name_no_tag (TYPE_BASECLASS (type, i)));
  362.  
  363.       if (pretty)
  364.     {
  365.       fprintf_filtered (stream, "\n");
  366.       print_spaces_filtered (2 * recurse, stream);
  367.     }
  368.       fputs_filtered ("<", stream);
  369.       fputs_filtered (type_name_no_tag (TYPE_BASECLASS (type, i)), stream);
  370.       fputs_filtered ("> = ", stream);
  371.       if (err != 0)
  372.     fprintf_filtered (stream, "<invalid address 0x%x>", baddr);
  373.       else
  374.     cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format,
  375.                    recurse, pretty,
  376.                    (struct type **) obstack_base (&dont_print_obstack));
  377.       fputs_filtered (", ", stream);
  378.  
  379.     flush_it:
  380.       ;
  381.     }
  382.  
  383.   if (dont_print == 0)
  384.     {
  385.       /* Free the space used to deal with the printing
  386.      of this type from top level.  */
  387.       obstack_free (&dont_print_obstack, last_dont_print);
  388.       /* Reset watermark so that we can continue protecting
  389.      ourselves from whatever we were protecting ourselves.  */
  390.       dont_print_obstack = tmp_obstack;
  391.     }
  392. }
  393.  
  394. void
  395. cp_print_class_member (valaddr, domain, stream, prefix)
  396.      char *valaddr;
  397.      struct type *domain;
  398.      FILE *stream;
  399.      char *prefix;
  400. {
  401.   
  402.   /* VAL is a byte offset into the structure type DOMAIN.
  403.      Find the name of the field for that offset and
  404.      print it.  */
  405.   int extra = 0;
  406.   int bits = 0;
  407.   register unsigned int i;
  408.   unsigned len = TYPE_NFIELDS (domain);
  409.   /* @@ Make VAL into bit offset */
  410.   LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;
  411.   for (i = TYPE_N_BASECLASSES (domain); i < len; i++)
  412.     {
  413.       int bitpos = TYPE_FIELD_BITPOS (domain, i);
  414.       QUIT;
  415.       if (val == bitpos)
  416.     break;
  417.       if (val < bitpos && i != 0)
  418.     {
  419.       /* Somehow pointing into a field.  */
  420.       i -= 1;
  421.       extra = (val - TYPE_FIELD_BITPOS (domain, i));
  422.       if (extra & 0x7)
  423.         bits = 1;
  424.       else
  425.         extra >>= 3;
  426.       break;
  427.     }
  428.     }
  429.   if (i < len)
  430.     {
  431.       char *name;
  432.       fprintf_filtered (stream, prefix);
  433.       name = type_name_no_tag (domain);
  434.       if (name)
  435.         fputs_filtered (name, stream);
  436.       else
  437.     c_type_print_base (domain, stream, 0, 0);
  438.       fprintf_filtered (stream, "::");
  439.       fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);
  440.       if (extra)
  441.     fprintf_filtered (stream, " + %d bytes", extra);
  442.       if (bits)
  443.     fprintf_filtered (stream, " (offset in bits)");
  444.     }
  445.   else
  446.     fprintf_filtered (stream, "%d", val >> 3);
  447. }
  448.  
  449. void
  450. _initialize_cp_valprint ()
  451. {
  452.   add_show_from_set
  453.     (add_set_cmd ("vtbl", class_support, var_boolean, (char *)&vtblprint,
  454.           "Set printing of C++ virtual function tables.",
  455.           &setprintlist),
  456.      &showprintlist);
  457.  
  458.   add_show_from_set
  459.     (add_set_cmd ("object", class_support, var_boolean, (char *)&objectprint,
  460.       "Set printing of object's derived type based on vtable info.",
  461.           &setprintlist),
  462.      &showprintlist);
  463.  
  464.   /* Give people the defaults which they are used to.  */
  465.   objectprint = 0;
  466.   vtblprint = 0;
  467.   obstack_begin (&dont_print_obstack, 32 * sizeof (struct type *));
  468. }
  469.