* jv-lang.c (get_java_utf8_name): Re-write so it works with
[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_STRUCT:
107       fprintf_filtered (stream, "class ");
108       if (TYPE_TAG_NAME (type) != NULL)
109         {
110           fputs_filtered (TYPE_TAG_NAME (type), stream);
111           if (show > 0)
112             fputs_filtered (" ", stream);
113         }
114       wrap_here ("    ");
115       if (show < 0)
116         {
117           /* If we just printed a tag name, no need to print anything else.  */
118           if (TYPE_TAG_NAME (type) == NULL)
119             fprintf_filtered (stream, "{...}");
120         }
121       else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
122         {
123           java_type_print_derivation_info (stream, type);
124           
125           fprintf_filtered (stream, "{\n");
126           if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
127             {
128               if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
129                 fprintfi_filtered (level + 4, stream, "<incomplete type>\n");
130               else
131                 fprintfi_filtered (level + 4, stream, "<no data fields>\n");
132             }
133
134           /* If there is a base class for this type,
135              do not print the field that it occupies.  */
136
137           len = TYPE_NFIELDS (type);
138           for (i = TYPE_N_BASECLASSES (type); i < len; i++)
139             {
140               QUIT;
141               /* Don't print out virtual function table.  */
142               if (STREQN (TYPE_FIELD_NAME (type, i), "_vptr", 5)
143                   && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5]))
144                 continue;
145
146               /* If this is a C++ class we can print the various C++ section
147                  labels. */
148
149               print_spaces_filtered (level + 4, stream);
150               if (HAVE_CPLUS_STRUCT (type))
151                 {
152                   if (TYPE_FIELD_PROTECTED (type, i))
153                     fprintf_filtered (stream, "protected ");
154                   else if (TYPE_FIELD_PRIVATE (type, i))
155                     fprintf_filtered (stream, "private ");
156                   else
157                     fprintf_filtered (stream, "public ");
158                 }
159
160               if (TYPE_FIELD_STATIC (type, i))
161                 {
162                   fprintf_filtered (stream, "static ");
163                 }
164               java_print_type (TYPE_FIELD_TYPE (type, i),
165                             TYPE_FIELD_NAME (type, i),
166                             stream, show - 1, level + 4);
167               fprintf_filtered (stream, ";\n");
168             }
169
170           /* If there are both fields and methods, put a space between. */
171           len = TYPE_NFN_FIELDS (type);
172           if (len)
173              fprintf_filtered (stream, "\n");
174
175           /* Print out the methods */
176
177           for (i = 0; i < len; i++)
178             {
179               struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
180               int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
181               char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
182               char *name = type_name_no_tag (type);
183               int is_constructor = name && STREQ(method_name, name);
184               for (j = 0; j < len2; j++)
185                 {
186                   char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
187                   int is_full_physname_constructor = 
188                     ((physname[0] == '_' && physname[1] == '_'
189                       && strchr ("0123456789Qt", physname[2]))
190                      || STREQN (physname, "__ct__", 6)
191                      || DESTRUCTOR_PREFIX_P (physname)
192                      || STREQN (physname, "__dt__", 6));
193
194                   QUIT;
195                   print_spaces_filtered (level + 4, stream);
196                   if (TYPE_FN_FIELD_PROTECTED (f, j))
197                     fprintf_filtered (stream, "protected ");
198                   else if (TYPE_FN_FIELD_PRIVATE (f, j))
199                     fprintf_filtered (stream, "private ");
200                   else
201                     fprintf_filtered (stream, "public ");
202
203                   if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
204                     fprintf_filtered (stream, "virtual ");
205                   else if (TYPE_FN_FIELD_STATIC_P (f, j))
206                     fprintf_filtered (stream, "static ");
207                   if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
208                     {
209                       /* Keep GDB from crashing here.  */
210                       fprintf_filtered (stream, "<undefined type> %s;\n",
211                                TYPE_FN_FIELD_PHYSNAME (f, j));
212                       break;
213                     }
214                   else if (!is_constructor && !is_full_physname_constructor)
215                     {
216                       type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
217                                   "", stream, -1);
218                       fputs_filtered (" ", stream);
219                     }
220                   if (TYPE_FN_FIELD_STUB (f, j))
221                     /* Build something we can demangle.  */
222                     mangled_name = gdb_mangle_name (type, i, j);
223                   else
224                     mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
225
226                   demangled_name =
227                     cplus_demangle (mangled_name,
228                                     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
229                   if (demangled_name == NULL)
230                     fprintf_filtered (stream, "<badly mangled name '%s'>",
231                                       mangled_name);
232                   else
233                     {
234                       char *demangled_no_class = demangled_name;
235                       char *ptr = demangled_name;
236                       for ( ; ; )
237                         {
238                           char c = *ptr++;
239                           if (c == 0 || c == '(')
240                             break;
241                           if (c == '.')
242                             demangled_no_class = ptr;
243                         }
244                       fputs_filtered (demangled_no_class, stream);
245                       free (demangled_name);
246                     }
247
248                   if (TYPE_FN_FIELD_STUB (f, j))
249                     free (mangled_name);
250
251                   fprintf_filtered (stream, ";\n");
252                 }
253             }
254
255           fprintfi_filtered (level, stream, "}");
256         }
257       break;
258
259       default:
260         c_type_print_base (type, stream, show, level);
261     }
262 }
263
264 /* LEVEL is the depth to indent lines by.  */
265
266 void
267 java_print_type (type, varstring, stream, show, level)
268      struct type *type;
269      char *varstring;
270      GDB_FILE *stream;
271      int show;
272      int level;
273 {
274   java_type_print_base (type, stream, show, level);
275
276   if (varstring != NULL && *varstring != '\0')
277     {
278       fputs_filtered (" ", stream);
279       fputs_filtered (varstring, stream);
280     }
281 #if 0
282   /* For demangled function names, we have the arglist as part of the name,
283      so don't print an additional pair of ()'s */
284
285   demangled_args = strchr(varstring, '(') != NULL;
286   c_type_print_varspec_suffix (type, stream, show, 0, demangled_args);
287 #endif
288 }