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