* c-typeprint.c (c_type_print_args): Don't print "void"
[external/binutils.git] / 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
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   QUIT;
94
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           fputs_filtered (name, stream);
126           xfree (name);
127           break;
128         }
129
130       if (show >= 0)
131         fprintf_filtered (stream, "class ");
132
133       if (TYPE_TAG_NAME (type) != NULL)
134         {
135           fputs_filtered (TYPE_TAG_NAME (type), stream);
136           if (show > 0)
137             fputs_filtered (" ", stream);
138         }
139
140       wrap_here ("    ");
141
142       if (show < 0)
143         {
144           /* If we just printed a tag name, no need to print anything else.  */
145           if (TYPE_TAG_NAME (type) == NULL)
146             fprintf_filtered (stream, "{...}");
147         }
148       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
149         {
150           java_type_print_derivation_info (stream, type);
151
152           fprintf_filtered (stream, "{\n");
153           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
154             {
155               if (TYPE_STUB (type))
156                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
157               else
158                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
159             }
160
161           /* If there is a base class for this type,
162              do not print the field that it occupies.  */
163
164           len = TYPE_NFIELDS (type);
165           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
166             {
167               QUIT;
168               /* Don't print out virtual function table.  */
169               if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
170                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
171                 continue;
172
173               /* Don't print the dummy field "class". */
174               if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
175                 continue;
176
177               print_spaces_filtered (level + 4, stream);
178
179               if (HAVE_CPLUS_STRUCT (type))
180                 {
181                   if (TYPE_FIELD_PROTECTED (type, i))
182                     fprintf_filtered (stream, "protected ");
183                   else if (TYPE_FIELD_PRIVATE (type, i))
184                     fprintf_filtered (stream, "private ");
185                   else
186                     fprintf_filtered (stream, "public ");
187                 }
188
189               if (field_is_static (&TYPE_FIELD (type, i)))
190                 fprintf_filtered (stream, "static ");
191
192               java_print_type (TYPE_FIELD_TYPE (type, i),
193                                TYPE_FIELD_NAME (type, i),
194                                stream, show - 1, level + 4);
195
196               fprintf_filtered (stream, ";\n");
197             }
198
199           /* If there are both fields and methods, put a space between. */
200           len = TYPE_NFN_FIELDS (type);
201           if (len)
202             fprintf_filtered (stream, "\n");
203
204           /* Print out the methods */
205
206           for (i = 0; i < len; i++)
207             {
208               struct fn_field *f;
209               int j;
210               char *method_name;
211               char *name;
212               int is_constructor;
213               int n_overloads;
214
215               f = TYPE_FN_FIELDLIST1 (type, i);
216               n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
217               method_name = TYPE_FN_FIELDLIST_NAME (type, i);
218               name = type_name_no_tag (type);
219               is_constructor = name && strcmp (method_name, name) == 0;
220
221               for (j = 0; j < n_overloads; j++)
222                 {
223                   char *real_physname, *physname, *p;
224                   int is_full_physname_constructor;
225
226                   real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);
227
228                   /* The physname will contain the return type
229                      after the final closing parenthesis.  Strip it off.  */
230                   p = strrchr (real_physname, ')');
231                   gdb_assert (p != NULL);
232                   ++p;   /* Keep the trailing ')'.  */
233                   physname = alloca (p - real_physname + 1);
234                   memcpy (physname, real_physname, p - real_physname);
235                   physname[p - real_physname] = '\0';
236
237                   is_full_physname_constructor
238                     = (is_constructor_name (physname)
239                        || is_destructor_name (physname));
240
241                   QUIT;
242
243                   print_spaces_filtered (level + 4, stream);
244
245                   if (TYPE_FN_FIELD_PROTECTED (f, j))
246                     fprintf_filtered (stream, "protected ");
247                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
248                     fprintf_filtered (stream, "private ");
249                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
250                     fprintf_filtered (stream, "public ");
251
252                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
253                     fprintf_filtered (stream, "abstract ");
254                   if (TYPE_FN_FIELD_STATIC (f, j))
255                     fprintf_filtered (stream, "static ");
256                   if (TYPE_FN_FIELD_FINAL (f, j))
257                     fprintf_filtered (stream, "final ");
258                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
259                     fprintf_filtered (stream, "synchronized ");
260                   if (TYPE_FN_FIELD_NATIVE (f, j))
261                     fprintf_filtered (stream, "native ");
262
263                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
264                     {
265                       /* Keep GDB from crashing here.  */
266                       fprintf_filtered (stream, "<undefined type> %s;\n",
267                                         TYPE_FN_FIELD_PHYSNAME (f, j));
268                       break;
269                     }
270                   else if (!is_constructor && !is_full_physname_constructor)
271                     {
272                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
273                                   "", stream, -1);
274                       fputs_filtered (" ", stream);
275                     }
276
277                   if (TYPE_FN_FIELD_STUB (f, j))
278                     /* Build something we can demangle.  */
279                     mangled_name = gdb_mangle_name (type, i, j);
280                   else
281                     mangled_name = physname;
282
283                   demangled_name =
284                     cplus_demangle (mangled_name,
285                                     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
286
287                   if (demangled_name == NULL)
288                     demangled_name = xstrdup (mangled_name);
289
290                   {
291                     char *demangled_no_class;
292                     char *ptr;
293
294                     ptr = demangled_no_class = demangled_name;
295
296                     while (1)
297                       {
298                         char c;
299
300                         c = *ptr++;
301
302                         if (c == 0 || c == '(')
303                           break;
304                         if (c == '.')
305                           demangled_no_class = ptr;
306                       }
307
308                     fputs_filtered (demangled_no_class, stream);
309                     xfree (demangled_name);
310                   }
311
312                   if (TYPE_FN_FIELD_STUB (f, j))
313                     xfree (mangled_name);
314
315                   fprintf_filtered (stream, ";\n");
316                 }
317             }
318
319           fprintfi_filtered (level, stream, "}");
320         }
321       break;
322
323     default:
324       c_type_print_base (type, stream, show, level);
325     }
326 }
327
328 /* LEVEL is the depth to indent lines by.  */
329
330 extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
331                                          int, int, int);
332
333 void
334 java_print_type (struct type *type, char *varstring, struct ui_file *stream,
335                  int show, int level)
336 {
337   int demangled_args;
338
339   java_type_print_base (type, stream, show, level);
340
341   if (varstring != NULL && *varstring != '\0')
342     {
343       fputs_filtered (" ", stream);
344       fputs_filtered (varstring, stream);
345     }
346
347   /* For demangled function names, we have the arglist as part of the name,
348      so don't print an additional pair of ()'s */
349
350   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
351   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
352 }