]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/prdbg.c
gdb/testsuite/lib/rocm: Fix with_rocm_gpu_lock
[thirdparty/binutils-gdb.git] / binutils / prdbg.c
CommitLineData
252b5132 1/* prdbg.c -- Print out generic debugging information.
fd67aa11 2 Copyright (C) 1995-2024 Free Software Foundation, Inc.
252b5132 3 Written by Ian Lance Taylor <ian@cygnus.com>.
51cdc6e0 4 Tags style generation written by Salvador E. Tropea <set@computer.org>.
252b5132
RH
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
32866df7 10 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
b43b5d5f
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21 02110-1301, USA. */
252b5132
RH
22
23/* This file prints out the generic debugging information, by
24 supplying a set of routines to debug_write. */
25
3db64b00 26#include "sysdep.h"
252b5132 27#include <assert.h>
252b5132 28#include "bfd.h"
252b5132 29#include "libiberty.h"
ed180cc5 30#include "demangle.h"
252b5132
RH
31#include "debug.h"
32#include "budbg.h"
33
34/* This is the structure we use as a handle for these routines. */
35
36struct pr_handle
37{
38 /* File to print information to. */
39 FILE *f;
40 /* Current indentation level. */
41 unsigned int indent;
42 /* Type stack. */
43 struct pr_stack *stack;
44 /* Parameter number we are about to output. */
45 int parameter;
51cdc6e0
NC
46 /* The following are used only by the tags code (tg_). */
47 /* Name of the file we are using. */
48 char *filename;
49 /* The BFD. */
50 bfd *abfd;
51 /* The symbols table for this BFD. */
52 asymbol **syms;
53 /* Pointer to a function to demangle symbols. */
ed180cc5 54 char *(*demangler) (bfd *, const char *, int);
252b5132
RH
55};
56
57/* The type stack. */
58
59struct pr_stack
60{
61 /* Next element on the stack. */
62 struct pr_stack *next;
63 /* This element. */
64 char *type;
65 /* Current visibility of fields if this is a class. */
66 enum debug_visibility visibility;
67 /* Name of the current method we are handling. */
a5f3ca48 68 char *method;
51cdc6e0
NC
69 /* The following are used only by the tags code (tg_). */
70 /* Type for the container (struct, union, class, union class). */
71 const char *flavor;
72 /* A comma separated list of parent classes. */
73 char *parents;
252b5132
RH
74};
75
015dc7e1
AM
76static bool pr_start_compilation_unit (void *, const char *);
77static bool pr_start_source (void *, const char *);
78static bool pr_empty_type (void *);
79static bool pr_void_type (void *);
80static bool pr_int_type (void *, unsigned int, bool);
81static bool pr_float_type (void *, unsigned int);
82static bool pr_complex_type (void *, unsigned int);
83static bool pr_bool_type (void *, unsigned int);
84static bool pr_enum_type
2da42df6 85 (void *, const char *, const char **, bfd_signed_vma *);
015dc7e1
AM
86static bool pr_pointer_type (void *);
87static bool pr_function_type (void *, int, bool);
88static bool pr_reference_type (void *);
89static bool pr_range_type (void *, bfd_signed_vma, bfd_signed_vma);
90static bool pr_array_type (void *, bfd_signed_vma, bfd_signed_vma, bool);
91static bool pr_set_type (void *, bool);
92static bool pr_offset_type (void *);
93static bool pr_method_type (void *, bool, int, bool);
94static bool pr_const_type (void *);
95static bool pr_volatile_type (void *);
96static bool pr_start_struct_type
97 (void *, const char *, unsigned int, bool, unsigned int);
98static bool pr_struct_field
2da42df6 99 (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
015dc7e1
AM
100static bool pr_end_struct_type (void *);
101static bool pr_start_class_type
102 (void *, const char *, unsigned int, bool, unsigned int, bool, bool);
103static bool pr_class_static_member
2da42df6 104 (void *, const char *, const char *, enum debug_visibility);
015dc7e1
AM
105static bool pr_class_baseclass
106 (void *, bfd_vma, bool, enum debug_visibility);
107static bool pr_class_start_method (void *, const char *);
108static bool pr_class_method_variant
109 (void *, const char *, enum debug_visibility, bool, bool, bfd_vma, bool);
110static bool pr_class_static_method_variant
111 (void *, const char *, enum debug_visibility, bool, bool);
112static bool pr_class_end_method (void *);
113static bool pr_end_class_type (void *);
114static bool pr_typedef_type (void *, const char *);
115static bool pr_tag_type
2da42df6 116 (void *, const char *, unsigned int, enum debug_type_kind);
015dc7e1
AM
117static bool pr_typdef (void *, const char *);
118static bool pr_tag (void *, const char *);
119static bool pr_int_constant (void *, const char *, bfd_vma);
120static bool pr_float_constant (void *, const char *, double);
121static bool pr_typed_constant (void *, const char *, bfd_vma);
122static bool pr_variable (void *, const char *, enum debug_var_kind, bfd_vma);
123static bool pr_start_function (void *, const char *, bool);
124static bool pr_function_parameter
2da42df6 125 (void *, const char *, enum debug_parm_kind, bfd_vma);
015dc7e1
AM
126static bool pr_start_block (void *, bfd_vma);
127static bool pr_end_block (void *, bfd_vma);
128static bool pr_end_function (void *);
129static bool pr_lineno (void *, const char *, unsigned long, bfd_vma);
a5f3ca48 130
51cdc6e0 131static const char *visibility_name (enum debug_visibility);
a5f3ca48 132
51cdc6e0 133/* Tags style replacements. */
015dc7e1
AM
134static bool tg_start_compilation_unit (void *, const char *);
135static bool tg_start_source (void *, const char *);
136static bool tg_enum_type
2da42df6 137 (void *, const char *, const char **, bfd_signed_vma *);
015dc7e1
AM
138static bool tg_start_struct_type
139 (void *, const char *, unsigned int, bool, unsigned int);
140static bool pr_struct_field
2da42df6 141 (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
015dc7e1 142static bool tg_struct_field
2da42df6 143 (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
015dc7e1 144static bool tg_struct_field
2da42df6 145 (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
015dc7e1
AM
146static bool tg_end_struct_type (void *);
147static bool tg_start_class_type
148 (void *, const char *, unsigned int, bool, unsigned int, bool, bool);
149static bool tg_class_static_member
2da42df6 150 (void *, const char *, const char *, enum debug_visibility);
015dc7e1
AM
151static bool tg_class_baseclass (void *, bfd_vma, bool, enum debug_visibility);
152static bool tg_class_method_variant
153 (void *, const char *, enum debug_visibility, bool, bool, bfd_vma, bool);
154static bool tg_class_static_method_variant
155 (void *, const char *, enum debug_visibility, bool, bool);
156static bool tg_end_class_type (void *);
157static bool tg_tag_type
2da42df6 158 (void *, const char *, unsigned int, enum debug_type_kind);
015dc7e1
AM
159static bool tg_typdef (void *, const char *);
160static bool tg_tag (void *, const char *);
161static bool tg_int_constant (void *, const char *, bfd_vma);
162static bool tg_float_constant (void *, const char *, double);
163static bool tg_typed_constant (void *, const char *, bfd_vma);
164static bool tg_variable (void *, const char *, enum debug_var_kind, bfd_vma);
165static bool tg_start_function (void *, const char *, bool);
166static bool tg_function_parameter
2da42df6 167 (void *, const char *, enum debug_parm_kind, bfd_vma);
015dc7e1
AM
168static bool tg_start_block (void *, bfd_vma);
169static bool tg_end_block (void *, bfd_vma);
170static bool tg_lineno (void *, const char *, unsigned long, bfd_vma);
51cdc6e0 171\f
252b5132
RH
172static const struct debug_write_fns pr_fns =
173{
174 pr_start_compilation_unit,
175 pr_start_source,
176 pr_empty_type,
177 pr_void_type,
178 pr_int_type,
179 pr_float_type,
180 pr_complex_type,
181 pr_bool_type,
182 pr_enum_type,
183 pr_pointer_type,
184 pr_function_type,
185 pr_reference_type,
186 pr_range_type,
187 pr_array_type,
188 pr_set_type,
189 pr_offset_type,
190 pr_method_type,
191 pr_const_type,
192 pr_volatile_type,
193 pr_start_struct_type,
194 pr_struct_field,
195 pr_end_struct_type,
196 pr_start_class_type,
197 pr_class_static_member,
198 pr_class_baseclass,
199 pr_class_start_method,
200 pr_class_method_variant,
201 pr_class_static_method_variant,
202 pr_class_end_method,
203 pr_end_class_type,
204 pr_typedef_type,
205 pr_tag_type,
206 pr_typdef,
207 pr_tag,
208 pr_int_constant,
209 pr_float_constant,
210 pr_typed_constant,
211 pr_variable,
212 pr_start_function,
213 pr_function_parameter,
214 pr_start_block,
215 pr_end_block,
216 pr_end_function,
217 pr_lineno
218};
219\f
51cdc6e0
NC
220static const struct debug_write_fns tg_fns =
221{
222 tg_start_compilation_unit,
223 tg_start_source,
224 pr_empty_type, /* Same, push_type. */
225 pr_void_type, /* Same, push_type. */
226 pr_int_type, /* Same, push_type. */
227 pr_float_type, /* Same, push_type. */
228 pr_complex_type, /* Same, push_type. */
229 pr_bool_type, /* Same, push_type. */
230 tg_enum_type,
231 pr_pointer_type, /* Same, changes to pointer. */
232 pr_function_type, /* Same, push_type. */
233 pr_reference_type, /* Same, changes to reference. */
234 pr_range_type, /* FIXME: What's that?. */
235 pr_array_type, /* Same, push_type. */
236 pr_set_type, /* FIXME: What's that?. */
237 pr_offset_type, /* FIXME: What's that?. */
238 pr_method_type, /* Same. */
239 pr_const_type, /* Same, changes to const. */
240 pr_volatile_type, /* Same, changes to volatile. */
241 tg_start_struct_type,
242 tg_struct_field,
243 tg_end_struct_type,
244 tg_start_class_type,
245 tg_class_static_member,
246 tg_class_baseclass,
50c2245b 247 pr_class_start_method, /* Same, remembers that's a method. */
51cdc6e0
NC
248 tg_class_method_variant,
249 tg_class_static_method_variant,
250 pr_class_end_method, /* Same, forgets that's a method. */
251 tg_end_class_type,
252 pr_typedef_type, /* Same, just push type. */
253 tg_tag_type,
254 tg_typdef,
255 tg_tag,
256 tg_int_constant, /* Untested. */
257 tg_float_constant, /* Untested. */
258 tg_typed_constant, /* Untested. */
259 tg_variable,
260 tg_start_function,
261 tg_function_parameter,
262 tg_start_block,
263 tg_end_block,
264 pr_end_function, /* Same, does nothing. */
265 tg_lineno
266};
af03af8f
NC
267
268static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
51cdc6e0 269\f
252b5132
RH
270/* Print out the generic debugging information recorded in dhandle. */
271
015dc7e1 272bool
2da42df6 273print_debugging_info (FILE *f, void *dhandle, bfd *abfd, asymbol **syms,
b38ead21 274 char * (*demangler) (struct bfd *, const char *, int),
015dc7e1 275 bool as_tags)
252b5132
RH
276{
277 struct pr_handle info;
278
279 info.f = f;
280 info.indent = 0;
281 info.stack = NULL;
282 info.parameter = 0;
51cdc6e0
NC
283 info.filename = NULL;
284 info.abfd = abfd;
285 info.syms = syms;
b38ead21 286 info.demangler = demangler;
51cdc6e0
NC
287
288 if (as_tags)
289 {
290 fputs ("!_TAG_FILE_FORMAT\t2\t/extended format/\n", f);
291 fputs ("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted/\n", f);
292 fputs ("!_TAG_PROGRAM_AUTHOR\tIan Lance Taylor, Salvador E. Tropea and others\t//\n", f);
293 fputs ("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f);
294 }
252b5132 295
a5f3ca48
AM
296 bool ret = debug_write (dhandle, as_tags ? &tg_fns : &pr_fns, &info);
297 while (info.stack != NULL)
298 {
299 struct pr_stack *s = info.stack;
300 info.stack = s->next;
301 free (s->type);
302 free (s->method);
303 free (s->parents);
304 free (s);
305 }
306 free (info.filename);
307 return ret;
252b5132
RH
308}
309\f
310/* Indent to the current indentation level. */
311
312static void
2da42df6 313indent (struct pr_handle *info)
252b5132
RH
314{
315 unsigned int i;
316
317 for (i = 0; i < info->indent; i++)
318 putc (' ', info->f);
319}
320
321/* Push a type on the type stack. */
322
015dc7e1 323static bool
2da42df6 324push_type (struct pr_handle *info, const char *type)
252b5132
RH
325{
326 struct pr_stack *n;
327
328 if (type == NULL)
015dc7e1 329 return false;
252b5132 330
a5f3ca48 331 n = xmalloc (sizeof *n);
252b5132
RH
332 memset (n, 0, sizeof *n);
333
334 n->type = xstrdup (type);
335 n->visibility = DEBUG_VISIBILITY_IGNORE;
336 n->method = NULL;
337 n->next = info->stack;
338 info->stack = n;
339
015dc7e1 340 return true;
252b5132
RH
341}
342
343/* Prepend a string onto the type on the top of the type stack. */
344
015dc7e1 345static bool
2da42df6 346prepend_type (struct pr_handle *info, const char *s)
252b5132
RH
347{
348 char *n;
349
350 assert (info->stack != NULL);
351
a5f3ca48 352 n = xmalloc (strlen (s) + strlen (info->stack->type) + 1);
252b5132
RH
353 sprintf (n, "%s%s", s, info->stack->type);
354 free (info->stack->type);
355 info->stack->type = n;
356
015dc7e1 357 return true;
252b5132
RH
358}
359
360/* Append a string to the type on the top of the type stack. */
361
015dc7e1 362static bool
2da42df6 363append_type (struct pr_handle *info, const char *s)
252b5132
RH
364{
365 unsigned int len;
366
367 if (s == NULL)
015dc7e1 368 return false;
252b5132
RH
369
370 assert (info->stack != NULL);
371
372 len = strlen (info->stack->type);
a5f3ca48 373 info->stack->type = xrealloc (info->stack->type, len + strlen (s) + 1);
252b5132
RH
374 strcpy (info->stack->type + len, s);
375
015dc7e1 376 return true;
252b5132
RH
377}
378
51cdc6e0
NC
379/* Append a string to the parents on the top of the type stack. */
380
015dc7e1 381static bool
51cdc6e0
NC
382append_parent (struct pr_handle *info, const char *s)
383{
384 unsigned int len;
385
386 if (s == NULL)
015dc7e1 387 return false;
51cdc6e0
NC
388
389 assert (info->stack != NULL);
390
391 len = info->stack->parents ? strlen (info->stack->parents) : 0;
a5f3ca48 392 info->stack->parents = xrealloc (info->stack->parents, len + strlen (s) + 1);
51cdc6e0
NC
393 strcpy (info->stack->parents + len, s);
394
015dc7e1 395 return true;
51cdc6e0
NC
396}
397
252b5132
RH
398/* We use an underscore to indicate where the name should go in a type
399 string. This function substitutes a string for the underscore. If
400 there is no underscore, the name follows the type. */
401
015dc7e1 402static bool
2da42df6 403substitute_type (struct pr_handle *info, const char *s)
252b5132
RH
404{
405 char *u;
406
407 assert (info->stack != NULL);
408
409 u = strchr (info->stack->type, '|');
410 if (u != NULL)
411 {
412 char *n;
413
a5f3ca48 414 n = xmalloc (strlen (info->stack->type) + strlen (s));
252b5132
RH
415
416 memcpy (n, info->stack->type, u - info->stack->type);
417 strcpy (n + (u - info->stack->type), s);
418 strcat (n, u + 1);
419
420 free (info->stack->type);
421 info->stack->type = n;
422
015dc7e1 423 return true;
252b5132
RH
424 }
425
426 if (strchr (s, '|') != NULL
427 && (strchr (info->stack->type, '{') != NULL
428 || strchr (info->stack->type, '(') != NULL))
429 {
430 if (! prepend_type (info, "(")
431 || ! append_type (info, ")"))
015dc7e1 432 return false;
252b5132
RH
433 }
434
435 if (*s == '\0')
015dc7e1 436 return true;
252b5132
RH
437
438 return (append_type (info, " ")
439 && append_type (info, s));
440}
441
442/* Indent the type at the top of the stack by appending spaces. */
443
015dc7e1 444static bool
2da42df6 445indent_type (struct pr_handle *info)
252b5132
RH
446{
447 unsigned int i;
448
449 for (i = 0; i < info->indent; i++)
450 {
451 if (! append_type (info, " "))
015dc7e1 452 return false;
252b5132
RH
453 }
454
015dc7e1 455 return true;
252b5132
RH
456}
457
458/* Pop a type from the type stack. */
459
460static char *
2da42df6 461pop_type (struct pr_handle *info)
252b5132
RH
462{
463 struct pr_stack *o;
464 char *ret;
465
466 assert (info->stack != NULL);
467
468 o = info->stack;
469 info->stack = o->next;
470 ret = o->type;
471 free (o);
472
473 return ret;
474}
475
476/* Print a VMA value into a string. */
477
478static void
015dc7e1 479print_vma (bfd_vma vma, char *buf, bool unsignedp, bool hexp)
252b5132 480{
0e3c1eeb
AM
481 if (hexp)
482 sprintf (buf, "%#" PRIx64, (uint64_t) vma);
483 else if (unsignedp)
484 sprintf (buf, "%" PRIu64, (uint64_t) vma);
252b5132 485 else
0e3c1eeb 486 sprintf (buf, "%" PRId64, (int64_t) vma);
252b5132
RH
487}
488\f
489/* Start a new compilation unit. */
490
015dc7e1 491static bool
2da42df6 492pr_start_compilation_unit (void *p, const char *filename)
252b5132
RH
493{
494 struct pr_handle *info = (struct pr_handle *) p;
495
496 assert (info->indent == 0);
497
498 fprintf (info->f, "%s:\n", filename);
499
015dc7e1 500 return true;
252b5132
RH
501}
502
503/* Start a source file within a compilation unit. */
504
015dc7e1 505static bool
2da42df6 506pr_start_source (void *p, const char *filename)
252b5132
RH
507{
508 struct pr_handle *info = (struct pr_handle *) p;
509
510 assert (info->indent == 0);
511
512 fprintf (info->f, " %s:\n", filename);
513
015dc7e1 514 return true;
252b5132
RH
515}
516
517/* Push an empty type onto the type stack. */
518
015dc7e1 519static bool
2da42df6 520pr_empty_type (void *p)
252b5132
RH
521{
522 struct pr_handle *info = (struct pr_handle *) p;
523
524 return push_type (info, "<undefined>");
525}
526
527/* Push a void type onto the type stack. */
528
015dc7e1 529static bool
2da42df6 530pr_void_type (void *p)
252b5132
RH
531{
532 struct pr_handle *info = (struct pr_handle *) p;
533
534 return push_type (info, "void");
535}
536
537/* Push an integer type onto the type stack. */
538
015dc7e1
AM
539static bool
540pr_int_type (void *p, unsigned int size, bool unsignedp)
252b5132
RH
541{
542 struct pr_handle *info = (struct pr_handle *) p;
cea7a285 543 char ab[40];
252b5132
RH
544
545 sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
546 return push_type (info, ab);
547}
548
549/* Push a floating type onto the type stack. */
550
015dc7e1 551static bool
2da42df6 552pr_float_type (void *p, unsigned int size)
252b5132
RH
553{
554 struct pr_handle *info = (struct pr_handle *) p;
cea7a285 555 char ab[40];
252b5132
RH
556
557 if (size == 4)
558 return push_type (info, "float");
559 else if (size == 8)
560 return push_type (info, "double");
561
562 sprintf (ab, "float%d", size * 8);
563 return push_type (info, ab);
564}
565
566/* Push a complex type onto the type stack. */
567
015dc7e1 568static bool
2da42df6 569pr_complex_type (void *p, unsigned int size)
252b5132
RH
570{
571 struct pr_handle *info = (struct pr_handle *) p;
572
573 if (! pr_float_type (p, size))
015dc7e1 574 return false;
252b5132
RH
575
576 return prepend_type (info, "complex ");
577}
578
015dc7e1 579/* Push a bool type onto the type stack. */
252b5132 580
015dc7e1 581static bool
2da42df6 582pr_bool_type (void *p, unsigned int size)
252b5132
RH
583{
584 struct pr_handle *info = (struct pr_handle *) p;
cea7a285 585 char ab[40];
252b5132
RH
586
587 sprintf (ab, "bool%d", size * 8);
588
589 return push_type (info, ab);
590}
591
592/* Push an enum type onto the type stack. */
593
015dc7e1 594static bool
2da42df6
AJ
595pr_enum_type (void *p, const char *tag, const char **names,
596 bfd_signed_vma *values)
252b5132
RH
597{
598 struct pr_handle *info = (struct pr_handle *) p;
599 unsigned int i;
600 bfd_signed_vma val;
601
602 if (! push_type (info, "enum "))
015dc7e1 603 return false;
252b5132
RH
604 if (tag != NULL)
605 {
606 if (! append_type (info, tag)
607 || ! append_type (info, " "))
015dc7e1 608 return false;
252b5132
RH
609 }
610 if (! append_type (info, "{ "))
015dc7e1 611 return false;
252b5132
RH
612
613 if (names == NULL)
614 {
615 if (! append_type (info, "/* undefined */"))
015dc7e1 616 return false;
252b5132
RH
617 }
618 else
619 {
620 val = 0;
621 for (i = 0; names[i] != NULL; i++)
622 {
623 if (i > 0)
624 {
625 if (! append_type (info, ", "))
015dc7e1 626 return false;
252b5132
RH
627 }
628
629 if (! append_type (info, names[i]))
015dc7e1 630 return false;
252b5132
RH
631
632 if (values[i] != val)
633 {
98a4fc78 634 char ab[22];
252b5132 635
015dc7e1 636 print_vma (values[i], ab, false, false);
252b5132
RH
637 if (! append_type (info, " = ")
638 || ! append_type (info, ab))
015dc7e1 639 return false;
252b5132
RH
640 val = values[i];
641 }
642
643 ++val;
644 }
645 }
646
647 return append_type (info, " }");
648}
649
650/* Turn the top type on the stack into a pointer. */
651
015dc7e1 652static bool
2da42df6 653pr_pointer_type (void *p)
252b5132
RH
654{
655 struct pr_handle *info = (struct pr_handle *) p;
656 char *s;
657
658 assert (info->stack != NULL);
659
660 s = strchr (info->stack->type, '|');
661 if (s != NULL && s[1] == '[')
662 return substitute_type (info, "(*|)");
663 return substitute_type (info, "*|");
664}
665
666/* Turn the top type on the stack into a function returning that type. */
667
015dc7e1
AM
668static bool
669pr_function_type (void *p, int argcount, bool varargs)
252b5132
RH
670{
671 struct pr_handle *info = (struct pr_handle *) p;
672 char **arg_types;
673 unsigned int len;
674 char *s;
675
676 assert (info->stack != NULL);
677
678 len = 10;
679
680 if (argcount <= 0)
681 {
682 arg_types = NULL;
683 len += 15;
684 }
685 else
686 {
687 int i;
688
a5f3ca48 689 arg_types = xmalloc (argcount * sizeof (*arg_types));
252b5132
RH
690 for (i = argcount - 1; i >= 0; i--)
691 {
a5f3ca48
AM
692 if (!substitute_type (info, "")
693 || (arg_types[i] = pop_type (info)) == NULL)
09192bc7 694 {
a5f3ca48
AM
695 for (int j = i + 1; j < argcount; j++)
696 free (arg_types[j]);
09192bc7 697 free (arg_types);
015dc7e1 698 return false;
09192bc7 699 }
252b5132
RH
700 len += strlen (arg_types[i]) + 2;
701 }
702 if (varargs)
703 len += 5;
704 }
705
706 /* Now the return type is on the top of the stack. */
707
a5f3ca48 708 s = xmalloc (len);
57ae980e 709 strcpy (s, "(|) (");
252b5132
RH
710
711 if (argcount < 0)
712 strcat (s, "/* unknown */");
713 else
714 {
715 int i;
716
717 for (i = 0; i < argcount; i++)
718 {
719 if (i > 0)
720 strcat (s, ", ");
721 strcat (s, arg_types[i]);
a5f3ca48 722 free (arg_types[i]);
252b5132
RH
723 }
724 if (varargs)
725 {
726 if (i > 0)
727 strcat (s, ", ");
728 strcat (s, "...");
729 }
a5f3ca48 730 free (arg_types);
252b5132
RH
731 }
732
733 strcat (s, ")");
734
0d02e70b 735 bool ret = substitute_type (info, s);
252b5132 736 free (s);
0d02e70b 737 return ret;
252b5132
RH
738}
739
740/* Turn the top type on the stack into a reference to that type. */
741
015dc7e1 742static bool
2da42df6 743pr_reference_type (void *p)
252b5132
RH
744{
745 struct pr_handle *info = (struct pr_handle *) p;
746
747 assert (info->stack != NULL);
748
749 return substitute_type (info, "&|");
750}
751
752/* Make a range type. */
753
015dc7e1 754static bool
2da42df6 755pr_range_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper)
252b5132
RH
756{
757 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 758 char abl[22], abu[22];
252b5132
RH
759
760 assert (info->stack != NULL);
761
762 if (! substitute_type (info, ""))
015dc7e1 763 return false;
252b5132 764
015dc7e1
AM
765 print_vma (lower, abl, false, false);
766 print_vma (upper, abu, false, false);
252b5132
RH
767
768 return (prepend_type (info, "range (")
769 && append_type (info, "):")
770 && append_type (info, abl)
771 && append_type (info, ":")
772 && append_type (info, abu));
773}
774
775/* Make an array type. */
776
015dc7e1 777static bool
2da42df6 778pr_array_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper,
015dc7e1 779 bool stringp)
252b5132
RH
780{
781 struct pr_handle *info = (struct pr_handle *) p;
782 char *range_type;
98a4fc78 783 char abl[22], abu[22], ab[50];
252b5132
RH
784
785 range_type = pop_type (info);
786 if (range_type == NULL)
015dc7e1 787 return false;
252b5132
RH
788
789 if (lower == 0)
790 {
791 if (upper == -1)
792 sprintf (ab, "|[]");
793 else
794 {
015dc7e1 795 print_vma (upper + 1, abu, false, false);
252b5132
RH
796 sprintf (ab, "|[%s]", abu);
797 }
798 }
799 else
800 {
015dc7e1
AM
801 print_vma (lower, abl, false, false);
802 print_vma (upper, abu, false, false);
252b5132
RH
803 sprintf (ab, "|[%s:%s]", abl, abu);
804 }
805
806 if (! substitute_type (info, ab))
a5f3ca48 807 goto fail;
252b5132
RH
808
809 if (strcmp (range_type, "int") != 0)
810 {
811 if (! append_type (info, ":")
812 || ! append_type (info, range_type))
a5f3ca48 813 goto fail;
252b5132
RH
814 }
815
816 if (stringp)
817 {
818 if (! append_type (info, " /* string */"))
a5f3ca48 819 goto fail;
252b5132
RH
820 }
821
a5f3ca48 822 free (range_type);
015dc7e1 823 return true;
a5f3ca48
AM
824
825 fail:
826 free (range_type);
827 return false;
252b5132
RH
828}
829
830/* Make a set type. */
831
015dc7e1
AM
832static bool
833pr_set_type (void *p, bool bitstringp)
252b5132
RH
834{
835 struct pr_handle *info = (struct pr_handle *) p;
836
837 if (! substitute_type (info, ""))
015dc7e1 838 return false;
252b5132
RH
839
840 if (! prepend_type (info, "set { ")
841 || ! append_type (info, " }"))
015dc7e1 842 return false;
252b5132
RH
843
844 if (bitstringp)
845 {
846 if (! append_type (info, "/* bitstring */"))
015dc7e1 847 return false;
252b5132
RH
848 }
849
015dc7e1 850 return true;
252b5132
RH
851}
852
853/* Make an offset type. */
854
015dc7e1 855static bool
2da42df6 856pr_offset_type (void *p)
252b5132
RH
857{
858 struct pr_handle *info = (struct pr_handle *) p;
859 char *t;
860
861 if (! substitute_type (info, ""))
015dc7e1 862 return false;
252b5132
RH
863
864 t = pop_type (info);
865 if (t == NULL)
015dc7e1 866 return false;
252b5132 867
a5f3ca48
AM
868 bool ret = (substitute_type (info, "")
869 && prepend_type (info, " ")
870 && prepend_type (info, t)
871 && append_type (info, "::|"));
872 free (t);
873 return ret;
252b5132
RH
874}
875
876/* Make a method type. */
877
015dc7e1
AM
878static bool
879pr_method_type (void *p, bool domain, int argcount, bool varargs)
252b5132
RH
880{
881 struct pr_handle *info = (struct pr_handle *) p;
882 unsigned int len;
a5f3ca48 883 char *domain_type = NULL, *free_domain = NULL;
252b5132
RH
884 char **arg_types;
885 char *s;
886
887 len = 10;
888
a5f3ca48 889 if (domain)
252b5132
RH
890 {
891 if (! substitute_type (info, ""))
015dc7e1 892 return false;
252b5132
RH
893 domain_type = pop_type (info);
894 if (domain_type == NULL)
015dc7e1 895 return false;
a5f3ca48 896 free_domain = domain_type;
08dedd66 897 if (startswith (domain_type, "class ")
252b5132
RH
898 && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
899 domain_type += sizeof "class " - 1;
08dedd66 900 else if (startswith (domain_type, "union class ")
252b5132
RH
901 && (strchr (domain_type + sizeof "union class " - 1, ' ')
902 == NULL))
903 domain_type += sizeof "union class " - 1;
904 len += strlen (domain_type);
905 }
906
907 if (argcount <= 0)
908 {
909 arg_types = NULL;
910 len += 15;
911 }
912 else
913 {
914 int i;
915
a5f3ca48 916 arg_types = xmalloc (argcount * sizeof (*arg_types));
252b5132
RH
917 for (i = argcount - 1; i >= 0; i--)
918 {
a5f3ca48
AM
919 if (!substitute_type (info, "")
920 || (arg_types[i] = pop_type (info)) == NULL)
09192bc7 921 {
a5f3ca48
AM
922 for (int j = i + 1; j < argcount; ++j)
923 free (arg_types[j]);
09192bc7 924 free (arg_types);
015dc7e1 925 return false;
09192bc7 926 }
252b5132
RH
927 len += strlen (arg_types[i]) + 2;
928 }
929 if (varargs)
930 len += 5;
931 }
932
933 /* Now the return type is on the top of the stack. */
934
a5f3ca48
AM
935 s = xmalloc (len);
936 *s = 0;
937 if (domain)
938 {
939 strcpy (s, domain_type);
940 free (free_domain);
941 }
252b5132
RH
942 strcat (s, "::| (");
943
944 if (argcount < 0)
945 strcat (s, "/* unknown */");
946 else
947 {
948 int i;
949
950 for (i = 0; i < argcount; i++)
951 {
952 if (i > 0)
953 strcat (s, ", ");
954 strcat (s, arg_types[i]);
a5f3ca48 955 free (arg_types[i]);
252b5132
RH
956 }
957 if (varargs)
958 {
959 if (i > 0)
960 strcat (s, ", ");
961 strcat (s, "...");
962 }
a5f3ca48 963 free (arg_types);
252b5132
RH
964 }
965
966 strcat (s, ")");
967
a5f3ca48 968 bool ret = substitute_type (info, s);
252b5132 969 free (s);
a5f3ca48 970 return ret;
252b5132
RH
971}
972
973/* Make a const qualified type. */
974
015dc7e1 975static bool
2da42df6 976pr_const_type (void *p)
252b5132
RH
977{
978 struct pr_handle *info = (struct pr_handle *) p;
979
980 return substitute_type (info, "const |");
981}
982
983/* Make a volatile qualified type. */
984
015dc7e1 985static bool
2da42df6 986pr_volatile_type (void *p)
252b5132
RH
987{
988 struct pr_handle *info = (struct pr_handle *) p;
989
990 return substitute_type (info, "volatile |");
991}
992
993/* Start accumulating a struct type. */
994
015dc7e1 995static bool
2da42df6 996pr_start_struct_type (void *p, const char *tag, unsigned int id,
015dc7e1 997 bool structp, unsigned int size)
252b5132
RH
998{
999 struct pr_handle *info = (struct pr_handle *) p;
1000
1001 info->indent += 2;
1002
1003 if (! push_type (info, structp ? "struct " : "union "))
015dc7e1 1004 return false;
252b5132
RH
1005 if (tag != NULL)
1006 {
1007 if (! append_type (info, tag))
015dc7e1 1008 return false;
252b5132
RH
1009 }
1010 else
1011 {
1012 char idbuf[20];
1013
1014 sprintf (idbuf, "%%anon%u", id);
1015 if (! append_type (info, idbuf))
015dc7e1 1016 return false;
252b5132
RH
1017 }
1018
1019 if (! append_type (info, " {"))
015dc7e1 1020 return false;
252b5132
RH
1021 if (size != 0 || tag != NULL)
1022 {
1023 char ab[30];
1024
1025 if (! append_type (info, " /*"))
015dc7e1 1026 return false;
252b5132
RH
1027
1028 if (size != 0)
1029 {
1030 sprintf (ab, " size %u", size);
1031 if (! append_type (info, ab))
015dc7e1 1032 return false;
252b5132
RH
1033 }
1034 if (tag != NULL)
1035 {
1036 sprintf (ab, " id %u", id);
1037 if (! append_type (info, ab))
015dc7e1 1038 return false;
252b5132
RH
1039 }
1040 if (! append_type (info, " */"))
015dc7e1 1041 return false;
252b5132
RH
1042 }
1043 if (! append_type (info, "\n"))
015dc7e1 1044 return false;
252b5132
RH
1045
1046 info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
1047
1048 return indent_type (info);
1049}
1050
1051/* Output the visibility of a field in a struct. */
1052
015dc7e1 1053static bool
2da42df6 1054pr_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
252b5132 1055{
b4c96d0d 1056 const char *s = NULL;
252b5132
RH
1057 char *t;
1058 unsigned int len;
1059
1060 assert (info->stack != NULL);
1061
1062 if (info->stack->visibility == visibility)
015dc7e1 1063 return true;
252b5132 1064
252b5132
RH
1065 switch (visibility)
1066 {
1067 case DEBUG_VISIBILITY_PUBLIC:
1068 s = "public";
1069 break;
1070 case DEBUG_VISIBILITY_PRIVATE:
1071 s = "private";
1072 break;
1073 case DEBUG_VISIBILITY_PROTECTED:
1074 s = "protected";
1075 break;
1076 case DEBUG_VISIBILITY_IGNORE:
1077 s = "/* ignore */";
1078 break;
1079 default:
1080 abort ();
015dc7e1 1081 return false;
252b5132
RH
1082 }
1083
1084 /* Trim off a trailing space in the struct string, to make the
1085 output look a bit better, then stick on the visibility string. */
1086
1087 t = info->stack->type;
1088 len = strlen (t);
1089 assert (t[len - 1] == ' ');
1090 t[len - 1] = '\0';
1091
1092 if (! append_type (info, s)
1093 || ! append_type (info, ":\n")
1094 || ! indent_type (info))
015dc7e1 1095 return false;
252b5132
RH
1096
1097 info->stack->visibility = visibility;
1098
015dc7e1 1099 return true;
252b5132
RH
1100}
1101
1102/* Add a field to a struct type. */
1103
015dc7e1 1104static bool
2da42df6
AJ
1105pr_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize,
1106 enum debug_visibility visibility)
252b5132
RH
1107{
1108 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 1109 char ab[22];
252b5132
RH
1110 char *t;
1111
1112 if (! substitute_type (info, name))
015dc7e1 1113 return false;
252b5132
RH
1114
1115 if (! append_type (info, "; /* "))
015dc7e1 1116 return false;
252b5132
RH
1117
1118 if (bitsize != 0)
1119 {
015dc7e1 1120 print_vma (bitsize, ab, true, false);
252b5132
RH
1121 if (! append_type (info, "bitsize ")
1122 || ! append_type (info, ab)
1123 || ! append_type (info, ", "))
015dc7e1 1124 return false;
252b5132
RH
1125 }
1126
015dc7e1 1127 print_vma (bitpos, ab, true, false);
252b5132
RH
1128 if (! append_type (info, "bitpos ")
1129 || ! append_type (info, ab)
1130 || ! append_type (info, " */\n")
1131 || ! indent_type (info))
015dc7e1 1132 return false;
252b5132
RH
1133
1134 t = pop_type (info);
1135 if (t == NULL)
015dc7e1 1136 return false;
252b5132 1137
a5f3ca48
AM
1138 bool ret = pr_fix_visibility (info, visibility) && append_type (info, t);
1139 free (t);
1140 return ret;
252b5132
RH
1141}
1142
1143/* Finish a struct type. */
1144
015dc7e1 1145static bool
2da42df6 1146pr_end_struct_type (void *p)
252b5132
RH
1147{
1148 struct pr_handle *info = (struct pr_handle *) p;
1149 char *s;
1150
1151 assert (info->stack != NULL);
1152 assert (info->indent >= 2);
1153
1154 info->indent -= 2;
1155
1156 /* Change the trailing indentation to have a close brace. */
1157 s = info->stack->type + strlen (info->stack->type) - 2;
1158 assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
1159
1160 *s++ = '}';
1161 *s = '\0';
1162
015dc7e1 1163 return true;
252b5132
RH
1164}
1165
1166/* Start a class type. */
1167
015dc7e1 1168static bool
2da42df6 1169pr_start_class_type (void *p, const char *tag, unsigned int id,
015dc7e1
AM
1170 bool structp, unsigned int size,
1171 bool vptr, bool ownvptr)
252b5132
RH
1172{
1173 struct pr_handle *info = (struct pr_handle *) p;
1174 char *tv = NULL;
a5f3ca48 1175 bool ret = false;
252b5132
RH
1176
1177 info->indent += 2;
1178
1179 if (vptr && ! ownvptr)
1180 {
1181 tv = pop_type (info);
1182 if (tv == NULL)
015dc7e1 1183 return false;
252b5132
RH
1184 }
1185
1186 if (! push_type (info, structp ? "class " : "union class "))
a5f3ca48 1187 goto out;
252b5132
RH
1188 if (tag != NULL)
1189 {
1190 if (! append_type (info, tag))
a5f3ca48 1191 goto out;
252b5132
RH
1192 }
1193 else
1194 {
1195 char idbuf[20];
1196
1197 sprintf (idbuf, "%%anon%u", id);
1198 if (! append_type (info, idbuf))
a5f3ca48 1199 goto out;
252b5132
RH
1200 }
1201
1202 if (! append_type (info, " {"))
a5f3ca48 1203 goto out;
252b5132
RH
1204 if (size != 0 || vptr || ownvptr || tag != NULL)
1205 {
1206 if (! append_type (info, " /*"))
a5f3ca48 1207 goto out;
252b5132
RH
1208
1209 if (size != 0)
1210 {
1211 char ab[20];
1212
1213 sprintf (ab, "%u", size);
1214 if (! append_type (info, " size ")
1215 || ! append_type (info, ab))
a5f3ca48 1216 goto out;
252b5132
RH
1217 }
1218
1219 if (vptr)
1220 {
1221 if (! append_type (info, " vtable "))
a5f3ca48 1222 goto out;
252b5132
RH
1223 if (ownvptr)
1224 {
1225 if (! append_type (info, "self "))
a5f3ca48 1226 goto out;
252b5132
RH
1227 }
1228 else
1229 {
1230 if (! append_type (info, tv)
1231 || ! append_type (info, " "))
a5f3ca48 1232 goto out;
252b5132
RH
1233 }
1234 }
1235
1236 if (tag != NULL)
1237 {
1238 char ab[30];
1239
1240 sprintf (ab, " id %u", id);
1241 if (! append_type (info, ab))
a5f3ca48 1242 goto out;
252b5132
RH
1243 }
1244
1245 if (! append_type (info, " */"))
a5f3ca48 1246 goto out;
252b5132
RH
1247 }
1248
1249 info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
1250
a5f3ca48
AM
1251 ret = append_type (info, "\n") && indent_type (info);
1252 out:
1253 free (tv);
1254 return ret;
252b5132
RH
1255}
1256
1257/* Add a static member to a class. */
1258
015dc7e1 1259static bool
2da42df6
AJ
1260pr_class_static_member (void *p, const char *name, const char *physname,
1261 enum debug_visibility visibility)
252b5132
RH
1262{
1263 struct pr_handle *info = (struct pr_handle *) p;
1264 char *t;
1265
1266 if (! substitute_type (info, name))
015dc7e1 1267 return false;
252b5132
RH
1268
1269 if (! prepend_type (info, "static ")
1270 || ! append_type (info, "; /* ")
1271 || ! append_type (info, physname)
1272 || ! append_type (info, " */\n")
1273 || ! indent_type (info))
015dc7e1 1274 return false;
252b5132
RH
1275
1276 t = pop_type (info);
1277 if (t == NULL)
015dc7e1 1278 return false;
252b5132 1279
a5f3ca48
AM
1280 bool ret = pr_fix_visibility (info, visibility) && append_type (info, t);
1281 free (t);
1282 return ret;
252b5132
RH
1283}
1284
1285/* Add a base class to a class. */
1286
015dc7e1
AM
1287static bool
1288pr_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual,
2da42df6 1289 enum debug_visibility visibility)
252b5132
RH
1290{
1291 struct pr_handle *info = (struct pr_handle *) p;
1292 char *t;
1293 const char *prefix;
98a4fc78 1294 char ab[22];
252b5132
RH
1295 char *s, *l, *n;
1296
1297 assert (info->stack != NULL && info->stack->next != NULL);
1298
1299 if (! substitute_type (info, ""))
015dc7e1 1300 return false;
252b5132
RH
1301
1302 t = pop_type (info);
1303 if (t == NULL)
015dc7e1 1304 return false;
252b5132 1305
252b5132
RH
1306 /* Push it back on to take advantage of the prepend_type and
1307 append_type routines. */
a5f3ca48
AM
1308 if (! push_type (info, t + (startswith (t, "class ")
1309 ? sizeof "class " - 1 : 0)))
1310 {
1311 free (t);
1312 return false;
1313 }
1314 free (t);
252b5132 1315
3f5e193b 1316 if (is_virtual)
252b5132
RH
1317 {
1318 if (! prepend_type (info, "virtual "))
015dc7e1 1319 return false;
252b5132
RH
1320 }
1321
1322 switch (visibility)
1323 {
1324 case DEBUG_VISIBILITY_PUBLIC:
1325 prefix = "public ";
1326 break;
1327 case DEBUG_VISIBILITY_PROTECTED:
1328 prefix = "protected ";
1329 break;
1330 case DEBUG_VISIBILITY_PRIVATE:
1331 prefix = "private ";
1332 break;
1333 default:
1334 prefix = "/* unknown visibility */ ";
1335 break;
1336 }
1337
1338 if (! prepend_type (info, prefix))
015dc7e1 1339 return false;
252b5132
RH
1340
1341 if (bitpos != 0)
1342 {
015dc7e1 1343 print_vma (bitpos, ab, true, false);
252b5132
RH
1344 if (! append_type (info, " /* bitpos ")
1345 || ! append_type (info, ab)
1346 || ! append_type (info, " */"))
015dc7e1 1347 return false;
252b5132
RH
1348 }
1349
1350 /* Now the top of the stack is something like "public A / * bitpos
1351 10 * /". The next element on the stack is something like "class
1352 xx { / * size 8 * /\n...". We want to substitute the top of the
1353 stack in before the {. */
1354 s = strchr (info->stack->next->type, '{');
1355 assert (s != NULL);
1356 --s;
1357
1358 /* If there is already a ':', then we already have a baseclass, and
1359 we must append this one after a comma. */
1360 for (l = info->stack->next->type; l != s; l++)
1361 if (*l == ':')
1362 break;
1363 if (! prepend_type (info, l == s ? " : " : ", "))
015dc7e1 1364 return false;
252b5132
RH
1365
1366 t = pop_type (info);
1367 if (t == NULL)
015dc7e1 1368 return false;
252b5132 1369
a5f3ca48 1370 n = xmalloc (strlen (info->stack->type) + strlen (t) + 1);
252b5132
RH
1371 memcpy (n, info->stack->type, s - info->stack->type);
1372 strcpy (n + (s - info->stack->type), t);
1373 strcat (n, s);
1374
1375 free (info->stack->type);
1376 info->stack->type = n;
1377
1378 free (t);
1379
015dc7e1 1380 return true;
252b5132
RH
1381}
1382
1383/* Start adding a method to a class. */
1384
015dc7e1 1385static bool
2da42df6 1386pr_class_start_method (void *p, const char *name)
252b5132
RH
1387{
1388 struct pr_handle *info = (struct pr_handle *) p;
1389
1390 assert (info->stack != NULL);
a5f3ca48
AM
1391 free (info->stack->method);
1392 info->stack->method = xstrdup (name);
015dc7e1 1393 return true;
252b5132
RH
1394}
1395
1396/* Add a variant to a method. */
1397
015dc7e1 1398static bool
2da42df6
AJ
1399pr_class_method_variant (void *p, const char *physname,
1400 enum debug_visibility visibility,
015dc7e1
AM
1401 bool constp, bool volatilep,
1402 bfd_vma voffset, bool context)
252b5132
RH
1403{
1404 struct pr_handle *info = (struct pr_handle *) p;
1405 char *method_type;
1406 char *context_type;
a5f3ca48 1407 bool ret = false;
252b5132
RH
1408
1409 assert (info->stack != NULL);
1410 assert (info->stack->next != NULL);
1411
1412 /* Put the const and volatile qualifiers on the type. */
1413 if (volatilep)
1414 {
1415 if (! append_type (info, " volatile"))
015dc7e1 1416 return false;
252b5132
RH
1417 }
1418 if (constp)
1419 {
1420 if (! append_type (info, " const"))
015dc7e1 1421 return false;
252b5132
RH
1422 }
1423
1424 /* Stick the name of the method into its type. */
1425 if (! substitute_type (info,
1426 (context
1427 ? info->stack->next->next->method
1428 : info->stack->next->method)))
015dc7e1 1429 return false;
252b5132
RH
1430
1431 /* Get the type. */
1432 method_type = pop_type (info);
1433 if (method_type == NULL)
015dc7e1 1434 return false;
252b5132
RH
1435
1436 /* Pull off the context type if there is one. */
1437 if (! context)
1438 context_type = NULL;
1439 else
1440 {
1441 context_type = pop_type (info);
1442 if (context_type == NULL)
a5f3ca48 1443 goto out;
252b5132
RH
1444 }
1445
1446 /* Now the top of the stack is the class. */
1447
1448 if (! pr_fix_visibility (info, visibility))
a5f3ca48 1449 goto out;
252b5132
RH
1450
1451 if (! append_type (info, method_type)
1452 || ! append_type (info, " /* ")
1453 || ! append_type (info, physname)
1454 || ! append_type (info, " "))
a5f3ca48 1455 goto out;
252b5132
RH
1456 if (context || voffset != 0)
1457 {
98a4fc78 1458 char ab[22];
252b5132
RH
1459
1460 if (context)
1461 {
1462 if (! append_type (info, "context ")
1463 || ! append_type (info, context_type)
1464 || ! append_type (info, " "))
a5f3ca48 1465 goto out;
252b5132 1466 }
015dc7e1 1467 print_vma (voffset, ab, true, false);
252b5132
RH
1468 if (! append_type (info, "voffset ")
1469 || ! append_type (info, ab))
a5f3ca48 1470 goto out;
252b5132
RH
1471 }
1472
a5f3ca48
AM
1473 ret = append_type (info, " */;\n") && indent_type (info);
1474 out:
1475 free (method_type);
1476 free (context_type);
1477 return ret;
252b5132
RH
1478}
1479
1480/* Add a static variant to a method. */
1481
015dc7e1 1482static bool
2da42df6
AJ
1483pr_class_static_method_variant (void *p, const char *physname,
1484 enum debug_visibility visibility,
015dc7e1 1485 bool constp, bool volatilep)
252b5132
RH
1486{
1487 struct pr_handle *info = (struct pr_handle *) p;
1488 char *method_type;
1489
1490 assert (info->stack != NULL);
1491 assert (info->stack->next != NULL);
1492 assert (info->stack->next->method != NULL);
1493
1494 /* Put the const and volatile qualifiers on the type. */
1495 if (volatilep)
1496 {
1497 if (! append_type (info, " volatile"))
015dc7e1 1498 return false;
252b5132
RH
1499 }
1500 if (constp)
1501 {
1502 if (! append_type (info, " const"))
015dc7e1 1503 return false;
252b5132
RH
1504 }
1505
1506 /* Mark it as static. */
1507 if (! prepend_type (info, "static "))
015dc7e1 1508 return false;
252b5132
RH
1509
1510 /* Stick the name of the method into its type. */
1511 if (! substitute_type (info, info->stack->next->method))
015dc7e1 1512 return false;
252b5132
RH
1513
1514 /* Get the type. */
1515 method_type = pop_type (info);
1516 if (method_type == NULL)
015dc7e1 1517 return false;
252b5132
RH
1518
1519 /* Now the top of the stack is the class. */
1520
a5f3ca48
AM
1521 bool ret = (pr_fix_visibility (info, visibility)
1522 && append_type (info, method_type)
1523 && append_type (info, " /* ")
1524 && append_type (info, physname)
1525 && append_type (info, " */;\n")
1526 && indent_type (info));
1527 free (method_type);
1528 return ret;
252b5132
RH
1529}
1530
1531/* Finish up a method. */
1532
015dc7e1 1533static bool
2da42df6 1534pr_class_end_method (void *p)
252b5132
RH
1535{
1536 struct pr_handle *info = (struct pr_handle *) p;
1537
a5f3ca48 1538 free (info->stack->method);
252b5132 1539 info->stack->method = NULL;
015dc7e1 1540 return true;
252b5132
RH
1541}
1542
1543/* Finish up a class. */
1544
015dc7e1 1545static bool
2da42df6 1546pr_end_class_type (void *p)
252b5132
RH
1547{
1548 return pr_end_struct_type (p);
1549}
1550
1551/* Push a type on the stack using a typedef name. */
1552
015dc7e1 1553static bool
2da42df6 1554pr_typedef_type (void *p, const char *name)
252b5132
RH
1555{
1556 struct pr_handle *info = (struct pr_handle *) p;
1557
1558 return push_type (info, name);
1559}
1560
1561/* Push a type on the stack using a tag name. */
1562
015dc7e1 1563static bool
2da42df6
AJ
1564pr_tag_type (void *p, const char *name, unsigned int id,
1565 enum debug_type_kind kind)
252b5132
RH
1566{
1567 struct pr_handle *info = (struct pr_handle *) p;
1568 const char *t, *tag;
98a4fc78 1569 char idbuf[22];
252b5132
RH
1570
1571 switch (kind)
1572 {
1573 case DEBUG_KIND_STRUCT:
1574 t = "struct ";
1575 break;
1576 case DEBUG_KIND_UNION:
1577 t = "union ";
1578 break;
1579 case DEBUG_KIND_ENUM:
1580 t = "enum ";
1581 break;
1582 case DEBUG_KIND_CLASS:
1583 t = "class ";
1584 break;
1585 case DEBUG_KIND_UNION_CLASS:
1586 t = "union class ";
1587 break;
1588 default:
5be2b2f5 1589 /* PR 25625: Corrupt input can trigger this case. */
015dc7e1 1590 return false;
252b5132
RH
1591 }
1592
1593 if (! push_type (info, t))
015dc7e1 1594 return false;
252b5132
RH
1595 if (name != NULL)
1596 tag = name;
1597 else
1598 {
1599 sprintf (idbuf, "%%anon%u", id);
1600 tag = idbuf;
1601 }
1602
1603 if (! append_type (info, tag))
015dc7e1 1604 return false;
252b5132
RH
1605 if (name != NULL && kind != DEBUG_KIND_ENUM)
1606 {
1607 sprintf (idbuf, " /* id %u */", id);
1608 if (! append_type (info, idbuf))
015dc7e1 1609 return false;
252b5132
RH
1610 }
1611
015dc7e1 1612 return true;
252b5132
RH
1613}
1614
1615/* Output a typedef. */
1616
015dc7e1 1617static bool
2da42df6 1618pr_typdef (void *p, const char *name)
252b5132
RH
1619{
1620 struct pr_handle *info = (struct pr_handle *) p;
1621 char *s;
1622
1623 if (! substitute_type (info, name))
015dc7e1 1624 return false;
252b5132
RH
1625
1626 s = pop_type (info);
1627 if (s == NULL)
015dc7e1 1628 return false;
252b5132
RH
1629
1630 indent (info);
1631 fprintf (info->f, "typedef %s;\n", s);
1632
1633 free (s);
1634
015dc7e1 1635 return true;
252b5132
RH
1636}
1637
1638/* Output a tag. The tag should already be in the string on the
1639 stack, so all we have to do here is print it out. */
1640
015dc7e1 1641static bool
2da42df6 1642pr_tag (void *p, const char *name ATTRIBUTE_UNUSED)
252b5132
RH
1643{
1644 struct pr_handle *info = (struct pr_handle *) p;
1645 char *t;
1646
1647 t = pop_type (info);
1648 if (t == NULL)
015dc7e1 1649 return false;
252b5132
RH
1650
1651 indent (info);
1652 fprintf (info->f, "%s;\n", t);
1653
1654 free (t);
1655
015dc7e1 1656 return true;
252b5132
RH
1657}
1658
1659/* Output an integer constant. */
1660
015dc7e1 1661static bool
2da42df6 1662pr_int_constant (void *p, const char *name, bfd_vma val)
252b5132
RH
1663{
1664 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 1665 char ab[22];
252b5132
RH
1666
1667 indent (info);
015dc7e1 1668 print_vma (val, ab, false, false);
252b5132 1669 fprintf (info->f, "const int %s = %s;\n", name, ab);
015dc7e1 1670 return true;
252b5132
RH
1671}
1672
1673/* Output a floating point constant. */
1674
015dc7e1 1675static bool
2da42df6 1676pr_float_constant (void *p, const char *name, double val)
252b5132
RH
1677{
1678 struct pr_handle *info = (struct pr_handle *) p;
1679
1680 indent (info);
1681 fprintf (info->f, "const double %s = %g;\n", name, val);
015dc7e1 1682 return true;
252b5132
RH
1683}
1684
1685/* Output a typed constant. */
1686
015dc7e1 1687static bool
2da42df6 1688pr_typed_constant (void *p, const char *name, bfd_vma val)
252b5132
RH
1689{
1690 struct pr_handle *info = (struct pr_handle *) p;
1691 char *t;
98a4fc78 1692 char ab[22];
252b5132
RH
1693
1694 t = pop_type (info);
1695 if (t == NULL)
015dc7e1 1696 return false;
252b5132
RH
1697
1698 indent (info);
015dc7e1 1699 print_vma (val, ab, false, false);
252b5132
RH
1700 fprintf (info->f, "const %s %s = %s;\n", t, name, ab);
1701
1702 free (t);
1703
015dc7e1 1704 return true;
252b5132
RH
1705}
1706
1707/* Output a variable. */
1708
015dc7e1 1709static bool
2da42df6
AJ
1710pr_variable (void *p, const char *name, enum debug_var_kind kind,
1711 bfd_vma val)
252b5132
RH
1712{
1713 struct pr_handle *info = (struct pr_handle *) p;
1714 char *t;
98a4fc78 1715 char ab[22];
252b5132
RH
1716
1717 if (! substitute_type (info, name))
015dc7e1 1718 return false;
252b5132
RH
1719
1720 t = pop_type (info);
1721 if (t == NULL)
015dc7e1 1722 return false;
252b5132
RH
1723
1724 indent (info);
1725 switch (kind)
1726 {
1727 case DEBUG_STATIC:
1728 case DEBUG_LOCAL_STATIC:
1729 fprintf (info->f, "static ");
1730 break;
1731 case DEBUG_REGISTER:
1732 fprintf (info->f, "register ");
1733 break;
1734 default:
1735 break;
1736 }
015dc7e1 1737 print_vma (val, ab, true, true);
252b5132
RH
1738 fprintf (info->f, "%s /* %s */;\n", t, ab);
1739
1740 free (t);
1741
015dc7e1 1742 return true;
252b5132
RH
1743}
1744
1745/* Start outputting a function. */
1746
015dc7e1
AM
1747static bool
1748pr_start_function (void *p, const char *name, bool global)
252b5132
RH
1749{
1750 struct pr_handle *info = (struct pr_handle *) p;
1751 char *t;
1752
1753 if (! substitute_type (info, name))
015dc7e1 1754 return false;
252b5132
RH
1755
1756 t = pop_type (info);
1757 if (t == NULL)
015dc7e1 1758 return false;
252b5132
RH
1759
1760 indent (info);
1761 if (! global)
1762 fprintf (info->f, "static ");
1763 fprintf (info->f, "%s (", t);
1764
a5f3ca48
AM
1765 free (t);
1766
252b5132
RH
1767 info->parameter = 1;
1768
015dc7e1 1769 return true;
252b5132
RH
1770}
1771
1772/* Output a function parameter. */
1773
015dc7e1 1774static bool
2da42df6
AJ
1775pr_function_parameter (void *p, const char *name,
1776 enum debug_parm_kind kind, bfd_vma val)
252b5132
RH
1777{
1778 struct pr_handle *info = (struct pr_handle *) p;
1779 char *t;
98a4fc78 1780 char ab[22];
252b5132
RH
1781
1782 if (kind == DEBUG_PARM_REFERENCE
1783 || kind == DEBUG_PARM_REF_REG)
1784 {
1785 if (! pr_reference_type (p))
015dc7e1 1786 return false;
252b5132
RH
1787 }
1788
1789 if (! substitute_type (info, name))
015dc7e1 1790 return false;
252b5132
RH
1791
1792 t = pop_type (info);
1793 if (t == NULL)
015dc7e1 1794 return false;
252b5132
RH
1795
1796 if (info->parameter != 1)
1797 fprintf (info->f, ", ");
1798
1799 if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
1800 fprintf (info->f, "register ");
1801
015dc7e1 1802 print_vma (val, ab, true, true);
252b5132
RH
1803 fprintf (info->f, "%s /* %s */", t, ab);
1804
1805 free (t);
1806
1807 ++info->parameter;
1808
015dc7e1 1809 return true;
252b5132
RH
1810}
1811
1812/* Start writing out a block. */
1813
015dc7e1 1814static bool
2da42df6 1815pr_start_block (void *p, bfd_vma addr)
252b5132
RH
1816{
1817 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 1818 char ab[22];
252b5132
RH
1819
1820 if (info->parameter > 0)
1821 {
1822 fprintf (info->f, ")\n");
1823 info->parameter = 0;
1824 }
1825
1826 indent (info);
015dc7e1 1827 print_vma (addr, ab, true, true);
252b5132
RH
1828 fprintf (info->f, "{ /* %s */\n", ab);
1829
1830 info->indent += 2;
1831
015dc7e1 1832 return true;
252b5132
RH
1833}
1834
1835/* Write out line number information. */
1836
015dc7e1 1837static bool
2da42df6 1838pr_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr)
252b5132
RH
1839{
1840 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 1841 char ab[22];
252b5132
RH
1842
1843 indent (info);
015dc7e1 1844 print_vma (addr, ab, true, true);
252b5132
RH
1845 fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab);
1846
015dc7e1 1847 return true;
252b5132
RH
1848}
1849
1850/* Finish writing out a block. */
1851
015dc7e1 1852static bool
2da42df6 1853pr_end_block (void *p, bfd_vma addr)
252b5132
RH
1854{
1855 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 1856 char ab[22];
252b5132
RH
1857
1858 info->indent -= 2;
1859
1860 indent (info);
015dc7e1 1861 print_vma (addr, ab, true, true);
252b5132
RH
1862 fprintf (info->f, "} /* %s */\n", ab);
1863
015dc7e1 1864 return true;
252b5132
RH
1865}
1866
1867/* Finish writing out a function. */
1868
015dc7e1 1869static bool
2da42df6 1870pr_end_function (void *p ATTRIBUTE_UNUSED)
252b5132 1871{
015dc7e1 1872 return true;
252b5132 1873}
51cdc6e0
NC
1874\f
1875/* Tags style generation functions start here. */
1876
1877/* Variables for address to line translation. */
1878static bfd_vma pc;
1879static const char *filename;
1880static const char *functionname;
1881static unsigned int line;
015dc7e1 1882static bool found;
51cdc6e0
NC
1883
1884/* Look for an address in a section. This is called via
1885 bfd_map_over_sections. */
1886
1887static void
1888find_address_in_section (bfd *abfd, asection *section, void *data)
1889{
1890 bfd_vma vma;
1891 bfd_size_type size;
1892 asymbol **syms = (asymbol **) data;
1893
1894 if (found)
1895 return;
1896
fd361982 1897 if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
51cdc6e0
NC
1898 return;
1899
fd361982 1900 vma = bfd_section_vma (section);
51cdc6e0
NC
1901 if (pc < vma)
1902 return;
1903
fd361982 1904 size = bfd_section_size (section);
51cdc6e0
NC
1905 if (pc >= vma + size)
1906 return;
1907
1908 found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
1909 &filename, &functionname, &line);
1910}
1911
1912static void
1913translate_addresses (bfd *abfd, char *addr_hex, FILE *f, asymbol **syms)
1914{
1915 pc = bfd_scan_vma (addr_hex, NULL, 16);
015dc7e1 1916 found = false;
51cdc6e0
NC
1917 bfd_map_over_sections (abfd, find_address_in_section, syms);
1918
1919 if (! found)
1920 fprintf (f, "??");
1921 else
1922 fprintf (f, "%u", line);
1923}
1924
1925/* Start a new compilation unit. */
1926
015dc7e1 1927static bool
91d6fa6a 1928tg_start_compilation_unit (void * p, const char *fname ATTRIBUTE_UNUSED)
51cdc6e0
NC
1929{
1930 struct pr_handle *info = (struct pr_handle *) p;
1931
51cdc6e0
NC
1932 free (info->filename);
1933 /* Should it be relative? best way to do it here?. */
a5f3ca48 1934 info->filename = xstrdup (fname);
51cdc6e0 1935
015dc7e1 1936 return true;
51cdc6e0
NC
1937}
1938
1939/* Start a source file within a compilation unit. */
1940
015dc7e1 1941static bool
91d6fa6a 1942tg_start_source (void *p, const char *fname)
51cdc6e0
NC
1943{
1944 struct pr_handle *info = (struct pr_handle *) p;
1945
1946 free (info->filename);
1947 /* Should it be relative? best way to do it here?. */
a5f3ca48 1948 info->filename = xstrdup (fname);
51cdc6e0 1949
015dc7e1 1950 return true;
51cdc6e0
NC
1951}
1952
1953/* Push an enum type onto the type stack. */
1954
015dc7e1 1955static bool
51cdc6e0
NC
1956tg_enum_type (void *p, const char *tag, const char **names,
1957 bfd_signed_vma *values)
1958{
1959 struct pr_handle *info = (struct pr_handle *) p;
1960 unsigned int i;
1961 const char *name;
98a4fc78 1962 char ab[22];
51cdc6e0
NC
1963
1964 if (! pr_enum_type (p, tag, names, values))
015dc7e1 1965 return false;
51cdc6e0
NC
1966
1967 name = tag ? tag : "unknown";
1968 /* Generate an entry for the enum. */
1969 if (tag)
1970 fprintf (info->f, "%s\t%s\t0;\"\tkind:e\ttype:%s\n", tag,
1971 info->filename, info->stack->type);
1972
1973 /* Generate entries for the values. */
1974 if (names != NULL)
1975 {
1976 for (i = 0; names[i] != NULL; i++)
1977 {
015dc7e1 1978 print_vma (values[i], ab, false, false);
51cdc6e0
NC
1979 fprintf (info->f, "%s\t%s\t0;\"\tkind:g\tenum:%s\tvalue:%s\n",
1980 names[i], info->filename, name, ab);
1981 }
1982 }
1983
015dc7e1 1984 return true;
51cdc6e0
NC
1985}
1986
1987/* Start accumulating a struct type. */
1988
015dc7e1 1989static bool
51cdc6e0 1990tg_start_struct_type (void *p, const char *tag, unsigned int id,
015dc7e1 1991 bool structp,
2da42df6 1992 unsigned int size ATTRIBUTE_UNUSED)
51cdc6e0
NC
1993{
1994 struct pr_handle *info = (struct pr_handle *) p;
1995 const char *name;
1996 char idbuf[20];
1997
1998 if (tag != NULL)
1999 name = tag;
2000 else
2001 {
2002 name = idbuf;
2003 sprintf (idbuf, "%%anon%u", id);
2004 }
2005
2006 if (! push_type (info, name))
015dc7e1 2007 return false;
51cdc6e0
NC
2008
2009 info->stack->flavor = structp ? "struct" : "union";
2010
2011 fprintf (info->f, "%s\t%s\t0;\"\tkind:%c\n", name, info->filename,
2012 info->stack->flavor[0]);
2013
2014 info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
2015
2016 return indent_type (info);
2017}
2018
2019/* Output the visibility of a field in a struct. */
2020
015dc7e1 2021static bool
51cdc6e0
NC
2022tg_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
2023{
2024 assert (info->stack != NULL);
2025
2026 if (info->stack->visibility == visibility)
015dc7e1 2027 return true;
51cdc6e0
NC
2028
2029 assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
2030
2031 info->stack->visibility = visibility;
2032
015dc7e1 2033 return true;
51cdc6e0
NC
2034}
2035
2036/* Add a field to a struct type. */
2037
015dc7e1 2038static bool
51cdc6e0
NC
2039tg_struct_field (void *p, const char *name, bfd_vma bitpos ATTRIBUTE_UNUSED,
2040 bfd_vma bitsize ATTRIBUTE_UNUSED,
2041 enum debug_visibility visibility)
2042{
2043 struct pr_handle *info = (struct pr_handle *) p;
2044 char *t;
2045
2046 t = pop_type (info);
2047 if (t == NULL)
015dc7e1 2048 return false;
51cdc6e0
NC
2049
2050 if (! tg_fix_visibility (info, visibility))
a5f3ca48
AM
2051 {
2052 free (t);
2053 return false;
2054 }
51cdc6e0 2055
aaad4cf3 2056 /* It happens, a bug? */
51cdc6e0 2057 if (! name[0])
a5f3ca48
AM
2058 {
2059 free (t);
2060 return true;
2061 }
51cdc6e0
NC
2062
2063 fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n",
2064 name, info->filename, t, info->stack->flavor, info->stack->type,
2065 visibility_name (visibility));
2066
a5f3ca48
AM
2067 free (t);
2068
015dc7e1 2069 return true;
51cdc6e0
NC
2070}
2071
2072/* Finish a struct type. */
2073
015dc7e1 2074static bool
51cdc6e0
NC
2075tg_end_struct_type (void *p ATTRIBUTE_UNUSED)
2076{
9d7c77a5 2077 assert (((struct pr_handle *) p)->stack != NULL);
51cdc6e0 2078
015dc7e1 2079 return true;
51cdc6e0
NC
2080}
2081
2082/* Start a class type. */
2083
015dc7e1 2084static bool
51cdc6e0 2085tg_start_class_type (void *p, const char *tag, unsigned int id,
015dc7e1
AM
2086 bool structp, unsigned int size,
2087 bool vptr, bool ownvptr)
51cdc6e0
NC
2088{
2089 struct pr_handle *info = (struct pr_handle *) p;
2090 char *tv = NULL;
2091 const char *name;
1f67cf98 2092 char idbuf[20];
a5f3ca48 2093 bool ret = false;
51cdc6e0
NC
2094
2095 info->indent += 2;
2096
2097 if (vptr && ! ownvptr)
2098 {
2099 tv = pop_type (info);
2100 if (tv == NULL)
015dc7e1 2101 return false;
51cdc6e0
NC
2102 }
2103
2104 if (tag != NULL)
2105 name = tag;
2106 else
2107 {
51cdc6e0
NC
2108 sprintf (idbuf, "%%anon%u", id);
2109 name = idbuf;
2110 }
2111
2112 if (! push_type (info, name))
a5f3ca48 2113 goto out;
51cdc6e0
NC
2114
2115 info->stack->flavor = structp ? "class" : "union class";
a5f3ca48 2116 free (info->stack->parents);
51cdc6e0 2117 info->stack->parents = NULL;
51cdc6e0
NC
2118
2119 if (size != 0 || vptr || ownvptr || tag != NULL)
2120 {
2121 if (vptr)
2122 {
2123 if (! append_type (info, " vtable "))
a5f3ca48 2124 goto out;
51cdc6e0
NC
2125 if (ownvptr)
2126 {
2127 if (! append_type (info, "self "))
a5f3ca48 2128 goto out;
51cdc6e0
NC
2129 }
2130 else
2131 {
2132 if (! append_type (info, tv)
2133 || ! append_type (info, " "))
a5f3ca48 2134 goto out;
51cdc6e0
NC
2135 }
2136 }
2137 }
2138
2139 info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
2140
a5f3ca48
AM
2141 ret = true;
2142 out:
2143 free (tv);
2144 return ret;
51cdc6e0
NC
2145}
2146
2147/* Add a static member to a class. */
2148
015dc7e1 2149static bool
51cdc6e0
NC
2150tg_class_static_member (void *p, const char *name,
2151 const char *physname ATTRIBUTE_UNUSED,
2152 enum debug_visibility visibility)
2153{
2154 struct pr_handle *info = (struct pr_handle *) p;
2155 char *t;
2156 int len_var, len_class;
2157 char *full_name;
2158
2159 len_var = strlen (name);
2160 len_class = strlen (info->stack->next->type);
a5f3ca48 2161 full_name = xmalloc (len_var + len_class + 3);
ea9986ff 2162 sprintf (full_name, "%s::%s", info->stack->next->type, name);
51cdc6e0
NC
2163
2164 if (! substitute_type (info, full_name))
09192bc7
NC
2165 {
2166 free (full_name);
015dc7e1 2167 return false;
09192bc7 2168 }
51cdc6e0
NC
2169
2170 if (! prepend_type (info, "static "))
09192bc7
NC
2171 {
2172 free (full_name);
015dc7e1 2173 return false;
09192bc7 2174 }
51cdc6e0
NC
2175
2176 t = pop_type (info);
2177 if (t == NULL)
09192bc7
NC
2178 {
2179 free (full_name);
015dc7e1 2180 return false;
09192bc7 2181 }
51cdc6e0
NC
2182
2183 if (! tg_fix_visibility (info, visibility))
09192bc7
NC
2184 {
2185 free (t);
2186 free (full_name);
015dc7e1 2187 return false;
09192bc7 2188 }
51cdc6e0
NC
2189
2190 fprintf (info->f, "%s\t%s\t0;\"\tkind:x\ttype:%s\tclass:%s\taccess:%s\n",
2191 name, info->filename, t, info->stack->type,
2192 visibility_name (visibility));
2193 free (t);
2194 free (full_name);
2195
015dc7e1 2196 return true;
51cdc6e0
NC
2197}
2198
2199/* Add a base class to a class. */
2200
015dc7e1 2201static bool
51cdc6e0 2202tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED,
015dc7e1 2203 bool is_virtual, enum debug_visibility visibility)
51cdc6e0
NC
2204{
2205 struct pr_handle *info = (struct pr_handle *) p;
2206 char *t;
2207 const char *prefix;
2208
2209 assert (info->stack != NULL && info->stack->next != NULL);
2210
2211 t = pop_type (info);
2212 if (t == NULL)
015dc7e1 2213 return false;
51cdc6e0 2214
51cdc6e0
NC
2215 /* Push it back on to take advantage of the prepend_type and
2216 append_type routines. */
a5f3ca48
AM
2217 if (! push_type (info, t + (startswith (t, "class ")
2218 ? sizeof "class " - 1 : 0)))
2219 {
2220 free (t);
2221 return false;
2222 }
2223 free (t);
51cdc6e0 2224
3f5e193b 2225 if (is_virtual)
51cdc6e0
NC
2226 {
2227 if (! prepend_type (info, "virtual "))
015dc7e1 2228 return false;
51cdc6e0
NC
2229 }
2230
2231 switch (visibility)
2232 {
2233 case DEBUG_VISIBILITY_PUBLIC:
2234 prefix = "public ";
2235 break;
2236 case DEBUG_VISIBILITY_PROTECTED:
2237 prefix = "protected ";
2238 break;
2239 case DEBUG_VISIBILITY_PRIVATE:
2240 prefix = "private ";
2241 break;
2242 default:
2243 prefix = "/* unknown visibility */ ";
2244 break;
2245 }
2246
2247 if (! prepend_type (info, prefix))
015dc7e1 2248 return false;
51cdc6e0
NC
2249
2250 t = pop_type (info);
2251 if (t == NULL)
015dc7e1 2252 return false;
51cdc6e0 2253
a5f3ca48
AM
2254 bool ret = ((!info->stack->parents || append_parent (info, ", "))
2255 && append_parent (info, t));
51cdc6e0 2256 free (t);
a5f3ca48 2257 return ret;
51cdc6e0
NC
2258}
2259
2260/* Add a variant to a method. */
2261
015dc7e1 2262static bool
51cdc6e0
NC
2263tg_class_method_variant (void *p, const char *physname ATTRIBUTE_UNUSED,
2264 enum debug_visibility visibility,
015dc7e1 2265 bool constp, bool volatilep,
51cdc6e0 2266 bfd_vma voffset ATTRIBUTE_UNUSED,
015dc7e1 2267 bool context)
51cdc6e0
NC
2268{
2269 struct pr_handle *info = (struct pr_handle *) p;
2270 char *method_type;
2271 char *context_type;
2272 char *method_name;
2273
2274 assert (info->stack != NULL);
2275 assert (info->stack->next != NULL);
2276
2277 /* Put the const and volatile qualifiers on the type. */
2278 if (volatilep)
2279 {
2280 if (! append_type (info, " volatile"))
015dc7e1 2281 return false;
51cdc6e0
NC
2282 }
2283 if (constp)
2284 {
2285 if (! append_type (info, " const"))
015dc7e1 2286 return false;
51cdc6e0
NC
2287 }
2288
2289 method_name = strdup (context ? info->stack->next->next->method
2290 : info->stack->next->method);
2da42df6 2291
51cdc6e0
NC
2292 /* Stick the name of the method into its type. */
2293 if (! substitute_type (info, method_name))
09192bc7
NC
2294 {
2295 free (method_name);
015dc7e1 2296 return false;
09192bc7 2297 }
51cdc6e0
NC
2298
2299 /* Get the type. */
2300 method_type = pop_type (info);
2301 if (method_type == NULL)
09192bc7
NC
2302 {
2303 free (method_name);
015dc7e1 2304 return false;
09192bc7 2305 }
51cdc6e0
NC
2306
2307 /* Pull off the context type if there is one. */
2308 if (! context)
2309 context_type = NULL;
2310 else
2311 {
2312 context_type = pop_type (info);
2313 if (context_type == NULL)
09192bc7
NC
2314 {
2315 free (method_type);
2316 free (method_name);
015dc7e1 2317 return false;
09192bc7 2318 }
51cdc6e0
NC
2319 }
2320
2321 /* Now the top of the stack is the class. */
2322 if (! tg_fix_visibility (info, visibility))
09192bc7
NC
2323 {
2324 free (method_type);
2325 free (method_name);
2326 free (context_type);
015dc7e1 2327 return false;
09192bc7 2328 }
51cdc6e0
NC
2329
2330 fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\n",
2331 method_name, info->filename, method_type, info->stack->type);
2332 free (method_type);
2333 free (method_name);
2334 free (context_type);
2da42df6 2335
015dc7e1 2336 return true;
51cdc6e0
NC
2337}
2338
2339/* Add a static variant to a method. */
2340
015dc7e1 2341static bool
51cdc6e0
NC
2342tg_class_static_method_variant (void *p,
2343 const char *physname ATTRIBUTE_UNUSED,
2344 enum debug_visibility visibility,
015dc7e1 2345 bool constp, bool volatilep)
51cdc6e0
NC
2346{
2347 struct pr_handle *info = (struct pr_handle *) p;
2348 char *method_type;
2349 char *method_name;
2350
2351 assert (info->stack != NULL);
2352 assert (info->stack->next != NULL);
2353 assert (info->stack->next->method != NULL);
2354
2355 /* Put the const and volatile qualifiers on the type. */
2356 if (volatilep)
2357 {
2358 if (! append_type (info, " volatile"))
015dc7e1 2359 return false;
51cdc6e0
NC
2360 }
2361 if (constp)
2362 {
2363 if (! append_type (info, " const"))
015dc7e1 2364 return false;
51cdc6e0
NC
2365 }
2366
2367 /* Mark it as static. */
2368 if (! prepend_type (info, "static "))
015dc7e1 2369 return false;
51cdc6e0
NC
2370
2371 method_name = strdup (info->stack->next->method);
2372 /* Stick the name of the method into its type. */
2373 if (! substitute_type (info, info->stack->next->method))
09192bc7
NC
2374 {
2375 free (method_name);
015dc7e1 2376 return false;
09192bc7 2377 }
51cdc6e0
NC
2378
2379 /* Get the type. */
2380 method_type = pop_type (info);
2381 if (method_type == NULL)
09192bc7
NC
2382 {
2383 free (method_name);
015dc7e1 2384 return false;
09192bc7 2385 }
51cdc6e0
NC
2386
2387 /* Now the top of the stack is the class. */
2388 if (! tg_fix_visibility (info, visibility))
09192bc7
NC
2389 {
2390 free (method_type);
2391 free (method_name);
015dc7e1 2392 return false;
09192bc7 2393 }
51cdc6e0
NC
2394
2395 fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\taccess:%s\n",
2396 method_name, info->filename, method_type, info->stack->type,
2397 visibility_name (visibility));
2398 free (method_type);
2399 free (method_name);
2400
015dc7e1 2401 return true;
51cdc6e0
NC
2402}
2403
2404/* Finish up a class. */
2405
015dc7e1 2406static bool
51cdc6e0
NC
2407tg_end_class_type (void *p)
2408{
2409 struct pr_handle *info = (struct pr_handle *) p;
2410
2411 fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type,
2412 info->filename, info->stack->flavor);
a5f3ca48 2413 if (info->stack->parents)
51cdc6e0
NC
2414 {
2415 fprintf (info->f, "\tinherits:%s", info->stack->parents);
2416 free (info->stack->parents);
a5f3ca48 2417 info->stack->parents = NULL;
51cdc6e0
NC
2418 }
2419 fputc ('\n', info->f);
2420
2421 return tg_end_struct_type (p);
2422}
2423
2424/* Push a type on the stack using a tag name. */
2425
015dc7e1 2426static bool
51cdc6e0
NC
2427tg_tag_type (void *p, const char *name, unsigned int id,
2428 enum debug_type_kind kind)
2429{
2430 struct pr_handle *info = (struct pr_handle *) p;
2431 const char *t, *tag;
2432 char idbuf[20];
2433
2434 switch (kind)
2435 {
2436 case DEBUG_KIND_STRUCT:
2437 t = "struct ";
2438 break;
2439 case DEBUG_KIND_UNION:
2440 t = "union ";
2441 break;
2442 case DEBUG_KIND_ENUM:
2443 t = "enum ";
2444 break;
2445 case DEBUG_KIND_CLASS:
2446 t = "class ";
2447 break;
2448 case DEBUG_KIND_UNION_CLASS:
2449 t = "union class ";
2450 break;
2451 default:
2452 abort ();
015dc7e1 2453 return false;
51cdc6e0
NC
2454 }
2455
2456 if (! push_type (info, t))
015dc7e1 2457 return false;
51cdc6e0
NC
2458 if (name != NULL)
2459 tag = name;
2460 else
2461 {
2462 sprintf (idbuf, "%%anon%u", id);
2463 tag = idbuf;
2464 }
2465
2466 if (! append_type (info, tag))
015dc7e1 2467 return false;
51cdc6e0 2468
015dc7e1 2469 return true;
51cdc6e0
NC
2470}
2471
2472/* Output a typedef. */
2473
015dc7e1 2474static bool
51cdc6e0
NC
2475tg_typdef (void *p, const char *name)
2476{
2477 struct pr_handle *info = (struct pr_handle *) p;
2478 char *s;
2479
2480 s = pop_type (info);
2481 if (s == NULL)
015dc7e1 2482 return false;
51cdc6e0
NC
2483
2484 fprintf (info->f, "%s\t%s\t0;\"\tkind:t\ttype:%s\n", name,
2485 info->filename, s);
2486
2487 free (s);
2488
015dc7e1 2489 return true;
51cdc6e0
NC
2490}
2491
2492/* Output a tag. The tag should already be in the string on the
2493 stack, so all we have to do here is print it out. */
2494
015dc7e1 2495static bool
51cdc6e0
NC
2496tg_tag (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED)
2497{
2498 struct pr_handle *info = (struct pr_handle *) p;
2499 char *t;
2500
2501 t = pop_type (info);
2502 if (t == NULL)
015dc7e1 2503 return false;
51cdc6e0
NC
2504 free (t);
2505
015dc7e1 2506 return true;
51cdc6e0
NC
2507}
2508
2509/* Output an integer constant. */
2510
015dc7e1 2511static bool
51cdc6e0
NC
2512tg_int_constant (void *p, const char *name, bfd_vma val)
2513{
2514 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 2515 char ab[22];
51cdc6e0
NC
2516
2517 indent (info);
015dc7e1 2518 print_vma (val, ab, false, false);
51cdc6e0
NC
2519 fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const int\tvalue:%s\n",
2520 name, info->filename, ab);
015dc7e1 2521 return true;
51cdc6e0
NC
2522}
2523
2524/* Output a floating point constant. */
2525
015dc7e1 2526static bool
51cdc6e0
NC
2527tg_float_constant (void *p, const char *name, double val)
2528{
2529 struct pr_handle *info = (struct pr_handle *) p;
2530
2531 indent (info);
2532 fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const double\tvalue:%g\n",
2533 name, info->filename, val);
015dc7e1 2534 return true;
51cdc6e0
NC
2535}
2536
2537/* Output a typed constant. */
2538
015dc7e1 2539static bool
51cdc6e0
NC
2540tg_typed_constant (void *p, const char *name, bfd_vma val)
2541{
2542 struct pr_handle *info = (struct pr_handle *) p;
2543 char *t;
98a4fc78 2544 char ab[22];
51cdc6e0
NC
2545
2546 t = pop_type (info);
2547 if (t == NULL)
015dc7e1 2548 return false;
51cdc6e0
NC
2549
2550 indent (info);
015dc7e1 2551 print_vma (val, ab, false, false);
51cdc6e0
NC
2552 fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const %s\tvalue:%s\n",
2553 name, info->filename, t, ab);
2554
2555 free (t);
2556
015dc7e1 2557 return true;
51cdc6e0
NC
2558}
2559
2560/* Output a variable. */
2561
015dc7e1 2562static bool
51cdc6e0
NC
2563tg_variable (void *p, const char *name, enum debug_var_kind kind,
2564 bfd_vma val ATTRIBUTE_UNUSED)
2565{
2566 struct pr_handle *info = (struct pr_handle *) p;
e74ecdb3 2567 char *t, *dname, *from_class;
51cdc6e0
NC
2568
2569 t = pop_type (info);
2570 if (t == NULL)
015dc7e1 2571 return false;
51cdc6e0 2572
e74ecdb3 2573 dname = NULL;
51cdc6e0 2574 if (info->demangler)
af03af8f 2575 dname = info->demangler (info->abfd, name, demangle_flags);
51cdc6e0 2576
e74ecdb3
AM
2577 from_class = NULL;
2578 if (dname != NULL)
51cdc6e0
NC
2579 {
2580 char *sep;
2581 sep = strstr (dname, "::");
2582 if (sep)
2583 {
2584 *sep = 0;
2585 name = sep + 2;
2586 from_class = dname;
2587 }
2588 else
e74ecdb3
AM
2589 /* Obscure types as vts and type_info nodes. */
2590 name = dname;
51cdc6e0 2591 }
51cdc6e0
NC
2592
2593 fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:%s", name, info->filename, t);
2594
2595 switch (kind)
2596 {
2597 case DEBUG_STATIC:
2598 case DEBUG_LOCAL_STATIC:
2599 fprintf (info->f, "\tfile:");
2600 break;
2601 case DEBUG_REGISTER:
2602 fprintf (info->f, "\tregister:");
2603 break;
2604 default:
2605 break;
2606 }
2607
2608 if (from_class)
e74ecdb3
AM
2609 fprintf (info->f, "\tclass:%s", from_class);
2610
2611 if (dname)
2612 free (dname);
51cdc6e0
NC
2613
2614 fprintf (info->f, "\n");
2615
2616 free (t);
2617
015dc7e1 2618 return true;
51cdc6e0
NC
2619}
2620
2621/* Start outputting a function. */
2622
015dc7e1
AM
2623static bool
2624tg_start_function (void *p, const char *name, bool global)
51cdc6e0
NC
2625{
2626 struct pr_handle *info = (struct pr_handle *) p;
e74ecdb3 2627 char *dname;
51cdc6e0
NC
2628
2629 if (! global)
2630 info->stack->flavor = "static";
2631 else
2632 info->stack->flavor = NULL;
2633
e74ecdb3 2634 dname = NULL;
51cdc6e0 2635 if (info->demangler)
af03af8f 2636 dname = info->demangler (info->abfd, name, demangle_flags);
51cdc6e0 2637
e74ecdb3 2638 if (! substitute_type (info, dname ? dname : name))
015dc7e1 2639 return false;
2da42df6 2640
a5f3ca48 2641 free (info->stack->method);
e74ecdb3
AM
2642 info->stack->method = NULL;
2643 if (dname != NULL)
51cdc6e0
NC
2644 {
2645 char *sep;
2646 sep = strstr (dname, "::");
2647 if (sep)
2648 {
2649 info->stack->method = dname;
a5f3ca48 2650 dname = NULL;
51cdc6e0
NC
2651 *sep = 0;
2652 name = sep + 2;
2653 }
2654 else
2655 {
a5f3ca48 2656 info->stack->method = xstrdup ("");
51cdc6e0
NC
2657 name = dname;
2658 }
2659 sep = strchr (name, '(');
2660 if (sep)
2661 *sep = 0;
2662 /* Obscure functions as type_info function. */
2663 }
51cdc6e0 2664
a5f3ca48 2665 free (info->stack->parents);
51cdc6e0 2666 info->stack->parents = strdup (name);
a5f3ca48 2667 free (dname);
51cdc6e0
NC
2668
2669 if (! info->stack->method && ! append_type (info, "("))
015dc7e1 2670 return false;
51cdc6e0
NC
2671
2672 info->parameter = 1;
2673
015dc7e1 2674 return true;
51cdc6e0
NC
2675}
2676
2677/* Output a function parameter. */
2678
015dc7e1 2679static bool
51cdc6e0
NC
2680tg_function_parameter (void *p, const char *name, enum debug_parm_kind kind,
2681 bfd_vma val ATTRIBUTE_UNUSED)
2682{
2683 struct pr_handle *info = (struct pr_handle *) p;
2684 char *t;
2685
2686 if (kind == DEBUG_PARM_REFERENCE
2687 || kind == DEBUG_PARM_REF_REG)
2688 {
2689 if (! pr_reference_type (p))
015dc7e1 2690 return false;
51cdc6e0
NC
2691 }
2692
2693 if (! substitute_type (info, name))
015dc7e1 2694 return false;
51cdc6e0
NC
2695
2696 t = pop_type (info);
2697 if (t == NULL)
015dc7e1 2698 return false;
51cdc6e0
NC
2699
2700 if (! info->stack->method)
2701 {
2702 if (info->parameter != 1 && ! append_type (info, ", "))
a5f3ca48
AM
2703 {
2704 free (t);
2705 return false;
2706 }
2da42df6 2707
51cdc6e0
NC
2708 if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
2709 if (! append_type (info, "register "))
a5f3ca48
AM
2710 {
2711 free (t);
2712 return false;
2713 }
2da42df6 2714
51cdc6e0 2715 if (! append_type (info, t))
a5f3ca48
AM
2716 {
2717 free (t);
2718 return false;
2719 }
51cdc6e0
NC
2720 }
2721
2722 free (t);
2723
2724 ++info->parameter;
2725
015dc7e1 2726 return true;
51cdc6e0
NC
2727}
2728
2729/* Start writing out a block. */
2730
015dc7e1 2731static bool
51cdc6e0
NC
2732tg_start_block (void *p, bfd_vma addr)
2733{
2734 struct pr_handle *info = (struct pr_handle *) p;
98a4fc78 2735 char ab[22], kind, *partof;
51cdc6e0 2736 char *t;
015dc7e1 2737 bool local;
51cdc6e0
NC
2738
2739 if (info->parameter > 0)
2740 {
2741 info->parameter = 0;
2742
2743 /* Delayed name. */
2744 fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename);
2745 free (info->stack->parents);
a5f3ca48 2746 info->stack->parents = NULL;
51cdc6e0 2747
015dc7e1 2748 print_vma (addr, ab, true, true);
51cdc6e0
NC
2749 translate_addresses (info->abfd, ab, info->f, info->syms);
2750 local = info->stack->flavor != NULL;
2751 if (info->stack->method && *info->stack->method)
2752 {
2753 kind = 'm';
2754 partof = (char *) info->stack->method;
2755 }
2756 else
2757 {
2758 kind = 'f';
2759 partof = NULL;
2760 if (! info->stack->method && ! append_type (info, ")"))
015dc7e1 2761 return false;
51cdc6e0
NC
2762 }
2763 t = pop_type (info);
2764 if (t == NULL)
015dc7e1 2765 return false;
51cdc6e0 2766 fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t);
a5f3ca48 2767 free (t);
51cdc6e0
NC
2768 if (local)
2769 fputs ("\tfile:", info->f);
2770 if (partof)
a5f3ca48 2771 fprintf (info->f, "\tclass:%s", partof);
51cdc6e0 2772 fputc ('\n', info->f);
a5f3ca48
AM
2773 free (info->stack->method);
2774 info->stack->method = NULL;
51cdc6e0
NC
2775 }
2776
015dc7e1 2777 return true;
51cdc6e0
NC
2778}
2779
2780/* Write out line number information. */
2781
015dc7e1 2782static bool
91d6fa6a 2783tg_lineno (void *p ATTRIBUTE_UNUSED, const char *fname ATTRIBUTE_UNUSED,
51cdc6e0
NC
2784 unsigned long lineno ATTRIBUTE_UNUSED,
2785 bfd_vma addr ATTRIBUTE_UNUSED)
2786{
015dc7e1 2787 return true;
51cdc6e0
NC
2788}
2789
2790/* Finish writing out a block. */
2791
015dc7e1 2792static bool
51cdc6e0
NC
2793tg_end_block (void *p ATTRIBUTE_UNUSED, bfd_vma addr ATTRIBUTE_UNUSED)
2794{
015dc7e1 2795 return true;
51cdc6e0
NC
2796}
2797
2798/* Convert the visibility value into a human readable name. */
2799
2800static const char *
2801visibility_name (enum debug_visibility visibility)
2802{
2803 const char *s;
2804
2805 switch (visibility)
2806 {
2807 case DEBUG_VISIBILITY_PUBLIC:
2808 s = "public";
2809 break;
2810 case DEBUG_VISIBILITY_PRIVATE:
2811 s = "private";
2812 break;
2813 case DEBUG_VISIBILITY_PROTECTED:
2814 s = "protected";
2815 break;
2816 case DEBUG_VISIBILITY_IGNORE:
2817 s = "/* ignore */";
2818 break;
2819 default:
2820 abort ();
015dc7e1 2821 return false;
51cdc6e0
NC
2822 }
2823 return s;
2824}