]>
Commit | Line | Data |
---|---|---|
373a8247 | 1 | /* Support for printing Pascal types for GDB, the GNU debugger. |
4a94e368 | 2 | Copyright (C) 2000-2022 Free Software Foundation, Inc. |
373a8247 PM |
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 | |
a9762ec7 | 8 | the Free Software Foundation; either version 3 of the License, or |
373a8247 PM |
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 | |
a9762ec7 | 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
373a8247 PM |
18 | |
19 | /* This file is derived from p-typeprint.c */ | |
20 | ||
21 | #include "defs.h" | |
bf31fd38 | 22 | #include "gdbsupport/gdb_obstack.h" |
373a8247 PM |
23 | #include "bfd.h" /* Binary File Description */ |
24 | #include "symtab.h" | |
25 | #include "gdbtypes.h" | |
26 | #include "expression.h" | |
27 | #include "value.h" | |
28 | #include "gdbcore.h" | |
29 | #include "target.h" | |
373a8247 | 30 | #include "language.h" |
373a8247 PM |
31 | #include "p-lang.h" |
32 | #include "typeprint.h" | |
50f182aa | 33 | #include "gdb-demangle.h" |
373a8247 | 34 | #include <ctype.h> |
7f6aba03 | 35 | #include "cli/cli-style.h" |
373a8247 | 36 | |
46157d77 | 37 | /* See language.h. */ |
373a8247 PM |
38 | |
39 | void | |
46157d77 AB |
40 | pascal_language::print_type (struct type *type, const char *varstring, |
41 | struct ui_file *stream, int show, int level, | |
42 | const struct type_print_options *flags) const | |
373a8247 | 43 | { |
52f0bd74 | 44 | enum type_code code; |
373a8247 PM |
45 | int demangled_args; |
46 | ||
78134374 | 47 | code = type->code (); |
373a8247 PM |
48 | |
49 | if (show > 0) | |
f168693b | 50 | type = check_typedef (type); |
373a8247 | 51 | |
3e9313ab PM |
52 | if ((code == TYPE_CODE_FUNC |
53 | || code == TYPE_CODE_METHOD)) | |
373a8247 | 54 | { |
46157d77 | 55 | type_print_varspec_prefix (type, stream, show, 0, flags); |
373a8247 PM |
56 | } |
57 | /* first the name */ | |
0426ad51 | 58 | gdb_puts (varstring, stream); |
373a8247 | 59 | |
3e9313ab PM |
60 | if ((varstring != NULL && *varstring != '\0') |
61 | && !(code == TYPE_CODE_FUNC | |
62 | || code == TYPE_CODE_METHOD)) | |
373a8247 | 63 | { |
0426ad51 | 64 | gdb_puts (" : ", stream); |
373a8247 PM |
65 | } |
66 | ||
3e9313ab PM |
67 | if (!(code == TYPE_CODE_FUNC |
68 | || code == TYPE_CODE_METHOD)) | |
373a8247 | 69 | { |
46157d77 | 70 | type_print_varspec_prefix (type, stream, show, 0, flags); |
373a8247 PM |
71 | } |
72 | ||
46157d77 | 73 | type_print_base (type, stream, show, level, flags); |
373a8247 | 74 | /* For demangled function names, we have the arglist as part of the name, |
0df8b418 | 75 | so don't print an additional pair of ()'s. */ |
373a8247 PM |
76 | |
77 | demangled_args = varstring ? strchr (varstring, '(') != NULL : 0; | |
46157d77 | 78 | type_print_varspec_suffix (type, stream, show, 0, demangled_args, |
79d43c61 | 79 | flags); |
373a8247 PM |
80 | |
81 | } | |
82 | ||
46157d77 | 83 | /* See language.h. */ |
5c6ce71d TT |
84 | |
85 | void | |
46157d77 AB |
86 | pascal_language::print_typedef (struct type *type, struct symbol *new_symbol, |
87 | struct ui_file *stream) const | |
5c6ce71d | 88 | { |
f168693b | 89 | type = check_typedef (type); |
6cb06a8c TT |
90 | gdb_printf (stream, "type "); |
91 | gdb_printf (stream, "%s = ", new_symbol->print_name ()); | |
5c6ce71d | 92 | type_print (type, "", stream, 0); |
6cb06a8c | 93 | gdb_printf (stream, ";"); |
5c6ce71d TT |
94 | } |
95 | ||
46157d77 | 96 | /* See p-lang.h. */ |
373a8247 | 97 | |
46157d77 AB |
98 | void |
99 | pascal_language::type_print_derivation_info (struct ui_file *stream, | |
100 | struct type *type) const | |
373a8247 | 101 | { |
0d5cff50 | 102 | const char *name; |
373a8247 PM |
103 | int i; |
104 | ||
105 | for (i = 0; i < TYPE_N_BASECLASSES (type); i++) | |
106 | { | |
0426ad51 | 107 | gdb_puts (i == 0 ? ": " : ", ", stream); |
6cb06a8c TT |
108 | gdb_printf (stream, "%s%s ", |
109 | BASETYPE_VIA_PUBLIC (type, i) ? "public" : "private", | |
110 | BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : ""); | |
7d93a1e0 | 111 | name = TYPE_BASECLASS (type, i)->name (); |
6cb06a8c | 112 | gdb_printf (stream, "%s", name ? name : "(null)"); |
373a8247 PM |
113 | } |
114 | if (i > 0) | |
115 | { | |
0426ad51 | 116 | gdb_puts (" ", stream); |
373a8247 PM |
117 | } |
118 | } | |
119 | ||
46157d77 | 120 | /* See p-lang.h. */ |
373a8247 PM |
121 | |
122 | void | |
46157d77 AB |
123 | pascal_language::type_print_method_args (const char *physname, |
124 | const char *methodname, | |
125 | struct ui_file *stream) const | |
373a8247 | 126 | { |
61012eef GB |
127 | int is_constructor = (startswith (physname, "__ct__")); |
128 | int is_destructor = (startswith (physname, "__dt__")); | |
373a8247 | 129 | |
c96d965c | 130 | if (is_constructor || is_destructor) |
373a8247 | 131 | { |
c96d965c MS |
132 | physname += 6; |
133 | } | |
00b8699c | 134 | |
0426ad51 | 135 | gdb_puts (methodname, stream); |
00b8699c | 136 | |
c96d965c MS |
137 | if (physname && (*physname != 0)) |
138 | { | |
0426ad51 | 139 | gdb_puts (" (", stream); |
0df8b418 | 140 | /* We must demangle this. */ |
8ce17b9a | 141 | while (isdigit (physname[0])) |
373a8247 | 142 | { |
3a9d7214 | 143 | int len = 0; |
1d06ead6 | 144 | int i, j; |
3a9d7214 PM |
145 | char *argname; |
146 | ||
8ce17b9a | 147 | while (isdigit (physname[len])) |
373a8247 PM |
148 | { |
149 | len++; | |
150 | } | |
151 | i = strtol (physname, &argname, 0); | |
152 | physname += len; | |
1d06ead6 TT |
153 | |
154 | for (j = 0; j < i; ++j) | |
a11ac3b3 | 155 | gdb_putc (physname[j], stream); |
1d06ead6 | 156 | |
373a8247 PM |
157 | physname += i; |
158 | if (physname[0] != 0) | |
159 | { | |
0426ad51 | 160 | gdb_puts (", ", stream); |
373a8247 PM |
161 | } |
162 | } | |
0426ad51 | 163 | gdb_puts (")", stream); |
373a8247 PM |
164 | } |
165 | } | |
166 | ||
46157d77 | 167 | /* See p-lang.h. */ |
373a8247 PM |
168 | |
169 | void | |
46157d77 AB |
170 | pascal_language::type_print_varspec_prefix (struct type *type, |
171 | struct ui_file *stream, | |
172 | int show, int passed_a_ptr, | |
173 | const struct type_print_options *flags) const | |
373a8247 | 174 | { |
373a8247 PM |
175 | if (type == 0) |
176 | return; | |
177 | ||
7d93a1e0 | 178 | if (type->name () && show <= 0) |
373a8247 PM |
179 | return; |
180 | ||
181 | QUIT; | |
182 | ||
78134374 | 183 | switch (type->code ()) |
373a8247 PM |
184 | { |
185 | case TYPE_CODE_PTR: | |
6cb06a8c | 186 | gdb_printf (stream, "^"); |
27710edb | 187 | type_print_varspec_prefix (type->target_type (), stream, 0, 1, |
79d43c61 | 188 | flags); |
0df8b418 MS |
189 | break; /* Pointer should be handled normally |
190 | in pascal. */ | |
373a8247 | 191 | |
373a8247 PM |
192 | case TYPE_CODE_METHOD: |
193 | if (passed_a_ptr) | |
6cb06a8c | 194 | gdb_printf (stream, "("); |
27710edb SM |
195 | if (type->target_type () != NULL |
196 | && type->target_type ()->code () != TYPE_CODE_VOID) | |
373a8247 | 197 | { |
6cb06a8c | 198 | gdb_printf (stream, "function "); |
373a8247 PM |
199 | } |
200 | else | |
201 | { | |
6cb06a8c | 202 | gdb_printf (stream, "procedure "); |
373a8247 PM |
203 | } |
204 | ||
205 | if (passed_a_ptr) | |
206 | { | |
6cb06a8c | 207 | gdb_printf (stream, " "); |
46157d77 | 208 | type_print_base (TYPE_SELF_TYPE (type), |
79d43c61 | 209 | stream, 0, passed_a_ptr, flags); |
6cb06a8c | 210 | gdb_printf (stream, "::"); |
373a8247 PM |
211 | } |
212 | break; | |
213 | ||
214 | case TYPE_CODE_REF: | |
27710edb | 215 | type_print_varspec_prefix (type->target_type (), stream, 0, 1, |
46157d77 | 216 | flags); |
6cb06a8c | 217 | gdb_printf (stream, "&"); |
373a8247 PM |
218 | break; |
219 | ||
220 | case TYPE_CODE_FUNC: | |
221 | if (passed_a_ptr) | |
6cb06a8c | 222 | gdb_printf (stream, "("); |
373a8247 | 223 | |
27710edb SM |
224 | if (type->target_type () != NULL |
225 | && type->target_type ()->code () != TYPE_CODE_VOID) | |
373a8247 | 226 | { |
6cb06a8c | 227 | gdb_printf (stream, "function "); |
373a8247 PM |
228 | } |
229 | else | |
230 | { | |
6cb06a8c | 231 | gdb_printf (stream, "procedure "); |
373a8247 PM |
232 | } |
233 | ||
234 | break; | |
235 | ||
236 | case TYPE_CODE_ARRAY: | |
237 | if (passed_a_ptr) | |
6cb06a8c TT |
238 | gdb_printf (stream, "("); |
239 | gdb_printf (stream, "array "); | |
df86565b | 240 | if (type->target_type ()->length () > 0 |
cf88be68 | 241 | && type->bounds ()->high.kind () != PROP_UNDEFINED) |
6cb06a8c TT |
242 | gdb_printf (stream, "[%s..%s] ", |
243 | plongest (type->bounds ()->low.const_val ()), | |
244 | plongest (type->bounds ()->high.const_val ())); | |
245 | gdb_printf (stream, "of "); | |
373a8247 PM |
246 | break; |
247 | ||
248 | case TYPE_CODE_UNDEF: | |
249 | case TYPE_CODE_STRUCT: | |
250 | case TYPE_CODE_UNION: | |
251 | case TYPE_CODE_ENUM: | |
252 | case TYPE_CODE_INT: | |
253 | case TYPE_CODE_FLT: | |
254 | case TYPE_CODE_VOID: | |
255 | case TYPE_CODE_ERROR: | |
256 | case TYPE_CODE_CHAR: | |
257 | case TYPE_CODE_BOOL: | |
258 | case TYPE_CODE_SET: | |
259 | case TYPE_CODE_RANGE: | |
260 | case TYPE_CODE_STRING: | |
373a8247 PM |
261 | case TYPE_CODE_COMPLEX: |
262 | case TYPE_CODE_TYPEDEF: | |
0c9150e4 | 263 | case TYPE_CODE_FIXED_POINT: |
373a8247 | 264 | /* These types need no prefix. They are listed here so that |
dda83cd7 | 265 | gcc -Wall will reveal any types that haven't been handled. */ |
373a8247 PM |
266 | break; |
267 | default: | |
46157d77 | 268 | gdb_assert_not_reached ("unexpected type"); |
373a8247 PM |
269 | break; |
270 | } | |
271 | } | |
272 | ||
46157d77 AB |
273 | /* See p-lang.h. */ |
274 | ||
275 | void | |
276 | pascal_language::print_func_args (struct type *type, struct ui_file *stream, | |
277 | const struct type_print_options *flags) const | |
373a8247 | 278 | { |
1f704f76 | 279 | int i, len = type->num_fields (); |
ad3bbd48 | 280 | |
373a8247 PM |
281 | if (len) |
282 | { | |
6cb06a8c | 283 | gdb_printf (stream, "("); |
373a8247 PM |
284 | } |
285 | for (i = 0; i < len; i++) | |
286 | { | |
287 | if (i > 0) | |
288 | { | |
0426ad51 | 289 | gdb_puts (", ", stream); |
1285ce86 | 290 | stream->wrap_here (4); |
373a8247 | 291 | } |
0df8b418 | 292 | /* Can we find if it is a var parameter ?? |
46157d77 AB |
293 | if ( TYPE_FIELD(type, i) == ) |
294 | { | |
6cb06a8c | 295 | gdb_printf (stream, "var "); |
46157d77 AB |
296 | } */ |
297 | print_type (type->field (i).type (), "" /* TYPE_FIELD_NAME | |
298 | seems invalid! */ | |
79d43c61 | 299 | ,stream, -1, 0, flags); |
373a8247 PM |
300 | } |
301 | if (len) | |
302 | { | |
6cb06a8c | 303 | gdb_printf (stream, ")"); |
373a8247 PM |
304 | } |
305 | } | |
306 | ||
46157d77 | 307 | /* See p-lang.h. */ |
7022349d | 308 | |
46157d77 AB |
309 | void |
310 | pascal_language::type_print_func_varspec_suffix (struct type *type, | |
311 | struct ui_file *stream, | |
312 | int show, int passed_a_ptr, | |
313 | int demangled_args, | |
314 | const struct type_print_options *flags) const | |
7022349d | 315 | { |
27710edb SM |
316 | if (type->target_type () == NULL |
317 | || type->target_type ()->code () != TYPE_CODE_VOID) | |
7022349d | 318 | { |
6cb06a8c | 319 | gdb_printf (stream, " : "); |
27710edb | 320 | type_print_varspec_prefix (type->target_type (), |
7022349d PA |
321 | stream, 0, 0, flags); |
322 | ||
27710edb | 323 | if (type->target_type () == NULL) |
7022349d PA |
324 | type_print_unknown_return_type (stream); |
325 | else | |
27710edb | 326 | type_print_base (type->target_type (), stream, show, 0, |
7022349d PA |
327 | flags); |
328 | ||
27710edb | 329 | type_print_varspec_suffix (type->target_type (), stream, 0, |
46157d77 | 330 | passed_a_ptr, 0, flags); |
7022349d PA |
331 | } |
332 | } | |
333 | ||
46157d77 | 334 | /* See p-lang.h. */ |
373a8247 | 335 | |
46157d77 AB |
336 | void |
337 | pascal_language::type_print_varspec_suffix (struct type *type, | |
338 | struct ui_file *stream, | |
339 | int show, int passed_a_ptr, | |
340 | int demangled_args, | |
341 | const struct type_print_options *flags) const | |
373a8247 PM |
342 | { |
343 | if (type == 0) | |
344 | return; | |
345 | ||
7d93a1e0 | 346 | if (type->name () && show <= 0) |
373a8247 PM |
347 | return; |
348 | ||
349 | QUIT; | |
350 | ||
78134374 | 351 | switch (type->code ()) |
373a8247 PM |
352 | { |
353 | case TYPE_CODE_ARRAY: | |
354 | if (passed_a_ptr) | |
6cb06a8c | 355 | gdb_printf (stream, ")"); |
373a8247 PM |
356 | break; |
357 | ||
373a8247 PM |
358 | case TYPE_CODE_METHOD: |
359 | if (passed_a_ptr) | |
6cb06a8c | 360 | gdb_printf (stream, ")"); |
46157d77 AB |
361 | type_print_method_args ("", "", stream); |
362 | type_print_func_varspec_suffix (type, stream, show, | |
7022349d | 363 | passed_a_ptr, 0, flags); |
373a8247 PM |
364 | break; |
365 | ||
366 | case TYPE_CODE_PTR: | |
367 | case TYPE_CODE_REF: | |
27710edb | 368 | type_print_varspec_suffix (type->target_type (), |
46157d77 | 369 | stream, 0, 1, 0, flags); |
373a8247 PM |
370 | break; |
371 | ||
372 | case TYPE_CODE_FUNC: | |
373 | if (passed_a_ptr) | |
6cb06a8c | 374 | gdb_printf (stream, ")"); |
373a8247 | 375 | if (!demangled_args) |
46157d77 AB |
376 | print_func_args (type, stream, flags); |
377 | type_print_func_varspec_suffix (type, stream, show, | |
7022349d | 378 | passed_a_ptr, 0, flags); |
373a8247 PM |
379 | break; |
380 | ||
381 | case TYPE_CODE_UNDEF: | |
382 | case TYPE_CODE_STRUCT: | |
383 | case TYPE_CODE_UNION: | |
384 | case TYPE_CODE_ENUM: | |
385 | case TYPE_CODE_INT: | |
386 | case TYPE_CODE_FLT: | |
387 | case TYPE_CODE_VOID: | |
388 | case TYPE_CODE_ERROR: | |
389 | case TYPE_CODE_CHAR: | |
390 | case TYPE_CODE_BOOL: | |
391 | case TYPE_CODE_SET: | |
392 | case TYPE_CODE_RANGE: | |
393 | case TYPE_CODE_STRING: | |
373a8247 PM |
394 | case TYPE_CODE_COMPLEX: |
395 | case TYPE_CODE_TYPEDEF: | |
0c9150e4 | 396 | case TYPE_CODE_FIXED_POINT: |
373a8247 | 397 | /* These types do not need a suffix. They are listed so that |
dda83cd7 | 398 | gcc -Wall will report types that may not have been considered. */ |
373a8247 PM |
399 | break; |
400 | default: | |
46157d77 | 401 | gdb_assert_not_reached ("unexpected type"); |
373a8247 PM |
402 | break; |
403 | } | |
404 | } | |
405 | ||
46157d77 | 406 | /* See p-lang.h. */ |
373a8247 PM |
407 | |
408 | void | |
46157d77 AB |
409 | pascal_language::type_print_base (struct type *type, struct ui_file *stream, int show, |
410 | int level, const struct type_print_options *flags) const | |
373a8247 | 411 | { |
52f0bd74 AC |
412 | int i; |
413 | int len; | |
b4aa388a | 414 | LONGEST lastval; |
373a8247 PM |
415 | enum |
416 | { | |
417 | s_none, s_public, s_private, s_protected | |
418 | } | |
419 | section_type; | |
373a8247 | 420 | |
ad3bbd48 | 421 | QUIT; |
1285ce86 | 422 | stream->wrap_here (4); |
373a8247 PM |
423 | if (type == NULL) |
424 | { | |
7f6aba03 | 425 | fputs_styled ("<type unknown>", metadata_style.style (), stream); |
373a8247 PM |
426 | return; |
427 | } | |
428 | ||
429 | /* void pointer */ | |
78134374 | 430 | if ((type->code () == TYPE_CODE_PTR) |
27710edb | 431 | && (type->target_type ()->code () == TYPE_CODE_VOID)) |
373a8247 | 432 | { |
0426ad51 TT |
433 | gdb_puts (type->name () ? type->name () : "pointer", |
434 | stream); | |
373a8247 PM |
435 | return; |
436 | } | |
437 | /* When SHOW is zero or less, and there is a valid type name, then always | |
438 | just print the type name directly from the type. */ | |
439 | ||
440 | if (show <= 0 | |
7d93a1e0 | 441 | && type->name () != NULL) |
373a8247 | 442 | { |
0426ad51 | 443 | gdb_puts (type->name (), stream); |
373a8247 PM |
444 | return; |
445 | } | |
446 | ||
f168693b | 447 | type = check_typedef (type); |
373a8247 | 448 | |
78134374 | 449 | switch (type->code ()) |
373a8247 PM |
450 | { |
451 | case TYPE_CODE_TYPEDEF: | |
452 | case TYPE_CODE_PTR: | |
373a8247 | 453 | case TYPE_CODE_REF: |
27710edb | 454 | type_print_base (type->target_type (), stream, show, level, |
46157d77 | 455 | flags); |
373a8247 PM |
456 | break; |
457 | ||
458 | case TYPE_CODE_ARRAY: | |
27710edb | 459 | print_type (type->target_type (), NULL, stream, 0, 0, flags); |
373a8247 PM |
460 | break; |
461 | ||
462 | case TYPE_CODE_FUNC: | |
463 | case TYPE_CODE_METHOD: | |
373a8247 PM |
464 | break; |
465 | case TYPE_CODE_STRUCT: | |
7d93a1e0 | 466 | if (type->name () != NULL) |
373a8247 | 467 | { |
0426ad51 TT |
468 | gdb_puts (type->name (), stream); |
469 | gdb_puts (" = ", stream); | |
373a8247 PM |
470 | } |
471 | if (HAVE_CPLUS_STRUCT (type)) | |
472 | { | |
6cb06a8c | 473 | gdb_printf (stream, "class "); |
373a8247 PM |
474 | } |
475 | else | |
476 | { | |
6cb06a8c | 477 | gdb_printf (stream, "record "); |
373a8247 PM |
478 | } |
479 | goto struct_union; | |
480 | ||
481 | case TYPE_CODE_UNION: | |
7d93a1e0 | 482 | if (type->name () != NULL) |
373a8247 | 483 | { |
0426ad51 TT |
484 | gdb_puts (type->name (), stream); |
485 | gdb_puts (" = ", stream); | |
373a8247 | 486 | } |
6cb06a8c | 487 | gdb_printf (stream, "case <?> of "); |
373a8247 PM |
488 | |
489 | struct_union: | |
1285ce86 | 490 | stream->wrap_here (4); |
373a8247 PM |
491 | if (show < 0) |
492 | { | |
493 | /* If we just printed a tag name, no need to print anything else. */ | |
7d93a1e0 | 494 | if (type->name () == NULL) |
6cb06a8c | 495 | gdb_printf (stream, "{...}"); |
373a8247 | 496 | } |
7d93a1e0 | 497 | else if (show > 0 || type->name () == NULL) |
373a8247 | 498 | { |
46157d77 | 499 | type_print_derivation_info (stream, type); |
373a8247 | 500 | |
6cb06a8c | 501 | gdb_printf (stream, "\n"); |
1f704f76 | 502 | if ((type->num_fields () == 0) && (TYPE_NFN_FIELDS (type) == 0)) |
373a8247 | 503 | { |
e46d3488 | 504 | if (type->is_stub ()) |
6cb06a8c TT |
505 | gdb_printf (stream, "%*s<incomplete type>\n", |
506 | level + 4, ""); | |
373a8247 | 507 | else |
6cb06a8c TT |
508 | gdb_printf (stream, "%*s<no data fields>\n", |
509 | level + 4, ""); | |
373a8247 PM |
510 | } |
511 | ||
512 | /* Start off with no specific section type, so we can print | |
513 | one for the first field we find, and use that section type | |
0df8b418 | 514 | thereafter until we find another type. */ |
373a8247 PM |
515 | |
516 | section_type = s_none; | |
517 | ||
518 | /* If there is a base class for this type, | |
519 | do not print the field that it occupies. */ | |
520 | ||
1f704f76 | 521 | len = type->num_fields (); |
373a8247 PM |
522 | for (i = TYPE_N_BASECLASSES (type); i < len; i++) |
523 | { | |
524 | QUIT; | |
525 | /* Don't print out virtual function table. */ | |
33d16dd9 SM |
526 | if ((startswith (type->field (i).name (), "_vptr")) |
527 | && is_cplus_marker ((type->field (i).name ())[5])) | |
373a8247 PM |
528 | continue; |
529 | ||
530 | /* If this is a pascal object or class we can print the | |
dda83cd7 | 531 | various section labels. */ |
373a8247 PM |
532 | |
533 | if (HAVE_CPLUS_STRUCT (type)) | |
534 | { | |
535 | if (TYPE_FIELD_PROTECTED (type, i)) | |
536 | { | |
537 | if (section_type != s_protected) | |
538 | { | |
539 | section_type = s_protected; | |
6cb06a8c TT |
540 | gdb_printf (stream, "%*sprotected\n", |
541 | level + 2, ""); | |
373a8247 PM |
542 | } |
543 | } | |
544 | else if (TYPE_FIELD_PRIVATE (type, i)) | |
545 | { | |
546 | if (section_type != s_private) | |
547 | { | |
548 | section_type = s_private; | |
6cb06a8c TT |
549 | gdb_printf (stream, "%*sprivate\n", |
550 | level + 2, ""); | |
373a8247 PM |
551 | } |
552 | } | |
553 | else | |
554 | { | |
555 | if (section_type != s_public) | |
556 | { | |
557 | section_type = s_public; | |
6cb06a8c TT |
558 | gdb_printf (stream, "%*spublic\n", |
559 | level + 2, ""); | |
373a8247 PM |
560 | } |
561 | } | |
562 | } | |
563 | ||
d0b1020b | 564 | print_spaces (level + 4, stream); |
ceacbf6e | 565 | if (field_is_static (&type->field (i))) |
6cb06a8c | 566 | gdb_printf (stream, "static "); |
46157d77 | 567 | print_type (type->field (i).type (), |
33d16dd9 | 568 | type->field (i).name (), |
79d43c61 | 569 | stream, show - 1, level + 4, flags); |
ceacbf6e | 570 | if (!field_is_static (&type->field (i)) |
373a8247 PM |
571 | && TYPE_FIELD_PACKED (type, i)) |
572 | { | |
573 | /* It is a bitfield. This code does not attempt | |
574 | to look at the bitpos and reconstruct filler, | |
575 | unnamed fields. This would lead to misleading | |
576 | results if the compiler does not put out fields | |
577 | for such things (I don't know what it does). */ | |
6cb06a8c TT |
578 | gdb_printf (stream, " : %d", |
579 | TYPE_FIELD_BITSIZE (type, i)); | |
373a8247 | 580 | } |
6cb06a8c | 581 | gdb_printf (stream, ";\n"); |
373a8247 PM |
582 | } |
583 | ||
0df8b418 | 584 | /* If there are both fields and methods, put a space between. */ |
373a8247 PM |
585 | len = TYPE_NFN_FIELDS (type); |
586 | if (len && section_type != s_none) | |
6cb06a8c | 587 | gdb_printf (stream, "\n"); |
373a8247 | 588 | |
0df8b418 | 589 | /* Object pascal: print out the methods. */ |
373a8247 PM |
590 | |
591 | for (i = 0; i < len; i++) | |
592 | { | |
593 | struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); | |
594 | int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); | |
0d5cff50 | 595 | const char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); |
9216103f | 596 | |
373a8247 | 597 | /* this is GNU C++ specific |
dda83cd7 SM |
598 | how can we know constructor/destructor? |
599 | It might work for GNU pascal. */ | |
373a8247 PM |
600 | for (j = 0; j < len2; j++) |
601 | { | |
1d06ead6 | 602 | const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); |
373a8247 | 603 | |
61012eef GB |
604 | int is_constructor = (startswith (physname, "__ct__")); |
605 | int is_destructor = (startswith (physname, "__dt__")); | |
373a8247 PM |
606 | |
607 | QUIT; | |
608 | if (TYPE_FN_FIELD_PROTECTED (f, j)) | |
609 | { | |
610 | if (section_type != s_protected) | |
611 | { | |
612 | section_type = s_protected; | |
6cb06a8c TT |
613 | gdb_printf (stream, "%*sprotected\n", |
614 | level + 2, ""); | |
373a8247 PM |
615 | } |
616 | } | |
617 | else if (TYPE_FN_FIELD_PRIVATE (f, j)) | |
618 | { | |
619 | if (section_type != s_private) | |
620 | { | |
621 | section_type = s_private; | |
6cb06a8c TT |
622 | gdb_printf (stream, "%*sprivate\n", |
623 | level + 2, ""); | |
373a8247 PM |
624 | } |
625 | } | |
626 | else | |
627 | { | |
628 | if (section_type != s_public) | |
629 | { | |
630 | section_type = s_public; | |
6cb06a8c TT |
631 | gdb_printf (stream, "%*spublic\n", |
632 | level + 2, ""); | |
373a8247 PM |
633 | } |
634 | } | |
635 | ||
d0b1020b | 636 | print_spaces (level + 4, stream); |
373a8247 | 637 | if (TYPE_FN_FIELD_STATIC_P (f, j)) |
6cb06a8c | 638 | gdb_printf (stream, "static "); |
27710edb | 639 | if (TYPE_FN_FIELD_TYPE (f, j)->target_type () == 0) |
373a8247 PM |
640 | { |
641 | /* Keep GDB from crashing here. */ | |
6cb06a8c TT |
642 | gdb_printf (stream, "<undefined type> %s;\n", |
643 | TYPE_FN_FIELD_PHYSNAME (f, j)); | |
373a8247 PM |
644 | break; |
645 | } | |
646 | ||
647 | if (is_constructor) | |
648 | { | |
6cb06a8c | 649 | gdb_printf (stream, "constructor "); |
373a8247 PM |
650 | } |
651 | else if (is_destructor) | |
652 | { | |
6cb06a8c | 653 | gdb_printf (stream, "destructor "); |
373a8247 | 654 | } |
27710edb SM |
655 | else if (TYPE_FN_FIELD_TYPE (f, j)->target_type () != 0 |
656 | && (TYPE_FN_FIELD_TYPE(f, j)->target_type ()->code () | |
657 | != TYPE_CODE_VOID)) | |
373a8247 | 658 | { |
6cb06a8c | 659 | gdb_printf (stream, "function "); |
373a8247 PM |
660 | } |
661 | else | |
662 | { | |
6cb06a8c | 663 | gdb_printf (stream, "procedure "); |
373a8247 | 664 | } |
0df8b418 | 665 | /* This does not work, no idea why !! */ |
373a8247 | 666 | |
46157d77 | 667 | type_print_method_args (physname, method_name, stream); |
373a8247 | 668 | |
27710edb SM |
669 | if (TYPE_FN_FIELD_TYPE (f, j)->target_type () != 0 |
670 | && (TYPE_FN_FIELD_TYPE(f, j)->target_type ()->code () | |
671 | != TYPE_CODE_VOID)) | |
373a8247 | 672 | { |
0426ad51 | 673 | gdb_puts (" : ", stream); |
27710edb | 674 | type_print (TYPE_FN_FIELD_TYPE (f, j)->target_type (), |
373a8247 PM |
675 | "", stream, -1); |
676 | } | |
677 | if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) | |
6cb06a8c | 678 | gdb_printf (stream, "; virtual"); |
373a8247 | 679 | |
6cb06a8c | 680 | gdb_printf (stream, ";\n"); |
373a8247 PM |
681 | } |
682 | } | |
6cb06a8c | 683 | gdb_printf (stream, "%*send", level, ""); |
373a8247 PM |
684 | } |
685 | break; | |
686 | ||
687 | case TYPE_CODE_ENUM: | |
7d93a1e0 | 688 | if (type->name () != NULL) |
373a8247 | 689 | { |
0426ad51 | 690 | gdb_puts (type->name (), stream); |
373a8247 | 691 | if (show > 0) |
0426ad51 | 692 | gdb_puts (" ", stream); |
373a8247 PM |
693 | } |
694 | /* enum is just defined by | |
dda83cd7 | 695 | type enume_name = (enum_member1,enum_member2,...) */ |
6cb06a8c | 696 | gdb_printf (stream, " = "); |
1285ce86 | 697 | stream->wrap_here (4); |
373a8247 PM |
698 | if (show < 0) |
699 | { | |
700 | /* If we just printed a tag name, no need to print anything else. */ | |
7d93a1e0 | 701 | if (type->name () == NULL) |
6cb06a8c | 702 | gdb_printf (stream, "(...)"); |
373a8247 | 703 | } |
7d93a1e0 | 704 | else if (show > 0 || type->name () == NULL) |
373a8247 | 705 | { |
6cb06a8c | 706 | gdb_printf (stream, "("); |
1f704f76 | 707 | len = type->num_fields (); |
373a8247 PM |
708 | lastval = 0; |
709 | for (i = 0; i < len; i++) | |
710 | { | |
711 | QUIT; | |
712 | if (i) | |
6cb06a8c | 713 | gdb_printf (stream, ", "); |
1285ce86 | 714 | stream->wrap_here (4); |
0426ad51 | 715 | gdb_puts (type->field (i).name (), stream); |
970db518 | 716 | if (lastval != type->field (i).loc_enumval ()) |
373a8247 | 717 | { |
6cb06a8c TT |
718 | gdb_printf (stream, |
719 | " := %s", | |
720 | plongest (type->field (i).loc_enumval ())); | |
970db518 | 721 | lastval = type->field (i).loc_enumval (); |
373a8247 PM |
722 | } |
723 | lastval++; | |
724 | } | |
6cb06a8c | 725 | gdb_printf (stream, ")"); |
373a8247 PM |
726 | } |
727 | break; | |
728 | ||
729 | case TYPE_CODE_VOID: | |
6cb06a8c | 730 | gdb_printf (stream, "void"); |
373a8247 PM |
731 | break; |
732 | ||
733 | case TYPE_CODE_UNDEF: | |
6cb06a8c | 734 | gdb_printf (stream, "record <unknown>"); |
373a8247 PM |
735 | break; |
736 | ||
737 | case TYPE_CODE_ERROR: | |
6cb06a8c | 738 | gdb_printf (stream, "%s", TYPE_ERROR_NAME (type)); |
373a8247 PM |
739 | break; |
740 | ||
0df8b418 | 741 | /* this probably does not work for enums. */ |
373a8247 PM |
742 | case TYPE_CODE_RANGE: |
743 | { | |
27710edb | 744 | struct type *target = type->target_type (); |
ad3bbd48 | 745 | |
5537ddd0 | 746 | print_type_scalar (target, type->bounds ()->low.const_val (), stream); |
0426ad51 | 747 | gdb_puts ("..", stream); |
5537ddd0 | 748 | print_type_scalar (target, type->bounds ()->high.const_val (), stream); |
373a8247 PM |
749 | } |
750 | break; | |
751 | ||
752 | case TYPE_CODE_SET: | |
0426ad51 | 753 | gdb_puts ("set of ", stream); |
46157d77 | 754 | print_type (type->index_type (), "", stream, |
79d43c61 | 755 | show - 1, level, flags); |
373a8247 PM |
756 | break; |
757 | ||
6604db2e | 758 | case TYPE_CODE_STRING: |
0426ad51 | 759 | gdb_puts ("String", stream); |
6604db2e PM |
760 | break; |
761 | ||
373a8247 PM |
762 | default: |
763 | /* Handle types not explicitly handled by the other cases, | |
dda83cd7 SM |
764 | such as fundamental types. For these, just print whatever |
765 | the type name is, as recorded in the type itself. If there | |
766 | is no type name, then complain. */ | |
7d93a1e0 | 767 | if (type->name () != NULL) |
373a8247 | 768 | { |
0426ad51 | 769 | gdb_puts (type->name (), stream); |
373a8247 PM |
770 | } |
771 | else | |
772 | { | |
773 | /* At least for dump_symtab, it is important that this not be | |
774 | an error (). */ | |
7f6aba03 TT |
775 | fprintf_styled (stream, metadata_style.style (), |
776 | "<invalid unnamed pascal type code %d>", | |
78134374 | 777 | type->code ()); |
373a8247 PM |
778 | } |
779 | break; | |
780 | } | |
781 | } |