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