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