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