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