Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / jv-typeprint.c
1 /* Support for printing Java types for GDB, the GNU debugger.
2    Copyright (C) 1997, 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20
21 #include "defs.h"
22 #include "symtab.h"
23 #include "gdbtypes.h"
24 #include "value.h"
25 #include "demangle.h"
26 #include "jv-lang.h"
27 #include "gdb_string.h"
28 #include "typeprint.h"
29 #include "c-lang.h"
30 #include "cp-abi.h"
31 #include "gdb_assert.h"
32
33 /* Local functions */
34
35 static void java_type_print_base (struct type * type,
36                                   struct ui_file *stream, int show,
37                                   int level);
38
39 static void
40 java_type_print_derivation_info (struct ui_file *stream, struct type *type)
41 {
42   char *name;
43   int i;
44   int n_bases;
45   int prev;
46
47   n_bases = TYPE_N_BASECLASSES (type);
48
49   for (i = 0, prev = 0; i < n_bases; i++)
50     {
51       int kind;
52
53       kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E';
54
55       fputs_filtered (kind == prev ? ", "
56                       : kind == 'I' ? " implements "
57                       : " extends ",
58                       stream);
59       prev = kind;
60       name = type_name_no_tag (TYPE_BASECLASS (type, i));
61
62       fprintf_filtered (stream, "%s", name ? name : "(null)");
63     }
64
65   if (i > 0)
66     fputs_filtered (" ", stream);
67 }
68
69 /* Print the name of the type (or the ultimate pointer target,
70    function value or array element), or the description of a
71    structure or union.
72
73    SHOW positive means print details about the type (e.g. enum values),
74    and print structure elements passing SHOW - 1 for show.
75    SHOW negative means just print the type name or struct tag if there is one.
76    If there is no name, print something sensible but concise like
77    "struct {...}".
78    SHOW zero means just print the type name or struct tag if there is one.
79    If there is no name, print something sensible but not as concise like
80    "struct {int x; int y;}".
81
82    LEVEL is the number of spaces to indent by.
83    We increase it for some recursive calls.  */
84
85 static void
86 java_type_print_base (struct type *type, struct ui_file *stream, int show,
87                       int level)
88 {
89   int i;
90   int len;
91   char *mangled_name;
92   char *demangled_name;
93
94   QUIT;
95   wrap_here ("    ");
96
97   if (type == NULL)
98     {
99       fputs_filtered ("<type unknown>", stream);
100       return;
101     }
102
103   /* When SHOW is zero or less, and there is a valid type name, then always
104      just print the type name directly from the type.  */
105
106   if (show <= 0
107       && TYPE_NAME (type) != NULL)
108     {
109       fputs_filtered (TYPE_NAME (type), stream);
110       return;
111     }
112
113   CHECK_TYPEDEF (type);
114
115   switch (TYPE_CODE (type))
116     {
117     case TYPE_CODE_PTR:
118       java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
119       break;
120
121     case TYPE_CODE_STRUCT:
122       if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
123         {                       /* array type */
124           char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
125
126           fputs_filtered (name, stream);
127           xfree (name);
128           break;
129         }
130
131       if (show >= 0)
132         fprintf_filtered (stream, "class ");
133
134       if (TYPE_TAG_NAME (type) != NULL)
135         {
136           fputs_filtered (TYPE_TAG_NAME (type), stream);
137           if (show > 0)
138             fputs_filtered (" ", stream);
139         }
140
141       wrap_here ("    ");
142
143       if (show < 0)
144         {
145           /* If we just printed a tag name, no need to print anything else.  */
146           if (TYPE_TAG_NAME (type) == NULL)
147             fprintf_filtered (stream, "{...}");
148         }
149       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
150         {
151           java_type_print_derivation_info (stream, type);
152
153           fprintf_filtered (stream, "{\n");
154           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
155             {
156               if (TYPE_STUB (type))
157                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
158               else
159                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
160             }
161
162           /* If there is a base class for this type,
163              do not print the field that it occupies.  */
164
165           len = TYPE_NFIELDS (type);
166           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
167             {
168               QUIT;
169               /* Don't print out virtual function table.  */
170               if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
171                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
172                 continue;
173
174               /* Don't print the dummy field "class".  */
175               if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
176                 continue;
177
178               print_spaces_filtered (level + 4, stream);
179
180               if (HAVE_CPLUS_STRUCT (type))
181                 {
182                   if (TYPE_FIELD_PROTECTED (type, i))
183                     fprintf_filtered (stream, "protected ");
184                   else if (TYPE_FIELD_PRIVATE (type, i))
185                     fprintf_filtered (stream, "private ");
186                   else
187                     fprintf_filtered (stream, "public ");
188                 }
189
190               if (field_is_static (&TYPE_FIELD (type, i)))
191                 fprintf_filtered (stream, "static ");
192
193               java_print_type (TYPE_FIELD_TYPE (type, i),
194                                TYPE_FIELD_NAME (type, i),
195                                stream, show - 1, level + 4);
196
197               fprintf_filtered (stream, ";\n");
198             }
199
200           /* If there are both fields and methods, put a space between.  */
201           len = TYPE_NFN_FIELDS (type);
202           if (len)
203             fprintf_filtered (stream, "\n");
204
205           /* Print out the methods.  */
206
207           for (i = 0; i < len; i++)
208             {
209               struct fn_field *f;
210               int j;
211               char *method_name;
212               char *name;
213               int is_constructor;
214               int n_overloads;
215
216               f = TYPE_FN_FIELDLIST1 (type, i);
217               n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
218               method_name = TYPE_FN_FIELDLIST_NAME (type, i);
219               name = type_name_no_tag (type);
220               is_constructor = name && strcmp (method_name, name) == 0;
221
222               for (j = 0; j < n_overloads; j++)
223                 {
224                   char *real_physname, *physname, *p;
225                   int is_full_physname_constructor;
226
227                   real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);
228
229                   /* The physname will contain the return type
230                      after the final closing parenthesis.  Strip it off.  */
231                   p = strrchr (real_physname, ')');
232                   gdb_assert (p != NULL);
233                   ++p;   /* Keep the trailing ')'.  */
234                   physname = alloca (p - real_physname + 1);
235                   memcpy (physname, real_physname, p - real_physname);
236                   physname[p - real_physname] = '\0';
237
238                   is_full_physname_constructor
239                     = (is_constructor_name (physname)
240                        || is_destructor_name (physname));
241
242                   QUIT;
243
244                   print_spaces_filtered (level + 4, stream);
245
246                   if (TYPE_FN_FIELD_PROTECTED (f, j))
247                     fprintf_filtered (stream, "protected ");
248                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
249                     fprintf_filtered (stream, "private ");
250                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
251                     fprintf_filtered (stream, "public ");
252
253                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
254                     fprintf_filtered (stream, "abstract ");
255                   if (TYPE_FN_FIELD_STATIC (f, j))
256                     fprintf_filtered (stream, "static ");
257                   if (TYPE_FN_FIELD_FINAL (f, j))
258                     fprintf_filtered (stream, "final ");
259                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
260                     fprintf_filtered (stream, "synchronized ");
261                   if (TYPE_FN_FIELD_NATIVE (f, j))
262                     fprintf_filtered (stream, "native ");
263
264                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
265                     {
266                       /* Keep GDB from crashing here.  */
267                       fprintf_filtered (stream, "<undefined type> %s;\n",
268                                         TYPE_FN_FIELD_PHYSNAME (f, j));
269                       break;
270                     }
271                   else if (!is_constructor && !is_full_physname_constructor)
272                     {
273                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
274                                   "", stream, -1);
275                       fputs_filtered (" ", stream);
276                     }
277
278                   if (TYPE_FN_FIELD_STUB (f, j))
279                     /* Build something we can demangle.  */
280                     mangled_name = gdb_mangle_name (type, i, j);
281                   else
282                     mangled_name = physname;
283
284                   demangled_name =
285                     cplus_demangle (mangled_name,
286                                     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
287
288                   if (demangled_name == NULL)
289                     demangled_name = xstrdup (mangled_name);
290
291                   {
292                     char *demangled_no_class;
293                     char *ptr;
294
295                     ptr = demangled_no_class = demangled_name;
296
297                     while (1)
298                       {
299                         char c;
300
301                         c = *ptr++;
302
303                         if (c == 0 || c == '(')
304                           break;
305                         if (c == '.')
306                           demangled_no_class = ptr;
307                       }
308
309                     fputs_filtered (demangled_no_class, stream);
310                     xfree (demangled_name);
311                   }
312
313                   if (TYPE_FN_FIELD_STUB (f, j))
314                     xfree (mangled_name);
315
316                   fprintf_filtered (stream, ";\n");
317                 }
318             }
319
320           fprintfi_filtered (level, stream, "}");
321         }
322       break;
323
324     default:
325       c_type_print_base (type, stream, show, level);
326     }
327 }
328
329 /* LEVEL is the depth to indent lines by.  */
330
331 extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
332                                          int, int, int);
333
334 void
335 java_print_type (struct type *type, const char *varstring,
336                  struct ui_file *stream, int show, int level)
337 {
338   int demangled_args;
339
340   java_type_print_base (type, stream, show, level);
341
342   if (varstring != NULL && *varstring != '\0')
343     {
344       fputs_filtered (" ", stream);
345       fputs_filtered (varstring, stream);
346     }
347
348   /* For demangled function names, we have the arglist as part of the name,
349      so don't print an additional pair of ()'s.  */
350
351   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
352   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
353 }