Import gdb-7.0
[dragonfly.git] / contrib / gdb-6 / gdb / jv-typeprint.c
1 /* Support for printing Java types for GDB, the GNU debugger.
2    Copyright (C) 1997, 1998, 1999, 2000, 2007 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 3 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, see <http://www.gnu.org/licenses/>.  */
18
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "gdbtypes.h"
23 #include "value.h"
24 #include "demangle.h"
25 #include "jv-lang.h"
26 #include "gdb_string.h"
27 #include "typeprint.h"
28 #include "c-lang.h"
29 #include "cp-abi.h"
30
31 /* Local functions */
32
33 static void java_type_print_base (struct type * type,
34                                   struct ui_file *stream, int show,
35                                   int level);
36
37 static void
38 java_type_print_derivation_info (struct ui_file *stream, 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 (struct type *type, struct ui_file *stream, int show,
85                       int level)
86 {
87   int i;
88   int len;
89   char *mangled_name;
90   char *demangled_name;
91   QUIT;
92
93   wrap_here ("    ");
94
95   if (type == NULL)
96     {
97       fputs_filtered ("<type unknown>", stream);
98       return;
99     }
100
101   /* When SHOW is zero or less, and there is a valid type name, then always
102      just print the type name directly from the type.  */
103
104   if (show <= 0
105       && TYPE_NAME (type) != NULL)
106     {
107       fputs_filtered (TYPE_NAME (type), stream);
108       return;
109     }
110
111   CHECK_TYPEDEF (type);
112
113   switch (TYPE_CODE (type))
114     {
115     case TYPE_CODE_PTR:
116       java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
117       break;
118
119     case TYPE_CODE_STRUCT:
120       if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
121         {                       /* array type */
122           char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
123           fputs_filtered (name, stream);
124           xfree (name);
125           break;
126         }
127
128       if (show >= 0)
129         fprintf_filtered (stream, "class ");
130
131       if (TYPE_TAG_NAME (type) != NULL)
132         {
133           fputs_filtered (TYPE_TAG_NAME (type), stream);
134           if (show > 0)
135             fputs_filtered (" ", stream);
136         }
137
138       wrap_here ("    ");
139
140       if (show < 0)
141         {
142           /* If we just printed a tag name, no need to print anything else.  */
143           if (TYPE_TAG_NAME (type) == NULL)
144             fprintf_filtered (stream, "{...}");
145         }
146       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
147         {
148           java_type_print_derivation_info (stream, type);
149
150           fprintf_filtered (stream, "{\n");
151           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
152             {
153               if (TYPE_STUB (type))
154                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
155               else
156                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
157             }
158
159           /* If there is a base class for this type,
160              do not print the field that it occupies.  */
161
162           len = TYPE_NFIELDS (type);
163           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
164             {
165               QUIT;
166               /* Don't print out virtual function table.  */
167               if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
168                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
169                 continue;
170
171               /* Don't print the dummy field "class". */
172               if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
173                 continue;
174
175               print_spaces_filtered (level + 4, stream);
176
177               if (HAVE_CPLUS_STRUCT (type))
178                 {
179                   if (TYPE_FIELD_PROTECTED (type, i))
180                     fprintf_filtered (stream, "protected ");
181                   else if (TYPE_FIELD_PRIVATE (type, i))
182                     fprintf_filtered (stream, "private ");
183                   else
184                     fprintf_filtered (stream, "public ");
185                 }
186
187               if (TYPE_FIELD_STATIC (type, i))
188                 fprintf_filtered (stream, "static ");
189
190               java_print_type (TYPE_FIELD_TYPE (type, i),
191                                TYPE_FIELD_NAME (type, i),
192                                stream, show - 1, level + 4);
193
194               fprintf_filtered (stream, ";\n");
195             }
196
197           /* If there are both fields and methods, put a space between. */
198           len = TYPE_NFN_FIELDS (type);
199           if (len)
200             fprintf_filtered (stream, "\n");
201
202           /* Print out the methods */
203
204           for (i = 0; i < len; i++)
205             {
206               struct fn_field *f;
207               int j;
208               char *method_name;
209               char *name;
210               int is_constructor;
211               int n_overloads;
212
213               f = TYPE_FN_FIELDLIST1 (type, i);
214               n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
215               method_name = TYPE_FN_FIELDLIST_NAME (type, i);
216               name = type_name_no_tag (type);
217               is_constructor = name && strcmp (method_name, name) == 0;
218
219               for (j = 0; j < n_overloads; j++)
220                 {
221                   char *physname;
222                   int is_full_physname_constructor;
223
224                   physname = TYPE_FN_FIELD_PHYSNAME (f, j);
225
226                   is_full_physname_constructor
227                     = (is_constructor_name (physname)
228                        || is_destructor_name (physname));
229
230                   QUIT;
231
232                   print_spaces_filtered (level + 4, stream);
233
234                   if (TYPE_FN_FIELD_PROTECTED (f, j))
235                     fprintf_filtered (stream, "protected ");
236                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
237                     fprintf_filtered (stream, "private ");
238                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
239                     fprintf_filtered (stream, "public ");
240
241                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
242                     fprintf_filtered (stream, "abstract ");
243                   if (TYPE_FN_FIELD_STATIC (f, j))
244                     fprintf_filtered (stream, "static ");
245                   if (TYPE_FN_FIELD_FINAL (f, j))
246                     fprintf_filtered (stream, "final ");
247                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
248                     fprintf_filtered (stream, "synchronized ");
249                   if (TYPE_FN_FIELD_NATIVE (f, j))
250                     fprintf_filtered (stream, "native ");
251
252                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
253                     {
254                       /* Keep GDB from crashing here.  */
255                       fprintf_filtered (stream, "<undefined type> %s;\n",
256                                         TYPE_FN_FIELD_PHYSNAME (f, j));
257                       break;
258                     }
259                   else if (!is_constructor && !is_full_physname_constructor)
260                     {
261                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
262                                   "", stream, -1);
263                       fputs_filtered (" ", stream);
264                     }
265
266                   if (TYPE_FN_FIELD_STUB (f, j))
267                     /* Build something we can demangle.  */
268                     mangled_name = gdb_mangle_name (type, i, j);
269                   else
270                     mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
271
272                   demangled_name =
273                     cplus_demangle (mangled_name,
274                                     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
275
276                   if (demangled_name == NULL)
277                     demangled_name = xstrdup (mangled_name);
278
279                   {
280                     char *demangled_no_class;
281                     char *ptr;
282
283                     ptr = demangled_no_class = demangled_name;
284
285                     while (1)
286                       {
287                         char c;
288
289                         c = *ptr++;
290
291                         if (c == 0 || c == '(')
292                           break;
293                         if (c == '.')
294                           demangled_no_class = ptr;
295                       }
296
297                     fputs_filtered (demangled_no_class, stream);
298                     xfree (demangled_name);
299                   }
300
301                   if (TYPE_FN_FIELD_STUB (f, j))
302                     xfree (mangled_name);
303
304                   fprintf_filtered (stream, ";\n");
305                 }
306             }
307
308           fprintfi_filtered (level, stream, "}");
309         }
310       break;
311
312     default:
313       c_type_print_base (type, stream, show, level);
314     }
315 }
316
317 /* LEVEL is the depth to indent lines by.  */
318
319 extern void c_type_print_varspec_suffix (struct type *, struct ui_file *,
320                                          int, int, int);
321
322 void
323 java_print_type (struct type *type, char *varstring, struct ui_file *stream,
324                  int show, int level)
325 {
326   int demangled_args;
327
328   java_type_print_base (type, stream, show, level);
329
330   if (varstring != NULL && *varstring != '\0')
331     {
332       fputs_filtered (" ", stream);
333       fputs_filtered (varstring, stream);
334     }
335
336   /* For demangled function names, we have the arglist as part of the name,
337      so don't print an additional pair of ()'s */
338
339   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
340   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
341 }