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