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