Upgrade GDB from 7.4.1 to 7.6.1 on the 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-2013 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 "gdb-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                                   const struct type_print_options *flags);
39
40 static void
41 java_type_print_derivation_info (struct ui_file *stream, struct type *type)
42 {
43   const char *name;
44   int i;
45   int n_bases;
46   int prev;
47
48   n_bases = TYPE_N_BASECLASSES (type);
49
50   for (i = 0, prev = 0; i < n_bases; i++)
51     {
52       int kind;
53
54       kind = BASETYPE_VIA_VIRTUAL (type, i) ? 'I' : 'E';
55
56       fputs_filtered (kind == prev ? ", "
57                       : kind == 'I' ? " implements "
58                       : " extends ",
59                       stream);
60       prev = kind;
61       name = type_name_no_tag (TYPE_BASECLASS (type, i));
62
63       fprintf_filtered (stream, "%s", name ? name : "(null)");
64     }
65
66   if (i > 0)
67     fputs_filtered (" ", stream);
68 }
69
70 /* Print the name of the type (or the ultimate pointer target,
71    function value or array element), or the description of a
72    structure or union.
73
74    SHOW positive means print details about the type (e.g. enum values),
75    and print structure elements passing SHOW - 1 for show.
76    SHOW negative means just print the type name or struct tag if there is one.
77    If there is no name, print something sensible but concise like
78    "struct {...}".
79    SHOW zero means just print the type name or struct tag if there is one.
80    If there is no name, print something sensible but not as concise like
81    "struct {int x; int y;}".
82
83    LEVEL is the number of spaces to indent by.
84    We increase it for some recursive calls.  */
85
86 static void
87 java_type_print_base (struct type *type, struct ui_file *stream, int show,
88                       int level, const struct type_print_options *flags)
89 {
90   int i;
91   int len;
92   char *mangled_name;
93   char *demangled_name;
94
95   QUIT;
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                             flags);
121       break;
122
123     case TYPE_CODE_STRUCT:
124       if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[')
125         {                       /* array type */
126           char *name = java_demangle_type_signature (TYPE_TAG_NAME (type));
127
128           fputs_filtered (name, stream);
129           xfree (name);
130           break;
131         }
132
133       if (show >= 0)
134         fprintf_filtered (stream, "class ");
135
136       if (TYPE_TAG_NAME (type) != NULL)
137         {
138           fputs_filtered (TYPE_TAG_NAME (type), stream);
139           if (show > 0)
140             fputs_filtered (" ", stream);
141         }
142
143       wrap_here ("    ");
144
145       if (show < 0)
146         {
147           /* If we just printed a tag name, no need to print anything else.  */
148           if (TYPE_TAG_NAME (type) == NULL)
149             fprintf_filtered (stream, "{...}");
150         }
151       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
152         {
153           java_type_print_derivation_info (stream, type);
154
155           fprintf_filtered (stream, "{\n");
156           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
157             {
158               if (TYPE_STUB (type))
159                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
160               else
161                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
162             }
163
164           /* If there is a base class for this type,
165              do not print the field that it occupies.  */
166
167           len = TYPE_NFIELDS (type);
168           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
169             {
170               QUIT;
171               /* Don't print out virtual function table.  */
172               if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0
173                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
174                 continue;
175
176               /* Don't print the dummy field "class".  */
177               if (strncmp (TYPE_FIELD_NAME (type, i), "class", 5) == 0)
178                 continue;
179
180               print_spaces_filtered (level + 4, stream);
181
182               if (HAVE_CPLUS_STRUCT (type))
183                 {
184                   if (TYPE_FIELD_PROTECTED (type, i))
185                     fprintf_filtered (stream, "protected ");
186                   else if (TYPE_FIELD_PRIVATE (type, i))
187                     fprintf_filtered (stream, "private ");
188                   else
189                     fprintf_filtered (stream, "public ");
190                 }
191
192               if (field_is_static (&TYPE_FIELD (type, i)))
193                 fprintf_filtered (stream, "static ");
194
195               java_print_type (TYPE_FIELD_TYPE (type, i),
196                                TYPE_FIELD_NAME (type, i),
197                                stream, show - 1, level + 4, flags);
198
199               fprintf_filtered (stream, ";\n");
200             }
201
202           /* If there are both fields and methods, put a space between.  */
203           len = TYPE_NFN_FIELDS (type);
204           if (len)
205             fprintf_filtered (stream, "\n");
206
207           /* Print out the methods.  */
208
209           for (i = 0; i < len; i++)
210             {
211               struct fn_field *f;
212               int j;
213               const char *method_name;
214               const char *name;
215               int is_constructor;
216               int n_overloads;
217
218               f = TYPE_FN_FIELDLIST1 (type, i);
219               n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i);
220               method_name = TYPE_FN_FIELDLIST_NAME (type, i);
221               name = type_name_no_tag (type);
222               is_constructor = name && strcmp (method_name, name) == 0;
223
224               for (j = 0; j < n_overloads; j++)
225                 {
226                   const char *real_physname;
227                   char *physname, *p;
228                   int is_full_physname_constructor;
229
230                   real_physname = TYPE_FN_FIELD_PHYSNAME (f, j);
231
232                   /* The physname will contain the return type
233                      after the final closing parenthesis.  Strip it off.  */
234                   p = strrchr (real_physname, ')');
235                   gdb_assert (p != NULL);
236                   ++p;   /* Keep the trailing ')'.  */
237                   physname = alloca (p - real_physname + 1);
238                   memcpy (physname, real_physname, p - real_physname);
239                   physname[p - real_physname] = '\0';
240
241                   is_full_physname_constructor
242                     = (TYPE_FN_FIELD_CONSTRUCTOR (f, j)
243                        || is_constructor_name (physname)
244                        || is_destructor_name (physname));
245
246                   QUIT;
247
248                   print_spaces_filtered (level + 4, stream);
249
250                   if (TYPE_FN_FIELD_PROTECTED (f, j))
251                     fprintf_filtered (stream, "protected ");
252                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
253                     fprintf_filtered (stream, "private ");
254                   else if (TYPE_FN_FIELD_PUBLIC (f, j))
255                     fprintf_filtered (stream, "public ");
256
257                   if (TYPE_FN_FIELD_ABSTRACT (f, j))
258                     fprintf_filtered (stream, "abstract ");
259                   if (TYPE_FN_FIELD_STATIC (f, j))
260                     fprintf_filtered (stream, "static ");
261                   if (TYPE_FN_FIELD_FINAL (f, j))
262                     fprintf_filtered (stream, "final ");
263                   if (TYPE_FN_FIELD_SYNCHRONIZED (f, j))
264                     fprintf_filtered (stream, "synchronized ");
265                   if (TYPE_FN_FIELD_NATIVE (f, j))
266                     fprintf_filtered (stream, "native ");
267
268                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
269                     {
270                       /* Keep GDB from crashing here.  */
271                       fprintf_filtered (stream, "<undefined type> %s;\n",
272                                         TYPE_FN_FIELD_PHYSNAME (f, j));
273                       break;
274                     }
275                   else if (!is_constructor && !is_full_physname_constructor)
276                     {
277                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
278                                   "", stream, -1);
279                       fputs_filtered (" ", stream);
280                     }
281
282                   if (TYPE_FN_FIELD_STUB (f, j))
283                     /* Build something we can demangle.  */
284                     mangled_name = gdb_mangle_name (type, i, j);
285                   else
286                     mangled_name = physname;
287
288                   demangled_name =
289                     cplus_demangle (mangled_name,
290                                     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
291
292                   if (demangled_name == NULL)
293                     demangled_name = xstrdup (mangled_name);
294
295                   {
296                     char *demangled_no_class;
297                     char *ptr;
298
299                     ptr = demangled_no_class = demangled_name;
300
301                     while (1)
302                       {
303                         char c;
304
305                         c = *ptr++;
306
307                         if (c == 0 || c == '(')
308                           break;
309                         if (c == '.')
310                           demangled_no_class = ptr;
311                       }
312
313                     fputs_filtered (demangled_no_class, stream);
314                     xfree (demangled_name);
315                   }
316
317                   if (TYPE_FN_FIELD_STUB (f, j))
318                     xfree (mangled_name);
319
320                   fprintf_filtered (stream, ";\n");
321                 }
322             }
323
324           fprintfi_filtered (level, stream, "}");
325         }
326       break;
327
328     default:
329       c_type_print_base (type, stream, show, level, flags);
330     }
331 }
332
333 /* LEVEL is the depth to indent lines by.  */
334
335 void
336 java_print_type (struct type *type, const char *varstring,
337                  struct ui_file *stream, int show, int level,
338                  const struct type_print_options *flags)
339 {
340   int demangled_args;
341
342   java_type_print_base (type, stream, show, level, flags);
343
344   if (varstring != NULL && *varstring != '\0')
345     {
346       fputs_filtered (" ", stream);
347       fputs_filtered (varstring, stream);
348     }
349
350   /* For demangled function names, we have the arglist as part of the name,
351      so don't print an additional pair of ()'s.  */
352
353   demangled_args = varstring != NULL && strchr (varstring, '(') != NULL;
354   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args, flags);
355 }