GDB (API)
/home/stan/gdb/src/gdb/jv-typeprint.c
Go to the documentation of this file.
00001 /* Support for printing Java types for GDB, the GNU debugger.
00002    Copyright (C) 1997-2013 Free Software Foundation, Inc.
00003 
00004    This file is part of GDB.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00018 
00019 
00020 #include "defs.h"
00021 #include "symtab.h"
00022 #include "gdbtypes.h"
00023 #include "value.h"
00024 #include "demangle.h"
00025 #include "gdb-demangle.h"
00026 #include "jv-lang.h"
00027 #include "gdb_string.h"
00028 #include "typeprint.h"
00029 #include "c-lang.h"
00030 #include "cp-abi.h"
00031 #include "cp-support.h"
00032 #include "gdb_assert.h"
00033 
00034 /* Local functions */
00035 
00036 static void java_type_print_base (struct type * type,
00037                                   struct ui_file *stream, int show,
00038                                   int level,
00039                                   const struct type_print_options *flags);
00040 
00041 static void
00042 java_type_print_derivation_info (struct ui_file *stream, struct type *type)
00043 {
00044   const char *name;
00045   int i;
00046   int n_bases;
00047   int prev;
00048 
00049   n_bases = TYPE_N_BASECLASSES (type);
00050 
00051   for (i = 0, prev = 0; i < n_bases; i++)
00052     {
00053       int kind;
00054 
00055       kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E';
00056 
00057       fputs_filtered (kind == prev ? ", "
00058                       : kind == 'I' ? " implements "
00059                       : " extends ",
00060                       stream);
00061       prev = kind;
00062       name = type_name_no_tag (TYPE_BASECLASS (type, i));
00063 
00064       fprintf_filtered (stream, "%s", name ? name : "(null)");
00065     }
00066 
00067   if (i > 0)
00068     fputs_filtered (" ", stream);
00069 }
00070 
00071 /* Print the name of the type (or the ultimate pointer target,
00072    function value or array element), or the description of a
00073    structure or union.
00074 
00075    SHOW positive means print details about the type (e.g. enum values),
00076    and print structure elements passing SHOW - 1 for show.
00077    SHOW negative means just print the type name or struct tag if there is one.
00078    If there is no name, print something sensible but concise like
00079    "struct {...}".
00080    SHOW zero means just print the type name or struct tag if there is one.
00081    If there is no name, print something sensible but not as concise like
00082    "struct {int x; int y;}".
00083 
00084    LEVEL is the number of spaces to indent by.
00085    We increase it for some recursive calls.  */
00086 
00087 static void
00088 java_type_print_base (struct type *type, struct ui_file *stream, int show,
00089                       int level, const struct type_print_options *flags)
00090 {
00091   int i;
00092   int len;
00093   char *mangled_name;
00094   char *demangled_name;
00095 
00096   QUIT;
00097   wrap_here ("    ");
00098 
00099   if (type == NULL)
00100     {
00101       fputs_filtered ("<type unknown>", stream);
00102       return;
00103     }
00104 
00105   /* When SHOW is zero or less, and there is a valid type name, then always
00106      just print the type name directly from the type.  */
00107 
00108   if (show <= 0
00109       && TYPE_NAME (type) != NULL)
00110     {
00111       fputs_filtered (TYPE_NAME (type), stream);
00112       return;
00113     }
00114 
00115   CHECK_TYPEDEF (type);
00116 
00117   switch (TYPE_CODE (type))
00118     {
00119     case TYPE_CODE_PTR:
00120       java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level,
00121                             flags);
00122       break;
00123 
00124     case TYPE_CODE_STRUCT:
00125       if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
00126         {                       /* array type */
00127           char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
00128 
00129           fputs_filtered (name, stream);
00130           xfree (name);
00131           break;
00132         }
00133 
00134       if (show >= 0)
00135         fprintf_filtered (stream, "class ");
00136 
00137       if (TYPE_TAG_NAME (type) != NULL)
00138         {
00139           fputs_filtered (TYPE_TAG_NAME (type), stream);
00140           if (show > 0)
00141             fputs_filtered (" ", stream);
00142         }
00143 
00144       wrap_here ("    ");
00145 
00146       if (show < 0)
00147         {
00148           /* If we just printed a tag name, no need to print anything else.  */
00149           if (TYPE_TAG_NAME (type) == NULL)
00150             fprintf_filtered (stream, "{...}");
00151         }
00152       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
00153         {
00154           java_type_print_derivation_info (stream, type);
00155 
00156           fprintf_filtered (stream, "{\n");
00157           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
00158             {
00159               if (TYPE_STUB (type))
00160                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
00161               else
00162                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
00163             }
00164 
00165           /* If there is a base class for this type,
00166              do not print the field that it occupies.  */
00167 
00168           len = TYPE_NFIELDS (type);
00169           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
00170             {
00171               QUIT;
00172               /* Don't print out virtual function table.  */
00173               if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
00174                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
00175                 continue;
00176 
00177               /* Don't print the dummy field "class".  */
00178               if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
00179                 continue;
00180 
00181               print_spaces_filtered (level + 4, stream);
00182 
00183               if (HAVE_CPLUS_STRUCT (type))
00184                 {
00185                   if (TYPE_FIELD_PROTECTED (type, i))
00186                     fprintf_filtered (stream, "protected ");
00187                   else if (TYPE_FIELD_PRIVATE (type, i))
00188                     fprintf_filtered (stream, "private ");
00189                   else
00190                     fprintf_filtered (stream, "public ");
00191                 }
00192 
00193               if (field_is_static (&TYPE_FIELD (type, i)))
00194                 fprintf_filtered (stream, "static ");
00195 
00196               java_print_type (TYPE_FIELD_TYPE (type, i),
00197                                TYPE_FIELD_NAME (type, i),
00198                                stream, show - 1, level + 4, flags);
00199 
00200               fprintf_filtered (stream, ";\n");
00201             }
00202 
00203           /* If there are both fields and methods, put a space between.  */
00204           len = TYPE_NFN_FIELDS (type);
00205           if (len)
00206             fprintf_filtered (stream, "\n");
00207 
00208           /* Print out the methods.  */
00209 
00210           for (i = 0; i < len; i++)
00211             {
00212               struct fn_field *f;
00213               int j;
00214               const char *method_name;
00215               const char *name;
00216               int is_constructor;
00217               int n_overloads;
00218 
00219               f = TYPE_FN_FIELDLIST1 (type, i);
00220               n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
00221               method_name = TYPE_FN_FIELDLIST_NAME (type, i);
00222               name = type_name_no_tag (type);
00223               is_constructor = name && strcmp (method_name, name) == 0;
00224 
00225               for (j = 0; j < n_overloads; j++)
00226                 {
00227                   const char *real_physname;
00228                   char *physname, *p;
00229                   int is_full_physname_constructor;
00230 
00231                   real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);
00232 
00233                   /* The physname will contain the return type
00234                      after the final closing parenthesis.  Strip it off.  */
00235                   p = strrchr (real_physname, ')');
00236                   gdb_assert (p != NULL);
00237                   ++p;   /* Keep the trailing ')'.  */
00238                   physname = alloca (p - real_physname + 1);
00239                   memcpy (physname, real_physname, p - real_physname);
00240                   physname[p - real_physname] = '\0';
00241 
00242                   is_full_physname_constructor
00243                     = (TYPE_FN_FIELD_CONSTRUCTOR (f, j)
00244                        || is_constructor_name (physname)
00245                        || is_destructor_name (physname));
00246 
00247                   QUIT;
00248 
00249                   print_spaces_filtered (level + 4, stream);
00250 
00251                   if (TYPE_FN_FIELD_PROTECTED (f, j))
00252                     fprintf_filtered (stream, "protected ");
00253                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
00254                     fprintf_filtered (stream, "private ");
00255                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
00256                     fprintf_filtered (stream, "public ");
00257 
00258                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
00259                     fprintf_filtered (stream, "abstract ");
00260                   if (TYPE_FN_FIELD_STATIC (f, j))
00261                     fprintf_filtered (stream, "static ");
00262                   if (TYPE_FN_FIELD_FINAL (f, j))
00263                     fprintf_filtered (stream, "final ");
00264                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
00265                     fprintf_filtered (stream, "synchronized ");
00266                   if (TYPE_FN_FIELD_NATIVE (f, j))
00267                     fprintf_filtered (stream, "native ");
00268 
00269                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
00270                     {
00271                       /* Keep GDB from crashing here.  */
00272                       fprintf_filtered (stream, "<undefined type> %s;\n",
00273                                         TYPE_FN_FIELD_PHYSNAME (f, j));
00274                       break;
00275                     }
00276                   else if (!is_constructor && !is_full_physname_constructor)
00277                     {
00278                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
00279                                   "", stream, -1);
00280                       fputs_filtered (" ", stream);
00281                     }
00282 
00283                   if (TYPE_FN_FIELD_STUB (f, j))
00284                     /* Build something we can demangle.  */
00285                     mangled_name = gdb_mangle_name (type, i, j);
00286                   else
00287                     mangled_name = physname;
00288 
00289                   demangled_name =
00290                     gdb_demangle (mangled_name,
00291                                   DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
00292 
00293                   if (demangled_name == NULL)
00294                     demangled_name = xstrdup (mangled_name);
00295 
00296                   {
00297                     char *demangled_no_class;
00298                     char *ptr;
00299 
00300                     ptr = demangled_no_class = demangled_name;
00301 
00302                     while (1)
00303                       {
00304                         char c;
00305 
00306                         c = *ptr++;
00307 
00308                         if (c == 0 || c == '(')
00309                           break;
00310                         if (c == '.')
00311                           demangled_no_class = ptr;
00312                       }
00313 
00314                     fputs_filtered (demangled_no_class, stream);
00315                     xfree (demangled_name);
00316                   }
00317 
00318                   if (TYPE_FN_FIELD_STUB (f, j))
00319                     xfree (mangled_name);
00320 
00321                   fprintf_filtered (stream, ";\n");
00322                 }
00323             }
00324 
00325           fprintfi_filtered (level, stream, "}");
00326         }
00327       break;
00328 
00329     default:
00330       c_type_print_base (type, stream, show, level, flags);
00331     }
00332 }
00333 
00334 /* LEVEL is the depth to indent lines by.  */
00335 
00336 void
00337 java_print_type (struct type *type, const char *varstring,
00338                  struct ui_file *stream, int show, int level,
00339                  const struct type_print_options *flags)
00340 {
00341   int demangled_args;
00342 
00343   java_type_print_base (type, stream, show, level, flags);
00344 
00345   if (varstring != NULL && *varstring != '\0')
00346     {
00347       fputs_filtered (" ", stream);
00348       fputs_filtered (varstring, stream);
00349     }
00350 
00351   /* For demangled function names, we have the arglist as part of the name,
00352      so don't print an additional pair of ()'s.  */
00353 
00354   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
00355   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args, flags);
00356 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines