import gdb-1999-05-25 snapshot
[external/binutils.git] / gdb / jv-typeprint.c
1 /* Support for printing Java types for GDB, the GNU debugger.
2    Copyright 1997, 1998, 1999 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, Boston, MA 02111-1307, USA.  */
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
31 /* Local functions */
32
33 static void java_type_print_base PARAMS ((struct type *type, GDB_FILE *stream, int show, int level));
34
35 static void
36 java_type_print_derivation_info (stream, type)
37      GDB_FILE *stream;
38      struct type *type;
39 {
40   char *name;
41   int i;
42   int n_bases;
43   int prev;
44
45   n_bases = TYPE_N_BASECLASSES (type);
46
47   for (i = 0, prev = 0; i < n_bases; i++)
48     {
49       int kind;
50
51       kind = BASETYPE_VIA_VIRTUAL(type, i) ? 'I' : 'E';
52
53       fputs_filtered (kind == prev ? ", "
54                       : kind == 'I' ? " implements "
55                       : " extends ",
56                       stream);
57       prev = kind;
58       name = type_name_no_tag (TYPE_BASECLASS (type, i));
59
60       fprintf_filtered (stream, "%s", name ? name : "(null)");
61     }
62
63   if (i > 0)
64     fputs_filtered (" ", stream);
65 }
66
67 /* Print the name of the type (or the ultimate pointer target,
68    function value or array element), or the description of a
69    structure or union.
70
71    SHOW positive means print details about the type (e.g. enum values),
72    and print structure elements passing SHOW - 1 for show.
73    SHOW negative means just print the type name or struct tag if there is one.
74    If there is no name, print something sensible but concise like
75    "struct {...}".
76    SHOW zero means just print the type name or struct tag if there is one.
77    If there is no name, print something sensible but not as concise like
78    "struct {int x; int y;}".
79
80    LEVEL is the number of spaces to indent by.
81    We increase it for some recursive calls.  */
82
83 static void
84 java_type_print_base (type, stream, show, level)
85      struct type *type;
86      GDB_FILE *stream;
87      int show;
88      int level;
89 {
90   register int i;
91   register int len;
92   char *mangled_name;
93   char *demangled_name;
94   QUIT;
95
96   wrap_here ("    ");
97
98   if (type == NULL)
99     {
100       fputs_filtered ("<type unknown>", stream);
101       return;
102     }
103
104   /* When SHOW is zero or less, and there is a valid type name, then always
105      just print the type name directly from the type.  */
106
107   if (show <= 0
108       && TYPE_NAME (type) != NULL)
109     {
110       fputs_filtered (TYPE_NAME (type), stream);
111       return;
112     }
113
114   CHECK_TYPEDEF (type);
115
116   switch (TYPE_CODE (type))
117     {
118     case TYPE_CODE_PTR:
119       java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
120       break;
121
122     case TYPE_CODE_STRUCT:
123       if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
124         {                       /* array type */
125           char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
126           fputs_filtered (name, stream);
127           free (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_FLAGS (type) & TYPE_FLAG_STUB)
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 (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
171                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
172                 continue;
173
174               /* Don't print the dummy field "class". */
175               if (STREQN (TYPE_FIELD_NAME (type, i), "class", 5))
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 (TYPE_FIELD_STATIC (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 && STREQ (method_name, name);
221
222               for (j = 0; j < n_overloads; j++)
223                 {
224                   char *physname;
225                   int is_full_physname_constructor;
226
227                   physname = TYPE_FN_FIELD_PHYSNAME (f, j);
228
229                   is_full_physname_constructor = 
230                     ((physname[0] == '_' && physname[1] == '_'
231                       && strchr ("0123456789Qt", physname[2]))
232                      || STREQN (physname, "__ct__", 6)
233                      || DESTRUCTOR_PREFIX_P (physname)
234                      || STREQN (physname, "__dt__", 6));
235
236                   QUIT;
237
238                   print_spaces_filtered (level + 4, stream);
239
240                   if (TYPE_FN_FIELD_PROTECTED (f, j))
241                     fprintf_filtered (stream, "protected ");
242                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
243                     fprintf_filtered (stream, "private ");
244                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
245                     fprintf_filtered (stream, "public ");
246
247                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
248                     fprintf_filtered (stream, "abstract ");
249                   if (TYPE_FN_FIELD_STATIC (f, j))
250                     fprintf_filtered (stream, "static ");
251                   if (TYPE_FN_FIELD_FINAL (f, j))
252                     fprintf_filtered (stream, "final ");
253                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
254                     fprintf_filtered (stream, "synchronized ");
255                   if (TYPE_FN_FIELD_NATIVE (f, j))
256                     fprintf_filtered (stream, "native ");
257
258                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
259                     {
260                       /* Keep GDB from crashing here.  */
261                       fprintf_filtered (stream, "<undefined type> %s;\n",
262                                TYPE_FN_FIELD_PHYSNAME (f, j));
263                       break;
264                     }
265                   else if (!is_constructor && !is_full_physname_constructor)
266                     {
267                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
268                                   "", stream, -1);
269                       fputs_filtered (" ", stream);
270                     }
271
272                   if (TYPE_FN_FIELD_STUB (f, j))
273                     /* Build something we can demangle.  */
274                     mangled_name = gdb_mangle_name (type, i, j);
275                   else
276                     mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
277
278                   demangled_name =
279                     cplus_demangle (mangled_name,
280                                     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
281
282                   if (demangled_name == NULL)
283                     demangled_name = strdup (mangled_name);
284
285                   {
286                     char *demangled_no_class;
287                     char *ptr;
288
289                     ptr = demangled_no_class = demangled_name;
290
291                     while (1)
292                       {
293                         char c;
294
295                         c = *ptr++;
296
297                         if (c == 0 || c == '(')
298                           break;
299                         if (c == '.')
300                           demangled_no_class = ptr;
301                       }
302
303                     fputs_filtered (demangled_no_class, stream);
304                     free (demangled_name);
305                   }
306
307                   if (TYPE_FN_FIELD_STUB (f, j))
308                     free (mangled_name);
309
310                   fprintf_filtered (stream, ";\n");
311                 }
312             }
313
314           fprintfi_filtered (level, stream, "}");
315         }
316       break;
317
318       default:
319         c_type_print_base (type, stream, show, level);
320     }
321 }
322
323 /* LEVEL is the depth to indent lines by.  */
324
325 extern void
326 c_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *, int, int, int));
327
328 void
329 java_print_type (type, varstring, stream, show, level)
330      struct type *type;
331      char *varstring;
332      GDB_FILE *stream;
333      int show;
334      int level;
335 {
336   int demangled_args;
337
338   java_type_print_base (type, stream, show, level);
339
340   if (varstring != NULL && *varstring != '\0')
341     {
342       fputs_filtered (" ", stream);
343       fputs_filtered (varstring, stream);
344     }
345
346   /* For demangled function names, we have the arglist as part of the name,
347      so don't print an additional pair of ()'s */
348
349   demangled_args = strchr(varstring, '(') != NULL;
350   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
351 }