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