gdb/jv-typeprint.c - gdb

Functions defined

Source code

  1. /* Support for printing Java types for GDB, the GNU debugger.
  2.    Copyright (C) 1997-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */


  14. #include "defs.h"
  15. #include "symtab.h"
  16. #include "gdbtypes.h"
  17. #include "value.h"
  18. #include "demangle.h"
  19. #include "gdb-demangle.h"
  20. #include "jv-lang.h"
  21. #include "typeprint.h"
  22. #include "c-lang.h"
  23. #include "cp-abi.h"
  24. #include "cp-support.h"

  25. /* Local functions */

  26. static void java_type_print_base (struct type * type,
  27.                                   struct ui_file *stream, int show,
  28.                                   int level,
  29.                                   const struct type_print_options *flags);

  30. static void
  31. java_type_print_derivation_info (struct ui_file *stream, struct type *type)
  32. {
  33.   const char *name;
  34.   int i;
  35.   int n_bases;
  36.   int prev;

  37.   n_bases = TYPE_N_BASECLASSES (type);

  38.   for (i = 0, prev = 0; i < n_bases; i++)
  39.     {
  40.       int kind;

  41.       kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E';

  42.       fputs_filtered (kind == prev ? ", "
  43.                       : kind == 'I' ? " implements "
  44.                       : " extends ",
  45.                       stream);
  46.       prev = kind;
  47.       name = type_name_no_tag (TYPE_BASECLASS (type, i));

  48.       fprintf_filtered (stream, "%s", name ? name : "(null)");
  49.     }

  50.   if (i > 0)
  51.     fputs_filtered (" ", stream);
  52. }

  53. /* Print the name of the type (or the ultimate pointer target,
  54.    function value or array element), or the description of a
  55.    structure or union.

  56.    SHOW positive means print details about the type (e.g. enum values),
  57.    and print structure elements passing SHOW - 1 for show.
  58.    SHOW negative means just print the type name or struct tag if there is one.
  59.    If there is no name, print something sensible but concise like
  60.    "struct {...}".
  61.    SHOW zero means just print the type name or struct tag if there is one.
  62.    If there is no name, print something sensible but not as concise like
  63.    "struct {int x; int y;}".

  64.    LEVEL is the number of spaces to indent by.
  65.    We increase it for some recursive calls.  */

  66. static void
  67. java_type_print_base (struct type *type, struct ui_file *stream, int show,
  68.                       int level, const struct type_print_options *flags)
  69. {
  70.   int i;
  71.   int len;
  72.   char *mangled_name;
  73.   char *demangled_name;

  74.   QUIT;
  75.   wrap_here ("    ");

  76.   if (type == NULL)
  77.     {
  78.       fputs_filtered ("<type unknown>", stream);
  79.       return;
  80.     }

  81.   /* When SHOW is zero or less, and there is a valid type name, then always
  82.      just print the type name directly from the type.  */

  83.   if (show <= 0
  84.       && TYPE_NAME (type) != NULL)
  85.     {
  86.       fputs_filtered (TYPE_NAME (type), stream);
  87.       return;
  88.     }

  89.   CHECK_TYPEDEF (type);

  90.   switch (TYPE_CODE (type))
  91.     {
  92.     case TYPE_CODE_PTR:
  93.       java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level,
  94.                             flags);
  95.       break;

  96.     case TYPE_CODE_STRUCT:
  97.       if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
  98.         {                        /* array type */
  99.           char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));

  100.           fputs_filtered (name, stream);
  101.           xfree (name);
  102.           break;
  103.         }

  104.       if (show >= 0)
  105.         fprintf_filtered (stream, "class ");

  106.       if (TYPE_TAG_NAME (type) != NULL)
  107.         {
  108.           fputs_filtered (TYPE_TAG_NAME (type), stream);
  109.           if (show > 0)
  110.             fputs_filtered (" ", stream);
  111.         }

  112.       wrap_here ("    ");

  113.       if (show < 0)
  114.         {
  115.           /* If we just printed a tag name, no need to print anything else.  */
  116.           if (TYPE_TAG_NAME (type) == NULL)
  117.             fprintf_filtered (stream, "{...}");
  118.         }
  119.       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
  120.         {
  121.           java_type_print_derivation_info (stream, type);

  122.           fprintf_filtered (stream, "{\n");
  123.           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
  124.             {
  125.               if (TYPE_STUB (type))
  126.                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
  127.               else
  128.                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
  129.             }

  130.           /* If there is a base class for this type,
  131.              do not print the field that it occupies.  */

  132.           len = TYPE_NFIELDS (type);
  133.           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
  134.             {
  135.               QUIT;
  136.               /* Don't print out virtual function table.  */
  137.               if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
  138.                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
  139.                 continue;

  140.               /* Don't print the dummy field "class".  */
  141.               if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
  142.                 continue;

  143.               print_spaces_filtered (level + 4, stream);

  144.               if (HAVE_CPLUS_STRUCT (type))
  145.                 {
  146.                   if (TYPE_FIELD_PROTECTED (type, i))
  147.                     fprintf_filtered (stream, "protected ");
  148.                   else if (TYPE_FIELD_PRIVATE (type, i))
  149.                     fprintf_filtered (stream, "private ");
  150.                   else
  151.                     fprintf_filtered (stream, "public ");
  152.                 }

  153.               if (field_is_static (&TYPE_FIELD (type, i)))
  154.                 fprintf_filtered (stream, "static ");

  155.               java_print_type (TYPE_FIELD_TYPE (type, i),
  156.                                TYPE_FIELD_NAME (type, i),
  157.                                stream, show - 1, level + 4, flags);

  158.               fprintf_filtered (stream, ";\n");
  159.             }

  160.           /* If there are both fields and methods, put a space between.  */
  161.           len = TYPE_NFN_FIELDS (type);
  162.           if (len)
  163.             fprintf_filtered (stream, "\n");

  164.           /* Print out the methods.  */

  165.           for (i = 0; i < len; i++)
  166.             {
  167.               struct fn_field *f;
  168.               int j;
  169.               const char *method_name;
  170.               const char *name;
  171.               int is_constructor;
  172.               int n_overloads;

  173.               f = TYPE_FN_FIELDLIST1 (type, i);
  174.               n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
  175.               method_name = TYPE_FN_FIELDLIST_NAME (type, i);
  176.               name = type_name_no_tag (type);
  177.               is_constructor = name && strcmp (method_name, name) == 0;

  178.               for (j = 0; j < n_overloads; j++)
  179.                 {
  180.                   const char *real_physname;
  181.                   char *physname, *p;
  182.                   int is_full_physname_constructor;

  183.                   real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);

  184.                   /* The physname will contain the return type
  185.                      after the final closing parenthesis.  Strip it off.  */
  186.                   p = strrchr (real_physname, ')');
  187.                   gdb_assert (p != NULL);
  188.                   ++p;   /* Keep the trailing ')'.  */
  189.                   physname = alloca (p - real_physname + 1);
  190.                   memcpy (physname, real_physname, p - real_physname);
  191.                   physname[p - real_physname] = '\0';

  192.                   is_full_physname_constructor
  193.                     = (TYPE_FN_FIELD_CONSTRUCTOR (f, j)
  194.                        || is_constructor_name (physname)
  195.                        || is_destructor_name (physname));

  196.                   QUIT;

  197.                   print_spaces_filtered (level + 4, stream);

  198.                   if (TYPE_FN_FIELD_PROTECTED (f, j))
  199.                     fprintf_filtered (stream, "protected ");
  200.                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
  201.                     fprintf_filtered (stream, "private ");
  202.                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
  203.                     fprintf_filtered (stream, "public ");

  204.                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
  205.                     fprintf_filtered (stream, "abstract ");
  206.                   if (TYPE_FN_FIELD_STATIC (f, j))
  207.                     fprintf_filtered (stream, "static ");
  208.                   if (TYPE_FN_FIELD_FINAL (f, j))
  209.                     fprintf_filtered (stream, "final ");
  210.                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
  211.                     fprintf_filtered (stream, "synchronized ");
  212.                   if (TYPE_FN_FIELD_NATIVE (f, j))
  213.                     fprintf_filtered (stream, "native ");

  214.                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
  215.                     {
  216.                       /* Keep GDB from crashing here.  */
  217.                       fprintf_filtered (stream, "<undefined type> %s;\n",
  218.                                         TYPE_FN_FIELD_PHYSNAME (f, j));
  219.                       break;
  220.                     }
  221.                   else if (!is_constructor && !is_full_physname_constructor)
  222.                     {
  223.                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
  224.                                   "", stream, -1);
  225.                       fputs_filtered (" ", stream);
  226.                     }

  227.                   if (TYPE_FN_FIELD_STUB (f, j))
  228.                     /* Build something we can demangle.  */
  229.                     mangled_name = gdb_mangle_name (type, i, j);
  230.                   else
  231.                     mangled_name = physname;

  232.                   demangled_name =
  233.                     gdb_demangle (mangled_name,
  234.                                   DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);

  235.                   if (demangled_name == NULL)
  236.                     demangled_name = xstrdup (mangled_name);

  237.                   {
  238.                     char *demangled_no_class;
  239.                     char *ptr;

  240.                     ptr = demangled_no_class = demangled_name;

  241.                     while (1)
  242.                       {
  243.                         char c;

  244.                         c = *ptr++;

  245.                         if (c == 0 || c == '(')
  246.                           break;
  247.                         if (c == '.')
  248.                           demangled_no_class = ptr;
  249.                       }

  250.                     fputs_filtered (demangled_no_class, stream);
  251.                     xfree (demangled_name);
  252.                   }

  253.                   if (TYPE_FN_FIELD_STUB (f, j))
  254.                     xfree (mangled_name);

  255.                   fprintf_filtered (stream, ";\n");
  256.                 }
  257.             }

  258.           fprintfi_filtered (level, stream, "}");
  259.         }
  260.       break;

  261.     default:
  262.       c_type_print_base (type, stream, show, level, flags);
  263.     }
  264. }

  265. /* LEVEL is the depth to indent lines by.  */

  266. void
  267. java_print_type (struct type *type, const char *varstring,
  268.                  struct ui_file *stream, int show, int level,
  269.                  const struct type_print_options *flags)
  270. {
  271.   int demangled_args;

  272.   java_type_print_base (type, stream, show, level, flags);

  273.   if (varstring != NULL && *varstring != '\0')
  274.     {
  275.       fputs_filtered (" ", stream);
  276.       fputs_filtered (varstring, stream);
  277.     }

  278.   /* For demangled function names, we have the arglist as part of the name,
  279.      so don't print an additional pair of ()'s.  */

  280.   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
  281.   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args, flags);
  282. }