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