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